-
Notifications
You must be signed in to change notification settings - Fork 0
/
transfer_funcs.ks
275 lines (231 loc) · 8.38 KB
/
transfer_funcs.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
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
function time_to_pa
{
// returns the time until the given target phase angle
// Assumes moving prograde and that PA is getting smaller over time
parameter target_angle.
local ang1 is get_phase_angle().
local t1 is time:seconds.
wait 10.
local ang2 is get_phase_angle().
if (ang2 > ang1) set ang1 to ang1 + 360.
local t2 is time:seconds.
local rate_change is (ang1 - ang2) /(t2 - t1).
local angle_left is "x".
local phase_angle is get_phase_angle().
local tcalc is time:seconds.
set phase_angle to phase_angle - target_angle.
if (phase_angle < 2) set phase_angle to phase_angle + 360.
local time_left is phase_angle / rate_change.
return time_left.
}
function moon_midcourse_correction
{
print "Doing Mid-Course Correction".
local wait_time is "x".
local wait_end is "x".
local step_sizes is "x".
if (ship:orbit:hasnextpatch = false or ship:orbit:nextpatch:body <> target)
{
set wait_time to eta:apoapsis/3.
set wait_end to time:seconds + wait_time + 15.
set step_sizes to list(100, 10, 1, 0.1, 0.01).
}
else
{
local time_body is ship:orbit:nextpatcheta.
set wait_time to time_body/2 - 120.
set wait_end to time:seconds + wait_time + 15.
set step_sizes to list(10, 1, 0.1, 0.01).
}
do_warp(wait_time).
wait until time:seconds > wait_end.
local step_sizes is list(100, 10, 1, 0.1, 0.01).
local min_start is time:seconds + 120.
local params is list(0, 0).
set params to converge_on_mnv(params, score_moon_midcourse_correction@, list(10000, next_inc), min_start, step_sizes).
set mnv to node(min_start, 0, params[0], params[1]).
print "Maneuver Burn:".
print mnv.
add_maneuver(mnv).
execute_mnv().
wait 5.
}
function transfer_orbit_moon
{
local t_semi_major is (ship:orbit:semimajoraxis + target:orbit:semimajoraxis)/2.
local transit_time is 2*constant:pi*sqrt(t_semi_major^3/body:mu).
local transfer_angle is 180 - 180*transit_time/target:orbit:period.
print "Transfer Angle: " + transfer_angle.
until false
{
local time_to_mnv is time_to_pa(transfer_angle).
local time_of_mnv is time:seconds + time_to_mnv.
local vinit is velocityat(ship, time_of_mnv):orbit:mag.
local burn_radius is ship:body:altitudeof(positionat(ship, time_of_mnv)) + ship:body:radius.
local transfer_vel is sqrt(ship:body:mu * (2/burn_radius - 1/t_semi_major)).
local dv is transfer_vel - vinit.
local mnv is node(timestamp(time_of_mnv), 0, 0, dv).
add_maneuver(mnv).
if (mnv:orbit:hasnextpatch = true and mnv:orbit:nextpatch:body <> target)
{
remove_maneuver(mnv).
print "Waiting 1 Orbit to avoid interaction".
local wait_time is ship:orbit:period.
local wait_end is time:seconds + wait_time + 5.
do_warp(wait_time).
wait until time:seconds > wait_end.
}
else
{
print "Transfer Maneuver:".
print mnv.
break.
}
}
execute_mnv().
}
function transfer_orbit_interplanetary
{
local t_semi_major is (ship:body:orbit:semimajoraxis + target:orbit:semimajoraxis)/2.
local burn_radius is ship:body:orbit:semimajoraxis.
local body_vel is body:velocity:orbit - sun:velocity:orbit.
local transfer_vel is sqrt(ship:body:body:mu * (2/burn_radius - 1/t_semi_major)) - body_vel:mag.
until false
{
local ejection_angle is calc_ejection_angle(transfer_vel).
print ejection_angle.
local ang is current_ejection_angle().
print ang.
local ang_left is ejection_angle - ang.
if (ang_left < 0) set ang_left to 360 + ang_left.
local time_to_mnv is ship:orbit:period * ang_left / 360.
local time_of_mnv is time:seconds + time_to_mnv.
local r1 is ship:body:altitudeof(positionat(ship, time_of_mnv)) + ship:body:radius.
local r2 is body:soiradius.
local wanted_v is sqrt((r1 * (r2*transfer_vel*transfer_vel - 2*body:mu) + 2*r2*body:mu) / (r1*r2)).
local vinit is velocityat(ship, time_of_mnv):orbit:mag.
local dv is wanted_v - vinit.
local mnv is node(timestamp(time_of_mnv), 0, 0, dv).
add_maneuver(mnv).
if (mnv:orbit:nextpatch:body <> sun)
{
remove_maneuver(mnv).
print "Waiting 1 Orbit to avoid interaction".
local wait_time is ship:orbit:period.
local wait_end is time_seconds + wait_time + 10.
do_warp(wait_time).
wait until time:seconds > wait_end.
}
else
{
print "Transfer Maneuver:".
print mnv.
break.
}
}
execute_mnv().
}
function calc_ejection_angle
{
// Returns the ejection angle for transfer burn to target
parameter v_inf. // velocity you need to have relative to the current body when leaving its SOI
set v_esc to sqrt(2 * body:mu / ship:orbit:semimajoraxis). // escape velocity from parking orbit.
set v to sqrt ( v_esc^2 + v_inf^2). // velocity of hyperbolic trajectory at periapsis
set r to ship:orbit:semimajoraxis.
set L to v * r. // v-cross-r, without direction
set En to v^2/2 - body:mu / r. //specific orbital energy. Is negative unless you're on an escape trajectory
set e to sqrt(1 + (2*En*L^2)/(body:mu ^2)). // eccentricity. Should be > 1.
set theta to arccos(1/e).
set theta to 180 - theta.
if (target:orbit:semimajoraxis > body:orbit:semimajoraxis) set theta to 360 - theta.
else set theta to 180 - theta.
return theta.
}
function current_ejection_angle
{
// returns the angle between orbiting body prograde and ship prograde
// returns false if current body is Kerbol
if (ship:body = sun) return false.
local ship_vel is ship:velocity:orbit.
local body_vel is body:velocity:orbit - sun:velocity:orbit.
local ship_vel_sun is ship_vel - sun:velocity:orbit.
local orb_vel1 is ship_vel_sun:mag - body_vel:mag.
wait 0.1.
set ship_vel to ship:velocity:orbit.
set body_vel to body:velocity:orbit - sun:velocity:orbit.
set ship_vel_sun to ship_vel - sun:velocity:orbit.
set ang to vang(ship_vel, body_vel).
local orb_vel2 is ship_vel_sun:mag - body_vel:mag.
if (orb_vel2 > orb_vel1) set ang to 360 - ang.
return ang - 90.
}
function capture_next_body
{
lock steering to retrograde.
print "Warping to Next Body".
local old_body is ship:body.
do_warp(ship:orbit:nextpatcheta).
wait until ship:body <> old_body.
wait 5.
adjust_apsides("p", next_ap).
lock steering to retrograde.
wait 5.
local diff1 is abs(ship:apoapsis - next_ap).
local diff2 is abs(ship:periapsis - next_pe).
if (diff1 < diff2) adjust_apsides("a", next_pe).
else adjust_apsides("p", next_ap).
wait 5.
}
function moon_transfer_functions
{
// Need to set global next_ap, next_pe, next_inc and set target
transfer_orbit_moon().
wait 5.
deploy_payload("payload").
activate_engines().
wait 5.
moon_midcourse_correction().
wait 5.
capture_next_body().
}
function moon_transfer
{
// Parking Orbit Params
global target_ap_km is 120.
global target_pe_km is target_ap_km.
global target_inc is 0.
global target_ap is target_ap_km*1000.
global target_pe is target_pe_km*1000.
// Target Body Orbit Params
local tbody is Mun.
set target to tbody.
global next_inc is 57.
global next_ap_km is 50.
global next_pe_km is next_ap_km.
global next_ap is next_ap_km * 1000.
global next_pe is next_pe_km * 1000.
// do launch until apoapsis in parking orbit
launch_to_ap(true).
lights on.
set steeringmanager:maxstoppingtime to 2.
deploy_solar_panels().
deploy_antenna().
deploy_dp_shield().
transfer_orbit_moon().
wait 5.
// deploy_payload("payload").
// wait 2.
// if (kuniverse:activevessel <> core:vessel)
// {
// kuniverse:forcesetactivevessel(core:vessel).
// unlock steering.
// set target to tbody.
// AG1 on.
// wait 10.
// }
// activate_engines().
moon_midcourse_correction().
wait 5.
capture_next_body().
print "In Moon Orbit".
}