Jump to content

[1.3] kOS Scriptable Autopilot System v1.1.3.0


erendrake

Recommended Posts

RXchTS1.jpg

studied the docs and can't find a reason for this error: Collection was modified, enumeration operation may not execute

I've create a debug screen that updates variables for me to check, and I have room for 10 log messages at any time. So I'm using a list to display only the last 10 things logged (full list is in the actual log file). Reading through the docs I think I'm using it right. So I set it up:

set recentLogList to list().

and then places in the code where I'm logging things I check to see if the list has gotten too long and then remove the first entry.

set recentLogList:add to "<" + time:clock + "> program initialized".
log "<" + time:clock + "> program initialized" to RoverLog.
if recentLogList:length = maxLogEntries {
set recentLogList:remove to 0.
}.

Finally in the "main loop" of the program I use an iterator to wipe the old log list in the display and print the new one

until abort = true {
set logItem to recentLogList:iterator.
set dummy to logItem:reset.
until not logItem:next {
print "| |" at (0, logLineStart + logItem:index).
print logItem:value at (2, logLineStart + logItem:index).
}.

wait 0.001.
}.

And it all works fine and dandy... until that error pops up (it then inserted that blank line in the log listing). It would seem recentLogList is being changed while in the until {} loop. Somehow. Given that all the logging I showed in the second code example takes place within when {} blocks, could it be possible? I would think the until {} loop would complete before any when {} triggers fire and execute, if I'm understanding things correctly as explained in the docs on kOS hardware.

Also note the currentSlopeAngle readout that has a hanging number. It's because that's supposed to be rounding off to 2 decimal places (so I'm only refreshing enough text for "0.00") but occasionally for some reason it shows up with three (but only when it's positive).

Edited by Gaiiden
Link to comment
Share on other sites

The message "Collection was modified, enumeration operation may not execute", does not come directly from kOS. It comes from C#. It happens because C# iterators are limited to only work when the collection is frozen during the iteration. It can't deal with altering a collection while iterating over it like some languages can. If you insert, remove, or modify an element inside the LIST while you are trying to iterate over it with an iterator, you will get that complaint.

You didn't explain in your post how the code snippets you posted are included in the main program, but is it possible for this line:


set recentLogList:remove to 0.

Can get executed while inside of this loop:


until not logItem:next {

? (i.e. is that SET command happening inside a WHEN trigger so it could happen during the loop?)

Link to comment
Share on other sites

You didn't explain in your post how the code snippets you posted are included in the main program...
And it all works fine and dandy... until that error pops up (it then inserted that blank line in the log listing). It would seem recentLogList is being changed while in the until {} loop. Somehow. Given that all the logging I showed in the second code example takes place within when {} blocks, could it be possible? I would think the until {} loop would complete before any when {} triggers fire and execute, if I'm understanding things correctly as explained in the docs on kOS hardware.

Ok so you've confirmed what I thought was happening. I realized after stepping away from it for a while that yea, there is a chance it could be doing this since every tick kOS executes a bit more of the "main loop" after first executing any triggers at the start of the tick.

The solution I think would be to just iterate through a copy of the list instead, as that won't be touched by the when {} triggers if they fire to modify the list as it is being rendered.

Edit: or not?? :(

MShu2WE.jpg

So when I try to do this:

  set renderLog to recentLogList:copy.
set logItem to renderLog:iterator.
until not logItem:next {
print "| |" at (0, logLineStart + logItem:index).
print logItem:value at (2, logLineStart + logItem:index).
}.

I get the error Values of type System.Collections.Generic.List 1[system.Object] cannot have suffixes. You can then see after that I did some console experimentation with similar results.

okay... next solution! Print only the first x amount of items from the list and then clean up extra ones afterwards.

edit: Alright, now we're rolling.

  set index to 0.
until index = maxLogEntries or index = recentLogList:length {
print "| |" at (0, logLineStart + index).
print recentLogList[index] at (2, logLineStart + index).
set index to index + 1.
}.

if recentLogList:length > maxLogEntries {
until recentLogList:length = maxLogEntries {
set recentLogList:remove to 0.
}.
}.

I like this way better anyhow since the list culling is only performed in this one place rather than after every single add, which means less code, smaller footprint.

Edited by Gaiiden
Link to comment
Share on other sites

Um I have a question. I put a .txt file in my Archive but I am not able to get it in-game when I type in list. Also doing edit (filename). does absolutely nothing. There's no new screen which allows me to save. I downloaded from spaceport and my version is "v.0.12.0"

Link to comment
Share on other sites

Edit: or not?? :(

That should not return a c# type :P another bug! Thanks!

- - - Updated - - -

Um I have a question. I put a .txt file in my Archive but I am not able to get it in-game when I type in list. Also doing edit (filename). does absolutely nothing. There's no new screen which allows me to save. I downloaded from spaceport and my version is "v.0.12.0"

Its not in 12.0 but the newer pre-releases have an editor again. they are pretty stable so you should try them out.

Link to comment
Share on other sites

this may be an issue related to the problem with MM compatibility. I've seen previous posts where people have had issues adding kOS direct to a command part via MM. I'm doing it now with the rover brain from Rover Science and surprisingly I'm able to save the game, reload back to the rover and it's all there. Sweet! Only problem is that all the programs I copied from the archive are gone - they show up in the list but have 0 size. The one file created locally (log file for the program) is properly maintained in the save file.

Link to comment
Share on other sites

I need a logic check. I'm attempting to do a three-zone altitude controlled climb.

Please look at this, and tell me if I have the correct {if/else} techniques. Not sure if I have the (optional) periods correctly placed. I keep getting a syntax arror at the first ELSE statent.

BTW, I'm having problems with the code brackets showing the final closing bracket here...it's in my code.


IF ALTR < 80 {
DO TAKEOFF STUFF.
}
} ELSE IF ALTITUDE < HIGHALT {
SET COUNTER TO 0.
UNTIL ALTR > ENDALT {
DO PITCH MAGIC.
IF ALTITUDE > 25000 AND < 30000{
DO AIRBREATHING ENGINE THROTTLE
}
DO STUFF.
IF COUNTER > 30 {
DO STUFF.
SET COUNTER TO 0.
}
}
} ELSE IF ALTITUDE > ENDALT {
SET COUNTER TO 0.
UNTIL ALTITUDE > HIGHALT {
DO PITCH MAGIC.
IF ALTITUDE > 30000 {
DO HIGH ALT ENGINE STUFF.
}.
DO STUFF.
IF COUNTER > 30 {
DO STUFF.
SET COUNTER TO 0.
}
}
}
} .


Edited by Pondafarr
Link to comment
Share on other sites

Solved previous problem, (don't ask me how) so now I would like to do a set of instructions ONLY between certain altitudes, and have three altitude zones to define:

IF altitude > MINALT < MAXALT {

DO STUFF.

Will this work? I'm not getting the results I expected.

Edited by Pondafarr
Link to comment
Share on other sites

First time trying this out and I can't get files to run. Sorry if this is a common question. I switch to the archive and run "list files." and get back the correct list of files, including one called "hello.txt". However "run hello." results in "File 'hello' not found. I've got a fresh 0.23.5 install with just KER and the KSP Mod Admin going. Thanks.

Link to comment
Share on other sites

I need a logic check.

You had a couple issues with your nesting (indented code) and when I aligned things properly some extra braces appeared, including why your first IF is failing:

IF ALTR < 80 {
DO TAKEOFF STUFF.
} <--- remove this
} ELSE IF ALTITUDE < HIGHALT {
SET COUNTER TO 0.
UNTIL ALTR > ENDALT {
DO PITCH MAGIC.
IF ALTITUDE > 25000 AND < 30000 {
DO AIRBREATHING ENGINE THROTTLE
}
DO STUFF.
IF COUNTER > 30 {
DO STUFF.
SET COUNTER TO 0.
}
}. <- this was missing a period
} ELSE IF ALTITUDE > ENDALT {
SET COUNTER TO 0.
UNTIL ALTITUDE > HIGHALT {
DO PITCH MAGIC.
IF ALTITUDE > 30000 {
DO HIGH ALT ENGINE STUFF.
}.
DO STUFF.
IF COUNTER > 30 {
DO STUFF.
SET COUNTER TO 0.
}. <- optional period was missing (I like using them)
} <-- remove this too
}. <-- also missing a period
}.

While the "." after braces is optional, I like using it anyways to keep me in the habit of using it :P

Will this work? I'm not getting the results I expected.

No, you need to use boolean operators (and, or, not, etc). In this case since is seems you want both to be true

IF altitude > MINALT AND altitude < MAXALT {
DO STUFF.

if you needed only one or the other to be true, you'd use OR.

First time trying this out and I can't get files to run. Sorry if this is a common question. I switch to the archive and run "list files." and get back the correct list of files, including one called "hello.txt". However "run hello." results in "File 'hello' not found. I've got a fresh 0.23.5 install with just KER and the KSP Mod Admin going. Thanks.

The docs don't say run won't work when switched to the archive but it seems to me that you would never want to run a program off the archive for various reasons (such as losing comms, or corrupting the file). Therefore I would assume the run command only works on files stored on the local volume. You should copy the file to your local volume and then run it

Edited by Gaiiden
Link to comment
Share on other sites

I need a logic check. I'm attempting to do a three-zone altitude controlled climb.

Was what you posted the entirety of your program or was there some missing context before and after the part you quoted?

The reason I ask is that it looks like one straight fall-through if/else ladder without a loop around it (again, this is assuming you posted everything and not just a subset of the code).

If that's true, then a big problem you'd run into is that an if/else ladder will only execute ONE of the conditions inside, never more than one.

Consider this example code snippet:


set x to 4.
set y to 5.
if x > 0 {
print "x is positive.".
} else if x < y {
print "x is less than y.".
} else {
print "x is neither positive nor less than y.".
}.

Consider that code - BOTH the first conditions are true - X is both positive AND it's also less than Y. Therefore you might think it will execute both sections and print:

x is positive.

x is less than y.

But it won't. It will only print the first one:

x is positive.

Why? Because it says "ELSE IF", meaning "only perform this check if the previous check failed." It will only ever check the second condition (x < y) if (x > 0) was false. Once the first check succeeds, it will skip ALL the remaining checks and drop all the way to the bottom of the entire if/else structure.

So at first ALTR is < 80, so it executes the "DO TAKEOFF STUFF", and once it finishes that it skips past all the other checks, because it already knows the first check worked so all the other "ELSE" checks won't work because they say "ELSE" - meaning only try them if the previous conditions didn't succeed.

(Now, if you wrap all this in a loop, that's different. Then on one pass through the loop it might do the first part, and on a second pass through the loop it might skip the first part and try the second part, and so on.)

Edited by Steven Mading
typo spelling the word "nor" as "not".
Link to comment
Share on other sites

First time trying this out and I can't get files to run. Sorry if this is a common question. I switch to the archive and run "list files." and get back the correct list of files, including one called "hello.txt". However "run hello." results in "File 'hello' not found. I've got a fresh 0.23.5 install with just KER and the KSP Mod Admin going. Thanks.

The docs don't say run won't work when switched to the archive but it seems to me that you would never want to run a program off the archive for various reasons (such as losing comms, or corrupting the file). Therefore I would assume the run command only works on files stored on the local volume. You should copy the file to your local volume and then run it

What Avdacar described *should* work, actually, You can run files directly from the archive so long as you have radio range (a check which is currently disabled anyway because the future plan is to only enable that check if you have RT2 installed).

Advacar, can you post the exact sequence of commands you run and the exact output you get? (A screenshot showing the terminal window would be great if you can frame it up so it all fits on one screenshot).

Link to comment
Share on other sites

What Avdacar described *should* work, actually, You can run files directly from the archive so long as you have radio range (a check which is currently disabled anyway because the future plan is to only enable that check if you have RT2 installed).

Advacar, can you post the exact sequence of commands you run and the exact output you get? (A screenshot showing the terminal window would be great if you can frame it up so it all fits on one screenshot).

Sure, give me a minute. In the mean time, all I had was a tank, engine, probe core, struts, legs, parachutes and the KOS core. I'm just trying to do some really basic stuff. Also, copying to the local KOS core didn't work either for the same reason.

Link to comment
Share on other sites

The LIST command should strip off the .txt from the display. Is the actual file in the archive called "hello.txt.txt"?

/facepalm. That's probably it. It's a new install of Windows and I don't remember turning off the extension hider feature in Explorer. I'll check it out when I get home. Thanks.

Link to comment
Share on other sites

Actually one thing that always bugged me about the kosscript syntax is how the language syntax makes the filenames be identifiers instead of string values. That means you can't do this:

set fname to "myprog".

run fname(arg1).

and you can't do this:

run "filename with spaces"(arg1).

There's nothing in the underlying volume system that requires the filenames to be identifiers. It's just the syntax grammar definition that has the limitation.

Link to comment
Share on other sites

It's too complex to go into here, but there's very good reasons to have end-of-statement markers in languages, if they're the sorts of languages that ignore whitespace and line breaks and just treat a run of spaces,tabs,and end of lines as being identical - all get mashed down to just "there is some space here" in the syntax. The languages that don't require them instead have to require tighter rules on what the spacing means, which is a different type of limitation.

The only thing I'm not happy with is that period(.) is a poor choice for the end-of-statement marker because of its conflation with decimal points, and how it being used for end markers precluded it from being used for member separators (thus why you say SHIP:FACING:VECTOR, instead of the more normal Ship.Facing.Vector that most languages would have you use for that type of thing).

Link to comment
Share on other sites

bear in mind i am NOT a programmer, so don't treat this question with the derision it probably deserves.....simply remember i'm ignorant of proper coding :)

so, for a hypothetical version 13, why not rip out the period requirement and replace it with something else?

Link to comment
Share on other sites

bear in mind i am NOT a programmer, so don't treat this question with the derision it probably deserves.....simply remember i'm ignorant of proper coding :)

so, for a hypothetical version 13, why not rip out the period requirement and replace it with something else?

I think one of the main reasons they would not due this is that all the scripts that people have to will have to be rewritten changing all the periods to semi-colons. But there could also be a deeper reason.

On another note, I have been playing with the vecdraw() and I was wondering if it would be possible to include the ability to draw/print the angle between two vectors on the screen for easier debugging, and also if there was any interest in that idea from others.

Link to comment
Share on other sites

I think one of the main reasons they would not due this is that all the scripts that people have to will have to be rewritten changing all the periods to semi-colons.

That's not a big deal at all. Find/Replace. Done.

Link to comment
Share on other sites

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