Jump to content

kOS Scriptable Autopilot System 0.9


KevinLaity

Recommended Posts

My guess would be that the program ends the instant after you launch. kOS probably resets throttle after that happens. Try adding "wait 10." or something after "stage."

Bingo! I had sure that I forgot something! Thanks a lot!

Link to comment
Share on other sites

The above won't work. You need vector math to do it properly you can't just convert vectors to their magnitudes and expect things to work, last time I tried to build code like this in kOS vector math was only implemented for some very specific situations. I requested it but got no response. I'm still hoping Kevin gets round to it. There's a really lame workaround, split the vectors into x/y/z variables and do the math yourself.

A computer system on board a rocket like this one will primarily be used as a navigation tool. You can't do navigation without a proper implementation of vector math. I really like kOS but without vector math it's not usable for me. I'm really eager, I think kOS and a handfull of scripts should be able to replace mechjeb.

What I've been trying to do (with the node calculations) is use the nextNode:deltaV:mag as the the reference for the throttle control. Something like: if (nextNode:deltaV:mag<1 and isBurning=1) {throttle = 0.}. It works, sort-of, but the script is so slow that it overshoots before the system realizes. If it doesn't overshoot and stop, then the node flips and the ship starts wandering in an attempt to chase it back. A good formula for the throttle control would be a boon, but I've yet to find one gradual enough. Hopefully there's a more simple solution less prone to failure, but it seems it doesn't exist yet.

I really do hope some more apparent (and less process intensive) ways of completing these basic tasks get implemented. If not, I'll settle for "else if..." and "else..." statements and making "=" synonymous with "to" in set and lock statements. "else if..." especially, it would considerably simplify my logical checks. Oh! And a logical statement for "not". That would help too.

Edited by Stiggles
Link to comment
Share on other sites

@Stiggles:

I get repeatable circular orbits with 1% error. My recipe works by designing your burn to exactly reach the orbital velocity for the orbit. Then the maneuver node and the burn must exactly provide deltav up to the orbital velocity. Step by step:

1. calculate orbital velocity: set ov to (G * mk / r)^0.5. with G: gravitational constant, mk: Kerbin mass, r: radius of orbit, r = 600000 + apoapsis

2. There is no good way to determine your velocity at apoapsis while coasting there. I continuously recalculate velocity:orbit:mag - ov until the burn starts.

3. When does the burn start? Well, half of the burn time before apoapsis so you distribute your deltav around apoapsis evenly.

4. How long is your burn? You know your deltav and the acceleration your engine(s) provide (which is deltav per second). Engine acceleration a is F/m (force by mass), set maxA to maxthrust/mass, and then set burnduration to deltav / maxA.

5. During the end of the burn the node target indicator will wander off as deltav gets close to 0. In order to avoid uncontrolled gearing I unlock steering and turn on sas to keep the ship stable.

I uploaded my script and craft to kOS Wiki for reference.

Regards, Andreas

far2.txt

orbiter2.craft

PS: There is an issue with unlocking steering in the end. The script retains the NODE locked earlier while on the console it can be unlocked. Any workaround?

Edited by baloan
Link to comment
Share on other sites

@willow:

Actually I was collecting which modules might be worth implementing:

1. create kOS modules

a) ascent w/ (Kerbin)

B) w/o atmosphere (Mun)

c) orbit circularisation

d) descent & landing w/ and w/o atmosphere

e) Mun transfer

f) interplanetary transfers

g) docking

and then there are some kOS challenges:

2. send satellites to each planet & moon

3. land rovers on each planet & moon

4. land & return manned missions

but also some problems which are currently unsolved:

5. how to operate rcs for maneuvering?

6. how to align for interplanetary transfers? (requires planetary coordinates relative to the sun)?

7. how to run multiple missions simultaneously? Autonomous engine burns? Can kOS run in the background?

5. to 7. are feature requests.

Regards, Andreas

KSP 0.22.0 with kOS 0.9.1 - nothing else.

Link to comment
Share on other sites

What I've been trying to do (with the node calculations) is use the nextNode:deltaV:mag as the the reference for the throttle control. Something like: if (nextNode:deltaV:mag<1 and isBurning=1) {throttle = 0.}. It works, sort-of, but the script is so slow that it overshoots before the system realizes.

One thing I'm coming to realize is the need to anticipate what the value WILL be at the next iteration, and then pick a setting halfway between that value and the value you have now as the number to work from in calculations like these. In my case I'm trying to make a "suicide burn" landing script that burns the least amount and waits until the bottom to burn, but the error you get from slow iterations means my script is always calculating based on what the situation WAS a half second ago, not what it is now. That "slight" error can mean about 10-20 m/s difference in impact speed.

It's slightly different from what you need it for but the basic problem is the same problem. We're both trying to calculate a thing once per iteration of a loop, which is essentially the problem of approximating calculus by using a finite number of timeslices, and our timeslices are large enough to cause error.

Here, with amount of deltaV remaining what that means is this:

1 - Keep track of the deltaTime your loop is taking to execute by comparing missionTime this iteration to missionTime last iteration.

2 - Using maxthrust, throttle setting, mass, and delta time, you should be able to calculate a fairly accurate idea of how much your speed is expected to change per loop iteration at this throttle setting: dV per iteration = (delta Time) * ( (current throttle * maxthrottle) / mass )

3 - decide your program behavior based on what the dV WILL be next iteration. not what it is now.

In your case, try this: If the node dV remaining after next iteration is predicted to be zero or less than zero, then adjust your throttle down NOW, but not all the way down to zero. Scale it down based on how much you're going to overshoot. (i.e. if the current throttle setting would give you three times as much dV as you needed to get to zero in the next iteration, then cut your throttle to 1/3 of what it was. That should finish the job in the next iteration.)

Or alternatively, for more accuracy, add a fudge factor to reduce the throttle by a bit more than the amount needed to get to zero, so there will still be a bit of dV left next iteration. This will make the throttle slower and slower and slower and make it asymptotically approach the right delta V rather than get there in one single iteration (which is still likely to overshoot a bit).

Link to comment
Share on other sites

Which might look like this:

// calculate maneuver properties

// Errors in calculation: a) velocity points upward, traveling to apoapsis
// causes horizont to turn "down". Calculation is correct only at apoapsis.
// Thus burn parameters are adjusted while travelling to apoapsis.

set maxda to maxthrust/mass.
print "T+" + round(missiontime) + " Max DeltaA for engine: " + maxda.
set vom to velocity:orbit:mag.
set dv to (ov - vom).
set tfb to dv/maxda.
print "T+" + round(missiontime) + " DeltaV for final burn: " + dv.
print "T+" + round(missiontime) + " Duration of final burn: " + tfb.

set x to node(time:seconds + eta:apoapsis, 0, 0, dv).
add x.
// warp only
when alt:radar > 50000 then { set warp to 2. }
when eta:apoapsis < tfb/2 + 30 then { set warp to 0. }
lock steering to x.
// iteratively correct burn parameters
until eta:apoapsis < tfb/2 {
set vom to velocity:orbit:mag.
set dv to ov - vom.
set tfb to dv/maxda.
set x:prograde to dv.
print "DeltaV for final burn: " + dv at (0,29).
print "Duration of final burn: " + tfb at (0,30).
wait 1.
}
print "T+" + round(missiontime) + " DeltaV for final burn: " + dv.
print "T+" + round(missiontime) + " Duration of final burn: " + tfb.
// lock steering to node:prograde which wanders off at small deltav
when x:deltav:mag < 2 * maxda then {
print "T+" + round(missiontime) + " Reducing throttle, fuel:" + stage:liquidfuel.
// continue to accelerate x:prograde
unlock steering.
sas on.
}
print "T+" + round(missiontime) + " Orbital burn start " + round(eta:apoapsis) + " s before apoapsis.".
set th to 1.
lock throttle to th.
until velocity:orbit:mag > ov {
set thrust to maxthrust * throttle.
set da to thrust/mass.
set newth to x:deltav:mag * mass / maxthrust.
if x:deltav:mag < 2 * da and newth > 0.2 {
set th to newth.
}
print "Thrust: " + thrust at (0,28).
print "DeltaA: " + da at (0,29).
print "Node DeltaV: " + x:deltav:mag at (0,30).
}
lock throttle to 0.
remove x.
print "T+" + round(missiontime) + " Orbit complete, apoapsis: " + apoapsis + ", periapsis: " + periapsis.

Link to comment
Share on other sites

I have a question. Is there a tutorial explaining how to create a MechJeb-style ascent profile? I'm using FAR and thus need to mind my AoA, so simple "lock steering to heading 90 by 45" will result in a rocket "falling off it's tail" and flipping. I'd really like to get into using KOS, it seems very realistic to steer a spacecraft by executing various programs.

Link to comment
Share on other sites

I have a question. Is there a tutorial explaining how to create a MechJeb-style ascent profile? I'm using FAR and thus need to mind my AoA, so simple "lock steering to heading 90 by 45" will result in a rocket "falling off it's tail" and flipping. I'd really like to get into using KOS, it seems very realistic to steer a spacecraft by executing various programs.

This is a bit of old code, don't know if it works with the latest kOS, but I used to use this:


until apoapsis > orbitAltitude {
set pitch to -90.
if apoapsis < 69078 {
set pitch to 0 - (apoapsis / 768).
}.
lock steering to UP + R(0,0,180) + R(0,pitch,0).
}.

This causes the pitch to gradually decrease during ascent. 69078m is the height of Kerbin's atmosphere. Once the peak of the orbit has cleared the atmosphere, it'll be thrusting completely horizontally, putting all its energy into circularizing the orbit.

Edited by Gaius
Link to comment
Share on other sites

That's nice, but I need a customizable function that would essentially duplicate MechJeb's ascent functionality. For example, I've got a turn that starts at 0.5km and ends at 250km, with the 35% curve grade. Also, it needs to be terminated before it's fully executed, after a certain mission time has elapsed (that's because of peculiar characteristics of the particular rocket it's supposed to run on). I need a function that can give similar turn to what MechJeb does in such conditions. I know how to start it and what to do once the turn is terminated, but the function itself eludes me. Oh, and I'd rather have it not depend on any other constants, since it also has to work on Earth-size Kerbin. I'd like to know how exactly MechJeb calculates it's turn, maybe it'd help.

Link to comment
Share on other sites

Dragon01, I did something like this in 0.84, not sure if it's good enough. (incFlag is used to make sure I didn't go below 10 degrees when doing the gravity turn.)


if altitude > 500 {
if incFlag=0 {
set tfv to velocity:surface.
set tfA to latitude.

set tfupyaw to up:yaw.
set tfB to 0 - tfupyaw.

set tfW to tfv:x*cos(tfB) + 0 + tfv:z*sin(tfB).
set tfN to tfv:x*sin(tfA)*sin(tfB) + tfv:y*cos(tfA) + tfv:z*(0-sin(tfA)*cos(tfB)).
set tfU to tfv:x*(0-cos(tfA)*sin(tfB)) + tfv:y*sin(tfA) + tfv:z*cos(tfA)*cos(tfB).

set tfE to 0 - tfW.

set tfradius to (tfe^2 + tfn^2 + tfu^2)^0.5.

set incl to arcsin(tfu/tfradius).

lock steering to heading angle by incl-10.
if incl<10 {set incFlag to 1.}.
}.
}.

Link to comment
Share on other sites

That's nice, but I need a customizable function that would essentially duplicate MechJeb's ascent functionality. For example, I've got a turn that starts at 0.5km and ends at 250km, with the 35% curve grade. Also, it needs to be terminated before it's fully executed, after a certain mission time has elapsed (that's because of peculiar characteristics of the particular rocket it's supposed to run on). I need a function that can give similar turn to what MechJeb does in such conditions. I know how to start it and what to do once the turn is terminated, but the function itself eludes me. Oh, and I'd rather have it not depend on any other constants, since it also has to work on Earth-size Kerbin. I'd like to know how exactly MechJeb calculates it's turn, maybe it'd help.

I've been toying with a polynomial function to keep the angle in check. This one has been working for me during my launches (I am using FAR):


[COLOR="Blue"]lock [/COLOR][COLOR="Black"]pVal [/COLOR][COLOR="Blue"]to [/COLOR][COLOR="Black"]-[/COLOR][COLOR="Orange"]1[/COLOR][COLOR="Black"]*([/COLOR][COLOR="Orange"]1.25[/COLOR][COLOR="Black"]*([/COLOR][COLOR="Purple"]altitude[/COLOR][COLOR="Black"]/[/COLOR][COLOR="Orange"]1000[/COLOR][COLOR="Black"])+([/COLOR][COLOR="Orange"]45[/COLOR][COLOR="Black"]*([/COLOR][COLOR="Purple"]apoapsis[/COLOR][COLOR="Black"]/[/COLOR][COLOR="Black"]tAlt[/COLOR][COLOR="Black"])^[/COLOR][COLOR="Orange"]2[/COLOR][COLOR="Black"])).[/COLOR][COLOR="Black"]
[/COLOR][COLOR="Blue"]lock [/COLOR][COLOR="Purple"]steering [/COLOR][COLOR="Blue"]to [/COLOR][COLOR="Purple"]up [/COLOR][COLOR="Black"]+ [/COLOR][COLOR="Black"]R[/COLOR][COLOR="Black"]([/COLOR][COLOR="Orange"]0[/COLOR][COLOR="Black"],[/COLOR][COLOR="Orange"]0[/COLOR][COLOR="Black"],[/COLOR][COLOR="Orange"]180[/COLOR][COLOR="Black"]) + [/COLOR][COLOR="Black"]R[/COLOR][COLOR="Black"]([/COLOR][COLOR="Orange"]0[/COLOR][COLOR="Black"],[/COLOR][COLOR="Black"]pVal[/COLOR][COLOR="Black"],[/COLOR][COLOR="Orange"]0[/COLOR][COLOR="Black"]).[/COLOR]

It definitely could use some work, though. This has a check inside the main launch loop that halts it if the ship reaches horizontal and the ship will burn gradually more horizontal as the apoapsis approaches the target altitude. If you want it to turn faster, change the coefficient on the first term (The 1.25; effectively 1.25 degrees for every 1000 meters of altitude). The coefficient on the second term adjusts the maximum effect (in degrees) of the apoapsis approaching the target altitude.

Edited by Stiggles
Link to comment
Share on other sites

That's nice, but I need a customizable function that would essentially duplicate MechJeb's ascent functionality. For example, I've got a turn that starts at 0.5km and ends at 250km, with the 35% curve grade. Also, it needs to be terminated before it's fully executed, after a certain mission time has elapsed (that's because of peculiar characteristics of the particular rocket it's supposed to run on). I need a function that can give similar turn to what MechJeb does in such conditions. I know how to start it and what to do once the turn is terminated, but the function itself eludes me. Oh, and I'd rather have it not depend on any other constants, since it also has to work on Earth-size Kerbin. I'd like to know how exactly MechJeb calculates it's turn, maybe it'd help.

1) Get your current altitude and subtract the altitude of where you want to start turning. If its negative go straight up instead.

2) Choose an altitude where you want to stop turning and subtract the altitude where you start, then divide the value from 1) by that number. Think of something clever for when you're above the turn end that doesnt cause bugs.

3) Vessel specific: Figure out some function that maps from [0,1] -> [90,0] for your pitch angle and use it on the value from 2)

You could try a similiar function of altitude to define a target speed or thrust setting

To prevent the angle of attack getting out of hand compute the angle between your prograde vector and the vector you want to lock onto. If that exceeds some safety limit then only change steering up to that point.

Link to comment
Share on other sites

I don't know if this has been addressed since the beginning versions, but has the issue with loading programs been fixed? i used to write a program and then it would be gone whenever i went into the VAB and back onto the launch pad, or even reverted to that same launch. Do you have to start an archive before hand, then create a program file and save it to that archive?

Link to comment
Share on other sites

and how do you direct it to save it in that specific archive volume?

If making a new program from scratch:


switch to archive.
edit programname.

If you have a program already on the local volume and want to move it to the archive;


copy programname to archive.

Link to comment
Share on other sites

kOS9.0 is the first and only plugin in my game.

I had a SPH (PRELAUNCH) plane on the grass by the runway, a VAB plane (LANDED) on the runway and a VAB rocket in space in a comfortable orbibt around kerbin, all three with space computers.

I'd been playing with rotaions and vectors, and had finally worked out the formulae I wanted. I left it in the rocket console when I went to bed.

I woke in the morning to find myself statring at a catastrophic failure for my rocket - despite being in orbit it had, apparently, collided with the launchpad. when I switched to the spaceplane on the runway, it blew up. the capsule was launched into the air, and then vapourised. I swithced to the remaining plance, it too blew apart. the capsule travelled ("skimmed") across the grass without any rotation or deceleration at ~19m/s.

the revert to launch option allowed me to go back to this about to explode plane, and goging to the space center and switching to the plance also resulted in it exploding

I put a launch towered rocket on the pad (which gave an almighty lean on physics start) and was then able to switch to the plane which behaved normally.

Link to comment
Share on other sites

When running some programs from the archive it says Error on line 0: Syntax Error. But there is not any syntax error!

I run another program that has the same thing on line 0 and it runs just fine?? Does anyone know about this error?

Link to comment
Share on other sites

When running some programs from the archive it says Error on line 0: Syntax Error. But there is not any syntax error!

I run another program that has the same thing on line 0 and it runs just fine?? Does anyone know about this error?

It's impossible to give a concrete answer without seeing the code, but here's one quick thing that may help explain it:

When KOS tells you there's an error on a line number, the line number it reports to you is often utterly wrong, especially if it's saying line number 0. Just because it says line 0 doesn't mean it really is line 0. It could be anywhere in the program.

The line number problem is a bug that seems especially difficult to get rid of, as Kevin keeps claiming it's fixed in each release and yet it keeps happening.

Link to comment
Share on other sites

Here's the code:


set Final to 250000.

set t to 0.
Lock throttle to t.

clearscreen.
Print 3. wait 1.
Print 2. wait 1.
Print 1. wait 1.
set t to 1.
lock steering to up.
Print "Launch!".
stage.

if stage:solidfuel > 0 {
set SRB to 1.
}.
if stage:solidfuel < 1 {
set SRB to 0.
}.

when stage:solidfuel = 0 AND SRB = 1 then {
stage.
set SRB to 0.
}.

when altitude > 500 {
lock pVal to -1*(1.25*(altitude/1000)+(45*(apoapsis/Final)^2)).
lock steering to up + R(0,0,180) + R(0,pVal,0).
}.

until apoapsis>0.9*Final {
if stage:liquidfuel=0 {stage.}.
}.

lock steering to prograde.
set t to 0.5.

until apoapsis>Final {
if stage:liquidfuel=0 {stage.}.
}.
set t to 0.

until altitude > 105000 {
if apoapsis < Final and t<0.1 {set t to t+0.025.}.
if apoapsis > Final {set t to 0.}.
if stage:liquidfuel=0 {stage.}.
}.

I made this program just to test Stiggles function and KOS refuses to run it :P

Link to comment
Share on other sites

Just a quick question:

So, my scripts are saved to the Archive volume fine, but can new volumes be saved permanently? Or do I have to copy all the necessary scripts at the start of each launch? It doesn't seem to save new volumes, even after saving the game, starting the launch etc.

Link to comment
Share on other sites

Just a quick question:

So, my scripts are saved to the Archive volume fine, but can new volumes be saved permanently? Or do I have to copy all the necessary scripts at the start of each launch? It doesn't seem to save new volumes, even after saving the game, starting the launch etc.

As far as I understand it you have to copy programs from your rocket(s) volume to the archive to save it permanently. Though I thought I saw somewhere something about them being saved in the quicksave/persistant file but maybe that was just variables. I've not really tested to see if my programs stay on the volume if I launch a rocket, get to orbit, save then reload.

Link to comment
Share on other sites

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