protected override void AdjustNode( ManeuverNode originalNode, Maneuver original, double originalPeriod, double originalMagnitude, ManeuverNode node, double value, double splitDv) { double fraction; double minFraction = 0; double maxFraction = 1; double targetPeriod = value * 60; for(int iteration = 0; iteration < MNSSettings.Instance.splitByPeriodIterations; iteration += 1) { fraction = (minFraction + maxFraction) / 2; Vector3d dv = original.DeltaV * fraction; if(node != originalNode) { RotateDeltaV(originalNode, node, ref dv); } node.DeltaV = dv; node.solver.UpdateFlightPlan(); if(node.nextPatch.ApA > 0 && node.nextPatch.period < targetPeriod) minFraction = fraction; else maxFraction = fraction; } }
protected override void AdjustNode( ManeuverNode originalNode, Maneuver original, double originalPeriod, double originalMagnitude, ManeuverNode node, double value, double splitDv) { Vector3d dv = original.DeltaV * (value / originalMagnitude); if(node != originalNode) { RotateDeltaV(originalNode, node, ref dv); } node.DeltaV = dv; node.solver.UpdateFlightPlan(); }
private void SplitNode(List<double> list, bool fix) { if(IsSolverAvailable() && Solver.maneuverNodes.Count > 0) { ManeuverNode originalNode = Solver.maneuverNodes[0]; Maneuver original = new Maneuver(originalNode); double originalPeriod = originalNode.patch.period; double originalMagnitude = original.DeltaV.magnitude; int nodeCount = list.Count; double splitDv = 0; ManeuverNode node = originalNode; for(int index = 0; index < list.Count; index += 1) { LogNode("Before " + index, node); AdjustNode(originalNode, original, originalPeriod, originalMagnitude, node, list[index], splitDv); LogNode("After " + index, node); if(node.nextPatch.patchEndTransition == Orbit.PatchTransitionType.ESCAPE) { ScreenMessages.PostScreenMessage("Input values cause ejection in fewer burns than specified!", 8f, ScreenMessageStyle.UPPER_CENTER); Debug.Log(string.Format("Early ejection at index {0}", index)); break; } else if(node.nextPatch.patchEndTransition == Orbit.PatchTransitionType.ENCOUNTER) { ScreenMessages.PostScreenMessage("Encounter detected! Unable to split the maneuver as specified!", 8f, ScreenMessageStyle.UPPER_CENTER); Debug.Log(string.Format("Encounter at index {0}", index)); break; } splitDv += node.DeltaV.magnitude; node = Solver.AddManeuverNode(node.UT + node.nextPatch.period); } if(supportsRepeat && repeat) { double limit = double.Parse(repeatLimit) * 1000; double value = list[list.Count - 1]; while(node.nextPatch.ApA < limit) { LogNode("Before", node); AdjustNode(originalNode, original, originalPeriod, originalMagnitude, node, value, splitDv); LogNode("After", node); if(node.nextPatch.ApA < limit) { nodeCount += 1; splitDv += node.DeltaV.magnitude; node = Solver.AddManeuverNode(node.UT + node.nextPatch.period); } } } if(fix) { // TBD } else { Vector3d dv = original.DeltaV * ((originalMagnitude - splitDv) / originalMagnitude); RotateDeltaV(originalNode, node, ref dv); node.DeltaV = dv; node.solver.UpdateFlightPlan(); LogNode("Final", node); double timeDifference = node.UT - original.UT; double orbitsToReverse = Math.Ceiling(timeDifference / originalPeriod); DebugLog("UT: {0} time diff: {1} orbits to reverse: {2}", Planetarium.GetUniversalTime(), timeDifference, orbitsToReverse); while(orbitsToReverse > 0 && original.UT - orbitsToReverse * originalPeriod < Planetarium.GetUniversalTime()) { orbitsToReverse -= 1; } DebugLog("Reversing {0} orbits", orbitsToReverse); if(orbitsToReverse > 0) { double timeToReverse = orbitsToReverse * originalPeriod; for(int index = 0; index <= nodeCount; index += 1) { ManeuverNode mn = Solver.maneuverNodes[index]; Debug.Log(string.Format("Moving node {0} ({1}) back {2} from {3}", index, mn.DeltaV.magnitude, timeToReverse, mn.UT)); mn.UT -= timeToReverse; mn.solver.UpdateFlightPlan(); } } double dt = original.UT - node.UT; if(dt < 0) { dt = dt * -1; ScreenMessages.PostScreenMessage( string.Format("Final ejection will happen {0} later than originally planned", DurationToDisplayString(dt)), 8f, ScreenMessageStyle.UPPER_CENTER); } else { ScreenMessages.PostScreenMessage( string.Format("Final ejection will happen {0} earlier than originally planned", DurationToDisplayString(dt)), 8f, ScreenMessageStyle.UPPER_CENTER); } } Debug.Log("Done!"); } }
protected abstract void AdjustNode( ManeuverNode originalNode, Maneuver original, double originalPeriod, double originalMagnitude, ManeuverNode node, double value, double splitDv);
protected override void AdjustNode( ManeuverNode originalNode, Maneuver original, double originalPeriod, double originalMagnitude, ManeuverNode node, double value, double splitDv) { double fraction; double minFraction = 0; double maxFraction = 1; IBurnCalculator calculator = GetAvailableCalculator(); for(int iteration = 0; iteration < MNSSettings.Instance.splitByBurnTimeIterations; iteration += 1) { fraction = (minFraction + maxFraction) / 2; Vector3d dv = original.DeltaV * fraction; if(node != originalNode) { RotateDeltaV(originalNode, node, ref dv); } node.DeltaV = dv; node.solver.UpdateFlightPlan(); double burnTime = calculator.CalculateBurnTime(dv.magnitude, splitDv); if(node.nextPatch.ApA > 0 && burnTime < value) minFraction = fraction; else maxFraction = fraction; } }