# [1.3] kOS Scriptable Autopilot System v1.1.3.0

## Recommended Posts

Silly question, doesn't g decrease with distance? or is it too small a difference?

Not a silly question. There are two different g values being used here.

The g value when calculating mass flow rate is always 1 standard earth gravity (9.80665m/s2, 9.81m/s2 is usually used for most stuff though). However since the ksp exposes the mass flow rate of the engines you donÃ¢â‚¬â„¢t need to calculate it, just add it all up from the different engines.

The g value in calculating the force due to gravity does decrease with distance and you can see my calculation for it in the code i put up (re-posting the line here for reference)

`local grav is -(body:mu/(body:radius+ship:altitude)^2)*up:vector. // negavive magnitude to up vector is down.`

Would it make sense to compute lift as the component along vessel:top and real drag as the component along surface velocity?

Mostly yes. I am actually defining drag as the force that slows you down and lift as the force causing you to deviate. so the drag being along the surface velocity is correct. And while most of the time the lift is acting through vessel:top i am using the component at right angles to the surface velocity (so it could be coming out the side of your vessel too if you yaw to far.)

would you guys agree that terminal velocity is reached when the magnitude of drag equals mass times g, if we apply the above formulas?

Yes.

##### Share on other sites
According to this.. that speed is not right - the horizontal speed should be close to Zero from the start

It's literally just spitting out exactly what the KSP API says, for this:

Vessel.horizontalSrfSpeed

I have no clue why that is returning weird numbers that don't make sense.

##### Share on other sites
According to this.. that speed is not right - the horizontal speed should be close to Zero from the start, relative to the SOI body (Earth), and should remain close to zero until the rocket pitches over from the vertical.

What's VESSEL:AIRSPEED? I'd expect that to return what I first expected SURFACESPEED to return.

##### Share on other sites

I'd expect Vessel:Airspeed = (Vessel:SURFACESPEED^2 + Vessel:VERTICALSPEED^2) ^0.5... according to the KOS definitions.

##### Share on other sites

I'm not sure whether it me or not, but I notice that when staging.. the throttle reverts back to the 'launch' throttle setting... Is this a bee, or a feature

I get around it with..

IF STAGE:LQDOXYGEN < 0.1 // LqdOxy tanks on first two stages

{ // are enough to get us into orbit.

STAGE. // Staging causes throttle to reset...!!

LOCK THROTTLE TO 1. // Annoying, but lets max it anyway

}

;***********************************************************

; EXTRA QUESTION AS THE WEBSITE IS COMBINING MY TWO POSTS :-)

;***********************************************************

I seem to be struggling a bit here.. maybe with common sense

I trying as much to simplify the launch to orbit, in 'cooked' mode, but have a problem in converting a vector into a HEADING(direction, pitch).

Maybe I'm having a dense moment, but the documentation doesn't seem to be clear about this ??

Thanks for any help

Der Col

Edited by ColKlonk

##### Share on other sites

if @VFB1210 or anyone else wants to give these a go and fly around with lift and drag arrows coming out their vessel here is my lift/drag script.

you will need to stick an accelerometer (the science experiment) on the vessel and the script still produces the occasional spike in lift or drag.

feedback with any improvements or fixes would be greatly appreciated.

example_lib_lift_drag.ks

`set ag1 to false.run lib_lift_drag.ks.clearscreen.set drag to vecdrawargs(v(0,0,0),v(0,0,0),red,"Drag",1,True).set lift to vecdrawargs(v(0,0,0),v(0,0,0),blue,"lift",1,True).print "Lift:" at (0,1).print "Drag:" at (0,3).until ag1 { set vec to lift_drag(). set lift:vec to vxcl(ship:srfprograde:vector,vec). set drag:vec to vdot(vec,ship:srfprograde:vector)*ship:srfprograde:vector. print round(lift:vec:mag,2) +" kN     " at (6,1). print round(drag:vec:mag,2) +" kN     " at (6,3).}.set ag1 to false.`

lib_lift_drag.ks

`@LAZYGLOBAL off.function lift_drag { local M is ship:mass. local a is ship:sensors:acc. local grav is -(body:mu/(body:radius+ship:altitude)^2)*up:vector. // negavive magnitude to up vector is down. local thrust is 0.     // calculated by queriying the engines local fuel_flow is 0.// calculated by queriying the engines local eng_list is list(). list engines in eng_list. for eng in eng_list {  set thrust to thrust+eng:thrust.  set fuel_flow to fuel_flow + eng:fuelflow. }. local resultant is M * ( a - grav ) + fuel_flow * vxcl(ship:up:vector,ship:velocity:surface) - thrust * ship:facing:vector. return resultant.}.`

##### Share on other sites
I'd expect Vessel:Airspeed = (Vessel:SURFACESPEED^2 + Vessel:VERTICALSPEED^2) ^0.5... according to the KOS definitions.

But we know those seem to be inaccurate. So what _is_ it in the situation we got an image of?

##### Share on other sites

I trying as much to simplify the launch to orbit, in 'cooked' mode, but have a problem in converting a vector into a HEADING(direction, pitch).

Maybe I'm having a dense moment, but the documentation doesn't seem to be clear about this ??

Thanks for any help

Der Col

This is what I did:

`// run program as follows: ->program name ->LL(Start ALTITUDE for Gravity Turn) i.e: RUN LL(5) starts altitude turn at 5 kmPARAMETER StartTurnAt.LOCK WantedPitch TO MAX(MIN((90 - (90*(Ship:ALTITUDE/BODY:ATM:HEIGHT)))*(90/(90 - 90 * (StartTurnAt / BODY:ATM:HEIGHT))),90),0).LOCK STEERING TO HEADING(90,WantedPitch).`

Basically, I lock my orientation to due east, with the pitch scaling as an asymptotic curve from 90 to 0 between the start of the turn and the end of the atmosphere. If I need to launch to a different plane, then I could edit the '90' directly (although that is really more finicky - you really want to head a little to the side of due north/south, as to cancel the unwanted velocity due to rotation of planet).

in the LOCK statement, the MAX prevents the ship from turning back down towards the planet (pitch < 0) if I am above the atmosphere. The MIN statement is what allows the altitude turn start height to work (Basically, the function part returns pitch > 90 until the desired height is reached)

Edited by ABZB

##### Share on other sites
It's literally just spitting out exactly what the KSP API says, for this:

Vessel.horizontalSrfSpeed

I have no clue why that is returning weird numbers that don't make sense.

KER also reports weird horizontal velocities. I was told over in that thread that it's a bug in recent versions of stock KSP.

...and just as I was writing this, the new KER release dropped, with a fix for this. Whatever they're doing, kOS could in theory do the same thing.

##### Share on other sites

I seem to be struggling a bit here.. maybe with common sense

I trying as much to simplify the launch to orbit, in 'cooked' mode, but have a problem in converting a vector into a HEADING(direction, pitch).

Maybe I'm having a dense moment, but the documentation doesn't seem to be clear about this ??

https://github.com/KSP-KOS/KSLib/blob/master/library/lib_navball.ks

##### Share on other sites

The record of the live stream from tonight is now up on Twitch:

http://www.twitch.tv/dunbaratu/c/6959259

##### Share on other sites

I never could imagine that mass flow would play here, but hey this is rocket science, where anything can happen in equations. Out of curiosity, what values did you get while flying?

To be truthful, even I have a difficult time wrapping my mind around how (dm/dt)v actually plays into the equation, but the math doesn't lie, and the math that derives it is very simple, and makes it plain that it cannot be ignored. (Provided you know Calculus, that is.) But physically, it is pretty unintuitive.

(Again, as in my last post, bolded values are vectors. Just for bookkeeping and clarity.)

So, to start off, we have commonly taught version of Newton's 2nd law: ÃŽÂ£F = ma. This is read as "The sum of all external forces on an object (ÃŽÂ£F) is equal to the mass of the object multiplied by the rate at which it accelerates." As I said in a previous post, this is not 100% true in every possible situation, but it works in the case of a constant mass. (In fact, as you'll see later, it actually IS this in the case of constant mass. The general case will simplify down to this.)

However, to get the whole story, you need the equation ÃŽÂ£F=dp/dt. This is read as "The sum of all external forces on an object is equal to the time derivative of its momentum." Now, I'm sure you know what momentum is, it is mass multiplied by velocity! Or mv. But, what the heck does "time derivative" mean?

Well, in calculus, there are three big concepts: limits, derivatives, and integrals. Limits hare extremely useful tools, but they're not relevant here. All you need to know about them for now is that they are used in the construction of the next two tools we gain from calculus: derivatives and integrals. Integrals are also extremely useful, but also very confusing, and not needed here, so we will throw them out for now too. That leaves us with derivatives, which is the relevant topic. A derivative, in short, is the rate of change of something. It can be the same everywhere (as is the case in a linear function), it can change smoothly according to its own function (as with any polynomial that isn't a linear function), or it can even jump around pretty wildly in some weird cases. But, for any function which has a derivative, the derivative will tell you how fast that function is changing at any point you want! (Well, not any point you want, there are some rules. But they're not relevant to us here.) That is what a derivative is, it is a function that tells you how fast another function is changing at any point you need to know. In the case of a time derivative, we are concerned with how our function changes as time changes. You can take a functions derivative with respect to any variable you want, but time is the one we are looking for here. Whenever you see something like dm/dt, that is what it means. You want to know how the top variable (m, in our case) changes as the bottom variable (t) changes. Don't worry about the d's, those are just part of the notation.

So, for the sake of brevity, we are going to skip a lot of steps here, stuff like calculating derivatives by hand, and go right to the shortcuts! As it turns out, derivatives of certain types of functions always follow the same rules, and instead of doing everything out the long way, you can use these rules to calculate your derivative much quicker. The rule we are interested in is called The Product Rule.

The product rule says that whenever you have a function (which we will call h(t)) that is equal to two other functions multiplied by each other, (e.g. h(t) = f(t)*g(t)) the derivative of h(t) is equal to the derivative of the first function, multiplied by the second function, plus the first function multiplied by the derivative of the second function. (dh/dt = df/dt * g(t) + f(t) * dg/dt)

Now that we have our rule, let's see how it applies to what we were talking about: we know that ÃŽÂ£F = dp/dt. And we know that p = mv. And we know how to take the derivative of two things multiplied together, so let's do that! Our result ends up being dp/dt = (dm/dt) * v + m * (dv/dt). Now, it just so happens that dv/dt (the rate of change of velocity as time changes) has its own name: acceleration. It also has its own symbol: a. So we'll plug a in for dv/dt so things get less cluttered.

Now we have ÃŽÂ£F = dp/dt = (dm/dt) * v + ma. This is the general form of Newton's 2nd law. But, most of the time when you're using it, the mass of the thing your using it on (such as a billiard ball, to pull an example out of a hat) doesn't change at all. Ever. Period. In this case, dm/dt (the rate of change of mass as time changes) is 0. Everywhere. Always. So, if we plug that in, we get ÃŽÂ£F = dp/dt = 0 * v + ma = ma. In this case, the bit with dm/dt goes away, and the law simplifies down to what you were taught in school. But, in our case, we have rockets that do little else but throw their mass away really fast so they can get to space. (Or the ground 100 feet from the launch pad.) In this case, our mass is always changing, so dm/dt is never zero, and so that part of the equation never goes away, and so we can't pretend it doesn't exist, we have to take it into account. That's the math, and the math doesn't lie.

TL;DR: I don't understand it either, but the math says it has to be there, and the math doesn't lie.

Also, unfortunately I haven't had much time to play with KSP and experiment with this, as much as it's been gnawing at me. So I have no data to report.

##### Share on other sites
This is what I did:

Basically, I lock my orientation to due east, with the pitch scaling as an asymptotic curve from 90 to 0 between the start of the turn and the end of the atmosphere. If I need to launch to a different plane, then I could edit the '90' directly (although that is really more finicky - you really want to head a little to the side of due north/south, as to cancel the unwanted velocity due to rotation of planet).

in the LOCK statement, the MAX prevents the ship from turning back down towards the planet (pitch < 0) if I am above the atmosphere. The MIN statement is what allows the altitude turn start height to work (Basically, the function part returns pitch > 90 until the desired height is reached)

Thanks.. I've done something similar.. but am stuck at how I'd like to implement velocity control.

`SET m_Thrott to 1.SET m_starthgt TO 500.SET m_endhght TO 130000.SET m_pitch TO 90.SET m_heading TO 90 - 28.404.SET dumpheight TO 110000.// START LAUNCH SEQUENCE //PRINT "COUNTDOWN SEQUENCE BEGIN".FROM {local countdown is 5.} UNTIL countdown = 1 STEP {SET countdown to countdown - 1.} DO {    PRINT "..." + countdown.    WAIT 1.}LOCK THROTTLE TO m_Thrott .LOCK STEERING TO UP.WAIT 1.STAGE.// Rotate to correct heading// This takes about 350mCLEARSCREEN.PRINT "ROTATING TO HEADING: " + m_heading.LOCK STEERING TO HEADING(m_heading , m_pitch).// Dump egg fairing when over 110km// You can put this trigger anywhere - better earlier than late :-)WHEN SHIP:ALTITUDE > dumpheight THEN{  toggle ag1.}// Pitch over point and wait a few secondWAIT UNTIL SHIP:ALTITUDE > m_starthgt.LOCK STEERING TO HEADING(m_heading , 87).WAIT UNTIL SHIP:ALTITUDE > m_starthgt + 400.// This control loop continues until we exit the atmosphere at 130km// then the Orbit stabilisation loop takes over.UNTIL SHIP:ALTITUDE > end_height{  IF STAGE:LQDOXYGEN < 0.1    // LqdOxy tanks on first two stages  {                // are enough to get us into orbit.    STAGE.            // Staging causes throttle to reset...!!    LOCK THROTTLE TO 1.        // Annoying, but lets max it anyway  }  SET m_pitch TO 87 * ((m_endhght - SHIP:ALTITUDE)/end_height).  IF m_pitch < 0 { SET m_pitch TO 0.}  LOCK STEERING TO HEADING(m_heading , m_pitch).// Put throttle control here, based on difference between// prograde and facing vectors}CLEARSCREEN.PRINT "STARTING ORBITAL MANEUVER:".LOCK THROTTLE TO 1.`

Thanks all.

I'll have gander at the other code examples...

##### Share on other sites

From what I've learned from the current version of kOS let me run my idea of how to organize library code by you. A set of library files, like

nodes.ks

`function aponode {    parameter  altitude.    local myvar is 1.    ...}.function perinode {    parameter  altitude.    ...}.function exenode {    ...}.`

and mission.ks

`run loadfuncs.run aponode(100).run exenode().`

`run nodes.// more library files to be added`

Makes sense or are there better solutions recommended?

##### Share on other sites
if @VFB1210 or anyone else wants to give these a go and fly around with lift and drag arrows coming out their vessel here is my lift/drag script.

I'll sure try that when I get back to fixing my space plane that doesn't want to go on orbit.

That's the math, and the math doesn't lie.

TL;DR: I don't understand it either, but the math says it has to be there, and the math doesn't lie.

Sometimes the truth is painful, and math is a b***,but it's true it doesn't lie.

I'll reread about Oberth effect, I feel that's where it comes from. If that's the case, I'll be so happy to finally start grasping its meaning.

Also, unfortunately I haven't had much time to play with KSP and experiment with this, as much as it's been gnawing at me. So I have no data to report.

I'm anxious to see it on my space plane, with arrows side by side with m.a

That was a calculus 101 along with rocket science 101. Thanks for putting it down as simple as it can get.

Edit: well, oberth effect is not related to mass loss.

But if you integrate flow rate over time you're getting a lighter vessel, I'll try that way and see whether it leads me anywhere. God it's tough to think over a tiny phone screen!

BTW I'm still puzzled by that constant g, more on that later.

Edited by Qigon

##### Share on other sites

I like the integration with RemoteTech, mods that play nicely are great!

Any thoughts on integration with AntennaRange as well? It has a simplified LoS and remote control model than RT, for us softcore types.

##### Share on other sites

Quigon-integrating the flow rate leads to a lighter vessel because integration is actually the opposite of differentiation. When you integrate the mass flow rate, you go from knowing how fast you're throwing mass away to finding out how much you've thrown away. And of course, once you've thrown away some of your rocket's mass, it is going to be lighter.

And the constant g has to do with the fact that is just a conversion factor, and in this case has nothing to do with the actual strength of the gravitational field. At some point, someone needed to dividentify by an arbitrary value with units [l]/[t]^2, and they said "I'm just going to use g, because everyone agrees that that is 9.80665m/s^2, or 32.174ft/s^2, or whatever it is in whatever units they want to use. They all know what it is, and there will be no confusion when calculating."

##### Share on other sites
Quigon-integrating the flow rate leads to a lighter vessel because integration is actually the opposite of differentiation. When you integrate the mass flow rate, you go from knowing how fast you're throwing mass away to finding out how much you've thrown away. And of course, once you've thrown away some of your rocket's mass, it is going to be lighter.

And the constant g has to do with the fact that is just a conversion factor, and in this case has nothing to do with the actual strength of the gravitational field. At some point, someone needed to dividentify by an arbitrary value with units [l]/[t]^2, and they said "I'm just going to use g, because everyone agrees that that is 9.80665m/s^2, or 32.174ft/s^2, or whatever it is in whatever units they want to use. They all know what it is, and there will be no confusion when calculating."

Got it on the g thing, thanks for the patience.

About flow rate, I still can't wrap my head around the v, maybe it makes more sense if I describe momentum from a kinectic point of view. There should be a downside to being some 15 years away from calculus anyway. I'm quitting the math and will start running some experiments, maybe I'd need to build a VTOL to have control over those variables and see how dm/dt behaves when aligned or orthogonal to v.

Math won me again

##### Share on other sites

dm/dt is a scalar value, a regular number, not a vector. It can't be parallel or orthogonal to v.

##### Share on other sites

@VFB1210

You seem far more familiar with this than me. can you clarify:

should I be taking the +v(dm/dt) into account when calculating the force due to gravity as well as when calculating the force from the thrust?

and if so should it be the full velocity or just the component of velocity in the direction of the force (vertical velocity)?

Thanks

##### Share on other sites

It should be taken into account whenever you are calculating the net force on the vessel. But the v(dm/dt) term only emerges when you are burning because dm/dt is zero when you aren't.

##### Share on other sites

Is there an emulator for kOS? I have searched for a while and have not turned up any results.

##### Share on other sites
Is there an emulator for kOS? I have searched for a while and have not turned up any results.

Uhm. Can you elaborate a bit further what you mean by this? Do you want to run a kOS program outside of KSP? In a sense, the kOS mod *is* the emulator, in the sense that the kOS computer doesn't really exist as a hardware device anywhere in the world right now, and only exists in "emulation" inside a computer game.

There's a sort of neverending slow refactor of trying to divorce all the things kOS does that don't use Unity from all the things it does that do need Unity, with an eye toward us eventualy being able to run unit tests of small kerboscript "proof" programs as part of the build pipeline, without having to run KSP to do it. But that's a major task that's only being embarked upon half-heartedly in small pieces, because it's not "interesting" enough. If that ever goes further, it would have to include a kOS virtual CPU that lives outside of Unity and runs scripts so long as those scripts never need to call SHIP:, or VESSEL:, or BODY:, etc.

##### Share on other sites
There's a sort of neverending slow refactor of trying to divorce all the things kOS does that don't use Unity from all the things it does that do need Unity, with an eye toward us eventualy being able to run unit tests of small kerboscript "proof" programs as part of the build pipeline, without having to run KSP to do it. But that's a major task that's only being embarked upon half-heartedly in small pieces, because it's not "interesting" enough. If that ever goes further, it would have to include a kOS virtual CPU that lives outside of Unity and runs scripts so long as those scripts never need to call SHIP:, or VESSEL:, or BODY:, etc.

I've been looking at this.. creating a mod that runs externally to KSP... and there does seem to be a way to do it. (only windows at the mo though)

I must do some further reading and write a few test programs to check this.

The mod will link up to the Unity and KSP pieces in the 'same way' as mods currently do, and if you have an extra screen, the mod GUI can sit on this while KSP runs on the other screen.

##### Share on other sites

When I crate a maneuvernode to enter a circle orbit during launch, I think I shall get Velocity at Apoapsis firstly.

So I code VelocityAt(Ship,Time:Seconds+ETA:Apoapsis):Orbit:Mag,

but its value is different from real velocity. So new orbit's Apoapsis will be different from I expect.

like following:

set EtaTime to ETA:Apoapsis.

set V1 to VelocityAt(Ship,Time:Seconds+EtaTime):Orbit:Mag. //get V1 -> Velocity at Apoapsis according to current orbit. BUT IT RETURN A WRONG VALUE

set V2 to Sqrt (Constant():G*Kerbin:Mass/Kerbin:Radius). //get V2 -> Velocity shall be after node, I want to get a circle orbit. calculate from GM=V2R

set MyNode to Node (Time:Seconds+EtaTime,0,0,V2-V1). //get deltaV=V2-V1