Jump to content

[1.3] kOS Scriptable Autopilot System v1.1.3.0


erendrake

Recommended Posts

Have you had calculus?

You lost me at "calculus". Truth be told I did learn it but it was so long ago, all I remember about it was that it has something to do with functions, and integration and derivation are opposite or something.

Is anyone aware of any really good and interesting online resources that will hold my hand through learning this? Because I really want to write PID controllers for landing and hovering.

Edited by Cpt. Kipard
Link to comment
Share on other sites

You can calculate barometric pressure without needing to lug around a sensor:


set pbaro to 0.

if body:atm:scale > 0 {

set f to -1 * altitude / body:atm:scale.

set pbaro to body:atm:sealevelpressure * ( e ^ f).
}.

Should work for every celestial body with an atmosphere :)

Cheers

Hans

Link to comment
Share on other sites

You can calculate barometric pressure without needing to lug around a sensor:

I'm already aware of this. My script used that formula before the capacity to read sensors had been added to kOS.

The problem isn't the sensor or lack thereof. It's that something in the other math in my script is breaking KSP when atmosphere density is zero, which is a perfectly legitimate condition to operate under some of the time, like when taking off from the moon, so I need to work out how to make the script work under those conditions (which it used to in the past).

When I replace the sensor reading in the expression with a hardcoded zero, the problem still persists. When I replace it with a hardcoded 1. It goes away. It's not the manner in which I'm reading the air density that's the problem. It's what the math does when it's a zero, which it could validly be under a lot of cases.

marianoapp thinks it's because of trying to set the throttle to infinity, but I'm not entirely convinced of that because in my testing I've just discovered that I can manually set the throttle to infinity without it triggering the bug:


set divByZero to 1/0.
print divByZero.
Infinity
lock throttle to divByZero.

When I do that, it doesn't cause KSP to black screen crash like it does when I run the full script, so I'm still trying to narrow it down to the exact cause.

Also weirdly, once the black screen happens, it's hard to diagnose the problem because the value of ALL the variables changes to NaNs, which I think is an an effect of, rather than cause of, the crash. Even variables I never touched at all during the loop have suddenly become NaN after that, and some other variables suddenly stop being printable at all because kOS claims they don't even exist. Whatever the black screen crash is doing, it makes it impossible to see what the values of the variables had been right at the moment prior to the crash.

Link to comment
Share on other sites

I'm using ship:termvelocity at the moment, that one also gives "Infinity" when outside the atmosphere.

This doesn't seem to cause any issues.

All my black screens happened while still climbing out of the atmosphere IIRC.

I'll try again tomorrow and log more data...

Cheers

Link to comment
Share on other sites

OK I gave it a short try because I had an idea.

The old code went something like:


lock throttle to t.

// main loop
set vt to ship:termvelocity.
set v to airspeed.
set t to (vt - v) * k.

if (t > 1) { set t to 1. }.
if (t < 0) { set t to 0. }.
// main loop

This doesn't work as excepted, since apparently each write to t causes a direct update of throttle.

That means I set throttle to infinity when leaving the atmosphere, followed by an immediate crash.

Using an intermediate variable fixes the crash:


set [COLOR="#00FF00"]tt[/COLOR] to t.
lock throttle to [COLOR="#00FF00"]tt[/COLOR].

// main loop
set vt to ship:termvelocity.
set v to airspeed.
set t to (vt - v) * k.

if (t > 1) { set t to 1. }.
if (t < 0) { set t to 0. }.
set [COLOR="#00FF00"]tt[/COLOR] to t.

// main loop

Curiously the crash only happened when I was using an LV-N...

Cheers

Link to comment
Share on other sites

OK I gave it a short try because I had an idea.

The old code went something like:


lock throttle to t.

// main loop
set vt to ship:termvelocity.
set v to airspeed.
set t to (vt - v) * k.

if (t > 1) { set t to 1. }.
if (t < 0) { set t to 0. }.
// main loop

This doesn't work as excepted, since apparently each write to t causes a direct update of throttle.

That means I set throttle to infinity when leaving the atmosphere, followed by an immediate crash.

Using an intermediate variable fixes the crash:


set [COLOR="#00FF00"]tt[/COLOR] to t.
lock throttle to [COLOR="#00FF00"]tt[/COLOR].

// main loop
set vt to ship:termvelocity.
set v to airspeed.
set t to (vt - v) * k.

if (t > 1) { set t to 1. }.
if (t < 0) { set t to 0. }.
set [COLOR="#00FF00"]tt[/COLOR] to t.

// main loop

Curiously the crash only happened when I was using an LV-N...

Cheers

Hmm. That is truly weird. I'm able to:

lock throttle to inf

where inf is a variable that has a value of infinity. And it does not bug out at all. It just behaves as if the throttle is 1.0.

Link to comment
Share on other sites

I found a simpler way to reproduce the error, just lock the steering to a rotation that has a NaN component and launch (for example "lock steering to R(sqrt(-1),0,0).")

Hmm.... that *could* be the cause. See, my script waits until the pressure is down below 0.25 ATM's before starting the gravity turn. Therefore when it thinks the air pressure is zero it's going to start that gravity turn right away on liftoff. So that could actually be the relevant difference - not the throttle but the steering commands that come from starting the gravity turn right away. I'll look into that.

Link to comment
Share on other sites

Okay I think I'm going to have to install a C# and .NET dev environment. Any good ideas that work without Visual Studio Express? I tried using it before but the 30 day expiration was annoying, and paying for a full dev suite when I really don't plan to use C# for anything else than this seems a bit silly. Even a low level command-line only solution is fine by me.

The problem is that something in the kOS code is changing my steering value. *I* am not doing it, and I can't trace down where it's happening. Partway through the liftoff, for no apparent reason, my steering becomes:

R(270,NaN,0)

When it hadn't been a moment beforehand and none of my own variables that go into calculating it had changed. I expect this is a symptom of, rather than cause of, the problem, because a bunch of my other variables suddenly all become NaN at exactly the same time.

Edited by Steven Mading
Link to comment
Share on other sites

You could go with Unity's Monodevelop or SharpDevelop as far as "free" C# IDEs are concerned.

I haven't checked how exactly to use postbuild commands with these, but i'm certain that it's possible similar to Visual Studio. If you like, i could check that out later and post some examples of basic "autoload" implementations for KSP (It's very helpful to instantly load the last quicksave on KSP launch, without having to navigate through the menu every time)

Link to comment
Share on other sites

Can somebody help me patch in a little bit of code into my script so that my rockets speed can be locked until a certain height? Something like this?

until 23000 {

if speed > x [set throttle to t - x}

if speed < x [set throttle to t + x}

}.

Or something like that, I dunno I'm terrible at this...

Edited by erkha343
Link to comment
Share on other sites

You could do something like this:


set g to 9.81.
set t to ship:maxthrust.
if t = 0
{
set t to 0.001.
}

set w to ship:mass.
if w = 0
{
set w to 0.001.
}

set twr to t / (w * g ).





set velocityDifferenceToTerminalVelocity to ship:termvelocity - ship:velocity:surface:mag.
set accelerationPerSecond to twr * g.
if velocityDifferenceToTerminalVelocity <= 0
{
set velocityDifferenceToTerminalVelocity to 0.
}
set thrustLevel to velocityDifferenceToTerminalVelocity / (accelerationPerSecond *0.25 ).

Not the best way to achieve it, but this keeps you roughly below terminal velocity. If you want a different velocity, you have to swap out ship:termvelocity for your desired velocity. And of course you have to lock the throttle to thrustLevel :)

Hope this helps

Edited by kaesekuchen
Link to comment
Share on other sites

As far as I can see, you'll need none of those two special cases:


if t = 0
{
set t to 0.001.
}
if w = 0
{
set w to 0.001.
}

Your mass never gets 0 (even the kOS unit has mass) and your maxthrust can get 0 without producing an error.

Also you can use this formula to get the current acceleration due to gravity:

(altitude+body:radius)^2/body:mu

(distance from gravity source divided by gravitational parameter of the body).

Protip: Use "Lock ... to ..." with things like thrust-acceleration, twr, etc. This saves a whole lot of processing time.

Link to comment
Share on other sites

Hi!

I was pointed here from reddit. I've a bipedal T-rex and wanted to ask if its possible to time action groups to switch at a specific time. The robot moves by pressing "1" and "2" at the right time. IT should be easy to see when and add a number to it.

I've read the commands, but still, looks impossible to me!

Link to comment
Share on other sites

It kind of depends on what you want exactly - parallel or sequential switching. Currently there is no possibility of controlling Infernal Robotics directly (yet), but if you use action groups, everything should work.

The basic code could look something like this:

ag1 on.
wait 2.
ag1 off.

Of course, it is well possible to code something a lot more complex, but that should get you going. If you can explain in some more detail what you need, we might be able to provide code that is a little more detailed.

That being said, I would strongly advise having a go yourself :) It is easier than it looks, you just have to do it.

If you want a loop, you could go with something like:

ag1 off.
until ag1 = True {
ag2 on.
wait 1.
ag2 off.
wait 1.
}.

By pressing action group one, the loop will be exited. There are other (probably a little neater) ways of doing it, but I will leave some for you to discover.

Edited by Camacha
Link to comment
Share on other sites

I'm convinced *something* broken is happening in the mod in regards to lock values, but I'm still having a hard time tracing it down. It seems to be hard to trace

Consider the following case from the ascend script I posted about before.

I took this part that prints out some info into the status box once each loop iteration:


print " " at (2,1).
print stageMsg at (2,1).
print " " at (19,1).
print modeMsg at (19,1).
print " " at (18,3).

I narrowed down the place where numbers were suddenly becoming NAN on their own to that part of the loop, and inserted the following debugging print statements into it, which do mess up the nice "print at" display, by scrolling everything down, but that's just temporary while I try to find the bug:


print " " at (2,1).
print "A) stageMsg = " + stageMsg + " mypitch = "+mypitch. // eraseme
print stageMsg at (2,1).
print "B) stageMsg = " + stageMsg + " mypitch = "+mypitch. // eraseme
print " " at (19,1).
print "C) modeMsg = " + modeMsg + " mypitch = "+mypitch. // eraseme
print modeMsg at (19,1).
print "D) modeMsg = " + modeMsg + " mypitch = "+mypitch. // eraseme
print " " at (18,3).

When I ran it, I usually get output like this, when it's working right:


A) stageMsg = Stage 2 mypitch = 63.2824214170012
stageMsg = Stage 2 mypitch = 63.2824214170012
C) modeMsg = Thrusting myptich = 62.2630527414027
D) modeMsg = Thrusting mypitch = 62.2630527414027

But at the moment when the black screen of death hits, it looks like this:


A) stageMsg = Stage 2 mypitch = 63.166334067263
stageMsg = Stage 2 mypitch = 63.166334067263
C) modeMsg = Thrusting mypitch = NaN
D) modeMsg = Thrusting mypitch = NaN

If you look at the code, there is absolutely nothing between B) and C) that should do that to the value of mypitch.

This is the value that mypitch is locked to:


lock mypitch to 90 - ( sqrt( (usevel:mag+(altitude/4)) / (endSpd+(endAlt/4)) ) * 90 ).

endAlt and endSpd are set up at the top of the program and never changed after that.

usevel is set to surface vel at first, and then switches to orbital vel partway through the launch, because of this way it was set up up at the top before the loop:


lock usevel to velocity:surface.
when altitude > endAlt/3 then {
lock usevel to velocity:orbit.
}.

The problem happens at an altitude of 6500 m or so, so it can't be switching usevel to orbital at that point (endAlt is 80000 so endAlt/3 is 26666.666)

I can't figure out anything that could possibly legitimately change mypitch to NaN in that code, and yet it does.

And once it does become NaN then everything breaks because steering is locked to HEADING( mycompass, mypitch ).

Is there some sort of timing issue with the way lock expressions are used to fly by wire that might make it possible to try to fly using an incompletely calculated expression? I'm really grasping at straws here because the behavior makes no sense. I'm at wit's end and almost considering trying to add debug info to a fork of the kOS github code that literally logs each and every low level opcode as it runs to figure out exactly what's happening when and where.

Edited by Steven Mading
Link to comment
Share on other sites

thank you guys, I'll give it a try. I guess I'll need to set all the joints to action groups, instead of IR setups, even if they are the same keys! :)

The main goal is that when i run the script, it activates the ag1 for a second or so, and then deactivates the ag1 and activates the ag2 for a second, then deactivates the ag2 and activates the ag1 for a second, and so on until I stop it!

Link to comment
Share on other sites

thank you guys, I'll give it a try. I guess I'll need to set all the joints to action groups, instead of IR setups, even if they are the same keys! :)

If I remember correctly, that is important :) I have tested with kOS and IR a while ago, though some details are a bit fuzzy.

The main goal is that when i run the script, it activates the ag1 for a second or so, and then deactivates the ag1 and activates the ag2 for a second, then deactivates the ag2 and activates the ag1 for a second, and so on until I stop it!

It pretty much is as simple as:


ag0 off.

until ag0 = True {
ag1 on.
wait 2.
ag1 off.
ag2 on.
wait 2
ag2 off.
}.

Note: I did not test this in KSP, some syntax might be slightly off.

Link to comment
Share on other sites

Hello! I want to do guided missiles and write in a avionicsNoseCone part.cfg module from Processor.

Problem: when missile is detached, programm stop actually work. May it be in association with re-written config or it`s a bug?

73787_screenshot1002.png

31550_screenshot1004.png

52813_screenshot1005.png

Link to comment
Share on other sites

Is there some sort of timing issue with the way lock expressions are used to fly by wire that might make it possible to try to fly using an incompletely calculated expression?

No, every lock es calculated completely every time is called.

I think the problem may arise from somewhere else because when the game crashes the altitude goes nuts, and the pitch lock may end up calculating the square root of a negative number (and returning a NaN). If that's the case then the pitch NaN is a consequence and not a cause of the problem.

You could try replacing the pitch parameter in all the headings with a fixed number and see if you still have the problem.

Link to comment
Share on other sites

No, every lock es calculated completely every time is called.

I think the problem may arise from somewhere else because when the game crashes the altitude goes nuts, and the pitch lock may end up calculating the square root of a negative number (and returning a NaN). If that's the case then the pitch NaN is a consequence and not a cause of the problem.

That's entirely possible and seems to make sense (that pitch NaN is a symptom, not a cause), because it seems that many of the script's 'Double' variables go haywire and become NaN at exactly the same time. Whatever causes the crash also causes much of the data in memory to corrupt, making it extremely difficult to trace the cause because once the problem happens, anything you try to print out can't be reliably trusted. Any weird numbers could be the result of the crash not the cause of it.

And this is true even down inside the C# code. I added a Debug.Log() call to FlyByWire to catch the first moment when it tries to pass any flight control parameter containing NaN, null, or infinity into KSP, and try to trace it down from there, and I'm still having trouble finding the cause.

Thus why I suspect that I may have to resort to verbosely logging each and every opcocde as it runs, and hope that the slowdown of doing that doesn't bog the system enough to cause other unrelated breakages that ruin the integrity of the test.

Link to comment
Share on other sites

Hi there, I'm new to this forum and I have a simple question.

The installation of this mod does not seem to work for me. I copied the contents of the zip file into the game folder, but the Compotronix part is nowhere to be found. My game is in sandbox mode, so it should be there under Control.

Can someone explain to me what I'm doing wrong? Thanks

Link to comment
Share on other sites

The comptronix part looks very similar to other parts. Go to the "control" tab and hover over all the parts there to make sure none of them are it.

If you're sure that it's not there, then check your installation as follows:

Is the part located here?

Kerbal Space Program -> GameData -> kOS -> Parts -> kOSMachine1m ->

You should see these files there:

model.mu

model000.mbm

modeloo1.mbm

part.cfg

If you don't see that in that location, then you probably exploded the ZIP file in the wrong place.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...