【ROS2笔记六】ROS2中自定义接口
6.ROS2中自定义接口
文章目录
- 6.ROS2中自定义接口
- 6.1接口常用的CLI
- 6.2标准的接口形式
- 6.3接口的数据类型
- 6.4自定义接口
- Reference
在ROS2中接口interface是一种定义消息、服务或动作的规范,用于描述数据结构、字段和数据类型。ROS2中的接口可以分为以下的几种消息类型:
- 消息接口:消息接口定义了一种数据结构,用于在ROS 2节点之间传递信息。消息接口通常用于发布者(publishers)和订阅者(subscribers)之间的通信。消息接口由一组字段组成,每个字段都有一个名称和一个数据类型。ROS 2使用消息接口来实现发布-订阅模式。
- 服务接口:服务接口定义了一种客户端(client)和服务器(server)之间的通信协议。服务接口由请求(request)和响应(response)两部分组成。客户端发送请求给服务器,并等待服务器返回响应。服务接口在ROS 2中用于实现请求-响应模式。
- 动作接口:动作接口是ROS 2中的一种高级通信模式,它扩展了服务接口,允许在执行期间传输连续的反馈信息。动作接口由一个目标(goal)、一个反馈(feedback)和一个结果(result)组成。客户端向服务器发送目标,服务器执行相应的操作,并提供反馈信息。动作接口用于实现高级的行为控制和任务执行。
接口在ROS2中以.msg、.srv和.action文件的形式定义,分别对应消息、服务和动作。这些文件包含了接口的定义,包括字段名称和数据类型。通过使用接口,ROS2节点可以进行灵活的通信,并与其他节点共享数据和执行任务。
6.1接口常用的CLI
(1)查看接口列表
ros2 interface list
(2)查看某个具体接口的内容
ros2 interface show xxxx
6.2标准的接口形式
下面对三种接口类型.msg、.srv、.action都进行举例说明
(1)消息Message
int32 x
int32 y
这个消息定义了两个int32的字段x和y,
(2)服务Service
int32 a
int32 b
---
int32 sum
这个服务定义了一个请求包含两个整型字段a和b,以及一个响应包含一个整型字段sum。
(3)动作Action
int32 order
---
int32 progress
---
int32 result
这个动作定义了一个目标包含一个整型字段order,一个反馈包含一个整型字段progress,以及一个结果包含一个整型字段result。
6.3接口的数据类型
- 基本数据类型:
- 整型:
int8,int16,int32,int64,uint8,uint16,uint32,uint64 - 浮点型:
float32,float64 - 布尔型:
bool - 字符型:
char
- 整型:
- 数组和序列:
- 数组:使用方括号表示,例如
int32[3]表示包含3个int32元素的数组。 - 序列:使用尖括号表示,例如
std_msgs/String[]表示包含多个std_msgs/String消息的序列。
- 数组:使用方括号表示,例如
- 字符串:
- 字符串类型:
string表示一个字符串。
- 字符串类型:
- 时间和持续时间:
- 时间:
builtin_interfaces/Time表示一个时间戳。 - 持续时间:
builtin_interfaces/Duration表示一个时间间隔。
- 时间:
- 其他消息类型:
- 其他消息类型:你可以使用其他消息类型作为字段类型,以创建更复杂的消息结构。例如,
geometry_msgs/Point表示一个三维点的消息类型。
- 其他消息类型:你可以使用其他消息类型作为字段类型,以创建更复杂的消息结构。例如,
6.4自定义接口
这里我的工作空间名为colcon_test_ws,我们首先在这个工作空间目录下创建一个新的功能包custom_interfaces
ros2 pkg create custom_interfaces --build-type ament_cmake --license Apache-2.0 --dependencies rosidl_default_generators
进入功能包,然后创建msg和srv目录
cd custom_interfaces
mkdir msg srv
目录结构如下:
.
├── CMakeLists.txt
├── include
│ └── custom_interfaces
├── LICENSE
├── msg
├── package.xml
├── src
└── srv5 directories, 3 files
(1)自定义构建msg
进入custom_interfaces/msg新建一个Num.msg文件,然后写入以下内容:
int64 num
这里构建了一个自定义的消息,消息的内容是64整型的int
(2)自定义构建srv
进入custom_interfaces/srv新建一个AddThreeInts.srv文件,然后写入以下内容:
int64 a
int64 b
int64 c
---
int64 sum
这里构建了一个自定义的服务消息,request包含三个数a、b、c,response包含一个数sum
(3)修改配置文件CMakeLists.txt
find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}"msg/Num.msg""srv/AddThreeInts.srv"DEPENDENCIES # Add packages that above messages depend on
)
(4)修改配置文件package.xml
<buildtool_depend>ament_cmake</buildtool_depend><!-- 添加以下三行 --><build_depend>rosidl_default_generators</build_depend><exec_depend>rosidl_default_runtime</exec_depend><member_of_group>rosidl_interface_packages</member_of_group> <test_depend>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend>
然后进行编译
colcon build --packages-select example_custom_interfaces
然后查看自定义的消息接口
source install/setup.bash
ros2 interface show example_custom_interfaces/msg/Num
Output:
int64 num
再输入:
ros2 interface show example_custom_interfaces/srv/AddThreeInts
Output:
int64 a
int64 b
int64 c
---
int64 sum
这样我们就能够在colcon_ws/install/custom_interfaces/include/example_custom_interfaces/example_custom_interfaces/msg/num.hpp看到编译好的msg头文件了,在colcon_test_ws/install/custom_interfaces/include/example_custom_interfaces/example_custom_interfaces/srv/add_three_ints.hpp中看到编译好的srv头文件
这里可以使用自定义的服务接口类型,把【ROS2笔记五】ROS2服务通信中使用的服务数据类型修改为自定义的,如下:
service_client_01.cpp
#include "rclcpp/rclcpp.hpp"
#include "custom_interfaces/srv/add_three_ints.hpp"class ServiceClient01: public rclcpp::Node{
public:ServiceClient01(std::string name) : Node(name){RCLCPP_INFO(this->get_logger(), "Node: %s has been launched", name.c_str());// 创建客户端client_ = this->create_client<custom_interfaces::srv::AddThreeInts>("add_two_ints_srv");}void send_request(int a, int b, int c){RCLCPP_INFO(this->get_logger(), "Calculate %d + %d + %d", a, b, c);// 等待服务上线while (!client_->wait_for_service(std::chrono::seconds(1))){if (!rclcpp::ok()){RCLCPP_ERROR(this->get_logger(), "Waiting for service to be interrupted");return;}RCLCPP_INFO(this->get_logger(), "Waiting for service");}auto request = std::make_shared<custom_interfaces::srv::AddThreeInts_Request>();request->a = a;request->b = b;request->c = c;client_->async_send_request(request, std::bind(&ServiceClient01::result_callback_, this, std::placeholders::_1));}private:// 声明客户端rclcpp::Client<custom_interfaces::srv::AddThreeInts>::SharedPtr client_;void result_callback_(rclcpp::Client<custom_interfaces::srv::AddThreeInts>::SharedFuture result_future){auto response = result_future.get();RCLCPP_INFO(this->get_logger(), "Result: %ld", response->sum);}
};int main(int argc, char** argv){rclcpp::init(argc, argv);auto node = std::make_shared<ServiceClient01>("service_client_01");// 调用服务node->send_request(5, 6, 7);rclcpp::spin(node);rclcpp::shutdown();return 0;
}
service_server_01.cpp
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "custom_interfaces/srv/add_three_ints.hpp"class ServiceServer01: public rclcpp::Node{
public:ServiceServer01(std::string name) : Node(name){RCLCPP_INFO(this->get_logger(), "Node: %s has been launched", name.c_str());// 创建服务add_ints_server_ = this->create_service<custom_interfaces::srv::AddThreeInts>("add_two_ints_srv",std::bind(&ServiceServer01::handle_add_three_ints, this, std::placeholders::_1, std::placeholders::_2));}
private:// 在私有域中再次声明服务rclcpp::Service<custom_interfaces::srv::AddThreeInts>::SharedPtr add_ints_server_;// 服务的处理函数void handle_add_three_ints(const std::shared_ptr<custom_interfaces::srv::AddThreeInts::Request> request,std::shared_ptr<custom_interfaces::srv::AddThreeInts::Response> response){RCLCPP_INFO(this->get_logger(), "Recieve a: %ld b: %ld c: %ld", request->a, request->b, request->c);response->sum = request->a + request->b + request->c;};};int main(int argc, char** argv){rclcpp::init(argc, argv);auto node = std::make_shared<ServiceServer01>("service_server_01");rclcpp::spin(node);rclcpp::shutdown();return 0;
}
修改CMakeLists.txt
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
# 新加这一行
find_package(custom_interfaces REQUIRED) add_executable(service_server_01 src/service_server_01.cpp)
ament_target_dependencies(service_server_01 rclcpp custom_interfaces) #修改这里add_executable(service_client_01 src/service_client_01.cpp)
ament_target_dependencies(service_client_01 rclcpp custom_interfaces) #修改这里install(TARGETSservice_server_01service_client_01DESTINATION lib/${PROJECT_NAME}
)
然后编译,运行
colcon build --packages-select example_service_rclcpp
source install/setup.bash
ros2 run example_service_rclcpp service_client_01ros2 run example_service_rclcpp service_server_01
结果如下:
Reference
[1]d2lros2
[2]ROS2 Tutorial Official
相关文章:
【ROS2笔记六】ROS2中自定义接口
6.ROS2中自定义接口 文章目录 6.ROS2中自定义接口6.1接口常用的CLI6.2标准的接口形式6.3接口的数据类型6.4自定义接口Reference 在ROS2中接口interface是一种定义消息、服务或动作的规范,用于描述数据结构、字段和数据类型。ROS2中的接口可以分为以下的几种消息类型…...
设计模式-代理模式(Proxy)
1. 概念 代理模式(Proxy Pattern)是程序设计中的一种结构型设计模式。它为一个对象提供一个代理对象,并由代理对象控制对该对象的访问。 2. 原理结构图 抽象角色(Subject):这是一个接口或抽象类࿰…...
中伟视界:智慧矿山智能化预警平台功能详解
矿山智能预警平台是一种高度集成化的安全监控系统,它能够提供实时的监控和报警功能,帮助企业和机构有效预防和响应潜在的安全威胁。以下是矿山智能预警平台的一些关键特性介绍: 报警短视频生成: 平台能够在检测到报警时自动生成短…...
如何在PPT中获得网页般的互动效果
如何在PPT中获得网页般的互动效果 效果可以看视频 PPT中插入网页有互动效果 当然了,获得网页般的互动效果,最简单的方法就是在 PPT 中插入网页呀。 那么如何插入呢? 接下来为你讲解如何获得(此方法在 PowerPoint中行得通&#…...
HTML段落标签、换行标签、文本格式化标签与水平线标签
目录 HTML段落标签 HTML换行标签 HTML格式化标签 加粗标签 倾斜标签 删除线标签 下划线标签 HTML水平线标签 HTML段落标签 在网页中,要把文字有条理地显示出来,就需要将这些文字分段显示。在 HTML 标签中,<p>标签用于定义段落…...
NVIC简介
NVIC(Nested Vectored Interrupt Controller)是ARM处理器中用于中断管理的一个重要硬件模块。它负责处理来自多个中断源的中断请求,并根据中断的优先级来安排处理器执行相应的中断服务例程(ISR)。NVIC是ARM Cortex-M系…...
LeetCode-924. 尽量减少恶意软件的传播【深度优先搜索 广度优先搜索 并查集 图 哈希表】
LeetCode-924. 尽量减少恶意软件的传播【深度优先搜索 广度优先搜索 并查集 图 哈希表】 题目描述:解题思路一:解题思路二:0解题思路三:0 题目描述: 给出了一个由 n 个节点组成的网络,用 n n 个邻接矩阵图…...
【linux】yum 和 vim
yum 和 vim 1. Linux 软件包管理器 yum1.1 什么是软件包1.2 查看软件包1.3 如何安装软件1.4 如何卸载软件1.5 关于 rzsz 2. Linux编辑器-vim使用2.1 vim的基本概念2.2 vim的基本操作2.3 vim命令模式命令集2.4 vim底行模式命令集2.5 vim操作总结补充:vim下批量化注释…...
excel试题转word格式
序号试题选项答案 格式如上。输出后在做些适当调整就可以。 import pandas as pd from docx import Document from docx.shared import Inches# 读取Excel文件 df pd.read_excel(r"你的excel.xlsx")# 创建一个新的Word文档 doc Document()# 添加标题 doc.add_headi…...
C语言学习笔记之指针(二)
指针基础知识:C语言学习笔记之指针(一)-CSDN博客 目录 字符指针 代码分析 指针数组 数组指针 函数指针 代码分析(出自《C陷阱和缺陷》) 函数指针数组 指向函数指针数组的指针 回调函数 qsort() 字符指针 一…...
在Debian 12系统上安装Docker
Docker 在 Debian 12 上的安装 安装验证测试更多信息 引言 在现代的开发环境中,容器技术发挥着至关重要的作用。Docker 提供了快速、可靠和易于使用的容器化解决方案,使开发人员和 DevOps 专业人士能够以轻松的方式将应用程序从一个环境部署到另一个环…...
策略者模式(代码实践C++/Java/Python)————设计模式学习笔记
文章目录 1 设计目标2 Java2.1 涉及知识点2.2 实现2.2.1 实现两个接口飞行为和叫行为2.2.2 实现Duck抽象基类(把行为接口作为类成员)2.2.3 实现接口飞行为和叫行为的具体行为2.2.4 具体实现鸭子2.2.5 模型调用 3 C(用到了大量C2.0的知识&…...
vue2/Vue3项目中,通过请求接口来刷新列表中的某个字段(如:Axios)
vue2/Vue3项目中,通过请求接口来刷新列表中的某个字段。可以使用 Vue 的异步请求库(如 Axios)来发送请求,并在请求成功后更新相应的字段。 示例如下(Vue2): 简单的示例如下,假设列…...
Java多线程锁定
前言 利用多线程编程虽然能极大地提升运行效率,但是多线程本身的不稳定也会带来一系列的问题,其中最经典莫过于售票问题;这时就需要人为地加以限制和干涉已解决问题,譬如今日之主题——锁定。 锁定是我们在多线程中用来解决售票…...
【C 数据结构】单链表
文章目录 【 1. 基本原理 】1.1 链表的节点1.2 头指针、头节点、首元节点 【 2. 链表的创建 】2.0 创建1个空链表(仅有头节点)2.1 创建单链表(头插入法)*2.2 创建单链表(尾插入法) 【 3. 链表插入元素 】【…...
[MAUI]集成富文本编辑器Editor.js至.NET MAUI Blazor项目
文章目录 获取资源从源码构建从CDN获取获取扩展插件 创建项目创建控件创建Blazor组件初始化保存销毁编写渲染逻辑 实现只读/编辑功能切换模式获取只读模式状态响应切换事件 实现明/暗主题切换项目地址 Editor.js 是一个基于 Web 的所见即所得富文本编辑器,它由CodeX…...
Spring Boot | Spring Boot 整合 “Servlet三大组件“ ( Servlet / Filter / Listene )
目录: Spring Boot 整合 "Servlet三大组件" :1. 使用 "组件注册" 的方式 "整合Servlet三大组件" ( 实际操作为 : 创建自定义的"三大组件"对象 结合刚创建"的自定义组件对象"来 将 XxxRegistrationBean对象 通过…...
错误分析 (Machine Learning研习十九)
错误分析 您将探索数据准备选项,尝试多个模型,筛选出最佳模型,使用 Grid SearchCV微调其超参数,并尽可能实现自动化。在此,我们假设您已经找到了一个有前途的模型,并希望找到改进它的方法。其中一种方法就…...
SQL系统函数知识点梳理(Oracle)
这里写目录标题 函数系统函数转换函数to_date()to_char()将数值转换成字符格式 添加货币符号将日期转换成字符 其他不常用的转换函数 字符型函数连接函数大小写转换函数大写转换小写转换首字母大写,其余的小写 替换函数去除空格函数截取函数填充函数获取字符长度函数…...
面试突击---MySQL索引
面试突击---MYSQL索引 面试表达技巧:1、谈一下你对于mysql索引的理解?(为什么mysql要选择B树来存储索引)2、索引有哪些分类?3、聚簇索引与非聚簇索引4、回表、索引覆盖、最左匹配原则、索引下推(1ÿ…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
