// Perturb an orbit by a deltaV vector
        public static void Perturb(this Orbit orbit, Vector3d deltaVV, double universalTime, double deltaTime)
        {
            // If there is a deltaV, perturb orbit
            if (deltaVV.magnitude <= 0)
            {
                return;
            }

            // Transpose deltaVV Y and Z to match orbit frame
            Vector3d deltaVV_orbit = deltaVV.xzy;
            Vector3d position      = orbit.getRelativePositionAtUT(universalTime);

            Orbit orbit2 = orbit.Clone();

            orbit2.UpdateFromStateVectors(position, orbit.getOrbitalVelocityAtUT(universalTime) + deltaVV_orbit, orbit.referenceBody, universalTime);
            if (!double.IsNaN(orbit2.inclination) && !double.IsNaN(orbit2.eccentricity) && !double.IsNaN(orbit2.semiMajorAxis) && orbit2.timeToAp > deltaTime)
            {
                orbit.inclination         = orbit2.inclination;
                orbit.eccentricity        = orbit2.eccentricity;
                orbit.semiMajorAxis       = orbit2.semiMajorAxis;
                orbit.LAN                 = orbit2.LAN;
                orbit.argumentOfPeriapsis = orbit2.argumentOfPeriapsis;
                orbit.meanAnomalyAtEpoch  = orbit2.meanAnomalyAtEpoch;
                orbit.epoch               = orbit2.epoch;
                orbit.referenceBody       = orbit2.referenceBody;
                orbit.Init();
                orbit.UpdateFromUT(universalTime);
            }
            else
            {
                orbit.UpdateFromStateVectors(position, orbit.getOrbitalVelocityAtUT(universalTime) + deltaVV_orbit, orbit.referenceBody, universalTime);
                orbit.Init();
                orbit.UpdateFromUT(universalTime);
            }
        }
예제 #2
0
        // Constructor & calculate
        public void Propagate(Navigator navigator, Orbit orbit0, double UT0, double UTf, double dT, Control control, double m0in)
        {
            // Control parameters
            var throttle = control.throttle;
            var sailon = control.sailon;
            var frame = control.frame;

            // Update segment initial mass
            m0 = m0in;

            // Working orbit at each time step
            Orbit orbit = orbit0.Clone();

            // Number of time steps
            int nsteps = Convert.ToInt32(Math.Ceiling((UTf - UT0) / dT));

            // Last time step size
            double dTlast = (UTf - UT0) % dT;

            // Current universal time
            double UT;

            // Current mass
            double m0i = m0;

            // Reseting time step to sample orbits for saving
            double dTchoose = 0.0;

            // List of orbits to preview
            orbits = new List<Orbit>();

            // Add initial orbit
            orbits.Add(orbit0.Clone());

            // Iterate for nsteps
            for (int i = 0; i < nsteps; i++) {

            // Last step goes to UTf
            if (i == nsteps - 1) {
            dT = dTlast;
            UT = UTf;
            } else {
            UT = UT0 + i * dT;
            }

            // Spacecraft reference frame
            Quaternion sailFrame = frame.qfn(orbit, UT, control.angles);

            // Total deltaV vector
            Vector3d deltaVV = new Vector3d(0.0, 0.0, 0.0);

            // Accumulated mass change for all engines
            double dms = 0.0;

            // Iterate over engines
            foreach (var pe in navigator.persistentEngines) {

            // Only count thrust of engines that are not shut down in preview
            if (pe.engine.getIgnitionState) {

            // Thrust unit vector
            Vector3d thrustUV = sailFrame * new Vector3d(0.0, 1.0, 0.0);

            // Isp: Currently vacuum. TODO: calculate at current air pressure
            float isp = pe.engine.atmosphereCurve.Evaluate(0);

            // Thrust vector
            float thrust = throttle * pe.engine.maxThrust;

            // Calculate deltaV vector
            double demandMass;
            deltaVV += pe.CalculateDeltaVV(m0i, dT, thrust, isp, thrustUV, out demandMass);

            // Update mass usage
            dms += demandMass * pe.densityAverage;
            }
            }

            // Iterate over sails
            if (sailon) {
            foreach (var s in navigator.solarSails) {

            // Check if sail in sun
            double sunlightFactor = 1.0;
            if (!SolarSailPart.inSun(orbit, UT)) {
                sunlightFactor = 0.0;
            }

            // Normal vector
            Vector3d n = sailFrame * new Vector3d(0.0, 1.0, 0.0);

            // Force on sail
            Vector3d solarForce = SolarSailPart.CalculateSolarForce(s, orbit, n, UT) * sunlightFactor;

            // Sail acceleration
            Vector3d solarAccel = solarForce / m0i / 1000.0;

            // Update deltaVV
            deltaVV += solarAccel * dT;
            }
            }

            // Update starting mass for next time step
            m0i -= dms;

            // Update

            // Update orbit
            orbit.Perturb(deltaVV, UT);

            // Increment time step at which to sample orbits
            dTchoose += dT;

            // Orbit period
            double TP = orbit.period;

            // Decide whether to add orbit to list of orbits to draw
            if (i == nsteps - 1) { // Always add last orbit
            orbits.Add(orbit.Clone());
            } else if (dTchoose >= TP / 360) { // If 1/360th of current period passed, add orbit
            orbits.Add(orbit.Clone());
            // Reset dTchoose
            dTchoose = 0.0;
            }
            }

            // Update final mass
            m1 = m0i;
        }
        public double m1;                 // Final mass

        // Constructor & calculate

        public void Propagate(Navigator navigator, Orbit orbit0, double UT0, double UTf, double dT, Control control, double m0in)
        {
            // Control parameters
            var throttle = control.throttle;
            var sailon   = control.sailon;
            var frame    = control.frame;

            // Update segment initial mass
            m0 = m0in;

            // Working orbit at each time step
            Orbit orbit = orbit0.Clone();

            // Number of time steps
            int nsteps = Convert.ToInt32(Math.Ceiling((UTf - UT0) / dT));

            // Last time step size
            double dTlast = (UTf - UT0) % dT;

            // Current universal time
            double UT;

            // Current mass
            double m0i = m0;

            // Reseting time step to sample orbits for saving
            double dTchoose = 0.0;

            // List of orbits to preview
            orbits = new List <Orbit>();

            // Add initial orbit
            orbits.Add(orbit0.Clone());

            // Iterate for nsteps
            for (int i = 0; i < nsteps; i++)
            {
                // Last step goes to UTf
                if (i == nsteps - 1)
                {
                    dT = dTlast;
                    UT = UTf;
                }
                else
                {
                    UT = UT0 + i * dT;
                }

                // Spacecraft reference frame
                Quaternion sailFrame = frame.qfn(orbit, UT, control.angles);

                // Total deltaV vector
                Vector3d deltaVV = new Vector3d(0.0, 0.0, 0.0);

                // Accumulated mass change for all engines
                double dms = 0.0;

                // Iterate over engines
                foreach (var pe in navigator.persistentEngines)
                {
                    // Only count thrust of engines that are not shut down in preview
                    if (pe.engine.getIgnitionState)
                    {
                        // Thrust unit vector
                        Vector3d thrustUV = sailFrame * new Vector3d(0.0, 1.0, 0.0);

                        // Isp: Currently vacuum. TODO: calculate at current air pressure
                        float isp = pe.engine.atmosphereCurve.Evaluate(0);

                        // Thrust vector
                        float thrust = throttle * pe.engine.maxThrust;

                        // Calculate deltaV vector
                        double demandMass;
                        deltaVV += pe.CalculateDeltaVV(m0i, dT, thrust, isp, thrustUV, out demandMass);

                        // Update mass usage
                        dms += demandMass * pe.densityAverage;
                    }
                }

                // Iterate over sails
                if (sailon)
                {
                    foreach (var s in navigator.solarSails)
                    {
                        // Check if sail in sun
                        double sunlightFactor = 1.0;
                        if (!SolarSailPart.inSun(orbit, UT))
                        {
                            sunlightFactor = 0.0;
                        }

                        // Normal vector
                        Vector3d n = sailFrame * new Vector3d(0.0, 1.0, 0.0);

                        // Force on sail
                        Vector3d solarForce = SolarSailPart.CalculateSolarForce(s, orbit, n, UT) * sunlightFactor;

                        // Sail acceleration
                        Vector3d solarAccel = solarForce / m0i / 1000.0;

                        // Update deltaVV
                        deltaVV += solarAccel * dT;
                    }
                }

                // Update starting mass for next time step
                m0i -= dms;

                // Update

                // Update orbit
                orbit.Perturb(deltaVV, UT);

                // Increment time step at which to sample orbits
                dTchoose += dT;

                // Orbit period
                double TP = orbit.period;

                // Decide whether to add orbit to list of orbits to draw
                if (i == nsteps - 1)   // Always add last orbit
                {
                    orbits.Add(orbit.Clone());
                }
                else if (dTchoose >= TP / 360)     // If 1/360th of current period passed, add orbit
                {
                    orbits.Add(orbit.Clone());
                    // Reset dTchoose
                    dTchoose = 0.0;
                }
            }

            // Update final mass
            m1 = m0i;
        }
예제 #4
0
 public void SetOrbit(Orbit orbit)
 {
     m_orbit.Clone(orbit);
 }