Jump to content

Dunbaratu

Members
  • Posts

    3,857
  • Joined

  • Last visited

Everything posted by Dunbaratu

  1. I noticed in your screenshot that Kerbin looks like Earth, with the camera aimed at Indonesia. Which mod are you using that does this? I'd heard people had had all sorts of problems getting RSS to work with kOS.
  2. I almost thought I understood what you meant until I got to the phrase "then go back to the first ON AG1" - I have no idea what you mean by that. If I understand what you were talking about earlier, you have a routine that does two robotic footsteps. You want it to do that each time a user hits AG1, then wait for the user to hit AG1 again before it takes another two steps. Is this correct? Or did you want it to continue taking two steps over and over until AG1 is hit again to stop it? The main trick you have to realize is that triggers like ON and WHEN are not supposed to contain long running loops. This is because they run all the way to the end before kOS finishes its animation frame update, and the entire KSP universe is frozen in place until they finish. Thus you can't really do any piloting or controlling in loops with them, because the universe won't react to your control inputs until you finish the body of the ON or WHEN and allow the KSP animation to resume. This is not intuitively obvious from the language definition, and furthermore it is a change from the way it used to be implemented back when Kevin designed the system. If you got your information from the out of date Wiki it probably won't mention this because back in version 0.9 it wasn't the case yet. I've implemented a new error check that catches it when you try to run long-lasting code inside a trigger, but it's not going to be released for a while. Contrast that with main body code. In main body code, the CPU only runs as much of your code as it thinks it's prudent to run within one animation frame of KSP, and then pauses your script program, lets the rest of KSP, and all the other KSP mods, do their update work for that frame of animation, and on the next animation frame, it continues your program where it left off - so long running loops are safe in the main body of the code, but not in ON or WHEN. So what you can do is run the main loop in the main body of the code, but use triggers like On and WHEN to just fiddle with variable settings to affect what will happen in the main body. The first example program below does this. For these two examples, replace the word TAKE_TWO_STEPS with whatever the lines of code are that you've written that you said takes two steps with your rover. // This is a version where AG1 is supposed to just take two steps once, and you have to keep hitting AG1 again and again // to keep taking steps over and over: SET doSteps to false. ON AG1 { SET doSteps to true. PRESERVE. // Causes the ON statement to remain in place for next time. // (The default is that ON and WHEN will only trigger once and then delete // themselves, unless you explicitly tell them not to with this keyword.). }. SET done to false. UNTIL done { if doSteps { TAKE_TWO_STEPS. SET doSteps to False. // will not trigger again until AG1 hit again. }. }. // Note, I didn't set done to true anywhere. This is an infinite loop // until you decide how you want it to end, and implement it by // doing a SET DONE TO TRUE somewhere. // This is a version where the rover is supposed to continue walking continually // as long as AG1 is on. When AG1 is toggled again to off, the rover stops // until AG1 is hit again: SET done to false. UNTIL done { if AG1 { // The first time you hit 1, AG1 becomes True. Hit it again and it becomes false (and the walking stops). TAKE_TWO_STEPS. }. }. // Note, I didn't set done to true anywhere. This is an infinite loop // until you decide how you want it to end, and implement it by // doing a SET DONE TO TRUE somewhere.
  3. Furthermore, this is what the ON trigger is designed to do, and was made that way specifically because of the way action group booleans work (which is the way they're implemented in KSP itself). You might have wondered why there even is an ON statement, given that you can write "WHEN AG1=TRUE THEN...". The reason is that ON triggers on any CHANGE TO the boolean variable it mentions: from false to true or from true to false. ON AG1 { dostuff. } is the same as: set previous_AG1 to AG1. WHEN AG1 <> previous_AG1 THEN { set previous_AG1 to AG1. dostuff. }. But without you having to mess about with tracking previous_AG1 yourself. The ON command does that tracking internally for you.
  4. I've often thought that a neat feature might be to create a "space center mainframe" kOS CPU that lives inside one of the ground buildings, conceptually, who's "local drive" is the archive. You could use it to run kOS code, so long as that kOS code doesn't do anything that requires ship-based information like your velocity, your current fuel, etc, because the CPU wouldn't be associated with a vessel. This would let you do things like write code that tries to calculate a good launch window for you, and tells you the date/time that you should probably launch your mission if your goal is to get to planet so-and-so. It would also let you use the infinite storage to run something too complex for the remote probe, and just transmit the final answer to the remote probe. It always seemed a bit silly to me that the way kOS is working now, you'd have to first put your vessel on the launchpad, then run the code to find the launch window, then wait for several months with the vessel on the launchpad, then launch it. A real space program would be doing those calculations on a ground-based computer first in order to learn when to put the vessel on the launchpad. The only reason this isn't done yet (well, besides kOS being a neat huge project with a "would be nice" list a mile long already) is that so much of how the system works is built on the assumption that all cpu's are contained in a KSP part, which is contained in a KSP vessel. If you tried to run code that said, for example, "PRINT SHIP:VELOCITY" on a kOS CPU that isn't ON a ship, I suspect it wouldn't just give a nice error message, but would crash the Csharp code because it presumes there will always be a SHIP no matter what. Trying to divorce the system from that assumption would be a lot of work and there's bigger problems to tackle right now. But it is something for the future I'd like to see "some day". As a stopgap, I've considered building a rover vessel that has a kOS CPU on it and an antenna array, launching it at KSP, and just driving it over to the buildings and parking it there and leaving it for the rest of my campaign. Then it could be my "ground" mainframe, and could participate in remoteTech transmissions and the like, and it would be close enough to KSC that it would always be in range of the archive.
  5. At the moment, no. Because an unset target has value NULL, and kOS doesn't have a way to check against whether or not something is NULL, which is a hole in the language I'd like to see fixed. Temp fix for now: explicitly state that the arguments are floating point, like so: 10.0 ^ -1.0 The problem is that when both operands are integer, it's assuming the output should be integer, and thus rounding. You're getting 0 because it's rounding the value of 0.1 down. long term fix - I'd like to change all math operations so they find out whether the result will be a round number or not, and then decide whether to return it as an integer or floating point based on that, rather than based on the input operands' types. This is an area of the code I haven't touched much and the person who has has been very busy and out of contact for a while, making me reluctant to stick my hands in his code and change everything without buy-in from him.
  6. This is happening because every position and distance is measured from the center of mass of the vessel containing the kOS part. When you ask "what is my altitude?" that immediately raises the question, "do you mean the altitude of your landing legs? The altitude of your control capsule?..." kOS always picks the center of mass of the ship, because that's what the native KSP system uses. Rather than call that a problem, I think it's fine that it does this, and the real problem is that you don't have a way to detect "what is the shape and size of this vessel?" The real fix isn't to change how altitude is reported, but to give you the ability to query "How many meters away from the center of mass is the bottom of my ship?" Right now that can't be done, but work is being done on features that would let you do that (mainly the ability to get the position and orientation of each part individually). Other users have reported this problem lately and we've discovered that it's not a bug in kOS but rather it's a weird buggy behavior in KSP itself that kOS is exposing you to in ways the manual flying interface tends to hide. What seems to be happening is that your animation frame rate takes a sliver of time, and KSP refuses to burn fuel if the fuel won't last the entire duration of that animation frame. So hypothetically if you have a choppy framerate of say 10 frames/sec, and the remaining tiny last drops of fuel, at the current throttle setting, would only last for, say, 1/20th of a second, then KSP flames out the engine now, since there's not enough fuel to last one whole animation frame. Thus the last fuel never gets consumed. You don't notice it when flying manually because values tend to be displayed rounded off so much that the little sliver of fuel gets hidden from sight. Therefore, a more reliable check for whether an engine is starved is to query the engine's :FLAMEOUT boolean value. It will return TRUE when the fuel is in that scenario where there's fuel for the engine, but not enough to last an entire animation frame. I've never been happy with the way the code size is counted. Basically, these two programs have different source code size, but are identical after being compiled: // This is a one-line program with // a lot of verbose comments, // and it uses long variable names and // a lot of indenting spaces: DECLARE PARAMETER this_is_my_long_variable_name PRINT "val squared is " + this_is_my_long_variable_name ^ 2. DECLARE PARAMETER x. PRINT "val squared is "+x^2. Once they're compiled, they're the same size. It's rather annoying to have to "pay" for writing good variable names and using readable indentation. Given that kOS actually compiles your script code to a pseudo-bytecode machine language in its head when you issue the RUN command, I've been contemplating the notion of letting users actually store pre-compiled "object code" files on the craft's local volume and running from them instead of from the full source files.
  7. Replying to myself here: I should warn people that as this gets implemented it might appear to "slow down" some existing scripts a bit, but that would be because it's now going to be counting the triggers like LOCK and WHEN statements toward the 100 instructions per update limit. In the past what you got was 100 instructions per Update, PLUS ALSO whatever your WHEN and LOCK and ON statements were doing, which wasn't being tracked as part of that 100. The new design will make the program behave much more predictably, in terms of how many milliseconds of runtime it steals from KSP itself being mostly the same no matter how you wrote your code, and I might raise CONFIG:IPU to a bigger default to handle the fact that it would now be counting everything.
  8. Your technique is correct. If SHIP:ALTITUDE > ALT:RADAR, then you have ground terrain under you, else you are over water. To detect if you are landed, try using STATUS instead and check for if its value is either "LANDED" or "SPLASHED". What you're doing with the flags is fine. The error must come from somewhere else. No, that cannot be the cause of a NaN error. You don't get NaN for throttle values out of range. Instead for throttle values out of range, kOS just sets the real throttle to max or min. (if you say THROTTLE is 2, the actual throttle you'll get just caps out at 1 instead.) NaN, meaning "Not a Number", is an acronym for how computers store the fact that a calculated value cannot be properly represented in real numbers. The floating point numbers kOS uses (and most computer programs use) are only capable of storing Real Numbers. If you try to calculate the square root of a negative number, for example, the computer can't store the result because the native number type doesn't do imaginary numbers. (There are more messy homebrewed number types that can do complex math, but the native low-level numbers computers use can't.) Another place where you might get NaN is when using a math function call where you passed in an invalid input that's outside the range of values it can give an answer for. For example, there is no such thing as the arccos(1.001), because there's no angle at which the cosine of that angle is higher than 1. If you try to call arccos(1.001), you'll get a result of NaN. Look elsewhere in your code for either taking roots of negative numbers, or using inverse trig passing in values outside the range [-1,1]. It's probably one of those two things. Incedentally, this sort of problem ("where is this runtime error coming from?") should get easier in the future, I hope. I spent the last few days working on an update to kOS that will have it trace backward from the compiled code to the original script source code line from which runtime errors happened. If it's approved and works, it would let you see "oh, THAT's the math operation where it generated a NaN, right there, on line 15, column 24." At first glance this logic looks okay to me. Have you tried inserting print statements at the top of the loop to verify that all the relevant variable values are what you think they are? Usually if I have an if clause that should be triggering, but isn't, I diagnose it by inserting a print statement just before the if check that prints out the value of all the variables the conditional expression is using, so I can see if it's really using the values I think it is. By not using WHEN statements? Asynchronous flow, where you are interrupting the normal program flow by inserting a diversion into the WHEN clause before continuing with the rest of the mainline code is the *sole purpose* of a WHEN statement. That is simply not true. When the WHEN statement is finished, control should pick up where it left off in the main code, and that means continuing right where it left off in the middle of the UNTIL loop. It would only abort the loop if your WHEN block altered one of the variables that the UNTIL loop is using as its conditional check so the check's boolean value changes, but then that's correct behavior if it does that. What you might be expriencing is that flow won't continue until the WHEN statement is finished. THAT is true, but it's not what you said. (You claimed it would never resume the original statement and that's false. It will - but only when the WHEN statement is finished. You shouldn't be putting loops that are meant to run in the background in a WHEN. WHEN clauses should be designed to flow through fast and finish to the bottom.) This is especially true because WHEN doesn't just interrupt the flow of your program. It actually interrupts the flow of the entire KSP simulation itself. If you put an infinite loop in your WHEN clause, it won't just stop your program - it will freeze-frame all of KSP and require killing and restarting KSP. (All mods are allowed to register an updater function that gets called once per animation frame by Unity. But the process of iterating over all the registered updater functions and calling all of them is single-threaded and therefore any misbehaving mod can freeze ALL the updates for the whole game if it never finishes its own update call.) The WHEN clause allows users to write programs that can do this, because unlike with the rest of the program flow, WHEN is designed to run its flow all the way to the bottom before finishing the update (while the mainline code just runs 100 or so instructions and then waits for the next update to continue, the WHEN code runs all the way through to the bottom and is supposed to finish in a single animation update.) One of the issues on the issues tracker is to make it explicitly notice when a WHEN clause is taking too long, and abort it with an error message telling the user what's going on and why and how they have to redesign their code. (edit: If your program logic is one in which you'd LIKE to have a WHEN clause that behaves a bit like a background loop, I recommend looking into the PRESERVE keyword in the docs. It keeps the WHEN trigger around after it finishes, making it possible for it to get called again in the next update, and the next, and the next. This can make a sort of loop out of the WHEN clause, but its one that executes exactly one iteration per animation frame.)
  9. Hmm... I wonder if those 30 days would be enough to learn how to create an assets file, stick a font into it, export it, and then use it from then on, never having to run Unity Pro ever again.
  10. For current orbit your ship is drifting on: SHIP:ORBIT (i.e. SHIP:ORBIT:PERIOD). For the orbit that will start after a manuever node is executed, assuming it gets executed exactly as planned: SET mynode to NODE( time:seconds + 120, 0, 0, 100 ). ADD mynode. print "After upcoming burn, period will be " + mynode:ORBIT:PERIOD.
  11. @madlemur, can you tell us what the acronyms "Q" and "AoA" are? I'm guessing AoA might be Angle of Attack? In which case, you can already get the SHIP:VELOCITY:SURFACE which is the way you're going, and you can get vectors pointing in the ship-relative axes with (SHIP:FACING*V(1,0,0)), (SHIP:FACING*V(0,1,0), and (SHIP:FACING*V(0,0,1)). Putting all that together with some dot product math it should be possible to obtain your angle of attack, even in kerboscript today. (Basically, take the component of the velocity that is in your ship's "top" facing direction, by dot-producting with one of those 3 axis vectors (I forgot which one is "top" in the SPH-built ships). It will tell you how much your velocity is going upward or downward relative to your facing. Then to transform that into an angle, get the arcsin() of the triangle in which the vertical leg is the vertical velocity component you created, and the hypotenuse is the length of SHIP:VELOCITY:SURFACE.) This is all doable today in a single expression in kOS without any changes behind the scenes. For example, it might look something like this: LOCK AoA TO arcsin( VDOT(SHIP:FACING*V(0,1,0),SHIP:VELOCITY:SURFACE) / SHIP:VELOCITY:SURFACE:MAG ). (Although I may have the V(0,1,0) wrong and it's actually V(1,0,0) or V(0,0,1) depending on which way the axes go for spaceplane hangar ships.)
  12. There is a UnityEngine.DLL that comes packaged with KSP itself that you're supposed to use. It's under (I think - this is from memory because I'm not on my Windows machine at the moment) KSP_Data/Managed/ (or KSP_Data_x64). The only time you care about the version of unity beyond just "use the one KSP ships with" is when you want to run Unity yourself in order to do things like make meshes and parts. For that information, look at the start of the ouput_log.txt that KSP spits out whenever it runs. It begins with a dump of the Unity Version number.
  13. If you find a way to do it, please let me know because I want to do the same thing - I want to use a built-in Unity TextArea widget, but have it showing a monospace font, and all of the fonts KSP includes are proportional.
  14. It's still not there by default but it is easy to simulate the delay - just google the speed of light in meters per second, and multiply it by Kerbin:Distance to get the number of seconds a signal should take to make a one-way trip between home and the craft. If you want to simulate that you need a two-way communication, then wait twice as long as that. This is *supposed* to be supported, but I'm not sure it's really working well. The entire load/save system needs looking at at some point.
  15. The problem is that Resource.Load searches a path of locations to look for resources, and you can't change this path to include more directories than SQUAD decided to include. SQUAD decided to look for some types of resources (textures and meshes) by looking through everything in GameData, but not other types of resources (fonts). So the problem is that your TTF font file isn't in the search pattern SQUAD set up, and you're not allowed to alter that search pattern. The only solution that might work, or so I've heard, is to build your own assets file and put the font into it. But the problem with this is that to export an assets file from Unity requires the very expensive full-on developer version of Unity, not the freebie play-around version of Unity, so most of us modders can't do it. (And If I'm going to fork over that much money, I want an assurance that it would fix the problem before I do so. I don't want to fork over the money as an *expeirment* to find out if it would work, and then find out that it doesn't.
  16. There's a current bug report for kOS about getting terminal velocity wrong when FAR is installed. kOS still tries using the stock game's terminal velocity, and the way FAR was implemented it doesn't alter the built-in stock values the API returns to all the other mods, but rather it creates a whole new API on the side that other mods have to call instead of the stock API calls. I strongly dislike this approach, since if more mods adopted that approach, it would render the task of making mods compatible with other mods into an enormous task with something on the order of O(n!) special cases in mod code (n being the number of mods that exist that use this type of design that renders the existing stock API incorrect). It seems quite anti-object-oriented design to expose a different API depending on what's present, instead of masking your special exception case behind the same universal API that everyone uses. If you want to work on FAR integration in kOS, I don't think it's already there. I think it's an area that's open to being fixed.
  17. It's trying to say "this is an orbit of ...." where the "...." turns out to be the maneuver node rather than the vessel. And maneuver nodes don't have names so it doesn't have anything to print there.
  18. The velocity of the vessel will be a vector, rather than a scalar, making the meaning of "negative direction" sort of meaningless. It's more like "velocity in this 3-D direction." To get the surface-relative velocity instead of the orbit-relative velocity, use Vessel.GetSrfVelocity(). To get a unit vector pointing in the direction the vessel is pointed, do one of these two things: roverFrontUnit = Vessel.GetTransform().rotation * V(0,0,1) // Gives a unit vector pointing "up to the nosecone" of a rocket built in the VAB. roverFrontUnit = Vessel.GetTransform().rotation * V(1,0,0) // Gives a unit vector pointing "ahead to the front" of a vehicle built in the SPH. Which way is correct depends on which way you built the rover orientation. (This is from my memory and I might have it wrong which unit vector to start from. It might be the Y axis not the X axis. Please experiment and try). Once you have such a unit vector, you can dot-product the vector with the surface velocity to get the component of the surface velocity that is aimed forward (positive number) or backward (negative number).
  19. If you are NOT going to execute any manuever nodes and are already on a path drifting toward an encounter, it works like so: Each Orbit has a suffix called PATCHES which is a LIST of all the follow-on ORBITs that represent the next patches of orbit after the current one. For example, if you are currently in an orbit of Kerbin, which will pass through Mun'a SOI on a gravity slingshot, back into Kerbin's SOI, and then escape Kerbin's SOI into the Sun's SOI, then you'd have a data structure like this: SHIP:Orbit describes your current orbit patch in Kerbin. SET futurePatches to SHIP:Orbit:Patches makes a LIST of the orbits you'll transition into later, in which: futurePatches[0] describes the Mun orbit patch of your flyby gravity slingshot (and therefore its :PERIAPSIS will be the closest approach to the Mun) futurePatches[1] describes the Kerbin orbit patch after the flyby of the mun, in which you are on an escape trajectory out of Kerbin's SOI. futurePatches[2] describes the Sun orbit after you leave Kerbin's SOI. Now, what about when you have a manuever node? When you have a maneuver node, it will have a suffix called :ORBIT, which is the predicted orbit patch that begins just after the maneuver node burn will have occured, assuming you somehow managed to execute the maneuver node as predicted with perfect precision. This Manuever node's :ORBIT is just like any other Orbit, in that it too will have a :PATCHES suffix that you can use to see its future transitions.
  20. Both the page about Directions (like R(a,b,c) ) and Vectors (like V(a,b,c)) have links to a page describing the coordinate system of KSP: http://ksp-kos.github.io/KOS_DOC/ref_frame/index.html This is messy behavior inherited from the main base game. The actual coordinate system of KSP itself doesn't really stay put in a rational way, owing to all the weird tricks they did for optimizations. Lock steering to R(0,0,-90) is a case of gimbol lock, I think, given the messy way things work in Unity (where the rotations occur in a very strange order, I think it was Around Z, then Around X then Around Y, if I remember correctly, thus making controlling the roll actually quite hard to do). At any rate, the rotations expressed in R(a,b,c) are, sadly, based on KSP's native system, not the craft. You're not rolling around the CRAFT's Z axis when you put a value in the 3rd argument to R(). You're rolling around the Universe's Z axis, which sadly keeps moving so I can't give a straight answer what it means all the time. The easiest way I've found to deal with the mess if you want to think in axes rotated with the ship's current facing, is this: lock shipx to ship:facing * V(1,0,0). lock shipy to ship:facing * V(0,1,0). lock shipz to ship:facing * V(0,0,1). From now on the unit vectors shipx, shipy, and shipz are unit vectors expressed in KSP's messy native coordinate orientation, but they are describing the directions that the X, Y, and Z axes would be if they were oriented with the ship. Therefore you can use dot products with them to convert any vector expressed in KSP's messy native coordinate orientation into a vector expressed in a ship-relative orientation, like so: // Assume someVec is a vector in KSP messy native coords - like SHIP:VELOCITY:ORBIT for example. set someVecShipFrame to V( vdot(shipx,someVec), vdot(shipy,someVec), vdot(shipz,someVec) ). Now someVecShipFrame is a vector expressed in an alternate frame of reference in which X,Y, and Z are shipx, shipy, and shipz respectively.
  21. Easier, but if your goal is to discover WHICH mod is doing the traffic that doesn't tell you because it would just treat all of KSP as one monolithic application. All you would learn is "network being used by some part of KSP". I'm not familiar enough with Windows to know how to track it at the level of individual DLLs, without the mistake of doing it at way too high a level (Csharp calls), which has the problems I've already mentioned.
  22. It's very hard to predict future stages because of the ability to perform weird staging methods. If every stage was simply a fuel tank and an engine and a separator it would be easy - but there are stages that siphon fuel with yellow hoses, and have fuel feeds taking fuel from tanks on the other side of a decoupler - these make it very hard to predict the fuel level in future stages. It's messy enough just to get the values of the current stage. (The algorithm is to walk the list of parts starting from each engine that is currently active, summing up all the fuel that is 'suckable' by that engine, and culling out all the duplicate fuel that you get from having multiple engines sucking fuel from the same tank.) I doubt you'll ever run into a memory cap. There hypothetically is one, but it would be quite hard to actually reach it. The game doesn't have a way to tell you how many bytes of ram you're using. The disk space will be a problem long before the memory would be.
  23. Your response is predicated on the presumption that preference for other languages besides CSharp must be due to deception - an unfair presumption. It might be that what the mod does is a lot more sensible to implement in another language, or that the author is a lot more familiar with another language. And you don't have to implement an entire separate firewall, or use the OS's firewall to get what I'm talking about - just have the mod look for calls to the much more low-level OS calls instead of looking for calls to the higher level API. i.e. look for the opening of sockets, the sending of packets, that sort of thing, rather than the Csharp .NET libraries, which are just one particular abstraction of the network calls. So it would basically be a firewall, yes, but one that is inside of KSP and is only looking at traffic owned by KSP's application. I think that would be a far more robust and sane design.
  24. stage:liquidfuel is supposed to be how much fuel is in the current stage. If you have no active engines, it returns zero. If you do have active engines and they have fuel, and it still says zero, then that's a bug.
  25. Wouldn't it make a lot more sense to do this using the OS itself and not the library routines of a *particular language* running on that OS? If you want to implement this it seems like doing it at the level of .NET framework libraries is way, waaaay too high-level of a location to be catching network usage. What about the mod that calls out to a non-Csharp library to accomplish things? Basically, if you're going to call it a firewall, then make it work like an actual firewall. Have it look for network traffic coming from the KSP application, regardless of what exact method call was used to cause the network traffic. Trap the *traffic*, not the API calls. That would also solve your problem of picking up false positives from people using the WWW libraries to load local sound files, because of course using WWW to look at a file: url won't actually cause any network traffic that a real proper firewall would see.
×
×
  • Create New...