Steven Mading

[1.4.1] kOS v1.1.5.2 : kOS Scriptable Autopilot System

Recommended Posts

Ok, so in relation to a shuttle launch script I've been working on, I'm trying to create a function that generates the thrust and torque vectors produced by the engines.

Since engine gimbals moving would obviously change the direction of the thrust vectors, I want to account for that in my equations. However I've come across something that's left me scratching my head, that is, what exactly does the "roll" of the gimbal mean?

5apw6Hj.jpg

This is a test I ran. I told kOS to display the eng:gimbal:range*eng:gimbal:<insert_axis_here>angle as I figured this would give the angle the engine bell was deflected in each axis. I thought that, since there is only one engine, there should be no roll deflection at all, but apparently the engine somehow has roll gimbal? This would only make sense if there were vanes in the nozzle, or multiple that could add swirl to the exhaust plume, but the engines don't really act like that. The rapier, mammoth, and twin boar are the only ones with multiple nozzles.

So really there is only two axis that the engine deflects in, the pitch and yaw axis. If you have two engines on opposing sides, they can produce torque in the roll axis by deflecting in opposite directions in the pitch axis, but they themselves are not gimbaling in the roll axis.

So how do I make mathematical sense out of this? Am I missing something simple that would allow my script to get what it needs?

 

Not even really sure if this is a kOS question or a KSP question.

Edited by EpicSpaceTroll139

Share this post


Link to post
Share on other sites

Does anyone have a guided missile code that works? I just need something nice and simple, no need to account for a moving target. Just double click on a stationary target and have it follow a trajectory to get to that target.

Share this post


Link to post
Share on other sites
On 10/16/2017 at 10:18 AM, Steven Mading said:

That's not what I meant.  That's resetting to the beginning of a task.  In that context you don't need to remember any variable values other than just which mode you were in.  I was talking about having to pick up right where you left off, and thus needing to remember things like what the value of a loop counter was, what a running total in a variable was, etc.  (Basically, like hibernation mode on a PC).  Howver, yes, given the tasks these autopilot scripts are doing, it is usually possible to restart at a reasonable point, as CheersKevin's scripts usually do.  It's a good-enough solution to the problem given the kinds of tasks these programs do.  To a large extent it works because all the variables you need to remember can be queried again from the system ( ship position, ship velocity, what planet are we around, etc), instead of *actually* having to save the full memory context.

so what is needed here is a "quicksave" vessel state before packing?

Share this post


Link to post
Share on other sites

Are the arguments of the R() function actually pitch, yaw and roll values as mentioned in the docs or are those rotations around X, Y and Z axis? If its the former, then there's something really wrong with my understanding of how rotations work. If it's the latter, please change the docs to say that. Please clarify the Q() function too. Are the args quaternion components or (x,y,z, rotation angle) where (x,y,z) would give the axis of rotation?

I've spent entirely too much time trying to understand how directions and kOS direction operations work and I still don't think I understand it. In the end I started using cross products on up:vector, ship:velocity:orbit/surface and Rodrigues' rotation formula to get things done.

Share this post


Link to post
Share on other sites
7 hours ago, scimas said:

Are the arguments of the R() function actually pitch, yaw and roll values as mentioned in the docs or are those rotations around X, Y and Z axis? If its the former, then there's something really wrong with my understanding of how rotations work. If it's the latter, please change the docs to say that. Please clarify the Q() function too. Are the args quaternion components or (x,y,z, rotation angle) where (x,y,z) would give the axis of rotation?

I've spent entirely too much time trying to understand how directions and kOS direction operations work and I still don't think I understand it. In the end I started using cross products on up:vector, ship:velocity:orbit/surface and Rodrigues' rotation formula to get things done.

They are around x, y, and z.  The use of the words "pitch", "yaw", and "roll" is quite wrong and date back to the start of the mod under Kevin Laity.  I have no idea why he chose those terms  The problem is that it has too much legacy to change the terms now.  Doing so would break every script anyone has ever wrote.  The Q() args are the quaternion components, which for some reason Unity itself calls x,y,z,w even though they're NOT x,y,z, rotation angle so I don't know why it used those terms.

The fact that pitch/yaw/roll mean rotation around the axes and not around the ship's orientation is mentioned in several places through the docs, but I guess not right next to where the R() function is defined so it should be mentioned there too.

 

  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, Steven Mading said:

Doing so would break every script anyone has ever wrote.

I don't understand.. If the R function does give rotations around the axes and not ship local rotations, why would changing the docs to reflect this fact break scripts? You aren't changing anything in kOS code itself, just clarifying the real working of the function in the docs. Same about the Q function, I'm just asking for clarity in the docs, not asking to change how kOS works. 

Because at least my method of learning any new programming language is to start with a tutorial, if one is provided, and then to look up any differemt/interesting/difficult things in the docs. I went from kOS tutorial to mathematics -> directions and found out that it doesn't make any sense, even accounting for the left handed system. 

Anyway, thanks for the clarification! 

Share this post


Link to post
Share on other sites
5 minutes ago, scimas said:

I don't understand.. If the R function does give rotations around the axes and not ship local rotations, why would changing the docs to reflect this fact break scripts?

Because I wasn't talking about just changing the docs.  I was talking about what it would take to actually fix the real problem, which is that they shouldn't *be* called "pitch", "yaw", and "roll" in the first place.  But changing the suffix names would break scripts.

 

Share this post


Link to post
Share on other sites

Is there a way to add delay to terminal commands (using gui:extradelay or otherwise) from another plugin? Maybe I looked in the wrong place, but I haven't found any public API documentation for kOS.

Share this post


Link to post
Share on other sites
55 minutes ago, garwel said:

Is there a way to add delay to terminal commands (using gui:extradelay or otherwise) from another plugin? Maybe I looked in the wrong place, but I haven't found any public API documentation for kOS.

kOS has extra code in its repository specifically to support Remote Tech's signal delay.  In order to make another delaying mod do something similar would require an additional Addon for that other mod. 

You can see examples of how ADDONs for kOS work in the kOS Github under src/kOS/AddOns/

Specifically, how we do it for remotetech is that kOS.AddOns.RemoteTech implements the interface called kOS.Communication.IConnectivityManager. 

Among other things, that interface requires implementing these methods:

kOS.AddOns.RemoteTech.GetDelay(Vessel vessel1, Vessel vessel2)

kOS.AddOns.RemoteTech.GetDelayToControl(Vessel vessel)

kOS.AddOns.RemoteTech.GetDelayToHome(Vessel vessel)

That should give you an example to start with, but if you have more questions, feel free to ask.  @hvacengi is more of an expert on how this system works than I am.  The interface IConnectivityManager has pretty well commented <summary> sections that explain what each of the methods you have to implement are supposed to do.

Edited by Steven Mading

Share this post


Link to post
Share on other sites
1 minute ago, Steven Mading said:

kOS has extra code in its repository specifically to support Remote Tech's signal delay.  In order to make another delaying mod do something similar would require an additional Addon for that other mod. 

You can see examples of how ADDONs for kOS work in the kOS Github under src/kOS/AddOns/

Specifically, how we do it for remotetech is that kOS.AddOns.RemoteTech implements the interface called kOS.Communication.IConnectivityManager. 

Among other things, that interface requires implementing these methods:

kOS.AddOns.RemoteTech.GetDelay(Vessel vessel1, Vessel vessel2)

kOS.AddOns.RemoteTech.GetDelayToControl(Vessel vessel)

kOS.AddOns.RemoteTech.GetDelayToHome(Vessel vessel)

That should give you an example to start with, but if you have more questions, feel free to ask.

I understand I can't implement such interaction from within my mod and need to make a separate project/DLL? Does it have to reside in kOS folder?

Share this post


Link to post
Share on other sites
6 minutes ago, garwel said:

I understand I can't implement such interaction from within my mod and need to make a separate project/DLL? Does it have to reside in kOS folder?

At the moment I don't think we have any such support.  You have to make a pull request against the kOS mod to get us to incorporate changes into kOS itself.  I don't know off the top of my head what it would take to make it possible to make things work from outside kOS's source tree.  It might be a good idea to look into how we could do that.  I know it's a thing we've discussed before but never really worked out exactly how we'd do it.

Share this post


Link to post
Share on other sites
3 hours ago, Steven Mading said:

Because I wasn't talking about just changing the docs.  I was talking about what it would take to actually fix the real problem, which is that they shouldn't *be* called "pitch", "yaw", and "roll" in the first place.  But changing the suffix names would break scripts.

 

Ah, I see. I had somehow totally forgotten/ignored that directions have those suffixes too.. and that makes my original question about the R function stupid too.

Share this post


Link to post
Share on other sites
Just now, Steven Mading said:

At the moment I don't think we have any such support.  You have to make a pull request against the kOS mod to get us to incorporate changes into kOS itself.  I don't know off the top of my head what it would take to make it possible to make things work from outside kOS's source tree.  It might be a good idea to look into how we could do that.  I know it's a thing we've discussed before but never really worked out exactly how we'd do it.

Got it, thanks. I think it's too much of a hassle right now to make an addon solely for adding a delay to the terminal. If one day there is a more accessible way to interact with kOS (e.g. feed it a script) from another plugin, I'll be more than happy.

Share this post


Link to post
Share on other sites

Hi

Just looking for a little help with a script. Probably bitten off more than i can chew. I'm a scripting beginner and am trying to write a script for a shuttle launch in RO/RSS.

So far i get everything going okay and am getting to about 150000m but now want to switch the type of command i'm giving. Up to this point it is fairly simple to just give commands based on waiting for set speeds or altitudes to make pitch adjustments. (it may not be elegant but i'm just learning). But what i want now is instead of it actioning my exact pitch change, i want it to react to external factors, in this case, maintaining prograde at about 2 degrees above the horizon while the velocity is increased to close to orbital speeds. The issue i have is that if i set a pitch angle of, for example, 15 degrees, the prograde may be X degrees above the horizon but slowly dips until i'm losing altitude. I need to know how to instruct kOS to recognise and make changes without me giving specific pitch corrections.

It would be almost impossible for me to script exact pitch angles that would guarantee a successful launch based on varying payloads so need kOS to make adjustments on the fly. I'm not looking for someone to write the code for me, just some help in which kerboscript commands i should be using.

Any help really appreciated.

Daniel 

Share this post


Link to post
Share on other sites

@windystig

There is a heading(hdg, pitch) command that allows to keep a set angle above horizon.

I'd recommend you to find the thread about PEGAS which has a link to the real-world terminal guidance algorithm called Unified Powered Flight Guidance.

Share this post


Link to post
Share on other sites
9 hours ago, windystig said:

in this case, maintaining prograde at about 2 degrees above the horizon while the velocity is increased to close to orbital speeds

What you're looking for, in this case, is either a P, a PI, a PD, or a PID controller.  (EDIT: if not using PEGAS, as described above by Pand5461, which is a much more intensive (but accurate) approach for a first timer).

You want to move the rocket's pitch angle up if your measured prograde angle above horizion is too small, or move the rocket's pitch angle down if the prograde angle measured is too big.

You want to set up a PIDloop that causes the pitch of lock steering to heading(compass, pitch) to be adjusted using the angle above horizon of the prograde vector as your proportional output value that seeks a set point.

You can calculate angle of prograde vector above horizon with this:
function angle_above_horizon { return 90 - vang(ship:velocity:surface,ship:up:vector). }
Then you want to tell PIDLoop to target an angle_above_horizion of a few degrees (I don't know how many you want), with a pitch that is proportional to that.
One example might be to use these terms:
Kp = 2 (for every degree you are off, aim off by two degrees to compensate)
Ki = 0.05 (usually want to keep this a small fraction of Kp)
Kd = 0.2 (usually want to keep this a bigger fraction of Kp, but still not as big as Kp).

Obviously, you need to test these and play with them to get a good feel.  PID loops are too complex a topic to explain in a forum post, but there's a lot of information about them online, and kOS comes with a built-in PIDloop type that will do all the arithmetic under the hood for you.

Edited by Steven Mading

Share this post


Link to post
Share on other sites
4 hours ago, Steven Mading said:

What you're looking for, in this case, is either a P, a PI, a PD, or a PID controller.  (EDIT: if not using PEGAS, as described above by Pand5461, which is a much more intensive (but accurate) approach for a first timer).

You want to move the rocket's pitch angle up if your measured prograde angle above horizion is too small, or move the rocket's pitch angle down if the prograde angle measured is too big.

You want to set up a PIDloop that causes the pitch of lock steering to heading(compass, pitch) to be adjusted using the angle above horizon of the prograde vector as your proportional output value that seeks a set point.

You can calculate angle of prograde vector above horizon with this:
function angle_above_horizon { return 90 - vang(ship:velocity:surface,ship:up:vector). }
Then you want to tell PIDLoop to target an angle_above_horizion of a few degrees (I don't know how many you want), with a pitch that is proportional to that.
One example might be to use these terms:
Kp = 2 (for every degree you are off, aim off by two degrees to compensate)
Ki = 0.05 (usually want to keep this a small fraction of Kp)
Kd = 0.2 (usually want to keep this a bigger fraction of Kp, but still not as big as Kp).

Obviously, you need to test these and play with them to get a good feel.  PID loops are too complex a topic to explain in a forum post, but there's a lot of information about them online, and kOS comes with a built-in PIDloop type that will do all the arithmetic under the hood for you.

Okay, i may have been wrong, i do need someone to write the script because this nearly burned my brain out. :confused: I sort of get the premise but think i'm in too deep. with no background in developing i think a shuttle launch may be too ambitious but is also all i need kOS for because i'm well into an ISS build that i want to complete.

I hate to ask but would a framework of the script be possible to get that i can then play around with numbers in? Or would that require seeing all of the script so far and the craft file of the shuttle i'm using?

Share this post


Link to post
Share on other sites

Had a question about triggers and preserve.

Does a when trigger with preserve persist after the script has ended? If it does how can I get rid of it, apart from toggling power to the CPU?

Share this post


Link to post
Share on other sites
1 hour ago, scimas said:

Does a when trigger with preserve persist after the script has ended? If it does how can I get rid of it, apart from toggling power to the CPU?

If you have "preserve" keyword inside when command block, block will be executed again when conditions are met. Without "preserve" keyword it will be executed only once.
If you want to make trigger toggable without turning off CPU, use more than one variable in condition. For example, set some "allowed" variable to action group or GUI button to toggle true/false value and other usual condition you already using with "when" command, for example when craft reached certain altitude or certain speed, whatever you have designed it for.

  • Like 2

Share this post


Link to post
Share on other sites
2 hours ago, kcs123 said:

If you have "preserve" keyword inside when command block, block will be executed again when conditions are met. Without "preserve" keyword it will be executed only once.
If you want to make trigger toggable without turning off CPU, use more than one variable in condition. For example, set some "allowed" variable to action group or GUI button to toggle true/false value and other usual condition you already using with "when" command, for example when craft reached certain altitude or certain speed, whatever you have designed it for.

Ok, so it does persist even after the script has ended. Having another condition would help with it not firing, but it would bog down the CPU if I run multiple scripts one after another in a single session. I guess I'm going to use return statements instead.

Share this post


Link to post
Share on other sites
12 hours ago, scimas said:

Ok, so it does persist even after the script has ended. Having another condition would help with it not firing, but it would bog down the CPU if I run multiple scripts one after another in a single session. I guess I'm going to use return statements instead.

Hmm, no. I have assumed that your script run in endless loop, like I usualy design my own scripts. If your script have finished and exited to terminal propmpt then when trigger is unloaded from memory and it is no longer active, regardless of used preserve keyword. When you start new script only new defined triggers are active. I'm not certain what is happening if you have multiple "run" calls for other scripts within one small script that just have run calls for other scripts in sequence, though. Easiest way to test it is to put writting some debug message on screen or terminal inside when trigger, to know what part of program is triggered.

Share this post


Link to post
Share on other sites

Is there a safe way to call Part:GetModule when I don't know if such module exists? I have basically to do this work twice: first to iterate through all the Part:Modules to find the one I need and then to request it via Part:GetModule; otherwise I risk getting an error. I wish there were Part:HasModule command or GetModule returned false or something if nothing was found.

Edited by garwel

Share this post


Link to post
Share on other sites
29 minutes ago, garwel said:

Is there a safe way to call Part:GetModule when I don't know if such module exists? I have basically to do this work twice: first to iterate through all the Part:Modules to find the one I need and then to request it via Part:GetModule; otherwise I risk getting an error. I wish there were Part:HasModule command or GetModule returned false or something if nothing was found.

As PART:MODULES is a list, you can use CONTAINS() instead of iterating yourself.

  IF p:MODULES:CONTAINS(mn) {
      LOCAL m IS p:GETMODULE(mn).

Where p is a part and mn is a module name (string).

Edit: yes a PART:HASMODULE() check would be a bit more obvious and save a few characters...

Edited by ElWanderer
  • Like 1

Share this post


Link to post
Share on other sites
On 27.10.2017 at 4:20 PM, windystig said:

Okay, i may have been wrong, i do need someone to write the script because this nearly burned my brain out. :confused: I sort of get the premise but think i'm in too deep. with no background in developing i think a shuttle launch may be too ambitious but is also all i need kOS for because i'm well into an ISS build that i want to complete.

I hate to ask but would a framework of the script be possible to get that i can then play around with numbers in? Or would that require seeing all of the script so far and the craft file of the shuttle i'm using?

ignore the experts.
simple scrips can do the same thing

you just need to know wer prograd is = 90 - vang(ship:velocity:surface,ship:up:vector).
do a lock steering to prograd+R(0,pitchup,0).
and chinge pitchup to keep prograde wer you want it
thers more then 1 way to do it.
PID is good and not hard but i dont allwise use it, simple if`s can do that too

 

p.s.

the PEGAS mentioned by Pand5461 is a KOS script for lunching a shutel. you can download it and use that too

  • Like 1

Share this post


Link to post
Share on other sites

Is this a bug or intended behaviour? The resource values for a stage (STAGE:RESOURCES) are all zero unless the next stage has a decoupler. I'm running into a problem because of this.

The context is this: I'm placing a satellite in orbit. The stages are as follows (0 - upper engine, 1 - stack decoupler, 2 - fairings, 3 - lower engine). When I perform a 'STAGE' command on launch pad, the resources in the current stage are detected as zero :confused:. And yes, I am waiting a full second before I check for the resource values. My script is basically staging once (current stage 3) and then staging again (current stage 2) because of this.

Could someone confirm this either as bug or intended (and if its intended, I would appreciate if you tell me the reason too)? Thanks!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now