Jump to content

[1.3] kOS Scriptable Autopilot System v1.1.3.0


erendrake

Recommended Posts

Okay, so I'm trying to program the guidance for my Mercury-Redstone type rocket using the method I was describing before. Initially I had a program that worked, but was very inconsistent in trajectory that it produced. It simply waited until the vertical speed of the rocket reached a certain point, pitched it over a set amount, waited a predetermined time, and then locked steering to SHIP:VELOCITY:SURFACE: DIRECTION.

The idea behind the new program is that it waits until it reaches a certain vertical speed, locks guidance to an initial pitchover angle, and then continually checks the rocket's current angle against the specified initial angle. Once it reaches an optimal angle (within 0.1 degrees of the specified pitchover angle) it switches guidance to SHIP:VELOCITY:SURFACE: DIRECTION for the rest of the gravity turn. It seems to work until I compare the actual difference in angle to the difference in angle allowed by the program. When I try to do that I get an "Argument is out of range. Parameter name: index" error.

Here's the code:



COPY mrbooster TO ARCHIVE.

DECLARE pitchAngleInitial.
DECLARE turnStartSpeed.
DECLARE correctRoll.
DECLARE initialPitchAng.
DECLARE intitalPitchVec.
DECLARE angDiff.
DECLARE closeNuff.

SET pitchAngleInitial TO 88.
SET turnStartSpeed TO 50.
SET correctRoll to R(0,0,-90). //Roll correction to keep the craft oriented correctly.
SET initialPitchAng TO HEADING(90,pitchAngleInitial).
SET initialPitchVec TO initialPitchAng:VECTOR. //Used for calculating when we are close enough to the initial pitchover to begin actual gravity turn.
SET closeNuff to 0.1. //Ship direction must be no more than this many degrees from the correct pitchover angle to begin gravity turn.

LOCK THROTTLE TO 1. //Throttle up.
STAGE. //Ignite engine.
WAIT 2. //Wait for thrust to build up.
LOCK STEERING TO UP + correctRoll.
STAGE. //Launch.

WAIT UNTIL VERTICALSPEED > turnStartSpeed. //Vertical ascent.

LOCK STEERING TO initialPitchAng.
print "Debug1".
LOCK angDiff TO ABS(VANG(SHIP:VELOCITY:SURFACE:DIRECTION,initialPitchVec)). //Checking angle between current and desired directions.
print "Debug2".
WAIT UNTIL angDiff < closeNuff. //Wait until we are close enough to the proper heading.
print "Debug3".
LOCK STEERING TO SHIP:VELOCITY:SURFACE:DIRECTION. //Gravity turn time! Keeping the rocket pointed along the prograde vector.

WAIT UNTIL SHIP:LIQUIDFUEL < 150. //Burning, burning, burning. We're turning and we're burning...
STAGE. //Escape tower jettison.

WAIT UNTIL SHIP:LIQUIDFUEL = 0. //Booster cutoff.
WAIT 5. //Chill for a bit.

STAGE. //Booster seperation/posipack firing.

COPY mrpostboost FROM ARCHIVE. //Load up next program.

RUN mrpostboost. //Run it.

It only gets as far as the "Debug2" print command, and locks up on the line of code after that. I have also tried executing it in a while loop like the one below without succes.


stuff

WHILE 0 {
SET angDiff TO ABS(VANG(SHIP:VELOCITY:SURFACE:DIRECTION,initialPitchVec)).
IF angDiff < closeNuff {
BREAK.
}.
}.

more_stuff

Can anyone help me stop it from doing this?

EDIT: Also, Steven, as a user and not a programmer, it seems like breaking backwards compatibility in that way wouldn't be too bad of a thing. It's not a huge inconvenience to go and wrap a couple of file names in quotes to comply with the new syntax, especially considering the kind of possibilities it could open up. Just my 2¢.

Edited by VFB1210
Link to comment
Share on other sites

I agree... bring on the quotes (but then again, I don't have a library of script I'd have to fix... of course, then again, if you've got a library of script to fix... you might write a script to fix it)

Your problem is that you're trying to use an incorrect argument in the vang() function. It compares the angle of incidence between two vectors [vang(vector1,vector2)] but ship:velocity:surface:direction doesn't return a vector, it returns a euler direction in the form of r(yaw,pitch,roll). Simply swap ship:velocity:surface:direction for ship:velocity:surface:vector and that should fix it. As a side note, I believe (*though I could be mistaken*) that ship:velocity:surface is already stored as a vector, and can be used directly without the :vector structure tag.

Link to comment
Share on other sites

It's not that changing RUN FILENAME to RUN "FILENAME" is hard. It's not. It's a very simple change. It's that I anticipate lots of bug reports from people who didn't read the release notes and just installed the update, or, more likely, from people who had never run kOS before and install it for the first time, but then find example code posted on the internet and try running it, not knowing the example code is for an out of date kOS (because if it's an old post, the person writing the post won't have known to put the warning there in the first place, because the problem wasn't there yet when it was written.)

I'd feel more comfortable about it if kOS could detect the attempt to do it the old way and issue a special-case error message. That way people who didn't know about the problem would discover it when they try using it. As it stands, the error message they'd get would just be "Variable not Defined" as they tried using the bare identifier that doesn't refer to any variable value. It's not going to be clear why that's wrong, especially if the user is looking at supposedly working examples that do it *exactly* the same way they're trying to do it, and they pull out their hair in frustration going, "Come On! I'm doing it EXACTLY like the example shows and it doesn't let me! What a piece of garbage this kOS thing is…."

That's the problem with breaking backward compatibility - the inability to force people to go out there and fix up all their old code examples that have been posted on the net makes life very frustrating to people trying to follow those examples. The experience of a user who's been with the project continually and is making small updates all along is very different from the experience of a user coming in new who doesn't realize a lot of what they see online is obsolete advice that won't work.

I might be more comfortable with it if I could find a way to detect this specific case (getting the undefined variable error in the outermost expression evaluation of a disk command's (run,rename,copy,switch to, etc) argument) and printing a different error message explicitly mentioning the deliberate break in backward compatibility and how to fix it.

Link to comment
Share on other sites

I'd feel more comfortable about it if kOS could detect the attempt to do it the old way and issue a special-case error message. That way people who didn't know about the problem would discover it when they try using it. As it stands, the error message they'd get would just be "Variable not Defined" as they tried using the bare identifier that doesn't refer to any variable value. It's not going to be clear why that's wrong, especially if the user is looking at supposedly working examples that do it *exactly* the same way they're trying to do it, and they pull out their hair in frustration going, "Come On! I'm doing it EXACTLY like the example shows and it doesn't let me! What a piece of garbage this kOS thing is…."

To be fair, that is exactly how Real Programsâ„¢ work. Or do not work, more accurately. Coincidentally, I have been wrestling all week with a simulation that should work, but does not and only communicates in cryptic error messages and random failures. That is very high-end, expensive software.

Link to comment
Share on other sites

To be fair, that is exactly how Real Programsâ„¢ work. Or do not work, more accurately. Coincidentally, I have been wrestling all week with a simulation that should work, but does not and only communicates in cryptic error messages and random failures. That is very high-end, expensive software.

Real Programs have the advantage of google-able help. There's a large enough base of users that if a major change happened in an update, and you google for the problem, you'll find other people who had the same issue and you'll find out about the break in backward compatibility. With a smaller user base like kOS has, that doesn't work as well. If, say, Python, or Java, or Csharp had a sudden change the broke the ability to open files the old way, you know there'd be lots of incidences of others who ran into the problem and asked about it (and thus got answered "that changed in version xxxx, now you have to do this…").

One of the frustrations we've been having with kOS is that old stuff shows up HIGHER in most google searches than the new stuff. Most of the time if you google about kOS you're seeing things about Kevin's older versions.

Link to comment
Share on other sites

Honestly the fact that kerboscript does not tell you which variable is undefined is a far more important issue to address - if you fix that then this whole problem and many like it disappear.

Already implemented, but waiting to be incorporated into the rest of kOS:

a5e4e680-1f4a-11e4-97d6-3c86205b2a2c.png

Once this gets pulled in, runtime errors should be getting a trace of line/col they came from dumped out.

Link to comment
Share on other sites

Quick question, is there a way to get kOS to simulate a keystroke in a program? I'm working with Action Groups Extended, and if I could get kOS to simulate certain keystrokes bound to action groups in AGX then that would open up a lot of opportunities to control actions without having them bound to staging, which I frequently forget to set up correctly.

Link to comment
Share on other sites

So this will sound like a dumb question but I can't seem to find a correct answer.

How do you lock steering to a maneuver node?

I tried:

set mynodevariable to node( time:seconds + 60, 0, 0, 100 ).

lock steering to mynodevariable:deltav.

But it says you have to attach the node. Looking for attach didn't bring up anything and I couldn't find any other working examples.

Link to comment
Share on other sites

But it says you have to attach the node. Looking for attach didn't bring up anything and I couldn't find any other working examples.

SET myNode to NODE( time:seconds + 60, 0, 0, 100 ).

ADD myNode. // This is the "attach" that its talking about.

lock steering to myNode:deltav.

Link to comment
Share on other sites

SET myNode to NODE( time:seconds + 60, 0, 0, 100 ).

ADD myNode. // This is the "attach" that its talking about.

lock steering to myNode:deltav.

Darn I was so close. Thanks for the quick response.

Would it be too much trouble to explain the command to me?

I understand that SET myNode to NODE is making myNode a variable. However I'm not quite understanding the need for the time thing and what those numbers are.

This would be locking steering a node I already created correct?

Edited by Nori
Link to comment
Share on other sites

Darn I was so close. Thanks for the quick response.

Would it be too much trouble to explain the command to me?

I understand that SET myNode to NODE is making myNode a variable. However I'm not quite understanding the need for the time thing and what those numbers are.

( http://ksp-kos.github.io/KOS_DOC/structure/node/index.html )

NODE( universalTime, radialOut, normal, prograde )

UniversalTime means the number of simulated seconds since the beginning of the campaign game. (When you start a new campaign and launch your very first thing on the launchpad, it's zero. After that it's a count of all the time that passed in-game, not counting the frozen time (like in the VAB, or in the ESC menu). Unlike your computer clock time, this actually moves with the time warp speed. So it's basically, "If you convert the current game clock's years, days, hours, minutes, seconds, into just a big raw number of seconds, what is the result?". When you call TIME:SECONDS, you are getting that result for "right now". In this example where you say TIME:SECONDS+60 you are setting a maneuver node that you'd like to occur on your orbit path exactly 60 seconds from now.

The other 3 arguments are the three direction components, corresponding to using the mouse to twiddle the colored knobs of the maneuver node:

radialOut,Normal,prograde

They can be set to negative numbers to get the opposite directions (i.e. to burn retrograde, use a negative number for prograde).

This would be locking steering a node I already created correct?

When you say "I already created" do you mean "the script I wrote already created it" or do you mean "I created it manually by using mouseclicks on the map view's orbit line"?

Link to comment
Share on other sites

( http://ksp-kos.github.io/KOS_DOC/structure/node/index.html )

NODE( universalTime, radialOut, normal, prograde )

UniversalTime means the number of simulated seconds since the beginning of the campaign game. (When you start a new campaign and launch your very first thing on the launchpad, it's zero. After that it's a count of all the time that passed in-game, not counting the frozen time (like in the VAB, or in the ESC menu). Unlike your computer clock time, this actually moves with the time warp speed. So it's basically, "If you convert the current game clock's years, days, hours, minutes, seconds, into just a big raw number of seconds, what is the result?". When you call TIME:SECONDS, you are getting that result for "right now". In this example where you say TIME:SECONDS+60 you are setting a maneuver node that you'd like to occur on your orbit path exactly 60 seconds from now.

The other 3 arguments are the three direction components, corresponding to using the mouse to twiddle the colored knobs of the maneuver node:

radialOut,Normal,prograde

They can be set to negative numbers to get the opposite directions (i.e. to burn retrograde, use a negative number for prograde).

When you say "I already created" do you mean "the script I wrote already created it" or do you mean "I created it manually by using mouseclicks on the map view's orbit line"?

Thanks, makes more sense. If I already created one on the map is what I mean for this situation.

Link to comment
Share on other sites

Thanks, makes more sense. If I already created one on the map is what I mean for this situation.

The special variable NEXTNODE should return the next node that's on the flight plan, regardless of whether it was created manually or by kOS code.

I just realized it's not in the documentation page. It needs to be added.

Link to comment
Share on other sites

Has anyone been able to confirm that print throttle is broken?

Also, is there any way to have the boot file open the terminal window automatically?

Edited by impyre
Link to comment
Share on other sites

The special variable NEXTNODE should return the next node that's on the flight plan, regardless of whether it was created manually or by kOS code.

I just realized it's not in the documentation page. It needs to be added.

That would explain why I couldn't find it. :)

So would it be this then?

lock steering to NEXTNODE:deltav.

Link to comment
Share on other sites

One of the frustrations we've been having with kOS is that old stuff shows up HIGHER in most google searches than the new stuff. Most of the time if you google about kOS you're seeing things about Kevin's older versions.

That is just how it is, but you cannot get too stuck on older versions. Things are quite different anyway, so better make the best new version you can, rather than also impairing that one.

Link to comment
Share on other sites

Has anyone been able to confirm that print throttle is broken?

Also, is there any way to have the boot file open the terminal window automatically?

Unless you've already locked it before, you can't read from THROTTLE. For the terminal window, I just use the Action Group 10 to toggle it, then add "toggle ag10." to the boot file.

I've almost made a complete autopilot with kOS, and each time I write a new function, I realize there's a lot of undocumented things (like the WARPMODE, or boot files, wich I found in changelogs). Is the documentation link in first page up to date?

Edit: also, my prog is almost ready for a kOS challenge, is there an active one somewhere?

Edited by Lilleman
Link to comment
Share on other sites

I figured it's been long enough without much word on where things are going that it was worthwhile to post a teaser of a few things that are in development for kOS. Everything on this list is a thing that has at least *some* first-attempt implementation code already there in the source code on github that works for the simple test cases I've tried so this isn't just pie-in-the-sky future stuff.

Caveat: These are NOT to be taken as promises. We may find in brutal testing that a feature is so problematic it might need to be removed. But I don't *expect* that to happen. I'm just saying we haven't really beat on these that hard yet:

  • Separate simultaneous terminals : Each Comptronix SCS unit will get its own separate terminal window. You will be able rightclick one computer part, pull up its terminal, then later on rightclick a different computer part and pull up its terminal and have the two onscreen side-by-side.
  • Runtime errors finally tell you where in your script they happened : In the past, after compiling there was no information remaining about which parts of the program came from which parts of the source script. Now that information will be retained, and the error reporting will show you where it was in your code that they happened, with a full stack trace if you had one program running another program running another program, running a WHEN trigger, etc.
  • Long-running Triggers will be caught and generate an explanatory runtime error : New users often have difficulty with the ON and WHEN triggers, as it's not always obvious how they should be fast and cannot last longer than one Update. To protect KSP from the infinite hanging that will happen if you stick a long-lasting loop in a trigger, it now counts the instructions that execute during triggers against the CONFIG:IPU setting, and if the triggers last longer than CONFIG:IPU they will be caught and stopped. (CONFIG:IPU should be set higher than it is now to get roughly the same performance, as a result, since right now it only measures the non-trigger code and isn't counting everything.)
  • LIST FILES IN VARIABLE: Previously, the LIST FILES only worked for printing to the screen, not for putting in a variable.

And the following isn't quite in the same state as all the above are, as I only just started on it today, so it might not be ready for a bit longer, and we're still messing about with the exact way to make the syntax look:

Read the values of fields you can see in the rightclick menus on parts: For example, DeadlyReentry adds a field to the rightclick menu called "Temperature" to every part. So you could do something like:

LIST PARTS IN PARLIST.

PRINT PARTLIST[12]:ModuleAreoReentry:Temperature.

I hope @erendrake doesn't mind that I posted this. It's just that it's been so long without publicly visible activity that I felt it needed to be shown what things are happening to raise a little bit of buzz.

Link to comment
Share on other sites

could accessing the parts data lead up to eventually maybe possibly hopefully being able to control the status of the parts? Like telling an antenna to deploy without using an action group?

Overall though, the new features look very nice! Hope a few bugs are squished along the way too... like that targeting issue

Thanks for the update

Link to comment
Share on other sites

could accessing the parts data lead up to eventually maybe possibly hopefully being able to control the status of the parts?

Absolutely! We want to let you do anything you can do with the right click menu, eventually. some stuff gets a little complicated and so this was the part we were most confident in.

Link to comment
Share on other sites

could accessing the parts data lead up to eventually maybe possibly hopefully being able to control the status of the parts? Like telling an antenna to deploy without using an action group?

That's the plan. Erendrake and I have been having lots of google hangout talks about how to pull this off. It's not easy because everything we think of for how to make it nicer ends up turning into a more low-level discussion about making new features in the language itself to support making it simpler. Using existing language features, trying to say "get me this particular part" is a clunky nested for-loop that really can't be simplified without extra language support.

But yeah, the basic design goal was "you see all that stuff that's in the rightclick menu for a part? Wouldn't it be a good idea to allow access to all of that, generically for any part, without having to write special case code for each and every KSP mod out there?" When other mod writers create the fields and click buttons of those menus, they sort of ARE making a public API for their module - an API for the GUI, so to speak. It's also the goal to use the names that YOU can see on that menu for those fields, rather than the actual names for those fields in the csharp code behind the scenes that you don't see. (i.e. if the mod writer made a field called "temp" behind the scenes, but the gui label you see for it in the menu is "Temperature", then we want kOS to use the term "Temperature" to access it, because that's the term that the users of kOS know about. You don't see the "secret" name under the hood.)

First pass: reading the fields, read-only.

Second pass: allowing you to press the cyan-colored buttons (call the function associated with that event).

Third pass: maybe the more complex tweakables widgets too? Not sure about that one yet.

Overall though, the new features look very nice! Hope a few bugs are squished along the way too... like that targeting issue

Thanks for the update

There are also several bug fixes. I just didn't mention them because I wanted the post to be exclusively about new things.

Link to comment
Share on other sites

I got the ability to SET the tweakable fields working tonight.

Here's another screenshot of the progress so far. This is using my LaserDist mod, but it's not specific to LaserDist. It works on just about anything, without needing buy-in from that mod's author, and without needing to know any of that author's code.

0LwTwAX.png

The bits that erendrake and I were trying to work on were how to make it easier to get to the bit where you know that plist[37] happens to be the part you were looking for. That's not shown in any of my example screenshots because I expect that part to probably change.

I'd feel happier if I just entirely bypassed the step where you have to name the PartModule that is on the part to get to its fields, and instead you could just treat the fields as direct suffixes of the part. The only reason I didn't go with that plan is because there's no guarantee that different mod authors didn't use the same gui name for their fields. The KSP design allows for this and doesn't stop it. You can have two Mods that both add a field to the same rightclick menu for the same part that have the same gui label. That is the only reason you have to name the partmodule in the example is because of the potential for that clash. Were it not for that, I'd have preferred to bypass that step and let people treat the field as a direct suffix of the part itself.

Link to comment
Share on other sites

I got the ability to SET the tweakable fields working tonight.

Here's another screenshot of the progress so far. This is using my LaserDist mod, but it's not specific to LaserDist. It works on just about anything, without needing buy-in from that mod's author, and without needing to know any of that author's code.

http://i.imgur.com/0LwTwAX.png

The bits that erendrake and I were trying to work on were how to make it easier to get to the bit where you know that plist[37] happens to be the part you were looking for. That's not shown in any of my example screenshots because I expect that part to probably change.

I'd feel happier if I just entirely bypassed the step where you have to name the PartModule that is on the part to get to its fields, and instead you could just treat the fields as direct suffixes of the part. The only reason I didn't go with that plan is because there's no guarantee that different mod authors didn't use the same gui name for their fields. The KSP design allows for this and doesn't stop it. You can have two Mods that both add a field to the same rightclick menu for the same part that have the same gui label. That is the only reason you have to name the partmodule in the example is because of the potential for that clash. Were it not for that, I'd have preferred to bypass that step and let people treat the field as a direct suffix of the part itself.

Are there any plans for how to handle the case where a part has more than one instance of the same PartModule? E.g. I've seen solar panels with multiple ModuleDeployableSolarPanel to handle all of their animations.

Link to comment
Share on other sites

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