Пример #1
0
        public override bool Pop(FlightComputer f)
        {
            var burn = f.ActiveCommands.FirstOrDefault(c => c is BurnCommand);

            if (burn != null)
            {
                f.Remove(burn);
            }

            OriginalDelta        = Node.DeltaV.magnitude;
            RemainingDelta       = this.getRemainingDeltaV(f);
            this.EngineActivated = true;

            double thrustToMass = FlightCore.GetTotalThrust(f.Vessel) / f.Vessel.GetTotalMass();

            if (thrustToMass == 0.0)
            {
                this.EngineActivated = false;
                RTUtil.ScreenMessage("[Flight Computer]: No engine to carry out the maneuver.");
            }
            else
            {
                RemainingTime = RemainingDelta / thrustToMass;
            }

            return(true);
        }
Пример #2
0
        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);
        }
Пример #3
0
        public override bool Execute(FlightComputer f, FlightCtrlState fcs)
        {
            if (mAbort)
            {
                fcs.mainThrottle = 0.0f;
                return(true);
            }

            if (Duration > 0)
            {
                fcs.mainThrottle = Throttle;
                Duration        -= TimeWarp.deltaTime;
            }
            else if (DeltaV > 0)
            {
                fcs.mainThrottle = Throttle;
                DeltaV          -= (Throttle * FlightCore.GetTotalThrust(f.Vessel) / f.Vessel.GetTotalMass()) * TimeWarp.deltaTime;
            }
            else
            {
                fcs.mainThrottle = 0.0f;
                return(true);
            }
            return(false);
        }
Пример #4
0
        /// <summary>
        /// Returns the total time for this burn in seconds
        /// </summary>
        /// <param name="f">Flightcomputer for the current vessel</param>
        /// <returns>max burn time</returns>
        public double getMaxBurnTime(FlightComputer f)
        {
            if (Duration > 0)
            {
                return(Duration);
            }

            return(DeltaV / (Throttle * FlightCore.GetTotalThrust(f.Vessel) / f.Vessel.GetTotalMass()));
        }
Пример #5
0
        /// <summary>
        /// Returns the total time for this burn in seconds
        /// </summary>
        /// <param name="f">Flightcomputer for the current vessel</param>
        /// <returns>max burn time</returns>
        public double getMaxBurnTime(FlightComputer f)
        {
            if (Node == null)
            {
                return(0);
            }

            return(Node.DeltaV.magnitude / (FlightCore.GetTotalThrust(f.Vessel) / f.Vessel.GetTotalMass()));
        }
Пример #6
0
        public override bool Pop(FlightComputer f)
        {
            if (f.Vessel.patchedConicSolver == null)
            {
                f.Vessel.AttachPatchedConicsSolver();
                f.Vessel.patchedConicSolver.Update();
            }

            if (this.Node.solver == null)                                // need to repair (due to the scenario of 2 vessels within phyical range)
            {
                if (f.Vessel.patchedConicSolver.maneuverNodes.Count < 1) // no nodes
                {
                    RTUtil.ScreenMessage("[Flight Computer]: No maneuver node to execute.");
                    return(false);
                }

                this.Node = f.Vessel.patchedConicSolver.maneuverNodes.Find(x => x.UT == this.Node.UT);
            }

            var burn = f.ActiveCommands.FirstOrDefault(c => c is BurnCommand);

            if (burn != null)
            {
                f.Remove(burn);
            }

            OriginalDelta        = Node.DeltaV.magnitude;
            RemainingDelta       = this.getRemainingDeltaV(f);
            this.EngineActivated = true;

            double thrustToMass = FlightCore.GetTotalThrust(f.Vessel) / f.Vessel.GetTotalMass();

            if (thrustToMass == 0.0)
            {
                this.EngineActivated = false;
                RTUtil.ScreenMessage("[Flight Computer]: No engine to carry out the maneuver.");
            }
            else
            {
                RemainingTime = RemainingDelta / thrustToMass;
            }

            f.PIDController.setPIDParameters(FlightComputer.PIDKp, FlightComputer.PIDKi, FlightComputer.PIDKd);

            return(true);
        }
Пример #7
0
        public override bool Pop(FlightComputer f)
        {
            if (f.Vessel.patchedConicSolver == null)
            {
                f.Vessel.AttachPatchedConicsSolver();
                f.Vessel.patchedConicSolver.Update();
            }

            // check if the stored node is still valid
            if (f.Vessel.patchedConicSolver.maneuverNodes.FindIndex(x => x.UT == this.Node.UT && x.DeltaV == this.Node.DeltaV) < 0)//IndexOf() is bad comparer
            {
                RTUtil.ScreenMessage("[Flight Computer]: No maneuver node found.");
                return(false);
            }

            if (this.Node.solver == null) // need to repair (due to the scenario of 2 vessels within phyical range)
            {
                this.Node = f.Vessel.patchedConicSolver.maneuverNodes.Find(x => x.UT == this.Node.UT && x.DeltaV == this.Node.DeltaV);
            }

            var burn = f.ActiveCommands.FirstOrDefault(c => c is BurnCommand);

            if (burn != null)
            {
                f.Remove(burn);
            }

            OriginalDelta        = Node.DeltaV.magnitude;
            RemainingDelta       = this.getRemainingDeltaV(f);
            this.EngineActivated = true;

            double thrustToMass = FlightCore.GetTotalThrust(f.Vessel) / f.Vessel.GetTotalMass();

            if (thrustToMass == 0.0)
            {
                this.EngineActivated = false;
                RTUtil.ScreenMessage("[Flight Computer]: No engine to carry out the maneuver.");
            }
            else
            {
                RemainingTime = RemainingDelta / thrustToMass;
            }

            return(true);
        }
Пример #8
0
        public static ManeuverCommand WithNode(int nodeIndex, FlightComputer f)
        {
            double       thrust  = FlightCore.GetTotalThrust(f.Vessel);
            ManeuverNode node    = f.Vessel.patchedConicSolver.maneuverNodes[nodeIndex];
            double       advance = f.Delay;

            if (thrust > 0)
            {
                advance += (node.DeltaV.magnitude / (thrust / f.Vessel.GetTotalMass())) / 2;
            }

            var newNode = new ManeuverCommand()
            {
                Node      = node,
                TimeStamp = node.UT - advance,
            };

            return(newNode);
        }
Пример #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)
            {
                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);
        }