private void DoTriggerPressed(object sender, ControllerInteractionEventArgs e) { DebugLogger(e.controllerIndex, "TRIGGER", "pressed", e); ; if (false)//leftController == null) { PorkChopPlot.triggerPork = true; double time = 30d; var thisodata = UXStateManager.GetSource().GetComponent <OrbitData>(); Vector3d r1 = thisodata.getR(); var oe2 = UXStateManager.GetTarget().GetComponent <OrbitData>().GetOE(); var tra2 = OrbitalTools.Program.anomalyAfterTime(OrbitData.parentGM, oe2, time); oe2.tra = tra2; Vector3d r2 = OrbitalTools.Util.oe2rd(OrbitData.parentGM, oe2); Vector3d initVel, finalVel; LambertSolver.Solve(r1, r2, time, OrbitData.parentGM, true, out initVel, out finalVel); thisodata.rv[3] = initVel.x; thisodata.rv[4] = initVel.y; thisodata.rv[5] = initVel.z; } }
public void TestLambertSolver() { (Vector3 re, Vector3 ve) = Earth.GetComponent <VisualizeBodyRealtimeOverview>() .Body.GetGlobalPositionAndVelocityAt(Time.time); (Vector3 rm, Vector3 vm) = Mars.GetComponent <VisualizeBodyRealtimeOverview>() .Body.GetGlobalPositionAndVelocityAt(Time.time + 8); LambertSolver.Solve( Body.GravitationalParameter, re, ve, rm, vm, 8, 0, out Vector3 vi, out Vector3 vf ); Orbit orbit = Orbit.FromPositionAndVelocity(Body, re, vi, Time.time); var body = ScriptableObject.CreateInstance <CelestialBody>(); body.SetOrbit(orbit); GameObject orbitVisual = Instantiate(OrbitPrefab); orbitVisual.GetComponent <VisualizeOrbit>().Body = body; GameObject vesselVisual = Instantiate(VesselPrefab); vesselVisual.GetComponent <VisualizeBodyRealtimeOverview>().Body = body; }
void mainGUI(int windowID) { CelestialBody target; ITargetable t; try { t = FlightGlobals.fetch.VesselTarget; if (t != null && t is CelestialBody) { target = (CelestialBody)FlightGlobals.fetch.VesselTarget; GUILayout.Label("You have selected " + target.name + " as your target."); if (UT == 0 || UT < Planetarium.GetUniversalTime() || targetBody != target.name) { targetBody = target.name; UT = LambertSolver.NextLaunchWindowUT(vessel.mainBody, target); } GUILayout.Label((UT - Planetarium.GetUniversalTime()).ToString() + " s to window"); if (vessel.situation == Vessel.Situations.ORBITING) { bool plot = GUILayout.Button("Plot"); if (plot) { double UT2; Vector3d dv = LambertSolver.EjectionBurn(vessel, target, out UT2); ManeuverNode mn = vessel.patchedConicSolver.AddManeuverNode(UT2); mn.DeltaV = dv; mn.solver.UpdateFlightPlan(); plot = false; } } else { GUILayout.Label("Now get into orbit!"); } } else { GUILayout.Label("No valid target selected"); } } catch { GUILayout.Label("Error selecting target"); } GUI.DragWindow(); }
private void SetTransferDetails() { DepartureSelected = DepartureMin + (vectSelected.x - PlotPosition.x) * xResolution; TravelSelected = TravelMax - (vectSelected.y - PlotPosition.y) * yResolution; LambertSolver.TransferDeltaV(cbOrigin, cbDestination, DepartureSelected, TravelSelected, InitialOrbitAltitude, FinalOrbitAltitude, out TransferSelected); TransferSelected.CalcEjectionValues(); mbTWP.EjectAngle.AngleTargetValue = TransferSelected.EjectionAngle * LambertSolver.Rad2Deg; mbTWP.EjectAngle.DrawToRetrograde = TransferSelected.EjectionAngleIsRetrograde; mbTWP.PhaseAngle.AngleTargetValue = TransferSelected.PhaseAngle * LambertSolver.Rad2Deg; if (!mbTWP.PhaseAngle.ShowTargetAngle) { mbTWP.PhaseAngle.ShowTargetAngle = true; } }
void SetupTransferParams() { LogFormatted_DebugOnly("Running Maths for Default values for this transfer"); cbDestination = lstBodies.First(x => x.Name == ddlDestination.SelectedValue.Trim(' ')).CB; LogFormatted_DebugOnly("Destination:{0}", cbOrigin.bodyName); //work out the synodic period and a reasonable range from the min to max - ie x axis synodicPeriod = Math.Abs(1 / (1 / cbDestination.orbit.period - 1 / cbOrigin.orbit.period)); DepartureRange = Math.Min(2 * synodicPeriod, 2 * cbOrigin.orbit.period); //Set this to yesterday //DepartureMin = 0; DepartureMax = DepartureMin + DepartureRange; //Work out the time necessary for a hohmann transfer between the two orbits hohmannTransferTime = LambertSolver.HohmannTimeOfFlight(cbOrigin.orbit, cbDestination.orbit); //Set some reasonable defaults for the travel time range - ie y-axis TravelMin = Math.Max(hohmannTransferTime - cbDestination.orbit.period, hohmannTransferTime / 2); TravelMax = TravelMin + Math.Min(2 * cbDestination.orbit.period, hohmannTransferTime); SetWindowStrings(); }
private void SetTransferDetails() { DepartureSelected = DepartureMin + (vectSelected.x - PlotPosition.x) * xResolution; TravelSelected = TravelMax - (vectSelected.y - PlotPosition.y) * yResolution; LambertSolver.TransferDeltaV(cbOrigin, cbDestination, DepartureSelected, TravelSelected, InitialOrbitAltitude, FinalOrbitAltitude, out TransferSelected); if (TransferSelected != null) { //Only if its not a NaN TransferSelected.CalcEjectionValues(); if (TransferWindowPlanner.lstScenesForAngles.Contains(HighLogic.LoadedScene)) { mbTWP.EjectAngle.AngleTargetValue = TransferSelected.EjectionAngle * LambertSolver.Rad2Deg; mbTWP.EjectAngle.DrawToRetrograde = TransferSelected.EjectionAngleIsRetrograde; mbTWP.PhaseAngle.AngleTargetValue = TransferSelected.PhaseAngle * LambertSolver.Rad2Deg; if (!mbTWP.PhaseAngle.ShowTargetAngle) { mbTWP.PhaseAngle.ShowTargetAngle = true; } } } }
internal override void OnPreCull() { base.OnPreCull(); //not sure if this is right - but its working if (!TransferWindowPlanner.lstScenesForAngles.Contains(HighLogic.LoadedScene)) { return; } if (MapView.MapIsEnabled && isDrawing) { //Get the Vector of the Origin body from the ref point and its distance Vector3d vectStart = bodyOrigin.transform.position - bodyOrigin.referenceBody.transform.position; Double vectStartMag = vectStart.magnitude; //now work out the angle //Double _PhaseAngleCurrent = ClampDegrees180(LambertSolver.CurrentPhaseAngle(bodyOrigin.orbit,bodyTarget.orbit)); _PhaseAngleCurrent = LambertSolver.CurrentPhaseAngle(bodyOrigin.orbit, bodyTarget.orbit); if (bodyTarget.orbit.semiMajorAxis < bodyOrigin.orbit.semiMajorAxis) { _PhaseAngleCurrent = _PhaseAngleCurrent - 360; } //And therefore the 2nd arm of the angle Vector3d vectEnd = Quaternion.AngleAxis(-(Single)_PhaseAngleCurrent, bodyOrigin.orbit.GetOrbitNormal().xzy) * vectStart; //make it 120% of the target bodies orbit vectEnd = vectEnd.normalized * bodyTarget.orbit.ApR * 1.2; Double vectEndMag = vectEnd.magnitude; Vector3d vectPointEnd = bodyOrigin.referenceBody.transform.position + vectEnd; //and heres the three points vectPosWorldPivot = bodyOrigin.referenceBody.transform.position; vectPosWorldOrigin = bodyOrigin.transform.position; vectPosWorldEnd = vectPointEnd; if (ShowTargetAngle) { Vector3d vectTarget = Quaternion.AngleAxis(-(Single)AngleTargetValue, bodyOrigin.orbit.GetOrbitNormal().xzy) * vectStart; vectPosWorldTarget = vectTarget.normalized * vectEndMag * 0.9; vectPosWorldTarget += bodyOrigin.referenceBody.transform.position; } //Are we Showing, Hiding or Static State if (_isHiding) { Single pctDone = (Single)(DateTime.Now - StartDrawing).TotalSeconds / 0.25f; if (pctDone >= 1) { _isHiding = false; isDrawing = false; } vectPosPivotWorking = bodyOrigin.transform.position - Mathf.Lerp(0, (Single)vectStartMag, Mathf.Clamp01(pctDone)) * vectStart.normalized; DrawLine(lineStart, vectPosWorldPivot, vectPosWorldPivot + (vectPosWorldOrigin - vectPosWorldPivot).normalized * Mathf.Lerp((Single)vectStartMag, 0, pctDone)); DrawLine(lineEnd, vectPosWorldPivot, vectPosWorldPivot + (vectPosWorldEnd - vectPosWorldPivot).normalized * Mathf.Lerp((Single)vectEndMag, 0, pctDone)); DrawArc(lineArc, vectStart, _PhaseAngleCurrent, Mathf.Lerp((Single)bodyOrigin.orbit.radius, 0, pctDone), Mathf.Lerp((Single)bodyTarget.orbit.radius, 0, pctDone)); if (ShowTargetAngle) { DrawLine(lineTarget, vectPosWorldPivot, vectPosWorldPivot + (vectPosWorldTarget - vectPosWorldPivot).normalized * Mathf.Lerp((Single)vectEndMag, 0, pctDone)); DrawArc(lineTargetArc, vectStart, AngleTargetValue, Mathf.Lerp((Single)bodyOrigin.orbit.radius * 0.9f, 0, pctDone), Mathf.Lerp((Single)bodyTarget.orbit.radius * 0.9f, 0, pctDone)); } } else if (isBecomingVisible) { if (!_isBecomingVisible_LinesDone) { Single pctDone = (Single)(DateTime.Now - StartDrawing).TotalSeconds / 0.5f; if (pctDone >= 1) { _isBecomingVisible_LinesDone = true; StartDrawing = DateTime.Now; } vectPosPivotWorking = bodyOrigin.transform.position - Mathf.Lerp(0, (Single)vectStartMag, Mathf.Clamp01(pctDone)) * vectStart.normalized; DrawLine(lineStart, vectPosPivotWorking, vectPosWorldOrigin); } else if (!_isBecomingVisible_ArcDone) { Single pctDone = (Single)(DateTime.Now - StartDrawing).TotalSeconds / 0.5f; if (pctDone >= 1) { _isBecomingVisible_ArcDone = true; StartDrawing = DateTime.Now; } Double vectEndMagWorking = Mathf.Lerp((Single)vectStartMag, (Single)vectEndMag, Mathf.Clamp01(pctDone)); Double PhaseAngleWorking = Mathf.Lerp(0, (Single)_PhaseAngleCurrent, Mathf.Clamp01(pctDone)); vectPosEndWorking = (Vector3d)(Quaternion.AngleAxis(-(Single)PhaseAngleWorking, bodyOrigin.orbit.GetOrbitNormal().xzy) * vectStart).normalized * vectEndMagWorking; vectPosEndWorking += bodyOrigin.referenceBody.transform.position; //draw the origin and end lines DrawLine(lineStart, vectPosWorldPivot, vectPosWorldOrigin); DrawLine(lineEnd, vectPosWorldPivot, vectPosEndWorking); DrawArc(lineArc, vectStart, PhaseAngleWorking, bodyOrigin.orbit.radius, bodyTarget.orbit.radius); } else if (!_isBecomingVisible_TargetArcDone) { if (!ShowTargetAngle) { _isBecomingVisible_TargetArcDone = true; _isBecomingVisible = false; } else { Single pctDone = (Single)(DateTime.Now - StartDrawing).TotalSeconds / 0.5f; if (pctDone >= 1) { _isBecomingVisible_TargetArcDone = true; _isBecomingVisible = false; } Double PhaseAngleWorking = Mathf.Lerp(0, (Single)AngleTargetValue, Mathf.Clamp01(pctDone)); vectPosTargetWorking = (Vector3d)(Quaternion.AngleAxis(-(Single)PhaseAngleWorking, bodyOrigin.orbit.GetOrbitNormal().xzy) * vectStart).normalized * vectEndMag * 0.9; vectPosTargetWorking += bodyOrigin.referenceBody.transform.position; DrawLine(lineStart, vectPosWorldPivot, vectPosWorldOrigin); DrawLine(lineEnd, vectPosWorldPivot, vectPosWorldEnd); DrawArc(lineArc, vectStart, _PhaseAngleCurrent, bodyOrigin.orbit.radius, bodyTarget.orbit.radius); DrawLine(lineTarget, vectPosWorldPivot, vectPosTargetWorking); DrawArc(lineTargetArc, vectStart, PhaseAngleWorking, bodyOrigin.orbit.radius * 0.9, bodyTarget.orbit.radius * 0.9); } } } else { DrawLine(lineStart, vectPosWorldPivot, vectPosWorldOrigin); DrawLine(lineEnd, vectPosWorldPivot, vectPosWorldEnd); DrawArc(lineArc, vectStart, _PhaseAngleCurrent, bodyOrigin.orbit.radius, bodyTarget.orbit.radius);// vectStartMag, vectEndMag); if (ShowTargetAngle) { DrawLine(lineTarget, vectPosWorldPivot, vectPosWorldTarget); DrawArc(lineTargetArc, vectStart, AngleTargetValue, bodyOrigin.orbit.radius * 0.9, bodyTarget.orbit.radius * 0.9); } } } else { lineStart.enabled = false; lineEnd.enabled = false; lineArc.enabled = false; lineTarget.enabled = false; lineTargetArc.enabled = false; } }
void bw_GeneratePorkchop(object sender, DoWorkEventArgs e) { try { sumlogDeltaV = 0; sumSqLogDeltaV = 0; maxDeltaV = 0; minDeltaV = Double.MaxValue; //Loop through getting the DeltaV's and assigning em all to an array Int32 iCurrent = 0; #if DEBUG ////////need to make sure this bombing out cause file is locked doesnt stop process :) String strCSVLine = ""; try { if (System.IO.File.Exists(String.Format("{0}/DeltaVWorking-{1}-{2}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName))) { System.IO.File.Delete(String.Format("{0}/DeltaVWorking-{1}-{2}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName)); } } catch (Exception ex) { LogFormatted("Unable to delete file:{0}", ex.Message); } #endif LogFormatted("Generating DeltaV Values"); for (int x = 0; x < PlotWidth; x++) { #if DEBUG strCSVLine = ""; #endif //LogFormatted("{0:0.000}-{1}", workingpercent, iCurrent); for (int y = 0; y < PlotHeight; y++) { //have to keep this this way so the texture draws the right way around iCurrent = (int)(y * PlotWidth + x); //Set the Value for this position to be the DeltaV of this Transfer DeltaVs[iCurrent] = LambertSolver.TransferDeltaV(cbOrigin, cbDestination, DepartureMin + ((Double)x * xResolution), TravelMax - ((Double)y * yResolution), InitialOrbitAltitude, FinalOrbitAltitude); //LogFormatted("dt: {0} TT:{1}", TravelMax - ((Double)y * yResolution), transferTemp.TravelTime); #if DEBUG strCSVLine += String.Format("{0:0.00},", DeltaVs[iCurrent]); #endif /////////////// Long Running //////////////////////////// //LogFormatted("{0}x{1} ({3}) = {2:0}", x, y, DeltaVs[iCurrent],iCurrent); if (DeltaVs[iCurrent] > maxDeltaV) { maxDeltaV = DeltaVs[iCurrent]; } if (DeltaVs[iCurrent] < minDeltaV) { minDeltaV = DeltaVs[iCurrent]; minDeltaVPoint = new Vector2(x, y); } logDeltaV = Math.Log(DeltaVs[iCurrent]); sumlogDeltaV += logDeltaV; sumSqLogDeltaV += logDeltaV * logDeltaV; workingpercent = (x * PlotHeight + y) / (Double)(PlotHeight * PlotWidth); } #if DEBUG try { System.IO.File.AppendAllText(String.Format("{0}/DeltaVWorking.csv", Resources.PathPlugin), strCSVLine.TrimEnd(',') + "\r\n"); } catch (Exception) { } #endif } Double mean, stddev; //Calculate the ColorIndex for the plot - BUT DONT AFFECT TEXTURES ON THE BW THREAD LogFormatted("Working out Log Values to determine DeltaV->Color Mapping"); logMinDeltaV = Math.Log(DeltaVs.Min()); mean = sumlogDeltaV / DeltaVs.Length; stddev = Math.Sqrt(sumSqLogDeltaV / DeltaVs.Length - mean * mean); logMaxDeltaV = Math.Min(Math.Log(maxDeltaV), mean + 2 * stddev); if (DeltaVColorPalette == null) { GenerateDeltaVPalette(); } LogFormatted("Placing ColorIndexes in array"); for (int y = 0; y < PlotHeight; y++) { for (int x = 0; x < PlotWidth; x++) { iCurrent = (Int32)(y * PlotWidth + x); logDeltaV = Math.Log(DeltaVs[iCurrent]); double relativeDeltaV = (logDeltaV - logMinDeltaV) / (logMaxDeltaV - logMinDeltaV); Int32 ColorIndex = Math.Min((Int32)(Math.Floor(relativeDeltaV * DeltaVColorPalette.Count)), DeltaVColorPalette.Count - 1); DeltaVsColorIndex[iCurrent] = ColorIndex; } } //Set the Best Transfer vectSelected = new Vector2(PlotPosition.x + minDeltaVPoint.x, PlotPosition.y + minDeltaVPoint.y); SetTransferDetails(); } catch (Exception ex) { LogFormatted("ERROR: Background Worker Failed\r\n{0}\r\n{1}", ex.Message, ex.StackTrace); } }
void bw_GenerateDataPorkchop(object sender, DoWorkEventArgs e) { try { //Loop through getting the DeltaV's and assigning em all to an array Int32 iCurrent = 0; ////////need to make sure this bombing out cause file is locked doesnt stop process :) //String strCSVLine = "", strCSVLine2 = ""; Boolean blnCSVTransferFirst = true; try { if (System.IO.File.Exists(String.Format("{0}/DeltaVWorking-{1}-{2}-{3}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName, lstPlots[CurrentPlot].DepMinYear))) { System.IO.File.Delete(String.Format("{0}/DeltaVWorking-{1}-{2}-{3}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName, lstPlots[CurrentPlot].DepMinYear)); } } catch (Exception ex) { LogFormatted("Unable to delete file:{0}", ex.Message); } try { if (System.IO.File.Exists(String.Format("{0}/DeltaVTravelWorking-{1}-{2}-{3}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName, lstPlots[CurrentPlot].DepMinYear))) { System.IO.File.Delete(String.Format("{0}/DeltaVTravelWorking-{1}-{2}-{3}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName, lstPlots[CurrentPlot].DepMinYear)); } } catch (Exception ex) { LogFormatted("Unable to delete file:{0}", ex.Message); } try { if (System.IO.File.Exists(String.Format("{0}/DeltaVDaily-{1}-{2}-{3}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName, lstPlots[CurrentPlot].DepMinYear))) { System.IO.File.Delete(String.Format("{0}/DeltaVDaily-{1}-{2}-{3}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName, lstPlots[CurrentPlot].DepMinYear)); } } catch (Exception ex) { LogFormatted("Unable to delete file:{0}", ex.Message); } LogFormatted("Generating DeltaV Values"); for (int x = 0; x < PlotWidth; x++) { //strCSVLine = ""; TransferDetails transferDailyBest = new TransferDetails(); Double transferDailyBestDV = Double.MaxValue; //LogFormatted("{0:0.000}-{1}", workingpercent, iCurrent); for (int y = 0; y < PlotHeight; y++) { //have to keep this this way so the texture draws the right way around iCurrent = (int)(y * PlotWidth + x); TransferDetails transferTemp; //Set the Value for this position to be the DeltaV of this Transfer DeltaVs[iCurrent] = LambertSolver.TransferDeltaV(cbOrigin, cbDestination, DepartureMin + ((Double)x * xResolution), TravelMax - ((Double)y * yResolution), InitialOrbitAltitude, FinalOrbitAltitude, out transferTemp); //LogFormatted("dt: {0} TT:{1}", TravelMax - ((Double)y * yResolution), transferTemp.TravelTime); //strCSVLine += String.Format("{0:0.00},", DeltaVs[iCurrent]); //if (blnCSVTransferFirst) // strCSVLine2 += String.Format("{0:0.00},", transferTemp.TravelTime); if (transferTemp.DVTotal < transferDailyBestDV) { transferDailyBest = transferTemp; transferDailyBestDV = transferTemp.DVTotal; } /////////////// Long Running //////////////////////////// //LogFormatted("{0}x{1} ({3}) = {2:0}", x, y, DeltaVs[iCurrent],iCurrent); if (DeltaVs[iCurrent] > maxDeltaV) { maxDeltaV = DeltaVs[iCurrent]; } if (DeltaVs[iCurrent] < minDeltaV) { minDeltaV = DeltaVs[iCurrent]; minDeltaVPoint = new Vector2(x, y); } logDeltaV = Math.Log(DeltaVs[iCurrent]); sumlogDeltaV += logDeltaV; sumSqLogDeltaV += logDeltaV * logDeltaV; workingpercent = (x * PlotHeight + y) / (Double)(PlotHeight * PlotWidth); } try { //System.IO.File.AppendAllText(String.Format("{0}/DeltaVWorking-{1}-{2}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName), strCSVLine.TrimEnd(',') + "\r\n"); } catch (Exception) { } try { if (blnCSVTransferFirst) { //System.IO.File.AppendAllText(String.Format("{0}/DeltaVTravelWorking-{1}-{2}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName), strCSVLine2.TrimEnd(',') + "\r\n"); blnCSVTransferFirst = false; } } catch (Exception) { } try { System.IO.File.AppendAllText(String.Format("{0}/DeltaVDaily-{1}-{2}-{3}.csv", Resources.PathPlugin, cbOrigin.bodyName, cbDestination.bodyName, lstPlots[CurrentPlot].DepMinYear), //String.Format("{0:0.00},{1:0.00},{2:0.00}\r\n", transferDailyBest.DepartureTime, transferDailyBest.DVTotal, transferDailyBest.TravelTime)); String.Format("{0:0.00},{1:0.00},{2:0.00},\"{3}\",\"{4}\"\r\n", transferDailyBest.DepartureTime, transferDailyBest.DVTotal, transferDailyBest.TravelTime, new KSPDateTime(transferDailyBest.DepartureTime).ToStringStandard(DateStringFormatsEnum.KSPFormat), new KSPTimeSpan(transferDailyBest.TravelTime).ToStringStandard(TimeSpanStringFormatsEnum.IntervalLong))); } catch (Exception) { } } } catch (Exception ex) { LogFormatted("ERROR: Background Worker Failed\r\n{0}\r\n{1}", ex.Message, ex.StackTrace); } }