def transfer(self, target_position, target_velocity, flight_time = None, \ r_history = None, v_history = None, t_history = None, \ Minimize_Energy = False, SaveFlow = False): # giving lists to r_history, v_history and t_history arguments will #+ populate them with the r, v state and time histories # given export_flow will store the entire flow in export_flow # Minimize_Energy = True will override 'flight_time' with the # minimum energy time of flight given from lambert from utilities import rv2ic from shootingmodule import firstorder as shoot # if no flight_time is given, #+ hopefully the user has switched on Minimize_Energy if flight_time == None: flight_time = 0.0 # create the initial conditions vector # select an appropriate eom model that includes the #+ variational equations if len(target_position) == 2: ic = rv2ic(self.r[0:2], self.v[0:2], self.Mu, STM = True) temp_eom = 'P2BP_varEqns' elif len(target_position) == 3: ic = rv2ic(self.r, self.v, self.Mu, STM = True) temp_eom = 'S2BP_varEqns' # Override 'flight_time' if Minimize_Energy = True if Minimize_Energy: from utilities import create_one_list from lambert import prussing_conway from numpy import array ic0 = create_one_list([self.r, self.v], 0, 1) icf = create_one_list([target_position, target_velocity], 0, 1) # find the minimum time for a lambert solution lambert_solution = prussing_conway(ic0, icf, self.Mu, \ FindMinEnergy = True, \ NonDimUnits = False, \ ScaleOutput = False) time_for_min_energy = lambert_solution['tm'] # use the minimum time as a flight time to compute #+ the lambert solution lambert_solution = prussing_conway(ic0, icf, self.Mu, \ TransferTime = time_for_min_energy, \ NonDimUnits = False, \ ScaleOutput = False) # calculate the delta-v dv1_guess = list(lambert_solution['v1'] - array(ic0[2:4])) dv1_guess.append(0.0) flight_time = lambert_solution['time'] else: dv1_guess = None # apply the first order shooting method trajectory = shoot(ic, target_position, [0, flight_time], temp_eom, \ tol = 1E-2, iLimit = 60, \ damping = 0.3, guess = dv1_guess, \ print_status = True) # store the delta-v impulsive maneuvers needed #+ for the given transfer if len(target_position) == 2: self.dv1 = trajectory['y'][0][2:4] - self.v self.dv2 = target_velocity - trajectory['y'][-1][2:4] elif len(target_position) == 3: self.dv1 = trajectory['y'][0][3:6] - self.v self.dv2 = target_velocity - trajectory['y'][-1][3:6] # save trajectory states if desired from utilities import extract_elements n = len(target_position) if r_history != None: extract_elements(trajectory['y'], 0, n - 1, r_history) else: extract_elements(trajectory['y'], 0, n - 1, self.r_history) if v_history != None: extract_elements(trajectory['y'], n, 2*n - 1, v_history) else: extract_elements(trajectory['y'], n, 2*n - 1, self.v_history) # save the time history of the trajectory if t_history != None: t_history = trajectory['x'] else: self.t_history = trajectory['x'] # if the user wants the entire flow history, #+ give it to them! if SaveFlow: self.theflow = trajectory
def opt_pterminal(x0, ic1, ic2, dt): """ 1.) flow #1, #2 based on x0 2.) run prussing_conway 3.) run shooting method w/ variational eqns 4.) generate delta-vs 5.) generate primer history 6.) extract slopes 7.) compute cost function """ """ FUTURE WORK 1.) add in intelligent step sizing for flow3 = shoot() """ # import statements from flow import P2B as flow from lambert import prussing_conway from shootingmodule import firstorder as shoot from numpy.linalg import norm from numpy import array, zeros, eye print ("Starting an iteration of opt_pterminal!") print ("x0 is: %e, %e " % (x0[0], x0[1])) # function parameters """ FW 1.) """ step = 1e-2 tol = 1e-3 # extract mu mu = ic1[4] # flow #1, #2 based on x0[0] tspan = [0, x0[0]] ministep = abs(x0[0] / 2e2) print ("Midpoint-A of an iteration of opt_pterminal!") print ("tspan is: %e, %e " % (tspan[0], tspan[1])) print ("ministep is: %e " % ministep) flow1 = flow(ic1, tspan, ministep, trim_output=False, print_status=True, solver="rk4p") print ("Midpoint-B of an iteration of opt_pterminal!") flow2 = flow(ic2, tspan, ministep, trim_output=False) print ("Midpoint-C of an iteration of opt_pterminal!") # update ic1 and ic2 ic1 = array(flow1["y"][-1]) ic2 = array(flow2["y"][-1]) # update of flow time based on x0 tspan = [0, dt - x0[0] + x0[1]] # flow #2 based on x0[1] flow2 = flow(ic2, tspan, tstep=step, trim_output=False) # target position target = array(flow2["y"][-1][0:4]) # solve for lambert arc print ("Midpoint-0 of an iteration of opt_pterminal!") arc = prussing_conway(ic1, target, mu, TransferTime=abs(tspan[1])) # setup initial conditions for flow of spacecraft with # variational equations ic = zeros(21) ic[0:2] = ic1[0:2] ic[2:4] = arc["v1"] ic[4] = mu ic[5:] = eye(4).reshape(16) # flow spacecraft using lambert arc print ("Midpoint-1 of an iteration of opt_pterminal!") flow3 = flow(ic, tspan, tstep=step, eom="P2BP_varEqns", trim_output=False) print ("Midpoint-2 of an iteration of opt_pterminal!") # position error poserror = flow3["y"][-1][0:2] - flow2["y"][-1][0:2] # apply shooting method to reduce error if norm(poserror) > tol: flow3 = shoot( ic, target[0:2], tspan, eom="P2BP_varEqns", tstep=step, damping=1 / 3.0, tol=tol, trim_output=False ) poserror = flow3["y"][-1][0:2] - flow2["y"][-1][0:2] print ("Midpoint-3 of an iteration of opt_pterminal!") # delta-vs dv1 = array([flow3["y"][0][2], flow3["y"][0][3]]) - array([ic1[2], ic1[3]]) dv2 = -array([flow3["y"][-1][2], flow3["y"][-1][3]]) + array([flow2["y"][-1][2], flow2["y"][-1][3]]) # generate primer vector history p = phistory(dv1, dv2, flow3) # extract the slopes of the primer vector dp0 = pslope(flow3, p, 1, 0) dp1 = pslope(flow3, p, -1, -2) # scalar cost function J = dp0 ** 2 + dp1 ** 2 print ("Finished an iteration of opt_pterminal!") return J, flow1, flow2, flow3