在多机ROS中的时间同步问题

本文详细介绍了如何在局域网内实现两台Ubuntu系统的设备时间同步。通过在服务器端和客户端配置ntp服务,确保了ROS框架下无人车与笔记本的时间一致性,避免了因时间不同步引发的错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

局域网内两台设备时间同步

由于项目需要,需要笔记本和无人车上的tx2在无人车上的路由内组建局域网。但本项目系统是以ROS为框架的,需要两设备时间同步(不然会报各种莫名其妙的错误,笔者困惑了几天才发现…)。

笔记本是Uuntu16.04的系统,移动机器人的TX2也是16.04,二者通过路由器组建局域网,没有与外网连接。下面介绍如何通过ntp来对局域网内的两台电脑进行时间同步。

(1) 服务器端配置

在笔记本上安装ntp:

$ sudo apt install ntp

编辑配置文件/etc/ntp.conf

$ sudo vim /etc/ntp.conf

在文件中添加如下内容:

restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10

第一行是为了能让192.168.2.0/255网段上的机器能和本机进行时间同步;第二行和第三行是为了让本机的硬件时间和本机的ntp服务进行时间同步。

重启ntp服务:

$ sudo /etc/init.d/ntp restart

(2) 客户端配置

在笔记本上安装ntp:

$ sudo apt install ntp

编辑配置文件/etc/ntp.conf

$ sudo vim /etc/ntp.conf

使用指令进行时间同步:

$ sudo /usr/sbin/ntpdate 192.168.2.4

为了避免每次时间同步都要输入上述指令,可以在/etc/crontab文件中配置,让树莓派每分钟和笔记本进行一次时间同步。

$ sudo vim /etc/crontab

在文件末尾添加如下内容:

* * * * * /usr/sbin/ntpdate 192.168.1.101;/sbin/hwlocal -w

表示每分钟和局域网内ip为192.168.1.101的主机进行一次时间同步,并将时间写入硬件中。

ROS2中实现相雷达的时间同步主要依赖于ROS2的**时间同步制**以及**消息过滤器(message_filters)**。ROS2提供了比ROS1更强大的时间管理功能,包括支持**时间同步****传感器数据融合**。以下是具体实现步骤: ### 1. 确保传感器数据具有正确的时间戳 相雷达节点在发布数据时,必须为每个消息添加准确的时间戳(`header.stamp`)。通常,传感器驱动程序会自动设置时间戳,但需要确认是否启用该功能。 - 对于相,使用`usb_cam`或其他相驱动时,确保`image_raw`话题的消息头包含正确时间戳。 - 对于雷达,如`rslidar`,确保`PointCloud2`或`LaserScan`消息的时间戳准确无误。 ### 2. 使用 `message_filters` 实现时间同步 ROS2 提供了 `message_filters::TimeSynchronizer` 模板类,用于将个传感器消息按时间戳对齐。以下是一个C++示例,展示如何同步图像雷达点云数据: ```cpp #include <rclcpp/rclcpp.hpp> #include <sensor_msgs/msg/image.hpp> #include <sensor_msgs/msg/point_cloud2.hpp> #include <message_filters/subscriber.h> #include <message_filters/synchronizer.h> #include <message_filters/sync_policies/approximate_time.hpp> class SensorSyncNode : public rclcpp::Node { public: SensorSyncNode() : Node("sensor_sync_node") { // 创建订阅者 image_sub_.subscribe(this, "/usb_cam/image_raw"); lidar_sub_.subscribe(this, "/rslidar_points"); // 设置同步策略(ApproximateTime) using SyncPolicy = message_filters::sync_policies::ApproximateTime<sensor_msgs::msg::Image, sensor_msgs::msg::PointCloud2>; sync_.reset(new Synchronizer<SyncPolicy>(SyncPolicy(10), image_sub_, lidar_sub_)); sync_->registerCallback(std::bind(&SensorSyncNode::syncCallback, this, std::placeholders::_1, std::placeholders::_2)); } private: message_filters::Subscriber<sensor_msgs::msg::Image> image_sub_; message_filters::Subscriber<sensor_msgs::msg::PointCloud2> lidar_sub_; std::shared_ptr<message_filters::Synchronizer<message_filters::sync_policies::ApproximateTime<sensor_msgs::msg::Image, sensor_msgs::msg::PointCloud2>>> sync_; void syncCallback(const sensor_msgs::msg::Image::ConstSharedPtr& image_msg, const sensor_msgs::msg::PointCloud2::ConstSharedPtr& lidar_msg) { RCLCPP_INFO(this->get_logger(), "同步成功:图像时间戳 %f,雷达时间戳 %f", rclcpp::Time(image_msg->header.stamp).seconds(), rclcpp::Time(lidar_msg->header.stamp).seconds()); // 在此处处理同步后的数据 } }; ``` ### 3. 使用 ApproximateTime 同步策略 ROS2中推荐使用 `ApproximateTime` 策略,它允许一定时间误差内进行同步(默认为0.1秒),适用于大数实际应用。可以通过构造函数参数调整同步容忍时间。 ### 4. 录制与回放验证同步效果 可以使用 `ros2 bag record` 命令录制相雷达话题: ```bash ros2 bag record -O lidar_camera /usb_cam/image_raw /rslidar_points ``` 录制完成后,使用 `ros2 bag play` 回放并验证同步逻辑是否正常运行: ```bash ros2 bag play lidar_camera ``` ### 5. 可视化验证 使用 `rviz2` 可以加载录制的图像点云数据,观察是否同步显示: ```bash rviz2 -d $(find package_name)/rviz/config.rviz ``` ### 6. 时间戳查看与调试 可以通过 `ros2 topic echo` 查看消息的时间戳字段: ```bash ros2 topic echo /usb_cam/image_raw/header/stamp ros2 topic echo /rslidar_points/header/stamp ``` ### 注意事项 - 确保系统时间同步,使用`chronyd`或`ntp`服务保持系统时间准确。 - 如果传感器数据频率差异较大,适当调整同步队列大小时间容忍度。 - 若使用ROS2 Humble或更高版本,可结合`rclcpp::Time``rcl_time_point_value_t`进行更精细的时间处理。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值