3. Un-guided Capsule Entry

The example described on this page is that of Apollo on a re-entry trajectory towards the surface of Earth. The code for this tutorial is given here on Github, and is also located in your tudat bundle at:

tudatBundle/tudatExampleApplications/satellitePropagatorExamples/SatellitePropagatorExamples/apolloCapsuleEntry.cpp

For this example, we have the following problem statement:

Given the position and velocity of the Apollo capsule at a certain point in time with respect to the Earth, what will its position and velocity be once it reaches an altitude of 25 km over the surface of Earth?

Warning

The example described in this page assumes that the user has read the Unperturbed Earth-orbiting Satellite. This page only describes the differences with respect to such example, so please go back before proceeding.

3.1. Create the vehicle

First, the vehicle is created by placing an "Apollo" entry vehicle in the bodyMap, as shown below:

// Create vehicle objects.
bodyMap[ "Apollo" ] = boost::make_shared< simulation_setup::Body >( );

Once that is done, an AerodynamicCoefficientInterface is linked to the vehicle by means of the following command:

// Create vehicle aerodynamic coefficients
bodyMap[ "Apollo" ]->setAerodynamicCoefficientInterface(
            unit_tests::getApolloCoefficientInterface( ) );

In this example a pre-made interface is used to define the aerodynamic coefficients. The getApolloCoefficientInterface( ) function returns a HypersonicLocalInclinationAnalysis object, which is a derived-class from AerodynamicCoefficientInterface. It computes the aerodynamic coefficients during propagation by means of a local-inclination method. Finally, the mass of the Apollo capsule is set and the body creation is finalized:

bodyMap[ "Apollo" ]->setConstantBodyMass( 5.0E3 );

// Finalize body creation.
setGlobalFrameBodyEphemerides( bodyMap, "SSB", "J2000" );

Tip

If you want to include a different vehicle, you will have to define a new AerodynamicCoefficientInterface and implement your own custom aerodynamic database. Please go to Aerodynamic Guidance for further details.

3.2. Set up the acceleration models

A major difference with respect to the Unperturbed Earth-orbiting Satellite is the use of a spherical-harmonic gravity model and the presence of an aerodynamic force on the vehicle. The spherical-harmonic gravity model is selected by the derived-class SphericalHarmonicAccelerationSettings with degree and order as input parameters. Both acceleration models are added to the accelerationMap as follows:

// Define acceleration model settings.
std::map< std::string, std::vector< boost::shared_ptr< AccelerationSettings > > > accelerationsOfApollo;
accelerationsOfApollo[ "Earth" ].push_back( boost::make_shared< SphericalHarmonicAccelerationSettings >( 4, 0 ) );
accelerationsOfApollo[ "Earth" ].push_back( boost::make_shared< AccelerationSettings >( aerodynamic ) );
accelerationMap[  "Apollo" ] = accelerationsOfApollo;

A crucial step in re-entry modelling is the definition of a AerodynamicGuidance model. Controlling the orientation of the vehicle during atmospheric flight plays an important role in the shape of the trajectory as well as on the magnitude of the aerodynamic and thermal loads. In this example, a simple fixed-angle aerodynamic guidance model is used. This is implemented using a boost::lambda::constant function (explained in detail here). In short this function always outputs the value of constantAngleOfAttack which in turn sets the orientation angles of the "Apollo" body:

// Define constant 30 degree angle of attack
double constantAngleOfAttack = unit_conversions::convertDegreesToRadians(30.0);
bodyMap.at( "Apollo" )->getFlightConditions( )->getAerodynamicAngleCalculator( )->setOrientationAngleFunctions(
            boost::lambda::constant( constantAngleOfAttack ) );

Tip

To view the available options for aerodynamic guidance check out the Aerodynamic Guidance section.

3.3. Set up the propagation settings

In most re-entry studies, it is convenient to define the entry conditions using a spherical state. The following entry state is used:

  • Altitude: 120 km
  • Latitude: 0 deg
  • Longitude: 68.75 deg
  • Inertial speed: 7.7 km/s
  • Flight-path angle: -0.9 deg
  • Heading angle: 34.37 deg

Such state must is defined and converted to Cartesian state variables as follows:

// Set spherical elements for Apollo.
Eigen::Vector6d apolloSphericalEntryState;
apolloSphericalEntryState( SphericalOrbitalStateElementIndices::radiusIndex ) =
        spice_interface::getAverageRadius( "Earth" ) + 120.0E3;
apolloSphericalEntryState( SphericalOrbitalStateElementIndices::latitudeIndex ) =
        unit_conversions::convertDegreesToRadians( 0.0 );
apolloSphericalEntryState( SphericalOrbitalStateElementIndices::longitudeIndex ) =
        unit_conversions::convertDegreesToRadians( 68.75 );
apolloSphericalEntryState( SphericalOrbitalStateElementIndices::speedIndex ) = 7.7E3;
apolloSphericalEntryState( SphericalOrbitalStateElementIndices::flightPathIndex ) =
        unit_conversions::convertDegreesToRadians( -0.9 );
apolloSphericalEntryState( SphericalOrbitalStateElementIndices::headingAngleIndex ) =
        unit_conversions::convertDegreesToRadians( 34.37 );

// Convert apollo state from spherical elements to Cartesian elements.
Eigen::Vector6d systemInitialState = convertSphericalOrbitalToCartesianState(
            apolloSphericalEntryState );

Note

Note that speed defined in the speedIndex makes reference to the inertial speed of the vehicle. Furthermore, the latitudeIndex makes reference to the geocentric latitude.

3.3.1. Create a list of dependent variables to save

In this example, a number of dependent variables are saved to plot the trajectory of Apollo after re-entry. The following dependent variables are saved:

  • Mach number
  • Altitude
  • Aerodynamic acceleration norm
  • Aerodynamic force coefficients (CD, CS, CL)

First, a dependentVariablesList needs to be created, which will list all the variables to save:

// Define list of dependent variables to save.
std::vector< boost::shared_ptr< SingleDependentVariableSaveSettings > > dependentVariablesList;

Next, the list is populated with the desired dependent variables. Please go to Propagator Settings: Dependent Variables for further details on the various dependent variables that can be stored:

dependentVariablesList.push_back(
            boost::make_shared< SingleDependentVariableSaveSettings >( mach_number_dependent_variable, "Apollo" ) );
dependentVariablesList.push_back(
            boost::make_shared< SingleDependentVariableSaveSettings >(
                altitude_dependent_variable, "Apollo", "Earth" ) );
dependentVariablesList.push_back(
            boost::make_shared< SingleAccelerationDependentVariableSaveSettings >(
                aerodynamic, "Apollo", "Earth", 1 ) );
dependentVariablesList.push_back(
            boost::make_shared< SingleDependentVariableSaveSettings >(
                aerodynamic_force_coefficients_dependent_variable, "Apollo" ) );

// Create object with list of dependent variables
boost::shared_ptr< DependentVariableSaveSettings > dependentVariablesToSave =
        boost::make_shared< DependentVariableSaveSettings >( dependentVariablesList );

3.3.2. Define the termination conditions

Finally, the termination conditions are established. The termination settings are stored in the PropagationTerminationSettings object. In this example, the re-entry trajectory is propagated until Apollo’s altitude drops below 25 km. The boolean in the constructor of the derived-class PropagationDependentVariableTerminationSettings indicates whether the simulation is terminated when terminationDependentVariable goes below the supplied value (true) or above (false):

// Define termination conditions
boost::shared_ptr< SingleDependentVariableSaveSettings > terminationDependentVariable =
        boost::make_shared< SingleDependentVariableSaveSettings >(
            altitude_dependent_variable, "Apollo", "Earth" );
boost::shared_ptr< PropagationTerminationSettings > terminationSettings =
        boost::make_shared< PropagationDependentVariableTerminationSettings >(
            terminationDependentVariable, 25.0E3, true );

Tip

Please go to Propagator Settings: Termination Settings for a detailed description of the available termination conditions.

3.4. Results

Below the history of some of the saved parameters is shown. One can see the capsule skipping several times before it’s final descent into the atmosphere until reaching 25km altitude. The dependent variable history can be obtained in Tudat from the getDependentVariableHistory function inside the DynamicsSimulator class. The resulting std::map can be saved as discussed in Input/Output.

../../_images/apolloResults.png

Tip

Open the figure in a new tab for more detail.