Patched conics computations - poliastro/poliastro GitHub Wiki

Fly-by maneuvers are extremely sensitive to initial conditions. In simulations, it is frequently observed that changes of ~0.5 m/s a quarter of an orbit before the encounter can result in dramatic differences, often changing the post-flyby trajectory more than 40º.

Maybe, an interesting approach can be the following:

  1. First, use the desired objective of the maneuver, like the vectorial dV obtained or flyby trayectory, to obtain a hyperbolic flyby orbit, and propagate it backwards in time with precision to the limit of the SOI.
  2. Using the required speed vector, a collision heliocentric orbit is calculated.
  3. Then calculate the correction maneuvers required to get to the entering SOI point with the required speed vector.

Maybe, the first two steps can be executed in the inverse order, getting a cone of the possible post flyby trajectories given a collision trajectory, and then finding the optimum one from this possibility space.

I propose having a minimun flyby altitude for every planet equal to 2% of the planet radius (p.ej, for Earth is ~120 km).

Imagine a generic orbit plane. Assuming a hyperbolic orbit with minimum periapsis, depending on the speed at the periapsis, a speed can be calculated either at both intersections of the orbit with the SOI or at the infinite before and after flyby. Then, a vectorial difference between the entering and leaving velocities can be calculated. Therefore, we can correlate a maximum speed change with every entering speed, that is to say, the maximum delta v obtainable with a flyby without additional propulsion can be calculated depending only on the scalar value of the relative speed between the spacecraft and the planet.

Also, the delta-v vector can be projected on axis parallel to the entering speed, separating it in normal delta-v which can be oriented at will and tangential delta-v that will always go against the entering speed.

Proposed approach:

First Objective: Being able to calculate the capabilities of an unpowered flyby

  • Step 0: assign the body a property min_orbit equal to 1.02 times the radius.

  • Step 1: define a method in the body object that returns these information depending on the relative speed. proposed API:

    • call: body.max_flyby(relative_speed) [Able to process either vector or scalar? only the value matters]
    • returns: max_norm_dv, max_tan_dv, max_angle_change [scalar km/s, negative scalar km/s, rad resp.]
  • Step 2: define a method to calculate a sub-maximum flyby. By using a flyby at a higher altitude, you can get a less intense flyby. Therefore, periapsis altitude, total dv, normal dv, tangential dv and speed angle change are intrinsecally related, and imposing one is enough to calculate all the others. Here we have two possibilities: either we have only one function that calculate the missing 4 parameters, and we specify which is the parameter provided via input variable, or we have five separated functions. I think this second way is more simmilar to the way the orbit object is generated. Note that as the tangential dv will always go in the opposite direction of the speed, its value will always be a negative number. proposed API:

    • call: body.unpowered_flyby_from_[periapsis/dv/norm_dv/tan_dv/angle](relative_speed, parameter)
    • returns: periapsis, norm_dv, tan_dv, angle_change [scalar km, scalar km/s, negative scalar km/s, rad resp.]

Once this state is achieved, we would be able to use the Lambert problem solutions and planetary ephemeris already implemented to calculate planetary flybys:

With Lambert and ephemeris, we can get a collision orbit with the desired planet, depending only on launch date and flight duration. This gives us a speed vector at the encounter position. We can then usethe maximum flyby to check if our desired post-flyby orbit is achievable. Analyze an array of launch dates and flight times to picture a window of launches. Add a sub-maximum fly-by parameter as a degree of freedom to calculate the exact manuver required in each position of the window space. Optionally, apply an optimization algorithm to the results to get the best unpowered flyby.

Second Objective: Being able to calculate the capabilities of a powered flyby

  • Step 3: define a method in the body object that returns the dv necessary to capture the body depending on the relative speed. To do so, I propose calculating a burn at the periapsis that transform the hyperbolic orbit into an elliptical one with the apoapsis height at the SOI radius. Proposed API:

    • call: body.min_capture_dv(relative_speed)[Again, only the scalar value matters]
    • returns: min_dv [also semi-major axis and eccentricity?]
  • Step 4: define a method that returns the retrograde burn necessary to get a parabolic orbit. I think it is important, because any retrograde burn between this value and the captured one from step 2 would produce an elliptical orbit with an apoapsis outside the sphere of influence, which I think wouldn't be calculated precisely enough with patched conics, and would be better left to a future 3-body analysis module. This module is suggested in https://github.com/poliastro/poliastro/issues/8 . Proposed API:

    • call: body.max_flyby_retro_dv(relative_speed)[Again, only the scalar value matters]
    • returns: max_retro_dv
  • Step 5: define a method that returns the same as maximun unpowered flyby, but in a powered flyby with a given dv. To do so, we assume an hyperbolic unpowered trajectory until the periapsis. Then, an instantaneous burn is done with the given dv, that should have a positive sign for a prograde burn and a negative sign for retrograde burn. The inferior limit to this delta-v should be calculated with the step 3 method. Then, the resultant hyperbolic trayectory is calculated with the same criteria as the unpowered flyby from step 1. Note that retrograde burns will increase the achivable angle change, while prograde burns will increase the delta-v obtained via Oberth effect. For the tangential dv, we will use a negative value when its direction is opposite to the direction of the enter speed. proposed API:

    • call: body.max_powered_flyby(relative_speed, dv)
    • returns: max_norm_dv, max_tan_dv, max_angle_change [scalar km/s, scalar km/s, rad resp.]

More ideas

(This is for unpowered flybys only)

There are several things we have to figure out:

  • What are the inputs and outputs
  • How do we control "trailing" vs "leading" flybys
  • How is the latter related to B-Plane targetting
  • What should be the reference frame of the inputs and outputs

Flyby

[The flyby] is a leading-side flyby because the periapsis is on the side of the planet facing into the direction of motion.

The inputs for the direct problem are:

  • Heliocentric velocity of the planet V
  • Inbound heliocentric velocity of the spacecraft V_1^v
  • The periapsis radius r_p

And we want to find out the outbound heliocentric velocity of the spacecraft V_2^v. For the inverse problem, we could set the outbound heliocentric velocity and find out the periapsis radius.

An intermediate step is to compute the flyby hyperbola. For that, we assume that we already have the inbound hyperbolic excess velocity v_∞1 in the trajectory plane. The magnitude of the outbound hyperbolic excess velocity v_∞2 will be the same, and the turn angle δ has to be computed.

  1. Compute the magnitude of v_∞
  2. Compute the eccentricity using the periapsis radius r_p
  3. Compute the turn angle as 2 arcsin (1 / ecc)

Flyby with B-plane

(from http://www.trylam.com/wp-content/uploads/2017/01/Lecture9thWeek.pdf)