# [1.7.3] kOS v1.1.9.0 : kOS Scriptable Autopilot System

## Recommended Posts

20 hours ago, jefferyharrell said:

...

Since acceleration is the rate at which the speed is changing, you could measure airspeed / speed at two points of time with a known seperation between the measurement, then divide the difference by the time and you got the acceleration. Of course you'd need to do that inside a main loop which runs all the time, otherwise you'd only get one measurement, it would look something like this:

```set p to 1.
until p = 0
{
set v1 to airspeed.
wait 0.01.
set v2 to airspeed.
set acc to (v2-v1) / 0.01.
print "acc: " + round(acc,2) + "m/s^2     " at (0,2).

on ag10 set p to 0.
}```

You might need to multiply or divide acc by a factor of 2 or 4, don't know why it sometimes doesn't work out directly.

##### Share on other sites
Posted (edited)

@Kartoffelkuchen Yeah, I did some work along those lines.

Somebody sanity-check me here. When a spacecraft is in orbit above Kerbin's atmosphere and the engines are off (including RCS thrusters), the only force acting on the vehicle is gravity, right? (Not in real life, just in KSP.) So if we say v is the spacecraft's velocity in the orbital reference frame (a vector quantity), and the spacecraft is at altitude r (measured from V(0,0,0) to the center of the planet), then dv/dt should be equal to μ / r².

I went round and round on this yesterday until I started to doubt my basic arithmetic skills. The following code snippet works...

```DECLARE LOCAL Δt IS TIME(0).
DECLARE LOCAL tPrevious IS TIME(0).
DECLARE LOCAL vPrevious IS SHIP:VELOCITY:ORBIT.

UNTIL FALSE {
SET Δt TO TIME() - tPrevious.
SET tPrevious TO TIME().

DECLARE LOCAL dv IS (SHIP:VELOCITY:ORBIT - vPrevious) / Δt:SECONDS.
DECLARE LOCAL grav IS SHIP:BODY:MU / SHIP:BODY:DISTANCE^2 * SHIP:BODY:DIRECTION:VECTOR.

PRINT( (dv - grav):MAG ).

SET vPrevious TO SHIP:VELOCITY:ORBIT.
WAIT 0.
}```

...but only approximately, and only to a good accuracy above a certain critical orbital altitude. In a 100 × 100 km orbit above Kerbin, this program returns a small number, on the order 0.0002 m / s². But down at 86,750 m (the lowest altitude you can cheat-set-orbit your spacecraft into) the error is much bigger, of order 0.6612 m / s².

Is an unaccounted-for acceleration of two feet per second per second going to screw up my programs? Doubtful. But I'm more concerned about why the math isn't coming out right. So far my leading hypotheses are (a) KSP is just being buggy yet again or (b) I've been staring at this for so long I've gone cross-eyed and I'm missing something obvious.

Edited by jefferyharrell

##### Share on other sites
1 hour ago, jefferyharrell said:

DECLARE LOCAL grav IS SHIP:BODY:MU / SHIP:BODY:DISTANCE^2 * SHIP:BODY:DIRECTION:VECTOR.

Have you confirmed whether SHIP:BODY:DIRECTION:VECTOR is an unit vector?

##### Share on other sites
1 hour ago, scimas said:

Have you confirmed whether SHIP:BODY:DIRECTION:VECTOR is an unit vector?

I have now. SHIP:BODY:DIRECTION:VECTOR:MAG returns exactly 1 every time I look at it.

##### Share on other sites

Then it's probably completely caused by the size of orbit and the sampling rate. At the 86 km orbit, the angle by which your velocity vector rotates in a finite non-zero Δt is much more than in a 100 km orbit in the same Δt. Try an even higher orbit and the error will become even smaller.

Since the angular velocity goes down as r^(-3/2), the error also probably false at the same rate.

##### Share on other sites

Hello, I'm currently writing a piece of code for a boostback burn for my Falcon 9. I want it to steer to (270, 30) to start the burn but when i do "lock steering to heading(270, 30), it starts turning to 270 but only levels out the RCS when it goes past the 270, 30 point. Then it tries to go back and does the same thing again and again, swaying back and forth and never locking to 270, 30. What's going on here? How can i fix this? Thanks.

KSP 1.6.1

##### Share on other sites

I have another feature request! I hope it's more plausible than my last one, but I suspect it's probably not really a very good idea. It's this: FORTRAN syntax for exponentiation.

In kOS, you raise a number to a power by doing

`x^y`

which makes perfect sense. It's the C-language exponentiation operator, and it's used in a ton of other languages. But FORTRAN uses

`x**y`

for exponentiation, and for what it's worth Python uses this operator too. I've been copy-and-pasting a LOT of code from a Python-based symbolic algebra system into kOS, and it's great but for having to change all the "**"s to "^"s. Would it be possible for kOS to support both the ^ operator and the ** operator? It would of course be terrible to switch from "^" to "**", but it'd be terrific if either one worked.

I have absolutely no idea how language parsers work, so this could be anything from utterly trivial to completely impossible. But I thought I'd ask!

While we're on the subject, a built-in EXP function wouldn't be the worst thing in the world. It's trivial to include your own by writing

```DECLARE GLOBAL FUNCTION EXP {
DECLARE PARAMETER x
RETURN CONSTANT:e^x
}```

but it'd be nice not to have to.

Thanks!

##### Share on other sites

@jefferyharrell, wouldn't it be easier to use your code editor of choice and do a "find & replace"?

##### Share on other sites
Just now, Tabris said:

@jefferyharrell, wouldn't it be easier to use your code editor of choice and do a "find & replace"?

Easier than adding "**" as an operator to kOS? Well yeah. But when you copy-and-paste a lot of equations with the "**" notation in them, even find-and-replace becomes shockingly tedious after a while.

##### Share on other sites

Slowly getting good enough for a release I think.

So much new stuff has been added and remade since the last video, a much better & smoother pitch control logic, a glideslope control logic which makes sure the plane stays roughly in the desired glideslope, a new landing "flare mode" trigger, which contributes to overall much more accurate and smoother landings. Also some more safety features have been added, for example bank angle & pitch limits, a ground-proximity-warning-system (you can see the warnings in the video, however system was not activated because the plane was in a lanidng configuration), flight prediction and terrain scanning and of course also a rule to disable some of these systems in case of a detected emergency, kind of like an alternate flight law in an Airbus. Really like how this is coming along, crazy that it's been over a year since I started this project.

##### Share on other sites
On 7/11/2019 at 1:16 AM, jefferyharrell said:

[...] even find-and-replace becomes shockingly tedious after a while.

If I may add, most decent editors can record, save, and exec saved macros (e.g. Sublime Text). You have a pretty good usecase for them here. Text replacements via RegEx can also come in very handy every now and then.

##### Share on other sites

There's a new version of kOS - v1.1.9.0.

You can get it from Curse or from kOS's Github.  WARNING SPACEDOCK IS BROKEN AS I WRITE THIS AND NOT UPDATED YET - YOU HAVE TO USE ONE OF THE OTHER SITES AT THE MOMENT.

(I have tried for about an hour to get it uploaded to Spacedock but their upload progress bar keeps hanging forever and I can't wait for them to get fixed so I'm publishing without Spacedock for now.  I'll update Spacedock later if I get a response from my support e-mail about it.)

# v1.1.9.0 Breaking Bounds

This update is a mix of new features, mostly

### NEW FEATURES

• Bounding box information for parts and for the vessel as a whole is now exposed for scripts to read. pull request 1. pull request 2.
• The above bounding box feature also came with some new suffixes for Vecdraw so you can now draw plain lines (suppress the arrowhead, suppress the opacity fade) with them.
• Lexicons can now use the suffix syntax. i.e. where you say `mylex["key1"]` you can now say `mylex:key1`, provided the key is something that works as a valid identifier string (no spaces, etc). pull request.
• Can now set the default terminal Width and Height for all newly spawned terminals. pull request 1.
• A ternary conditional operator exists in kerboscript now, using the syntax `CHOOSE expr1 IF bool_expr ELSE expr2`. If bool_expr is true, it returns expr1. If it's false, it returns expr2. pull request.
• Added support to read more atmospheric values from KSP. pull request.

### BUG FIXES

• TimeSpan now peeks at the KSP game to learn its notion of how long a day is, and how long a year is, rather than hardcoding the values. pull request.
• Fix cooked control triggers not working during a WHEN/ON trigger. pull request.
• Fix mangled state if kOS is out of electricity when scenes switch or the game is saved. pull request.
• Obsolete list command documentation removed. pull request.
• Allow part modules'd fields to work even when no GUI name is defined. It seems that the main game allows the GUI name to be left out and if so it inherits from the base name under tne hood. Now kOS follows this behaviour. pull request.
• Prevent using UNSET on built-in variable names like SHIP, ALTITUDE, and so on. pull request.
• RP-1 used a different technique to lock out controls due to insufficient avionics that kOS didn't know about. kOS bypassed this lockout and still controlled the vessel anyway. This is no longer the case. pull request.
• PartModule:SETFIELD now works properly with the new type of slider widget that robotic parts use in KSP 1.7.x. KSP introduced a new type of slider widget that presents false information when kOS tried to obey its min, max, and detent values, those being only dummy placeholders for these types of sliders, not actually populated with the real values. For these sliders, the real limit values come from another field, requiring a more indirect method call to get the information. pull request.
• GUI windows no longer use the KSP control lock system to emulate keyboard focus, instead relying on the built-in Unity IMGUI focus rules for widgets, thus they won't 'steal focus' as much. pull request.

##### Share on other sites
Posted (edited)

Got a new cooked steering behavior I can't figure out. I'm feeding the rocket a pitch formula that should have the blue line follow the red curve (and the blue line should flatten out at the bottom of it to hold 48°) but for some reason the rocket decides to keep pitching downwards:

Pitch angle is vertical axis, time in seconds is horizontal. Yea, it still does that "pitch bump" in the early ascent but I'm not looking into that problem right now. Also the separation in the beginning isn't an issue so ignore that. The problem I'm trying to figure out is where the Actual line deviates from the Planned line later in the ascent after 60s. If you look at that point in the launch video, you'll see that the control surface deflection reaches maximum at this time. Okay that's cool because taking a closer look at this time it does need to pitch down to reach the proper angle:

But then for some reason it holds the deflection and doesn't let up to maintain the proper pitch rate that has been coded. To make sure this was behaving properly, I outputted the calculated value straight from the program while it was running and got values that matched the red curve.

Furthermore, there was a bug in my ascent program. It was supposed to hold pitch at 48° - however I failed to take a close look at the values for my pitch formula and it turns out the minimum pitch value that would be reached was 48.3° before it began to climb again, which means the pitch variable never got locked to 48° and the value being fed into the locked steering would begin to increase, and still the pitch controls remained pinned at max deflection for downwards rotation.

So from everything I can determine the cooked steering is being properly fed the values that make up the red line, but for some reason it just maxes out pitch deflection and keeps heading downwards the entire time at a rate faster than needed. Any one with any ideas as to why? I've run the ascent several times, all with the exact same results. I've flown this rocket 6 other times with various pitch profiles and I've never seen it deviate like this before. The only major difference between this and previous flights is I had the throttle locked to a 1.65 TWR but it's apparent that control authority due to moving slower wasn't an issue since it pitched over faster than intended rather than slower.

Edit: Okay I ran the ascent and took off the TWR hold and left the throttle at full. This is what I got:

Falloff at the end is due to engine cutoff.

So seems like the PID is getting stuck somehow when the control deflection maxes out? During the ascent at full thrust the control deflection never maxed out

Edited by Drew Kerman

##### Share on other sites

@Drew KermanThere just isn't enough background information to figure out what on earth you're talking about, sorry.  I feel like I'm stepping into the tail end of a conversation.  There's nothing in that post about what you mean by "planned" - is that a steering command by a script that you are changing over time in the fashion the curve describes?  What is commanding the change?  I just don't understand what you're saying.

##### Share on other sites
3 hours ago, Steven Mading said:

There﻿﻿﻿'s nothing in that post about what you mean by ﻿"planned﻿﻿﻿﻿﻿"

It's the link I included in the post to this formula which outputs the values that create the red line on the graph, which is the line that the rocket should be following. The rocket does not follow it when the thrust is low and the control surface deflection hits max (see the video). When I leave the throttle wide open and the steering never gets pinned thx to greater airflow, the rocket follows the pitch profile (red line) properly (last image)

So it seems to me the PID is getting over saturated or something when the control reaches max deflection and it no longer makes any adjustments for some reason

##### Share on other sites
Posted (edited)
8 hours ago, Drew Kerman said:

It's the link I included in the post to this formula which outputs the values that create the red line on the graph, which is the line that the rocket should be following. The rocket does not follow it when the thrust is low and the control surface deflection hits max (see the video). When I leave the throttle wide open and the steering never gets pinned thx to greater airflow, the rocket follows the pitch profile (red line) properly (last image)

So it seems to me the PID is getting over saturated or something when the control reaches max deflection and it no longer makes any adjustments for some reason

Your launch script is complex and while I like diagnosing problems in kOS, I'm not a fan of having to first study someone else's very complex script and teach myself how it works before I can then begin to start diagnosing the kOS problem.  That's a huge time sink without a guarantee that it will even turn out to be a kOS problem in the end.

For example, I tried to find where in your code on github you might be possibly logging the data that goes into that red line in your graph, and all I can find is this maybe?

```set getter("addlLogData")["Pitch Target"] to {
return 1.14452E-8 * ship:altitude ^ 2 - 0.00181906 * ship:altitude + 88.6057.
}. ```

But that doesn't match the actual formula in your lock pitch, which is this:

``` lock pitch to 2.95304E-8 * ship:altitude^2 - 0.00218678 * ship:altitude + 88.8414.

```

So I'm back to having no clue what your graph is really showing me.  I don't see where you're dumping those values from.  Finding the kOS problem means first proving where it's doing something wrong.  If this is a kOS steering bug along the lines of "I told it to do X but it's doing Y instead", then logging what that X actually is you're passing into it, and the resulting Y it's doing instead, at as close a place as possible to where you directly feed it into the steering manager, is how you show it. I can't tell what you're logging in this script because I don't see anywhere that the `pitch` from `lock steering to heading(hdgHold,pitch) is getting logged in that script.  Maybe you are, but I am having a heck of a hard time finding it, and I need to budget my time here.

##### Share on other sites
Posted (edited)

Woah hold up I'm sorry but I didn't realize you would want to try and work out my launch script, because to me that's a moot point I already took care of for you. I gave all the information needed to show that it wasn't my script but the kOS PID controller was behaving improperly - when the rocket is traveling slow and maxes out the pitch control it seems unable to readjust, whereas when it is moving fast and doesn't need to use the full range of pitch the rocket properly follows the red line, which is the programmed pitch profile. So I've demonstrated my launch script does work as intended under the proper conditions. All I did to get the rocket to properly follow the pitch profile I wanted was to change this line and simply lock the throttle to 1. So this, to me, seems to be the real problem:

The PID has the ability to output debug information, so maybe I should go back and do that later today

Also I shouldn't really say that the PID is making a mistake. I may be pushing it outside what it's capable of, but if so that's just something I'm looking for help in understanding

Edited by Drew Kerman

##### Share on other sites
Posted (edited)
53 minutes ago, Drew Kerman said:

Woah hold up I'm sorry but I didn't realize you would want to try and work out my launch script, because to me that's a moot point

It's not moot if the descriptive text doesn't prove what's going on.  The graph is not proof on its own that the PID is wrong.  But the graph, *In combination with* with the knowledge of where it's actually pulling those numbers from could be, if I could tell where it was pulling those numbers from.  That's why trying to find out where it actually dumps those numbers out was relevant.

The most helpful thing to do if you suspect you know something is wrong is to create a simpler example that JUST shows that one thing, with as much removed as possible.  As it stands, this is too complex an example for me to spend any time trying to diagnose it.  It doesn't trim things down to just the one relevant thing.

##### Share on other sites
Posted (edited)
31 minutes ago, Steven Mading said:

It is *not* a moot point.  I need to see *exactly* what you are using to draw those graphs to understand what they supposedly are showing.  And that means I needed to see where in your script you are outputting the values that you end up putting into that graph.  I needed to see which kOS variables the red line and the blue line actually are. ﻿

All right. I understand you want to make sure the data I present to you is not itself a possible issue.

You are correct here for the red line:

13 hours ago, Steven Mading said:

For example, I tried to find where in your code on github you might be possibly logging the data that goes into that red line in your graph, and all I can find is this maybe? ﻿

```
return 1.14452E-8 * ship:altitude ^ 2 - 0.00181906 * ship:altitude + 88.6057.
}. ```

But that doesn't match the actual formula in your lock pitch﻿, which is this:

It doesn't match the formula in my lock pitch because you must have found this in another operations file, not in the initialize.ks used in conjunction with the ascent.ks for that flight. Rest assured that on my local file, which I modified to add the above code, the formula is indeed the same as the one used in ascent.ks for Flight 7. So the red line is the pitch values that are being fed to the cooked steering. To make double sure, in the image of my code environment below the highlighted line is me also outputting the actual value of pitch that is locked into the cooked steering. It and the formula output both match.

the blue line is the actual pitch value the rocket is following. I get that value from this code which outputs various telemetry data.

Above graph is rocket (blue line) ascending using a locked TWR of 1.65 and not following the pitch profile (red line) after the controls for pitch are saturated

Above graph is the rocket (blue line) ascending under full thrust and properly following the pitch profile (red line) until it exits the atmosphere and loses control authority entirely (where blue line deviates at end - not an issue)

I've also reflown the ascent both ways once again with exact same results but this time with PID debugging enabled - log files. Don't know what I'm looking for here but I am working through them to see if I can spot anything amiss between the two

Edited by Drew Kerman

##### Share on other sites
1 minute ago, Drew Kerman said:

Above graph is the rocket (blue line) ascending under full thrust and properly following the pitch profile (red line) until it exits the atmosphere and loses control authority entirely (where blue line deviates at end)

That sentence reveals more than you might realize.  It implies your *entire* control authority is coming from areodynamics with control surfaces, none from RCS or reaction wheels or engine gimbal.  That might have a lot more to do with this than it seems.  It's much harder for kOS to get accurate torque info about the areodynamics of fins than other sources of torque - especially if FAR is in use which changes everything about that information.  This may have a lot more to do with that than with anything else.

##### Share on other sites

That sentence reveals more than you might realize.  It implies your *entire* control authority is coming from areodynamics with control surfaces, none from RCS or reaction wheels or engine gimbal.  That might have a lot more to do with this than it seems.  It's much harder for kOS to get accurate torque info about the areodynamics of fins than other sources of torque - especially if FAR is in use which changes everything about that information.  This may have a lot more to do with that than with anything else.

No I realize that - my whole initial post was an attempt to prove outright that this was the problem and seek more details about what I can do to solve or work around it. I'm trying to say that the total saturation of the control surface seems to be a point where we can start discussing what is going wrong

##### Share on other sites
Posted (edited)
29 minutes ago, Drew Kerman said:

No I realize that - my whole initial post was an attempt to prove outright that this was the problem and seek more details about what I can do to solve or work around it. I'm trying to say that the total saturation of the control surface seems to be a point where we can start discussing what is going wrong

It's possible it has nothing to do with the control surface and is just PID integral windup.  There is meant to be a protection against that (so it doesn't "think" it's successfully deflecting at 400% just because that's what it told the control to do, and instead records the fact that it only successfully deflected at 100%.)  But that protection might not be working perhaps.

##### Share on other sites
Posted (edited)
5 minutes ago, Steven Mading said:

PID integral ﻿windup﻿

yes, that is I suppose the proper term I was trying to get across with "over saturation" - it hits max, holds max but then when it comes time to move the other direction it fails to come off that max setting. Like, the amount that it needs to deflect the other way isn't enough to bring it down since it traveled so far past max and thus doesn't move the control surface in the opposite direction. Hopefully the PID debug data I have provided can help determine if the protection is not working. Let me know if you need any additional data.

Also, I think there is a way I can test this during ascent... let me try to read the pitch output and when it reaches max I'm going to "bump" it back down manually and see how the controller reacts. I'll have that sometime in the next hour or so

Edited by Drew Kerman

##### Share on other sites
Just now, Drew Kerman said:

yes, that is I suppose the proper term I was trying to get across with "over saturation" - it hits max, holds max but then when it comes time to move the other direction it fails to come off that max setting. Hopefully the PID debug data I have provided can help determine if the protection is not working. Let me know if you need any additional data.

Also, I think there is a way I can test this during ascent... let me try to read the pitch output and when it reaches max I'm going to "bump" it back down manually and see how the controller reacts. I'll have that sometime in the next hour or so

I'm not the one who wrote the PID steering - that dev isn't active anymore.  So I don't know how to read that log, but I can look into it and try to decipher it from the source code.

##### Share on other sites
1 minute ago, Steven Mading said:

I'm not the one who wrote the PID steering - that dev isn't active anymore.  So I don't know how to read that log, but I can look into it and try to decipher it from the source code﻿﻿﻿. ﻿

sounds good - I'm also interested in opinions from @kcs123 and @FloppyRocket since they chimed in with some wisdom last I posted about PID issues

I'll be back later with some more ascent testing

## 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.