def test_path_can_be_calculated_with_a_maneuver(self): """ This method is intended to be a direct translation of the test in testpath.cc of the same name. """ body = PyBody(gm=const.G * 1.98891691172467e30, r=10) system = PySystem(root=body) r = PyVector(617244712358.0, -431694791368.0, -12036457087.0) v = PyVector(7320.0, 11329.0, -0211.0) path_ = path.PyFlightPath(system, r, v, 0) half_orbit_t = 374942509.78053558 / 2 performance = path.PyPerformanceData(3000, 20000) # ve, thrust path_.add( path.PyManeuver(path.PyManeuver.Types.Prograde, 2000, performance, 150, half_orbit_t)) # predict orbit of 1/2 period from t0. prediction1 = path_.predict(half_orbit_t) # This test doesn't try to determine a precise position, just that # the calculation can complete, and results in a changed orbit. position1 = prediction1.r self.assertAlmostEqual(-719081127257.4052, position1.x, 0) self.assertAlmostEqual(364854624247.8101, position1.y, 0) self.assertAlmostEqual(14595231066.51168, position1.z, 0) # predict orbit of 3/2 period from t0. # Orbit should have changed notably prediction2 = path_.predict(374942509.78053558 * 3.0 / 2.0) position2 = prediction2.r self.assertNotAlmostEqual(-712305324741.15112, position2.x, 0) self.assertNotAlmostEqual(365151451881.22858, position2.y, 0) self.assertNotAlmostEqual(14442203602.998617, position2.z, 0)
def test_path_maneuver_increases_velocity(self): """ This method is intended to be a direct translation of the test in testpath.cc of the same name. """ body = PyBody(gm=const.G * 1.98891691172467e30, r=10) system = PySystem(root=body) r = PyVector(617244712358.0, -431694791368.0, -12036457087.0) v = PyVector(7320.0, 11329.0, -0211.0) path_ = path.PyFlightPath(system, r, v, 0) half_orbit_t = 374942509.78053558 / 2 performance = path.PyPerformanceData(3000, 20000) # ve, thrust dv = 2000 maneuver = path.PyManeuver(path.PyManeuver.Types.Prograde, dv, performance, 150, half_orbit_t) path_.add(maneuver) # Predict orbit of 1/2 period from t0. prediction0 = path_.predict(half_orbit_t) # Predict orbit at end of burn prediction1 = path_.predict(maneuver.t1) # This test doesn't try to determine a precise velocity, just that # it has increased a roughly expected amount. v0 = prediction0.v v1 = prediction1.v self.assertAlmostEqual(v1.norm, v0.norm + dv, -1) # within ~10
def test_r_and_v_between_segment_groups_match(self): body = PyBody(gm=const.G * 1.98891691172467e30, r=10) system = PySystem(root=body) r = PyVector(617244712358.0, -431694791368.0, -12036457087.0) v = PyVector(7320.0, 11329.0, -0211.0) path_ = path.PyFlightPath(system, r, v, 0) period0 = 374942509.78053558 performance = path.PyPerformanceData(3000, 200) # ve, thrust burn_start_t = period0 / 2 maneuver = path.PyManeuver( path.PyManeuver.Types.Prograde, # Maneuver Type 2, # DV performance, 150.0, # m0 burn_start_t) # t0 path_.add(maneuver) seg0_end_data = path_.predict(burn_start_t - 0.001) seg1_start_data = path_.predict(burn_start_t) # Roundabout check to make sure both predictions were different self.assertNotEqual(seg0_end_data.v.x, seg1_start_data.v.x) # Check that velocities nearly match self.assertAlmostEqual(seg0_end_data.v.x, seg1_start_data.v.x, 6) self.assertAlmostEqual(seg0_end_data.v.y, seg1_start_data.v.y, 6) self.assertAlmostEqual(seg0_end_data.v.z, seg1_start_data.v.z, 6)
def burn_plot() -> None: body = PyBody(gm=const.G * 1.98891691172467e30, r=10) system = PySystem(root=body) r = PyVector(617_244_712_358.0, -431_694_791_368.0, -12_036_457_087.0) v = PyVector(7320.0, 11329.0, -0211.0) path_ = path.PyFlightPath(system, r, v, 0) period0 = 374942509.78053558 performance = path.PyPerformanceData(3000, 2000) # ve, thrust burn_start_t = 2 maneuver = path.PyManeuver(path.PyManeuver.Types.Prograde, 10, performance, 150, burn_start_t) path_.add(maneuver) maneuver = path.PyManeuver(path.PyManeuver.Types.Prograde, 10, performance, 150, burn_start_t + 2) path_.add(maneuver) # Get Data to plot t_pts = [] v_pts = [] apo_pts = [] a_pts = [] t0 = maneuver.t0 - 3 tf = maneuver.t1 + 3 plot_duration = tf - t0 for i in range(N_POINTS): t = plot_duration / N_POINTS * i + t0 t_pts.append(t - maneuver.t0) # Time relative to burn t0 orbit_data = path_.predict_orbit(t) v_pts.append(orbit_data.orbit.velocity.norm) apo_pts.append(orbit_data.orbit.apoapsis) a_pts.append(orbit_data.orbit.semi_major_axis) # Plot gs = gridspec.GridSpec(2, 2) plt.subplots_adjust(hspace=0.5, wspace=0.35) # Velocity plot plt.subplot(gs[0, 0]) plt.title('Velocity') plt.plot(t_pts, v_pts, 'r-') # Apoapsis plot plt.subplot(gs[1, 0]) plt.title('Apoapsis') plt.plot(t_pts, apo_pts) # Semi major axis plot plt.subplot(gs[0, 1]) plt.title('Semi Major Axis') plt.plot(t_pts, a_pts) plt.show()
def test_orbit_data_can_be_calculated_at_time_0(self): body = PyBody(gm=const.G * 1.98891691172467e30, r=10) system = PySystem(root=body) r = PyVector(-719081127257.4052, -364854624247.8101, -14595231066.51168) v = PyVector(7320.0, 11329.0, -0211.0) path_ = path.PyFlightPath(system, r, v, 0) prediction: path.PyOrbitData = path_.predict_orbit(0) position: PyVector = prediction.orbit.position self.assertAlmostEqual(-719081127257.4052, position.x, 0) self.assertAlmostEqual(-364854624247.8101, position.y, 0) self.assertAlmostEqual(-14595231066.51168, position.z, 0) self.assertEqual(body.id, prediction.body.id)
def test_orbit_data_can_be_calculated_at_arbitrary_time(self): body = PyBody(gm=const.G * 1.98891691172467e30, r=10) system = PySystem(root=body) r = PyVector(-719081127257.4052, -364854624247.8101, -14595231066.51168) v = PyVector(7320.0, 11329.0, -0211.0) path_ = path.PyFlightPath(system, r, v, 0) prediction: path.PyOrbitData = \ path_.predict_orbit(374942509.78053558 / 2) position: PyVector = prediction.orbit.position self.assertAlmostEqual(-483167275930.97107, position.x, 0) self.assertAlmostEqual(-1432791663675.9163, position.y, 0) self.assertAlmostEqual(46273154729.87547, position.z, 0) self.assertEqual(body.id, prediction.body.id)
def test_path_with_no_maneuvers_can_be_calculated(self): """ This method is intended to be a direct translation of the test in testpath.cc of the same name. """ body = PyBody(gm=const.G * 1.98891691172467e30, r=10) system = PySystem(root=body) r = PyVector(617244712358.0, -431694791368.0, -12036457087.0) v = PyVector(7320.0, 11329.0, -0211.0) path_ = path.PyFlightPath(system, r, v, 0) prediction: path.PyKinematicData = path_.predict(374942509.78053558 / 2) position: PyVector = prediction.r self.assertAlmostEqual(-719081127257.4052, position.x, 0) self.assertAlmostEqual(364854624247.8101, position.y, 0) self.assertAlmostEqual(14595231066.51168, position.z, 0)
def simple_hyperbolic_path() -> None: body = PyBody(gm=const.G * 1.98891691172467e30, r=10) system = PySystem(root=body) r = PyVector(-719081127257.4052, -364854624247.8101, -14595231066.51168) v = PyVector(7320.0, 21000.0, -0211.0) path_ = path.PyFlightPath(system, r, v, 0) # Get points to plot x_pts = [] y_pts = [] z_pts = [] for i in range(N_POINTS): t = 374942509.78053558 * 2 / N_POINTS * i predicted: path.PyKinematicData = path_.predict(t) x_pts.append(predicted.r.x) y_pts.append(predicted.r.y) z_pts.append(predicted.r.z) # Plot plt.figure(1) gs = gridspec.GridSpec(1, 2) plt.subplots_adjust(hspace=0.5, wspace=0.35) plt.subplot(gs[0, 0]) plt.plot(0, 0, 'ro') # Body position. plt.plot(x_pts, y_pts, 'r-') # line plt.plot(r.x, r.y, 'ro') # current pos plt.plot(x_pts[0], y_pts[0], 'yo') plt.axis('equal') plt.subplot(gs[0, 1]) plt.plot(0, 0, 'ro') # Body position. plt.plot(x_pts, z_pts, 'r-') # line plt.plot(r.x, r.z, 'ro') # current pos plt.plot(x_pts[0], z_pts[0], 'yo') plt.axis('equal') plt.show()
def position_plot() -> None: body = PyBody(gm=const.G * 5.972e24, r=10) system = PySystem(root=body) r = PyVector(617_244_712.0, -431_694_791.0, -12_036_457.0) v = PyVector(132.00, 632.90, -21.1) path_ = path.PyFlightPath(system, r, v, 0) period0 = 374942509.78053558 / 25 performance = path.PyPerformanceData(3000, 20000) # ve, thrust burn_start_t = period0 / 4 maneuver = path.PyManeuver(path.PyManeuver.Types.Prograde, 100, performance, 150, burn_start_t) path_.add(maneuver) # Get points to plot x_pts = [] y_pts = [] for i in range(N_POINTS): t = period0 / N_POINTS * i kinematic_data: path.PyKinematicData = path_.predict(t) x_pts.append(kinematic_data.r.x) y_pts.append(kinematic_data.r.y) burn_start_prediction = path_.predict(burn_start_t) burn_start_pos = burn_start_prediction.r # Plot plt.figure(1) plt.subplots_adjust(hspace=0.5, wspace=0.35) plt.plot(0, 0, 'ro') # Body position. plt.plot(x_pts, y_pts, 'r-') # line plt.plot(burn_start_pos.x, burn_start_pos.y, 'ro') # current pos plt.axis('equal') plt.show()