def lambert_transfer(ss_dpt, ss_arr, revs): """ Returns the short and long transfer orbits when solving Lambert's problem. Parameters ---------- ss_dpt: poliastro.twobody.Orbit Deprature orbit. ss_arr: poliastro.twobody.Orbit Arrival orbit. revs: int Number of revolutions. Returns ------- ss_short: poliastro.twobody.Orbit Short transfer orbit. ss_long: poliastro.twobody.Orbit Long transfer orbit. """ # Solving for short and long maneuvers lambert_short = Maneuver.lambert(earth_departure, mars_arrival, short=True, M=revs) lambert_long = Maneuver.lambert(earth_departure, mars_arrival, short=False, M=revs) # Aplly both maneuvers ss_short, _ = ss_dpt.apply_maneuver(lambert_short, intermediate=True) ss_long, _ = ss_dpt.apply_maneuver(lambert_long, intermediate=True) return ss_short, ss_long
def test_lambert_tof_exception(): ss_f = Orbit.circular( attractor=Earth, alt=36_000 * u.km, inc=0 * u.deg, raan=0 * u.deg, arglat=0 * u.deg, epoch=Time("J2000"), ) ss_i = Orbit.circular( attractor=Earth, alt=36_000 * u.km, inc=0 * u.deg, raan=0 * u.deg, arglat=0 * u.deg, epoch=Time("J2001"), ) with pytest.raises(ValueError) as excinfo: Maneuver.lambert(ss_i, ss_f) assert excinfo.type == ValueError assert ( str(excinfo.value) == "Epoch of initial orbit greater than epoch of final orbit, causing a negative time of flight" )
def _targetting(departure_body, target_body, t_launch, t_arrival): """This function returns the increment in departure and arrival velocities.""" # Get position and velocities for departure and arrival rr_dpt_body, vv_dpt_body = _get_state(departure_body, t_launch) rr_arr_body, vv_arr_body = _get_state(target_body, t_arrival) # Transform into Orbit objects attractor = departure_body.parent ss_dpt = Orbit.from_vectors(attractor, rr_dpt_body, vv_dpt_body, epoch=t_launch) ss_arr = Orbit.from_vectors(attractor, rr_arr_body, vv_arr_body, epoch=t_arrival) # Define time of flight tof = ss_arr.epoch - ss_dpt.epoch if tof <= 0: return None, None, None, None, None try: # Lambert is now a Maneuver object man_lambert = Maneuver.lambert(ss_dpt, ss_arr) # Get norm delta velocities dv_dpt = norm(man_lambert.impulses[0][1]) dv_arr = norm(man_lambert.impulses[1][1]) # Compute all the output variables c3_launch = dv_dpt**2 c3_arrival = dv_arr**2 return ( dv_dpt.to(u.km / u.s).value, dv_arr.to(u.km / u.s).value, c3_launch.to(u.km**2 / u.s**2).value, c3_arrival.to(u.km**2 / u.s**2).value, tof.jd, ) except AssertionError: return None, None, None, None, None
def total_delta_v(launch, arrival): """Calculate the total delta v for specific combination of launch date and arrival date :param launch: launch time in isoformat string :param arrival: desired arrival time in isoformat string """ date_launch = time.Time(launch, scale="utc") date_arrival = time.Time(arrival, scale="utc") ss_earth = Orbit.from_body_ephem(Earth, date_launch) ss_mars = Orbit.from_body_ephem(Mars, date_arrival) man_lambert = Maneuver.lambert(ss_earth, ss_mars) return { 'delta_v': man_lambert.get_total_cost().value, 'total_seconds': man_lambert.get_total_time().value }
v_2 = orbit2.v print("Period: " + str(period)) print("t_maneuver = " + str(t_maneuver)) # 72699 # sec date_arrival = time.Time((DATA_LAUNCH.unix + t_maneuver), format='unix') r_arr = [r_x, 10, 0] * u.km # orbit_arr = Orbit.from_vectors(Earth, r_2, v_2, epoch=date_arrival) orbit_arr = Orbit.from_vectors(Earth, r_arr, v, epoch=date_arrival) # orbit3 = orbit2.propagate_to_anomaly(2*30/180 * np.pi * u.rad) man_lambert = Maneuver.lambert(orbit_dpt, orbit_arr, short=False, M=2) orbit_trans, orbit_target = orbit_dpt.apply_maneuver(man_lambert, intermediate=True) # try to plot it fig, ax = plt.subplots() # (figsize=(4, 4)) plotter = StaticOrbitPlotter(ax) plotter.plot(orbit_dpt, label="Initial orbit", color="red") plotter.plot(orbit_trans, label="Trans orbit", color="blue") plotter.plot(orbit_target, label="Final orbit", color="green") print("Total cost") print(man_lambert.get_total_cost()) print("Total time") print(man_lambert.get_total_time())
earth = Ephem.from_body(Earth, time_range(date_launch, end=date_arrival)) mars = Ephem.from_body(Mars, time_range(date_launch, end=date_arrival)) # In[6]: # Solve for departure and target orbits ss_earth = Orbit.from_ephem(Sun, earth, date_launch) ss_mars = Orbit.from_ephem(Sun, mars, date_arrival) # We can now solve for the maneuver that will take us from Earth to Mars. After solving it, we just need to apply it to the departure orbit to solve for the transfer one. # In[7]: # Solve for the transfer maneuver man_lambert = Maneuver.lambert(ss_earth, ss_mars) # Get the transfer and final orbits ss_trans, ss_target = ss_earth.apply_maneuver(man_lambert, intermediate=True) # Let's plot this transfer orbit in 3D! # In[8]: from poliastro.plotting import OrbitPlotter3D # In[9]: plotter = OrbitPlotter3D() plotter.set_attractor(Sun)
label="Inner cruise 1 full orbit", color="C1", ) # We can check that the period of the orbit is similar to the one stated in the mission's documentation. Remember that in previous plot we only plotter half of the orbit for Juno first maneuver and the period is the time that would take Juno to complete one full revolution around this new orbit. # In[7]: ic1.period.to(u.day) # Notice in previous plot that Earth's position is not the initial one since while Juno is moving Earth also does. We now solve for the Lambert maneuver in order to perform a flyby around the earth when it is at flyby date. # In[8]: # Let's compute the Lambert solution to do the flyby of the Earth man_flyby = Maneuver.lambert(ic1_end, ss_efly) imp_a, imp_b = man_flyby.impulses print("Initial impulse:", imp_a) print("Final impulse:", imp_b) # In[9]: # Check the initial delta-V dv_a = imp_a[-1] norm(dv_a.to(u.km / u.s)) # We can now solve for the flyby orbit that will help Juno with the gravity assist. Again, the inner pahse 2 maneuver is define till Juno reaches Earth's position for the flyby date although the full orbit is plotted. # In[10]:
def maneuver_lambert(orbit_dpt, orbit_arr_sc, orbit_last, t_maneuver, file_maneuvers, distance_sc_dergee, flag, plot=False, num_revol=None, is_short=False, intermediate=True): # calculate time to return back alfa_back = (360 - distance_sc_dergee * 5) / 180 * np.pi * u.rad orbit_back = orbit_last.propagate_to_anomaly(alfa_back) r2_back = orbit_back.r v2_back = orbit_back.v date_arrival_back = time.Time( (DATA_LAUNCH.unix + 2.5 * orbit_dpt.period.value * ((360 - distance_sc_dergee * 5) / 360)), format='unix') orbit_arr_back = Orbit.from_vectors(Earth, r2_back, v2_back, epoch=date_arrival_back) man_lambert_back = Maneuver.lambert(orbit_last, orbit_arr_back, short=is_short, M=1) cost_maneuver_back = man_lambert_back.get_total_cost() time_maneuver_back = man_lambert_back.get_total_time() dv_tot = cost_maneuver_back T_man_tot = time_maneuver_back if flag: file_maneuvers.write( "Last maneuver to return at init point (similar for all), it is a part of maneuvers, " "which is added automatic to final answers " + '\n') file_maneuvers.write("dv back: " + str(cost_maneuver_back) + '\n') file_maneuvers.write("T maneuver back: " + str(time_maneuver_back) + '\n\n') t_maneuver = (t_maneuver - time_maneuver_back.value) / 5 file_maneuvers.write("Number of revolution to go to one sc: " + str(num_revol) + '\n') file_maneuvers.write("Time of maneuver to go to one sc [sec]: " + str(t_maneuver) + '\n') alfa = orbit_dpt.n.value * t_maneuver * u.rad orbit = orbit_arr_sc.propagate_to_anomaly(alfa) r2 = orbit.r v2 = orbit.v date_arrival = time.Time((DATA_LAUNCH.unix + t_maneuver), format='unix') orbit_arr = Orbit.from_vectors(Earth, r2, v2, epoch=date_arrival) if num_revol: man_lambert = Maneuver.lambert(orbit_dpt, orbit_arr, short=is_short, M=num_revol) else: man_lambert = Maneuver.lambert(orbit_dpt, orbit_arr, short=is_short) orbit_trans, orbit_target = orbit_dpt.apply_maneuver( man_lambert, intermediate=intermediate) if plot: # try to plot it fig, ax = plt.subplots() # (figsize=(4, 4)) plotter = StaticOrbitPlotter(ax) plotter.plot(orbit_dpt, label="Initial orbit", color="red") plotter.plot(orbit_trans, label="Trans orbit", color="blue") plotter.plot(orbit_target, label="Final orbit", color="green") if num_revol: plt.savefig("figures_lamb/ManeuverLambert, t_man [month] = " + str(t_maneuver / (3600 * 24 * 30)) + "T, revol=" + str(num_revol) + ".png") else: plt.savefig("figures_lamb/ManeuverLambert, t_man [month] = " + str(t_maneuver / (3600 * 24 * 30)) + "T.png") plt.show() check_alt(orbit_trans, file_maneuvers) cost_maneuver = man_lambert.get_total_cost() time_maneuver = man_lambert.get_total_time() dv_tot = dv_tot + cost_maneuver * 5 T_man_tot = T_man_tot + time_maneuver * 5 file_maneuvers.write("dv: " + str(dv_tot) + '\n') file_maneuvers.write("T maneuver: " + str(T_man_tot) + '\n\n') file_maneuvers.write("- - - - - - - - - - " + '\n') print("dv: " + str(dv_tot) + '\n') print("T maneuver: " + str(T_man_tot) + '\n\n') return False