ROS学习第十五节——常用API(C++)

news2024/11/13 9:36:33

由于时间问题,从这一节开始只记录C++实现效果,加油

以下附上这一节调试用的程序

https://download.csdn.net/download/qq_45685327/87708069

1.初始化函数


void init(int &argc, char **argv, const std::string& name, uint32_t options = 0);
作用:ROS初始化函数

参数:
1.argc :封装实参的个数(n+1)
2.argv :封装参数的数组
3.name :为集诶但命名(唯一性)
4.options :节点启动选项

返回值:void

使用:
1.argc 与 argv 的使用
    如果按照ROS中的特定格式传入实参,那么ROS可以加以使用,比如用来设置全局参数,给节点重命名
2.options 的使用
    节点名称需要保证唯一性,同一个节定不能重复启动,启动一个节点以后,再启动相同节点,前一个窗口的节
    点运行就会被强制关闭,然后再在新的窗口重新运行节点 
    需求:特定场景下,需要一个节点多次启动且能正常运行,该怎么办?
    ros::init(argc,argv,"talker_api",ros::init_options::AnonymousName);
    这样写,每次打开相同节点就会在节点后面添加一个数字,两个都能正常运行



void init(int &argc, char **argv, const std::string& name, uint32_t options = 0);

实际操作:

2.1.argv作用

创建一个工程,demo01_pub_apis

 使用命令给argv数组中添加参数并赋值

rosrun learn_apis demo01_pub_apis _number:=0

2.2options作用

启动一个节点以后,再启动相同节点,前一个窗口的节点运行就会被强制关闭,然后再在新的窗口重新运行节点

    ros::init(argc,argv,"talker_api",ros::init_options::AnonymousName);

 这样设置

 

 2.创建发布者对象

作用:创建发布者对象

模板:被发布的消息的类型

参数:
    1.话题名称
    2.队列长度
    3.latch(可选)如果设置为true,会保存发布方的最后一条消息,并且新的订阅对象连接到发布方时,发布
    方会将这条消息发送给订阅者

使用
    latch 设置为 true的作用?
    以静态地图发布为例,方案一:可以使用固定频率发布数据,效率低。方案二:可以将地图发布对象的latch
    并且发布方只发布一次数据,每当订阅者连接时,将地图信息发送给订阅者(只发送一次),这样提升数据发
    送效率
    ros::Publisher pub = nh.advertise<std_msgs::String>("apis_0",10,true);

 3.回旋函数

在ROS程序中,频繁的使用了 ros::spin() 和 ros::spinOnce() 两个回旋函数,可以用于处理回调函数。

3.1spinOnce()

/**
 * \brief 处理一轮回调
 *
 * 一般应用场景:
 *     在循环体内,处理所有可用的回调函数
 * 
 */
ROSCPP_DECL void spinOnce();

3.2spin()

/** 
 * \brief 进入循环处理回调 
 */
ROSCPP_DECL void spin();

3.3二者比较

相同点:二者都用于处理回调函数;

不同点:ros::spin() 是进入了循环执行回调函数,而 ros::spinOnce() 只会执行一次回调函数(没有循环),在 ros::spin() 后的语句不会执行到,而 ros::spinOnce() 后的语句可以执行。

4.时间

ROS中时间相关的API是极其常用,比如:获取当前时刻、持续时间的设置、执行频率、休眠、定时器...都与时间相关。

4.1时刻

获取时刻,或是设置指定时刻:

ros::init(argc,argv,"hello_time");
ros::NodeHandle nh;//必须创建句柄,否则时间没有初始化,导致后续API调用失败
ros::Time right_now = ros::Time::now();//将当前时刻封装成对象
ROS_INFO("当前时刻:%.2f",right_now.toSec());//获取距离 1970年01月01日 00:00:00 的秒数
ROS_INFO("当前时刻:%d",right_now.sec);//获取距离 1970年01月01日 00:00:00 的秒数

ros::Time someTime(100,100000000);// 参数1:秒数  参数2:纳秒
ROS_INFO("时刻:%.2f",someTime.toSec()); //100.10
ros::Time someTime2(100.3);//直接传入 double 类型的秒数
ROS_INFO("时刻:%.2f",someTime2.toSec()); //100.30

演示效果

4.2持续时间

设置一个时间区间(间隔):

ROS_INFO("当前时刻:%.2f",ros::Time::now().toSec());
ros::Duration du(10);//持续10秒钟,参数是double类型的,以秒为单位
du.sleep();//按照指定的持续时间休眠
ROS_INFO("持续时间:%.2f",du.toSec());//将持续时间换算成秒
ROS_INFO("当前时刻:%.2f",ros::Time::now().toSec());

演示效果

4.3持续时间与时刻运算

为了方便使用,ROS中提供了时间与时刻的运算:

ROS_INFO("时间运算");
ros::Time now = ros::Time::now();
ros::Duration du1(10);
ros::Duration du2(20);
ROS_INFO("当前时刻:%.2f",now.toSec());
//1.time 与 duration 运算
ros::Time after_now = now + du1;
ros::Time before_now = now - du1;
ROS_INFO("当前时刻之后:%.2f",after_now.toSec());
ROS_INFO("当前时刻之前:%.2f",before_now.toSec());

//2.duration 之间相互运算
ros::Duration du3 = du1 + du2;
ros::Duration du4 = du1 - du2;
ROS_INFO("du3 = %.2f",du3.toSec());
ROS_INFO("du4 = %.2f",du4.toSec());
//PS: time 与 time 不可以运算
// ros::Time nn = now + before_now;//异常

运行效果

4.4设置运行频率

ros::Rate rate(1);//指定频率
while (true)
{
    ROS_INFO("-----------code----------");
    rate.sleep();//休眠,休眠时间 = 1 / 频率。
}

4.5定时器

ROS 中内置了专门的定时器,可以实现与 ros::Rate 类似的效果:

ros::NodeHandle nh;//必须创建句柄,否则时间没有初始化,导致后续API调用失败

 // ROS 定时器
 /**
* \brief 创建一个定时器,按照指定频率调用回调函数。
*
* \param period 时间间隔
* \param callback 回调函数
* \param oneshot 如果设置为 true,只执行一次回调函数,设置为 false,就循环执行。
* \param autostart 如果为true,返回已经启动的定时器,设置为 false,需要手动启动。
*/
 //Timer createTimer(Duration period, const TimerCallback& callback, bool oneshot = false,
 //                bool autostart = true) const;

 // ros::Timer timer = nh.createTimer(ros::Duration(0.5),doSomeThing);
 ros::Timer timer = nh.createTimer(ros::Duration(0.5),doSomeThing,true);//只执行一次

 // ros::Timer timer = nh.createTimer(ros::Duration(0.5),doSomeThing,false,false);//需要手动启动
 // timer.start();
 ros::spin(); //必须 spin

定时器的回调函数:

void doSomeThing(const ros::TimerEvent &event){
    ROS_INFO("-------------");
    ROS_INFO("event:%s",std::to_string(event.current_real.toSec()).c_str());
}

运行效果

 5.其他函数

在发布实现时,一般会循环发布消息,循环的判断条件一般由节点状态来控制,C++中可以通过 ros::ok() 来判断节点状态是否正常,而 python 中则通过 rospy.is_shutdown() 来实现判断,导致节点退出的原因主要有如下几种:

  • 节点接收到了关闭信息,比如常用的 ctrl + c 快捷键就是关闭节点的信号;
  • 同名节点启动,导致现有节点退出;
  • 程序中的其他部分调用了节点关闭相关的API(C++中是ros::shutdown(),python中是rospy.signal_shutdown())

另外,日志相关的函数也是极其常用的,在ROS中日志被划分成如下级别:

  • DEBUG(调试):只在调试时使用,此类消息不会输出到控制台;
  • INFO(信息):标准消息,一般用于说明系统内正在执行的操作;
  • WARN(警告):提醒一些异常情况,但程序仍然可以执行;
  • ERROR(错误):提示错误信息,此类错误会影响程序运行;
  • FATAL(严重错误):此类错误将阻止节点继续运行。

5.1节点状态判断

/** \brief 检查节点是否已经退出
 *
 *  ros::shutdown() 被调用且执行完毕后,该函数将会返回 false
 *
 * \return true 如果节点还健在, false 如果节点已经火化了。
 */
bool ok();

5.2节点关闭函数

/*
*   关闭节点
*/
void shutdown();

5.3日志函数

使用示例

ROS_DEBUG("hello,DEBUG"); //不会输出
ROS_INFO("hello,INFO"); //默认白色字体
ROS_WARN("Hello,WARN"); //默认黄色字体
ROS_ERROR("hello,ERROR");//默认红色字体
ROS_FATAL("hello,FATAL");//默认红色字体

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/462938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

openEuler NFS+协议全新发布:实现NAS存储性能与可靠性倍增

4月21日&#xff0c;在openEuler Developer Day 2023上&#xff0c;openEuler发布NFS协议&#xff0c;实现单客户端访问NAS存储可靠性提升3倍、性能提升6倍&#xff0c;助力NAS存储全面满足新型生产核心场景下苛刻要求。 传统NFS面临挑战 网络文件系统&#xff08;NFS&#xf…

vue打包如何开启gzip压缩

文章目录 场景gzip压缩有两种方案&#xff1a;个人实践 场景 本人前端打包的js达到了6.9M,导致网站加载很慢&#xff0c;想了下可以用gzip的方式压缩&#xff0c;减少文件大小。 “前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c…

什么蓝牙耳机好?测评达人精选五款性价比高蓝牙耳机推荐

用蓝牙耳机听歌、刷视频、玩游戏已经成为趋势&#xff0c;有线耳机已经逐渐被取代&#xff0c;但蓝牙耳机价格跨度大&#xff0c;品牌和型号也非常多&#xff0c;究竟什么蓝牙耳机好&#xff1f;我作为测评员这几年已经体验过五十款蓝牙耳机&#xff0c;今天就来总结五款性价比…

模仿网易云音乐黑胶唱片的交互实现

今天在 .NET MAUI 中我们来实现这个交互效果&#xff0c;先来看看效果&#xff1a; 使用.NET MAU实现跨平台支持&#xff0c;本项目可运行于Android、iOS平台。 创建页面布局 项目模拟了网易云音乐的播放主界面&#xff0c;可播放本地音乐文件。使用MatoMusic.Core作为播放内…

ChatGLM ptuning predict(预测)为空值的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

html学习(布局方式(layout)、浮动(float)、定位(position)、弹性盒(flex))

布局方式(layout) 文档流 文档流&#xff08;normal flow&#xff09; 文档流通俗的讲&#xff0c;就是一个web页面中&#xff0c;每一个模块只能从上到下从左往右的方式排列在页面上。 将窗口自下而上分成一行一行&#xff0c;应在每行中按从左至右的依次排放元素&#xff0…

[ZJCTF 2019]EasyHeap-patchlibc-调试

1,三连 主要功能&#xff1a; 1、malloc申请chunk 2、修改chunk内容 3、free chunk 4、exit 堆题多看一个libc信息&#xff1a; 2,IDA分析 2.1、malloc申请chunk heaparray[i]&#xff1a;存放 chunk 的地址。read_input(heaparray[i], size)&#xff1a;向 chunk 写入 s…

亚马逊云科技宣布四大举措,全方位赋能创新成长企业

4月13日&#xff0c;以“加速创新&#xff0c;成就未来”为主题的亚马逊云科技创新成长中国行深圳论坛圆满举行。会上亚马逊云科技宣布&#xff0c;将围绕创新成长企业的三大业务需求——云上创新、出海拓展、业务加速&#xff0c;提供行业聚焦、技术支撑、伙伴扶持、人才培养四…

ENVI5.3 自动配准流程化工具(Image Registration Workflow)配准方法流程

ENVI5.3 自动配准流程化工具&#xff08;Image Registration Workflow&#xff09;配准方法流程。 打开 ENVI软件中的Image Registration Workflow工具&#xff0c;分辨打开参考图像和待校正的图像。 Base Image File是参考图像&#xff0c;参考图像的范围应比待校正图像的范围…

LaTeX论文自动化排版

本文介绍了一些论文写作的在线课程&#xff0c;方便读者朋友们自学&#xff0c;提高论文写作的能力。论文写作的在线课程非常多&#xff0c;读者朋友们也可以在网上自行搜索&#xff0c;选择适合自己的在线课程进行学习。如需要打开课程的网站&#xff0c;请复制课程的网址到浏…

威胁行为者针对云中的常见漏洞

Palo Alto Networks 已发布其第 42 单元云威胁报告的第 7 卷。该报告调查了 1300 多家组织。它分析了所有主要云服务提供商 (CSP) 的 210000 个云帐户、订阅和项目中的工作负载&#xff0c;为安全领导者和从业者提供了云安全的多方面视图。 云迁移的速度从 2021 年的 3700 亿…

Codeforces Round 867 (Div. 3) (E-G)

Problem - E - Codeforces &#xff08;1&#xff09;题目大意 给你一个字符串&#xff0c;问你让字符串每一对相对应位置都不同的最小操作数是多少&#xff1f;&#xff08;A[i]和A[n - i],A[i 1]和A[n - i - 1]&#xff09; &#xff08;2&#xff09;解题思路 1.首…

数据库基础篇 《16.变量、流程控制与游标》

数据库基础篇 《16.变量、流程控制与游标》 1. 变量 在MySQL数据库的存储过程和函数中&#xff0c;可以使用变量来存储查询或计算的中间结果数据&#xff0c;或者输出最终的结果数据。 在 MySQL 数据库中&#xff0c;变量分为系统变量以及用户自定义变量。 1.1 系统变量 1…

深度学习入门:多层感知机实现异或门

文章目录 前言感知机2层感知机实现异或门总结参考文献&#xff1a; 前言 最近又开始看深度学习的内容了&#xff0c;好久不用忘得差不多了&#xff0c;先从最简单的感知机入手了&#xff0c;这里记录下用2层感知机实现异或门。 感知机 什么是感知机呢&#xff1f;这里粗浅的介…

初步了解c语言(三)

注&#xff1a;此篇文章仅限初步了解&#xff0c;本小白后续会持续进行详解。 目录&#xff1a; 函数数组数组的定义数组的下标 操作符常见关键字关键字static的使用修饰局部变量修饰全局变量修饰函数 关键字register的大概了解#define定义常量和宏结构体&#x1f49e;结尾 函数…

RuntimeError: “LayerNormKernelImpl“ not implemented for ‘Long‘解决方法

问题出现的场景&#xff1a; 输入&#xff1a; import torch import torch.nn as nn atorch.randint(10,[3,4]) # atorch.DoubleTensor(a) # aa.double() print(a) layer_normnn.LayerNorm(4) layer_norm(a) 我就是想测试一下经过layernorm之后的输出会变成什么样 但是报错…

Pycharm中如何安装 OpenAI ——ChatGPT的python包?

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 Pycharm中如何安装 OpenAI ——ChatGPT的python包? 摘要背景安装1、安装前准备2、安装前提条件3、依赖库 最佳安装过程1、检查 VC2、看哪些依赖库未安装3、将未装模块写成 test02.b…

js 打开资源管理器(经典范例:纯前端选择并预览图片)

效果预览 完整代码范例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"width…

C++STL详解(十) -- 使用哈希表封装unordered_set和unordered_map

文章目录 哈希表模板参数改造针对模板参数V改造增加仿函数获取具体数据类型. 哈希表的正向迭代器正向迭代器中的内置成员:正向迭代器的成员函数 哈希表插入函数的修改(适用于unordered_map)一个类型K去做set和unordered_set他的模板参数的必备条件.unordered_set的模拟实现(完整…

不得不的创建型模式-原型模式

原型模式是一种创建型模式&#xff0c;它通过复制一个已有对象来创建新的对象&#xff0c;而无需知道新对象的具体类型。 原型模型的结构&#xff1a; 下面是一个简单的C实现原型模式的代码示例&#xff1a; #include <iostream> #include <string> #include <…