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

ops/2025/1/22 5:56:14/

我们将构建一个完整的项目来讲解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/ops/152115.html

相关文章

linux-FTP服务配置与应用

也许你对FTP不陌生&#xff0c;但是你是否了解FTP到底是个什么玩意&#xff1f; FTP 是File Transfer Protocol&#xff08;文件传输协议&#xff09;的英文简称&#xff0c;而中文简称为 “文传协议” 用于Internet上的控制文件的双向传输。同时&#xff0c;它也是一个应用程序…

特殊类设计

[本节目标] 掌握常见特殊类的设计方式 1.请设计一个类&#xff0c;不能被拷贝 拷贝只会放生在两个场景中&#xff1a;拷贝构造函数以及赋值运算符重载&#xff0c;因此想要让一个类禁止拷贝&#xff0c;只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 C98 将拷贝构…

直驱式风电储能制氢仿真模型matlab/simulink

接着还是以直驱式风电为DG中的研究对象&#xff0c;上篇博客考虑的风电并网惯性的问题&#xff0c;这边博客主要讨论功率消纳的问题。 考虑到风速是随机变化的&#xff0c;导致风电输出功率的波动性和间歇性问题突出&#xff1b;随着其应用规模的不断扩大以及风电在电网中渗透率…

将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(1.标准版)

问题 项目里使用了 AzureBlob 存储了用户上传的各种资源文件&#xff0c;近期 AzureBlob 的流量费用增长很快&#xff0c;想通过分析Blob的日志&#xff0c;获取一些可用的信息&#xff0c;所以有了这个需求&#xff1a;将存储账户的日志&#xff08;读写&#xff0c;审计&…

Excel 技巧15 - 在Excel中抠图头像,换背景色(★★)

本文讲了如何在Excel中抠图头像&#xff0c;换背景色。 1&#xff0c;如何在Excel中抠图头像&#xff0c;换背景色 大家都知道在PS中可以很容易抠图头像&#xff0c;换背景色&#xff0c;其实Excel中也可以抠简单的图&#xff0c;换背景色。 ※所用头像图片为百度搜索&#x…

【一个按钮一个LED】用STM32F030单片机实现苹果充电器的定时装置

文章目录 前言一、要实现的功能1、循环定时2、倒计时3、指示灯提示4、使用场景二、实现方法1、使用方法2、电路设计三、程序代码和成品1.定时中断子程序2.键值处理3.主函数总结前言 笔者前几年买苹果手机、IPAD配的适配器是A1443型号,这种5V1A,USB-A口、小功率的适配器,苹果…

【深度学习】Pytorch:在 ResNet 中加入注意力机制

在这篇教程中&#xff0c;我们将介绍如何在 ResNet 网络中加入注意力机制模块。我们将通过对标准 ResNet50 进行改进&#xff0c;向网络中添加两个自定义的注意力模块&#xff0c;并展示如何实现这一过程。 为什么要加入注意力机制 注意力机制可以帮助神经网络专注于图像中重要…

PyBroker:利用 Python 和机器学习助力算法交易

PyBroker&#xff1a;利用 Python 和机器学习助力算法交易 你是否希望借助 Python 和机器学习的力量来优化你的交易策略&#xff1f;那么你需要了解一下 PyBroker&#xff01;这个 Python 框架专为开发算法交易策略而设计&#xff0c;尤其关注使用机器学习的策略。借助 PyBrok…