-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- update requirements - update parameters.json - update gitignore - some nbks to test the new features (might be excluded in the future
- Loading branch information
1 parent
6760bdd
commit 5e15ad4
Showing
17 changed files
with
1,933 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,3 +113,5 @@ dmypy.json | |
|
||
# VS Code | ||
.vscode/ | ||
|
||
databank/ |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import logging | ||
import os | ||
|
||
# Configure the logging settings | ||
logging.basicConfig( | ||
filename="script.log", # Specify the log file name | ||
level=logging.INFO, # Set the logging level to INFO (you can adjust this as needed) | ||
format="%(asctime)s - %(levelname)s - %(message)s", # Define log message format | ||
datefmt="%Y-%m-%d %H:%M:%S", # Define date and time format | ||
) | ||
|
||
|
||
def destroy_the_bank(file): | ||
""" | ||
Run the 'ork2json' command on the given file. | ||
Args: | ||
file (str): The path to the .ork file. | ||
""" | ||
cli = "ork2json" | ||
output = file[:-4] # Remove '.ork' extension | ||
verbose = True | ||
|
||
command = f"{cli} --filepath {file} --output {output} --verbose {verbose}" | ||
logging.info(f"Executing command: {command}") | ||
|
||
try: | ||
import subprocess | ||
|
||
subprocess.run(command, shell=True, check=True) | ||
logging.info(f"Execution successful for file: {file}") | ||
except subprocess.CalledProcessError as e: | ||
logging.error(f"Error in file: {file}") | ||
logging.error(str(e)) | ||
raise | ||
|
||
|
||
if __name__ == "__main__": | ||
folder = "examples/databank" | ||
|
||
ork_files = [file for file in os.listdir(folder) if file.endswith(".ork")] | ||
|
||
for file in ork_files: | ||
file_path = os.path.join(folder, file) | ||
try: | ||
destroy_the_bank(file_path) | ||
except Exception as e: | ||
# Log any unexpected exceptions | ||
logging.exception(f"An unexpected error occurred in file: {file}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import json | ||
import os | ||
from datetime import datetime, timedelta | ||
from multiprocessing.sharedctypes import Value | ||
|
||
import nbformat | ||
import numpy as np | ||
import orhelper | ||
from bs4 import BeautifulSoup | ||
|
||
flight_parameters = {} | ||
|
||
|
||
def generate(ork_file, nb_file, eng_file, open_rocket_instance): | ||
nb = nbformat.read(nb_file, nbformat.NO_CONVERT) | ||
|
||
main_code = f'Main = Calisto.addParachute(\n "Main",\n CdS=parameters["MainCds{idx}"],\n trigger=mainTrigger,\n samplingRate=105,\n lag=parameters["MainDeployDelay{idx}"],\n noise=(0, 8.3, 0.5),\n)' | ||
main_trigger = f'def mainTrigger(p, y):\n # p = pressure\n # y = [x, y, z, vx, vy, vz, e0, e1, e2, e3, w1, w2, w3]\n # activate main when vz < 0 m/s and z < 800 + 1400 m (+1400 due to surface elevation).\n return True if y[5] < 0 and y[2] < parameters["MainDeployAltitude{idx}"] + parameters["elevation"] else False' | ||
chute_cell_code += f"{main_trigger}\n\n{main_code}\n\n" | ||
|
||
for idx, drogue in enumerate( | ||
filter(lambda x: "Drogue" in x.find("name").text, chutes) | ||
): | ||
drogue_cds = ( | ||
search_cd_chute_if_auto(bs) | ||
if drogue.find("cd").text == "auto" | ||
else float(drogue.find("cd").text) | ||
) | ||
drogue_deploy_delay = float(drogue.find("deploydelay").text) | ||
drogue_code = f'Drogue = Calisto.addParachute(\n "Drogue",\n CdS=parameters["DrogueCds{idx}"],\n trigger=drogueTrigger,\n samplingRate=105,\n lag=parameters["DrogueDeployDelay{idx}"],\n noise=(0, 8.3, 0.5),\n)' | ||
drogue_area = np.pi * float(drogue.find("diameter").text) ** 2 / 4 | ||
|
||
drogue_trigger = "def drogueTrigger(p, y):\n # p = pressure\n # y = [x, y, z, vx, vy, vz, e0, e1, e2, e3, w1, w2, w3]\n # activate drogue when vz < 0 m/s.\n return True if y[5] < 0 else False\n\n\n" | ||
chute_cell_code += f"{drogue_trigger}\n\n{drogue_code}\n" | ||
flight_parameters.update( | ||
{ | ||
f"DrogueCds{idx}": drogue_area * drogue_cds, | ||
f"DrogueDeployDelay{idx}": drogue_deploy_delay, | ||
} | ||
) | ||
|
||
# TODO: rail_button, tuple for launch date | ||
|
||
nb["cells"][4][ | ||
"source" | ||
] = f'%matplotlib widget\n\nimport json\n\nparameters = json.loads(open("parameters.json").read())' | ||
nb["cells"][15]["source"] = generate_motor_code( | ||
path, | ||
burnout_position, | ||
burnout_time, | ||
thrust_vect, | ||
time_vector, | ||
propelant_mass, | ||
motor_radius, | ||
tube_length, | ||
) | ||
nb["cells"][20][ | ||
"source" | ||
] = f'Calisto = Rocket(\n motor=Pro75M1670,\n radius=parameters["radius"],\n mass=parameters["rocketMass"],\n inertiaI=parameters["inertiaI"],\n inertiaZ=parameters["inertiaZ"],\n distanceRocketNozzle=parameters["distanceRocketNozzle"],\n distanceRocketPropellant=parameters["MotorCm"],\n powerOffDrag="drag_coefficient.csv",\n powerOnDrag="drag_coefficient.csv",\n)\n\nCalisto.setRailButtons([0.2, -0.5])' | ||
|
||
nb["cells"][23]["source"] = f"{nosecone}\n\n{trapezoidal_fin}\n\n{tail}" | ||
|
||
nb["cells"][27]["source"] = chute_cell_code | ||
|
||
nb["cells"][7][ | ||
"source" | ||
] = f'Env = Environment(\n railLength=parameters["railLength"], latitude=39.3897, longitude=-8.28896388889, elevation=parameters["elevation"]\n)' | ||
nb["cells"][30][ | ||
"source" | ||
] = f'TestFlight = Flight(rocket=Calisto, environment=Env, inclination=parameters["inclination"], heading=parameters["heading"])' | ||
print(np.max(altitude_vector)) | ||
|
||
with open(f"{path}parameters.json", "w") as convert_file: | ||
convert_file.write(json.dumps(flight_parameters)) | ||
|
||
nbformat.write(nb, f"{path}Simulation.ipynb") | ||
|
||
|
||
def trapezoidal_fin_code(fin, element, idx): | ||
trapezoidal_fin = f'Calisto.addTrapezoidalFins(parameters["finN{idx}"], rootChord=parameters["finRootChord{idx}"], tipChord=parameters["finTipChord{idx}"], span=parameters["finSpan{idx}"], distanceToCM=parameters["finDistanceToCm{idx}"], sweepAngle=parameters.get("finSweepAngle{idx}"), sweepLength=parameters.get("finSweepLength{idx}"))\n\n' | ||
return trapezoidal_fin | ||
|
||
|
||
def generate_nosecone_code(bs, cm): | ||
nosecone = f'NoseCone = Calisto.addNose(length=parameters["noseLength"], kind=parameters["noseShape"], distanceToCM=parameters["noseDistanceToCM"])' | ||
return nosecone | ||
|
||
|
||
def generate_motor_code( | ||
path, | ||
burnout_position, | ||
burnout_time, | ||
thrust_vect, | ||
time_vector, | ||
propelant_mass, | ||
motor_radius, | ||
motor_height, | ||
): | ||
code = f'Pro75M1670 = SolidMotor(\n thrustSource="thrust_source.csv",\n burnOut=parameters["burnOut"],\n grainNumber=1,\n grainSeparation=0,\n grainDensity=parameters["grainDensity"],\n grainOuterRadius=parameters["grainOuterRadius"],\n grainInitialInnerRadius=parameters["grainInitialInnerRadius"],\n grainInitialHeight=parameters["grainInitialHeight"],\n nozzleRadius=parameters["nozzleRadius"],\n throatRadius=parameters["throatRadius"],\n interpolationMethod="linear",\n)' | ||
return code | ||
|
||
|
||
with orhelper.OpenRocketInstance() as instance: | ||
nb_file = "./docs/notebooks/getting_started.ipynb" | ||
generate(ork_file, nb_file, eng_file, instance) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import logging | ||
from pathlib import Path | ||
from zipfile import BadZipFile, ZipFile | ||
|
||
from bs4 import BeautifulSoup | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def extract_ork_from_zip(zip_path: Path, extract_dir: Path) -> Path: | ||
"""Extracts .ork file from a zip archive and returns its path. | ||
This is important because sometimes the .xml file is stuck inside the .ork | ||
file. The function extracts the .ork (.xml) file from the zip (.ork) file | ||
and returns its path as a Path object. | ||
For illustration: if you try to open the .ork file with a text editor and | ||
you see a bunch of weird characters, it is probably a "zip" file. You can | ||
try to rename the file to .zip and open it with a zip extractor. | ||
Parameters | ||
---------- | ||
zip_path : Path | ||
The path to the .zip file. | ||
extract_dir : Path | ||
The path to the directory where the .ork file will be extracted. | ||
Returns | ||
------- | ||
Path | ||
The path to the extracted .ork file. | ||
""" | ||
try: | ||
with ZipFile(zip_path) as zf: | ||
zf.extract("rocket.ork", path=extract_dir) | ||
logger.info( | ||
'Successfully extracted rocket.ork from "%s" to "%s"', | ||
zip_path.as_posix(), | ||
extract_dir.as_posix(), | ||
) | ||
return extract_dir / "rocket.ork" | ||
except BadZipFile: | ||
logger.warning( | ||
'The file "%s" seems to be a direct .ork file and not a compressed archive.', | ||
zip_path.as_posix(), | ||
) | ||
return zip_path | ||
except Exception as e: | ||
logger.error( | ||
'Error while extracting data from "%s": %s', zip_path.as_posix(), e | ||
) | ||
raise | ||
|
||
|
||
def parse_ork_file(ork_path: Path): | ||
"""Parses the .ork file and returns BeautifulSoup and a list of datapoints. | ||
Parameters | ||
---------- | ||
ork_path : Path | ||
The path to the .ork file. | ||
Returns | ||
------- | ||
BeautifulSoup | ||
The BeautifulSoup object. | ||
""" | ||
try: | ||
with open(ork_path, encoding="utf-8") as file: | ||
bs = BeautifulSoup(file, features="xml") | ||
datapoints = bs.findAll("datapoint") | ||
logger.info( | ||
"Successfully parsed .ork file at '%s' with %d datapoints", | ||
ork_path.as_posix(), | ||
len(datapoints), | ||
) | ||
return bs, datapoints | ||
except UnicodeDecodeError as exc: | ||
error_msg = ( | ||
"The .ork file is not in UTF-8." | ||
+ "Please open the .ork file in a text editor and save it as UTF-8." | ||
) | ||
logger.error(error_msg) | ||
raise UnicodeDecodeError(error_msg) from exc | ||
except Exception as e: | ||
logger.error("Error while parsing the file '%s': %s", ork_path.as_posix(), e) | ||
raise e | ||
|
||
|
||
def _dict_to_string(dictionary, indent=0): | ||
"""Converts a dictionary to a string. | ||
Parameters | ||
---------- | ||
dictionary : dict | ||
Dictionary to be converted. | ||
indent : int, optional | ||
Indentation level, by default 0. | ||
Returns | ||
------- | ||
str | ||
String representation of the dictionary. | ||
Examples | ||
-------- | ||
>>> from open_rocket_serializer._helpers import _dict_to_string | ||
>>> _dict_to_string({"a": 1, "b": {"c": 2}}) | ||
" a: 1\n b: \n c: 2\n" | ||
""" | ||
string = "" | ||
for key, value in dictionary.items(): | ||
string += " " * indent + str(key) + ": " | ||
if isinstance(value, dict): | ||
string += "\n" + _dict_to_string(value, indent + 4) | ||
else: | ||
string += str(value) + "\n" | ||
return string | ||
|
||
|
||
# if __name__ == "__main__": | ||
# import doctest | ||
|
||
# doctest.testmod() |
Oops, something went wrong.