Пример #1
0
        public override ManeuverParameters MakeNodeImpl(Orbit o, double UT, MechJebModuleTargetController target)
        {
            // Check preconditions
            if (!target.NormalTargetExists)
            {
                throw new Exception("must select a target for the interplanetary transfer.");
            }

            if (o.referenceBody.referenceBody == null)
            {
                throw new Exception("doesn't make sense to plot an interplanetary transfer from an orbit around " + o.referenceBody.theName + ".");
            }

            if (o.referenceBody.referenceBody != target.TargetOrbit.referenceBody)
            {
                if (o.referenceBody == target.TargetOrbit.referenceBody)
                {
                    throw new Exception("use regular Hohmann transfer function to intercept another body orbiting " + o.referenceBody.theName + ".");
                }
                throw new Exception("an interplanetary transfer from within " + o.referenceBody.theName + "'s sphere of influence must target a body that orbits " + o.referenceBody.theName + "'s parent, " + o.referenceBody.referenceBody.theName + ".");
            }

            // Simple warnings
            if (o.referenceBody.orbit.RelativeInclination(target.TargetOrbit) > 30)
            {
                errorMessage = "Warning: target's orbital plane is at a " + o.RelativeInclination(target.TargetOrbit).ToString("F0") + "º angle to " + o.referenceBody.theName + "'s orbital plane (recommend at most 30º). Planned interplanetary transfer may not intercept target properly.";
            }
            else
            {
                double relativeInclination = Vector3d.Angle(o.SwappedOrbitNormal(), o.referenceBody.orbit.SwappedOrbitNormal());
                if (relativeInclination > 10)
                {
                    errorMessage = "Warning: Recommend starting interplanetary transfers from " + o.referenceBody.theName + " from an orbit in the same plane as " + o.referenceBody.theName + "'s orbit around " + o.referenceBody.referenceBody.theName + ". Starting orbit around " + o.referenceBody.theName + " is inclined " + relativeInclination.ToString("F1") + "º with respect to " + o.referenceBody.theName + "'s orbit around " + o.referenceBody.referenceBody.theName + " (recommend < 10º). Planned transfer may not intercept target properly.";
                }
                else if (o.eccentricity > 0.2)
                {
                    errorMessage = "Warning: Recommend starting interplanetary transfers from a near-circular orbit (eccentricity < 0.2). Planned transfer is starting from an orbit with eccentricity " + o.eccentricity.ToString("F2") + " and so may not intercept target properly.";
                }
            }

            var dV = OrbitalManeuverCalculator.DeltaVAndTimeForInterplanetaryTransferEjection(o, UT, target.TargetOrbit, waitForPhaseAngle, out UT);

            return(new ManeuverParameters(dV, UT));
        }
        public override List <ManeuverParameters> MakeNodesImpl(Orbit o, double UT, MechJebModuleTargetController target)
        {
            // Check preconditions
            if (!target.NormalTargetExists)
            {
                throw new OperationException(Localizer.Format("#MechJeb_transfer_Exception1"));//"must select a target for the interplanetary transfer."
            }
            if (o.referenceBody.referenceBody == null)
            {
                throw new OperationException(Localizer.Format("#MechJeb_transfer_Exception2", o.referenceBody.displayName));//doesn't make sense to plot an interplanetary transfer from an orbit around <<1>>
            }
            if (o.referenceBody.referenceBody != target.TargetOrbit.referenceBody)
            {
                if (o.referenceBody == target.TargetOrbit.referenceBody)
                {
                    throw new OperationException(Localizer.Format("#MechJeb_transfer_Exception3", o.referenceBody.displayName));                                                                     //use regular Hohmann transfer function to intercept another body orbiting <<1>>
                }
                throw new OperationException(Localizer.Format("#MechJeb_transfer_Exception4", o.referenceBody.displayName, o.referenceBody.displayName, o.referenceBody.referenceBody.displayName)); //"an interplanetary transfer from within "<<1>>"'s sphere of influence must target a body that orbits "<<2>>"'s parent, "<<3>>.
            }

            // Simple warnings
            if (o.referenceBody.orbit.RelativeInclination(target.TargetOrbit) > 30)
            {
                errorMessage = Localizer.Format("#MechJeb_transfer_errormsg1", o.RelativeInclination(target.TargetOrbit).ToString("F0"), o.referenceBody.displayName);//"Warning: target's orbital plane is at a"<<1>>"º angle to "<<2>>"'s orbital plane (recommend at most 30º). Planned interplanetary transfer may not intercept target properly."
            }
            else
            {
                double relativeInclination = Vector3d.Angle(o.SwappedOrbitNormal(), o.referenceBody.orbit.SwappedOrbitNormal());
                if (relativeInclination > 10)
                {
                    errorMessage = Localizer.Format("#MechJeb_transfer_errormsg2", o.referenceBody.displayName, o.referenceBody.displayName, o.referenceBody.referenceBody.displayName, o.referenceBody.displayName, relativeInclination.ToString("F1"), o.referenceBody.displayName, o.referenceBody.referenceBody.displayName);//Warning: Recommend starting interplanetary transfers from  <<1>> from an orbit in the same plane as "<<2>>"'s orbit around "<<3>>". Starting orbit around "<<4>>" is inclined "<<5>>"º with respect to "<<6>>"'s orbit around "<<7>> " (recommend < 10º). Planned transfer may not intercept target properly."
                }
                else if (o.eccentricity > 0.2)
                {
                    errorMessage = Localizer.Format("#MechJeb_transfer_errormsg3", o.eccentricity.ToString("F2"));//Warning: Recommend starting interplanetary transfers from a near-circular orbit (eccentricity < 0.2). Planned transfer is starting from an orbit with eccentricity <<1>> and so may not intercept target properly.
                }
            }

            var dV = OrbitalManeuverCalculator.DeltaVAndTimeForInterplanetaryTransferEjection(o, UT, target.TargetOrbit, waitForPhaseAngle, out UT);
            List <ManeuverParameters> NodeList = new List <ManeuverParameters>();

            NodeList.Add(new ManeuverParameters(dV, UT));
            return(NodeList);
        }
Пример #3
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);
        }
Пример #4
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);
        }