KSP-KOS / KOS

Fully programmable autopilot mod for KSP. Originally By Nivekk
Other
697 stars 230 forks source link

Two CPUs steering one vessel #1670

Open Gotbread opened 8 years ago

Gotbread commented 8 years ago

I have several (two will reproduce the issue) vessels which have one cpu on each of them. I try to dock them together in athmosphere hovering under engine power. As soon as they dock one of the cpus crashes with the error

"Steering Manager on this ship is already in use by another processor."

which in itself is fine. But how do i avoid the problem? I Cant avoid the steering manager since all vessels need active control. I cant switch the steering of a millisecond before docking because i do not know the precise moment the ships dock. (They seem to crash in the wait function, so the issue occures during the internal update which the script has no control over).

My current approach is to replicate the code on all CPUs so they stay functional even if one of them crashes, and then reboot them after docking.

docking

Dunbaratu commented 8 years ago

I'd like to confirm that I've had the exact same problem in my client/server docking script.

Even if your script has a check to see if the docking port has attached, and you try to unlock the steering the instant you know a docking happened, you are still helpless to avoid the script crash. In the last instruction of the previous FixedUpdate, the docking hadn't happened yet and there was no evidence that it was about to connect in the next update, and in the very first instruction of the next FixedUpdate, the exception has already been thrown by SteeringManager. Because of the order in which things happen, a script cannot detect the docking and unlock the steering in time.

It would be nice if the unlocking of the steering that the SteeringManager does wasn't treated as a script-ending event. Or perhaps have the SteeringManager go ahead and ignore the sterring information and not use it, but don't complain with an error yet until one or two more FixedUpdates have happened - to give the script some time to react to noticing.

hvacengi commented 8 years ago

I too have a docking script for station building/fueling. To avoid this issue, I do 2 things: first, I unlock steering based on the docking port changing from "ready" rather than waiting to confirm "docked" (effectively unlocking during the "acquire" state). Second, I turn on SAS for the larger ship that I am docking to, rather than have cooked steering maintain a certain heading. I confirmed this evening that docking two ship together using the following code does not result in an error even when lock steering to "kill". is active on the larger vessel:

when docker:state <> "ready" then {
    set dockDone to true.
}
set dockDone to false.
until (dockDone) {
    // do dock stuff here
}
set ship:control:neutralize to true.
unlock steering.
unlock throttle.

The nice thing about using the acquire state is that releasing the controls will also let the magnetic force guide the vessel the rest of the way without potential for your RCS or steering to fight the force.

I'm not sure I'm on board with the idea of not throwing an error if steering is already locked. If your script expects to be steering but isn't really, that really is an error state. We could possibly look at a delayed exception, I think that would be a better compromise. Let me know if my above work around helps for both of you.

Gotbread commented 8 years ago

I will try this for orbital docking, seems a good approach. However in the case of atmospheric docking, the moment i let go of the controls the ship will crash, since the magnetic force is not enough to hold a 30tons+ ship in air.

The real issue seems to be the way docking is handled. In real life, each vessel still controls itself even after docking. Then one vessel gives the controls to the main vessel. KSP does not model this (which in itself is fine).

A good workaround would be to only throw the exception the moment the script tries to set steering or throttle, but not in the internal update. When the vessels are docked you silently unlock the controls, the first cpu to lock them again gets them, the other cpu gets the error when it tries to access them. This way you can check before trying to set them again. It should also not break existing scripts.

AlchemistCH commented 8 years ago

Interesting finding: it throws error even if you unlock steering on both, but it doesn't throw the exception if at least one of the scripts actually ends when the docking is confirmed - so you at least can choose which core stops (correctly, not just by exception) and which continues to control the vehicle