/
MechJebModuleSpinupController.cs
97 lines (76 loc) · 2.98 KB
/
MechJebModuleSpinupController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
* Copyright Lamont Granquist (lamont@scriptkiddie.org)
* Dual licensed under the MIT (MIT-LICENSE) license
* and GPLv2 (GPLv2-LICENSE) license or any later version.
*/
#nullable enable
using System;
using JetBrains.Annotations;
namespace MuMech
{
[UsedImplicitly]
public class MechJebModuleSpinupController : ComputerModule
{
private enum SpinupState { INITIALIZED, STARTING, STABILIZING, SPINUP, FINISHED }
public double RollAngularVelocity = 0;
public MechJebModuleSpinupController(MechJebCore core) : base(core)
{
}
private SpinupState _state;
private double _startTime;
public override void OnModuleEnabled()
{
_state = SpinupState.INITIALIZED;
_startTime = Math.Max(vesselState.time, _startTime);
core.Attitude.users.Add(this);
}
public override void OnModuleDisabled()
{
_state = SpinupState.FINISHED;
core.Attitude.SetOmegaTarget(roll: double.NaN);
core.Attitude.SetActuationControl();
// FIXME: this might overwrite someone else, but the only other consumer so far is the GuidanceController
core.Staging.autostageLimitInternal = 0;
core.Attitude.users.Remove(this);
base.OnModuleDisabled();
}
public override void OnStart(PartModule.StartState state)
{
GameEvents.onStageActivate.Add(HandleStageEvent);
}
public override void OnDestroy()
{
GameEvents.onStageActivate.Remove(HandleStageEvent);
}
private void HandleStageEvent(int data)
{
// wait a second to enable after staging because aerodynamics may kick us,
// but on the first tick we may think we are stable
_startTime = vesselState.time + 1.0;
}
public override void Drive(FlightCtrlState s)
{
if (_state == SpinupState.INITIALIZED)
return;
core.Staging.autostageLimitInternal = vessel.currentStage;
if (vesselState.time < _startTime)
return;
if (_state == SpinupState.STARTING)
_state = SpinupState.STABILIZING;
if (vessel.angularVelocityD.y / RollAngularVelocity >= 0.99)
enabled = false;
if (!vessel.ActionGroups[KSPActionGroup.RCS])
vessel.ActionGroups.SetGroup(KSPActionGroup.RCS, true);
if (_state == SpinupState.STABILIZING && (core.Attitude.attitudeAngleFromTarget() > 1.0 || core.vessel.angularVelocity.magnitude > 0.001))
return;
_state = SpinupState.SPINUP;
core.Attitude.SetOmegaTarget(roll: RollAngularVelocity);
core.Attitude.SetActuationControl(false, false);
}
public void AssertStart()
{
if (_state == SpinupState.INITIALIZED)
_state = SpinupState.STARTING;
}
}
}