侧边栏壁纸
  • 累计撰写 131 篇文章
  • 累计创建 16 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录
ROS   

ROS的时间系统,以及时间相关

ROS时间系统对于实现同步、调试和控制至关重要。以下是对ROS时间系统、时间戳及时间相关设置的详细讲解。

时间系统概述

ROS中有两种主要的时间概念:

  • Wall Time(墙钟时间):基于系统时钟,反映实际的时间。适用于大多数需要实际时间戳的场景。
  • ROSTime(ROS时间):可以被模拟器和仿真器控制,用于仿真环境中。可通过暂停、快进、慢放等方式操控时间流逝。

时间类型

ROS提供了三个主要的时间相关数据类型:

  • ros::Time:表示时间点,支持wall time和ROS time两种模式。
  • ros::Duration:表示时间段。
  • ros::Rate:控制循环频率,确保循环以固定的时间间隔执行。

在ROS中,时间的格式主要有两种:秒(seconds)纳秒(nanoseconds)。以下是详细介绍。

ros::Time类型表示一个具体的时间点,包含两个字段:

class Time {
public:
    uint32_t sec;  // 秒
    uint32_t nsec; // 纳秒
};

时间戳

时间戳在ROS中通常用来标记消息的生成时间。在消息定义中,常包含一个std_msgs/Header,其中Header结构有一个时间戳字段:

std_msgs/Header header
uint32 seq
time stamp
string frame_id

stamp字段就是一个时间戳,表示消息生成的具体时间点。

时间戳的生成

时间戳可以通过ros::Time类来生成。通常,时间戳在消息生成时获取当前时间:

#include <ros/ros.h>
#include <std_msgs/String.h>

void generateMessage() {
    std_msgs::String msg;
    msg.header.stamp = ros::Time::now();  // 获取当前时间作为时间戳
    msg.header.frame_id = "base_link";    // 设置坐标系
    msg.data = "Hello, world!";
    // 发布消息...
}

时间戳的格式

时间戳在ROS中以秒和纳秒表示。ros::Time类包含两个主要字段:

class Time {
public:
    uint32_t sec;  // 秒
    uint32_t nsec; // 纳秒
};

基准时间的获取

在ROS中,时间的准确性和同步性对于多机器人系统、传感器数据同步和控制系统至关重要。PTP(Precision Time Protocol,精密时间协议)是一种用于同步计算机网络中时钟的协议,它提供了比NTP(Network Time Protocol,网络时间协议)更高的精度。

1. 精密时间协议(PTP)

PTP是一种用于网络设备间时间同步的协议,常用于需要高精度时间同步的场景,例如金融交易、工业控制和电信领域。

PTP的特点
  • 高精度:PTP可以实现亚微秒级的时间同步,远高于NTP的毫秒级。
  • 硬件支持:许多高端网络设备(如交换机、网卡)直接支持PTP,进一步提高了同步精度。
  • 层级结构:PTP使用主从架构,一个主时钟(Grandmaster)和多个从时钟(Slave),通过时间戳消息进行同步。
PTP在ROS中的应用

在ROS中,使用PTP进行时间同步可以确保多机器人系统或分布式传感器的时间一致性。

配置PTP
  1. 安装PTP工具:大多数Linux系统可以使用ptpdphc2sys等工具进行PTP配置。

    sudo apt-get install ptpd
    
  2. 配置PTP守护进程:编辑/etc/ptpd.conf或使用命令行参数配置PTP。

    sudo ptpd -M -i eth0 -f /etc/ptpd.conf
    
  3. 启动PTP守护进程

    sudo systemctl start ptpd
    
  4. 验证同步状态:使用ptp4lpmc工具检查PTP同步状态。

    sudo ptp4l -i eth0 -m
    

2. 网络时间协议(NTP)

NTP是一种常见的时间同步协议,广泛用于Internet和局域网中。

NTP的特点
  • 广泛支持:几乎所有的操作系统和网络设备都支持NTP。
  • 中等精度:通常可以达到毫秒级别的同步精度。
  • 分层结构:NTP服务器分层次工作,最顶层是Stratum 1服务器,与原子钟或GPS同步。
NTP在ROS中的应用

NTP适用于大多数需要时间同步的ROS应用,尤其是时间精度要求不高的场景。

配置NTP
  1. 安装NTP客户端

    sudo apt-get install ntp
    
  2. 配置NTP服务器:编辑/etc/ntp.conf文件,添加NTP服务器地址。

    server ntp.ubuntu.com
    
  3. 启动NTP服务

    sudo systemctl start ntp
    
  4. 检查同步状态

    ntpq -p
    

3. 本地系统时间

在ROS中,默认使用本地系统时间(Wall Time)。在不需要高精度时间同步的单机应用中,使用本地系统时间即可。

获取本地系统时间
ros::Time now = ros::Time::now();  // 获取当前时间

设置与使用

初始化与当前时间获取

ros::Time::init(); // 初始化时间系统
ros::Time now = ros::Time::now(); // 获取当前时间

创建时间与持续时间对象

// 创建具体时间点
ros::Time t1(10.5); // 表示10.5秒
ros::Time t2 = ros::Time::now(); // 当前时间

// 创建时间段对象
ros::Duration d1(5.0); // 5秒
ros::Duration d2 = t2 - t1; // 两个时间点之间的差值

时间操作

ros::Time t3 = t1 + d1; // 时间加上持续时间
ros::Duration d3 = t2 - t1; // 两个时间点的差值

使用Rate控制频率

ros::Rate loop_rate(10); // 10Hz的循环频率

while (ros::ok()) {
    // 循环体
    loop_rate.sleep(); // 休眠以维持循环频率
}

模拟时间

在仿真环境中(如使用Gazebo),需要使用模拟时间。可以在启动文件中启用模拟时间:

<param name="use_sim_time" value="true"/>

使用rospy时,类似的设置:

import rospy

rospy.init_node('my_node')
rospy.set_param('use_sim_time', True)

时间转换与比较

if (t1 < t2) {
    // t1早于t2
}

ros::Duration duration = t1 - t2; // 时间差
ros::Time future_time = t1 + ros::Duration(10); // 未来时间
0

评论区