// 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); } }
// 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; }
public void SetOrbit(Orbit orbit) { m_orbit.Clone(orbit); }