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" } }
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"; } }
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); }
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); }
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); }