Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // MAIN_PROGRAM
- // a script to launch to and land at a predesignated target on the Mun, Apollo style
- // by /u/supreme_blorgon, AKA kickpuncher on Discord
- // DOES NOT INCLUDE ASCENT, RENDEZVOUS, TRANS-KERBIN INJECTION, OR REENTRY
- // also requires a lot of specific action groups, name tags, and craft construction
- // if you plan on using the script as-is, you will need to build a similar craft, or get the .craft file from me
- //to parking orbit
- clearscreen.
- lock twr to (0.84/(1+1.01^(apoapsis - 81000))) + (0.35/(1+1.01^(apoapsis - 100000))+0.25). // stair stepping sigmoid function of my own creation
- on twr {
- set throt to (twr * (mass * (9.81*(600000/(600000 + altitude))^2)) / availablethrust). // sure, it's not really practical, but it's awesome
- if twr = 0.25 return false.
- else return true.
- }
- when stage:liquidfuel < 0.1 then {
- stage. wait 5. stage.
- set throt to (0.6 * (mass * (9.81*(600000/(600000 + altitude))^2)) / availablethrust).
- toggle AG1. return false.
- }
- stage.
- set gain to 1.
- set throt to 1.
- lock throttle to throt*gain.
- set pitch to 90.
- lock steering to heading(-90,pitch).
- set throt to (twr * (mass * 9.81)) / availablethrust. // sets the throttle to meet an exact TWR, also useful for hovering, and slow, constant velocity descents
- until apoapsis >= 149999.925 {
- set pitch to min(180,(max(90,(sqrt(0.170283 * altitude) + 85)))). // basic square root function that puts me totally horizontal at about 53 km
- set gain to -(1/149999.95 * round(apoapsis,4))^128 + 1. // kills the throttle smoothly as apo approaches 150 km, for precision
- wait 0.
- }
- set throt to 0.
- set gain to 1.
- wait 5.
- warpto(time:seconds + (eta:apoapsis - 60)).
- until ship:orbit:eccentricity < 0.00001 {
- set throt to (availablethrust/(6.2784*mass))*constant:e^(-0.0025*constant:e^(((availablethrust/(6.2784*mass))^1.4696)*min(30,eta:apoapsis))). // black magic, sorry
- wait 0.
- }
- set throt to 0.
- set gain to 1.
- set pitch to 180.
- wait 5.
- warpto(time:seconds + ship:orbit:period).
- //trans-Munar injection
- until false {
- set mun_0 to (1445625 - (mun:position:mag / 10000)^2)/180000.
- set mun_1 to (1445625 - (positionat(mun, time:seconds + 1):mag / 10000)^2)/180000.
- set p_0 to arccos(min(max(mun_0, -1), 1)). // current phase angle
- set p_1 to arccos(min(max(mun_1, -1), 1)). // phase angle one second into the future
- // the range of arccos(x) is [0°,180°]. In order to convert to [0°,360°] I have to find if my phase angle is increasing or decreasing
- if p_1 > p_0 set phase to p_0. // I compare the two here, and if the future angle is smaller, the phase angle is decreasing from 180°
- else set phase to 360 - p_0. // if increasing, I subtract the value from 360, so that the phase angle is always decreasing from 360° to 0° and then resetting at 360° again, instead of counting up to 180°, and then counting back down to 0° and then back up.
- print "Phase angle: " + round(phase,0) at (0,0).
- if round(phase,0) = 135 kuniverse:timewarp:cancelwarp(). // kills the warp command from line 39, since waiting for the proper phase angle can take a while
- if round(phase,0) = 128 break. // proper phase angle, quite a bit higher than usual; compensating for the ~45 second trans-Munar injection burn
- wait 0.
- }
- // burning full throttle here until my orbit has a "next patch"
- set throt to 1.
- until orbit:hasnextpatch = true wait 0.
- until false {
- set gain to max(-constant:e^(-0.0000125*orbit:nextpatch:periapsis + 0.375) + 1, 0). // now I'm controlling my throttle based on my desired "closest approach"
- if gain = 0 break.
- wait 0.
- }
- set throt to 0.
- wait 10.
- //Munar module extraction
- set mm to processor("MMcpu").
- set mm:bootfilename to f.ks. // sends the CPU on the Munar Module it's own little program to run. See AUX_PROGRAM.
- mm:activate. // wake up, yo
- wait 5. toggle AG3.
- RCS on. set ship:control:fore to 0.25. wait 1.
- set ship:control:fore to 0. RCS off. wait 3.
- set target to "Saturn K Lander".
- lock steering to target:position.
- wait 15.
- RCS on.
- list dockingports in my_dp.
- set originDP to my_dp[0].
- originDP:controlfrom().
- set tar_dp to target:partstagged("MMdock").
- set targetDP to tar_dp[0].
- until false {
- set rel_pos to ship:facing:inverse * (originDP:nodeposition - targetDP:nodeposition). // thanks again hvacengi, my own coordinate system worked okay but this is much better
- set rel_vel to ship:facing:inverse * (ship:velocity:orbit - target:velocity:orbit).
- set x_dist to rel_pos:x. // getting my distance from my target in all three axes
- set y_dist to rel_pos:y.
- set z_dist to rel_pos:z.
- set x_vec to rel_vel:x. // getting my velocity relative to my target in all three axes
- set y_vec to rel_vel:y.
- set z_vec to rel_vel:z.
- set st to 2/(1 + constant:e^(5*x_vec + x_dist)) - 1. // more black magic
- set tp to 2/(1 + constant:e^(5*y_vec + y_dist)) - 1. // I *really* like sigmoid functions
- set fr to 2/(1 + constant:e^(5*z_vec + z_dist)) - 1. // okay fine, so these three functions control how fast I'm allowed to go based on my distance to my target in all three axes
- set ship:control:translation to v(st, tp, fr). // so if I'm going too fast, the RCS thrusters burn in the opposite direction to slow me down. NO RUNNING BY THE POOL
- if z_dist > -0.5 {
- set ship:control:neutralize to true. // once I'm close enough, the magnets in the docking ports take over. I'm killing RCS here so that I'm not wasting fuel fighting that
- if z_dist > -0.1 break. // breaking from the loop because the crafts are about to join, and some important stuff needs to happen before that
- }
- else wait 0.
- }
- unlock steering. wait 1. RCS off.
- set target to "".
- set mm:bootfilename to "".
- toggle AG4.
- wait 5.
- warpto(time:seconds + eta:transition). // this bit's annoying. I'm warping to the transition from Kerbin orbit to Munar fly-by here,
- wait 1.
- wait until ship:unpacked. // but as far as I can tell, you can't get your eta to your next patch's periapsis
- wait 1.
- warpto(time:seconds + (eta:periapsis - 60)). // so I have to get to my next patch, and then warp to the periapsis from there
- wait 1.
- wait until ship:unpacked. // ¯\_(ツ)_/¯
- //orbital insertion and circularization
- lock throttle to throt.
- lock steering to retrograde.
- wait until eta:periapsis <= 25.
- stage. wait 5.
- until false {
- if apoapsis < 0 set throt to 1. // orbital insertion, full throttle until my orbit closes
- else set throt to -constant:e^(-0.0005*apoapsis + 20) + 1. // still full throttle until I approach my target apoapsis, where I smoothly kill it, for precision
- if throt < 0.000001 break.
- wait 0.
- }
- set throt to 0.
- warpto(time:seconds + (eta:apoapsis - 30)).
- lock steering to prograde.
- until round(periapsis,0) >= 39999 {
- set eta_ap to min(eta:apoapsis, 1.5).
- set throt to 1/(1 + constant:e^(20*eta_ap - 15)). // just circularizing to a nice clean 40 km orbit
- wait 0.
- }
- set throt to 0.
- //inclination change
- lock steering to prograde * r(0, 90, 0).
- set done to false.
- warpto(time:seconds + orbit:period).
- wait 1.
- clearscreen.
- until done {
- set eta_AN to (360 - (orbit:argumentofperiapsis + orbit:trueanomaly)) / (360/orbit:period). // the lazy way to do orbital mechanics. DOES NOT WORK SUPER GREAT FOR ELLIPTICAL ORBITS, but can be made to do so. I'll leave the exercise to the reader. The proof is trivial.
- if eta_AN < 0 set t_AN to eta_AN + orbit:period. // eta_AN returns a negative number when your true anomaly + arg of periapsis is > 360, so I add the orbit's period in order to sate the Kraken.
- else set t_AN to eta_AN.
- print "time to ascending node: " + t_AN at (0,0).
- set t to min(t_AN, 3).
- if t_AN < 35 kuniverse:timewarp:cancelwarp().
- set throt to 1/(1 + constant:e^(10*t - 20)). // yet another sigmoid function, my god. They're so useful!
- if orbit:inclination < 0.00005 set done to true. // this honestly could be zero, sigmoid functions are that boss, but it'd take a little bit more time than is really worth it. 0.00005° inclination is pretty dang nice.
- else wait 0.
- }
- set throt to 0.
- lock steering to retrograde.
- wait 20.
- //Munar module separation
- unlock steering.
- set mm to processor("MMcpu"). // okay, we're in a 0° inclination orbit, we're ready to separate the Command Module from the Munar Module
- set mm:bootfilename to sep.ks. // tells the Munar Module's CPU the next program it needs to run. see DESCENT_PROGRAM.
- mm:activate. // wake up again, yo
- wait 5.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement