-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkoslib.ks
More file actions
337 lines (286 loc) · 7.77 KB
/
koslib.ks
File metadata and controls
337 lines (286 loc) · 7.77 KB
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
// KOS LIB
// These are generally informational and convenience functions. They can stage,
// but generally don't point or throttle.
function angdiff {
parameter src.
parameter tgt.
set a to tgt - src.
set a to mod(a + 180, 360) - 180.
return a.
}
function xyz2enu {
parameter vin.
// Rotation angles for rotation matrix:
set a to latitude.
set CosA to cos(a).
set SinA to sin(a).
set b to -up:yaw. // use UP:yaw like it was longitude
set CosB to cos(b).
set SinB to sin(b).
// The rotation matrix around z axis (latitude) then y axis (longitude):
set vout to V(0, 0, 0).
set vout:x to -vin:x*CosB + 0 + -vin:z*SinB .
set vout:y to vin:x*SinA*SinB + vin:y*CosA + -vin:z*SinA*CosB.
set vout:z to -vin:x*CosA*SinB + vin:y*SinA + vin:z*CosA*CosB .
return vout.
}
function enu2xyz {
parameter vin.
// Rotation angles for rotation matrix:
set a to latitude.
set CosA to cos(a).
set SinA to sin(a).
set b to -up:yaw. // use UP:yaw like it was longitude
set CosB to cos(b).
set SinB to sin(b).
// The rotation matrix around z axis (latitude) then y axis (longitude):
set vout to V(0, 0, 0).
set vout:x to -vin:x*CosB + vin:y*SinA*SinB + -vin:z*CosA*SinB.
set vout:y to 0 + vin:y*CosA + vin:z*SinA .
set vout:z to -vin:x*SinB + -vin:y*SinA*CosB + vin:z*CosA*CosB .
return vout.
}
function term {
core:part:getmodule("kOSProcessor"):doevent("Open Terminal").
}
function str {
parameter param_in.
set param_in to param_in:replace("\''", char(34)).
return param_in.
}
function runner {
parameter name.
if exists("run_helper.ks") {
deletepath("run_helper.ks").
}
log str("run \''" + name + "\''.") to "run_helper.ks".
run run_helper.ks.
}
function disp {
parameter msg.
parameter delay is 5.
parameter style is 2.
parameter size is 24.
parameter color is green.
parameter echo is false.
hudtext(msg, delay, style, size, color, echo).
}
function warn {
parameter msg.
parameter delay is 5.
parameter style is 2.
parameter size is 24.
parameter color is yellow.
parameter echo is false.
hudtext(msg, delay, style, size, color, echo).
}
function error {
parameter msg.
parameter delay is 10.
parameter style is 2.
parameter size is 36.
parameter color is red.
parameter echo is false.
hudtext(msg, delay, style, size, color, echo).
}
// Time to closest approach with target
function closest_approach_eta {
function distance_at_t {
parameter t.
return (positionat(ship, t) - positionat(target, t)):mag.
}
local start is time:seconds.
return btls(distance_at_t@, start, 10, 0.1) - start.
}
function normang {
parameter a.
set a to posang(a).
if a > 180 {
set a to a - 360.
}
return a.
}
function posang {
parameter a.
return mod(a + 360, 360).
}
function pos {
parameter x.
return max(0, x).
}
function neg {
parameter x.
return min(0, x).
}
// Minimize a 1D pseudoconvex function via backtracking line search
function btls {
parameter objective.
parameter guess.
parameter forward_step.
parameter backward_step.
parameter line is 0.
local last is objective(guess).
local now is last.
// Forward search
print "Forward search:" at (0, line).
until now > last {
set last to now.
set guess to guess + forward_step.
set now to objective(guess).
print "Guessing " + round(guess, 2) at (0, line + 1).
print "Obj is " + round(now, 2) at (0, line + 2).
}
// Backtrack.
print "Backward search:" at (0, line + 3).
set last to now.
until now > last {
set last to now.
set guess to guess - backward_step.
set now to objective(guess).
print "Guessing " + round(guess, 2) at (0, line + 4).
print "Obj is " + round(now, 2) at (0, line + 5).
}
return guess.
}
// Get the TWR relative to Kerbin's surface
function get_twr {
set g to 9.81.
return ship:availablethrust / (ship:mass * g).
}
// Get a G-limited throttle, accounting for SRBs
function glimited_throttle {
parameter glimit.
set g to 9.81.
set fixed_tr to 0.
set float_tr to 0.
list engines in engs.
for eng in engs {
if eng:ignition {
if eng:allowshutdown {
set float_tr to float_tr + eng:availablethrust.
} else {
set fixed_tr to fixed_tr + eng:availablethrust.
}
}
}
if float_tr > 0 {
return clip((glimit * g * ship:mass - fixed_tr) / float_tr, 0, 1).
} else {
return 1.
}
}
// Get the ship radial direction
function radial {
return vectorcrossproduct(prograde:vector, antinormal()).
}
// Get the ship normal direction
function antiradial {
return -1 * radial().
}
// Get the ship normal direction
function normal {
return vectorcrossproduct(prograde:vector, up:vector).
}
// Get the ship antinormal direction
function antinormal {
return -1 * normal().
}
// Find height of cpu above bottom of craft.
function craft_height {
list parts in partList.
local lp is 0.//lowest part height
local hp is 0.//hightest part height
for p in partList{
local cp is facing:vector * p:position.
if cp < lp
set lp to cp.
else if cp > hp
set hp to cp.
}
return hp - lp.
}
// Clip a value.
function clip {
parameter v. // value
parameter a. // low
parameter b. // high
return max(min(v, b), a).
}
// Determines the precise burn duration for a given dV.
function burn_time {
parameter dv.
parameter thrust is ship:availablethrust.
local f is thrust.
local m is ship:mass.
local e is constant:e.
local i is available_isp().
local g is 9.81.
return g * m * i * (1 - e^(-dv / (g * i))) / f.
}
// Assuming only one type of ignited engine, gets current ISP.
// TODO: Can handle RCS thrust, if all RCS thruster included.
function available_isp {
list engines in all_engines.
for engine in all_engines {
if engine:ignition {
return engine:ISP.
}
}
//list ship:modulesnamed("moduleRCSFX") in all_rcs.
//for rcs_module in all_rcs {
// set rcs_part to rcs_module:part.
//}
}
// Kill all ignited engine
function killengines {
list engines in all_engines.
for engine in all_engines {
if engine:ignition {
engine:shutdown().
}
}
}
// Autostaging logic
function anyflameout {
list engines in all_engines.
for engine in all_engines {
if engine:flameout {
return true.
}
}
return false.
}
function handleflameout {
// If there are no other engines running coast for a bit
if maxthrust = 0 {
disp("MECO detected").
disp("Coasting for " + stage_coast + "s").
set t0 to time:seconds.
on time:seconds {
print sec2timestr(time:seconds - t0) at (0, 2).
if time:seconds > stage_coast + t0 {
stage.
disp(stage_wait + "s hold to clear debris").
set t0 to time:seconds.
when time:seconds > stage_wait + t0 then {
stage.
when anyflameout() then {
return handleflameout().
}
}
return false.
}
return true.
}
// If there are still engines running just decouple immediately.
} else {
disp("BECO detected").
stage.
return true.
}
}
// Human-readable time display function
function sec2timestr {
parameter t.
return (t + time - time):clock.
}