Esempio n. 1
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());
    }
Esempio n. 2
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);
    }
Esempio n. 3
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));
    }
Esempio n. 4
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);
    }