Jump to content

[KSP 1.12.x] kOS v1.4.0.0: kOS Scriptable Autopilot System


Dunbaratu

Recommended Posts

Ah, I hadn't realised you could SET a variable in a PARAMETER line of a function like that.

That tutorial example is using the node:DeltaV continuously in the loop, on a long burn (I tend to use nukes for interplanetary and sometimes do the burn in 2 or 3 stages) wouldn't the rotating co-ordinate system still bring an error in?   Ideally I want to reach the point of not using nodes, I calculate a vector and time for my burn instead.  At the moment I'm cheating somewhat and using the node system iteratively to find the most efficient burn to the Mun.

On ‎04‎/‎04‎/‎2018 at 10:29 AM, Pand5461 said:

 


function toIRF {
// changes to inertial right-handed coordinate system where ix = SPV, iy = vcrs(SPV, V(0, 1, 0)), iz = V(0, 1, 0)
  parameter oldVec, SPV to SolarPrimeVector.
  return V( oldVec:x * SPV:x + oldVec:z * SPV:z, oldVec:z * SPV:x - oldVec:x * SPV:z, oldVec:y).
}

function fromIRF {
// changes from inertial right-handed coordinate system where ix = SPV, iy = vcrs(SPV, V(0, 1, 0)), iz = V(0, 1, 0)
  parameter irfVec, SPV to SolarPrimeVector.
  return V( irfVec:x * SPV:x - irfVec:y * SPV:z, irfVec:z, irfVec:x * SPV:z + irfVec:y * SPV:x ).
}

 

I'm still struggling to get my head around this to be honest.  If I convert to a different frame of reference presumably the idea is I convert the vector back at the time I use it so it's in the current frame of reference, so to get my Mun ejection burn I calculate it in my current frame of reference, but immediately convert it to the SPV frame of reference:

Set IRF MunVector to ToIRF(VelocityAt(Ship,Node:ETA)+ node:DeltaV).

Then as I'm burning I convert that back to the local frame of reference within my loop, so my required acceleration vector would be:

Set CurrentDV to FromIRF(MunVector)-ship:velocity:orbit.

(I know this is slightly over complicated as I could just use the node:deltaV vector but my long term goal is to calculate the ejection burn without using a node, plus I want to be able to split burns across 2 or 3 orbits)

Is that right?

 

My understanding of it based on the posts so far:

  • Below 100km the ship's frame of reference is rotating, meaning that if I get a vector now for some point further down my path, it will have rotated relative to my ship.  Does the frame of reference rotate with the planets orbit (ie 360 degrees per year), or the planets rotation (360 degrees per 6 hours)?
  • Once above 100km the frame of reference switches to something that doesn't rotate.  Presumably this is based on the Solar Prime Vector, so anything I convert in to a left hand SPV frame of reference can be used above 100km without converting back?
  • Is it always 100km from any body's SOI or does it vary for different bodies?
  • V(0,1,0) is the same across all frames of reference, presumably the line through the planets poles?

 

Any chance of a simple explanation of ...

V( oldVec:x * SPV:x + oldVec:z * SPV:z, oldVec:z * SPV:x - oldVec:x * SPV:z, oldVec:y)

...for the hard of thinking.?

Apologies for the amount of questions but my engineering degree was a long time ago and my maths teacher wife lost interest in explaining this stuff when she realised I was doing it for a computer game rather than for work :D

Link to comment
Share on other sites

Me again.

Does the Steering parameter somehow try and steer the ship differently than the SAS?

I'm trying to steer a re-entering ship, but is seems like the controls aren't strong enough.  If I take out my steering parameters so my loop is basically setting a variable to the retrograde vector (and I'm plotting this parameter on the screen so I know it's working ok), and have already got Steering locked to that variable, it starts to loose control at around 20km and swings 30 or so degrees around the prograde marker.  However if I switch SAS on and set it to retrograde it's perfectly stable on the retrograde marker.

(From the bottom, the ship's a Mk1 capsule, an upside down Mk1 capsule, a SAS module, and another Mk1 capsule with a Mk16 and Mk2t parachute.  This isn't completely stable in re-entry and will flap around the retrograde marker a bit if there isn't any steering/sas input)

Link to comment
Share on other sites

35 minutes ago, RizzoTheRat said:

Does the Steering parameter somehow try and steer the ship differently than the SAS?

Yes. kOS's steering manager is a separate steering mechanism, implemented differently to KSP's SAS. For certain designs, one or the other may steer "better" because of this.

That said, are you steering to RETROGRADE or to SRFRETROGRADE? The former would differ from the latter more and more as you slow during descent. SAS steers to the surface or orbital retrograde according to the navball, which automatically switches to surface mode during descent.

Link to comment
Share on other sites

It's surface retrograde but via a function that gives me the bearing and heading of the ship:velocity:surface, so it's actually 

set shipheading to heading(CurrentBearing-180,Attitude-90).  

Where CurrentBearing is the angle of the horizontal surface velocity vector from North and Attitude is the angle of the surface velocity from Up.

The idea being I can then steer by changing the Bearing while keeping the Attitude at Prograde.

 

The roll/yaw/pitch markers don't look like they're reaching their stops.  Looks like it's possible to up the torque applied with the SteeringManager so I guess that might help if applies more torque for a smaller deflection setting.

Link to comment
Share on other sites

Are you locking the steering outside the loop or inside? From what you're saying, I think you're doing it outside, but if you were to lock it inside the loop, it'd reset all the terms of the PID loop each tick, which would not help the steering settle.

It may be just that you have a lot more torque (from all those pods) than kOS's steering manager is expecting/optimised for.

Link to comment
Share on other sites

Steering is locked to the variable Shipheading before the loop, and then Shipheading updated in the loop.

Hadn't thought about the possibility of too much torque, I'll try it with a Pod/Tank/Terrier craft and see if that's any different. 

It's my usual early game tourist orbiter that can re-renter without any steering input if the pilot's inexperienced.  After playing with kOS in a 1.3.1 Sandbox game I've started a 1.4.2 career game trying to use it as much as I can, the lack of parts makes it more of a challenge :)

Link to comment
Share on other sites

9 hours ago, RizzoTheRat said:

Hadn't thought about the possibility of too much torque, I'll try it with a Pod/Tank/Terrier craft and see if that's any different. 

You could disable the reaction wheels in some of the pods, which avoids needing a new design. If kOS is not expecting so much torque, then playing with the steering manager settings would be one solution for that vessel.

Usually, though, kOS is confused by ultra-low-torque designs (e.g. realism overhaul rockets and plane designs), so it's a bit of a punt on my side that it is not working well with lots of wheel torque.

Link to comment
Share on other sites

Yeah, disabling reaction wheels would have been a simpler option, I didn't think of that :D  I had a quick test with a Mk1 pod/FL-T200/Terrier upper stage and it suffered the same problem (until the Terrier exploded, need to experiment to re-rentry profiles it seems)

I then tried the original craft but with the steering manager torque factors set to 2, and then again at 3.  Both these still flapped about but only up and down in pitch (looked like it had a stable position 20 or so degrees above and below the retrograde but couldn't react fast enough to hold retrograde), and held stable in roll/yaw.

I'm guessing maybe the extra torque means it overcompensates as it nears the retrograde and so carries on past it, or possibly it reacts slower than SAS.

I know however that this craft isn't stable in retrograde, but will want to sit 20 or so degrees off, so the obvious way to fix this is to design a ship that's stable in retrograde, kind of a shame though as this is a useful early career ship and SAS can overcome its stability issue.  No that I really need to steer this one anyway as it still comes down pretty close to the KSC without aerodynamic steering, but I was just using it as a test bed.   My usual later game SSTO designs that I'm really working towards have a significant proportion of the mass in the engines by the time they re-renter, so should be pretty stable.

I think I might park this one and go back to developing my Mun script.

Link to comment
Share on other sites

20 minutes ago, Kartoffelkuchen said:

Is there any way to get the correct roll angle of an airplane (relative to the surface)? I really am starting to give up on this, the only thing I want is the (relative) roll of the aircraft around its longitudinal axis.

I use this code

declare function find_angle
{
declare parameter v.
declare parameter v0.
declare parameter v90.

return arctan2(v:normalized*vxcl(v0,v90):normalized, v:normalized*v0:normalized).
}

declare function get_roll
{
local shipup is ship:facing:upvector.
local ax is ship:facing:vector.
local u is vxcl(ax, ship:up:vector):normalized.
local r is vcrs(u, ax).

return find_angle(shipup, u, r).
}

Note that find_angle is made to distinguish left and right by also using a +90 degrees vector

 

also, you may be interested in roll-included version of heading

declare function heading2
{
declare parameter az.
declare parameter ptc.
declare parameter rll. //positive = right

local d1 is heading(az,ptc).
return angleaxis(-rll, d1:vector)*d1.

}

 

Link to comment
Share on other sites

4 minutes ago, Alchemist said:

I use this code


declare function find_angle
{
declare parameter v.
declare parameter v0.
declare parameter v90.

return arctan2(v:normalized*vxcl(v0,v90):normalized, v:normalized*v0:normalized).
}

declare function get_roll
{
local shipup is ship:facing:upvector.
local ax is ship:facing:vector.
local u is vxcl(ax, ship:up:vector):normalized.
local r is vcrs(u, ax).

return find_angle(shipup, u, r).
}

Note that find_angle is made to distinguish left and right by also using a +90 degrees vector

 

also, you may be interested in roll-included version of heading


declare function heading2
{
declare parameter az.
declare parameter ptc.
declare parameter rll. //positive = right

local d1 is heading(az,ptc).
return angleaxis(-rll, d1:vector)*d1.

}

 

Beautiful, thank you so much!

Link to comment
Share on other sites

15 minutes ago, Drew Kerman said:

You mean the docs? Or is there actually a wiki that might be outdated? Anyways, the term you were looking for was break

http://ksp-kos.github.io/KOS_DOC/language/flow.html?highlight=break

No, break is not a continue.  They're different things.

@scimas- kerboscript does not have a continue.  Perhaps it should and it could be added.  Although I never liked the name "continue" because it's a misleading name for it (it's the exact opposite of "continuing" given that what it does is abort the current iteration and skip to the next.  In my mind, the word "continue" implies doing what always happens anyway - going on to the next line of code like normal.)

If I added it I'd pick some other name for it - maybe "next" or "skip", as that's more indicative of what it actually does.

Edited by Steven Mading
the @scimas was misspelled so the notification wouldn't have been made
Link to comment
Share on other sites

2 minutes ago, Steven Mading said:

No, break is not a continue.  They're different things.

You're correct. When I skimmed the post I thought he wanted to continue to the next line of code outside the loop, not the next iteration of the loop as he literally so clearly states

I should probably move "checking KSP forums" further down my ToDo list in the morning so I'm more awake :confused:

 

Link to comment
Share on other sites

3 hours ago, Drew Kerman said:

You mean the docs?

Yes, I meant the docs, 'wiki' was just a slip.

 

3 hours ago, Steven Mading said:

If I added it I'd pick some other name for it - maybe "next" or "skip", as that's more indicative of what it actually does.

Though I agree that "skip" might be more intuitive, wouldn't it be better to stick to convention? If people have been using 'skip' as a variable name, it might break (no pun intended, though it is a nice one :D) their scripts. The same case can be made for 'continue' too, but I think those familiar with programming wouldn't use it as a variable name - leading to perhaps less number of broken scripts?

Link to comment
Share on other sites

On 06.04.2018 at 12:07 PM, RizzoTheRat said:

That tutorial example is using the node:DeltaV continuously in the loop, on a long burn (I tend to use nukes for interplanetary and sometimes do the burn in 2 or 3 stages) wouldn't the rotating co-ordinate system still bring an error in? 

...

The good thing about the in-game node:deltav is that it's adjusted accordingly by the game engine, so rotating frame does not matter. The game also updates node:deltav with the progress of the burn

Your code for calculation of the remaining dV for ejection seems sane. For a "node without a node", might be an easy-to-implement solution.

There is also a solution used on shuttles as "external Lambert DeltaV routine" - constantly recalculate a trajectory that starts at current vessel position and intercepts the target object, obtain dV to change to that trajectory and steer to that dV vector. This is obviously more complicated but quite doable if you can implement an intercept solver (Lambert's problem, one of the solver algorithms is described on the Braeunig's page).

On the rotational speed: the frame does 360 degrees in the sidereal period of body (5h 50-something min for Kerbin). This means, if you have a fixed object on surface of planet, then (ship:body:position - object:position) will always output the same vector. This also means that the rate of change of ship:body:position is consistent with ship:velocity:surface in the rotating frame and ship:velocity:orbit in the inertial frame.

When the ship gets above the rotating-to-inertial transition altitude, ship:body:position remains continuous, as far as I can tell. That means, coordinate axes do not suddenly align with the SolarPrimeVector on the transition. If you get a ship to a high altitude and query SolarPrimeVector from kOS, you will most likely see it's not V(1,0,0) but more like V(cos(a),0,sin(a)). It's just that it does not change in time at high altitudes at appears rotating (in fact, it's coordinate axes that are rotating) at low altitudes. So, if you have a vector in SolarPrimeVector frame, you still need to convert it to the kOS frame, but then you can use the converted vector indefinitely without worrying that it stops representing the correct direction.

I'm not sure whether transition altitude is the same for all bodies or not. Most likely, it's different. I know for sure the transition altitude is not 100 km on the parent body in scaled systems.

V(0, 1, 0) is universal, that is correct, just note that ecliptical plane in modded systems is not necessarily normal to this vector (most notable example is RSS). Kopernicus devs can probably better comment on this topic, if you are really interested.

On 06.04.2018 at 12:07 PM, RizzoTheRat said:

Any chance of a simple explanation of ...


V( oldVec:x * SPV:x + oldVec:z * SPV:z, oldVec:z * SPV:x - oldVec:x * SPV:z, oldVec:y)

...for the hard of thinking.?

Just the orthogonal projections to the newly chosen coordinate axes.

We know that SPV = V(SPV:x, SPV:y, SPV:z) by definition, we also assume that SPV:y = 0, meaning SPV lies in the equatorial plane, and SPV:x^2 + SPV:z^2 = 1, meaning SPV is a unit vector.

Given that assumptions, the projection of any vector onto SPV is VDOT(oldVec, SPV) = oldVec:x * SPV:x + oldVec:z * SPV:z. This is exactly the X component of the return vector in question.

The direction SPV2 orthogonal to the SPV in the XZ plane may be either V(-SPV:z, 0, SPV:x) or V(SPV:z, 0, -SPV:x). I opted to make [SPV, SPV2, V(0,1,0)] a right-handed triplet, so I chose SPV2 = V(-SPV:z, 0, SPV:x), another option will give a left-handed triplet. VDOT(SPV2, oldVec) is the Y component of the return vector.

Link to comment
Share on other sites

Thanks, I'll have a play with changing vector in to SPV and back.

I think it should be pretty simple to implement something similar to the Lambert approach.  Currently I'm working out the required dV for a Mun shot using the Vis-viva equation for an orbit with my Kerbin altitude (plus kerbin radius) as the periapsis and the Mun altitude for Apoapsis to give the velocity needed at perispsis.  I If I were to keep recalculating this to get the remaining dV it should sort out errors caused by the duration of the burn.

At the moment I'm using this calculated dV to put a node in, and then burning node:deltaV until I get the required Mun periapsis, but the vector translation stuff should let me do away with the node completely but getting a tangential vector at the right time.

 

 

Link to comment
Share on other sites

What is a good way of dealing with divisions by zero in kos? To be specific, sometimes I want to lock burntime calculation, which has a division by ship:availablethrust. The availablethrust is of course not guaranteed to be non zero at all times.

I could limit the value by something like min(calculation_that_has_division_by_zero, ridiculously_large_number).

So that it's unrealistically large, but still not infinite. But I would prefer to not have to do that if there are other more elegant ways to deal with it.

Edited by scimas
was using wrong example to demonstrate
Link to comment
Share on other sites

33 minutes ago, scimas said:

 min(calculation_that_has_division_by_zero, ridiculously_large_number).

That would still error out when calculating the division by zero, before it got to doing the min().

A better approach might be this:

If you think that X / Y might fail because Y might be zero, and you'd like a bignumber result when Y is zero, try maybe doing this:

x / max(y, 0.0001)

In other words, limit how close to zero the denominator is allowed to become.  The example shown wouldn't let it get closer to zero than 0.0001.

- Warning: the above example presumes Y is something that isn't expected to become negative.  Because max(-900, 0.0001) would return 0.0001.

 

Link to comment
Share on other sites

Hey, I've just started playing KSP again after a long hiatus. kOS doesn't seem to be working for me any more. Are you all playing on KSP v1.4.1? I'm on 1.4.2 due to Steam patching my game whether I like it or not. Am I missing something about how to get it working, or do I just need to wait for an update?

Edited by Hyperlynx
Link to comment
Share on other sites

3 hours ago, Hyperlynx said:

Hey, I've just started playing KSP again after a long hiatus. kOS doesn't seem to be working for me any more. Are you all playing on KSP v1.4.1? I'm on 1.4.2 due to Steam patching my game whether I like it or not. Am I missing something about how to get it working, or do I just need to wait for an update?

Just get the kOS version for KSP 1.4.1.  It works on KSP 1.4.2 just fine - it's just that CKAN and Spacedock and Curse don't know that.  If you ask them to allow you to install "incompatible" versions so it will list it, it works.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...