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));
    }
    // Check eccentricity and inclination
    public void RVtoCOEtoRV()
    {
        GameObject star = TestSetupUtils.CreateNBody(10, new Vector3(0, 0, 0));

        TestSetupUtils.SetupGravityEngine(star, null);
        NBody starBody = star.GetComponent <NBody>();

        RVpair[] rvp =
        {
            new RVpair(10,   0, 0,  0,   1, 0),
            new RVpair(10,   0, 0,  0,  10, 0),
            new RVpair(10,   0, 0,  0,  -1, 0),
            new RVpair(10,   0, 0,  0, -10, 0),
            new RVpair(-10, 10, 0, -4,   3, 0),
            new RVpair(-10, 10, 0,  4,  -3, 0)
        };

        for (int i = 0; i < rvp.Length; i++)
        {
            OrbitUtils.OrbitElements oe = OrbitUtils.RVtoCOE(rvp[i].r, rvp[i].v, starBody, false);
            Vector3d r1 = new Vector3d();
            Vector3d v1 = new Vector3d();
            OrbitUtils.COEtoRV(oe, starBody, ref r1, ref v1, false);

            Debug.LogFormat("i={0} r_in={1} r_out={2}\n v_in={3} v_out={4}\n oe: {5}",
                            i, rvp[i].r, r1, rvp[i].v, v1, oe);
            Assert.IsTrue(GEUnit.Vec3dEqual(rvp[i].r, r1, small));
            Assert.IsTrue(GEUnit.Vec3dEqual(rvp[i].v, v1, small));
        }
    }
    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));
        }
    }
示例#6
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));
    }
    // Check eccentricity and inclination
    public void EccentricityInclTest()
    {
        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>();

        float eccentricity = 0.3f;

        // MUST reset the scale after ecc is changed, since -> p
        orbitU.eccentricity = eccentricity;
        orbitU.SetMajorAxisInspector(orbitRadius);
        TestSetupUtils.SetupGravityEngine(star, planet);

        // Try some values of inclination and ecc
        float[] eccValues         = { 0f, .1f, .2f, 0.5f, 0.9f };
        float[] inclinationValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f };

        foreach (float inc in inclinationValues)
        {
            foreach (float ecc in eccValues)
            {
                Debug.Log("====EccentricityInclTest====    ecc=" + ecc + " incl = " + inc);
                orbitU.inclination  = inc;
                orbitU.eccentricity = ecc;
                orbitU.SetMajorAxisInspector(orbitRadius);      // can only use for ellipses
                TestSetupUtils.SetupGravityEngine(star, planet);
                OrbitData od = new OrbitData();
                od.SetOrbitForVelocity(planet.GetComponent <NBody>(), starNbody);
                Debug.Log("TEST: incl = " + orbitU.inclination + " ecc=" + orbitU.eccentricity + " od:" + od.LogString());
                Debug.LogFormat("Check ecc: {0} vs {1}", ecc, od.ecc);
                Assert.IsTrue(GEUnit.FloatEqual(ecc, od.ecc, 1E-3));
                float axis = (float)orbitU.GetMajorAxisInspector();
                Debug.LogFormat("Check axis: {0} vs {1}", axis, od.a);
                Assert.IsTrue(GEUnit.FloatEqual(axis, od.a, 1E-3));
                Debug.LogFormat("Check incl: {0} vs {1}", inc, od.inclination);
                Assert.IsTrue(GEUnit.FloatEqual(inc, od.inclination, 1E-3));
                // TestRV(od, planet, starNbody, orbitRadius);
            }
        }
    }