-
Notifications
You must be signed in to change notification settings - Fork 0
/
libcapture.ks
200 lines (142 loc) · 5.24 KB
/
libcapture.ks
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Planetary Tranfer Library
@lazyglobal off.
run once libguido.
run once libtransfer.
// Orbit table
// Format is Body, Standard Orbit, Aerocapture Orbit, Departure Orbit
declare global orbit_table to list(
list(Kerbin, 150, 45, 1000),
list(Duna, 100, 15, 500),
list(Eve, 200, 90, 500 ),
list(Dres, 100, 100, 500)
).
function get_orbit_data {
parameter dst.
declare local p to 0.
for p in orbit_table {
if ship:orbit:body = p[0] {
return p.
}
}
print "orbital parameter lookup failed for "+dst.
return list(0,0,0).
}
// Get into a stable orbit around a planet or moon
// Assumes we are already in the SOI of the planet
//
// Parameters: Destination, target altitude (0 for capture), yes/no flag if we should try to fix inclination.
function capture_1 {
parameter dst is ship:orbit:body.
parameter dst_alt is -1.
parameter wrp is 0.
declare local s to "".
// If no altitude was specified, figure it out
if dst_alt <= 0 {
local p_data is get_orbit_data(dst).
if dst_alt = 0 {
// Aerocapture
set dst_alt to p_data[2]*1000.
set s to ", aerocapture".
} else {
set dst_alt to p_data[1]*1000.
set s to ", standard orbit".
}
}
print "Capture mode for "+dst:name+" target alt "+km(dst_alt)+s.
// Error checking that we in the right spot.
if dst = ship:orbit:body {
print "in SOI of "+body:name+" pe: "+floor(ship:periapsis).
if ship:apoapsis > 0 AND ship:periapsis > dst_alt*0.75 {
print "We are in a stable orbit. Nothing to do.".
return True.
}
} else {
if dst:orbit:body = ship:orbit:body {
print "in SOI of "+body:name+", parent of "+dst:name+" pe: "+floor(ship:periapsis).
panic("Capture to moons not supported yet.").
return False.
} else {
print "Error: destination"+dst:name+" is not in orbit of "+body:name.
panic("Wrong planet?").
}
}
// If there is no maneuver node, create one.
local mynode is NODE(600+time:seconds,0,0,0).
if NOT hasnode { ADD mynode. }
else set mynode to nextnode.
local old_node to list(mynode:prograde, mynode:normal, mynode:radialout, mynode:eta+time:seconds).
local n_pro to 0.
local n_nor to 0.
local n_rad to 0.
local step to 20.
local v to 0.
local i to 0.
local pe to calc_pe(mynode,0).
local original_pe to pe.
local old_pe to 0.
local old_i to 0.
local old_i2 to 0.
clr_status().
// Burn retro
// Goal is to set/keep PE to target by going radial to raise and retrograde to lower
set step to 1.
set pe to vary_node(mynode, old_node, n_pro, n_nor, n_rad, 0, 0).
until mynode:orbit:apoapsis > 0 AND mynode:orbit:apoapsis < 100000000 AND pe > dst_alt {
set old_pe to pe.
if pe < dst_alt {
// Vary radial, in whichever direction increases the PE.
set v to vary_node(mynode, old_node, n_pro, n_nor, n_rad+step, 0, 0).
if v > old_pe {
set n_rad to n_rad+step.
} else {
set v to vary_node(mynode, old_node, n_pro, n_nor, n_rad-step, 0, 0).
if v > old_pe {
set n_rad to n_rad-step.
}
}
} else {
// PE is not too low, burn retrograde
set n_pro to n_pro-step.
}
set pe to vary_node(mynode, old_node, n_pro, n_nor, n_rad, 0, 0).
p_status("PE: "+km(pe)+" ("+percent(pe, original_pe)+")",1).
p_status("Incl:"+round(i ,1),2).
p_status("Pro: "+round(n_pro,2),3).
p_status("Nor: "+round(n_nor,2),4).
p_status("Rad: "+round(n_rad,2),5).
p_status("step:"+round(step,2),6).
}
print "Maneuver pe: "+km(mynode:orbit:periapsis)+" incl:"+mynode:orbit:inclination..
exec_n(nextnode,wrp).
wait 1.
myquicksave("x6-dstorbit-1").
}
function capture_2 {
parameter dst_alt.
parameter wrp is 0.
if ship:apoapsis > 0 AND ship:apoapsis < dst_alt*1.1 AND ship:periapsis > dst_alt*0.9 {
print "Orbit looking good enough. Capture module done.".
return True.
}
// Now plan the Periapsis burn.
// This time we can simply calculate with VV equations.
local dv is vv_circular(ship:periapsis)-vv_alt(ship:periapsis).
local mynode is NODE(eta:periapsis+time:seconds,0,0,dv).
ADD mynode.
print "breaking at PE for "+round(dv,1)+" m/s".
exec_n(nextnode,wrp).
print "Welcome to "+body:name+" ap/pe: "+km(ship:apoapsis)+" / "+km(ship:periapsis).
myquicksave("x7-dstorbit-2").
}
function capture {
parameter dst.
parameter dst_alt is -1.
parameter wrp is 0.
if ship:orbit:body <> dst {
print "Wrong planet?".
return False.
}
// Twice seems to work better
capture_1(dst, dst_alt,wrp).
capture_2(dst_alt,wrp).
}