import turtle,time,random bob = turtle.Turtle() sc = turtle.Screen() WIDTH = 1000 HEIGHT = 500 sc.setup(WIDTH,HEIGHT) ROWS = 10 COLUMNS = 20 START = (1,1) END = (10,20) centers = [[0 for i in range(COLUMNS)] for j in range(ROWS)] if HEIGHT//ROWS < WIDTH//COLUMNS: side = HEIGHT//ROWS-5 else: side = WIDTH//COLUMNS-5 def square(x,y,side,fill): bob.penup() bob.setpos(x,y) bob.setheading(0) bob.pendown() if fill: bob.begin_fill() for i in range(4): bob.forward(side) bob.right(90) bob.penup() if fill: bob.end_fill() def drawGrid(rows,columns): sc.tracer(1000) ycor = (-HEIGHT//2)+side+10 for i in range(rows): xcor = -WIDTH//2+10 for j in range(columns): centers[i][j] = (xcor+side//2,ycor-side//2) square(xcor,ycor,side,0) xcor+=side ycor+=side def goto(row,column): row = row-1 column = column-1 bob.setpos(centers[row][column][0],centers[row][column][1]) def gridsquare(row,column): row = row-1 column = column-1 bob.setpos(centers[row][column][0]-side//2,centers[row][column][1]+side//2) bob.begin_fill() for i in range(4): bob.forward(side) bob.right(90) bob.penup() bob.end_fill() def setobstacles(number): obstacles = [0]*number n = 0 while obstacles[-1] == 0: x = random.randint(1,ROWS) y = random.randint(1,COLUMNS) print(x,y) if (x,y) != START and (x,y) != END: obstacles[n] = (x,y) n += 1 return obstacles def drawobstacles(obstacles): for i in obstacles: print(i) gridsquare(i[0],i[1]) def drawstartend(START,END): bob.fillcolor("green") gridsquare(START[0],START[1]) bob.fillcolor("red") gridsquare(END[0],END[1]) obstacles = setobstacles(30) drawGrid(ROWS,COLUMNS) drawobstacles(obstacles) drawstartend(START,END) sc.tracer(2) bob.penup() goto(START[0],START[1]) currentx = START[0] currenty = START[1] DONE = False while not DONE: bob.pendown() candidates = [0]*4 if currentx-1 > 0 and (currentx-1,currenty) not in obstacles: candidates[0]=(currentx-1,currenty) if currentx+1 <= ROWS and (currentx+1,currenty) not in obstacles: candidates[1]=(currentx+1,currenty) if currenty+1 <= COLUMNS and (currentx,currenty+1) not in obstacles: candidates[2]=(currentx,currenty+1) if currenty-1 > 0 and (currentx,currenty-1) not in obstacles: candidates[3]=(currentx,currenty-1) candidates = [x for x in candidates if x != 0] print(currentx,currenty) #print(candidates) future = random.choice(candidates) print(future) #time.sleep(0.1) goto(future[0],future[1]) currentx = future[0] currenty = future[1] if currentx == END[0] and currenty == END[1]: DONE = True
Author Archives: admin
7/19/24 Balloon Launch from High Point State Park
Here is the data from our successful launch on 7/19/24.
We launched at 12:16 pm from the Appalachian Trail head parking lot in High Point State Park, Sussex, NJ.
At 3:46 pm, 125 miles of flight later, the balloon landed in Bantam Lake, Bantam, CT.
Splashdown was witnessed by the ops team of Leonardo DRS from Danbury, CT, out on the lake for a boat day, who made the recovery. A special thank you to Shae and the DRS ops team for saving the electronics from a watery grave!
Long Island in the distance.
Peak altitude: 24 km!!
The fork of Long Island.
Here is the complete flight video. Note that the software cut out midway through the descent. The problem is being investigated – it is possible the battery froze.
Balloon Code V4
import os import picamera import serial import time import board import adafruit_bmp280 import RPi.GPIO as GPIO import json GPIO.setwarnings(False) #GPIO.setmode(GPIO.BOARD) GPIO.setup(18, GPIO.OUT, initial=GPIO.LOW) i2c = board.I2C() bmp = adafruit_bmp280.Adafruit_BMP280_I2C(i2c) bmp.sea_level_pressure = 1013.25 camera = picamera.PiCamera() camera.resolution = (1280, 720) camera.rotation = 180 framerate = 5 camera.framerate = framerate camera.annotate_text_size = 18 gps = "GPS Data" gpsPort = "/dev/ttyACM0" gpsSerial = serial.Serial(gpsPort, baudrate = 9600, timeout = 0.5) loggingObject = { 'GPS':{ 'latitude':{ 'degrees': 0, 'minutes': 0, 'seconds': 0, 'NS': 0 }, 'longitude':{ 'degrees': 0, 'minutes': 0, 'seconds': 0, 'EW': 0 }, 'altitude': 0, 'satellites': 0 }, 'speed': 0, 'altitude': 0, 'time': '', 'temperature': 0, 'humidity': 0 } def getPicture(annotation): filename = "/home/pi/Pictures/" + str(time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())) + ".jpg" try: camera.start_preview() time.sleep(2.5) camera.annotate_text = annotation camera.capture(filename) camera.stop_preview() except Exception as error: return(error) camera.stop_preview() return filename def getVideo(length): filename = "/home/pi/Videos/" + str(time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())) + ".mp4" try: camera.start_recording("/home/pi/testVideo.h264") for index in range(length): start = time.time() camera.annotate_text = (annotate()) end = time.time() elapsed = start - end if elapsed <= 1: time.sleep(1 - elapsed) camera.stop_recording() except Exception as error: return(error) os.system("ffmpeg -r " + str(framerate) + " -i /home/pi/testVideo.h264 -vcodec copy " + filename) os.system("del /home/pi/testVideo.h264") return filename def gpgga(): output = "" emailgps = "" try: n = 1 while output == "" and n<50: gps = str(gpsSerial.readline()) #print(n) if (gps[2:8] == "$GPGGA" or gps[2:8] == "$GNGGA"): gps = gps.split(",") #lat long formatted for digital maps latgps = gps[2][0:2] + ' ' + gps[2][2:] longgps = '-'+gps[4][1:3] + ' ' + gps[4][3:] emailgps = latgps+','+longgps latDeg = int(gps[2][0:2]) latMin = int(gps[2][2:4]) latSec = round(float(gps[2][5:9]) * (3/500)) latNS = gps[3] output += "Latitude: " + str(latDeg) + " deg " + str(latMin) + "'" + str(latSec) + '" ' + latNS + "\n" longDeg = int(gps[4][0:3]) longMin = int(gps[4][3:5]) longSec = round(float(gps[4][6:10]) * (3/500)) longEW = gps[5] output += "Longitude: " + str(longDeg) + " deg " + str(longMin) + "'" + str(longSec) + '" ' + longEW + "\n" alt = float(gps[9]) output += "Altitude: " + str(alt) + " m" + "\n" sat = int(gps[7]) output += "Satellites: " + str(sat) loggingObject['GPS'] = { 'latitude':{ 'degrees': latDeg, 'minutes': latMin, 'seconds': latSec, 'NS': latNS }, 'longitude':{ 'degrees': longDeg, 'minutes': longMin, 'seconds': longSec, 'EW': longEW }, 'altitude': alt, 'satellites': sat } n+=1 return [output,emailgps] except Exception as error: return ["",""] def gprmc(): output = "" try: n = 1 while output == "" and n<50: #print(n) gps = str(gpsSerial.readline()) if gps[2:8] == "$GPRMC" or gps[2:8] == "$GNRMC": gps = gps.split(",") output = "" speed = round(float(gps[7]) * 1852)/1000 loggingObject["speed"] = speed output += "Speed: " + str(speed) + " km/h" n+=1 return output except Exception as error: return("") def gps(): try: output = gpgga()[0] + "\n" + gprmc() return output except Exception as error: return("") def accurate_altitude(): try: output = 'BMP280 Altitude: {} m'.format(round(bmp.altitude)) loggingObject['altitude'] = round(bmp.altitude) return output except Exception as error: return("") def annotate(): timeNow = str(time.strftime("%a %d %b %Y %H:%M:%S", time.localtime())) print(timeNow) locationNow = gps() bmpa = accurate_altitude() annotation = timeNow + "\n" + locationNow + "\n" + bmpa return annotation def logData(): try: loggingObject['time'] = time.time() filename = 'home/pi/loggedData/' + str(time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())) + '.json' writtenFile = open(filename,'w') writtenFile.write(json.dumps(loggingObject, sort_keys=True, indent=4)) writtenFile.close() except Exception as error: pass def flyBalloon(): while True: try: getVideo(10) #40 GPIO.output(18, GPIO.HIGH) getPicture("") getPicture(annotate()) logData() GPIO.output(18,GPIO.LOW) except Exception as error: return(error) flyBalloon()
Advent of Code 2023-25a
import networkx as nx import matplotlib.pyplot as plt import re floppy = open("input25.txt", mode='r', encoding='utf-8') thing = floppy.readlines() floppy.close() sourcenode = [] for i, word in enumerate(thing): sourcenode.append(word[0:3]) thing[i] = word[4:].split() visual = [] for i, source in enumerate(sourcenode): for dest in thing[i]: visual.append([source,dest]) G = nx.Graph() G.add_edges_from(visual) nx.draw_networkx(G) plt.show()
import networkx as nx import matplotlib.pyplot as plt G = nx.Graph() G.add_edges_from([['a','b'],['b','c'],['a','c'],['s','u']]) nx.draw_networkx(G) plt.show()
6/15/19 Balloon Launch
7/9/21 Balloon Launch Allentown, PA to Lafayette, NJ
7/29/22 Balloon Launch from High Point State Park
8/3/23 Balloon Launch from Cold Spring
Balloon Code V3
import os import picamera import serial import time import board import adafruit_bmp280 import RPi.GPIO as GPIO GPIO.setwarnings(False) #GPIO.setmode(GPIO.BOARD) GPIO.setup(18, GPIO.OUT, initial=GPIO.LOW) i2c = board.I2C() bmp = adafruit_bmp280.Adafruit_BMP280_I2C(i2c) bmp.sea_level_pressure = 1013.25 camera = picamera.PiCamera() camera.resolution = (1280, 720) camera.rotation = 180 framerate = 5 camera.framerate = framerate camera.annotate_text_size = 18 gps = "GPS Data" gpsPort = "/dev/ttyACM0" gpsSerial = serial.Serial(gpsPort, baudrate = 9600, timeout = 0.5) def getPicture(annotation): filename = "/home/pi/Pictures/" + str(time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())) + ".jpg" try: camera.start_preview() time.sleep(2.5) camera.annotate_text = annotation camera.capture(filename) camera.stop_preview() except Exception as error: return(error) camera.stop_preview() return filename def getVideo(length): filename = "/home/pi/Videos/" + str(time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())) + ".mp4" try: camera.start_recording("/home/pi/testVideo.h264") for index in range(length): start = time.time() camera.annotate_text = (annotate()) end = time.time() elapsed = start - end if elapsed <= 1: time.sleep(1 - elapsed) camera.stop_recording() except Exception as error: return(error) os.system("ffmpeg -r " + str(framerate) + " -i /home/pi/testVideo.h264 -vcodec copy " + filename) os.system("del /home/pi/testVideo.h264") return filename def gpgga(): output = "" emailgps = "" try: n = 1 while output == "" and n<50: gps = str(gpsSerial.readline()) #print(n) if (gps[2:8] == "$GPGGA" or gps[2:8] == "$GNGGA"): gps = gps.split(",") #lat long formatted for digital maps latgps = gps[2][0:2] + ' ' + gps[2][2:] longgps = '-'+gps[4][1:3] + ' ' + gps[4][3:] emailgps = latgps+','+longgps latDeg = int(gps[2][0:2]) latMin = int(gps[2][2:4]) latSec = round(float(gps[2][5:9]) * (3/500)) latNS = gps[3] output += "Latitude: " + str(latDeg) + " deg " + str(latMin) + "'" + str(latSec) + '" ' + latNS + "\n" longDeg = int(gps[4][0:3]) longMin = int(gps[4][3:5]) longSec = round(float(gps[4][6:10]) * (3/500)) longEW = gps[5] output += "Longitude: " + str(longDeg) + " deg " + str(longMin) + "'" + str(longSec) + '" ' + longEW + "\n" alt = float(gps[9]) output += "Altitude: " + str(alt) + " m" + "\n" sat = int(gps[7]) output += "Satellites: " + str(sat) n+=1 return [output,emailgps] except Exception as error: return ["",""] def gprmc(): output = "" try: n = 1 while output == "" and n<50: #print(n) gps = str(gpsSerial.readline()) if gps[2:8] == "$GPRMC" or gps[2:8] == "$GNRMC": gps = gps.split(",") output = "" speed = round(float(gps[7]) * 1852)/1000 output += "Speed: " + str(speed) + " km/h" n+=1 return output except Exception as error: return("") def gps(): try: output = gpgga()[0] + "\n" + gprmc() return output except Exception as error: return("") def accurate_altitude(): try: output = 'BMP280 Altitude: {} m'.format(round(bmp.altitude)) return output except Exception as error: return("") def annotate(): timeNow = str(time.strftime("%a %d %b %Y %H:%M:%S", time.localtime())) locationNow = gps() bmpa = accurate_altitude() annotation = timeNow + "\n" + locationNow + "\n" + bmpa return annotation def flyBalloon(): while True: try: getVideo(10) #40 GPIO.output(18, GPIO.HIGH) getPicture("") getPicture(annotate()) GPIO.output(18,GPIO.LOW) except Exception as error: return(error) flyBalloon()
Prim’s Algorithm Maze Generation
</div> # Maze generator -- Randomized Prim Algorithm ## Imports import random import time from colorama import init from colorama import Fore, Back, Style ## Functions def printMaze(maze): for i in range(0, height): for j in range(0, width): if (maze[i][j] == 'u'): print(Fore.WHITE + str(maze[i][j]), end=" ") elif (maze[i][j] == 'c'): print(Fore.GREEN + str(maze[i][j]), end=" ") else: print(Fore.RED + str(maze[i][j]), end=" ") print('\n') # Find number of surrounding cells def surroundingCells(rand_wall): s_cells = 0 if (maze[rand_wall[0]-1][rand_wall[1]] == 'c'): s_cells += 1 if (maze[rand_wall[0]+1][rand_wall[1]] == 'c'): s_cells += 1 if (maze[rand_wall[0]][rand_wall[1]-1] == 'c'): s_cells +=1 if (maze[rand_wall[0]][rand_wall[1]+1] == 'c'): s_cells += 1 return s_cells ## Main code # Init variables wall = 'w' cell = 'c' unvisited = 'u' height = 11 width = 27 maze = [] # Initialize colorama init(convert=True) # Denote all cells as unvisited for i in range(0, height): line = [] for j in range(0, width): line.append(unvisited) maze.append(line) # Randomize starting point and set it a cell starting_height = int(random.random()*height) starting_width = int(random.random()*width) if (starting_height == 0): starting_height += 1 if (starting_height == height-1): starting_height -= 1 if (starting_width == 0): starting_width += 1 if (starting_width == width-1): starting_width -= 1 # Mark it as cell and add surrounding walls to the list maze[starting_height][starting_width] = cell walls = [] walls.append([starting_height - 1, starting_width]) walls.append([starting_height, starting_width - 1]) walls.append([starting_height, starting_width + 1]) walls.append([starting_height + 1, starting_width]) # Denote walls in maze maze[starting_height-1][starting_width] = 'w' maze[starting_height][starting_width - 1] = 'w' maze[starting_height][starting_width + 1] = 'w' maze[starting_height + 1][starting_width] = 'w' while (walls): # Pick a random wall rand_wall = walls[int(random.random()*len(walls))-1] # Check if it is a left wall if (rand_wall[1] != 0): if (maze[rand_wall[0]][rand_wall[1]-1] == 'u' and maze[rand_wall[0]][rand_wall[1]+1] == 'c'): # Find the number of surrounding cells s_cells = surroundingCells(rand_wall) if (s_cells < 2): # Denote the new path maze[rand_wall[0]][rand_wall[1]] = 'c' # Mark the new walls # Upper cell if (rand_wall[0] != 0): if (maze[rand_wall[0]-1][rand_wall[1]] != 'c'): maze[rand_wall[0]-1][rand_wall[1]] = 'w' if ([rand_wall[0]-1, rand_wall[1]] not in walls): walls.append([rand_wall[0]-1, rand_wall[1]]) # Bottom cell if (rand_wall[0] != height-1): if (maze[rand_wall[0]+1][rand_wall[1]] != 'c'): maze[rand_wall[0]+1][rand_wall[1]] = 'w' if ([rand_wall[0]+1, rand_wall[1]] not in walls): walls.append([rand_wall[0]+1, rand_wall[1]]) # Leftmost cell if (rand_wall[1] != 0): if (maze[rand_wall[0]][rand_wall[1]-1] != 'c'): maze[rand_wall[0]][rand_wall[1]-1] = 'w' if ([rand_wall[0], rand_wall[1]-1] not in walls): walls.append([rand_wall[0], rand_wall[1]-1]) # Delete wall for wall in walls: if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]): walls.remove(wall) continue # Check if it is an upper wall if (rand_wall[0] != 0): if (maze[rand_wall[0]-1][rand_wall[1]] == 'u' and maze[rand_wall[0]+1][rand_wall[1]] == 'c'): s_cells = surroundingCells(rand_wall) if (s_cells < 2): # Denote the new path maze[rand_wall[0]][rand_wall[1]] = 'c' # Mark the new walls # Upper cell if (rand_wall[0] != 0): if (maze[rand_wall[0]-1][rand_wall[1]] != 'c'): maze[rand_wall[0]-1][rand_wall[1]] = 'w' if ([rand_wall[0]-1, rand_wall[1]] not in walls): walls.append([rand_wall[0]-1, rand_wall[1]]) # Leftmost cell if (rand_wall[1] != 0): if (maze[rand_wall[0]][rand_wall[1]-1] != 'c'): maze[rand_wall[0]][rand_wall[1]-1] = 'w' if ([rand_wall[0], rand_wall[1]-1] not in walls): walls.append([rand_wall[0], rand_wall[1]-1]) # Rightmost cell if (rand_wall[1] != width-1): if (maze[rand_wall[0]][rand_wall[1]+1] != 'c'): maze[rand_wall[0]][rand_wall[1]+1] = 'w' if ([rand_wall[0], rand_wall[1]+1] not in walls): walls.append([rand_wall[0], rand_wall[1]+1]) # Delete wall for wall in walls: if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]): walls.remove(wall) continue # Check the bottom wall if (rand_wall[0] != height-1): if (maze[rand_wall[0]+1][rand_wall[1]] == 'u' and maze[rand_wall[0]-1][rand_wall[1]] == 'c'): s_cells = surroundingCells(rand_wall) if (s_cells < 2): # Denote the new path maze[rand_wall[0]][rand_wall[1]] = 'c' # Mark the new walls if (rand_wall[0] != height-1): if (maze[rand_wall[0]+1][rand_wall[1]] != 'c'): maze[rand_wall[0]+1][rand_wall[1]] = 'w' if ([rand_wall[0]+1, rand_wall[1]] not in walls): walls.append([rand_wall[0]+1, rand_wall[1]]) if (rand_wall[1] != 0): if (maze[rand_wall[0]][rand_wall[1]-1] != 'c'): maze[rand_wall[0]][rand_wall[1]-1] = 'w' if ([rand_wall[0], rand_wall[1]-1] not in walls): walls.append([rand_wall[0], rand_wall[1]-1]) if (rand_wall[1] != width-1): if (maze[rand_wall[0]][rand_wall[1]+1] != 'c'): maze[rand_wall[0]][rand_wall[1]+1] = 'w' if ([rand_wall[0], rand_wall[1]+1] not in walls): walls.append([rand_wall[0], rand_wall[1]+1]) # Delete wall for wall in walls: if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]): walls.remove(wall) continue # Check the right wall if (rand_wall[1] != width-1): if (maze[rand_wall[0]][rand_wall[1]+1] == 'u' and maze[rand_wall[0]][rand_wall[1]-1] == 'c'): s_cells = surroundingCells(rand_wall) if (s_cells < 2): # Denote the new path maze[rand_wall[0]][rand_wall[1]] = 'c' # Mark the new walls if (rand_wall[1] != width-1): if (maze[rand_wall[0]][rand_wall[1]+1] != 'c'): maze[rand_wall[0]][rand_wall[1]+1] = 'w' if ([rand_wall[0], rand_wall[1]+1] not in walls): walls.append([rand_wall[0], rand_wall[1]+1]) if (rand_wall[0] != height-1): if (maze[rand_wall[0]+1][rand_wall[1]] != 'c'): maze[rand_wall[0]+1][rand_wall[1]] = 'w' if ([rand_wall[0]+1, rand_wall[1]] not in walls): walls.append([rand_wall[0]+1, rand_wall[1]]) if (rand_wall[0] != 0): if (maze[rand_wall[0]-1][rand_wall[1]] != 'c'): maze[rand_wall[0]-1][rand_wall[1]] = 'w' if ([rand_wall[0]-1, rand_wall[1]] not in walls): walls.append([rand_wall[0]-1, rand_wall[1]]) # Delete wall for wall in walls: if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]): walls.remove(wall) continue # Delete the wall from the list anyway for wall in walls: if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]): walls.remove(wall) # Mark the remaining unvisited cells as walls for i in range(0, height): for j in range(0, width): if (maze[i][j] == 'u'): maze[i][j] = 'w' # Set entrance and exit for i in range(0, width): if (maze[1][i] == 'c'): maze[0][i] = 'c' break for i in range(width-1, 0, -1): if (maze[height-2][i] == 'c'): maze[height-1][i] = 'c' break # Print final maze printMaze(maze)