Source code for RCAIDE.Library.Mission.Common.Residuals.flight_dynamics
# RCAIDE/Library/Missions/Common/Residuals/flight_dynamics.py
#
#
# Created: Jul 2023, M. Clarke
# ----------------------------------------------------------------------------------------------------------------------
# IMPORT
# ----------------------------------------------------------------------------------------------------------------------
import RCAIDE
import numpy as np
from RCAIDE.Framework.Core import orientation_product, orientation_transpose
# ----------------------------------------------------------------------------------------------------------------------
# Residual Total Forces
# ----------------------------------------------------------------------------------------------------------------------
[docs]
def flight_dynamics(segment):
"""
Evaluates flight dynamics residuals for mission segment analysis.
Parameters
----------
segment : Segment
The mission segment being analyzed
- state : Data
Contains conditions, numerics, and residuals
- analyses : Data
Contains vehicle analysis objects
- flight_dynamics : Data
Contains flags for which equations to evaluate
Returns
-------
None
Updates segment residuals directly in segment.state.residuals
Notes
-----
This function calculates the residuals for force and moment equations
in all three axes. It handles special cases for transition and ground
segments, including acceleration calculations and final velocity constraints.
The function processes:
1. Force equation residuals (F = ma)
2. Moment equation residuals (M = Iα)
3. Special handling for transition and ground segments
**Required Segment State Variables**
state.conditions.frames.inertial:
- velocity_vector : array
Vehicle velocity [m/s]
- acceleration_vector : array
Vehicle acceleration [m/s²]
- total_force_vector : array
Net forces [N]
- total_moment_vector : array
Net moments [N⋅m]
- angular_velocity_vector : array
Angular rates [rad/s]
- angular_acceleration_vector : array
Angular accelerations [rad/s²]
state.conditions.weights:
- mass.total : array
Vehicle mass [kg]
analyses.vehicle.mass_properties:
- moments_of_inertia.tensor : array
Inertia tensor [kg⋅m²]
**Segment Types**
Special handling for:
- Ground segments
* Takeoff
* Landing
* Ground operations
**Major Assumptions**
* Rigid body dynamics
* Principal axes aligned with body axes
* Constant inertia properties during segment
* Valid mass properties
* Non-zero final velocity for ground segments (minimum 0.01 m/s)
**Theory**
Force equations (Newton's Second Law):
.. math::
\\frac{F_i}{m} - a_i = 0
Moment equations:
.. math::
\\frac{M_i}{I_{ii}} - \\alpha_i = 0
where :math:`i` represents each axis (x, y, z), :math:`F` is force,
:math:`a` is acceleration, :math:`M` is moment, :math:`I` is moment of inertia,
and :math:`\\alpha` is angular acceleration.
See Also
--------
RCAIDE.Framework.Mission.Segments
RCAIDE.Framework.Mission.Segments.Ground
"""
T_wind2inertial = segment.state.conditions.frames.wind.transform_to_inertial
T_inertia2wind = orientation_transpose(T_wind2inertial)
transition_seg_flag = type(segment) == RCAIDE.Framework.Mission.Segments.Climb.Constant_Acceleration_Constant_Pitchrate_Constant_Angle
ground_seg_flag = (type(segment) == RCAIDE.Framework.Mission.Segments.Ground.Landing) or\
(type(segment) == RCAIDE.Framework.Mission.Segments.Ground.Takeoff) or \
(type(segment) == RCAIDE.Framework.Mission.Segments.Ground.Ground)
if transition_seg_flag or ground_seg_flag:
v = segment.state.conditions.frames.inertial.velocity_vector
D = segment.state.numerics.time.differentiate
segment.state.conditions.frames.inertial.acceleration_vector = np.dot(D,v)
FT_i = segment.state.conditions.frames.inertial.total_force_vector
a_i = segment.state.conditions.frames.inertial.acceleration_vector
FT_w = segment.state.conditions.frames.wind.total_force_vector
a_w = orientation_product(T_inertia2wind,a_i )
if transition_seg_flag:
omega = segment.state.conditions.frames.inertial.angular_velocity_vector
D = segment.state.numerics.time.differentiate
ang_acc_i = np.dot(D,omega)
segment.state.conditions.frames.inertial.angular_acceleration_vector = ang_acc_i
segment.state.conditions.frames.wind.angular_acceleration_vector = orientation_product(T_inertia2wind,ang_acc_i )
ang_acc_i = segment.state.conditions.frames.inertial.angular_acceleration_vector
MT_w = segment.state.conditions.frames.wind.total_moment_vector
ang_acc_w = segment.state.conditions.frames.wind.angular_acceleration_vector
m = segment.state.conditions.weights.vehicle.mass
MOI_Ixx = segment.state.conditions.weights.vehicle.moments_of_inertia_Ixx
MOI_Iyy = segment.state.conditions.weights.vehicle.moments_of_inertia_Iyy
MOI_Izz = segment.state.conditions.weights.vehicle.moments_of_inertia_Izz
if ground_seg_flag:
vf = segment.velocity_end
if vf == 0.0: vf = 0.01
segment.state.residuals.force_x[:,0] = FT_i[1:,0]/m[1:,0] - a_i[1:,0]
segment.state.residuals.final_velocity_error = (v[-1,0] - vf)
else:
if segment.flight_dynamics.force_x:
segment.state.residuals.force_x[:,0] = FT_w[:,0]/m[:,0] - a_w[:,0]
if segment.flight_dynamics.force_y:
segment.state.residuals.force_y[:,0] = FT_w[:,1]/m[:,0] - a_w[:,1]
if segment.flight_dynamics.force_z:
segment.state.residuals.force_z[:,0] = FT_w[:,2]/m[:,0] - a_w[:,2]
if segment.flight_dynamics.moment_x:
segment.state.residuals.moment_x[:,0] = MT_w[:,0]/MOI_Ixx[:,0] - ang_acc_w[:,0]
if segment.flight_dynamics.moment_y:
segment.state.residuals.moment_y[:,0] = MT_w[:,1]/MOI_Iyy[:,0] - ang_acc_w[:,1]
if segment.flight_dynamics.moment_z:
segment.state.residuals.moment_z[:,0] = MT_w[:,2]/MOI_Izz[:,0] - ang_acc_w[:,2]
return