# Define constraints ocp.constraints() \ .initial('h-h_0', 'm') \ .initial('theta', 'rad') \ .initial('v-v_0', 'm/s') \ .initial('gam-gam_0', 'rad') \ .initial('t', 's') \ .terminal('h-h_f', 'm') \ .terminal('theta-theta_f', 'rad') ocp.scale(m='h', s='h/v', kg='mass', rad=1) bvp_solver = beluga.bvp_algorithm('Shooting', algorithm='Armijo', derivative_method='fd', tolerance=1e-6, max_iterations=100, max_error=100) guess_maker = beluga.guess_generator('auto', start=[40000, 0, 4000, (-90) * pi / 180], direction='forward', costate_guess=-0.1) continuation_steps = beluga.init_continuation() # Start by flying straight towards the ground continuation_steps.add_step('bisection') \ .num_cases(11) \ .const('h_f', 0)
.terminal('x-x_f','m') \ .terminal('y-y_f','m') ocp.scale(m='y', s='y/v', kg=1, rad=1) # bvp_solver = beluga.bvp_algorithm('MultipleShooting', # derivative_method='fd', # tolerance=1e-4, # max_iterations=100, # verbose = True, # max_error=100 # ) bvp_solver = beluga.bvp_algorithm( 'MultipleShooting', tolerance=1e-4, max_iterations=50, verbose=True, ) # bvp_solver = beluga.bvp_algorithm('SingleShooting', # derivative_method='fd', # tolerance=1e-4, # max_iterations=50, # verbose = True, # ) guess_maker = beluga.guess_generator( 'auto', start=[0, 0, 1], # Starting values for states in order direction='forward', costate_guess=-0.1)
# Define costs ocp.path_cost('1', '1') # Define constraints ocp.constraints() \ .initial('x', 'm') \ .initial('y', 'm') \ .initial('v', 'm/s') \ .initial('t', 's') \ .terminal('x-x_f', 'm') \ .terminal('y-y_f', 'm') ocp.scale(m='y', s='y/v', kg=1, rad=1, nd=1) bvp_solver = beluga.bvp_algorithm('Shooting') guess_maker = beluga.guess_generator( 'auto', start=[0, 0, 0], # Starting values for states in order costate_guess=-0.1, control_guess=[-pi / 2], use_control_guess=True) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(21) \ .const('x_f', 10) \ .const('y_f', -10)
# Define constraints ocp.initial_constraint('x', 'm') ocp.initial_constraint('y', 'm') ocp.initial_constraint('t', 's') ocp.terminal_constraint('x-x_f', 'm') ocp.terminal_constraint('y-y_f', 'm', lower='-y_f_width', upper='y_f_width', activator='epsilon', method='utm') ocp.scale(m='x', s='x/V', rad=1) bvp_solver = beluga.bvp_algorithm('SPBVP') guess_maker = beluga.guess_generator('auto', start=[0, 0], control_guess=[0], use_control_guess=True, direction='forward') continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(10) \ .const('x_f', 10) continuation_steps.add_step('bisection') \ .num_cases(10) \
# Define constraints ocp_indirect.initial_constraint('x1 - x1_0', 'nd') ocp_indirect.initial_constraint('x2 - x2_0', 'nd') ocp_indirect.initial_constraint('t', 'nd') ocp_indirect.path_constraint('u', 'rad', lower='-2', upper='2', activator='epsilon1', method='epstrig') ocp_indirect.terminal_constraint('t - 1', 'nd') ocp_indirect.scale(rad=1, nd=1) bvp_solver_indirect = beluga.bvp_algorithm('spbvp') guess_maker_indirect = beluga.guess_generator('auto', start=[3, 5], direction='forward', costate_guess=-0.1, control_guess=[0], use_control_guess=True, time_integrate=0.1) beluga.add_logger(file_level=logging.DEBUG, display_level=logging.INFO) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(40, 'log') \
# Define costs ocp.terminal_cost('-v**2', 'm**2/s**2') # Define constraints ocp.initial_constraint('h-h_0', 'm') ocp.initial_constraint('theta', 'rad') ocp.initial_constraint('v-v_0', 'm/s') ocp.initial_constraint('gam-gam_0', 'rad') ocp.initial_constraint('t', 's') ocp.terminal_constraint('h-h_f', 'm') ocp.terminal_constraint('theta-theta_f', 'rad') ocp.scale(m='h', s='h/v', kg='mass', rad=1) bvp_solver = beluga.bvp_algorithm('spbvp') guess_maker = beluga.guess_generator( 'auto', start=[40000, 0, 2000, (-90)*pi/180], direction='forward', costate_guess=-0.1, control_guess=[0], use_control_guess=True) continuation_steps = beluga.init_continuation() # Start by flying straight towards the ground continuation_steps.add_step('bisection') \ .num_cases(5) \ .const('h_f', 0)
.terminal('zbar2-zbar2_f','nd')\ .terminal('psi2 - psi2_f', 'nd') \ # 1191 (45) - 5 vehicles with 4 path constraints # 911 seconds for 5 v and one path constraint # 247(31) seconds for 5 vehicle with GPOPS in background # 68(14) seconds for 3 vehicle with u constraints # 114(20) seconds for 4 vehicles with u constraint # 106(14) seconds for 3 vehicle unconstrained (with u constraints) # 75(10) seconds for 2 vehicle unconstrainted (with u constraints) ocp.scale(m=1, s=1, kg=1, rad=1, nd=1) bvp_solver = beluga.bvp_algorithm( 'Shooting', tolerance=1e-3, max_iterations=200, verbose=True, derivative_method='fd', max_error=20, ) bvp_solver = beluga.bvp_algorithm('qcpi', tolerance=1e-3, max_iterations=500, verbose=True, max_error=20, N=81) guess_maker = beluga.guess_generator( 'auto', start=[-.8, 0., -.1, -pi / 12.] + [-.8, .1, -.1, 0., 1.], direction='forward',
# Define constraints ocp.constraints() \ .initial('h-h_0', 'm') \ .initial('theta-theta_0', 'rad') \ .initial('v-v_0', 'm/s') \ .initial('gam-gam_0', 'rad') \ .terminal('h-h_f', 'm') \ .terminal('theta-theta_f', 'rad') ocp.scale(m='h', s='h/v', kg='mass', rad=1) bvp_solver = beluga.bvp_algorithm( 'ArmijoShooting', derivative_method='fd', tolerance=1e-4, max_iterations=100, verbose=True, max_error=100, ) # bvp_solver = beluga.bvp_algorithm('Collocation') guess_maker = beluga.guess_generator( 'auto', start=[40000, 0, 4000, (-90) * pi / 180], direction='forward', costate_guess=-0.1) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \
# Define costs ocp.terminal_cost('-v^2', 'm^2/s^2') # Define constraints ocp.constraints() \ .initial('h-h_0', 'm') \ .initial('theta', 'rad') \ .initial('v-v_0', 'm/s') \ .initial('t', 's') \ .terminal('h-h_f', 'm') \ .terminal('theta-theta_f', 'rad') ocp.scale(m='h', s='h/v', kg='mass', rad=1) bvp_solver = beluga.bvp_algorithm('Shooting', algorithm='Armijo') guess_maker = beluga.guess_generator( 'auto', start=[80000, 0, 4000, -90*pi/180], direction='forward', costate_guess=-0.1 ) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(11) \ .const('h_f', 0) \ .const('theta_f', 0.01*pi/180)
.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') \ .path('constraint1','y + x','>',-1.0,'m',start_eps=1e-1) # .path('constraint2','y + 0.75*x','>',-2,'m') #\ # ocp.scale(m='y', s='y/v', kg=1, rad=1, nd=1) ocp.scale(m=1, s=1, kg=1, rad=1, nd=1) bvp_solver = beluga.bvp_algorithm( 'MultipleShooting', derivative_method='fd', tolerance=1e-5, max_iterations=20, verbose=True, max_error=50, use_numba=True, # N = 30, ) guess_maker = beluga.guess_generator( 'auto', start=[0, 0, 1], # Starting values for states in order direction='forward', costate_guess=0.1, ) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \
ocp.constant('theta_f', 0, 'rad') # Define costs ocp.terminal_cost('-v^2', 'm^2/s^2') # Define constraints ocp.constraints() \ .initial('h-h_0','m') \ .initial('theta','rad') \ .initial('v-v_0','m/s') \ .terminal('h-h_f','m') \ .terminal('theta-theta_f','rad') ocp.scale(m='h', s='h/v', kg='mass', rad=1) bvp_solver = beluga.bvp_algorithm('Shooting', algorithm='SLSQP') guess_maker = beluga.guess_generator('auto', start=[80000, 0, 4000, -90 * pi / 180], direction='forward', costate_guess=-0.1) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(11) \ .const('h_f',0) \ .const('theta_f',0.01*pi/180) continuation_steps.add_step('bisection') \ .num_cases(11) \
def test_planarhypersonic(): from math import pi import beluga ocp = beluga.OCP('planarHypersonic') # Define independent variables ocp.independent('t', 's') # Define equations of motion ocp.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 quantities used in the problem ocp.quantity('rho', 'rho0*exp(-h/H)') ocp.quantity('Cl', '(1.5658*alfa + -0.0000)') ocp.quantity('Cd', '(1.6537*alfa^2 + 0.0612)') ocp.quantity('D', '0.5*rho*v^2*Cd*Aref') ocp.quantity('L', '0.5*rho*v^2*Cl*Aref') ocp.quantity('r', 're+h') # Define controls ocp.control('alfa', 'rad') # Define constants ocp.constant('mu', 3.986e5 * 1e9, 'm^3/s^2') # Gravitational parameter, m^3/s^2 ocp.constant('rho0', 0.0001 * 1.2, 'kg/m^3') # Sea-level atmospheric density, kg/m^3 ocp.constant('H', 7500, 'm') # Scale height for atmosphere of Earth, m ocp.constant('mass', 750 / 2.2046226, 'kg') # Mass of vehicle, kg ocp.constant('re', 6378000, 'm') # Radius of planet, m ocp.constant('Aref', pi * (24 * .0254 / 2)**2, 'm^2') # Reference area of vehicle, m^2 ocp.constant('h_0', 80000, 'm') ocp.constant('v_0', 4000, 'm/s') ocp.constant('h_f', 80000, 'm') ocp.constant('theta_f', 0, 'rad') # Define costs ocp.terminal_cost('-v^2', 'm^2/s^2') # Define constraints ocp.constraints() \ .initial('h-h_0', 'm') \ .initial('theta', 'rad') \ .initial('v-v_0', 'm/s') \ .terminal('h-h_f', 'm') \ .terminal('theta-theta_f', 'rad') ocp.scale(m='h', s='h/v', kg='mass', rad=1) bvp_solver = beluga.bvp_algorithm('Shooting', algorithm='SLSQP', tolerance=1e-6) guess_maker = beluga.guess_generator( 'auto', start=[80000, 0, 4000, -90 * pi / 180], direction='forward', costate_guess=-0.1) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(11) \ .const('h_f', 0) \ .const('theta_f', 0.01 * pi / 180) continuation_steps.add_step('bisection') \ .num_cases(11) \ .const('theta_f', 5.0 * pi / 180) continuation_steps.add_step('bisection') \ .num_cases(11) \ .const('rho0', 1.2) sol = beluga.solve(ocp, method='traditional', bvp_algorithm=bvp_solver, steps=continuation_steps, guess_generator=guess_maker) y0 = sol.y[0] yf = sol.y[-1] y0e = [ 8.00000000e+04, 0.00000000e+00, 4.00000000e+03, 1.95069984e-02, -1.68249327e+01, 1.21634197e+06, -2.83598229e+03, -6.15819100e-17 ] yfe = [ 5.23214346e-04, 8.72664626e-02, 2.69147623e+03, -9.38246813e-01, 5.46455659e+02, 1.21634197e+06, -5.38295257e+03, 1.67911185e-01 ] tfe = 144.5678 assert sol.t.shape[0] == sol.y.shape[0] assert sol.t.shape[0] == sol.u.shape[0] assert sol.y.shape[1] == 8 assert sol.u.shape[1] == 1 assert abs((y0[0] - y0e[0]) / y0e[0]) < tol assert abs((y0[1] - y0e[1])) < tol assert abs((y0[2] - y0e[2]) / y0e[2]) < tol assert abs((y0[3] - y0e[3]) / y0e[3]) < tol assert abs((y0[4] - y0e[4]) / y0e[4]) < tol assert abs((y0[5] - y0e[5]) / y0e[5]) < tol assert abs((y0[6] - y0e[6]) / y0e[6]) < tol assert abs((y0[7] - y0e[7])) < tol assert abs((sol.t[-1] - tfe) / tfe) < tol assert abs((yf[0] - yfe[0])) < tol assert abs((yf[1] - yfe[1]) / yfe[1]) < tol assert abs((yf[2] - yfe[2]) / yfe[2]) < tol assert abs((yf[3] - yfe[3]) / yfe[3]) < tol assert abs((yf[4] - yfe[4]) / yfe[4]) < tol assert abs((yf[5] - yfe[5]) / yfe[5]) < tol assert abs((yf[6] - yfe[6]) / yfe[6]) < tol assert abs((yf[7] - yfe[7]) / yfe[7]) < tol
def test_zermelo_custom_functions(): import beluga ocp = beluga.OCP('zermelos_problem') def drift_x(x, y): return 0 def drift_y(x, y): return ((x - 5)**4 - 625) / 625 ocp.custom_function('drift_x', drift_x) ocp.custom_function('drift_y', drift_y) # Define independent variables ocp.independent('t', 's') # Define equations of motion ocp.state('x', 'V*cos(theta) + epsilon*drift_x(x,y)', 'm') \ .state('y', 'V*sin(theta) + epsilon*drift_y(x,y)', 'm') # Define controls ocp.control('theta', 'rad') # Define constants ocp.constant('V', 10, 'm/s') ocp.constant('epsilon', 0.001, '1') ocp.constant('x_f', 0, 'm') ocp.constant('y_f', 0, 'm') # Define costs ocp.path_cost('1', '1') # Define constraints ocp.constraints() \ .initial('x', 'm') \ .initial('y', 'm') \ .terminal('x-x_f', 'm') \ .terminal('y-y_f', 'm') ocp.scale(m='x', s='x/V', rad=1) bvp_solver = beluga.bvp_algorithm('Shooting', derivative_method='fd', tolerance=1e-4, max_error=100, max_iterations=100) guess_maker = beluga.guess_generator('auto', start=[0, 0], control_guess=[0], use_control_guess=True, direction='forward') continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(10) \ .const('x_f', 10) continuation_steps.add_step('bisection') \ .num_cases(10) \ .const('y_f', 10) continuation_steps.add_step('bisection') \ .num_cases(10) \ .const('epsilon', 1) sol = beluga.solve(ocp, method='icrm', bvp_algorithm=bvp_solver, steps=continuation_steps, guess_generator=guess_maker) from beluga.ivpsol import Trajectory assert isinstance(sol, Trajectory)
guess_maker = beluga.guess_generator( 'ones', start=[1.0], # Starting values for states in order costate_guess=0.1, control_guess=[0.35], use_control_guess=True) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(10, 'log') \ .const('eps1', 2e-1) beluga.add_logger(logging_level=logging.DEBUG, display_level=logging.INFO) bvp_solver = beluga.bvp_algorithm('spbvp') beluga.solve(ocp=ocp, method='indirect', optim_options={ 'control_method': 'icrm', 'analytical_jacobian': True }, bvp_algorithm=bvp_solver, steps=continuation_steps, guess_generator=guess_maker, autoscale=False, save='indirect_data.blg') bvp_solver = beluga.bvp_algorithm('Collocation', num_nodes=60)
ocp.terminal_cost('-r^2', 'L') # Define constraints ocp.initial_constraint('r-r_0', 'L') ocp.initial_constraint('theta - theta_0', 'rad') ocp.initial_constraint('v_r - v_r_0', 'L/s') ocp.initial_constraint('v_theta - v_theta_0', 'L/s') ocp.initial_constraint('m - m_0', 'M') ocp.initial_constraint('t', 's') ocp.terminal_constraint('v_r - v_r_f', 'L/s') ocp.terminal_constraint('v_theta - sqrt(mu / r)', 'L/s') ocp.terminal_constraint('t - t_f', 's') ocp.scale(L='r', s='r/v_theta', M='m', rad=1) bvp_solver_shooting = beluga.bvp_algorithm('Shooting', algorithm='Armijo') bvp_solver_collocation = beluga.bvp_algorithm('spbvp') guess_maker = beluga.guess_generator('auto', start=[1, 0, 0, 1, 1], direction='forward', costate_guess=-0.1) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(3) \ .const('v_r_f', 0) continuation_steps.add_step('bisection') \ .num_cases(40) \
def test_planarhypersonic(): from math import pi import beluga ocp = beluga.OCP('planarHypersonic') # Define independent variables ocp.independent('t', 's') # Define equations of motion ocp.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 quantities used in the problem ocp.quantity('rho', 'rho0*exp(-h/H)') ocp.quantity('Cl', '(1.5658*alfa + -0.0000)') ocp.quantity('Cd', '(1.6537*alfa^2 + 0.0612)') ocp.quantity('D', '0.5*rho*v^2*Cd*Aref') ocp.quantity('L', '0.5*rho*v^2*Cl*Aref') ocp.quantity('r', 're+h') # Define controls ocp.control('alfa', 'rad') # Define constants ocp.constant('mu', 3.986e5 * 1e9, 'm^3/s^2') # Gravitational parameter, m^3/s^2 ocp.constant('rho0', 0.0001 * 1.2, 'kg/m^3') # Sea-level atmospheric density, kg/m^3 ocp.constant('H', 7500, 'm') # Scale height for atmosphere of Earth, m ocp.constant('mass', 750 / 2.2046226, 'kg') # Mass of vehicle, kg ocp.constant('re', 6378000, 'm') # Radius of planet, m ocp.constant('Aref', pi * (24 * .0254 / 2) ** 2, 'm^2') # Reference area of vehicle, m^2 # Define costs ocp.terminal_cost('-v^2', 'm^2/s^2') # Define constraints ocp.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') ocp.scale(m='h', s='h/v', kg='mass', rad=1) bvp_solver = beluga.bvp_algorithm('Shooting') guess_maker = beluga.guess_generator('auto', start=[80000, 0, 4000, -90 * pi / 180], direction='forward', costate_guess=-0.1) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(11) \ .terminal('h', 0) \ .terminal('theta', 0.01 * pi / 180) continuation_steps.add_step('bisection') \ .num_cases(11) \ .terminal('theta', 5.0 * pi / 180) continuation_steps.add_step('bisection') \ .num_cases(11) \ .const('rho0', 1.2) sol = beluga.solve(ocp, method='traditional', bvp_algorithm=bvp_solver, steps=continuation_steps, guess_generator=guess_maker) y0 = sol.y[0] yf = sol.y[-1] y0e = [80000, 0, 4000, 0.0195, -16.8243, 1212433.8085, -2836.0620, 0] yfe = [0, 0.0873, 2691.4733, -0.9383, 546.4540, 1212433.8085, -5382.9467, 0.1840] tfe = 144.5677 assert sol.t.shape[0] == sol.y.shape[0] assert sol.t.shape[0] == sol.u.shape[0] assert sol.y.shape[1] == 8 assert sol.u.shape[1] == 1 assert abs((y0[0] - y0e[0]) / y0e[0]) < tol assert abs((y0[1] - y0e[1])) < tol assert abs((y0[2] - y0e[2]) / y0e[2]) < tol assert abs((y0[3] - y0e[3]) / y0e[3]) < tol assert abs((y0[4] - y0e[4]) / y0e[4]) < tol assert abs((y0[5] - y0e[5]) / y0e[5]) < tol assert abs((y0[6] - y0e[6]) / y0e[6]) < tol assert abs((y0[7] - y0e[7])) < tol assert abs((sol.t[-1] - tfe) / tfe) < tol assert abs((yf[0] - yfe[0])) < tol assert abs((yf[1] - yfe[1]) / yfe[1]) < tol assert abs((yf[2] - yfe[2]) / yfe[2]) < tol assert abs((yf[3] - yfe[3]) / yfe[3]) < tol assert abs((yf[4] - yfe[4]) / yfe[4]) < tol assert abs((yf[5] - yfe[5]) / yfe[5]) < tol assert abs((yf[6] - yfe[6]) / yfe[6]) < tol assert abs((yf[7] - yfe[7]) / yfe[7]) < tol
# Define costs ocp.path_cost('1', '1') # Define constraints ocp.constraints() \ .initial('x', 'm') \ .initial('y', 'm') \ .initial('t', 's') \ .terminal('x-x_f', 'm') \ .terminal('y-y_f', 'm') ocp.scale(m='x', s='x/V', rad=1) bvp_solver = beluga.bvp_algorithm( 'Shooting', derivative_method='fd', tolerance=1e-4 ) guess_maker = beluga.guess_generator( 'auto', start=[0, 0], control_guess=[0], use_control_guess=True, direction='forward' ) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(10) \
def test_brachistochrone_shooting(): from math import pi import beluga from beluga.ivpsol import Trajectory from beluga.bvpsol import Solution ocp = beluga.OCP('brachisto') # Define independent variables ocp.independent('t', 's') # Define equations of motion ocp.state('x', 'v*cos(theta)', 'm') \ .state('y', 'v*sin(theta)', 'm') \ .state('v', 'g*sin(theta)', 'm/s') # Define controls ocp.control('theta', 'rad') # Define constants ocp.constant('g', -9.81, 'm/s^2') # Define costs ocp.path_cost('1', '1') # Define constraints ocp.constraints() \ .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') ocp.scale(m='y', s='y/v', kg=1, rad=1) shooting_solver = beluga.bvp_algorithm('Shooting') guess_maker = beluga.guess_generator('auto', start=[0, 0, 0], direction='forward', costate_guess=-0.1, control_guess = [-pi/2], use_control_guess=True) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(21) \ .terminal('x', 10) \ .terminal('y', -10) sol = beluga.solve(ocp, method='icrm', bvp_algorithm=shooting_solver, steps=continuation_steps, guess_generator=guess_maker) assert isinstance(sol, Trajectory) assert isinstance(sol, Solution) assert sol.t.shape[0] == sol.y.shape[0] assert sol.t.shape[0] == sol.u.shape[0] assert sol.y.shape[1] == 7 assert sol.u.shape[1] == 1 y0 = sol.y[0] yf = sol.y[-1] assert abs(y0[0] - 0) < tol assert abs(y0[1] - 0) < tol assert abs(y0[2] - 0) < tol assert abs(y0[3] + 0.0667) < tol assert abs(y0[4] - 0.0255) < tol assert abs(y0[5] + 0.1019) < tol assert abs(sol.t[-1] - 1.8433) < tol assert abs(yf[0] - 10) < tol assert abs(yf[1] + 10) < tol assert abs(yf[2] - 14.0071) < tol assert abs(yf[3] + 0.0667) < tol assert abs(yf[4] - 0.0255) < tol assert abs(yf[5] - 0) < tol assert abs(y0[3] - yf[3]) < tol assert abs(y0[4] - yf[4]) < tol sol = beluga.solve(ocp, method='traditional', bvp_algorithm=shooting_solver, steps=continuation_steps, guess_generator=guess_maker) y0 = sol.y[0] yf = sol.y[-1] assert sol.t.shape[0] == sol.y.shape[0] assert sol.t.shape[0] == sol.u.shape[0] assert sol.y.shape[1] == 6 assert sol.u.shape[1] == 1 assert abs(y0[0] - 0) < tol assert abs(y0[1] - 0) < tol assert abs(y0[2] - 0) < tol assert abs(y0[3] + 0.0667) < tol assert abs(y0[4] - 0.0255) < tol assert abs(y0[5] + 0.1019) < tol assert abs(sol.t[-1] - 1.8433) < tol assert abs(yf[0] - 10) < tol assert abs(yf[1] + 10) < tol assert abs(yf[2] - 14.0071) < tol assert abs(yf[3] + 0.0667) < tol assert abs(yf[4] - 0.0255) < tol assert abs(yf[5] - 0) < tol assert abs(y0[3] - yf[3]) < tol assert abs(y0[4] - yf[4]) < tol
ocp.constraints() \ .initial('x-x_0','m') \ .initial('v-v_0','m/s') \ .terminal('x-x_f','m') \ .terminal('v-v_f','m/s') \ .path('xlim','x - 0.18','<',0.00,'m') \ .independent('tf - 1','s') # Fixed final time (not working for multiarc) ocp.scale(m=1, s=1, kg=1, rad=1, nd=1) # ocp.bvp_solver = algorithms.SingleShooting(derivative_method='fd',tolerance=1e-4, max_iterations=30, verbose = True, cached=False) bvp_solver = beluga.bvp_algorithm('MultipleShooting', derivative_method='fd', tolerance=1e-3, max_iterations=1000, verbose = True, max_error=200 ) guess_maker = beluga.guess_generator('auto', start=[0,.01], # Starting values for states in order direction='forward', costate_guess = -0.1, time_integrate = 1 ## REQUIRED BECAUSE OF FIXED FINAL TIME ) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection', max_divisions=30).num_cases(5) \ .terminal('x',0) \ .initial('v',1) \
'm**2') # Reference area of vehicle, m**2 ocp.constant('rn', 1 / 12 * 0.3048, 'm') # Nose radius, m ocp.constant('h_0', 40000, 'm') ocp.constant('theta_0', 0, 'rad') ocp.constant('v_0', 2000, 'm/s') ocp.constant('gam_0', -(90 - 10) * pi / 180, 'rad') ocp.constant('psi_0', 0, 'rad') ocp.constant('h_f', 0, 'm') ocp.constant('theta_f', 0, 'rad') ocp.constant('phi_f', 0, 'rad') ocp.scale(m='h', s='h/v', kg='mass', rad=1) bvp_solver = beluga.bvp_algorithm('Shooting', derivative_method='fd', tolerance=1e-4, max_iterations=100, max_error=400, algorithm='SLSQP') guess_maker = beluga.guess_generator( 'auto', start=[40000, 0, 0, 2000, -(90 - 10) * pi / 180, 0], direction='forward', costate_guess=-0.1, control_guess=[0.0, 0.0], use_control_guess=True, time_integrate=0.5, ) continuation_steps = beluga.init_continuation()
guess_maker = beluga.guess_generator( 'ones', start=[1.0], # Starting values for states in order costate_guess=0.1, control_guess=[0.35], use_control_guess=True) continuation_steps = beluga.init_continuation() continuation_steps.add_step('bisection') \ .num_cases(10, 'log') \ .const('eps1', 2e-1) beluga.add_logger(file_level=logging.DEBUG, display_level=logging.INFO) bvp_solver = beluga.bvp_algorithm('spbvp') beluga.solve(ocp=ocp, method='indirect', optim_options={ 'control_method': 'differential', 'analytical_jacobian': True }, bvp_algorithm=bvp_solver, steps=continuation_steps, guess_generator=guess_maker, autoscale=False, save_sols='indirect_data.beluga') # bvp_solver = beluga.bvp_algorithm('Collocation', num_nodes=60)
ocp.terminal_cost('-h', '1') # Define constraints ocp.constraints() \ .initial('h - h_0', '1') \ .initial('v - v_0', '1') \ .initial('m - m_0', '1') \ .initial('t', 's') \ .terminal('v - v_f', '1') \ .terminal('m - m_f', '1') ocp.path_constraint('thrust', '1', lower='T_min', upper='T_max', activator='eps', method='epstrig') ocp.scale(m=1, s=1, kg=1, rad=1, nd=1) bvp_solver = beluga.bvp_algorithm('spbvp', algorithm='armijo', num_arcs=4) guess_maker = beluga.guess_generator( 'auto', start=[h_0, v_0, m_0], # Starting values for states in order costate_guess=-0.0001, control_guess=[pi/3], time_integrate=0.1, ) continuation_steps = beluga.init_continuation() continuation_steps.add_step() \ .num_cases(3) \ .const('v_f', 0)