Пример #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";
            }
        }
Пример #3
0
        public override List <ManeuverParameters> MakeNodesImpl(Orbit o, double universalTime, MechJebModuleTargetController target)
        {
            double UT = timeSelector.ComputeManeuverTime(o, universalTime, target);

            List <ManeuverParameters> NodeList = new List <ManeuverParameters>();

            NodeList.Add(new ManeuverParameters(OrbitalManeuverCalculator.DeltaVToChangeInclination(o, UT, newInc), UT));

            return(NodeList);
        }
Пример #4
0
        void MakeNodeForOperation(Orbit o, double UT)
        {
            Vector3d dV = Vector3d.zero;

            double bodyRadius = o.referenceBody.Radius;

            switch (operation)
            {
            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.Orbit, UT, out UT);
                }
                else
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeToMatchPlanesDescending(o, core.target.Orbit, UT, out UT);
                }
                break;

            case Operation.TRANSFER:
                dV = OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(o, core.target.Orbit, 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.Orbit, targetBody, targetBody.Radius + courseCorrectFinalPeA, out UT);
                }
                else
                {
                    dV = OrbitalManeuverCalculator.DeltaVAndTimeForCheapestCourseCorrection(o, UT, core.target.Orbit, out UT);
                }
                break;

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

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

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

            vessel.PlaceManeuverNode(o, dV, 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);
        }