/// <summary>
    /// Callback to compute the launch transfer times and display them in the scene.
    /// </summary>
    public void Compute()
    {
        int       itemNo    = destDropdown.value;
        NBody     toNbody   = destinations[itemNo].GetComponent <NBody>();
        OrbitData fromOrbit = new OrbitData();

        fromOrbit.SetOrbit(fromNbody, centerNbody);
        OrbitData toOrbit = new OrbitData();

        toOrbit.SetOrbit(toNbody, centerNbody);

        HohmannXfer hohmannXfer = new HohmannXfer(fromOrbit, toOrbit, true);

        // Find launch windows
        double[] times = hohmannXfer.LaunchTimes(numWindows);
        List <Dropdown.OptionData> items = new List <Dropdown.OptionData>();

        foreach (double t in times)
        {
            Dropdown.OptionData item = new Dropdown.OptionData();
            item.text = GravityScaler.GetWorldTimeFormatted(t, GravityScaler.Units.SOLAR);
            items.Add(item);
        }
        launchTimes.ClearOptions();
        launchTimes.AddOptions(items);
    }
    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");
    }
Exemple #3
0
    public List <OrbitTransfer> FindTransfers()
    {
        // find orbit parameters for each body.
        OrbitData shipOrbit = new OrbitData();

        shipOrbit.SetOrbit(ship, centralMass);
        OrbitData targetOrbit = new OrbitData();

        targetOrbit.SetOrbit(target, centralMass);
        //Debug.Log("ship:" + shipOrbit.LogString());
        //Debug.Log("target:" + targetOrbit.LogString());
        List <OrbitTransfer> transfers = new List <OrbitTransfer>();

        if ((shipOrbit.ecc < 1f) && (targetOrbit.ecc < 1f))
        {
            // both ellipses
            if (shipOrbit.ecc >= DELTA_ECC)
            {
                // add option to circularize our orbit (independent of target)
                // TODO: need more general ellipse tuning
                transfers.Add(new CircularizeXfer(shipOrbit));
            }

            if ((shipOrbit.ecc < DELTA_ECC) && (targetOrbit.ecc < DELTA_ECC))
            {
                // both circular - can use Hohmann
                if (Mathf.Abs(shipOrbit.inclination - targetOrbit.inclination) > DELTA_INCL)
                {
                    // change in inclination
                    // DEBUG hack
                    // transfers.Add(new CircularPlaneChange(shipOrbit, targetOrbit));
                }
                else
                {
                    transfers.Add(new HohmannXfer(shipOrbit, targetOrbit));
                    if (BiellipticXfer.HasLowerDv(shipOrbit, targetOrbit))
                    {
                        // need to pick (or let user select) the xfer radius - could show a curve?
                        // Test code - just pick 1.5x dest as xfer radius
                        // TODO: Make transfer radius selectable
                        transfers.Add(new BiellipticXfer(shipOrbit, targetOrbit, targetOrbit.a * 1.5f));
                    }
                }
            }
            else
            {
                Debug.Log("TODO: Transfer between co-planar ellipses.");
            }
        }
        else
        {
            Debug.Log("Not transfer between ellipses.");
        }
        return(transfers);
    }
    /// <summary>
    /// Initiate a transfer of the spaceship to the moon. The name of the targets[] entry that is the moon
    /// is provided as a string argument.
    ///
    /// Typically called by the GEConsole.
    /// </summary>
    public string MoonTransfer(string moonName, float angle)
    {
        // Find xfer choices and present to user
        OrbitData shipOrbit = new OrbitData();

        shipOrbit.SetOrbit(spaceshipCtrl.GetNBody(), centralMass);
        OrbitData targetOrbit = new OrbitData();

        targetOrbit.SetOrbit(GetTargetByName(moonName), centralMass);
        OrbitTransfer xfer = new PatchedConicXfer(shipOrbit, targetOrbit, angle);

        spaceshipCtrl.SetTransfer(xfer);
        SetState(State.MANEUVER);
        // display the maneuver in the console (will only be one for patched conic)
        return(xfer.GetManeuvers()[0].LogString() + "\n");
    }
    /// <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);
    }
Exemple #6
0
    private void SetMarkers()
    {
        if (shipOrbitData == null)
        {
            // Cannot rely on controller start after GE start, so instead of forcing
            // start order, do a lazy init here
            shipOrbitData = new OrbitData();
            shipOrbitData.SetOrbit(spaceshipNBody, shipOrbit.centerNbody);
        }

        // skip scaling since we are in dimensionless units
        Vector3 pos = shipOrbitData.GetPhysicsPositionforEllipse(fromPhase);

        fromMarker.transform.position = pos;

        pos = shipOrbitData.GetPhysicsPositionforEllipse(toPhase);
        toMarker.transform.position = pos;
    }
    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));
        }
    }
Exemple #8
0
    public List <OrbitTransfer> FindTransfers(bool rendezvous)
    {
        // find orbit parameters for each body.
        OrbitData shipOrbit = new OrbitData();

        shipOrbit.SetOrbit(ship, centralMass);
        //shipOrbit.SetOrbitForVelocity(ship, centralMass);
        OrbitData targetOrbit = new OrbitData();

        targetOrbit.SetOrbit(target, centralMass);
        //targetOrbit.SetOrbitForVelocity(target, centralMass);
        //Debug.Log("ship:" + shipOrbit.LogString());
        //Debug.Log("target:" + targetOrbit.LogString());
        List <OrbitTransfer> transfers = new List <OrbitTransfer>();

        if ((shipOrbit.ecc < 1f) && (targetOrbit.ecc < 1f))
        {
            // both ellipses
            if (shipOrbit.ecc >= DELTA_ECC)
            {
                // add option to circularize our orbit (independent of target)
                // TODO: need more general ellipse tuning
                transfers.Add(new CircularizeXfer(shipOrbit));
            }

            if ((shipOrbit.ecc < DELTA_ECC) && (targetOrbit.ecc < DELTA_ECC))
            {
                // both circular - can use Hohmann
                if (Mathf.Abs(shipOrbit.inclination - targetOrbit.inclination) > DELTA_INCL)
                {
                    // Change in inclination
                    // If same radius can use CircularInclinationAndAN()
                    if (Mathf.Abs(shipOrbit.a - targetOrbit.a) < DELTA_RADIUS)
                    {
                        transfers.Add(new CircularInclinationAndAN(shipOrbit, targetOrbit));
                    }
                    else
                    {
                        Debug.Log("TODO: transfer between non-coplaner circles");
                    }
                }
                else
                {
                    // Same inclination
                    transfers.Add(new HohmannXfer(shipOrbit, targetOrbit, true));
                    // If the target is a moon (mass > 0) then consider a patched conic transfer
                    if (target.mass > 0)
                    {
                        // Need to let user pick the angle of arrival
                        transfers.Add(new PatchedConicXfer(shipOrbit, targetOrbit, PatchedConicXfer.LAMBDA1_DEFAULT));
                    }
                    if (BiellipticXfer.HasLowerDv(shipOrbit, targetOrbit))
                    {
                        // Pick 50% excess for orbit (UI can re-adjust as needed)
                        transfers.Add(new BiellipticXfer(shipOrbit, targetOrbit, 50f));
                    }
                }
            }
            else
            {
                Debug.Log("TODO: Transfer between co-planar ellipses.");
            }
        }
        else
        {
            Debug.Log("Not transfer between ellipses.");
        }
        return(transfers);
    }