public override bool Execute(FlightComputer f, FlightCtrlState fcs) { if (mAbort) { Mode = FlightMode.Off; mAbort = false; } switch (Mode) { case FlightMode.Off: break; case FlightMode.KillRot: FlightCore.HoldOrientation(fcs, f, Orientation * Quaternion.AngleAxis(90, Vector3.left)); break; case FlightMode.AttitudeHold: FlightCore.HoldAttitude(fcs, f, Frame, Attitude, Orientation); break; case FlightMode.AltitudeHold: break; } return(false); }
/// <summary> /// Executes the maneuver burn for the configured maneuver node. /// </summary> /// <param name="computer">FlightComputer instance of the computer of the vessel the ManeuverCommand is for.</param> /// <param name="ctrlState">FlightCtrlState instance of the current state of the vessel.</param> /// <returns>true if the command has finished its work, false otherwise.</returns> public override bool Execute(FlightComputer computer, FlightCtrlState ctrlState) { // Halt the command if we reached our target or were command to abort by the previous tick if (this.RemainingDelta <= 0.01 || this.abortOnNextExecute) { this.AbortManeuver(computer); return(true); } // Orientate vessel to maneuver prograde var forward = Node.GetBurnVector(computer.Vessel.orbit).normalized; var up = (computer.SignalProcessor.Body.position - computer.SignalProcessor.Position).normalized; var orientation = Quaternion.LookRotation(forward, up); FlightCore.HoldOrientation(ctrlState, computer, orientation, true); // This represents the theoretical acceleration but is off by a few m/s^2, probably because some parts are partially physicsless double thrustToMass = (FlightCore.GetTotalThrust(computer.Vessel) / computer.Vessel.GetTotalMass()); // We need to know if the engine was activated or not to show the proper info text in the command if (thrustToMass == 0.0) { this.EngineActivated = false; return(false); } this.EngineActivated = true; // Before any throttling, those two values may differ from after the throttling took place this.RemainingDelta = this.getRemainingDeltaV(computer); this.RemainingTime = this.RemainingDelta / thrustToMass; // In case we would overpower with 100% thrust, calculate how much we actually need and set it. if (computer.Vessel.acceleration.magnitude > this.RemainingDelta) { // Formula which leads to this: a = ( vE – vS ) / dT this.throttle = this.RemainingDelta / computer.Vessel.acceleration.magnitude; } ctrlState.mainThrottle = (float)this.throttle; // TODO: THIS CAN PROBABLY BE REMOVED? RemainingDelta = this.getRemainingDeltaV(computer); // After throttling, the remaining time differs from beforehand (dividing delta by throttled thrustToMass) this.RemainingTime = this.RemainingDelta / (ctrlState.mainThrottle * thrustToMass); // We need to abort if the remaining delta was already low enough so it only takes exactly one more tick! double ticksRemaining = this.RemainingTime / TimeWarp.deltaTime; if (ticksRemaining <= 1) { this.throttle *= ticksRemaining; ctrlState.mainThrottle = (float)this.throttle; this.abortOnNextExecute = true; return(false); } // we only compare up to the fiftieth part due to some burn-up delay when just firing up the engines if (this.lowestDeltaV > 0 && // Do ignore the first tick (this.RemainingDelta - 0.02) > this.lowestDeltaV && this.RemainingDelta < 1.0) // be safe that we do not abort the command to early { // Aborting because deltaV was rising again! this.AbortManeuver(computer); return(true); } // Lowest delta always has to be stored to be able to compare it in the next tick if (this.lowestDeltaV == 0 || // Always do it on the first tick this.RemainingDelta < this.lowestDeltaV) { this.lowestDeltaV = this.RemainingDelta; } return(false); }