def get_problem(): """Unconstrained Double integrator problem .""" # Rename this and/or move to optim package? problem = beluga.optim.Problem('brysondenham') # Define independent variables problem.independent('t', 's') # Define equations of motion problem.state('x', 'v','m') \ .state('v', 'u','m/s') \ # Define controls problem.control('u', 'm/s') # Define costs problem.cost['path'] = Expression('u^2', 'm^2/s') # Define constraints problem.constraints('default',0) \ .initial('x-x_0','m') \ .initial('v-v_0','m/s') \ .terminal('x-x_f','m') \ .terminal('v-v_f','m/s') problem.scale.unit('m','x') \ .unit('s',1)\ .unit('kg',1) \ .unit('rad',1) # problem.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=1000, verbose = True, cached=False) problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=10000, verbose=True, cached=False, number_arcs=4) problem.guess.setup( 'auto', start=[0, 1], # Starting values for states in order direction='forward', costate_guess=-0.1, time_integrate=1 ## REQUIRED BECAUSE OF FIXED FINAL TIME ) problem.steps.add_step().num_cases(5) \ .terminal('x',0) problem.steps.add_step().num_cases(5) \ .initial('v',1.0) \ .terminal('v', -1) return problem
def get_problem(): """A simple test of optimal surface track planning.""" # Rename this and/or move to optim package? problem = beluga.optim.Problem('Hannibal') #Define independent variables problem.independent('t', 's') # Define equations of motion problem.state('x','V*cos(hdg)','m') \ .state('y','V*sin(hdg)','m') \ # Define controls problem.control('hdg','rad') # Define Cost Functional problem.cost['path'] = Expression('(1-w)+w*V*conv*elev*(-0.3*exp(-0.5*((x-2.7)^2+1.5*(y-2.1)^2))+2.6*exp(-0.55*(0.87*(x-6.7)^2+(y-2.2)^2))+2.1*exp(-0.27*(0.2*(x-5.5)^2+(y-7.2)^2))+1.6*(cos(0.8*y))^2*(sin(0.796*x))^2)', 's') #Define constraints problem.constraints().initial('x-x_0','m') \ .initial('y-y_0','m') \ .terminal('x-x_f','m') \ .terminal('y-y_f','m') #Define constants problem.constant('w',0.0,'1') #Initial Terrain weighting factor problem.constant('conv',1,'s/m^2') #Integral conversion factor problem.constant('V',1,'m/s') #Vehicle speed problem.constant('elev',1,'m') #Initial Elevation #Unit scaling problem.scale.unit('m',1) \ .unit('s',1) \ .unit('rad',1) #Configure solver problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=1000, verbose = True, cached = False, number_arcs=4) #Initial Guess problem.guess.setup('auto',start=[4.9,0.4], costate_guess=[0.1,-0.1]) #City A #Add Continuation Steps problem.steps.add_step().num_cases(30) \ .terminal('x', 7.2) \ .terminal('y', 8.5) problem.steps.add_step().num_cases(30) \ .const('w',0.5) #Final Terrain weighting factor return problem
def get_problem(): """A simple test of optimal surface track planning.""" problem = beluga.optim.Problem('Track_demo') problem.mode = 'analytical' #Other options: 'numerical', 'dae' #Define independent variables problem.independent('t', 's') # Define equations of motion problem.state('x','V*cos(hdg)','k') \ .state('y','V*sin(hdg)','k') \ # Define controls problem.control('hdg', 'rad') # Define cost functional problem.cost['path'] = Expression('(1-w)+w*V*conv*elev*terrain(x,y)', 's') #Define constraints problem.constraints().initial('x-x_0','k') \ .initial('y-y_0','k') \ .terminal('x-x_f','k') \ .terminal('y-y_f','k') #Define constants problem.constant('w', 0.9, '1') #Initial Terrain weighting factor problem.constant('conv', 1, 's/k^2') #Integral conversion factor problem.constant('V', 1, 'k/s') #Vehicle speed problem.constant('elev', 0.001, 'k') #Units for the elevation #Unit scaling problem.scale.unit('k',1) \ .unit('s',1) \ .unit('rad',1) #Configure solver problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=50, verbose=True, cached=False, number_arcs=8) #problem.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=50, verbose = True, cached = False) #Initial Guess problem.guess.setup('auto', start=[16, 10], costate_guess=[0.0, -0.1]) #Add continuation steps problem.steps.add_step(strategy='HPA') \ .terminal('x', 180, 50) \ .terminal('y', 98, 50) return problem
problem.constant('v_s', 100, 'rad') problem.constant('gam_s', 1, 'rad') problem.constant('p11_s', 1e5, 'rad') problem.constant('p12_s', 1e-2, 'rad') problem.constant('p13_s', 1e2, 'rad') problem.constant('p14_s', 1e-1, 'rad') problem.constant('p22_s', 1e-10, 'rad') problem.constant('p23_s', 1e-5, 'rad') problem.constant('p24_s', 1e-8, 'rad') problem.constant('p33_s', 1e1, 'rad') problem.constant('p34_s', 1e-3, 'rad') problem.constant('p44_s', 1e-6, 'rad') problem.constant('ep', 5, 'rad') problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=1000, verbose=True, cached=False, number_arcs=16) # problem.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=1000, verbose=True, cached=False) problem.scale.unit('m', 1) \ .unit('s', 1) \ .unit('kg', 1) \ .unit('rad', 1) # Define quantity (not implemented at present) # Is this actually an Expression rather than a Value? # problem.quantity = [Value('tanAng','tan(theta)')] problem.guess.setup('auto', start=[80, 0, 50, -89*pi/180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], costate_guess=[0, 0, 0, 0, 0.0001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], time_integrate=2.5) # costate_guess=[0, 0, 0, 0, 0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # problem.guess.setup('auto',start=[80000,3.38575809e-21,5000,7.98617365e-02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],direction='forward',time_integrate=229.865209,costate_guess =[-1.37514494e+01,3.80852584e+06,-3.26290152e+03,-2.31984720e-14,0.00,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01]) # Figure out nicer way of representing this. Done?
def get_problem(): """Brachistochrone example.""" # Rename this and/or move to optim package? problem = beluga.optim.Problem('brachisto_MS') # Switch off DAE mode problem.mode = 'num' # Define independent variables problem.independent('t', 's') # Define equations of motion problem.state('x', 'v*cos(theta)','m') \ .state('y', '-v*sin(theta)','m') \ .state('v', 'g*sin(theta)','m/s') # Define controls problem.control('theta', 'rad') # Define costs problem.cost['path'] = Expression('1', 's') # Define constraints problem.constraints('default',0) \ .initial('x-x_0','m') \ .initial('y-y_0','m') \ .initial('v-v_0','m/s') \ .terminal('x-x_f','m') \ .terminal('y-y_f','m') # problem.constraints().interior_point('(x-x1)^2+(y-y1)^2','m^2') # Define constants (change to have units as well) problem.constant('g', '9.81', 'm/s^2') # problem.constant('x1','7.5','m') # problem.constant('y1','-15','m') # problem.quantity('gDown','g*sin(theta)') problem.scale.unit('m',1) \ .unit('s',1)\ .unit('kg',1) \ .unit('rad',1) problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=1000, verbose=True, cached=False, number_arcs=2, max_error=100) # problem.bvp_solver = algorithms.SingleShooting(derivative_method='csd',tolerance=1e-4, max_iterations=50, verbose = True, cached=False) # problem.bvp_solver = algorithms.BroydenShooting(tolerance=1e-4, max_iterations=1000) # Can be array or function handle # TODO: implement an "initial guess" class subclassing Solution # problem.guess = bvpsol.bvpinit(np.linspace(0,1,2), [0,0,1,-0.1,-0.1,-0.1,0.1]) # problem.guess.parameters = np.array([0.1,0.1,0.1,0.1,0.1]) problem.guess.setup( 'auto', start=[0, 0, 1], # Starting values for states in order direction='forward', costate_guess=-0.1) # Figure out nicer way of representing this. Done? problem.steps.add_step('bisection') \ .num_cases(2) \ .terminal('x', 5) \ .terminal('y',-5) # ( # problem.steps.add_step().num_cases(2) # .terminal('x', 30.0) # .terminal('y',-30.0), # problem.steps.add_step() # .num_cases(10) # .terminal('x', 1000.0) # .terminal('y',-1000.0) # ) return problem
def get_problem(): # Figure out way to implement caching automatically #@functools.lru_cache(maxsize=None) # from beluga.utils import keyboard # keyboard() """A simple planar hypersonic problem example.""" # Rename this and/or move to optim package? problem = beluga.optim.Problem('planarHypersonic') # problem = beluga.optim.Problem() # Define independent variables problem.independent('t', 's') # rho = 'rho0*exp(-h/H)' # Cl = '(1.5658*alfa + -0.0000)' # Cd = '(1.6537*alfa^2 + 0.0612)' # D = '(0.5*'+rho+'*v^2*'+Cd+'*Aref)' # L = '(0.5*'+rho+'*v^2*'+Cl+'*Aref)' # r = '(re+h)' problem.quantity('rho', 'rho0*exp(-h/H)') problem.quantity('Cl', '(Cl1*alfa + -0.0000)') problem.quantity('Cd', '(Cd2*alfa^2 + Cd0)') problem.quantity('qA', '0.5*rho*v^2*Aref') # problem.quantity('D','0.5*rho*v^2*Cd*Aref') # problem.quantity('L','0.5*rho*v^2*Cl*Aref') problem.quantity('r', 're+h') # Define equations of motion problem.state('h','v*sin(gam)','m') \ .state('theta','v*cos(gam)/r','rad') \ .state('v','-qA*Cd/mass - mu*sin(gam)/r**2','m/s') \ .state('gam','qA*Cl/(mass*v) + (v/r - mu/(v*r^2))*cos(gam)','rad') #.state('alfa','alfaRateMax*sin(alfaDotTrig)','rad') # problem.state('h','v*sin(gam)','m') \ # .state('theta','v*cos(gam)/'+r,'rad') \ # .state('v','-'+D+'/mass - mu*sin(gam)/'+r+'**2','m/s') \ # .state('gam',L+'/(mass*v) + (v/'+r+' - mu/(v*'+r+'^2))*cos(gam)','rad') # Define controls problem.control('alfa', 'rad') # problem.control('alfaDot','rad/s') # problem.control('alfaDotTrig','rad') # Define costs problem.cost['terminal'] = Expression('-v^2', 'm^2/s^2') # Define constraints problem.constraints().initial('h-h_0','m') \ .initial('theta-theta_0','rad') \ .initial('v-v_0','m/s') \ .terminal('h-h_f','m') \ .terminal('theta-theta_f','rad') \ #.path('h','<','hMax','m') \ #.control('alfaDot','-alfaRateMax','alfaRateMax','rad/s') # Define constants problem.constant('mu', 3.986e5 * 1e9, 'm^3/s^2') # Gravitational parameter, m^3/s^2 problem.constant('rho0', 1.2, 'kg/m^3') # Sea-level atmospheric density, kg/m^3 problem.constant('H', 7500, 'm') # Scale height for atmosphere of Earth, m problem.constant('Cd2', 1.6537, 'nd') problem.constant('Cd0', 0.0612, 'nd') problem.constant('Cl1', 1.5658, 'nd') problem.constant('mass', 750 / 2.2046226, 'kg') # Mass of vehicle, kg problem.constant('re', 6378000, 'm') # Radius of planet, m problem.constant('Aref', pi * (24 * .0254 / 2)**2, 'm^2') # Reference area of vehicle, m^2 problem.constant('rn', 1 / 12 * 0.3048, 'm') # Nose radius, m problem.constant('hMax', 150000, 'm') problem.constant('alfaRateMax', 10 * pi / 180, 'rad/s') problem.constant('eps', 100, 'm/s') problem.constant('w', 0, 'nd') problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=31, verbose=True, cached=False, number_arcs=2) # problem.bvp_solver = algorithms.SingleShooting(derivative_method='csd',tolerance=1e-4, max_iterations=100000, verbose = True, cached = False) problem.scale.unit('m','h') \ .unit('s','h/v') \ .unit('kg','mass') \ .unit('rad',1) \ .unit('nd',1) problem.guess.setup('auto', start=[80000, 0.01, 5000, -90 * pi / 180]) #problem.guess.setup('auto',start=[80000,3.38575809e-21,5000,7.98617365e-02],direction='forward',time_integrate=229.865209,costate_guess =[-1.37514494e+01,3.80852584e+06,-3.26290152e+03,-2.31984720e-14]) # Figure out nicer way of representing this. Done? problem.steps.add_step('bisection') \ .num_cases(11) \ .terminal('h', 0) problem.steps.add_step('bisection') \ .num_cases(11) \ .terminal('theta', 10*pi/180) # return problem
def get_problem(): #User Defined Terrain Elevation #def terr( x_pos, y_pos ): #Defines terrain elevation [m] as a function of x and y positions [m] # elev=100.0*(np.sin(0.5*(x_pos/1000.0)))**2.0 #User defined elevation map # return elev #User Defined Tunnel Cost #def tunnel(depth): #Defines additional cost for placing a 1 meter length of track a non-zero #depth below the ground. # TunnelCost=(50e3)/(1+np.exp(-(depth-5))) #Tunneling Cost (2016 USD) # return TunnelCost #def bridge(height): #Defines additional cost for placing a 1 meter length of track a non-zero #heigh above the ground. # BridgeCost=10e3*(height/10)**2 #Bridge Cost (2016 USD) # return BridgeCost """A simple test of optimal surface track planning.""" # Rename this and/or move to optim package? problem = beluga.optim.Problem('surftest_noinc') #Define independent variables problem.independent('t', 's') # Define equations of motion problem.state('x','V*cos(hdg)','m') \ .state('y','V*sin(hdg)','m') \ .state('V','amax*sin(thrA) + eps*(cos(thrA)+cos(hdgA))','m/s') \ .state('hdg','cmax/V*sin(hdgA)','rad') # Define controls #problem.control('thrA','rad') \ # .control('hdgA','rad') problem.control('hdgA', 'rad') # Define Cost Functional problem.cost['path'] = Expression('1', 's') #problem.cost['path'] = Expression('TimeToUSD+trk*V', 'USD') #+ \ #'(50e3)/(1.0+exp(-1.0*(z-0.0*(sin(0.5*(x/1000.0)))**2.0-5.0)))+'+ \ #'10e3*((0.0*(sin(0.5*(x/1000.0)))**2.0-z)/10.0)**2.0','USD') #Define constraints problem.constraints().initial('x-x_0','m') \ .initial('y-y_0','m') \ .initial('V-V_0','m/s') \ .initial('hdg-hdg_0','rad') \ .terminal('x-x_f','m') \ .terminal('y-y_f','m') #.terminal('V-V_f','m/s') #.initial('hdg-hdg_0','rad') \ #Define constants problem.constant('g', 9.81, 'm/s^2') #Acceleration due to gravity problem.constant( 'trk', 1, 'USD/m') #Basic cost of 1 m of track on ground (10k per m) problem.constant('amax', 1.0, 'm/s^2') #Maximum thrust acceleration of vehicle problem.constant('cmax', 1.0, 'm/s^2') #Maximum allowed centripetal acceleration problem.constant('eps', 10, 'm/s^2') #Error constant problem.constant('TimeToUSD', 1, 'USD/s') #Time is Money!! problem.constant('thrA', 0, 'rad') #Unit scaling problem.scale.unit('m','x') \ .unit('s','x/V') \ .unit('rad',1) \ .unit('USD',1) #Configure solver problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=1000, verbose=True, cached=False, number_arcs=2) #Initial Guess problem.guess.setup('auto', start=[0.0, 0.0, 1.0, pi / 4 - 0.2], costate_guess=-0.1) #City A #Add Continuation Steps problem.steps.add_step().num_cases(10) \ .terminal('x', 10) \ .terminal('y', 0) problem.steps.add_step().num_cases(10) \ .const('eps', 0.2) #problem.steps.add_step().num_cases(10) \ # .terminal('y', 2*pi*1000) \ # .terminal('z', 0.0) \ # .terminal('inc', 0.0) #^ City B return problem
def get_problem(): """A simple example of graph search continuation""" # Rename this and/or move to optim package? problem = beluga.optim.Problem('boat') #Define independent variables problem.independent('t', 's') # Define equations of motion problem.state('x','V*cos(hdg)+eps*k*cos(hdgA)','m') \ .state('y','V*sin(hdg)','m') \ .state('hdg','k*sin(hdgA)','rad') # Define controls problem.control('hdgA', 'rad') # problem.control('hdgdot','rad/s') problem.mode = 'analytic' # Define Cost Functional problem.cost['terminal'] = Expression('t', 's') #Define constraints problem.constraints().initial('x-x_0','m') \ .initial('y-y_0','m') \ .initial('hdg-hdg_0','rad') \ .terminal('x-x_f','m') \ .terminal('y-y_f','m') #Define constants problem.constant('cmax', 1.0, 'm/s^2') #Maximum allowed centripetal acceleration problem.constant('V', 1, 'm/s') #Velocity problem.constant('k', 1, 'rad/s') problem.constant('eps', 0.5, 'm') #Error constant #Problem scaling problem.scale.unit('m',1) \ .unit('s',1) \ .unit('rad',1) #Configure solver problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=1000, verbose=True, cached=False, number_arcs=16) #problem.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=100, verbose = True, cached = False) #Initial Guess....................x0..y0..hdg0 problem.guess.setup('auto', start=[0.0, 0.0, 0.0]) #Add Continuation Steps #problem.steps.add_step().num_cases(2) \ # .terminal('x', 3) \ # .terminal('y', 0.1) problem.steps.add_step().num_cases(10) \ .terminal('x', 1.0) \ .terminal('y', 0) \ problem.steps.add_step().num_cases(10) \ .terminal('x', 10.05) \ .terminal('y', 0) \ problem.steps.add_step().num_cases(10) \ .terminal('y', 10) \ problem.steps.add_step().num_cases(10) \ .const('eps', 0.1) \ problem.steps.add_step().num_cases(6) \ .const('eps', 0.01) return problem
def get_problem(): """A simple planar hypersonic problem example.""" # Rename this and/or move to optim package? problem = beluga.optim.Problem('HF_planarHypersonic') problem.mode = 'analytical' # problem = beluga.optim.Problem() # alfatest = 15*np.pi/180 # dc = 25*np.pi/180 # rc = 2.5 # rn = 0.25 # print(CLfunction(alfatest, dc, rn, rc)) # quit() # Define independent variables problem.independent('t', 's') # Define quantities used in the problem problem.quantity('rho', 'rho0*exp(-h/H)') # problem.quantity('Cl','CLfunction(alfa, dc, rn, rc)') # problem.quantity('Cd','CDfunction(alfa, dc, rn, rc)') # problem.quantity('Cl','(1.5658*alfa + -0.0000)') # problem.quantity('Cd','(1.6537*alfa^2 + 0.0612)') # problem.quantity('D','0.5*rho*v^2*Cd*Aref') # problem.quantity('L','0.5*rho*v^2*Cl*Aref') problem.quantity('r', 're+h') #TODO: need to look through problem quantities to find custom functions # Define equations of motion # problem.state('h','v*sin(gam)','m') \ # .state('theta','v*cos(gam)/r','rad') \ # .state('v','-D/mass - mu*sin(gam)/r**2','m/s') \ # .state('gam','L/(mass*v) + (v/r - mu/(v*r^2))*cos(gam)','rad') problem.state('h','v*sin(gam)','m') \ .state('theta','v*cos(gam)/r','rad') \ .state('v','-0.5*rho*v^2*CDlookup(alfa, dc, rn, rc)*Aref/mass - mu*sin(gam)/r**2','m/s') \ .state('gam','0.5*rho*v^2*CLlookup(alfa, dc, rn, rc)*Aref/(mass*v) + (v/r - mu/(v*r^2))*cos(gam)','rad') # Define controls problem.control('alfa', 'rad') # Define costs problem.cost['terminal'] = Expression('-v^2', 'm^2/s^2') # Define constraints problem.constraints().initial('h-h_0','m') \ .initial('theta-theta_0','rad') \ .initial('v-v_0','m/s') \ .terminal('h-h_f','m') \ .terminal('theta-theta_f','rad') # Define constants problem.constant('mu', 3.986e5 * 1e9, 'm^3/s^2') # Gravitational parameter, m^3/s^2 problem.constant('rho0', 1.2, 'kg/m^3') # Sea-level atmospheric density, kg/m^3 problem.constant('H', 7500, 'm') # Scale height for atmosphere of Earth, m problem.constant('dc', 25 * np.pi / 180, 'rad') #Vehicle cone angle problem.constant('rc', 0.3, 'm') #Vehicle cone base radius problem.constant('rn', 0.01, 'm') #Vehicle nose radius problem.constant('mass', 750 / 2.2046226, 'kg') # Mass of vehicle, kg problem.constant('re', 6378000, 'm') # Radius of planet, m problem.constant('Aref', pi * (0.3)**2, 'm^2') # Reference area of vehicle, m^2 problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=1000, verbose=True, cached=False, number_arcs=4, max_error=200) # problem.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=100000, verbose = True, cached = False) problem.scale.unit('m','h') \ .unit('s','h/v') \ .unit('kg','mass') \ .unit('rad',1) problem.guess.setup('auto', start=[80000, 0, 5000, -90 * pi / 180], costate_guess=-0.1) #problem.guess.setup('auto',start=[80000,3.38575809e-21,5000,7.98617365e-02],direction='forward',time_integrate=229.865209,costate_guess =[-1.37514494e+01,3.80852584e+06,-3.26290152e+03,-2.31984720e-14]) # Figure out nicer way of representing this. Done? problem.steps.add_step().num_cases(10) \ .terminal('h', 0) problem.steps.add_step().num_cases(40) \ .terminal('theta', 10*pi/180) # # # problem.steps.add_step() # .num_cases(3) # .terminal('x', 40.0) # .terminal('y',-40.0) # ) return problem
def get_problem(): """A simple planar hypersonic problem example.""" # Author: Joseph Williams problem = beluga.optim.Problem('planarHypersonicWithThrust') # Define independent variables problem.independent('t', 's') # alfa = 'alfa' # alfadot = '(3*pi/180*sin(alfadottrig))' alfa = '(10*pi/180*sin(alfatrig))' rho = 'rho0*exp(-h/H)' Cl = '(0.496*' + alfa + ' + 0.0049)' Cd = '(0.4747*' + alfa + '^2 + 0.0096*' + alfa + ' + 0.0007)' # T = 'ThrustFunction()' D = '(0.5*' + rho + '*v^2*' + Cd + '*Aref)' L = '(0.5*' + rho + '*v^2*' + Cl + '*Aref)' r = '(re+h)' Ft = '(T*cos(' + alfa + ') - ' + D + ')' Fn = '(T*sin(' + alfa + ') + ' + L + ')' # Define equations of motion problem.state('h','v*sin(gam)+ ep*(cos(alfadottrig))','m') \ .state('theta','v*cos(gam)/'+r,'rad') \ .state('v',Ft+'/mass - mu*sin(gam)/'+r+'**2','m/s') \ .state('gam',Fn+'/(mass*v) + (v/'+r+' - mu/(v*'+r+'^2))*cos(gam)','rad') \ .state('mass','-T/(G0*Isp)','kg') \ .state('alfatrig','(5*pi/180*sin(alfadottrig))/(10*pi/180*cos(alfatrig))','rad') # Define controls problem.control('alfadottrig', 'rad') # Define costs problem.cost['terminal'] = Expression('-v^2', 'm^2/s^2') # problem.cost['terminal'] = Expression('-theta','rad') # problem.cost['path'] = Expression('1','s') # Define constraints problem.constraints().initial('h-h_0','m') \ .initial('theta-theta_0','rad') \ .initial('v-v_0','m/s') \ .initial('mass-mass_0','kg') \ .terminal('h-h_f','m') \ .terminal('theta-theta_f','rad') # Define constants problem.constant('mu', 3.986e5 * 1e9, 'm^3/s^2') # Gravitational parameter, m^3/s^2 problem.constant('rho0', 1.2, 'kg/m^3') # Sea-level atmospheric density, kg/m^3 problem.constant('H', 7500, 'm') # Scale height for atmosphere of Earth, m # problem.constant('T',2668932,'kg*m/s^2') # Constant Thrust of Vehcicle, kgm/s^2 # problem.constant('mdotf',15.5*0.05,'kg/s') # Fuel Mass Flow Rate of Vehicle, kg problem.constant('T', 2668932, 'kg*m/s^2') # Constant Thrust of Vehcicle, kgm/s^2 problem.constant('G0', 9.81, 'm/s^2') # Gravitational Constant at the surface of Earth problem.constant('Isp', 1600, 's') # Specific Impulse of Engine problem.constant('ep', 0.5, 'm/s') problem.constant('re', 6378000, 'm') # Radius of planet, m problem.constant('Aref', 557.4, 'm^2') # Reference area of vehicle, m^2 problem.constant('rn', 1 / 12 * 0.3048, 'm') # Nose radius, m problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=10000, verbose=True, cached=False, number_arcs=4) #problem.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=1000, verbose = True, cached = False) problem.scale.unit('m','h') \ .unit('s','h/v') \ .unit('kg','mass') \ .unit('rad',1) # Define quantity (not implemented at present) # Is this actually an Expression rather than a Value? # problem.quantity = [Value('tanAng','tan(theta)')] # problem.guess.setup('auto',start=[1000,0,100,-90*pi/180,127005]) problem.guess.setup('auto', start=[50000, 0, 4000, -90 * pi / 180, 127005, 0], costate_guess=0.1) #problem.guess.setup('auto',start=[80000,3.38575809e-21,5000,7.98617365e-02],direction='forward',time_integrate=229.865209,costate_guess =[-1.37514494e+01,3.80852584e+06,-3.26290152e+03,-2.31984720e-14]) # Figure out nicer way of representing this. Done? problem.steps.add_step().num_cases(21) \ .terminal('h', 0) \ # .initial('h',60000)\ # .initial('v',5000) #.terminal('theta', 10*pi/180) # problem.steps.add_step().num_cases(5) \ # .const('T', 2668932) \ problem.steps.add_step().num_cases(101) \ .terminal('theta', 10*pi/180) \ problem.steps.add_step().num_cases(5) \ .const('T', 0) \ # # problem.steps.add_step() # .num_cases(3) # .terminal('x', 40.0) # .terminal('y',-40.0) # ) return problem
def get_problem(state,costate,param,time): # Rename this and/or move to optim package? problem = beluga.optim.Problem('hypersonci3DOFCrossrange') # Define independent variables problem.independent('t', 's') # Updated aero from Mike Bolender #x = 'v/a' # mach #y = '(9*sin(ang)+5)' Cl = '((14185132937801937*sin(alfa))/72057594037927936 - (5421779306486855*(v/a))/2305843009213693952 - (1574554238845453*(v/a)*(9*sin(alfa) + 5))/576460752303423488 - (1081832482396803*(v/a)*(9*sin(alfa) + 5)^2)/147573952589676412928 + (795005714371527*(v/a)^2*(9*sin(alfa) + 5))/4611686018427387904 - (2905380043335151*(v/a)^2)/18446744073709551616 + (7384633541699571*(9*sin(alfa) + 5)^2)/36893488147419103232 + (4723631850413463*(9*sin(alfa) + 5)^3)/4722366482869645213696 + 40090326007262905/288230376151711744)' Cd = '((7975570356452291*(v/a))/144115188075855872 - (939292000388127*sin(alfa))/144115188075855872 + (4181805097702493*(v/a)^2*(9*sin(alfa) + 5)^2)/295147905179352825856 + (5799269589896587*(v/a)*(9*sin(alfa) + 5))/2305843009213693952 - (3435815237005351*(v/a)*(9*sin(alfa) + 5)^2)/18446744073709551616 - (6565772557668597*(v/a)^2*(9*sin(alfa) + 5))/9223372036854775808 - (2327227566991187*(v/a)*(9*sin(alfa) + 5)^3)/1180591620717411303424 + (3879272510917453*(v/a)^3*(9*sin(alfa) + 5))/73786976294838206464 - (4630940327334427*(v/a)^2)/144115188075855872 + (3228336930707955*(v/a)^3)/576460752303423488 - (5752786461422987*(v/a)^4)/18446744073709551616 + (59645010131291*(9*sin(alfa) + 5)^2)/72057594037927936 + (1198177006620385*(9*sin(alfa) + 5)^3)/73786976294838206464 + (1971121512347433*(9*sin(alfa) + 5)^4)/302231454903657293676544 + 506236799411217/18014398509481984)' rho = 'rho0*exp(-(r-re)/H)' #Cl = '(1.5658*sin(alfa) + -0.0000)' #Cd = '(1.6537*sin(alfa)^2 + 0.0612)' # Cl = 'CLfunction(alfa)' # Cd = 'CDfunction(alfa)' D = '(0.5*'+rho+'*v^2*'+Cd+'*Aref)' L = '(0.5*'+rho+'*v^2*'+Cl+'*Aref)' #r = '(re+h)' r = 'r' # Define equations of motion problem.state('r','v*sin(gam)','m') \ .state('lam','v*cos(gam)*sin(chi)/('+r+'*cos(phi))','rad') \ .state('phi','v*cos(gam)*cos(chi)/'+r,'rad') \ .state('v','-'+D+'/mass - mu*sin(gam)/'+r+'^2','m/s') \ .state('gam',L+'*cos(bank)/(mass*v) - mu/(v*'+r+'^2)*cos(gam) + v/'+r+'*cos(gam)','rad') \ .state('chi',L+'*sin(bank)/(mass*cos(gam)*v) + v/'+r+'*cos(gam)*sin(chi)*tan(phi)','rad') # Define controls problem.control('bank','rad') \ .control('alfa','rad') # Define costs problem.cost['terminal'] = Expression('-phi^2','rad') # Define constraints problem.constraints().initial('r-r_0','m') \ .initial('lam-lam_0','rad') \ .initial('phi-phi_0','rad') \ .initial('v-v_0','m/s') \ .initial('gam-gam_0','rad') \ .initial('chi-chi_0','rad') \ .terminal('r-r_f','m') \ .terminal('lam-lam_f','rad') # Define constants problem.constant('mu',3.986e5*1e9,'m^3/s^2') # Gravitational parameter, m^3/s^2 problem.constant('rho0',1.2,'kg/m^3') # Sea-level atmospheric density, kg/m^3 problem.constant('H',7500,'m') # Scale height for atmosphere of Earth, m problem.constant('mass',750/2.2046226,'kg') # Mass of vehicle, kg problem.constant('re',6378000,'m') # Radius of planet, m problem.constant('Aref',pi*(24*.0254/2)**2,'m^2') # Reference area of vehicle, m^2 #problem.constant('rn',1/12*0.3048,'m') # Nose radius, m problem.constant('a',330,'m/s') # Speed of sound approx #in.const.a = {330,'m/s'}; % speed of sound #in.const.rn = {1/12*0.3048,'m'}; % Nose radius #in.const.k = {1.74153e-4,'sqrt(kg)/m^2'}; % heat rate coefficient #in.const.gammaThermo = {1.4,'nd'}; #in.const.RThermo = {287,'m^2/(s^2*K)'}; problem.scale.unit('m','r') \ .unit('s','r/v')\ .unit('kg','mass') \ .unit('rad',1) # Define quantity (not implemented at present) # Is this actually an Expression rather than a Value? # problem.quantity = [Value('tanAng','tan(theta)')] #problem.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=1000, verbose = True, cached = False) problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=1000, verbose = True, cached = False, number_arcs=4) #problem.guess.setup('auto',start=state,costate_guess=costate,time_integrate=time) problem.guess.setup('auto',start=[6378050,0,0,10,-80*pi/180,0]) #costate_guess = [.8*1000,-.2*1000,-1.0*1000,-0.09*1000,0.005*1000,-0.05*1000] #problem.guess.setup('auto',start=[40000,-45*pi/180,0,2200,-80*pi/180,-90*pi/180],costate_guess=costate_guess,time_integrate=1) problem.steps.add_step().num_cases(20) \ .terminal('r',6378000) problem.steps.add_step().num_cases(2) \ .terminal('r',6378000) \ .terminal('lam',-2.122494903350304) return problem
def get_problem(): """A test of dynamic continuation on aircraft noise minimization""" problem = beluga.optim.Problem('AircraftNoise3DOF') problem.mode = 'analytical' #Other options: 'numerical', 'dae' #Define independent variables problem.independent('t', 's') #Problem quantities problem.quantity('bank','bankmax*sin(banktrig)') \ .quantity('alfa','alfamax*sin(alfatrig)') \ .quantity('D','C1*v^2+C2/(v^2)') \ .quantity('L','mass*g') \ .quantity('T','1560*sin(Ttrignew)+1860') \ .quantity('Ft','T*cos(alfa) - D') \ .quantity('Fn','T*sin(alfa) + L') #Define equations of motion problem.state('x','v*cos(gam)*cos(psii)','m') \ .state('y','v*cos(gam)*sin(psii)','m') \ .state('z','v*sin(gam)','m') \ .state('v','Ft/mass - g*sin(gam)','m/s') \ .state('psii','Fn*sin(bank)/(mass*cos(gam)*v)','rad') \ .state('gam','Fn*cos(bank)/(mass*v) - g*cos(gam)/v','rad') # Define controls problem.control('banktrig','rad') \ .control('alfatrig','rad') \ .control('Ttrignew','kg*m/s^2') # Define cost functional problem.cost['path'] = Expression('T^5.2 * cos(gam)/(v*(z+50)^2.5)', 'nd') #Define constraints problem.constraints().initial('x-x_0','m') \ .initial('y-y_0','m') \ .initial('z-z_0','m') \ .initial('v-v_0','m/s') \ .initial('psii-psii_0','rad') \ .initial('gam-gam_0','rad') \ .terminal('x-x_f','m') \ .terminal('y-y_f','m') \ .terminal('z-z_f','m') \ .terminal('v-v_f','m/s') \ .terminal('psii-psii_f','rad') \ .terminal('gam-gam_f','rad') #Define constants problem.constant('mu', 3.986e5 * 1e9, 'm^3/s^2') #Gravitational parameter problem.constant('rho0', 1.2, 'kg/m^3') #Sea level atmospheric density problem.constant('H', 7500, 'm') #Atmospheric scale height problem.constant('re', 6378000, 'm') #Radius of Earth problem.constant('Aref', 112, 'm^2') problem.constant('bankmax', 60 * np.pi / 180, 'rad') problem.constant('alfamax', 15 * np.pi / 180, 'rad') problem.constant('Tmax', 3420, 'kg*m/s^2') problem.constant('Tmin', 300, 'kg*m/s^2') problem.constant('g', 9.81, 'm/s^2') problem.constant('mass', 7180 / 9.81, 'kg') problem.constant('C1', 0.226, 'kg/m') problem.constant('C2', 5.2e6, 'kg*m^3/s^4') #Unit scaling problem.scale.unit('m',1) \ .unit('s',1) \ .unit('kg',1) \ .unit('nd',1) \ .unit('rad',1) #Configure solver problem.bvp_solver = algorithms.MultipleShooting(derivative_method='fd', tolerance=1e-4, max_iterations=50, verbose=True, cached=False, number_arcs=8) #problem.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=50, verbose = True, cached = False) #Initial Guess problem.guess.setup( 'auto', start=[0, 0, 1197, 124, 0 * np.pi / 180, 0 * np.pi / 180]) #Add continuation steps problem.steps.add_step(strategy='manual').num_cases(20) \ .terminal('x', 5400) \ .terminal('y', 4600) \ .terminal('z', 0) \ .terminal('v', 77.5) \ .terminal('psii', 45*np.pi/180) \ .terminal('gam', 0) return problem