Trajectory Optimization with a Solar Sail: My GTOC13 Experience

The Global Trajectory Optimization Competition (GTOC) brings together astrodynamics, optimization, and creative problem-solving: it is the "America's Cup of rocket science". This year I took part in the competition for the first time, and managed to enter the leaderboard with a respectable final score.  In this post, the first part gives a high-level overview of how I approached the challenge, while the (more technical) second part will discuss the implementation details of my solution.


 

This year's edition revolved around the exploration of the exoplanetary system of the fictional star Altaira, whose planets sport a variety of pop-culture-inspired names. Assuming the interstellar leg is already taken care of, the task was to design a trajectory that maximizes the number and scientific value of reconnaissance close approaches with Altaira’s planets, asteroids, and comets. The dynamical model includes unpowered gravity assists with the major planets (minor bodies are considered massless), and propulsion from a deployable solar sail. When the sail is stowed, a patched-conics approximation can be used. Trajectories must satisfy a variety of constraints: initial conditions, feasible and consistent gravity assists, and a total mission duration of 200 years. 

As someone fairly new to trajectory optimization, and working with limited resources (two laptops and a solo team), I relied on a qualitative strategy guided largely by physical intuition rather than attempting a fully automated global search. In practice, this meant setting up a simple but flexible trajectory model, manually testing different sequences of planetary flybys, and trying multiple definitions of the objective function. To keep the number of free parameters manageable, I constructed the trajectory as a sequence of arcs, each linking one gravity assist to the next. Every arc consisted of three sub-arcs: coast, sail-powered, coast; for each, I optimized the time of flight, the start and end times of sail deployment, and two angles specifying the sail orientation.

Since handling tens (or hundreds, as in the winning solution) of flybys was beyond what my simple approach could deliver, I focused on the outer major planets, which offered higher score weights. My best-scoring solution visits seven planets (Vulcan, Eden, Beyoncé, Jotunn, Wakonyingo, Rogue 1, and Planet X”), as shown in the interactive figure below. 

 

This experience gave me hands-on practice with trajectory modeling and optimization, and a deeper appreciation for the sometimes counterintuitive dynamics of solar sailing. Competing in GTOC has been a goal of mine for a while, and I am genuinely proud of what I could achieve this year. I may not be near the top of the leaderboard, but the participation, the learning, and the sense of exploration were the real rewards.

I am already looking forward to the next edition.

 

Technical Aspects

The optimization script was written in Python and uses a custom objective function together with linear and non-linear constraints within scipy.optimize.minimize.

For trajectory propagation, I use spiceypy (a Python interface to NAIF SPICE) for two-body dynamics, the Lambert solvers from lamberthub, and the Taylor-adaptive integrator Heyoka for the sail-powered sub-arcs.

The sequence of planets to be visited is held fixed, allowing the search space to remain manageable. The decision vector contains the freely adjustable components of the initial conditions, the periapsis altitudes of all gravity assists, and the arc parameters introduced earlier: time of flight, start and end times of the sail-powered interval, and two orientation angles for the sail.

Trajectory arc construction and optimization

Within the adopted patched-conics approximation, the position of the spacecraft at the start and end of each arc coincides with the known position of the planets being visited. The trajectory is therefore fully determined once the velocities at the two endpoints are known.

For a purely ballistic arc this reduces to a standard Lambert problem. To accommodate the sail-powered segment, I use an iterative procedure, starting from the Lambert solution. For an arc connecting positions ${\bf r}_s$ and ${\bf r}_f$ from time $t_s$ to $t_f$, the unknown terminal velocities ${\bf v}_s$ and ${\bf v}_f$ are obtained as follows:  

  1. Using the current guess for the terminal velocities, integrate forward from $t_s$ to the midpoint $t_m$, and backward from $t_f$ to $t_m$, with initial conditions $({\bf r}_s, {\bf v}_s)$ and $({\bf r}_f, {\bf v}_f)$, respectively.
  2. Compute the mismatch $(\delta {\bf r}_m, \delta {\bf v}_m)$ between the forward and backward integrations.
  3. Apply a correction to ${\bf v}_s$ and ${\bf v}_f$ calculated from the linearized equations:

$\Phi_{\bf r v}\, \delta {\bf v}_s - \Psi_{\bf r v}\, \delta {\bf v}_f = \delta {\bf r}_m$,

$\Phi_{\bf v v}\, \delta {\bf v}_s - \Psi_{\bf v v}\, \delta {\bf v}_f = \delta {\bf v}_m$,

where $\Phi_{\bf r v}$, $\Psi_{\bf r v}$, etc. are blocks from the state transition matrices $\Phi(t_m, t_s)$ and $\Psi(t_m, t_f)$, obtained in the forward and backward integration, respectively (sometimes referred to as navigation and guidance matrices, respectively; see, for instance, Battin, 1999). 

This procedure typically converged in about five iterations and proved robust across all tested arcs. 

Once the terminal velocities are known for all arcs, the entire trajectory is determined, and both the constraints and the objective function can be evaluated. The non-linear constraints enforce continuity of the asymptotic speed across each gravity assist and match the periapsis altitude of the assist to the value specified by the current decision vector. As objective function, I experimented both with a simplified implementation of the official GTOC score and with a straightforward minimization of the total mission duration. When optimizing for score, the total time less than 200 years was added as a linear constraint. 

Comments on my best solution 

The GTOC13 problem specifications partially fix the initial conditions: the trajectory begins at a point with heliocentric coordinates $x_0 = -200$ au (and adjustable $y_0$ and $z_0$), and with a velocity vector aligned with the X-axis, but of freely adjustable magnitude, $v_{x, 0}$. 

Through trial and error, I found that relatively large inbound speeds, $v_{x, 0} \approx 50$ km/s, can still be accommodated, provided that the first gravity assist is performed with Vulcan, the innermost planet. Vulcan is a hot Jupiter on a circular, zero-inclination orbit at $a \approx 0.1$ au, and it is massive enough to significantly deflect the initial fast trajectory. This first flyby is immediately followed by a close perihelion passage around the central star, Altaira. Together, the Vulcan assist and the subsequent stellar passage reduce the probe’s heliocentric speed to a moderate value and effectively inject it into the inner system, creating a suitable starting point for further exploration. These features are illustrated in the figure below.

 

Two-dimensional view of the trajectory as projected in the ecliptic plane; the orbits of the major planets are also shown. Sail-powered segments are highlighted in light blue along the trajectory.


Reaching the two outermost planets (Rogue 1 and Planet X) from the inner system requires long transfer times and/or a high heliocentric speed. For this reason, it is generally easiest to visit these planets at the end of the trajectory (though this is not strictly required). The long outbound leg can be partially mitigated by increasing the probe’s speed toward the end of the mission. 

Indeed, the probe begins the mission with a speed above the local escape velocity and becomes captured by the system only after the sequence “Vulcan gravity assist + first perihelion maneuver”. Low-thrust solar-sail segments then allow it to visit several additional planets while gradually increasing its heliocentric speed again. Eventually the spacecraft becomes unbound once more, enabling the final transfers to Rogue 1 and Planet X. These aspects are illustrated quantitatively in the next figure. 

 

Position, velocity, and acceleration of the probe along the trajectory (top, middle, and bottom panels, respectively). The striped regions mark the sail-powered segments. In the middle panel the local escape velocity is also plotted as a red, dot-dashed line, while the bottom panel also shows the sail acceleration (orange line).


This concludes the technical overview of my solution. The methods described here are certainly not state-of-the-art, but they were effective for my purposes and made for a rewarding learning exercise. Tackling this problem deepened my intuition for gravity-assist chaining and solar-sail dynamics. I may not have uncovered the optimal path through the Altaira system, but I certainly enjoyed charting my own!

I look forward to applying these ideas to future projects, and I hope these notes may be useful to anyone exploring similar problems.

Comments

Popular posts from this blog

The "Sphere of Influence" of the Moon is not really spherical

The rhythms of the sea: a primer on tides