Exemplo n.º 1
0
        internal void ResetWindow()
        {
            Done = false;
            if (bw != null && bw.IsBusy)
            {
                bw.CancelAsync();
            }
            Running           = false;
            TransferSelected  = null;
            WindowRect.height = 400;

            SetDepartureMinToYesterday();
            SetupDestinationControls();
            HideAngles();
        }
        internal void ResetWindow()
        {
            Done = false;
            if (bw != null && bw.IsBusy)
                bw.CancelAsync();
            Running = false;
            TransferSelected = null;
            WindowRect.height = 400;

            SetDepartureMinToYesterday();
            SetupDestinationControls();
            HideAngles();
        }
    //public static Double v1out, vedvout;
    //public static Vector3d oVel;

    /// <summary>
    /// Find the delta-v required for a ballistic transfer from <paramref name="origin"/> to <paramref name="destination"/>,
    /// departing at <paramref name="ut"/> UT, with a time of flight of <paramref name="dt"/> seconds, starting from a circular
    /// parking orbit <paramref name="initialOrbitAltitude"/> meters above the origin's surface, and optionally inserting into a
    /// final orbit <paramref name="finalOrbitAltitude"/> meters above the destination's surface.
    /// </summary>
    /// <returns>The total delta-v in meters per second of the specified transfer.</returns>
    /// <param name="origin">The origin body.</param>
    /// <param name="destination">The destination body. Must have the same <c>referenceBody</c> as <paramref name="origin"/>.</param>
    /// <param name="ut">The universal time of departure, in seconds. Must be greater than 0.</param>
    /// <param name="dt">The time of flight, in seconds. Must be greater than 0.</param>
    /// <param name="initialOrbitAltitude">The altitude of the initial circular parking orbit. If 0, parking orbit ejection is ignored. Must be greater than or equal to 0.</param>
    /// <param name="finalOrbitAltitude">(Optional) The altitude of the final circular orbit. Must be greater than or equal to 0 if provided.</param>
    /// <param name="oTransfer">Output object that contains all the basic details of the calculated transfer</param>
    public static double TransferDeltaV(CelestialBody origin, CelestialBody destination, double ut, double dt, double initialOrbitAltitude, double? finalOrbitAltitude, out TransferDetails oTransfer)
    {
        double gravParameter = origin.referenceBody.gravParameter;
        double tA = origin.orbit.TrueAnomalyAtUT(ut);
        Vector3d originPositionAtDeparture = OrbitPositionFromTrueAnomaly(origin.orbit, tA);
        Vector3d originVelocity = OrbitVelocityFromTrueAnomaly(origin.orbit, tA);
        //oVel = originVelocity;

        tA = destination.orbit.TrueAnomalyAtUT(ut + dt);
        Vector3d destinationPositionAtArrival = OrbitPositionFromTrueAnomaly(destination.orbit, tA);

        bool longWay = Vector3d.Cross(originPositionAtDeparture, destinationPositionAtArrival).z < 0;

        Vector3d velocityBeforeInsertion;
        Vector3d velocityAfterEjection = Solve(gravParameter, originPositionAtDeparture, destinationPositionAtArrival, dt, longWay, out velocityBeforeInsertion);

        Vector3d ejectionDeltaVector = velocityAfterEjection - originVelocity;
        double ejectionInclination = 0, vesselOriginOrbitalSpeed = 0;     //Extra variables for Transfer Details
        double ejectionDeltaV = ejectionDeltaVector.magnitude;
        if (initialOrbitAltitude > 0) {
            double mu = origin.gravParameter;
            double r0 = initialOrbitAltitude + origin.Radius;
            double rsoi = origin.sphereOfInfluence;
            double v0 = Math.Sqrt(origin.gravParameter / r0); // Initial circular orbit velocity
            double v1 = Math.Sqrt(ejectionDeltaV * ejectionDeltaV + 2 * v0 * v0 - 2 * mu / rsoi); // Velocity at periapsis

            //v1out = v1; vedvout = ejectionDeltaV;

            vesselOriginOrbitalSpeed = v0;                                //Store this for later

            double e = r0 * v1 * v1 / mu - 1; // Ejection orbit eccentricity
            double ap = r0 * (1 + e) / (1 - e); // Ejection orbit apoapsis

            if (ap > 0 && ap <= rsoi) { 
                oTransfer = null;                                   //Nuke this if we have no result
                return Double.NaN; // There is no orbit that leaves the SoI with a velocity of ejectionDeltaV
            }

            if (ejectionDeltaVector.z != 0) {
                double sinEjectionInclination = ejectionDeltaVector.z / ejectionDeltaV;
                ejectionInclination = Math.Asin(sinEjectionInclination);    //Store this for later
                ejectionDeltaV = Math.Sqrt(v0 * v0 + v1 * v1 - 2 * v0 * v1 * Math.Sqrt(1 - sinEjectionInclination * sinEjectionInclination));
            } else {
                ejectionDeltaV = v1 - v0;
            }
        }

        //Create a transfer object and set all the details we have
        oTransfer = new TransferDetails(origin, destination, ut, dt);
        oTransfer.OriginVesselOrbitalSpeed = vesselOriginOrbitalSpeed;
        oTransfer.OriginVelocity = originVelocity;
        oTransfer.TransferInitalVelocity = velocityAfterEjection;
        oTransfer.TransferFinalVelocity = velocityBeforeInsertion;
        oTransfer.TransferAngle = Math.Acos(Vector3d.Dot(originPositionAtDeparture, destinationPositionAtArrival) / (originPositionAtDeparture.magnitude * destinationPositionAtArrival.magnitude));
        oTransfer.EjectionDeltaVector = ejectionDeltaVector;
        //reset the magnitude of the ejectionDeltaV to take into account the orbital velocity of the craft
        oTransfer.EjectionDeltaVector = oTransfer.EjectionDeltaVector.normalized * ejectionDeltaV;
        oTransfer.EjectionInclination = ejectionInclination;

        double insertionDeltaV = 0;
        double insertionInclination = 0, vesselDestinationOrbitalSpeed = 0;     //Extra variables for Transfer Details
        if (finalOrbitAltitude.HasValue) {
            Vector3d destinationVelocity = OrbitVelocityFromTrueAnomaly(destination.orbit, tA);

            //Tweak this bit so we have the vector and inclination values for use later
            Vector3d insertionDeltaVector = velocityBeforeInsertion - destinationVelocity;
            insertionDeltaV = insertionDeltaVector.magnitude;
            if (insertionDeltaVector.z != 0) {
                insertionInclination = Math.Asin(insertionDeltaVector.z/insertionDeltaV);
            }

            if (finalOrbitAltitude.Value != 0) {
                double finalOrbitVelocity = Math.Sqrt(destination.gravParameter / (finalOrbitAltitude.Value + destination.Radius));
                vesselDestinationOrbitalSpeed = finalOrbitVelocity;                      //Store this for later
                insertionDeltaV = Math.Sqrt(insertionDeltaV * insertionDeltaV + 2 * finalOrbitVelocity * finalOrbitVelocity - 2 * destination.gravParameter / destination.sphereOfInfluence) - finalOrbitVelocity;

                //Store away the extra details about the Destination/Injection
                oTransfer.DestinationVesselOrbitalSpeed = vesselDestinationOrbitalSpeed;
                oTransfer.DestinationVelocity = destinationVelocity;
                //oTransfer.InjectionDeltaVector = (velocityBeforeInsertion - destinationVelocity);
                oTransfer.InjectionDeltaVector = oTransfer.EjectionDeltaVector.normalized * insertionDeltaV;
                oTransfer.InsertionInclination = insertionInclination;
            }
            else
            {
                //This is a flyby so there is no injection burn
                //Store away the extra details about the Destination/Injection
                oTransfer.DestinationVesselOrbitalSpeed = velocityBeforeInsertion.magnitude;
                oTransfer.DestinationVelocity = destinationVelocity;
                oTransfer.InjectionDeltaVector = new Vector3d();
                oTransfer.InsertionInclination = 0;
            }


        }

        return oTransfer.DVTotal; //ejectionDeltaV + insertionDeltaV;
    }
        internal override void DrawWindow(int id)
        {
            try
            {
                DrawTextBox(ref intTest1);
                DrawTextBox(ref intTest2);
                DrawTextBox(ref intTest3);
                DrawTextBox(ref intTest4);
                //DrawTextBox(ref intTest5);

                ///////////////RANGE Work//////////////////////
                //DrawTextBox(ref intPlotDeparturePerDay);
                //DrawTextBox(ref intPlotTravelPointsPerDay);

                //Double TravelRange = (new KSPTimeSpan(mbTWP.windowMain.strTravelMaxDays, "0", "0", "0") - new KSPTimeSpan(mbTWP.windowMain.strTravelMinDays, "0", "0", "0")).UT;
                //Double DepartureRange = (mbTWP.windowMain.dateMaxDeparture - mbTWP.windowMain.dateMinDeparture).UT;

                //DrawLabel("Dep:{0}  ({1})", new KSPTimeSpan(DepartureRange).ToStringStandard(TimeSpanStringFormatsEnum.IntervalLong), DepartureRange);
                //DrawLabel("Dep:{0}  ({1})", new KSPTimeSpan(TravelRange).ToStringStandard(TimeSpanStringFormatsEnum.IntervalLong), TravelRange);

                //width = (DepartureRange / KSPDateStructure.SecondsPerDay * intPlotDeparturePerDay) + 1;
                //height = (TravelRange / KSPDateStructure.SecondsPerDay * intPlotTravelPointsPerDay) + 1;

                //DrawLabel("{0}x{1}", width, height);

                //DrawLabel("Default Scale: {0}", (mbTWP.windowMain.PlotWidth == 292 && mbTWP.windowMain.PlotHeight == 292));
                //if (GUILayout.Button("Reset Scale"))
                //{
                //    mbTWP.windowMain.PlotWidth = 292;
                //    mbTWP.windowMain.PlotHeight = 292;
                //}

                //if (GUILayout.Button("Apply manual Scale (value 1 and 2)"))
                //{
                //    mbTWP.windowMain.PlotWidth = intTest1;
                //    mbTWP.windowMain.PlotHeight = intTest2;
                //}

                //if (GUILayout.Button("Apply calculates Scale and Run (value 5 - points per day)"))
                //{
                //    mbTWP.windowMain.PlotWidth = (Int32)width;
                //    mbTWP.windowMain.PlotHeight = (Int32)height;

                //    mbTWP.windowMain.RunPlots();
                //}
                ///////////////RANGE Work//////////////////////

                //Styles.styleTextFieldLabel.padding.top = intTest1;

                //if (GUILayout.Button("KSP")) SkinsLibrary.SetCurrent(SkinsLibrary.DefSkinType.KSP);
                //if (GUILayout.Button("UnityDef")) SkinsLibrary.SetCurrent(SkinsLibrary.DefSkinType.Unity);
                //if (GUILayout.Button("Default")) SkinsLibrary.SetCurrent("Default");
                //if (GUILayout.Button("Unity")) SkinsLibrary.SetCurrent("Unity");
                //if (GUILayout.Button("UnityWKSPButtons")) SkinsLibrary.SetCurrent("UnityWKSPButtons");

                // DrawLabel("{0}", KSPDateStructure.CalendarType);

                //if (mbTWP.btnAppLauncher != null)
                //{
                //    DrawLabel(Camera.current.WorldToScreenPoint(mbTWP.btnAppLauncher.GetAnchor()).ToString());

                //    DrawLabel(Camera.current.WorldToScreenPoint(mbTWP.btnAppLauncher.transform.localPosition).ToString());
                //}
                //if (GUILayout.Button("Make Date"))
                //{
                //    LogFormatted("a");
                //    //KSPDateTimeStructure.CalendarType = CalendarTypeEnum.Earth;
                //    KSPDateTime dt = new KSPDateTime(301.123);

                //    LogFormatted("1:{0}", dt.Minute);
                //    LogFormatted("2:{0}", dt.UT);
                //    LogFormatted("3:{0}", dt.Year);
                //    //LogFormatted("4:{0}", KSPDateTimeStructure.CalendarType);
                //    //LogFormatted("5:{0}", dt.Day);

                //}
                //if (GUILayout.Button("CreateAlarm"))
                //{
                //    String tmpID = KACWrapper.KAC.CreateAlarm(KACWrapper.KACAPI.AlarmTypeEnum.TransferModelled,
                //        String.Format("{0} -> {1}",mbTWP.windowMain.TransferSelected.Origin.bodyName,mbTWP.windowMain.TransferSelected.Destination.bodyName),
                //        mbTWP.windowMain.TransferSelected.DepartureTime);

                //    KACWrapper.KACAPI.KACAlarm alarmNew = KACWrapper.KAC.Alarms.First(a => a.ID == tmpID);
                //    LogFormatted("{0}==11=={1}", alarmNew.XferOriginBodyName, alarmNew.XferTargetBodyName);
                //    alarmNew.Notes = mbTWP.windowMain.GenerateTransferDetailsText();
                //    alarmNew.AlarmMargin = settings.KACMargin * 60 * 60;
                //    alarmNew.AlarmAction = settings.KACAlarmAction;
                //    LogFormatted("{0}==22=={1}", alarmNew.XferOriginBodyName, alarmNew.XferTargetBodyName);
                //    alarmNew.XferOriginBodyName = mbTWP.windowMain.TransferSelected.Origin.bodyName;
                //    LogFormatted("{0}==33=={1}", alarmNew.XferOriginBodyName, alarmNew.XferTargetBodyName);
                //    alarmNew.XferTargetBodyName = mbTWP.windowMain.TransferSelected.Destination.bodyName;

                //    LogFormatted("{0}======{1}", alarmNew.XferOriginBodyName, alarmNew.XferTargetBodyName);

                //}
                //DrawLabel("Windowpadding:{0}", SkinsLibrary.CurrentSkin.window.padding);

                //DrawLabel("{0}", KACWrapper.KAC.Alarms.Count);
                //foreach ( KACWrapper.KACAPI.KACAlarm a in KACWrapper.KAC.Alarms)
                //{
                //    DrawLabel("{1}-{2} ({0})", a.ID,a.Name, a.AlarmType);
                //}

                //DrawLabel("MouseOverAny:{0}", mbTWP.MouseOverAnyWindow);
                //DrawLabel("MouseOverMain:{0}", mbTWP.windowMain.IsMouseOver);
                //DrawLabel("MouseOverMain:{0}", mbTWP.windowMain.IsMouseOver);

                //DrawLabel("Settings:{0}", mbTWP.windowSettings.WindowRect);
                //DrawLabel("SettingsBlocker:{0}", mbTWP.windowSettingsBlockout.WindowRect);
                //DrawLabel("CI:{0} P:{1}", mbTWP.windowMain.ColorIndex, mbTWP.windowMain.Percent);

                DrawLabel("Mouse:{0}", mbTWP.windowMain.vectMouse);
                DrawLabel("Plot:{0}", new Rect(mbTWP.windowMain.PlotPosition.x, mbTWP.windowMain.PlotPosition.y, mbTWP.windowMain.PlotWidth, mbTWP.windowMain.PlotHeight));
                DrawLabel("Selected:{0}", mbTWP.windowMain.vectSelected);
                DrawLabel("Departure:{0:0}, Travel:{1:0}", mbTWP.windowMain.DepartureSelected / KSPDateStructure.SecondsPerDay, mbTWP.windowMain.TravelSelected / KSPDateStructure.SecondsPerDay);

                /////////////////////////////////Making ManNode/////////////////////////////
                /////////////////////////////////Making ManNode/////////////////////////////
                /////////////////////////////////Making ManNode/////////////////////////////
                if (mbTWP.windowMain.TransferSelected != null && FlightGlobals.ActiveVessel != null)
                {
                    if (GUILayout.Button("FindUT"))
                    {
                        dblEjectAt = Utilities.timeOfEjectionAngle(FlightGlobals.ActiveVessel.orbit, mbTWP.windowMain.TransferSelected.DepartureTime, mbTWP.windowMain.TransferSelected.EjectionAngle * LambertSolver.Rad2Deg,intTest1 , out dblOutAngle);
                        intTest5 = (Int32)dblEjectAt;
                    }
                    DrawLabel("UT: {0:0}", dblEjectAt);
                    DrawLabel("Angle: {0:0.000}", dblOutAngle);

                    DrawLabel("UTSelect: {0:0}", mbTWP.windowMain.TransferSelected.DepartureTime);
                    DrawLabel("OrbitPeriod: {0:0}", FlightGlobals.ActiveVessel.orbit.period);
                    DrawLabel("Scan: {0:0}->{1:0}", mbTWP.windowMain.TransferSelected.DepartureTime - FlightGlobals.ActiveVessel.orbit.period / 2, mbTWP.windowMain.TransferSelected.DepartureTime + FlightGlobals.ActiveVessel.orbit.period / 2);

                    Double dblEjectAt2;
                    Vector3d vectEject = new Vector3d();

                    if (GUILayout.Button("NewTransfer"))
                    {

                        transTemp = new TransferDetails();
                        LambertSolver.TransferDeltaV(mbTWP.windowMain.TransferSelected.Origin, mbTWP.windowMain.TransferSelected.Destination,
                            intTest5, mbTWP.windowMain.TransferSelected.TravelTime, mbTWP.windowMain.TransferSpecs.InitialOrbitAltitude, mbTWP.windowMain.TransferSpecs.FinalOrbitAltitude, out transTemp);

                        try
                        {
                            transTemp.CalcEjectionValues();
                        }
                        catch (Exception ex)
                        {
                            LogFormatted("Wouldnt Create EjectionValues :(\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);
                        }

                        LogFormatted("XFer: {0}", transTemp.TransferInitalVelocity);
                        LogFormatted("Origin: {0}", transTemp.OriginVelocity);
                        LogFormatted("Diff: {0}", (Vector3d)(transTemp.OriginVelocity - transTemp.TransferInitalVelocity));
                        LogFormatted("Eject: {0}", transTemp.EjectionDeltaVector);
                        LogFormatted("VesselOrbit: {0}", FlightGlobals.ActiveVessel.orbit.getOrbitalVelocityAtUT(transTemp.DepartureTime));
                        LogFormatted("VesselOrbit(m/s): {0}", transTemp.OriginVesselOrbitalSpeed);
                        //LogFormatted("oVel: {0}", LambertSolver.oVel);

                        LogFormatted("A");

                        dblEjectAt2 = timeOfLeastDVBurn(FlightGlobals.ActiveVessel.orbit, dblEjectAt, mbTWP.windowMain.TransferSelected.TransferInitalVelocity, 8, out vectEject);

                        //now massage that with the vessels vector at that UT!

                        //LogFormatted("OrbVelocity:{0}", FlightGlobals.ActiveVessel.orbit.getOrbitalVelocityAtUT(transTemp.DepartureTime));
                    }

                    if (transTemp != null)
                    {
                        //DrawLabel("v1:{0:0.000}  edv:{1:0.000}", LambertSolver.v1out, LambertSolver.vedvout);
                        DrawLabel("TransferInit:{0} - {1}", transTemp.TransferInitalVelocity.magnitude, transTemp.TransferInitalVelocity);
                        DrawLabel("Transtemp:{0} - {1}", transTemp.EjectionDeltaVector.magnitude, transTemp.EjectionDeltaVector);
                        DrawLabel("Eject:{0} - {1}", vectEject.magnitude, vectEject);

                        GUILayout.Label(transTemp.TransferDetailsText);
                        if (GUILayout.Button("Newnode"))
                        {
                            FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes.Clear();
                            ManeuverNode mNode = FlightGlobals.ActiveVessel.patchedConicSolver.AddManeuverNode(transTemp.DepartureTime);
                            mNode.DeltaV = new Vector3d(0, transTemp.EjectionDVNormal, transTemp.EjectionDVPrograde);
                            FlightGlobals.ActiveVessel.patchedConicSolver.UpdateFlightPlan();

                        }

                    }

                }
                /////////////////////////////////Making ManNode/////////////////////////////
                /////////////////////////////////Making ManNode/////////////////////////////
                /////////////////////////////////Making ManNode/////////////////////////////
                /////////////////////////////////Making ManNode/////////////////////////////

                //DrawLabel("Ass:{0}", KACWrapper.AssemblyExists);
                //DrawLabel("Ins:{0}", KACWrapper.InstanceExists);
                //DrawLabel("API:{0}", KACWrapper.APIReady);

                //if (mbTWP.windowMain.TransferSelected != null)
                //{
                //    DrawLabel("D:{0:0} T:{0:0}", mbTWP.windowMain.TransferSelected.DepartureTime, mbTWP.windowMain.TransferSelected.TravelTime);
                //    DrawLabel("Origin:{0}", mbTWP.windowMain.TransferSelected.OriginVelocity);
                //    DrawLabel("Initial:{0}", mbTWP.windowMain.TransferSelected.TransferInitalVelocity);
                //    DrawLabel("Final:{0}", mbTWP.windowMain.TransferSelected.TransferFinalVelocity);
                //    DrawLabel("Destination:{0}", mbTWP.windowMain.TransferSelected.DestinationVelocity);
                //    DrawLabel("Eject:{0}", mbTWP.windowMain.TransferSelected.EjectionDeltaVector);
                //    DrawLabel("Eject-Mag:{0}", mbTWP.windowMain.TransferSelected.EjectionDeltaVector.magnitude);
                //    DrawLabel("Insert:{0}", mbTWP.windowMain.TransferSelected.InjectionDeltaVector);
                //    DrawLabel("Insert-Mag:{0}", mbTWP.windowMain.TransferSelected.InjectionDeltaVector.magnitude);
                //    DrawLabel("TransferAngle:{0}", mbTWP.windowMain.TransferSelected.TransferAngle);
                //    DrawLabel("EjectionInclination:{0}", mbTWP.windowMain.TransferSelected.EjectionInclination);
                //    DrawLabel("InsertionInclination:{0}", mbTWP.windowMain.TransferSelected.InsertionInclination);

                //    DrawLabel("Phase:{0}", mbTWP.windowMain.TransferSelected.PhaseAngle);

                //    DrawLabel("EjectionDVNormal:{0}", mbTWP.windowMain.TransferSelected.EjectionDVNormal);
                //    DrawLabel("EjectionDVPrograde:{0}", mbTWP.windowMain.TransferSelected.EjectionDVPrograde);
                //    DrawLabel("EjectionHeading:{0}", mbTWP.windowMain.TransferSelected.EjectionHeading);
                //    DrawLabel("EjectionVector:{0}", mbTWP.windowMain.TransferSelected.EjectionVector);
                //    DrawLabel("EjectionAngle:{0}", mbTWP.windowMain.TransferSelected.EjectionAngle);

                //}

                //DrawLabel("Padding:{0}", SkinsLibrary.CurrentSkin.window.padding);
                //DrawLabel("Margin:{0}", SkinsLibrary.CurrentSkin.window.margin);
                //DrawLabel("Border:{0}", SkinsLibrary.CurrentSkin.window.border);

                //DrawLabel("Padding:{0}", SkinsLibrary.DefKSPSkin.window.padding);
                //DrawLabel("Margin:{0}", SkinsLibrary.DefKSPSkin.window.margin);
                //DrawLabel("Border:{0}", SkinsLibrary.DefKSPSkin.window.border);

                //CelestialBody cbK = FlightGlobals.Bodies[0];
                //CelestialBody cbO = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "kerbin");
                //CelestialBody cbD = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "duna");

                ////This is the frame of Reference rotation that is occuring
                //QuaternionD Rot = Planetarium.ZupRotation;
                //DrawLabel("Rotation:{0}", Rot);

                //DrawLabel("Kerbin");
                //DrawLabel("True Anomaly:{0}", cbO.orbit.trueAnomaly);
                //DrawLabel("True Anomaly at 0:{0}", cbO.orbit.TrueAnomalyAtUT(0));
                //DrawLabel("True Anomaly at first:{0}", cbO.orbit.TrueAnomalyAtUT(intTest1));
                //DrawLabel("Velocity at first:{0}", cbO.orbit.getOrbitalVelocityAtUT(intTest1).magnitude);
                //DrawLabel("Velocity at first:{0}", cbO.orbit.getOrbitalVelocityAtUT(intTest1));
                //DrawLabel("Pos at firstT:{0}", cbO.orbit.getRelativePositionAtUT(intTest1).magnitude);

                ////We have to remove the frame of ref rotation to get static values to plot
                //DrawLabel("Pos at firstT:{0}", Quaternion.Inverse(Rot) * cbO.orbit.getRelativePositionAtUT(intTest1));
                ////DrawLabel("Pos at firstUT:{0}", cbO.orbit.getRelativePositionAtT(intTest1));

                //DrawLabel("AbsPos at firstUT:{0}", cbO.orbit.getPositionAtUT(intTest1));

                //DrawLabel("Duna");
                //DrawLabel("True Anomaly:{0}", cbD.orbit.trueAnomaly);
                //DrawLabel("True Anomaly at 0:{0}", cbD.orbit.TrueAnomalyAtUT(0));
                //DrawLabel("True Anomaly at first:{0}", cbD.orbit.TrueAnomalyAtUT(intTest1));
                //DrawLabel("Velocity at first:{0}", cbD.orbit.getOrbitalVelocityAtUT(intTest1).magnitude);
                //DrawLabel("Velocity at first:{0}", cbD.orbit.getOrbitalVelocityAtUT(intTest1));
                //DrawLabel("Pos at firstT:{0}", cbD.orbit.getRelativePositionAtUT(intTest1).magnitude);

                ////We have to remove the frame of ref rotation to get static values to plot
                //DrawLabel("Pos at firstT:{0}", Quaternion.Inverse(Rot) * cbD.orbit.getRelativePositionAtUT(intTest1));
                ////DrawLabel("Pos at firstUT:{0}", cbD.orbit.getRelativePositionAtT(intTest1));

                //DrawLabel("AbsPos at firstUT:{0}", cbD.orbit.getPositionAtUT(intTest1));

                //DrawLabel("DepartureMin:{0}", mbTWP.windowMain.dateMinDeparture.UT);
                //DrawLabel("DepartureRange:{0}", DepartureRange);
                //DrawLabel("DepartureMax:{0}", mbTWP.windowMain.dateMaxDeparture.UT);
                //DrawLabel("TravelMin:{0}", TravelMin);
                //DrawLabel("TravelMax:{0}", TravelMax);

                //DrawLabel("Hohmann:{0}", hohmannTransferTime);
                //DrawLabel("synodic:{0}", synodicPeriod);

                //DrawLabel("Ktime:{0}", kTime.DateString());

                //if (GUILayout.Button("A number!"))
                //{
                //    CelestialBody cbO = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "kerbin");
                //    CelestialBody cbD = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "duna");
                //    LogFormatted_DebugOnly("Next UT:{0}->{1}: {2}",cbO.bodyName,cbD.bodyName,LambertSolver.NextLaunchWindowUT(cbO,cbD));
                //}

                //if (GUILayout.Button("A DV!"))
                //{
                //    CelestialBody cbO = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "kerbin");
                //    CelestialBody cbD = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "duna");
                //    LogFormatted_DebugOnly("DV:{0}->{1}: {2}", cbO.bodyName, cbD.bodyName, LambertSolver.TransferDeltaV(cbO, cbD, 5030208, 5718672, 100000, 100000));
                //}

                //if (GUILayout.Button("Solve!"))
                //{
                //    CelestialBody cbO = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "kerbin");
                //    CelestialBody cbD = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "duna");
                //    Vector3d originPositionAtDeparture = cbO.orbit.getRelativePositionAtUT(5030208);
                //    Vector3d destinationPositionAtArrival = cbD.orbit.getRelativePositionAtUT(5030208 + 5718672);
                //    bool longWay = Vector3d.Cross(originPositionAtDeparture, destinationPositionAtArrival).y < 0;

                //    LogFormatted_DebugOnly("DV:{0}->{1}: {2}", cbO.bodyName, cbD.bodyName, LambertSolver.Solve(cbO.referenceBody.gravParameter, originPositionAtDeparture, destinationPositionAtArrival, 5718672, longWay));
                //    LogFormatted_DebugOnly("Origin:{0}", originPositionAtDeparture);
                //    LogFormatted_DebugOnly("Dest:{0}", destinationPositionAtArrival);
                //}

                //if (GUILayout.Button("Maths"))
                //{
                //    CelestialBody cbK = FlightGlobals.Bodies[0];
                //    CelestialBody cbO = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "kerbin");
                //    CelestialBody cbD = FlightGlobals.Bodies.FirstOrDefault(x => x.bodyName.ToLower() == "duna");

                //    LogFormatted_DebugOnly("TAat0:{0}: {1}", cbO.bodyName, cbO.orbit.TrueAnomalyAtUT(0));
                //    LogFormatted_DebugOnly("TAat0:{0}: {1}", cbD.bodyName, cbD.orbit.TrueAnomalyAtUT(0));
                //    LogFormatted_DebugOnly("TAat5030208:{0}: {1}", cbO.bodyName, cbO.orbit.TrueAnomalyAtUT(5030208));
                //    LogFormatted_DebugOnly("TAat5030208:{0}: {1}", cbD.bodyName, cbD.orbit.TrueAnomalyAtUT(5030208));
                //    LogFormatted_DebugOnly("OVat5030208:{0}: {1}", cbO.bodyName, cbO.orbit.getOrbitalVelocityAtUT(5030208).magnitude);
                //    LogFormatted_DebugOnly("OVat5030208:{0}: {1}", cbD.bodyName, cbD.orbit.getOrbitalVelocityAtUT(5030208).magnitude);
                //    LogFormatted_DebugOnly("RPat5030208:{0}: X:{1},Y:{2},Z:{3}", cbO.bodyName, cbO.orbit.getRelativePositionAtUT(5030208).x, cbO.orbit.getRelativePositionAtUT(5030208).y, cbO.orbit.getRelativePositionAtUT(5030208).z);
                //    LogFormatted_DebugOnly("RPat5030208:{0}: X:{1},Y:{2},Z:{3}", cbD.bodyName, cbD.orbit.getRelativePositionAtUT(5030208).x, cbD.orbit.getRelativePositionAtUT(5030208).y, cbD.orbit.getRelativePositionAtUT(5030208).z);

                //    LogFormatted_DebugOnly("RPat5030208:{0}: X:{1},Y:{2},Z:{3}", cbO.bodyName, cbO.orbit.getRelativePositionAtUT(5030208 - Planetarium.GetUniversalTime()).x, cbO.orbit.getRelativePositionAtUT(5030208 - Planetarium.GetUniversalTime()).y, cbO.orbit.getRelativePositionAtUT(5030208 - Planetarium.GetUniversalTime()).z);
                //    LogFormatted_DebugOnly("RPat5030208:{0}: X:{1},Y:{2},Z:{3}", cbD.bodyName, cbD.orbit.getRelativePositionAtUT(5030208 - Planetarium.GetUniversalTime()).x, cbD.orbit.getRelativePositionAtUT(5030208 - Planetarium.GetUniversalTime()).y, cbD.orbit.getRelativePositionAtUT(5030208 - Planetarium.GetUniversalTime()).z);

                //    //LogFormatted_DebugOnly("SwapRPat5030208:{0}: X:{1},Y:{2},Z:{3}", cbO.bodyName, cbO.orbit.SwappedRelativePositionAtUT(5030208).x, cbO.orbit.SwappedRelativePositionAtUT(5030208).y, cbO.orbit.SwappedRelativePositionAtUT(5030208).z);
                //    //LogFormatted_DebugOnly("SwapRPat5030208:{0}: X:{1},Y:{2},Z:{3}", cbD.bodyName, cbD.orbit.SwappedRelativePositionAtUT(5030208).x, cbD.orbit.SwappedRelativePositionAtUT(5030208).y, cbD.orbit.SwappedRelativePositionAtUT(5030208).z);

                //    ////LogFormatted_DebugOnly("Absat5030208:{0}: {1}", cbK.bodyName, getAbsolutePositionAtUT(cbK.orbit, 5030208));
                //    //LogFormatted_DebugOnly("Absat5030208:{0}: {1}", cbO.bodyName, getAbsolutePositionAtUT(cbO.orbit,5030208));
                //    //LogFormatted_DebugOnly("Absat5030208:{0}: {1}", cbD.bodyName, getAbsolutePositionAtUT(cbD.orbit, 5030208));

                //    //LogFormatted_DebugOnly("Posat5030208:{0}: {1}", cbO.bodyName, cbO.getPositionAtUT(5030208));
                //    //LogFormatted_DebugOnly("TPosat5030208:{0}: {1}", cbO.bodyName, cbO.getTruePositionAtUT(5030208));
                //    //LogFormatted_DebugOnly("Posat5030208:{0}: {1}", cbD.bodyName, cbD.getPositionAtUT(5030208));
                //    //LogFormatted_DebugOnly("TPosat5030208:{0}: {1}", cbD.bodyName, cbD.getTruePositionAtUT(5030208));
                //    //LogFormatted_DebugOnly("Posat5030208:{0}: {1}", cbK.bodyName, cbK.getPositionAtUT(5030208));
                //    //LogFormatted_DebugOnly("TPosat5030208:{0}: {1}", cbK.bodyName, cbK.getTruePositionAtUT(5030208));

                //    Vector3d pos1 = new Vector3d(13028470326,3900591743,0);
                //    Vector3d pos2 = new Vector3d(-19970745720,-1082561296,15466922.92);
                //    double tof = 5718672;

                //    Vector3d vdest;
                //    Vector3d vinit = LambertSolver.Solve(cbK.gravParameter, pos1, pos2, tof, false, out vdest);
                //    LogFormatted_DebugOnly("Init:{0} - {1}", vinit.magnitude, vinit);
                //    LogFormatted_DebugOnly("vdest:{0} - {1}", vdest.magnitude, vdest);

                //    Vector3d vr1 = cbO.orbit.getOrbitalVelocityAtUT(5030208);
                //    Vector3d vr2 = cbD.orbit.getOrbitalVelocityAtUT(5030208 + 5718672);

                //    Vector3d vdest2;
                //    Vector3d vinit2;
                //    LambertSolver2.Solve(pos1, pos2, tof,cbK, true,out vinit2, out vdest2);

                //    LogFormatted_DebugOnly("Origin:{0} - {1}", vr1.magnitude, vr1);
                //    LogFormatted_DebugOnly("Dest:{0} - {1}", vr2.magnitude, vr2);

                //    LogFormatted_DebugOnly("Depart:{0} - {1}", vinit2.magnitude, vinit2);
                //    LogFormatted_DebugOnly("Arrive:{0} - {1}", vdest2.magnitude, vdest2);

                //    LogFormatted_DebugOnly("Eject:{0} - {1}", (vinit2 - vr1).magnitude, vinit2 - vr1);
                //    LogFormatted_DebugOnly("Inject:{0} - {1}", (vdest2 - vr2).magnitude, vdest2 - vr2);

                //}

            }
            catch (Exception ex)
            {
                LogFormatted("{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);
            }
        }
        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);
            }
        }