让接收机运行导出的场景
拥有实验室GNSS模拟器的接收机厂商,可以通过它回放Kshana场景的载体运动,记录被测接收机的表现,并用kshana receiver-trust对照运行前已声明的事件为该日志评分。Kshana提供运动、事件时间和评分。它不生成信号:此处导出的任何内容都不合成、不建模、不发射射频或基带波形,导出的事件是带标签的时间区间,而不是产生干扰的配方。信号由模拟器及其操作人员提供,操作人员有责任只在获得授权的场合运行它们(按模拟器自身的安全说明,采用传导或屏蔽方式)。
本页是一种方法。它不发布任何结果。
1. 导出#
kshana bench-export scenarios/gnss-ins.toml --out run1 --epoch 2025-03-01T10:00:00Z
适用于gnss-ins类型(带姿态的行驶档案;导航状态中断即为事件),以及jamming和gnss-sim(接收机在场景持续期间静止;jamming场景的干扰源是贯穿整个运行的一个事件)。其他类型会说明它们为何没有载体轨迹。--epoch是运动时间零点的UTC时刻(默认2024-01-01T00:00:00Z);这些场景本身不为载体运动提供日历日期。它必须是真实的UTC时刻,格式为YYYY-MM-DDTHH:MM:SS(接受末尾的Z),年份在2000至2099之间,每个字段都在范围内;否则会被拒绝。对于相同的场景和历元,输出逐字节相同。
| 文件 | 内容 |
|---|---|
run1.motion.csv |
每个采样一行:time_s、地固系x_m,y_m,z_m、vx_m_s,vy_m_s,vz_m_s、大地坐标lat_deg,lon_deg,h_m、heading_deg,pitch_deg,roll_deg、utc、kshana_row |
run1.motion.json |
该CSV的历元、坐标系、单位、列和往返容差 |
run1.nmea |
每个采样一条NMEA 0183 GGA和RMC语句,带校验和 |
run1.waypoints.txt |
一行RESOLUTION: <ms>,然后是longitude,latitude,altitude各行(仅当每个采样间隔都是相同的整数毫秒时才写出;省略时,命令会在标准错误中说明原因) |
run1.events.csv |
label,kind,onset_s,end_s,description |
run1.events.toml |
与receiver-trust场景的[[events]]块相同的事件 |
run1.conditions.json |
为receiver-log记录生成的kshana.test-conditions/1文档形式的运行:事件作为已声明的真值,其中recording.path、recording.sha256、receiver.*、每个事件的type和功率留给实验室填写 |
坐标系与约定#
- 位置:WGS 84,地固系(ECEF:
x在本初子午线处穿过赤道,z穿过极点);lat_deg、lon_deg、h_m以大地坐标给出同一位置,h_m为椭球面以上高度。 - 速度:地固坐标轴,相对于地球。
- Attitude:
heading_deg自真北起顺时针,范围为 [0, 360),pitch_deg机头向上为正,roll_deg右翼向下为正;偏航-俯仰-横滚(3-2-1),从当地北-东-下坐标系转到机体轴,x向前,y向右,z向下。静止源写零。NMEA和航点文本不带姿态。 - 航向是载体的偏航,不是行进方向。在
gnss-ins行驶档案中,载体以方波形式偏航,而速度随之变化,因此航向与对地航向可相差数十度(在内置的automotive-urban-canyon场景中最多约77度)。NMEARMC航向是对地航向,即速度矢量的方向,因此从运动文件读取航向的模拟器与从NMEA文件读取航向的模拟器看到的角度不同。CSV中的对地航向是其旋转到北-东-下后的速度的atan2(v_east, v_north)。 - 高度遵循场景。对于
gnss-ins,h_m是该类型对其真值按切平面逐步推进的结果,并不保持恒定(在automotive-urban-canyon的180秒内约7米);它是场景的运动,按原样写出。 - NMEA
GGA占位值。定位质量(1)、使用的卫星数(12)和HDOP(1.0)的写入只是为了使语句格式完整。它们不说明场景的几何或任何接收机状态。 - Time: 历元之后的
time_s,UTC,不对闰秒建模。 - NMEA高度是椭球高。
GGA的高度栏存放椭球高,大地水准面差距写作0.0。把该高度当作平均海平面以上高度的模拟器,会使载体偏离当地大地水准面起伏的量。 - 往返容差(通过回读每个文件来测试):CSV位置0.1 mm,纬度和经度1e-9度,速度0.1 mm/s,角度1e-6度;NMEA水平位置5 mm,高度1 mm,速度0.001节,航向0.001度。
将文件载入模拟器#
实验室模拟器各不相同,本仓库不复制任何模拟器的手册。请核对上述格式中哪些是你的模拟器能读取的,以及它所述的要求:
- 许多运动导入器要求固定的更新率,通常为10 Hz。
gnss-ins场景的步长为0.1秒;对于静止场景,将[time] step_s设为模拟器所需的速率。 - 有些导入器会跳过落在整秒之间的采样,或忽略时间列而使用行的顺序。请在整秒处开始运动,并保持网格规则。
- 允许映射列的CSV导入器可以直接读取
run1.motion.csv:选择地固系或大地坐标列,并按run1.motion.json设置其单位。截断小数会产生虚假加速度,因此请保留所写的精度。 - 该文件只含运动。请在模拟器中配置星座、干扰和接收机前端,并按
run1.events.csv中的事件为它们安排时间。
Kshana不编写任何厂商脚本接口。
用一个开源模拟器的读取器进行的核对
gps-sdr-sim(MIT,提交28ca29a6)的运动读取器收到了八个内置场景的导出文件。每个读取器都返回了导出的轨迹(tests/testbench_gpssdrsim_oracle.rs,已在xval/testbench-gpssdrsim/PREREGISTRATION.md中预先登记):
| gps-sdr-sim选项 | 输入 | 与CSV的最大差异 |
|---|---|---|
-g(NMEA GGA) |
按原样写出的run1.nmea |
1.2 mm |
-x(时间、纬度、经度、高度) |
tail -n +2 run1.motion.csv | cut -d, -f1,8,9,10 |
0.15 mm |
-u(时间、x、y、z) |
tail -n +2 run1.motion.csv | cut -d, -f1-4 |
完全一致 |
- 不要向
-u输入完整的运动CSV。其读取器每行容纳100个字符,而一行CSV约有160个字符,因此每行会被读成两个采样。标题行会被多读成一个不含数字的采样。 - gps-sdr-sim最多容纳3000个采样,即其固定10 Hz下的300秒,并忽略时间列。
gnss-ins导出的步长恰为0.1秒。更长的场景,例如20分钟的gnss-ins-maritime,只读取其最初的300秒。 - 这检查的是文件是否按所写内容被读取。它不检查场景的物理,也不检查模拟器发射的任何内容。
2. 在运行前声明你将评分的内容#
事件文件给出场景所定义的区间。将run1.events.toml复制到receiver-trust场景中,添加任何你想检验的预测,并在接收机运行之前确定监测器阈值和容差。不要在看到日志之后再调整它们;场景、阈值和日志的SHA-256都包含在结果的哈希之中。
kind = "receiver-trust"
name = "bench session 1"
[log]
format = "ubx" # ubx, rinex, android or nmea
path = "receiver-log.ubx"
[monitors]
calibration_s = 60.0
# paste run1.events.toml here, and shift onsets by the log offset (step 4)
[[events]]
label = "gnss-denied-1"
kind = "other"
onset_s = 100.0
end_s = 160.0
导出的事件带有场景自身的类型:jamming场景的干扰源是jamming;导航状态中断是other,因为场景声明的是GNSS不可用,而不是如何不可用。请更改kind,使其与你配置模拟器去做的事情一致。
3. 运行接收机#
启动接收机及其记录器,用运动文件启动模拟器场景,并让这次运行涵盖校准区间、每个事件,以及最后一个事件之后的余量。保留接收机自身的日志(UBX、RINEX 3观测、Android记录器CSV,或带卫星状态语句的NMEA)。没有各卫星信号强度的日志仍可根据接收机自身的位置评分,但载噪比监测器需要这些数据。
4. 对齐时钟#
receiver-trust从接收机日志的第一个历元开始计算事件时间;运动文件从其第一个采样开始计算。如果日志比运动的第一个采样早d秒开始,请对每个onset_s和end_s加上d。请记录该偏移及其测量方法,并写在场景的name或注释中,因为错误的偏移会改变每一项评分。仅凭事件时间无法得知偏移;请使用模拟器的场景起始标记或接收机自身的时间戳。
5. 评分#
kshana receiver-trust bench-session.toml
写出bench-session.result.json、.trust.csv和.trust.svg。对每个事件,结果给出起始前的虚警、首次告警及其监测器、延迟,以及结果状态(detected、late、missed、not-evaluable),以及在你声明了预测时,预测与观测的载噪比下降。出现分歧时如实报告,绝不通过调整来消除。参见RECEIVER-TRUST.md。
要查看该会话为哪些公开框架的行提供证据支持:
kshana compliance-report bench-session.result.json
参见compliance/README.md。该报告描述的是你所提供的运行中的证据;它不对接收机或任何框架作出任何结论。
6. 将往返过程关联到一个已签名的证据包中#
评分之后,kshana evidence round-trip将四项记录绑定在一起:你导出的场景、实验室的测试条件、接收机日志和评分。填写run1.conditions.json(日志的路径和SHA-256、被测接收机、每个事件的类型和所述功率),然后:
kshana evidence keygen --out lab.key
kshana evidence round-trip bench-session.toml --scenario scenarios/gnss-ins.toml \
--conditions run1.conditions.json --from 0 --to 180 --key lab.key --out round-trip-pack
kshana evidence verify round-trip-pack --pubkey <signer public key>
round-trip-pack/config.json带有一个round_trip块(kshana.round-trip/1),其中有scenario_sha256、conditions_hash、log_sha256以及评分(在可评估事件中检测到的事件数、首次告警),并受清单哈希和签名覆盖。如果证据包的条件与评分事件不一致,或其所述的日志哈希不是该日志的哈希,命令会拒绝该证据包。与每个证据包一样,它是技术记录,不是法律意见。
实例:用gps-sdr-sim写出文件#
本例使用开源模拟器gps-sdr-sim仅仅是为了根据导出的运动写出基带文件。Kshana不发射,本页上也没有任何内容将通过无线电回放该文件自动化。如果你的实验室将这样的文件播放到接收机中,那是你的操作人员的责任,只能在获得授权的场合进行(采用线缆连接或屏蔽,遵循模拟器和无线电设备自身的安全说明),Kshana既不记录也不封装这一做法。
kshana bench-export scenarios/gnss-ins.toml --out run1 --epoch 2025-03-01T10:00:00Z
tail -n +2 run1.motion.csv | cut -d, -f1-4 > run1.xyz # time, x, y, z (see above)
gps-sdr-sim -e brdc0600.25n -u run1.xyz -b 8 -o run1.iq # writes a file, nothing else
实验室此后对run1.iq所做的任何事情都发生在Kshana之外。无论如何获得,接收机自身的日志才是第5步评分、第6步关联的对象。这些文件以及Kshana对其自身导出所做的检查,仅在合成数据上测试过(tests/round_trip_pack.rs);此处不声称有任何实验室运行。
本方法不做什么#
- 它不产生信号,也不说明模拟器应当生成什么干扰。事件说明的是何时,而不是什么。
- 一次会话只是一个数据点。结果描述的是该配置下的那份日志,对其他接收机、固件、天线或真实干扰不作任何说明。
- 高度、速率和时间对齐需要由操作人员对照模拟器核对;导出只说明它自己的约定和容差,不多说。