Skip to content

Commit

Permalink
Hohmann/Bi-impulsive overhaul
Browse files Browse the repository at this point in the history
The problem has been recrafted as a conjugate gradient problem with
a bit of heuristics for a search.  Limiting to coplanar is still
supported.  Transfer/Rendezvous is still supported.

There are buttons for no capture burn and to plan the capture burn
(maybe that should be "intercept burn" or "matching burn" or
something?), but they don't yet work.

The period offset thingy needs to be changed and doesn't yet work.

The simulated annealing is gone for now and will probably come back as
a rewriting with a basin hopping algorithm, but needs some UI work.

This is going to be best when dealing with things that are closer to
circular-to-circular coplanar transfer with smaller synodic periods, and
will still break as you get away from it.

It can at least plan transfer burns to GEO with the optimal inclination
change at the equator included (~2.16 degrees for a 185x185 launch
from Kennedy).  All that is lacking is a UX/UI way to construct an
artificial target.orbit.

Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
  • Loading branch information
lamont-granquist committed Sep 27, 2023
1 parent 781f3a0 commit a926641
Show file tree
Hide file tree
Showing 14 changed files with 852 additions and 716 deletions.
87 changes: 53 additions & 34 deletions MechJeb2/Maneuver/OperationTransfer.cs
Expand Up @@ -12,7 +12,16 @@ public class OperationGeneric : Operation
public override string GetName() => _name;

[UsedImplicitly]
public bool InterceptOnly;
[Persistent(pass = (int)Pass.GLOBAL)]
public bool Capture = true;

[UsedImplicitly]
[Persistent(pass = (int)Pass.GLOBAL)]
public bool PlanCapture = true;

[UsedImplicitly]
[Persistent(pass = (int)Pass.GLOBAL)]
public bool Rendezvous = true;

[UsedImplicitly]
[Persistent(pass = (int)Pass.GLOBAL)]
Expand All @@ -26,7 +35,7 @@ public class OperationGeneric : Operation

[UsedImplicitly]
[Persistent(pass = (int)Pass.GLOBAL)]
public bool SimpleTransfer;
public bool Coplanar;

private static readonly TimeReference[] _timeReferences =
{
Expand All @@ -39,14 +48,24 @@ public class OperationGeneric : Operation

public override void DoParametersGUI(Orbit o, double universalTime, MechJebModuleTargetController target)
{
InterceptOnly =
GUILayout.Toggle(InterceptOnly, Localizer.Format("#MechJeb_Hohm_intercept_only")); //intercept only, no capture burn (impact/flyby)
SimpleTransfer = GUILayout.Toggle(SimpleTransfer, Localizer.Format("#MechJeb_Hohm_simpleTransfer")); //simple coplanar Hohmann transfer
Capture =
!GUILayout.Toggle(!Capture, Localizer.Format("#MechJeb_Hohm_intercept_only")); //no capture burn (impact/flyby)
if (Capture)
PlanCapture = GUILayout.Toggle(PlanCapture, "Plan capture burn");
Coplanar = GUILayout.Toggle(Coplanar, Localizer.Format("#MechJeb_Hohm_simpleTransfer")); //coplanar maneuver
GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Hohm_Label1"), PeriodOffset); //fractional target period offset
if (!SimpleTransfer)
GUILayout.BeginHorizontal();
if (GUILayout.Toggle(Rendezvous, "Rendezvous"))
Rendezvous = true;
if (GUILayout.Toggle(!Rendezvous, "Transfer"))
Rendezvous = false;
GUILayout.EndHorizontal();
/*
if (!Coplanar)
{
_timeSelector.DoChooseTimeGUI();
}
*/
}

protected override List<ManeuverParameters> MakeNodesImpl(Orbit o, double universalTime, MechJebModuleTargetController target)
Expand Down Expand Up @@ -75,43 +94,43 @@ protected override List<ManeuverParameters> MakeNodesImpl(Orbit o, double univer
targetOrbit.MutatedOrbit(PeriodOffset);
}

if (SimpleTransfer)
(dV, ut) = OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(o, targetOrbit, universalTime, coplanar: Coplanar, rendezvous: Rendezvous);

/*
else
{
if (_timeSelector.TimeReference == TimeReference.COMPUTED)
{
dV = OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(o, targetOrbit, universalTime, out ut);
dV = OrbitalManeuverCalculator.DeltaVAndTimeForBiImpulsiveAnnealed(o, targetOrbit, universalTime, out ut,
intercept_only: InterceptOnly);
}
else
{
if (_timeSelector.TimeReference == TimeReference.COMPUTED)
bool anExists = o.AscendingNodeExists(target.TargetOrbit);
bool dnExists = o.DescendingNodeExists(target.TargetOrbit);
if (_timeSelector.TimeReference == TimeReference.REL_ASCENDING && !anExists)
{
throw new OperationException(Localizer.Format("#MechJeb_Hohm_Exception3")); //ascending node with target doesn't exist.
}
if (_timeSelector.TimeReference == TimeReference.REL_DESCENDING && !dnExists)
{
dV = OrbitalManeuverCalculator.DeltaVAndTimeForBiImpulsiveAnnealed(o, targetOrbit, universalTime, out ut,
intercept_only: InterceptOnly);
throw new OperationException(Localizer.Format("#MechJeb_Hohm_Exception4")); //descending node with target doesn't exist.
}
else
if (_timeSelector.TimeReference == TimeReference.REL_NEAREST_AD && !(anExists || dnExists))
{
bool anExists = o.AscendingNodeExists(target.TargetOrbit);
bool dnExists = o.DescendingNodeExists(target.TargetOrbit);

if (_timeSelector.TimeReference == TimeReference.REL_ASCENDING && !anExists)
{
throw new OperationException(Localizer.Format("#MechJeb_Hohm_Exception3")); //ascending node with target doesn't exist.
}

if (_timeSelector.TimeReference == TimeReference.REL_DESCENDING && !dnExists)
{
throw new OperationException(Localizer.Format("#MechJeb_Hohm_Exception4")); //descending node with target doesn't exist.
}

if (_timeSelector.TimeReference == TimeReference.REL_NEAREST_AD && !(anExists || dnExists))
{
throw new OperationException(
Localizer.Format("#MechJeb_Hohm_Exception5")); //neither ascending nor descending node with target exists.
}

ut = _timeSelector.ComputeManeuverTime(o, universalTime, target);
dV = OrbitalManeuverCalculator.DeltaVAndTimeForBiImpulsiveAnnealed(o, targetOrbit, ut, out ut, intercept_only: InterceptOnly,
fixed_ut: true);
throw new OperationException(
Localizer.Format("#MechJeb_Hohm_Exception5")); //neither ascending nor descending node with target exists.
}
ut = _timeSelector.ComputeManeuverTime(o, universalTime, target);
dV = OrbitalManeuverCalculator.DeltaVAndTimeForBiImpulsiveAnnealed(o, targetOrbit, ut, out ut, intercept_only: InterceptOnly,
fixed_ut: true);
}
}
*/

return new List<ManeuverParameters> { new ManeuverParameters(dV, ut) };
}
Expand Down

0 comments on commit a926641

Please sign in to comment.