Esempio n. 1
0
        public ReentrySimulation(Orbit _initialOrbit, double _UT, double _dragMassExcludingUsedParachutes, List <SimulatedParachute> _parachuteList, double _mass,
                                 IDescentSpeedPolicy _descentSpeedPolicy, double _decelEndAltitudeASL, double _maxThrustAccel, double _parachuteSemiDeployMultiplier, double _probableLandingSiteASL, bool _multiplierHasError, double _dt)
        {
            // Store all the input values as they were given
            input_initialOrbit = _initialOrbit;
            input_UT           = _UT;
            input_dragMassExcludingUsedParachutes = _dragMassExcludingUsedParachutes;
            input_parachuteList                 = _parachuteList;
            input_mass                          = _mass;
            input_descentSpeedPolicy            = _descentSpeedPolicy;
            input_decelEndAltitudeASL           = _decelEndAltitudeASL;
            input_maxThrustAccel                = _maxThrustAccel;
            input_parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            input_probableLandingSiteASL        = _probableLandingSiteASL;
            input_multiplierHasError            = _multiplierHasError;
            input_dt = _dt;

            max_dt = _dt;
            dt     = max_dt;

            // Get a copy of the original orbit, to be more thread safe
            initialOrbit = new Orbit();
            initialOrbit.UpdateFromOrbitAtUT(_initialOrbit, _UT, _initialOrbit.referenceBody);

            CelestialBody body = _initialOrbit.referenceBody;

            bodyHasAtmosphere   = body.atmosphere;
            seaLevelAtmospheres = body.atmosphereMultiplier;
            scaleHeight         = 1000 * body.atmosphereScaleHeight;
            bodyRadius          = body.Radius;
            gravParameter       = body.gravParameter;
            this.dragMassExcludingUsedParachutes = _dragMassExcludingUsedParachutes;

            this.parachutes = _parachuteList;
            this.parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            this.multiplierHasError            = _multiplierHasError;

            this.mass               = _mass;
            bodyAngularVelocity     = body.angularVelocity;
            this.descentSpeedPolicy = _descentSpeedPolicy;
            decelRadius             = bodyRadius + _decelEndAltitudeASL;
            aerobrakedRadius        = bodyRadius + body.RealMaxAtmosphereAltitude();
            mainBody                       = body;
            this.maxThrustAccel            = _maxThrustAccel;
            this.probableLandingSiteASL    = _probableLandingSiteASL;
            this.probableLandingSiteRadius = _probableLandingSiteASL + bodyRadius;

            referenceFrame = ReferenceFrame.CreateAtCurrentTime(_initialOrbit.referenceBody);

            orbitReenters = OrbitReenters(_initialOrbit);

            if (orbitReenters)
            {
                startUT = _UT;
            }

            maxDragGees    = 0;
            deltaVExpended = 0;
            trajectory     = new List <AbsoluteVector>();
        }
Esempio n. 2
0
        public ReentrySimulation(Orbit initialOrbit, double UT, double dragCoefficient,
                                 IDescentSpeedPolicy descentSpeedPolicy, double endAltitudeASL, double maxThrustAccel)
        {
            CelestialBody body = initialOrbit.referenceBody;

            bodyHasAtmosphere       = body.atmosphere;
            seaLevelAtmospheres     = body.atmosphereMultiplier;
            scaleHeight             = 1000 * body.atmosphereScaleHeight;
            bodyRadius              = body.Radius;
            gravParameter           = body.gravParameter;
            this.dragCoefficient    = dragCoefficient;
            bodyAngularVelocity     = body.angularVelocity;
            this.descentSpeedPolicy = descentSpeedPolicy;
            landedRadius            = bodyRadius + endAltitudeASL;
            aerobrakedRadius        = bodyRadius + body.RealMaxAtmosphereAltitude();
            mainBody            = body;
            this.maxThrustAccel = maxThrustAccel;

            referenceFrame = ReferenceFrame.CreateAtCurrentTime(initialOrbit.referenceBody);

            orbitReenters = OrbitReenters(initialOrbit);

            if (orbitReenters)
            {
                startUT = UT;
                t       = startUT;
                AdvanceToFreefallEnd(initialOrbit);
            }

            maxDragGees    = 0;
            deltaVExpended = 0;
            trajectory     = new List <AbsoluteVector>();
        }
        public ReentrySimulation(Orbit _initialOrbit, double _UT, SimulatedVessel _vessel, SimCurves _simcurves, IDescentSpeedPolicy _descentSpeedPolicy, double _decelEndAltitudeASL, double _maxThrustAccel, double _parachuteSemiDeployMultiplier, double _probableLandingSiteASL, bool _multiplierHasError, double _dt, double _min_dt)
        {
            // Store all the input values as they were given
            input_initialOrbit = _initialOrbit;
            input_UT = _UT;
            
            vessel = _vessel;
            input_descentSpeedPolicy = _descentSpeedPolicy;
            input_decelEndAltitudeASL = _decelEndAltitudeASL;
            input_maxThrustAccel = _maxThrustAccel;
            input_parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            input_probableLandingSiteASL = _probableLandingSiteASL;
            input_multiplierHasError = _multiplierHasError;
            input_dt = _dt;

            // the vessel attitude relative to the surface vel. Fixed for now
            attitude = Quaternion.Euler(180,0,0);

            min_dt = _min_dt;
            max_dt = _dt;
            dt = max_dt;

            // Get a copy of the original orbit, to be more thread safe
            initialOrbit = new Orbit();
            initialOrbit.UpdateFromOrbitAtUT(_initialOrbit, _UT, _initialOrbit.referenceBody);

            CelestialBody body = _initialOrbit.referenceBody;
            bodyHasAtmosphere = body.atmosphere;
            bodyRadius = body.Radius;
            gravParameter = body.gravParameter;

            this.parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            this.multiplierHasError = _multiplierHasError;

            bodyAngularVelocity = body.angularVelocity;
            this.descentSpeedPolicy = _descentSpeedPolicy;
            decelRadius = bodyRadius + _decelEndAltitudeASL; 
            aerobrakedRadius = bodyRadius + body.RealMaxAtmosphereAltitude();
            mainBody = body;
            this.maxThrustAccel = _maxThrustAccel;
            this.probableLandingSiteASL = _probableLandingSiteASL;
            this.probableLandingSiteRadius = _probableLandingSiteASL + bodyRadius;

            referenceFrame = ReferenceFrame.CreateAtCurrentTime(_initialOrbit.referenceBody);

            orbitReenters = OrbitReenters(_initialOrbit);

            if (orbitReenters)
                startUT = _UT;

            maxDragGees = 0;
            deltaVExpended = 0;
            trajectory = new List<AbsoluteVector>();

            simCurves = _simcurves;

            once = true;

        }
Esempio n. 4
0
        public override void Drive(FlightCtrlState s)
        {
            if (landStep == LandStep.OFF)
            {
                return;
            }

            descentSpeedPolicy = PickDescentSpeedPolicy();

            predictor.descentSpeedPolicy = PickDescentSpeedPolicy(); //create a separate IDescentSpeedPolicy object for the simulation
            predictor.endAltitudeASL     = DecelerationEndAltitude();

            prediction = predictor.GetResult(); //grab a reference to the current result, in case a new one comes in while we're doing stuff

            if (!PredictionReady && landStep != LandStep.DEORBIT_BURN && landStep != LandStep.PLANE_CHANGE && landStep != LandStep.LOW_DEORBIT_BURN &&
                landStep != LandStep.UNTARGETED_DEORBIT && landStep != LandStep.FINAL_DESCENT)
            {
                return;
            }

            switch (landStep)
            {
            case LandStep.UNTARGETED_DEORBIT:
                DriveUntargetedDeorbit(s);
                break;

            case LandStep.PLANE_CHANGE:
                DrivePlaneChange(s);
                break;

            case LandStep.LOW_DEORBIT_BURN:
                DriveLowDeorbitBurn(s);
                break;

            case LandStep.DEORBIT_BURN:
                DriveDeorbitBurn(s);
                break;

            case LandStep.COURSE_CORRECTIONS:
                DriveCourseCorrections(s);
                break;

            case LandStep.KILLING_HORIZONTAL_VELOCITY:
                DriveKillHorizontalVelocity(s);
                break;

            case LandStep.FINAL_DESCENT:
                DriveUntargetedLanding(s);
                break;

            default:
                break;
            }
        }
        public override void Drive(FlightCtrlState s)
        {
            if (!active)
            {
                return;
            }

            // If the latest prediction is a landing, aerobrake or no-reentry prediciton then keep it.
            // However if it is any other sort or result it is not much use to us, so do not bother!
            {
                ReentrySimulation.Result result = predictor.Result;
                if (null != result)
                {
                    if (result.outcome != ReentrySimulation.Outcome.ERROR && result.outcome != ReentrySimulation.Outcome.TIMED_OUT)
                    {
                        this.prediction = result;
                    }
                }
            }
            {
                ReentrySimulation.Result result = predictor.GetErrorResult();
                if (null != result)
                {
                    if (result.outcome != ReentrySimulation.Outcome.ERROR && result.outcome != ReentrySimulation.Outcome.TIMED_OUT)
                    {
                        this.errorPrediction = result;
                    }
                }
            }

            descentSpeedPolicy = PickDescentSpeedPolicy();

            predictor.descentSpeedPolicy            = PickDescentSpeedPolicy(); //create a separate IDescentSpeedPolicy object for the simulation
            predictor.decelEndAltitudeASL           = DecelerationEndAltitude();
            predictor.parachuteSemiDeployMultiplier = this.parachutePlan.Multiplier;

            // Consider lowering the langing gear
            {
                double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue));
                if (deployGears && !deployedGears && (minalt < 1000))
                {
                    DeployLandingGears();
                }
            }

            base.Drive(s);
        }
        public override void Drive(FlightCtrlState s)
        {
            if (!active)
            {
                return;
            }

            descentSpeedPolicy = PickDescentSpeedPolicy();

            predictor.descentSpeedPolicy            = PickDescentSpeedPolicy(); //create a separate IDescentSpeedPolicy object for the simulation
            predictor.decelEndAltitudeASL           = DecelerationEndAltitude();
            predictor.parachuteSemiDeployMultiplier = this.parachutePlan.Multiplier;

            // Consider lowering the langing gear
            {
                double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue));
                if (deployGears && !deployedGears && (minalt < 1000))
                {
                    DeployLandingGears();
                }
            }

            base.Drive(s);
        }
        public void Init(Orbit _initialOrbit, double _UT, SimulatedVessel _vessel, SimCurves _simcurves, IDescentSpeedPolicy _descentSpeedPolicy, double _decelEndAltitudeASL, double _maxThrustAccel, double _parachuteSemiDeployMultiplier, double _probableLandingSiteASL, bool _multiplierHasError, double _dt, double _min_dt, double _maxOrbits, bool _noSKiptoFreefall)
        {
            // Store all the input values as they were given
            input_initialOrbit = _initialOrbit;
            input_UT = _UT;
            
            vessel = _vessel;
            input_descentSpeedPolicy = _descentSpeedPolicy;
            input_decelEndAltitudeASL = _decelEndAltitudeASL;
            input_maxThrustAccel = _maxThrustAccel;
            input_parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            input_probableLandingSiteASL = _probableLandingSiteASL;
            input_multiplierHasError = _multiplierHasError;
            input_dt = _dt;
            // the vessel attitude relative to the surface vel. Fixed for now
            attitude = Quaternion.Euler(180,0,0);

            min_dt = _min_dt;
            max_dt = _dt;
            dt = max_dt;
            steps = 0;

            maxOrbits = _maxOrbits;

            noSKiptoFreefall = _noSKiptoFreefall;

            // Get a copy of the original orbit, to be more thread safe
            //initialOrbit = new Orbit();
            initialOrbit.UpdateFromOrbitAtUT(_initialOrbit, _UT, _initialOrbit.referenceBody);

            CelestialBody body = _initialOrbit.referenceBody;
            bodyHasAtmosphere = body.atmosphere;
            bodyRadius = body.Radius;
            gravParameter = body.gravParameter;

            this.parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            this.multiplierHasError = _multiplierHasError;

            bodyAngularVelocity = body.angularVelocity;
            this.descentSpeedPolicy = _descentSpeedPolicy;
            decelRadius = bodyRadius + _decelEndAltitudeASL; 
            aerobrakedRadius = bodyRadius + body.RealMaxAtmosphereAltitude();
            mainBody = body;
            this.maxThrustAccel = _maxThrustAccel;
            this.probableLandingSiteASL = _probableLandingSiteASL;
            this.probableLandingSiteRadius = _probableLandingSiteASL + bodyRadius;
            referenceFrame.UpdateAtCurrentTime(_initialOrbit.referenceBody);
            orbitReenters = OrbitReenters(_initialOrbit);

            startX = initialOrbit.SwappedRelativePositionAtUT(startUT);
            // This calls some Unity function so it should be done outside the thread
            if (orbitReenters)
            {
                startUT = _UT;
                t = startUT;
                AdvanceToFreefallEnd(initialOrbit);
            }

            maxDragGees = 0;
            deltaVExpended = 0;
            trajectory = ListPool<AbsoluteVector>.Instance.Borrow();

            simCurves = _simcurves;

            once = true;
        }
 public static ReentrySimulation Borrow(Orbit _initialOrbit, double _UT, SimulatedVessel _vessel, SimCurves _simcurves, IDescentSpeedPolicy _descentSpeedPolicy, double _decelEndAltitudeASL, double _maxThrustAccel, double _parachuteSemiDeployMultiplier, double _probableLandingSiteASL, bool _multiplierHasError, double _dt, double _min_dt, double _maxOrbits, bool _noSKiptoFreefall)
 {
     ReentrySimulation sim = pool.Borrow();
     sim.Init(_initialOrbit, _UT, _vessel, _simcurves, _descentSpeedPolicy, _decelEndAltitudeASL, _maxThrustAccel, _parachuteSemiDeployMultiplier, _probableLandingSiteASL, _multiplierHasError, _dt, _min_dt, _maxOrbits, _noSKiptoFreefall);
     return sim;
 }
            public override AutopilotStep Drive(FlightCtrlState s)
            {
                if (vessel.LandedOrSplashed)
                {
                    core.landing.StopLanding();
                    return(null);
                }

                // TODO perhaps we should pop the parachutes at this point, or at least consider it depending on the altitude.

                double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue));

                if (vesselState.limitedMaxThrustAccel < vesselState.gravityForce.magnitude)
                {
                    // if we have TWR < 1, just try as hard as we can to decelerate:
                    // (we need this special case because otherwise the calculations spit out NaN's)
                    core.thrust.tmode         = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
                    core.thrust.trans_kill_h  = true;
                    core.thrust.trans_spd_act = 0;
                }
                else if (minalt > 200)
                {
                    if ((vesselState.surfaceVelocity.magnitude > 5) && (Vector3d.Angle(vesselState.surfaceVelocity, vesselState.up) < 80))
                    {
                        // if we have positive vertical velocity, point up and don't thrust:
                        core.attitude.attitudeTo(Vector3d.up, AttitudeReference.SURFACE_NORTH, null);
                        core.thrust.tmode         = MechJebModuleThrustController.TMode.DIRECT;
                        core.thrust.trans_spd_act = 0;
                    }
                    else if ((vesselState.surfaceVelocity.magnitude > 5) && (Vector3d.Angle(vesselState.forward, -vesselState.surfaceVelocity) > 45))
                    {
                        // if we're not facing approximately retrograde, turn to point retrograde and don't thrust:
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);
                        core.thrust.tmode         = MechJebModuleThrustController.TMode.DIRECT;
                        core.thrust.trans_spd_act = 0;
                    }
                    else
                    {
                        //if we're above 200m, point retrograde and control surface velocity:
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);

                        core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE;

                        //core.thrust.trans_spd_act = (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * minalt) * 0.90F;
                        Vector3d estimatedLandingPosition = vesselState.CoM + vesselState.surfaceVelocity.sqrMagnitude / (2 * vesselState.limitedMaxThrustAccel) * vesselState.surfaceVelocity.normalized;
                        double   terrainRadius            = mainBody.Radius + mainBody.TerrainAltitude(estimatedLandingPosition);
                        aggressivePolicy          = new GravityTurnDescentSpeedPolicy(terrainRadius, mainBody.GeeASL * 9.81, vesselState.limitedMaxThrustAccel); // this constant policy creation is wastefull...
                        core.thrust.trans_spd_act = (float)(aggressivePolicy.MaxAllowedSpeed(vesselState.CoM - mainBody.position, vesselState.surfaceVelocity));
                    }
                }
                else
                {
                    // last 200 meters:
                    core.thrust.trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.limitedMaxThrustAccel - vesselState.localg) * 2 * 200) * 0.90F, (float)minalt / 200);

                    // take into account desired landing speed:
                    core.thrust.trans_spd_act = (float)Math.Min(-core.landing.touchdownSpeed, core.thrust.trans_spd_act);

//                    core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
//                    core.thrust.trans_kill_h = true;

//                    if (Math.Abs(Vector3d.Angle(-vessel.surfaceVelocity, vesselState.up)) < 10)
                    if (vesselState.speedSurfaceHorizontal < 5)
                    {
                        // if we're falling more or less straight down, control vertical speed and
                        // kill horizontal velocity
                        core.thrust.tmode        = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
                        core.thrust.trans_kill_h = true;
                    }
                    else
                    {
                        // if we're falling at a significant angle from vertical, our vertical speed might be
                        // quite small but we might still need to decelerate. Control the total speed instead
                        // by thrusting directly retrograde
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);
                        core.thrust.tmode          = MechJebModuleThrustController.TMode.KEEP_SURFACE;
                        core.thrust.trans_spd_act *= -1;
                    }
                }

                status = "Final descent: " + vesselState.altitudeBottom.ToString("F0") + "m above terrain";

                // ComputeCourseCorrection doesn't work close to the ground

                /* if (core.landing.landAtTarget)
                 * {
                 *  core.rcs.enabled = true;
                 *  Vector3d deltaV = core.landing.ComputeCourseCorrection(false);
                 *  core.rcs.SetWorldVelocityError(deltaV);
                 *
                 *  status += "\nDV: " + deltaV.magnitude.ToString("F3") + " m/s";
                 * } */

                return(this);
            }
        public override void Drive(FlightCtrlState s)
        {
            if (landStep == LandStep.OFF) return;

            // If the latest prediction is a landing, aerobrake or no-reentry prediciton then keep it. However if it is any other sort or result it is not much use to us, so do not bother!
            {
                ReentrySimulation.Result result = predictor.GetResult();
                if (null != result)
                {
                    if (result.outcome != ReentrySimulation.Outcome.ERROR && result.outcome != ReentrySimulation.Outcome.TIMED_OUT)
                    {
                        this.prediction = result;
                    }
                }
            }
            {
                ReentrySimulation.Result result = predictor.GetErrorResult();
                if (null != result)
                {
                    if (result.outcome != ReentrySimulation.Outcome.ERROR && result.outcome != ReentrySimulation.Outcome.TIMED_OUT)
                    {
                        this.errorPrediction = result;
                    }
                }
            }

            descentSpeedPolicy = PickDescentSpeedPolicy();

            predictor.descentSpeedPolicy = PickDescentSpeedPolicy(); //create a separate IDescentSpeedPolicy object for the simulation
            predictor.decelEndAltitudeASL = DecelerationEndAltitude();
            predictor.parachuteSemiDeployMultiplier = this.parachutePlan.Multiplier;

            // Consider lowering the langing gear
            {
                double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue));
                if (deployGears && !deployedGears && (minalt < 1000)) DeployLandingGears();
            }

            if (!PredictionReady && landStep != LandStep.DEORBIT_BURN && landStep != LandStep.PLANE_CHANGE && landStep != LandStep.LOW_DEORBIT_BURN
                && landStep != LandStep.UNTARGETED_DEORBIT && landStep != LandStep.FINAL_DESCENT) return;

            switch (landStep)
            {
                case LandStep.UNTARGETED_DEORBIT:
                    DriveUntargetedDeorbit(s);
                    break;

                case LandStep.PLANE_CHANGE:
                    DrivePlaneChange(s);
                    break;

                case LandStep.LOW_DEORBIT_BURN:
                    DriveLowDeorbitBurn(s);
                    break;

                case LandStep.DEORBIT_BURN:
                    DriveDeorbitBurn(s);
                    break;

                case LandStep.COURSE_CORRECTIONS:
                    DriveCourseCorrections(s);
                    break;

                case LandStep.KILLING_HORIZONTAL_VELOCITY:
                    DriveKillHorizontalVelocity(s);
                    break;

                case LandStep.FINAL_DESCENT:
                    DriveUntargetedLanding(s);
                    break;

                default:
                    break;
            }
        }
        public override void Drive(FlightCtrlState s)
        {
            if (landStep == LandStep.OFF) return;

            descentSpeedPolicy = PickDescentSpeedPolicy();

            predictor.descentSpeedPolicy = PickDescentSpeedPolicy(); //create a separate IDescentSpeedPolicy object for the simulation
            predictor.endAltitudeASL = DecelerationEndAltitude();

            prediction = predictor.GetResult(); //grab a reference to the current result, in case a new one comes in while we're doing stuff

            if (!PredictionReady && landStep != LandStep.DEORBIT_BURN && landStep != LandStep.PLANE_CHANGE && landStep != LandStep.LOW_DEORBIT_BURN
                && landStep != LandStep.UNTARGETED_DEORBIT && landStep != LandStep.FINAL_DESCENT) return;

            switch (landStep)
            {
                case LandStep.UNTARGETED_DEORBIT:
                    DriveUntargetedDeorbit(s);
                    break;

                case LandStep.PLANE_CHANGE:
                    DrivePlaneChange(s);
                    break;

                case LandStep.LOW_DEORBIT_BURN:
                    DriveLowDeorbitBurn(s);
                    break;

                case LandStep.DEORBIT_BURN:
                    DriveDeorbitBurn(s);
                    break;

                case LandStep.COURSE_CORRECTIONS:
                    DriveCourseCorrections(s);
                    break;

                case LandStep.KILLING_HORIZONTAL_VELOCITY:
                    DriveKillHorizontalVelocity(s);
                    break;

                case LandStep.FINAL_DESCENT:
                    DriveUntargetedLanding(s);
                    break;

                default:
                    break;
            }
        }
Esempio n. 12
0
        Vector3d x; //coordinate system used is centered on main body

        #endregion Fields

        #region Constructors

        public ReentrySimulation(Orbit _initialOrbit, double _UT, double _dragMassExcludingUsedParachutes, List<SimulatedParachute> _parachuteList, double _mass,
            IDescentSpeedPolicy _descentSpeedPolicy, double _decelEndAltitudeASL, double _maxThrustAccel, double _parachuteSemiDeployMultiplier, double _probableLandingSiteASL, bool _multiplierHasError, double _dt)
        {
            // Store all the input values as they were given
            input_initialOrbit = _initialOrbit;
            input_UT = _UT;
            input_dragMassExcludingUsedParachutes = _dragMassExcludingUsedParachutes;
            input_parachuteList = _parachuteList;
            input_mass = _mass;
            input_descentSpeedPolicy = _descentSpeedPolicy;
            input_decelEndAltitudeASL = _decelEndAltitudeASL;
            input_maxThrustAccel = _maxThrustAccel;
            input_parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            input_probableLandingSiteASL = _probableLandingSiteASL;
            input_multiplierHasError = _multiplierHasError;
            input_dt = _dt;

            max_dt = _dt;
            dt = max_dt;

            CelestialBody body = _initialOrbit.referenceBody;
            bodyHasAtmosphere = body.atmosphere;
            seaLevelAtmospheres = body.atmosphereMultiplier;
            scaleHeight = 1000 * body.atmosphereScaleHeight;
            bodyRadius = body.Radius;
            gravParameter = body.gravParameter;
            this.dragMassExcludingUsedParachutes = _dragMassExcludingUsedParachutes;

            this.parachutes = _parachuteList;
            this.parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            this.multiplierHasError = _multiplierHasError;

            this.mass = _mass;
            bodyAngularVelocity = body.angularVelocity;
            this.descentSpeedPolicy = _descentSpeedPolicy;
            decelRadius = bodyRadius + _decelEndAltitudeASL;
            aerobrakedRadius = bodyRadius + body.RealMaxAtmosphereAltitude();
            mainBody = body;
            this.maxThrustAccel = _maxThrustAccel;
            this.probableLandingSiteASL = _probableLandingSiteASL;
            this.probableLandingSiteRadius = _probableLandingSiteASL + bodyRadius;

            referenceFrame = ReferenceFrame.CreateAtCurrentTime(_initialOrbit.referenceBody);

            orbitReenters = OrbitReenters(_initialOrbit);

            if (orbitReenters)
            {
                startUT = _UT;
                t = startUT;
                AdvanceToFreefallEnd(_initialOrbit);
            }

            maxDragGees = 0;
            deltaVExpended = 0;
            trajectory = new List<AbsoluteVector>();
        }
Esempio n. 13
0
            public override AutopilotStep Drive(FlightCtrlState s)
            {
                if (vessel.LandedOrSplashed)
                {
                    core.landing.StopLanding();
                    return null;
                }

                // TODO perhaps we should pop the parachutes at this point, or at least consider it depending on the altitude.

                double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue));

                if (vesselState.limitedMaxThrustAccel < vesselState.gravityForce.magnitude)
                {
                    // if we have TWR < 1, just try as hard as we can to decelerate:
                    // (we need this special case because otherwise the calculations spit out NaN's)
                    core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
                    core.thrust.trans_kill_h = true;
                    core.thrust.trans_spd_act = 0;
                }
                else if (minalt > 200)
                {
                    if ((vesselState.surfaceVelocity.magnitude > 5) && (Vector3d.Angle(vesselState.surfaceVelocity, vesselState.up) < 80))
                    {
                        // if we have positive vertical velocity, point up and don't thrust:
                        core.attitude.attitudeTo(Vector3d.up, AttitudeReference.SURFACE_NORTH, null);
                        core.thrust.tmode = MechJebModuleThrustController.TMode.DIRECT;
                        core.thrust.trans_spd_act = 0;
                    }
                    else if ((vesselState.surfaceVelocity.magnitude > 5) && (Vector3d.Angle(vesselState.forward, -vesselState.surfaceVelocity) > 45))
                    {
                        // if we're not facing approximately retrograde, turn to point retrograde and don't thrust:
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);
                        core.thrust.tmode = MechJebModuleThrustController.TMode.DIRECT;
                        core.thrust.trans_spd_act = 0;
                    }
                    else
                    {
                        //if we're above 200m, point retrograde and control surface velocity:
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);

                        core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE;

                        //core.thrust.trans_spd_act = (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * minalt) * 0.90F;
                        Vector3d estimatedLandingPosition = vesselState.CoM + vesselState.surfaceVelocity.sqrMagnitude / (2 * vesselState.limitedMaxThrustAccel) * vesselState.surfaceVelocity.normalized;
                        double terrainRadius = mainBody.Radius + mainBody.TerrainAltitude(estimatedLandingPosition);
                        aggressivePolicy = new GravityTurnDescentSpeedPolicy(terrainRadius, mainBody.GeeASL * 9.81, vesselState.limitedMaxThrustAccel);  // this constant policy creation is wastefull...
                        core.thrust.trans_spd_act = (float)(aggressivePolicy.MaxAllowedSpeed(vesselState.CoM - mainBody.position, vesselState.surfaceVelocity));
                    }
                }
                else
                {
                    // last 200 meters:
                    core.thrust.trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.limitedMaxThrustAccel - vesselState.localg) * 2 * 200) * 0.90F, (float)minalt / 200);

                    // take into account desired landing speed:
                    core.thrust.trans_spd_act = (float)Math.Min(-core.landing.touchdownSpeed, core.thrust.trans_spd_act);

//                    core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
//                    core.thrust.trans_kill_h = true;

//                    if (Math.Abs(Vector3d.Angle(-vessel.surfaceVelocity, vesselState.up)) < 10)
                    if (vesselState.speedSurfaceHorizontal < 5)
                    {
                        // if we're falling more or less straight down, control vertical speed and 
                        // kill horizontal velocity
                        core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
                        core.thrust.trans_kill_h = true;
                    }
                    else
                    {
                        // if we're falling at a significant angle from vertical, our vertical speed might be
                        // quite small but we might still need to decelerate. Control the total speed instead
                        // by thrusting directly retrograde
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);
                        core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE;
                        core.thrust.trans_spd_act *= -1;
                    }
                }

                status = "Final descent: " + vesselState.altitudeBottom.ToString("F0") + "m above terrain";

                // ComputeCourseCorrection doesn't work close to the ground
                /* if (core.landing.landAtTarget)
                {
                    core.rcs.enabled = true;
                    Vector3d deltaV = core.landing.ComputeCourseCorrection(false);
                    core.rcs.SetWorldVelocityError(deltaV);

                    status += "\nDV: " + deltaV.magnitude.ToString("F3") + " m/s";
                } */

                return this;
            }
Esempio n. 14
0
            public override AutopilotStep Drive(FlightCtrlState s)
            {
                if (vessel.LandedOrSplashed)
                {
                    core.landing.StopLanding();
                    vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true);
                    vessel.Autopilot.Enable(VesselAutopilot.AutopilotMode.RadialIn);
                    return(null);
                }

                if (useChute)
                {
                    waitForChute = vesselState.parachutes.Any(p => p.Anim.isPlaying);
                }

                double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue));

                if (vesselState.limitedMaxThrustAccel < vesselState.gravityForce.magnitude)
                {
                    // if we have TWR < 1, just try as hard as we can to decelerate:
                    // (we need this special case because otherwise the calculations spit out NaN's)
                    core.thrust.tmode         = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
                    core.thrust.trans_kill_h  = true;
                    core.thrust.trans_spd_act = 0;
                }
                else if (minalt > 25D * gee)
                {
                    if ((vesselState.surfaceVelocity.magnitude > 5) && (Vector3d.Angle(vesselState.surfaceVelocity, vesselState.up) < 80))
                    {
                        // if we have positive vertical velocity, point up and don't thrust:
                        core.attitude.attitudeTo(Vector3d.up, AttitudeReference.SURFACE_NORTH, null);
                        core.thrust.tmode         = MechJebModuleThrustController.TMode.DIRECT;
                        core.thrust.trans_spd_act = 0;
                    }
                    else if ((vesselState.surfaceVelocity.magnitude > 5) && (Vector3d.Angle(vesselState.forward, -vesselState.surfaceVelocity) > 45))
                    {
                        // if we're not facing approximately retrograde, turn to point retrograde and don't thrust:
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);
                        core.thrust.tmode         = MechJebModuleThrustController.TMode.DIRECT;
                        core.thrust.trans_spd_act = 0;
                    }
                    else if (useChute)
                    {
                        // rely on parachutes to get down to 200m
                        // always point up towards target, so any lift providing surface will get us closer
                        Vector3d diff = core.target.GetPositionTargetPosition() - core.landing.LandingSite;
                        core.attitude.attitudeTo(Quaternion.LookRotation(-vesselState.surfaceVelocity, diff), AttitudeReference.INERTIAL, null);
                        // for fine tuning we need to reduce deploy angles or we just spin around target
                        finalDifferenceTarget.value = diff.magnitude;
                        if (finalDifferenceTarget < 100)
                        {
                            foreach (var mcs in vessel.FindPartModulesImplementing <ModuleControlSurface>())
                            {
                                if (mcs.deploy)
                                {
                                    Vector2 scaledLimit = Vector2.Max((float)finalDifferenceTarget / 100f * mcs.deployAngleLimits, new Vector2(-2, 2));
                                    mcs.deployAngle = Mathf.Clamp(mcs.deployAngle, scaledLimit.x, scaledLimit.y);
                                }
                            }
                        }

                        //Debug.Log(String.Format("Diff to target: {0:F2} ", (Vector3) diff));

                        //assume we fall straight due to parachutes
                        double maxSpeed = 0.9 * Math.Sqrt(2d * vesselState.altitudeTrue * (vesselState.limitedMaxThrustAccel - gee));
                        if (!waitForChute && (vesselState.TerminalVelocity() > maxSpeed))
                        {
                            Debug.Log(String.Format("Emergency break in final descent alt:{0} accel:{1} maxSpeed:{2} terminal v:{3}", vesselState.altitudeTrue, vesselState.limitedMaxThrustAccel, maxSpeed, vesselState.TerminalVelocity()));
                            core.thrust.trans_spd_act = (float)maxSpeed;
                            core.thrust.tmode         = MechJebModuleThrustController.TMode.KEEP_SURFACE;
                        }
                        else
                        {
                            core.thrust.tmode         = MechJebModuleThrustController.TMode.DIRECT;
                            core.thrust.trans_spd_act = 0;
                        }
                    }
                    else
                    {
                        //if we're above 200m, point retrograde and control surface velocity:
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);

                        core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE;

                        //core.thrust.trans_spd_act = (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * minalt) * 0.90F;
                        Vector3d estimatedLandingPosition = vesselState.CoM + vesselState.surfaceVelocity.sqrMagnitude / (2 * vesselState.limitedMaxThrustAccel) * vesselState.surfaceVelocity.normalized;
                        double   terrainRadius            = mainBody.Radius + mainBody.TerrainAltitude(estimatedLandingPosition);
                        aggressivePolicy          = new GravityTurnDescentSpeedPolicy(terrainRadius, gee, vesselState.limitedMaxThrustAccel); // this constant policy creation is wastefull...
                        core.thrust.trans_spd_act = (float)(aggressivePolicy.MaxAllowedSpeed(vesselState.CoM - mainBody.position, vesselState.surfaceVelocity));
                    }
                }
                else
                {
                    // last 250m on Kerbin, lower on lighter, higher on heavier bodies
                    // + 15% safety margin on break distance + distance for last three second with touchdown speed
                    double safety_alt = Math.Max(0.85D * (minalt - core.landing.touchdownSpeed * 2D /*s*/), 0);
                    if (mainBody.atmosphere)
                    {
                        // calculate effective terminal velocity for powered landing
                        // it is smaller as reduced speed from slow down decreases drag
                        // equations are derived from F = k * v^2 + m* ( a -g ), meaning accelerating from ground with help of drag
                        // equation assumes that k is constant, which fails at bigger altitude, but within final touchdown it is safe assumption
                        double a_eff      = vesselState.limitedMaxThrustAccel - gee;
                        double v_terminal = vesselState.TerminalVelocity() * Math.Sqrt(a_eff / gee);
                        //double x_0 = - 0.5D * v_terminal / a_eff * Math.Log( 1+ core.landing.touchdownSpeed * core.landing.touchdownSpeed/ (v_terminal * v_terminal));
                        // v(t) = v_terminal * tan( a_eff * t / v_terminal) + arctan( touchdownSpeed / v_terminal) )
                        // x(t) =  x_o - v_terminal^2 / a_eff * ln(cos(a_eff / v_terminal * t + arctan(touchdownSpeed / v_terminal) ))
                        // note: equations are only for small t where assumption about drag holds -> parameter in cos stays in [0,pi/2]
                        // v(x) = v_terminal * tan( arccos( e ^(-a_eff/v_terminal^2 * ( x -x_0))))
                        // for survivable touchdownspeeds x_0 is few cm, so we neglect it
                        core.thrust.trans_spd_act = (float)(-v_terminal * Math.Tan(Math.Acos(Math.Exp(-a_eff / (v_terminal * v_terminal) * safety_alt))));

                        Debug.Log(String.Format("FinalDescent: Limit speed for safety alt={0:F0} to v_target={1:F1}, v={2:F1}, targetThrottle={3:P0}, tmode={4}", safety_alt, core.thrust.trans_spd_act, vesselState.speedVertical, core.thrust.targetThrottle, core.thrust.tmode));
                    }
                    else
                    {
                        // last 200 meters ramp down speed with limit of falling full throttle break
                        core.thrust.trans_spd_act = -Mathf.Sqrt((float)((vesselState.limitedMaxThrustAccel - vesselState.localg) * safety_alt * 2D + core.landing.touchdownSpeed * core.landing.touchdownSpeed));
                    }
                    // take into account desired landing speed:
                    core.thrust.trans_spd_act = (float)Math.Min(-core.landing.touchdownSpeed, core.thrust.trans_spd_act);

                    //avoid hopping due to throttle PID oversteering on very last moment, so we do direct control
                    if (-vesselState.speedVertical < 3D * core.landing.touchdownSpeed && core.thrust.targetThrottle > 0.2 && safety_alt < 5)
                    {
                        core.attitude.attitudeTo(Quaternion.LookRotation(vesselState.up, vessel.transform.forward), AttitudeReference.INERTIAL, null);
                        if (-vesselState.speedVertical > core.landing.touchdownSpeed + 1D)
                        {
                            // break with maximum thrust or 50 m/s if we have more available, so speed between 2 physical updates should change at most 1 m/s
                            core.thrust.trans_spd_act = 100f * Mathf.Clamp01((float)((gee + 50) / vesselState.limitedMaxThrustAccel));
                        }
                        else
                        {
                            //constant speed descent, we just fight gravity
                            core.thrust.trans_spd_act = 95f * Mathf.Clamp01((float)(gee / vesselState.limitedMaxThrustAccel));
                        }
                        core.thrust.tmode = MechJebModuleThrustController.TMode.DIRECT;
                        Debug.Log(String.Format("FinalDescent: Touchdown soon ! safety alt={0:F1}, v_vertical={2:F1}, v_horizontal={3:F1} => thrust={1:F0} % ", safety_alt, core.thrust.trans_spd_act, vesselState.speedVertical.value, vesselState.speedSurfaceHorizontal.value));
                    }
                    else if (vesselState.speedSurfaceHorizontal < 5)
                    {
                        // if we're falling more or less straight down, control vertical speed and
                        // kill horizontal velocity
                        core.thrust.tmode        = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
                        core.thrust.trans_kill_h = true;
                    }
                    else
                    {
                        // if we're falling at a significant angle from vertical, our vertical speed might be
                        // quite small but we might still need to decelerate. Control the total speed instead
                        // by thrusting directly retrograde
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);
                        core.thrust.tmode          = MechJebModuleThrustController.TMode.KEEP_SURFACE;
                        core.thrust.trans_spd_act *= -1;
                    }
                }

                status = "Final descent: " + vesselState.altitudeBottom.ToString("F0") + "m above terrain";

                // ComputeCourseCorrection doesn't work close to the ground

                /* if (core.landing.landAtTarget)
                 * {
                 *  core.rcs.enabled = true;
                 *  Vector3d deltaV = core.landing.ComputeCourseCorrection(false);
                 *  core.rcs.SetWorldVelocityError(deltaV);
                 *
                 *  status += "\nDV: " + deltaV.magnitude.ToString("F3") + " m/s";
                 * } */

                return(this);
            }
Esempio n. 15
0
        Vector3d x; //coordinate system used is centered on main body

        #endregion Fields

        #region Constructors

        public ReentrySimulation(Orbit initialOrbit, double UT, double dragCoefficient, List<SimulatedParachute> parachuteList, double mass,
            IDescentSpeedPolicy descentSpeedPolicy, double endAltitudeASL, double maxThrustAccel)
        {
            CelestialBody body = initialOrbit.referenceBody;
            bodyHasAtmosphere = body.atmosphere;
            seaLevelAtmospheres = body.atmosphereMultiplier;
            scaleHeight = 1000 * body.atmosphereScaleHeight;
            bodyRadius = body.Radius;
            gravParameter = body.gravParameter;
            this.dragCoefficient = dragCoefficient;

            this.parachutes = parachuteList;

            this.mass = mass;
            bodyAngularVelocity = body.angularVelocity;
            this.descentSpeedPolicy = descentSpeedPolicy;
            landedRadius = bodyRadius + endAltitudeASL;
            aerobrakedRadius = bodyRadius + body.RealMaxAtmosphereAltitude();
            mainBody = body;
            this.maxThrustAccel = maxThrustAccel;

            referenceFrame = ReferenceFrame.CreateAtCurrentTime(initialOrbit.referenceBody);

            orbitReenters = OrbitReenters(initialOrbit);

            if (orbitReenters)
            {
                startUT = UT;
                t = startUT;
                AdvanceToFreefallEnd(initialOrbit);
            }

            maxDragGees = 0;
            deltaVExpended = 0;
            trajectory = new List<AbsoluteVector>();
        }
Esempio n. 16
0
            public override AutopilotStep Drive(FlightCtrlState s)
            {
                if (vessel.LandedOrSplashed)
                {
                    core.landing.StopLanding();
                    return(null);
                }

                // TODO perhaps we should pop the parachutes at this point, or at least consider it depending on the altitude.

                double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue));

                if (vesselState.limitedMaxThrustAccel < vesselState.gravityForce.magnitude)
                {
                    // if we have TWR < 1, just try as hard as we can to decelerate:
                    // (we need this special case because otherwise the calculations spit out NaN's)
                    core.thrust.tmode         = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
                    core.thrust.trans_kill_h  = true;
                    core.thrust.trans_spd_act = 0;
                }
                else if (minalt > 200)
                {
                    if ((vesselState.surfaceVelocity.magnitude > 5) && (Vector3d.Angle(vesselState.surfaceVelocity, vesselState.up) < 80))
                    {
                        // if we have positive vertical velocity, point up and don't thrust:
                        core.attitude.attitudeTo(Vector3d.up, AttitudeReference.SURFACE_NORTH, null);
                        core.thrust.tmode         = MechJebModuleThrustController.TMode.DIRECT;
                        core.thrust.trans_spd_act = 0;
                    }
                    else if ((vesselState.surfaceVelocity.magnitude > 5) && (Vector3d.Angle(vesselState.forward, -vesselState.surfaceVelocity) > 45))
                    {
                        // if we're not facing approximately retrograde, turn to point retrograde and don't thrust:
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);
                        core.thrust.tmode         = MechJebModuleThrustController.TMode.DIRECT;
                        core.thrust.trans_spd_act = 0;
                    }
                    else
                    {
                        //if we're above 200m, point retrograde and control surface velocity:
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);

                        core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE;

                        //core.thrust.trans_spd_act = (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * minalt) * 0.90F;
                        Vector3d estimatedLandingPosition = vesselState.CoM + vesselState.surfaceVelocity.sqrMagnitude / (2 * vesselState.limitedMaxThrustAccel) * vesselState.surfaceVelocity.normalized;
                        double   terrainRadius            = mainBody.Radius + mainBody.TerrainAltitude(estimatedLandingPosition);
                        aggressivePolicy          = new GravityTurnDescentSpeedPolicy(terrainRadius, mainBody.GeeASL * 9.81, vesselState.limitedMaxThrustAccel); // this constant policy creation is wastefull...
                        core.thrust.trans_spd_act = (float)(aggressivePolicy.MaxAllowedSpeed(vesselState.CoM - mainBody.position, vesselState.surfaceVelocity));
                        thrustAt200Meters         = (float)vesselState.limitedMaxThrustAccel;                                                                    // this gets updated until we are below 200 meters
                    }
                }
                else
                {
                    float previous_trans_spd_act = Math.Abs(core.thrust.trans_spd_act); // avoid issues going from KEEP_SURFACE mode to KEEP_VERTICAL mode

                    // Last 200 meters, at this point the rocket has a TWR that will rise rapidly, so be sure to use the same policy based on an older
                    // TWR. Otherwise we would suddenly get a large jump in desired speed leading to a landing that is too fast.
                    core.thrust.trans_spd_act = Mathf.Lerp(0, (float)Math.Sqrt((thrustAt200Meters - vesselState.localg) * 2 * 200) * 0.90F, (float)minalt / 200);

                    // Sometimes during the descent we end up going up a bit due to overthrusting during breaking, avoid thrusting up even more and destabilizing the rocket
                    core.thrust.trans_spd_act = (float)Math.Min(previous_trans_spd_act, core.thrust.trans_spd_act);

                    // take into account desired landing speed:
                    core.thrust.trans_spd_act = (float)Math.Max(core.landing.touchdownSpeed, core.thrust.trans_spd_act);

                    // Prevent that we switch back from Vertical mode to KeepSurface mode
                    // When that happens the rocket will start tilting and end up falling over
                    if (vesselState.speedSurfaceHorizontal < 5)
                    {
                        forceVerticalMode = true;
                    }

                    if (forceVerticalMode)
                    {
                        // if we're falling more or less straight down, control vertical speed and
                        // kill horizontal velocity
                        core.thrust.tmode          = MechJebModuleThrustController.TMode.KEEP_VERTICAL;
                        core.thrust.trans_spd_act *= -1;
                        core.thrust.trans_kill_h   = false; // rockets are long, and will fall over if you attempt to do any manouvers to kill that last bit of horizontal speed
                        if (core.landing.rcsAdjustment)     // If allowed, use RCS to stablize the rocket
                        {
                            core.rcs.enabled = true;
                        }
                        // Turn on SAS because we are likely to have a bit of horizontal speed left that needs to stabilize
                        // Use SmartASS, because Mechjeb doesn't expect SAS to be used (i.e. it is automatically turned off again)
                        core.EngageSmartASSControl(MechJebModuleSmartASS.Mode.SURFACE, MechJebModuleSmartASS.Target.VERTICAL_PLUS, true);
                    }
                    else
                    {
                        // if we're falling at a significant angle from vertical, our vertical speed might be
                        // quite small but we might still need to decelerate. Control the total speed instead
                        // by thrusting directly retrograde
                        core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null);
                        core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE;
                    }
                }

                status = "Final descent: " + vesselState.altitudeBottom.ToString("F0") + "m above terrain";

                // ComputeCourseCorrection doesn't work close to the ground

                /* if (core.landing.landAtTarget)
                 * {
                 *  core.rcs.enabled = true;
                 *  Vector3d deltaV = core.landing.ComputeCourseCorrection(false);
                 *  core.rcs.SetWorldVelocityError(deltaV);
                 *
                 *  status += "\nDV: " + deltaV.magnitude.ToString("F3") + " m/s";
                 * } */

                return(this);
            }
        public override void Drive(FlightCtrlState s)
        {
            if (!active)
                return;

            // If the latest prediction is a landing, aerobrake or no-reentry prediciton then keep it.
            // However if it is any other sort or result it is not much use to us, so do not bother!
            {
                ReentrySimulation.Result result = predictor.Result;
                if (null != result)
                {
                    if (result.outcome != ReentrySimulation.Outcome.ERROR && result.outcome != ReentrySimulation.Outcome.TIMED_OUT)
                    {
                        this.prediction = result;
                    }
                }
            }
            {
                ReentrySimulation.Result result = predictor.GetErrorResult();
                if (null != result)
                {
                    if (result.outcome != ReentrySimulation.Outcome.ERROR && result.outcome != ReentrySimulation.Outcome.TIMED_OUT)
                    {
                        this.errorPrediction = result;
                    }
                }
            }

            descentSpeedPolicy = PickDescentSpeedPolicy();

            PatchPredictorPolicy();

            // Consider lowering the langing gear
            {
                double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue));
                if (deployGears && !deployedGears && (minalt < 1000))
                    DeployLandingGears();
            }

            base.Drive(s);
        }
Esempio n. 18
0
        public ReentrySimulation(Orbit _initialOrbit, double _UT, SimulatedVessel _vessel, SimCurves _simcurves, IDescentSpeedPolicy _descentSpeedPolicy, double _decelEndAltitudeASL, double _maxThrustAccel, double _parachuteSemiDeployMultiplier, double _probableLandingSiteASL, bool _multiplierHasError, double _dt, double _min_dt)
        {
            // Store all the input values as they were given
            input_initialOrbit = _initialOrbit;
            input_UT           = _UT;

            vessel = _vessel;
            input_descentSpeedPolicy            = _descentSpeedPolicy;
            input_decelEndAltitudeASL           = _decelEndAltitudeASL;
            input_maxThrustAccel                = _maxThrustAccel;
            input_parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            input_probableLandingSiteASL        = _probableLandingSiteASL;
            input_multiplierHasError            = _multiplierHasError;
            input_dt = _dt;

            // the vessel attitude relative to the surface vel. Fixed for now
            attitude = Quaternion.Euler(180, 0, 0);

            min_dt = _min_dt;
            max_dt = _dt;
            dt     = max_dt;

            // Get a copy of the original orbit, to be more thread safe
            initialOrbit = new Orbit();
            initialOrbit.UpdateFromOrbitAtUT(_initialOrbit, _UT, _initialOrbit.referenceBody);

            CelestialBody body = _initialOrbit.referenceBody;

            bodyHasAtmosphere = body.atmosphere;
            bodyRadius        = body.Radius;
            gravParameter     = body.gravParameter;

            this.parachuteSemiDeployMultiplier = _parachuteSemiDeployMultiplier;
            this.multiplierHasError            = _multiplierHasError;

            bodyAngularVelocity     = body.angularVelocity;
            this.descentSpeedPolicy = _descentSpeedPolicy;
            decelRadius             = bodyRadius + _decelEndAltitudeASL;
            aerobrakedRadius        = bodyRadius + body.RealMaxAtmosphereAltitude();
            mainBody                       = body;
            this.maxThrustAccel            = _maxThrustAccel;
            this.probableLandingSiteASL    = _probableLandingSiteASL;
            this.probableLandingSiteRadius = _probableLandingSiteASL + bodyRadius;

            referenceFrame = ReferenceFrame.CreateAtCurrentTime(_initialOrbit.referenceBody);

            orbitReenters = OrbitReenters(_initialOrbit);

            if (orbitReenters)
            {
                startUT = _UT;
            }

            maxDragGees    = 0;
            deltaVExpended = 0;
            trajectory     = new List <AbsoluteVector>();

            simCurves = _simcurves;

            once = true;
        }