Jump to content

Flagship - A kerbal-sized Starship built out of flags - Automated Launch & Booster Recovery, and Re-Entry & Landing with kOS GUI


Janus92

Recommended Posts

rPl6cf3.jpeg

 

5KpOswV.gif

 

W8r8jxs.jpg

 

abowrTJ.jpg

 

0D8aSDf.jpg

 

h1cWOUx.jpg

 

jIw4WC6.jpg

 

gl0vuod.jpg

 

2TO8399.jpeg

 

N0wVnUS.jpg

 

UY8SJcu.jpg

 

AnBRzMW.jpg

 

AR7QKlX.jpg

 

riT2L7d.jpg

 

4BTiuRt.jpg

 

XBJ97qQ.gif

 

Download Link:

https://kerbalx.com/Janus92/Flagship

 

Download Flags & Scripts here:
https://mega.nz/file/S5N0hJ4R#wR9Wg1EtKc-iE7UpGDxhpLr0_qL492ZP6c9XnUbmc8g

 

Mods required:

Both the Breaking Ground DLC & Making History DLC
https://github.com/neuoy/KSPTrajectories/releases
https://www.curseforge.com/kerbal/ksp-mods/kerbal-attachment-system-kas
https://github.com/KSP-KOS/KOS/releases

 

Scripts (raw text):

flagship.ks (in ships/script/boot):

//
// Flagship Flight Control System kOS Script
//
//
// Place this script in Kerbal Space Program/Ships/Script/boot/.
// Fly, and the GUI should show up!
// If the GUI doesn't show up: Check the bootfile has been selected in the ships kOS unit.
//
//
// Required Mods:
// - Breaking Grounds DLC & Making History DLC
// - Trajectories Mod
// - KAS
// - kOS
//
// Have Fun!
//
//
//
// Version 1.0 - GNUGPL3
// Janus92
//
//
//

        // Initial Program Start-Up.
set exit to false.
wait until ship:unpacked.
clearguis().
clearscreen.

        // Finds ships parts for later use.
set hinges to SHIP:PARTSNAMED("hinge.03").
set drains to SHIP:PARTSNAMED("ReleaseValve").
list ENGINES in allengines.

        // Sets Trajectories Mods initial settings.
set landingzone to latlng(-000.0972,-074.5577).
ADDONS:TR:RESETDESCENTPROFILE(67).
ADDONS:TR:SETTARGET(landingzone).

//-------------Graphic User Interface----------------------//


        // Defines GUI.
local g is GUI(400).

        // Adds Title Box.
local TitleBox is g:addhlayout().                                                                
    
        // Adds Title to Title Box.
local Title is TitleBox:addlabel("<size=22><b>Flight Control System</b></size>").
    set Title:style:align to "CENTER".
    set Title:style:hstretch to True.
    set Title:style:margin:h to 0.
    set Title:style:margin:v to 1.
    set Title:style:textcolor to white.

        // Adds Hide Button to Title Box.
local g_hide is TitleBox:addbutton("<size=18>_</size>").
    set g_hide:style:margin:h to 0.
    set g_hide:style:margin:v to 1.
    set g_hide:toggle to true.
    set g_hide:style:width to 25.
    set g_hide:style:height to 25.
    set g_hide:style:vstretch to true.

        // Adds Close Button to Title Box.
local g_close is TitleBox:addbutton("<size=18>X</size>").
        set g_close:style:margin:h to 0.
        set g_close:style:margin:v to 1.
        set g_close:style:width to 25.
        set g_close:style:height to 25.
        set g_close:style:vstretch to true.
        set g_close:onclick to {g:hide(). set exit to true. }.

        // Adds a Box to the GUI.
local box_all is g:addvlayout().
    set box_all:style:padding:v to 0.
    set box_all:style:padding:h to 0.
    set box_all:style:margin:v to 0.
    set box_all:style:margin:h to 0.

        // Adds Launch, Land and a Status Label to before mentioned Box.
local button1hbox is box_all:addhlayout().
local launchbutton to button1hbox:addbutton("<size=20>Launch</size>").
    set launchbutton:toggle to true.
    set launchbutton:style:width to 80.
    set launchbutton:style:on:textcolor to green.
    set launchbutton:style:hover_on:textcolor to green.
local edlbutton to button1hbox:addbutton("<size=20>Land</size>").
    set edlbutton:toggle to true.
    set edlbutton:style:width to 80.
    set edlbutton:style:on:textcolor to green.
    set edlbutton:style:hover_on:textcolor to green.
local statuslabel to button1hbox:addlabel("").
    set statuslabel:style:fontsize to 18.
    set statuslabel:style:textcolor to white.
    set statuslabel:style:align to "center".
    set statuslabel:style:vstretch to true.

        // Adds a Text Box with 3 message fields to before mentioned Box.
local textbox is box_all:addvbox().    
local message1 is textbox:addlabel().
    set message1:style:fontsize to 18.
    set message1:style:textcolor to green.
local message2 is textbox:addlabel().
    set message2:style:fontsize to 18.
    set message2:style:textcolor to green.
local message3 is textbox:addlabel().
    set message3:style:fontsize to 18.
    set message3:style:textcolor to green.

        // Sets Launch Button Actions. First what happens when the button is pushed in, then what it should do if it could not start the Launch() function, and finally what happens when the button is pushed out.
set launchbutton:ontoggle to {
    parameter click.
    if click {if alt:radar < 50 or verticalspeed > 1 and periapsis < 70000 {Droppriority(). set edlbutton:pressed to False. Launch().}.
        else {
            set message1:text to "Launch aborted..".
            set message2:text to "Are you flying?".
            set message3:text to "".
            set message1:style:textcolor to yellow.
            set message2:style:textcolor to yellow.
            set message3:style:textcolor to yellow.}}
    else {
        wait 0.001.
        lock throttle to 0.
        wait 0.001.
        unlock steering.
        unlock throttle. 
        set statuslabel:text to "Manual Control".
        set message1:text to "".
        set message2:text to "".
        set message3:text to "".}
    }.
    
        // Sets Land Button Actions. First what happens when the button is pushed in, then what it should do if it could not start the EDL() function, and finally what happens when the button is pushed out.
set edlbutton:ontoggle to {
    parameter click.
    if click {if altitude > 650 {Droppriority(). set launchbutton:pressed to False. CheckReEntry().}
                else {
                    set message1:text to "EDL Cancelled..".
                    set message2:text to "Are you on the ground?".
                    set message3:text to "".
                    set message1:style:textcolor to yellow.
                    set message2:style:textcolor to yellow.
                    set message3:style:textcolor to yellow.}}
    else {
        set statuslabel:text to "Manual Control".
        set message1:text to "".
        set message2:text to "".
        set message3:text to "".
        lock throttle to 0.
        unlock steering.
        unlock throttle.}
    }.

        // Sets the Hide Button Actions.
set g_hide:ontoggle to {
    parameter b. 
    if b {box_all:hide().}
    else {box_all:show().}}.
    
        // Show succesful Start-Up Message.
set message1:text to "Flagship FCS initialized..".
set statuslabel:text to "Hi there!".

        // Show GUI.
g:show().

        // Waits for Close Button to be pushed, and thereafter disposes the GUI and closes the Program.
wait until exit.
g:dispose().



//--------------Launch Program--------------------------------//
        // Launches to an estimated 75km orbit.

    

        // Starts the Launch() function and sets the Launch Pad Coordinates. Resets the GUI messages to green color, in case the function could not be started when the Launch Button was pressed priorly (then they turn yellow).
function Launch {
    set landingzone to latlng(-000.0972,-074.5577).
    set message1:style:textcolor to green.
    set message2:style:textcolor to green.
    set message3:style:textcolor to green.
    clearscreen.
    sas off.
    rcs off.
    setfwdflap(180). setaftflap(180).
    
    SET KUNIVERSE:DEFAULTLOADDISTANCE:FLYING:UNLOAD TO 600000.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:FLYING:LOAD TO 595000.
    WAIT 0.001.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:FLYING:PACK TO 599990.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:FLYING:UNPACK TO 590000.
    
    SET KUNIVERSE:DEFAULTLOADDISTANCE:SUBORBITAL:UNLOAD TO 600000.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:SUBORBITAL:LOAD TO 595000.
    WAIT 0.001.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:SUBORBITAL:PACK TO 599990.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:SUBORBITAL:UNPACK TO 590000.
    
    SET KUNIVERSE:DEFAULTLOADDISTANCE:ORBIT:UNLOAD TO 600000.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:ORBIT:LOAD TO 595000.
    WAIT 0.001.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:ORBIT:PACK TO 599990.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:ORBIT:UNPACK TO 590000.
    
    
            // When you're starting the function from the ground, it sets Guidance to Up, Throttle to full, and then waits 10 seconds.
    if alt:radar < 50 {
        lock throttle to 1.
        lock steering to lookdirup(ship:up:vector, ship:facing:topvector).
        stage.  
        set statuslabel:text to "Lift-off!".
        wait 2.}
        
            // When you're starting the function while already flying, it sets Throttle to full only.
    if apoapsis < 75000 {lock throttle to 1.}.
    
    until altitude > 500 {
        set statuslabel:text to "Lift-off!".
        set message1:text to "Actual/Target Apoapsis: " + round(apoapsis/1000,1) + "/75.0km".
        set message2:text to "Target Pitch: 90".
        set message3:text to "Down Range: " + round(landingzone:distance/1000, 1) + "km".}
    
    lock targetpitch to 90 - 10 * SQRT((altitude - 500)/1000).
    lock steering to heading(90, targetpitch).
    
    if stage:number = 1 {
        until stage:deltav:current < 500 {
            set statuslabel:text to "Launching to Orbit..".
            set message1:text to "Actual/Target Apoapsis: " + round(apoapsis/1000,1) + "/75.0km".
            set message2:text to "Target Pitch: " + round(targetpitch, 1).
            set message3:text to "Down Range: " + round(landingzone:distance/1000, 1) + "km".}.
        
        lock throttle to 0.
        wait 1.
        stage.
        
        wait 1.
        sendMessage(VESSEL("Flagship Booster"), "Boostback").
        
        wait 4.
        list ENGINES in allengines.
        lock throttle to 1.
        }
    
    lock steering to ship:prograde.
    
    until apoapsis > 75000 {
        set statuslabel:text to "Separation Complete..".
        set message1:text to "Actual/Target Apoapsis: " + round(apoapsis/1000,1) + "/75.0km".
        set message2:text to "Target Pitch: Orbit-Prograde".
        set message3:text to "Down Range: " + round(landingzone:distance/1000, 1) + "km".}.
    
    wait 0.001.
    lock throttle to 0.
    
    until altitude > 60000 {
        set statuslabel:text to "On the way to space..".
        set message1:text to "Actual/Target Apoapsis: " + round(apoapsis/1000,1) + "/75.0km".
        set message2:text to "Calculating Circularization Burn..".
        set message3:text to "Down Range: " + round(landingzone:distance/1000, 1) + "km".}
        
    set OrbitalVelocity to ship:body:radius * sqrt(9.81 / (ship:body:radius + APOAPSIS)).
    set ApoapsisVelocity to sqrt(Kerbin:mu * ((2 / (ship:body:radius + APOAPSIS)) - (1 / ship:obt:semimajoraxis))).
    set deltaV to (OrbitalVelocity - ApoapsisVelocity).
    set MaxAccel to (ship:availablethrust / ship:mass).
    set timeToBurn to deltaV/MaxAccel.
    KUniverse:FORCEACTIVE(VESSEL("Flagship")).
    set CircularizationNode to Node(timespan(ETA:APOAPSIS), 0, 0, deltaV).
    add CircularizationNode.
    lock steering to CircularizationNode:burnvector.
    rcs on.
    
            // Coasting to orbit.
    until ETA:APOAPSIS < 0.45 * timeToBurn {
        set statuslabel:text to "Finalizing Orbit..".
        set message1:text to "Circularization Burn calculated..".
        set message2:text to "Start Burn in " + round(ETA:APOAPSIS - (0.45 * timeToBurn), 0) + " seconds".
        if vessel("Flagship Booster"):altitude {
            set message3:text to "First Stage Alt / Spd:      " + round(vessel("Flagship Booster"):altitude) + "m / " + round(vessel("Flagship Booster"):airspeed) + "m/s".}
        else {
            set message3:text to "First Stage Loss of Signal..".
            set message3:style:textcolor to yellow.}}
    
    wait 0.001.
    lock throttle to 1.
    rcs off.
    
            // Orbit Circularization Burn.
    until CircularizationNode:deltav:mag < 1 or PERIAPSIS > 75000 {
        set kuniverse:timewarp:warp to 0.
        set statuslabel:text to "Performing Burn..".
        set message1:text to "Circularizing Orbit..".
        set message2:text to "Apoapsis: " + round(APOAPSIS / 1000, 1) + "km, Periapsis: " + round(PERIAPSIS / 1000, 1) + "km".
        if vessel("Flagship Booster"):altitude {
            set message3:text to "First Stage Alt / Spd:      " + round(vessel("Flagship Booster"):altitude) + "m / " + round(vessel("Flagship Booster"):airspeed) + "m/s".}
        else {
            set message3:text to "First Stage Loss of Signal..".
            set message3:style:textcolor to yellow.}}
        
            // Orbit Achieved. End of the Launch Program.
    wait 0.001.
    lock throttle to 0.
    unlock steering.
    remove CircularizationNode.
    unlock throttle.
    wait 0.001.
    set SHIP:CONTROL:PILOTMAINTHROTTLE to 0.
    sas on.
    for eng in allengines {eng:shutdown.}.

    if APOAPSIS > 70000 and PERIAPSIS >70000 {
        set statuslabel:text to "Manual Control".
        set message1:text to "Stable orbit achieved.".
        set message2:text to "Contacting First Stage..".}
    else {
        set statuslabel:text to "Manual Control".
        set message1:text to "Something went wrong..".
        set message2:text to "Current Orbit: " + round(APOAPSIS / 1000, 1) + "km x " + round(PERIAPSIS / 1000, 1) + "km".
        set message3:text to "Sorry for that!".}

    set t to time:seconds.
    until 0 {
        set kuniverse:timewarp:warp to 0.
        if vessel("Flagship Booster"):altitude {
            if vessel("Flagship Booster"):status = "LANDED" {
                set statuslabel:text to "Program Ended.".
                set message2:text to "Message received:".
                set message3:text to "First Stage Landing Confirmed!".
                BREAK.}
            else{
                set message2:text to "First Stage Signal: 69%".
                set message3:text to "First Stage Alt / Spd:      " + round(vessel("Flagship Booster"):altitude) + "m / " + round(vessel("Flagship Booster"):airspeed) + "m/s".}}
        else {
            set message2:text to "First Stage Loss of Signal..".
            set message3:text to "Uh oh..".}
        if time:seconds > t + 60 {
            set statuslabel:text to "Program Ended.".
            set message2:text to "No First Stage Confirmation..".
            set message3:text to "What happened to the First Stage?".
            set message2:style:textcolor to yellow.
            set message3:style:textcolor to yellow.
            BREAK.}
        }
        
    SET KUNIVERSE:DEFAULTLOADDISTANCE:FLYING:UNLOAD TO 30000.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:FLYING:LOAD TO 29500.
    WAIT 0.001.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:FLYING:PACK TO 29999.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:FLYING:UNPACK TO 29000.
    
    SET KUNIVERSE:DEFAULTLOADDISTANCE:SUBORBITAL:UNLOAD TO 30000.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:SUBORBITAL:LOAD TO 29500.
    WAIT 0.001.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:SUBORBITAL:PACK TO 29999.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:SUBORBITAL:UNPACK TO 29000.
    
    SET KUNIVERSE:DEFAULTLOADDISTANCE:ORBIT:UNLOAD TO 30000.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:ORBIT:LOAD TO 29500.
    WAIT 0.001.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:ORBIT:PACK TO 29999.
    SET KUNIVERSE:DEFAULTLOADDISTANCE:ORBIT:UNPACK TO 29000.
    
    print "Launch Program Ended".
    
}.



//--------------Entry, Descent and Landing Program  (EDL)  --------------//



function EDL {
    if addons:tr:hasimpact{

            // initial preparation.
    set message1:style:textcolor to green.
    set message2:style:textcolor to green.
    set message3:style:textcolor to green.
    sas off.
    rcs off.
    ag4 off.
    ag5 off.
    setfwdflap(120). setaftflap(120).
    set aoa to 67.
    set LandSomewhereElse to 0.
    set IsDrained to 0.
    lock trueRadar to alt:radar - 9.
    lock ErrorVector to ADDONS:TR:IMPACTPOS:POSITION - landingzone:POSITION.
    
            // Re-Entry PIDs.
    set PitchPID to PIDLOOP(0.05, 0, 0, -10, 10).
    set YawPID to PIDLOOP(0.05, 0, 0, -45, 45).
    set BodyFlapsPID to PIDLOOP(7.5, 0, 0, -30, 30).
    set LandingPID to PIDLOOP(0.15, 0.03, 0.03, -1, 1).
    
    set statuslabel:text to "Re-Entry Control..".
    until trueRadar < 650 {lock STEERING to ReEntrySteering().}
    
    
    
//------------------Re-Entry Loop-----------------------///



function ReEntrySteering {
    if kuniverse:timewarp:warp > 0 and altitude < 40000 {set kuniverse:timewarp:warp to 0.}
    //ADDONS:TR:RESETDESCENTPROFILE(67).
    set LngLatErrorList to LngLatError().
    
    set pitch to -PitchPID:UPDATE(TIME:SECONDS, LngLatErrorList[0]).
    set yaw to -YawPID:UPDATE(TIME:SECONDS, LngLatErrorList[1]).
    if airspeed > 300 {
        set DesiredAoA to aoa + pitch.}
    else {
        set finalpitchcorrection to LngLatErrorList[0] / 10.
        if finalpitchcorrection > 5 {set finalpitchcorrection to 5.}
        if finalpitchcorrection < -5 {set finalpitchcorrection to -5.}
        set DesiredAoA to aoa + pitch + finalpitchcorrection.}
    
    set AoAError to vang(vxcl(facing:starvector, facing:forevector), vxcl(facing:starvector, velocity:surface:vec)) - DesiredAoA.
    set PitchRate to -1 * angularmomentum:x /100.
    set DesiredPitchRate to - AoAError / (1 + (airspeed/500)).
    set BodyFlapsPID:SETPOINT to DesiredPitchRate.
    set BodyFlapsCtrl to BodyFlapsPID:UPDATE(TIME:SECONDS, PitchRate).
    if altitude < 50000{
        FlapControl(BodyFlapsCtrl, LngLatErrorList[1] / 10, -2 * allengines[0]:gimbal:yawangle).
        if IsDrained = 0 {
            drains[0]:getmodule("ModuleResourceDrain"):DoAction("drain", True).
            drains[1]:getmodule("ModuleResourceDrain"):DoAction("drain", True).
            set IsDrained to 1.}}
    
    set result to srfprograde * R(- DesiredAoA * cos(yaw), DesiredAoA * sin(yaw), 0).
    set result to lookdirup(result:vector, vxcl(velocity:surface, result:vector)).
    
    if vang(result:vector, facing:forevector) > 60 or altitude < 2500 or allengines[0]:gimbal:yawangle = 1 and altitude < 20000 or allengines[0]:gimbal:yawangle = -1 and altitude < 20000 {rcs on.} else {rcs off.}
    if altitude < 2500 {set ship:control:translation to v(LngLatErrorList[1],0,0).}
    
            // Update GUI text.
    if airspeed > 300 {
        set message1:text to "Remaining Flight Time:  " + round(ADDONS:TR:TIMETILLIMPACT, 0) + " seconds".
        set message2:text to "Distance to Target:        " + round(landingzone:distance/1000, 0) + "km".
        set message3:text to "Track/X-Trk Error:        " + round(LngLatErrorList[0] / 1000, 2) + "km  " + round((LngLatErrorList[1] / 1000), 2) + "km".}
    else {
        set statuslabel:text to "Subsonic Control..".
        set message1:text to "Flip Altitude:                  " + "650m".
        set message2:text to "Distance to Target:        " + round(landingzone:distance/1000, 0) + "km".
        set message3:text to "Track/X-Trk Error:        " + round((LngLatErrorList[0] - 32) / 1000, 2) + "km  " + round((LngLatErrorList[1] / 1000), 2) + "km".
        if altitude < 10000 {
            if LngLatErrorList[0] > 500 or LngLatErrorList[0] < -500 or LngLatErrorList[1] > 250 or LngLatErrorList[1] < -250 {
                set message3:style:textcolor to yellow.} else {set message3:style:textcolor to green.}}
        if altitude < 2500 {
            if LngLatErrorList[0] > 50 or LngLatErrorList[0] < 20 or LngLatErrorList[1] > 15 or LngLatErrorList[1] < -15 {
                set message3:style:textcolor to yellow.} else {set message3:style:textcolor to green.}}}
    
            // Re-Entry Telemetry
    //clearscreen.
    //print "GOAL AoA: " + round(DesiredAoA,2).
    //print "lng error: " + round(LngLatErrorList[0],0).
    //print "lat error: " + round(LngLatErrorList[1],0).
    //print "yaw: " + round(yaw,2).
    
    return result.
}


    
//------------------Landing Program-----------------------///



    lock maxDecel to (ship:availablethrust / ship:mass) - 9.81.
    lock stopTime to (0.5 * ship:verticalspeed) / maxDecel.
    lock stopDist to (ship:verticalspeed * stopTime) + (0.5 * maxDecel * stopTime * stopTime).
    lock landingthrottle to stopDist / trueRadar.
    
    rcs on.
    unlock steering.
    setfwdflap(180).
    setaftflap(90).
    for eng in allengines {eng:activate.}.
    if LngLatErrorList[0] > 50 or LngLatErrorList[0] < 20 or LngLatErrorList[1] > 15 or LngLatErrorList[1] < -15 {set LandSomewhereElse to 1.}
    if LandSomewhereElse = 1 {set FlipCorrection to 0.} else {set FlipCorrection to 1.}
    set statuslabel:text to "Landing..".
    set message1:text to "Performing Flip Maneuvre..".
    set message3:text to "Hold on to your Hats, Boys!".
    set ship:control:pitch to 1.
    wait 3 + ((FlipCorrection * LngLatErrorList[0] - 35) / 100).
    set ship:control:neutralize to true.
    LOCK THROTTLE to landingthrottle.
    LOCK STEERING TO LandingVector().
    gear on.
    setfwdflap(135).
    setaftflap(135).
    wait until verticalspeed > -1.



//------------------Landing Loop-----------------------///



function LandingVector {
    if kuniverse:timewarp:warp > 0 {set kuniverse:timewarp:warp to 0.}
    if addons:tr:hasimpact {
                // Sets the PID to input 'ErrorVector Magnitude', creates a result from retrograde and the error.
    set controller to LandingPID:UPDATE(TIME:SECONDS, ErrorVector:MAG).
    set result to -1 * VELOCITY:SURFACE + 0.3 * controller * ErrorVector.
            
            // GUI message. When the boundaries at the start of the flip were exceeded, this will guide the ship to a retrograde landing anywhere without regard for the Landing Pad.
    if LandSomewhereElse = 0 {
        set message2:text to "Distance from Target: " + round(ErrorVector:MAG,0) + "m".}
    else {
        set result to -1 * VELOCITY:SURFACE.
        set message1:text to "Can't reliably reach Landing Pad..".
        set message2:text to "Distance from Target: " + round(ErrorVector:MAG / 1000,2) + "km".
        set message3:text to "Watch out for obstacles!".
        set message1:style:textcolor to yellow.
        set message2:style:textcolor to yellow.
        set message3:style:textcolor to yellow.
        }
    if landingthrottle > 1 {
        set message1:text to "WARNING!".
        set message3:text to "IMPACT IMMINENT! (sorry..)".
        set message1:style:textcolor to red.
        set message3:style:textcolor to red.}
        }
        
            // Levels the ship prior to touchdown.
    if ship:verticalspeed > -40 {set result to -1 * VELOCITY:SURFACE.}
    return lookDirUp(result, facing:topvector).
}



//----------------After Landing------------------//



    for eng in allengines {eng:shutdown.}.
    set statuslabel:text to "Welcome to Kerbin!".
    set message1:text to "Succesful Landing Confirmed!  (" + (round(landingzone:distance, 0)-9) + "m)".
    set message2:text to "Performing Vehicle Self-Check..".
    set message3:text to "Please Standby..(30s)".
    sas off.
    lock steering to lookdirup(ship:up:vector,ship:facing:topvector).
    wait 30.
    unlock steering.
    rcs off.
    setfwdflap(90).
    setaftflap(90).
    set message1:text to "Vehicle Self-Check OK!".
    set message2:text to "Land Program ended..".
    set message3:text to "You may now disembark!".
    set message1:style:textcolor to green.
    set message2:style:textcolor to green.
    set message3:style:textcolor to green.
    ADDONS:TR:CLEARTARGET().


    
    
        // bracket ends the 'Has Impact' check.
}
        // When no Impact location can be found, I assume the ship is still in orbit.
else {
    set message1:text to "Error: Ship has no Impact Position..".
    set message2:text to "Adjust your Orbit!".
    set message3:text to "Ideal Accuracy: < 100km from target".
    set message1:style:textcolor to yellow.
    set message2:style:textcolor to yellow.
    set message3:style:textcolor to yellow.}.
}.
        // EDL() function officially ended.



//----------------Other Functions---------------------//



        // Provides Longitudinal and Lateral Error during Re-Entry.
function LngLatError {
    if addons:tr:hasimpact {
        set lngresult to ((ship:position - addons:tr:impactpos:position):mag - (ship:position - landingzone:position):mag).
        if landingzone:distance/1000 < 50 {
            set lngresult to (vdot(heading(landingzone:heading, 0):vector, ErrorVector)).}

        set latresult to (vdot(heading(landingzone:heading - 90, 0):vector, ErrorVector)).
        if landingzone:bearing > 90 or landingzone:bearing < -90 {
            set lngresult to ErrorVector:mag.
            set latresult to 0.}
        if airspeed < 300{set lngresult to lngresult -49.}
        return list(lngresult, latresult).}
}


function CheckReEntry {
    set ErrorVector to ADDONS:TR:IMPACTPOS:POSITION - landingzone:POSITION.
    set LngLatErrorList to LngLatError().
    if LngLatErrorList[0] > landingzone:distance / 10 and LngLatErrorList[0] > 40000 or LngLatErrorList[0] < -landingzone:distance / 10 and LngLatErrorList[0] < -40000 or LngLatErrorList[1] > landingzone:distance / 10 and LngLatErrorList[1] > 20000 or LngLatErrorList[1] < -landingzone:distance / 10 and LngLatErrorList[1] < -20000 {
        set message1:text to "Land Program Cancelled.".
        set message2:text to "Impact too far away from KSC..".
        set message3:text to "Adjust your Re-Entry!".
        set message1:style:textcolor to yellow.
        set message2:style:textcolor to yellow.
        set message3:style:textcolor to yellow.}
    else {EDL().}
}


        // Set Forward Body Flaps to the angle that can be passed with this function.
function setfwdflap {
    parameter angle.
    hinges[0]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", angle).
    hinges[1]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", angle).
}
    
    
        // Set Aft Body Flaps to the angle that can be passed with this function.
function setaftflap {
    parameter angle.
    hinges[2]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", angle).
    hinges[3]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", angle).
    hinges[4]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", angle).
    hinges[5]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", angle).
}


        // Provides Flap Control.
function FlapControl {
    parameter pitch.
    parameter roll.
    parameter yaw.
    if roll > 3 {set roll to 3.}
    if roll < -3 {set roll to -3.}
    set FWDFlap to 120.
    set AFTFlap to 120.
    
            // Left Flaps, hinges[0] = Forward Flap. Rest Aft.
    hinges[1]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", FWDFlap + pitch + roll + yaw).
    hinges[3]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", AFTFlap - pitch - roll + yaw).
    hinges[5]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", AFTFlap - pitch - roll + yaw).
    
            // Right Flaps, hinges[1] = Forward Flap. Rest Aft.
    hinges[0]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", FWDFlap + pitch - roll - yaw).
    hinges[2]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", AFTFlap - pitch + roll - yaw).
    hinges[4]:getmodule("ModuleRoboticServoHinge"):setfield("Target Angle", AFTFlap - pitch + roll - yaw).
}



function sendMessage{
  parameter v, msg.
  set cnx to v:connection.
  if cnx:isconnected {cnx:sendmessage(msg). print "message sent".} 
  else print "connection could not be established".
}

 

flagship_booster.ks (also located in ships/script/boot):

set Landed to 0.
set ErrorVector to V(0, 0, 0).
set landingzone to latlng(-000.0972,-074.5577).

until Landed {
    until (ship:messages:length = 0) {
        ship:messages:pop().
        Boostback().}
}



function Boostback {
    set kuniverse:timewarp:warp to 0.
    set speedbrakes to SHIP:PARTSNAMED("airbrake1").
    rcs on.
    
    until vang(facing:forevector, -vxcl(up:vector, ErrorVector)) < 10 {
        impactCalculation().
        lock steering to lookDirUp(-vxcl(up:vector, ErrorVector), up:vector).}
        
    lock throttle to ErrorVector:mag / 10000 + 0.05.
    
    until impactpos:lng < landingzone:lng {
        set kuniverse:timewarp:warp to 0.
        impactCalculation().
        lock steering to lookDirUp(-vxcl(up:vector, ErrorVector), up:vector).}
        
    print ErrorVector:mag.
    set throttle to 0.
    
    lock steering to lookDirUp(-1 * VELOCITY:SURFACE, up:vector).
    until vang(facing:forevector, -1 * VELOCITY:SURFACE) <10 {}
        
    until altitude < 35000 {
        impactCalculation().
        set ship:control:translation to v(0, 0, -10 * (impactpos:lng - landingzone:lng)).
        lock steering to lookDirUp(-1 * VELOCITY:SURFACE, up:vector).}
    
    set ship:control:translation to v(0, 0, 0).
    list ENGINES in allengines.
    for engine in list(0,1,2,3,4,5,6,7) {allengines[engine]:shutdown.}
    for speedbrake in list (0,1,2,3) {
        speedbrakes[speedbrake]:getmodule("ModuleAeroSurface"):DoAction("toggle pitch control",True).
        speedbrakes[speedbrake]:getmodule("ModuleAeroSurface"):DoAction("toggle yaw control",True).}
        
    lock trueRadar to alt:radar - 32.
    lock maxDecel to (ship:availablethrust / ship:mass) - 9.81.
    lock stopTime to (0.5 * ship:verticalspeed) / maxDecel.
    lock stopDist to (ship:verticalspeed * stopTime) + (0.5 * maxDecel * stopTime * stopTime).
    lock landingthrottle to stopDist / trueRadar.
 
    until airspeed < 350 and altitude < 10000 and landingthrottle > 0.9{
        impactCalculation().
        lock steering to lookdirup(-1 * VELOCITY:SURFACE + 0.25 * ErrorVector, up:vector).}
    
    lock throttle to landingthrottle.
    for speedbrake in list (0,1,2,3) {
    speedbrakes[speedbrake]:getmodule("ModuleAeroSurface"):DoAction("toggle pitch control",False).
    speedbrakes[speedbrake]:getmodule("ModuleAeroSurface"):DoAction("toggle yaw control",False).}
    
    until verticalspeed > -1 {
        impactCalculation().
        set result to -1 * VELOCITY:SURFACE - 0.05 * ErrorVector.
        if ship:verticalspeed > -120 {set result to -1 * VELOCITY:SURFACE.}
        lock steering to lookDirUp(result, up:vector).}
    set throttle to 0.
    unlock steering.
    wait 5.
    rcs off.
    set Landed to 1.
}



FUNCTION impactCalculation {
    set x to 1.
    set altPredict to body:radius + 1.
    until altPredict < body:radius {
        set posPredict to positionat(ship, time:seconds + x).
        set altPredict to (posPredict - body:position):mag.
        set x to x + 1.}
    set impactpos to body:geopositionof(positionat(ship, time:seconds + x - 1)).
    set impactpos to LATLNG(impactpos:LAT, impactpos:LNG - ((x / body:rotationperiod) * 360) + 0.13).
    set ErrorVector to impactpos:POSITION - landingzone:POSITION.
    return impactpos.
}

 

Edited by Janus92
new gif inserted
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...