APP下载

光学观测中几种太阳夹角计算方法及精度分析

2022-12-26虞炳文娄广国蔡红维周小杰

计算机测量与控制 2022年12期
关键词:弧度计算公式夹角

虞炳文,娄广国,蔡红维,周小杰,杨 宏

(西昌卫星发射中心,四川 西昌 615000)

0 引言

在航天发射、低轨卫星长期在轨运行管理,以及天文观测中,光学观测是一个重要且不可或缺的的观测方式,光学观测具备别的测量控制设备所不具备的优势,比如直观,在光学影像中,可以很直观的看见飞行器的外部状态,另外,光学观测的测角精度较高,可以作为飞行器在空间中位置的一个重要参考量。尤其在航天发射的起飞阶段中,光学观测设备是重要的辅助决策判决的手段,在发射场中得到了大量的运用。但是制约光学设备使用并发挥作用的限制条件也较为明显,除了包括山体、云等遮蔽物之外,直面部分强光源的物体的直射,可能会对光学设备的感光模块造成不可逆转的破坏,其中较为明显的,就是太阳以及月球的光线直射,因此,如何通过准确计算出飞行器与太阳的夹角,以达到有效规避强光直射的风险,避免太阳对光学设备的损坏,是文中将要论述的重点。

在计算飞行器与太阳夹角的过程中,有很多的算子可供选择,可区分为简单算子和复杂算子,简单算子的优势是只需要少量的参数即可计算出结果,但是精度相对较低,复杂算子的优势是计算精度高,但是其需要装填的参数较多,甚至有些参数需要专业设备才能测得,在日常使用中并不便捷。因此在日常使用中,通常会选用精度较高的简单算子来替代复杂算子,本文将通过计算及精度分析,论证简单算子中与复杂算子计算结果最为接近的算子组合,以达到在简单便捷使用的同时,又能保证一定的精度。

1 计算太阳赤纬及太阳时角

首先需要介绍一下什么是太阳赤纬及太阳时角。

1.1 太阳赤纬和时角的基本概念

要梳理清楚什么是太阳赤纬和时角,需要首先建立天球这个天文学概念。

1.1.1 天球坐标系的概念

首先需要理解的是,天球是一个无限大的球体,距离在这里没有意义,在天球坐标系中,天球的中心可以是任何的星球,虽然一般情况下,会将地球放在天球的中心。换言之,地球在天球的中心位置,此时的天球可以理解成,地球居民在地球上的观察视角,在某个位置,如果足够高,四周没有遮挡,观察者所能看见的就是半个天穹,即以观察者所在位置为切点的,与地球球体相切的一个无限延展的平面,理论上,因为观察者所观察的是整个宇宙,距离无穷远,此时观察者所站立的地球,其本身的半径相比较无穷大而言,可以忽略不计,因此,此时整个宇宙的所有星球,都可以区分为两种位置,一种是平面以上,一种是平面以下。

因此,可以简单地认为,观察者在任何一个位置,都能观察到其所在切平面以上的,即半个宇宙的所有星球,因为很难去准确知晓某个星球距离地球的位置,所以在天球坐标系中需要将距离的概念淡化,而淡化距离概念的最简单直接的方法,就是将所有的星球与地球的距离都假设成相同,即将所有的星球都放在同一个球面上,当忽略了距离,此时想要标识某个星球的位置,就只需要用到两个参数值,即一个用来标识其纵向上的位置,一个用来标识其横向上的位置的数值。

在天球坐标系中,选用何种标准来标识一个方位和一个俯仰上的值,其最简单直接的想法便是,既然都是球体,日常用来标识地球球体的经纬度体系,可否用来标识天球的度量体系?原理上是可以的,事实上也正是如此的。因此在天球坐标系的度量体系中,实际上选用了一套和地球大地坐标系同样的度量方式,区别在于地球坐标系中使用的经纬度和高程,而在天球坐标系中因为淡化了距离的概念,将所有的星球都假设在了同一距离的球面上,所以并不需要高程这一参数值,因为需要高程的地方所需的一个基本特征是能够测量高程,而在宇宙尺度下,距离是很难被获取的。将星球的距离都假设在同一个平面上的过程,也就是常说的投影。天球坐标系仅仅参考了地球大地坐标系的经纬度值,在天球坐标系中,这两个参数值被称之为赤经和赤纬。

在天球坐标系中,天球的中心是地球的中心。因为观察者虽然并不在地球中心观察,但是因为观察者所在的地球表面,其距离地球中心的距离,相比较天球无限大的距离来说,可以忽略不记,因此可以简单认为,观察者所在的位置就是地球中心。

1.1.2 天球坐标系

同样一个天球,根据定义的经过球心的水平面不同,可以区分为多种天球坐标系,在此重点介绍常见的天球坐标系有三种。

首先是经过球心的平面为赤道面时,该处所指赤道便是地球赤道经过往外无限延伸,最终势必将会与天球相交,此时便形成了第二赤道坐标系,此时的赤道面称之为天赤道,经地心,作一条与天赤道垂直的无限延长的线,与天球相交于两点,即图 1中所示P点(天北极)与P′点(天南极)。

图1 天球示意图

然后是将地球与太阳放在同一个平面上,所形成的平面,称之为黄道面,以此为基准,便是黄道坐标系,仅靠地球与太阳两点不能确认一个平面,还需要一到两个点,这另外两个点的选择,便是春分点和秋分点,即太阳直射点穿过赤道时的两个点。经过地心,作一条与黄道面垂直的直线,与天球相交于两点,便是图 1中的Q(黄北极)和Q′(黄南极)点。黄道面与赤道面相交所形成的夹角,便是黄赤交角。

最后还需要介绍的便是以观察者所在位置,所作的与地球相交的平面,称之为地平面,此时的地平面,在宇宙维度内,可以认为是经过地球地心的一个平面,过地心作一条垂直于地平面的直线,与天球相交于两点,即观察者的头顶与脚底,见图1中Z(天顶)和Z′(天底)。

1.1.3 对天球上的常用点线面的理解

对图 1中所涉及的标注进行解释。

F点指的是飞行器,G点指的时太阳,飞行器在此时,也可以当成一个映射在天球球面上的物体,M点为地球上观察者的位置,过天北极P点与天南极P′的赤经圈称之为天子午圈,天子午圈可以有很多条,但是通过天顶Z的,只有一个圈,称之为本初子午圈,即图 1中所画弧线PZP′所在圆。

C点为春分点,需要重点介绍一下,在后续计算过程中,很多的运算的数值,都与此概念相关。春分点时黄道面和赤道面的相交点,即太阳直射点从南向北经过赤道的那个点,这个点并不是一个实际上地球地理坐标点,是无法用经纬度表示的,春分点是两个平面的交点,始终处在两个平面的相交处。天文学上,将春分点作为很多天文概念的起算点,比如恒星时,比如太阳赤经。

太阳赤纬角为地心与太阳的连线与天赤道面的夹角,即图 1中δ角。

太阳赤经角,从春分点C向东,一直到太阳在天赤道上的投影线之间的夹角,即春分点所在的赤经圈与太阳所在的赤经圈之间的夹角,称之为赤经角,即图 1中的β角。

太阳时角,是从本初子午圈与天赤道相交的点向西,即太阳所在的赤经圈与本初子午圈之间的夹角,即图 1中的γ角。

最终需要求解的是太阳夹角,即从地球上某个位置观察飞行器和太阳时,太阳和飞行器之间的夹角,即图 1中的α角。

在此需要特别注意的是,上述涉及的天文概念中,前缀往往都带着参考的星球的名称,比如太阳,之所以这么解释,是因为可以不是太阳,可以是宇宙中任何一个天体,比如银河系的中心作为参考的银河坐标系。在本文中所涉及的未特别声明的天文概念,均以太阳作为参考。

1.2 太阳赤纬的计算方法

要计算太阳夹角,首先需要解决的问题,便是如何准确计算天球坐标系下,太阳赤纬及太阳时角的值。首先计算太阳赤纬的值。

计算太阳赤纬值的方法有很多,常见的简单算法有Cooper算法、Spencer算法、Stine算法、Bourges算法、Wang算法、Yu算法,上述六种算法均基于天文观测数据,通过公式拟合提出的数学公式,另外还可以通过对天文观测数据的数值拟合算法,求出拟合度更高的计算公式,只是通过该方法提出的公式,其系数会因年而异,所以不具备普适性,另外,李文提出通过傅里叶展开法提出对拟合公式的改进算法。除数学拟合算法之外,还有一种基于VSOP87行星理论,演算推导算法的方法。

下面结合C++代码语言,对太阳赤纬各算法进行逐个分析计算。

1.2.1 Bourges算子

Bourges是由Bourges提出的,Bourges算子的公式如下所示。其中ω为弧度参考系数,t为等效计日序数。太阳赤纬角的单位为弧度。

δ=0.3723+23.2567sin(ωt)+0.1149sin(2ωt)-0.1712sin(3ωt)-0.7580cos(ωt)+0.3656cos(2ωt)+0.02010cos(3ωt)

(1)

弧度参考系数如下所示:

(2)

计日序数的计算如下所示。其中dn为计日序数,即本年度的第几天。

t=dn-1-n0

(3)

n0的的计算公式如下,其中n表示年份,如本年度为2022年,则n=2022。

n0=78.801+[0.2422(n-1969)]-int[0.25(n-1969)]

(4)

Bourges算法实现的代码如下:

double Bourges(cDateTime date)

{

int n=getDaysOfYear(date);

int temp=0.25*(date.year-1969);

double n0=78.801+0.2422*(date.year-1969)-temp;

double t=n-1-n0;//等效计日序数

double w=2*M_PI/365.2422;//参考弧度系数

double dellta=0.3723+23.2567*sin(w*t)+0.1149*sin(2*w*t)-0.1712*sin(3*w*t)-0.7580*cos(w*t)+0.3656*cos(2*w*t)+0.0201*cos(3*w*t);

return dellta/180.0*M_PI;//弧度

}

1.2.2 Cooper算子

Cooper算子是由Cooper提出的,Cooper算子的公式如下所示。公式中n为该年度中的天数累计值,如1月11日,则n=11。太阳赤纬角的返回值单位是弧度。

(5)

δ为太阳赤纬角。代码实现如下:

double Cooper(cDateTime date)

{

int n=getDaysOfYear(date);

double dellta;

dellta=23.45*sin(2*M_PI*(284.0+n)/365.0);

return dellta/180.0*M_PI;//弧度

}

1.2.3 Spencer算子

Spencer算子是由Spencer提出的,其中太阳赤纬角的单位为弧度,θ为日角。算法公式如下所示:

δ=0.006918-0.399912cos(θ)+0.070257sin(θ)-0.006758cos(2θ)+0.000907sin(2θ)-0.002697cos(3θ)+0.00148sin(3θ)

日角的计算公式如下所示:

(6)

Spencer算子的实现代码如下:

double Spencer(cDateTime date)

{

int n=getDaysOfYear(date);

double gamma=2*M_PI*(n-1)/365.0;//日角

double dellta=0.006918-0.399912*cos(gamma)+0.070257*sin(gamma)-0.006758*cos(2*gamma)+0.000907*sin(2*gamma)-0.002697*cos(3*gamma)+0.00148*sin(3*gamma);

return dellta;//弧度

}

1.2.4 Yu算子

Yu算子是由Yu提出来的,是在Spencer算子的基础上做的简化,计算得到的太阳赤纬角单位为弧度。θ为日角,公式如下:

δ=0.006918-0.399912cos(θ)+0.070257sin(θ)-0.006758cos(2θ)+0.000907sin(2θ)

(7)

其中的日角的计算公式如下:

(8)

实现Yu算法的代码如下:

double Yu(cDateTime date)

{

int n=getDaysOfYear(date);

double theT=2*M_PI*(n-1)/365;//日角

double dellta=0.006918-0.399912*cos(theT)+0.070257*sin(theT)-0.006758*cos(2*theT)+0.000907*sin(2*theT);

return dellta;//弧度

}

1.2.5 Stine算子

Stine算子是由Stine提出的,其中太阳赤纬角的单位为弧度,其中n为计日序数,即本年度的第几天。

Stine算法的实现代码如下:

double Stine(cDateTime date)

{

int n=getDaysOfYear(date);

double dellta=asin(0.39795*cos(2*M_PI*(n-173)/365.242));

return dellta;//弧度

}

1.2.6 Wang算子

Wang算子是由王炳忠在Bourges的基础上,针对计日系数,修改了部分系数,并将起算年份从1969改为了1985,使得其更加贴近真实值。计算所得的太阳赤纬角的单位为弧度。公式如下所示,与Bourges算子相同。太阳赤纬角的单位为弧度。

δ=0.3723+23.2567sin(ωt)+0.1149sin(2ωt)-0.1712sin(3ωt)-0.7580cos(ωt)+0.3656cos(2ωt)+0.02010cos(3ωt)

(9)

其中的弧度参考系数也与Bourges相同。如下所示:

(10)

以及等效计日序数的算法也是相同的,如下:

t=dn-1-n0

(11)

与Bourges不同的是对n0的计算,如下所示:

n0=79.6764+[0.2422(n-1985)]-int[0.25(n-1985)]

(12)

Wang算法的实现代码如下所示:

double Wang(cDateTime date)

{

int n=getDaysOfYear(date);

int year=date.year;

int temp=0.25*(year-1985);

double n0=79.6764+0.2422*(year-1985)-temp;

double t=n-1-n0;//等效计日序数

double w=2*M_PI/365.2422;//参考弧度系数

double dellta=0.3723+23.2567*sin(w*t)+0.1149*sin(2*w*t)-0.1712*sin(3*w*t)-0.7580*cos(w*t)+0.3656*cos(2*w*t)+0.0201*cos(3*w*t);

return dellta/180.0*M_PI;//弧度

}

1.2.7 数值拟合法

数值拟合法是由李文提出的,根据2015年-2018年的天文年历,提出使用积日因子β作为多项式的中间系数,进行拟合计算。得到适2015-2018年的年份的改进公式。

太阳赤纬角的单位为弧度,其中太阳赤纬角的计算公式如下,其中的β为积日因子,ak为系数。

(13)

积日因子的求解公式如下所示。其中dn为积日系数。

(14)

n0的计算公式如下所示:

n0=79.6764+0.2422(n-1985)-int(n-1985)

(15)

数值拟合算法的代码如下所示:

double NumericalFitting(cDateTime date)

{

int n=getDaysOfYear(date);

int year=date.year;

int temp=year-1985;

double n0=79.6764+0.2422*(year-1985)-temp;

double b=2*M_PI*(n-1-n0)/365.2422;

int L=(year-2015)%4;

double dellta=0;

if(L==0)

{

dellta=calDellta(b,0.38835,22.911,-0.49055,-3.1217,0.043485,-0.19959,0.12879,0.045704,-0.040516,0.010031,-1.0946e-3,4.5142e-5);

}else if(L==1){

dellta=calDellta(b,0.38879,22.909,-0.49009,-3.1203,0.041657,-0.19950,0.12971,0.045246,-0.040482,0.010056,-1.1011e-3,4.5598e-5);

}else if(L==2){

dellta=calDellta(b,0.38769,22.909,-0.49277,-3.1178,0.046562,-0.20471,0.12953,0.047321,-0.041560,0.010309,-1.1302e-3,4.6935e-5);

}else if(L==3){

dellta=calDellta(b,0.38702,22.910,-0.49060,-3.1193,0.044708,-0.20270,0.12943,0.046646,-0.041166,0.010207,-1.1175e-3,4.6298e-5);

}

return dellta/180.0*M_PI;//弧度

}

double calDellta(double b, double a0,double a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9, double a10, double a11)

{

double dellta=a0*pow(b,0)+a1*pow(b,1)+a2*pow(b,2)+a3*pow(b,3)+a4*pow(b,4)+a5*pow(b,5)+a6*pow(b,6)+a7*pow(b,7)+a8*pow(b,8)+a9*pow(b,9)+a10*pow(b,10)+a11*pow(b,11);

return dellta;

}

1.2.8 傅里叶展开法

傅里叶展开法是由李文提出的,在数值拟合法的基础上,进行的改进算法,通过观察连续的太阳赤纬角的变化规律,发现太阳赤纬角的变化具备周期性,每4年一个循环,因此将算法的周期,从1年修改为4年,定义算法中的年份为每个周期中的第三年,并且将计日序数从之前的1年中的第几天,改成整个4年周期中的第几天,即总的计日序数。

得到的太阳赤纬角的值,单位为弧度,其中β为积日因子。计算公式如下所示:

(16)

积日因子的计算公式如下所示,其中dn为积日系数。

(17)

式中,n0表达式如下所示:

n0=79.6764+0.2422(n-1985)-int(n-1985)

(18)

傅里叶展开法的计算公式如下所示:

double FourierBaseNF(cDateTime date)

{

int n=getDaysOfYear(date);

int year=date.year;

int y=0;//周期内的第3个年份

int dn=0;//周期内的总计日序数

if(year>=2015)

{

y=((year-2015)/4)*4+2017;

}else{

y=2013-((2015-year)/4)*4;

}

int temp=(year-3)%4;//这是周期内的第几年

if(temp==0)

{

dn=n;

}else if(temp==1)

{

if(QDate::isLeapYear(year-1))

{

dn=dn+366;

}else {

dn=dn+365;

}

dn=dn+n;

}else if(temp==2)

{

if(QDate::isLeapYear(year-2))

{

dn=dn+366;

}else {

dn=dn+365;

}

if(QDate::isLeapYear(year-1))

{

dn=dn+366;

}else {

dn=dn+365;

}

dn=dn+n;

}else if(temp==3)

{

if(QDate::isLeapYear(year-3))

{

dn=dn+366;

}else {

dn=dn+365;

}

if(QDate::isLeapYear(year-2))

{

dn=dn+366;

}else {

dn=dn+365;

}

if(QDate::isLeapYear(year-1))

{

dn=dn+366;

}else {

dn=dn+365;

}

dn=dn+n;

}

double n0=79.6764+0.2422*(y-1985)-int(y-1985);

double b=2*M_PI*(dn-1-n0)/365.2422;

double dellta=calFourierBaseNF(b,0.3783,-0.5624,0.3654,0.0156,-0.007662,-0.0005366,23.25,0.1082,-0.1705,-0.002773,0.003393);

return dellta/180.0*M_PI;//弧度

}

double calFourierBaseNF(double b,double a0,double a1,double a2,double a3,double a4,double a5,double b1,double b2,double b3,double b4,double b5)

{

double dellta=a0+a1*cos(b)+a2*cos(2*b)+a3*cos(3*b)+a4*cos(4*b)+a5*cos(5*b)+b1*sin(b)+b2*sin(2*b)+b3*sin(3*b)+b4*sin(4*b)+b5*sin(5*b);

return dellta;

}

1.2.9 VSOP87行星理论

VSOP87理论是由Bretagnon和Francou在1987年提出的,是VSOP82理论的进一步完善,VSOP理论是用来描述太阳系范围内的行星的轨道,在很长时间内的周期性变化的一种半分析理论。

VSOP形形理论除了可以算出精确的行星轨道参数,还可以直接计算出行星的位置,在此所言的位置,包含各种坐标系在内,如黄道坐标系。

计算VSOP87计算太阳赤纬角的过程,大致可分为七步。

1)计算儒略日数,用J表示。

2)计算相对儒略实际数,用T表示,如下所示:

(19)

3)计算太阳几何平黄经,用L表示,如下所示:

L=280.466456+36000.76982779×T+0.003032028×

(20)

4)计算平黄赤交角,用MB表示,如下所示:

(21)

5)计算太阳平近点角,用MSs表示,如下所示:

MSs=357.52191+35999.0503×T-

(22)

6)计算太阳真黄经,用SYS表示,如下所示:

SYS=L+(1.9146-0.004817×T-0.000014×T2)

(23)

7)计算太阳地心赤纬角,用Dec表示,如下所示:

(24)

上式中涉及的radeg为弧度与度的转换量纲,取radeg值为57.295 779 513 07。

用代码实现上述公式如下:

double VSOP87(cDateTime date)

{

//儒略日数

double J=date2JD(date);

//计算相对儒略世纪数

double T=(J- 2451545.0)/36525;

//太阳几何平黄经

double L=280.466456+36000.76982779*T+0.003032028*pow(T,2)+pow(T,3)/49931-pow(T,5)/15299;

//平黄赤交角

double MB=23.4392911111-(46.815/3600)*T-(0.00059/3600)*pow(T,2)+(0.001813/3600)*pow(T,3);

//太阳平近点角

double MSs=357.52191+35999.0503*T-0.0001559*pow(T,2)-0.00000048*pow(T,3);

//太阳真黄经

double SYS=L+(1.9146-0.004817*T-0.000014*pow(T,2))*sin(MSs/radeg)+(0.019993-0.000101*T)*sin(2*MSs/radeg)+0.00029*sin(3*MSs/radeg);

//太阳地心赤纬

double Dec=asin(sin(MB/radeg)*sin(SYS/radeg));

return Dec;

}

1.3 太阳时角的计算方法

太阳时角是以太阳为参考,其值代表了观察者所在的子午圈与太阳所在的子午圈之间的夹角。太阳时角的单位通常可以是角度值,如度分秒,此时的取值范围为0至360度,也可以是时间值,如时分秒,此时的取值范围为0至24小时。当用角度表示时,其表示的含义可以理解为两个子午圈之间的夹角,当使用时分秒表示时,其含义可以理解为太阳在时角时间之前通过观察者正上空。如时角为3.5h,则代表在3.5小时之前,太阳在3.5小时之前从观察者所在的正上空通过。

太阳时角的计算采用下列公式。其中tS为真太阳时。

(25)

真太阳时的计算采用下面中的公式计算,其中t为平太阳时,单位为小时。在天文观测中,很多天文概念都会加一个“平”字,其含义往往是代表着未加误差修正的简单值,加上修正以后,通常称之为“真”。eot即对时间的修正值。太阳时角的计算,其重点就在于误差修正值eot的计算。

(26)

下面将介绍6种计算太阳时角的算子,分别为Lamm算子,Spencer算子,Whillier算子,Wloof算子,Yu算子,以及VSOP87行星理论。其区别主要便在误差修正值的计算上。

1.3.1 Lamm算子

Lamm算子是由Lamm提出的,其特点是考虑了平年和闰年的区别,其公式如下。以四年为一个周期,其中n为全周期中的计日序数。Ak和Bk为系数值,在此采用杜春旭提出的参数值进行计算。计算所得eot值单位为分钟值,需要转化为小时进行下一步计算。

(27)

实现代码如下所示:

double Lamm(cDateTime mDateTime, double lon)

{

int n=getDaysOfYear(mDateTime);

int n0=mDateTime.year%4;

if(n0==0)

{

n=n;

}else if(n0==1)

{

n=n+366;

}else if(n0==2)

{

n=n+366+365;

}else if(n==3)

{

n=n+366+365+365;

}

double t =getHours(mDateTime);

double thet =2*M_PI*n/365.25;

//eot为分钟的单位

double eot=0.00020870*cos(thet*0)+0.0092869*cos(thet*1)-0.052258*cos(thet*2)-0.0013077*cos(thet*3)-0.0021867*cos(thet*4)-0.000151*cos(thet*5)

-0.12229*sin(thet*1)-0.15698*sin(thet*2)-0.0051602*sin(thet*3)-0.0029823*sin(thet*4)-0.00023463*sin(thet*5);

double ts=0;

ts=t+eot/60+(lon-120)/15;

//转为弧度。1个小时对应15°。

double w=M_PI/12*(ts-12);

return w;

}

1.3.2 Spencer算子

Spencer算子除了可以计算太阳赤纬,也提出了计算太阳时角的公式。其计算公式如下。其中θ为日角,单位为弧度。

eot=229.18[0.000075+0.001868cos(θ)-0.032077sin(θ)-0.014615cos(2θ)-0.04089sin(2θ)]

(28)

日角的计算公式如下,周期为1年,n为计日序数。

(29)

公式计算所得的eot值单位为分钟,需要转换为小时再进行下一步计算。

实现代码如下所示:

double SpencerTimeAngle(cDateTime mDateTime, double lon)

{

int n=getDaysOfYear(mDateTime);

double t =getHours(mDateTime);

double thet =2*M_PI*(n-1)/365;

double eot=229.18*(0.000075+0.001868*cos(thet)-0.032077*sin(thet)-0.014615*cos(2*thet)-0.04089*sin(2*thet));

double ts=0;

ts=t+eot/60+(lon-120)/15;

double w=M_PI/12*(ts-12);

return w;

}

1.3.3 Whillier算子

Whillier算子由Whillier提出,其中θ为日角,单位为弧度。计算所得eot单位为分钟,需要转换成小时。

eot=9.87sin(2θ)-7.53cos(θ)-1.5sin(θ)

(30)

日角的计算公式如下,周期为1年,n为计日序数。

(31)

实现代码如下:

double Whillier(cDateTime mDateTime, double lon)

{

int n=getDaysOfYear(mDateTime);

double t =getHours(mDateTime);

double thet =2*M_PI*(n-81)/364;

double eot=9.87*sin(2*thet)-7.53*cos(thet)-1.5*sin(thet);

double ts=0;

ts=t+eot/60+(lon-120)/15;

double w=M_PI/12*(ts-12);

return w;

}

1.3.4 Wloof算子

Wloof算子由Wloof提出,其中θ为日角,单位为弧度。计算所得eot单位为分钟,需要转换成小时。误差修正值计算公式如下:

eot=0.258cos(θ)-7.416sin(θ)-3.648cos(2θ)-9.228sin(2θ)

(32)

其中的日角公式如下,周期为1年,n为计日序数。

(33)

代码实现如下:

double Wloof(cDateTime mDateTime, double lon)

{

int n=getDaysOfYear(mDateTime);

double t =getHours(mDateTime);

double thet =2*M_PI*(n-1)/365.242;

double eot=0.258*cos(thet)-7.416*sin(thet)-3.648*cos(2*thet)-9.228*sin(2*thet);

double ts=0;

ts=t+eot/60+(lon-120)/15;

double w=M_PI/12*(ts-12);

return w;

}

1.3.5 Yu算子

Yu算子由Yu提出,除了可计算赤纬,可提出了计算太阳时角的公式,其中θ为日角,单位为弧度。计算所得eot单位为分钟,需要转换成小时。误差修正值计算公式如下:

eot=0.0172+0.4281cos(θ)-7.351sin(θ)-3.3495cos(2θ)-9.3619sin(2θ)

其中的日角公式如下,周期为1年,n为计日序数。

代码实现如下:

double YuTimeAngle(cDateTime mDateTime, double lon)

{

int n=getDaysOfYear(mDateTime);

double t =getHours(mDateTime);

double thet =2*M_PI*n/365;

double eot=0.0172+0.4281*cos(thet)-7.351*sin(thet)-3.3495*cos(2*thet)-9.3619*sin(2*thet);

double ts=0;

ts=t+eot/60+(lon-120)/15;

double w=M_PI/12*(ts-12);

return w;

}

1.3.6 VSOP87行星理论

关于VSOP87行星理论上文已有介绍,利用该理论计算的过程如下。

1)计算相对儒略世纪数,用T表示:

(34)

2)计算黄道与月球平轨道升交点黄经,用mw表示:

mw=125.04452-1934.136261×T+

(35)

3)计算太阳几何平黄经,用L表示:

L=280.466456+36000.76982779×T+

(36)

4)计算月球几何平黄经,用L1表示:

L1=218.3164591+481267.88134236×T-0.0013268×T2+0.0000019×T3

(37)

5)计算黄经章动,用NHJ表示:

(38)

6)计算平黄赤交角,用MB表示:

(39)

7)计算任意时刻格林尼治恒星时,并加上黄经章动修正,得到视恒星时用Q0表示,需要将Q0值转换到0~360°范围内:

Q0=280.4606183+360.98564736629×(J-2451545)+

(40)

8)计算太阳平近点角,用MSs表示:

MSs=357.52191+35999.0503×T-

(41)

9)计算太阳真黄经,用SYS表示:

SYS=L+(1.9146-0.004817×T-0.000014×T2)

(42)

10)计算太阳赤经,用RM表示:

(43)

11)计算当地太阳时角,用ω,需要将ω值转换到0~360°范围内,计算结果为度值,通常需要转换成弧度值,方便后续计算:

(44)

ω=Q0+lon-120-RM

(45)

实现上述公式的代码如下:

double VSOP87TimeAngle(cDateTime date,double lon)

{

//儒略日数

double J=date2JD(date);

//计算相对儒略世纪数

double T=(J- 2451545.0)/36525;

//黄道与月球平轨道升交点黄经

double mw=125.04452-1934.136261*T+0.0020708*pow(T,2)+pow(T,4)/450000;

//太阳几何平黄经

double L=280.466456+36000.76982779*T+0.003032028*pow(T,2)+pow(T,3)/49931-pow(T,5)/15299;

//月球几何平黄经

double L1=218.3164591+481267.88134236*T-0.0013268*pow(T,2)+0.0000019*pow(T,3);

//黄经章动

double NHJ=(-17.2/3600)*sin(mw/radeg)-(1.32/3600)*sin(2*L/radeg)-(0.23/3600)*sin(2*L1/radeg)+(0.21/3600)*sin(2*mw/radeg);

//平黄赤交角

double MB=23.4392911111-(46.815/3600)*T-(0.00059/3600)*pow(T,2)+(0.001813/3600)*pow(T,3);

//任意时刻格林尼治视恒星时,加黄经章动修正,得到视恒星时

double Q0=280.4606183+360.98564736629*(J-2451545)+0.000387933*pow(T,2)-pow(T,3)/38710000+NHJ*MB;

int n=Q0/360;

Q0=Q0-n*360;

//太阳平近点角

double MSs=357.52191+35999.0503*T-0.0001559*pow(T,2)-0.00000048*pow(T,3);

//太阳真黄经

double SYS=L+(1.9146-0.004817*T-0.000014*pow(T,2))*sin(MSs/radeg)+(0.019993-0.000101*T)*sin(2*MSs/radeg)+0.00029*sin(3*MSs/radeg);

//太阳地心赤经

double RM=radeg*atan2(cos(MB/radeg)*sin(SYS/radeg),cos(SYS/radeg));

//当地时角

double w =Q0+lon-120-RM;

int temp=w/360;

w=w-temp*360;

return w/180*M_PI;

}

2 太阳高度角及方位角的计算方法

太阳高度角和方位角,即在观察者位置观察太阳时的方位俯仰角,与当地的水平面相关,太阳高度角从地表横切面起算,取值范围为0~90°,水平角从正北方向起算,取值范围为0~360°。

计算太阳高度角时,需要考虑蒙气差的影响。

2.1 太阳高度角的计算

太阳高度角的计算公式如下,其中ψ为观察者所处地点的纬度值,δ为太阳赤纬角,e为地球椭圆扁率:

(46)

其中地球扁率公式为:

(47)

太阳高度角和方位角计算的代码如下:

cAE SunAltitudeAngle::calSunAltitudeAngle(cLocation mLocation, double hourAngle, double Dec)

{

cAE mSunAE;

double e=(earth_a-earth_b)/earth_a;

double cos_lat=cos(mLocation.dLatitude/radeg);

double cos_w=cos(hourAngle);

double cos_Dec=cos(Dec);

double sin_lat=sin(mLocation.dLatitude/radeg);

double sin_Dec=sin(Dec);

double up=cos_lat*cos_w*cos_Dec+sin_lat*sin_Dec;

double down=sqrt(1+(1/pow(1-e,2)-1)*pow(cos_Dec,2)*pow(sin_lat,2)+(pow(1-e,2)-1)*pow(cos_lat,2)*pow(sin_Dec,2));

double cos_phi=up/down;

double phi=acos(cos_phi);

double E=M_PI_2-phi;

double R0=MongolianQiDiff(1,E,16,880);//计算蒙气差,单位为角秒

E=E+(R0/3600)/radeg;

mSunAE.E=E;

double cos_A=(sin(E)*sin_lat-sin_Dec)/(cos(E)*cos_lat);

mSunAE.A=acos(cos_A);

return mSunAE;

}

2.2 太阳方位角的计算

太阳方位角的计算在计算得出高度角的基础上进行,公式如下,其中,α为太阳高度角,ψ为观察者所处纬度值,δ为太阳赤纬角。

(48)

2.3 蒙气差计算公式

蒙气差修正,即对因大气折射、温度、气压带来的误差进行修正。蒙气差的单位为角秒。在此采用李文提出的计算公式,以公式适用范围为依据,将蒙气差计算按俯仰角进行划分。下列公式输入值α为俯仰角,单位为弧度,输出值为修正值,输出为角秒。

2.3.1 蒙气差对大气折射的修正

2.3.1.1 俯仰角0~14°范围的修正

在此范围内,使用傅里叶展开法进行计算修正,修正系数采用真实记录值进行计算。计算公式如下。

(49)

实现代码如下:

double SunAltitudeAngle::Fourier(double alpha,double a[6],double b[5],double w)

{

double z=M_PI_2-alpha;

double R0=a[0]+a[1]*cos(tan(z)*w)+a[2]*cos(2*tan(z)*w)+a[3]*cos(3*tan(z)*w)+a[4]*cos(4*tan(z)*w)+a[5]*cos(5*tan(z)*w)+b[0]*sin(tan(z)*w)+b[1]*sin(2*tan(z)*w)+b[2]*sin(3*tan(z)*w)+b[3]*sin(4*tan(z)*w)+b[4]*sin(5*tan(z)*w);

return R0;

}

2.3.1.2 俯仰角15~45°范围的修正

在此范围内,采用数值拟合法进行修正,修正系数采用真实记录值进行计算,修正公式如下:

(50)

实现代码如下:

double SunAltitudeAngle::NumericalFitting(double alpha, double a[8])

{

double z=M_PI_2-alpha;

double R0=a[0]*pow(tan(z),0)+a[1]*pow(tan(z),1)+a[2]*pow(tan(z),2)+a[3]*pow(tan(z),3)+a[4]*pow(tan(z),4)+a[5]*pow(tan(z),5)+a[6]*pow(tan(z),6)+a[7]*pow(tan(z),7);

return R0;

}

2.3.1.3 俯仰角46~90°范围的修正

高俯仰范围内的修正方法较多,常见的有5种算法。

1)算法一的计算公式如下:

(51)

2)算法二的计算公式如下:

(51)

3)算法三的计算公式如下:

(52)

4)算法四的计算公式如下:

(53)

5)算法五的计算公式如下:

(54)

实现上述公式的代码如下:

if(type==1)

{

R0=60.2*tan(z);

}else if(type==2)

{

R0=(1819.08+194.89*alpha+1.47*pow(alpha,2)-0.042*pow(alpha,3))/(1+0.41*alpha+0.067*pow(alpha,2)+0.000085*pow(alpha,3));

}else if(type==3)

{

R0=1.02/tan((alpha+10.3/(alpha+5.11))*M_PI/180);

}else if(type==4)

{

R0=60.097*tan(z)+0.0109*pow(tan(z),2)-0.073*pow(tan(z),3)+0.002*pow(tan(z),4);

}else if(type==5)

{

R0=60.103*tan(z)-0.066*pow(tan(z),3)-0.00015*pow(tan(z),5);

}

2.3.2 蒙气差对温度、气压的修正

蒙气差还会受温度和湿度的影响,因此需要对蒙气差进行附加值修正。输入值为蒙气差值,单位为角秒,输出值为蒙气差修正值,单位为角秒。蒙气差修正公式如下。其中在高仰角(通常指大于45°)的情况下,大气折射对温度也会有一个影响,因此需要对温度再进行一次修正,其中μ为对温度的附加修正。

R=R0(1+μA+B)

(55)

其中:μ的修正公式如下:

(56)

低仰角时,无需对温度进行修正。蒙气差修正公式如下:

R=R0(1+A+B)

(57)

对温度的修正公式如下:

(58)

对气压的修正公式如下:

(59)

上述公式实现代码如下:

double SunAltitudeAngle::MongolianQiDiffPlus(double alpha,double R,double T,double P)

{

double R0=0;

double A=-0.00383*T/(1+0.00363*T);

double B=P/101324.72-1;

if(alpha<(45/radeg))

{

double a[6]={1.00011366,-8.95854338e-4,1.77241695e-3,-9.29720341e-5,2.00679856e-6,-1.5325798e-8};

double z=M_PI_2-alpha;

double mu=a[0]*pow(tan(z),0)+a[1]*pow(tan(z),1)+a[2]*pow(tan(z),2)+a[3]*pow(tan(z),3)+a[4]*pow(tan(z),4)+a[5]*pow(tan(z),5);

R0=R*(1+mu*A+B);

}else{

R0=R*(1+A+B);

}

return R0;

}

3 飞行器与太阳夹角的计算方法

在计算出太阳高度角和方位角以后,同时已知飞行器的方位俯仰角,此时便能计算出飞行器与太阳之间的夹角。

计算夹角有两种方法:一种是向量点乘的方法,另一种是三角函数推导的方法。

飞行器与太阳及观测点之间的相互关系如图2。F点为飞行器,S点为太阳,P点为观察点,太阳夹角即图中所示∠FPS。

图2 太阳夹角示意图

计算时,为方便计算,取模的长度为1,α1为飞行器点的方位角,β1为飞行器的俯仰角,α2为太阳的方位角,β2为太阳的俯仰角。则F点方向可以假定一个模长为1点F′,其坐标可以表示为F′(cosβ1sinα1,cosβ1cosα1),同理,在S点方向可以假定一个模长为1的点S′,其坐标可以表示为S′(cosβ2sinα2,cosβ2cosα2)。正东方向取为X轴正方向,正北方向取为Y轴正方向。

3.1 向量点乘法

向量点乘的计算公式如下:

(60)

根据F′与S′的值,代码实现如下:

double SolarAngle::dotProduct(cAE SunAE, cAE CraftAE)

{

cXYZ Sun_XYZ;

cXYZ CraftAE_XYZ;

double alpha1=SunAE.A;

double beta1=SunAE.E;

double alpha2=CraftAE.A;

double beta2=CraftAE.E;

Sun_XYZ.X=cos(beta1)*cos(alpha1);

Sun_XYZ.Y=cos(beta1)*sin(alpha1);

Sun_XYZ.Z=sin(beta1);

CraftAE_XYZ.X=cos(beta2)*cos(alpha2);

CraftAE_XYZ.Y=cos(beta2)*sin(alpha2);

CraftAE_XYZ.Z=sin(beta2);

double thet=acos(Sun_XYZ.X*CraftAE_XYZ.X+Sun_XYZ.Y*CraftAE_XYZ.Y+Sun_XYZ.Z*CraftAE_XYZ.Z);

return thet;

}

3.2 三角函数推导

在PF与PS两条线段上,从P点出发,取一个长度为1的线段,记作F′和S′,将F′和S′相连,成一个等腰三角形,计算F′S′长度,从而求出∠F′PS′,即太阳夹角。

经推导,计算公式结果如下:

(61)

代码实现如下:

double SolarAngle::trigonometric(cAE SunAE, cAE CraftAE)

{

double alpha1=SunAE.A;

double beta1=SunAE.E;

double alpha2=CraftAE.A;

double beta2=CraftAE.E;

double thet=2*asin(sqrt(2-2*cos(beta1)*cos(beta2)*cos(alpha1-alpha2)-2*sin(beta1)*sin(beta2))/2);

return thet;

}

4 飞行器与太阳夹角的精度分析

为比较各算法的计算结果,进行精度分析。

4.1 精度分析方法

用以进行数值精度鉴定的参考数据,通常有两种来源,一是通过实际观察获取的实测记录值,另一种来源是精度更高的计算值。在本次计算赤经赤纬数值的精度鉴定中,采用第二种方法,以精度更高的计算值来作为参考值的办法。采用复杂算法SPA算法的计算值作为数据的参考值,SPA算法是综合考虑了海拔、压强、温度、倾斜度、方位角旋转、大气折射、时区、地球自转时间与地球时间之差等各方面因素的算法,其计算精度可达±0.000 3°,可以用来作为参考值对简单算法进行精度分析。

因此在对太阳夹角的数值分析时,选用SPA算法作为参考值。误差分析选用均值、方差、均方根三项指标进行分析。

飞行器飞行轨迹选用样本,按照每秒一个点,每秒在方位、俯仰方向上各新增0.000 1°,全时长为300秒设计。飞行时间设定为2018年8月8日上午10点整。起飞地点设置为东经102.241 897 39,北纬27.902 341 42。

数据样本为全飞行轨迹中,每个点的太阳夹角与参考值的差值。

均值即将样本值求均值。公式如下:

(62)

方差为将样本值与样本的均值相减,分别求平方后求和,再将平方和求均值。

(63)

均方根,将所有样本值分别求平方,再求平方和以后求平方和的均值,最后开平方。

(64)

分析对象为:9种太阳赤纬角算法,6种太阳时间算法。

4.2 精度分析结果

4.2.1 均值分析结果

均值分析结果如表1所示。

表1 均值计算结果

图3为折线图形式。横坐标为赤纬算子,每一条折现代表一种时角算法。

图3 均值折线图

均值能反映统计样本的大致的平均水准,均值越小,说明样本值整体越小。从表1均值计算结果分析可得以下结论。

1)不同的赤纬角算子下,VSOP87的时角计算结果偏差最小。

2)不同的时角算子下,Wang算法的赤纬角计算结果偏差最小。

4.2.2 方差分析结果

方差分析结果如表2所示。

表2 方差计算结果

图4为折线图形式。横坐标为赤纬算子,每一条折现代表一种时角算法。

图4 方差折线图

方差分析反映的是自变量对数值的影响。即对于均值的偏离度的一个分析,即数值的稳定程度。数值越小,说明数值越稳定,起伏越小。

1)在不同的赤纬角算子,VSOP87的时角计算结果波动最小。

2)在不同的时角算子下,Wang算子的赤纬角计算结果波动最小。

4.2.3 均方根分析结果

均方根分析结果如表3所示。

表3 均方根计算结果

图5为折线图形式。横坐标为赤纬算子,每一条折现代表一种时角算法。

图5 均方根折线图

均方根和均值一起分析,反映了样本的一致性情况。均方根和均值越接近,说明样本数据一致性越好。

1)在不同的赤纬角算子下,VSOP87的时角一致性最好。

2)在不同的时角算子下,Wang算子的赤纬角一致性最好。

5 结束语

本次实验实现了从计算太阳赤纬角和太阳时角,到计算太阳高度角和方位角,最后计算得到飞行器与太阳夹角。在C++环境中,实现了9种太阳赤纬角,6种太阳时角,2种太阳夹角以及相应的蒙气差修正等过程的计算,并分析了9种太阳赤纬角算法,以及6种太阳时角算法对太阳夹角的影响,结果表明,所有简单算法中,VSOP87的时角算子与Wang赤纬角算子的计算结果最为真实可靠。在日常使用的简单计算中,推荐使用Wang赤纬角算子及VSOP87时角算子计算太阳夹角。

猜你喜欢

弧度计算公式夹角
电机温升计算公式的推导和应用
把脉向量中两类夹角背景下参数的取值范围问题
探究钟表上的夹角
求解异面直线夹角问题的两个路径
2019离职补偿金计算公式一览表
如何求向量的夹角
谈拟柱体的体积
不自由
弧度制的三个基本应用
南瓜