当前位置:   article > 正文

机器人操作系统ROS(十一):ROS时间戳及其与年月日时分秒毫秒格式的转换_ros时间戳转换为年月日

ros时间戳转换为年月日

ROS时间戳

在ROS(机器人操作系统)中,时间戳(Timestamp)是一个重要的概念,用于在消息传递和数据同步中跟踪和标记事件的时间。ROS使用一种称为ROS::Time的数据结构来表示时间戳,通常与ROS消息一起使用。以下是有关ROS时间戳的一些关键信息:

  1. 数据结构

ROS::Time 是ROS中表示时间戳的数据结构。它包括两个成员变量:sec(秒)和nsec(纳秒)。这两个成员变量的组合提供了一个精确的时间戳,精度为纳秒级。例如,ros::Time(1633895107, 123456789) 表示的时间戳为1633895107秒 + 123456789纳秒。

  1. 时钟来源

在roscpp(C++)和rospy(Python)中,可以使用相应的API来获取当前时间、计算时间差、比较时间戳等。例如在C++中,ros::Time::now() 获取当前时间戳,在Python中,rospy.get_rostime()获取当前时间戳。

时间信息的来源有两种,系统时间和仿真时间,分别被称为Wall Time和ROS Time,可以通过参数use_sim_time来进行选择,当use_sim_timetrue时选择使用仿真时间,反之使用系统时间。

# 使用仿真时间
rosparam set use_sim_time true
# 使用系统时间
rosparam set use_sim_time false
  • 1
  • 2
  • 3
  • 4

系统时间直接通过访问本地时钟来获得,而仿真时间则需要订阅/clock话题的消息获得,每当接收到该话题的消息,时间才会更新,在没有接收到该话题的第一个消息时,当前时间为0,/clock是通过仿真时间服务器发布的,通常为ros_bag节点或仿真器。

此外,ROS的绝对时间戳ROS::WallTime,它不可以被人为修改,不同话题或服务数据的ROS::Time时间戳会和绝对时间戳ROS::WallTime有一个差值,如果需要满足较高精度的对齐,需要进行时间补偿。

  1. 应用

在ROS中,每个消息类型通常一般都包含一个时间戳字段,例如Header消息类型包括stamp字段,用于存储时间戳。这允许节点记录和传递消息的时间信息。使用ROS时间戳,可以实现多个节点之间的数据同步。

ROS时间戳转换为年月日时分秒毫秒格式

要将ROS时间戳转换为年、月、日、小时、分钟、秒和毫秒,可以使用C++或Python来解析时间戳的各个部分。以下是一个示例代码,展示如何在ROS中完成这项任务。

C++示例

#include <ros/ros.h>

int main(int argc, char** argv)
{
    ros::init(argc, argv, "timestamp_conversion_node");
    ros::NodeHandle nh;

    // 获取当前时间戳
    ros::Time current_time = ros::Time::now();

    // 将时间戳转换为秒和纳秒
    int32_t seconds = current_time.sec;
    int32_t nanoseconds = current_time.nsec;

    // 将秒转换为日期和时间
    ros::WallTime wall_time = ros::WallTime(current_time);
    int year = wall_time.toBoost().date().year();
    int month = wall_time.toBoost().date().month();
    int day = wall_time.toBoost().date().day();
    int hour = wall_time.toBoost().time_of_day().hours();
    int minute = wall_time.toBoost().time_of_day().minutes();
    int second = wall_time.toBoost().time_of_day().seconds();
    int millisecond = nanoseconds / 1e6; // 毫秒

    // 打印结果
    ROS_INFO("Year: %d, Month: %d, Day: %d, Hour: %d, Minute: %d, Second: %d, Millisecond: %d", year, month, day, hour, minute, second, millisecond);

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

Python示例

#!/usr/bin/env python
import rospy
from datetime import datetime

def timestamp_to_datetime():
    rospy.init_node('timestamp_conversion_node', anonymous=True)
    
    # 获取当前时间戳
    current_time = rospy.get_rostime()
    
    # 将时间戳转换为秒和纳秒
    seconds = current_time.secs
    nanoseconds = current_time.nsecs
    
    # 将秒转换为日期和时间
    dt = datetime.fromtimestamp(seconds)
    year = dt.year
    month = dt.month
    day = dt.day
    hour = dt.hour
    minute = dt.minute
    second = dt.second
    millisecond = nanoseconds / 1e6  # 毫秒
    
    # 打印结果
    rospy.loginfo("Year: %d, Month: %d, Day: %d, Hour: %d, Minute: %d, Second: %d, Millisecond: %d", year, month, day, hour, minute, second, millisecond)
    
    rospy.spin()

if __name__ == '__main__':
    try:
        timestamp_to_datetime()
    except rospy.ROSInterruptException:
        pass

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

这些示例代码会获取当前ROS时间戳,然后将其分解为年、月、日、小时、分钟、秒和毫秒,并将这些值打印出来。可以根据自己的需求来使用这些值。

年月日时分秒毫秒转换为ROS时间戳格式

要将年、月、日、小时、分钟、秒和毫秒转换为ROS时间戳,可以使用ROS的时间处理函数。以下是一个示例代码,演示如何从年、月、日、小时、分钟、秒和毫秒创建ROS时间戳。

C++示例

#include <ros/ros.h>

int main(int argc, char** argv)
{
    ros::init(argc, argv, "reverse_timestamp_conversion_node");
    ros::NodeHandle nh;

    // 定义日期和时间的各个部分
    int year = 2023;
    int month = 10;
    int day = 9;
    int hour = 14;
    int minute = 30;
    int second = 45;
    int millisecond = 500; // 毫秒

    // 创建tm结构体以便使用ROS的时间函数
    struct tm time_struct;
    time_struct.tm_year = year - 1900;  // 年份应减去1900
    time_struct.tm_mon = month - 1;     // 月份从0开始,所以需要减1
    time_struct.tm_mday = day;
    time_struct.tm_hour = hour;
    time_struct.tm_min = minute;
    time_struct.tm_sec = second;

    // 使用mktime将tm结构体转换为时间戳
    time_t time_seconds = mktime(&time_struct);

    // 创建ROS时间戳
    ros::Time ros_time(time_seconds, millisecond * 1e6); // 将毫秒转换为纳秒

    // 打印结果
    ROS_INFO("ROS Timestamp: %d.%09d", ros_time.sec, ros_time.nsec);

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

python示例

#!/usr/bin/env python
import rospy
from datetime import datetime
from time import mktime

def datetime_to_timestamp():
    rospy.init_node('reverse_timestamp_conversion_node', anonymous=True)
    
    # 定义日期和时间的各个部分
    year = 2023
    month = 10
    day = 9
    hour = 14
    minute = 30
    second = 45
    millisecond = 500  # 毫秒
    
    # 创建datetime对象
    dt = datetime(year, month, day, hour, minute, second, int(millisecond * 1e3))
    
    # 使用mktime将datetime对象转换为时间戳
    time_seconds = mktime(dt.timetuple())
    time_nanos = float(millisecond / 1e3)
    
    # 创建ROS时间戳
    ros_time = rospy.Time.from_sec(time_seconds+time_nanos)
    
    # 打印结果
    rospy.loginfo("ROS Timestamp: %d.%09d", ros_time.secs, ros_time.nsecs)
    
    rospy.spin()

if __name__ == '__main__':
    try:
        datetime_to_timestamp()
    except rospy.ROSInterruptException:
        pass

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

这些示例代码演示了如何从年、月、日、小时、分钟、秒和毫秒创建一个ROS时间戳。首先,需要定义这些时间部分,然后使用适当的函数(mktime或rospy.Time.from_sec)将它们转换为ROS时间戳的秒和纳秒部分。然后,可以将这些部分组合成一个ROS时间戳对象。

常见问题

在此汇总了在实践中一些常见的关于时间戳的问题。

时钟问题

rostopic echo /topic_name发现有数据,但是rostopic hz /topic_name显示no new massage
使用以下指令获取时钟来源:

rosparam get use_sim_time 
  • 1

发现使用了仿真时间,而不是系统时间。由于没有rosbag播放数据,因此需要设置使用系统时间,在终端输入下面指令即可解决:

rosparam set use_sim_time false
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/479926
推荐阅读
相关标签
  

闽ICP备14008679号