/
OperationPlane.cs
117 lines (103 loc) · 4.52 KB
/
OperationPlane.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
extern alias JetBrainsAnnotations;
using System.Collections.Generic;
using JetBrainsAnnotations::JetBrains.Annotations;
using KSP.Localization;
namespace MuMech
{
[UsedImplicitly]
public class OperationPlane : Operation
{
private static readonly string _name = Localizer.Format("#MechJeb_match_planes_title");
public override string GetName() => _name;
private static readonly TimeReference[] _timeReferences =
{
TimeReference.REL_HIGHEST_AD, TimeReference.REL_NEAREST_AD, TimeReference.REL_ASCENDING, TimeReference.REL_DESCENDING
};
private static readonly TimeSelector _timeSelector = new TimeSelector(_timeReferences);
public override void DoParametersGUI(Orbit o, double universalTime, MechJebModuleTargetController target) => _timeSelector.DoChooseTimeGUI();
protected override List<ManeuverParameters> MakeNodesImpl(Orbit o, double universalTime, MechJebModuleTargetController target)
{
double ut = _timeSelector.ComputeManeuverTime(o, universalTime, target);
if (!target.NormalTargetExists)
{
throw new OperationException(Localizer.Format("#MechJeb_match_planes_Exception1")); //must select a target to match planes with.
}
if (o.referenceBody != target.TargetOrbit.referenceBody)
{
throw
new OperationException(
Localizer.Format("#MechJeb_match_planes_Exception2")); //can only match planes with an object in the same sphere of influence.
}
bool anExists = o.AscendingNodeExists(target.TargetOrbit);
bool dnExists = o.DescendingNodeExists(target.TargetOrbit);
double anTime = 0;
double dnTime = 0;
Vector3d anDeltaV = anExists
? OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesAscending(o, target.TargetOrbit, ut, out anTime)
: Vector3d.zero;
Vector3d dnDeltaV = anExists
? OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesDescending(o, target.TargetOrbit, ut, out dnTime)
: Vector3d.zero;
Vector3d dV;
if (_timeSelector.TimeReference == TimeReference.REL_ASCENDING)
{
if (!anExists)
{
throw new OperationException(Localizer.Format("#MechJeb_match_planes_Exception3")); //ascending node with target doesn't exist.
}
ut = anTime;
dV = anDeltaV;
}
else if (_timeSelector.TimeReference == TimeReference.REL_DESCENDING)
{
if (!dnExists)
{
throw new OperationException(Localizer.Format("#MechJeb_match_planes_Exception4")); //descending node with target doesn't exist.
}
ut = dnTime;
dV = dnDeltaV;
}
else if (_timeSelector.TimeReference == TimeReference.REL_NEAREST_AD)
{
if (!anExists && !dnExists)
{
throw new OperationException(
Localizer.Format("#MechJeb_match_planes_Exception5")); //neither ascending nor descending node with target exists.
}
if (!dnExists || anTime <= dnTime)
{
ut = anTime;
dV = anDeltaV;
}
else
{
ut = dnTime;
dV = dnDeltaV;
}
}
else if (_timeSelector.TimeReference == TimeReference.REL_HIGHEST_AD)
{
if (!anExists && !dnExists)
{
throw new OperationException(
Localizer.Format("#MechJeb_match_planes_Exception5")); //neither ascending nor descending node with target exists.
}
if (!dnExists || anDeltaV.magnitude <= dnDeltaV.magnitude)
{
ut = anTime;
dV = anDeltaV;
}
else
{
ut = dnTime;
dV = dnDeltaV;
}
}
else
{
throw new OperationException(Localizer.Format("#MechJeb_match_planes_Exception6")); //wrong time reference.
}
return new List<ManeuverParameters> { new ManeuverParameters(dV, ut) };
}
}
}