Jump to content

kOS Autopilot


erendrake

Recommended Posts

NEW RELEASE

New Hotness



* Updated fonts, Thanks @MrOnak
* Now runtime errors show source location and call stack trace (Github issues #186 and #210). Example:
~~~
Tried To push Infinity into the stack.
At MyProgramFile2 on Archive, line 12
PRINT var1/var2.
^
Called from MyProgramFile1 on Archive, line 213
RUN MyProgramFIle2("hello").
^
Called from StartMission on Archive, line 2.
RUN MyProgramFile1.
^
_
~~~
* (WHEN and ON) Triggers that are taking longer than an Update is meant to take, and thus can freeze KSP are caught and reported (Github issue #104). Gives the user an explanatory message about the problem.
* WARNING: Because of a change that had to be done for this, it is **_Highly_ recommended that you increase your *InstructionsPerUpdate* setting in config.xml to 150% as much** as it was before (i.e. from 100 to 150, or if it was 200, make it 300.).
* Multiple Terminal Windows - possible to have one open per CPU part. (Github issue #158)

MultiEdit.png

Old and Busted ( now fixed )


* "rename" was deleting files instead of moving them. (Github issue #220).
* Was parsing array index brakets "[..]" incorrectly when they were on the lefthand side of an assignment. (Github issue #219)
* SHIP:SENSORS were reading the wrong ship's sensors sometimes in multi-ship scenarios. (GIthub issue #218 )
* Integer and Floating point numbers were not quite properly interchangable like they were meant to be. (Github issue #209)

Edited by erendrake
Link to comment
Share on other sites

Hello!

First of all, great job with 0.14.

I've tried to launch 2 SSTO at once.

All was good while distance between vessels hit 2.5 k

After that, one of the terminals disappears and one of the scripts stops working.

The ship itself is not unloaded because I use mod TT Nevers Unload, but engines stops and vessel continue freefall.

http://forum.kerbalspaceprogram.com/threads/48720-TT-NeverUnload-Vessel-Unloading-Preventer

Can you please fix this issue ?

I'll post example video soon

P.S> Sorry for bad english.

Link to comment
Share on other sites

Hello!

First of all, great job with 0.14.

I've tried to launch 2 SSTO at once.

All was good while distance between vessels hit 2.5 k

After that, one of the terminals disappears and one of the scripts stops working.

The ship itself is not unloaded because I use mod TT Nevers Unload, but engines stops and vessel continue freefall.

http://forum.kerbalspaceprogram.com/threads/48720-TT-NeverUnload-Vessel-Unloading-Preventer

Can you please fix this issue ?

I'll post example video soon

P.S> Sorry for bad english.

That is very interesting, I responded that the load distance needed to be changed but if you are using never unload then maybe we have another issue. I would be interested in seeing a log from when this happened.

Link to comment
Share on other sites

That is very interesting, I responded that the load distance needed to be changed but if you are using never unload then maybe we have another issue. I would be interested in seeing a log from when this happened.

I'll be happy to provide info but...

I'm noob.

Where are stored the logs ?

KSP itself did not crash, only one CPU unit stops.

Update:

Problem solved.

Sorry for false report.

I've totally noob and just forget to "enable" TT Never Unload part on my vessel.

TT Never unload part DISABLED

PRINT LOADDISTANCE
2500

TT Never unload part ENABLED

PRINT LOADDISTANCE
300000

Short video with 2x Stock Aeris + TT NU + KOS

So it's not KOS issue but my fault.

However, it would be nice, to control load distance directly from KOS.

by command "SET LOADDISTANCE TO XXX"

Edited by Skyfoxyz
problem solved
Link to comment
Share on other sites

  • 1 month later...

Hey everyone!

I hope I'm not in the wrong thread. I started using kOS a couple days ago after reading about it for some weeks. Since I use RemoteTech in my main (career) game, I was hoping I could use kOS to automate the first couple satellites for my RemoteTech communications network. (I know how to do it without, but I figured it's more fun to do a truly automated launch.)

Unfortunatly, after finally learning about the config-setting in kOS that's supposed to enable RemoteTech integration I tested that today but kOS still looses control of the vessel after going out of range. Am I doing something wrong or does it currently not work? (It is supposed to override the lack of connection, right?)

If needed, I can do further testing. :-)

Link to comment
Share on other sites

First, in case anyone missed my post in the other thread, I am the Action Groups Extended dev.

I have a couple conversations on-going about kOS integration and I want to make sure I'm covering everything so this post is my master list of things I am going to add. I will move this list to my GitHub issue here after a couple days of discussion for long term tracking.

To cover all my bases, here is what I'm planning to expose in AGX for kOS to use, in pseudo-code showing the method names to make sure I'm using the same type of objects you guys are.

public bool AGXTriggerAction(Vessel vsl, int grp) //basic toggle of an action group on a vessel.

I assume passing the Vessel object will work or does kOS use some other identifier?

Note this returns a bool, true if AGX is able to complete the command, false if not. I'm pretty sure just calling the method will also be fine if you don't want to use the bool that gets returned.

public bool AGXTriggerAction(Vessel vsl, int grp, bool force) //basic on/off of an action group. 

Same logic as previous but add a bool as a 3rd parameter (true = force activate, false = force deactivate) for what to do.

public bool AGXActionState(Vessel vsl, int grp) //Check action state on/off (true/false on returned bool)

One of the other conversations also requested the following:

-Getting the list of modules that have actions bound to them for an arbitrary group

-Getting the list of parts that have actions bound to them for an arbitrary group ( lower priority )

Both of these will be covered by:

 public List<BaseAction> AGXGetActions(Vessel vsl, int grp) //get list of actions assigned to the defined group

Then off the list of returned BaseActions you can use BaseAction.listParent.part and BaseAction.listParent.module to get the part and partModule that a specific action belongs to. It would also be straightfoward to return all actions on a vessel this way.

This one is the method I am most uncertain about, is a list of BaseAction's what makes sense for me to be returning?

Also planned would be using group names instead of group numbers, so:

public bool AGXTriggerAction(Vessel vsl, string grpName)

This would keep in mind kOS's intention that case does not matter and would match "lights" to the "Lights" group.

So, thoughts?

D.

edit: One other critical question I need answered, when is kOS available? Right now, AGX only runs during the editor and flight scenes. Do I need to add support for returning calls in other scenes?

Edited by Diazo
Link to comment
Share on other sites

public bool AGXTriggerAction(Vessel vsl, int grp) //basic toggle of an action group on a vessel.

I assume passing the Vessel object will work or does kOS use some other identifier?

Note this returns a bool, true if AGX is able to complete the command, false if not. I'm pretty sure just calling the method will also be fine if you don't want to use the bool that gets returned.

Vessel should work, using it depends on some reference equality because squad hasnt build custom equality comparision. The remotetech API uses vessel.rootpart.flightid and it works pretty well.

public bool AGXTriggerAction(Vessel vsl, int grp, bool force) //basic on/off of an action group. 

Same logic as previous but add a bool as a 3rd parameter (true = force activate, false = force deactivate) for what to do.

This is what i imagine we would hook up to to make it behave the same way that action groups work now in kOS.

public bool AGXActionState(Vessel vsl, int grp) //Check action state on/off (true/false on returned bool)

This too :)

 public List<BaseAction> AGXGetActions(Vessel vsl, int grp) //get list of actions assigned to the defined group

This one is the method I am most uncertain about, is a list of BaseAction's what makes sense for me to be returning?

I think that is a fine return value, a list of base actions is exactly what we use for finding the actions for parts and modules now.

Also planned would be using group names instead of group numbers, so:

public bool AGXTriggerAction(Vessel vsl, string grpName)

This would keep in mind kOS's intention that case does not matter and would match "lights" to the "Lights" group.

That sounds cool to me, it is going to take some work to give this to scripters but i like the idea. Also would the names match to one of the existing 250? or are they their own additional action groups?

Would you also extend the rest of the API to take a string as well as an int? im thinking about the force option, the getter, and the "get baseactions for this group".

edit: One other critical question I need answered, when is kOS available? Right now, AGX only runs during the editor and flight scenes. Do I need to add support for returning calls in other scenes?

We are currently available in the flight scene with thoughts of adding the editor eventually. Nothing else is needed for kOS right now :)

Does that answer all of your questions?

Link to comment
Share on other sites

That is pretty much what I needed. Comments in-line.

The remotetech API uses vessel.rootpart.flightid and it works pretty well.

I actually use rootpart.flightId internally and would have to convert it from the vessel object anyways.

It looks like I should accept "int flightID" rather then "Vessel vsl" as you already have the code for it worked out.

<SNIP methods to use actiongroups>

This is what i imagine we would hook up to to make it behave the same way that action groups work now in kOS.

One note I have is toggling an action vs. setting it on/off. At the moment I'm looking at 2 methods, one to toggle the group with 2 parameters (flightID, actionGroup), one with set the group on/off with 3 (flightID, actionGroup, activate [as bool])

<SNIP method to check a group's state>

This too :)

One thing I just thought of is that AGX handles group states differently.

In default KSP an action group's state is saved with the vessel. If group 1 is deactivated and the "toggle group 1" command is sent, all actions in group 1 get the "activate" command. This means that any actions that were already activated do not do anything as they are already activated.

In AGX, an actions state is tracked per action. If the "toggle group 1" is sent, each action is checked and any actions that are deactivated get activated and and actions that are activated get deactivated. This means however that I have to fudge the group state however.

My current thought is:

If all actions in the group are deactivated, return false (group deactivated)

If any actions in the group are activated, return true (group activated)

This means that if a group has 10 actions, 9 deactivated and 1 activated, my group status method will return true (activated) for that group.

Note that this is one of the primary reasons I offer two activation methods, one to toggle a group and one to activate/deactivate a group.

<SNIP returning List<BaseAction>>

I think that is a fine return value, a list of base actions is exactly what we use for finding the actions for parts and modules now.

Alright, this part is set then.
That sounds cool to me, it is going to take some work to give this to scripters but i like the idea. Also would the names match to one of the existing 250? or are they their own additional action groups?

Would you also extend the rest of the API to take a string as well as an int? im thinking about the force option, the getter, and the "get baseactions for this group".

First, on presenting it to the scripters, I was wondering about adding an AGX 'namespace' instead of trying to modify the existing AG 'namespace'. That way players don't have to keep track of if AGX is installed or not, the AG namespace will work the same regardless and the AGX namespace will throw an error if AGX is not present. (When you assign actions in AGX, they are back-ported to default KSP so action groups 1-10 will work the same regardless if AGX is installed or not.)

Second, there are 250 numbered action groups that can be given a name if desired. So if a player names action group 33 "Lights", they could do something like [AGX "Lights" on] to activate group 33.

Third, while the initial release will probably only support group numbers, when I add support for group names any place where AGX accepts a group number will accept a group name. Note however that it will be a first found thing. If a player names group 33 "Lights" and group 37 "lights", passing AGX "lights" will return only group 33.

We are currently available in the flight scene with thoughts of adding the editor eventually. Nothing else is needed for kOS right now :)

Good, that makes things simpler. You can only activate actions in flight so only having to offer the external methods there is straightforward.

D.

Link to comment
Share on other sites

I actually use rootpart.flightId internally and would have to convert it from the vessel object anyways.

It looks like I should accept "int flightID" rather then "Vessel vsl" as you already have the code for it worked out.

sounds fine to me!

One note I have is toggling an action vs. setting it on/off. At the moment I'm looking at 2 methods, one to toggle the group with 2 parameters (flightID, actionGroup), one with set the group on/off with 3 (flightID, actionGroup, activate [as bool])

Thats cool, we likely would only hook to the set/get rather than the toggle. We dont actually use the toggle from the base action groups either.

First, on presenting it to the scripters, I was wondering about adding an AGX 'namespace' instead of trying to modify the existing AG 'namespace'. That way players don't have to keep track of if AGX is installed or not, the AG namespace will work the same regardless and the AGX namespace will throw an error if AGX is not present. (When you assign actions in AGX, they are back-ported to default KSP so action groups 1-10 will work the same regardless if AGX is installed or not.)

My current plan is to have actiongroup 1-10 to use the stock game's method for activation and when we detect that AGX is installed we wire up the other 240 in their own kos "Binding" class. trying to use the extra Action groups would result in a kOS script error if AGX was not detected.

Second, there are 250 numbered action groups that can be given a name if desired. So if a player names action group 33 "Lights", they could do something like [AGX "Lights" on] to activate group 33.

One request for this behavior would be for you to log which action group came back from the name resolution, and if you are already walking the whole list it would be great to know when there was an ambigious call. I just assume someone will have a "bug" to report after the integration does something they didnt expect, and it would take a while to figure it out if we didnt know which AG# was getting called in AGX

Link to comment
Share on other sites

Okay, I think I have a working basis.

I took a look at how you are binding the current action groups and I will admit it went a bit over my head.

Just to confirm, if I give you:

public bool AGXGroupState(int FlightID, int group) //check if group is activated
public bool AGXTriggerAction(int FlightID, int group, bool doActivate) //doActivate = true to activate the group, false to deactivate
public List<BaseAction> AGXGetActions(int FlightID, int group)//actions list

You can bind those so that 'AG11' in the kOS console passes to AGX correctly?

If so, these are the 3 initial methods I will look at implementing.

D.

Edited by Diazo
Link to comment
Share on other sites

Okay, I think I have a working basis.

I took a look at how you are binding the current action groups and I will admit it went a bit over my head.

Just to confirm, if I give you:

public bool AGXGroupState(int FlightID, int group) //check if group is activated
public bool AGXTriggerAction(int FlightID, int group, bool doActivate) //doActivate = true to activate the group, false to deactivate
public List<BaseAction> AGXGetActions(int FlightID, int group)//actions list

You can bind those so that 'AG11' in the kOS console passes to AGX correctly?

If so, these are the 3 initial methods I will look at implementing.

D.

I believe that should do it :) I am pretty excited and i think this is going to be a cool new feature.

Link to comment
Share on other sites

What exactly does PARTSINGROUP return? (I can't find it on a search of kOS's Github.)

Right now I'm returning a List<BaseAction> that would need to be walked to pull all the BaseAction.listParent.Part properties to create the PARTSINGORUP list (assuming PARTSINGROUP returns a List<Part>). Would there be another return type you'd like to see instead?

D.

Edited by Diazo
Link to comment
Share on other sites

I wonder how this will need to be joined with the new SHIP:PARTSINGROUP() method. It should be doable. I'm just trying to think of how it would be done.

That is an excellent question. It will likely involve us building up that abstraction you were talking about wanting between the actiongroup binding and the partsingroup method.

What exactly does PARTSINGROUP return? (I can't find it on a search of kOS's Github.)

Right now I'm returning a List<BaseAction> that would need to be walked to pull all the BaseAction.listParent.Part properties to create the PARTSINGORUP list (assuming PARTSINGROUP returns a List<Part>).

D.

its not on the master branch yet because it is part of 0.15

https://github.com/KSP-KOS/KOS/blob/develop/src/kOS/Suffixed/VesselTarget.cs#L245-323

Link to comment
Share on other sites

Okay, I have come across a potential issue but I'm not sure how serious it is.

In the main kOS thread, there is that example code where they are using the "ON AG8" command to trigger when an action group changes state.

My search skills are failing me and I can't find where this is located in kOS's code. My worry that if this is implemented as a call to AGX for each separate group, that is 250 calls through reflection that I understand to be quite expensive in terms of CPU load.

Does kOS handle this some other way or did you want me to look at implementing either a callback in AGX that will trigger when an action group activates? Or pass you an enum that is the state of all action groups that you can do a compare against from last frame? (Would have to be 4 ulong's to cover all the groups.)

Otherwise things are coming along well. Depending on how much time I have after my kid's bedtime tonight (if I can get her to sleep, yay halloween!) I may have a test version ready for you to experiment with things on the kOS end.

(Test version meaning AGX will accept commands without throwing errors, but does not correctly execute actions yet.)

D.

Edited by Diazo
Link to comment
Share on other sites

Okay, I have come across a potential issue but I'm not sure how serious it is.

In the main kOS thread, there is that example code where they are using the "ON AG8" command to trigger when an action group changes state.

My search skills are failing me and I can't find where this is located in kOS's code. My worry that if this is implemented as a call to AGX for each separate group, that is 250 calls through reflection that I understand to be quite expensive in terms of CPU load.

Does kOS handle this some other way or did you want me to look at implementing either a callback in AGX that will trigger when an action group activates? Or pass you an enum that is the state of all action groups that you can do a compare against from last frame? (Would have to be 4 ulong's to cover all the groups.)

Otherwise things are coming along well. Depending on how much time I have after my kid's bedtime tonight (if I can get her to sleep, yay halloween!) I may have a test version ready for you to experiment with things on the kOS end.

(Test version meaning AGX will accept commands without throwing errors, but does not correctly execute actions yet.)

D.

Its a great observation. I think we should see how the performance looks once we have the methods we have talked about and we can always work on making it faster. Luckily we arent doing all of the reflection calls each time. they are getting done on load and then we only need a smaller delegate call to make it all work.

Link to comment
Share on other sites

Okay, I have come across a potential issue but I'm not sure how serious it is.

In the main kOS thread, there is that example code where they are using the "ON AG8" command to trigger when an action group changes state.

My search skills are failing me and I can't find where this is located in kOS's code. My worry that if this is implemented as a call to AGX for each separate group, that is 250 calls through reflection that I understand to be quite expensive in terms of CPU load.

Does kOS handle this some other way or did you want me to look at implementing either a callback in AGX that will trigger when an action group activates? Or pass you an enum that is the state of all action groups that you can do a compare against from last frame? (Would have to be 4 ulong's to cover all the groups.)

Otherwise things are coming along well. Depending on how much time I have after my kid's bedtime tonight (if I can get her to sleep, yay halloween!) I may have a test version ready for you to experiment with things on the kOS end.

(Test version meaning AGX will accept commands without throwing errors, but does not correctly execute actions yet.)

D.

The "ON AG8 { dosomething }" construct does this every update tick:

Query the current boolean value of AG8.

Set a "do it " flag to true if the previous boolean value of AG8 differs from this new value.

Store the new boolean value in the previous value variable for next time.

If the "do it" flag was true, then execute the body of the code, else skip it.

Each Update tick it re-queries the current state of the action group boolean value and compares it to what it was on the previous update tick. During the update tick in which the value had just changed, from false to true or from true to false, either way, it triggers the body to execute.

But none of the above work happens UNLESS the script actually mentions an ON AG8 command in it. Only those action groups for which there is an "ON AG#" command in the script get this query. It does not query all 10 groups just in case one of them is used. It only queries the action groups that were actually set up to have hooks on them, and furthermore it only starts querying for the group activation AFTER the point where the trigger is first mentioned.

If you have a kOS script like this:

ON AG7 { print "AG7 activated". }.

WAIT 60.

ON AG8 { print "AG8 activated". }.

WAIT 999999.

Then if action group 8 is activated by the user during the first minute of execution and never again (before the WAIT 60 is done), then the message "AG8 activated" will in fact NEVER get printed. Until the "ON AG8" is executed, the checking hasn't started yet, and it's only if the sate is toggled AFTER the checking is turned on that it does anything. In the case where AG8 was activated prior to the ON AG8 command being run, then when ON AG8 is first run, it's "previous value" STARTS off as already being "TRUE", and then it will activate if it becomes false.

Edited by Steven Mading
Link to comment
Share on other sites

Thank you for the explanation. That actually dispels my concern. Even a large vessel with a lot of action groups should not be an issue then as it does not monitor all groups, only the groups that have "ON AG" statements.

I can't see only a few groups being monitored any sort of performance issue.

D.

Link to comment
Share on other sites

Okay, I have a test version of AGX ready to go for kOS to try integrating with. Note that only the currently focused vessel works. If you pass AGX the FlightID of another vessel, it currently prints a message to the log and does not actually activate those action. However, fixing that is internal to AGX and will not change the reflection code I have given you below.

It is version 1.20a found on my GitHub.

I have included the entire AGX mod in the attached .zip.

I have updated my own thread about AGX's external interface with all 11 methods it currently supports, as can be found here.

I have also included my test file as "OSK.dll" which is not part of AGX but is the "separate mod" I used for testing purposes. It will draw a window with 11 buttons to call the external methods to AGX. Source of OSK.dll here. Note I have included several extra methods I expect kOS will not use. Delete/rename OSK.dll to get rid of the this window.

Now, I am still completely stumped on how to go about adding this to kOS. Would it work something like this? (I grabbed the ActionGroups.cs in the Bindings subfolder as a base for this, but it is horrendously broken at written. I don't understand Bindings as you are using them.)

using kOS.Utilities;
using System.Reflection;
namespace kOS.Binding
{
[kOSBinding("ksp")]
public class ActionGroupsAGX : Binding
{
public override void AddTo(SharedObjects shared)
{
if(AGExtInstalled) //check AGX installed?
{
Shared = shared;
for(int i = 11;i <= 250 ;i++) //rather then copy-pasting 240 lines, I think this works? Syntax is broken but the idea is valid?
{
Shared.BindingMgr.AddSetter("AG"+i.ToString(), (cpu.FlightID, val) => Shared.AGX2VslActivateGroup(cpu.FlightID,i,val);
Shared.BindingMgr.AddGetter("AG"+i.ToString(), cpu.FlightID => Shared.AGX2VslGroupState(cpu.FlightID,i);
}
}
else
{
//need placeholder code if AGX not installed?
}

}
//start AGX Reflection methods
public bool AGExtInstalled() //is AGX installed? Returns bool
{
Type calledType = Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt");

return (bool)calledType.InvokeMember("AGXInstalled", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, null);
}
public bool AGX2VslActivateGroup(uint FlightID, int group, bool forceDir) //Activate an action group, FlightID of rootpart of vessel, group of ActionGroup, forceDir is true to Activate, false to deActivate group
{
Type calledType = Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt");
bool GroupAct = (bool)calledType.InvokeMember("AGX2VslActivateGroup", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { FlightID, group, forceDir });
return GroupAct;
}
public bool AGX2VslGroupState(uint FlightID, int group) //check actiongroup state
{
Type calledType = Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt");
//FlightID = 4198041784;
//group = 10;
bool GroupAct = (bool)calledType.InvokeMember("AGX2VslGroupState", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { FlightID, group });
print(GroupAct);
return GroupAct;
}
public List<BaseAction> AGExtGet2VslGroupActions(uint FlightID, int group) //return list of all actions in a group, not sure where this goes.
{
Type calledType = Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt");
List<BaseAction> RetActs = (List<BaseAction>)calledType.InvokeMember("AGX2VslGroupActions", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { FlightID, group });
return RetActs;
}
}
}

I'm hoping you can make something out of this, I should be around most of the weekend if you have questions.

D.

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...