Exemplo n.º 1
0
        public static ManeuverParameters OptimizeEjection(ManeuverParameters original_maneuver, Orbit initial_orbit, Orbit target, double UT_arrival)
        {
            alglib.minlmstate  state;
            alglib.minlmreport rep;

            double[] x     = new double[4];
            double[] scale = new double[4];

            x[0] = original_maneuver.dV.x;
            x[1] = original_maneuver.dV.y;
            x[2] = original_maneuver.dV.z;
            x[3] = 0;

            scale[0] = scale[1] = scale[2] = original_maneuver.dV.magnitude;
            scale[3] = initial_orbit.period;

            OptimizerData data = new OptimizerData();

            data.initial_orbit = initial_orbit;
            data.original_UT   = original_maneuver.UT;
            data.UT_arrival    = UT_arrival;
            data.pos_arrival   = target.getTruePositionAtUT(UT_arrival);

            alglib.minlmcreatev(3, x, 0.01, out state);
            alglib.minlmsetcond(state, 0, 0, 0, 50);
            alglib.minlmsetscale(state, scale);
            alglib.minlmoptimize(state, DistanceToTarget, null, data);
            alglib.minlmresults(state, out x, out rep);

            return(new ManeuverParameters(new Vector3d(x[0], x[1], x[2]), original_maneuver.UT + x[3]));
        }
Exemplo n.º 2
0
        public static ManeuverParameters OptimizeEjection(ManeuverParameters original_maneuver, Orbit initial_orbit, Orbit target, double UT_arrival, double earliest_UT)
        {
            int N = 0;

            while (true)
            {
                alglib.minlmstate  state;
                alglib.minlmreport rep;

                double[] x     = new double[5];
                double[] scale = new double[5];

                x[0] = original_maneuver.dV.x;
                x[1] = original_maneuver.dV.y;
                x[2] = original_maneuver.dV.z;
                x[3] = original_maneuver.UT + N * initial_orbit.period;
                x[4] = UT_arrival;

                scale[0] = scale[1] = scale[2] = original_maneuver.dV.magnitude;
                scale[3] = initial_orbit.period;
                scale[4] = target.period / 4.0;

                OptimizerData data = new OptimizerData();
                data.initial_orbit = initial_orbit;
                data.target_orbit  = target;

                alglib.minlmcreatev(6, x, 0.001, out state);
                double epsx = 1e-16; // stop if |(x(k+1)-x(k)) ./ scale| <= EpsX
                double epsf = 1e-16; // stop if |F(k+1)-F(k)| <= EpsF*max{|F(k)|,|F(k+1)|,1}
                alglib.minlmsetcond(state, 0, epsf, epsx, 50);
                alglib.minlmsetscale(state, scale);
                alglib.minlmoptimize(state, DistanceToTarget, null, data);
                alglib.minlmresults(state, out x, out rep);

                Debug.Log("Transfer calculator: termination type=" + rep.terminationtype);
                Debug.Log("Transfer calculator: iteration count=" + rep.iterationscount);

                // try again in one orbit if the maneuver node is in the past
                if (x[3] < earliest_UT)
                {
                    Debug.Log("Transfer calculator: maneuver is " + (earliest_UT - x[3]) + " s too early, trying again in " + initial_orbit.period + " s");
                    N++;
                }
                else
                {
                    Debug.Log("from optimizer DV = " + Math.Sqrt(Math.Pow(x[0], 2.0) + Math.Pow(x[1], 2.0) + Math.Pow(x[2], 2.0)));
                    return(new ManeuverParameters(new Vector3d(x[0], x[1], x[2]), x[3]));
                }
            }
        }
Exemplo n.º 3
0
        public static ManeuverParameters OptimizeEjection(ManeuverParameters original_maneuver, Orbit initial_orbit, Orbit target, double UT_arrival, double earliest_UT)
        {
            while (true)
            {
                alglib.minlmstate  state;
                alglib.minlmreport rep;

                double[] x     = new double[4];
                double[] scale = new double[4];

                x[0] = original_maneuver.dV.x;
                x[1] = original_maneuver.dV.y;
                x[2] = original_maneuver.dV.z;
                x[3] = 0;

                scale[0] = scale[1] = scale[2] = original_maneuver.dV.magnitude;
                scale[3] = initial_orbit.period;

                OptimizerData data = new OptimizerData();
                data.initial_orbit = initial_orbit;
                data.original_UT   = original_maneuver.UT;
                data.UT_arrival    = UT_arrival;
                data.pos_arrival   = target.getTruePositionAtUT(UT_arrival);

                alglib.minlmcreatev(4, x, 0.01, out state);
                double epsx = 1e-4;                 // stop if |(x(k+1)-x(k)) ./ scale| <= EpsX
                double epsf = 0.01;                 // stop if |F(k+1)-F(k)| <= EpsF*max{|F(k)|,|F(k+1)|,1}
                alglib.minlmsetcond(state, 0, epsf, epsx, 50);
                alglib.minlmsetscale(state, scale);
                alglib.minlmoptimize(state, DistanceToTarget, null, data);
                alglib.minlmresults(state, out x, out rep);

                Debug.Log("Transfer calculator: termination type=" + rep.terminationtype);
                Debug.Log("Transfer calculator: iteration count=" + rep.iterationscount);

                // try again in one orbit if the maneuver node is in the past
                if (original_maneuver.UT + x[3] < earliest_UT)
                {
                    Debug.Log("Transfer calculator: maneuver is " + (earliest_UT - original_maneuver.UT - x[3]) + " s too early, trying again in " + initial_orbit.period + " s");
                    original_maneuver.UT += initial_orbit.period;
                }
                else
                {
                    return(new ManeuverParameters(new Vector3d(x[0], x[1], x[2]), original_maneuver.UT + x[3]));
                }
            }
        }
Exemplo n.º 4
0
        static void DistanceToTarget(double[] x, double[] fi, object obj)
        {
            OptimizerData data = (OptimizerData)obj;

            double   t  = x[3];
            Vector3d DV = new Vector3d(x[0], x[1], x[2]);

            Orbit orbit = new Orbit();

            orbit.UpdateFromStateVectors(data.initial_orbit.getRelativePositionAtUT(t), data.initial_orbit.getOrbitalVelocityAtUT(t) + DV.xzy, data.initial_orbit.referenceBody, t);
            orbit.StartUT = t;

            var      pars = new PatchedConics.SolverParameters();
            Vector3d pos;

            while (true)
            {
                Orbit next_orbit = new Orbit();
                PatchedConics.CalculatePatch(orbit, next_orbit, orbit.StartUT, pars, null);

                if (orbit.EndUT > x[4])
                {
                    pos = orbit.getTruePositionAtUT(x[4]);
                    Vector3d err = pos - data.target_orbit.getTruePositionAtUT(x[4]);

                    /* this needs to be components of err and cannot simply be err.magnitude */
                    fi[0] = err.x;
                    fi[1] = err.y;
                    fi[2] = err.z;
                    /* similarly here, and the 10,000x fudge factor was experimentally determined */
                    fi[3] = DV.x * 10000.0;
                    fi[4] = DV.y * 10000.0;
                    fi[5] = DV.z * 10000.0;
                    return;
                }

                // As of 0.25 CalculatePatch fails if the orbit does not change SoI
                if (next_orbit.referenceBody == null)
                {
                    next_orbit.UpdateFromOrbitAtUT(orbit, orbit.StartUT + orbit.period, orbit.referenceBody);
                }
                orbit = next_orbit;
            }
        }
Exemplo n.º 5
0
        static void DistanceToTarget(double[] x, double[] fi, object obj)
        {
            OptimizerData data = (OptimizerData)obj;

            double   t  = data.original_UT + x[3];
            Vector3d DV = new Vector3d(x[0], x[1], x[2]);

            Orbit orbit = new Orbit();

            orbit.UpdateFromStateVectors(data.initial_orbit.getRelativePositionAtUT(t), data.initial_orbit.getOrbitalVelocityAtUT(t) + DV.xzy, data.initial_orbit.referenceBody, t);
            orbit.StartUT = t;

            var      pars = new PatchedConics.SolverParameters();
            Vector3d pos;

            while (true)
            {
                Orbit next_orbit = new Orbit();
                PatchedConics.CalculatePatch(orbit, next_orbit, orbit.StartUT, pars, null);

                if (orbit.EndUT > data.UT_arrival)
                {
                    pos = orbit.getTruePositionAtUT(data.UT_arrival);
                    Vector3d err = pos - data.pos_arrival;

                    fi[0] = err.x;
                    fi[1] = err.y;
                    fi[2] = err.z;
                    return;
                }

                // As of 0.25 CalculatePatch fails if the orbit does not change SoI
                if (next_orbit.referenceBody == null)
                {
                    next_orbit.UpdateFromOrbitAtUT(orbit, orbit.StartUT + orbit.period, orbit.referenceBody);
                }
                orbit = next_orbit;
            }
        }
        public ManeuverParameters OptimizeEjection(double UT_transfer, Orbit initial_orbit, Orbit target, CelestialBody target_body, double UT_arrival, double earliest_UT)
        {
            int N = 0;

            while (true)
            {
                alglib.minlmstate  state;
                alglib.minlmreport rep;

                double[] x     = new double[5];
                double[] scale = new double[5];

                Vector3d exitDV, captureDV;
                CalcLambertDVs(UT_transfer, UT_arrival - UT_transfer, out exitDV, out captureDV);

                var maneuver = ComputeEjectionManeuver(exitDV, origin, UT_transfer);

                x[0] = maneuver.dV.x;
                x[1] = maneuver.dV.y;
                x[2] = maneuver.dV.z;
                x[3] = maneuver.UT + N * initial_orbit.period;

                scale[0] = scale[1] = scale[2] = maneuver.dV.magnitude;
                scale[3] = initial_orbit.period;

                OptimizerData data = new OptimizerData();
                data.initial_orbit = initial_orbit;
                data.target_orbit  = target;
                data.target_body   = target_body;
                data.UT_arrival    = UT_arrival;
                data.failed        = true;

                alglib.minlmcreatev(4, 3, x, 0.001, out state);
                alglib.minlmsetcond(state, 0, 0);
                alglib.minlmsetscale(state, scale);
                alglib.minlmoptimize(state, DistanceToTarget, null, data);
                alglib.minlmresults(state, out x, out rep);

                Log.info("Transfer calculator: termination type = {0}", rep.terminationtype);
                Log.info("Transfer calculator: iteration count = {0}", rep.iterationscount);

                // try again if we failed to intersect the target orbit
                if (data.failed)
                {
                    Log.info("Failed to intersect target orbit");
                    N++;
                }
                // try again in one orbit if the maneuver node is in the past
                else if (x[3] < earliest_UT || data.failed)
                {
                    Log.info("Transfer calculator: maneuver is {0} s too early, trying again in {1} s", (earliest_UT - x[3]), initial_orbit.period);
                    N++;
                }
                else
                {
                    Log.info("from optimizer DV = {0} t = {1} original arrival = {2}", new Vector3d(x[0], x[1], x[2]), x[3], UT_arrival);
                    return(new ManeuverParameters(new Vector3d(x[0], x[1], x[2]), x[3]));
                }
                if (N > 10)
                {
                    throw new OperationException("Ejection Optimization failed; try manual selection");
                }
            }
        }
        void DistanceToTarget(double[] x, double[] fi, object obj)
        {
            OptimizerData data = (OptimizerData)obj;

            double   t  = x[3];
            Vector3d DV = new Vector3d(x[0], x[1], x[2]);

            Orbit orbit = new Orbit();

            orbit.UpdateFromStateVectors(data.initial_orbit.getRelativePositionAtUT(t), data.initial_orbit.getOrbitalVelocityAtUT(t) + DV.xzy, data.initial_orbit.referenceBody, t);
            orbit.StartUT = t;
            orbit.EndUT   = orbit.eccentricity >= 1.0 ? orbit.period : t + orbit.period;
            Orbit next_orbit = new Orbit();

            PatchedConics.CalculatePatch(orbit, next_orbit, t, solverParameters, null);

            while (true)
            {
                if (orbit.referenceBody == data.target_body)
                {
                    if (orbit.PeR < 100000)
                    {
                        fi[0] = DV.x;
                        fi[1] = DV.y;
                        fi[2] = DV.z;
                    }
                    else
                    {
                        Vector3d err = orbit.getRelativePositionFromTrueAnomaly(0);
                        fi[0] = err.x;
                        fi[1] = err.y;
                        fi[2] = err.z;
                    }
                    data.failed = false;  /* we intersected at some point with the target body SOI */

                    return;
                }
                else if (orbit.EndUT > data.UT_arrival)
                {
                    Vector3d err;
                    if (orbit.referenceBody == data.target_orbit.referenceBody)
                    {
                        err = orbit.getRelativePositionAtUT(data.UT_arrival) - data.target_orbit.getRelativePositionAtUT(data.UT_arrival);
                    }
                    else
                    {
                        err = orbit.getTruePositionAtUT(data.UT_arrival) - data.target_orbit.getTruePositionAtUT(data.UT_arrival);
                    }

                    fi[0] = err.x;
                    fi[1] = err.y;
                    fi[2] = err.z;

                    return;
                }

                Orbit temp = orbit;
                orbit      = next_orbit;
                next_orbit = temp;
                PatchedConics.CalculatePatch(orbit, next_orbit, orbit.StartUT, solverParameters, null);
            }
        }
Exemplo n.º 8
0
		public static ManeuverParameters OptimizeEjection(ManeuverParameters original_maneuver, Orbit initial_orbit, Orbit target, double UT_arrival, double earliest_UT)
		{
			while(true)
			{
				alglib.minlmstate state;
				alglib.minlmreport rep;

				double[] x = new double[4];
				double[] scale = new double[4];

				x[0] = original_maneuver.dV.x;
				x[1] = original_maneuver.dV.y;
				x[2] = original_maneuver.dV.z;
				x[3] = 0;

				scale[0] = scale[1] = scale[2] = original_maneuver.dV.magnitude;
				scale[3] = initial_orbit.period;

				OptimizerData data = new OptimizerData();
				data.initial_orbit = initial_orbit;
				data.original_UT = original_maneuver.UT;
				data.UT_arrival = UT_arrival;
				data.pos_arrival = target.getTruePositionAtUT(UT_arrival);

				alglib.minlmcreatev(4, x, 0.01, out state);
				double epsx = 1e-4; // stop if |(x(k+1)-x(k)) ./ scale| <= EpsX
				double epsf = 0.01; // stop if |F(k+1)-F(k)| <= EpsF*max{|F(k)|,|F(k+1)|,1}
				alglib.minlmsetcond(state, 0, epsf, epsx, 50);
				alglib.minlmsetscale(state, scale);
				alglib.minlmoptimize(state, DistanceToTarget, null, data);
				alglib.minlmresults(state, out x, out rep);

				Debug.Log("Transfer calculator: termination type=" + rep.terminationtype);
				Debug.Log("Transfer calculator: iteration count=" + rep.iterationscount);

				// try again in one orbit if the maneuver node is in the past
				if (original_maneuver.UT + x[3] < earliest_UT)
				{
					Debug.Log("Transfer calculator: maneuver is " + (earliest_UT - original_maneuver.UT - x[3]) + " s too early, trying again in " + initial_orbit.period + " s");
					original_maneuver.UT += initial_orbit.period;
				}
				else
					return new ManeuverParameters(new Vector3d(x[0], x[1], x[2]), original_maneuver.UT + x[3]);
			}
		}