Jump to content

[1.3] kOS Scriptable Autopilot System v1.1.3.0


erendrake

Recommended Posts

<snip> Of course, now my ascent autopilot is over 3000 bytes. I suppose one way to shrink a program is to split it into separate programs to function as modules to do repetitive code.

Another way (unless this is what you're talking about) is to break the code up sequentially, and have two successive sequences loaded simultaneously, then just add a couple lines that erase the last unused section and then upload the next section all at the beginning of the section in use. To minimize (theoretical and/or actual) load times you could also isolate the routines that are used by most or all sequences and simply keep them loaded from the beginning (although that might increase the memory overhead a bit).

Link to comment
Share on other sites

I know, and i need the numbers of seconds "behind" the Apoapsis

Is "15" one example answer for the number you were querying for, rather than a given you know ahead of time? It didn't look like that way you phrased it. What you asked for was "I want to know how to get something like 15 seconds behind apoapsis", which sounded like you meant you already know you want "15 seconds behind apoapsis" and are querying for what that number would be, which is ETA:APOAPSIS+15.

So you have some point in mind and want to query to find out whether or not that point is 15 seconds after the apoapsis? I'm not following you.

Link to comment
Share on other sites

i like this mod, but the documentation seems out of date (even on the "newer" documentation). Do sensors work? I can't seem to get [print ship:sensors:acc:readout.] to do anything, and attempting to print without the readout just gives what I assume is the part's location/orientation.... also the sensor dump example doesn't work as shown (not to mention that it seems silly to use a list if you only need data from one sensor).

Link to comment
Share on other sites

Is "15" one example answer for the number you were querying for, rather than a given you know ahead of time? It didn't look like that way you phrased it. What you asked for was "I want to know how to get something like 15 seconds behind apoapsis", which sounded like you meant you already know you want "15 seconds behind apoapsis" and are querying for what that number would be, which is ETA:APOAPSIS+15.

So you have some point in mind and want to query to find out whether or not that point is 15 seconds after the apoapsis? I'm not following you.

It was already answered, but from what I understand, what he was looking for was a way to query how many seconds *behind* the vessel the apoapsis is at a given moment. IE: I want to go to apoapsis, wait an amount of time (so that I'm coming back down), and then do something... so I know how long after apoapsis I want to wait, but I need to know how long it's been since apoapsis to compare the two. (kinda like how when you pass maneuver nodes it switches from T-"some time" to T+"some time". He was looking for a T+"some time" for his apoapsis.)

Personally it seems like it would've been much simpler to just set a timer while at apoapsis and wait the specified amount of time (rather than constantly reading apoapsis eta and orbital periods, which seem like they might be computationally expensive) especially since (regardless of apoapsis eta and orbital period measurements) time is really what you're wanting to measure.

Link to comment
Share on other sites

i like this mod, but the documentation seems out of date (even on the "newer" documentation). Do sensors work? I can't seem to get [print ship:sensors:acc:readout.] to do anything, and attempting to print without the readout just gives what I assume is the part's location/orientation.... also the sensor dump example doesn't work as shown (not to mention that it seems silly to use a list if you only need data from one sensor).

It's not out of date. It's just that it was never tested. There's a LOT to document and running each and every example is very time consuming, and a lot of the time I was documenting code I hadn't written myself.

I just tested it and I see what's wrong with it.

In this case the error was the use of the word "sensor" as the variable name. "Sensor" is already a reserved word. In general, kOS doesn't have a good way to throw errors on using keywords as variable names right now. I think it should, but it doesn't.

So where the documentation says this:

FOR SENSOR IN SENSELIST {

PRINT "SENSOR " + SENSOR:TYPE + ": ACTIVE = " + SENSOR:ACTIVE + " VALUE = " + SENSOR:READOUT.

}.

Try replacing the word "SENSOR" with anything else, like "SEN", and then it works:

FOR SEN IN SENSELIST {

PRINT "SENSOR " + SEN:TYPE + ": ACTIVE = " + SEN:ACTIVE + " VALUE = " + SEN:READOUT.

}.

As far as having to get the list each time, you can just get the list once, find the sensor you want, and then just use that from then on, like so:


// Find the accelerometer sensor and keep a handle to it:
// ----------------------------------------------------
LIST SENSORS IN SENSELIST.
SET HAS_ACC_SENSOR TO FALSE.
FOR SEN IN SENSELIST {
IF SEN:TYPE = "ACC" {
SET ACC_SEN TO SEN.
SET HAS_ACC_SENSOR TO TRUE.
}.
}.
// FROM THEN ON, if HAS_ACC_SENSOR is TRUE, that means you can read the accelerometer with ACC_SEN:Readout.

BUT, There is an important caveat with this - you get the values as a TEXT readout, not as a number. So it's probably not that useful to your autopiloting needs.

On another note, SHIP:SENSORS is an entirely different thing. It's a totally different object type, confusingly.

LIST SENSORS gets you objects of type Part that happen to be sensors.

SHIP:SENSORS gets you a special object that is an abstraction of all those details and just lets you get the values - it's documented here: http://ksp-kos.github.io/KOS_DOC/structure/vesselsensors/index.html. It's probably more what you want.

Example: IF SHIP:SENSORS:TEMP > 100 { PRINT "HOTTER THAN BOILING!". }.

I made a note on github to fix the docs for sensors, but it will be a little bit before I get to it.

Edited by Steven Mading
Link to comment
Share on other sites

<snip>abstraction of all those details and just lets you get the values - it's documented here: http://ksp-kos.github.io/KOS_DOC/structure/vesselsensors/index.html. It's probably more what you want.

Example: IF SHIP:SENSORS:TEMP > 100 { PRINT "HOTTER THAN BOILING!". }.

I made a note on github to fix the docs for sensors, but it will be a little bit before I get to it.

Thanks, that's really helpful. As for the whole documentation thing, I just assumed I was not typing something correctly lol... but I couldn't find anywhere that showed me how to actually access the sensors. As for what i was trying to do, a text readout would be just fine by me... I'm building a datarecorder script that logs altitude, current TWR (since there seems to be no good way to read throttle position) as g-force + 1, and pitch into a csv... then I feed that data into a graphing utility afterward so that I can look at/analyze trajectory and compare different trajectory/thrust profiles to their related efficiencies to get a better idea of what works best for different vehicles with the mods i have currently set up.

EDIT: The sensor vs. sensors was what was getting to me, i had put a accelerometer on my craft and was trying to have kOS read from it lol. The ship:sensors:acc is much better for what I want to do. Thanks again. (btw, love your kOS videos... they are the reason I downloaded this mod)

Edited by impyre
Link to comment
Share on other sites

Okay, I've got to ask, what is going on with these vectors? These are just supposed to be the default X, Y, and Z axes, (the red, green and blue vectors accordingly.) but only the Y axis is pointing in a direction that makes sense; hence its label, and the labels on the other two.

uWzPDTn.png

Link to comment
Share on other sites

It seems right to me. What's most important to notice is the axes orientations relative to each other. I believe this is a left-hand-rule system, which is common in games. What you must remember is that "up" isn't always what you think it should be, and that these vectors represent the absolute x, y, and z directions free of any particular reference (that i'm aware of). If you do a time warp for a bit, then stop and check the orientation of the vectors, I think you'll find that the axes appear to rotate (but it's actually your ship that's rotating due to movement on the planet's surface)... there should be at least four points where the axes "look more right" with either the red or blue lining up with your ship's alignment.

Edit: If you want to create something like this that is oriented correctly with your ship, you could store ship:facing:vector in some variable, directionvector for example, then create three vectors just as you've done here, but instead of setting x to 1, you'd set it to directionvector:x. It'd look like v(directionvector:x,0,0). If you did that for each other axis, you'd have something that would look exactly like you expect it to.

Edit2:

at about 5 minutes in he does the same thing you're trying to do here (with the same code). You can also see how the positioning makes more sense while in orbit. Edited by impyre
Link to comment
Share on other sites

^

DECLARE someVar.

SET someVar TO <throttle value>.

LOCK THROTTLE TO someVar.

PRINT someVar.

It seems right to me. What's most important to notice is the axes orientations relative to each other. I believe this is a left-hand-rule system, which is common in games. What you must remember is that "up" isn't always what you think it should be, and that these vectors represent the absolute x, y, and z directions free of any particular reference (that i'm aware of). If you do a time warp for a bit, then stop and check the orientation of the vectors, I think you'll find that the axes appear to rotate (but it's actually your ship that's rotating due to movement on the planet's surface)... there should be at least four points where the axes "look more right" with either the red or blue lining up with your ship's alignment.

Edit: If you want to create something like this that is oriented correctly with your ship, you could store ship:facing:vector in some variable, directionvector for example, then create three vectors just as you've done here, but instead of setting x to 1, you'd set it to directionvector:x. It'd look like v(directionvector:x,0,0). If you did that for each other axis, you'd have something that would look exactly like you expect it to.

Edit2:

at about 5 minutes in he does the same thing you're trying to do here (with the same code). You can also see how the positioning makes more sense while in orbit.

I tried timewarping and the vectors did not appear to move at all, that was one of my first suspicions that it was due to Kerbin being in a weird orientation compared to the global coordinate system. Neither time of day nor time of year seem to affect affect the orientation of the vectors. I have not had a significant amount of time to test whether or not position on Kerbin affects them though.

Link to comment
Share on other sites

^

DECLARE someVar.

SET someVar TO <throttle value>.

LOCK THROTTLE TO someVar.

PRINT someVar.

I tried timewarping and the vectors did not appear to move at all, that was one of my first suspicions that it was due to Kerbin being in a weird orientation compared to the global coordinate system. Neither time of day nor time of year seem to affect affect the orientation of the vectors. I have not had a significant amount of time to test whether or not position on Kerbin affects them though.

The coordinate system is messy. The only constant is that the Y axis will always point along the "north pole ray". (the ray that aims straight up at the north pole - i.e. the ray that represents the north half of the planetary axis, and that the other two axes, X and Z, will always be 90 degrees apart from each other (to form an orthogonal set of basis vectors), and oriented parallel to the equatorial plane, but exactly which way they'll point relative to the longitude of the planet is impossible to predict. In one game at one point in time maybe the X axis points out the 134 longitude line, then next time maybe it's the 51 longitude line, etc. The reasons for this are complex and have to do with internal trickery KSP is doing (basically, at low altitude the planet is stationary and the universe rotates. but at high altitude the universe is stationary and the planet rotates. Depending on how much time you've spent in your saved game with the camera looking at a high altitude vessel versus a low altitude vessel, this locking and unlocking of the universe to the planet is why the axes are always so wacky. The game remembers what position the axes were at last time and keeps them that way when you reload.)

If you want a more sane looking picture of the axes, try this:


set xAxis to vecdrawargs( ship:body:position, V(2000000,0,0), RGB(1.0,0.5,0.5), "X axis", 5, true ).
set yAxis to vecdrawargs( ship:body:position, V(0,2000000,0), RGB(0.5,1.0,0.5), "Y axis", 5, true ).
set zAxis to vecdrawargs( ship:body:position, V(0,0,2000000), RGB(0.5,0.5,1.0), "Z axis", 5, true ).

That will make the arrows 2 million meters long, and origin them at the planet's center. Switch out to the map view and you'll see a much better image of what I'm talking about.

Link to comment
Share on other sites

I suppose that could work. What I'm trying to do is create a script to do a gravity turn for a suborbital rocket. (I'm using the 6.4x RSS config from Regex and haven't quite gotten used to everything, so to learn I'm trying to progress in a Mercury-> Gemini->Apollo fashion to get my bearings. If you can't tell, I'm still on Mercury.) The goal was to launch the rocket, wait until 1000m, perform the initial pitchover, and then lock the steering to ship:velocity:surface to produce a real gravity turn that is easily modified using the initial height and pitchover values. I ran into trouble with the vessel rolling to the wrong roll orientation when switching to a vector heading, and I couldn't correct it with an R() tuple because you can't add a vector and an angle tuple. The goal was to convert ship:velocity:surface to an R() tuple to enable roll guidance to keep the rocket oriented correctly. To start I needed to know which basis vectors pointed in which directions to convert from a vector to an euler angle and upon doing so I discovered the issue.

Link to comment
Share on other sites

I suppose that could work. What I'm trying to do is create a script to do a gravity turn for a suborbital rocket. (I'm using the 6.4x RSS config from Regex and haven't quite gotten used to everything, so to learn I'm trying to progress in a Mercury-> Gemini->Apollo fashion to get my bearings. If you can't tell, I'm still on Mercury.) The goal was to launch the rocket, wait until 1000m, perform the initial pitchover, and then lock the steering to ship:velocity:surface to produce a real gravity turn that is easily modified using the initial height and pitchover values.

If you lock steering to ship:velocity:surface, you can't recover if something perturbs your heading to one side or the other. Maybe not a problem for what you're doing, but it gets annoying once you start trying to launch to a particular inclination.

Here's the gravity-turn part of an auto-launch script I was just working on. I calculate the angle between ship:velocity:surface and up:vector, then lock steering to a heading() with a fixed compass heading and the calculated pitch angle. The numbers are for stock-size Kerbin with FAR.


set initialPitch to 84.
set targetAoA to -1.
lock velPitch to arcsin(vdot(up:vector, ship:velocity:surface:normalized)).

wait until ship:airspeed > 35.
print "Initial turn".
lock steering to heading(90,initialPitch).

wait until velPitch + targetAoA < initialPitch.
print "Maintaining AoA".
lock steering to heading(90, velPitch + targetAoA).

Link to comment
Share on other sites

<snip> The goal was to convert ship:velocity:surface to an R() tuple to enable roll guidance to keep the rocket oriented correctly. <snip>

It sounds like you want ship:velocity:surface:direction, if I'm not mistaken that usually works for anything that can return a vector, and instead returns a euler direction in the form of r(#,#,#). Of course, you lose any magnitude data with that, but it seems like the most direct route.

Link to comment
Share on other sites

^^ Interesting, I hadn't thought of doing that. Ill have to try it when I get home. Thanks for the input! Also, an far as not being able to correct for perturbations by locking to ship:velocity:surface, I understand that. I actually wanted that as it would require a lot of precision, and perhaps even require me to delve into raw vehicle control and writing my own control algorithms precise enough to get the initial pitch and roll maneuvers correct. (Lofty goal, I know. But its fun to me!) It would also add the variation in final orbits that you find in real life, normal rockets don't end up within a few hundred meters of their target orbit consistently.

Edit: ^That seems to be exactly what I'm looking for. Thanks!

Edited by VFB1210
Link to comment
Share on other sites

<snip>It would also add the variation in final orbits that you find in real life, normal rockets don't end up within a few hundred meters of their target orbit consistently.

Edit: ^That seems to be exactly what I'm looking for. Thanks!

Glad I could help! I couldn't find a page on the kOS documentation site with an example to link, but I knew I remembered reading about it somewhere. As for the reality thing, maybe someone will build a mod that will create a dynamic atmosphere that can toss you off course if you aren't careful. Personally, I doubt I'd use it... but who knows.

Edit: What I've been attempting to do is develop a more robust script similar to what Steve Mading uses in his youtube videos. However, I was trying to use something a bit more... efficient than the square root function. It seems that the root function is a pretty robust and efficient solution for being relatively simpler (as far as I can tell)... the OCD side of me wants something closer to the optimal trajectory, but it's incredibly difficult to represent mathematically.

Edited by impyre
Link to comment
Share on other sites

Edit: What I've been attempting to do is develop a more robust script similar to what Steve Mading uses in his youtube videos. However, I was trying to use something a bit more... efficient than the square root function. It seems that the root function is a pretty robust and efficient solution for being relatively simpler (as far as I can tell)... the OCD side of me wants something closer to the optimal trajectory, but it's incredibly difficult to represent mathematically.

I've heard pople had pretty good success with this simple algorithm:

Goal: Don't allow the apoapsis to get too high above you. If you have enough momentum going that the apoapsis is a lot higher than you are, then this means you're going too vertical and not horizontal enough.

Algorithm: Pick some desired height H - the height that the apoapsis should be above your current altitude. If the current apopasis-altitude is < H, then aim a bit higher than your current velocity vector. If its > H then aim a bit lower than your current velocity vector. For more sophistication, make the amount by which you want to deflect your aim from your velocity dependent on how far off from H you are.

Of course, don't kick this in until you have gone vertical a while and are outside the pea-soup low atmosphere. (with FAR it may be different).

Link to comment
Share on other sites

I've heard pople had pretty good success with this simple algorithm:

Goal: Don't allow the apoapsis to get too high above you. If you have enough momentum going that the apoapsis is a lot higher than you are, then this means you're going too vertical and not horizontal enough.

Algorithm: Pick some desired height H - the height that the apoapsis should be above your current altitude. If the current apopasis-altitude is < H, then aim a bit higher than your current velocity vector. If its > H then aim a bit lower than your current velocity vector. For more sophistication, make the amount by which you want to deflect your aim from your velocity dependent on how far off from H you are.

Of course, don't kick this in until you have gone vertical a while and are outside the pea-soup low atmosphere. (with FAR it may be different).

I used the method of ETA:apoapsis for awhile with apparently good results (and it is the easiest method of circularization as far as I can tell)... but it becomes difficult because the apoapsis will be closer at launch, then get further away... then get closer again. Still not sure what the mathematical relationship is.

Edit: "print throttle." doesn't work for me.

There's another problem I'm having, but it may be code-related. I'm trying to run a main control loop which runs through a list called subroutines. It uses "for routine in subroutines{ run routine. }" and is set up to loop until interrupted by action group. I want something that will let me re-configure on the fly by choosing what subroutines to run.

Edited by impyre
Link to comment
Share on other sites

The mathematical relationship between the time since launch and eta to apoapsis is far beyond the abilities of kOS to solve. It gets ugly very quickly due to the constantly changing mass of the ship throwing a wrench into what would be a relatively simple integration of the net force on the vessel.

Link to comment
Share on other sites

The mathematical relationship between the time since launch and eta to apoapsis is far beyond the abilities of kOS to solve. It gets ugly very quickly due to the constantly changing mass of the ship throwing a wrench into what would be a relatively simple integration of the net force on the vessel.

I didn't mean solving for anything, I meant waiting until a certain altitude then attempt to keep the apoapsis in front of you but as close as possible with throttle management. Basically you wait until the apoapsis starts to move away (ETA:apoapsis will be getting larger) then you decrease throttle until it gets closer... so basically you hover around a certain value. I usually shoot for around 12 seconds (this is also the way some of the apollo missions performed certain burns in order to use fuel as efficiently as possible).

edit: did you see the above edit about the control loop problem?

as a side note, is there any forum dedicated to mod discussion/questions? if not... there should be (so we could use it instead of hijacking the mod's showcase thread)

edit 2: nvm, i found the mod discussion thread... it just doesn't show up on the main forum index for whatever reason.

Edited by impyre
Link to comment
Share on other sites

I didn't mean solving for anything, I meant waiting until a certain altitude then attempt to keep the apoapsis in front of you but as close as possible with throttle management. Basically you wait until the apoapsis starts to move away (ETA:apoapsis will be getting larger) then you decrease throttle until it gets closer... so basically you hover around a certain value. I usually shoot for around 12 seconds (this is also the way some of the apollo missions performed certain burns in order to use fuel as efficiently as possible).

I wasn't proposing using the TIME to apoapsis, but the ALTITUDE to it, and not to adjust the throttle, but to adjust the aim. If Apoapsis is high above your current altitude, then aim more downward. If Apoapsis is not high enough above your current altitude, then aim more upward. Apoapsis might be only 2,000 meters above you, but also be 5 minutes away because you've nearly achieved your orbit and your velocity is nearly horizontal and it will take a long time to achieve those 3,000 meters of altitude. If you've set your desired apoapsis height to, say, 3000, and it's actually 5000 above you, then it's safe to aim more down because you've got so much vertical momentum. If, on the other hand, it's only 1000 above you, then you're not going fast enough yet to be considering aiming down like that.

as a side note, is there any forum dedicated to mod discussion/questions? if not... there should be (so we could use it instead of hijacking the mod's showcase thread)

edit 2: nvm, i found the mod discussion thread... it just doesn't show up on the main forum index for whatever reason.

This sort of thing seems perfectly on topic in this thread to me. Part of the reason there's 133 pages already is because its a mix of new announcements and people discussing algorithms with each other.

Link to comment
Share on other sites

Could you help me figure out why my control loop isn't working as planned? (from above-above post http://forum.kerbalspaceprogram.com/threads/68089-0-24-kOS-Scriptable-Autopilot-System-v0-13-1-2014-7-18?p=1355826&viewfull=1#post1355826)

apparently you can't do this. The for loop doesn't properly expand the variable before attempting to run the thing... so it's trying to run nothing each cycle. I tried to get around this by passing it to a sub-routine launcher script and then having that script launch the subroutines as declared variables... but that causes stack overflow error. Without the ability to build a solid control loop (without having to rewrite it every time i wanna change the program and taking up loads of unnecessary space) I'm not sure I can build anything useful.

Link to comment
Share on other sites

apparently you can't do this. The for loop doesn't properly expand the variable before attempting to run the thing... so it's trying to run nothing each cycle.

The fact that it's a loop has nothing to do with why it doesn't work. The example below ALSO wouldn't work, and isn't using a for loop:


SET progName to "my_program".
RUN progName.

The problem isn't the FOR, it's the RUN. You can't RUN some program name that's stored in a variable. Why? Because of the fact that the syntax is this:

RUN <identifier>

rather than this

RUN <expression-that-evaluates-to-a-string>

So, for the same reason, you can't do this either:

RUN "my" + "_" + "program".

Basically, the operand of RUN is an identifier, but then it's value isn't expanded, the identifier itself IS the filename. I don't like this design for the fact that it creates the problem you've run into here. But it's impossible to fix without breaking backward compatibility, because it would require changing everyone's kosscript code that does this:

RUN myProgram.

into this:

RUN "myProgram".

so that the value can be a string or a variable or any expression.

At the moment, the only way to do it is to take advantage of the self-modifying code trick using the LOG command.

(The fact that the files that the LOG command makes are seen by the system as being identical to the files you RUN, you can use LOG to actually write out a program, and then run the logfile.)

Example:

SET X TO 5.

LOG "PRINT X." TO MYLOG.

RUN MYLOG.

(prints 5, but if you run it again, the LOG command APPENDS, so on the second run it would have the print 5 command in it twice, so you have to delete it first.).

Using this trick you can do this:

LOG "DUMMY" TO TEMPSCRIPT. // ensure it exists so it doesn't bomb out on the next line.

DELETE TEMPSCRIPT. // clear it out.

LOG "RUN " + myVariable + "." TO TEMPSCRIPT. // the command RUN _____, where the ____ is the contents of myVariable.

RUN TEMPSCRIPT.

I've pulled this trick before but I don't like doing it, and would avoid it if at all possible, as it's very dependent on certain wonky behavior remaining wonky in future releases. (that being that log files and program files are indistinguishable).

Link to comment
Share on other sites

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