Jump to content

kOS Scriptable Autopilot System 0.9


KevinLaity

Recommended Posts

This does:

// For prograde. The system insists on only

// understanding steering by R()'s and not by V()'s.

// So you turn a V() into an R() by just multiplying

// it by the no-rotation rotation operator R(0,0,0)

// to force the system to cast it to an R().

set mySteer to R(0,0,0) * velocity:surface.

lock steering to mySteer.

//for retrograde, multiply vector by -1 :

set vs to velocity:surface.

set vsx to 0 - vs:x.

set vsy to 0 - vs:y.

vst vsz to 0 - vs:z.

set mySteer to R(0,0,0) * V(vsx, vsy, vsz).

lock steering to mySteer.

Using R(0,0,0) * V(x,y,z) allows me to live entirely in the sensible world of vectors and 3D space and not use Euler rotations. The only hard part is finding the zero point of the "universe" when I don't have access to the positional numbers, only the velocity. I've been asking mod makers in the development forum how the game's coordinate system is laid out and it's messy. I've got it worked out that the zero point of the universe is the center of your SOI planetary body, and that the universe's coordinates rotate with your SOI body, but only if you're lower than N (N changes depending on body), but when you're higher up than that, then the frame of reference changes such that the universe stays put and the planet starts rotating. All of that I can get, but then it turns out that for whatever strange reason SQUAD decided to make the axes of the system NOT extend through the prime meridian but at some oddball canted angle at about 100 degrees longitude or so... no idea why or how to query for "where is the x axis on this planet?".

Excellent, that is why I have been using V() as it is. I noticed that you can use R(180,0,0) + velocity:surface to get the correct heading but I haven't been able to get pitch out of it. It seems now you cant use pure V() unless you have something that is rotation based first.

I also wont let me add more than one vector and velocity surface is expressed as a vector.

I think those are current issues that Kevin was talking about in his blog. However, if you are getting prograde by multiplying the vector to an empty R() set, do you think it is possible one could get retrograde by multiplying by R(180,0,0)?

Edited by Payload
Link to comment
Share on other sites

I did this during the days the forum was down (and posted it right before the hack, so it got reverted. Here it is again:)

This should be handy to anyone who's been trying to work out various landing autopilots.

The vectors for velocity:orbit and velocity:surface are given in terms of the XYZ grid system that KSP uses natively behind the scenes.

The problem:

But users of KOSscript can't do much with that information other than use it precisely as-is, because we can't "see" that XYZ system. We can't get the positions of things in those coordinates. We don't know where our own ship's position is in that system. If we want to LOCK STEERING TO *exactly* surface prograde or retrograde its fine, but if we want to do something like "LOCK STEERING TO SOMETHING A LITTLE BIT WESTWARD OF RETROGRADE" there isn't a way to do that because we don't actually know which way is east, west, north, or south in the XYZ system. And we can't derive it either (or so I thought) because we can't see our own position. (For example, lets say you know you are going in V(50,0,50). You know that's going at a 45 degree angle from the grid lines, in the positive direction of the X axis and Z axis, but is that toward the planet? Away from it? Tangental to it? Dunno without the position information. If we assume the coordinate grid has an origin at the planet's center (it does but I only know that from asking other modders -KOS doesn't tell you that), then if my position was at X=100000 and Z=100000 then I'd know that a velocity of V(50,0,50) is straight up. But if my position is X= -100000 and Z = 100000 then the same velocity is due west.)

The solution

But from experimentation I worked out that there is ONE way to figure it out. By reading what the angle of Up:yaw is, you can find out exactly how far around the planetary circle in the XZ plane you are from its zero point (its X axis intercept). Once you've got that you can work out the rest of it.

So I made a small program file that if you pass in the XYZ coordinates of a vector, it will calculate for you the same vector in terms of a surface-relative frame of reference grid, using the three axes of East, North, and Up.

(negative east is west, negative north is south, and negative up is down, obviously).

Beware that this information is only correct at the instant it's derived. The further the craft moves from where it was at the moment you called the program, the more incorrect the data becomes, because East.North,Up is a polar coordinate system but your movement is linear.

The page has a lot of explanatory text but you can skip past it and just go to the bottom if you just want to snag the code:

The page is here: http://kos.wikia.com/wiki/Tutorial_-_KOS_0.65_and_above:_Finding_surface_dynamic_information

This program uses the new parameter passing of 0.65. You will need version 0.65 before it will run.

Edited by Steven Mading
Link to comment
Share on other sites

I guess my reply didn't make it through the "troubles"...

Soo how about that 0.65 update? I rewrote the launch program so now I can include the number of boosters (for asparagus staging) and desired orbital altitude. Not exactly the same as asking for the input when the program runs, but it works rather well. :)

On a different note, before the 0.65 update I could use filenames like "orbit2.9". Now with .65 that gives a syntax error so I had to change the file names to be like "orbit2-9" Not a big deal though, easy enough to do. :)

Link to comment
Share on other sites

I guess my reply didn't make it through the "troubles"...

Soo how about that 0.65 update? I rewrote the launch program so now I can include the number of boosters (for asparagus staging) and desired orbital altitude. Not exactly the same as asking for the input when the program runs, but it works rather well. :)

I had three different landing scripts called "lander", "hover", and "skycrane" that I've now merged together into one that just takes a parameter. Now I just call:

run descend("skycrane",0.2).

For example. Since they all do the same thing up until the last moment. (The 0.2 is a slope parameter. The lander will attempt to wait until it sees that the terrain beneath it has a sope of 0.2 or less before descending all the way to drop the payload. It avoids dropping the payload on a hill slope.)

On a different note, before the 0.65 update I could use filenames like "orbit2.9". Now with .65 that gives a syntax error so I had to change the file names to be like "orbit2-9" Not a big deal though, easy enough to do. :)

Oh so dashes are allowed now? Good. I've been trying to find a good word-separator in program names. I tried camel-casing it but that seems to cause trouble if I use mixed case in the program names.

Link to comment
Share on other sites

The 0.2 is a slope parameter. The lander will attempt to wait until it sees that the terrain beneath it has a sope of 0.2 or less before descending all the way to drop the payload. It avoids dropping the payload on a hill slope.)

Ooo! How does it do that? Can I see the code?

Link to comment
Share on other sites

Ooo! How does it do that? Can I see the code?

It performs the following logic.

You can calculate the height above sea level of the terrain directly under the lander (assuming you're close enough to the ground for alt:radar to work right) like so:

Terrain height = altitude - alt:radar.

If you remember the previous terrain height from the last time through the main loop, and compare it to the current terrain height, you have delta height. If you record the previous timestamp so you also know how long it took between iterations, you can get the horizontal distance traveled between those two samples as deltaTime * surfacespeed.

So the slope is deltaHeight / deltaHorizontalDist: Or in other words:

cur slope = (current terrain height - prev terrain height) / ( (curTime - prevTime)*surfacespeed )

So as long as abs(cur slope) is too big, I don't entirely allow it to kill horizontal speed. I allow it to continue moving at 10 m/s sideways until it finds terrain with shallower slope and then I begin the last few meters of descent.

I intend to post the code for it but not until I work out a few more bugs and land with it a few more times. I'm certain in its current state its still a bit wrong.

Link to comment
Share on other sites

I had three different landing scripts called "lander", "hover", and "skycrane" that I've now merged together into one that just takes a parameter. Now I just call:

run descend("skycrane",0.2).

For example. Since they all do the same thing up until the last moment. (The 0.2 is a slope parameter. The lander will attempt to wait until it sees that the terrain beneath it has a sope of 0.2 or less before descending all the way to drop the payload. It avoids dropping the payload on a hill slope.)

Oh so dashes are allowed now? Good. I've been trying to find a good word-separator in program names. I tried camel-casing it but that seems to cause trouble if I use mixed case in the program names.

It let me load/run it with a dash, think it did in 0.6 as well. Before that I was using underscore, because....well I'm use to not using "full stop" unless its to separate file name from extension. How ever I wanted to have different files as I made changes...you know just in case i totally mess something up lol. I finally decided to see how it handles using full stop in the name and it was fine, until now of course.

Nice work on detecting the slope, it's one I sort of understand actually...almost anyway. :) For now I think I'm going to stick to perfecting my ascent and circulation and a "kerbosync" program as well as one that can do automatic release of multi (at least 3) comm sats in kerbosync orbit. I'm likely going to set the AP of my delivery craft to the kerbosync altitude, and adjust my PE to get the 1/3 phase orbit. Currently I'm not too worried about if its directly over KSC, so long as its close enough to make a connection.

Oh, and now with the processing speed increased, my program is much more accurate, though needs some adjustments still I think. Changing the throttle to try and maintain 200m/s works a lot better now too. Can't wait to see what the next version will bring! :)

Link to comment
Share on other sites

Few inquiries..

this is the last segment of my code.


wait until apoapsis > 71500.
lock throttle to 0.
lock steering to prograde.
print "MECO."

Can someone tell me why the program is ending after MECO? The steering will not lock to prograde and the rocket tumbles wildly if I don't quickly set ASAS.

Which brings me to my next question. Is it possible to simply lock a crafts steering to a maneuver node? Nothing more.. After meco ill make the node then run it as a separate program.

And finally the one that troubles me most. The shaking. Now this particular craft is rigid all the way up supported by an SRB so it shakes/oscillates from side to side instead of a wobble. I can see the gimbals working way to hard... almost as if kOS's "built in asas" is pre .21. And the interesting thing is if I manually enable asas the shaking goes away and the rocket becomes as steady as can be. But kOS apparently cannot operate with it enabled.

Link to comment
Share on other sites

It let me load/run it with a dash, think it did in 0.6 as well. Before that I was using underscore, because....well I'm use to not using "full stop" unless its to separate file name from extension. How ever I wanted to have different files as I made changes...you know just in case i totally mess something up lol. I finally decided to see how it handles using full stop in the name and it was fine, until now of course.

Nice work on detecting the slope, it's one I sort of understand actually...almost anyway. :) For now I think I'm going to stick to perfecting my ascent and circulation and a "kerbosync" program as well as one that can do automatic release of multi (at least 3) comm sats in kerbosync orbit. I'm likely going to set the AP of my delivery craft to the kerbosync altitude, and adjust my PE to get the 1/3 phase orbit. Currently I'm not too worried about if its directly over KSC, so long as its close enough to make a connection.

Oh, and now with the processing speed increased, my program is much more accurate, though needs some adjustments still I think. Changing the throttle to try and maintain 200m/s works a lot better now too. Can't wait to see what the next version will bring! :)

My next project I've set for myself is to make a little library routine to detect the current lat/long where on the surface the trajectory is predicting to hit the ground. It can't be as accurate as the blue line in the game because the blue line is done knowing the terrain of the planet surface, and I don't have that information so I'll just make an approximate guess that the height is probably about half the max height of the planet terrain (from the KSP wiki). But the idea is that this is a requirement if I want to try to make something land near a chosen target. I first have to be able to at least predict where freefall is taking it now

It all hinges on pulling out my old rusty math skills and finding the intercept point between an ellipse (your orbit) and a sphere (the planet surface) *, and working out how to get the parameters of those equations given what information is in KOS. The altitude of apoapsis and periapsis plus the planet's diameter give me the length of the major axis of the ellipse, and I know that Kepler's laws of motion say that one of the foci of the ellipse has to be the planet center (the focus closer to the periopsis side will be), which conveniently is the origin in the XYZ grid, and the difference between apiopsis and periopsis should be able to tell me how far apart the foci of the ellipse are, and the current altitude (from core so + body radius) and current Up direction should get me the datapoint that I am currently on in the ellipse, so it seems to me the data to do it should all be there.. I just have to do some scratch-paper work to get it to come out.

Edited by Steven Mading
Link to comment
Share on other sites

It performs the following logic.

You can calculate the height above sea level of the terrain directly under the lander (assuming you're close enough to the ground for alt:radar to work right) like so:

Terrain height = altitude - alt:radar.

If you remember the previous terrain height from the last time through the main loop, and compare it to the current terrain height, you have delta height. If you record the previous timestamp so you also know how long it took between iterations, you can get the horizontal distance traveled between those two samples as deltaTime * surfacespeed.

So the slope is deltaHeight / deltaHorizontalDist: Or in other words:

cur slope = (current terrain height - prev terrain height) / ( (curTime - prevTime)*surfacespeed )

So as long as abs(cur slope) is too big, I don't entirely allow it to kill horizontal speed. I allow it to continue moving at 10 m/s sideways until it finds terrain with shallower slope and then I begin the last few meters of descent.

I intend to post the code for it but not until I work out a few more bugs and land with it a few more times. I'm certain in its current state its still a bit wrong.

Oh okay. I knew you could get a slope doing that, but it only gives you the slope in the direction of your horizontal velocity. I thought maybe you had figured out some otherway to get your absolute slope. Good job nonetheless.

But the idea is that this is a requirement if I want to try to make something land near a chosen target. I first have to be able to at least predict where freefall is taking it now

That's exactly what I'm working on now. Land anywhere so long as your target latitude is within your orbital inclination. But the damn inverse trig is broken, so I've hit a roadblock for now.

Edited by check
Link to comment
Share on other sites

Few inquiries..

this is the last segment of my code.


wait until apoapsis > 71500.
lock throttle to 0.
lock steering to prograde.
print "MECO."

Can someone tell me why the program is ending after MECO? The steering will not lock to prograde and the rocket tumbles wildly if I don't quickly set ASAS.

Which brings me to my next question. Is it possible to simply lock a crafts steering to a maneuver node? Nothing more.. After meco ill make the node then run it as a separate program.

And finally the one that troubles me most. The shaking. Now this particular craft is rigid all the way up supported by an SRB so it shakes/oscillates from side to side instead of a wobble. I can see the gimbals working way to hard... almost as if kOS's "built in asas" is pre .21. And the interesting thing is if I manually enable asas the shaking goes away and the rocket becomes as steady as can be. But kOS apparently cannot operate with it enabled.

Well, first off in your code, you're missing the full stop at the end, after the quote, but aside from that my program has been clearing the screen and printing "program ended". I can see what I wanted it to say for a second, but then quickly clears the screen like I said. Didn't notice if it does that with 0.65 but I think it still does.

As for the shaking, I'm pretty sure you can disable gimbal on the boosters. If you're craft is small enough/light enough SAS may be enough to keep it stable. Also if you don't have fins on it you could try that, maybe even static fins with no control surfaces, that way they sort of act like a keel on a boat or skegs i think they're called on surf boards.

Link to comment
Share on other sites

Few inquiries..

this is the last segment of my code.


wait until apoapsis > 71500.
lock throttle to 0.
lock steering to prograde.
print "MECO."

Can someone tell me why the program is ending after MECO?

Well.. you *did* describe that as being the last segment of your code. Is there anything that comes after it that you were expecting to execute that you didn't show us? Otherwise ending after the last statement seems perfectly normal to me.

The steering will not lock to prograde and the rocket tumbles wildly if I don't quickly set ASAS.

The program "lets go" of the steering after it ends and you return to interactive mode. This is deliberate so you can have manual control back after the program is done. If the MECO line is the last line and it is ending there, then what happened is that it tried to steer toward prograde for just a moment and then stopped trying when the program ended.

Which brings me to my next question. Is it possible to simply lock a crafts steering to a maneuver node? Nothing more.. After meco ill make the node then run it as a separate program.

Supposedly you can:

LOCK STEERING TO NODE.

But I haven't tried it to see if it works. And again, if your program ends it will stop trying to control the steering.

And finally the one that troubles me most. The shaking. Now this particular craft is rigid all the way up supported by an SRB so it shakes/oscillates from side to side instead of a wobble. I can see the gimbals working way to hard... almost as if kOS's "built in asas" is pre .21. And the interesting thing is if I manually enable asas the shaking goes away and the rocket becomes as steady as can be. But kOS apparently cannot operate with it enabled.

That's going to require information on the craft to diagnose.

Link to comment
Share on other sites

The program "lets go" of the steering after it ends and you return to interactive mode. This is deliberate so you can have manual control back after the program is done. If the MECO line is the last line and it is ending there, then what happened is that it tried to steer toward prograde for just a moment and then stopped trying when the program ended.

In one of the versions(dont remember which), at least for me, it seemed that if steering or location was locked and the program ended it would still be locked. At the end of my program I have it lock steering to prograde, fire off action group 1 (solar panels, dish/antenna etc) and wait a few seconds, then unlock all, just to be sure. Maybe the steering/throttle being locked after the program ended was a bug or something, and just in that one version.

Link to comment
Share on other sites

Oh okay. I knew you could get a slope doing that, but it only gives you the slope in the direction of your horizontal velocity. I thought maybe you had figured out some otherway to get your absolute slope. Good job nonetheless.

Yeah that is definitely a big problem. The craft can only "see" the height where it is at the moment so to get a proper slope would require hovering and "surveying" the terrain in several directions, which gets really messy and a good skycrane shouldn't have that much fuel to be puttering around like that. I tried having it veer a bit left and right and take samples that way to guess whether it can seek better ground to the left or to the right, but that was getting very messy and wasn't working well so I took it back out. I figure a better solution is working on the "land at position lat,long" algorithm and say that the people designing the probe's mission surveyed a good landing spot for the craft ahead of time.

That's exactly what I'm working on now. Land anywhere so long as your target latitude is within your orbital inclination. But the damn inverse trig is broken, so I've hit a roadblock for now.

I'm going to work out the math for how to do it in polar coordinates because I suspect it will make some of the messy terms go away and also perhaps remove some of the trig until the end when converting back out to XYZ.

Link to comment
Share on other sites

In one of the versions(dont remember which), at least for me, it seemed that if steering or location was locked and the program ended it would still be locked. At the end of my program I have it lock steering to prograde, fire off action group 1 (solar panels, dish/antenna etc) and wait a few seconds, then unlock all, just to be sure. Maybe the steering/throttle being locked after the program ended was a bug or something, and just in that one version.

Maybe it's different when the program crashes with error than when it ends nicely. As you noted there was a missing period at the end. I could see it making sense to say that when there's an error that aborts the program things need to return to manual control right away just in case there's an emergency coming up and the user didn't expect the program to kick out at this point.

Link to comment
Share on other sites

Ty Sma and Steven. No there is no more after MECO. How is it I can get the program to continue running? Id just get rid of the MECO line, but something tells me that won't do it. Because I have tried a seperate, small script.


clearscreen.
Lock steering to node.

And it did the same thing. It blurps the controls for a second then the program ends.

As for the shaking. The craft is great I don't think that's the issue. When under manual control there is no oscillations. But with kOS at the wheel its all over the place. Not crippling, but unsettling.

Link to comment
Share on other sites

Ty Sma and Steven. No there is no more after MECO. How is it I can get the program to continue running? Id just get rid of the MECO line, but something tells me that won't do it. Because I have tried a seperate, small script.

You could put a do-nothing loop at the end to keep the program running:

 until 0 { wait 1. }.

To wait 1 second, then wait 1 second again, then wait 1 second again.. etc. When you want control back you'll have to bring up the terminal window and "CONTROL-C" inside it. Obviously if you have something more sophisticated to check for to trigger the end use that instead.

You can't make a null loop body in KOSscript syntax so *something* has to go in there. It may as well be a wait statement. Besides, I can't shake the old UNIX programmer habit of considering all busy-loops with no blocking statements in them to be Very Bad Practice, even though in KOSscript you're not multitasking the SCS CPU with anything else so it doesn't matter. I just can't bring myself to do it , thus the wait statement in there.

As for the shaking. The craft is great I don't think that's the issue. When under manual control there is no oscillations. But with kOS at the wheel its all over the place. Not crippling, but unsettling.

I haven't experienced this. Sorry I don't know what's happening.

Link to comment
Share on other sites

"Lock wheelsteering"?

That's the thing I described as having no effect at all.

I described two different things I'd tried, although I admit I didn't say it very clearly.

Let me try describing it again:

Thing 1 I tried: lock wheelsteering.

What happened: Nothing at all. Drove in straight line on existing heading, ignoring the setting.

Thing 2 I tried: lock steering.

What happened: Turned to heading but then kept on turning. Was not just a case of oversteering because it didn't turn back again. It just kept going in a circle.

Link to comment
Share on other sites

Yeah that is definitely a big problem. The craft can only "see" the height where it is at the moment so to get a proper slope would require hovering and "surveying" the terrain in several directions, which gets really messy and a good skycrane shouldn't have that much fuel to be puttering around like that. I tried having it veer a bit left and right and take samples that way to guess whether it can seek better ground to the left or to the right, but that was getting very messy and wasn't working well so I took it back out. I figure a better solution is working on the "land at position lat,long" algorithm and say that the people designing the probe's mission surveyed a good landing spot for the craft ahead of time.

I'm going to work out the math for how to do it in polar coordinates because I suspect it will make some of the messy terms go away and also perhaps remove some of the trig until the end when converting back out to XYZ.

Take the data that you have gathered from your ISAMAP Sat survey. The whole idea of the pre-survey mapping is to have the body or at a minimum your landing site properly mapped. Then as you are making your approach, you can use the raw map data as a lookup.

Well, that's what i am doing.... I use the data from the mapsat surveys to check and plan for landing site survey, slope verification, and terrain avoidance (on Minmus it is required when coming in low and hot..) Found too many mountains that were just a little bit higher than i thought....

Cheers.

Link to comment
Share on other sites

You can't make a null loop body in KOSscript syntax so *something* has to go in there. It may as well be a wait statement. Besides, I can't shake the old UNIX programmer habit of considering all busy-loops with no blocking statements in them to be Very Bad Practice, even though in KOSscript you're not multitasking the SCS CPU with anything else so it doesn't matter.

Would you considder it a practical approach to use the state of an empty actiongroup as a blocking statement? Just wait for it to be fired and then exit that loop.

Link to comment
Share on other sites

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