diff --git a/orhelper/_orhelper.py b/orhelper/_orhelper.py index 75a5c4b..0746d77 100755 --- a/orhelper/_orhelper.py +++ b/orhelper/_orhelper.py @@ -220,6 +220,12 @@ def startSimulation(self, status) -> None: def endSimulation(self, status, simulation_exception) -> None: pass + def startSimulationBranch(self, status) -> None : + pass + + def endSimulationBranch(self, status, simulation_exception) -> None: + pass + def preStep(self, status) -> bool: return True diff --git a/orhelper/examples/lazy.py b/orhelper/examples/lazy.py deleted file mode 100644 index 36a7cf2..0000000 --- a/orhelper/examples/lazy.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import math -import numpy as np -from scipy.optimize import fmin -from matplotlib import pyplot as plt - -import orhelper -from orhelper import FlightDataType - -with orhelper.OpenRocketInstance() as instance: - orh = orhelper.Helper(instance) - - # Load document, run simulation and get data and events - doc = orh.load_doc(os.path.join(os.path.dirname(__file__), 'simple.ork')) - sim = doc.getSimulation(0) - - - # Define some functions for simulating and optimizing - def simulate_at_angle(ang, sim): - sim.getOptions().setLaunchRodAngle(math.radians(ang)) - orh.run_simulation(sim) - return orh.get_timeseries(sim, [FlightDataType.TYPE_ALTITUDE, FlightDataType.TYPE_POSITION_X]) - - - def to_min(ang, sim): - data = simulate_at_angle(ang, sim) - half_len = len(data[FlightDataType.TYPE_ALTITUDE]) // 2 # Don't want the launch - min_upwind_index = np.abs(data[FlightDataType.TYPE_ALTITUDE][half_len:]).argmin() - min_upwind_position = data[FlightDataType.TYPE_POSITION_X][half_len:][min_upwind_index] # X is upwind for simple.ork - return np.abs(min_upwind_position) - - - # Find and include the maximum upwind distance - optimal = fmin(to_min, (40,), args=(sim,)) - - angles = np.linspace(0, 30.0, num=10) - angles = np.append(angles, optimal) - angles.sort() - - # Calculate all the curves for plotting - data_runs = dict() - for ang in angles: - data_runs[ang] = simulate_at_angle(ang, sim) - - # Do the plotting - fig = plt.figure() - ax1 = fig.add_subplot(111) - for ang, data in data_runs.items(): - ax1.plot(data[FlightDataType.TYPE_POSITION_X], data[FlightDataType.TYPE_ALTITUDE], # X is upwind for simple.ork - label=f'{ang:.1f}\N{DEGREE SIGN}', - linestyle='-' if ang == optimal else '--') - - ax1.legend() - ax1.set_xlabel('Position upwind (m)') - ax1.set_ylabel('Altitude (m)') - ax1.set_title('Optimal launch rod angle for easy recovery') - ax1.grid(True) - -# Leave OpenRocketInstance context before showing plot in order to shutdown JVM first -plt.show() diff --git a/orhelper/examples/monte_carlo.py b/orhelper/examples/monte_carlo.py deleted file mode 100644 index 88eb13a..0000000 --- a/orhelper/examples/monte_carlo.py +++ /dev/null @@ -1,100 +0,0 @@ -import os -import numpy as np -import orhelper -from random import gauss -import math - - -class LandingPoints(list): - "A list of landing points with ability to run simulations and populate itself" - - def __init__(self): - self.ranges = [] - self.bearings = [] - - def add_simulations(self, num): - with orhelper.OpenRocketInstance() as instance: - - # Load the document and get simulation - orh = orhelper.Helper(instance) - doc = orh.load_doc(os.path.join(os.path.dirname(__file__), 'simple.ork')) - sim = doc.getSimulation(0) - - # Randomize various parameters - opts = sim.getOptions() - rocket = sim.getRocket() - - # Run num simulations and add to self - for p in range(num): - print('Running simulation ', p) - - opts.setLaunchRodAngle(math.radians(gauss(45, 5))) # 45 +- 5 deg in direction - opts.setLaunchRodDirection(math.radians(gauss(0, 5))) # 0 +- 5 deg in direction - opts.setWindSpeedAverage(gauss(15, 5)) # 15 +- 5 m/s in wind - for component_name in ('Nose cone', 'Body tube'): # 5% in the mass of various components - component = orh.get_component_named(rocket, component_name) - mass = component.getMass() - component.setMassOverridden(True) - component.setOverrideMass(mass * gauss(1.0, 0.05)) - - airstarter = AirStart(gauss(1000, 50)) # simulation listener to drop from 1000 m +- 50 - lp = LandingPoint(self.ranges, self.bearings) - orh.run_simulation(sim, listeners=(airstarter, lp)) - self.append(lp) - - def print_stats(self): - print( - 'Rocket landing zone %3.2f m +- %3.2f m bearing %3.2f deg +- %3.4f deg from launch site. Based on %i simulations.' % \ - (np.mean(self.ranges), np.std(self.ranges), np.degrees(np.mean(self.bearings)), - np.degrees(np.std(self.bearings)), len(self))) - - -class LandingPoint(orhelper.AbstractSimulationListener): - def __init__(self, ranges, bearings): - self.ranges = ranges - self.bearings = bearings - - def endSimulation(self, status, simulation_exception): - worldpos = status.getRocketWorldPosition() - conditions = status.getSimulationConditions() - launchpos = conditions.getLaunchSite() - geodetic_computation = conditions.getGeodeticComputation() - - if geodetic_computation != geodetic_computation.FLAT: - raise Exception("GeodeticComputationStrategy type not supported") - - self.ranges.append(range_flat(launchpos, worldpos)) - self.bearings.append(bearing_flat(launchpos, worldpos)) - - -class AirStart(orhelper.AbstractSimulationListener): - - def __init__(self, altitude): - self.start_altitude = altitude - - def startSimulation(self, status): - position = status.getRocketPosition() - position = position.add(0.0, 0.0, self.start_altitude) - status.setRocketPosition(position) - - -METERS_PER_DEGREE_LATITUDE = 111325 -METERS_PER_DEGREE_LONGITUDE_EQUATOR = 111050 - - -def range_flat(start, end): - dy = (end.getLatitudeDeg() - start.getLatitudeDeg()) * METERS_PER_DEGREE_LATITUDE - dx = (end.getLongitudeDeg() - start.getLongitudeDeg()) * METERS_PER_DEGREE_LONGITUDE_EQUATOR - return math.sqrt(dy * dy + dx * dx) - - -def bearing_flat(start, end): - dy = (end.getLatitudeDeg() - start.getLatitudeDeg()) * METERS_PER_DEGREE_LATITUDE - dx = (end.getLongitudeDeg() - start.getLongitudeDeg()) * METERS_PER_DEGREE_LONGITUDE_EQUATOR - return math.pi / 2 - math.atan(dy / dx) - - -if __name__ == '__main__': - points = LandingPoints() - points.add_simulations(20) - points.print_stats() diff --git a/orhelper/examples/simple.ork b/orhelper/examples/simple.ork deleted file mode 100644 index a44f8cf..0000000 Binary files a/orhelper/examples/simple.ork and /dev/null differ diff --git a/orhelper/examples/simple_plot.py b/orhelper/examples/simple_plot.py deleted file mode 100644 index 9e4a910..0000000 --- a/orhelper/examples/simple_plot.py +++ /dev/null @@ -1,53 +0,0 @@ -import os - -import numpy as np -from matplotlib import pyplot as plt - -import orhelper -from orhelper import FlightDataType, FlightEvent - -with orhelper.OpenRocketInstance() as instance: - orh = orhelper.Helper(instance) - - # Load document, run simulation and get data and events - - doc = orh.load_doc(os.path.join(os.path.dirname(__file__), 'simple.ork')) - sim = doc.getSimulation(0) - orh.run_simulation(sim) - data = orh.get_timeseries(sim, [FlightDataType.TYPE_TIME, FlightDataType.TYPE_ALTITUDE, FlightDataType.TYPE_VELOCITY_Z]) - events = orh.get_events(sim) - - # Make a custom plot of the simulation - - events_to_annotate = { - FlightEvent.BURNOUT: 'Motor burnout', - FlightEvent.APOGEE: 'Apogee', - FlightEvent.LAUNCHROD: 'Launch rod clearance' - } - - fig = plt.figure() - ax1 = fig.add_subplot(111) - ax2 = ax1.twinx() - - ax1.plot(data[FlightDataType.TYPE_TIME], data[FlightDataType.TYPE_ALTITUDE], 'b-') - ax2.plot(data[FlightDataType.TYPE_TIME], data[FlightDataType.TYPE_VELOCITY_Z], 'r-') - ax1.set_xlabel('Time (s)') - ax1.set_ylabel('Altitude (m)', color='b') - ax2.set_ylabel('Vertical Velocity (m/s)', color='r') - change_color = lambda ax, col: [x.set_color(col) for x in ax.get_yticklabels()] - change_color(ax1, 'b') - change_color(ax2, 'r') - - index_at = lambda t: (np.abs(data[FlightDataType.TYPE_TIME] - t)).argmin() - for event, times in events.items(): - if event not in events_to_annotate: - continue - for time in times: - ax1.annotate(events_to_annotate[event], xy=(time, data[FlightDataType.TYPE_ALTITUDE][index_at(time)]), - xycoords='data', xytext=(20, 0), textcoords='offset points', - arrowprops=dict(arrowstyle="->", connectionstyle="arc3")) - - ax1.grid(True) - -# Leave OpenRocketInstance context before showing plot in order to shutdown JVM first -plt.show() diff --git a/setup.py b/setup.py index 7722731..ef8ff7d 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="orhelper", - version="0.1.5", + version="0.1.6", author="Andrei Popescu and others", description="OrHelper is a module which aims to facilitate interacting and scripting with OpenRocket from Python.", long_description=long_description,