cmvr-es/cmvr-es/task
2026-08-27 11:26:36 +08:00
..
grpc_server_task merge: apply xtkuang code outside hardware-specific drivers 2026-08-27 11:26:36 +08:00
quic_edge_task fix(quic): match task interface after stop gate removal 2026-08-24 16:10:24 +08:00
self_collision_task feat(gen2): add MuJoCo collision recovery support 2026-08-05 10:49:07 +08:00
touch_screen_task merge: apply xtkuang code outside hardware-specific drivers 2026-08-27 11:26:36 +08:00
ume_teleop_task revert xtkuang integration before linbo hardware changes 2026-08-24 15:23:27 +08:00
CMakeLists.txt revert xtkuang integration before linbo hardware changes 2026-08-24 15:23:27 +08:00
README.md feat: add QUIC media transport and integrate Hikvision updates 2026-07-23 12:52:30 +08:00
task_factory.h feat(collision): add self-collision monitoring task 2026-07-27 15:37:39 +08:00
task.h merge: apply xtkuang code outside hardware-specific drivers 2026-08-27 11:26:36 +08:00

Task 模块开发指南

task/ 保存由 TaskManager 管理的可运行模块。任务分为周期调度任务和自持线程/事件循环的服务任务。

返回项目总览。

Task 契约

所有任务实现 task.h 中的接口:

  • id():配置和管理器使用的稳定唯一 ID;
  • runMode():周期任务或服务任务;
  • init():配置校验和本地资源准备;
  • start():启动执行,必须快速返回;
  • step(dt):周期任务的一次计算;
  • stop():幂等停止并回收任务拥有的资源;
  • state() 和状态辅助接口:线程安全地暴露状态;
  • detailStatusString():提供可诊断状态,不包含密钥。

析构函数应安全调用 stop()。异步状态、错误和统计必须使用 mutex/atomic 保护。

运行模式

PERIODIC_STEP

  • 由 TaskManager scheduler 调用 step();
  • 配置 control_period_s 必须是有限正数;
  • 只有 task state 为 RUNNING 时执行 step;
  • 所有周期任务共享一个 scheduler 线程;
  • step 不能做阻塞网络 I/O 或无界计算;
  • step 返回失败时应更新任务状态和可诊断错误;
  • 不要在 step 内同步停止 TaskManager。

BLOCKING_SERVICE

  • TaskManager 不调用其 step();
  • start 必须创建自己的 server/worker 后快速返回;
  • stop 必须关闭 server、唤醒等待并 join 线程;
  • 不能把 BLOCKING_SERVICE 理解为 start 可以永久阻塞。

GrpcServerTask 和 QuicEdgeTask 是当前服务任务参考实现。

新增任务的完整链路

1. 配置 Proto

在 protos/cmvr/config/ 新增:

message ExampleTaskConfig {
  string id = 1;
}

message ExampleTaskRootConfig {
  ExampleTaskConfig example_task = 1;
}

在 TaskConfigEntry::TaskType 中使用新的、稳定的枚举值。当前 2 和 4 已 reserved,不得复用。

2. 实现目录

task/example_task/
├── CMakeLists.txt
├── include/example_task.h
├── src/example_task.cpp
└── tests/example_task_test.cpp

实现 Task 全部接口。持续运行任务的典型状态转换为:

UNINITIALIZED -> IDLE -> RUNNING -> STOPPED
                         └-------> FAILED

持续周期任务必须在 start 后进入 RUNNING,否则 scheduler 不会调用 step。命令驱动任务可以在 start 后保持 IDLE,收到外部命令后再进入 RUNNING,当前 TouchScreenTask 就采用这种方式。

init、start 或 step 都可能进入 FAILED,一次性任务也可以进入 SUCCEEDED。失败后是否允许重新 init/start 必须在类注释和测试中明确。

3. Creator 与注册

creator 应:

  1. 校验 manager entry ID 和 config file;
  2. 使用 ConfigHelper 加载 root config;
  3. 校验子配置 ID 与 manager entry ID 一致;
  4. 只创建对象,不进行耗时外部连接;
  5. 返回 nullptr 并记录明确错误。

提供:

void registerExampleTaskFactory();

通过 task_factory.h 的 TaskFactory::registerCreator() 注册。

registerCreator() 对相同 TaskType 会覆盖旧 creator,当前不会报错。不要重复注册。creator 在 registry mutex 持有期间执行,因此不能从 creator 递归调用 register/create。

4. main 注册

在 TaskManager::getInstance() 之前显式调用注册函数。当前位置见 ../main.cpp。

TouchScreen 是 TaskFactory 内硬编码的历史实现;新任务优先使用显式 registry 模式。

5. TaskManager 映射

在 ../manager/task_manager/src/task_manager.cpp 的 TaskType 字符串映射中增加新类型,否则计划日志会显示 unknown。

6. 默认配置

新增:

cmvr-es/config/tasks/example_task/example_task.pb.txt

并在 config/manager/task_manager.pb.txt 增加 entry。依赖硬件、网络或证书的新任务默认 enable: false。

配置 run_mode 必须和 task 的 runMode() 一致,否则 TaskManager 会跳过该任务。

7. CMake

  • 为任务建立独立 library target;
  • 添加项目命名空间 alias;
  • 在 CMakeLists.txt 或 ../CMakeLists.txt 加入子目录;
  • 根 cmvr_es 必须链接注册函数所在 target,避免静态库未被带入;
  • 测试放在 if(BUILD_TESTING);
  • 使用 add_test() 登记到 CTest。

参考 quic_edge_task/CMakeLists.txt。

TaskManager 当前语义

  • init 按配置顺序执行;
  • init 失败只跳过该任务,进程继续;
  • ID 重复会跳过后加入项;
  • run mode 不匹配会跳过;
  • TASK_RUN_MODE_UNKNOWN 当前会记录错误并退化为 PERIODIC_STEP,配置不得依赖该历史行为;
  • start 阶段任一任务失败会停止此前已启动任务;
  • 返回 false 的 task 必须自行清理此次 start 的部分资源;
  • 任务保存在 unordered_map,不能依赖 start/stop 顺序;
  • manager 处于 running 状态时,stop 先停止 scheduler,再调用每个任务 stop;
  • 未启动或已经停止时,stopRunTask() 会直接返回;
  • TaskManager 单例已存在时传入新配置不会热更新。

任务之间有依赖时,应由一个协调 task 显式管理,或增加明确依赖模型;不能依赖配置顺序碰巧变成启动顺序。

测试最低要求

  • 缺失配置、空 ID 和 ID mismatch;
  • run-mode mismatch;
  • init/start/stop 状态转换;
  • stop 重复调用;
  • start 失败后的资源清理;
  • 周期 dt、调度延迟和 step 失败;
  • service worker 正常 shutdown;
  • stop 发生在阻塞等待期间;
  • 析构时仍处于 RUNNING;
  • fake 依赖下的无设备运行。

单项测试:

cmake --build build --target quic_edge_task_test
ctest \
  --test-dir build \
  -R '^quic_edge_task_test$' \
  --output-on-failure

提交检查

  • 使用新的 TaskType 枚举号
  • 配置 root message、默认配置和 ID 一致
  • creator 与 main 注册均已完成
  • run mode 与配置一致
  • start 快速返回
  • stop 幂等并 join 所有线程
  • 状态查询线程安全
  • CMake target 被根程序链接
  • 测试已登记到 CTest