越城網(wǎng)站建設(shè)公司陜西網(wǎng)站建設(shè)網(wǎng)絡(luò)公司
ROS2 入門應(yīng)用 請(qǐng)求和應(yīng)答(C++)
- 1. 創(chuàng)建功能包
- 2. 創(chuàng)建源文件
- 2.1. 服務(wù)端
- 2.2. 客戶端
- 3. 添加依賴關(guān)系
- 4. 添加編譯信息
- 4.1. 添加搜索庫(kù)
- 4.2. 增加可執(zhí)行文件
- 4.3. 增加可執(zhí)行文件位置
- 5. 編譯和運(yùn)行
1. 創(chuàng)建功能包
在《ROS2 入門應(yīng)用 工作空間》中已創(chuàng)建和加載了ros2_ws
工作空間
在《ROS2 入門應(yīng)用 元功能包(C++)》中已創(chuàng)建和加載了my_package
功能包
那么就創(chuàng)建一個(gè)獨(dú)立的cpp_srvcli
功能包來(lái)做服務(wù)的請(qǐng)求和應(yīng)答的功能
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake cpp_srvcli --dependencies rclcpp example_interfaces
--dependencies
可選參數(shù)將會(huì)自動(dòng)在package.xml
和CMakeLists.txt
中添加必要的依賴行
依賴example_interfaces
包,將會(huì)使用到example_interfaces
的srv
文件,兩位整數(shù)求和服務(wù):
int64 a
int64 b
---
int64 sum
2. 創(chuàng)建源文件
進(jìn)入cpp_srvcli
功能包的src
文件夾
cd ~/ros2_ws/src/cpp_srvcli/src
2.1. 服務(wù)端
新建add_two_ints_server.cpp
服務(wù)端源文件
nano add_two_ints_server.cpp
復(fù)制以下內(nèi)容到文件中:
#include "rclcpp/rclcpp.hpp"
#include "example_interfaces/srv/add_two_ints.hpp"#include <memory>/* 求和函數(shù) */
void add(const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,std::shared_ptr<example_interfaces::srv::AddTwoInts::Response> response)
{/* 從請(qǐng)求中添加兩個(gè)整數(shù),并將總和提供給響應(yīng) */response->sum = request->a + request->b;/* 使用日志通知控制臺(tái)其服務(wù)狀態(tài) */RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %ld" " b: %ld", request->a, request->b);RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%ld]", (long int)response->sum);
}int main(int argc, char **argv)
{/* 初始化ROS2 */rclcpp::init(argc, argv);/* 定義服務(wù)端節(jié)點(diǎn)add_two_ints_server */std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_server");/* 創(chuàng)建服務(wù)名為add_two_ints,服務(wù)函數(shù)為add的service服務(wù)端 */rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr service =node->create_service<example_interfaces::srv::AddTwoInts>("add_two_ints", &add);/* 通知準(zhǔn)備就緒 */RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to add two ints.");/* 運(yùn)行節(jié)點(diǎn) */rclcpp::spin(node);/* 退出ROS2 */rclcpp::shutdown();
}
2.2. 客戶端
新建add_two_ints_client.cpp
客戶端源文件
nano add_two_ints_client.cpp
復(fù)制以下內(nèi)容到文件中:
#include "rclcpp/rclcpp.hpp"
#include "example_interfaces/srv/add_two_ints.hpp"#include <chrono>
#include <cstdlib>
#include <memory>/* 方便表示時(shí)間 */
using namespace std::chrono_literals;int main(int argc, char **argv)
{/* 初始化ROS2 */rclcpp::init(argc, argv);/* 校驗(yàn) */if (argc != 3) {RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "usage: add_two_ints_client X Y");return 1;}/* 定義客戶端節(jié)點(diǎn)add_two_ints_client */std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_client");/* 創(chuàng)建服務(wù)名為add_two_ints的client客戶端 */rclcpp::Client<example_interfaces::srv::AddTwoInts>::SharedPtr client =node->create_client<example_interfaces::srv::AddTwoInts>("add_two_ints");/* 創(chuàng)建請(qǐng)求request */auto request = std::make_shared<example_interfaces::srv::AddTwoInts::Request>();request->a = atoll(argv[1]);request->b = atoll(argv[2]);/* 搜索服務(wù)節(jié)點(diǎn),間隔1s */while (!client->wait_for_service(1s)) {if (!rclcpp::ok()) {RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");return 0;}/* 如果找不到,將會(huì)繼續(xù)等待 */RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");}/* 獲得應(yīng)答并顯示其狀態(tài) */auto result = client->async_send_request(request);// Wait for the result.if (rclcpp::spin_until_future_complete(node, result) ==rclcpp::FutureReturnCode::SUCCESS){RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Sum: %ld", result.get()->sum);} else {RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Failed to call service add_two_ints");}/* 退出ROS2 */rclcpp::shutdown();return 0;
}
3. 添加依賴關(guān)系
創(chuàng)建功能包時(shí),已通過(guò)--dependencies
可選參數(shù)自動(dòng)在package.xml
中添加必要的依賴行
<depend>rclcpp</depend>
<depend>example_interfaces</depend>
4. 添加編譯信息
在CMakeLists.txt
編譯文件中
4.1. 添加搜索庫(kù)
創(chuàng)建功能包時(shí),已通過(guò)--dependencies
可選參數(shù)自動(dòng)在CMakeLists.txt
中添加必要的搜索庫(kù)依賴行
find_package(rclcpp REQUIRED)
find_package(example_interfaces REQUIRED)
4.2. 增加可執(zhí)行文件
然后,再增加可執(zhí)行文件,
src/add_two_ints_server.cpp
命名為server
可執(zhí)行文件,
src/add_two_ints_client.cpp
命名為client
可執(zhí)行文件,
并添加目標(biāo)依賴關(guān)系:
add_executable(server src/add_two_ints_server.cpp)
ament_target_dependencies(server rclcpp example_interfaces)add_executable(client src/add_two_ints_client.cpp)
ament_target_dependencies(client rclcpp example_interfaces)
4.3. 增加可執(zhí)行文件位置
最后,增加可執(zhí)行文件位置,這樣ROS2就可以找到現(xiàn)在的可執(zhí)行文件:
install(TARGETSserverclientDESTINATION lib/${PROJECT_NAME})
5. 編譯和運(yùn)行
進(jìn)入工作空間根目錄
cd ~/ros2_ws
在編譯之前檢查缺失的依賴項(xiàng)(可跳過(guò)):
rosdep install -i --from-path src --rosdistro humble -y
編譯:
colcon build --packages-select cpp_srvcli
打開一個(gè)新終端,運(yùn)行服務(wù)端節(jié)點(diǎn):
ros2 run cpp_srvcli server# [INFO] [rclcpp]: Ready to add two ints.
打開一個(gè)新終端,運(yùn)行客戶端節(jié)點(diǎn):
ros2 run cpp_srvcli client 1 2# [INFO] [rclcpp]: Sum: 3
謝謝