Пример #1
0
        void DriveCircularizationBurn(FlightCtrlState s)
        {
            if (!vessel.patchedConicsUnlocked() || skipCircularization)
            {
                this.users.Clear();
                return;
            }

            DriveDeployableComponents(s);

            if (placedCircularizeNode)
            {
                if (vessel.patchedConicSolver.maneuverNodes.Count == 0)
                {
                    MechJebModuleFlightRecorder recorder = core.GetComputerModule <MechJebModuleFlightRecorder>();
                    if (recorder != null)
                    {
                        launchPhaseAngle = recorder.phaseAngleFromMark;
                    }
                    if (recorder != null)
                    {
                        launchLANDifference = vesselState.orbitLAN - recorder.markLAN;
                    }

                    //finished circularize
                    this.users.Clear();
                    return;
                }
            }
            else
            {
                //place circularization node
                vessel.RemoveAllManeuverNodes();
                double UT = orbit.NextApoapsisTime(vesselState.time);
                //During the circularization burn, try to correct any inclination errors because it's better to combine the two burns.
                //  For example, if you're about to do a 1500 m/s circularization burn, if you combine a 200 m/s inclination correction
                //  into it, you actually only spend 1513 m/s to execute combined manuver.  Mechjeb should also do correction burns before
                //  this if possible, and this can't correct all errors... but it's better then nothing.
                //   (A better version of this should try to match inclination & LAN if target is specified)
                // FIXME? this inclination correction is unlikely to be at tha AN/DN and will throw the LAN off with anything other than high
                // TWR launches from equatorial launch sites -- should probably be made optional (or clip it if the correction is too large).
                Vector3d inclinationCorrection = OrbitalManeuverCalculator.DeltaVToChangeInclination(orbit, UT, Math.Abs(desiredInclination));
                Vector3d smaCorrection         = OrbitalManeuverCalculator.DeltaVForSemiMajorAxis(orbit.PerturbedOrbit(UT, inclinationCorrection), UT,
                                                                                                  desiredOrbitAltitude + mainBody.Radius);
                Vector3d dV = inclinationCorrection + smaCorrection;
                vessel.PlaceManeuverNode(orbit, dV, UT);
                placedCircularizeNode = true;

                core.node.ExecuteOneNode(this);
            }

            if (core.node.burnTriggered)
            {
                status = Localizer.Format("#MechJeb_Ascent_status7");                         //"Circularizing"
            }
            else
            {
                status = Localizer.Format("#MechJeb_Ascent_status8"); //"Coasting to circularization burn"
            }
        }
Пример #2
0
        void DriveCircularizationBurn(FlightCtrlState s)
        {
            if (!vessel.patchedConicsUnlocked() || skipCircularization)
            {
                this.users.Clear();
                return;
            }

            if (placedCircularizeNode)
            {
                if (!vessel.patchedConicSolver.maneuverNodes.Any())
                {
                    MechJebModuleFlightRecorder recorder = core.GetComputerModule <MechJebModuleFlightRecorder>();
                    if (recorder != null)
                    {
                        launchPhaseAngle = recorder.phaseAngleFromMark;
                    }
                    if (recorder != null)
                    {
                        launchLANDifference = vesselState.orbitLAN - recorder.markLAN;
                    }

                    //finished circularize
                    this.users.Clear();
                    return;
                }
            }
            else
            {
                //place circularization node
                vessel.RemoveAllManeuverNodes();
                double UT = orbit.NextApoapsisTime(vesselState.time);
                //During the circularization burn, try to correct any inclination errors because it's better to combine the two burns.
                //  For example, if you're about to do a 1500 m/s circularization burn, if you combine a 200 m/s inclination correction
                //  into it, you actually only spend 1513 m/s to execute combined manuver.  Mechjeb should also do correction burns before
                //  this if possible, and this can't correct all errors... but it's better then nothing.
                //   (A better version of this should try to match inclination & LAN if target is specified)
                Vector3d inclinationCorrection = OrbitalManeuverCalculator.DeltaVToChangeInclination(orbit, UT, desiredInclination);
                Vector3d smaCorrection         = OrbitalManeuverCalculator.DeltaVForSemiMajorAxis(orbit.PerturbedOrbit(UT, inclinationCorrection), UT,
                                                                                                  desiredOrbitAltitude + mainBody.Radius);
                Vector3d dV = inclinationCorrection + smaCorrection;
                vessel.PlaceManeuverNode(orbit, dV, UT);
                placedCircularizeNode = true;

                core.node.ExecuteOneNode(this);
            }

            if (core.node.burnTriggered)
            {
                status = "Circularizing";
            }
            else
            {
                status = "Coasting to circularization burn";
            }
        }
        void DriveCircularizationBurn(FlightCtrlState s)
        {
            if (!vessel.patchedConicsUnlocked() || skipCircularization)
            {
                this.users.Clear();
                return;
            }

            if (placedCircularizeNode)
            {
                if (!vessel.patchedConicSolver.maneuverNodes.Any())
                {
                    MechJebModuleFlightRecorder recorder = core.GetComputerModule <MechJebModuleFlightRecorder>();
                    if (recorder != null)
                    {
                        launchPhaseAngle = recorder.phaseAngleFromMark;
                    }
                    if (recorder != null)
                    {
                        launchLANDifference = vesselState.orbitLAN - recorder.markLAN;
                    }

                    //finished circularize
                    this.users.Clear();
                    return;
                }
            }
            else
            {
                //place circularization node
                vessel.RemoveAllManeuverNodes();
                double UT = orbit.NextApoapsisTime(vesselState.time);
                //Vector3d dV = OrbitalManeuverCalculator.DeltaVToCircularize(orbit, UT);
                Vector3d dV = OrbitalManeuverCalculator.DeltaVForSemiMajorAxis(orbit, UT, desiredOrbitAltitude + mainBody.Radius);
                vessel.PlaceManeuverNode(orbit, dV, UT);
                placedCircularizeNode = true;

                core.node.ExecuteOneNode(this);
            }

            if (core.node.burnTriggered)
            {
                status = "Circularizing";
            }
            else
            {
                status = "Coasting to circularization burn";
            }
        }
Пример #4
0
        public override ManeuverParameters MakeNodeImpl(Orbit o, double universalTime, MechJebModuleTargetController target)
        {
            double UT = timeSelector.ComputeManeuverTime(o, universalTime, target);

            if (2 * newSMA > o.Radius(UT) + o.referenceBody.sphereOfInfluence)
            {
                errorMessage = Localizer.Format("#MechJeb_Sa_errormsg");//Warning: new Semi-Major Axis is very large, and may result in a hyberbolic orbit
            }

            if (o.Radius(UT) > 2 * newSMA)
            {
                throw new OperationException(Localizer.Format("#MechJeb_Sa_Exception") + o.referenceBody.displayName + "(" + MuUtils.ToSI(o.referenceBody.Radius, 3) + "m)");//cannot make Semi-Major Axis less than twice the burn altitude plus the radius of
            }

            return(new ManeuverParameters(OrbitalManeuverCalculator.DeltaVForSemiMajorAxis(o, UT, newSMA), UT));
        }
Пример #5
0
        void MakeNodeForOperation(Orbit o, double UT, Operation op, double newPeA, double newApA, double newInc, double courseCorrectFinalPeA, double moonReturnAltitude, double interceptInterval)
        {
            Vector3d dV = Vector3d.zero;

            double bodyRadius = o.referenceBody.Radius;

//            print(newPeA + " - " + this.newPeA + "\n" +
//                  newApA + " - " + this.newApA + "\n" +
//                  newInc + " - " + this.newInc + "\n" +
//                  courseCorrectFinalPeA + " - " + this.courseCorrectFinalPeA + "\n" +
//                  moonReturnAltitude + " - " + this.moonReturnAltitude + "\n" +
//                  interceptInterval + " - " + this.interceptInterval);

            switch (op)
            {
            case Operation.CIRCULARIZE:
                dV = OrbitalManeuverCalculator.DeltaVToCircularize(o, UT);
                break;

            case Operation.ELLIPTICIZE:
                dV = OrbitalManeuverCalculator.DeltaVToEllipticize(o, UT, newPeA + bodyRadius, newApA + bodyRadius);
                break;

            case Operation.PERIAPSIS:
                dV = OrbitalManeuverCalculator.DeltaVToChangePeriapsis(o, UT, newPeA + bodyRadius);
                break;

            case Operation.APOAPSIS:
                dV = OrbitalManeuverCalculator.DeltaVToChangeApoapsis(o, UT, newApA + bodyRadius);
                break;

            case Operation.INCLINATION:
                dV = OrbitalManeuverCalculator.DeltaVToChangeInclination(o, UT, newInc);
                break;

            case Operation.PLANE:
                if (timeReference == TimeReference.REL_ASCENDING)
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesAscending(o, core.target.TargetOrbit, UT, out UT);
                }
                else
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesDescending(o, core.target.TargetOrbit, UT, out UT);
                }
                break;

            case Operation.TRANSFER:
                dV = OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(o, core.target.TargetOrbit, UT, out UT);
                break;

            case Operation.MOON_RETURN:
                dV = OrbitalManeuverCalculator.DeltaVAndTimeForMoonReturnEjection(o, UT, o.referenceBody.referenceBody.Radius + moonReturnAltitude, out UT);
                break;

            case Operation.COURSE_CORRECTION:
                CelestialBody targetBody = core.target.Target as CelestialBody;
                if (targetBody != null)
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeForCheapestCourseCorrection(o, UT, core.target.TargetOrbit, targetBody, targetBody.Radius + courseCorrectFinalPeA, out UT);
                }
                else
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeForCheapestCourseCorrection(o, UT, core.target.TargetOrbit, interceptDistance, out UT);
                }
                break;

            case Operation.INTERPLANETARY_TRANSFER:
                dV = OrbitalManeuverCalculator.DeltaVAndTimeForInterplanetaryTransferEjection(o, UT, core.target.TargetOrbit, true, out UT);
                break;

            case Operation.LAMBERT:
                dV = OrbitalManeuverCalculator.DeltaVToInterceptAtTime(o, UT, core.target.TargetOrbit, UT + interceptInterval);
                break;

            case Operation.KILL_RELVEL:
                dV = OrbitalManeuverCalculator.DeltaVToMatchVelocities(o, UT, core.target.TargetOrbit);
                break;

            case Operation.RESONANT_ORBIT:
                dV = OrbitalManeuverCalculator.DeltaVToResonantOrbit(o, UT, (double)resonanceNumerator.val / resonanceDenominator.val);
                break;

            case Operation.SEMI_MAJOR:
                dV = OrbitalManeuverCalculator.DeltaVForSemiMajorAxis(o, UT, newSMA);
                break;

            case Operation.LAN:
                dV = OrbitalManeuverCalculator.DeltaVToShiftLAN(o, UT, core.target.targetLongitude);
                break;
            }

            vessel.PlaceManeuverNode(o, dV, UT);
        }