Example #1
0
        public static Vector3d DeltaVAndTimeForCheapestCourseCorrection(Orbit o, double UT, Orbit target, CelestialBody targetBody, double finalPeR, out double burnUT)
        {
            Vector3d collisionDV       = DeltaVAndTimeForCheapestCourseCorrection(o, UT, target, out burnUT);
            Orbit    collisionOrbit    = o.PerturbedOrbit(burnUT, collisionDV);
            double   collisionUT       = collisionOrbit.NextClosestApproachTime(target, burnUT);
            Vector3d collisionPosition = target.SwappedAbsolutePositionAtUT(collisionUT);
            Vector3d collisionRelVel   = collisionOrbit.SwappedOrbitalVelocityAtUT(collisionUT) - target.SwappedOrbitalVelocityAtUT(collisionUT);

            double   soiEnterUT     = collisionUT - targetBody.sphereOfInfluence / collisionRelVel.magnitude;
            Vector3d soiEnterRelVel = collisionOrbit.SwappedOrbitalVelocityAtUT(soiEnterUT) - target.SwappedOrbitalVelocityAtUT(soiEnterUT);

            double E                      = 0.5 * soiEnterRelVel.sqrMagnitude - targetBody.gravParameter / targetBody.sphereOfInfluence; //total orbital energy on SoI enter
            double finalPeSpeed           = Math.Sqrt(2 * (E + targetBody.gravParameter / finalPeR));                                    //conservation of energy gives the orbital speed at finalPeR.
            double desiredImpactParameter = finalPeR * finalPeSpeed / soiEnterRelVel.magnitude;                                          //conservation of angular momentum gives the required impact parameter

            Vector3d displacementDir = Vector3d.Cross(collisionRelVel, o.SwappedOrbitNormal()).normalized;
            Vector3d interceptTarget = collisionPosition + desiredImpactParameter * displacementDir;

            Vector3d velAfterBurn;
            Vector3d arrivalVel;

            LambertSolver.Solve(o.SwappedRelativePositionAtUT(burnUT), interceptTarget - o.referenceBody.position, collisionUT - burnUT, o.referenceBody, true, out velAfterBurn, out arrivalVel);

            Vector3d deltaV = velAfterBurn - o.SwappedOrbitalVelocityAtUT(burnUT);

            return(deltaV);
        }
Example #2
0
        void ComputeDeltaV(object args)
        {
            CelestialBody origin_planet = origin.referenceBody;

            for (int date_index = TakeDateIndex();
                 date_index >= 0;
                 date_index = TakeDateIndex())
            {
                double   t0   = DateFromIndex(date_index);
                Vector3d V1_0 = origin_planet.orbit.getOrbitalVelocityAtUT(t0);
                Vector3d R1   = origin_planet.orbit.getRelativePositionAtUT(t0);

                int duration_samples = DurationSamplesForDate(date_index);
                for (int duration_index = 0; duration_index < duration_samples; duration_index++)
                {
                    if (stop)
                    {
                        break;
                    }

                    double dt = DurationFromIndex(duration_index);
                    double t1 = t0 + dt;

                    Vector3d R2 = destination.getRelativePositionAtUT(t1);

                    bool short_way = Vector3d.Dot(Vector3d.Cross(R1, R2), origin_planet.orbit.GetOrbitNormal()) > 0;
                    try
                    {
                        Vector3d V1, V2;
#if DEBUG
                        log[date_index, duration_index] = dt + ","
                                                          + R1.x + "," + R1.y + "," + R1.z + ","
                                                          + R2.x + "," + R2.y + "," + R2.z + ","
                                                          + V1_0.x + "," + V1_0.y + "," + V1_0.z;
#endif
                        LambertSolver.Solve(R1, R2, dt, origin_planet.referenceBody, short_way, out V1, out V2);

#if DEBUG
                        log[date_index, duration_index] += "," + V1.x + "," + V1.y + "," + V1.z;
#endif

                        Vector3d soi_exit_velocity = V1 - V1_0;
                        var      maneuver          = ComputeEjectionManeuver(soi_exit_velocity, origin, t0);
                        if (!double.IsNaN(maneuver.dV.sqrMagnitude) && !double.IsNaN(maneuver.UT))
                        {
                            computed[date_index, duration_index] = maneuver;
                        }
#if DEBUG
                        log[date_index, duration_index] += "," + maneuver.dV.magnitude;
#endif
                    }
                    catch (Exception) {}
                }
            }

            JobFinished();
        }
        public static Vector3d DeltaVAndTimeForCheapestCourseCorrection(Orbit o, double UT, Orbit target, double caDistance, out double burnUT)
        {
            Vector3d collisionDV    = DeltaVAndTimeForCheapestCourseCorrection(o, UT, target, out burnUT);
            Orbit    collisionOrbit = o.PerturbedOrbit(burnUT, collisionDV);
            double   collisionUT    = collisionOrbit.NextClosestApproachTime(target, burnUT);
            Vector3d position       = o.SwappedAbsolutePositionAtUT(collisionUT);
            Vector3d targetPos      = target.SwappedAbsolutePositionAtUT(collisionUT);
            Vector3d direction      = targetPos - position;

            Vector3d interceptTarget = targetPos + target.NormalPlus(collisionUT) * caDistance;

            Vector3d velAfterBurn;
            Vector3d arrivalVel;

            LambertSolver.Solve(o.SwappedRelativePositionAtUT(burnUT), interceptTarget - o.referenceBody.position, collisionUT - burnUT, o.referenceBody, true, out velAfterBurn, out arrivalVel);

            Vector3d deltaV = velAfterBurn - o.SwappedOrbitalVelocityAtUT(burnUT);

            return(deltaV);
        }
Example #4
0
        //Computes the delta-V of a burn at a given time that will put an object with a given orbit on a
        //course to intercept a target at a specific interceptUT.
        public static Vector3d DeltaVToInterceptAtTime(Orbit o, double UT, Orbit target, double interceptUT, double leadDistance = 0)
        {
            double   initialT      = UT;
            Vector3d initialRelPos = o.SwappedRelativePositionAtUT(initialT);
            double   finalT        = interceptUT;
            Vector3d finalRelPos   = target.SwappedRelativePositionAtUT(finalT);

            finalRelPos += leadDistance * target.SwappedOrbitalVelocityAtUT(finalT).normalized;

            double targetOrbitalSpeed = o.SwappedOrbitalVelocityAtUT(finalT).magnitude;
            double deltaTPrecision    = 20.0 / targetOrbitalSpeed;

            Vector3d initialVelocity, finalVelocity;

            LambertSolver.Solve(initialRelPos, finalRelPos, finalT - initialT, o.referenceBody, true, out initialVelocity, out finalVelocity);

            Vector3d currentInitialVelocity = o.SwappedOrbitalVelocityAtUT(initialT);

            return(initialVelocity - currentInitialVelocity);
        }
        //Computes the delta-V of a burn at a given time that will put an object with a given orbit on a
        //course to intercept a target at a specific interceptUT.
        public static Vector3d DeltaVToInterceptAtTime(Orbit o, double UT, Orbit target, double interceptUT, double offsetDistance = 0, bool shortway = true)
        {
            double   initialT      = UT;
            Vector3d initialRelPos = o.SwappedRelativePositionAtUT(initialT);
            double   finalT        = interceptUT;
            Vector3d finalRelPos   = target.SwappedRelativePositionAtUT(finalT);

            Vector3d initialVelocity, finalVelocity;

            LambertSolver.Solve(initialRelPos, finalRelPos, finalT - initialT, o.referenceBody, shortway, out initialVelocity, out finalVelocity);

            if (offsetDistance != 0)
            {
                finalRelPos += offsetDistance * Vector3d.Cross(finalVelocity, finalRelPos).normalized;
                LambertSolver.Solve(initialRelPos, finalRelPos, finalT - initialT, o.referenceBody, shortway, out initialVelocity, out finalVelocity);
            }

            Vector3d currentInitialVelocity = o.SwappedOrbitalVelocityAtUT(initialT);

            return(initialVelocity - currentInitialVelocity);
        }