Skip to content

Commit

Permalink
Code update
Browse files Browse the repository at this point in the history
  • Loading branch information
Turfader authored Mar 26, 2023
1 parent 0b6db39 commit 2260804
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 212 deletions.
128 changes: 88 additions & 40 deletions A_Star.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from PIL import Image
from PIL import Image, ImageDraw
import heapq
from numpy import sqrt
from utils import show_warning, timeit, load_json
from utils import show_warning, load_json, subdivide_path, height_from_rect
from ui import get_pathfinding_endpoints
import FileManager as fm
from tqdm import tqdm

SIZE_CONSTANT = fm.get_size_constant()
GRID = load_json(fm.ASTAR_JSONPATH)

class Node:
def __init__(self, x, y, parent=None):
Expand All @@ -14,8 +16,8 @@ def __init__(self, x, y, parent=None):

self.parent = parent

self.height = grid[y][x][2]
self.slope = grid[y][x][3]
self.height = GRID[y][x][2]
self.slope = GRID[y][x][3]

self.g = 0
self.h = 0
Expand Down Expand Up @@ -53,7 +55,60 @@ def new_g(self, other) -> float:
return eqn


@timeit
def is_valid_checkpoint(point):
x, y = point[0], point[1]
height = height_from_rect(x, y, GRID)

ALLOWANCE = 300 # Change this to change the stringency of checkpoint validity

for i in range(y, SIZE_CONSTANT):
# TODO Swap this with Elevation to be Rubric-Accurate
if height_from_rect(x, i, GRID) > (height + ALLOWANCE):
return False

return True


def generate_comm_path(comm_path):
for index, point in tqdm(enumerate(comm_path), desc="Generating Checkpoints"):
x, y = point[0], point[1]
# If a point is already valid, then just leave it.
if is_valid_checkpoint(point):
continue

# Define the bounds of the square, using max/min as point validity fail safes.
SEARCH_AREA = 50
left_bound = max(0, x - SEARCH_AREA)
right_bound = min(SIZE_CONSTANT - 1, x + SEARCH_AREA)
top_bound = max(0, y - SEARCH_AREA)
bottom_bound = min(SIZE_CONSTANT - 1, y + SEARCH_AREA)

# Loop through each square per each checkpoint. If it's valid, then replace it.
for i in range(left_bound, right_bound + 1):
for j in range(top_bound, bottom_bound + 1):
test_point = (i, j)
if is_valid_checkpoint(test_point):
comm_path[index] = test_point
else:
show_warning("Pathfinding Error", "No valid path with checkpoints was found.")
quit(1)


# Now we generate a new path.
final_path = []
for i in range(len(comm_path) - 1):
(start_x, start_y), (goal_x, goal_y) = (comm_path[i][0], comm_path[i][1]), (comm_path[i+1][0], comm_path[i+1][1])
global start_node
global goal_node
start_node: Node = Node(start_x, start_y)
goal_node: Node = Node(goal_x, goal_y)

path_btw = astar()
final_path.extend(path_btw)

return final_path, comm_path


def astar():
nodes = []

Expand Down Expand Up @@ -81,68 +136,61 @@ def astar():
x2 = current.x + dx
y2 = current.y + dy

if 0 <= x2 < len(grid) and 0 <= y2 < len(grid[0]):
if 0 <= x2 < len(GRID) and 0 <= y2 < len(GRID[0]):
new_node = Node(x2, y2, current)
heapq.heappush(nodes, new_node)

pbar.update()
return None


def update_image(image_path: str, mvmt_path: list):
def update_image(image_path: str, mvmt_path: list, comm_path: list):
path = image_path
img = Image.open(path)

color = (255, 0, 0)
for i in tqdm(range(len(mvmt_path)), desc="Updating image"):
color = (255, 0, 0)
x = mvmt_path[i][0]
y = mvmt_path[i][1]
img.putpixel((x, y), color)

img.save(fm.images_path + "/AStar_Path.png")
if comm_path is not None:
for i in range(len(comm_path)):
draw = ImageDraw.Draw(img)
color = (0, 255, 0)
radius = 3
draw.ellipse((comm_path[i][0] - radius, comm_path[i][1] - radius,
comm_path[i][0] + radius, comm_path[i][1] + radius), fill=color)

img.save(fm.ASTAR_PATH)

def div_10_points(final_path : list) -> list:
comm_points = []
dist = round(len(final_path) / 11)
for i in range(11):
comm_points.append(final_path[i * dist])

comm_points.pop(0)
return comm_points


def line_to_earth(x, y):
m = (y-1250)/(x-638)
b = -m*x + y
return int(m), int(b)


if __name__ == "__main__":

(start_x, start_y), (goal_x, goal_y) = get_pathfinding_endpoints(fm.get_size_constant(), fm.images_path)

grid = load_json(fm.data_path + "/AStarRawData.json")

# Testing. To be removed later
# start_x, start_y = 0, 0
# goal_x, goal_y = 100, 100
def run_astar():
(start_x, start_y), (goal_x, goal_y), checkpoints = \
get_pathfinding_endpoints(fm.get_size_constant(), fm.images_path)

global start_node, goal_node
start_node = Node(start_x, start_y)
goal_node = Node(goal_x, goal_y)

final_path = astar()
sub_10_path = None

if checkpoints:
sub_10_path = subdivide_path(final_path)
sub_10_path.insert(0, (start_x, start_y))
final_path, sub_10_path = generate_comm_path(sub_10_path)

if final_path is not None:
update_image(fm.images_path + '/moon_surface_texture.png', final_path)
update_image(fm.TEXTURE_PATH, final_path, sub_10_path)
else:
show_warning("A* Pathfinding Error", "No Valid Path found between points.")

# For Relative Earth position Pathfinding Calculation ---
divided_points = div_10_points(final_path)

m, b = line_to_earth(divided_points[0][0], divided_points[0][2])
# Slope of a line spanning from a point to the relative position of earth.
print(f'y = {m}x + {b}')
if checkpoints:
print("Created Path with Communication Checkpoints")
else:
print("Created Path without Communication Checkpoints")


if __name__ == "__main__":
run_astar()
4 changes: 2 additions & 2 deletions Artemis_ADC_Launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
print("Installed package: PySimpleGUI")
run([sys.executable, '-m', 'pip', 'install', 'tqdm'], check=True)
print("Installed package: tqdm")
run([sys.executable, '-m', 'pip', 'install', 'msgspec'], check=True)
print("Installed package: msgspec")
run([sys.executable, '-m', 'pip', 'install', 'orjson'], check=True)
print("Installed package: orjson")
run([sys.executable, '-m', 'pip', 'install', 'seaborn'], check=True)
print("Installed package: seaborn")

Expand Down
26 changes: 11 additions & 15 deletions Cartographer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@
from time import time
import random

max_z = fm.get_max_height()
CALCULATION_CONS = 255 / max_z
ONE_THIRD = 1 / 3
TWO_THIRDS = 2 / 3
SIZE_CONSTANT = fm.get_size_constant()

SIZE_CONSTANT = fm.get_size_constant()
Image.MAX_IMAGE_PIXELS = None


Expand All @@ -32,8 +28,8 @@ def sns_heatmap(arr, cmap, save):
print(f'{save} created in {round(time()-start, 2)}s')


heights = get_specific_from_json(8, fm.data_path + "/AStarRawData.json")
slopes = get_specific_from_json(3, fm.data_path + "/AStarRawData.json")
heights = get_specific_from_json(8, fm.ASTAR_JSONPATH)
slopes = get_specific_from_json(3, fm.ASTAR_JSONPATH)


def create_surface_texture():
Expand All @@ -45,7 +41,7 @@ def create_surface_texture():
for i in range(int(slopes[y][x])):
color -= random.randint(2, 5)
texture.putpixel((x, y), (color, color, color))
texture.save(fm.images_path + "/moon_surface_texture.png")
texture.save(fm.TEXTURE_PATH)


# Creates RAW_Heightmap, Slopemap, and Heightkey
Expand All @@ -55,22 +51,22 @@ def draw_all():
sns_heatmap(
arr=heights,
cmap="gist_gray",
save=fm.images_path + '/RAW_heightmap.png'
save=fm.RAW_HEIGHTMAP_PATH
)

# Creates Heightkey
#TODO Add Reduced Opacity Feature to Original Texture for this
# TODO Add Reduced Opacity Feature to Original Texture for this
sns_heatmap(
arr=heights,
cmap='viridis',
save=fm.images_path + '/heightkey_surface.png'
save=fm.SURFACE_HEIGHTKEY_PATH
)

# Creates Slopemap
sns_heatmap(
arr=slopes,
cmap='inferno',
save=fm.images_path + '/slopemap.png'
save=fm.SLOPEMAP_PATH
)

# Creates Surface Texture
Expand All @@ -93,15 +89,15 @@ def draw_path(path, image, color):

# Image Scaling for Faster Ursina Runs, as well as proper dimensions.
proper_heightmap = resize(
image_path=fm.images_path + '/RAW_heightmap.png',
image_path=fm.RAW_HEIGHTMAP_PATH,
new_name='processed_heightmap',
scale=128,
transpose=True
)
move(fm.images_path + '/processed_heightmap.png', getcwd() + '/processed_heightmap.png')
move(fm.images_path + fm.PROCESSED_HEIGHTMAP_PATH, getcwd() + '/processed_heightmap.png')

proper_surface_texture = resize(
image_path='Data/Images/moon_surface_texture.png',
image_path=fm.TEXTURE_PATH,
new_name='moon_surface_texture',
scale=SIZE_CONSTANT,
transpose=True
Expand Down
17 changes: 11 additions & 6 deletions DataProcessor.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import FileManager as fm
from utils import file2list, get_x_coord, get_y_coord, \
get_z_coord, get_azimuth, get_elevation, timeit, \
load_json
load_json, push_to_json
from tqdm import tqdm
from math import radians, degrees

# Get Constants

SIZE: int = fm.get_size_constant()
LUNAR_RAD: float = fm.get_lunar_rad()

# Legacy Constants
#DISTANCE_BETWEEN_POINTS: int = fm.get_dist_between_points()
# DISTANCE_BETWEEN_POINTS: int = fm.get_dist_between_points()


# Creates Lists of each Data Type from the Paths Given.
Expand All @@ -21,6 +22,7 @@

data = load_json(fm.INFO_JSONPATH)


@timeit
def process_data():
"""
Expand Down Expand Up @@ -48,16 +50,19 @@ def process_data():

radius: float = LUNAR_RAD + float(height)

latitude = radians(latitude)
longitude = radians(longitude)

x: float = float(get_x_coord(latitude, longitude, radius))
y: float = float(get_y_coord(latitude, longitude, radius))
z: float = float(get_z_coord(latitude, radius))

azi: float = get_azimuth(latitude, longitude)
elev: float = get_elevation(latitude, longitude, radius)
elev: float = get_elevation(latitude, longitude, x, y, z)

xs.append(x), ys.append(y), zs.append(z), heights.append(height)

a_star_data_array.append([x, y, z, slope, azi, elev, latitude, longitude, height])
a_star_data_array.append([x, y, z, slope, azi, elev, degrees(latitude), degrees(longitude), height])

min_x_: float = abs(min(xs))
min_y_: float = abs(min(ys))
Expand Down Expand Up @@ -99,8 +104,8 @@ def process_data():
array_to_be_written[j][i][0] = i
array_to_be_written[j][i][1] = j

fm.push_to_json(fm.ASTAR_JSONPATH, array_to_be_written)
fm.push_to_json(fm.INFO_JSONPATH, data)
push_to_json(fm.ASTAR_JSONPATH, array_to_be_written)
push_to_json(fm.INFO_JSONPATH, data)


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit 2260804

Please sign in to comment.