25/1/21 算法笔记<ROS2> 服务通信,参数

devtools/2025/1/22 9:12:16/

我们将构建一个完整的项目来讲解ROS2中的服务,通信和参数

  1. 服务通信:通过服务控制海龟的运动。

  2. 参数通信:动态修改海龟的背景颜色。

  3. Launch 文件:启动多个节点并传递参数。

项目结构

turtlesim_demo/
├── CMakeLists.txt
├── package.xml
├── src/
│   ├── turtle_controller.cpp
│   ├── background_changer.cpp
├── launch/
│   └── turtlesim_demo.launch.xml

1. 创建 ROS 2 包

创建包:

ros2 pkg create turtlesim_demo --build-type ament_cmake

进入包目录:

cd turtlesim_demo

2. 编写代码

(1)Turtle 控制器(服务通信)

src/turtle_controller.cpp

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include "turtlesim/srv/spawn.hpp"class TurtleController : public rclcpp::Node
{
public:TurtleController() : Node("turtle_controller"){// 创建发布者,控制海龟运动twist_pub_ = this->create_publisher<geometry_msgs::msg::Twist>("/turtle1/cmd_vel", 10);// 创建客户端,调用 spawn 服务生成新海龟spawn_client_ = this->create_client<turtlesim::srv::Spawn>("spawn");// 定时器,控制海龟运动timer_ = this->create_wall_timer(std::chrono::milliseconds(100),std::bind(&TurtleController::timer_callback, this));}private:void timer_callback(){// 发布运动指令auto twist_msg = geometry_msgs::msg::Twist();twist_msg.linear.x = 2.0;twist_msg.angular.z = 1.0;twist_pub_->publish(twist_msg);// 调用 spawn 服务生成新海龟if (!spawn_client_->wait_for_service(std::chrono::seconds(1))) {RCLCPP_WARN(this->get_logger(), "Waiting for spawn service...");return;}#创建一个spawn服务请求对象requestauto request = std::make_shared<turtlesim::srv::Spawn::Request>();#设置新海龟的初始参数request->x = 5.0;request->y = 5.0;request->theta = 0.0;request->name = "turtle2";auto future = spawn_client_->async_send_request(request);if (rclcpp::spin_until_future_complete(this->get_node_base_interface(), future) ==rclcpp::FutureReturnCode::SUCCESS) {RCLCPP_INFO(this->get_logger(), "Spawned turtle: %s", future.get()->name.c_str());} else {RCLCPP_ERROR(this->get_logger(), "Failed to call spawn service");}}rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr twist_pub_;rclcpp::Client<turtlesim::srv::Spawn>::SharedPtr spawn_client_;rclcpp::TimerBase::SharedPtr timer_;
};int main(int argc, char* argv[])
{rclcpp::init(argc, argv);auto node = std::make_shared<TurtleController>();rclcpp::spin(node);rclcpp::shutdown();return 0;
}

(2)背景颜色修改器(参数通信)

src/background_changer.cpp

#include "rclcpp/rclcpp.hpp"
#include "turtlesim/srv/set_pen.hpp"class BackgroundChanger : public rclcpp::Node
{
public:BackgroundChanger() : Node("background_changer"){// 创建客户端,调用 set_pen 服务修改背景颜色set_pen_client_ = this->create_client<turtlesim::srv::SetPen>("turtle1/set_pen");// 定时器,动态修改背景颜色timer_ = this->create_wall_timer(std::chrono::seconds(2),std::bind(&BackgroundChanger::timer_callback, this));}private:void timer_callback(){if (!set_pen_client_->wait_for_service(std::chrono::seconds(1))) {RCLCPP_WARN(this->get_logger(), "Waiting for set_pen service...");return;}// 随机生成颜色值auto request = std::make_shared<turtlesim::srv::SetPen::Request>();request->r = rand() % 256;request->g = rand() % 256;request->b = rand() % 256;request->width = 5;request->off = 0;// 调用 set_pen 服务auto future = set_pen_client_->async_send_request(request);if (rclcpp::spin_until_future_complete(this->get_node_base_interface(), future) ==rclcpp::FutureReturnCode::SUCCESS) {RCLCPP_INFO(this->get_logger(), "Changed background color to (%d, %d, %d)",request->r, request->g, request->b);} else {RCLCPP_ERROR(this->get_logger(), "Failed to call set_pen service");}}rclcpp::Client<turtlesim::srv::SetPen>::SharedPtr set_pen_client_;rclcpp::TimerBase::SharedPtr timer_;
};int main(int argc, char* argv[])
{rclcpp::init(argc, argv);auto node = std::make_shared<BackgroundChanger>();rclcpp::spin(node);rclcpp::shutdown();return 0;
}

以下是这段代码的基本步骤总结:

1. 初始化ROS 2环境

  • 使用rclcpp::init(argc, argv)初始化ROS 2节点,这是运行ROS 2程序的必要步骤。

2. 创建节点

  • 创建一个名为BackgroundChanger的节点类,继承自rclcpp::Node

  • 在构造函数中:

    • 初始化节点名称为"background_changer"

    • 创建一个服务客户端set_pen_client_,用于调用turtle1/set_pen服务,修改海龟的画笔颜色。

    • 创建一个定时器timer_,每隔2秒触发一次回调函数timer_callback

3. 定时器回调函数

  • timer_callback函数中:

    1. 检查服务是否可用

      • 使用set_pen_client_->wait_for_service(std::chrono::seconds(1))等待服务可用。

      • 如果服务不可用,打印警告信息并退出回调函数。

    1. 随机生成颜色值

      • 使用rand() % 256随机生成RGB颜色值(范围为0到255)。

      • 设置画笔宽度为5,启用画笔(off = 0)。

    2. 调用set_pen服务

      • 创建服务请求request,并设置随机颜色值。

      • 使用set_pen_client_->async_send_request(request)异步发送请求。

      • 使用rclcpp::spin_until_future_complete等待服务响应完成。

      • 如果服务调用成功,打印成功信息,显示当前设置的颜色。

      • 如果服务调用失败,打印错误信息。

4. 主函数

  • main函数中:

    1. 初始化ROS 2环境。

    2. 创建BackgroundChanger节点实例。

    3. 启动节点的事件循环rclcpp::spin(node),使节点能够处理定时器回调。

    4. 程序退出时,调用rclcpp::shutdown()关闭ROS 2节点。

5. 程序运行逻辑

  • 程序运行后,定时器每隔2秒触发一次回调函数。

  • 每次回调函数都会随机生成颜色值,并通过set_pen服务设置海龟的画笔颜色。

  • 由于画笔宽度较大(5),海龟会绘制整个窗口,从而间接改变背景颜色。

3. 配置 CMakeLists.txt

在 ROS 2 中,CMakeLists.txt 文件是用于配置和构建项目的核心文件。它定义了项目的编译规则、依赖项、可执行文件、库文件等。

cmake_minimum_required(VERSION 3.8)
project(turtlesim_demo)if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(turtlesim REQUIRED)add_executable(turtle_controller src/turtle_controller.cpp)
ament_target_dependencies(turtle_controller rclcpp geometry_msgs turtlesim)add_executable(background_changer src/background_changer.cpp)
ament_target_dependencies(background_changer rclcpp turtlesim)install(TARGETSturtle_controllerbackground_changerDESTINATION lib/${PROJECT_NAME}
)ament_package()

1. 定义项目的基本信息

CMakeLists.txt 文件的开头通常包含项目的基本信息,例如项目名称和最低 CMake 版本要求:

cmake_minimum_required(VERSION 3.8)
project(turtlesim_demo)

2. 设置编译器选项

在 CMakeLists.txt 中,可以为项目设置编译器选项,例如启用警告信息:

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()

3. 查找依赖项

ROS 2 项目通常依赖于其他包(如 rclcppgeometry_msgsturtlesim 等)。CMakeLists.txt 中需要明确声明这些依赖项:

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(turtlesim REQUIRED)

4. 添加可执行文件

在 CMakeLists.txt 中,需要定义如何将源代码编译为可执行文件:

add_executable(turtle_controller src/turtle_controller.cpp)
ament_target_dependencies(turtle_controller rclcpp geometry_msgs turtlesim)

5. 安装可执行文件

ROS 2 项目通常需要将生成的可执行文件安装到指定目录,以便在运行时能够找到它们:

install(TARGETSturtle_controllerbackground_changerDESTINATION lib/${PROJECT_NAME}
)

6. 生成包配置

CMakeLists.txt 文件的末尾需要调用 ament_package(),用于生成 ROS 2 包的配置:

7. 测试配置(可选)

如果项目包含测试代码,可以在 CMakeLists.txt 中配置测试:

if(BUILD_TESTING)find_package(ament_lint_auto REQUIRED)ament_lint_auto_find_test_dependencies()
endif()

8. 为什么需要配置 CMakeLists.txt

  1. 定义项目结构

    • CMakeLists.txt 定义了项目的源代码文件、依赖项、可执行文件等,确保项目能够正确编译和运行。

  2. 管理依赖项

    • ROS 2 项目通常依赖于多个包(如 rclcppgeometry_msgs 等),CMakeLists.txt 中需要明确声明这些依赖项。

  3. 控制编译过程

    • 通过 CMakeLists.txt,可以设置编译器选项、链接库文件、安装路径等,控制项目的编译过程。

  4. 生成包配置

    • CMakeLists.txt 中的 ament_package() 会生成 ROS 2 包的配置文件,使 ROS 2 能够正确加载和使用该包。

  5. 支持跨平台构建

    • CMake 是一个跨平台的构建工具,CMakeLists.txt 可以确保项目在不同平台上(如 Linux、Windows、macOS)都能正确编译。

4. 配置 package.xml

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3"><name>turtlesim_demo</name><version>0.0.0</version><description>A demo package for turtlesim with services, parameters, and launch files.</description><maintainer email="your-email@example.com">Your Name</maintainer><license>Apache-2.0</license><buildtool_depend>ament_cmake</buildtool_depend><depend>rclcpp</depend><depend>geometry_msgs</depend><depend>turtlesim</depend><test_depend>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend><export><build_type>ament_cmake</build_type></export>
</package>

在 ROS 2 中,package.xml 文件是包的元数据文件,用于描述包的基本信息、依赖项、作者、许可证等。

1. 定义包的基本信息

package.xml 文件的开头通常包含包的基本信息,例如包名称、版本、描述、维护者和许可证:

<package format="3"><name>turtlesim_demo</name><version>0.0.0</version><description>A demo package for turtlesim with services, parameters, and launch files.</description><maintainer email="your-email@example.com">Your Name</maintainer><license>Apache-2.0</license>
</package>

2. 声明构建工具依赖

ROS 2 使用 ament_cmake 作为构建工具,因此需要在 package.xml 中声明构建工具依赖:

<buildtool_depend>ament_cmake</buildtool_depend>

3. 声明运行时依赖

ROS 2 项目通常依赖于其他包(如 rclcppgeometry_msgsturtlesim 等),需要在 package.xml 中声明这些依赖项:

<depend>rclcpp</depend>
<depend>geometry_msgs</depend>
<depend>turtlesim</depend>

4. 声明测试依赖(可选)

如果项目包含测试代码,可以在 package.xml 中声明测试依赖项:

<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>

5. 导出包配置

package.xml 文件的末尾需要导出包的配置信息,以便 ROS 2 能够正确加载和使用该包:

<export><build_type>ament_cmake</build_type>
</export>

6. 为什么需要配置 package.xml

  1. 描述包的基本信息

    • package.xml 提供了包的名称、版本、描述、维护者和许可证等基本信息,方便其他开发者了解和使用该包。

  2. 管理依赖项

    • package.xml 中声明了包的依赖项,ROS 2 会在构建和运行时自动加载这些依赖项,确保项目能够正确运行。

  3. 支持包的管理和分发

    • package.xml 是 ROS 2 包的重要组成部分,ROS 2 工具(如 colcon)会根据 package.xml 中的信息管理包的构建、安装和分发。

  4. 支持测试和代码风格检查

    • 如果项目包含测试代码,可以在 package.xml 中声明测试依赖项,例如代码风格检查工具。

  5. 支持跨平台构建

    • package.xml 中的依赖项和配置信息可以确保项目在不同平台上(如 Linux、Windows、macOS)都能正确编译和运行。

5. 编写 Launch 文件

launch/turtlesim_demo.launch.xml

<launch><!-- 启动 turtlesim 节点 --><node pkg="turtlesim" exec="turtlesim_node" name="turtlesim" /><!-- 启动 Turtle 控制器 --><node pkg="turtlesim_demo" exec="turtle_controller" name="turtle_controller" /><!-- 启动背景颜色修改器 --><node pkg="turtlesim_demo" exec="background_changer" name="background_changer" />
</launch>

这个 <launch> 文件的作用是同时启动三个节点:

  1. turtlesim_node:启动 turtlesim 模拟器,显示一个小乌龟。

  2. turtle_controller:控制乌龟的移动。

  3. background_changer:修改 turtlesim 窗口的背景颜色。

通过这个配置文件,你可以一次性启动多个相关的节点,而不需要手动逐个启动。这在复杂的 ROS 2 系统中非常有用,可以简化启动过程并确保所有相关节点都能正确启动。

总结

我们构建了一个完整的项目来讲解ROS2中的服务,通信和参数

  1. 服务通信:通过服务控制海龟的运动。

  2. 参数通信:动态修改海龟的背景颜色。

  3. Launch 文件:启动多个节点并传递参数。


http://www.ppmy.cn/devtools/152549.html

相关文章

PHP语言的软件工程

PHP语言的软件工程 引言 软件工程是计算机科学中的一个重要分支&#xff0c;它涉及软件的规划、开发、测试和维护。在现代开发中&#xff0c;PHP作为一种流行的服务器端脚本语言&#xff0c;广泛应用于网页开发和各种企业应用中。本文将深入探讨PHP语言在软件工程中的应用&am…

医院管理系统小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

【QT】窗口/界面置于最前端显示,且激活该窗口

目录 0.环境 1.问题描述 2.具体实现 0.环境 windows11 qt 1.问题描述 我有一个窗口QMainWindow&#xff08;也适用于QWidget或QDialog&#xff09;&#xff0c;想让其在显示的时候置于最前面&#xff0c;且激活成为当前活动窗口 2.具体实现 mainWindow->show();mainWind…

dubbo 的 spi 思想是什么?

面试题 dubbo 的 spi 思想是什么&#xff1f; 面试官心理分析 继续深入问呗&#xff0c;前面一些基础性的东西问完了&#xff0c;确定你应该都 ok&#xff0c;了解 dubbo 的一些基本东西&#xff0c;那么问个稍微难一点点的问题&#xff0c;就是 spi&#xff0c;先问问你 sp…

Sentinel配置流控规则详解

前言 在微服务架构中&#xff0c;流量控制&#xff08;Flow Control&#xff09;是保障服务稳定性的重要手段之一。Sentinel作为一款开源的流量控制、熔断降级Java库&#xff0c;以其丰富的应用场景和完善的监控能力&#xff0c;在微服务保护中扮演了重要角色。本文将详细介绍…

Node.js接收文件分片数据并进行合并处理

前言&#xff1a;上一篇文章讲了如何进行文件的分片&#xff1a;Vue3使用多线程处理文件分片任务&#xff0c;那么本篇文章主要看一下后端怎么接收前端上传来的分片并进行合并处理。 目录&#xff1a; 一、文件结构二、主要依赖1. express2. multer3. fs (文件系统模块)4. pat…

KubeSphere部署安装,接入KubeKey安装的k8s集群

KubeSphere安装接入KubeKey安装的k8s集群 文章目录 KubeSphere安装接入KubeKey安装的k8s集群 一.NFS安装配置1.服务器安装NFS服务2.下载并部署 NFS Subdir External Provisioner1).下载部署文件2).创建 NameSpace3).创建 RBAC 资源4).配置 deployment.yaml5).部署 Storage Clas…

线上商城拼团功能搭建指南

规划与设计 明确拼团模式&#xff1a;确定是常规的多人拼团、团长免单、阶梯拼团还是其他创新模式。比如常规拼团可设定 3 人或 5 人成团&#xff0c;团长免单模式则需规定团长的角色和权益等。确定功能需求&#xff1a;包括拼团活动创建、展示、参与、支付、成团通知、售后处理…