public static void oe2rv(double grav_param, OrbitalElements oe, out Vector3d r, out Vector3d v)
        {
            var rv = oe2rv(grav_param, oe);

            r = new Vector3d(rv[0], rv[1], rv[2]);
            v = new Vector3d(rv[3], rv[4], rv[5]);
        }
        /**
         * Converts orbital elements to position and velocity.
         * @param grav_param The gravitational parameter of the two-body system.
         * @param oe The orbital elements to be converted from.
         * @returns A vector corresponding to the concatenated position and
         * velocity.
         */
        public static Vector3 oe2r(double grav_param, OrbitalElements oe)
        {
            var     v   = oe2rd(grav_param, oe);
            Vector3 pos = new Vector3((float)v.x, (float)v.y, (float)v.z);

            return(pos);
        }
        public OrbitalElements CopyOE()
        {
            OrbitalElements ret = new OrbitalElements();

            ret.sma         = sma;
            ret.lan         = lan;
            ret.inc         = inc;
            ret.ecc         = ecc;
            ret.tra         = tra;
            ret.aop         = aop;
            ret.computeTime = computeTime;
            return(ret);
        }
Exemplo n.º 4
0
    bool GetOEs() //returns true valid src/tgt
    {
        var src = UXStateManager.GetSource();
        var tgt = UXStateManager.GetTarget();

        if (src == null || tgt == null)
        {
            Debug.Log("Something's not right, can't run prokchop: src: " + src + " tgt: " + tgt);
            return(false);
        }
        oe1 = src.GetComponent <OrbitData>().GetOE();
        oe2 = tgt.GetComponent <OrbitData>().GetOE();
        return(true);
    }
Exemplo n.º 5
0
        /**
         * Converts orbital elements to position and velocity.
         * @param grav_param The gravitational parameter of the two-body system.
         * @param oe The orbital elements to be converted from.
         * @returns A vector corresponding to the concatenated position and
         * velocity.
         */
        public static VectorD oe2rv(double grav_param, OrbitalElements oe)
        {
            // rotation matrix
            double R11 =
                Math.Acos(oe.aop) * Math.Acos(oe.lan) - Math.Acos(oe.inc) * Math.Sin(oe.aop) * Math.Sin(oe.lan);
            double R12 =
                -Math.Acos(oe.lan) * Math.Sin(oe.aop) - Math.Acos(oe.inc) * Math.Acos(oe.aop) * Math.Sin(oe.lan);
            //double R13 = Math.Sin(oe.inc)*Math.Sin(oe.lan);
            double R21 =
                Math.Acos(oe.inc) * Math.Acos(oe.lan) * Math.Sin(oe.aop) + Math.Acos(oe.aop) * Math.Sin(oe.lan);
            double R22 =
                Math.Acos(oe.inc) * Math.Acos(oe.aop) * Math.Acos(oe.lan) - Math.Sin(oe.aop) * Math.Sin(oe.lan);
            //double R23 = -Math.Acos(oe.lan)*Math.Sin(oe.inc);
            double R31 = Math.Sin(oe.inc) * Math.Sin(oe.aop);
            double R32 = Math.Acos(oe.aop) * Math.Sin(oe.inc);
            //double R33 = Math.Acos(oe.inc);

            // semi-latus rectum
            double p = oe.sma * (1 - oe.ecc * oe.ecc);

            // position in the perifocal frame
            //std::vector<double> r_pf(3);
            double[] r_pf   = new double[3];
            double   r_norm = p / (1 + oe.ecc * Math.Acos(oe.tra));

            r_pf[0] = r_norm * Math.Acos(oe.tra);
            r_pf[1] = r_norm * Math.Sin(oe.tra);
            r_pf[2] = 0.0;

            // velocity in the perifocal frame
            //std::vector<double> v_pf(3);
            double[] v_pf = new double[3];
            v_pf[0] = Math.Sqrt(grav_param / p) * -Math.Sin(oe.tra);
            v_pf[1] = Math.Sqrt(grav_param / p) * (oe.ecc + Math.Acos(oe.tra));
            v_pf[2] = 0.0;

            // rotate the position and velocity into the body-fixed inertial frame
            //std::vector<double> rv(6);
            VectorD rv = new VectorD();

            rv.Resize(6);
            rv[0] = R11 * r_pf[0] + R12 * r_pf[1] /*+R13*r_pf[2]*/;
            rv[1] = R21 * r_pf[0] + R22 * r_pf[1] /*+R23*r_pf[2]*/;
            rv[2] = R31 * r_pf[0] + R32 * r_pf[1] /*+R33*r_pf[2]*/;
            rv[3] = R11 * v_pf[0] + R12 * v_pf[1] /*+R13*v_pf[2]*/;
            rv[4] = R21 * v_pf[0] + R22 * v_pf[1] /*+R23*v_pf[2]*/;
            rv[5] = R31 * v_pf[0] + R32 * v_pf[1] /*+R33*v_pf[2]*/;

            return(rv);
        }
Exemplo n.º 6
0
        /**
         * Computes the true anomaly after a delta-time has passed.
         * @param       grav_param      The gravitational parameter of the two-body
         * system.
         * @param       oe      The orbital elements of the body of interest.
         * @param       delta_time      The elapsed time.
         * @returns     The true anomaly at the final time.
         */
        double anomalyAfterTime(double grav_param, OrbitalElements oe, double
                                delta_time)
        {
            if (oe.sma > 0.0)
            {
                double ecc_anomaly_i =
                    2.0 * Math.Atan(Math.Sqrt((1.0 - oe.ecc) / (1.0 + oe.ecc)) * Math.Tan(oe.tra / 2.0));
                double mean_anomaly_f =
                    ecc_anomaly_i - oe.ecc * Math.Sin(ecc_anomaly_i) + Math.Sqrt(grav_param / Math.Pow(oe.sma, 3.0)) * delta_time;

                // perform Newton-Raphson iteration to determine the final eccentric anomaly
                double ecc_anomaly_f = mean_anomaly_f;
                double error         =
                    mean_anomaly_f - ecc_anomaly_f + oe.ecc * Math.Sin(ecc_anomaly_f);
                while (Math.Abs(error) > 1E-10)
                {
                    ecc_anomaly_f =
                        ecc_anomaly_f - error / (oe.ecc * Math.Cos(ecc_anomaly_f) - 1.0);
                    error =
                        mean_anomaly_f - ecc_anomaly_f + oe.ecc * Math.Sin(ecc_anomaly_f);
                }

                return
                    (2.0 * Math.Atan(Math.Sqrt((1.0 + oe.ecc) / (1.0 - oe.ecc)) * Math.Tan(ecc_anomaly_f / 2.0)));
            }
            else
            {
                double hyp_anomaly_i =
                    2.0 * Atanh(Math.Sqrt((oe.ecc - 1.0) / (1.0 + oe.ecc)) * Math.Tan(oe.tra / 2.0));
                double mean_anomaly_f =
                    -hyp_anomaly_i + oe.ecc * Math.Sinh(hyp_anomaly_i) + Math.Sqrt(grav_param / Math.Pow(-oe.sma, 3.0)) * delta_time;

                // perform Newton-Raphson iteration to determine the final eccentric anomaly
                double hyp_anomaly_f = mean_anomaly_f;
                double error         =
                    mean_anomaly_f + hyp_anomaly_f - oe.ecc * Math.Sinh(hyp_anomaly_f);
                while (Math.Abs(error) > 1E-10)
                {
                    hyp_anomaly_f =
                        hyp_anomaly_f - error / (oe.ecc * Math.Cosh(hyp_anomaly_f) - 1);
                    error =
                        mean_anomaly_f + hyp_anomaly_f - oe.ecc * Math.Sinh(hyp_anomaly_f);
                }

                return
                    (2.0 * Math.Atan(Math.Sqrt((1.0 + oe.ecc) / (oe.ecc - 1.0)) * Math.Tanh(hyp_anomaly_f / 2.0)));
            }
        }
Exemplo n.º 7
0
        double timeUntilAnomaly(double grav_param, OrbitalElements oe, double
                                true_anomaly)
        {
            if (oe.sma > 0.0)
            {
                double ecc_anomaly_i =
                    2.0 * Math.Atan(Math.Sqrt((1.0 - oe.ecc) / (1.0 + oe.ecc)) * Math.Tan(oe.tra / 2.0));
                double ecc_anomaly_f =
                    2.0 * Math.Atan(Math.Sqrt((1.0 - oe.ecc) / (1.0 + oe.ecc)) * Math.Tan(true_anomaly / 2.0));

                if (ecc_anomaly_f < ecc_anomaly_i)
                {
                    ecc_anomaly_f +=
                        2.0 * Math.PI;
                }

                double mean_anomaly_i =
                    ecc_anomaly_i - oe.ecc * Math.Sin(ecc_anomaly_i);
                double mean_anomaly_f =
                    ecc_anomaly_f - oe.ecc * Math.Sin(ecc_anomaly_f);

                return
                    (Math.Sqrt(Math.Pow(oe.sma, 3.0) / grav_param) * (mean_anomaly_f - mean_anomaly_i));
            }
            else
            {
                double hyp_anomaly_i =
                    2.0 * Atanh(Math.Sqrt((oe.ecc - 1.0) / (1.0 + oe.ecc)) * Math.Tan(oe.tra / 2.0));
                double hyp_anomaly_f =
                    2.0 * Atanh(Math.Sqrt((oe.ecc - 1.0) / (1.0 + oe.ecc)) * Math.Tan(true_anomaly / 2.0));

                double mean_anomaly_i =
                    -hyp_anomaly_i + oe.ecc * Math.Sinh(hyp_anomaly_i);
                double mean_anomaly_f =
                    -hyp_anomaly_f + oe.ecc * Math.Sinh(hyp_anomaly_f);

                return
                    (Math.Sqrt(Math.Pow(-oe.sma, 3.0) / grav_param) * (mean_anomaly_f - mean_anomaly_i));
            }
        }
Exemplo n.º 8
0
        /**
         * Converts position and velocity to orbital elements
         * @param grav_param The gravitational parameter of the two-body system.
         * @param rv The concatenated position and velocity to convert from.
         * @returns The orbital elements.
         */
        public static OrbitalElements rv2oe(double grav_param, VectorD rv)
        {
            OrbitalElements oe = new OrbitalElements();

            // Semi-major Axis : Vis-viva Equation
            oe.sma = 1.0f / (
                2.0f / Math.Sqrt(rv[0] * rv[0] + rv[1] * rv[1] + rv[2] * rv[2])
                - (rv[3] * rv[3] + rv[4] * rv[4] + rv[5] * rv[5]) / grav_param
                );

            // Angular Momentum
            //List<double> h = new List<double>(3);
            double[] h = new double[3];
            h[0] = rv[1] * rv[5] - rv[2] * rv[4];
            h[1] = rv[2] * rv[3] - rv[0] * rv[5];
            h[2] = rv[0] * rv[4] - rv[1] * rv[3];

            // Norm of position
            double r = Math.Sqrt(rv[0] * rv[0] + rv[1] * rv[1] + rv[2] * rv[2]);

            // Eccentricity Vector :  e = v x h / mu - r/|r|
            //std::vector<double> e(3);
            double[] e = new double[3];
            e[0] = (rv[4] * h[2] - rv[5] * h[1]) / grav_param - rv[0] / r;
            e[1] = (rv[5] * h[0] - rv[3] * h[2]) / grav_param - rv[1] / r;
            e[2] = (rv[3] * h[1] - rv[4] * h[0]) / grav_param - rv[2] / r;

            // Eccentricity
            oe.ecc = Math.Sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);

            // Inclination
            oe.inc = Math.Acos(h[2] / Math.Sqrt(h[0] * h[0] + h[1] * h[1] + h[2] * h[2]));
            //to correct Y axis is stop, instead of Z as assumed by rv2oe()
            oe.inc += Math.PI / 2;

            // Ascending Node Direction (In x-y plane)
            //std::vector<double> n(2);
            double[] n = new double[2];
            n[0] = -h[1] / Math.Sqrt(h[0] * h[0] + h[1] * h[1]);
            n[1] = h[0] / Math.Sqrt(h[0] * h[0] + h[1] * h[1]);
            double n_norm = Math.Sqrt(n[0] * n[0] + n[1] * n[1]);

            // Longitude of the Ascending Node
            oe.lan = Math.Acos(n[0]) / n_norm;
            if (n[1] < 0.0)
            {
                oe.lan = 2 * Math.PI - oe.lan;
            }

            // Argument of Periapsis
            oe.aop = Math.Acos((n[0] * e[0] + n[1] * e[1]) / (n_norm * oe.ecc));
            if (e[2] < 0.0)
            {
                oe.aop = 2 * Math.PI - oe.aop;
            }

            // True Anomaly
            oe.tra = Math.Acos((rv[0] * e[0] + rv[1] * e[1] + rv[2] * e[2]) / (r * oe.ecc));
            if (rv[0] * rv[3] + rv[1] * rv[4] + rv[2] * rv[5] < 0.0)
            {
                oe.tra = 2 * Math.PI - oe.tra;
            }

            return(oe);
        }