# 6.1. Low-Thrust Trajectories¶

This code allows to design a low-thrust trajectory, starting at a given departure state to reach a specified final state, in a given time-of-flight. The current implementation of low-thrust trajectories does not include gravity assists, so they are referred to as low-thrust trajectory “legs”. Various low-thrust trajectory models have been implemented:

• Direct methods:

They rely on discretisation to turn the problem into a parameter optimisation problem. One of the most commonly used direct method is the so-called Sims-Flanagan method, developed in Sims & Flanagan (2000) (Preliminary Design of Low-Thrust Interplanetary Missions). Direct methods are easy to implement, but are computationally demanding as they require optimisation of a large set of free parameters, and they are found hard to converge without a good initial guess.

• Hybrid methods:

Hybrid methods offer an interesting alternative to direct and indirect methods. Indirect methods are also a common approach to deal with low-thrust trajectory problems. They are based on the optimal control theory (costates) and require an analytical solution of the two-point-boundary problem, to ensure that the boundary and optimality conditions are fulfilled. The inherent complexity of the analytical derivations often leads to the need for simplifying the problem, which limits the accuracy of the solution. Modifying the dynamical model also implies to re-derive the analytical solution. Hybrid methods aim at combining the advantages of both direct and indirect methods, and limiting their drawbacks. The hybrid method developped in Boudestijn (2014) (Development of a low-thrust Earth-centered transfer optimizer for the preliminary mission design phase) and further improved in Jimenez-Lluva (2018) has been implemented in TUDAT.

• Shape-based methods:

Shaping methods assume a certain shape for the low-thrust trajectory, and tune the parameters defining the trajectory shape so that the boundary conditions can be fulfilled. Their main advantage lies in their analytical formulation, which makes them extremely computationnally effective when compared to direct, indirect, or even hybrid methods. This allows for exploring a larger design space, reducing the chances to converge to a local optimum (which is one of the risks of using direct/indirect/hybrid methods). Shape-based methods can thus provide a good preliminary trajectory design. On the other hand, their accuracy is limited, due to the assumed trajectory shape and to the simplified dynamical model required to solve the problem analytically.

The low-thrust trajectory methods currenly available are:

• Shape-based methods

• Hodographic shaping
• Spherical shaping
• Sims-Flanagan method

• Hybrid method

## 6.1.1. Low-Thrust trajectory leg¶

class LowThrustLeg

Base class for low-thrust trajectory leg. This class is defined as follows:

LowThrustLeg( const Eigen::Vector6d& stateAtDeparture,
const Eigen::Vector6d& stateAtArrival,
const double timeOfFlight,
simulation_setup::NamedBodyMap& bodyMap,
const std::string bodyToPropagate,
const std::string centralBody )


where the input parameters are the following ones:

• stateAtDeparture
State of the spacecraft at departure.
• stateAtArrival
State of the spacecraft at arrival.
• timeOfFlight
Time of flight specified for the targeted low-thrust trajectory.
• bodyMap
Map of pointers to Body objects involved in the low-thrust trajectory.
• bodyToPropagate
Name of the spacecraft to be propagated.
• centralBody
Name of the central body of the low-thrust trajectory.

Each class derived from this base class contains the following methods:

• convertTimeToIndependentVariable
Converts current time to the corresponding independent variable value, depending on what kind of low-thrust trajectory model is used.
• convertIndependentVariableToTime
Converts current independent variable value to corresponding time, depending on what kind of low-thrust trajectory model is used.
• computeCurrentThrustAccelerationDirection
Returns direction of the current low-thrust acceleration vector.
• computeCurrentThrustAccelerationMagnitude
Returns magnitude of the current acceleration vector.
• computeCurrentStateVector
Returns current state vector along the low-thrust trajectory.
• getTrajectory
Returns trajectory map (by reference), filled with state history of the spacecraft at a given set of epochs, provided in an input vector.
• computeCurrentMass
Returns current mass of the spacecraft.
• getMassProfile
Returns map (by reference), filled with mass history of the spacecraft, at a given set of epochs provided in an input vector.
• getLowThrustAccelerationModel
Returns the thrust acceleration model corresponding to the designed trajectory.
• retrieveLowThrustAccelerationMap
Returns accelerations map corresponding to the low-thrust trajectory. This includes thrust acceleration and gravitational acceleration exerted by the central body of the trajectory.
• computeCurrentThrust
Returns current thrust vector.
• getThrustProfile
Returns map (by reference) filled with thrust history along the low-thrust trajectory for a set of epochs provided in an input vector.
• computeCurrentThrustAcceleration
Returns current thrust acceleration vector.
• getThrustAccelerationProfile
Returns map (by reference) filled with thrust acceleration history along the low-thrust trajectory for a set of epochs provided in an input vector.
• computeDeltaV
Returns deltaV associated with the low-thrust trajectory.
• computeSemiAnalyticalAndFullPropagation
Computes the analytical or semi-analytical low-thrust trajectory, and propagates the associated fully perturbed problem. The propagation starts at half of the time-of-flight and is performed backward until departure, and forward until arrival. Once the numerical propagation is over, the semi-analytical results are computed for the same set of epochs, to make direct comparison possible and assess the quality of the semi-analytical method. Both full propagation and semi-analytical results maps, as well as the dependent variables history maps are returned by reference.
• createLowThrustPropagatorSettings
Returns pair of appropriate propagator settings for the backward and forward propagations of the fully perturbed problem, to be used as input for the computeSemiAnalyticalAndFullPropagation method described above. This function returns a multi-type propagator settings, including settings to propagate the translational state and the mass of the spacecraft.
• createLowThrustTranslationalStatePropagatorSettings
Returns pair of appropriate translational state propagator settings for the backward and forward propagations of the fully perturbed problem, to be used as input for the computeSemiAnalyticalAndFullPropagation method described above.

## 6.1.2. Setting up a low-thrust trajectory¶

A LowThrustTrajectoryObject can be created using the settings class LowThrustLegSettings, using the function createLowThrustLeg.

createLowThrustLeg(
const std::shared_ptr< LowThrustLegSettings >& lowThrustLegSettings,
const Eigen::Vector6d& stateAtDeparture,
const Eigen::Vector6d& stateAtArrival,
const double& timeOfFlight,
simulation_setup::NamedBodyMap& bodyMap,
const std::string& bodyToPropagate,
const std::string& centralBody )


In addition to the std::shared_ptr< LowThrustLegSettings > object, this function takes as inputs the departure and arrival states, as well as the required time-of-flight, the names of the spacecraft and of the central body of the trajectory, and the body map defining the trajectory environment. Using this createLowThrustLeg function allows the user to switch easily from one trajectory type to another by modifying the std::shared_ptr< LowThrustLegSettings >, while still addressing the same design problem.

class LowThrustLegSettings

This is the base class to create LowThrustTrajectoryObject. The low-thrust trajectory is constructed from the settings classes derived from this base class.

class HodographicShapingLegSettings

This class defines the settings to construct a HodographicShaping object, which will provide a preliminary, hodographically shaped trajectory design. For more details about the hodographic shaping method, the reader is referred to Hodographic shaping). The definition of HodographicShapingLegSettings requires the user to specify the base functions to be used for the trajectory shaping, and the values of the free parameters, if any.

HodographicShapingLegSettings(
const int numberOfRevolutions,
const double centralBodyGravitationalParameter,
std::vector< std::shared_ptr< shape_based_methods::BaseFunctionHodographicShaping > >& radialVelocityFunctionComponents,
std::vector< std::shared_ptr< shape_based_methods::BaseFunctionHodographicShaping > >& normalVelocityFunctionComponents,
std::vector< std::shared_ptr< shape_based_methods::BaseFunctionHodographicShaping > >& axialVelocityFunctionComponents,
const Eigen::VectorXd freeCoefficientsNormalVelocityFunction,
const Eigen::VectorXd freeCoefficientsAxialVelocityFunction )

class SphericalShapingLegSettings

This is the settings class for SphericalShaping object, which provides a spherically shaped trajectory (spherical shaping is described in more details in Spherical shaping). This shaping method has only one parameter whose value is not directly deduced from the satisfaction of departure and arrival boundary conditions. The value of this parameter is tuned until the targeted time-of-flight can be achieved. The SphericalShapingLegSettings settings class thus requires to specify the initial value for this free parameter, along with a rootFinderSettings object, to be used to find the free parameter value which will match the required time-of-flight.

SphericalShapingLegSettings(
const int numberOfRevolutions,
const double centralBodyGravitationalParameter,
const double initialValueFreeCoefficient,
const std::shared_ptr< root_finders::RootFinderSettings >& rootFinderSettings,
const std::pair< double, double > boundsFreeCoefficient = std::make_pair( TUDAT_NAN, TUDAT_NAN ) )

class SimsFlanaganLegSettings

This is the settings class for SimsFlanaganLeg object. Among other inputs, it requires the user to provide the number of segments into which the trajectory is to be subdivided, according to the Sims-Flanagan parametrisation method (more details here Sims-Flanagan Method). An OptimisationSettings object is also to be provided to solve the Sims-Flanagan parametrised optimisation problem.

SimsFlanaganLegSettings(
const double maximumThrust,
std::function< double( const double ) > specificImpulseFunction,
const int numberOfSegments,
const std::string centralBody,
std::shared_ptr< transfer_trajectories::OptimisationSettings > optimisationSettings )

class HybridMethodLegSettings

This class defines the settings to construct a HybridMethodLeg object (more details about the hybrid method can be found in Hybrid Method). Among the different inputs of this settings class, an OptimisationSettings object must be provided to define the way the inherent hybrid method optimisation problem will be tackled.

HybridMethodLegSettings(
const double maximumThrust,
const double specificImpulse,
const std::string centralBody,
std::shared_ptr< numerical_integrators::IntegratorSettings< double > > integratorSettings,
std::shared_ptr< transfer_trajectories::OptimisationSettings > optimisationSettings )


## 6.1.3. Optimising a low-thrust trajectory¶

A pre-defined optimisation problem has been implemented, to allow the user to address a simple trajectory design optimisation problem, with limited coding effort. It tries to identify the best time-of-flight and/or departure date in order to minimize the deltaV required by the trajectory.

The optimisation problem is defined in the class TrajectoryOptimisationProblem, which is implemented so that it is compatible with the PAGMO library.

class TrajectoryOptimisationProblem

This is the low-thrust trajectory optimisation class, defined as follows:

TrajectoryOptimisationProblem(
simulation_setup::NamedBodyMap bodyMap,
const std::string bodyToPropagate,
const std::string centralBody,
std::function< Eigen::Vector6d( const double ) > departureStateFunction,
std::function< Eigen::Vector6d( const double ) > arrivalStateFunction,
std::pair< double, double > departureTimeBounds,
std::pair< double, double > timeOfFlightBounds,
const std::shared_ptr< transfer_trajectories::LowThrustLegSettings >& lowThrustLegSettings )


The input parameters are the following ones:

• bodyMap
Map of pointers to Body objects defining the trajectory environment.
• bodyToPropagate
Name of the spacecraft to be propagated.
• centralBody
Name of the central body of the trajectory.
• departureStateFunction
Function returning the state vector at departure, as a function of the departure date.
• arrivalStateFunction
Function returning the state vector at arrival, as a function of the arrival date (defined as departure date + time-of-flight)
• departureTimeBounds
pair object containing the lower and upper bounds for the departure date of the trajectory.
• timeOfFlightBounds
pair object containing the lower and upper bounds for the time-of-flight of the trajectory.
• LowThrustLegSettings
Settings for the low-thrust trajectory to be designed.

The fitness function creates the relevant LowThrustTrajectoryLeg object out of the provided low-thrust leg settings. It then calculates the corresponding trajectory, and returns the associated deltaV.

The get_bounds function simply returns the time-of-flight and departure bounds which are provided as inputs of the TrajectoryOptimisationProblem constructor.