-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPropagator.J2MeanElements.cs
193 lines (165 loc) · 7.12 KB
/
Propagator.J2MeanElements.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
using System;
using System.Linq;
using System.Windows.Forms;
using AGI.Foundation.Coordinates;
using AGI.Foundation;
using AGI.Foundation.Time;
// Edit By: Li Yunfei
// 20160822: 初次修改
namespace AeroSpace.Propagator
{
// Edit By: Li Yunfei
// 20160822: 初次修改
// 20160929: 增加InitialElement属性
// 20161108: 添加Name属性,及相应的构造函数
// 20170104: 给Name添加缺省名称"DefaultName"
/// <summary>
/// 地球J2项的平均轨道根数计算(仅考虑一、二阶长期项)
/// <para>采用刘林的平均根数公式,轨道平均角速度n仅与平均半长轴a相关,不含MeanAnomaly的长期项</para>
/// <para>RAAN考虑二阶长期项</para>
/// <para>注意单位的统一</para>
/// </summary>
public class J2MeanElements
{
/// <summary>
/// 编号
/// </summary>
public int Id { get; set; }
/// <summary>
/// (第8届轨道竞赛,碎片雷达散射面积)
/// </summary>
public int Sm { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
// 内部保留的初始 Kozai平均根数
public KeplerianElements KozaiMeanElement { get; private set; }
/// <summary>
/// 初始轨道根数(初始输入的)
/// </summary>
public KeplerianElements InitialElement { get; private set; }
/// <summary>
/// 引力常数
/// </summary>
public double Mu { get; set; }
/// <summary>
/// J2项系数(未归一化)
/// </summary>
public double J2 { get; set; }
/// <summary>
/// 参考椭球体半径
/// </summary>
public double Re { get; set; }
#region 私有字段
double unitT;
// 初始平均轨道根数
double sma;
double ecc;
double inc;
double RAAN;
double omg;
double ma;
// 一阶、二阶长期项
double n, madot, RAANdot, RAANdot2, omgdot;
#endregion
//#########################################################################################
/// <summary>
/// 构造函数
/// </summary>
/// <param name="elements">初始轨道根数(平瞬根数由inputIsMean决定)</param>
/// <param name="inputIsMean">true:平均根数;false:瞬时根数</param>
/// <param name="j2UnnormalizedValue">未归一化的J2项系数</param>
/// <param name="referenceDistance">参考半径(与elements单位一致)</param>
public J2MeanElements(KeplerianElements elements, bool inputIsMean, double j2UnnormalizedValue, double referenceDistance)
{
Name = "DefaultName";
Mu = elements.GravitationalParameter;
J2 = j2UnnormalizedValue;
Re = referenceDistance;
unitT = Math.Sqrt(Re * Re * Re / Mu);
// 保留初始输入的根数
InitialElement = elements;
// 利用kozai方法计算平均根数
KozaiIzsakMeanElements kozaiElement = new KozaiIzsakMeanElements(elements, inputIsMean, j2UnnormalizedValue, referenceDistance);
// 初始平均根数(Kozai)
KozaiMeanElement = kozaiElement.ToMeanKeplerianElements();
this.sma = KozaiMeanElement.SemimajorAxis / Re;
this.ecc = KozaiMeanElement.Eccentricity;
this.inc = KozaiMeanElement.Inclination;
this.RAAN = KozaiMeanElement.RightAscensionOfAscendingNode;
this.omg = KozaiMeanElement.ArgumentOfPeriapsis;
this.ma = KozaiMeanElement.ComputeMeanAnomaly();
// 计算长期项
// 以下公式皆为无量纲
double A2 = 1.5 * J2;
double sini2 = Math.Sin(inc) * Math.Sin(inc);
double sq1e2 = Math.Sqrt(1.0 - ecc * ecc);
double p2 = sma * sma * (1.0 - ecc * ecc) * (1.0 - ecc * ecc);
n = Math.Sqrt(1.0 / sma / sma / sma);
// 平近点角的一阶长期项
madot = A2 / p2 * n * (1 - 1.5 * sini2) * sq1e2;
// RAAN和Argument Of Periapse的一阶长期项
RAANdot = -A2 / p2 * n * Math.Cos(inc);
omgdot = A2 / p2 * n * (2 - 2.5 * sini2);
// RAAN的二阶长期项
RAANdot2 = -A2 * A2 / p2 / p2 * n * Math.Cos(inc) * ((1.5 + ecc * ecc / 6.0 + sq1e2) - (5.0 / 3.0 - 5.0 * ecc * ecc / 24.0 + 1.5 * sq1e2) * sini2);
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="elements">初始轨道根数(平瞬根数由inputIsMean决定)</param>
/// <param name="inputIsMean">true:平均根数;false:瞬时根数</param>
/// <param name="j2UnnormalizedValue">未归一化的J2项系数</param>
/// <param name="referenceDistance">参考半径(与elements单位一致)</param>
/// <param name="name">名称</param>
public J2MeanElements(KeplerianElements elements, bool inputIsMean, double j2UnnormalizedValue, double referenceDistance, string name)
: this(elements, inputIsMean, j2UnnormalizedValue, referenceDistance)
{
Name = name;
}
/// <summary>
/// 计算Dt时间后的平均根数(RAAN,omg,M考虑一阶长期项,RAAN考虑二阶长期项)
/// </summary>
/// <param name="dt">一段时间(s)</param>
/// <returns></returns>
public KeplerianElements ComputeMeanElementAfterDt(double dt)
{
// 无量纲时间
dt = dt / unitT;
double RAANt = Round2Pi(RAAN + (RAANdot + RAANdot2) * dt);
double omgt = Round2Pi(omg + omgdot * dt);
double mat = Round2Pi(ma + (n + madot) * dt);
double tat = KeplerianElements.MeanAnomalyToTrueAnomaly(mat, ecc);
// 返回dt时间后的平均根数
return new KeplerianElements(sma * Re, ecc, inc, omgt, RAANt, tat, Mu);
}
/// <summary>
/// 返回Dt时间后的平均根数(J2MeanElements类型)
/// </summary>
/// <param name="dt">一段时间(s)</param>
/// <returns></returns>
public J2MeanElements GetJ2MeanElementsAfterDt(double dt)
{
J2MeanElements tpmean = new J2MeanElements(ComputeMeanElementAfterDt(dt), true, J2, Re);
tpmean.Id = Id;
tpmean.Sm = Sm;
tpmean.Name = Name;
// 始终保留初始轨道根数
tpmean.InitialElement = this.InitialElement;
return tpmean;
}
static double Round2Pi(double theta)
{
while (theta < 0)
{
theta = theta + 2.0 * Math.PI;
}
while (theta > 2.0 * Math.PI)
{
theta = theta - 2.0 * Math.PI;
}
return theta;
}
}
}