Source code for RCAIDE.Library.Mission.Segments.Transition.Constant_Acceleration_Constant_Angle_Linear_Climb

# RCAIDE/Library/Missions/Segments/Transition/Constant_Acceleration_Constant_Angle_Linear_Climb.py
# 
# 
# Created:  Jul 2023, M. Clarke 
 
# ----------------------------------------------------------------------------------------------------------------------  
#  Initialize Conditions
# ----------------------------------------------------------------------------------------------------------------------  

import numpy as np

# ----------------------------------------------------------------------------------------------------------------------  
#  Initialize Conditions
# ----------------------------------------------------------------------------------------------------------------------   
[docs] def initialize_conditions(segment): """ Initializes conditions for transition segment with constant acceleration and climb angle Parameters ---------- segment : Segment The mission segment being analyzed - altitude_start : float Initial altitude [m] - altitude_end : float Final altitude [m] - climb_angle : float Fixed climb angle [rad] - air_speed_start : float Initial true airspeed [m/s] - acceleration : float Constant acceleration [m/s^2] - sideslip_angle : float Aircraft sideslip angle [rad] - pitch_initial : float Initial pitch angle [rad] - pitch_final : float Final pitch angle [rad] - state: numerics: dimensionless: control_points : array Discretization points [-] conditions : Data State conditions container initials : Data, optional Initial conditions from previous segment Returns ------- None Updates segment conditions directly: - conditions.freestream.altitude [m] - conditions.frames.inertial.position_vector [m] - conditions.frames.inertial.velocity_vector [m/s] - conditions.frames.body.inertial_rotations [rad] - conditions.frames.inertial.time [s] Notes ----- This function sets up the initial conditions for a transition segment with constant acceleration, constant climb angle, and linear pitch variation. The segment handles the transition between different flight phases while climbing. **Calculation Process** 1. Check required inputs 2. Calculate trajectory geometry: - Ground distance = (alt_f - alt_0)/tan(γ) - True distance = sqrt((alt_f - alt_0)^2 + ground_distance^2) where γ is climb angle 3. Calculate time required: t = (-V0 + sqrt(V0^2 + 2ax))/ax where: - V0 is initial velocity - ax is acceleration 4. Compute velocity components: - vx = V*cos(β)*cos(γ) - vy = V*sin(β)*cos(γ) - vz = V*sin(γ) 5. Linear pitch transition **Major Assumptions** * Constant acceleration * Constant climb angle * Linear pitch variation * Coordinated flight * Small angle approximations See Also -------- RCAIDE.Framework.Mission.Segments """ # unpack alt0 = segment.altitude_start altf = segment.altitude_end climb_angle = segment.climb_angle v0 = segment.air_speed_start beta = segment.sideslip_angle ax = segment.acceleration T0 = segment.pitch_initial Tf = segment.pitch_final t_nondim = segment.state.numerics.dimensionless.control_points conditions = segment.state.conditions # check for climb angle if climb_angle is None: raise AttributeError('set climb') if ax is None: raise AttributeError('set acceleration') # check for initial and final altitude if alt0 is None: if not segment.state.initials: raise AttributeError('altitude not set') alt0 = -1.0 * segment.state.initials.conditions.frames.inertial.position_vector[-1,2] if altf is None: raise AttributeError('final altitude not set') # check for initial pitch if T0 is None: T0 = segment.state.initials.conditions.frames.body.inertial_rotations[-1,1] # check for initial velocity vector if v0 is None: if not segment.state.initials: raise AttributeError('initial airspeed not set') v0 = segment.state.initials.conditions.frames.inertial.velocity_vector[-1,:] segment.velocity_vector = v0 elif len(np.shape(v0)) == 0: v0 = np.array([v0, 0, 0]) # discretize on altitude v0_mag = np.linalg.norm(v0) alt = t_nondim * (altf-alt0) + alt0 ground_distance = (altf-alt0)/np.tan(climb_angle) true_distance = np.sqrt((altf-alt0)**2 + ground_distance**2) t_initial = conditions.frames.inertial.time[0,0] elapsed_time = (-v0_mag + np.sqrt(v0_mag**2 + 2*ax*true_distance))/(ax) vf_mag = v0_mag + ax*(elapsed_time) # dimensionalize time t_final = t_initial + elapsed_time t_nondim = segment.state.numerics.dimensionless.control_points time = t_nondim * (t_final-t_initial) # Figure out vx V = (vf_mag-v0_mag) vx = t_nondim * V * np.cos(beta) * np.cos(climb_angle) + v0[0] * np.cos(climb_angle) vy = t_nondim * V * np.sin(beta) * np.cos(climb_angle) + v0[1] * np.cos(climb_angle) vz = t_nondim * V * np.sin(climb_angle) + v0[2] * np.sin(climb_angle) # set the body angle body_angle = time*(Tf-T0)/(t_final-t_initial) + T0 segment.state.conditions.frames.body.inertial_rotations[:,1] = body_angle[:,0] # pack segment.state.conditions.freestream.altitude[:,0] = alt[:,0] segment.state.conditions.frames.inertial.position_vector[:,2] = -alt[:,0] # z points down segment.state.conditions.frames.inertial.velocity_vector[:,0] = vx[:,0] segment.state.conditions.frames.inertial.velocity_vector[:,1] = vy[:,0] segment.state.conditions.frames.inertial.velocity_vector[:,2] = -vz[:,0] segment.state.conditions.frames.inertial.time[:,0] = time[:,0]