Jump to content

kOS Scriptable Autopilot System 0.9


KevinLaity

Recommended Posts

@Captain_Party Have you tried using a simple launcher code? does the steering work for you? For me it wobbles like crazy and can't get the lock steering to work properly, did the launch manually and the ship was very maneuverable, with KOS, a total mess. Weird thing is, MJ could fly as usual

Link to comment
Share on other sites

@Captain_Party Have you tried using a simple launcher code? does the steering work for you? For me it wobbles like crazy and can't get the lock steering to work properly, did the launch manually and the ship was very maneuverable, with KOS, a total mess. Weird thing is, MJ could fly as usual

I've seen that KOS's steering system tends to violently wiggle the craft back and forth as it self-corrects. It's like the old ASAS used to work. It seems the only real solution is to build an extremely rigid craft, strutted all over the place to prevent any flexibility.

Link to comment
Share on other sites

Of course, I phrased myself poorly, I meant making an intentional infinite loop with basically no exit clause. Not that your loop becomes infinite because due to other factors the conditions never get fulfilled.

The point is that any pretend legibility improvement of putting a condition in the loop header versus checking explicitly and calling "break" in the body is largely imaginary because in EITHER case you still have to go examine the loop body to see how the loop exits, or indeed IF it exits at all. If the loop header looks unconditional and says "until 0" then you have to search the loop body for the word "break" to see how (or if) it ends, but on the other hand if the loop header looks conditional and mentions a variable or an expression then you STILL have to search the loop body to see the place where that expression or variable's value will get altered.

Now, if we had a FOR loop in KOS, THAT would be the one exception I make to that general principle, because unlike an UNTIL or a WHILE, a FOR loop does in fact encapsulate all the information up in the loop header in one place - you show how you'll initialize, what you'll check for, and how you'll increment, all up in the header. So that I do agree is more legible and less error prone. But once you remove init and increment and leave just the check alone, so you still have to look inside the body for the increment and look outside the body for the initialization, then there's zero legibility "win" over just explicitly using break instead.

Link to comment
Share on other sites

To @Sacred Aardvark and @blizzy78, the term "open source" actually has a group that approves whether or not people can legally call their license an open source license. They trademarked the term specifically to fight the definitional drift that your arguments are both based on.

You can read the whole thing here: http://opensource.org/docs/osd

But this is the relevant part of it:

3. Derived Works

The license must allow modifications and derived works, and must allow them to be distributed under the same terms as the license of the original software.

So can you let this rest for once? GNU GPL is AN open sourced license. There are others too. The property I was referring to that GPL has which allows someone to fork the code and make their own mod is *precisely* this property that GPL shares with all the other open source licenses too.

I wrote up longer responses, but I went back to delete them because really, this should settle it once and for all. The point is moot. I obviously was NOT referring merely to the ability to view the code when I called it open sourced, and I was using the term the same way the OSI (Open Source Initiative) themselves uses it.

Link to comment
Share on other sites

Can someone provide an example for the veriticlespeed function, and the If statement? I don't know how to use them fully.


until 0{
print <verticalspeed>. //has to be within <> when printing
if verticalspeed>400 {
lock throttle to 0.5.
break.
}.
}.

if verticalspeed gets over 400 then throttle will be set to 0.5 and the loop will break

Link to comment
Share on other sites



print <verticalspeed>. //has to be within <> when printing

Really? I've gotten "print verticalspeed" to work. I thought the angle-bracket notation was deprecated in favor of ship:thingy. (i.e. where it used to be <liquidfuel> it's now ship:liquidfuel).

Link to comment
Share on other sites

Really? I've gotten "print verticalspeed" to work. I thought the angle-bracket notation was deprecated in favor of ship:thingy. (i.e. where it used to be <liquidfuel> it's now ship:liquidfuel).

What you are saying is true, but both still work.

Link to comment
Share on other sites

Is it possible to get the vernal equinox coordinate? to calculate the right ascension of the ascending node and the argument of the perigee?

Or how does the LAN and Longitude of Periapsis work? Longitude based on what? Kerbin is always rotating, so does the LAN vary with time? Not sure if I should ask this here or somewhere else :P

Link to comment
Share on other sites

What you are saying is true, but both still work.

I was more referring to the bit about "//has to be within <> when printing".

You can print it without the <> and vertical speed isn't a ship expendable resource like the other things with <> are. I thought the <> marks were for expendables like fuel and monoprop and battery charge.

Edited by Steven Mading
Link to comment
Share on other sites

I was more referring to the bit about "//has to be within <> when printing".

You can print it without the <> and vertical speed isn't a ship expendable resource like the other things with <> are. I thought the <> marks were for expendables like fuel and monoprop and battery charge.

Both <liquidfuel> and ship:liquidfuel work, the same goes for other resources that can be queried. <verticalspeed> and verticalspeed both work too.

It is my understanding that the <> notation is to be removed at some point and replaced by ship:resource and just plain variables like verticalspeed and altitude.

Edited by Camacha
Link to comment
Share on other sites

Both <liquidfuel> and ship:liquidfuel work, the same goes for other resources that can be queried. <verticalspeed> and verticalspeed both work too.

I knew it worked for resources but verticalspeed and altitude aren't resources, which is why I didn't know it worked for that too

But the real thing that struck me as wrong and made me comment in the first place was the bit about how it has to be within <> when printing when I knew I had printed it many times before without the <>. Even if it CAN be in <> it certainly doesn't have to be. It will print just fine without the <> so I thought people might be mislead by that comment.

Edited by Steven Mading
Link to comment
Share on other sites

I think you are right and <liquidfuel> has to be like that but apoapsis or verticalspeed do not. It still works with the <> but you do not get an error if they are not there. I just have a habit of putting anything without a : inside <> for ease of error checking. I also wanted to show the different way you would print an attribute and the usage within an if statement.

EDIT : I have found that if you put stage:lquidfuel inside <> it causes an error.

EDIT2 : It seems that instead of using <liquidfuel> apoapsis and verticalspeed we should be using ship:liquidfuel ship:apoapsis and ship:verticalspeed (from the 0.90 release video)

My bad. I only downloaded KOS a couple of days ago.

Could someone direct me to a list of `targets` like "mun", "kerbin", "directly above kerbin"(seen that last one in a program but it causes an error which is why I`d like to find a list)

Also I have an issue causing me to do weird programming as a workaround. I am replicating Apollo and one of the things I need to do is to shut down the center engine when stage:liquidfuel=25% of the original amount. This works fine except after shutting down the center engine the program thinks stage:liquidfuel is zero and dumps the stage. The workaround is to have the program find out the total amount of liquidfuel in the ship and subtract the amounts in the tanks and to stage when liquidfuel reaches those set points.

This is the code I use


print "1st stage fuel 25%".
print stage:liquidfuel.
toggle AG9.
print stage:liquidfuel.
print "center engine shut down to reduce stresses".

and this is the output. AG9 ONLY shuts down the center engine (the other 4 are on thrust plates so are not directly connected to the tank). To my mind I have not staged and the stage has not run out of fuel so I should still detect the fuel left in the stage.

ZFTw5GL.png

Can someone tell me if this is the intended behaviour or whether I am reporting a bug? I am not familiar enough yet to know which.

Edited by John FX
Link to comment
Share on other sites

Can someone tell me if this is the intended behaviour or whether I am reporting a bug? I am not familiar enough yet to know which.

You must realize, that stage;liquidfuel has to have definition. Be aware that fuel tanks are not assigned to stages as they used few versions os KSP ago. So how KOS can know which fuel is it should count? Answer - it just counts fuel avaiable to current stage engines, not checking where this tank is (you can use fuel crossfeds to pump fuel between stages).

But - how KOS can know what are current stage engines? You can use action groups or light click menu to start or stop engines from what stages you want.

So, KOS uses definition "current stage fuel is fuel avaiable to currently active engines". For me its good and simple solution.

Link to comment
Share on other sites

You must realize, that stage;liquidfuel has to have definition. Be aware that fuel tanks are not assigned to stages as they used few versions of KSP ago. So how KOS can know which fuel is it should count? Answer - it just counts fuel available to current stage engines, not checking where this tank is (you can use fuel crossfeeds to pump fuel between stages).

But - how KOS can know what are current stage engines? You can use action groups or light click menu to start or stop engines from what stages you want.

So, KOS uses definition "current stage fuel is fuel available to currently active engines". For me its good and simple solution.

Reading between the lines it would seem I am reporting a bug because KOS does not function as you describe (It would have been a lot easier if you had simply said "you are reporting a bug because KOS should not work that way"...

As you can easily see in my image, the engines are lit, there is over 5000 liquidfuel left available to them and KOS is telling my program that there is 0 liquidfuel left. I shutdown only one of the engines in the current stage with an action group and KOS did not like that.

Also, does anyone know if there is a key to bring up the terminal? - answered (use an acrtion group)

Edited by John FX
Link to comment
Share on other sites

Also, does anyone know if there is a key to bring up the terminal?

There can be. In all my kOS craft, open terminal gets linked to ag1 in the action group menu in the VAB. That really helps to reduce the right clicking and annoyance of doing that over and over.

Link to comment
Share on other sites

There can be. In all my kOS craft, open terminal gets linked to ag1 in the action group menu in the VAB. That really helps to reduce the right clicking and annoyance of doing that over and over.

Ah, nice workaround. I`ll use that until something better comes along.

If the mod dev returns, I`d like to make a feature request for a hotkey that opens the interface.

Link to comment
Share on other sites

So, KOS uses definition "current stage fuel is fuel avaiable to currently active engines". For me its good and simple solution.

If it worked like that it wouldn't be a problem, but it doesn't work like that. It does NOT report the fuel available to currently active engines, but rather it reports the fuel directly connected to the currently active engines (i.e. there exist no stage decouplers between the tank and the engine.)

The relevant difference between those two meanings is due to the existence of the yellow fuel hoses. Fuel that is available to an active engine, but it's only available via a yellow hose, doesn't get reported in stage:liquidfuel or stage:oxidizer.

@JohnFX, I can't see your dark screenshot well enough to tell for sure, but it seems from your description that this might be what's happening in your case. if your engines are pushing against plates and have no fuel tanks directly attached but instead are getting all their fuel through yellow hoses, then ship:liquidfuel isn't sophisticated enough to "see" through that hose to report that fuel. It's not a trivial problem to fix because it's fuzzy how much of that fuel is really part of this stage and how much is for another stage, and also if four engines are all siphoning from the same tank you don't want to end up counting the tank's contents 4 times over into the total (adding it once for each engine). But if you make an asparagus staged rocket you can tell that KSP itself gets it a bit wrong, counting the same fuel toward multiple engines in the little green fuel bars on the staging list.

But at any rate, an engine who's sole fuel supply is a yellow hose will report as having zero fuel in stage:liquidfuel.

I ran into this problem myself as I had an ascent script with the logic to stage whenever stage:liquidfuel hits zero, and it kept skipping right past one of my stages to the next one even though it had fuel. I eventually traced it down to this cause.

One workaround is to, instead of building those engines against pusher plates, put them against the smallest fuel tank available in the game that will take the engine. Use those little fuel tanks as the pusher plates, and feed a yellow hose from the center tank out to the side "pusher plate" tanks.

For example, lets say you use the small 45 unit fuel tanks as the pusher plates and they get fed by hoses from a center tank with 320 units, and you've got 2 engines thusly mounted. Your total stage:liquidfuel *should* be 410 units, the 320 plus 2 of the 45's. But it will only be reported as 90 units (the two 45's). BUT those 90 units will be the LAST units spent, so you can still use stage:liquidfuel=0 to decide when to stage. You won't be able to tell the difference between having 300 units left versus having 200 units left, but you'll be able to tell the difference between having 90 units versus 80 units. Once you've emptied the center tank and only the "pusher plate" tanks have fuel left, (i.e. there's less than 90 units left in this example) then stage:liquidfuel would start becoming accurate again.

Link to comment
Share on other sites

I noticed the laggy stuttering also can be triggered not just by UNTIL loops but also by running WAIT UNTIL's that have a complex enough expression as the conditional check.

In fact, WAIT UNTIL seems to be even worse. With an UNTIL loop I can manually throttle down the speed of execution with a WAIT 0.5. or so when speed is not important and that greatly helps reduce the stutter. But there's no way to tell WAIT UNTIL (condition) that it doesn't need to check all that often. I seem to get less lag by turning an instance of this:

WAIT UNTIL (some condition).

into this:

UNTIL some condition { wait 0.2 . }.

Link to comment
Share on other sites

I noticed the laggy stuttering also can be triggered not just by UNTIL loops but also by running WAIT UNTIL's that have a complex enough expression as the conditional check.

In fact, WAIT UNTIL seems to be even worse. With an UNTIL loop I can manually throttle down the speed of execution with a WAIT 0.5. or so when speed is not important and that greatly helps reduce the stutter. But there's no way to tell WAIT UNTIL (condition) that it doesn't need to check all that often. I seem to get less lag by turning an instance of this:

WAIT UNTIL (some condition).

into this:

UNTIL some condition { wait 0.2 . }.

I usually use an until 0{if condition {break.}. stuff.). because it allows me to make changes very easily later as all my code is almost constantly updated and just add commands to the loop if I need to. I also get to control where the break happens and be able to keep the program live and maybe have other breaks in there or checks on the flight or update the on screen display (if any) for example :


until 0 {
if turnprofile<minangle {lock turnprofile to minangle.}.
if apoapsis<60000 {LOCK STEERING TO HEADING(turnProfile, 90).}.
if apoapsis>80000 {lock throttle to 0.}.
if apoapsis<79999 {lock throttle to 1.}.
if altitude>69100 {break.}.
if apoapsis>60000 {lock steering to heading(0,90).}.
if fuel<((fueltot-tanka)-(tankb*.75)) {break.}.
wait 0.3.
}.

or


until 0 {
if condition (break.).
if othercondition {set othertoggle to 1. break.}.
wait 0.3.
}.

I didn`t know about wait until (condition) being a cause of lag though. I`ll be aware of that in future. Thanks ;)

If it worked like that it wouldn't be a problem, but it doesn't work like that. It does NOT report the fuel available to currently active engines, but rather it reports the fuel directly connected to the currently active engines (i.e. there exist no stage decouplers between the tank and the engine.)

The relevant difference between those two meanings is due to the existence of the yellow fuel hoses. Fuel that is available to an active engine, but it's only available via a yellow hose, doesn't get reported in stage:liquidfuel or stage:oxidizer.

@JohnFX, I can't see your dark screenshot well enough to tell for sure, but it seems from your description that this might be what's happening in your case. if your engines are pushing against plates and have no fuel tanks directly attached but instead are getting all their fuel through yellow hoses, then ship:liquidfuel isn't sophisticated enough to "see" through that hose to report that fuel. It's not a trivial problem to fix because it's fuzzy how much of that fuel is really part of this stage and how much is for another stage, and also if four engines are all siphoning from the same tank you don't want to end up counting the tank's contents 4 times over into the total (adding it once for each engine). But if you make an asparagus staged rocket you can tell that KSP itself gets it a bit wrong, counting the same fuel toward multiple engines in the little green fuel bars on the staging list.

But at any rate, an engine who's sole fuel supply is a yellow hose will report as having zero fuel in stage:liquidfuel.

I ran into this problem myself as I had an ascent script with the logic to stage whenever stage:liquidfuel hits zero, and it kept skipping right past one of my stages to the next one even though it had fuel. I eventually traced it down to this cause.

One workaround is to, instead of building those engines against pusher plates, put them against the smallest fuel tank available in the game that will take the engine. Use those little fuel tanks as the pusher plates, and feed a yellow hose from the center tank out to the side "pusher plate" tanks.

For example, lets say you use the small 45 unit fuel tanks as the pusher plates and they get fed by hoses from a center tank with 320 units, and you've got 2 engines thusly mounted. Your total stage:liquidfuel *should* be 410 units, the 320 plus 2 of the 45's. But it will only be reported as 90 units (the two 45's). BUT those 90 units will be the LAST units spent, so you can still use stage:liquidfuel=0 to decide when to stage. You won't be able to tell the difference between having 300 units left versus having 200 units left, but you'll be able to tell the difference between having 90 units versus 80 units. Once you've emptied the center tank and only the "pusher plate" tanks have fuel left, (i.e. there's less than 90 units left in this example) then stage:liquidfuel would start becoming accurate again.

That makes complete sense and explains everything about my issue. I think I will fix the issue in software as that causes slightly less explosions than hardware changes, well at least in my workshop anyway.

What I do is lock a variable to be ship:liquidfuel, another to be stage:liquidfuel and then set triggerfuel to be (ship:liquidfuel-stage:liquidfuel) just after staging and when ship:liquidfuel reaches triggerfuel I know it is time to stage.

Edited by John FX
Link to comment
Share on other sites

In case anyone missed the latest squadcast.... throttling engines independently confirmed for 0.23 :)

I know that that's been requested feature for KOS players...

Yes, oh yes. This will complicate matters a lot more, but increases the possibilites almost infinitly. I am afraid I will have to write some proper code now :P

Link to comment
Share on other sites

Ok, I have another issue. After docking two craft, I try to `lock steering to prograde.` at which point my craft just starts a roll then translates as fast as it can. I suspect the roll cannot keep up with the translate...

Is there *any* other way of setting my orientation *other* than using `lock steering` as `lock steering` does not operate well? All I want is to be able to roll x degrees or not roll depending on my whim, then steer my craft like normal, up down left and right the same way you always can. Not absolute directions, relative. It should be the most basic function of controlling your craft.

(is there a way to only adjust each value individually, so I could roll, then translate?)

I`m currently trying to lock steering for 1 seconds then sas on for 5 seconds to slow it down, then lock for two seconds again, rinse repeat.

this is not working. Every minute or so it ends up about 5 degrees closer to prograde with lots and lots of `not knowing which way to turn` inbetween...

Also is there a way to check your orientation is close to prograde so I can tell when to end this loop for example?

I refuse to accept that a ship design that rolls slower than it pitches is fundamentally uncontrollable. That would be terrible. This `you are forced to roll whenever you lock steering` is also very very frustrating.

At the core, is there any way to alter your attitude *without* doing a roll?

Mechjeb can control this craft perfectly FYI. It moves to the prograde marker and just sits there.

EDIT : After examining and forcing it to stop between letting it go for only a small amount of time it is actively heading *away* from prograde if it is near it. If I lock steering to up then it spins around the horizon and does nothing else and never settles down.

Edited by John FX
Link to comment
Share on other sites

You might be wanting too much at once and doing it too abruptly. You could try finding out the difference between your current position and the one you want to be in and then ease into it. I did some testing which indicates that small steps prevent wild movements. Using larger increments or changing direction faster will lead to an increasing loss of control. You could even go the fancy route and have your script monitor the deviation. If that becomes too large, you slow down.

I assume you now that lock steering to (pitch, heading, roll) allows you to individually control each one?

EDIT : After examining and forcing it to stop between letting it go for only a small amount of time it is actively heading *away* from prograde if it is near it.

Are you sure prograde remains the same direction all the time? Because if you use prograde or retrograde for something like landing, the directions will change if you are near standstill.

Edited by Camacha
Link to comment
Share on other sites

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