/
OperationTransfer.cs
126 lines (104 loc) · 5.06 KB
/
OperationTransfer.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
118
119
120
121
122
123
124
125
126
using System.Collections.Generic;
using JetBrains.Annotations;
using KSP.Localization;
using UnityEngine;
namespace MuMech
{
[UsedImplicitly]
public class OperationGeneric : Operation
{
public override string GetName() { return Localizer.Format("#MechJeb_Hohm_title"); } //bi-impulsive (Hohmann) transfer to target
[UsedImplicitly]
public bool InterceptOnly;
[UsedImplicitly]
[Persistent(pass = (int)Pass.GLOBAL)]
public EditableDouble PeriodOffset = 0;
[Persistent(pass = (int)Pass.GLOBAL)]
public EditableTime MinDepartureUT = 0;
[Persistent(pass = (int)Pass.GLOBAL)]
public EditableTime MaxDepartureUT = 0;
[UsedImplicitly]
[Persistent(pass = (int)Pass.GLOBAL)]
public bool SimpleTransfer;
private readonly TimeSelector _timeSelector;
public OperationGeneric()
{
_timeSelector = new TimeSelector(new[]
{
TimeReference.COMPUTED, TimeReference.PERIAPSIS, TimeReference.APOAPSIS, TimeReference.X_FROM_NOW, TimeReference.ALTITUDE,
TimeReference.EQ_DESCENDING, TimeReference.EQ_ASCENDING, TimeReference.REL_NEAREST_AD, TimeReference.REL_ASCENDING,
TimeReference.REL_DESCENDING, TimeReference.CLOSEST_APPROACH
});
}
public override void DoParametersGUI(Orbit o, double universalTime, MechJebModuleTargetController target)
{
InterceptOnly =
GUILayout.Toggle(InterceptOnly, Localizer.Format("#MechJeb_Hohm_intercept_only")); //intercept only, no capture burn (impact/flyby)
SimpleTransfer = GUILayout.Toggle(SimpleTransfer, Localizer.Format("#MechJeb_Hohm_simpleTransfer")); //simple coplanar Hohmann transfer
GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Hohm_Label1"), PeriodOffset); //fractional target period offset
if (!SimpleTransfer)
{
_timeSelector.DoChooseTimeGUI();
}
}
protected override List<ManeuverParameters> MakeNodesImpl(Orbit o, double universalTime, MechJebModuleTargetController target)
{
double ut;
if (!target.NormalTargetExists)
{
throw new OperationException(Localizer.Format("#MechJeb_Hohm_Exception1")); //must select a target for the bi-impulsive transfer.
}
if (o.referenceBody != target.TargetOrbit.referenceBody)
{
throw
new OperationException(
Localizer.Format("#MechJeb_Hohm_Exception2")); //target for bi-impulsive transfer must be in the same sphere of influence.
}
Vector3d dV;
Orbit targetOrbit = target.TargetOrbit;
if (PeriodOffset != 0)
{
targetOrbit = target.TargetOrbit.Clone();
targetOrbit.MutatedOrbit(PeriodOffset);
}
if (SimpleTransfer)
{
dV = OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(o, targetOrbit, universalTime, out ut);
}
else
{
if (_timeSelector.TimeReference == TimeReference.COMPUTED)
{
dV = OrbitalManeuverCalculator.DeltaVAndTimeForBiImpulsiveAnnealed(o, targetOrbit, universalTime, out ut,
intercept_only: InterceptOnly);
}
else
{
bool anExists = o.AscendingNodeExists(target.TargetOrbit);
bool dnExists = o.DescendingNodeExists(target.TargetOrbit);
if (_timeSelector.TimeReference == TimeReference.REL_ASCENDING && !anExists)
{
throw new OperationException(Localizer.Format("#MechJeb_Hohm_Exception3")); //ascending node with target doesn't exist.
}
if (_timeSelector.TimeReference == TimeReference.REL_DESCENDING && !dnExists)
{
throw new OperationException(Localizer.Format("#MechJeb_Hohm_Exception4")); //descending node with target doesn't exist.
}
if (_timeSelector.TimeReference == TimeReference.REL_NEAREST_AD && !(anExists || dnExists))
{
throw new OperationException(
Localizer.Format("#MechJeb_Hohm_Exception5")); //neither ascending nor descending node with target exists.
}
ut = _timeSelector.ComputeManeuverTime(o, universalTime, target);
dV = OrbitalManeuverCalculator.DeltaVAndTimeForBiImpulsiveAnnealed(o, targetOrbit, ut, out ut, intercept_only: InterceptOnly,
fixed_ut: true);
}
}
return new List<ManeuverParameters> { new ManeuverParameters(dV, ut) };
}
public TimeSelector GetTimeSelector() //Required for scripts to save configuration
{
return _timeSelector;
}
}
}