menu

无人车实时优化-链路延迟计算

1. 背景

如何为自动驾驶程序计算链路延迟?

一般来说在互联网开发上, 我们采用Distributed Systems Tracing(比如说Google Dapper), 来追踪一次服务调用的链路延迟.
但是对机器人程序来说, 是不存在”服务调用”的概念的, 有可能链路上的程序对数据都是buffer的形式来使用. 无法建立上下游的关联.

换种思路, 其实可以大问题分解成小问题: 通过各部分task/io的执行情况, 来证明某个链路的延迟.

1.1. 任务分类

计算延迟前, 再介绍下ros程序的两种写法:

  • time-based(time-triggered)
  • event-based(data-triggered)

  • 一般来说, 触发原因分为下面两种:
    • event-based
    • time-based
  • 一个任务可以有很多触发原因, 不过在实际编程场景下倾向用单触发.
  • 不负责任的说, 公式里带t的用时间触发
    • PID: ${\displaystyle u(t)=K_{\text{p}}e(t)+K_{\text{i}}\int {0}^{t}e(t’)\,dt’+K{\text{d}}{\frac {de(t)}{dt}},}$
    • Kalman filter: ${\displaystyle \mathbf {x} _{t}=\mathbf {F} _{t}\mathbf {x} _{t-1}+\mathbf {B} _{t}\mathbf {u} _{t}+\mathbf {w} _{t}}$
      • 反例:
        • imu积分求位移, 最好由imu sensor-data event触发
        • 所以修正: 两者都可以用, 随你喜欢……
  • 优先event-based, 可以减少latency
  • 使用time-based的几种情况
    • latency不敏感, 无关紧要的链路
    • 输入事件的频率的达不到要求或者不稳定, 需要插值的场合(比如说各种control)
      • 如果频率不够高, 会带来很大的延迟, 比如20hz就是50ms的链路延迟.
      • 如果上下游都用到了插值, 尽量合并
    • 无法决定合适的输入事件
      • 自动驾驶上规划决策是个例子, 一般都是定时器触发为一个frame
  • time-based的任务适合deadline调度
  • event-based的任务适合优先级抢占式调度

1.2. 链路建模

我们可以尝试用图形语言来描述任务pipeline.

图形含义:

Pattern 1: Data-triggered pipelines:

Pattern 2: Synchronized starts: 省略, time-based

Pattern 3: Explicit synchronization

1.3. deadline

关于deadline概念:

可以把deadline理解成预期的任务从触发到执行的最大时间, 下面会用到.

2. 延迟计算

一个链路如下, 从决策一直到底盘:

Decider --> Planning --> Control --> Guardian --> Chassis

程序逻辑如下:
(time-based, 100hz)表示是定时触发, 频率为100hz

Decider --> Planning(time-based, 10hz) --> Control(time-based, 100hz) --> Guardian(event-based) --> Chassis(time-based, 100hz)

按照我们的逻辑, 先关心Decider到Planning的情况.

如下假设是Decider到Planning发decision的一个io情况:

max_delay(测量) = Planning收到queue - Decider发出 = cpu调度响应时间 + 处理时间 = 10ms

根据上面的数据, 该io的deadline可以设置到10ms

Planning的timer callback执行情况如下:

max_delay(测量) = Planning完成task- timer wakeup = cpu调度响应时间 + 处理时间 = 10ms

根据上面的数据, Planning的timer task的deadline可以设置10ms.

最终:

Decider到Planning消费decision的延迟 = Planning周期间隔(100ms) + Planning Timer Deadline(10ms) + io Deadline(10ms) = 120ms

其他地方同理, 一个个计算过来叠加, 就可以得到整个链路的预期最大延迟.
这样算过来的值会偏大, 但还是足够合理.

一个简单的延迟示意图:

3. 其他

使用上述方法, 链路的延迟就简化为deadline一种可变量.
控制了deadline, 就可以保证所有链路延迟的确定.