首页 / 资讯中心 / 文章详情

carla_simulation 实战:ROS 自动驾驶仿真环境搭建与 CMake 编译避坑指南

carla_simulation 实战:ROS 自动驾驶仿真环境搭建与 CMake 编译避坑指南 ★ FEATURED ARTICLE
简介这份资源面向ROS与自动驾驶仿真方向的开发者与学习者提供基于Carla模拟器的纯追踪Pure Pursuit控制实践方案帮助读者在仿真环境中搭建车辆循迹与速度控制流程。包内共10个文件以launch启动文件、Python脚本、pickle数据文件为主另含xml、json、txt与md等配置和说明文档压缩包约90KB结构紧凑便于快速导入ROS工作空间运行。资源围绕Carla与ROS的联合仿真展开涉及ego_vehicle里程计消息读取、路径分辨率调节默认0.2m、林肯MKZ 2017车型模型以及PID速度控制目标速度12m/s与纯追踪转向控制等关键环节并附有运行记录与参考路径说明。目前已有505人学习下载适合具备一定ROS基础、希望理解轨迹跟踪算法实现细节的读者参考可据此复现仿真流程、调整控制参数并对照代码梳理纯追踪与PID的配合逻辑。1. 从一份 ROS 仿真包说起carla_simulation 到底能跑出什么如果你正在做自动驾驶感知或控制的验证手头又没有实车大概率会碰到同一个问题仿真环境搭起来太碎。传感器模型、车辆动力学、ROS 话题桥接、场景加载每一块都能单独折腾半天。carla_simulation 这个包解决的就是这件事——它把 CARLA 模拟器和 ROS 之间的接口层打包好了让你不用从零写 bridge 节点直接跑通「仿真车 传感器数据 ROS 话题」这条链路。它适合两类人一是刚接触自动驾驶仿真的 ROS 开发者想快速看到点云、图像、车辆状态在 RViz 里动起来二是已经在用 CARLA 但被版本兼容和编译问题反复折腾的熟手需要一个结构清晰的 CMake 工程做二次开发底座。关键词 CMake 在这里不是装饰——整个包的构建逻辑、依赖查找、消息生成都压在 CMakeLists 里改错一行就编译不过。下面按「能跑起来 → 改得动 → 不翻车」的顺序拆。2. 环境搭建与 CMake 构建链路从 clone 到第一个节点启动2.1 依赖关系与版本对齐这个包的核心依赖分三层底层是 CARLA 模拟器本体和它的 PythonAPI中间是 ROS常见做法是 Melodic 或 Noetic对应 Ubuntu 18.04 / 20.04上层是 carla_ros_bridge 和 ros-bridge 相关消息包。很多人翻车不是代码问题是版本没对齐——CARLA 0.9.x 不同小版本之间 PythonAPI 的接口签名会变ros-bridge 又对 CARLA 版本有要求。我一般会先确认三件事CARLA 的版本号./CarlaUE4.sh --version或看 PythonAPI 里的carla.__version__、ROS 发行版echo $ROS_DISTRO、以及 ros-bridge 仓库对应的分支。这三个对不上后面 CMake 找包阶段就会报find_package(carla_ros_bridge REQUIRED)失败。提示不要混用 apt 安装的 ros-bridge 和源码编译的 carla_ros_bridge头文件路径冲突时 CMake 不会给你明确报错只会在一堆 include 里丢一个找不到的符号。2.2 工作空间初始化与编译假设你已经装好 CARLA 和 ROS接下来是标准 catkin 流程。这里把关键命令和参数含义写清楚方便你按自己路径改。# 创建工作空间名字随意这里用 carla_ws mkdir -p ~/carla_ws/src cd ~/carla_ws/src # 克隆 ros-bridgecarla_simulation 通常依赖它提供的消息和服务定义 git clone https://github.com/carla-simulator/ros-bridge.git # 切到与你的 CARLA 版本匹配的分支比如 0.9.13 对应 ros-bridge 的对应 tag cd ros-bridge git checkout 与你 CARLA 版本匹配的 tag # 回到工作空间根目录编译 cd ~/carla_ws catkin_makecatkin_make背后做的事先扫描src下所有包的package.xml建立依赖图再按拓扑顺序调用每个包的 CMakeLists。如果某个包依赖另一个还没编译的消息包顺序错了就会报Could not find message。常见做法是加-DCATKIN_WHITELIST_PACKAGES只编译你需要的包减少干扰。编译通过后source devel/setup.bash用rospack find carla_ros_bridge验证路径能被找到。这一步过了说明 CMake 链路是通的。2.3 启动顺序与话题验证启动不是一条命令的事顺序错了节点会连不上。典型流程# 终端 1启动 CARLA 服务端-quality-level 控制渲染质量 ./CarlaUE4.sh -quality-levelLow -world-port2000 # 终端 2启动 ros-bridge加载对应地图和车辆 roslaunch carla_ros_bridge carla_ros_bridge.launch # 终端 3启动示例客户端生成 ego 车辆和传感器 roslaunch carla_ros_bridge carla_example_ego_vehicle.launch-world-port2000是 CARLA 默认端口ros-bridge 的 launch 文件里passive参数决定它是主动连接还是等待连接。如果终端 2 报连接超时先确认终端 1 的 CARLA 是否真的起来了看有没有CarlaUE4进程再看端口有没有被占。验证话题用rostopic list正常应该能看到/carla/ego_vehicle/...下的一串传感器话题。rostopic hz /carla/ego_vehicle/camera/rgb/front/image_color能看帧率帧率异常低通常是渲染质量开太高或者机器 GPU 扛不住。3. 传感器数据流与 ROS 话题映射点云、图像、IMU 怎么接3.1 传感器配置与话题命名规则carla_simulation 里传感器的挂载和话题生成是绑定的。你在 CARLA 里给车辆加一个sensor.lidar.ray_castros-bridge 会自动把它映射成/carla/ego_vehicle/lidar话题消息类型是sensor_msgs/PointCloud2。相机对应sensor_msgs/ImageIMU 对应sensor_msgs/ImuGNSS 对应sensor_msgs/NavSatFix。这个映射规则写在 ros-bridge 的 actor 工厂里不是配置文件。想改话题名要么改源码里的命名逻辑要么在 launch 里用 remap。我一般用 remap不动源码node pkgcarla_ros_bridge typecarla_ros_bridge namecarla_ros_bridge remap from/carla/ego_vehicle/lidar to/perception/lidar_raw / /noderemap的 from 必须和实际发布的话题完全一致差一个斜杠就不生效。验证方法是rostopic info /perception/lidar_raw看发布者是不是 bridge 节点。3.2 点云数据的坐标系与帧率控制激光雷达数据在 RViz 里显示时最常见的坑是坐标系对不上。CARLA 的 lidar 默认坐标系和 ROS 的sensor_msgs/PointCloud2的frame_id需要显式设置。ros-bridge 一般会把frame_id设成ego_vehicle/lidar这类名字你在 RViz 里要把 Fixed Frame 设成对应的父坐标系通常是map或ego_vehicle否则点云飘在天上或者干脆不显示。帧率控制靠 CARLA 的sensor_tick参数。默认是每帧都发仿真步长 0.05s 的话就是 20Hz。如果 ROS 端处理不过来可以在传感器配置里把sensor_tick设成 0.1降到 10Hz。这个参数在 PythonAPI 里设置lidar_bp world.get_blueprint_library().find(sensor.lidar.ray_cast) lidar_bp.set_attribute(sensor_tick, 0.1) # 单位秒0.1 表示 10Hz lidar_bp.set_attribute(range, 50) # 探测距离 50 米 lidar_bp.set_attribute(channels, 32) # 32 线range和channels直接影响数据量和计算量。32 线 50 米在普通工作站上跑 10Hz 问题不大64 线 100 米就要看 GPU 和内存了。改完参数记得重新 spawn 传感器运行中改 blueprint 不生效。3.3 图像与 IMU 的时间戳对齐多传感器融合时时间戳不对齐是玄学问题的根源。CARLA 的仿真时间和 ROS 的 wall time 是两套时钟。ros-bridge 默认用仿真时间发布消息你需要把 ROS 的/use_sim_time参数设成 true并且让 bridge 发布/clock话题。rosparam set /use_sim_time true设完之后rostopic echo /carla/ego_vehicle/imu看 header.stamp应该是仿真时间在走。如果还是 wall time检查 bridge 的 launch 里有没有param nameuse_sim_time valuetrue /。图像和 IMU 的时间戳如果差了几十毫秒融合算法会直接跑偏这个坑在调试 EKF 的时候特别明显。4. 避坑与排查编译、连接、数据异常的血泪记录4.1 CMake 报找不到 CARLA 的 PythonAPI现象catkin_make时报Could not find CARLA PythonAPI或者carla模块导入失败。原因CMakeLists 里用find_package(PythonLibs)或者直接include_directories指向 CARLA 的 PythonAPI 路径但这个路径依赖环境变量CARLA_ROOT。很多人装了 CARLA 但没设这个变量或者设了但没 source 到当前终端。解决在~/.bashrc里加export CARLA_ROOT/path/to/carla然后source ~/.bashrc。如果 CMakeLists 里写的是硬编码路径改成${CARLA_ROOT}/PythonAPI/carla。改完删掉build和devel重新catkin_make不要增量编译缓存会骗你。4.2 bridge 连接 CARLA 超时现象roslaunch carla_ros_bridge启动后卡在Waiting for CARLA server一直连不上。原因三种可能——CARLA 服务端没起、端口不对、防火墙拦了本地回环。最常见的是 CARLA 起了但用了非默认端口而 bridge 的 launch 里还是 2000。解决先netstat -tlnp | grep 2000确认端口监听状态。如果 CARLA 用的是 3000改 launch 里的port参数。本地回环一般不会被防火墙拦但如果你在容器里跑要确认容器网络模式是不是 host。4.3 点云在 RViz 里不显示或显示错位现象rostopic echo有点云数据但 RViz 里看不到或者点云位置明显偏移。原因Fixed Frame 设错或者frame_id和 TF 树对不上。CARLA 的 lidar 数据默认在传感器自身坐标系下需要 TF 变换到车辆坐标系再到地图坐标系。如果 TF 树缺了某一环RViz 就不知道往哪画。解决rosrun tf view_frames生成 TF 树 PDF看ego_vehicle到lidar的变换有没有。缺的话检查 bridge 的tf发布频率或者手动加 static_transform_publisher 补上。Fixed Frame 设成map或ego_vehicle都行但要和 TF 树根节点一致。4.4 仿真时间跳变导致控制算法震荡现象车辆控制算法在仿真里表现正常但偶尔会突然抽一下像收到一个巨大的误差信号。原因/clock话题的时间跳变。CARLA 在加载新地图或重置场景时仿真时间会跳如果控制算法没做时间戳有效性检查就会把跳变当成真实时间差积分项直接爆掉。解决在控制节点里加时间戳校验如果两帧时间差超过阈值比如 0.5s跳过这一帧或者重置积分项。另外确认/use_sim_time在所有节点里都设了 true混用 wall time 和 sim time 必出这个问题。4.5 传感器数据频率和仿真步长不匹配现象rostopic hz看到的频率和预期差很多比如设了 20Hz 实际只有 5Hz。原因CARLA 的仿真步长fixed_delta_seconds和传感器 tick 是联动的。如果仿真步长是 0.05s传感器 tick 也是 0.05s理论上 20Hz但实际渲染和物理计算耗时会导致丢帧。另外如果开了同步模式但没设fixed_delta_seconds仿真会按实际计算速度跑频率完全不可控。解决在 CARLA 的 world 设置里开同步模式并固定步长settings world.get_settings() settings.synchronous_mode True settings.fixed_delta_seconds 0.05 # 20Hz 仿真步长 world.apply_settings(settings)同步模式下仿真和 ROS 时间绑定频率稳定但要求所有传感器和客户端都跟上节奏否则会卡住。异步模式频率飘但不容易死锁。调试阶段用异步正式跑数据用同步。5. 进阶用 CMake 定制自己的仿真节点与验证闭环5.1 在现有包里加自定义消息和节点carla_simulation 的 CMake 结构是标准的 catkin 包加自定义消息的流程在包目录下建msg/文件夹写.msg文件然后在package.xml里加message_generation和message_runtime依赖在 CMakeLists 里加add_message_files和generate_messages。# 在 CMakeLists.txt 里find_package 之后 add_message_files( FILES CustomControl.msg ) generate_messages( DEPENDENCIES std_msgs ) catkin_package( CATKIN_DEPENDS message_runtime std_msgs )add_message_files里的文件名必须和msg/下的完全一致大小写敏感。generate_messages的 DEPENDENCIES 写这个消息依赖的其他消息包漏了会在编译时找不到类型。改完 CMakeLists 一定要重新catkin_make而且最好catkin_make clean再编消息生成的中间文件缓存很容易出问题。5.2 验证闭环从仿真数据到算法输出跑通数据流只是第一步验证算法得有个闭环。我一般会写一个简单的订阅节点订阅点云和车辆状态做一个最简的障碍物距离判断然后把结果发布成visualization_msgs/Marker在 RViz 里看。import rospy from sensor_msgs.msg import PointCloud2 from visualization_msgs.msg import Marker import sensor_msgs.point_cloud2 as pc2 def callback(msg): # 只取前 100 个点做演示实际用的时候做降采样 points list(pc2.read_points(msg, field_names(x, y, z), skip_nansTrue))[:100] min_dist min([p[0] for p in points]) if points else 0 marker Marker() marker.header msg.header marker.type Marker.TEXT_VIEW_FACING marker.text min_x: %.2f % min_dist marker.scale.z 1.0 pub.publish(marker) rospy.init_node(verify_node) pub rospy.Publisher(/verify/marker, Marker, queue_size1) rospy.Subscriber(/carla/ego_vehicle/lidar, PointCloud2, callback) rospy.spin()这个节点的作用是快速确认数据链路是通的、坐标系是对的、数值是合理的。read_points的field_names要和点云的字段匹配CARLA 的 lidar 一般有 x,y,z,intensity。skip_nansTrue过滤无效点。Marker 的 header 直接复用点云的 header保证在 RViz 里位置一致。5.3 参数调试的实用习惯调仿真参数最怕改完不知道哪个值生效了。我的习惯是每次改 launch 或 Python 配置先在终端rosparam dump一份当前参数快照出问题直接 diff。另外 CARLA 的 PythonAPI 里很多参数是 spawn 时生效运行中改 blueprint 没用必须 destroy 再 spawn。这个习惯帮我省了很多「改了没反应」的无效调试。从那以后我每次动 CMakeLists 或者 launch 文件之前都会先git stash存一份能跑的版本改崩了直接回滚比一点点找哪行改错快得多。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站