I want to implement a simple target/vary sequence to find the required delta-v of a impulsive maneuver.
So in core, I would like to 1. propagate to apogee.
From here a optimizer should apply a impulsive delta-v in flight direction, propagate to perigee and check whether we reached the required radius here.
So, Target = Perigee-Radius
Vary = delta-v in apogee
So the cost-function would be:
“apply delta-v (input) in apogee”
" prop to apogee"
with “input” as the only variable the optimizer should vary.
I see that hipparchus lib has several optimization utilities, however I struggle so setup a simple running example for the described case.
I assume this is a often approached problem by orekit users, i.e. optimize maneuvers etc.
So, I hope there’s a easy starting sample you could kick-start me with.
There is no built-in function for optimizing impulse maneuvers in Orekit. @serrof recently added an indirect optimal control method for low-thrust trajectory optimization. This is the only maneuver-optimization scheme that we have, but this is not what you’re looking for.
For your use case I think a least-square may do the trick, you will need to compute the derivatives though.
There is also the BOBYQAOptimizer and several more if you don’t want to compute the derivatives.
Also, as you say, there are lots of different optimizers in Hipparchus. Some were recently added by @roccafrancesco, maybe he will be able to give you more insights on which ones to use.
To get the derivatives of the impulse maneuver there are two methods:
Use SmallManeuverAnalyticalModel and the method getJacobian. The assumptions are that only the Keplerian effect (2-body problem + maneuver) are taken into account with this model
Use a FieldImpulseManeuver (also recently added by @Serrof) with a Gradient as field.
This must be paired with a FieldPropagator (example here). It uses automatic differentiation to compute both the state and its derivatives with respect to a set of user-defined parameters (in your case the 3 components of the DV)
The Jacobian and residuals (difference between expected state and actual state) can then be added to a LeastSquareProblem which will provide the fit.
You can use the root finding methods provided by the hipparchus library, such as Newton-Raphson, Bi-Section or Secant. For this purpose, you can define your own function for example by simply implementing to UnivariateFunction. One can define the procedure inside their own function and return the difference between targeted value and the calculated value such as;
public class Function implements UnivariateFunction {
public Function(You can pass your targeted parameters, spacecraft states and etc. through your constructer method.)
@Override
public double value(double x) {
Define your procedure here such as;
Propagate to apogee,
Apply the given value of "x" (m/s) delta-v to orbit, which is provided by the root finding algorithm,
Propagate to next apogee,
Collect apogee altitude,
Calculate the difference between calculated apogee altitude and targeted one,
return the difference,
}
}
Then, in your main code, you can call the newton raphson such as;
public class Main{
public static void main(String[] args){
NewtonRaphsonSolver solver = new NewtonRaphsonSolver();
UnivariateFunction funciton = new Function(Pass your parameters to your function, such as maneuver force models, target values, etc.);
double your solution =solver.solve(Max Eval, function, Your Initial Guess);
}
}