Jump to content

[1.3] kOS Scriptable Autopilot System v1.1.3.0


erendrake

Recommended Posts

It's what I would expect. "wait until <variable>" makes no logical sense to me. Afterall, whatever the variable is, that's what the condition is, so I would expect that script above to not wait at all.

Is that just a shorthand for "wait until (<variable> == true)"?

is "(<variable> == true)" the truth statement whose place it taken by the boolean variable <done>?

so if "(<false> == true)" is false then it waits?

but "(<true> == true)" is true so it continues?

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

Is that just a shorthand for "wait until (<variable> == true)"?

Almost. Technically it's shorthand for "<variable> is not false " which you might think is the same thing as "<variable> is true" but it's *slightly* different. I won't go into why it's slightly different here.)

This may look weird to you but it's actually *very* common in programming languages to allow you to store a boolean check result in a variable and then use that variable later in place of performing the check again.

Hmm.. How to explain....

When you do this:

set x to y + z.

The computer runs a math operation, "+", which is defined to take the following 3 terms:

itself,

the value to the left of itself,

the value to the right of itself,

and replace all three with a single value:

the sum of what had been the left value and what had been the right value.

Similarly, when you do this:

set x to y < z.

The computer is doing basically the same thing, but now the math operation is the '<', defined to do this:

take the following 3 terms:

itself,

the value to the left of itself,

the value to the right of itself,

and replace all three with a single value:

if the left value was smaller than the right, then the value to replace them with is 1 (true).

otherwise the value to replace them with is 0 (false).

In boolean algebra, operators like "<", ">", and so on are just another sort of math operator that consumes operand values and spits out a new value based on some rule. They have orders of operations, rules of precedence, and so on just like any other sort of math.

As far as the computer "thinks", this expression:

3*x + 4*y

isn't really all that different from this expression:

2*x < 4*y

So, yes you can store the result of a test like "is a < b?" in a variable.

When you say something like this:

if _stuff_ { .... }.

The _stuff_ part of it is just another expression like any other math expression. If the expression results in a value that means boolean "true", then it does the stuff in the brackets, regardless of whether that expression is written out right here or whether it was already run earlier and the result put into a variable and just that variable is mentioned here.

This:

set var to 4*x < 3*y.
if var { ... }.

Gives the same result as this:

if 4*x < 3*y { ... }.

For the exact same reason that this:

set var to 4*x + 3*y.
print "value is " + var.

Gives the same result as this:

print "value is " + (4*x + 3*y).

They're both doing the same thing. Storing the result of an expression in a variable. The result of an expression could be a boolean true/false value, because in a sense those are just a special type of number - a number that's only allowed to have 2 values: 0 or 1.

Edited by Steven Mading
Link to comment
Share on other sites

Loving playing with this mod - it's resulted in me learning more about orbital mechanics than the rest of KSP combined!

I wonder if anyone can help me figure out how to do something that should be really easy: getting the current orbital velocity vector of a body. thebody:velocity doesn't give me the right answer (based on the numbers in the KSP wiki). If I subtract the parent body's velocity I get the correct answer, but I can't do this for heliocentric orbits because the Sun doesn't have a velocity vector, which seems like a bug.

Has anyone got a solution for this?

Link to comment
Share on other sites

Is there a way to react to custom keystrokes?

No. I'd like there to be. Maybe it can be an upcoming feature. At the moment all you can do is react to action groups 0-9 (basically the user hitting ALT-0 through ALT-9 can be used as triggers to things in your kos script code because your code can react to the triggered action group, but that's got the big problem that people might be using those action groups for important parts of their rocket design.

Link to comment
Share on other sites

Loving playing with this mod - it's resulted in me learning more about orbital mechanics than the rest of KSP combined!

I wonder if anyone can help me figure out how to do something that should be really easy: getting the current orbital velocity vector of a body. thebody:velocity doesn't give me the right answer (based on the numbers in the KSP wiki). If I subtract the parent body's velocity I get the correct answer, but I can't do this for heliocentric orbits because the Sun doesn't have a velocity vector, which seems like a bug.

Has anyone got a solution for this?

All velocities are given relative to the current body you're orbiting. That's why body:velocity always returns V(0,0,0).

But POSITIONS on the other hand, are given relative to your ship, which is a bit of a confusing contradiction.

Link to comment
Share on other sites

Having trouble with this little bit of code meant to control throttle on the stock Kerbal X to keep it from going faster than terminal velocity.

//1000-2800m Terminal vel. of 125 m/s

PRINT "2800m ascent/125 m/s MAX.".
UNTIL ALTITUDE > 2800
{
IF VERTICALSPEED < 124
{
SET Tlvl TO Tlvl+0.02.
WAIT 0.2.
}.
IF VERTICALSPEED > 125
{
SET Tlvl TO Tlvl-0.01.
WAIT 0.2.
}.
}.
print "next.".


The vertical speed goes well beyond 130 m/s and the throttle doesn't respond at all. When I comment out the first part that is meant to keep the craft from going too slow by slowly throttling up the craft the second part that throttles down the craft works just fine. Here is what that code looks like.

//1000-2800m Terminal vel. of 125 m/s

PRINT "2800m ascent/125 m/s MAX.".
UNTIL ALTITUDE > 2800
{
// IF VERTICALSPEED < 124
// {
// SET Tlvl TO Tlvl+0.02.
// WAIT 0.2.
// }.
IF VERTICALSPEED > 125
{
SET Tlvl TO Tlvl-0.01.
WAIT 0.2.
}.
}.
print "next.".


So what am I not getting here. Here's the entire code

Link to comment
Share on other sites

When you reach that part of the code the Tlvl variable is set to 1 and the vertical speed is less than 124m/s (because you limited it to 110m/s before) but the script keeps incrementing the variable even if the throttle is already at maximum. So when the speed is finally over 125m/s and the script try to decrease the throttle the variable is going to have a value bigger than 1 making it seem like it's not doing anything.

You should add boundary checks to all the speed validations, something like


IF VERTICALSPEED < 124 AND Tlvl < 1
{
...
}

IF VERTICALSPEED > 125 AND Tlvl > 0
{
...
}

Also you could move the wait out of the IFs, there's no point in asking if the speed has gone over a threshold 50 times per second.

Link to comment
Share on other sites

Also you could move the wait out of the IFs, there's no point in asking if the speed has gone over a threshold 50 times per second.

The reason I put the WAITs inside the IFs is that without them, during testing (before I put the part that would throttle the craft up if it was going to slow) the throttle would be decreased too fast and the craft would slow down way too much.

This way the throttle would be taken down a notch and then the script would wait a half second (originally tested it with 'WAIT 0.5.', but it was too slow so I changed it to 'WAIT 0.2.', and it worked pretty well) to let the vertical velocity change before checking it again and throttling down if necessary. Given your suggestions though it would probably be a better idea to nest the UNTIL's inside the IF's like so...

IF VERTICALSPEED > 125 AND Tlvl > 0
{
UNTIL VERTICALSPEED <= 125
{
SET Tlvl TO Tlvl-0.02.
WAIT 0.2.
}.
}.

I'm not sure if the equals to or less than operator is recognized in KerboScript so if it isn't then I guess

UNTIL VERTICALSPEED <= 125

would have to be replaced with

UNTIL VERTICALSPEED = 125 OR VERTICALSPEED < 125

Link to comment
Share on other sites

Does anyone have an User-Defined language file for notepad++?

THIS!! I've been looking everywhere for this or at least instructions on how to make one myself as it would save a lot of time and make things easier. There already exists a kOS IDE but that's only for Windows.

And by creating this we wouldn't need to have and entire dev effort to create a text editor just for this one language when there already exists a perfectly well-functioning OPEN-SOURCE platform we can use and easily keep up-to-date with the latest version of kOS.

I would do it myself but I'm nowhere near familiar enough with KerboScript to take on this project. The user-defined language file could even be included with the download for the mod.

Link to comment
Share on other sites

For Linux/Win there is Saturn (no Mac as of now 'cos I don't have a Mac to compile it): http://forum.kerbalspaceprogram.com/threads/62834-Saturn-yet-another-kOS-IDE

I haven't got the time to properly maintain it (it's up to date with v0.11.1), but once I can get up to speed again it will include stuff that you won't find in Notepad++, if I can say so myself. :D

Link to comment
Share on other sites

All velocities are given relative to the current body you're orbiting. That's why body:velocity always returns V(0,0,0).

But POSITIONS on the other hand, are given relative to your ship, which is a bit of a confusing contradiction.

That's what I suspected was the case. Does that mean there's no way to get the orbital velocity of a body then?

As an example: If I have a ship orbiting Kerbin and I want Duna's current orbital velocity, it would be DUNA:VELOCITY - SUN:VELOCITY. This works because both are relative to Kerbin's velocity. However, because SUN has no velocity parameter, I need a different method...

The only approach I can come up with, would be to abuse the fact that Kerbin's orbital speed is constant. Using Kerbin's position and orbital speed I can get an orbital velocity vector relative to the Sun, which (assuming the ship is orbiting Kerbin) can be inversed to give the Sun's velocity relative to Kerbin, which can then finally give Duna's real orbital velocity.

This is completely mad for what should be such as a simple problem. :confused:

Link to comment
Share on other sites

As far as I remember it was originally based off the old/clunky "Basic", think C64. ;)

It looks nothing like Basic.

The terminal does, however, look like a bit like a C64, specifically the font. But I'd prefer it if it *really* looked like a C64. That would be great for nostalgia: 40 columns, 24 rows, cyan color on blue background.

Link to comment
Share on other sites

That's what I suspected was the case. Does that mean there's no way to get the orbital velocity of a body then?

As an example: If I have a ship orbiting Kerbin and I want Duna's current orbital velocity, it would be DUNA:VELOCITY - SUN:VELOCITY. This works because both are relative to Kerbin's velocity. However, because SUN has no velocity parameter, I need a different method...

The only approach I can come up with, would be to abuse the fact that Kerbin's orbital speed is constant. Using Kerbin's position and orbital speed I can get an orbital velocity vector relative to the Sun, which (assuming the ship is orbiting Kerbin) can be inversed to give the Sun's velocity relative to Kerbin, which can then finally give Duna's real orbital velocity.

This is completely mad for what should be such as a simple problem. :confused:

What does Ship:Body:Body:Velocity return? That would be, I'd assume, the velocity of your SOI body's parent relative to your SOI body. (i.e. if Ship is in orbit around Kerbin, it's the velocity of Sun relative to Kerbin.)

So Ship:Body:Body:Velocity would be the inverse of the velocity you want - just multiply it by the scalar -1.

If that works (I haven't tried it) then I have no problem with the system as it would at least be using a consistent frame of reference.

On the other hand, if BOTH Kerbin's velocity AND the Sun's velocity are both reported as V(0,0,0) *at the same time from the same position* then I'd consider that a bug, as it means the frame of reference isn't remaining consistent for all measures returned.

Link to comment
Share on other sites

Is there a way to run the following part of a script I'm working on

UNTIL ALTITUDE > AltRng{


//Diagnostic PRINT statements begin


SET DelTlv TO "at rest.".
PRINT DelTlv AT (16,1). PRINT AltRng AT (0,0).
PRINT TrmVel AT (14,0).


//End of diagnostic PRINT statements


IF VERTICALSPEED > TrmVel AND Tlv > 0
{
UNTIL VERTICALSPEED = TrmVel OR VERTICALSPEED < TrmVel
{
SET Tlv TO Tlv-0.01.
WAIT 0.2.


//Diagnostic PRINT statements begin


SET DelTlv TO "decreasing.". PRINT DelTlv AT (16,1).
PRINT Tlv AT (5,2).


//End of diagnostic PRINT statements


}.
}.
IF VERTICALSPEED < TrmVel AND Tlv < 1
{
UNTIL VERTICALSPEED = TrmVel OR VERTICALSPEED > TrmVel-5
{
SET Tlv TO Tlv+0.01.
WAIT 0.2.


//Diagnostic PRINT statements begin


SET DelTlv TO "increasing.". PRINT DelTlv AT (16,1).
PRINT Tlv AT (5,2).


//End of diagnostic PRINT statements


}.
}.
}.

multiple times with different values for the AltRng, TrmVel and Tlv variables each time without having to repeat the code multiple times in the same script. I've tried running it as a separate program called TrmVel-Tlv-Control-Uns (Uns = unstripped code) and then declare the three variables as parameters like so...

DECLARE PARAMATER AltRng, TrmVel, Tlv.

UNTIL ALTITUDE > AltRng
{


//Diagnostic PRINT statements begin


SET DelTlv TO "at rest.".
PRINT DelTlv AT (16,1). PRINT AltRng AT (0,0).
PRINT TrmVel AT (14,0).

.......(code continues)

that way each time I need to run that code instead of copypasting it onto my script which would make it inelegant and really long (take up way too much space) I could just insert this code into the main script.


SET AltRng TO [new value].
SET TrmVel TO [new value].

RUN TrmVel-Tlv-Control-Uns(AltRng, TrmVel, Tlv).

Unfortunately this doesn't seem to work and it just seems to skip to the end of my main script (made visible by the quickly flashing diagnostic PRINT statements.

The last part of my code locks the throttle (Tlv) to 100% and has a PRINT statement so that I know it has reached near the end of my main script

//temporary code placeholder.

CLEARSCREEN.
PRINT "Throttling up to 100%".
LOCK Tlv TO 1.


//end placeholder




//This is just to keep the program running for
//testing purposes.


WAIT UNTIL SHIP:LIQUIDFUEL = 0 AND
SHIP:OXIDIZER = 0.

Again I appreciate everyone's massive amount of patience for a complete noob:P. All the help and support is appreciated. I've got a long way to hopefully I'll get my commsat network up sometime this month.

Link to comment
Share on other sites

Again I appreciate everyone's massive amount of patience for a complete noob:P. All the help and support is appreciated. I've got a long way to hopefully I'll get my commsat network up sometime this month.

It's hard to diagnose a program with key parts of it not being shown. You're showing cut and pasted sections and the problem may be outside those sections.

But at any rate, I notice you tried to call you program by this name:

TrmVel-Tlv-Control-Uns

And I don't think that's a legal name. A program name must be a valid identifier and the definition of an identifier is this regular expression:

[a-z_][a-z0-9_]*

It doesn't look like it allows minus-signs in the identifier. Just underscores.

I have no idea how the parser is managing to read this:


RUN TrmVel-Tlv-Control-Uns(AltRng, TrmVel, Tlv).

and not end up barfing with syntax errors. I imagine it would interpret that as "run something called TrmVel, without any arguments, then subtract the value of Tlv from that, then subtract the value of Control from that, then run a function called Uns, with arguments AltRng, TrmVel, Tlv, and subtract that result."

And since there's no such program called TrmVel, no such function called Uns, and subprograms aren't implemented with return values (yet?) so there shouldn't be anything to subtract FROM after doing a run.... I have no idea how it's not complaining like crazy when it sees that line.

Link to comment
Share on other sites

Here's the full code.

Here's a video demonstrating my problem:

Okay I didn't have time yet to view the entire video but here's two things I can see so far that might be problems:

1 - You're using an older version of kOS than I am. I'm operating on the prerelease from the development thread. That's evident from the fact that you can use the EDIT command and it works (in newer versions it was dropped in favor of just editing the code outside KSP in a text editor which is what everyone seems to do anyway). This is also probably why you can use the "-" character in a filename. The parser changed in more recent versions and no longer will accept a filename that isn't a valid identifier (it has to follow the same naming rules as a variable name now). Just a heads-up warning - I think you'll have to change your filenames when the next update gets released.

2 - You appear to be trying to change a parameter passed in to a subprogram in the hope that doing this will change the value in the parent program. That doesn't work. You can't do something like this:

incrementProg


declare parameter thingy.
set thingy to thingy + 1.

mainProg


set val to 1.
print "value before: " + val.
run incrementProg( val ).
print "value after: " + val.

You appear to be trying to write code as if that would print this:


value before: 1
value after: 2

When in fact it would print this:


value before: 1
value after: 1

All variables in kOSscript are global *except for* program parameters. Those are local to the subprogram only, and are passed by value, not by reference (if you know what that means).

IMO, the ability of kosscript to pass information into and out of subprograms could use an overhaul. Currently there's no such thing as a return value from a subprogram, and no such thing as passing by reference, so the only way the subprogram can do any mathematical work on behalf of the main program is for it to store the results in global variables that the main program already created before the subprogram was called. Otherwise the main program can't see the results.

But that's for another time. There's other bugs to squash first.

Edited by Steven Mading
Link to comment
Share on other sites

Okay I didn't have time yet to view the entire video but here's two things I can see so far that might be problems:

I'm going to have to read this post at least 20 times before I understand what parts about it are what I don't understand. Thanks anyways, I'll get back to you when I know what it is I want to ask.

Link to comment
Share on other sites

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