/// <summary> /// 构造函数(注意单位的一致性) /// </summary> /// <param name="t0">初始时刻(s),没有多大意义</param> /// <param name="elements">初始轨道根数</param> /// <param name="j2UnnormalizedValue">J2项系数</param> /// <param name="referenceDistance">参考椭球体半长轴</param> public J2NumericalPropagator(double t0, KeplerianElements elements, double j2UnnormalizedValue, double referenceDistance) : this(elements.GravitationalParameter, j2UnnormalizedValue, referenceDistance) { this.T0 = t0; // 初始位置、速度 InitialCondition = elements.ToCartesian(); }
/// <summary> /// Propagate a Platform using a NumericalPropagator configured with the entered KeplerianElements, /// ForceModels, NumericalIntegrator, and start and stop dates. /// </summary> private void PropagateSatellite() { KeplerianElements orbitalElements = m_keplerianOrbitalElementsEntry.KeplerianElementValues; if (orbitalElements == null) { return; } Motion <Cartesian> initialMotion = orbitalElements.ToCartesian(); PropagationNewtonianPoint point = new PropagationNewtonianPoint(m_elementID, m_forceModelSettings.CurrentCentralBody.InertialFrame, initialMotion.Value, initialMotion.FirstDerivative); point.Mass = new ScalarFixed(double.Parse(m_mass.Text)); m_forceModelSettings.SetForceModelsOnPoint(point, new ScalarFixed(double.Parse(m_area.Text))); CentralBody primaryCentralBody = m_forceModelSettings.CurrentCentralBody; NumericalPropagatorDefinition state = new NumericalPropagatorDefinition(); state.IntegrationElements.Add(point); state.Integrator = m_integratorSettings.GetIntegrator(); JulianDate start = new JulianDate(GregorianDate.ParseExact(m_start.Text, DateFormat, null)); JulianDate end = new JulianDate(GregorianDate.ParseExact(m_end.Text, DateFormat, null)); state.Epoch = start; NumericalPropagator propagator = state.CreatePropagator(); propagator.StepTaken += (sender, args) => { // Telling the propagator to stop if we get too close to the central body Cartesian position = propagator.Converter.ConvertState <Cartesian>(m_elementID, args.CurrentState).Value; if (position.Magnitude <= primaryCentralBody.Shape.SemimajorAxisLength + 10000) { args.Indication = PropagationEventIndication.StopPropagationAfterStep; } }; DateMotionCollection <Cartesian> answer = null; var backgroundCalculation = new BackgroundCalculation(); backgroundCalculation.DoWork += (sender, e) => { // actually propagate var result = propagator.Propagate(end.Subtract(start), 1, backgroundCalculation); answer = result.GetDateMotionCollection <Cartesian>(m_elementID); }; backgroundCalculation.ProgressChanged += (sender, e) => m_propagationProgress.Value = e.ProgressPercentage; backgroundCalculation.RunWorkerCompleted += (sender, e) => { // when finished, draw the satellite DrawSatellite(answer, primaryCentralBody.InertialFrame); m_propagate.Enabled = true; }; m_propagate.Enabled = false; backgroundCalculation.RunWorkerAsync(); }
public static void TestLamber1() { double Gm = 3.986e14; double sma = 7000000; double ecc = 0.09956; double f1 = 0.0; double f2 = Math.PI; //double f2 = 1.0; //double f2 = 5.0; KeplerianElements k1 = new KeplerianElements(sma, ecc, 0.2, 0.4, 1.0, f1, Gm); KeplerianElements k2 = new KeplerianElements(sma, ecc, 0.2, 0.4, 1.0, f2, Gm); double tof = KeplerianElements.ComputeTimeOfFlight(f1, f2, sma, ecc, Gm); Motion <Cartesian> rv1 = k1.ToCartesian(); Motion <Cartesian> rv2 = k2.ToCartesian(); Cartesian v1p, v2p; Lambert_RhGooding(Gm, rv1.Value, rv1.FirstDerivative, rv2.Value, rv2.FirstDerivative, tof, out v1p, out v2p); Cartesian dv1 = v1p - rv1.FirstDerivative; Cartesian dv2 = v2p - rv2.FirstDerivative; }