1. 程式人生 > >ROS的學習(十六)用C++寫一個簡單的伺服器(service)和客戶端(client)

ROS的學習(十六)用C++寫一個簡單的伺服器(service)和客戶端(client)

      我們將建立一個伺服器節點add_two_ints_server,它將會收到兩個整數,並且返回它們的和。切換目錄到之前建立的beginner_tutorials包下:
cd ~/catkin_ws/src/beginner_tutorials

     編輯src/add_two_ints_server.cpp檔案:
vim src/add_two_ints_server.cpp

     將下面的程式碼複製到檔案中,儲存後退出:
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"

bool add(beginner_tutorials::AddTwoInts::Request  &req,
         beginner_tutorials::AddTwoInts::Response &res)
{
  res.sum = req.a + req.b;
  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
  return true;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "add_two_ints_server");
  ros::NodeHandle n;

  ros::ServiceServer service = n.advertiseService("add_two_ints", add);
  ROS_INFO("Ready to add two ints.");
  ros::spin();

  return 0;
}

     下面解釋一下程式碼:
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"

beginner_tutorials/AddTwoInts.h是由之前我們建立的srv檔案自動產生的標頭檔案。
bool add(beginner_tutorials::AddTwoInts::Request  &req,
         beginner_tutorials::AddTwoInts::Response &res)

這個函式為兩個整數相加提供了服務,它使用了在srv檔案中定義的請求和響應型別,並且返回一個布林型別的值。
{
  res.sum = req.a + req.b;
  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
  return true;
}

在這裡兩個整數相加並存儲在response中,然後輸出了一些關於request和response的資訊,最後返回一個真值。
ros::ServiceServer service = n.advertiseService("add_two_ints", add);

這行程式碼建立了一個服務。

     接下來建立一個客戶端,開啟一個終端輸入:

vim src/add_two_ints_client.cpp

       將下面的程式碼複製進去,儲存後退出:
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>

int main(int argc, char **argv)
{
  ros::init(argc, argv, "add_two_ints_client");
  if (argc != 3)
  {
    ROS_INFO("usage: add_two_ints_client X Y");
    return 1;
  }

  ros::NodeHandle n;
  ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
  beginner_tutorials::AddTwoInts srv;
  srv.request.a = atoll(argv[1]);
  srv.request.b = atoll(argv[2]);
  if (client.call(srv))
  {
    ROS_INFO("Sum: %ld", (long int)srv.response.sum);
  }
  else
  {
    ROS_ERROR("Failed to call service add_two_ints");
    return 1;
  }

  return 0;
}

     下面看一下程式碼解釋:
 ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");

 這行程式碼為add_two_ints建立了一個客戶端,ros::ServiceClient物件之後被用來呼叫服務。
  beginner_tutorials::AddTwoInts srv;
  srv.request.a = atoll(argv[1]);
  srv.request.b = atoll(argv[2]);

我們示例了一個自動產生的服務類,並且在它的請求成員中分配值。一個服務類包括了兩個成員,請求和服務。它同樣包括了兩個類的定義,請求和響應。
if (client.call(srv))

這句程式碼才開始真正呼叫了服務,因為服務呼叫被阻塞,當呼叫完成後就立即返回。如果服務呼叫成功,call()將會返回真及srv中的值。否則,call()將會返回假及srv中的值。

     開啟~/catkin_ws/src/beginner_tutorials/CMakeLists.txt,把下面程式碼複製到檔案末尾,儲存,退出:

add_executable(add_two_ints_server src/add_two_ints_server.cpp)
target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
add_dependencies(add_two_ints_server beginner_tutorials_gencpp)

add_executable(add_two_ints_client src/add_two_ints_client.cpp)
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
add_dependencies(add_two_ints_client beginner_tutorials_gencpp)

     這將會建立兩個可執行檔案,add_two_ints_serveradd_two_ints_client,預設將會產生在~/catkin_ws/devel/lib/share/<package name>目錄下,你可以直接執行它們,也可以通過rosrun來執行。

     現在開始構建:

cd ~/catkin_ws

catkin_make

     ok了,一切準備就緒,現在就開始檢驗一下程式是否正確吧。開啟一個終端,執行伺服器:
rosrun beginner_tutorials add_two_ints_server

會出現一下提示:

Ready to add two ints.

     再開啟一個終端,執行客戶端:
rosrun beginner_tutorials add_two_ints_client 1 3

     我們可以看到返回的結果如下:
Requesting 1+3
1 + 3 = 4

     說明你已經成功了。

相關推薦

ROS學習C++一個簡單伺服器(service)客戶(client)

      我們將建立一個伺服器節點add_two_ints_server,它將會收到兩個整數,並且返回它們的和。切換目錄到之前建立的beginner_tutorials包下: cd ~/catkin_ws/src/beginner_tutorials      編輯sr

C++語言學習——多繼承

虛函數表 -o nag http layout 調用 img error names C++語言學習(十六)——多繼承 一、多繼承簡介 1、多繼承簡介 C++語言支持多繼承,一個子類可以有多個父類,子類擁有所有父類的成員變量,子類繼承所有父類的成員函數,子類對象可以當作任意

【轉】 JMeter學習JMeter函數學習

blog 自動 當前 3.2 add 函數的調用 瀏覽器 con 保存 JMeter函數是一些能夠轉化在測試樹中取樣器或者其他配置元件的域的特殊值。一個函數的調用就像這樣:${_functionName(var1,var2,var3)},-functionName匹配函數名

linux學習戶組管理

gin rec uda username type /usr 之前 密碼 只有一個 一、用戶文件 文件:/etc/passwd 這個文件記錄了用戶了用戶名,用戶id,所屬組,家目錄,shell信息: [root@iZ25lzba47vZ ~]# tail -n3 /etc

Linux學習VIM

etc es2017 移動 進行 ges code inux nbsp 安裝 一、簡介 VIM是vi的增強版。VIM是Linux平臺上的主要編輯器。基本上所有的文檔的新增,修改,保存都需要用到它。所以,掌握VIM是很有必要的。 vim的安裝非常簡單,一條命令就可以了: y

Python學習內置函數,遞歸

font ID lam 效率 ascii碼 span 自帶 打印 十六 1、遞歸 def test1(): num=int(input(‘輸入數字‘)) if num%2==0: #判斷輸入數字是不是偶數 return True #是偶數

GO語言學習Go 語言結構體

指針 描述 ble title 設定 import spa 輸出 sub Go 語言結構體 Go 語言中數組可以存儲同一類型的數據,但在結構體中我們可以為不同項定義不同的數據類型。 結構體是由一系列具有相同類型或不同類型的數據構成的數據集合。 結構體表示一項記錄,比如

吳恩達機器學習機器學習流水線、上限分析

目錄 0. 前言 1. 流水線 2. 上限分析(Ceiling analysis) 學習完吳恩達老師機器學習課程的照片OCR,簡單的做個筆記。文中部分描述屬於個人消化後的理解,僅供參考。 如果這篇文章對你有一點小小的幫助,請給個關注

JMeter學習JMeter函式學習

JMeter函式是一些能夠轉化在測試樹中取樣器或者其他配置元件的域的特殊值。一個函式的呼叫就像這樣:${_functionName(var1,var2,var3)},-functionName匹配函式名,圓括號內設定函式的引數,例如${_time(YMD)}實際引數因函式而不同。不需要引數的函式使圓

PE檔案格式學習:延遲載入表

1.介紹 延遲載入表本質上跟繫結匯入表的目的是一樣的,都是為了加快程式載入檔案的速度,只不過方法不一樣。 延遲載入是指在呼叫某個DLL時才去載入,目的是為了避免在程式啟動之初就載入了不必要的DLL而浪費了時間。微軟建議在兩種情況下使用延遲載入: 程式並非在啟動時就會呼叫D

python學習之網站的編寫HTML,CSS,JS----------示例,構造一個左側管理選單的功能,點選主選單才顯示下面的內容

結果: 程式碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>逆水行舟不進則退</title>

機器學習與深度學習系列連載: 第二部分 深度學習迴圈神經網路 4BiDirectional RNN, Highway network, Grid-LSTM

深度學習(十六)迴圈神經網路 4(BiDirectional RNN, Highway network, Grid-LSTM) RNN處理時間序列資料的時候,不僅可以正序,也可以正序+逆序(雙向)。下面顯示的RNN模型,不僅僅是simple RNN,可以是LSTM,或者GRU 1 B

機器學習 電商O2O優惠券使用預測-2

介紹        這篇文章是想繼續總結一遍優惠券預測,寫寫感受並進行一個記錄總結,零零散散以作為記錄整理之用。 本篇是選了三點本人覺得專案中重要的寫了一下,其它內容暫時略過 第一部分:資料清洗資料分析程式碼

深度學習

1、學習率改變的新方法:剛開始陡升,後來慢慢下降;其中32是最大的學習率與最小的學習率之比,10代表第一個epoch升高,後面九個epoch緩緩下降 2、Concat pooling:即將啟用值,啟用值的平均池化,啟用值的最大池化連線在一起 3、注意力機制其實就是對不同的狀態進行加權

opencv學習:超大影象二值化

超大影象二值化的方法         1.可以採用分塊方法;2.先縮放處理就行二值化,然後還原大小。 一:分塊處理超大影象的二值化問題 #匯入cv模組 import cv2 as cv import numpy as np #超大影象二值化 de

opencv學習:影象的二值化

影象二值化介紹:https://blog.csdn.net/qq_30490125/article/details/80458500                       &nbs

python學習——多型、封裝、反射、、動態匯入模組、類內建attr方法

一、多型 # 不同的例項呼叫同樣的方法,產生不同的結果 # 多型來自繼承 class H2O: def __init__(self,name,temperature): self.name=name self.temperature=

spring深入學習 IOC 之parentBeanFactory 與依賴處理

繼上篇部落格 【死磕 Spring】—– 載入 bean 之 快取中獲取單例 bean,如果從單例快取中沒有獲取到單例 bean,則說明兩種情況: 該 bean 的 scope 不是 singleton 該 bean 的 scope 是 singleton ,但是沒有初始化

Spring 學習——Spring AOP之前置通知後置通知

spring aop 1)加入jar包 com.springsource.net.sf.cglib-2.2.0.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.R

機器學習無監督學習、聚類KMeans聚類

無監督學習、聚類 聚類是在樣本沒有標註的情況下,對樣本進行特徵提取並分類,屬於無監督學習的內容。有監督學習和無監督學習的區別就是需要分析處理的資料樣本是否事先已經標註。如下圖,左邊是有監督,右邊是無監督: 應用場景也有所不同。 無