返回专辑
·Johan·3 分钟阅读

Python Launch 重构:部署图,而不是第二套业务代码

按子系统拆分、参数外置、顶层组装;用冒烟守住入口,把业务逻辑赶回节点。

Python Launch 重构:部署图,而不是第二套业务代码

1. 谁都不敢动的 bringup

最危险的文件常常是 bringup.launch.py:几百行条件、硬编码路径、复制粘贴的节点块,以及「临时」的 TimerAction(period=5.0)。Launch 本应描述部署图——谁启动、参数从哪来、命名空间、生命周期顺序——却吞下了业务分支与环境侦探逻辑。典型事故:用未声明环境变量切换雷达 remap,开发机 .bashrc 里碰巧有值,CI 与另一台车没有——同提交、不同图。业务判断放错层,调试按指数涨。

2. 三层配置,越界就脏

  1. xacro/URDF:模型与接口名
  2. YAML:节点与控制器参数
  3. Launch:装配(起谁、命名空间、注入路径)

Launch 里算轨迹、拼控制律、解析传感器语义,都是泄漏。Python 表达力很强,要主动克制。按子系统拆文件,顶层只 IncludeLaunchDescription;参数进 yaml + 少量 LaunchConfigurationOpaqueFunction 只用于找 share 路径;条件用 DeclareLaunchArgument,不要读环境变量碰运气。

python
def generate_launch_description():
    use_sim = LaunchConfiguration("use_sim")
    pkg = FindPackageShare("my_robot_bringup")
    return LaunchDescription([
        DeclareLaunchArgument("use_sim", default_value="false"),
        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(
                PathJoinSubstitution([pkg, "launch", "control.launch.py"])
            ),
            launch_arguments={"use_sim": use_sim}.items(),
        ),
    ])

3. 删掉 sleep,换成依赖边

睡 5 秒「等硬件」在 CI 与慢盘上必碎。换成 lifecycle 事件、话题就绪或超时失败。每删一处 sleep,补一条依赖边;失败打进诊断。控制栈顺序应是硬件 active → 控制器 → 导航,而不是平铺乱序靠运气。use_sim_time 由顶层唯一注入;子系统只接收。混用时钟的锅常背在算法上,其实是 launch 参数不一致。

旧 launch 用 os.environ.get("LEGACY_LIDAR") 决定 remap,一人本机有 export,另一台没有,同提交不同图。改为 DeclareLaunchArgument("lidar_model"),由部署系统按车注入。环境变量只留给真正的环境(如 ROS_DOMAIN_ID),不留给产品分支。重构后「偶发无雷达」单接近消失——雷达没变,条件树变诚实了。

4. 多入口与冒烟

至少三个入口:minimal(驱动联调)、simrobot。禁止一个全能 launch 靠二十个参数切换世界。参数尽量共享,差异用 overlay yaml。冒烟断言:进程在、关键 topic 在、lifecycle/控制器 active。不替代路测,但挡住图断裂。断言少而硬;flaky 要 quarantine。入口改名,测试必须改。干净机安装后能起,才能发现漏掉的 package.xml 依赖。

现场需要「只重启导航/雷达」——子系统 launch 可独立启动是运维要求。一切只能整车 relaunch,故障隔离成本极高。旧入口保留一个版本周期并转发,避免出差现场踩空。

5. 覆盖顺序、路径、命名空间

固定:命令行 > launch > yaml > 代码默认;启动后抽样 ros2 param get。路径一律 FindPackageShare,禁止 /home/xxx。节点内相对名,launch 推命名空间;双实例启动测串话。兼容旧硬件的条件要有参数名、负责人与到期日——无限兼容是债务利息。XML/YAML 适合稳定声明式图;Python 适合复杂装配。团队默认一种,例外写进贡献指南。迁移时只换装配层,别顺便改话题名。

6. 案例:环境变量条件

旧 launch 用环境变量决定 remap。一人本机有 export,另一台没有,同提交不同图。改为 DeclareLaunchArgument("lidar_model"),由部署系统按车注入。这类「偶发」故障在重构前很难复现,因为依赖开发者本机环境。Launch 是部署的源代码——条件树不诚实,第二台车就是第一台车的镜像幻觉。

7. 验收

  • 顶层短、子系统可单独起。
  • 无业务 sleep;时钟模式顶层注入。
  • 冒烟覆盖 minimal/sim/robot 入口。
  • 双实例不串话;干净机可启动。
  • 兼容项有到期日;环境变量不承载产品分支。

Launch 是部署的源代码。业务回节点,装配留 launch,冒烟守门——第二台车应是改 yaml/xacro,而不是分叉 800 行 bringup。

← 全部文章

johan's blog