☰
carla_simulation 实战:ROS 自动驾驶仿真环境搭建与 CMake 编译避坑指南
2026/10/15 16:18:32 网站建设 项目流程

简介:这份资源面向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-bridge(carla_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_make

catkin_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-level=Low -world-port=2000 # 终端 2:启动 ros-bridge,加载对应地图和车辆 roslaunch carla_ros_bridge carla_ros_bridge.launch # 终端 3:启动示例客户端,生成 ego 车辆和传感器 roslaunch carla_ros_bridge carla_example_ego_vehicle.launch

-world-port=2000是 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_cast,ros-bridge 会自动把它映射成/carla/ego_vehicle/lidar话题,消息类型是sensor_msgs/PointCloud2。相机对应sensor_msgs/Image,IMU 对应sensor_msgs/Imu,GNSS 对应sensor_msgs/NavSatFix。

这个映射规则写在 ros-bridge 的 actor 工厂里,不是配置文件。想改话题名,要么改源码里的命名逻辑,要么在 launch 里用 remap。我一般用 remap,不动源码:

<node pkg="carla_ros_bridge" type="carla_ros_bridge" name="carla_ros_bridge"> <remap from="/carla/ego_vehicle/lidar" to="/perception/lidar_raw" /> </node>

remap的 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 name="use_sim_time" value="true" />。图像和 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_nans=True))[: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_size=1) rospy.Subscriber('/carla/ego_vehicle/lidar', PointCloud2, callback) rospy.spin()

这个节点的作用是快速确认数据链路是通的、坐标系是对的、数值是合理的。read_points的field_names要和点云的字段匹配,CARLA 的 lidar 一般有 x,y,z,intensity。skip_nans=True过滤无效点。Marker 的 header 直接复用点云的 header,保证在 RViz 里位置一致。

5.3 参数调试的实用习惯

调仿真参数最怕改完不知道哪个值生效了。我的习惯是每次改 launch 或 Python 配置,先在终端rosparam dump一份当前参数快照,出问题直接 diff。另外 CARLA 的 PythonAPI 里很多参数是 spawn 时生效,运行中改 blueprint 没用,必须 destroy 再 spawn。这个习惯帮我省了很多「改了没反应」的无效调试。

从那以后我每次动 CMakeLists 或者 launch 文件之前,都会先git stash存一份能跑的版本,改崩了直接回滚,比一点点找哪行改错快得多。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询