ROS1/2机器人操作系统与时间Time的不解之缘
时间对于机器人操作系统非常重要。
所有机器人类的编程中所涉及的变量如果需要在网络中传输都需要这个数据结构的时间戳。
宏观上,ROS1、ROS2各版本都有官方支持的时间节点。
ROS时钟--支持时间倒计时小工具
效果如下:

如果要部署机器人操作系统,ROS1最好选择noetic,ROS2最好选择humble。
学习核心要点:
ros1:indigo、kinetic、melodic、noetic均可。
ros2:foxy、humble均可。
时钟和时间
官网介绍了支持编程的 ROS 原理和应用,这些编程既可以实时运行,也可以模拟时间运行,后者可能更快或更慢。
背景知识
许多机器人算法本质上依赖于定时和同步。 为此,要求在ROS网络中运行的节点具有同步的系统时钟,以便它们可以准确地报告事件的时间戳。
与此同时,在很多实际案例中,能够控制系统的进度很重要。
实时计算需要严格的时间控制。还有后续处理如下:
在回放记录的数据时,支持对时间进度的加速、减慢或阶梯控制通常非常有价值。 此控件允许到达特定时间并暂停系统,以便可以对其进行深入调试。 可以使用传感器数据的日志来执行此操作,但是如果传感器数据与系统的其余部分不同步,则会破坏许多算法。
使用抽象时间源的另一个重要用例是,当针对模拟机器人而不是真实机器人运行记录的数据时。 根据仿真特性,模拟器可能能够比实时运行得快得多,或者可能需要运行得更慢。 比实时运行得更快的速度对于高级测试以及允许重复系统测试很有价值。 对于精度比速度更重要的复杂系统,比实时仿真慢是必要的。 通常,仿真是系统的限制因素,因此模拟器可以成为更快或更慢播放的时间源。 此外,如果模拟暂停,系统也可以使用相同的机制暂停。
为了提供简化的时间接口,将提供 ROS 时间和持续时间数据类型。 要查询最新时间,将提供 ROS 时钟接口。 时间源可以管理一个或多个时钟实例。
使用抽象时间的挑战
有许多同步算法,它们通常可以实现比网络上设备之间网络通信延迟更好的精度。 但是,这些算法利用了有关时间恒定和连续性质的假设。
使用抽象时间的一个重要方面是能够操纵时间。 在某些情况下,加速、减慢或完全暂停时间对于调试非常重要。
支持暂停时间的能力要求不假设时间值总是在增加。
当通信时间传播的变化时,通信网络中的延迟成为一个挑战。 时间抽象的任何更改都必须传达给图中的其他节点,但会受到正常的网络通信延迟的影响。 这种不准确性与通信延迟成正比,也与模拟时间与实时相比前进的速率增加成正比(“实时因素”)。 如果在使用时间抽象时需要非常准确的时间戳,可以通过减慢实时因素来实现,从而使通信延迟相对较小。
最后一个挑战是时间抽象必须能够向后跳转,此功能对于日志文件播放非常有用。 此行为类似于负日期更改后的系统时钟,并且要求开发人员使用时间抽象来确保其算法可以处理不连续性。 必须为开发人员 API 提供适当的 API,以启用向前和向后的时间跳转通知。
使用介绍
通常,ROS 客户端库将使用计算机的系统时钟作为时间源,也称为“clock”或“挂钟”(如实验室墙上的时钟)。但是,当运行模拟或回放记录的数据时,通常需要让系统使用模拟时钟,以便可以加速、减慢或逐步控制系统的感知时间。例如,如果要将传感器数据回放到系统中,则可能希望时间与传感器数据的时间戳相对应。
为了支持这一点,ROS 客户端库可以监听用于发布“模拟时间”的 /clock 主题。
为了使代码利用 ROS 模拟时间,所有代码都必须使用适当的 ROS 客户端库时间 API 来访问时间和睡眠,而不是使用语言原生例程。这将使您的系统无论使用挂钟还是模拟时钟,都能进行一致的时间测量。下面简要介绍了这些 API,但您应该熟悉所选的客户端库以获取更多详细信息。
在多台计算机上使用挂钟时间时,在它们之间同步时间非常重要。ROS 不提供此功能,因为已经有成熟的方法(例如 ntp,我们推荐的同步工具是 chrony)来执行此操作。如果不同步多台机器的时钟,它们将不会就 tf 中使用的时间计算达成一致。
注意:这不是实时系统的 API!
使用 /clock 主题中的模拟时间
为了让ROS节点根据/clock主题使用模拟时间,在初始化节点之前,必须将/use_sim_time参数设置为true。这可以在启动文件中或从命令行完成。
如果设置了 /use_sim_time 参数,ROS 时间 API 将返回 time=0,直到收到来自 /clock 主题的值。然后,时间将仅在收到来自 /clock 主题的消息时更新,并且在更新之间保持不变。
对于使用模拟时间时持续时间的计算,客户端应始终等到收到第一个非零时间值后再开始,因为 /clock 主题中的第一个模拟时间值可能很高。
注意:在 ROS C Turtle 之前,节点会自动订阅 /clock 主题,如果有任何内容发布到 /clock 主题,节点将使用模拟时间。
运行时钟服务器
时钟服务器是发布到 /clock 主题的任何节点,单个 ROS 网络中不应运行多个节点。在大多数情况下,时钟服务器是模拟器或日志回放工具。
为了解决启动顺序的任何问题,在使用时钟服务器的任何启动文件中将 /use_sim_time 参数设置为 true 非常重要。如果您正在播放带有 rosbag 播放的包文件,则使用 --clock 选项将在播放包文件时运行时钟服务器。
最简单的案例演示:
ROS1
roscpp
//Get the time and store it in the time variable.
ros::Time time = ros::Time::now();
//Wait a duration of one second.
ros::Duration d = ros::Duration(1, 0);
d.sleep();
rospy
rospy.get_rostime() #get time as rospy.Time instance
rospy.get_time() #get time as float secs
rospy.sleep(duration)
具体cpp案例:
获取当前时间
ros::Time begin = ros::Time::now();
创建时间和持续时间实例
浮点数
ros::Time a_little_after_the_beginning(0.001);
ros::Duration five_seconds(5.0);
整型数
ros::Time a_little_after_the_beginning(0, 1000000);
ros::Duration five_seconds(5, 0);
转换时间和持续时间实例
double secs =ros::Time::now().toSec();ros::Duration d(0.5);
secs = d.toSec();
时间和持续时间算术
ros::Duration two_hours = ros::Duration(60*60) + ros::Duration(60*60);
ros::Duration one_hour = ros::Duration(2*60*60) - ros::Duration(60*60);
ros::Time tomorrow = ros::Time::now() + ros::Duration(24*60*60);
ros::Duration negative_one_day = ros::Time::now() - tomorrow;
云端实践-蓝桥ROS云课
使用turtlesim看一下时间戳的重要性。
在三个终端分别输入:
roscore

开启主节点roscore
rosrun turtlesim turtlesim_node [13:46:56]
[ INFO] [1677476826.846406306]: Starting turtlesim with node name /turtlesim
[ INFO] [1677476826.858068449]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]

启动turtlesim仿真
rosrun turtlesim draw_square [13:46:58]
[ INFO] [1677476941.925480026]: New goal [7.544445 5.544445, 0.000000]
[ INFO] [1677476943.845465404]: Reached goal
[ INFO] [1677476943.845537205]: New goal [7.448444 5.544445, 1.570796]
[ INFO] [1677476947.797971492]: Reached goal
[ INFO] [1677476947.798056675]: New goal [7.454037 7.544437, 1.568000]
[ INFO] [1677476949.733859442]: Reached goal
[ INFO] [1677476949.733924604]: New goal [7.453769 7.448437, 3.138796]
[ INFO] [1677476953.669993390]: Reached goal
[ INFO] [1677476953.670053662]: New goal [5.453913 7.472422, 3.129600]
[ INFO] [1677476955.605801148]: Reached goal
[ INFO] [1677476955.605865104]: New goal [5.549906 7.471271, 4.700396]
[ INFO] [1677476959.541884586]: Reached goal
[ INFO] [1677476959.541945308]: New goal [5.507532 5.471720, 4.691200]
[ INFO] [1677476961.478066122]: Reached goal
[ INFO] [1677476961.478127597]: New goal [5.509565 5.567698, 6.261996]
[ INFO] [1677476965.413272345]: Reached goal
[ INFO] [1677476965.413332146]: New goal [7.508642 5.506937, 6.252800]
[ INFO] [1677476967.349857822]: Reached goal
[ INFO] [1677476967.349916915]: New goal [7.412686 5.509853, 1.540412]
[ INFO] [1677476971.285716384]: Reached goal

启动画正方形
这里面时间不是常见格式的,那么参考如下:
rqt→console

时间不同格式表达
其中关于时间:
ros::Timer timer = nh.createTimer(ros::Duration(0.016), boost::bind(timerCallback, _1, twist_pub));
Node: /draw_square
Time: 13:55:19.311055762 (2023-02-27)
Severity: Info
Published Topics: /rosout, /turtle1/cmd_velNew goal [5.306689 5.861878, 5.998100]Location:
/tmp/binarydeb/ros-kinetic-turtlesim-0.7.1/tutorials/draw_square.cpp:printGoal:41
#include <boost/bind.hpp>
#include <ros/ros.h>
#include <turtlesim/Pose.h>
#include <geometry_msgs/Twist.h>
#include <std_srvs/Empty.h>turtlesim::PoseConstPtr g_pose;
turtlesim::Pose g_goal;enum State
{FORWARD,STOP_FORWARD,TURN,STOP_TURN,
};State g_state = FORWARD;
State g_last_state = FORWARD;
bool g_first_goal_set = false;#define PI 3.141592void poseCallback(const turtlesim::PoseConstPtr& pose)
{g_pose = pose;
}bool hasReachedGoal()
{return fabsf(g_pose->x - g_goal.x) < 0.1 && fabsf(g_pose->y - g_goal.y) < 0.1 && fabsf(g_pose->theta - g_goal.theta) < 0.01;
}bool hasStopped()
{return g_pose->angular_velocity < 0.0001 && g_pose->linear_velocity < 0.0001;
}void printGoal()
{ROS_INFO("New goal [%f %f, %f]", g_goal.x, g_goal.y, g_goal.theta);
}void commandTurtle(ros::Publisher twist_pub, float linear, float angular)
{geometry_msgs::Twist twist;twist.linear.x = linear;twist.angular.z = angular;twist_pub.publish(twist);
}void stopForward(ros::Publisher twist_pub)
{if (hasStopped()){ROS_INFO("Reached goal");g_state = TURN;g_goal.x = g_pose->x;g_goal.y = g_pose->y;g_goal.theta = fmod(g_pose->theta + PI/2.0, 2*PI);printGoal();}else{commandTurtle(twist_pub, 0, 0);}
}void stopTurn(ros::Publisher twist_pub)
{if (hasStopped()){ROS_INFO("Reached goal");g_state = FORWARD;g_goal.x = cos(g_pose->theta) * 2 + g_pose->x;g_goal.y = sin(g_pose->theta) * 2 + g_pose->y;g_goal.theta = g_pose->theta;printGoal();}else{commandTurtle(twist_pub, 0, 0);}
}void forward(ros::Publisher twist_pub)
{if (hasReachedGoal()){g_state = STOP_FORWARD;commandTurtle(twist_pub, 0, 0);}else{commandTurtle(twist_pub, 1.0, 0.0);}
}void turn(ros::Publisher twist_pub)
{if (hasReachedGoal()){g_state = STOP_TURN;commandTurtle(twist_pub, 0, 0);}else{commandTurtle(twist_pub, 0.0, 0.4);}
}void timerCallback(const ros::TimerEvent&, ros::Publisher twist_pub)
{if (!g_pose){return;}if (!g_first_goal_set){g_first_goal_set = true;g_state = FORWARD;g_goal.x = cos(g_pose->theta) * 2 + g_pose->x;g_goal.y = sin(g_pose->theta) * 2 + g_pose->y;g_goal.theta = g_pose->theta;printGoal();}if (g_state == FORWARD){forward(twist_pub);}else if (g_state == STOP_FORWARD){stopForward(twist_pub);}else if (g_state == TURN){turn(twist_pub);}else if (g_state == STOP_TURN){stopTurn(twist_pub);}
}int main(int argc, char** argv)
{ros::init(argc, argv, "draw_square");ros::NodeHandle nh;ros::Subscriber pose_sub = nh.subscribe("turtle1/pose", 1, poseCallback);ros::Publisher twist_pub = nh.advertise<geometry_msgs::Twist>("turtle1/cmd_vel", 1);ros::ServiceClient reset = nh.serviceClient<std_srvs::Empty>("reset");ros::Timer timer = nh.createTimer(ros::Duration(0.016), boost::bind(timerCallback, _1, twist_pub));std_srvs::Empty empty;reset.call(empty);ros::spin();
}
相关文章:

ROS1/2机器人操作系统与时间Time的不解之缘
时间对于机器人操作系统非常重要。所有机器人类的编程中所涉及的变量如果需要在网络中传输都需要这个数据结构的时间戳。宏观上,ROS1、ROS2各版本都有官方支持的时间节点。ROS时钟--支持时间倒计时小工具效果如下:如果要部署机器人操作系统,R…...
华为OD机试真题2022(JAVA)
华为机试题库已换 →→→ 华为OD机试2023(JAVA) 以下题目为旧版题库,供大家课外消遣 基础题: 序号题目分值1查找众数及中位数1002出错的或电路1003连续字母长度1004分班1005计算面积1006最远足迹1007判断一组不等式是否满足约束…...

【3】MyBatis+Spring+SpringMVC+SSM整合一套通关
三、SpringMVC 1、SpringMVC简介 1.1、什么是MVC MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分 M:Model,模型层,指工程中的JavaBean,作用是处理数据 JavaBean分为两类: 一类称为实体…...
20道前端高频面试题(附答案)
ES6新特性 1.ES6引入来严格模式变量必须声明后在使用函数的参数不能有同名属性, 否则报错不能使用with语句 (说实话我基本没用过)不能对只读属性赋值, 否则报错不能使用前缀0表示八进制数,否则报错 (说实话我基本没用过)不能删除不可删除的数据, 否则报错不能删除变量delete p…...

android EditText设置后缀
有两种实现方案。 方案一:是自己写一个TextWatcher。 方案二:是重写TextView的getOffsetForPosition方法,返回一个计算好的offset。 我在工作时,使用的是方案一。在离职之后,我还是对这个问题耿耿于怀,所以…...

prometheus+cadvisor监控docker
官方解释 cAdvisor(ContainerAdvisor)为容器用户提供了对其运行容器的资源使用和性能特性的了解。它是一个正在运行的守护程序,用于收集、聚合、处理和导出有关正在运行的容器的信息。具体来说,它为每个容器保存资源隔离参数、历史…...

正演(1): 二维声波正演模拟程序(中心差分)Python实现
目录 1、原理: 1)二维声波波动方程: 编辑 2)收敛条件(不是很明白) 3)雷克子波 4)二维空间衰减函数 5)边界吸收条件 (不是很明白。。) 2、编程实现 1)参数设置&…...

珠海数据智能监控器+SaaS平台 轻松实现SMT生产管控
数据智能监控器 兼容市面上99%的SMT设备 直接读取设备生产数据与状态,如:计划产出、实际产出、累计产出、停机、节拍、线利用率、直通率、停产时间、工单状态、OEE…… 产品功能价值 ◎ OEE不达标报警,一手掌握生产效能 ◎ 首检/巡检/成…...
习题22对前面21节的归纳总结
笨方法学python --习题22 Vi---Rum 于 2021-01-12 14:16:10 发布 python 习题22 这节内容主要是归纳总结 ex1.py 第一次学习 1.print:打印 2.# :是注释的意思,井号右边的内容不再执行 3.end"":,在句子结尾加上这个就不会再换行…...
使用Vite快速构建前端React项目
一、Vite简介 Vite是一种面向现代浏览器的一个更轻、更快的前端构建工具,能够显著提升前端开发体验。除了Vite外,前端著名的构建工具还有Webpack和Gulp。目前,Vite已经发布了Vite3,Vite全新的插件架构、丝滑的开发体验,可以和Vue3完美结合。 相比Webpack和Gulp等构建工具…...

人工智能高等数学--人工智能需要的数学知识_微积分_线性代数_概率论_最优化---人工智能工作笔记0024
然后我们看一下人工智能中需要的数学知识 数学知识是重要的,对于理解人工智能底层原理来说很重要,但是工作中 工作中一般都不会涉及的自己写算法之类的,只是面试,或者理解底层原理的时候需要 然后看一下人工智能需要哪些数学知识 这里需要微积分 线性代数 概率论 最优化的知识…...

阿里大数据之路总结
一、数据采集 二、数据同步 2.1、数据同步方式: 数据同步的三种方式:直连方式、数据文件同步、数据库日志解析方式 关系型数据库的结构化数据:MYSQL、Oracle、DB2、SQL Server非关系型数据库的非结构化数据(数据库表形式存储&am…...

ABAP中Literals的用法(untyped literal vs. typed literal)
1. 什么是Literals ? Literals的字面意思即“文字”。其实,Literals就是在ABAP代码中直接指定的一个字符串,但注意哦,这个字符串并不意味着其类型一定是string哦。 要弄清这个概念,就要清楚ABAP对于Literals 的定义和处理方式。…...

tensorflow1.14.0安装教程
1首先电脑安装好Anaconda3(Anaconda介绍、安装及使用教程 - 知乎 (zhihu.com),) 蟒蛇 |全球最受欢迎的数据科学平台 (anaconda.com) 2打开Anaconda Prompt(本人更新win11后,主菜单不再显示,那么我们可以打…...

C++赋值运算符重载
赋值运算符重载 目录赋值运算符重载示例1:示例2:示例3:示例4:很巧妙的是,在编写这篇文章时(2023年2月27日),再加100天就是6月7日,恰好是今年高考的百日誓师! …...

网络性能总不好?专家帮你来“看看”— CANN 6.0 黑科技 | 网络调优专家AOE,性能效率双提升
随着深度学习模型复杂度和数据集规模的增大,计算效率的提升成为不可忽视的问题。然而,算法网络的多样性、输入数据的不确定性以及硬件之间的差异性,使得网络调优耗费巨大成本,即使是经验丰富的专家,也需要耗费数天的时…...

Qss自定义属性
QSS自定义属性 更多精彩内容👉个人内容分类汇总 👈👉QSS样式学习 👈文章目录QSS自定义属性[toc]前言一、实现效果二、使用方式1.QSS设置Q_PROPERTY属性样式2.QSS设置动态属性样式3.qproperty-<属性名称>语法14.qproperty-&…...

连接金蝶云星空,数据交互轻松搞定!丨三叠云
金蝶云星空 路径 拓展 >> 插件 功能简介 新增插件「金蝶云星空」。 用户可通过配置「金蝶云星空」插件,就可以实时获取「金蝶云星空」的数据,同时支持回填数据至金蝶系统内。 地图视图 路径 表单 >> 表单设计 功能简介 新增「地图视…...
JSX是什么,React为什么使用JSX,babel怎么转译JSX的
JSX是什么,React为什么使用JSX,babel怎么转译JSX的 在前端的框架中有两种“描述UI”的方案,一种是JSX语法,一种是模板语言。 其中React就是选择的JSX,Vue就是选择的模板语言。 JSX其实就是一个语法糖,在…...

从工地转行软件测试,拿下13k+年终奖是种什么体验?
最近,一则名为《我:毕业五年,存款5000。她:中传硕士,火锅店保洁》的视频走红网络,两位名校毕业生看似高开低走的就业经历,引起了很多人的共鸣。她们所传达的并不是所谓的躺平、摆烂,而是希望更多…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...