1.硬件方面采用PTP+PPS 统一时钟基准
2.软件层时间戳对齐和补偿
a. 雷达 点云帧嵌入ptt时间戳,相机每帧图像元数据写入触发时刻ptp时间戳
3.帧匹配,雷达10hz,相机30hz 以相机时间戳为基准,取前后两帧雷达点云插值到相机的曝光时刻

同步精度1~5ms
应用实例:
PTP 系统时钟同步 + ROS 时间戳软同步(时间戳插值 + 最近帧匹配)
原理 1. 雷达、相机、域控制器 系统时钟完全统一(PTP) 2. 相机自由运行(不用触发) 3. ROS 节点自动找时间最接近的一帧做配对 4. 低速下 1~3ms 误差完全不影响融合 精度 1~3ms → 低速场景(10km/h)移动距离仅 0.3~3cm,完全可用。 二、不需要做的事(你可以省掉) • ❌ 不需要接任何触发线 • ❌ 不需要 PPS • ❌ 不需要解串板 • ❌ 不需要硬件同步 • ❌ 不需要改相机参数 三、必须做的唯一硬件前提 1. 雷达网线插域控制器 2. 相机 GMSL 直插域控制器 GMSL 口 3. 所有设备共用域控制器的系统时钟 四、第一步:安装 PTP 时钟同步(让所有传感器时间统一) 1. 安装 PTP(必须) bash 运行 sudo apt update
sudo apt install linuxptp
- 启动 PTP 同步雷达时钟 雷达是以太网设备,必须同步: bash 运行 sudo ptp4l -i eth0 -m -S &
sudo phc2sys -s /dev/ptp0 -c CLOCK_REALTIME -w &
- 验证时间是否统一 bash 运行 timedatectl
看到 System clock synchronized: yes 就成功。 五、第二步:ROS 同步代码(直接复制使用) 功能 • 自动匹配时间最近的雷达 + 相机 • 自动对齐时间戳 • 输出同步后的点云与图像 • 低速场景完美使用 1. 创建功能包 bash 运行 cd ~/catkin_ws/src
catkin_create_pkg lidar_cam_sync roscpp sensor_msgs cv_bridge image_transport message_filters
- 核心代码 src/sync_node.cpp cpp 运行 #include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/Image.h>
#include <message_filters/subscriber.h>
#include <message_filters/sync_policies/approximate_time.h>
#include <message_filters/synchronizer.h>
using namespace message_filters;
// 同步后发布
ros::Publisher pub_lidar;
ros::Publisher pub_image;
// 同步回调
void callback(
const sensor_msgs::PointCloud2ConstPtr& lidar,
const sensor_msgs::ImageConstPtr& cam)
{
// 时间差(单位:秒)
double diff = fabs((lidar->header.stamp - cam->header.stamp).toSec());
// 只同步时间差 < 0.003s (3ms) 的帧(低速足够)
if (diff > 0.003) {
ROS_WARN("时间差过大: %.1f ms → 丢弃", diff * 1000);
return;
}
// 统一时间戳(用雷达时间作为基准)
ros::Time t = lidar->header.stamp;
sensor_msgs::PointCloud2 lidar_out = *lidar;
sensor_msgs::Image cam_out = *cam;
lidar_out.header.stamp = t;
cam_out.header.stamp = t;
pub_lidar.publish(lidar_out);
pub_image.publish(cam_out);
ROS_INFO("同步成功 | 时间差: %.1f ms", diff * 1000);
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "lidar_cam_time_sync");
ros::NodeHandle nh;
// 订阅话题(你可以改成自己的实际话题)
Subscriber<sensor_msgs::PointCloud2> sub_lidar(nh, "/hesai/pandar", 10);
Subscriber<sensor_msgs::Image> sub_cam(nh, "/senyun_camera/image_raw", 10);
// 近似时间同步(软同步核心)
typedef sync_policies::ApproximateTime<sensor_msgs::PointCloud2, sensor_msgs::Image> MySyncPolicy;
Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), sub_lidar, sub_cam);
sync.registerCallback(boost::bind(&callback, _1, _2));
// 发布同步后的数据
pub_lidar = nh.advertise<sensor_msgs::PointCloud2>("/sync/lidar", 10);
pub_image = nh.advertise<sensor_msgs::Image>("/sync/image", 10);
ros::spin();
return 0;
}
- CMakeLists.txt cmake cmake_minimum_required(VERSION 3.0.2)
project(lidar_cam_sync)
set(CMAKE_CXX_STANDARD 14)
find_package(catkin REQUIRED COMPONENTS
roscpp
sensor_msgs
cv_bridge
image_transport
message_filters
)
catkin_package()
include_directories(${catkin_INCLUDE_DIRS})
add_executable(sync_node src/sync_node.cpp)
target_link_libraries(sync_node ${catkin_LIBRARIES})
- launch 文件 launch/sync.launch xml <launch>
<!-- 速腾雷达 -->
<include file="$(find hesai_lidar)/launch/lidar.launch" />
<!-- 森云相机 -->
<include file="$(find senyun_camera)/launch/camera.launch" />
<!-- 同步节点 -->
<node pkg="lidar_cam_sync" type="sync_node" name="sync_node" output="screen"/>
</launch>
六、编译运行 bash 运行 cd ~/catkin_ws
catkin_make -DCMAKE_BUILD_TYPE=Release
source devel/setup.bash
roslaunch lidar_cam_sync sync.launch
七、看到下面日志 = 同步成功 plaintext [INFO] [1718881234.123456]: 同步成功 | 时间差: 1.2 ms
INFO\] \[1718881234.223456\]: 同步成功 \| 时间差: 0.8 ms 时间差 \< 3ms 就是优秀! 八、低速场景为什么这个方案足够 九、我给你总结最简步骤(你照着做就行) 1. 安装 PTP,统一系统时钟 2. 启动雷达驱动 3. 启动相机驱动 4. 运行我给你的同步节点 5. 完成!