Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 22 additions & 17 deletions MechJeb2/MechJebModuleGuidanceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ private bool WillDoRCSButNotYet()
bool hasRCS = Vessel.hasEnabledRCSModules() &&
VesselState.RCSThrustAvailable.Up > 0.1 * VesselState.RCSThrustAvailable.MaxMagnitude();

return hasRCS && Status != PSGStatus.TERMINAL_RCS && Core.StageStats.VacStats.Count - 1 <= Solution.TerminalMJPhase();
return hasRCS && Status != PSGStatus.TERMINAL_RCS && Vessel.currentStage == Solution.TerminalKSPStage();
}

private void HandleTerminal()
Expand All @@ -150,6 +150,21 @@ private void HandleTerminal()
return;
}

/*
* FIXME: consider liquid booster()s + unguided beehive cluster
*
* 1. we should enter terminal guidance on the top liquid booster and shut it down precisely and suspend the optimizer
* there because we CANNOT use the residuals because we're about to loose our degrees of freedom. but the optimizer should
* have burned this stage to completion. we also don't want to use TERMINAL_RCS here.
* 2. we should still enter terminal guidance on the top aerobee stage and precisely shut it down to actually hit the target as
* best as possible, and this burntime should have been tuned by the optimizer. we do want to use TERMINAL_RCS here.
*
* Right now we only support one OptimizeKSPStage() and really the SolutionBuilder needs to know to slap a PreciseShutdown flag
* onto the last liquid booster segment (even though the optimizer didn't optimize it) and likely could use the same flag for
* precise shutdown of engines before a coast. Although maybe there should be two different flags (for precise shutdown with
* and without RCS cleanup).
*/

// this handles termination of thrust for final stages of "fixed" burntime rockets (due to residuals Tgo may go less than zero so we
// wait for natural termination of thrust). no support for RCS terminal trim.
if (Solution.OptimizeKSPStage() < 0 && Vessel.currentStage <= Solution.TerminalKSPStage() && Solution.Tgo(VesselState.Time) <= 0 &&
Expand All @@ -169,26 +184,16 @@ private void HandleTerminal()
Status = PSGStatus.BURNING;
}

// We should either be in an non-upper stage optimized stage, or we should be within 10 seconds of the whole
// burntime in order to enter terminal guidance.
if (Vessel.currentStage != Solution.OptimizeKSPStage() && Solution.Tgo(VesselState.Time) > 10)
// we need to have an optimizable stage to run terminal guidance
if (Vessel.currentStage != Solution.OptimizeKSPStage())
return;

// The includeCoast: false flag here is to skip a coast which is in the past in the Solution when
// we are ending the coast and the optimizer hasn't run the solution, but CoastBefore is set so
// that both the coast and burn have the same KSPStage. So we want the index of the current burn
// and not the index of the first matching KSPStage in the Solution which is the coast. Might
// also consider modifying APIs like IndexForKSPStage to omit stages which are in the past -- but
// I have concerns about that with residuals where you may currently be in a burning stage which
// is in the "past" in the Solution but you're burning down residuals and you don't know when
// the stage will actually run out (assuming it isn't a burn before a coast or an optimized burntime
// so that we burn past the end of the stage and into whatever residuals are available).
int solutionIndex = Solution.IndexForKSPStage(Vessel.currentStage, Core.Guidance.IsCoasting());
if (solutionIndex < 0)
// we need to be within 10 seconds of the end of the stage to run terminal guidance
if (Solution.TgoForKSPStage(VesselState.Time, Vessel.currentStage) > 10)
return;

// Only enter terminal guidance within 10 seconds of the current stage
if (Solution.Tgo(VesselState.Time, solutionIndex) > 10)
// but if we're doing a coast, or going to do a coast we don't enter terminal guidance yet
if (Vessel.currentStage == Solution.CoastKSPStage() && Solution.WillCoast(VesselState.Time))
return;

if (Status != PSGStatus.TERMINAL_RCS)
Expand Down
14 changes: 14 additions & 0 deletions MechJebLib/PSG/Solution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,19 @@ public double Tgo(double t, int n)
return TgoBar(tbar, n) * _timeScale;
}

public double TgoForKSPStage(double t, int kspStage)
{
double tbar = (t - T0) / _timeScale;
double sum = 0;
for (int i = IndexForTbar(tbar); i < Phases.Count && Phases[i].KSPStage == kspStage; i++)
{
if (Phases[i].Coast)
continue;
sum += TgoBar(tbar, i) * _timeScale;
}
return sum;
}

public double TgoBar(double tbar, int n)
{
if (tbar > _tmin[n])
Expand All @@ -255,6 +268,7 @@ public bool Coast(double t)
}

// Specialized API to determine if we still have the coast in our future or not
// (or if we're in a coast right now)
public bool WillCoast(double t)
{
double tbar = (t - T0) / _timeScale;
Expand Down
Loading