国家太空安全是国家安全在空间领域的表现。随着太空技术在政治、经济、军事、文化等各个领域的应用不断增加,太空已经成为国家赖以生存与发展的命脉之一,凝聚着巨大的国家利益,太空安全的重要性日益凸显[1]。而在信息化时代,太空安全与信息安全紧密地结合在一起。
2020年9月4日,美国白宫发布了首份针对太空网络空间安全的指令——《航天政策第5号令》,其为美国首个关于卫星和相关系统网络安全的综合性政策,标志着美国对太空网络安全的重视程度达到新的高度。在此背景下,美国自2020年起,连续两年举办太空信息安全大赛“黑掉卫星(Hack-A-Sat)”,在《Hack-A-Sat太空信息安全挑战赛深度解析》一书中有详细介绍,本文介绍了Hack-A-Sat黑掉卫星挑战赛的跟踪卫星这道赛题的解题过程。
题目介绍
You're in charge of controlling our hobbyist antenna. The antenna is controlled by two servos, one for azimuth and the other for elevation. Included is an example file from a previous control pattern. Track the satellite requested so we can see what it is broadcasting.
主办方假定参赛者已经获得了地面站卫星天线的控制系统的权限。天线控制是通过两个舵机控制的,分别控制方位角和仰角。题目要求参赛者通过控制天线的方位角和仰角跟踪卫星。
给出的资料有examples.tar.gz,解压后包含4个文件:
(1)README.txt:描述了题目更加详细的信息。方位角舵机和仰角舵机由来自控制器的PWM信号控制(关于PWM的知识会在下文介绍)。已知舵机的占空比(Duty Circles)为2457~7372,对应天线的0°~180°。要求得出控制舵机信号在观测的720s内每一秒的占空比来控制天线,从而成功跟踪卫星。
(2)challenge[0-4].txt、solution[0-4].txt:这两个文件告诉我们最终要输入的格式。题目没有给出关于解决方案格式的信息,但我们察看其中一个示例解决方案,以challenge[0].txt和 solution[0].txt为例,如下所示,challenge[0].txt给出地面站的位置、要跟踪的卫星、开始跟踪卫星的时刻、要跟踪的时长。查看solution[0].txt得知我们最终要输入的文件格式如下,要输入720行,每一行对应1s:包括3个要素,分别为时间戳、控制地面站卫星天线方位、俯仰的舵机PWM值。
<timestamp>,<PWM0>,<PWM1>
challenge[0].txt内容:
Track-a-sat control system
Latitude: 52.5341
Longitude: 85.18
Satellite: PERUSAT 1
Start time GMT: 1586789933.820023
720 observations, one every 1 second
Waiting for your solution followed by a blank line...
solution[0].txt内容:
1586789933.820023, 6001, 2579
1586789934.820023, 5999, 2581
1586789935.820023, 5997, 2583
1586789936.820023, 5995, 2585
1586789937.820023, 5994, 2587
1586789938.820023, 5992, 2589
1586789939.820023, 5990, 2591
1586789940.820023, 5988, 2593
1586789941.820023, 5987, 2594
1586789942.820023, 5985, 2596
1586789943.820023, 5983, 2598
1586789944.820023, 5981, 2600
1586789945.820023, 5979, 2602
1586789946.820023, 5977, 2604
1586789947.820023, 5976, 2606
……
(3)active.txt:地面站使用的TLE。如下所示,该文件包含许多公共卫星,通过某颗卫星的TLE可以计算该卫星在后续某一时刻的位置。
CALSPHERE 1
1 00900U 64063C 20101.19586769 .00000241 00000-0 24890-3 0 9996
2 00900 90.1576 27.2823 0024882 263.3747 232.8474 13.73355076761081
CALSPHERE 2
1 00902U 64063E 20101.07898481 .00000023 00000-0 20957-4 0 9991
2 00902 90.1686 29.8886 0016745 309.6664 60.7009 13.52681717551296
LCS 1
1 01361U 65034C 20101.48494378 .00000021 00000-0 16643-2 0 9996
2 01361 32.1376 139.9201 0004925 231.9284 128.0769 9.89297118986548
TEMPSAT 1
1 01512U 65065E 20101.13158021 .00000007 00000-0 -51836-5 0 9992
2 01512 89.8739 226.9331 0071605 111.6801 301.3452 13.33427200658976
CALSPHERE 4A
1 01520U 65065H 20101.19568728 .00000042 00000-0 65250-4 0 9998
2 01520 90.0331 128.8999 0069815 356.3666 119.2980 13.35809885661087
OPS 5712 (P/L 160)
1 02826U 67053A 20101.49397074 .00000535 00000-0 15707-3 0 9992
2 02826 69.9298 358.0006 0004382 11.4117 348.7115 14.49027125737592
……
另外,主办方给出了一个链接地址,使用netcat连接到题目给的链接后,会给出进一步提示,如图4-1所示(其中的坐标、观察时间和需要跟踪的卫星都是随机的)。
图4-1 antenna题目的提示信息
连接后,会告诉参赛者需要跟踪的卫星,以及地面站的位置、开始跟踪卫星的时刻,要求参赛者输入天线控制舵机在观测的720s内每一秒的占空比来控制天线,从而成功跟踪卫星,全部720s的占空比都正确后,会返回flag值。
题目编译及测试
该挑战题的代码位于antenna目录下,查看challenge、solver目录下的Dockerfile,发现其中用到的是python:3.7-slim,为了加快题目的编译进度,在antenna目录下新建一个文件sources.list,内容如下:
deb https://mirrors.tuna.tsinghua.edu.cn/debian/deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free
将sources.list复制到antenna、challenge、solver目录下,修改challenge、solver目录下的Dockerfile,在所有的FROM python:3.7-slim下方添加:
ADD sources.list /etc/apt/sources.list
打开终端,进入antenna所在目录,执行命令:
sudo make build
使用make test命令进行测试,会顺利通过,其输出信息如图4-2所示。
图4-2 antenna挑战题测试输出
相关背景知识
1.卫星星历TLE文件介绍
TLE是两行轨道根数(TLE),覆盖了气象卫星、海洋卫星、地球资源卫星、教育卫星等应用卫星。以北斗的某颗卫星TLE数据为例,如下:
BEIDOU 2A
1 30323U 07003A 07067.68277059 .00069181 13771-5 44016-2 0 587
2 30323 025.0330 358.9828 7594216 197.8808 102.7839 01.92847527 650
第一行主要元素解析如下:
(1)30323U:30323是北美防空司令部给出的卫星编号,U代表不保密,我们看到的都是U,否则我们就不会看到这组TLE了。
(2)07003A:国际编号,07表示2007年,003表示这一年的第3次发射,A表示这次发射编号为A的物体,其他还有B、C、D等。国际编号就是2007-003A。
(3)07067.68277059:表示这组轨道数据的时间点,07表示2007年,067表示第67天,即3月8日。
(4)68277059:表示这一天里的时刻,大约是16时22分左右。
(5)58:表示关于这个空间物体的第58组TLE。
(6)7:最后一位是校验位。
第二行主要元素解析如下:
(1)30323:北美防空司令部给出的卫星编号。
(2)025.0330:轨道倾角。
(3)358.9828:升交点赤经。
(4)7594216:轨道偏心率。
(5)197.8808:近地点幅角。
(6)102.7839:平近点角,表示在给出这组TLE时,卫星在轨道的什么位置。
(7)01.92847527:每天环绕地球的圈数。其倒数就是周期。可以看出,该北斗卫星目前的周期大约是12h。
(8)65:发射以来飞行的圈数。
(9)0:校验位。
2.GMT、UTC和UNIX时间戳
GMT的全名是格林威治标准时间(Greenwich Mean Time)。十七世纪,格林威治皇家天文台进行了天体观测。1675年,旧皇家观测所(Old Royal Observatory)正式成立,到了1884年决定以通过格林威治的子午线作为划分地球东西两半球的经度零度。观测所门口墙上有一个标志24h的时钟,显示当下的时间,对全球而言,这里所设定的时间是世界时间参考点,全球都以格林威治的时间作为标准来设定时间。
UTC(Universal Time Coordinated,协调世界时),又称世界标准时间、世界统一时间,是经过平均太阳时(以GMT为准)、地轴运动修正后的新时标,以及以秒为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以“世界标准时间”的角度来说,UTC比GMT更加精准,其误差值必须保持在0.9s以内,若大于0.9s,则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。所以UTC的本质强调的是比GMT更为精确的世界时间标准。GMT和UTC均用秒数来计算,对于大多数用途来说,我们可以认为GMT就是UTC,GMT=UTC。
在计算机中看到的UNIX时间戳(UNIX epoch或UNIX timestamp)都是从1970年01月01日0:00:00(GMT/UTC)开始计算秒数的,即从1970年这个时间点起到具体时间共有多少秒。这个秒数就是UNIX时间戳。例如,UTC时间2022年3月21日下午2点58分转换成UNIX时间戳为1647874701。
3.方位角(Azimuth)和仰角(Elevation)
方位角:是从观察者的指北方向线起,依顺时针方向到目标方向线之间的水平夹角。也就是说,0°方位角表示正北,90°方位角表示正东,180°方位角表示正南,270°方位角表示正西,360°方位角表示角度回归,依然是正北。
仰角:当方位角测量完毕后,需要用仰角来描述被观察物体相对于观察者的高度。如果被观察物体在观察者上方,那么仰角范围为0°~90°,有时仰角范围还为-90°~90°,这是因为被观察物体在观察者下方。
如图4-3所示,以观察者为中心建立坐标系,3个坐标轴分别指向相互垂直的东向、北向和天向,可以计算出卫星在此坐标系中的仰角和方位角,以及卫星到观察者的距离。
图4-3 方位角和仰角示意图
要进行卫星信号收发,关键点是地面站天线的指向,天线必须准确可靠地对准卫星,天线的方位角和仰角是天线指向的重要参数。当卫星处于地平线下方时,处于卫星天线盲区,因此,地面站天线的仰角范围为0°~90°,方位角范围为0°~360°。
4.PWM信号和占空比
脉冲宽度调制(Pulse Width Modulation,PWM),是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。PWM信号通过周期性跳变的高低电平组成方波来进行连续数据的输出。
PWM在合适的信号频率下,通过一个周期内改变占空比的方式来改变输出的有效电压。例如,具有30%占空比的PWM信号波形如图4-4所示。
图4-4 30%占空比的PWM信号波形
占空比是射频、微波电路、低频交流和直流电流等领域的一个概念,最普遍的含义是表示在一个周期内,工作时间与总时间的比值。以单片机为例,单片机的I/O口输出的是数字信号,I/O口只能输出高电平和低电平。
假设高电平为5V,低电平为0V,那么要输出不同的模拟电压,就要用到PWM,通过改变I/O口输出的方波的占空比,从而获得使用数字信号模拟成的模拟电压信号。如图4-5所示,占空比为50%即高电平时间一半,低电平时间一半,在一定的频率下,就可以得到模拟的2.5V输出电压,那么75%的占空比,得到的电压就是3.75V。依此类推,20%的占空比,得到的电压就是1V。PWM的调节作用来源于对“占周期”的宽度控制,“占周期”变宽,输出的平均电压值就会上升,“占周期”变窄,输出的平均电压值就会下降。
图4-5 不同占空比的模拟电压示意图
具体在本题中,题目给出天线的舵机接收的占空比为2457~7372,这里占空比可以理解为天线控制舵机转动一定角度所需的值。
5.舵机控制原理和结构
舵机,其学名为伺服电机,是一种带有输出轴的装置。当我们向伺服器发送一个控制信号时,输出轴就可以转到特定的位置。只要控制信号持续不变,伺服机构就会保持轴的位置不改变。如果控制信号发生变化,输出轴的位置也会相应发生变化。
图4-6 舵机的内部结构
一种简单的舵机的内部结构如图4-6所示,有控制电路、电机、一组减速齿轮和外壳等。控制电路由PWM进行控制。PWM信号对舵机的控制通过一个固定的频率,给其不同的占空比,来控制舵机不同的转角。
因此,我们很容易理解,题目中“舵机的占空比为2457~7372,对应天线的0°~180°。”这句话的含义。本题目中,控制方位角的舵机和控制仰角的舵机分别接收不同的占空比,来控制天线朝向。
6.pyorbital.orbital模块
pyorbital.orbital模块是用于计算卫星轨道参数的模块。本题目需要用到以下函数:
pyorbital.orbital.get_observer_look(utc_time, lon, lat, alt)
Return: (Azimuth, Elevation)
参数如下:
utc_time:观察时间,其时间格式为UTC。
lon:地面站的经度,以东经为单位。
lat:地面站的纬度,以北纬为单位。
alt:地面站的海拔高度,以km为单位。
调用本函数,返回地面站天线的方位角和仰角。
题目解析
本题目的解法还是比较直观的,使用Python提供的pyorbital.orbital函数,可以分为3步:
(1)知道要跟踪的卫星名称,依据此信息,从给出的active.txt文件中找到目标卫星对应的TLE。
(2)获取了目标卫星的TLE、开始观察时间和地面站的位置后,调用前文介绍过的orb.get_observer_look函数,返回方位角和仰角。
(3)方位角和仰角换算成驱动舵机转动的PWM占空比。
关键代码如下:
from pyorbital.orbital import Orbital
import datetime
# 加载TLE文件,读出CALSPHERE 1卫星,保存在orb 中
orb = Orbital(' CALSPHERE 1', tle_file='active.txt')
# time为开始观察目标卫星的那个时刻
time = 1587057945.165157
# 角度和舵机占空比换算函数
def angle_to_servos(angle):
val = angle / 180.0
val = int(val * (7372 - 2457))
val += 2457
return val
# 输入观察时间、地面站的位置、要跟踪的卫星的TLE,调用orb.get_observer_look函数,返回方位角和仰角
for i in range(720):
ts = time+i
t = datetime.datetime.utcfromtimestamp(ts)
angles = orb.get_observer_look(t,-91.43, 17.4804, 0)
# 将方位角和仰角的角度分别换算成控制方位角舵机和控制仰角舵机的占空比
a0 = angle_to_servos(angles[0])
a1 = angle_to_servos(angles[1])
# 打印720行格式为<timestamp>,<PWM0>,<PWM1>的输出
print(f"{ts}, {a0}, {a1}")
其中角度和舵机占空比换算具体过程是:0°用2457表示,180°用7372表示。由(7372-2457)/180°≈ 27.31/°,那么天线占空比和度数关系为: