Skip to content

Commit

Permalink
More attitude control buttons
Browse files Browse the repository at this point in the history
Adds the ability to completely suppress actuation on any axis.

When actuation is suppressed the BetterController doesn't windup
on that axis.

Also adds the (presently unused) ability for external modules to
set a manual target omega (to be used for spin-up).

Also re-fixes launch wobblies.  There's now small wobble that happens
when steering kicks in at 5m above the pad, but there's no windup and
we should have lots of torque by then.

I don't want to fly completely unguided until we clear the pad and
roll because asymmetric thrust vehicles will probably start to flip
on launch (they may start to flip a bit already as it is).

Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
  • Loading branch information
lamont-granquist committed Jun 20, 2021
1 parent 46b890e commit 7ba8fc6
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 33 deletions.
46 changes: 28 additions & 18 deletions MechJeb2/AttitudeControllers/BetterController.cs
Expand Up @@ -230,28 +230,35 @@ private void UpdatePredictionPI()
if (_maxAlpha[i] == 0)
_maxAlpha[i] = 1;

// the cube root scaling was determined mostly via experience
double maxAlphaCbrt = Math.Pow(_maxAlpha[i], 1.0 / 3.0);
double effLD = maxAlphaCbrt * PosFactor;
double posKp = Math.Sqrt(_maxAlpha[i] / (2 * effLD));

if (Math.Abs(error) <= 2 * effLD)
// linear ramp down of acceleration
_targetOmega[i] = -posKp * error;
if (ac.OmegaTarget[i].IsFinite())
{
_targetOmega[i] = ac.OmegaTarget[i];
}
else
// v = - sqrt(2 * F * x / m) is target stopping velocity based on distance
_targetOmega[i] = -Math.Sqrt(2 * _maxAlpha[i] * (Math.Abs(error) - effLD)) * Math.Sign(error);

if (useStoppingTime)
{
_maxOmega[i] = _maxAlpha[i] * maxStoppingTime;
if (useFlipTime) _maxOmega[i] = Math.Max(_maxOmega[i], Math.PI / minFlipTime);
_targetOmega[i] = MuUtils.Clamp(_targetOmega[i], -_maxOmega[i], _maxOmega[i]);
// the cube root scaling was determined mostly via experience
double maxAlphaCbrt = Math.Pow(_maxAlpha[i], 1.0 / 3.0);
double effLD = maxAlphaCbrt * PosFactor;
double posKp = Math.Sqrt(_maxAlpha[i] / (2 * effLD));

if (Math.Abs(error) <= 2 * effLD)
// linear ramp down of acceleration
_targetOmega[i] = -posKp * error;
else
// v = - sqrt(2 * F * x / m) is target stopping velocity based on distance
_targetOmega[i] = -Math.Sqrt(2 * _maxAlpha[i] * (Math.Abs(error) - effLD)) * Math.Sign(error);

if (useStoppingTime)
{
_maxOmega[i] = _maxAlpha[i] * maxStoppingTime;
if (useFlipTime) _maxOmega[i] = Math.Max(_maxOmega[i], Math.PI / minFlipTime);
_targetOmega[i] = MuUtils.Clamp(_targetOmega[i], -_maxOmega[i], _maxOmega[i]);
}

if (useControlRange && _errorTotal * Mathf.Rad2Deg > rollControlRange)
_targetOmega[1] = 0;
}

if (useControlRange && _errorTotal * Mathf.Rad2Deg > rollControlRange)
_targetOmega[1] = 0;

_pid[i].Kp = VelKp / (_maxAlpha[i] * warpFactor);
_pid[i].Ki = VelKi / (_maxAlpha[i] * warpFactor * warpFactor);
_pid[i].Kd = VelKd / _maxAlpha[i];
Expand All @@ -271,6 +278,9 @@ private void UpdatePredictionPI()
_actuation[i] = 0;

_targetTorque[i] = _actuation[i] / ac.torque[i];

if (ac.ActuationControl[i] == 0)
Reset(i);
}

_error1 = _error0;
Expand Down
22 changes: 10 additions & 12 deletions MechJeb2/MechJebModuleAscentAutopilot.cs
Expand Up @@ -23,10 +23,10 @@ public class MechJebModuleAscentAutopilot : ComputerModule
// this is the public API for ascentPathIdx which is enum type and does wiring
public ascentType ascentPathIdxPublic {
get {
return (ascentType) this.ascentPathIdx;
return (ascentType) ascentPathIdx;
}
set {
this.ascentPathIdx = (int) value;
ascentPathIdx = (int) value;
doWiring();
}
}
Expand Down Expand Up @@ -76,7 +76,7 @@ public bool autostage
_autostage = value;
if (changed)
{
if (_autostage && this.enabled) core.staging.users.Add(this);
if (_autostage && enabled) core.staging.users.Add(this);
if (!_autostage) core.staging.users.Remove(this);
}
}
Expand Down Expand Up @@ -334,7 +334,7 @@ void DriveCircularizationBurn(FlightCtrlState s)
{
if (!vessel.patchedConicsUnlocked() || skipCircularization)
{
this.users.Clear();
users.Clear();
return;
}

Expand All @@ -349,7 +349,7 @@ void DriveCircularizationBurn(FlightCtrlState s)
if (recorder != null) launchLANDifference = vesselState.orbitLAN - recorder.markLAN;

//finished circularize
this.users.Clear();
users.Clear();
return;
}
}
Expand Down Expand Up @@ -423,8 +423,8 @@ private MechJebModuleAscentMenuBase ascentMenuForType(ascentType type)
{
if ( type == ascentType.CLASSIC )
return core.GetComputerModule<MechJebModuleAscentClassicMenu>();
else
return null;

return null;
}

}
Expand All @@ -436,13 +436,11 @@ public abstract class MechJebModuleAscentMenuBase : DisplayModule

public abstract class MechJebModuleAscentBase : ComputerModule
{
public MechJebModuleAscentBase(MechJebCore core) : base(core) { }
protected MechJebModuleAscentBase(MechJebCore core) : base(core) { }

public string status { get; set; }
public string status { get; protected set; }

public MechJebModuleAscentAutopilot autopilot { get { return core.GetComputerModule<MechJebModuleAscentAutopilot>(); } }
private MechJebModuleStageStats stats { get { return core.GetComputerModule<MechJebModuleStageStats>(); } }
private FuelFlowSimulation.FuelStats[] vacStats { get { return stats.vacStats; } }
protected MechJebModuleAscentAutopilot autopilot => core.GetComputerModule<MechJebModuleAscentAutopilot>();

public abstract bool DriveAscent(FlightCtrlState s);

Expand Down
4 changes: 4 additions & 0 deletions MechJeb2/MechJebModuleAscentPVG.cs
@@ -1,5 +1,6 @@
using System;
using KSP.Localization;
using UnityEngine;

/*
* Optimized launches for RSS/RO
Expand Down Expand Up @@ -184,8 +185,11 @@ private void DriveVerticalAscent(FlightCtrlState s)

bool liftedOff = vessel.LiftedOff() && !vessel.Landed && vesselState.altitudeBottom > 5;

core.attitude.SetActuationControl(liftedOff, liftedOff, liftedOff);
core.attitude.SetAxisControl(liftedOff, liftedOff, liftedOff && vesselState.altitudeBottom > autopilot.rollAltitude);

Debug.Log($"actuation control: {core.attitude.ActuationControl}");

if (!liftedOff)
{
status = Localizer.Format("#MechJeb_Ascent_status12"); //"Awaiting liftoff"
Expand Down
22 changes: 19 additions & 3 deletions MechJeb2/MechJebModuleAttitudeController.cs
Expand Up @@ -42,7 +42,9 @@ public class MechJebModuleAttitudeController : ComputerModule

private AttitudeReference _attitudeReference = AttitudeReference.INERTIAL;

public Vector3d AxisControl { get; private set; } = Vector3d.one;
public Vector3d AxisControl { get; private set; } = Vector3d.one;
public Vector3d ActuationControl { get; private set; } = Vector3d.one;
public Vector3d OmegaTarget { get; private set; } = new Vector3d(double.NaN, double.NaN, double.NaN);

public BaseAttitudeController Controller { get; private set; }
private readonly List<BaseAttitudeController> _controllers = new List<BaseAttitudeController>();
Expand All @@ -59,6 +61,9 @@ public void SetActiveController(int i)
public override void OnModuleEnabled()
{
timeCount = 50;
SetAxisControl(true, true, true);
SetActuationControl(true, true, true);
SetOmegaTarget();
Controller.OnModuleEnabled();
}

Expand Down Expand Up @@ -144,8 +149,17 @@ public override void OnSave(ConfigNode local, ConfigNode type, ConfigNode global

public void SetAxisControl(bool pitch, bool yaw, bool roll)
{
AxisControl = new Vector3d(pitch ? 1 : 0, roll ? 1 : 0, yaw ? 1 : 0
);
AxisControl = new Vector3d(pitch ? 1 : 0, roll ? 1 : 0, yaw ? 1 : 0);
}

public void SetActuationControl(bool pitch, bool yaw, bool roll)
{
ActuationControl = new Vector3d(pitch ? 1 : 0, roll ? 1 : 0, yaw ? 1 : 0);
}

public void SetOmegaTarget(double pitch = double.NaN, double yaw = double.NaN, double roll = double.NaN)
{
OmegaTarget = new Vector3d(pitch, yaw, roll);
}

public Quaternion attitudeGetReferenceRotation(AttitudeReference reference)
Expand Down Expand Up @@ -369,6 +383,8 @@ public override void Drive(FlightCtrlState s)
Vector3d deltaEuler;
Controller.DrivePre(s, out act, out deltaEuler);

act.Scale(ActuationControl);

SetFlightCtrlState(act, deltaEuler, s, 1);

act = new Vector3d(s.pitch, s.roll, s.yaw);
Expand Down

0 comments on commit 7ba8fc6

Please sign in to comment.