Source code for RCAIDE.Library.Mission.Segments.Climb.Constant_Throttle_Constant_Speed

# RCAIDE/Library/Missions/Segments/Climb/Constant_Throttle_Constant_Speed.py
# 
# 
# Created:  Jul 2023, M. Clarke

# ----------------------------------------------------------------------------------------------------------------------
#  IMPORT
# ---------------------------------------------------------------------------------------------------------------------- 

# Package imports  
import numpy as np
 
# ----------------------------------------------------------------------------------------------------------------------
#  Initialize Conditions
# ----------------------------------------------------------------------------------------------------------------------
[docs] def unpack_body_angle(segment): """ Unpacks and sets the proper value for body angle Parameters ---------- segment : Segment The mission segment being analyzed Notes ----- This function handles the initialization of the body angle for a climb segment with constant throttle and constant speed. **Required Segment Components** segment: state: unknowns: body_angle : array Aircraft body angle [rad] conditions: frames: body: transform_to_inertial : array Rotation matrix from body to inertial frame Returns ------- None Updates segment conditions directly: - conditions.frames.body.transform_to_inertial """ ctrls = segment.assigned_control_variables # Body Angle Control if ctrls.body_angle.active: segment.state.conditions.frames.body.inertial_rotations[:,1] = segment.state.unknowns.body_angle[:,0] else: segment.state.conditions.frames.body.inertial_rotations[:,1] = segment.angle_of_attack if ctrls.bank_angle.active: segment.state.conditions.frames.body.inertial_rotations[:,0] = segment.state.unknowns.bank_angle[:,0] else: segment.state.conditions.frames.body.inertial_rotations[:,0] = segment.bank_angle segment.state.conditions.frames.body.inertial_rotations[:,2] = segment.state.conditions.frames.planet.true_heading[:,0]
# ---------------------------------------------------------------------- # Initialize Conditions # ----------------------------------------------------------------------
[docs] def initialize_conditions(segment): """Sets the specified conditions which are given for the segment type. Assumptions: Constant throttle estting, with a constant true airspeed Source: N/A Inputs: segment.air_speed [meters/second] segment.altitude_start [meters] segment.altitude_end [meters] segment.state.numerics.dimensionless.control_points [Unitless] conditions.freestream.density [kilograms/meter^3] Outputs: conditions.frames.inertial.velocity_vector [meters/second] Properties Used: N/A """ # unpack alt0 = segment.altitude_start v_mag = segment.air_speed beta = segment.sideslip_angle alpha = segment.state.unknowns.wind_angle[:,0][:,None] theta = segment.state.unknowns.body_angle[:,0][:,None] conditions = segment.state.conditions # check for initial altitude if alt0 is None: if not segment.state.initials: raise AttributeError('initial altitude not set') alt0 = -1.0 *segment.state.initials.conditions.frames.inertial.position_vector[-1,2] # Flight path angle gamma = theta-alpha # process v_x = np.cos(beta) *v_mag * np.cos(gamma) v_y = np.sin(beta) *v_mag * np.cos(gamma) v_z = -v_mag * np.sin(gamma) # z points down # pack conditions.frames.inertial.velocity_vector[:,0] = v_x[:,0] conditions.frames.inertial.velocity_vector[:,1] = v_y[:,0] conditions.frames.inertial.velocity_vector[:,2] = v_z[:,0]
[docs] def update_differentials_altitude(segment): """On each iteration creates the differentials and integration funcitons from knowns about the problem. Sets the time at each point. Must return in dimensional time, with t[0] = 0 Assumptions: Constant throttle setting, with a constant true airspeed. Source: N/A Inputs: segment.climb_angle [radians] state.conditions.frames.inertial.velocity_vector [meter/second] segment.altitude_start [meters] segment.altitude_end [meters] Outputs: state.conditions.frames.inertial.time [seconds] conditions.frames.inertial.position_vector [meters] conditions.freestream.altitude [meters] Properties Used: N/A """ # unpack t = segment.state.numerics.dimensionless.control_points I = segment.state.numerics.dimensionless.integrate # Unpack segment initials alt0 = segment.altitude_start altf = segment.altitude_end conditions = segment.state.conditions v = segment.state.conditions.frames.inertial.velocity_vector # check for initial altitude if alt0 is None: if not segment.state.initials: raise AttributeError('initial altitude not set') alt0 = -1.0 *segment.state.initials.conditions.frames.inertial.position_vector[-1,2] # get overall time step vz = -v[:,2,None] # Inertial velocity is z down dz = altf- alt0 dt = dz / np.dot(I[-1,:],vz)[-1] # maintain column array # Integrate vz to get altitudes alt = alt0 + np.dot(I*dt,vz) # rescale operators t = t * dt # pack t_initial = segment.state.conditions.frames.inertial.time[0,0] segment.state.conditions.frames.inertial.time[:,0] = t_initial + t[:,0] conditions.frames.inertial.position_vector[:,2] = -alt[:,0] # z points down conditions.freestream.altitude[:,0] = alt[:,0] # positive altitude in this context return
# ---------------------------------------------------------------------- # Update Velocity Vector from Wind Angle # ----------------------------------------------------------------------
[docs] def update_velocity_vector_from_wind_angle(segment): # unpack conditions = segment.state.conditions v_mag = segment.air_speed beta = segment.sideslip_angle alpha = segment.state.unknowns.wind_angle[:,0][:,None] theta = segment.state.unknowns.body_angle[:,0][:,None] # Flight path angle gamma = theta-alpha # process v_x = np.cos(beta) *v_mag * np.cos(gamma) v_y = np.sin(beta) *v_mag * np.cos(gamma) v_z = -v_mag * np.sin(gamma) # z points down # pack conditions.frames.inertial.velocity_vector[:,0] = v_x[:,0] conditions.frames.inertial.velocity_vector[:,1] = v_y[:,0] conditions.frames.inertial.velocity_vector[:,2] = v_z[:,0] return conditions