예제 #1
0
    public void HyperOmegaLNoInclNoPhase()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float orbitPeri  = 15f;
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.ecc        = 1.4f;
        orbitHyper.perihelion = orbitPeri;
        orbitHyper.r_initial  = orbitPeri;

        // Try some values of om
        float[] omegaValues = { 30f, 45f, 60f, 90f, 135f, 180f, 0f };
        foreach (float omega in omegaValues)
        {
            orbitHyper.omega_lc = omega;
            orbitHyper.Init();
            orbitHyper.InitNBody(1f, 1f);
            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("omega = " + omega + " od.omega_l=" + od.omega_lc);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqual(omega, od.omega_lc, 0.05));
            TestRV(od, planet, star);
        }
    }
 /// <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());
     }
 }
예제 #3
0
    public void HyperOmegaUInclNoPhase()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.ecc         = 1.4f;
        orbitHyper.perihelion  = 20f;
        orbitHyper.r_initial   = 20f;
        orbitHyper.inclination = 35f;

        // Try some values of om
        float[] omegaValues = { 30f, 45f, 60f, 90f, 135f, 180f, 210f, 275f, 355f };
        foreach (float omega in omegaValues)
        {
            orbitHyper.omega_uc = omega;
            TestSetupUtils.SetupGravityEngine(star, planet);

            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("omega = " + omega + " od.omega_uc=" + od.omega_uc);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqualMod360(omega, od.omega_uc, 0.05));
        }
    }
예제 #4
0
    // Update is called once per frame
    void Update()
    {
        if (xferRequested)
        {
            return;
        }

        if (Input.GetKeyUp(KeyCode.T))
        {
            OrbitData od1 = new OrbitData();
            od1.SetOrbitForVelocity(orbit1, centerBody);
            OrbitData od2 = new OrbitData();
            od2.SetOrbitForVelocity(orbit2, centerBody);

            OrbitTransfer transfer = new CircularInclinationAndAN(od1, od2);

            // Update for as many markers as provided
            List <Maneuver> maneuvers = transfer.GetManeuvers();
            for (int i = 0; i < commonPointMarker.Length; i++)
            {
                commonPointMarker[i].transform.position = maneuvers[i].physPosition.ToVector3();
            }

            GravityEngine.instance.AddManeuvers(transfer.GetManeuvers());
            xferRequested = true;
        }
    }
예제 #5
0
    public void PhaseRetrogradeEllipse()
    {
        const float  mass         = 1000f;
        GameObject   star         = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float  orbitRadius  = 10f;
        GameObject   planet       = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse orbitEllipse = planet.GetComponent <OrbitEllipse>();

        orbitEllipse.ecc         = 0.4f;
        orbitEllipse.inclination = 180f;

        // Try some values of om
        float[] phaseValues = { 30f, 45f, 60f, 90f, 135f, 180f, 0f };
        foreach (float phase in phaseValues)
        {
            orbitEllipse.phase = phase;
            orbitEllipse.Init();
            orbitEllipse.ApplyScale(1f);
            orbitEllipse.InitNBody(1f, 1f);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("phase = " + phase + " od.phase=" + od.phase);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqual(phase, od.phase, 0.02));
            TestRV(od, planet, star, orbitRadius);
        }
    }
예제 #6
0
 // Update is called once per frame
 void Update()
 {
     if (Input.GetKeyUp(KeyCode.C))
     {
         OrbitData currentOrbit = new OrbitData();
         currentOrbit.SetOrbitForVelocity(shipNbody, centerNbody);
         // circularize the orbit
         OrbitTransfer t = new CircularizeXfer(currentOrbit);
         // If this is a ship with a Kepler sequence take the maneuvers and add them as KeplerSequence elements
         // This allows the transfer to be time-reversible if the whole scene is on rails.
         if (keplerSeq != null)
         {
             keplerSeq.AddManeuvers(t.GetManeuvers());
         }
         else
         {
             // Nbody evolution (or plain onRails w/o KeplerSequence) use maneuvers
             GravityEngine.Instance().AddManeuver(t.GetManeuvers()[0]);
         }
     }
     else if (Input.GetKeyDown(KeyCode.R))
     {
         // return orbit to GravityEngine control (go Off-Rails)
         if (keplerSeq != null)
         {
             keplerSeq.AppendReturnToGE(GravityEngine.Instance().GetPhysicalTime(), shipNbody);
         }
     }
     else if (Input.GetKeyDown(KeyCode.W))
     {
         // return orbit to GravityEngine control (go Off-Rails)
         GravityEngine.Instance().ApplyImpulse(shipNbody, Vector3.up);
     }
 }
예제 #7
0
    public void HyperInclOmega()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.r_initial = 20f;
        orbitHyper.ecc       = 2.5f;

        // Try some values of phase
        float[] inclinationValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f };
        float[] omegaUValues      = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        foreach (float incl in inclinationValues)
        {
            foreach (float omegau in omegaUValues)
            {
                orbitHyper.inclination = incl;
                orbitHyper.omega_uc    = omegau;
                orbitHyper.Init();
                orbitHyper.InitNBody(1f, 1f);
                orbitHyper.Log("Initial circle:");
                OrbitData od = new OrbitData();
                od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
                Debug.Log("incl = " + incl + " od.incl=" + od.inclination);
                Debug.Log("omegaU = " + omegau + " od.omegau=" + od.omega_uc);
                TestRV(od, planet, star);
            }
        }
    }
예제 #8
0
    public void HyperInclination()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.ecc       = 1.4f;
        orbitHyper.r_initial = 20f;

        // Try some values of om
        float[] inclValues = { 30f, 45f, 60f, 90f, 135f, 180f, 0f };
        foreach (float incl in inclValues)
        {
            orbitHyper.inclination = incl;
            TestSetupUtils.SetupGravityEngine(star, planet);

            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("incl = " + incl + " od.incl=" + od.inclination);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqual(incl, od.inclination, 0.02));
        }
    }
예제 #9
0
    public void HyperPhaseNoIncl()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float orbitPeri  = 15f;
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.ecc        = 1.4f;
        orbitHyper.perihelion = orbitPeri;
        orbitHyper.r_initial  = orbitPeri;

        // Try some values of om
        float[] rinit_values = { orbitPeri, orbitPeri + 2f, orbitPeri + 5f, orbitPeri + 10f, orbitPeri + 20f };
        foreach (float rinit in rinit_values)
        {
            orbitHyper.r_initial = rinit;
            TestSetupUtils.SetupGravityEngine(star, planet);

            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("rinit = " + rinit + " od.r_initial=" + od.r_initial);
            // Need a bit of leeway at 0 with error
            TestRV(od, planet, star);
        }
    }
    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));
        }
    }
예제 #11
0
    public void OmegasEllipseInclination()
    {
        const float  mass         = 1000f;
        GameObject   star         = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float  orbitRadius  = 10f;
        GameObject   planet       = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse orbitEllipse = planet.GetComponent <OrbitEllipse>();

        orbitEllipse.InitNBody(1f, 1f);

        orbitEllipse.inclination = 35f;
        orbitEllipse.ecc         = 0.25f;
        orbitEllipse.Init();
        orbitEllipse.ApplyScale(1f);
        orbitEllipse.InitNBody(1f, 1f);

        // Try some values of om
        float[] omegaValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f };
        foreach (float omega in omegaValues)
        {
            orbitEllipse.omega_uc = omega;
            orbitEllipse.Init();
            orbitEllipse.InitNBody(1f, 1f);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            TestRV(od, planet, star, orbitRadius);
        }
    }
예제 #12
0
    public void OmegaULEllipseInclined()
    {
        const float  mass         = 1000f;
        GameObject   star         = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float  orbitRadius  = 10f;
        GameObject   planet       = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse orbitEllipse = planet.GetComponent <OrbitEllipse>();

        orbitEllipse.InitNBody(1f, 1f);

        orbitEllipse.inclination = 30f;
        orbitEllipse.ecc         = 0.2f;
        orbitEllipse.Init();
        orbitEllipse.ApplyScale(1f);
        orbitEllipse.InitNBody(1f, 1f);

        // Try some values of om
        float[] omegaUValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 310f };
        float[] omegaLValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 310f };
        foreach (float omegaU in omegaUValues)
        {
            foreach (float omegaL in omegaLValues)
            {
                orbitEllipse.omega_uc = omegaU;
                orbitEllipse.omega_lc = omegaL;
                TestSetupUtils.SetupGravityEngine(star, planet);

                orbitEllipse.Log("OmegaUL inclined:");
                OrbitData od = new OrbitData();
                od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
                Debug.Log("omegaU = " + omegaU + "omegaL = " + omegaL + " OD:=" + od.LogString());
                TestRV(od, planet, star, orbitRadius);
            }
        }
    }
 // Update is called once per frame
 void Update()
 {
     if (Input.GetKeyUp(KeyCode.H))
     {
         OrbitData shipOrbit = new OrbitData();
         shipOrbit.SetOrbitForVelocity(shipNbody, centerNbody);
         OrbitData targetOrbit = new OrbitData();
         targetOrbit.SetOrbitForVelocity(targetNbody, centerNbody);
         // determine the transfer
         orbitTransfer = new HohmannXfer(shipOrbit, targetOrbit, rendezvous);
         // If this is a ship with a Kepler sequence take the maneuvers and add them as KeplerSequence elements
         // This allows the transfer to be time-reversible if the whole scene is on rails.
         if (keplerSeq != null)
         {
             keplerSeq.AddManeuvers(orbitTransfer.GetManeuvers());
         }
         else
         {
             // Nbody evolution (or plain onRails w/o KeplerSequence) use maneuvers
             foreach (Maneuver m in orbitTransfer.GetManeuvers())
             {
                 GravityEngine.Instance().AddManeuver(m);
             }
         }
         // Maneuver markers
         if (markerPrefab != null)
         {
             foreach (Maneuver m in orbitTransfer.GetManeuvers())
             {
                 // set maneuver position marker
                 GameObject marker = Instantiate(markerPrefab, centerNbody.gameObject.transform, true);
                 marker.transform.position = m.physPosition.ToVector3();
                 markers.Add(marker);
                 m.onExecuted = RemoveMarker;
             }
         }
     }
     if (Input.GetKeyUp(KeyCode.C))
     {
         // clear maneuvers
         GravityEngine.Instance().ClearManeuvers();
         // delete on rails maneuvers
         if (keplerSeq != null)
         {
             keplerSeq.RemoveManeuvers(orbitTransfer.GetManeuvers());
         }
         foreach (GameObject marker in markers)
         {
             Destroy(marker);
         }
         markers.Clear();
     }
     // optionally report time to next maneuver
     // for now just do first maneuver
     if ((timeToManeuverText != null) && (orbitTransfer != null))
     {
         double time = orbitTransfer.GetManeuvers()[0].worldTime - GravityEngine.Instance().GetPhysicalTime();
         timeToManeuverText.text = string.Format("Time to Next Maneuver = {0:0.00}", time);
     }
 }
예제 #14
0
    public void CirclePhaseOmegaInclined()
    {
        const float  mass         = 1000f;
        GameObject   star         = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float  orbitRadius  = 10f;
        GameObject   planet       = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse orbitEllipse = planet.GetComponent <OrbitEllipse>();

        orbitEllipse.inclination = 20f;

        // Try some values of phase
        // omegaU for a circle does not make sense, no axis to relate it to.
        float[] phaseValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        foreach (float phase in phaseValues)
        {
            orbitEllipse.phase    = phase;
            orbitEllipse.omega_uc = 0;
            TestSetupUtils.SetupGravityEngine(star, planet);
            Debug.LogFormat("Test for phase={0} omegau={1}", phase, 0);
            orbitEllipse.Log("Initial circle:");
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("OrbitData: " + od.LogString());
            Assert.IsTrue(FloatEqualMod360(phase, od.phase, 0.05));
            Assert.IsTrue(FloatEqualMod360(0, od.omega_uc, 0.05));
            TestRV(od, planet, star, orbitRadius);
        }
    }
예제 #15
0
    public void PhaseNoInclinationEllipse()
    {
        const float  mass         = 1000f;
        GameObject   star         = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float  orbitRadius  = 20f;
        GameObject   planet       = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse orbitEllipse = planet.GetComponent <OrbitEllipse>();

        orbitEllipse.ecc = 0.2f;

        // Try some values of om
        float[] phaseValues = { 30f, 45f, 60f, 90f, 135f, 180f, 225f, 270f, 325f, 0f };
        foreach (float phase in phaseValues)
        {
            orbitEllipse.phase = phase;
            TestSetupUtils.SetupGravityEngine(star, planet);

            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            orbitEllipse.Log("PhaseNoInclinationEllipse:");
            Debug.Log(od.LogString());
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqualMod360(phase, od.phase, 0.02));
            Assert.IsTrue(FloatEqualMod360(0f, od.omega_lc, 0.02));
            Assert.IsTrue(FloatEqualMod360(0f, od.omega_uc, 0.02));
            TestRV(od, planet, star, orbitRadius);
        }
    }
예제 #16
0
    // Check eccentricity and inclination
    public void EllipseInclination()
    {
        const float  mass         = 1000f;
        GameObject   star         = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float  orbitRadius  = 10f;
        GameObject   planet       = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse orbitEllipse = planet.GetComponent <OrbitEllipse>();

        float eccentricity = 0.3f;

        orbitEllipse.ecc = eccentricity;
        TestSetupUtils.SetupGravityEngine(star, planet);

        // take the velocity and check
        OrbitData orbitData = new OrbitData();

        orbitData.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
        Assert.IsTrue(FloatEqual(orbitRadius, orbitData.a));
        Assert.IsTrue(FloatEqual(eccentricity, orbitData.ecc));

        // Try some values of inclination
        float[] inclinationValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f };
        foreach (float inc in inclinationValues)
        {
            Debug.Log("====EclipseInclination====    inc=" + inc);
            orbitEllipse.inclination = inc;
            TestSetupUtils.SetupGravityEngine(star, planet);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("TEST: incl = " + orbitEllipse.inclination + " ecc=" + orbitEllipse.ecc + " od:" + od.LogString());
            Assert.IsTrue(FloatEqual(inc, od.inclination));
            TestRV(od, planet, star, orbitRadius);
        }
    }
예제 #17
0
    public void CirclePhaseOmegaInclined()
    {
        const float  mass         = 1000f;
        GameObject   star         = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float  orbitRadius  = 10f;
        GameObject   planet       = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse orbitEllipse = planet.GetComponent <OrbitEllipse>();

        orbitEllipse.inclination = 20f;

        // Try some values of phase
        float[] phaseValues  = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        float[] omegaUValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        foreach (float phase in phaseValues)
        {
            foreach (float omegau in omegaUValues)
            {
                orbitEllipse.phase    = phase;
                orbitEllipse.omega_uc = omegau;
                orbitEllipse.Init();
                orbitEllipse.ApplyScale(1f);
                orbitEllipse.InitNBody(1f, 1f);
                orbitEllipse.Log("Initial circle:");
                OrbitData od = new OrbitData();
                od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
                Debug.Log("TEST: phase = " + phase + " od.phase=" + od.phase +
                          " omegaU = " + omegau + " od.omegau=" + od.omega_uc);
                TestRV(od, planet, star, orbitRadius);
            }
        }
    }
 /// <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());
     }
 }
예제 #19
0
    public void OmegaUNoInclination()
    {
        const float  mass         = 1000f;
        GameObject   star         = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float  orbitRadius  = 10f;
        GameObject   planet       = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse orbitEllipse = planet.GetComponent <OrbitEllipse>();

        orbitEllipse.InitNBody(1f, 1f);

        orbitEllipse.ecc = 0.1f;

        // Try some values of om
        float[] omegaValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        foreach (float omega in omegaValues)
        {
            orbitEllipse.omega_uc = omega;
            orbitEllipse.Init();
            orbitEllipse.ApplyScale(1f);
            orbitEllipse.InitNBody(1f, 1f);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("omega = " + omega + " od.omega_lc=" + od.omega_lc);
            Assert.IsTrue(FloatEqual(omega, od.omega_lc, 0.4));
        }
    }
예제 #20
0
    private void ComputeTransfer()
    {
        shipData             = new OrbitData();
        shipData.centralMass = starNBody;
        shipData.SetOrbitForVelocity(spaceshipNBody, starNBody);

        targetData       = new OrbitData(targetEllipses[selectedEllipse].orbitData);
        targetData.phase = targetEllipses[selectedEllipse].manueverPhase;

        // compute the min energy path (this will be in the short path direction)
        lambertU = new LambertUniversal(shipData, targetData, shortPath);

        // apply any time of flight change
        transferTime = tflightFactor * lambertU.GetTMin();
        bool reverse = !shortPath;

        // recompute with updated time
        const bool df    = false;
        const int  nrev  = 0;
        int        error = lambertU.ComputeXfer(reverse, df, nrev, transferTime);

        if (error != 0)
        {
            Debug.LogWarning("Lambert failed to find solution.");
            maneuverSegment.gameObject.SetActive(false);
            return;
        }
        Vector3 vel = lambertU.GetTransferVelocity();

        maneuverOrbitPredictor.SetVelocity(vel);
        maneuverSegment.SetVelocity(vel);
        maneuverOrbitPredictor.gameObject.SetActive(true);
        maneuverSegment.gameObject.SetActive(true);
    }
예제 #21
0
    private void ComputeTransfer()
    {
        Vector3d  r_from    = GravityEngine.Instance().GetPositionDoubleV3(spaceship);
        Vector3d  r_to      = new Vector3d(targetPoint.transform.position);
        OrbitData shipOrbit = new OrbitData();

        shipOrbit.SetOrbitForVelocity(spaceship, centralMass);

        // compute the min energy path (this will be in the short path direction)
        lambertU = new LambertUniversal(shipOrbit, r_from, r_to, shortPath);

        // apply any time of flight change
        double t_flight = tflightFactor * lambertU.GetTMin();
        bool   reverse  = !shortPath;

        const bool df    = false;
        const int  nrev  = 0;
        int        error = lambertU.ComputeXfer(reverse, df, nrev, t_flight);

        if (error != 0)
        {
            Debug.LogWarning("Lambert failed to find solution.");
            maneuverSegment.gameObject.SetActive(false);
            return;
        }
        Vector3 dv = lambertU.GetTransferVelocity() - GravityEngine.Instance().GetVelocity(spaceship);

        dvText.text = string.Format("dV = {0:00.00}    Time={1:00.00}", dv.magnitude, t_flight);
        maneuverOrbitPredictor.SetVelocity(lambertU.GetTransferVelocity());
        maneuverSegment.gameObject.SetActive(true);
        maneuverSegment.SetDestination(r_to.ToVector3());
        maneuverSegment.SetVelocity(lambertU.GetTransferVelocity());
    }
예제 #22
0
    public OrbitTransfer Circularize()
    {
        OrbitData shipOrbit = new OrbitData();

        shipOrbit.SetOrbitForVelocity(ship, centralMass);
        return(new CircularizeXfer(shipOrbit));
    }
예제 #23
0
    // Create an NBody and check it's mass
    public void CircleA()
    {
        const float mass        = 1000f;
        GameObject  star        = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float orbitRadius = 10f;
        GameObject  planet      = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);

        // confirm planet is in correct location
        Assert.AreEqual(Vector3.Distance(planet.transform.position, new Vector3(10f, 0f, 0)), 0);
        // take the velocity and check
        OrbitData orbitData = new OrbitData();

        orbitData.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
        Assert.AreEqual(orbitData.a, orbitRadius);
        Assert.AreEqual(orbitData.omega_uc, 0f);
    }
예제 #24
0
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            fromPhase += PHASE_PER_KEY;
        }
        else if (Input.GetKey(KeyCode.S))
        {
            fromPhase -= PHASE_PER_KEY;
        }
        else if (Input.GetKey(KeyCode.Q))
        {
            toPhase += PHASE_PER_KEY;
        }
        else if (Input.GetKey(KeyCode.W))
        {
            toPhase -= PHASE_PER_KEY;
        }
        fromPhase = NUtils.DegreesMod360(fromPhase);
        toPhase   = NUtils.DegreesMod360(toPhase);
        SetMarkers();

        shipOrbitData.SetOrbitForVelocity(spaceshipNBody, shipOrbit.centerNbody);

        // Determine TOF
        Vector3d from = new Vector3d(shipOrbitData.GetPhysicsPositionforEllipse(fromPhase));
        Vector3d to   = new Vector3d(shipOrbitData.GetPhysicsPositionforEllipse(toPhase));

        Vector3d shipPos = GravityEngine.instance.GetPositionDoubleV3(spaceshipNBody);
        double   tPeri   = shipOrbit.TimeOfFlight(shipPos, new Vector3d(shipOrbitData.GetPhysicsPositionforEllipse(0f)));
        double   tApo    = shipOrbit.TimeOfFlight(shipPos, new Vector3d(shipOrbitData.GetPhysicsPositionforEllipse(180f)));
        double   tof     = shipOrbit.TimeOfFlight(from, to);

        // Scale to game time
        //tApo = GravityScaler.ScaleToGameSeconds((float) tApo);
        //tPeri = GravityScaler.ScaleToGameSeconds((float)tPeri);
        //tof = GravityScaler.ScaleToGameSeconds((float)tof);
        //tofText.text = string.Format("Time of Flight = {0:#.#}\nTime to Apoapsis = {1:#.#}\nTime to Periapsis = {2:#.#}\ntau = {3}",
        //    tof, tApo, tPeri, shipOrbitData.tau);
        GravityScaler.Units units = GravityEngine.instance.units;
        tofText.text = string.Format("Time of Flight = {0}\nTime to Apoapsis = {1}\nTime to Periapsis = {2}\ntau = {3}",
                                     GravityScaler.GetWorldTimeFormatted(tof, units),
                                     GravityScaler.GetWorldTimeFormatted(tApo, units),
                                     GravityScaler.GetWorldTimeFormatted(tPeri, units),
                                     GravityScaler.GetWorldTimeFormatted(shipOrbitData.tau, units));
    }
    // 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);
            }
        }
    }
예제 #26
0
    public void HyperBasic()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        // Try some values of om
        float[] eccValues = { 1.1f, 1.3f, 2f, 2.2f, 3f, 10f };
        foreach (float ecc in eccValues)
        {
            orbitHyper.ecc = ecc;
            orbitHyper.Init();
            orbitHyper.InitNBody(1f, 1f);
            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("ecc = " + ecc + " od.ecc=" + od.ecc);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqual(ecc, od.ecc, 0.02));
        }
    }
예제 #27
0
    public void HyperInclOmega()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.r_initial = 20f;
        orbitHyper.ecc       = 2.5f;

        // Try some values of phase (incl=0 covered by another test)
        float[] inclinationValues = { 30f, 45f, 60f, 90f, 135f, 180f };
        float[] omegaUValues      = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        foreach (float incl in inclinationValues)
        {
            foreach (float omegau in omegaUValues)
            {
                orbitHyper.inclination = incl;
                orbitHyper.omega_uc    = omegau;
                TestSetupUtils.SetupGravityEngine(star, planet);
                Debug.LogFormat("Test for i={0} omegaU={1}", incl, omegau);
                orbitHyper.Log("Initial circle:");
                OrbitData od = new OrbitData();
                od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
                Debug.Log("OrbitData: " + od.LogString());
                TestRV(od, planet, star);
                Debug.Log("incl = " + incl + " od.incl=" + od.inclination);
                Debug.Log("omegaU = " + omegau + " od.omegau=" + od.omega_uc + " od.omega_lc=" + od.omega_lc);
                if (incl != 180f)
                {
                    // 180 comes back as omegaL = omegaU = 180, but TestRV is ok
                    Assert.IsTrue(FloatEqual(incl, od.inclination, 0.02));
                    Assert.IsTrue(FloatEqualMod360(omegau, od.omega_uc, 0.02));
                }
            }
        }
    }
예제 #28
0
 // Update is called once per frame
 void Update()
 {
     if (initOk)
     {
         // velocities not normally updated in NBody (to reduce CPU). Need to ask
         // object to update its velocity from Gravity Engine if engine is running
         if (GravityEngine.instance.GetEvolve())
         {
             nbody.UpdateVelocity();
         }
         orbitData.SetOrbitForVelocity(nbody, aroundNBody);
         // Is the resulting orbit and ellipse or hyperbola?
         if (orbitData.ecc < 1f)
         {
             ellipseBase.InitFromOrbitData(orbitData);
             lineR.SetPositions(ellipseBase.OrbitPositions(numPoints));
         }
         else
         {
             orbitHyper.InitFromOrbitData(orbitData);
             lineR.SetPositions(orbitHyper.OrbitPositions(numPoints));
         }
     }
 }
예제 #29
0
    //============================================================================================
    // Console commands: If there is a GEConsole in the scene, these commands will be available
    //============================================================================================

    // In-class console method
    // Quick and Dirty implementation for testing LambertUniversal code.

    private string LambertUniversal(float time)
    {
        OrbitData shipData = new OrbitData();

        shipData.SetOrbitForVelocity(spaceshipNBody, starNBody);

        OrbitData targetData = targetEllipses[selectedEllipse].orbitData;

        targetData.phase = targetEllipses[selectedEllipse].manueverPhase;

        // get time and try universal
        LambertUniversal lu      = new LambertUniversal(shipData, targetData, true);
        const bool       reverse = false;
        const bool       df      = false;
        const int        nrev    = 0;
        int error = lu.ComputeXfer(reverse, df, nrev, time);

        if (error != 0)
        {
            return(string.Format("Error: LambertUniversal rc=" + error));
        }
        spaceshipNBody.vel_phys = lu.GetTransferVelocity();
        return(string.Format("time={0}  univ={1}", time, lu.GetTransferVelocity()));
    }
    /// <summary>
    /// Computes the transfer with the moon on the +X axis without accounting for the moon motion during
    /// transit. (That is accounted for in the ExecuteTransfer routine).
    ///
    /// This allows a co-rotating visualization of the orbit.
    /// </summary>
    /// <returns></returns>
    private Vector3 ComputeTransfer()
    {
        OrbitData shipOrbit = new OrbitData();

        shipOrbit.SetOrbitForVelocity(spaceship, planet);

        // compute the min energy path (this will be in the short path direction)
        lambertU = new LambertUniversal(shipOrbit, startPoint, targetPoint, shortPath);

        // apply any time of flight change
        double t_flight = tflightFactor * lambertU.GetTMin();
        bool   reverse  = !shortPath;

        const bool df    = false;
        const int  nrev  = 0;
        int        error = lambertU.ComputeXfer(reverse, df, nrev, t_flight);

        if (error != 0)
        {
            Debug.LogWarning("Lambert failed to find solution.");
            aroundMoonSegment.gameObject.SetActive(false);
            return(Vector3.zero);
        }
        // Check Lambert is going in the correct direction
        Vector3 shipOrbitAxis = Vector3.Cross(ge.GetVelocity(spaceship), ge.GetPhysicsPosition(spaceship)).normalized;
        Vector3 tliOrbitAxis  = Vector3.Cross(lambertU.GetTransferVelocity(), startPoint.ToVector3());

        if (Vector3.Dot(shipOrbitAxis, tliOrbitAxis) < 0)
        {
            error = lambertU.ComputeXfer(!reverse, df, nrev, t_flight);
            if (error != 0)
            {
                Debug.LogWarning("Lambert failed to find solution for reverse path. error=" + error);
                return(Vector3.zero);
            }
        }

        Vector3 tliVelocity = lambertU.GetTransferVelocity();

        toMoonOrbit.SetVelocity(tliVelocity);
        toMoonSegment.SetVelocity(tliVelocity);
        aroundMoonSegment.gameObject.SetActive(true);

        // Set velocity for orbit around moon
        Vector3 soiEnterVel = lambertU.GetFinalVelocity();

        aroundMoonSegment.SetVelocity(soiEnterVel);

        // update shipEnterSOI object
        ge.UpdatePositionAndVelocity(shipEnterSOI, targetPoint.ToVector3(), soiEnterVel);

        // Find the orbit around the moon. By using the mirror position we're assuming it's
        // a hyperbola (since there is no course correction at SOI this is true).
        // (Moon is in correct position for these calcs so can use world positions, relativePos=false)
        Vector3d soiEnterV = new Vector3d(lambertU.GetFinalVelocity());

        OrbitUtils.OrbitElements oe = OrbitUtils.RVtoCOE(targetPoint, soiEnterV, moonBody, false);
        Vector3d soiExitR           = new Vector3d();
        Vector3d soiExitV           = new Vector3d();

        OrbitUtils.COEtoRVMirror(oe, moonBody, ref soiExitR, ref soiExitV, false);
        // Set position and vel for exit ship, so exit orbit predictor can run. Moon offset/vel already added.
        ge.SetPositionDoubleV3(shipExitSOI, soiExitR);
        ge.SetVelocityDoubleV3(shipExitSOI, soiExitV);
        aroundMoonSegment.UpdateOrbit();
        return(tliVelocity);
    }