Jump to content

[1.3] kOS Scriptable Autopilot System v1.1.3.0


erendrake

Recommended Posts

Yes. If you scan the video to the very last few seconds of it and freeze frame it there you can see a still screenshot of me doing just that.

print "No sleep for me until T+" + ETA:NEW_KOS_VERSION.

Link to comment
Share on other sites

The KSP API is internally inconsistent with which axis is which sometimes. (Don't get me started on trying to deal with CelestialBody, which can't make up it's damn mind and keeps swapping them depending on what method you're calling).

So it's entirely believable that rotational velocity it's messed up this way. It could very well be. So my question is this: I could make it be consistent with ship:raw. I could make the change but then it would be a while before it got released. So, are you the only one who has used it? If its just you, then I think I should change it. If there's a lot of people who used it the broken way then there's backward compatibility problems.

I'm in favor of making this change. I'm using angularvel for a PID controller, but I'd much rather have it make sense and fix my code when the change happens, rather than currently where angular vectors don't make mathematical sense but work because I switched them around.

-----

Secondly, I seem to have found a bug with the pilot-translation GETs. Specifically, ship:control:pilotfore and ship:control:pilotstarboard return the negative of what they should. Eg. when you press the translate right key ('L'), ship:control:pilotstarboard returns (-1) when it should return (+1), and the opposite for 'J'. It's easy to work around this, but it should probably be fixed.

Can be demonstrated with this script :

UNTIL false {

WAIT 0.001.

PRINT "pilotfore: " + round(ship:control:pilotfore,1) + " " at (0,3).

PRINT "pilottop: " + round(ship:control:pilottop,1) + " " at (0,4).

PRINT "pilotstarboard: " + round(ship:control:pilotstarboard,1) + " " at (0,5).

PRINT "pilotpitch: " + round(ship:control:pilotpitch,1) + " " at (0,6).

PRINT "pilotyaw: " + round(ship:control:pilotyaw,1) + " " at (0,7).

PRINT "pilotroll: " + round(ship:control:pilotroll,1) + " " at (0,8).

}

Ship:control:pilottop works correctly, as do all the rotate GETs (pitch, yaw, roll).

Link to comment
Share on other sites

This video demonstrates how to de-orbit and land a rocket propulsively near the Kerbal Space Center. Enjoy!

While I'm quite happy that someone is doing this, I wonder why you chose video. Would the kOS code be available somewhere?

kOS Telnet. The pull request is in and now we're working on getting it all merged in nicely:

So I can soon use putty/telnet to control kOS? Will it support 200 columns?


I'm currently having the most curious problem where "when..then" is triggered twice:


when flout >=1 then {
toggle ag1. print "jet 1 off".
set flout to 0.
set tmp to missiontime.
when flout >=1 and missiontime > tmp +1 then {
toggle ag2. print "jet 2 off".
set flout to 0.
when flout >=1 then {
set flout to 0.
toggle ag3. print "jet 3 off".
when flout >=1 then {
set flout to 0.
toggle ag4. print "jet 4 off".
}}}}

"flout" is shorthand for flameout. The code above used to work in older versions of kOS but in v0.15.4 it doesn't. What I'm getting:


output of main loop
output of main loop
output of main loop
jet 1 off
jet 2 off
output of main loop
output of main loop

I take it that one flameout triggers two of the when-then blocks before returning to the main loop. Not one as it should, and not the whole cascade as would be kinda-sorta understandable, but exactly two. What's most interesting is that even the "set tmp to missiontime" thing doesn't fix it. The next block is triggered anyway.

EDIT: in v0.15.6 it works again. Sorry to have bothered you.

Edited by Laie
Link to comment
Share on other sites

/telnet to control kOS? Will it support 200 columns?

Yes. There is no upper limit, other than what framerate you can tolerate working with. (There is a 'diff' algorithm at work that gets more expensive the more characters wide the screen is. I haven't profiled its expense yet, but having about 5 different 80x24 terminals open at once seemed fine, so it's probably not a problem.)

Not one as it should, and not the whole cascade as would be kinda-sorta understandable, but exactly two.

This is impossible to diagnose with just looking at the whens only. The code that turns on the flout condition isn't shown making it impossible to see why the existing behavior is supposedly wrong. If flout was turned on exactly twice it would make sense.

Link to comment
Share on other sites

This is impossible to diagnose with just looking at the whens only. The code that turns on the flout condition isn't shown making it impossible to see why the existing behavior is supposedly wrong. If flout was turned on exactly twice it would make sense.

I'm keeping it seperate. There's a block of nested when..then, and then there is the main loop. Or rather, a series of main loops, like this:


list engines in el.

when then {
when then {
when then {
}}}

until altitude > x {
(do some stuff)
print "some flight data".
wait 1.
set flout to 0.
for e in enginelist {if e:ignition and e:flameout set flout to flout + 1.}
}
until apoapsis > x {
(do some stuff)
print "some flight data".
wait 1.
set flout to 0.
for e in enginelist {if e:ignition and e:flameout set flout to flout + 1.}
}

until out of atmosphere {
(maintain apoapsis)
print "some flight data"
wait 1.
set flout to 0.
for e in enginelist {if e:ignition and e:flameout set flout to flout + 1.}
}

That way, jets may flameout at any stage of the flight, the when-then block preceding everything will catch it. Every instance of when-then resets flout to zero, and it won't become nonzero until the currently active loop has had time to run at least once. I shouldn't get two flameouts without at least a one-second delay and status line in-between.

Most infuriating: a test rig on the launchpad works as intended. But a real vessel during a real flight will double-trigger even in 0.15.6.

Edited by Laie
Link to comment
Share on other sites

Your whens could interrupt your main code at any time, even in the middle of those for loops where you are incrementing flout. So you could have a case where two iterations of the same loop do a flout = flout +1, and have one trigger kick off in between the two, thus making the second flout = flout + 1 trigger the second trigger.

example:

there are two flamed out engines. you do the for loop. On one iteration you do SET flout to flout +1, and flout is now 1. Then the first trigger catches this and fires turning flout back to 0. Then on your second iteration of the SAME loop you do the second SET flout to flout + 1, and a second trigger catches that.

It would be inconsistent behavior because it would depend on exactly when you've exhausted CONFIG:IPU instructions and thus a new Update interrupts your flow. If that happens exactly in the middle of the for loop, the scenario I describe can happen.

In general, you should be thinking like "threaded" programming when using WHEN triggers. Remember they could get called any time. If they read a variable your main program fiddles with, try to keep your main program's alteration of it instantaneous and all at once.

for example, have the for loop work on a temp variable, say, tempFlout. Then after it's done adding it all up at the bottom of the loop, then in one single statement say SET flout to tempFLout.

Edited by Steven Mading
Link to comment
Share on other sites

So I made a radar screen, works so far but I have one problem.

As you can see I get an error at the end, I dont know why really, maybe because the script runs while the missile is destroyed?

Here is the code for the RADAR:


SET counter TO 0.
UNTIL counter = 10000 {
CLEARSCREEN.
PRINT "90" AT (0,0).
PRINT "-" AT (0,5).
PRINT "60" AT (0,10).
PRINT "-" AT (0,15).
PRINT "30" AT (0,20).
PRINT "-" AT (0,25).
PRINT "0" AT (0,30).
PRINT " | | | | | | | | |" AT (0,31).
PRINT " 45 22.5 0 22.5 45" AT (0,32).
LIST TARGETS IN radar.
FOR VESSEL IN radar {
IF VESSEL:DISTANCE < 90000 AND ABS(VESSEL:BEARING) < 45 {
IF VESSEL:BEARING < 0 {
SET X TO 1 + (24 - ROUND(ABS(VESSEL:BEARING / 45) * 24)).
}.
IF VESSEL:BEARING > 0 {
SET X TO 1 + (24 + ROUND(ABS(VESSEL:BEARING / 45) * 24)).
}.
IF VESSEL:BEARING = 0 {
SET X TO ROUND(VESSEL:DISTANCE / 1000).
}.
SET Y TO (30 - ROUND(VESSEL:DISTANCE / 3000)).
IF NOT (VESSEL:NAME = "AIM-120 AMRAAM Missile (fired)" OR VESSEL:NAME = "AIM-9 Sidewinder Missile (fired)" OR VESSEL:NAME = "AIM-54 Phoenix Missile (fired)") {
PRINT " " + CEILING(VESSEL:DISTANCE/1000) AT(X,Y-1).
PRINT "U " + CEILING(VESSEL:ALTITUDE/1000) AT(X,Y).
PRINT " " + CEILING(VESSEL:AIRSPEED) AT(X,Y+1).
} ELSE {
PRINT "." AT(X,Y).
}.
}.
}.
SET counter TO counter + 1.
WAIT 0.1.
}.

Link to comment
Share on other sites

As you can see I get an error at the end, I dont know why really, maybe because the script runs while the missile is destroyed?

Hmm. It's probably the fact that the FOR loop takes longer than one update to run. So you query the list of targets, put it in radar, and then start working with those targets one at a time, and in the meantime one of them is gone but you still have a reference to it.

Does the Vessel:LOADED check work as a protection check? Hmm. That's still an awful lot of places to have to check it even if it does. I'd recommend using WAIT 0.01 to force an update sync right before you take your readings, then take all your readings at once into variables (i.e. SET BEARING TO VESSEL:BEARING, and so on, rather than mentioning VESSEL:BEARING over and over).

So maybe this would work?


FOR VESSEL in radar {
WAIT 0.01.
IF VESSEL:LOADED {
SET VDIST TO VESSEL:DISTANCE.
SET VBEAR TO VESSEL:BEARING.
SET VALT TO VESSEL:ALTITUDE.
SET VAIR TO VESSEL:AIRSPEED.
SET VNAME TO VESSEL:NAME.

// /|\
// |
// put the rest of your loop in here, using the values above instead of direct queries.
// |
// \|/

}

I can't guarantee that working, because I don't know how Vessel:LOADED will behave here, but it might work as a check.

We may need to create an additional suffix for vessel if it doesn't - Vessel:EXISTS. (Because I can see a scenario where the vessel exists but as a far away object (packed into a single point on the map view, not loaded as a full list of parts), so some suffixes still work (like distance), but not others (like :PARTS). It may be necessary to let a script differentiate those two conditions.))

Behind the scenes, because your script causes us to have a C# reference pointing to the vessel, that means the vessel object doesn't really get orphaned and go away when it crashes. It's still in memory, but now many of its methods won't work right. We might need a way to detect that situation and report it to the script.

- - - Updated - - -

Another idea I'd been tossing around a while is to just make an "ATOMIC" keyword, or some sort of equivalent, like so:


line 1.
line 2.
ATOMIC {
line 3.
line 4.
line 5.
line 6.
}
line 7.
line 8.
line 9.

And what it would mean is "Force the section containing lines 3,4,5, and 6 to occur within the span of one Update, even if that means exceeding CONFIG:IPU by a bit." It would cause a wait 0.001 just beforehand, then start a new fresh update at line 3, then stick with it until like 6, even if it goes past config:ipu instructions to do so.

The reluctance I have with that is that it may create infinite hang of KSP if a script is designed badly, or we might have to enforce that no looping is allowed inside such a section.

But at any rate the name would have to be something besides "ATOMIC". "Atomic" means something to experienced programmers that communicates exactly what the section would do, very well, but would be quite confusing to a typical player who's going to think it's got something to do with atomic engines. One of the kOS design goals is to make it easy for a person new to programming to get ramped up to speed without having to be an expert. I fear that throwing around terminology like "atomic section" might be contrary to that goal.

Edited by Steven Mading
Come on, SQUAD! Turning OFF an extra unwanted feature shouldn't be an "advanced" edit. Let us disable smilelys as a user preference that stays on!
Link to comment
Share on other sites

Ok I just tried it and it didnt work, it gave and error about 'SET VDIST TO VESSEL:DISTANCE.' so it basically threw a tantrum about the first line of code in the FOR loop.

I will try a longer wait time in at the start and try again.

Yeah VESSEL:LOADED doesnt seem to work at all :/

The error I get is always the first line in the FOR loop.

"At test on 1, line 20

SET VDIST TO VESSEL:DISTANCE."

Link to comment
Share on other sites

Actually, looking at the code again I'm surprised it ever worked at all even prior to the vessel blowing up.

VESSEL is the name of a function call. Function calls in kOS are allowed to skip the parentheses and it means the same thing as having no arguments in the parentheses. (so VESSEL:FOO is the same as VESSEL():FOO).

So when you say FOR VESSEL IN RADAR you create an ambiguous override where VESSEL means two things at the same time. It apparently is taking it to mean the variable first, but ...it is weird that it works.

Link to comment
Share on other sites

Hi everyone :)

I am completely new to kOS and also almost completely new to programming as such.

I'm trying to make my first launch and circularization script and i just can't make it work.

I have everything worked out up until the coasting to ap phase, and though it may be crude and ugly it works. However I just can't seem to make the last part work.

I've tried multiple approaches, but frankly, I have no idea what I'm doing wrong :(

Any help would be much appreciated

My code:

 Print "------------------------------------------------------".
Print "Throttle to 100%. Waiting for fuel flow stabilization.".
Print "------------------------------------------------------".


Lock Throttle to 1.0.
Wait 2.
Print "-----------------".
Print "Assuming Control".
Print "-----------------".
Lock steering to heading(90,90).
Wait 2.




Set countdown to -10.
Print " ".
Print "--------------------------".
Print "Launch Sequence Initiated".
Print "--------------------------".

Wait 2.

Until countdown = 0 {
Print "T" + countdown + "s".
Set countdown to countdown +1.
Wait 1.
}

When Stage:Liquidfuel < 0.001 Then {
Print "----------------------------".
Print "No LFO. Attempting to stage.".
Print "----------------------------".
STAGE.
PRESERVE.
}




When ship:altitude > 500 then {
Lock Steering to heading(90,87).
}

When ship:altitude > 1500 then {
Lock Steering to heading(90,85).
}

When ship:altitude > 2500 then {
Lock Steering to heading(90,80).
}

When ship:altitude > 5000 then {
Lock Steering to heading(90,75).
}

When ship:altitude > 8000 then {
Lock Steering to heading(90,65).
}

When ship:altitude > 12000 then {
Lock Steering to heading(90,45).
}





when ship:apoapsis > 100000 then {
lock throttle to 0.
Print "----------------------".
Print "Coasting to apoapsis.".
Print "----------------------".
}

//everything works fine until here


set q to 1.

set u to 1.

if ship:altitude > 90000 {
set q to q - 1.
}

When ship:altitude > 90000 then
{
when eta:apoapsis < 25 then {
set u to u - 1.
}
preserve.
}



when q = 0 then {
Print "prograde".
lock steering to prograde.
}


if u = 0 {
Print "burn".
lock throttle to 1.0.
}

when periapsis > 90000 then {
lock throttle to 0.
}

wait until ship:altitude > 120000.
//end program


//I also tried this


set quak to 0.

when ship:altitude > 90000 then {
if eta:apoapsis = 25
set quak to quak + 1.
}

if quak = 1
Lock steering to prograde.
Print "--------------------------------------------".
Print "Executing circularization Burn".
Print "--------------------------------------------".
Wait 10.
Lock throttle to 1.


Wait until ship:periapsis =99000.
//end program.


//and this, which is direcly from a tutorial

wait until eta:apoapsis < 15.
lock throttle to 1.
print "Burn.".

wait until periapsis = 99500.
//end program

Link to comment
Share on other sites

Hi everyone :)

I am completely new to kOS and also almost completely new to programming as such.

I'm trying to make my first launch and circularization script and i just can't make it work.

I have everything worked out up until the coasting to ap phase, and though it may be crude and ugly it works. However I just can't seem to make the last part work.

Ok, on your first attempt you kept mixing IF statements and WHEN..THEN statements. The WHEN statements appear to be set up correctly, for the most part, but the IF statements are the problem. The WHEN statements are just triggers, so the program continues executing when it finds one, and just stores the trigger condition. That means your IF statements are getting executed immediately upon the program getting to that stage... eg. right after countdown.

So, what the program sees is this, sort of:

Until countdown = 0 {
Print "T" + countdown + "s".
Set countdown to countdown +1.
Wait 1.
}

set q to 1.
set u to 1.
if ship:altitude > 90000 {
set q to q - 1.
}

etc.

with a whole bunch of WHEN's stacked up waiting to happen. That IF evaluates to false, kOS doesn't ever execute the code inside it, and moves on. You need to change those IF statements to WHENs, or better yet, rewrite them as WAIT UNTIL or do things with UNTIL loops. In one case, you have an IF nested in a WHEN, and that one would have to be made a WHEN, I think.

Your second attempt suffers from the same problem. IF statements that evaluate to false and the program moves on.

For the last one, directly from the tutorial. I assume you are locking steering to prograde. Is the engine firing but never stopping on that one? I think it probably just needs the last check changed to ship:obt:periapsis > 99500. "Periapsis" has been deprecated and shouldn't be used anymore, but more importantly, it is unlikely for the periapsis to be exactly 99500 at any physics tick, so waiting until it is greater than the specified value should suffice. Also, it would probably be best to finish with "LOCK throttle TO 0." just to make sure you don't keep going. The program should release control when it starts, and return the throttle to whatever it was set at before it started.

Hope that helps.

Link to comment
Share on other sites

I'm in favor of making this change. I'm using angularvel for a PID controller, but I'd much rather have it make sense and fix my code when the change happens, rather than currently where angular vectors don't make mathematical sense but work because I switched them around.

OK, I've submitted a GitHub issue for this. FWIW, I agree: please break my scripts, if it makes the API better. Just make sure there's an explanation in the changelog so I can make the necessary corrections.

---

Separate question: does anyone know how to get the orbital velocity of the current SOI body, relative to its parent? It appears that body velocities are reported in the SOI-RAW reference frame, which means the SOI body's velocity is zero by definition. I tried BODY:BODY:VELOCITY:ORBIT, but that seems to be undefined when the SOI body is a planet (i.e. BODY:BODY is the Sun).

Link to comment
Share on other sites

Actually, looking at the code again I'm surprised it ever worked at all even prior to the vessel blowing up.

VESSEL is the name of a function call. Function calls in kOS are allowed to skip the parentheses and it means the same thing as having no arguments in the parentheses. (so VESSEL:FOO is the same as VESSEL():FOO).

So when you say FOR VESSEL IN RADAR you create an ambiguous override where VESSEL means two things at the same time. It apparently is taking it to mean the variable first, but ...it is weird that it works.

Ok I now changed it to this :


SET counter TO 0.
UNTIL counter = 10000 {
CLEARSCREEN.
LIST TARGETS IN contacts.
FOR contact IN contacts {
IF contact:DISTANCE < 90000 AND ABS(contact:BEARING) < 45 {
IF contact:BEARING < 0 {SET X TO 1 + (24 - ROUND(ABS(contact:BEARING / 45) * 24)).}.
IF contact:BEARING > 0 {SET X TO 1 + (24 + ROUND(ABS(contact:BEARING / 45) * 24)).}.
IF contact:BEARING = 0 {SET X TO ROUND(contact:DISTANCE / 1000).}.
SET Y TO (30 - ROUND(contact:DISTANCE / 3000)).
PRINT "." AT(X,Y).
}.
}.

PRINT "90" AT (0,0).
PRINT "-" AT (0,3).
PRINT "-" AT (0,7).
PRINT "60" AT (0,10).
PRINT "-" AT (0,13).
PRINT "-" AT (0,17).
PRINT "30" AT (0,20).
PRINT "-" AT (0,23).
PRINT "-" AT (0,27).
PRINT "0" AT (0,30).
PRINT " | | | | | | | | |" AT (0,31).
PRINT " 45 22.5 0 22.5 45" AT (0,32).
SET counter TO counter + 1.
WAIT 0.01.
}.

Still the same error occurs. :/

I didnt use VESSEL this time. I also noticed that the impact of the missile causes alot of debris to appear which vanishes shortly after, I guess because of explosive/thermal damage of the explosion (I made the script pit out all the targets as a continously scrolling list. Went like this :

SHIP

MISSILE

(update)

SHIP

MISSILE

(update)

SHIP

MISSILE(vanishes)

(update)

SHIP(hit)

(update)

SHIP DEBRIS

SHIP DEBRIS

SHIP DEBRIS

(update)

SHIP(remains)

(update)

SHIP

(update)

SHIP

(update)

etc.

It is weird If I do not perform any contact:SOMETHING calls then it works, but it will not give me anything that I can work with.

Edited by VentZer0
Link to comment
Share on other sites

@VentZero: This may be an intractable problem. As a further debug test, try printing out contact:name at the top of each run of the loop, then you can see which one it was working on when it bugged out (i.e. was it the debris, was it the missile, etc).

Link to comment
Share on other sites

Separate question: does anyone know how to get the orbital velocity of the current SOI body, relative to its parent? It appears that body velocities are reported in the SOI-RAW reference frame, which means the SOI body's velocity is zero by definition. I tried BODY:BODY:VELOCITY:ORBIT, but that seems to be undefined when the SOI body is a planet (i.e. BODY:BODY is the Sun).

I think using body:obt:velocity will give you what you want.

Edited by Wercho
Link to comment
Share on other sites

when using the ENCOUNTER method instead of the return being BODY:NAME it gives me "ORBIT of <unnamed>" if there is an encounter or NONE if there isn't.

HERE is the code (munshot.ks) a log of the encounter (minmus.ks) and a video of the script executing.

Link to comment
Share on other sites

@VentZero: This may be an intractable problem. As a further debug test, try printing out contact:name at the top of each run of the loop, then you can see which one it was working on when it bugged out (i.e. was it the debris, was it the missile, etc).

It is interessting

This generates an error.


LIST TARGETS IN contacts.
FOR contact IN contacts {
IF contact:DISTANCE < 90000 AND ABS(contact:BEARING) < 45 {
PRINT contact:NAME.
}.
}.

This does not.


LIST TARGETS IN contacts.
FOR contact IN contacts {
PRINT contact:NAME.
}.

First thing will break up directly after all the debris appears, the other one just goes thru without problem.

If I could check if the part actually has a :DISTANCE suffix that would maybe be enough to fix this bug.

Moar testing ...


LIST TARGETS IN contacts.
FOR contact IN contacts {
WAIT 0.1.
IF contact:DISTANCE > 0 {
SET VDIST TO contact:DISTANCE.
SET VBEAR TO contact:BEARING.
SET VNAME TO contact:NAME.
IF contact:DISTANCE < 90000 AND ABS(contact:BEARING) < 45 {
IF contact:BEARING < 0 {SET X TO 1 + (24 - ROUND(ABS(contact:BEARING / 45) * 24)).}.
IF contact:BEARING > 0 {SET X TO 1 + (24 + ROUND(ABS(contact:BEARING / 45) * 24)).}.
IF contact:BEARING = 0 {SET X TO ROUND(contact:DISTANCE / 1000).}.
SET Y TO (30 - ROUND(contact:DISTANCE / 3000)).
IF NOT (VNAME = "AIM-120 AMRAAM Missile (fired)" OR VNAME = "AIM-9 Sidewinder Missile (fired)" OR VNAME = "AIM-54 Phoenix Missile (fired)") {
PRINT " " + ROUND(contact:HEADING) AT(X,Y-1).
PRINT "U " + ROUND(contact:ALTITUDE) AT(X,Y).
PRINT " " + ROUND(contact:AIRSPEED) AT(X,Y+1).
} ELSE {
PRINT "." AT(X,Y).
}.
}.
}.
}.

Doesn't work either, IF contact:DISTANCE > 0 gives an error.

I wonder why. Is the distance not a number in this instance or is it too quickly gone. I wonder.

It is definitely the :DISTANCE


SET counter TO 0.
UNTIL counter = 10000 {

LIST TARGETS IN contacts.
FOR contact IN contacts {
PRINT contact:NAME.
PRINT contact:DISTANCE.
}.
SET counter TO counter + 1.
WAIT 0.001.
}.

That gives an error.

Edited by VentZer0
Link to comment
Share on other sites

It is interessting

This generates an error.


LIST TARGETS IN contacts.
FOR contact IN contacts {
IF contact:DISTANCE < 90000 AND ABS(contact:BEARING) < 45 {
PRINT contact:NAME.
}.
}.

This does not.


LIST TARGETS IN contacts.
FOR contact IN contacts {
PRINT contact:NAME.
}.

First thing will break up directly after all the debris appears, the other one just goes thru without problem.

If I could check if the part actually has a :DISTANCE suffix that would maybe be enough to fix this bug.

Moar testing ...


LIST TARGETS IN contacts.
FOR contact IN contacts {
WAIT 0.1.
IF contact:DISTANCE > 0 {
SET VDIST TO contact:DISTANCE.
SET VBEAR TO contact:BEARING.
SET VNAME TO contact:NAME.
IF contact:DISTANCE < 90000 AND ABS(contact:BEARING) < 45 {
IF contact:BEARING < 0 {SET X TO 1 + (24 - ROUND(ABS(contact:BEARING / 45) * 24)).}.
IF contact:BEARING > 0 {SET X TO 1 + (24 + ROUND(ABS(contact:BEARING / 45) * 24)).}.
IF contact:BEARING = 0 {SET X TO ROUND(contact:DISTANCE / 1000).}.
SET Y TO (30 - ROUND(contact:DISTANCE / 3000)).
IF NOT (VNAME = "AIM-120 AMRAAM Missile (fired)" OR VNAME = "AIM-9 Sidewinder Missile (fired)" OR VNAME = "AIM-54 Phoenix Missile (fired)") {
PRINT " " + ROUND(contact:HEADING) AT(X,Y-1).
PRINT "U " + ROUND(contact:ALTITUDE) AT(X,Y).
PRINT " " + ROUND(contact:AIRSPEED) AT(X,Y+1).
} ELSE {
PRINT "." AT(X,Y).
}.
}.
}.
}.

Doesn't work either, IF contact:DISTANCE > 0 gives an error.

I wonder why. Is the distance not a number in this instance or is it too quickly gone. I wonder.

It is definitely the :DISTANCE


SET counter TO 0.
UNTIL counter = 10000 {

LIST TARGETS IN contacts.
FOR contact IN contacts {
PRINT contact:NAME.
PRINT contact:DISTANCE.
}.
SET counter TO counter + 1.
WAIT 0.001.
}.

That gives an error.

can you show what the error is, preferably from the output log?

- - - Updated - - -

by the way, put the wait 0.01 before the LIST TARGETS IN contacts. You are getting the list in a different update from when you query its members

Link to comment
Share on other sites

I am trying to enumerate resources of per-part basis and so far i had success on my test craft with "MK1 5m Universal Fuselage" from "B9 Aerospace" pack. It is tagged as "FUSELAGE" and modified with Modular Fuel Tanks.

Below is both command and output (there is no text copy from KOS terminal that i know of, except logging - i manually typed what is shown in terminal).

Dumping list of all present resources for desired part.


PRINT SHIP:PARTSTAGGED("FUSELAGE")[0]:RESOURCES.
LIST of 4 items:
[ 0]= RESOURCE(LiquidFuel,100,100
[ 1]= RESOURCE(Oxidizer,200,200
[ 2]= RESOURCE(MonoPropellant,300,300
[ 3]= RESOURCE(XenonGas,400,400

(NB: missing closing parenthesis at end of line for item in printed list ?)

Detail about desired resource.


PRINT SHIP:PARTSTAGGED("FUSELAGE")[0]:RESOURCE[0]:NAME.
LiquidFuel

Shouldn't be there something like


PRINT SHIP:PARTSTAGGED("FUSELAGE")[0]:RESOURCENAMED("LiquidFuel"):AMOUNT.
100

Or better yet to avoid errors in script by checking first


PRINT SHIP:PARTSTAGGED("FUSELAGE")[0]:RESOURCENAMED("LiquidFuel"):EXISTS.
True

As far as i can tell, there is no such suffix. Until then, KOS script first has to list all resources and match indexes to names before acting on specific resurce by name.

Also where is option to lock specific resource from being used ?

All i know this was already mentioned and there were no direct solutions for this, except when using Diazo's Actions Everywhere which locks all resources at once.

Another idea : log to clipboard. That way player can dump all output and paste in browser, text editor etc...

Example:


LOG SHIP:PARTSTAGGED("FUSELAGE")[0]:RESOURCES TO CLIPBOARD.

Edited by fatcargo
Link to comment
Share on other sites

After much messing around, I finally got my docking script to work...well most of the time anyway.

The code is an absolute mess and my vectors overshoot, as you can see in the video. Basically, I should calculate the needed thrust better (instead of just running a pulse until the desired speed is met). I have ideas of how to make this work better, but I'm going to have to take a break for the next 3 months while RL gets in the way. Thank you Steven for helping me! Here's a pastbin to the code, I added lots of comments to help myself and anyone else who'd look at what's going on. See you guys mid May! Can't wait to see how this has progressed by then!

Link to comment
Share on other sites

can you show what the error is, preferably from the output log?

- - - Updated - - -

by the way, put the wait 0.01 before the LIST TARGETS IN contacts. You are getting the list in a different update from when you query its members

Ok I played around with the WAIT time before the LIST ... command. It seems that this actually has something to do with it, the longer it was the fewer the occurancies of the error.

You can see the error at the very end of the video. That is the only error message I get, nothing else just these two lines even when I don't have anything else printed in the terminal window. It is weird.

If you can tell me where to find the error log for it I will look there, or how to log the output somewhere.

Link to comment
Share on other sites

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