예제 #1
0
    /// <summary>
    /// Get the physics position for a specified phase for the ellipse defined by this OrbitData.
    /// </summary>
    /// <param name="phaseDeg"></param>
    /// <param name="relativePos">Return the position relative to the center object, otherwise absolute wolrd value.</param>
    /// <returns></returns>
    private Vector3 GetPhysicsPositionforEllipse(float phaseDeg, bool relativePos)
    {
        // C&P from EllipseBase - make common someday
        Quaternion ellipse_orientation = Quaternion.AngleAxis(omega_uc, GEConst.zunit) *
                                         Quaternion.AngleAxis(inclination, GEConst.xunit) *
                                         Quaternion.AngleAxis(omega_lc, GEConst.zunit);

        float phaseRad = phaseDeg * Mathf.Deg2Rad;
        // position object using true anomoly (angle from  focus)
        // a is really a_scaled when constructed from OrbitEllipse (so scaling has been done)
        float r = a * (1f - ecc * ecc) / (1f + ecc * Mathf.Cos(phaseRad));

        Vector3 pos = new Vector3(r * Mathf.Cos(phaseRad), r * Mathf.Sin(phaseRad), 0);
        // move from XY plane to the orbital plane
        Vector3 new_p = ellipse_orientation * pos;

        // orbit position is WRT center. Could be adding dynamically to an object in motion, so need current position.
        if (!relativePos)
        {
            Vector3 centerPos = Vector3.zero;
            // used by widgets - so need to get explcitly
            if (centralMass.engineRef != null)
            {
                centerPos = GravityEngine.Instance().GetPhysicsPosition(centralMass);
            }
            else
            {
                // setup - not yet added to GE
                centerPos = centralMass.initialPhysPosition;
            }
            new_p += centerPos;
        }
        return(new_p);
    }
예제 #2
0
    /// <summary>
    /// Calculate an array of orbit positions. Used by the OrbitPredictor, OrbitRenderer and Editor
    /// Gimzo to illustrate the hyperbola.
    /// </summary>
    /// <returns>The positions.</returns>
    /// <param name="numPoints">Number points.</param>
    public Vector3[] OrbitPositions(int numPoints, Vector3 centerPos, bool doSceneMapping)
    {
        CalculateRotation();

        Vector3[] emptyArray = { new Vector3(0, 0, 0), new Vector3(0, 0, 0) };
        // need to have a center to create positions.
        if (centerObject == null)
        {
            centerObject = transform.parent.gameObject;
            if (centerObject == null)
            {
                return(emptyArray);
            }
        }
        Vector3[]     points = new Vector3[numPoints];
        float         theta  = -1f * branchDisplayFactor * Mathf.PI;
        float         dTheta = 2f * Mathf.Abs(theta) / (float)numPoints;
        GravityEngine ge     = GravityEngine.Instance();

        for (int i = 0; i < numPoints; i++)
        {
            points[i] = PositionForThetaLeftBranch(theta, centerPos);
            if (NUtils.VectorNaN(points[i]))
            {
                points[i] = Vector3.zero;
            }
            else if (doSceneMapping && ge.mapToScene)
            {
                points[i] = ge.MapToScene(points[i]);
            }
            theta += dTheta;
        }
        return(points);
    }
 /// <summary>
 /// Get the corrected velocity for the lunar course correction.
 ///
 /// This routine should only be called from the correction done callback to ensure
 /// the computation has completed.
 /// </summary>
 /// <param name="v"></param>
 public void GetCorrectionVelocity(ref double[] v)
 {
     GravityEngine.Instance().GetVelocityDouble(spaceship, ref v);
     v[0] *= 1 + correctionFinal.correction;
     v[1] *= 1 + correctionFinal.correction;
     v[2] *= 1 + correctionFinal.correction;
 }
예제 #4
0
    /// <summary>
    /// Detach the active stage and enable the next one if present.
    /// </summary>
    private void DropStage()
    {
        // automatic staging when a preceeding stage runs out of fuel (engine still on)
        if (multiStage.activeStage < multiStage.numStages)
        {
            // release stage as child, add to GravityEngine
            GameObject spentStage = stages[multiStage.activeStage];
            spentStage.transform.parent = null;
            // add an NBody component,so GE can manage the stage
            NBody nbody = spentStage.AddComponent <NBody>();
            nbody.initialPos = spentStage.transform.position;
            nbody.vel        = shipNbody.vel;
            // Add an atmosphere model, copy general values from rocket and then adjust
            EarthAtmosphere stageAtmosphere = spentStage.AddComponent <EarthAtmosphere>();
            stageAtmosphere.InitFrom(atmosphere, nbody);
            stageAtmosphere.coeefDrag          = multiStage.coeefDrag[multiStage.activeStage];
            stageAtmosphere.crossSectionalArea = multiStage.crossSectionalArea[multiStage.activeStage];
            stageAtmosphere.inertialMassKg     = multiStage.massStageEmpty[multiStage.activeStage];

            GravityEngine.Instance().AddBody(spentStage);

            // activate the next stage
            multiStage.NextStage();
            multiStage.SetEngine(true);
            GravityEngine.Instance().TrajectoryRestart();
            DisplayManager.Instance().DisplayMessage("Staging");
        }
        else
        {
            multiStage.SetEngine(false);
            DisplayManager.Instance().DisplayMessage("Engine Shutdown");
        }
    }
예제 #5
0
    /// <summary>
    /// Detach the active stage and enable the next one if present.
    /// </summary>
    private void DropStage()
    {
        // automatic staging when a preceeding stage runs out of fuel (engine still on)
        if (multiStage.activeStage < multiStage.numStages)
        {
            // release stage as child, add to GravityEngine
            GameObject spentStage = stages[multiStage.activeStage];
            spentStage.transform.parent = null;
            spentStage.AddComponent <NBody>();
            NBody nbody = spentStage.GetComponent <NBody>();
            nbody.initialPos = spentStage.transform.position;
            nbody.vel        = shipNbody.vel;
            GravityEngine.Instance().AddBody(spentStage);

            // activate the next stage
            multiStage.NextStage();
            multiStage.SetEngine(true);
            GravityEngine.Instance().TrajectoryRestart();
            DisplayManager.Instance().DisplayMessage("Staging");
        }
        else
        {
            multiStage.SetEngine(false);
            DisplayManager.Instance().DisplayMessage("Engine Shutdown");
        }
    }
    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));
        }
    }
    // 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);
    }
 // 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);
     }
 }
예제 #9
0
    // Use this for initialization
    void Start()
    {
        if (GetComponent <NBody>() == null)
        {
            Debug.LogError("Component must be attached to object with an NBody attached.");
            return;
        }
        // Check all the prefabs have NBody and OrbitEllipse components
        foreach (GameObject g in planetPrefabs)
        {
            if (g.GetComponent <NBody>() == null)
            {
                Debug.LogError("Prefab " + g.name + " missing component NBody");
                return;
            }
            if (g.GetComponent <OrbitEllipse>() == null)
            {
                Debug.LogError("Prefab " + g.name + " missing component OrbitEllipse");
                return;
            }
        }

        for (int i = 0; i < numPlanets; i++)
        {
            AddBody();
        }
        GravityEngine.Instance().SetEvolve(true);

        ClearAllTrails();
    }
    /// <summary>
    /// Mark intercepts with the designated symbols and return a list of intercepts found
    /// for the predicted path of ship intersecting with the path of the target.
    /// </summary>
    ///
    /// <param name="ship">The ship</param>
    /// <param name="target">The target</param>
    ///
    /// <returns>The intercepts.</returns>
    private List <TrajectoryData.Intercept> MarkIntercepts(SpaceshipController shipCtrl, NBody target)
    {
        // delta distance is scale dependent. For now use an ugly *if*
        float deltaDistance = 1f;

        if (GravityEngine.Instance().units == GravityScaler.Units.ORBITAL)
        {
            deltaDistance = 20f;
        }
        const float deltaTime    = 2f;
        const float rendezvousDT = 1f;

        trajIntercepts.spaceship = shipCtrl.GetTrajectory();
        Trajectory trajectory = target.GetComponentInChildren <Trajectory>();

        if (trajectory == null)
        {
            Debug.LogError("Target requires a child with a trajectory component");
            return(new List <TrajectoryData.Intercept>());
        }
        trajIntercepts.target = trajectory;
        trajIntercepts.ComputeAndMarkIntercepts(deltaDistance, deltaTime, rendezvousDT);
        intercepts = trajIntercepts.GetIntercepts();
        return(intercepts);
    }
    public string ApproachPrediction(string moonName)
    {
        // @TODO: Too much C&P!
        // Step 1: Determine the patched conic xfer
        OrbitData shipOrbit = new OrbitData();
        NBody     shipNbody = spaceshipCtrl.GetNBody();

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

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

        // want to be within 10% of Earth-Moon distance, before start checking
        courseCorrectionData = new LunarCourseCorrection.CorrectionData();
        courseCorrectionData.gravityState     = gs;
        courseCorrectionData.approachDistance = 0.1f * moonOrbit.a;;
        courseCorrectionData.correction       = 0;
        courseCorrectionData.maxPhysTime      = time_to_moon_phys;
        lcc.ClosestApproachAsync(courseCorrectionData, MoonPreviewCompleted);
        return("Calculation started...\n");
    }
예제 #12
0
    private void TestRV(OrbitData od, GameObject planet, GameObject star, float orbitRadius)
    {
        GameObject   testPlanet  = TestSetupUtils.CreatePlanetInOrbit(star, 1f, orbitRadius);
        OrbitEllipse testEllipse = testPlanet.GetComponent <OrbitEllipse>();

        // Run init explicitly to update transform details
        testEllipse.InitFromOrbitData(od);

        // Awkward but cannot add a new object to GE when it is stopped, so re-add all three
        GravityEngine ge = GravityEngine.Instance();

        ge.Clear();
        ge.AddBody(star);
        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(FloatEqual(Vector3.Distance(r_i, r_od), 0f, 1E-2));
        Assert.IsTrue(FloatEqual(Vector3.Distance(v_i, v_od), 0f, 1E-2));
    }
예제 #13
0
    // Check eccentricity and inclination
    public void CheckTestRV()
    {
        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         = .25f;
        orbitEllipse.inclination = 25f;
        orbitEllipse.omega_uc    = 10f;
        orbitEllipse.omega_lc    = 20f;
        orbitEllipse.phase       = 190f;

        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;
        GravityEngine.Instance().UnitTestAwake();
        TestRV(od, planet, star, orbitRadius);
    }
예제 #14
0
 void Update()
 {
     if (Input.GetKeyDown(KeyCode.C))
     {
         GravityEngine.Instance().Clear();
         Debug.Log("Clear all bodies");
         List <GameObject>[] lists = { moonObjects,
                                       hyperObjects,
                                       fixedObjects,
                                       massiveObjects,
                                       masslessObjects,
                                       keplerObjects,
                                       binaryObjects,
                                       dustObjects };
         foreach (List <GameObject> l in lists)
         {
             foreach (GameObject g in l)
             {
                 Destroy(g);
             }
             l.Clear();
         }
     }
     if (runChaosMonkey)
     {
         RunChaosMonkey();
     }
 }
예제 #15
0
    private void TestRV(OrbitData od, GameObject planet, GameObject star)
    {
        GameObject testPlanet = TestSetupUtils.CreatePlanetInHyper(star, 1f);

        testPlanet.name = "TestPlanet";
        OrbitHyper testHyper = testPlanet.GetComponent <OrbitHyper>();

        testHyper.InitFromOrbitData(od);

        planet.name = "Planet";

        // Awkward but cannot add a new object to GE when it is stopped, so re-add all three
        GravityEngine ge = GravityEngine.Instance();

        ge.Clear();
        ge.AddBody(star);
        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(FloatEqual(Vector3.Distance(r_i, r_od), 0f, 5E-2));
        Assert.IsTrue(FloatEqual(Vector3.Distance(v_i, v_od), 0f, 5E-2));
    }
예제 #16
0
    // Use this for initialization
    void Start()
    {
        ge = GravityEngine.Instance();

        // scale to GE time base
        timeRangePhysical = timeRange;
    }
    void Update()
    {
        // space toggles evolution
        if (Input.GetKeyDown(KeyCode.Space))
        {
            GravityEngine.Instance().SetEvolve(!GravityEngine.Instance().GetEvolve());
        }
        DateTime newTime = SolarUtils.DateForEpoch(solarSystem.GetStartEpochTime());

        newTime += GravityScaler.GetTimeSpan(GravityEngine.Instance().GetPhysicalTimeDouble(), GravityScaler.Units.SOLAR);
        //currentTime.text =  newTime.ToString("yyyy:MM:dd"); // 24h format
        //currentTime.text = newTime.ToString("yyyy:MM:dd HH:mm:ss");
        CurrentDate.SetText(newTime.ToString("yyyy:MM:dd HH:mm:ss"));
        CurrentDateHighlighted.SetText(newTime.ToString("yyyy:MM:dd HH:mm:ss"));

        // ICK! Need to wait until GE moves these objects before can clear the trail
        if (clearTrail)
        {
            if (clearTrailDelay-- <= 0)
            {
                ResetTrails();
                clearTrail = false;
            }
        }
    }
예제 #18
0
    // Use this for initialization
    // Start() NOT Awake() to ensure that objects created on the fly can have centerBody etc. assigned
    // Awake is called from within Object.Instatiate()
    void Start()
    {
        nbody = body.GetComponent <NBody>();
        if (nbody == null)
        {
            Debug.LogWarning("Cannot show orbit - Body requires NBody component");
            return;
        }
        if (centerBody == null)
        {
            Debug.LogError("Center body is null " + gameObject.name);
        }
        if (body == null)
        {
            Debug.LogError("Body is null " + gameObject.name);
        }
        aroundNBody = centerBody.GetComponent <NBody>();
        orbitU.SetNBody(nbody);
        orbitU.centerNbody = aroundNBody;

        ge = GravityEngine.Instance();

        lineR = GetComponent <LineRenderer>();
        lineR.positionCount = numPoints + 2 * numPlaneProjections;
    }
    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));
    }
예제 #20
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());
    }
    // 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>();
    }
예제 #22
0
    // Use this for initialization
    void Start()
    {
        GravityEngine ge = GravityEngine.Instance();

        time.text = string.Format(time_format, ge.GetTimeWorldSeconds(), ge.GetTimeZoom());
        Vector3 pos = ship.initialPos;

        position.text = string.Format(pos_format, pos.x, pos.y, pos.z);
        velocity.text = string.Format(vel_format, 0f, 0f, 0f);
        if (rocketEngine == null)
        {
            Debug.LogError("Need a rocket component");
        }
        fuelText.text = string.Format(fuel_format, rocketEngine.GetFuel());
        attitude.text = string.Format(attitude_format, 0f, 0f, 0f);

        // assume earth at (0,0,0)
        initial_altitude = Vector3.Magnitude(ship.transform.position) - (float)atmosphere.heightEarthSurface;
        altitude.text    = string.Format(altitude_format, initial_altitude);

        if (drag != null)
        {
            drag.text = string.Format(drag_format, atmosphere.GetAccelSI());
        }

        if (accel != null)
        {
            accel.text = string.Format(accel_format, earthRocket.GetAccel());
        }

        if (thrust != null)
        {
            thrust.text = string.Format(thrust_format, 100f);
        }
    }
예제 #23
0
    // Use this for initialization
    void Start()
    {
        if (GetComponent <NBody>() != null)
        {
            Debug.LogWarning("Trajectory should be attached to a child of an Nbody (not directly)");
        }

        // If text, check for canvas
        if (textPrefab != null)
        {
            if (GravityEngine.instance.trajectoryCanvas == null)
            {
                Debug.LogError("Text labels require GravityEngine trajectory Canvas be configured");
            }
            else
            {
                canvas = GravityEngine.instance.trajectoryCanvas.GetComponent <Canvas>();
                if (canvas == null)
                {
                    Debug.LogError("No canvas component on " + GravityEngine.instance.trajectoryCanvas.name);
                }
            }
        }
        ge = GravityEngine.Instance();
    }
예제 #24
0
    public void SetTextInfo(float fuel, Vector3 angles)
    {
        GravityEngine ge = GravityEngine.Instance();

        time.text = string.Format(time_format, ge.GetTimeWorldSeconds(), ge.GetTimeZoom());
        double[] r = new double[3];
        double[] v = new double[3];
        GravityEngine.Instance().GetPositionVelocityScaled(ship, ref r, ref v);

        position.text = string.Format(pos_format, r[0], r[1], r[2]);
        velocity.text = string.Format(vel_format, v[0], v[1], v[2]);
        fuelText.text = string.Format(fuel_format, fuel);
        attitude.text = string.Format(attitude_format, angles.y, angles.x, angles.z);

        altitudeNow   = Vector3.Magnitude(ship.transform.position) - (float)atmosphere.heightEarthSurface;
        altitude.text = string.Format(altitude_format, altitudeNow);

        if (drag != null)
        {
            drag.text = string.Format(drag_format, atmosphere.GetAccelSI());
        }

        if (accel != null)
        {
            accel.text = string.Format(accel_format, earthRocket.GetAccel());
        }
        if (thrust != null)
        {
            thrust.text = string.Format(thrust_format, rocketEngine.GetThrottlePercent());
        }
    }
예제 #25
0
    // Vallado Algorithm 10, p118
    // (generic, will work for Ellipse as well, provided special cases are handled)
    // Not used yet.
    private void SetInitialPosition(NBody nbody)
    {
        // phase is in
        float   denom = 1 + ecc * Mathf.Cos(phase_nu);
        Vector3 r_pqw = new Vector3(p * Mathf.Cos(phase_nu) / denom, p * Mathf.Sin(phase_nu) / denom, 0);

        r_initial_phy = r_pqw.magnitude;
        Vector3 r = hyper_orientation * r_pqw;

        // orbit position is WRT center. Could be adding dynamically to an object in motion, so need current position.
        Vector3 centerPos = Vector3.zero;

        // used by widgets - so need to get explcitly
        centerNbody = OrbitUtils.GetCenterNbody(this.transform, centerObject);
        if (centerNbody.engineRef != null)
        {
            centerPos = GravityEngine.Instance().GetPhysicsPosition(centerNbody);
        }
        else
        {
            // setup - not yet added to GE
            centerPos = centerNbody.initialPhysPosition;
        }
        nbody.initialPhysPosition = r + centerPos;
    }
예제 #26
0
    public static float ScalePeriod(float period)
    {
        float lengthScale = GravityEngine.Instance().GetLengthScale();
        float massScale   = GravityEngine.Instance().massScale;

        return(Mathf.Sqrt(lengthScale * lengthScale * lengthScale) / Mathf.Sqrt(massScale) * period);
    }
예제 #27
0
 // Update is called once per frame
 void Update()
 {
     if (Input.GetKeyUp(KeyCode.W))
     {
         GravityEngine.Instance().ApplyImpulse(ship, thrust * Vector3.up);
     }
 }
예제 #28
0
    public void SetupBodies()
    {
        if (transform.childCount != 2)
        {
            // Binary must have 2 NBody children
            Debug.LogError("Must have exactly two Nbody objects attached");
            return;
        }
        body1 = transform.GetChild(0).GetComponent <NBody>();
        body2 = transform.GetChild(1).GetComponent <NBody>();
        if (body1 == null || body2 == null)
        {
            Debug.LogError("Binary requires children to have NBody scripts attached.");
            return;
        }

        if (transform.parent)
        {
            binaryNbody = transform.parent.GetComponent <NBody>();
            if (binaryNbody)
            {
                binaryNbody.InitPosition(GravityEngine.Instance());
                cmPosition = GravityEngine.Instance().GetPhysicsPosition(binaryNbody);
            }
        }

        // mass is scaled by GE
        float m_total = (body1.mass + body2.mass);
        float mu1     = body1.mass / m_total;
        float mu2     = body2.mass / m_total;

        SetupBody(body1, a_scaled * mu2, mu2 * mu2 * body2.mass, false);
        SetupBody(body2, a_scaled * mu1, mu1 * mu1 * body1.mass, true);
    }
예제 #29
0
    public static void SetupGravityEngine(GameObject centerBody, GameObject orbitingBody)
    {
        GravityEngine ge = GravityEngine.Instance();

        if (ge == null)
        {
            Debug.LogError("No GE in scene");
        }
        if (ge.evolveAtStart)
        {
            Debug.LogError("Evolve at start set. Are you in the TestRunner scene?");
        }
        else if (ge.detectNbodies)
        {
            Debug.LogError("Detect NBodies at start set. Are you in the TestRunner scene?");
        }
        ge.UnitTestAwake();
        ge.Clear();
        ge.AddBody(centerBody);
        if (orbitingBody != null)
        {
            ge.AddBody(orbitingBody);
        }
        ge.Setup();
        ge.LogDump();
    }
예제 #30
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);
     }
 }