private void CorrectionCalcCompleted(LunarCourseCorrection lcc)
    {
        // Update the GE Console
        string s = LunarCorrectionApply();

        GEConsole.Instance().AddToHistory(s);
    }
    public string ApproachPrediction(string moonName)
    {
        // @TODO: Too much C&P!
        // Step 1: Determine the patched conic xfer
        OrbitData shipOrbit = new OrbitData();
        NBody     shipNbody = spaceshipCtrl.GetNBody();

        shipOrbit.SetOrbit(shipNbody, centralMass);
        OrbitData moonOrbit = new OrbitData();
        NBody     moonNbody = GetTargetByName(moonName);

        moonOrbit.SetOrbit(moonNbody, centralMass);
        //Make a copy of the universe state and evolve forward to find min distance to
        // moon.
        GravityEngine ge = GravityEngine.Instance();
        GravityState  gs = ge.GetGravityStateCopy();
        // run a simulation and find the closest approach (Expensive!)
        LunarCourseCorrection lcc = new LunarCourseCorrection(shipNbody, moonNbody);

        // want to be within 10% of Earth-Moon distance, before start checking
        courseCorrectionData = new LunarCourseCorrection.CorrectionData();
        courseCorrectionData.gravityState     = gs;
        courseCorrectionData.approachDistance = 0.1f * moonOrbit.a;;
        courseCorrectionData.correction       = 0;
        courseCorrectionData.maxPhysTime      = time_to_moon_phys;
        lcc.ClosestApproachAsync(courseCorrectionData, MoonPreviewCompleted);
        return("Calculation started...\n");
    }
    /// <summary>
    /// Callback for MoonPreview when run in async mode.
    /// </summary>
    /// <param name="lcc"></param>
    private void MoonPreviewCompleted(LunarCourseCorrection lcc)
    {
        // Update the GE Console with the result stored in calcData
        string s = string.Format("Closest approach of {0} at t={1}\n",
                                 courseCorrectionData.distance, courseCorrectionData.timeAtApproach);

        GEConsole.Instance().AddToHistory(s);
    }
    /// <summary>
    /// Determine the correction required to establish the desired distance to the moon (i.e. that which
    /// was predicted by the preview)
    /// </summary>
    /// <param name="moonName"></param>
    /// <returns></returns>
    public string LunarCourseCorrection(string moonName)
    {
        NBody     moon      = GetTargetByName(moonName);
        OrbitData moonOrbit = new OrbitData();
        NBody     moonNbody = GetTargetByName(moonName);

        moonOrbit.SetOrbit(moonNbody, centralMass);
        GravityEngine.Instance().SetEvolve(false);
        lcc = new LunarCourseCorrection(spaceshipCtrl.GetNBody(), moon);
        float  approachDistance = 0.1f * moonOrbit.a;
        double targetDistance   = predictedDistance;
        double targetAccuracy   = 0; // Does not matter for closest
        string result           = lcc.CorrectionCalcAsync(targetDistance, targetAccuracy, approachDistance,
                                                          time_to_moon_phys, CorrectionCalcCompleted);

        // GravityEngine.Instance().SetEvolve(true);
        return(result);
    }
    public string MoonPreview(string moonName, float lambda1, bool async)
    {
        // Step 1: Determine the patched conic xfer
        OrbitData shipOrbit = new OrbitData();
        NBody     shipNbody = spaceshipCtrl.GetNBody();

        shipOrbit.SetOrbit(shipNbody, centralMass);
        OrbitData moonOrbit = new OrbitData();
        NBody     moonNbody = GetTargetByName(moonName);

        moonOrbit.SetOrbit(moonNbody, centralMass);
        OrbitTransfer xfer = new PatchedConicXfer(shipOrbit, moonOrbit, lambda1);

        // Step 2: Make a copy of the universe state and evolve forward to find min distance to
        // moon.
        GravityEngine ge = GravityEngine.Instance();
        GravityState  gs = ge.GetGravityStateCopy();

        // there is only one maneuver to add
        gs.maneuverMgr.Add(xfer.GetManeuvers()[0]);
        // run a simulation and find the closest approach (Expensive!)
        LunarCourseCorrection lcc = new LunarCourseCorrection(shipNbody, moonNbody);

        // want to be within 10% of Earth-Moon distance, before start checking
        courseCorrectionData = new LunarCourseCorrection.CorrectionData();
        courseCorrectionData.gravityState     = gs;
        courseCorrectionData.approachDistance = 0.1f * moonOrbit.a;;
        courseCorrectionData.correction       = 0;
        courseCorrectionData.maxPhysTime      = time_to_moon_phys;
        // Direct (unthreaded) calculation
        if (async)
        {
            lcc.ClosestApproachAsync(courseCorrectionData, MoonPreviewCompleted);
            return("Calculation started...\n");
        }
        else
        {
            predictedDistance = lcc.ClosestApproach(courseCorrectionData);
            return(string.Format("Patched Conic with lambda={0} => approach={1}\n", lambda1, predictedDistance));
        }
    }
 public string LunarCorrectionApply()
 {
     if (lcc != null)
     {
         Debug.Log("LCC is done.");
         // Get the final correction and apply it
         double[] v = new double[3];
         lcc.GetCorrectionVelocity(ref v);
         GravityEngine.Instance().SetVelocityDouble(spaceshipCtrl.GetNBody(), ref v);
         LunarCourseCorrection.CorrectionData cdata = lcc.correctionFinal;
         string s = string.Format("Correction applied. correction={0} giving distance={1} at {2}\n",
                                  cdata.correction, cdata.distance, cdata.timeAtApproach);
         Debug.Log(s);
         lcc = null;
         return(s);
     }
     else
     {
         return("No calculation was scheduled.");
     }
 }