# Pathfinding Algorithm

```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.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

```

# 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 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.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:
#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)

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()
```

```import networkx as nx
import matplotlib.pyplot as plt
import re
floppy = open("input25.txt", mode='r', encoding='utf-8')
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()

nx.draw_networkx(G)
plt.show()
```
```import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
nx.draw_networkx(G)
plt.show()
```

# Balloon Code V3

```import os
import picamera
import serial
import time
import board
import RPi.GPIO as GPIO

GPIO.setwarnings(False)
#GPIO.setmode(GPIO.BOARD)
GPIO.setup(18, GPIO.OUT, initial=GPIO.LOW)

i2c = board.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:
#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)

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

```&lt;/div&gt;
# 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)

```