CARLA ROS2 原生传感器参考:Topic 命名规则、消息类型与源码级原理全指南
2026/9/22 22:04:24 网站建设 项目流程
  • 自动驾驶
  • 科研
  • 仿真

【免费下载链接】carla

Open-source simulator for autonomous driving research.

项目地址:https://gitcode.com/gh_mirrors/ca/carla
点击查看免费下载

CARLA 模拟器(CARLA Simulator)从服务端原生支持 ROS2 通信,无需外部桥接进程即可将仿真中生成的传感器数据直接发布为 ROS2 Topic。本文以 Docs/ros2_native_sensors.md 为核心,完整梳理 13 类传感器对应的 Topic 名称与 ROS 消息类型,并结合仓库源码(LibCarla/source/carla/ros2 下的发布器实现)讲解数据格式、发布机制与订阅方式。读完本文,你将能准确规划感知节点的 Topic 订阅方案,理解/clock时间同步、enable_for_ros()启用逻辑以及sensor_msgs各消息的字段来源,可直接对接目标检测、点云处理、里程计等 ROS2 下游应用。

前置概念:ROS2 原生接口与仿真时钟/clock

在进入传感器 Topic 清单之前,需要先理解两条贯穿全文的机制:

  1. 服务端原生发布:CARLA 的 ROS2 支持内建于服务端。启动时只需在命令行追加--ros2选项(详见 Docs/ros2_native.md):

    ./CarlaUnreal.sh --ros2

    此后,任何被显式启用 ROS 的传感器都会由服务端直接向 DDS 总线广播数据,不需要额外的 ros-bridge 进程。

  2. 仿真时钟/clockCARLA 服务端负责基于仿真时间发布/clockTopic,并且每个仿真帧都会更新一次。这是 ROS2 应用保持时间同步的关键——下游节点应将该时钟作为use_sim_time的时间源,确保时间戳与仿真帧一致。从源码看,该发布器位于 CarlaClockPublisher.cpp,它通过BasePublisher("rt/clock")创建名为rt/clock的写者,并将仿真秒数与纳秒写入rosgraph_msgs/Clock消息:

    CarlaClockPublisher::CarlaClockPublisher() : BasePublisher("rt/clock"), _impl(std::make_shared<PublisherImpl<CarlaClockMsgTraits>>()) { if (!_impl->Init(GetBaseTopicName())) { log_error("CarlaClockPublisher: failed to initialise writer for rt/clock"); } } bool CarlaClockPublisher::Write(std::int32_t seconds, std::uint32_t nanoseconds) { auto *message = _impl->GetMessage(); message->clock().sec(seconds); message->clock().nanosec(nanoseconds); return true; }

    可以看到底层通过 eProsima Fast-DDS 类型的ClockPubSubType序列化发布,Topic 名以rt/前缀声明(对应 ROS 的 reliable-transient-local 语义)。

传感器数据广播机制:如何让传感器"进入 ROS"

默认情况下,仿真中 spawn 的传感器不会自动向 ROS 发布数据。必须显式调用传感器对象的enable_for_ros()方法,例如在 Python 客户端中:

sensor = world.spawn_actor(sensor_blueprint, transform) sensor.enable_for_ros()

这条调用在客户端侧形成一条完整的链路:ServerSideSensor.cpp 中的ServerSideSensor::EnableForROS()请求所在 Episode,进而由 Simulator.cpp 的Simulator::EnableForROS()调用 Client.cpp 的Client::EnableForROS(),通过该传感器的 streaming token 通知服务端开启对应流的 ROS 转发。也就是说,"是否发布"由服务端按传感器逐一控制,而非全局开关。

Topic 命名规则

Topic 名称由传感器 blueprint 中的ros_name属性决定,需在 spawn 之前设置(默认会生成随机字符串名称):

bp = bp_lib.find('sensor.camera.rgb') bp.set_attribute('ros_name', 'front_camera')

无父级时的 Topic 形如:

/carla/front_camera/image

若传感器挂载在某个 actor(例如自车)之下,Topic 会再拼接父级 actor 的 role name,形如:

/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/image

例如自车 role name 为ego、相机ros_namefront_camera时,图像 Topic 为/carla/ego/front_camera/image(对应 Docs/ros2_native.md 的示例)。下表所有 Topic 中的<PARENT ROLE NAME>即为父级 actor 的 role name,<SENSOR ROLE NAME>ros_name;无父级时两者之间的路径段省略。

相机类传感器:图像与内参消息

相机类传感器通常同时发布两个 Topic:图像数据(sensor_msgs/Image)与相机内参(sensor_msgs/CameraInfo)。从源码看,这一对写者统一实现在 CarlaCameraPublisher.cpp 中:构造函数同时为base_topic + "/image"base_topic + "/camera_info"各初始化一个PublisherImplPublish()时两者无条件共同发布(一处失败不会压制另一处)。

CameraInfo消息的填充值得注意(同一源文件中WriteCameraInfo()):

  • distortion_model固定为"plumb_bob",畸变向量D为 5 个零值;
  • 内参矩阵KComputeIntrinsics(width, height, fov)依据分辨率与视场角实时计算(fx/fy、主点 cx/cy);
  • 矫正矩阵R为单位阵,投影矩阵P为标准针孔形式,binning_x/binning_y为 0;
  • roi区域直接回填图像的 offset、height、width 与do_rectify标志。

Image消息的stepencoding则由各传感器子类决定:例如 RGB 相机发布器 CarlaRGBCameraPublisher.h 重写GetChannels()返回 4、GetEncoding()返回"bgra8"(BGRA 四通道像素)。可以推断,Depth、Semantic Segmentation、Instance Segmentation、Normals、Optical Flow 等发布器(CarlaDepthCameraPublisher.hCarlaSSCameraPublisher.hCarlaISCameraPublisher.hCarlaNormalsCameraPublisher.hCarlaOpticalFlowCameraPublisher.h)均以同样的子类化方式定义各自的像素格式,下游消费者应依据消息中的encoding字段做对应解码。

RGB camera

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/imagesensor_msgs/Image
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/camera_infosensor_msgs/CameraInfo

Depth camera

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/imagesensor_msgs/Image
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/camera_infosensor_msgs/CameraInfo

Semantic segmentation camera

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/imagesensor_msgs/Image
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/camera_infosensor_msgs/CameraInfo

Instance segmentation camera

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/imagesensor_msgs/Image
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/camera_infosensor_msgs/CameraInfo

Normals camera

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/imagesensor_msgs/Image
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/camera_infosensor_msgs/CameraInfo

Optical flow camera

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/imagesensor_msgs/Image
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/camera_infosensor_msgs/CameraInfo

光流数据以图像形式承载在/imageTopic 中。仓库中 OpticalFlowEncoding.h 专门负责光流结果的编码转换,说明仿真内部的光流计算结果在进入 ROS 消息前会经过一次编码层处理,消费端需按该编码规则解码出二维光流矢量。

DVS camera

DVS 事件相机是唯一同时发布"事件流 + 图像 + 内参"三类 Topic 的传感器:

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/eventssensor_msgs/PointCloud2
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/imagesensor_msgs/Image
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>/camera_infosensor_msgs/CameraInfo

其实现 CarlaDVSCameraPublisher.cpp 由两个子发布器组合而成:CarlaDVSImagePublisher通过 DvsEventEncoding.h 中的EncodeDvsEventsToBgr将原始事件累加编码为 BGR 图像;CarlaDVSPointCloudPublisher则通过EncodeDvsEventsToPointCloud把每个事件(基于carla/sensor/data/DVSEvent结构,见GetPointSize()返回的sizeof(sensor::data::DVSEvent))转换为带时间戳t字段的点云消息。源码注释特别指出:事件时间戳为 int64,必须在编码为 FLOAT64t槽位时转换为 double,不能直接做字节拷贝,否则订阅方按 double 解码会得到错误比特。这解释了为什么eventsTopic 采用PointCloud2而非自定义消息——每个点即一个 (x, y, t, polarity) 事件。

点云类传感器:Lidar / Semantic lidar / Radar

三类三维感知传感器统一发布为sensor_msgs/PointCloud2,Topic 名不带后缀,直接落在基础名称上。

Lidar

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>sensor_msgs/PointCloud2

发布器实现在 CarlaLidarPublisher.cpp,点云字段布局由 PointCloudFieldsLayout.h 统一定义,保证下游(如 rviz、点云滤波、目标检测)可按标准PointField结构解析 x/y/z/intensity 等字段。

Semantic lidar

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>sensor_msgs/PointCloud2

语义激光雷达在几何信息基础上附带对象标签信息,发布器 CarlaSemanticLidarPublisher.cpp 负责将语义点数据写入PointCloud2字段。

Radar

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>sensor_msgs/PointCloud2

雷达发布器 CarlaRadarPublisher.cpp 需要把雷达返回的极坐标量测转换为笛卡尔坐标系下的点云,仓库中的 RadarPolarToCartesian.h 即承担这一坐标转换职责。消费雷达点云时,注意其字段除位置外通常还包含径向速度、方位角与俯仰角信息,字段名以PointCloud2消息内实际声明为准。

位姿与导航类传感器:IMU / GNSS

IMU

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>sensor_msgs/Imu

IMU 发布器 CarlaIMUPublisher.cpp 输出标准sensor_msgs/Imu(含线加速度、角速度与四元数姿态)。实现中引用了 ImuMath.h,可以推断原始惯性数据在写入消息前经过数学变换(例如坐标系对齐或单位换算),订阅方以消息内容为准即可。

GNSS

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>sensor_msgs/NavSatFix

GNSS 发布器 CarlaGNSSPublisher.cpp 输出sensor_msgs/NavSatFix,携带纬度、经度、海拔与定位状态协方差,可直接对接机器人导航栈(如 robot_localization、mapviz)。

事件类传感器:Lane Invasion Sensor

Lane Invasion Sensor

Topic类型
/carla/[<PARENT ROLE NAME>]/<SENSOR ROLE NAME>carla_msgs/CarlaLaneInvasionEvent

车道入侵传感器发布自定义消息CarlaLaneInvasionEvent,其字段在 Docs/ros2_native_msgs.md 中有完整定义:

字段类型描述
headerstd_msgs/Header消息发布时的时间戳与 frame ID
crossed_lane_markingsint32[]上一仿真步内被跨越的车道线集合,使用常量标识:LANE_MARKING_OTHER=0、LANE_MARKING_BROKEN=1、LANE_MARKING_SOLID=2

该消息属于carla_msgs自定义消息族。与sensor_msgs标准消息不同,使用前需要安装对应的消息定义包(CARLA 生态中的ros-carla-msgs),订阅方在编译期即可获得强类型定义。

实践指南:如何订阅这些 Topic

1. 验证数据是否在发布

启动带--ros2的 CARLA 服务端、spawn 并enable_for_ros()传感器后,使用 ROS2 命令行工具即可列出并检查 Topic:

ros2 topic list ros2 topic echo /carla/ego/front_camera/camera_info --once ros2 topic hz /carla/lidar

其中ros2 topic hz可用于确认点云/图像的发布频率与仿真帧率一致;相机图像可借助rqt_image_view直接可视化/carla/.../image

2. 订阅相机图像(Python 示例)

以下示例订阅 RGB 相机图像并打印其尺寸、编码与step

import rclpy from rclpy.node import Node from sensor_msgs.msg import Image class CarlaImageSubscriber(Node): def __init__(self): super().__init__('carla_image_subscriber') self.sub = self.create_subscription( Image, '/carla/ego/front_camera/image', self.on_image, 10) def on_image(self, msg: Image): self.get_logger().info( f'image {msg.width}x{msg.height}, encoding={msg.encoding}, ' f'step={msg.step}, stamp={msg.header.stamp.sec}.{msg.header.stamp.nanosec}') def main(): rclpy.init() rclpy.spin(CarlaImageSubscriber()) rclpy.shutdown()

注意三点:一是相机消息encoding字段(如 RGB 相机为"bgra8")决定了像素解码方式;二是header.stamp/clock来自同一仿真时钟,建议为节点启用use_sim_time;三是Image.data的长度为height * step,其中step = width * channels,不可用裸width * height计算(源码 CarlaCameraPublisher.cpp 中step(width * GetChannels())明确了这一关系)。

3. 订阅点云与 IMU

点云与 IMU 都是标准sensor_msgs消息,可直接复用通用处理管线:

  • PointCloud2:使用sensor_msgs_py.point_cloud2.read_points()逐点解析,或直接送入rviz2的 PointCloud2 显示插件;
  • Imu/NavSatFix:可分别接入惯性导航融合与全局定位模块,NavSatFix的经纬高直接对应仿真世界坐标在 WGS84 下的投影。

延伸阅读

  • 传感器之外的控制链路与启用细节,见 ROS2 原生接口总览(含--ros2启动、ros_name设置、/carla/ego/vehicle_control_cmd控制 Topic 与CarlaEgoVehicleControl字段说明);
  • 全部 CARLA 自定义消息(含CarlaLaneInvasionEventCarlaEgoVehicleControlCarlaStatusCarlaWorldInfo等)的逐字段参考,见 CARLA 消息参考;
  • 感兴趣的读者可深入 LibCarla/source/carla/ros2/publishers 目录逐一阅读各发布器实现,理解每个消息的序列化类型(...PubSubTypes,见 LibCarla/source/carla/ros2/types)与字段填充逻辑。
  • 自动驾驶
  • 科研
  • 仿真

【免费下载链接】carla

Open-source simulator for autonomous driving research.

项目地址:https://gitcode.com/gh_mirrors/ca/carla
点击查看免费下载

相关推荐

上一篇:一招治好键盘连击:免费工具 Keyboard Chatter Blocker 使用指南
下一篇:SR300 Python连接实战(Ubuntu 22.04):librealsense 深度流一次跑通

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询