public static ManeuverNode PlaceManeuverNode(this Vessel vessel, Orbit patch, Vector3d dV, double UT) { //placing a maneuver node with bad dV values can really mess up the game, so try to protect against that //and log an exception if we get a bad dV vector: for (int i = 0; i < 3; i++) { if (double.IsNaN(dV[i]) || double.IsInfinity(dV[i])) { throw new Exception("VesselExtensions.PlaceManeuverNode: bad dV: " + dV); } } if (double.IsNaN(UT) || double.IsInfinity(UT)) { throw new Exception("VesselExtensions.PlaceManeuverNode: bad UT: " + UT); } //It seems that sometimes the game can freak out if you place a maneuver node in the past, so this //protects against that. UT = Math.Max(UT, Planetarium.GetUniversalTime()); //convert a dV in world coordinates into the coordinate system of the maneuver node, //which uses (x, y, z) = (radial+, normal-, prograde) Vector3d nodeDV = patch.DeltaVToManeuverNodeCoordinates(UT, dV); ManeuverNode mn = vessel.patchedConicSolver.AddManeuverNode(UT); mn.DeltaV = nodeDV; vessel.patchedConicSolver.UpdateFlightPlan(); return(mn); }
public static ManeuverNode PlaceManeuverNode(this Vessel vessel, Orbit patch, Vector3d dV, double UT) { for (int i = 0; i < 3; i++) { if (double.IsNaN(dV[i]) || double.IsInfinity(dV[i])) { throw new Exception("MechJim.Extensions.VesselExtension.PlaceManeuverNode: bad dV: " + dV); } } if (double.IsNaN(UT) || double.IsInfinity(UT)) { throw new Exception("MechJim.Extensions.VesselExtension.PlaceManeuverNode: bad UT: " + UT); } /* never place nodes in the past */ UT = Math.Max(UT, Planetarium.GetUniversalTime()); Vector3d nodeDV = patch.DeltaVToManeuverNodeCoordinates(UT, dV); Debug.Log("nodeDV = " + nodeDV); ManeuverNode mn = vessel.patchedConicSolver.AddManeuverNode(UT); mn.DeltaV = nodeDV; Debug.Log("UT = " + UT); Debug.Log("Node = " + mn); vessel.patchedConicSolver.UpdateFlightPlan(); /* mn.OnGizmoUpdated(nodeDV, UT); */ return(mn); }
public static ManeuverNode PlaceManeuverNode(this Vessel vessel, Orbit patch, Vector3d dV, double UT) { //placing a maneuver node with bad dV values can really mess up the game, so try to protect against that //and log an exception if we get a bad dV vector: for (int i = 0; i < 3; i++) { if (double.IsNaN(dV[i]) || double.IsInfinity(dV[i])) { throw new Exception("VesselExtensions.PlaceManeuverNode: bad dV: " + dV); } } if (double.IsNaN(UT) || double.IsInfinity(UT)) { throw new Exception("VesselExtensions.PlaceManeuverNode: bad UT: " + UT); } //It seems that sometimes the game can freak out if you place a maneuver node in the past, so this //protects against that. UT = Math.Max(UT, Planetarium.GetUniversalTime()); //convert a dV in world coordinates into the coordinate system of the maneuver node, //which uses (x, y, z) = (radial+, normal-, prograde) Vector3d nodeDV = patch.DeltaVToManeuverNodeCoordinates(UT, dV); ManeuverNode mn = vessel.patchedConicSolver.AddManeuverNode(UT); mn.OnGizmoUpdated(nodeDV, UT); return mn; }
protected void MaintainAerobrakeNode() { if (makeAerobrakeNodes) { //Remove node after finishing aerobraking: if (aerobrakeNode != null && vessel.patchedConicSolver.maneuverNodes.Contains(aerobrakeNode)) { if (aerobrakeNode.UT < vesselState.time && vesselState.altitudeASL > mainBody.RealMaxAtmosphereAltitude()) { aerobrakeNode.RemoveSelf(); aerobrakeNode = null; } } //Update or create node if necessary: ReentrySimulation.Result r = Result; if (r != null && r.outcome == ReentrySimulation.Outcome.AEROBRAKED) { //Compute the node dV: Orbit preAerobrakeOrbit = GetReenteringPatch(); //Put the node at periapsis, unless we're past periapsis. In that case put the node at the current time. double UT; if (preAerobrakeOrbit == orbit && vesselState.altitudeASL < mainBody.RealMaxAtmosphereAltitude() && vesselState.speedVertical > 0) { UT = vesselState.time; } else { UT = preAerobrakeOrbit.NextPeriapsisTime(preAerobrakeOrbit.StartUT); } Orbit postAerobrakeOrbit = MuUtils.OrbitFromStateVectors(r.WorldAeroBrakePosition(), r.WorldAeroBrakeVelocity(), r.body, r.aeroBrakeUT); Vector3d dV = OrbitalManeuverCalculator.DeltaVToChangeApoapsis(preAerobrakeOrbit, UT, postAerobrakeOrbit.ApR); if (aerobrakeNode != null && vessel.patchedConicSolver.maneuverNodes.Contains(aerobrakeNode)) { //update the existing node Vector3d nodeDV = preAerobrakeOrbit.DeltaVToManeuverNodeCoordinates(UT, dV); aerobrakeNode.UpdateNode(nodeDV, UT); } else { //place a new node aerobrakeNode = vessel.PlaceManeuverNode(preAerobrakeOrbit, dV, UT); } } else { //no aerobraking, remove the node: if (aerobrakeNode != null && vessel.patchedConicSolver.maneuverNodes.Contains(aerobrakeNode)) { aerobrakeNode.RemoveSelf(); } } } else { //Remove aerobrake node when it is turned off: if (aerobrakeNode != null && vessel.patchedConicSolver.maneuverNodes.Contains(aerobrakeNode)) { aerobrakeNode.RemoveSelf(); } } }