Наследование: AbstractCommand
        /// <summary>
        /// Load and creates a command after saving a command. Returns null if no object
        /// has been loaded.
        /// </summary>
        /// <param name="n">Node with the command infos</param>
        /// <param name="fc">Current flightcomputer</param>
        public static ICommand LoadCommand(ConfigNode n, FlightComputer fc)
        {
            ICommand command = null;

            // switch the different commands
            switch (n.name)
            {
                case "AttitudeCommand":     { command = new AttitudeCommand(); break; }
                case "ActionGroupCommand":  { command = new ActionGroupCommand(); break; }
                case "BurnCommand":         { command = new BurnCommand(); break; }
                case "ManeuverCommand":     { command = new ManeuverCommand(); break; }
                case "CancelCommand":       { command = new CancelCommand(); break; }
                case "TargetCommand":       { command = new TargetCommand(); break; }
                case "EventCommand":        { command = new EventCommand(); break; }
                case "DriveCommand":        { command = new DriveCommand(); break; }
                case "ExternalAPICommand":  { command = new ExternalAPICommand(); break; }
                case "PartActionCommand":   { command = new PartActionCommand(); break; }
            }

            if (command != null)
            {
                ConfigNode.LoadObjectFromConfig(command, n);
                // additional loadings
                var result = command.Load(n, fc);
                RTLog.Verbose("Loading command {0}({1})={2}", RTLogLevel.LVL1, n.name, command.CmdGuid, result);
                // delete command if we can't load the command correctlys
                if (result == false)
                    command = null;
            }

            return command;
        }
Пример #2
0
        /// <summary>
        /// Executes this command and invokes the <see cref="ReflectionExecuteMethod"/>
        /// on the <see cref="ReflectionType"/>. When this command is aborted the
        /// fallback commnd is "KillRot".
        /// </summary>
        /// <param name="computer">Current flightcomputer</param>
        /// <param name="ctrlState">Current FlightCtrlState</param>
        /// <returns>true: delete afterwards.</returns>
        public override bool Execute(FlightComputer computer, FlightCtrlState ctrlState)
        {
            bool finished = true;

            if (this.ReflectionExecuteMethod != "")
            {
                // invoke the Execution-method
                finished = (bool)this.callReflectionMember(this.ReflectionExecuteMethod);
                if (this.AbortCommand)
                {
                    if (RTSettings.Instance.FCOffAfterExecute)
                    {
                        computer.Enqueue(AttitudeCommand.Off(), true, true, true);
                        finished = true;
                    }
                    if (!RTSettings.Instance.FCOffAfterExecute)
                    {
                        computer.Enqueue(AttitudeCommand.KillRot(), true, true, true);
                        finished = true;
                    }
                }
            }

            return(finished);
        }
Пример #3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="computer">FlightComputer instance of the computer of the vessel.</param>
 private void AbortManeuver(FlightComputer computer)
 {
     RTUtil.ScreenMessage("[Flight Computer]: Maneuver removed");
     if (computer.Vessel.patchedConicSolver != null)
     {
         Node.RemoveSelf();
     }
     // enqueue kill rot
     computer.Enqueue(AttitudeCommand.KillRot(), true, true, true);
 }
Пример #4
0
        /// <summary>
        /// Load and creates a command after saving a command. Returns null if no object
        /// has been loaded.
        /// </summary>
        /// <param name="n">Node with the command infos</param>
        /// <param name="fc">Current flightcomputer</param>
        public static ICommand LoadCommand(ConfigNode n, FlightComputer fc)
        {
            ICommand command = null;

            // switch the different commands
            switch (n.name)
            {
            case "AttitudeCommand":       { command = new AttitudeCommand(); break; }

            case "ActionGroupCommand":    { command = new ActionGroupCommand(); break; }

            case "BurnCommand":           { command = new BurnCommand(); break; }

            case "ManeuverCommand":       { command = new ManeuverCommand(); break; }

            case "CancelCommand":         { command = new CancelCommand(); break; }

            case "TargetCommand":         { command = new TargetCommand(); break; }

            case "EventCommand":          { command = new EventCommand(); break; }

            case "DriveCommand":          { command = new DriveCommand(); break; }

            case "ExternalAPICommand":    { command = new ExternalAPICommand(); break; }

            case "PartActionCommand":     { command = new PartActionCommand(); break; }

            case "StockAutopilotCommand": { command = new StockAutopilotCommand(); break; }

            case "HibernationCommand":    { command = new HibernationCommand(); break; }

            case "AxisGroupCommand":      { command = new AxisGroupCommand(); break; }

            case "PIDCommand":            { command = new PIDCommand(); break; }

            case "FlightControlCommand":  { command = new FlightControlCommand(); break; }
            }

            if (command != null)
            {
                ConfigNode.LoadObjectFromConfig(command, n);
                // additional loadings
                var result = command.Load(n, fc);
                RTLog.Verbose("Loading command {0}({1})={2}", RTLogLevel.LVL1, n.name, command.CmdGuid, result);
                // delete command if we can't load the command correctlys
                if (result == false)
                {
                    command = null;
                }
            }

            return(command);
        }
Пример #5
0
        /// <summary>
        /// This method will be triggerd right after the command was enqueued to
        /// the flight computer list.
        /// </summary>
        /// <param name="computer">Current flightcomputer</param>
        public override void CommandEnqueued(FlightComputer computer)
        {
            var timetoexec = (TimeStamp + ExtraDelay) - RTSettings.Instance.FCLeadTime;

            if (timetoexec - RTUtil.GameTime >= 0 && RTSettings.Instance.AutoInsertKaCAlerts)
            {
                var kaCAddonLabel = computer.Vessel.vesselName + " Maneuver";

                if (RTCore.Instance != null && RTCore.Instance.KacAddon != null)
                {
                    KaCItemId = RTCore.Instance.KacAddon.CreateAlarm(RemoteTech_KACWrapper.KACWrapper.KACAPI.AlarmTypeEnum.Maneuver, kaCAddonLabel, timetoexec, computer.Vessel.id);
                }
            }

            // also add a maneuver node command to the queue
            computer.Enqueue(AttitudeCommand.ManeuverNode(timetoexec), true, true, true);
        }
Пример #6
0
        /// <summary>
        /// This method will be triggerd right after the command was enqueued to
        /// the flight computer list.
        /// </summary>
        /// <param name="computer">Current flightcomputer</param>
        public override void CommandEnqueued(FlightComputer computer)
        {
            string KaCAddonLabel = String.Empty;
            double timetoexec    = (this.TimeStamp + this.ExtraDelay) - 180;

            if (timetoexec - RTUtil.GameTime >= 0 && RTSettings.Instance.AutoInsertKaCAlerts == true)
            {
                KaCAddonLabel = computer.Vessel.vesselName + " Maneuver";

                if (RTCore.Instance != null && RTCore.Instance.kacAddon != null)
                {
                    this.KaCItemId = RTCore.Instance.kacAddon.CreateAlarm(AddOns.KerbalAlarmClockAddon.AlarmTypeEnum.Maneuver, KaCAddonLabel, timetoexec);
                }
            }

            // also add a maneuver node command to the queue
            computer.Enqueue(AttitudeCommand.ManeuverNode(timetoexec), true, true, true);
        }
Пример #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="computer">FlightComputer instance of the computer of the vessel.</param>
        private void AbortManeuver(FlightComputer computer)
        {
            RTUtil.ScreenMessage("[Flight Computer]: Maneuver removed");
            if (computer.Vessel.patchedConicSolver != null)
            {
                Node.RemoveSelf();
            }

            // Flight Computer mode after execution based on settings
            if (RTSettings.Instance.FCOffAfterExecute)
            {
                computer.Enqueue(AttitudeCommand.Off(), true, true, true);
            }
            if (!RTSettings.Instance.FCOffAfterExecute)
            {
                computer.Enqueue(AttitudeCommand.KillRot(), true, true, true);
            }
        }
Пример #8
0
        /// <summary>
        /// Executes this command and invokes the <see cref="ReflectionExecuteMethod"/>
        /// on the <see cref="ReflectionType"/>. When this command is aborted the
        /// fallback commnd is "KillRot".
        /// </summary>
        /// <param name="computer">Current flightcomputer</param>
        /// <param name="ctrlState">Current FlightCtrlState</param>
        /// <returns>true: delete afterwards.</returns>
        public override bool Execute(FlightComputer computer, FlightCtrlState ctrlState)
        {
            bool finished = true;

            if (this.ReflectionExecuteMethod != "")
            {
                // invoke the Execution-method
                finished = (bool)this.callReflectionMember(this.ReflectionExecuteMethod);
                if (this.AbortCommand)
                {
                    // enqueue killRot after aborting this command
                    computer.Enqueue(AttitudeCommand.KillRot(), true, true, true);
                    finished = true;
                }
            }

            return(finished);
        }
Пример #9
0
        /// <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)
            {
                computer.Enqueue(AttitudeCommand.KillRot(), true, true, true);
                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);

            // 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)
            {
                // Aborting because deltaV was rising again!
                computer.Enqueue(AttitudeCommand.KillRot(), true, true, true);
                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);
        }