Skip to content

andreabellome/astra

Repository files navigation

ASTRA

ASTRA (Automatic Swing-by TRAjectories) is a MATLAB-based toolbox for optimally building multi-gravity assist (MGA) trajectories. This has been built as a result of Andrea Bellome's Ph.D. thesis [1]. ASTRA is based on Dynamic Programming (DP) to optimize MGA trajectories, both in single-objective (SODP) and multi-objective (MODP).

To cite this folder please use the references [1] and [2].

Installation & Requirements

To work with ASTRA, one can simply clone the repository in the local machine:

git clone "https://github.com/andreabellome/astra"

To run a full exploration of MGA trajectories, the following system requirements are recommended:

  • CPU six-core from 2.6 GHz to 3.6 GHz
  • RAM minimum 16 GB
  • Any version of MATLAB>2021b
  • A compiler for C functions should be used. You can use the minGW

Lighter requirements will be required in future releases, as ASTRA will be able to optimize one launch year at a time, and even one date at a time. The price will be the computational time.

Usage and test cases

To use the repository, one finds different test scripts. These are listed here:

  1. Test script 1: st1_astra_main.m, to optimize MGA missions. Refer to this section.
  2. Test script 2: st2_astra_main_saturn_system.m, to optimize MGA missions using custom constraints and different planetary systems. Refer to this section.
  3. Test scripts 3-4: st2_astra_main_uranus_system.m and st21_astra_main_uranus_system_long_chain.m, to optimize MGA missions using custom constraints and Uranus planetary systems.
  4. Test script 5: low_thrust_trajectories.m. This contains a number of test cases for low-thrust trajectories. Please, refer to this section.
  5. Test script 6: astra_with_custom_eph_mice.m. This script shows how to include custom ephemerides, including high-precision .bsp file integrating with NASA SPICE toolkit. Refer to this section.

Test script 1: Run DP optimization with ASTRA

This script allows to optimize ASTRA using both SODP (single-objective dynamic programming) and MODP (multi-objective dynamic programming). This section provides a breakdown of the minimal input parameters needed.

The following script is used to add ASTRA and to build mex functions (namely the Lambert solver and the defects function).

clearDeleteAdd;

Then one proceeds to select appropriate input parameters.

%% --> input section

% --> clear INPUT and define new ones
try clear INPUT; catch; end; clc;

% --> sequence to be optimized
INPUT.idcentral = 1; 
seq = [ 3 2 3 3 5 ]; res = [ 2 1 3 ];

%%%%%%%%%% multi-rev. options %%%%%%%%%%
maxrev                        = 0;                                         % --> max. number of revolutions (round number)
chosenRevs                    = differentRuns_v2(seq, maxrev);             % --> generate successive runs
[INPUT.chosenRevs, INPUT.res] = processResonances(chosenRevs, res);        % --> process the resonances options
[INPUT.chosenRevs]            = maxRevOuterPlanets(seq, INPUT.chosenRevs); % --> only zero revs. on outer planets
%%%%%%%%%% multi-rev. options %%%%%%%%%%

%%%%%%%%%% set departing options %%%%%%%%%%
t0 = date2mjd2000([2023 1 1 0 0 0]); % --> initial date range (MJD2000)
tf = t0 + 1*365.25;                  % --> final date range (MJD2000)
dt = 2.5;                              % --> step size (days)
INPUT.depOpts = [t0 tf dt];
%%%%%%%%%% set departing options %%%%%%%%%%

%%%%%%%%%% set options %%%%%%%%%%
INPUT.opt      = 2;          % --> (1) is for SODP, (2) is for MODP, (3) is for DATES, (4) is for YEARS - MODP
INPUT.vInfOpts = [3 5];      % --> min/max departing infinity velocities (km/s)
INPUT.dsmOpts  = [1 Inf];    % --> max defect DSM, and total DSMs (km/s)
INPUT.plot     = [0 0];      % --> plot(1) for Pareto front, plot(2) for best traj. DV
INPUT.parallel = true;       % --> put true for parallel, false otherwise
INPUT.tstep    = dt;         % --> step size for Time of flight            
%%%%%%%%%% set options %%%%%%%%%%

Things to notice are:

  • INPUT.idcentral allows to select the system. In this example, INPUT.idcentral = 1 means that Solar System is selected. Other options are: 5 for Jupiter system, 6 for Saturn system and 7 for Uranus system. See also constants.m for knowing about the IDs of the bodies.
  • maxRevOuterPlanets will prune options with more than one rev. on legs towards outer planets (i.e., from Jupiter on). This to prevent the mission duration to increase a lot.
  • res is a list of integers with [ N, M, LEG_ID ], where N and M are the object and spacecraft revolutions, respectively, and LEG_ID is the number of the leg at which the resonance is.
  • INPUT.opt selects the type of optimization.
    • 1 is for SODP
    • 2 is for MODP
    • 3 is for SODP run each launch date.
    • 4 is for MODP run each launch year. If the user selects a launch window greater or equal than 3 year AND INPUT.opt=2, this option is selected automatically. This allows to reduce the computational burden in terms of RAM.

The options defined above allow for an MGA trajectory search of Earth-Venus-Earth-Earth-Jupiter mission in year 2023 using MODP (INPUT.opt=2). There is a specified 2:1 resonance on the Earth-Earth leg, i.e., res = [2 1 3].

ASTRA main engine can then be run using:

%% --> optimize using ASTRA

% --> launch ASTRA optimization
OUTPUT = ASTRA_DP(seq, INPUT);

Results are saved in a structure called OUTPUT.

If needed, one can then post-process the results, extracting the desired trajectory from the Pareto front, plotting the Pareto front itself and the selected path.

%% --> extract desired path and plot

close all; clc;

% --> extract path from Pareto front
[path, revs, res] = pathfromPF(OUTPUT);

% --> plot the Pareto front
figPareto = plotPareto(OUTPUT(1).ovPF);

% --> plot the path
[figECI, STRUC, figSYN, figRSC, figVSC] = plotPath(path, INPUT.idcentral);

% --> save the output
generateOutputTXT(path, INPUT.idcentral, './results');

The plot of the Pareto front is the following:

Pareto-front

The plot of the optimal trajectory in inertial and Earth-Sun synodic frame is the following:

fig-eci fig-syn

The function plotPath.m also allows to plot the evolutions of spacecraft distance and velocity with respect to central body:

fig-rr fig-vv

The function generateOutputTXT.m creates a .txt file in a folder called ./results that has all the info of the trajectory. This is reported here:


          _/_/_/     _/_/_/  _/_/_/_/_/  _/_/_/    _/_/_/ 
        _/    _/   _/           _/     _/    _/  _/    _/ 
       _/_/_/_/     _/_/       _/     _/_/_/    _/_/_/_/  
      _/    _/         _/     _/     _/    _/  _/    _/   
     _/    _/    _/_/_/      _/     _/    _/  _/    _/    


               - ASTRA solution - 

-------------------------------------------------------------- 

Departing body                 : Earth  
Distance from the central body : 1.0000 AU 

-------------------------------------------------------------- 

Arrival body                   : Jupiter
Distance from the central body : 5.2026 AU 
Departing C3                   : 11.1821 km^2/s^2 
Departing infinity velocity    : 3.3440 km/s 
Arrival infinity velocity      : 5.5560 km/s 
Total cost (DSMs)              : 0.2297 km/s 
Total cost                     : 9.1297 km/s 
Time of flight                 : 6.5995 years 

-------------------------------------------------------------- 

MGA Details : 

Swing-by sequence      : -E--V--E--E--J-

Departing date         : [2023   6   5   0   0   0]
Arrival date           : [2030   1   9  11  32  29]
Time of flight per leg : 175 days 
                         325 days 
                         730.4809 days 
                         1180 days 

DSMs magnitudes        : 0 km/s 
                         0 km/s 
                         0.0025302 km/s 
                         0 km/s 
                         0.22717 km/s 

Infinity velocities    : 
Earth   - Venus        : 3.344 - 5.5398 km/s 
Venus   - Earth        : 5.5423 - 9.3649 km/s 
Earth   - Earth        : 9.3649 - 9.3667 km/s 
Earth   - Jupiter      : 9.5899 - 5.556 km/s 

State at departure/arrival (km and km/s) : 
Earth                         : [-41536210.28622      -145973470.626                   0      25.22061812303     -7.815385638442     -1.511901456476]  
Venus                         : [-68483058.5096      82679154.4959      5068735.73872     -31.9673430837     -19.9046273943      1.44904973131]  

Venus                         : [-68483058.5096      82679154.4959      5068735.73872     -31.8207835326     -24.8436384232    -0.473867544232]  
Earth                         : [136074658.5919      60926320.94723                   0     -20.73484901584      22.55369065354      1.423799578027]  

Earth                         : [136074658.5919      60926320.94723                   0     -21.90609082435      27.19379108781      1.468331664356]  
Earth                         : [136074658.5919      60926320.94723                   0     -21.90609082435      27.19379108781      1.468331664356]  

Earth                         : [136074658.5919      60926320.94723                   0     -19.36823020848      33.54168925672     -2.256209104279]  
Jupiter                       : [-590948699.8079     -555350715.9192      15543181.54531      5.830113194957     -4.241447010639     0.3662016507624]  

Encounter dates        : 
Earth                  : [2023   6   5   0   0   0]
Venus                  : [2023  11  27   0   0   0]
Earth                  : [2024  10  17   0   0   0]
Earth                  : [2026  10  17  11  32  29]
Jupiter                : [2030   1   9  11  32  29]

Transfer types         : 
Earth   - Venus        : outbound - outbound 
Venus   - Earth        : outbound - inbound 
Earth   - Earth        : inbound - inbound 
Earth   - Jupiter      : inbound - inbound 

-------------------------------------------------------------- 

Finally, one can further refine the solution around a specified trajectory, to further reduce the defects that might arise:

%% --> futher refine around the optimal DV-solution

INPUT.t0days  = 10;   % --> days around current solution departing epoch
INPUT.tofdays = 15;   % --> days around current solution TOFs
INPUT.dt      = 0.5;  % --> step size (days)
INPUT.revs    = revs;
INPUT.res     = res;

% --> further refine using ASTRA
OUTPUTref = refineUsingASTRApath(path, INPUT);

Test script 2: Run DP optimization with ASTRA using custom constraints

If one wants to set up specific constraints for a custom optimization scenario, it can write as follows:

% --> specify custom bounds for TOFs and VINFs
INPUT.TOF_LIM = [[30 60]; [20 40]; [20 40]];
% INPUT.vInfLim = [ [0 XXX]; [0 XXX]; [0 XXX]; [0 XXX]; [0 XXX]];   % --> PL1, PL2, PL3, ...   

where the matrix INPUT.TOF_LIM refers to lower and upper bounds for TOFs per MGA leg, while the matrix INPUT.vInfLim refers to lower and upper bounds for infinity velocity at each fly-by body.

With the current setup:

%% --> input section

% --> clear INPUT and define new ones
try clear INPUT; catch; end; clc;

% --> sequence to be optimized
INPUT.idcentral = 6; % --> central body (Sun in this case)
seq = [ 5 4 4 3 ]; res = [ 13 7 2 ];

%%%%%%%%%% multi-rev. options %%%%%%%%%%
maxrev                        = 3;                                                          % --> max. number of revolutions (round number)
chosenRevs                    = differentRuns_v2(seq, maxrev);                              % --> generate successive runs
[INPUT.chosenRevs, INPUT.res] = processResonances(chosenRevs, res);                         % --> process the resonances options
[INPUT.chosenRevs]            = maxRevOuterPlanets(seq, INPUT.chosenRevs, INPUT.idcentral); % --> only zero revs. on outer planets
%%%%%%%%%% multi-rev. options %%%%%%%%%%

%%%%%%%%%% set departing options %%%%%%%%%%
t0 = date2mjd2000([2023 1 1 0 0 0]); % --> initial date range (MJD2000)
tf = t0 + 0.5*365.25;                  % --> final date range (MJD2000)
dt = 0.1;                            % --> step size (days)
INPUT.depOpts = [t0 tf dt];
%%%%%%%%%% set departing options %%%%%%%%%%

%%%%%%%%%% set options %%%%%%%%%%
INPUT.opt      = 2;          % --> (1) is for SODP, (2) is for MODP, (3) is for DATES, (4) is for YEARS - MODP
INPUT.vInfOpts = [0 2];      % --> min/max departing infinity velocities (km/s)
INPUT.dsmOpts  = [1 Inf];    % --> max defect DSM, and total DSMs (km/s)
INPUT.plot     = [1 1];      % --> plot(1) for Pareto front, plot(2) for best traj. DV
INPUT.parallel = true;       % --> put true for parallel, false otherwise
INPUT.tstep    = dt;         % --> step size for Time of flight            
%%%%%%%%%% set options %%%%%%%%%%

% --> specify custom bounds for TOFs and VINFs
INPUT.TOF_LIM = [[30 60]; [20 40]; [20 40]]; 

%% --> optimize using ASTRA

% --> launch ASTRA optimization
OUTPUT = ASTRA_DP(seq, INPUT);

one has the following resulting trajectories:

Pareto-front Pareto-front

where the MGA mission is around Saturn, flying-by Titan-Rhea-Rhea-Dione, with a 13:7 resonance on the Rhea-Rhea leg.

The corresponding output is reported here:


          _/_/_/     _/_/_/  _/_/_/_/_/  _/_/_/    _/_/_/ 
        _/    _/   _/           _/     _/    _/  _/    _/ 
       _/_/_/_/     _/_/       _/     _/_/_/    _/_/_/_/  
      _/    _/         _/     _/     _/    _/  _/    _/   
     _/    _/    _/_/_/      _/     _/    _/  _/    _/    


               - ASTRA solution - 

-------------------------------------------------------------- 

Departing body                 : Titan
Distance from the central body : 20.9828 Rs 

-------------------------------------------------------------- 

Arrival body                   : Dione  
Distance from the central body : 6.4809 Rs 
Departing C3                   : 2.4048 km^2/s^2 
Departing infinity velocity    : 1.5508 km/s 
Arrival infinity velocity      : 1.7465 km/s 
Total cost (DSMs)              : 0.7016 km/s 
Total cost                     : 3.9988 km/s 
Time of flight                 : 0.3065 years 

-------------------------------------------------------------- 

MGA Details : 

Swing-by sequence      : -T--R--R--D-

Departing date         : [2023   6  24  19  11  59]
Arrival date           : [2023  10  14  17  51   0]
Time of flight per leg : 31.6 days 
                         58.7438 days 
                         21.6 days 

DSMs magnitudes        : 0 km/s 
                         0 km/s 
                         0 km/s 
                         0.70157 km/s 

Infinity velocities    : 
Titan - Rhea         : 1.5508 - 3.4391 km/s 
Rhea    - Rhea         : 3.4391 - 3.4391 km/s 
Rhea    - Dione        : 3.2324 - 1.7465 km/s 

State at departure/arrival (km and km/s) : 
Titan                       : [230777.07612      1199878.4264                 0     -3.9470736019     0.76717345853                 0]  
Rhea                          : [424287.5053     -312766.6167                0      8.215458564      5.523455913                0]  

Rhea                          : [424287.5053     -312766.6167                0      8.174753313      5.428292303                0]  
Rhea                          : [424287.5053     -312766.6167                0      8.174753313      5.428292303                0]  

Rhea                          : [424287.5053     -312766.6167                0      7.602562939      4.866499723                0]  
Dione                         : [-233098.6853     -296804.2178                0      9.251156872     -7.279494237                0]  

Encounter dates        : 
Jupiter                : [2023   6  24  19  11  59]
Mars                   : [2023   7  26   9  35  59]
Mars                   : [2023   9  23   3  27   0]
Earth                  : [2023  10  14  17  51   0]

Transfer types         : 
Titan - Rhea         : outbound - outbound 
Rhea    - Rhea         : outbound - outbound 
Rhea    - Dione        : outbound - outbound 

-------------------------------------------------------------- 

Test script 5: Low-thrust trajectories

This script provides a number of test cases for the solution of low-thrust trajectories using ASTRA. In particular, at the moment ASTRA module Low thrust can solve the following optimal control problems

  • Energy-optimal time-fixed optimal control problem using indirect optimization.
  • Fuel-optimal time-fixed optimal control problem using indirect optimization (energy-optimal solution is used as first guess).

The script is well commented and should be intuitive to use.

Please note that to run some of the test cases in the script one needs a specific file called fuel_optimal_db.csv, containing parameters of transfers (i.e., initial and final position and velocity vectors, initial mass and time of flight). This can be found in ESA Zenodo repository.

Below, one reports the set-up and results for the Earth-Dionysus case (TEST CASE 5 from the script).

One loads the parameters:

% --> parameters
idcentral = 1;        % --> 1) central body is the Sun
Tmax      = 0.32;     % --> max. thrust                       [N]
Isp       = 3000;     % --> specific impulse                  [s]
m0        = 4000;     % --> initial mass                      [kg]          
g0        = 9.80665;  % --> Earth acceleration at sea level   [m/s]

% --> initialise the parameters
param     = writeParamLT( Tmax, Isp, m0, g0, idcentral, true );

And selects initial and final states (expressed in Mean Equinoctial Elements (MEE)), as well as the time of flight. This is taken from [3].

% --> Earth-to-Dionysus
tStart    = 0;
tEnd      = 3534; % --> please note that in this case the tof is in [days] as this is already scaled!!!
initState = [ 0.999316, -0.004023, 0.015873, -1.623e-5, 1.667e-5, 1.59491 ];
finState  = [ 1.555261 0.152514 -0.519189 0.016353 0.117461 2.36696 ];

One finally sets-up the remaining parameters for the search (e.g., the smoothing parameter -- see again Ref. [3]) and the number of revolutions:

param.tStart = tStart;
param.tEnd   = tEnd;
param.x0     = initState;
param.xf     = finState;

param.plot    = true;
param.rhoLim  = 0.0001;
param.rho     = 1;
param.gamma   = 0.1;
param.iterMax = 5;
param.tol     = 1e-8;

while param.xf(end) < param.x0(end)
    param.xf(end) = param.xf(end) + 2*pi;
end

Nrev            = 5;
param.xf(end)   = param.xf(end) + 2*Nrev*pi;
NrevCheck       = floor(( param.xf(end) - param.x0(end) )/(2*pi));

The solution to the fuel-optimal time-fixed control problem is provided by calling:

% --> solve the problem
LTsol = wrapSolveFopt( param );

The following lines plot the results, whose figures are reported below.

% --> plot the solution
transfer                      = LTsol.transfer;
[figTRAJ, figMASS, figTHRmag] = plotLT( transfer, param );

The following images show the optimal trajectory from Earth to Dionysus as well as the thrust profile and the mass evolution over time.

Earth-Dionysus-traj

Earth-Dionysus-thrust Earth-Dionysus-mass

Test script 6: Integrating ASTRA with custom ephemerides and NASA SPICE Toolkit

This script shows how the user can define custom ephemerides. The test case shown here is for integrating high-precision NASA planetary ephemerides to be integrated with the SPICE toolkit. In particular, the MATLAB interface of SPICE is called MICE.

Bug detected: currently, using the MICE toolkit prevents ASTRA to be run in parallel mode when resonances are included in the sequence. Next update will eliminate this...

In order to run such script, one creates a folder called MICE_TOOLBOX and puts there the mice folder downloaded from NASA as well as a folder called Kernels inside the mice one (i.e., MICE_TOOLBOX/mice/Kernels). Then, one can add the toolbox to the path:

% --> load custom ephemerides
MICE_path = './MICE_TOOLBOX' ;
addpath(genpath(MICE_path)); % --> always include this
cspice_furnsh([MICE_path '/data.mk']);

Note that a MICE_TOOLBOX/data.mk file is needed, which is the makefile that allows to load the kernels needed by MICE. This should look like the following:

KPL/MK


   \begindata

      PATH_VALUES     = ( './MICE_TOOLBOX/mice/Kernel' )

      PATH_SYMBOLS    = ( 'KERNELS' )

      KERNELS_TO_LOAD = (

                          '$KERNELS/naif0012.tls'
			  '$KERNELS/de430.bsp'
                          '$KERNELS/sat375.bsp'
                          '$KERNELS/mar097.bsp'
                          '$KERNELS/gm_de431.tpc'
                          '$KERNELS/pck00010.tpc'
                        )

   \begintext

End of MK.

One recognises naif0012.tls (for leapseconds), gm_de431.tpc (for gravity fields), pck00010.tpc (for bodies properties and orientation), as well as Solar system planetary ephemerides (all those files with .bsp extension). All of these are available through NASA website.

One then needs a function that allows ASTRA to read those ephemerides. This is provided in EphSS_from_mice. Finally, one can pass it as input in ASTRA by simply setting the field:

INPUT.customEphemerides = @EphSS_from_mice;

That's it.

ASTRA is now ready to be run with NASA ephemerides.

This script optimises an EVEMEJ sequence as a test case. One can check what is the difference between using high-precision ephemerides and approximate position of planets, i.e., those from EphSS_car.m file, by simply removing the line INPUT.customEphemerides = @EphSS_from_mice;, or commenting it.

Obviously, if one needs to integrate other bodies in MICE, the corresponding .bsp file should be added to the kernels and a proper reference should be made to the data.mk file. Otherwise, one can simpy use this line:

cspice_furnsh([ pwd '\' spk_dir '\' num2str(spk_id) '.bsp']);

where spk_dir is the directory where the .bsp file of the desired body is located, and spk_id is the SPK ID of the body. One can have SPK ID of desired bodies and download corresponding .bsp files directly from NASA Small-Body Database Lookup.

Additionally, a script is added that automatically downloads .bsp files from NASA database via API request. Essentially, one needs to set up the lower and upper bounds for ephemerides:

% --> lower and upper bounds for ephemerides
t0 = [ 2030 1 1 12 0 0 ];
tf = [ 2100 1 1 12 0 0 ];

and then pass the SPKID of the desired object, found at NASA website:

% --> set the path where to save the ephemerides
spk_dir = pwd;

% --> SPKID of the object (found at https://ssd.jpl.nasa.gov/tools/sbdb_lookup.html#/)
spk_id = 1000508;

Finally, the path to save the .bsp file is added ad the function getSPK is run:

% --> run the code (if success=1 then everything is okay)
success = getSPK(num2str(spk_id), num2str(t0), num2str(tf), spk_dir, 'overwrite', 'on');

If success=1, then a fresh new .bsp file should be present in the local directory, and ready to use.

An example to call position and velocity of the downloaded object is also provided:

% --> load custom ephemerides
cspice_furnsh([ spk_dir '\' num2str(spk_id) '.bsp']); % --> load the object ephemerides

INPUT.customEphemerides = @EphSS_from_mice;

t0_mjd2000 = date2mjd2000(t0);
[rr, vv]   = INPUT.customEphemerides( spk_id, t0_mjd2000, 1 );

A sequence to the object will look like: [planet_id, planet_id, spkid]. Then one simply falls back again the test script astra_with_custom_eph_mice.m. In particular, when using other objects one should use the following lines before launching ASTRA:

cspice_furnsh([ pwd '\' spk_dir '\' num2str(spk_id) '.bsp']); % --> load the object ephemerides
INPUT.customEphemerides = @EphSS_from_mice;

where again spk_dir is the location of the recently downloaded .bsp file, and spk_id is the SPKID of the object.

Contributing

Currently, only invited developers can contribute to the repository.

License

The work is under license CC BY-NC-SA 4.0, that is an Attribution Non-Commercial license.

References

[1] Bellome, A., “Trajectory design of multi-target missions via graph transcription and dynamic programming,” Ph.D. thesis, Cranfield University, 2023. https://dspace.lib.cranfield.ac.uk/items/711f45c8-e6e4-4f27-909d-94170df400e3

[2] Bellome, A., et al. "Multiobjective design of gravity-assist trajectories via graph transcription and dynamic programming." Journal of Spacecraft and Rockets 60.5 (2023): 1381-1399. https://doi.org/10.2514/1.A35472.

[3] Junkins, John L., and Ehsan Taheri. "Exploration of alternative state vector choices for low-thrust trajectory optimization." Journal of Guidance, Control, and Dynamics 42.1 (2019): 47-64. https://doi.org/10.2514/1.G003686

About

ASTRA is a MATLAB-based toolbox for optimally build MGA trajectories.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published