Skip to content

Commit

Permalink
one more ullage refactoring (#900)
Browse files Browse the repository at this point in the history
- VesselState now exposes the lowestUllage condition rather than
stableUllage

- The "prevent unstable ignitions" box now only does what it says
it does.  If its checked, ullage must be stable.

- Introduced a new "Use RCS to ullage" checkbox, and moved the
auto-RCS ullaging to this function.  It is a bit smarter and does
nothing if there's no ModuleRCS active.  It will also enable the
RCS action group automatically (if there is ModuleRCS to activate)

The latter function should pretty much be safe to run with all the
time, since stuff like sounding rockets don't have any RCS.

Auto-RCS should also not get confused by RCS in probe modules since
the RCS module needs to be enabled, and with KSP >= 1.2.x we all
should be staging our RCS properly.

Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
  • Loading branch information
lamont-granquist authored and sarbian committed Jun 11, 2017
1 parent 63bfc73 commit 00747f8
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 25 deletions.
44 changes: 36 additions & 8 deletions MechJeb2/MechJebModuleThrustController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ public void LimitToPreventUnstableIgnitionInfoItem()
limitToPreventUnstableIgnition = GUILayout.Toggle(limitToPreventUnstableIgnition, "Prevent unstable ignition", s);
}

[Persistent(pass = (int)Pass.Global)]
public bool autoRCSUllaging = true;

[GeneralInfoItem("Prevent unstable ignition", InfoItem.Category.Thrust)]
public void AutoRCsUllageInfoItem()
{
GUIStyle s = new GUIStyle(GUI.skin.toggle);
if (limiter == LimitMode.AutoRCSUllage) s.onHover.textColor = s.onNormal.textColor = Color.green;
autoRCSUllaging = GUILayout.Toggle(autoRCSUllaging, "Use RCS to ullage", s);
}

// 5% safety margin on flameouts
[Persistent(pass = (int)Pass.Global)]
public EditableDouble flameoutSafetyPct = 5;
Expand Down Expand Up @@ -213,7 +224,7 @@ public void LimitElectricInfoItem()
GUILayout.EndHorizontal();
}

public enum LimitMode { None, TerminalVelocity, Temperature, Flameout, Acceleration, Throttle, DynamicPressure, MinThrottle, Electric, UnstableIgnition }
public enum LimitMode { None, TerminalVelocity, Temperature, Flameout, Acceleration, Throttle, DynamicPressure, MinThrottle, Electric, UnstableIgnition, AutoRCSUllage }
public LimitMode limiter = LimitMode.None;

public float targetThrottle = 0;
Expand Down Expand Up @@ -502,21 +513,38 @@ public override void Drive(FlightCtrlState s)
}
}

// RealFuels ullage integration. Stock always has stableUllage.
if (limitToPreventUnstableIgnition && !vesselState.stableUllage)
/* auto-RCS ullaging up to very stable */
if (autoRCSUllaging && s.mainThrottle > 0.0F && throttleLimit > 0.0F )
{
if (s.mainThrottle > 0.0F && throttleLimit > 0.0F )
if (vesselState.lowestUllage < VesselState.UllageState.VeryStable)
{
// We want to fire the throttle, and nothing else is limiting us, but we have unstable ullage
setTempLimit(0.0F, LimitMode.UnstableIgnition);
if (vessel.ActionGroups[KSPActionGroup.RCS] && s.Z == 0)
Debug.Log("MechJeb RCS auto-ullaging: found state below very stable: " + vesselState.lowestUllage);
if (vessel.hasEnabledRCSModules())
{
// RCS is on, so use it to ullage
if (!vessel.ActionGroups[KSPActionGroup.RCS])
{
Debug.Log("MechJeb RCS auto-ullaging: enabling RCS action group for automatic ullaging");
vessel.ActionGroups.SetGroup(KSPActionGroup.RCS, true);
}
Debug.Log("MechJeb RCS auto-ullaging: firing RCS to stabilize ulllage");
setTempLimit(0.0F, LimitMode.UnstableIgnition);
s.Z = -1.0F;
} else {
Debug.Log("MechJeb RCS auto-ullaging: vessel has no enabled/staged RCS modules");
}
}
}

/* prevent unstable ignitions */
if (limitToPreventUnstableIgnition && s.mainThrottle > 0.0F && throttleLimit > 0.0F )
{
if (vesselState.lowestUllage < VesselState.UllageState.Stable)
{
Debug.Log("MechJeb Unstable Ignitions: preventing ignition in state: " + vesselState.lowestUllage);
setTempLimit(0.0F, LimitMode.UnstableIgnition);
}
}

if (double.IsNaN(throttleLimit)) throttleLimit = 1.0F;
throttleLimit = Mathf.Clamp01(throttleLimit);

Expand Down
15 changes: 8 additions & 7 deletions MechJeb2/MechJebModuleThrustWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ protected override void WindowGUI(int windowID)
{
// does nothing in stock, so we suppress displaying it if RF is not loaded
core.thrust.LimitToPreventUnstableIgnitionInfoItem();
core.thrust.AutoRCsUllageInfoItem();
}
core.thrust.smoothThrottle = GUILayout.Toggle(core.thrust.smoothThrottle, "Smooth throttle");
core.thrust.manageIntakes = GUILayout.Toggle(core.thrust.manageIntakes, "Manage air intakes");
Expand All @@ -75,32 +76,32 @@ protected override void WindowGUI(int windowID)
GUILayout.EndHorizontal();
}

core.thrust.DifferentialThrottle();

core.thrust.DifferentialThrottle();

if (core.thrust.differentialThrottle && vessel.LiftedOff())
{
switch (core.thrust.differentialThrottleSuccess)
{
case MechJebModuleThrustController.DifferentialThrottleStatus.MoreEnginesRequired:
GUILayout.Label("Differential throttle failed\nMore engines required", new GUIStyle(GUI.skin.label) { normal = { textColor = Color.yellow } });
GUILayout.Label("Differential throttle failed\nMore engines required", new GUIStyle(GUI.skin.label) { normal = { textColor = Color.yellow } });
break;
case MechJebModuleThrustController.DifferentialThrottleStatus.AllEnginesOff:
GUILayout.Label("Differential throttle failed\nNo active engine", new GUIStyle(GUI.skin.label) { normal = { textColor = Color.yellow } });
break;
case MechJebModuleThrustController.DifferentialThrottleStatus.SolverFailed:
GUILayout.Label("Differential throttle failed\nCannot find solution", new GUIStyle(GUI.skin.label) { normal = { textColor = Color.yellow } });
GUILayout.Label("Differential throttle failed\nCannot find solution", new GUIStyle(GUI.skin.label) { normal = { textColor = Color.yellow } });
break;
case MechJebModuleThrustController.DifferentialThrottleStatus.Success:
case MechJebModuleThrustController.DifferentialThrottleStatus.Success:
break;
}
}

core.solarpanel.AutoDeploySolarPanelsInfoItem();

Autostage();

if (!core.staging.enabled && GUILayout.Button("Autostage once")) core.staging.AutostageOnce(this);

if (core.staging.enabled) core.staging.AutostageSettingsInfoItem();

if (core.staging.enabled) GUILayout.Label(core.staging.AutostageStatus());
Expand Down
24 changes: 22 additions & 2 deletions MechJeb2/VesselExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static List<ITargetable> GetTargetables(this Vessel vessel)
for (int m = 0; m < count; m++)
{
T mod = part.Modules[m] as T;

if (mod != null)
list.Add(mod);
}
Expand All @@ -61,7 +61,7 @@ public static MechJebCore GetMasterMechJeb(this Vessel vessel)
lastFixedTime = Time.fixedTime;
}
Guid vesselKey = vessel == null ? Guid.Empty : vessel.id;

MechJebCore mj;
if (!masterMechJeb.TryGetValue(vesselKey, out mj))
{
Expand Down Expand Up @@ -340,5 +340,25 @@ public static void UpdateNode(this ManeuverNode node, Vector3d dV, double ut)
node.attachedGizmo.patchBefore = node.patch;
node.attachedGizmo.patchAhead = node.nextPatch;
}

// The part loop in VesselState could expose this, but it gets disabled when the RCS action group is disabled.
// This method is also useful when the RCS AG is off.
public static bool hasEnabledRCSModules(this Vessel vessel)
{
var rcsModules = vessel.FindPartModulesImplementing<ModuleRCS>();

for (int m = 0; m < rcsModules.Count; m++)
{
ModuleRCS rcs = rcsModules[m];

if (rcs == null)
continue;

if (rcs.rcsEnabled && rcs.isEnabled && !rcs.isJustForShow)
return true;
}

return false;
}
}
}
45 changes: 37 additions & 8 deletions MechJeb2/VesselState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,18 @@ public class VesselState
private static FieldInfo RFignitionsField;
// RealFuels.ModuleEngineRF ullage field to call via reflection
private static FieldInfo RFullageField;
// stableUllage is always true without RealFuels installed
public bool stableUllage { get { return this.einfo.stableUllage; } }

public enum UllageState {
VeryUnstable,
Unstable,
VeryRisky,
Risky,
Stable,
VeryStable // "Nominal" also winds up here
}

// lowestUllage is always VeryStable without RealFuels installed
public UllageState lowestUllage { get { return this.einfo.lowestUllage; } }

private Vessel vesselRef = null;

Expand Down Expand Up @@ -310,7 +320,7 @@ static bool isAssemblyLoaded(string assemblyName)
return null;
}

Type type = Type.GetType("RealFuels.ModuleEnginesRF, " + assemblyName);
Type type = Type.GetType(className + ", " + assemblyName);

if (type == null)
{
Expand Down Expand Up @@ -1164,8 +1174,8 @@ public class EngineInfo
public Vector3d thrustMin = new Vector3d(); // thrust at zero throttle
public double maxResponseTime = 0;
public Vector6 torqueDiffThrottle = new Vector6();
// stableUllage is always true without RealFuels installed
public bool stableUllage = true;
// lowestUllage is always VeryStable without RealFuels installed
public UllageState lowestUllage = UllageState.VeryStable;

public struct FuelRequirement
{
Expand All @@ -1190,7 +1200,7 @@ public void Update(Vector3d c, Vessel vessel)

resourceRequired.Clear();

stableUllage = true;
lowestUllage = UllageState.VeryStable;

CoM = c;

Expand Down Expand Up @@ -1277,9 +1287,28 @@ public void CheckUllageStatus(ModuleEngines e)
return;
}

if ((propellantStatus != "Nominal") && (propellantStatus != "Very Stable") && (propellantStatus != "Stable"))
UllageState propellantState;

if (propellantStatus == "Nominal" || propellantStatus == "Very Stable" )
propellantState = UllageState.VeryStable;
else if (propellantStatus == "Stable")
propellantState = UllageState.Stable;
else if (propellantStatus == "Risky")
propellantState = UllageState.Risky;
else if (propellantStatus == "Very Risky")
propellantState = UllageState.VeryRisky;
else if (propellantStatus == "Unstable")
propellantState = UllageState.Unstable;
else if (propellantStatus == "Very Unstable")
propellantState = UllageState.VeryUnstable;
else {
propellantState = UllageState.VeryStable;
Debug.Log("BUG: Unknown propellantStatus from RealFuels: " + propellantStatus);
}

if (propellantState < lowestUllage)
{
stableUllage = false;
lowestUllage = propellantState;
}
}

Expand Down

0 comments on commit 00747f8

Please sign in to comment.