MAFman Posted July 4, 2016 Share Posted July 4, 2016 Made some tweaks, but I'm still getting the same dang error... Boot.ks: SET SHIP:CONTROL:PILOTMAINTHROTTLE TO 0. LIGHTS OFF. GEAR OFF. BRAKES OFF. SAS OFF. RCS OFF. FUNCTION NOTIFY { PARAMETER message, priority. IF priority = "NOMINAL" { SET col TO GREEN. } ELSE IF priority = "ALERT" { SET col TO RGB(1,0.31,0). // international orange } ELSE IF priority = "WARNING" { SET col TO RED. } HUDTEXT("kOS: " + message, 1.5, 2, 30, col, FALSE). } FUNCTION ON_DRIVE { PARAMETER filename, vol. SWITCH TO vol. LIST FILES in allFiles. FOR f IN allFiles { IF f:NAME = filename { SWITCH TO 1. RETURN TRUE. } } SWITCH TO 1. RETURN FALSE. } // First-pass at introducing artificial delay. ADDONS:RT:DELAY(SHIP) represents // the line-of-site latency to KSC, as per RemoteTech FUNCTION DELAY { SET dTime TO ADDONS:RT:DELAY(SHIP) * 3. // Total delay time SET accTime TO 0. // Accumulated time UNTIL accTime >= dTime { SET start TO TIME:SECONDS. WAIT UNTIL (TIME:SECONDS - start) > (dTime - accTime) OR NOT ADDONS:RT:HASCONNECTION(SHIP). SET accTime TO accTime + TIME:SECONDS - start. } } // Get a file from KSC FUNCTION DOWNLOAD { PARAMETER filename. DELAY(). IF ON_DRIVE(filename, 1) { DELETE filename. } IF ON_DRIVE(filename, 0) { COPY filename FROM 0. } } // Put a file on KSC FUNCTION UPLOAD { PARAMETER filename. DELAY(). IF ON_DRIVE(filename, 0) { SWITCH TO 0. DELETE filename. SWITCH TO 1. } IF ON_DRIVE(filename, 1) { COPY filename TO 0. } } // Run a library, downloading it from KSC if necessary FUNCTION REQUIRE { PARAMETER filename. IF NOT ON_DRIVE(filename, 1) { DOWNLOAD(filename). } RENAME filename TO "tmp.exec.ks". RUN tmp.exec.ks. RENAME "tmp.exec.ks" TO filename. } // THE ACTUAL BOOTUP PROCESS SET updateScript TO SHIP:NAME + ".update.ks". // If we have a connection, see if there are new instructions. If so, download // and run them. IF ADDONS:RT:HASCONNECTION(SHIP) { IF ON_DRIVE(updateScript, 0) { DOWNLOAD(updateScript). SWITCH TO 0. DELETE updateScript. SWITCH TO 1. IF ON_DRIVE("update.ks", 1) { DELETE update.ks. } RENAME updateScript TO "update.ks". RUN update.ks. DELETE update.ks. } } // If a startup.ks file exists on the disk, run that. SET bootScript TO SHIP:NAME + ".bootup.ks". IF ON_DRIVE(bootScript, 0) { DOWNLOAD(bootScript). RENAME bootScript TO "startup.ks". RUN startup.ks. IF ON_DRIVE("startup.ks", 1) { SWITCH TO 1. DELETE startup.ks. } } ELSE { WAIT UNTIL ADDONS:RT:HASCONNECTION(SHIP). WAIT 10. // Avoid thrashing the CPU (when no startup.ks, but we have a // persistent connection, it will continually reboot) REBOOT. } Relay.bootup.ks: DOWNLOAD(autoNavInit.ks). DOWNLOAD(autoNavIterate.ks). RUN autoNavInit(270). AutoNavInit.ks: PARAMETER goalHeading. BRAKES ON. NOTIFY("Starting navigation script...Done.", "NOMINAL"). WAIT 2.5. NOTIFY("Downloading navigation instructions...Done.", "NOMINAL"). WAIT 2.5. NOTIFY("Running iterative navigator...", "NOMINAL"). SWITCH TO 0. RUN autoNav(goalHeading). AutoNav.ks: // Until the goal has been reached, go through this process. PARAMETER direct. DRIVE_FORWARD(). DRIVE_BACK(). PARK(). // The loop... Functions are defined below FUNCTION DRIVE_FORWARD { UNTIL FALSE { POPULATE(direct). DECIDE_NEXT(options). NOTIFY("Selecting next waypoint.", "NOMINAL"). WAIT 0.5. DRIVE_TO(nextPoint). STOP(). WAIT 5. IF NOT ADDONS:RT:HASCONNECTION(SHIP) { BREAK. } } } FUNCTION DRIVE_BACK { UNTIL FALSE { POPULATE(360 - direct). DECIDE_NEXT(options). NOTIFY("Selecting next waypoint", "NOMINAL"). WAIT 0.5. DRIVE_TO(nextPoint). STOP(). WAIT 5. IF ADDONS:RT:HASCONNECTION(SHIP) { BREAK. } } } FUNCTION THERE_YET { PARAMETER point. IF point:DISTANCE < 10 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION POPULATE { PARAMETER hdg. SET offset_90 TO SIN(hdg) * ((360 * 100) / (BODY:RADIUS * 2 * CONSTANT:PI)). // duh SET offset_675 TO offset_90 * SIN(67.5). // 67.5 deg. SET offset_45 TO offset_90 * SIN(45). // 45 deg. SET offset_225 TO offset_90 * SIN(22.5). // 22.5 deg. SET op_A TO LATLNG(SHIP:GEOPOSITION:LAT + offset_225, SHIP:GEOPOSITION:LNG - offset_675). SET op_B TO LATLNG(SHIP:GEOPOSITION:LAT + offset_45, SHIP:GEOPOSITION:LNG - offset_45). SET op_C TO LATLNG(SHIP:GEOPOSITION:LAT + offset_90, SHIP:GEOPOSITION:LNG). SET op_D TO LATLNG(SHIP:GEOPOSITION:LAT + offset_45, SHIP:GEOPOSITION:LNG + offset_45). SET op_E TO LATLNG(SHIP:GEOPOSITION:LAT + offset_225, SHIP:GEOPOSITION:LNG + offset_675). SET options TO LIST ( op_A, op_B, op_C, op_D, op_E ). RETURN options. } FUNCTION SLOPE_IS_SAFE { PARAMETER option. SET here TO SHIP:GEOPOSITION. SET there TO option. SET slope TO ABS(ARCTAN2(there:TERRAINHEIGHT - here:TERRAINHEIGHT, lookAhead)). IF slope < 10 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE_NEXT { PARAMETER options. SET startPos TO 0. UNTIL startPos > options:LENGTH - 1 { SET o TO options[startPos]. IF SLOPE_IS_SAFE(o) { SET nextPoint TO o. RETURN nextPoint. BREAK. } ELSE { SET startPos TO startPos + 1. } } } FUNCTION DRIVE_TO { PARAMETER point. BRAKES OFF. SET spd TO 1. // Really stinkin' slow, but safe. // Throttle control variables SET throttlePID TO PIDLOOP(0.15, 0.05, 0.1, -1.0, 1.0). SET throttlePID:SETPOINT TO spd. // Steering control variables SET steerPID TO PIDLOOP(0.15, 0.05, 0.1, -1.0, 1.0). SET steerPID:SETPOINT TO point:HEADING. CLEARSCREEN. SET thrott TO 0. SET steerVal TO 0. UNTIL THERE_YET(point) { SET thrott TO throttlePID:UPDATE(TIME:SECONDS, SHIP:GROUNDSPEED). SET steerVal TO steerPID:UPDATE(TIME:SECONDS, SHIP:HEADING). LOCK WHEELTHROTTLE TO thrott. LOCK WHEELSTEER TO steerVal. PRINT "Current Location: " + ROUND(SHIP:GEOPOSITION:LAT,3) + ", " + ROUND(SHIP:GEOPOSITION:LNG,3) at (0,3). PRINT "Next waypoint: " + ROUND(point:LAT,3) + ", " + ROUND(point:LNG, 3) AT (0,4). PRINT "Throttle: " + ROUND(thrott, 3) AT (0,9). PRINT "Steering: " + ROUND(steerVal,3) AT (0,10). WAIT 0.01. } STOP(). } FUNCTION STOP { IF GROUNDSPEED > 0.5 { LOCK WHEELTHROTTLE TO -0.5. } ELSE { UNLOCK WHEELTHROTTLE. IF NOT BRAKES { BRAKES ON. } } UNLOCK ALL. NOTIFY("Arrived!", "NOMINAL"). } FUNCTION PARK { STOP(). LIGHTS ON. FOR someAntenna IN SHIP:PARTSNAMED("RTLongAntenna2") { someAntenna:GETMODULE("ModuleRTAntenna"):DOEVENT("activate"). } } Can someone help me find my mistake(s)? Link to comment Share on other sites More sharing options...
kcs123 Posted July 4, 2016 Share Posted July 4, 2016 35 minutes ago, MAFman said: Can someone help me find my mistake(s)? Sorry, I don't have much time on disposal to inspect every line of code, neither to try it in KSP. At first sight, everything looks OK, but oviously it is not, otherwise you would not ask for help. Only thing I can is to give you tip for selfhelp. Put some additional lines of near suspicious part of code. Just print some info, either on screen or log file that could give you a clue is something work as intended or not. Similar to those "notify" lines like you already have in code. Without modern debuger and code insight info too see each value in variable it is pretty much only way to find logic errors or exact spot what is problematic line of code. You will need that kind of experience anyhow if you encounter in real life problematic situatons with some piece of software that is pretty much closed black box. Not only for game purposes in kOS, but other programming areas too. Link to comment Share on other sites More sharing options...
Dunbaratu Posted July 4, 2016 Share Posted July 4, 2016 Quote [LOG 19:11:11.259] System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2[System.String,System.Int32].get_Item (System.String key) [0x00000] in <filename unknown>:0 at kOS.Safe.Compilation.ProgramBuilder.ReplaceLabels When you get this error (key was not present in the dictionary) and you get it being done by ProgramBuilder.ReplaceLabels() as shown here, there's a good chance it's not your fault and it's a bug in how things are being loaded into the VM by kOS. We've done a lot of overhauling in that area in recent developer work so I can't tell if this problem would still exist in the next release or not unless I can re-run exactly everything you're doing in exactly the way you have been running it. That would mean, starting from the same saved game, running the same program, the same way, on the same craft. Some of what your program is doing looks like it's dependent on having a craft that is exactly like it expects it to be, with the same parts on it. (Which is why I'm reluctant to give it a test. It's a lot of set up work for a problem that for all I know might already be fixed.) The code change under the hood that may or may not have already fixed this in the development version is this one: https://github.com/KSP-KOS/KOS/pull/1657 The old way the RUN command was implemented before that had some odd failure cases where it would crash the ProgramBuilder.ReplaceLabels method. If you aren't in a position to be able to compile the kOS C# code yourself, I could try to give you a temporary ZIP file you can try to use to re-install kOS and it would give you the development version as-is (possible problems and all), and it might let you test if you still have this problem or not. I'm a bit reluctant to do this, though, as I don't think we're that far away from having a more official proper release anyway, and spending time on this problem would detract from getting that release out, which might fix it anyway. Link to comment Share on other sites More sharing options...
dewin Posted July 4, 2016 Share Posted July 4, 2016 @Steven Mading I'd be happy to do a build to save developer time. The mod I'm currently developing can't release until the next kOS release happens, anyways. Link to comment Share on other sites More sharing options...
MAFman Posted July 5, 2016 Share Posted July 5, 2016 9 hours ago, Steven Mading said: When you get this error (key was not present in the dictionary) and you get it being done by ProgramBuilder.ReplaceLabels() as shown here, there's a good chance it's not your fault and it's a bug in how things are being loaded into the VM by kOS. We've done a lot of overhauling in that area in recent developer work so I can't tell if this problem would still exist in the next release or not unless I can re-run exactly everything you're doing in exactly the way you have been running it. That would mean, starting from the same saved game, running the same program, the same way, on the same craft. Some of what your program is doing looks like it's dependent on having a craft that is exactly like it expects it to be, with the same parts on it. (Which is why I'm reluctant to give it a test. It's a lot of set up work for a problem that for all I know might already be fixed.) The code change under the hood that may or may not have already fixed this in the development version is this one: https://github.com/KSP-KOS/KOS/pull/1657 The old way the RUN command was implemented before that had some odd failure cases where it would crash the ProgramBuilder.ReplaceLabels method. If you aren't in a position to be able to compile the kOS C# code yourself, I could try to give you a temporary ZIP file you can try to use to re-install kOS and it would give you the development version as-is (possible problems and all), and it might let you test if you still have this problem or not. I'm a bit reluctant to do this, though, as I don't think we're that far away from having a more official proper release anyway, and spending time on this problem would detract from getting that release out, which might fix it anyway. I'd be super excited for a new patch version! I think I'll wait until the official release. 9 hours ago, Steven Mading said: When you get this error (key was not present in the dictionary) and you get it being done by ProgramBuilder.ReplaceLabels() as shown here, there's a good chance it's not your fault and it's a bug in how things are being loaded into the VM by kOS. We've done a lot of overhauling in that area in recent developer work so I can't tell if this problem would still exist in the next release or not unless I can re-run exactly everything you're doing in exactly the way you have been running it. That would mean, starting from the same saved game, running the same program, the same way, on the same craft. Some of what your program is doing looks like it's dependent on having a craft that is exactly like it expects it to be, with the same parts on it. (Which is why I'm reluctant to give it a test. It's a lot of set up work for a problem that for all I know might already be fixed.) The code change under the hood that may or may not have already fixed this in the development version is this one: https://github.com/KSP-KOS/KOS/pull/1657 The old way the RUN command was implemented before that had some odd failure cases where it would crash the ProgramBuilder.ReplaceLabels method. If you aren't in a position to be able to compile the kOS C# code yourself, I could try to give you a temporary ZIP file you can try to use to re-install kOS and it would give you the development version as-is (possible problems and all), and it might let you test if you still have this problem or not. I'm a bit reluctant to do this, though, as I don't think we're that far away from having a more official proper release anyway, and spending time on this problem would detract from getting that release out, which might fix it anyway. I can send you my save game and rover.craft if you want to try it. I'm also using RemoteTech and the RT Communotron 32, which is the only non-stock part on the rover. Link to comment Share on other sites More sharing options...
MAFman Posted July 6, 2016 Share Posted July 6, 2016 On 7/4/2016 at 1:51 PM, Steven Mading said: When you get this error (key was not present in the dictionary) and you get it being done by ProgramBuilder.ReplaceLabels() as shown here, there's a good chance it's not your fault and it's a bug in how things are being loaded into the VM by kOS. We've done a lot of overhauling in that area in recent developer work so I can't tell if this problem would still exist in the next release or not unless I can re-run exactly everything you're doing in exactly the way you have been running it. That would mean, starting from the same saved game, running the same program, the same way, on the same craft. Some of what your program is doing looks like it's dependent on having a craft that is exactly like it expects it to be, with the same parts on it. (Which is why I'm reluctant to give it a test. It's a lot of set up work for a problem that for all I know might already be fixed.) The code change under the hood that may or may not have already fixed this in the development version is this one: https://github.com/KSP-KOS/KOS/pull/1657 The old way the RUN command was implemented before that had some odd failure cases where it would crash the ProgramBuilder.ReplaceLabels method. If you aren't in a position to be able to compile the kOS C# code yourself, I could try to give you a temporary ZIP file you can try to use to re-install kOS and it would give you the development version as-is (possible problems and all), and it might let you test if you still have this problem or not. I'm a bit reluctant to do this, though, as I don't think we're that far away from having a more official proper release anyway, and spending time on this problem would detract from getting that release out, which might fix it anyway. What folder in GitHub is the Program-Builder in? Link to comment Share on other sites More sharing options...
MAFman Posted July 6, 2016 Share Posted July 6, 2016 (edited) Found it! Also found the log line where the error happened... Apparently, it tried to get a key from System.Collections.Generic.Dictionary`2 and it didn't find it. What is the difference between Dictionary and Dictionary`2? Also, shouldn't the code try to access just System.Collections.Generic.Dictionary? Why is it saying AddObjectParts(IEnumerable`1 parts)[0x00000] in <filename unknown>:0 ? Especially the <filename unknown>? I'm guessing it should be "in <autonav>:0" or something. [LOG 13:51:15.203] kOS: FunctionCopy: Volume: 1 Direction: to Filename: autonav.ks [LOG 13:51:15.728] kOS: At autonavinit.ks on 1, line 17 RUN autoNav(direct). ^ Called from startup.ks on 1, line 20 RUN autoNavInit(270). ^ Called from boot.ks on 1, line 139 RUN startup.ks. ^ Called from boot.ks on 1, line 153 RUN startup.ks. ^ Called from sys:boot, line 1 (Can't show source line) ^ [LOG 13:51:15.730] System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2[System.String,System.Int32].get_Item (System.String key) [0x00000] in <filename unknown>:0 at kOS.Safe.Compilation.ProgramBuilder.ReplaceLabels (System.Collections.Generic.List`1 program) [0x00000] in <filename unknown>:0 at kOS.Safe.Compilation.ProgramBuilder.BuildProgram () [0x00000] in <filename unknown>:0 at kOS.Safe.Execution.ProgramContext.AddObjectParts (IEnumerable`1 parts) [0x00000] in <filename unknown>:0 at kOS.Function.FunctionLoad.Execute (kOS.SharedObjects shared) [0x00000] in <filename unknown>:0 at kOS.Function.FunctionManager.CallFunction (System.String functionName) [0x00000] in <filename unknown>:0 at kOS.Safe.Execution.CPU.CallBuiltinFunction (System.String functionName) [0x00000] in <filename unknown>:0 at kOS.Safe.Compilation.OpcodeCall.StaticExecute (ICpu cpu, Boolean direct, System.Object destination, Boolean calledFromKOSDelegateCall) [0x00000] in <filename unknown>:0 at kOS.Safe.Compilation.OpcodeCall.Execute (ICpu cpu) [0x00000] in <filename unknown>:0 at kOS.Safe.Execution.CPU.ExecuteInstruction (IProgramContext context, Boolean doProfiling) [0x00000] in <filename unknown>:0 [LOG 13:51:15.735] Code Fragment File Line:Col IP label opcode operand ==== ====:=== ==== ================================ 1/startup.ks 20:17 0740 @0736 push 270 1/startup.ks 20:17 0741 @0737 call 674 1/startup.ks 20:17 0742 @0738 pop 0:0 0743 push 0 0:0 0744 return 0 deep 1/autonavinit.ks 17:1 0745 @0739 push $program-autonav* 1/autonavinit.ks 17:1 0746 @0740 exists 1/autonavinit.ks 17:1 0747 @0741 br.false +4 1/autonavinit.ks 17:1 0748 @0742 br.false +11 1/autonavinit.ks 17:1 0749 @0743 push 0 1/autonavinit.ks 17:1 0750 @0744 return 0 deep 1/autonavinit.ks 17:1 0751 @0745 pop 1/autonavinit.ks 17:1 0752 @0746 push $program-autonav* 1/autonavinit.ks 17:1 0753 @0747 push _KOSArgMarker_ 1/autonavinit.ks 17:1 0754 @0748 push autonav 1/autonavinit.ks 17:1 0755 @0749 push null 1/autonavinit.ks 17:1 0756 @0750 call load() <<--INSTRUCTION POINTER-- 1/autonavinit.ks 17:1 0757 @0751 pop 1/autonavinit.ks 17:1 0758 @0752 store 1/autonavinit.ks 17:1 0759 @0753 call $program-autonav* 1/autonavinit.ks 17:1 0760 @0754 pop 1/autonavinit.ks 17:1 0761 @0755 push 0 1/autonavinit.ks 17:1 0762 @0756 return 0 deep 1/autonavinit.ks 1:11 0763 @0757 push direct 1/autonavinit.ks 1:11 0764 @0758 swap 1/autonavinit.ks 1:11 0765 @0759 storelocal 1/autonavinit.ks 1:11 0766 @0760 argbottom 1/autonavinit.ks 2:1 0767 @0761 push $brakes 1/autonavinit.ks 2:8 0768 @0762 push True 1/autonavinit.ks 2:8 0769 @0763 store 1/autonavinit.ks 3:1 0770 @0764 push _KOSArgMarker_ 1/autonavinit.ks 3:11 0771 @0765 push 1 1/autonavinit.ks 3:11 0772 @0766 call switch() FOUND IT! In the function ReplaceLabels(), there's a variable var labels = new Dictionary<string, int>(); It's complaining because the string parameter is missing. Looking further down the code, there's an if statement that is not being met, and it doesn't have an "else": private void ReplaceLabels(List<Opcode> program) { var labels = new Dictionary<string, int>(); // get the index of every label for (int index = 0; index < program.Count; index++) { if (program[index].Label != string.Empty) { if (labels.ContainsKey(program[index].Label)) { if (program[index].Label.EndsWith("-default")) continue; // This is one of those "should never happen" errors that if it happens // it means kOS devs screwed up - so dump the partially relabeled program // to the log just to help in diagnosing the bug report that may happen: // Utilities.SafeHouse.Logger.LogError("=====Relabeled Program so far is: ========="); Utilities.SafeHouse.Logger.LogError(Utilities.Debug.GetCodeFragment(program)); throw new Exceptions.KOSCompileException(LineCol.Unknown(), string.Format( "ProgramBuilder.ReplaceLabels: Cannot add label {0}, label already exists. Opcode: {1}", program[index].Label, program[index].ToString())); } labels.Add(program[index].Label, index); } } You should have an "else" condition to "if (program[index].Label != string.Empty) { //stuff}" as well as "if(labels.containsKey(program[index].Label)){//More stuff} Lesson: If you have an IF(), always follow it with ELSE(). Edited July 6, 2016 by MAFman Link to comment Share on other sites More sharing options...
hvacengi Posted July 7, 2016 Share Posted July 7, 2016 On 7/3/2016 at 8:17 PM, MAFman said: Ok, here's the log file... I finally found it... (at least the part with the kOS error.) Well, I found the problem. I don't know why it's true, but `unlock all` doesn't appear to do anything, but it screws up function declaration. It literally compiles as a `NOP` opcode, which is essentially "don't do anything, just move to the next instruction". I'm pretty sure it was supposed to go away at the same time as `unset all`. That being said, it is still documented as working. If you simply exit the program, there is no need to make this call anyways, since all flight controls automatically unlock upon returning to the terminal. Basically, remove the one reference to `unlock all.` from inside the `stop` function, and you should compile. Oh, and never use it again! We'll have to update the docs, and kill it once and for all. Link to comment Share on other sites More sharing options...
hvacengi Posted July 7, 2016 Share Posted July 7, 2016 Odd, your post some how crossed mine... even though I refreshed before posting. Anyways, I'll respond to your comments, but my above post still applies. 4 hours ago, MAFman said: Found it! Also found the log line where the error happened... Apparently, it tried to get a key from System.Collections.Generic.Dictionary`2 and it didn't find it. What is the difference between Dictionary and Dictionary`2? Also, shouldn't the code try to access just System.Collections.Generic.Dictionary? Why is it saying AddObjectParts(IEnumerable`1 parts)[0x00000] in <filename unknown>:0 ? Especially the <filename unknown>? I'm guessing it should be "in <autonav>:0" or something. This is a result of the use of Generics. Essentially C# does some fancy things to dynamically create the type definition for the dictionary based on the Type data that was passed to it. So our code accesses a `Dictionary<string, int>` which the compiler then defines as `System.Collections.Generic.Dictionary`2` 4 hours ago, MAFman said: FOUND IT! In the function ReplaceLabels(), there's a variable [...] It's complaining because the string parameter is missing. Looking further down the code, there's an if statement that is not being met, and it doesn't have an "else": Actually, I added some debugging statements and this is not the section of code that throws the error. The applicable code is here: https://github.com/KSP-KOS/KOS/blob/develop/src/kOS.Safe/Compilation/ProgramBuilder.cs#L235 You'll notice that the code section you cited is actually protected by checking for an empty string before using it as a key, and it checks the dictionary to make sure it contains the key before attempting to use it. The line I cited has no such protection, and can only be triggered in very rare circumstances (like using `unlock all.` with functions). I almost added a better error message here about 6 months back, but got busy working on other things including fixing another bug that was causing this same message. 4 hours ago, MAFman said: You should have an "else" condition to "if (program[index].Label != string.Empty) { //stuff}" as well as "if(labels.containsKey(program[index].Label)){//More stuff} Lesson: If you have an IF(), always follow it with ELSE(). Since this if condition isn't the problem, an else won't fix it. More importantly, an if statement does not always need an else. In our particular instance, we have an implicit else: "if this condition is true, continue to the next loop." which will skip the section of code that follows "throw an error". Because "continue" skips the rest of the loop, it's the same as saying "if this condition is true, continue to the next loop, else throw an error". And there are plenty of practical times where no else condition is required at all. "create a new variable x equal to 1, if the current time is after noon, set x equal to 2" is perfectly valid. I wanted to take a moment to point this out specifically because kOS tends to attract, and focus on, new programmers. I don't want to have a bunch of people now think that they absolutely need an else for every if. I'm gonna find a whole lot of user scripts that read `if true { doSomething(). } else { doNothing() }`. I appreciate that you were walking through our code, and thought you found the error, but speaking in general absolutes can often be taken out of context and confuse others. Link to comment Share on other sites More sharing options...
Dunbaratu Posted July 7, 2016 Share Posted July 7, 2016 (edited) Twitch devs show kOS v1.0.0 UTC time 2016-07-08 21:00 (Friday) Stream Channel: https://www.twitch.tv/dunbaratu With kOS v1.0.0 coming up Real Soon Now (tm), we decided to do a stream on Twitch of new things, with an eye toward Q&A about it. Come along and see what important things are changing and have a chance to ask about it. We intend this to be timed very close to the release of kOS v1.0.0. The release might go out just a few hours before, or just a few hours after, the stream itself. In any case the release is expected to be roughly co-incident with the stream. Unlike the release, for the stream we figured it was more important to announce a predictable time ahead of time (thus this message) because it's live interaction. With the actual release, well, it comes out whenever we happen to have gotten all the last pieces in place (changelogs, documentation updates, etc). This is in no way a binding promise to get the release out at the expected time!! Who knows what might be found in those last few hours of work before it goes out. It could be something that is a showstopper. We'd LIKE to get it out at the same time as the stream. We don't PROMISE to do so however. The stream will be broadcast here: https://www.twitch.tv/dunbaratu And include at least 2 of the devs on microphone: Dunbaratu (Also known as Steven Mading here on the forums, AKA "me") Hvacengi The duration is unknown. It depends on questions and interaction. Edited July 7, 2016 by Steven Mading Just removed the math entirely. The title says 21:00 UTC, that should be enough. Link to comment Share on other sites More sharing options...
meyerweb Posted July 7, 2016 Share Posted July 7, 2016 13 minutes ago, Steven Mading said: For reference, 21:00 UTC-5 Friday is: - Berlin: 11pm - UK: 10pm - New York: 6pm - Los Angeles: 3pm - Sydney: Saturday 8pm Something’s off with at least the American times listed: 2100 UTC can’t be 1800 NYC, as that’s only a three-hour difference. Currently NYC is UTC-0400 (and it’s UTC-0500 in winter), so if this really is happening 2100 UTC tomorrow, it will be at 5pm New York time. LA is similarly off, more likely 2pm than 3pm. Not sure about the rest. Link to comment Share on other sites More sharing options...
dewin Posted July 7, 2016 Share Posted July 7, 2016 2 minutes ago, meyerweb said: Something’s off with at least the American times listed: 2100 UTC can’t be 1800 NYC, as that’s only a three-hour difference. Currently NYC is UTC-0400 (and it’s UTC-0500 in winter), so if this really is happening 2100 UTC tomorrow, it will be at 5pm New York time. LA is similarly off, more likely 2pm than 3pm. Not sure about the rest. The indicated time was UTC-5, not UTC. That said, if the actual time zone is Eastern Daylight Time (Eastern Standard Time is UTC-5), the US times are correct as listed and the other timezones are possibly off. If EDT isn't the origin time zone, then we'll have to wait for @Steven Madingto correct us Link to comment Share on other sites More sharing options...
meyerweb Posted July 7, 2016 Share Posted July 7, 2016 1 minute ago, dewin said: The indicated time was UTC-5, not UTC. That said, if the actual time zone is Eastern Daylight Time (Eastern Standard Time is UTC-5), the US times are correct as listed and the other timezones are possibly off. If EDT isn't the origin time zone, then we'll have to wait for @Steven Madingto correct us No, that doesn’t work either. 2100 UTC-5 would be 10pm NYC time, because UTC-5 is currently the US Central time zone, one hour behind NYC. Even if they meant the Eastern US time zone under DST, as it presently is, 2100 is still 9pm, not 5pm. Further, the top-of-post time given is 2100 UTC, not 2100 UTC-5. Link to comment Share on other sites More sharing options...
dewin Posted July 7, 2016 Share Posted July 7, 2016 That'll teach me to not read the entire post before replying. Yeah. It's just plain wrong Link to comment Share on other sites More sharing options...
kcs123 Posted July 7, 2016 Share Posted July 7, 2016 I might not be able watch live stream, but I would appretiate if you cover some of stuff in it: Dmagic science part support IR part sequencer support (with respect to latest available changes in IR mod) gamebalance changes - power consuption vs IPU, earler/later kOS parts reintroduction of LaserDist mod, some folks might be even forget that it exist, it can be combined with IR parts if possible fine tune PID for built in STEER command (not to be confused with custom PIDloop and raw pilot input) Besides that, whatever is new/changed from last version of kOS. Also, Steven always have some nice math methods to show how things were done, like how slope is calculated that more falls into general math category, rather than kOS programming itself. Some of things I never learned trough formal education and for some there is never real life purpose for using it until there is need for it in KSP. A link for recorded stream will be appreciated too, don't be discouraged if there was not many watchers on live stream, plenty of kOS users are scatered trough various time zones. Link to comment Share on other sites More sharing options...
dewin Posted July 7, 2016 Share Posted July 7, 2016 One of the new kOS features is proper support for external addons, in that other addons can now add structures that you can access from your kOS scripts. This means that rather than waiting for kOS to provide support for a mod, it is now possible for a mod to provide support for kOS (or a third mod that supports both). I'm actually working on a mod that takes advantage of this, with the primary goal of talking between kOS and KRPC. (Though it will probably include communication between kOS Processors as a freebie, and that portion doesn't require KRPC). Link to comment Share on other sites More sharing options...
hvacengi Posted July 7, 2016 Share Posted July 7, 2016 2 minutes ago, dewin said: will probably include communication between kOS Processors as a freebie Inter-processor and inter-vessel communication is included as part of this next release. I'm sorry that I haven't had any opportunity yet to look at your mod and see if I have any useful comments or pointers, but I do mean to do that soon. I also have a sample addon prepared that I intend to make available so that other modders can see the recommended workflow. I just need to add a simple reflection interface so that people won't have to dig through the really complicated IR or RT addons to understand how to use reflection to access an api. 18 minutes ago, kcs123 said: I might not be able watch live stream, but I would appretiate if you cover some of stuff in it: Most of those items are not specific to v1.0.0. While we're happy to discuss them, the new features will be the main focus of the stream. If we don't have few enough questions that we can kind of pick a direction, we'll definitely keep that list in mind though. If we don't get to it, Stephen tries to stream regularly so ping us with a reminder and I'm sure that he can find a way to fit it into one of his other streams. 59 minutes ago, meyerweb said: Something’s off with at least the American times listed: 2100 UTC can’t be 1800 NYC, as that’s only a three-hour difference. Currently NYC is UTC-0400 (and it’s UTC-0500 in winter), so if this really is happening 2100 UTC tomorrow, it will be at 5pm New York time. LA is similarly off, more likely 2pm than 3pm. Not sure about the rest. I'm scheduled for 5PM (17:00) EDT (UTC-4, local time for me), 4PM (16:00) CDT (UTC-5, local to Stephen), 9PM (21:00) UTC. Feel free to extrapolate the other time zones from that. I'll ping him in chat to update it. Link to comment Share on other sites More sharing options...
Dunbaratu Posted July 7, 2016 Share Posted July 7, 2016 (edited) 2 hours ago, meyerweb said: Something’s off with at least the American times listed: 2100 UTC can’t be 1800 NYC, as that’s only a three-hour difference. Currently NYC is UTC-0400 (and it’s UTC-0500 in winter), so if this really is happening 2100 UTC tomorrow, it will be at 5pm New York time. LA is similarly off, more likely 2pm than 3pm. Not sure about the rest. What's off is that I originally typed in my time in my local time zone as 16:00 UTC-5, then decided it was better to just post the UTC time, so I converted it to 21:00 for UTC, but then neglected to change the label from "UTC-5" to just "UTC". Add to that the fact when I composed the message yesterday and saved it as draft, I was planning on a different start time and when I changed the start time to the one I went with in the end, I didn't edit all the cities' times to match that edit. In the end it was an inconsistent mess. What I meant was this: I live in UTC-5, my local time is going to be 16:00 when I stream. That will be 21:00 in UTC+0. I've edited and corrected the post now. Thanks for catching it. Edited July 7, 2016 by Steven Mading Link to comment Share on other sites More sharing options...
Dunbaratu Posted July 7, 2016 Share Posted July 7, 2016 1 hour ago, kcs123 said: there is never real life purpose for using it until there is need for it in KSP. A link for recorded stream will be appreciated too, don't be discouraged if there was not many watchers on live stream, plenty of kOS users are scatered trough various time zones. For this reason I plan to not have the background music I usually have when I stream. I want the recorded video to be un-muted for people who have to watch it later. Link to comment Share on other sites More sharing options...
dewin Posted July 7, 2016 Share Posted July 7, 2016 1 hour ago, hvacengi said: Inter-processor and inter-vessel communication is included as part of this next release. I'm sorry that I haven't had any opportunity yet to look at your mod and see if I have any useful comments or pointers, but I do mean to do that soon. Heh, looking through my mod probably won't find much at this point anyways as it's not really at a functional level yet It'll be interesting to look at your inter-(processor,vessel) communication bits though; it might change how I approach the kRPC bridge -- particularly if I can just treat kRPC clients as a 'virtual' vessel of sorts rather than everything else that I'm doing. Some key differences I'm seeing poking at the github docs: I'm using a different mechanism for serialization than kOS's inbuilt one, so there are different restrictions on what constitutes a valid message. (Notable: Mine uses something like {"type": "vessel", "data": "vesselguid"} as its mechanism for representing everything except primitives, and can properly handle things like a particular list being referenced in multiple places (or referencing itself). The output is generally more compact than kOS's format) Parts are serializable in my implementation. I don't implement actual message queues to keep things simple and avoid 'leaked' messages in the case of a kRPC client never checking for them. Instead, a given processor has at most one inbound and one outbound message and mechanisms for atomically setting either field. A given processor can both "send" (setting its outbound message) and "send to" (setting another processor's inbound message), the two are separate queues. The kRPC side has no inbound/outbound message -- it communicates by examining the outbound field of other processors or setting their inbound fields. RT is ignored completely, but this is true for kRPC in general. In-game-wise, this can be explained as kRPC being additional processing power on the same vessel -- though one could totally "cheat" at remotetech with this (kOS from one ship -> kRPC -> kOS to ship far away/out of communications range with no latency). Now that I think about it more, I might just stash my current code somewhere and start from sort-of-scratch using the kOS API, focusing solely on the kRPC bridge (which was my original intent). I knew that inter-vessel/processor communication was on the kOS roadmap but had no idea it was going to be in this release. Oh, one convenience feature I'm seeing missing from the current kOS implementation: My implementation had a notion of a message ID or count of received/sent messages or whatnot -- mainly so that messages can be processed in the background(ish) by doing something like: ON something:messagerxcount { // changes every time we receive a new message. handleMessage(); } The only way I see to do that in the current implementation is to do ON messagequeue:length, but there's a lot of complexities in that particular case. (Also, a count of "packets" tx/rx would be neat anyways). Though now I almost wonder if a future version of kOS should have a proper event system. As I understand ON, it's examining an output every update and firing when it changes -- as opposed to a more passive "sleep until I'm awoken, event X wakes me up" system. Link to comment Share on other sites More sharing options...
seamus2849 Posted July 8, 2016 Share Posted July 8, 2016 Looking for some help as I am trying to write some ascent and plane-change scripts. What I want is for the craft to burn until the apoapsis is located directly above the equator. I have been doing some basic research, but I am brand new to KoS and computer language in general and having some tough times. Here is what I have been trying: //First I tried the general POSITIONAT(SHIP, APOAPSIS), but then saw a negative return on the Y, //so I tried to minus the SHIP:BODY:POSITION to get a good value, but then realized the Y value it returned was not a readout of the latitude //I then tried this, but again, to no avail SET varname TO POSITIONAT(SHIP, APOAPSIS) - SHIP:BODY:POSITION. WAIT UNTIL varname:Y < 1000. LOCK THROTTLE TO .2. WAIT UNTIL varname:Y < 100. LOCK THROTTLE TO 0. Does anyone know a better way of telling KoS what my future latitude will be at Apoapsis? (while burning) Link to comment Share on other sites More sharing options...
dewin Posted July 8, 2016 Share Posted July 8, 2016 (edited) 12 minutes ago, seamus2849 said: Does anyone know a better way of telling KoS what my future latitude will be at Apoapsis? (while burning) Since KSP doesn't have axial tilt, latitude is (IIRC): ARCSIN(position:y / position:mag) where position is your relative position to the planet. (If the magnitude of your position somehow is 0, latitude is technically undefined and you have bigger problems.) Latitude for a given true anomaly value is: ARCSIN(SIN(trueanomaly + argumentofperiapsis) * SIN(inclination)) True anomaly at periapsis is 0, at apoapsis is 180. Thus, you can do ARCSIN(SIN(180 + argumentofperiapsis) * SIN(inclination)) to get latitude at apoapsis without even needing to use POSITIONAT. Edited July 8, 2016 by dewin Link to comment Share on other sites More sharing options...
seamus2849 Posted July 8, 2016 Share Posted July 8, 2016 37 minutes ago, dewin said: Since KSP doesn't have axial tilt, latitude is (IIRC): ARCSIN(position:y / position:mag) where position is your relative position to the planet. (If the magnitude of your position somehow is 0, latitude is technically undefined and you have bigger problems.) Latitude for a given true anomaly value is: ARCSIN(SIN(trueanomaly + argumentofperiapsis) * SIN(inclination)) True anomaly at periapsis is 0, at apoapsis is 180. Thus, you can do ARCSIN(SIN(180 + argumentofperiapsis) * SIN(inclination)) to get latitude at apoapsis without even needing to use POSITIONAT. Thanks for the quick post and great math! I plugged that in and the Quote ARCSIN(SIN(trueanomaly + argumentofperiapsis) * SIN(inclination)) does provide a reading of my vessel current latitude, but I have to add "ship:orbit:" in front of the argumentofperiapsis and inclination in order to get a readout. Am I doing it wrong still? Link to comment Share on other sites More sharing options...
dewin Posted July 8, 2016 Share Posted July 8, 2016 Nope! I was using descriptive variables, not quite actual kOS code, and completely meant it as "replace this value with your current (or desired) true anomaly, this value with your argument of periapsis, etc.) You may want to use ship:obt:trueanomaly and ship:obt:inclination for consistency, or just use obt:* in all 3 cases (the 'ship:' is optional). Also, two months ago I didn't know any of the math either. I'm particularly proud of the latitude-at-anomaly function though -- other orbital formulae I found or derived from well-known published equations/etc somewhere, but I managed to figure out latitude entirely on my own. It's deprecated and undocumented, but some of my stuff is here -- mostly focused on orbital math. (lib_obt has the newest versions after i dropped the "create my own representation of an orbit" bits) https://github.com/dewiniaid/ksp-kos-scripts/commits/master Link to comment Share on other sites More sharing options...
CoriW Posted July 9, 2016 Share Posted July 9, 2016 (edited) Hello, does anyone know how I'd go about getting the compass heading of my prograde vector? EDIT: Never mind, I found this Reddit post regarding how to do this. https://www.reddit.com/r/Kos/comments/4mkqn9/vector_heading/ Edited July 9, 2016 by CoriW Link to comment Share on other sites More sharing options...
Recommended Posts