/// <summary> /// J2积分器(惯性系中计算,无岁差章动),右函数采用J2Gravity模型 /// <para>积分变量仅位置、速度</para> /// <para>给position仅添加J2项右函数</para> /// <para>RKF7(8)数值积分器,缺省绝对和相对精度皆为1e-13</para> /// <para>Epoch属性需手动赋值</para> /// </summary> /// <param name="position">PropagationNewtonianPoint,单位:m,m/s</param> /// <param name="centralBody"></param> /// <param name="gravitationalParameter">引力常数GM(m^3/s^2)</param> /// <param name="j2UnnormalizedValue">J2</param> /// <param name="referenceDistance">Re(m)</param> /// <param name="absTolerance">RKF7(8)的绝对精度</param> /// <param name="relRolerance">RKF7(8)的相对精度</param> public PropagatorDefinitionPureJ2(PropagationNewtonianPoint position, CentralBody centralBody, double gravitationalParameter = 3.986004418e14, double j2UnnormalizedValue = 0.001082629989052, double referenceDistance = 6378137.0, double absTolerance = 1e-13, double relRolerance = 1e-13) { // 中心天体的J2项引力摄动(含中心引力,中心天体的惯性系中计算),无岁差章动 J2Gravity gravity = new J2Gravity(position.IntegrationPoint, centralBody, gravitationalParameter, j2UnnormalizedValue, referenceDistance); // 添加右函数 position.AppliedForces.Clear(); position.AppliedForces.Add(gravity); // 积分变量 this.IntegrationElements.Add(position); // RKF7(8)数值积分器 RungeKuttaFehlberg78Integrator integrator = new RungeKuttaFehlberg78Integrator(); integrator.AbsoluteTolerance = absTolerance; integrator.RelativeTolerance = relRolerance; integrator.InitialStepSize = 60.0; integrator.StepSizeBehavior = KindOfStepSize.Relative; integrator.MaximumStepSize = 200.0; integrator.MinimumStepSize = 1.0; //* This is STK's default and truncates each step to 3 decimal places integrator.StepTruncationOrder = -3; this.Integrator = integrator; }
/// <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(); }
/// <summary> /// 构造函数,给定瞬时点、中心天体、引力常数、J2项系数、参考半径 /// <para>缺省:忽略偏微分</para> /// </summary> /// <param name="targetPoint">计算引力的瞬时点(位置、速度)</param> /// <param name="centralBody">中心天体</param> /// <param name="gravitationalParameter">引力常数</param> /// <param name="j2UnnormalizedValue">J2项系数</param> /// <param name="referenceDistance">参考半径</param> public J2Gravity(Point targetPoint, CentralBody centralBody, double gravitationalParameter, double j2UnnormalizedValue, double referenceDistance) : base(RoleOfForce.Principal, KindOfForce.NewtonianSpecificForce) { this.m_ignorePartials = false; this.m_targetPoint = targetPoint; this.m_centralBody = centralBody; this.m_gravitationalParameter = gravitationalParameter; this.m_j2ZonalHarmonicCoefficient = j2UnnormalizedValue; this.m_referenceDistance = referenceDistance; }
//######################################################################################### #region 构造函数 /// <summary> /// 构造函数,缺省使用中心天体:地球(J2项系数为0) /// </summary> //public J2Gravity() // : base(RoleOfForce.Principal, KindOfForce.NewtonianSpecificForce) //{ // CentralBodiesFacet fromContext = CentralBodiesFacet.GetFromContext(); // this.m_centralBody = fromContext.Earth; // this.m_gravitationalParameter = WorldGeodeticSystem1984.GravitationalParameter; // this.J2ZonalHarmonicCoefficient = 0.0; // this.m_referenceDistance = m_centralBody.Shape.SemimajorAxisLength; //} /// <summary> /// 构造函数,缺省使用中心天体:地球(J2项系数为0) /// </summary> /// <param name="targetPoint">计算引力的瞬时点(位置、速度)</param> //public J2Gravity(Point targetPoint) // : this() //{ // this.m_targetPoint = targetPoint; //} /// <summary> /// 构造函数,从已有对象复制 /// </summary> /// <param name="existingInstance">已有对象</param> /// <param name="context">A CopyContext that controls the depth of the copy.</param> protected J2Gravity(J2Gravity existingInstance, CopyContext context) : base(existingInstance, context) { this.m_centralBody = context.UpdateReference <CentralBody>(existingInstance.m_centralBody); this.m_gravitationalParameter = existingInstance.m_gravitationalParameter; this.m_ignorePartials = existingInstance.m_ignorePartials; this.m_targetPoint = context.UpdateReference <Point>(existingInstance.m_targetPoint); this.m_j2ZonalHarmonicCoefficient = existingInstance.m_j2ZonalHarmonicCoefficient; this.m_referenceDistance = existingInstance.m_referenceDistance; }
/// <summary> /// Positions the camera to view a given extent on the surface from a given azimuth and elevation angle. /// </summary> public static void ViewExtent(Insight3D insight3D, CentralBody centralBody, double west, double south, double east, double north, double azimuthAngle, double elevationAngle) { var camera = insight3D.Scene.Camera; camera.ViewExtent(centralBody, west, south, east, north); var offset = new Cartesian(new AzimuthElevationRange(azimuthAngle, elevationAngle, camera.Distance)); camera.Position = camera.ReferencePoint + offset; }
/// <summary> /// Positions the camera to view a given bounding sphere from a given azimuth and elevation angle. /// </summary> public static void ViewBoundingSphere(Insight3D insight3D, CentralBody centralBody, BoundingSphere sphere, double azimuthAngle, double elevationAngle) { var boundingSphereCenter = new PointFixedOffset(centralBody.FixedFrame, sphere.Center); var boundingSphereAxes = new AxesEastNorthUp(centralBody, boundingSphereCenter); var camera = insight3D.Scene.Camera; var offset = new Cartesian(new AzimuthElevationRange(azimuthAngle, elevationAngle, camera.DistancePerRadius * sphere.Radius)); camera.ViewOffset(boundingSphereAxes, boundingSphereCenter, offset); }
/// <summary> /// J2积分器(惯性系中计算,含岁差章动),右函数采用SphericalHarmonicGravity模型 /// <para>积分变量仅位置、速度</para> /// <para>给position仅添加J2项右函数</para> /// <para>RKF7(8)数值积分器,缺省绝对和相对精度皆为1e-13</para> /// <para>Epoch属性需手动赋值</para> /// </summary> /// <param name="position">PropagationNewtonianPoint,单位:m,m/s</param> /// <param name="centralBody"></param> /// <param name="gravitationalParameter">引力常数GM(m^3/s^2)</param> /// <param name="j2UnnormalizedValue">J2</param> /// <param name="referenceDistance">Re(m)</param> /// <param name="absTolerance">RKF7(8)的绝对精度</param> /// <param name="relRolerance">RKF7(8)的相对精度</param> public PropagatorDefinitionJ2(PropagationNewtonianPoint position, CentralBody centralBody, double gravitationalParameter = 3.986004418e14, double j2UnnormalizedValue = 0.001082629989052, double referenceDistance = 6378137.0, double absTolerance = 1e-13, double relRolerance = 1e-13) { // 中心天体的J2项引力摄动(含中心引力,中心天体的惯性系中计算),含岁差章动 SphericalHarmonicGravity gravity = new SphericalHarmonicGravity(); gravity.TargetPoint = position.IntegrationPoint; //* Will represent the position during propagation double[][] coe = new double[3][]; coe[0] = new double[1]; coe[1] = new double[2]; coe[2] = new double[3]; SphericalHarmonicGravityModel gravityModel = new SphericalHarmonicGravityModel("WGS84", centralBody.Name, gravitationalParameter, referenceDistance, new double[] { 1.0, 0.0, j2UnnormalizedValue }, coe, coe, false, false); int degree = 2; int order = 0; bool includeTwoBodyForce = true; gravity.GravityField = new SphericalHarmonicGravityField(gravityModel, degree, order, includeTwoBodyForce, SphericalHarmonicsTideType.None); // 添加右函数 position.AppliedForces.Clear(); position.AppliedForces.Add(gravity); // 积分变量 this.IntegrationElements.Add(position); // RKF7(8)数值积分器 RungeKuttaFehlberg78Integrator integrator = new RungeKuttaFehlberg78Integrator(); integrator.AbsoluteTolerance = absTolerance; integrator.RelativeTolerance = relRolerance; integrator.InitialStepSize = 60.0; integrator.StepSizeBehavior = KindOfStepSize.Relative; integrator.MaximumStepSize = 200.0; integrator.MinimumStepSize = 1.0; //* This is STK's default and truncates each step to 3 decimal places integrator.StepTruncationOrder = -3; this.Integrator = integrator; }
/// <summary> /// Handles updating the various central body lists if the primary central body changes. /// </summary> /// <param name="sender">What fired this event.</param> /// <param name="e">Additional information about this event.</param> private void OnPrimaryCBSelectedIndexChanged(object sender, EventArgs e) { if (m_primaryCB.SelectedItem.ToString() != m_lastCB) { m_thirdBodies.Items.Remove(m_primaryCB.SelectedItem.ToString()); m_thirdBodies.Items.Add(m_lastCB); m_lastCB = m_primaryCB.SelectedItem.ToString(); if (m_primaryCB.SelectedItem.ToString() != EARTH) { // we only have drag models for the earth m_lastDragChecked = m_useDrag.Checked; m_useDrag.Checked = false; m_useDrag.Enabled = false; } else { m_useDrag.Checked = m_lastDragChecked; m_useDrag.Enabled = true; } CurrentCentralBodysGravitationalParameter = m_gravConstants[m_primaryCB.SelectedItem.ToString()]; CurrentCentralBody = CentralBodiesFacet.GetFromContext().GetByName(m_primaryCB.SelectedItem.ToString()); } }
/// <summary> /// Positions the camera to view a given extent on the surface from a given azimuth and elevation angle. /// </summary> public static void ViewExtent(Insight3D insight3D, CentralBody centralBody, CartographicExtent extent, double azimuthAngle, double elevationAngle) { ViewExtent(insight3D, centralBody, extent.WestLongitude, extent.SouthLatitude, extent.EastLongitude, extent.NorthLatitude, azimuthAngle, elevationAngle); }
/// <summary> /// Positions the camera to view a given bounding sphere. /// </summary> public static void ViewBoundingSphere(Insight3D insight3D, CentralBody centralBody, BoundingSphere sphere) { ViewBoundingSphere(insight3D, centralBody, sphere, Trig.DegreesToRadians(-90.0), Trig.DegreesToRadians(-30.0)); }
// Edit By: Li Yunfei // 20161208: 初次编写 // 20170104: 使用Orbitbase中的常数 /// <summary> /// 中心天体J2项摄动力(含中心引力,惯性系中计算,含岁差章动),右函数采用SphericalHarmonicGravity模型 /// <para>**缺省单位:m,m/s</para> /// <para>**Mu,J2,Re默认采用缺省值</para> /// </summary> /// <param name="position">PropagationNewtonianPoint,单位:m,m/s</param> /// <param name="centralBody"></param> /// <param name="gravitationalParameter">引力常数GM(m^3/s^2)</param> /// <param name="j2UnnormalizedValue">J2</param> /// <param name="referenceDistance">Re(m)</param> public static SphericalHarmonicGravity GetJ2Gravity(PropagationNewtonianPoint position, CentralBody centralBody, double gravitationalParameter = OrbitBase.EarthMu, double j2UnnormalizedValue = OrbitBase.EarthJ2, double referenceDistance = OrbitBase.EarthRe) { // 中心天体的J2项引力摄动(含中心引力,中心天体的惯性系中计算),含岁差章动 SphericalHarmonicGravity gravity = new SphericalHarmonicGravity(); gravity.TargetPoint = position.IntegrationPoint; //* Will represent the position during propagation // 单位一致性检查 if (gravitationalParameter > 1e10 && (referenceDistance < 1e6 || position.InitialPosition.Magnitude < 1e6)) { throw new Exception("单位不一致Gm/Re/position!"); } if (gravitationalParameter < 1e10 && (referenceDistance > 1e6 || position.InitialPosition.Magnitude > 1e6)) { throw new Exception("单位不一致Gm/Re/position!"); } double[][] coe = new double[3][]; coe[0] = new double[1]; coe[1] = new double[2]; coe[2] = new double[3]; SphericalHarmonicGravityModel gravityModel = new SphericalHarmonicGravityModel("WGS84", centralBody.Name, gravitationalParameter, referenceDistance, new double[] { 1.0, 0.0, j2UnnormalizedValue }, coe, coe, false, false); int degree = 2; int order = 0; bool includeTwoBodyForce = true; gravity.GravityField = new SphericalHarmonicGravityField(gravityModel, degree, order, includeTwoBodyForce, SphericalHarmonicsTideType.None); return(gravity); }