Example #1
0
    // Create an NBody and check it's mass
    public void EccentricityPrediction()
    {
        const float    mass        = 1000f;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        const float    orbitRadius = 10f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        OrbitPredictor op = TestSetupUtils.AddOrbitPredictor(planet, star);

        Assert.NotNull(op);

        double[] ecc_values = { 0, 0.1, 0.7, 0.9, 0.99, 1.01, 1.5, 2 };
        foreach (double ecc in ecc_values)
        {
            Debug.LogFormat("#### EccentricityPrediction ecc={0}", ecc);
            orbitU.eccentricity = ecc;
            TestSetupUtils.SetupGravityEngine(star, planet);
            op.TestRunnerSetup();

            OrbitUniversal predictedOrbit = op.GetOrbitUniversal();
            Assert.NotNull(predictedOrbit);
            CompareOrbits(orbitU, predictedOrbit, small);
        }
    }
    public override void OnInspectorGUI()
    {
        KeplerSequence keplerSeq = (KeplerSequence)target;

        OrbitUniversal orbitU = keplerSeq.GetComponent <OrbitUniversal>();

        if (orbitU.evolveMode == OrbitUniversal.EvolveMode.GRAVITY_ENGINE)
        {
            EditorGUILayout.LabelField("Base orbit is in GRAVITY MODE. Kepler sequence will be ignored!");
            return;
        }
        if (EditorApplication.isPlaying)
        {
            EditorGUILayout.LabelField("Dump of Kepler Sequence Elements");
            EditorGUILayout.LabelField(string.Format("time={0} current={1}",
                                                     GravityEngine.Instance().GetPhysicalTime(), keplerSeq.GetCurrentOrbitIndex()));
            string[] info = keplerSeq.DumpInfo().Split('\n');
            foreach (string s in info)
            {
                EditorGUILayout.LabelField(s);
            }
            EditorGUILayout.LabelField("Tip: GetCurrentOrbit() returns the active element.");
        }
        else
        {
            EditorGUILayout.LabelField("Inspector will show active elements when playing");
        }
    }
Example #3
0
    // Create an NBody and check it's mass
    public void OmegaUEllipsePrediction()
    {
        const float    mass        = 1000f;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        const float    orbitRadius = 10f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        // Need a bit of incl, otherwise omegaU comes back as omegaL.
        orbitU.inclination  = 10;
        orbitU.eccentricity = 0.05;

        OrbitPredictor op = TestSetupUtils.AddOrbitPredictor(planet, star);

        Assert.NotNull(op);

        double[] ou_values = { 0, 1, 5, 10, 30, 60, 90, 180, 270, 355, 360 };
        foreach (double ou in ou_values)
        {
            Debug.LogFormat("#### OmegaUPrediction ou={0}", ou);
            orbitU.omega_uc = ou;
            TestSetupUtils.SetupGravityEngine(star, planet);
            op.TestRunnerSetup();

            OrbitUniversal predictedOrbit = op.GetOrbitUniversal();
            Assert.NotNull(predictedOrbit);
            CompareOrbits(orbitU, predictedOrbit, small);
        }
    }
    // Check eccentricity and inclination
    public void CheckTestRV()
    {
        const float    mass        = 1000f;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        const float    orbitRadius = 10f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        orbitU.eccentricity = .25f;
        orbitU.inclination  = 25f;
        orbitU.omega_uc     = 10f;
        orbitU.omega_lc     = 20f;
        orbitU.phase        = 190f;
        orbitU.SetMajorAxisInspector(orbitRadius);

        OrbitData od = new OrbitData();

        od.a           = orbitRadius;
        od.ecc         = 0.25f;
        od.inclination = 25f;
        od.omega_uc    = 10f;
        od.omega_lc    = 20f;
        od.phase       = 190f;
        od.centralMass = starNbody;
        GravityEngine.Instance().UnitTestAwake();
        Debug.LogFormat("major-axis: {0} vs {1}", orbitU.GetMajorAxisInspector(), orbitRadius);
        Assert.AreEqual(orbitU.GetMajorAxisInspector(), orbitRadius);
        TestRV(od, planet, starNbody, orbitRadius);
    }
Example #5
0
    // Create an NBody and check it's mass
    public void InclinationPrediction()
    {
        const float    mass        = 1000f;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        const float    orbitRadius = 10f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        OrbitPredictor op = TestSetupUtils.AddOrbitPredictor(planet, star);

        Assert.NotNull(op);

        double[] incl_values = { 0, 1, 5, 10, 30, 45, 60, 90, 145, 179, 180 };
        foreach (double incl in incl_values)
        {
            Debug.LogFormat("#### InclinationPrediction incl={0}", incl);
            orbitU.inclination = incl;
            TestSetupUtils.SetupGravityEngine(star, planet);
            op.TestRunnerSetup();

            OrbitUniversal predictedOrbit = op.GetOrbitUniversal();
            Assert.NotNull(predictedOrbit);
            CompareOrbits(orbitU, predictedOrbit, small);
        }
    }
 /// <summary>
 /// Raise a circular orbit by the specified percent
 /// - only on-rail is implemented
 /// </summary>
 /// <param name="percentRaise"></param>
 private void NewCircularOrbit(float percentRaise)
 {
     if (onRails)
     {
         KeplerSequence keplerSeq = spaceship.GetComponent <KeplerSequence>();
         OrbitUniversal orbitU    = keplerSeq.GetCurrentOrbit();
         // check orbit is circular
         if (orbitU.eccentricity < 1E-2)
         {
             // circular, ok to proceed
             OrbitData fromOrbit = new OrbitData(orbitU);
             OrbitData toOrbit   = new OrbitData(fromOrbit);
             toOrbit.a = percentRaise * fromOrbit.a;
             const bool    rendezvous  = false;
             OrbitTransfer hohmannXfer = new HohmannXfer(fromOrbit, toOrbit, rendezvous);
             keplerSeq.RemoveFutureSegments();
             keplerSeq.AddManeuvers(hohmannXfer.GetManeuvers());
         }
     }
     else
     {
         // assume we're in orbit around the moon
         OrbitData orbitData = new OrbitData();
         orbitData.SetOrbitForVelocity(spaceship, moonBody);
         OrbitData toOrbit = new OrbitData(orbitData);
         toOrbit.a = percentRaise * orbitData.a;
         const bool    rendezvous  = false;
         OrbitTransfer hohmannXfer = new HohmannXfer(orbitData, toOrbit, rendezvous);
         ge.AddManeuvers(hohmannXfer.GetManeuvers());
     }
 }
Example #7
0
    /// <summary>
    /// The spaceship has a fixed orbit that is on rails (must be an OrbitUniversal).
    ///
    /// To allow for setting of specific times and forward/backward motion implement the transfer as a
    /// KeplerSequence of three OrbitUniversals:
    /// - initial orbit when t less then now
    /// - transfer ellipse when t between now and (now + transfer_time)
    /// - destination orbit when t greater than (now + transfer_time)
    ///
    /// </summary>
    private void TransferOnRails()
    {
        // initial orbit - needs to be OrbitUniversal (could morph an OrbitEllipse, but keep things simple)
        OrbitUniversal initialOrbit = spaceshipNBody.GetComponent <OrbitUniversal>();

        if (initialOrbit == null)
        {
            Debug.LogError("script assumes ship orbit will be OrbitUniversal");
            return;
        }

        KeplerSequence keplerSeq = spaceshipNBody.GetComponent <KeplerSequence>();

        if (keplerSeq == null)
        {
            Debug.LogError("Cannot do on-rails transfer. Ship does not have a KeplerSequence");
            return;
        }

        // Kepler sequence already has the initial orbit.
        // transfer orbit
        Vector3d xfer_r0 = lambertU.GetTransferPositionDouble();
        Vector3d xfer_v0 = lambertU.GetTransferVelocityDouble();
        double   xfer_t  = ge.GetPhysicalTimeDouble();

        keplerSeq.AppendElementRVT(xfer_r0, xfer_v0, xfer_t, false, spaceshipNBody, starNBody, null);
        // destination orbit
        double   dest_t = xfer_t + transferTime;
        Vector3d dest_v = new Vector3d(targetData.GetPhysicsVelocityForEllipse(targetData.phase));
        Vector3d dest_r = new Vector3d(targetData.GetPhysicsPositionforEllipse(targetData.phase));

        keplerSeq.AppendElementRVT(dest_r, dest_v, dest_t, false, spaceshipNBody, starNBody, SequenceDoneCallback);
    }
    /// <summary>
    /// Add an element to the sequence that begins at time and evolves based on the orbit data provided.
    ///
    /// Orbit elements must be added in increasing time order.
    /// </summary>
    /// <param name="time"></param>
    /// <param name="orbitData"></param>
    /// <param name="body"></param>
    /// <param name="centerBody"></param>
    /// <param name="callback">(Optional) Method to call when sequence starts</param>
    /// <returns></returns>
    public OrbitUniversal AppendElementOrbitData(double time,
                                                 OrbitData orbitData,
                                                 NBody body,
                                                 NBody centerBody,
                                                 ElementStarted callback)
    {
        if (BadTime(time))
        {
            return(null);
        }
        KeplerElement ke = new KeplerElement
        {
            timeStart  = time,
            returnToGE = false,
            callback   = callback
        };
        OrbitUniversal orbit = orbitsGO.AddComponent <OrbitUniversal>();

        orbit.centerNbody = centerBody;
        orbit.SetNBody(body);
        orbit.InitFromOrbitData(orbitData, time);
        orbit.evolveMode = OrbitUniversal.EvolveMode.KEPLERS_EQN;
        ke.orbit         = orbit;
        keplerElements.Add(ke);
        return(orbit);
    }
 /// <summary>
 /// Circularize around Moon
 /// - currently only onRails is implemented
 /// </summary>
 private void CircularizeAroundMoon()
 {
     // check ship is on segment where it near Moon
     if (onRails)
     {
         KeplerSequence keplerSeq = spaceship.GetComponent <KeplerSequence>();
         OrbitUniversal orbitU    = keplerSeq.GetCurrentOrbit();
         if (orbitU.centerNbody == moonBody)
         {
             // in orbit around the moon - do circularization
             OrbitData     orbitData       = new OrbitData(orbitU);
             OrbitTransfer circularizeXfer = new CircularizeXfer(orbitData);
             keplerSeq.RemoveFutureSegments();
             keplerSeq.AddManeuvers(circularizeXfer.GetManeuvers());
         }
     }
     else
     {
         // assume we're in orbit around the moon
         OrbitData orbitData = new OrbitData();
         orbitData.SetOrbitForVelocity(spaceship, moonBody);
         OrbitTransfer circularizeXfer = new CircularizeXfer(orbitData);
         ge.AddManeuvers(circularizeXfer.GetManeuvers());
     }
 }
    // Use this for initialization (must Awake, since start of GameLoop will set states)
    void Awake()
    {
        state      = State.SELECT_OBJECTIVE;
        intercepts = null;

        time_to_moon_phys = TIME_TO_MOON_SEC / GravityScaler.GetGameSecondPerPhysicsSecond();

        if (targets.Length == 0)
        {
            Debug.LogError("No targets configured");
        }
        // Player is spaceship 1, others are objectives

        // take first ship to tbe the player
        target = targets[0];


        // Need to configure objective chooser
        SetObjectiveOptions(targets);

        SetState(state);

        // add a trajectory intercepts component (it need to handle markers so it has
        // a monobehaviour base class).
        // The pair of spaceships to be checked will be selected dynamically
        trajIntercepts = gameObject.AddComponent <TrajectoryIntercepts>();
        trajIntercepts.interceptSymbol  = interceptMarker;
        trajIntercepts.rendezvousSymbol = rendezvousMarker;

        spaceshipGO = spaceshipCtrl.transform.parent.gameObject;
        // optional
        spaceshipOrbit = spaceshipGO.GetComponent <OrbitUniversal>();

        // only record the elements that are active at the start of the scene
        orbitPredictors = new List <OrbitPredictor>();
        foreach (OrbitPredictor op in  (OrbitPredictor[])Object.FindObjectsOfType(typeof(OrbitPredictor)))
        {
            if (op.gameObject.activeInHierarchy)
            {
                orbitPredictors.Add(op);
                if (op.transform.parent == spaceshipGO.transform)
                {
                    shipOrbitPredictor = op;
                }
            }
        }
        if (shipOrbitPredictor == null)
        {
            Debug.LogError("Did not find orbit predictor for ship");
        }

        orbitRenderers = new List <OrbitRenderer>();
        foreach (OrbitRenderer or in (OrbitRenderer[])Object.FindObjectsOfType(typeof(OrbitRenderer)))
        {
            if (or.gameObject.activeInHierarchy)
            {
                orbitRenderers.Add(or);
            }
        }
    }
    /// <summary>
    /// Add an element to the sequence using r0/v0/t0 initial conditions.
    ///
    /// Position and velocity are with respect to the center body (NOT world/physics space!).
    ///
    /// Orbit segements must be added in increasing time order.
    /// </summary>
    /// <param name="r0"></param>
    /// <param name="v0"></param>
    /// <param name="time"></param>
    /// <param name="relativePos"></param>
    /// <param name="body"></param>
    /// <param name="centerBody"></param>
    /// <param name="callback">(Optional) Method to call when sequence starts</param>
    /// <returns></returns>
    public OrbitUniversal AppendElementRVT(Vector3d r0,
                                           Vector3d v0,
                                           double time,
                                           bool relativePos,
                                           NBody body,
                                           NBody centerBody,
                                           ElementStarted callback)
    {
        if (BadTime(time))
        {
            return(null);
        }
        KeplerElement ke = new KeplerElement
        {
            timeStart  = time,
            callback   = callback,
            returnToGE = false
        };
        OrbitUniversal orbit = orbitsGO.AddComponent <OrbitUniversal>();

        orbit.centerNbody = centerBody;
        orbit.SetNBody(body);
        orbit.InitFromRVT(r0, v0, time, centerBody, relativePos);
        orbit.evolveMode = OrbitUniversal.EvolveMode.KEPLERS_EQN;
        ke.orbit         = orbit;
        keplerElements.Add(ke);
        return(orbit);
    }
Example #12
0
    /// <summary>
    /// Determine the SOI radius in internal physics units.
    /// </summary>
    /// <param name="planet"></param>
    /// <param name="moon"></param>
    /// <returns></returns>
    public static float SoiRadius(NBody planet, NBody moon)
    {
        // to allow to run before GE is up, use Ellipse component to get radius
        OrbitEllipse moonEllipse = moon.gameObject.GetComponent <OrbitEllipse>();
        float        a;

        if (moonEllipse != null)
        {
            a = moonEllipse.a_scaled;
        }
        else
        {
            OrbitUniversal orbitU = moon.GetComponent <OrbitUniversal>();
            if (orbitU != null)
            {
                a = (float)orbitU.GetApogee();
            }
            else
            {
                Debug.LogWarning("Could not get moon orbit size");
                return(float.NaN);
            }
        }
        // mass scaling will cancel in this ratio
        return(Mathf.Pow(moon.mass / planet.mass, 0.4f) * a);
    }
Example #13
0
    // Create an NBody and check it's mass
    public void CirclePrediction()
    {
        const float    mass        = 1000f;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        const float    orbitRadius = 10f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        OrbitPredictor op = TestSetupUtils.AddOrbitPredictor(planet, star);

        Assert.NotNull(op);

        double[] p_values = { 10, 100, 1000 };
        foreach (double p in p_values)
        {
            Debug.LogFormat("#### CirclePrediction p={0}", p);
            orbitU.p = p;
            TestSetupUtils.SetupGravityEngine(star, planet);
            op.TestRunnerSetup();

            OrbitUniversal predictedOrbit = op.GetOrbitUniversal();
            Assert.NotNull(predictedOrbit);
            CompareOrbits(orbitU, predictedOrbit, small);
        }
    }
    /// <summary>
    /// Set up a KeplerSeqeunce to do the three phases of the transfer as Kepler mode conics.
    ///
    /// Add all the ghost orbits with the required times
    /// </summary>
    /// <param name="transferTime"></param>
    private void TransferOnRails()
    {
        // the ship needs to have a KeplerSequence
        KeplerSequence kseq = spaceship.GetComponent <KeplerSequence>();

        if (kseq == null)
        {
            Debug.LogError("Could not find a KeplerSequence on " + spaceship.name);
            return;
        }
        // Ellipse 1: shipPos/shipvel already phased by the caller.
        double t_start = ge.GetPhysicalTime();
        double t_toSoi = timeHohmann * tflightFactor;

        KeplerSequence.ElementStarted noCallback = null;
        Vector3d r0    = new Vector3d();
        Vector3d v0    = new Vector3d();
        double   time0 = 0;

        ghostShipOrbit[TO_MOON].GetRVT(ref r0, ref v0, ref time0);
        kseq.AppendElementRVT(r0, v0, t_start, true, spaceship, planet, noCallback);

        // Hyperbola: start at t + transferTime
        // Need to add wrt to ghostMoon (relative=true), then for actual Kepler motion want it around moon
        ghostShipOrbit[SOI_HYPER].GetRVT(ref r0, ref v0, ref time0);
        OrbitUniversal hyperObit = kseq.AppendElementRVT(r0, v0, t_start + t_toSoi, true, spaceship, ghostMoon[MOON_SOI_ENTER], EnterMoonSoi);

        hyperObit.centerNbody = moonBody;

        // Ellipse 2:
        ghostShipOrbit[EXIT_SOI].GetRVT(ref r0, ref v0, ref time0);
        kseq.AppendElementRVT(r0, v0, t_soiExit, true, spaceship, planet, ExitMoonSoi);
    }
    private void TestRV(OrbitData od, GameObject planet, NBody starNbody, float orbitRadius)
    {
        GameObject     testPlanet = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU     = testPlanet.GetComponent <OrbitUniversal>();

        // Run init explicitly to update transform details
        orbitU.InitFromOrbitData(od, 0);

        // Awkward but previously could not add a new object to GE when it is stopped, so re-add all three
        // Leave as is, since it works!
        GravityEngine ge = GravityEngine.Instance();

        ge.Clear();
        ge.AddBody(starNbody.gameObject);
        ge.AddBody(planet);
        ge.AddBody(testPlanet);
        ge.Setup();
        ge.LogDump();
        Vector3 r_od = ge.GetPhysicsPosition(testPlanet.GetComponent <NBody>());
        Vector3 v_od = ge.GetVelocity(testPlanet);
        Vector3 r_i  = ge.GetPhysicsPosition(planet.GetComponent <NBody>());
        Vector3 v_i  = ge.GetVelocity(planet);

        Debug.Log(" r_i=" + r_i + " r_od=" + r_od + " delta=" + Vector3.Distance(r_i, r_od));
        Debug.Log(" v_i=" + v_i + " v_od=" + v_od + " delta=" + Vector3.Distance(v_i, v_od));
        Assert.IsTrue(GEUnit.FloatEqual(Vector3.Distance(r_i, r_od), 0f, 1E-2));
        Assert.IsTrue(GEUnit.FloatEqual(Vector3.Distance(v_i, v_od), 0f, 1E-2));
    }
    public void PositionForRadius()
    {
        const float    mass        = 1000f;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        const float    orbitRadius = 10f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        orbitU.inclination = 5;
        orbitU.SetMajorAxisInspector(orbitRadius);
        float r = 10.0f;

        float[] eccValues = { 0f, 0.1f, 0.9f, 1.1f };
        foreach (float ecc in eccValues)
        {
            Debug.LogFormat("======= ecc={0}  =======", ecc);
            orbitU.eccentricity = ecc;
            orbitU.SetMajorAxisInspector(orbitRadius); // updates p
            TestSetupUtils.SetupGravityEngine(star, planet);

            Vector3[] positions = orbitU.GetPositionsForRadius(r, new Vector3(0, 0, 0));
            Debug.LogFormat("pos[0]={0} pos[1]={1}", positions[0], positions[1]);
            foreach (Vector3 p in positions)
            {
                Debug.LogFormat("Position error={0}", Mathf.Abs(p.magnitude - r));
                Assert.IsTrue(GEUnit.FloatEqual(p.magnitude, r, 1E-2));
            }
        }
    }
    public void KeplerVsTimeOfFlight()
    {
        // Need to make sure TOF < 1 period
        const float    mass        = 100f;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        const float    orbitRadius = 10f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        // Parabola (ecc=1.0 fails, need to investigate)
        float[] ecc_values = { 0.0f, 0.1f, 0.5f, 0.9f, 1.2f, 1.5f };
        foreach (float ecc in ecc_values)
        {
            Debug.LogFormat("======= ecc={0}  =======", ecc);
            orbitU.eccentricity = ecc;
            orbitU.p            = 10f;
            orbitU.evolveMode   = OrbitUniversal.EvolveMode.KEPLERS_EQN;
            // Evolve to position r1
            double time = 5.0;
            TestSetupUtils.SetupGravityEngine(star, planet);
            double[] r1 = new double[] { 0, 0, 0 };
            // orbitU.PreEvolve(pscale, mscale);
            // Ugh. Need to do this before call evolve, since it caches the value.
            Vector3d r0_vec = GravityEngine.Instance().GetPositionDoubleV3(planet.GetComponent <NBody>());
            orbitU.Evolve(time, ref r1);
            Vector3d r1_vec = new Vector3d(ref r1);
            // check time to r1
            double time_test = orbitU.TimeOfFlight(r0_vec, r1_vec);
            Debug.LogFormat("check r0={0} to r1={1} p ={2} after t={3} TOF => {4}",
                            r0_vec, r1_vec, orbitU.p, time, time_test);
            Assert.IsTrue(GEUnit.DoubleEqual(time, time_test, 1E-4));
        }
    }
    public void OmegaUCircleInclination()
    {
        const float    mass        = 1000f;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        const float    orbitRadius = 10f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 1f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        orbitU.eccentricity = 0.0f;
        orbitU.inclination  = 5;
        orbitU.SetMajorAxisInspector(orbitRadius);
        // Try some values of om
        float[] omegaValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        foreach (float omega in omegaValues)
        {
            orbitU.omega_uc = omega;
            TestSetupUtils.SetupGravityEngine(star, planet);

            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("Omega = " + omega + " od.omega_lc=" + od.omega_lc + " od:" + od.LogString());
            Assert.IsTrue(GEUnit.FloatEqual(omega, od.omega_uc, 0.1));
        }
    }
    // Use this for initialization
    void Start()
    {
        ge     = GravityEngine.Instance();
        x_axis = new Vector3d(1, 0, 0);

        // mass scaling will cancel in this ratio
        soiRadius = OrbitUtils.SoiRadius(planet, moonBody);

        // TODO: allow moon to be OrbitUniversal as well.
        OrbitUniversal moonOrbit = moonBody.gameObject.GetComponent <OrbitUniversal>();

        if (moonOrbit == null)
        {
            Debug.LogError("Moon is required to have OrbitUniversal");
        }
        moonRadius = moonOrbit.GetMajorAxis();

        shipOrbit = spaceship.GetComponent <OrbitUniversal>();
        if (shipOrbit == null)
        {
            Debug.LogError("Require that the ship have an OrbitU");
        }
        if (shipOrbit.evolveMode != OrbitUniversal.EvolveMode.KEPLERS_EQN)
        {
            Debug.LogError("Controller requires ship on-rails but spaceship is off-rails");
        }

        // assuming circular orbit for ship
        shipRadius = shipOrbit.GetApogee();

        shipOrbitPredictor = spaceship.GetComponentInChildren <OrbitPredictor>();
    }
Example #20
0
 // Use this for initialization
 void Start()
 {
     shipOrbit = spaceshipNBody.GetComponent <OrbitUniversal>();
     if (shipOrbit == null)
     {
         Debug.LogError("spaceship needs an OrbitUniversal");
     }
 }
 /// <summary>
 /// Do hand off from one center to a new center in the OrbitUniversal class.
 /// </summary>
 /// <param name="newObject"></param>
 /// <param name="oldObject"></param>
 public void OnNewInfluencer(NBody newObject, NBody oldObject)
 {
     if (keplerSeq != null)
     {
         orbitU = keplerSeq.GetCurrentOrbit();
     }
     orbitU.SetNewCenter(newObject);
     if (orbitPredictor != null)
     {
         orbitPredictor.SetCenterObject(newObject.gameObject);
     }
 }
Example #22
0
    // Use this for initialization
    void Start()
    {
        soiRenderer = GetComponent <LineRenderer>();
        soiRadius   = OrbitUtils.SoiRadius(planetBody, moonBody);

        OrbitUniversal orbitU = moonBody.GetComponent <OrbitUniversal>();

        if (orbitU != null)
        {
            inclination = (float)orbitU.inclination;
        }
    }
 /// <summary>
 /// New center. Update the Kepler depth and any children holding orbit predictors or segments
 /// </summary>
 /// <param name="orbitU"></param>
 private void NewCenter(OrbitUniversal orbitU)
 {
     GravityEngine.Instance().UpdateKeplerDepth(nbody, orbitU);
     foreach (OrbitPredictor op in gameObject.GetComponentsInChildren <OrbitPredictor>())
     {
         op.SetCenterObject(orbitU.centerNbody.gameObject);
     }
     foreach (OrbitSegment os in gameObject.GetComponentsInChildren <OrbitSegment>())
     {
         os.SetCenterObject(orbitU.centerNbody.gameObject);
     }
 }
    // Create a planet in orbit around center object with semi-major axis a
    public static GameObject CreatePlanetInOrbitUniversal(NBody center, float mass, float a)
    {
        // position will be trumped by orbit
        GameObject planet = CreateNBody(mass, new Vector3(1, 0, 0));

        OrbitUniversal orbitU = planet.AddComponent <OrbitUniversal>();

        orbitU.centerNbody = center;
        orbitU.SetNBody(planet.GetComponent <NBody>());
        orbitU.SetMajorAxisInspector(a);
        return(planet);
    }
Example #25
0
    private void DoTestForPhase(double fromPhase, double toPhase)
    {
        const float    mass        = 1000f;
        const bool     reverse     = false;
        GameObject     star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        NBody          starNbody   = star.GetComponent <NBody>();
        float          orbitRadius = 20f;
        GameObject     planet      = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 0f, orbitRadius);
        OrbitUniversal orbitU      = planet.GetComponent <OrbitUniversal>();

        orbitU.phase = fromPhase;
        orbitU.SetMajorAxisInspector(orbitRadius);

        orbitRadius = 30.0f;
        GameObject     planet2 = TestSetupUtils.CreatePlanetInOrbitUniversal(starNbody, 0f, orbitRadius);
        OrbitUniversal orbitU2 = planet2.GetComponent <OrbitUniversal>();

        orbitU2.phase = toPhase;
        orbitU2.SetMajorAxisInspector(orbitRadius);

        GravityEngine.Instance().UnitTestAwake();
        GravityEngine.Instance().AddBody(star);
        GravityEngine.Instance().AddBody(planet);
        GravityEngine.Instance().AddBody(planet2);
        GravityEngine.Instance().Setup();

        Debug.Log("Find transfers");
        OrbitData        fromOrbit = new OrbitData(orbitU);
        OrbitData        toOrbit   = new OrbitData(orbitU2);
        LambertUniversal lambertU  = new LambertUniversal(fromOrbit, toOrbit, true);

        Assert.AreNotEqual(lambertU, null);
        double time = 0.8f * lambertU.GetTMin();

        lambertU.ComputeXfer(reverse, false, 0, time);
        LambertBattin lambertB = new LambertBattin(fromOrbit, toOrbit);
        int           error    = lambertB.ComputeXfer(reverse, false, 0, time);

        Assert.AreEqual(error, 0);
        Assert.AreNotEqual(lambertB, null);
        Assert.AreNotEqual(lambertB.GetTransferVelocity(), null);
        Debug.LogFormat("initial velocity {0} vs {1}", lambertU.GetTransferVelocity(), lambertB.GetTransferVelocity());
        Debug.LogFormat("initial velocity mag {0} vs {1}",
                        lambertU.GetTransferVelocity().magnitude, lambertB.GetTransferVelocity().magnitude);
        Debug.LogFormat("final velocity {0} vs {1}", lambertU.GetFinalVelocity(), lambertB.GetFinalVelocity());
        Debug.LogFormat("final velocity mag {0} vs {1}",
                        lambertU.GetFinalVelocity().magnitude, lambertB.GetFinalVelocity().magnitude);
        // best can do for 180 degree case is E-2 accuracy on the magnitude. Not sure why...seems too big
        Assert.IsTrue(GEUnit.DoubleEqual(lambertU.GetTransferVelocity().magnitude,
                                         lambertB.GetTransferVelocity().magnitude,
                                         1E-2));
    }
Example #26
0
 /// <summary>
 /// Construct an orbit data routine from an existing orbit universal by copying the orbital elements
 /// </summary>
 /// <param name="orbitU"></param>
 public OrbitData(OrbitUniversal orbitU)
 {
     a           = (float)orbitU.GetMajorAxis();
     omega_lc    = (float)orbitU.omega_lc;
     omega_uc    = (float)orbitU.omega_uc;
     inclination = (float)orbitU.inclination;
     ecc         = (float)orbitU.eccentricity;
     phase       = (float)orbitU.phase;
     nbody       = orbitU.GetNBody();
     centralMass = orbitU.centerNbody;
     mu          = GravityEngine.Instance().GetPhysicsMass(centralMass);
     period      = CalcPeriod();
 }
Example #27
0
 /// <summary>
 /// SetOrbit
 /// Determine orbit params from an attached orbit component (if Kepler) otherwise use the velocity to
 /// determine the orbit
 /// </summary>
 /// <param name="forNbody"></param>
 /// <param name="aroundNBody"></param>
 public void SetOrbit(NBody forNbody, NBody aroundNBody)
 {
     nbody       = forNbody;
     centralMass = aroundNBody;
     // is this a Kepler body
     if (nbody.engineRef.fixedBody != null)
     {
         OrbitEllipse orbitEllipse = nbody.GetComponent <OrbitEllipse>();
         if (orbitEllipse != null)
         {
             ecc         = orbitEllipse.ecc;
             a           = orbitEllipse.a * GravityEngine.Instance().GetLengthScale();
             omega_lc    = orbitEllipse.omega_lc;
             omega_uc    = orbitEllipse.omega_uc;
             inclination = orbitEllipse.inclination;
             mu          = GravityEngine.Instance().GetPhysicsMass(aroundNBody);
             period      = CalcPeriod();
             // TODO:  tau
             phase = orbitEllipse.phase;
             return;
         }
         OrbitUniversal orbitU = nbody.GetComponent <OrbitUniversal>();
         if (orbitU != null)
         {
             ecc = (float)orbitU.eccentricity;
             // Might need to make a > 0 for hyperbola since OrbitData got this wrong??
             a           = (float)orbitU.p / (1 - ecc * ecc);
             omega_lc    = (float)orbitU.omega_lc;
             omega_uc    = (float)orbitU.omega_uc;
             inclination = (float)orbitU.inclination;
             mu          = GravityEngine.Instance().GetPhysicsMass(aroundNBody);
             period      = CalcPeriod();
             // TODO:  tau
             phase = (float)orbitU.phase;
             return;
         }
         OrbitHyper orbitHyper = nbody.GetComponent <OrbitHyper>();
         if (orbitHyper != null)
         {
             ecc         = orbitHyper.ecc;
             perihelion  = orbitHyper.perihelion * GravityEngine.Instance().GetLengthScale();
             omega_lc    = orbitHyper.omega_lc;
             omega_uc    = orbitHyper.omega_uc;
             inclination = orbitHyper.inclination;
             // need phase, tau, period
             return;
         }
     }
     SetOrbitForVelocity(forNbody, aroundNBody);
 }
    // Use this for initialization
    void Start()
    {
        ge = GravityEngine.Instance();

        shipAngle = shipAngleDeg * Mathf.Deg2Rad;
        soiAngle  = soiAngleDeg * Mathf.Deg2Rad;

        // disable maneuver predictor until things settle (can get Invalid local AABB otherwise)
        SetOrbitDisplays(false);

        // mass scaling will cancel in this ratio
        soiRadius = OrbitUtils.SoiRadius(planet, moonBody);
        toMoonOrbit.hyperDisplayRadius = soiRadius;

        // TODO: allow moon to be OrbitUniversal as well.
        OrbitEllipse moonEllipse = moonBody.gameObject.GetComponent <OrbitEllipse>();

        moonRadius  = moonEllipse.a_scaled;
        targetPoint = new Vector3d(moonRadius, soiRadius, 0);

        float        inclination = 0;
        OrbitEllipse shipEllipse = spaceship.gameObject.GetComponent <OrbitEllipse>();

        if (shipEllipse != null)
        {
            shipRadius  = shipEllipse.a_scaled;
            inclination = shipEllipse.inclination;
        }
        else
        {
            OrbitUniversal orbitU = spaceship.GetComponent <OrbitUniversal>();
            if (orbitU != null)
            {
                // assuming circular orbit
                shipRadius  = (float)orbitU.GetApogee();
                inclination = (float)orbitU.inclination;
            }
        }

        // check moon and ship orbit are co-planar
        if (Mathf.Abs(inclination - moonEllipse.inclination) > 1E-3)
        {
            Debug.LogWarning("Ship inclination and moon inclination are not equal.");
        }

        startPoint = new Vector3d(0, -shipRadius, 0);
        UpdateSoiPosition();
        UpdateStartPosition();
    }
    void Start()
    {
        // calculate positions for the LineRenderer (cannot assume Editor script has been invoked to do this)
        GameObject parent = transform.parent.gameObject;

        if (parent != null)
        {
            EllipseBase ellipseBase = parent.GetComponent <EllipseBase>();
            if (ellipseBase != null)
            {
                centerNBody = ellipseBase.centerObject.GetComponent <NBody>();
                orbitP      = ellipseBase;
            }
            else
            {
                OrbitUniversal orbitU = parent.GetComponent <OrbitUniversal>();
                if (orbitU != null)
                {
                    centerNBody = orbitU.GetCenterNBody();
                    orbitP      = orbitU;
                }
                else
                {
                    OrbitHyper orbitHyper = parent.GetComponent <OrbitHyper>();

                    if (orbitHyper != null)
                    {
                        centerNBody = orbitHyper.centerObject.GetComponent <NBody>();
                        orbitP      = orbitHyper;
                    }
                    else
                    {
                        Debug.LogWarning("Parent object must have OrbitEllipse or OrbitHyper - cannot compute positions for line");
                    }
                }
            }
        }
        else
        {
            Debug.LogWarning("No parent object - cannot compute positions for line");
        }
        if (centerNBody == null)
        {
            Debug.LogError("Parent must have an NBody");
        }
        lineR = GetComponent <LineRenderer>();
        lineR.positionCount = numPoints;
    }
Example #30
0
    /// <summary>
    /// Determine if and how many objects are orbital parents.
    /// e.g. Sun = 0, planet=1, moon=2
    /// </summary>
    public void CalcOrbitDepth()
    {
        GameObject go = gameObject;

        do
        {
            OrbitEllipse ellipse = go.GetComponent <OrbitEllipse>();
            if (ellipse != null)
            {
                go = ellipse.centerObject;
                orbitDepth++;
                continue;
            }
            OrbitUniversal orbitU = go.GetComponent <OrbitUniversal>();
            if (orbitU != null)
            {
                go = orbitU.centerNbody.gameObject;
                orbitDepth++;
                continue;
            }
            OrbitHyper hyper = go.GetComponent <OrbitHyper>();
            if (hyper != null)
            {
                go = hyper.centerObject;
                orbitDepth++;
                continue;
            }
            if (go.transform.parent != null)
            {
                BinaryPair bp = go.transform.parent.gameObject.GetComponent <BinaryPair>();
                if (bp != null)
                {
                    go = bp.gameObject;
                    orbitDepth++;
                    continue;
                }
                // If parent has an NBody, then it's an orbital parent, since need to inherit its velocity
                NBody nbody_parent = go.transform.parent.gameObject.GetComponent <NBody>();
                if (nbody_parent != null)
                {
                    go = nbody_parent.gameObject;
                    orbitDepth++;
                    continue;
                }
            }
            go = null;
        } while (go != null);
    }