帧头与采样状态
需要:uBotSensor 0.1.x(含依赖 uBotCore)
了解帧头(Frame Header)里有什么,以及怎样判断一帧数据能不能用、有没有新数据。
每次采样都会生成一个帧头(UBot Frame Header),随数据一起出现在事件和 Get Latest … 节点里。
| 字段 | 类型 | 含义 |
|---|---|---|
Sensor Id |
String | 传感器 id;留空时用组件名 |
Frame Id |
String | 传感器所在的坐标系名;留空时等于 Sensor Id |
Sequence |
Integer64 | 帧序号,每个传感器组件各算各的,每次采样加 1 |
Timestamp Seconds |
Float (double) | 采样时的仿真时间,单位秒 |
Valid |
Boolean | 只有 Status 为 Valid 时为 true |
Status |
EUBot Sample Status | 本次采样的结果,见下表 |
Sensor Id 和 Frame Id 怎样取值,见标识与命名。
状态码(Status)的类型是 EUBot Sample Status:
Status |
什么时候出现 |
|---|---|
Valid |
正常样本,数据可以直接使用 |
Warming Up |
IMU 和里程计要靠相邻样本的差分算速度,刚启动或刚被重置时历史不够,这几次采样是预热样本 |
Invalid Delta Time |
与上次采样的间隔不合理,历史被清空:IMU 为 0 或超过 Max Sample Delta Seconds;里程计小于 Minimum Valid Delta Seconds(默认 0.0001 s)或超过 Maximum Valid Delta Seconds;两个上限默认都是 0.5 s |
Teleport Detected |
两次采样间的位移或转角超过阈值(IMU 和里程计默认 5 m 或 120°),视为瞬移,历史被清空 |
Disabled |
Sensor Enabled 为 false 时手动调用 Sample Sensor 得到的样本 |
Error |
采样出错,比如激光雷达的扫描范围无效;帧头的默认值也是它,表示还没采样过 |
各传感器什么时候给出哪个状态,见它自己的页面,比如 IMU 传感器。
判断一帧能不能用
Section titled “判断一帧能不能用”不是 Valid 的样本也会触发事件。用到速度、加速度这类差分结果之前,先检查 Valid:
连线:
- On Sensor Sampled (IMU) 的 执行,连到 Branch 的 执行
- On Sensor Sampled (IMU) 的 Header,连到 Break UBot Frame Header 的 UBot Frame Header
- Break UBot Frame Header 的 Valid,连到 Branch 的 Condition
On Sensor Sampled (IMU)
UBot Sensor Component · UBotSensor
每次采样后触发,Header 是本次的帧头。每种传感器都有这个事件。
输出
- 执行
- Header
UBot Frame Header结构体
查看参考UUBotSensorComponent.OnSensorSampled
Break UBot Frame Header
UBotCore
把帧头拆成 Sensor Id、Frame Id、Sequence、Timestamp Seconds、Valid 和 Status。
输入
- UBot Frame Header
UBot Frame Header结构体
输出
- Sensor Id
String - Frame Id
String - Sequence
Integer64 - Timestamp Seconds
Float (double) - Valid
Boolean - Status
EUBot Sample Status枚举
查看参考Break:FUBotFrameHeader
Branch
UE 引擎 · 中文界面:分支
Branch Statement If Condition is true, execution goes to True, otherwise it goes to False
输入
- 执行
- Condition
Boolean
输出
- True
- False
查看参考K2Node_IfThenElse
差分得到的速度和加速度只在有效样本里有值。
用 Sequence 判断是否有新数据
Section titled “用 Sequence 判断是否有新数据”用事件取数时,每个样本触发一次事件,不需要比较 Sequence。在 Event Tick 里用 Get Latest … 主动读取时,同一个样本可能被读到好几次,Sequence 和上次处理的不同,才是新样本:
连线:
- Event Tick 的 执行,连到 Branch 的 执行
- IMU 的 IMU,连到 Get Latest Frame Header 的 Target
- Get Latest Frame Header 的 Return Value,连到 Break UBot Frame Header 的 UBot Frame Header
- Break UBot Frame Header 的 Sequence,连到 Not Equal (Integer64) 的 A
- Not Equal (Integer64) 的 Return Value,连到 Branch 的 Condition
B接一个 Integer64 变量,保存上次处理的序号(初值 0)。- 为 True 时处理样本。
Event Tick
UE 引擎 · 中文界面:事件Tick
Event called every frame, if ticking is enabled
输出
- 执行
- Delta Seconds
Float
查看参考AActor.ReceiveTick
IMU
组件或变量引用。在 Components 面板里把 IMU 拖进事件图即可得到它。
输出
- IMU
uBot IMU Sensor对象引用
Get Latest Frame Header
Target is UBot Sensor Component · UBotSensor
返回最近一次采样的帧头。
输入
- Target
UBot Sensor Component对象引用
输出
- Return Value
UBot Frame Header结构体
查看参考UUBotSensorComponent.GetLatestFrameHeader
Break UBot Frame Header
UBotCore
把帧头拆成 Sensor Id、Frame Id、Sequence、Timestamp Seconds、Valid 和 Status。
输入
- UBot Frame Header
UBot Frame Header结构体
输出
- Sensor Id
String - Frame Id
String - Sequence
Integer64 - Timestamp Seconds
Float (double) - Valid
Boolean - Status
EUBot Sample Status枚举
查看参考Break:FUBotFrameHeader
Not Equal (Integer64)
UE 引擎 · 中文界面:不相等(Integer64)
Returns true if A is not equal to B (A != B)
输入
- A
Wildcard - B
Wildcard
输出
- Return Value
Boolean
查看参考UKismetMathLibrary.NotEqual_Int64Int64
Branch
UE 引擎 · 中文界面:分支
Branch Statement If Condition is true, execution goes to True, otherwise it goes to False
输入
- 执行
- Condition
Boolean
输出
- True
- False
查看参考K2Node_IfThenElse
处理完样本以后,把保存的序号设为这次的 Sequence,下一帧才能和新样本比较。
序号的规则:
- 每个传感器组件的第一个样本是 1,之后每个样本加 1。无效样本和手动
Sample Sensor得到的样本也算。 Stop Sensor再Start Sensor不会让序号回到 1。- 两次读到的序号相差大于 1,说明中间有样本没读到。
- 因帧率太低而跳过的采样时刻不占序号,它们只计入
Get Dropped Sample Count。