r/Kos Sep 13 '24

Announcement kOS 1.5.0.0 - Leaks plugged

42 Upvotes

A new release of kOS after more than a year this is a smaller release that is mostly bugfixes though there are few new features.

Be aware that the new features do not yet have documentation and so if you want to use them you will need to look at the committed code to figure out the details how they work.

Downloading:

Direct from the GitHub Project

v1.5.0.0

NEW FEATURES

  • New crewmember suffixes commit
  • Added COM suffix to parts to get the accurate center of mass (thanks SofieBrink) commit
  • 3rd party addons can now add custom suffixes to PartModules commit

BUG FIXES


r/Kos 7d ago

Solved The CREATEORBIT function with state inputs produce unexpected results

3 Upvotes

I'm trying to create theoretical orbits via the state vector inputs position, velocity, body, and ut (and body). I cannot seem to get something that make sense except with one set of inputs. Here's a snippet that gives me what I expect:

SET ut TO TIME:SECONDS.


SET raw_pos TO POSITIONAT(SHIP, ut) - POSITIONAT(SHIP:BODY, ut).
SET raw_vel TO VELOCITYAT(SHIP, ut):ORBIT.


SET test_orbit TO CREATEORBIT(
  raw_pos,
  raw_vel,
  SHIP:BODY,
  ut
).


PRINT "test apoapsis: " + test_orbit:APOAPSIS.
PRINT "my apoapsis: " + SHIP:ORBIT:APOAPSIS.

Using apoapsis as a testing metric, this gives me what I expect. the test_orbit:APOAPSIS and SHIP:ORBIT:APOAPSIS match exactly because I'm measuring the state of my current orbit exactly at this moment.

But as soon as I set ut to something like

SET ut TO TIME:SECONDS + 1.

the test_orbit:APOAPSIS jumps to a huge number. They way I understand it (which is apparently wrong), using my current orbit parameters with some delta in the future should result in an identical orbit and something like apoapsis should be identical because I'm using state vectors from the same orbit, just some time in the future.

Based on the git issues mentioned, I've also tried "swizzling" the y and z components of the velocity and position, but to no avail. The kos docs also have an example to create orbits that seems to swap position and velocity, but that doesn't work either.

The end goal I have in mind is to try adding some deltaV at some time along my current orbit to the velocity I would have at that point so that I can optimize a maneuver to put there.

I've been able to accomplish something similar optimizing directly on maneuver node parameters, but wanted to see if there was a way to avoid having to

ADD newnode.

...get resulting stuff

REMOVE newnode.

over and over again

If anyone has any suggestions I would greatly appreciate it.


r/Kos 8d ago

Help Can someone help me with the idea on how to do this? No code post, I just genuinely have no idea because nothing I tried works, I think people done starships here so it should be possible but I am too much of a begginer to pull it off I think (Specifics in main text)

Post image
6 Upvotes

This is a 9 engine rocket with 8 radial engines which need to be tied to each other in pairs so if one shuts down the other one also shuts down. For example in case of an engine failure the opposite to it will shut down not to ruin the balance and tilt the rocket. I named them east, west, northwest etc. Things I tried: Shutting them off by assigning opposites and checking for flameout, checking for less than 0.1 thrust and basically all of these with 20 different variants of checking for flameout or engine tags. I came up with a bit easier idea while typing this maybe just to check the engine thrust and then set the opposite engine throttle to zero instead of shutting it down and make all of the engines as pairs instead of signing them as opposite, kinda messy but maybe it will work, I just don't understand how to make them communicate between each other, I named them all properly, even tried auto naming and still nothing, if one fails all other just move on and the rocket fly's into the ground


r/Kos 8d ago

Help Can someone help please i am already genuinly at loss, there is zero error mistakes it just doesnt works. I need to make auto opposite engine shutdown for my 9 engine first stage and it just doesnt shuts anything down

2 Upvotes
The engines are tagged, no error codes in the console, i dont have any idead already, i changed flameout to thrust loss but still it doesnt works 




wait 5.
print "START".


function main {
  DASDIFO().
  lock throttle to 1.
  stage.
  wait 0.5.
  stage.
  wait 0.1.
  stage.


  until false. 
  
}


function DASDIFO {
  local opposites is lexicon(
    "North",     "South",
    "South",     "North",
    "East",      "West",
    "West",      "East",
    "NorthEast", "SouthWest",
    "SouthWest", "NorthEast",
    "NorthWest", "SouthEast",
    "SouthEast", "NorthWest"
  ).


  local shutdown_tags is list().


  when true then {
    list engines in englist.


    for eng in englist {
      local tag is eng:tag.


      if opposites:haskey(tag) {
        // Only change: check if ignited and thrust has dropped to 0
        if eng:ignition and eng:thrust = 0 and not shutdown_tags:contains(tag) {
          local opposite_tag is opposites[tag].


          for other in englist {
            if other:tag = opposite_tag {
              if not other:flameout {                // still alive, so shut it down
                other:shutdown().
              }
              shutdown_tags:add(tag).
              shutdown_tags:add(opposite_tag).
              break.
            }
          }
        }
      }
    }
    preserve.
  }
}


main().

r/Kos 8d ago

Can someone please help me with the engines shutdown code? I have a 9 engine pattern with one in the middle and i need to shut down the engine opposite to it if one of the engines flameout since its RP-1 and engine fail is a thing. Its a huge code for me so i think i definitely mixed something up

Post image
3 Upvotes
function DASDIFO {
  local opposites to lexicon(
    "North",     "South",
    "South",     "North",
    "East",      "West",
    "West",      "East",
    "NorthEast", "SouthWest",
    "SouthWest", "NorthEast",
    "NorthWest", "SouthEast",
    "SouthEast", "NorthWest"
  ).


  local shutdown_tags to list().


  until false {
    list engines in englist.


    for eng in englist {
      local tag is eng:tag.


      if opposites:haskey(tag) {
        local myEngine is eng:engine.


        if myEngine:flameout and not shutdown_tags:contains(tag) {
          local opposite_tag is opposites[tag].


          for other in englist {
            if other:tag = opposite_tag {
              local oppEngine is other:engine.


              if not oppEngine:flameout {
                oppEngine:shutdown().
              }


              shutdown_tags:add(tag).
              shutdown_tags:add(opposite_tag).
              break.
            }
          }
        }
      }
    }
    wait 0.1.
  }
}


function main {
  DASDIFO().
  lock throttle to 1.
  stage.
  wait 0.5.
  stage.
  until false.
}


main().

r/Kos 12d ago

Apollo's Herald. First Moon impactor. KOS + Principia.

11 Upvotes

r/Kos 12d ago

Help Hi can someone help me please with a kOS bug? It happens only if i put my boot script in active in the avionics RP-1 and is going away when i control my rocket myself, tiny code

Thumbnail
gallery
3 Upvotes

This is an extremely simple code i made for the start of my RP-1 progression and it uses hot staging, i think maybe because the engine is burning while the stage is attached causes this? They both ignite on the ground

lock throttle to 1.
stage.
wait 4.
stage.
wait until false.


r/Kos 12d ago

Help A way check the ground height from sea level at any point on a planet defined with latitude and longitude?

2 Upvotes

As said in the title, I want to know if it is possible to, in some way, get the ground height from sea level at any point on a planet defined with latitude and longitude.


r/Kos 12d ago

Help Why does the burn start one second late?

5 Upvotes
set mnv to nextnode.
set burnTime to deltaV_calc().
lock steering to mnv:deltav.


until ((mnv:eta-(burnTime/2))<=0){ //runs till burn starts
    clearscreen.
    print "--------------------------".
    print "Burn time: ".
    print round(burnTime,2)+"s".
    print "--------------------------".
    print "Maneuver node ETA: ".
    print floor(mnv:eta/60)+ "m " +round(mod(mnv:eta,60),2)+"s".
    print "--------------------------".
    print "Maneuver node burn ETA: ".
    print floor((mnv:eta-(burnTime/2))/60)+ "m " +round(mod((mnv:eta-(burnTime/2)),60),2)+"s".
    print "--------------------------".
}


until((mnv:eta-(burnTime/2))<=(-burnTime)){ //burn starts here
    lock throttle to 1.
    clearscreen.
    print "--------------------------".
    print "Burn time: ".
    print round(burnTime,2)+"s".
    print "--------------------------".
    print "Maneuver node ETA: ".
    print floor(mnv:eta/60)+ "m " +round(mod(mnv:eta,60),2)+"s".
    print "--------------------------".
    print "Maneuver node burn ETA: ".
    print floor((mnv:eta-(burnTime/2))/60)+ "m " +round(mod((mnv:eta-(burnTime/2)),60),2)+"s".
    print "--------------------------".
}
lock throttle to 0. //burn ends here


FUNCTION deltaV_calc {
    local startmass is ship:mass.
    local deltaV is mnv:burnvector:mag.
    local thrust is thrust_calc().
    if thrust = 0 {
        return 0.
    }
    local g0 is CONSTANT:g0.
    local E is CONSTANT:E.
    return (((g0*isp_calc()*startmass)/(thrust))*(1-E^((-deltaV)/(g0*isp_calc())))).
}


FUNCTION isp_calc { 
    LOCAL engineList IS LIST().
    LOCAL totalFlow IS 0.
    LOCAL totalThrust IS 0.
    LIST ENGINES IN engineList.
    FOR engine IN engineList {
        IF engine:IGNITION AND NOT engine:FLAMEOUT {
            SET totalFlow TO totalFlow + (engine:AVAILABLETHRUST / (engine:ISP * CONSTANT:g0)).
            SET totalThrust TO totalThrust + engine:AVAILABLETHRUST.
        }
    }
    IF totalThrust = 0 {
        RETURN 1.
    }
    RETURN (totalThrust / (totalFlow * CONSTANT:g0)).
}


FUNCTION thrust_calc {
    LOCAL sum is 0.
    LIST ENGINES IN engineList.
    FOR engine IN engineList {
        IF engine:IGNITION AND NOT engine:FLAMEOUT {
            SET sum TO sum + engine:AVAILABLETHRUST.
        }
    }
    RETURN sum.
}

r/Kos 14d ago

Help Can someone help please? Why does my range safely command doesnt works in RP-1 (Code is in the main text)

Post image
3 Upvotes
set mule to ship.


set avionics to 
mule:partsdubbed("proceduralAvionics")[0].


set disintegration to avionics:getmodule("ModuleRangeSafety").

lock throttle to 1.

stage.


wait 0.2.

stage.

wait 10.

when mule:verticalspeed < -10 and altitude < 60000 then {


disintegration:doevent("range safety").


}


wait until false. 

r/Kos 14d ago

Help Cannot Disengage Alligator Hinge Motor via KOS

Thumbnail
gallery
5 Upvotes

In the middle of my first foray into KOS. Trying to get this alligator hinge motor to DISENGAGE after it completes a KAL-1000 operation. I figured that would be simple enough, but evidently not, because it simply refuses to disengage when under KOS control.

Issues identified and attempts made:
1. ISSUE - There are two "MOTOR" fields. Given that fields are accessed via string, I am not sure how to differentiate them, or if I even need to for this part. I also do not know if this is for whether or not the part is MOTORIZED, or if the field is for the the ENGAGEMENT STATUS. Or if one is for one, and the other is for the other.

  1. ISSUE - Alligator Hinge will not revert to "Disengaged" when commanded by KOS. The only exception to this is if I have the UI for a hinge OPEN when commands are sent, in which case, it will disengage as normal.

  2. Alligator hinges will all DISENGAGE when I manually use an action group (AG5) to disengage them. Works without issue

  3. Alligator hinges will not disengage when I trigger the action group via KOS, even if I put a long delay before the command.

  4. Alligator hinges show no change in engagement status when I write to the motor fields using "ENGAGED", "DISENGAGED", TRUE, FALSE, 0, 1.

  5. Alligator hinges show no change in engagement status when I DOACTION on the "disengage motor drive" action, regardless of true or false status.

  6. Alligator hinges show no change in engagement status when I DOACTION on the "toggle motor engaged" action, regardless of true or false status.


r/Kos 19d ago

Video New Glenn booster powered landing - YouTube

Thumbnail
youtube.com
16 Upvotes

Here we go again. A new family of rockets to simulate using kOS. I will publish the scripts when I get my GitHub issues sorted out (I am tired of using Google Drive).

The algorithm I used to write the guidance script is not particularly good, it is "tuned" to a certain extent which is never a good sign in a control program. Still working on a more general algorithm that won't do weird things.


r/Kos 24d ago

Program Advice on designing and coding an active drag system to optimise apoapsis

3 Upvotes

Hello everyone, for a uni undergrad project I am designing an active drag system for a fairly basic sounding rocket on a suborbital trajectory. The goal of the system is to deploy airbrakes/fins to create drag and slow the rocket if it is overshooting its target apoapsis, and actively responds to its flight conditions and craft speed to actuate a response. I wanted to use Kerbal for a simulation of said system and was directed to use kOS for creating the automation, but I am pretty lost on where to start my understanding of kOS and how I would actually program it.

I have an entry level coding skill, and I have a basic understanding of Python, so intro coding concepts are assumed, but I am finding the tutorials on the kOS github to be a bit too basic, yet also not really explaining how the language works.

In short, I am asking for advice on where I should look for ideas similar to mine, and/or a directory where I can read all the in-built functions of kOS and how they work. If anyone has done a project like this, I would love to see your code and chat to you about it.

Ultimately, I can't imagine the code for the system is that complex, but I just don't understand how I would reference the parts in the craft, or even what kOS code should look like.


r/Kos 25d ago

Why does it just not work

Post image
8 Upvotes

trying to learn kos and its just not doing anything with his scrip or any other i run its like they arent communicating with the ship at all


r/Kos 28d ago

Vtol Balance Script - HELP

1 Upvotes

Hi, im working on my vtol balance script, i cant get it work, plane is untable when flying in vtol mode, and landing is mostly impossible.

CLEARSCREEN.
set FlightState to 4.
set spoolFinished to false.
set avgForePerf to 1.
set avgAftPerf to 1.

if exists("log.csv") { deletepath("log.csv"). }

until FlightState = 0 {
    wait 0.05.

    set Body_X to ship:facing:forevector:normalized. 
    set Body_Y to ship:facing:starvector:normalized. 
    set Body_Z to ship:facing:topvector:normalized. 

    set avgForePerf to 1.
    set avgAftPerf to 1.

    set ForeEngines to ship:partsTagged("eng_f").
    set AftEngines to ship:partsTagged("eng_b").
    set MainDrive to ship:partsTagged("main_drive").

    set VTOL_Engines to list().
    for e in ForeEngines { VTOL_Engines:ADD(e). }
    for e in AftEngines { VTOL_Engines:ADD(e). }

    set enginesInVtolPos to 0.
    for eng in VTOL_Engines {
        set ThrustUnitVec to v(eng:facing:vector*Body_X, eng:facing:vector*Body_Y, eng:facing:vector*Body_Z):normalized.
        if ABS(ThrustUnitVec:z) > 0.5 { set enginesInVtolPos to enginesInVtolPos + 1. }
    }

    if enginesInVtolPos < VTOL_Engines:length { set flightstate to 2. } 
    else { set flightstate to 1. }

    if flightstate = 2 {
        for eng in ForeEngines { if eng:IGNITION { eng:SHUTDOWN. } }
        for eng in AftEngines { if not eng:IGNITION { eng:ACTIVATE. } set eng:THRUSTLIMIT to 100. }
        for eng in MainDrive { if not eng:IGNITION { eng:ACTIVATE. } set eng:THRUSTLIMIT to 100. }
    } 
    else {
        for eng in MainDrive { if eng:IGNITION { eng:SHUTDOWN. } }

        set enginesReady to true.
        for eng in ForeEngines { if not eng:IGNITION { eng:ACTIVATE. set enginesReady to false. } }

        if not enginesReady {
            for eng in VTOL_Engines { set eng:THRUSTLIMIT to 0. }
            wait 0.2. 
        } else {
            set TotalForeMaxThrust to 0. set ForeMomentSum to 0.
            for eng in ForeEngines {
                set PosVec to v(eng:position*Body_X, eng:position*Body_Y, eng:position*Body_Z).
                set ThrustVec to v(eng:facing:vector*Body_X, eng:facing:vector*Body_Y, eng:facing:vector*Body_Z):normalized * eng:MAXTHRUST.
                set ForeMomentSum to ForeMomentSum + VCRS(ThrustVec, PosVec):y.
                set TotalForeMaxThrust to TotalForeMaxThrust + eng:MAXTHRUST.
            }
            set TotalAftMaxThrust to 0. set AftMomentSum to 0.
            for eng in AftEngines {
                set PosVec to v(eng:position*Body_X, eng:position*Body_Y, eng:position*Body_Z).
                set ThrustVec to v(eng:facing:vector*Body_X, eng:facing:vector*Body_Y, eng:facing:vector*Body_Z):normalized * eng:MAXTHRUST.
                set AftMomentSum to AftMomentSum + VCRS(ThrustVec, PosVec):y.
                set TotalAftMaxThrust to TotalAftMaxThrust + eng:MAXTHRUST.
            }

            set FinalRatio_F to 100. set FinalRatio_B to 100.
            if ABS(ForeMomentSum) > ABS(AftMomentSum) and TotalForeMaxThrust > 0 {
                set FinalRatio_F to (ABS(AftMomentSum) / (ABS(ForeMomentSum)+0.01)) * 100.
            } else if ABS(AftMomentSum) > ABS(ForeMomentSum) and TotalAftMaxThrust > 0 {
                set FinalRatio_B to (ABS(ForeMomentSum) / (ABS(AftMomentSum)+0.01)) * 100.
            }

            set totalF to 0. for eng in ForeEngines { set totalF to totalF + eng:THRUST. }
            set totalA to 0. for eng in AftEngines { set totalA to totalA + eng:THRUST. }
            if TotalForeMaxThrust > 0 { set avgForePerf to totalF / TotalForeMaxThrust. }
            if TotalAftMaxThrust > 0 { set avgAftPerf to totalA / TotalAftMaxThrust. }

            set syncCap to MIN(avgForePerf, avgAftPerf) + 0.2.

            for eng in ForeEngines { set eng:THRUSTLIMIT to MIN(FinalRatio_F, syncCap * 100). }
            for eng in AftEngines { set eng:THRUSTLIMIT to MIN(FinalRatio_B, syncCap * 100). }
        }
    }

    print "Mode: " + flightstate + " F_Perf: " + round(avgForePerf,2) + " A_Perf: " + round(avgAftPerf,2) at (0,2).

    set logLine to round(time:seconds,2) + "," + flightstate + "," + round(avgForePerf,3) + "," + round(avgAftPerf,3) + "," + round(throttle,2).
    log logLine to "log.csv".

    if status <> "PRELAUNCH" and MAXTHRUST = 0 { set FlightState to 0. }
}

clearscreen.
print "Program ended.".

r/Kos May 04 '26

Help Can the kos code run even when the ship is not being selected?

9 Upvotes

I want to get into kos but an important factor for me is like can I do multiple missions at the same time? Can I leave an ion probe to do its thing for a while while also launching a second mission?

Also how does it handle time warps? Does it just stop working?


r/Kos May 02 '26

Program Code snippet for getting banking, heading, and attitude

3 Upvotes

Been experimenting with a number of things, but I wanted to get a banking, heading, and attitude variable.

Initially I planned to just do the maths in one variable lock for each to make it very instruction efficient, which for attitude was nice and easy, just a simple:

LOCK GRND_ATTTUDE TO 90-VECTORANGLE(SHIP:UP:VECTOR, SHIP:FACING:VECTOR).

It's calculating the (vector)angle between UP (away from a planet's surface) and the direction the ship is pointing (a value from 0 to 180) then subtracts that from 90 to make it so 90 points up, -90 points down, and 0 is horizontal.

Banking and Heading were a bit more complicated, and have ended up as 3 variable locks each. I was avoiding IF statements, and so I may (at the cost of readability) reduce them down to a single variable lock in the future (which should take it down to just 1 instruction cost I think?)

However, here they are currently,

Banking

LOCK QERY_BANKING TO VECTORANGLE(SHIP:UP:VECTOR, SHIP:FACING:RIGHTVECTOR)-90.
LOCK QERY_INVERTD TO FLOOR(VECTORANGLE(SHIP:UP:VECTOR, SHIP:FACING:UPVECTOR)/90).
LOCK GRND_BANKING TO (QERY_INVERTD*SIGN(QERY_BANKING)*180)+((1-QERY_INVERTD*2)*QERY_BANKING).

Heading

LOCK QERY_HEADING TO VECTORANGLE(SHIP:NORTH:VECTOR,VXCL(SHIP:UP:VECTOR,SHIP:FACING:VECTOR)).
LOCK QERY_EASTWRD TO FLOOR(VECTORANGLE(SHIP:NORTH:RIGHTVECTOR,VXCL(SHIP:UP:VECTOR,SHIP:FACING:VECTOR))/90).
LOCK GRND_HEADING TO ((1-QERY_EASTWRD)*360)+(QERY_HEADING*(QERY_EASTWRD*2-1)).

Both are somewhat similar in how they work, the first LOCK statement for each is producing a vector angle similar to how the attitude variable works.

I should also mention the "SIGN" function I have:

DECLARE FUNCTION SIGN {
  PARAMETER X.
  RETURN X/ABS(X).
}.

It's sort of like a counterpart to ABS (absolute value). It's discarding the value, but retaining a sign (so I can feed it a positive or negative number, and get +1 or -1).

Banking:

  1. The first LOCK for banking (QERY_BANKING) compares the rightvector (an imaginary right wing) of the vessel to UP, however because I want level flight to be a value of 0, I subtract 90 from it. This also means that clockwise banking makes it more positive, and counterclockwise banking makes it more negative.
  2. An issue with this however, is that it cannot distinguish if the vessel is rolled into inverted (upside down) flight, so past ±90° the value decreases back down to 0.
  3. I know however if "up" (relative to the ship) and UP (relative to the surface) have an angle of over 90 degrees, the ship is at least partially upside down, so QERY_INVERTD takes this value, divides it by 90, and rounds down, leaving me with either 0 (right way up) or 1 (upside down).
  4. GRND_BANKING uses these two values to create a correct banking value, when QERY_INVERTD is 0, its doing (0×180)+(1-(0×2))QERY_BANKING, so just QERY_BANKING no adjustments necessary.
  5. For inverted flight however it's doing ±(1×180)+(1-(1×2))QERY_BANKING, so ±180-QERY_BANKING, this means it preserves anything on the counterclockwise half as going up to -180, and anything on the clockwise half as going up to 180, with a discontinuity as you cross being totally inverted.

Heading:

  1. First LOCK is working out a value from 0 to +180 by comparing the direction the ship is facing, with any attitude (pitch/upward) component excluded (VXCL). It's the direction the ship is pointing if you looked at it from directly above, projected onto the ground. North is 0, 180 is south, 90 is either east or west.
  2. I want to get a value that starts at 0 (North) and as you spin clockwise it goes up to 360, so first step, similar to where in banking I check if the ship is upright or inverted, I am checking if it's eastward (1) or westward (0) through QERY_EASTWRD. This is done from comparing the rightvector of north (90 degrees to the right, or east), in a similar way to how QERY_HEADING works, but then I divide the value by 90 and round down (so I get 0 or +1).
  3. I'm then either doing (0×360)+(1×QERY_HEADING) in the eastward half, so QERY_HEADING...
  4. ...then (1×360)+(-1×QERY_HEADING) in the westward half, so 360-QERY_HEADING.

(I do have a second heading variable in my own code not included here which outputs heading more similarly to roll, as a value of ±180 with 0 as north, in case that becomes more practical for any reason in my code).

As for using the language "heading", "banking", and "attitude", over "pitch", "yaw", "roll", the latter terms I'm reserving for ship-reference-frame, and these more aviation-derived terms for external (presently just planetary) reference frames, even though at the moment I'm launching rockets and not planes.

Hopefully I did a decent explanation of my code.

Is this absolutely the best way (by whatever metric you want to measure "best") to get these values? Probably not, but when searching for other people's solutions while muddling through these problems I couldn't find much out there, so I thought I'd offer my solutions up for reference for any future people with the same problem.


r/Kos May 02 '26

Help Ship pitches when going to lookdirup

3 Upvotes

Howdy yall,

Been messing around and essentially, when my ship is pointing away from target_v, it instead of just yawing around decides to pitch hard. Help would be much obliged.

To summarize: ship is facing like a plane initially, I draw target vector, and despite specifying a top vector, it pitches, flips, and if I am lucky, only after all that, rolls with the roof up

Many thanks.

set runmode to 0.
set target_pos to latlng(-0.096747566447266,-74.577846859067).


set hover_height to 80.


set throt_control to 0.



SET forward_pos_d TO VECDRAW(
      V(0,0,0),
      V(0,0,0),
      RGB(1,0,0),
      "Forward COE",
      1.0,
      TRUE,
      0.2,
      TRUE,
      TRUE
).


SET back_pos_d TO VECDRAW(
      V(0,0,0),
      V(0,0,0),
      RGB(0,1,0),
      "Back COE",
      1.0,
      TRUE,
      0.2,
      TRUE,
      TRUE
).


SET forward_torque_d TO VECDRAW(
      V(0,0,0),
      V(0,0,0),
      RGB(1,1,0),
      "Forward T",
      1.0,
      TRUE,
      0.2,
      TRUE,
      TRUE
).


SET back_torque_d TO VECDRAW(
      V(0,0,0),
      V(0,0,0),
      RGB(0,1,1),
      "Back T",
      1.0,
      TRUE,
      0.2,
      TRUE,
      TRUE
).




set ytard to vecDraw(
      V(0,0,0),
      V(0,0,0),
      RGB(0,155,255),
      "y tar",
      1.0,
      TRUE,
      0.2,
      TRUE,
      TRUE
).


set xtard to vecDraw(
      V(0,0,0),
      V(0,0,0),
      RGB(255,155,0),
      "x tar",
      1.0,
      TRUE,
      0.2,
      TRUE,
      TRUE
).


clearScreen.



set de to vecDraw(
      V(0,0,0),
      V(0,0,0),
      RGB(255,155,255),
      "de",
      10.0,
      TRUE,
      0.2,
      TRUE,
      TRUE
).









set heightpid to pidLoop(2,0,5,0,1).
set body_gravity to body:mu/(body:radius)^2.


set anglepid to pidLoop(3,0,3,-10,10).
set anglevelpid to pidLoop(5,0,1,-5,5).


set pitchpid to pidLoop(3,0,1,-10,10).



set heightpid:setpoint to hover_height.
lock throttle to 1.
set f_list to ship:partsdubbed("Front").
set b_list to ship:partsdubbed("Back").


set f_torque to v(0,0,0).
set b_torque to v(0,0,0).
set front_position to v(0,0,0).
set back_position to v(0,0,0).
set rollpid to pidLoop(1,0,5,-10,10).



set forward_pos_d:vecupdater to {return front_position.}.
set back_pos_d:vecupdater to {return back_position.}.
set forward_torque_d:vecupdater to {return f_torque.}.
set back_torque_d:vecupdater to {return b_torque.}.


set kp_d to 1.
set kd_d to 5.
set kd_v to 5.




set pitchpid to pidLoop(kp_d,0,kd_d*1.5,-20,20).
set pitchvelpid to pidLoop(kp_d,0,kd_v*1.5,-10,10).



set a to 0.
set b to 0.


set x to north:vector:normalized.
set z to up:vector:normalized.
set y to vcrs(z,x).
set xtar to vxcl(y,target_pos:altitudeposition(ship:altitude)).
set ytar to vxcl(x,target_pos:altitudeposition(ship:altitude)).
if xtar:mag>ytar:mag{


    set correctedangle to 90-vang(target_pos:altitudeposition(ship:altitude),y).
    set target_v to x*angleAxis(-correctedangle,z).
    set rollaxis to vcrs(z,target_v).
    set pitchtar to vxcl(rollaxis,target_pos:altitudeposition(ship:altitude)).


    
    
    
    set sign to vdot(pitchtar:normalized,target_v:normalized).
    set target_v to sign*target_v.
    set pitchaxis to target_v .
    
}


else if ytar:mag>xtar:mag{



    set correctedangle to 90-vang(target_pos:altitudeposition(ship:altitude),x).
    set target_v to y*angleAxis(-correctedangle,z).
    set rollaxis to vcrs(z,x).
    set pitchtar to vxcl(rollaxis,target_pos:altitudeposition(ship:altitude)).


    
    
    
    set sign to vdot(pitchtar:normalized,target_v:normalized).
    set target_v to sign*target_v.
    set pitchaxis to target_v .
    
   
}   


else{


    set correctedangle to 90-vang(target_pos:altitudeposition(ship:altitude),y).
    set target_v to x*angleAxis(-correctedangle,z).
    set rollaxis to vcrs(z,target_v).
    set pitchtar to vxcl(rollaxis,target_pos:altitudeposition(ship:altitude)).


    
    
    
    set sign to vdot(pitchtar:normalized,target_v:normalized).
    set target_v to (sign*target_v):dir.
    set pitchaxis to target_v .
    
}




set pitchaxistar to vxcl(up:vector,vxcl(rollaxis, target_pos:altitudeposition(ship:altitude))).
set rollaxistar to vxcl(up:vector, vxcl(pitchaxis,target_pos:altitudeposition(ship:altitude))).


set xtard:vecupdater to {return pitchaxistar.}.
set ytard:vecupdater to {return rollaxistar.}.
set qed to (xtar+ytar).
set de:vecupdater to {return qed.}.
set follow to lookDirUp(x*angleAxis(-correctedangle,z),up:vector).
lock steering to follow.


until runmode = 3{
    print(xtar:mag) at (0,1).
    print(ytar:mag) at (0,2).
    set x to north:vector:normalized.
    set z to up:vector:normalized.
        set y to vcrs(z,x).



    set pitchaxistar to vxcl(up:vector,vxcl(rollaxis, target_pos:altitudeposition(ship:altitude))).
    set rollaxistar to vxcl(up:vector, vxcl(pitchaxis,target_pos:altitudeposition(ship:altitude))).


    if alt:radar<hover_height-1 and runmode=0 {
        set heightpid:setpoint to hover_height.
        set anglepid:setpoint to 0.
    }


    else{
        set runmode to 1.
        print("runmode 1") at (0,40).
        
        set yawflatplane to vxcl(up:vector,ship:facing:starvector).
        //set target_flat_plane to vxcl()
        set rollflatplane to vxcl(up:vector,ship:facing:vector).
        set heightpid:setpoint to hover_height.
        set pitch_v to -pitchpid:update(time:seconds,vdot(pitchaxistar,pitchaxis:normalized)).
        set pitchvelpid:setpoint to pitch_v.
        set pang to pitchvelpid:update(time:seconds,vdot(ship:velocity:surface,pitchaxis:normalized)).
        set anglepid:setpoint to pang.
        set pitchaxisfollow to pitchaxis:normalized * angleAxis(pang,rollaxis).
        set rollpid:setpoint to 0.


        
        set roll_angle to rollpid:update(time:seconds, vdot(rollaxistar,rollaxis:normalized)).
        set follow to lookdirup(pitchaxisfollow,ship:up:vector)*r(0,0,roll_angle).



        print("--- PITCH ---") at (0,5).
        print("pitch_dist: " + round(vdot(pitchaxistar,pitchaxis:normalized),2)) at (0,6).
        print("pitch_v:    " + round(pitch_v,2)) at (0,7).
        print("pang:       " + round(pang,2)) at (0,8).
        print("pitch vel:  " + round(vdot(ship:velocity:surface,pitchaxis:normalized),2)) at (0,9).
        print("--- ROLL ---") at (0,11).
        print("roll_angle: " + round(roll_angle,2)) at (0,14).
        print("roll vel:   " + round(vdot(ship:velocity:surface,rollaxis:normalized),2)) at (0,15).
        print("--- SHIP ---") at (0,17).
        print("ang:        " + round(ang,2)) at (0,18).
        print("alt:        " + round(alt:radar,2)) at (0,19).
        print("pitchaxis:  " + pitchaxis) at (0,20).
        print("rollaxis:   " + rollaxis) at (0,21).
        print("throt:      " + round(throt_control,2)) at (0,22).
        print("a:          " + round(a,2)) at (0,23).
        print("b:          " + round(b,2)) at (0,24).
        
    }
    set ff to body_gravity*ship:mass/(ship:maxthrust).
    set throt_control to ff+heightpid:update(time:seconds,alt:radar).
    
    set front_position to vxcl(ship:facing:upvector,(f_list[0]:position+f_list[1]:position)/2).
    set back_position to vxcl(ship:facing:upvector,(b_list[0]:position+b_list[1]:position)/2).
    set front_thrust to a*(ship:maxthrust/2)*(ship:facing:upvector).
    set back_thrust to b*(ship:maxthrust/2)*(ship:facing:upvector).


    set f_torque to -vcrs(front_position,front_thrust).
    set b_torque to -vcrs(back_position,back_thrust).
    
    set ang to 90-vang(ship:facing:vector,up:vector).
    set des_vel to anglepid:update(time:seconds,ang).
    set anglevelpid:setpoint to des_vel.
    set pitch_angv to vdot(ship:facing:starvector,angularVel).
    set com_torque to anglevelpid:update(time:seconds,-pitch_angv).


    
    
    set f_torque_pitch to vdot(-vcrs(front_position, ship:facing:upvector), ship:facing:starvector) * (ship:maxthrust/2).
    set b_torque_pitch to vdot(-vcrs(back_position,  ship:facing:upvector), ship:facing:starvector) * (ship:maxthrust/2).
    set denom to -(f_torque_pitch-b_torque_pitch).
    if abs(denom)<0.001{


        set a to 0.5.
        set b to 0.5.


    }


    else {
        
        set b to (com_torque - f_torque_pitch* throt_control) / denom.
        set a to throt_control - b.



    }



    for f in f_list{



        f:getmodule("ModuleEnginesFX"):setfield("thrust limiter",a*100).
    }
    for bc in b_list{



        bc:getmodule("ModuleEnginesFX"):setfield("thrust limiter",b*100).
    }
    set qed to target_v.
   
    
    
    


}

r/Kos May 01 '26

Suggestion Make the kOS controllers movable in IVA and an inventory item?

5 Upvotes

Would really like to place them on some of my career save spacecraft.

edit: I meant EVA construction mode. Idk why I thought it was called IVA.


r/Kos Apr 27 '26

Video Wrote an auto docking script

70 Upvotes

r/Kos Apr 28 '26

Help Script doesn't reset after reloading to a quicksave.

1 Upvotes

Hi, I noticed a part of my script started behaving inconsistently after I reloaded a save so I picked out the line at fault and pasted it into a new "debugging" script just to see its behaviour:

The line at fault is: VELOCITYAT(SHIP, TIME + ETA:APOAPSIS):SURFACE:X.

and the debugging script I used was:

clearscreen.

UNTIL SAS{

PRINT SHIP:VELOCITY:SURFACE:X AT (0,0). // val1

PRINT VELOCITYAT(SHIP, TIME + ETA:APOAPSIS):SURFACE:X AT (0,10). // val2

PRINT TIME AT (0,20). //val3

PRINT ETA:APOAPSIS AT (0,30). //val4

WAIT 1.

}

I made a save, ran the debugging script and noted the starting values, warped about 10 minutes and stopped the script and noted the final values.

I then reloaded the save, ran the script again and compared these new starting values to what I noted before.

Values 3 and 4 were the same as the previous starting values which I expect, but values 1 and 2 were the same as the previous final values.

Any help to understand why values 1 and 2 did not reset like values 3 and 4 would be greatly appreciated, thank you! :)


r/Kos Apr 27 '26

Help Different height every time

3 Upvotes

i am new and wanted to make a simple take off and land but the height of the fp9 test spacex ship is diffrent each time can someone help me

lock throttle to 1.

lock steering to up.

stage.

wait until SHIP:APOAPSIS >= 757.

lock throttle to 0.

wait 17.525.

lock throttle to 1.

SET GEAR TO ALT:RADAR>200.

wait 5.112.

lock throttle to 0.5.

wait 0.1.

lock throttle to 0.

until false.


r/Kos Apr 26 '26

Help Can someone help please why my rocket doesnt stages when it is done with apoapsis raising burn (Repost)

5 Upvotes
function main {
    dolaunch().
    doAscent().
    until apoapsis > 100000 { 
    doAutoStage().
    }
    doShutdown().
}


function dolaunch  {
lock throttle to 1.
dosafestage().
doAutoStage().
}




function doAscent {
lock targetPitch to 88.963 - 1.03287 * alt:radar^0.409511.
set targetDirection to 90.
lock steering to heading(targetDirection, targetPitch).
}





function doAutostage {


   if not(defined oldThrust) {
    declare global oldThrust to ship:availablethrust.
    }
   if ship:availableThrust < (oldThrust - 10){
    dosafestage(). wait 1.
    declare global oldThrust to ship:availablethrust.
   } 
}




function doShutdown {
lock throttle to 0.
lock steering to prograde.
wait until false.
}


function dosafestage {
    wait until stage:ready.
    stage.
}


main().

r/Kos Apr 26 '26

Help Loading librarys

2 Upvotes

Been getting into kos and am already struggling with a logistics problem, i want to be able to have very easilly imported librarys, but cant find a nice solution and am very close to just giving up and leaving everything in the archive, but then if say im doing a crewed landing on the other side of a planet, and dont have ksc connection, i wont have suicide burn scripts or anything

should i maybe just give up on trying to make a generic loader and have everything manually load the librarys it needs?

Im mostly curious to see the way other people do this sort of thing, rather than fixing mine currently, im sure i can fix it, but i may also be doing something very silly, these are also the first kos scripts i have ever written (i have quite a good idea of what my launch guidence will look like, but currently it is just a bit of R simulations to tweak parameters to find a nice turn)

This is my program for loading scripts (loadlib.ks), the idea is to just be able to run runpath(0:/loadlib.ks) conditionally at the start to grab it from ksc, or load itself if its already on local disk, then after that you can just call loadlib("lib/epiclib") to add another, but it just does not work, i dont know if im completely misunderstanding how kOS works, but im entirely stumped and do not know what is not working, i get very odd errors about name collisions

loadlib.ks ```kscript @lazyglobal off.

parameter filepath is "loadlib". loadlib(filepath).

/// loads a library at the given path in 0:/lib global function loadlib { parameter filepath is "loadlib".

local archive_path to "archive:/" + filepath.
local local_path to filepath.

if homeconnection:isconnected {
    if exists(local_path) {
        deletepath(local_path).
    }
    copypath(archive_path, local_path).
}

if exists(local_path) {
    runpath(local_path).
} else {
    print "Missing library: " + filepath.
}

} ```

This is my generic bootstrap for crafts to get them the load lib function, this also leads to a very unfun chicken and egg where if i have a specialized boot file, i still want it to run this one first, but dont have the loadlib function yet :P

boot/bootstrap.ks /// loads the loadlib function if exists("loadlib.ks") { runoncepath("loadlib.ks"). } else if homeconnection:isconnected { runoncepath("archive:/loadlib.ks", "loadlib"). } else { print "WARNING: BOOT STRAP COULD NOT FIND loadlib.ksm ON LOCAL DRIVE AND CANNOT CALL HOME TO GET IT". FROM {local x is 3.} UNTIL x = 0 STEP {set x to x-1.} DO { print char(7). wait 0.1. print char(7). wait 0.1. print char(7). wait 0.5. } }

and finally the file im actually trying to write, very simple orbit script, that i have not written any of because im stuck on getting library loading

launch.ks ``` @LAZYGLOBAL OFF.

run loadlib. loadlib("lib/utils").

clearscreen.

beep(). input(0, 0, "test").

```

also the utils file, just a beep and little line editor for inputting launch parameters, i actually quite like the line editor its very fun working with such a limited enviroment, it ends up giving you alot of freedom to play with ideas you normally would not when programming

lib/utils.ks ``` @LAZYGLOBAL OFF.

/// simple line editor for string input /// /// PARAMETERS: /// line -- the line to print the prompt at /// col -- the colunmn to print the prompt at /// prompt -- the prompt to present to the user /// /// DEFAULTS: /// line -- 0 /// col -- 0 /// prompt -- "input: " global function input { parameter col is 0, line is 0, prompt is "input: ". print prompt at (col,line).

local termin is terminal:input.

local ignored is list(
    termin:deleteright,
    termin:upcursorone,
    termin:downcursorone,
    termin:leftcursorone,
    termin:rightcursorone,
    termin:homecursor,
    termin:endcursor,
    termin:pagedowncursor,
    termin:pageupcursor
).

local input_stack is stack().
local character is "".
local done is false.

lock line_end to col + prompt:length + input_stack:length.

print "_" at (line_end, line).

until done {
    local character is termin:getchar().

    if ignored:contains(character) {
        beep.
    } else if character = termin:return {
        print " " at (line_end, line). // remove cursor
        set done to true.
    } else if character = termin:backspace {
        input_stack:pop().
        // print cursor and whitespace to clear character after it
        print "_ " at (line_end, line).
    } else {
        // print character and cursor
        print character + "_" at (line_end, line).
        input_stack:push(character).
    }
}

local output_string is "".
for character in input_stack {
    set output_string to output_string:insert(0, character).
}
return output_string.

}

/// triggers a terminal beep by printing char(7) global function beep { print char(7). }

```


r/Kos Apr 25 '26

Help Can someone help please? My code does everything at the same time. I added heading 90 70 after stage 1 and yet the second it starts it ignores the heading 90 90. The same goes with (wait 2. stage.) it completely ignores previous commands ans stages 2 seconds into the flight no matter where i put it

3 Upvotes

Sorry for dumb mistakes i am a complete beginner and trying to learn from documentations and videos but this one doesn't work and i have no idea how to fix it

PRINT "Press SPACE to start the launch sequence.".
TERMINAL:INPUT:GETCHAR(). 
PRINT "Starting the Sequence.".


Lock steering to heading(90,90).


stage.


on ship:maxthrustat(0) stage. 
wait 2.
stage.
lock steering to heading(90,70).
on ship:maxthrustat(0) stage.
wait until altitude > 5000 and verticalspeed < 0.
stage.
wait until false.PRINT "Press SPACE to start the launch sequence.".
TERMINAL:INPUT:GETCHAR(). 
PRINT "Starting the Sequence.".


Lock steering to heading(90,90).


stage.


on ship:maxthrustat(0) stage. 
wait 2.
stage.
lock steering to heading(90,70).
on ship:maxthrustat(0) stage.
wait until altitude > 5000 and verticalspeed < 0.
stage.
wait until false.