陪你度过漫长岁月

源码阅读《CarlaUE5 UChaosVehicleMovementComponent关键调用链》

前言

初衷是希望看在CarlaUE5里面,一个apply_control调用是怎么一步步影响到车辆的状态的。

逻辑上是个比较直接的功能,更新车辆的输入信息,tick推帧,返回车辆更新后的状态。

就是这么个功能,在CarlaUE5里面还实现得挺复杂。

其中最关键的模块是UE5的UChaosVehicleMovementComponent,本文主要介绍这个模块更新车辆信息时的关键调用链,即UChaosVehicleMovementComponent是怎么将input传给simulator得到output的。

至于simulator的具体逻辑,以及怎么将apply_control中的input传给UChaosVehicleMovementComponent先按下不表。

下面按照核心类关系图和核心类时序图两部分展开。

核心类关系图

核心的类如下图所示:

  • FChaosVehicleManager:主入口,运行在Game Thread,负责创建/提交运行在Physics Thread的async task
  • UChaosVehicleMovementComponent:逻辑实现类,管理着车辆的输入以及状态,simulator也在这个类里面
  • FChaosVehicleManagerAsyncCallback:async task类,由FChaosVehicleManager创建,会在Physics Thread被调用执行,一个task就负责所有车辆的更新
  • FChaosVehicleManagerAsyncInput/Output:负责FChaosVehicleManagerFChaosVehicleManagerAsyncCallback的通信,里面包含所有车辆的信息
  • FChaosVehicleAsyncInput/Output:负责FChaosVehicleManagerAsyncCallbackUChaosVehicleMovementComponent的通信,是单辆车的信息

核心类关系图

核心类时序图


核心类时序图

看代码的时候最难以理解的是为什么UChaosVehicleMovementComponent需要绑定跟FChaosVehicleManagerAsyncCallback通信用的FChaosVehicleAsyncInput/Output,这个东西的用法是:

  • 将input成员变量(比如油门大小)赋值给FChaosVehicleAsyncInput
  • FChaosVehicleManagerAsyncCallback通过UChaosVehicleMovementComponent中的simulator将FChaosVehicleAsyncInput转为FChaosVehicleAsyncOutput
  • FChaosVehicleAsyncOutput获取更新后的状态赋值给output成员变量(比如引擎力矩)

我感觉完全可以抛开FChaosVehicleAsyncInput/Output,直接在UChaosVehicleMovementComponent的成员这一层里完成input到output的转换,毕竟input / output / simulator都是成员。

我现在能想到的解释是:这样子做,主视角是FChaosVehicleManagerAsyncCallback(知道input / output以及调用的函数),可以在这一层做一些统一的修改(比如修改传给simulator的input)。