<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【ROS教程】服務通信

      @


      1.流程

      服務通信也是ROS中一種極其常用的通信模式,服務通信是基于請求響應模式的,是一種應答機制。也即: 一個節點A向另一個節點B發送請求,B接收處理請求并產生響應結果返回給A。在ROS中,實現服務通信只需要如下幾步:

      1. 確定客戶端發送的請求的數據類型和服務端響應的數據類型需要自定義.srv文件,修改好CMakeLists.txt文件和package.xml文件并重編譯
      2. 編寫發布方和訂閱方的cpp文件,修改好CMakeLists.txt文件并重編譯
      3. 分別啟動發布方節點和訂閱方節點,必須先啟動服務端再啟動客戶端

      2.自定義請求和響應的數據

      2.1 std_msgs內置類型

      • 內置類型與 C++ 和 Python 中的對應關系:
      Primitive Type C++ Python
      bool uint8_t bool
      int8 int8_t int
      uint8 uint8_t int
      int16 int16_t int
      uint16 uint16_t int
      int32 uint32_t int
      uint64 uint64_t long int
      float32 float float
      float64 double float
      string std::string str bytes
      time ros::Time rospy.Time
      duration ros::Duration rospy.Duration
      • 內置類型的數組與 C++ 和 Python 中的對應關系:
      Primitive Type C++ Python
      variable-length std::vector tuple
      fixed-length boost::array<T, length>或std::vector tuple

      2.2 編寫.srv文件

      示例如下:

      #文件名AddInt.srv
      # 客戶端請求時發送的兩個數字
      int32 num1
      int32 num2
      ---
      # 服務器響應發送的數據
      int32 sum
      
      • 中間的三橫用以區分請求數據和響應數據

      2.3 修改package.xml文件

      • 查看是否存在如下編譯依賴
      <build_depend>message_generation</build_depend>
      
      • 查看是否存在如下執行依賴
      <exec_depend>message_generation</exec_depend>
      

      2.4 修改CMakeLists.txt文件

      2.4.1 修改find_package指令

      # 需要加入 message_generation,必須有 std_msgs
      find_package(catkin REQUIRED COMPONENTS
        roscpp
        rospy
        std_msgs
        message_generation
      )
      

      2.4.2 添加add_message_files指令

      ## 配置 srv 源文件
      add_service_files(
        FILES
        AddInt.srv
      )
      

      2.4.3 添加generate_messages指令

      generate_messages(
        DEPENDENCIES
        std_msgs
      )
      

      其中,add_service_files指令必須要在generate_messages指令的前面,然后在工作空間目錄編譯即可。

      2.5 查看頭文件

      經過以上幾步,在${workspace}/devel/include/${package}/目錄下應該會出現頭文件,如圖:

      在這里插入圖片描述

      • 如果沒有出現,是無法進行接下來的步驟的。這時,只需要把${workspace}/目錄下的build目錄和devel目錄全部刪除,然后重新編譯即可。
      rm -rf build/
      rm -rf devel/
      catkin_make
      

      3.編寫cpp文件

      3.1 功能包目錄文件樹

      在這里插入圖片描述

      3.2 修改CMakeLists.txt文件

      3.2.1 添加add_executable指令

      add_executable(server src/server.cpp)
      add_executable(client src/client.cpp)
      

      3.2.2 添加add_dependencies指令

      add_dependencies(server ${PROJECT_NAME}_gencpp)
      add_dependencies(client ${PROJECT_NAME}_gencpp)
      
      target_link_libraries(server
              ${catkin_LIBRARIES}
              )
      target_link_libraries(client
              ${catkin_LIBRARIES}
              )
      

      3.3 服務端cpp

      示例如下:

      /*
          需求:
              編寫兩個節點實現服務通信,客戶端節點需要提交兩個整數到服務器
              服務器需要解析客戶端提交的數據,相加后,將結果響應回客戶端,
              客戶端再解析
      
          服務器實現:
              1.包含頭文件
              2.初始化 ROS 節點
              3.創建 ROS 句柄
              4.創建 服務 對象
              5.回調函數處理請求并產生響應
              6.由于請求有多個,需要調用 ros::spin()
      
      */
      // 1.包含頭文件
      #include "ros/ros.h"
      #include "serve/AddInt.h"
      
      // bool 返回值由于標志是否處理成功
      bool reponse(serve::AddInt::Request& req,
                 serve::AddInt::Response& resp){
          int num1 = req.num1;
          int num2 = req.num2;
      
          ROS_INFO("服務器接收到的請求數據為:num1 = %d, num2 = %d",num1, num2);
      
          //邏輯處理
          if (num1 < 0 || num2 < 0)
          {
              ROS_ERROR("提交的數據異常:數據不可以為負數");
              return false;
          }
      
          //如果沒有異常,那么相加并將結果賦值給 resp
          resp.sum = num1 + num2;
          return true;
      
      
      }
      
      int main(int argc, char *argv[])
      {
          //設置編碼
          setlocale(LC_ALL,"");
          // 2.初始化 ROS 節點
          ros::init(argc,argv,"server");
          // 3.創建 ROS 句柄
          ros::NodeHandle nh;
          // 4.創建 服務 對象,回調函數的返回值必須是布爾類型
          ros::ServiceServer server = nh.advertiseService("AddInt",reponse);
          ROS_INFO("服務已經啟動....");
          //     5.回調函數處理請求并產生響應
          //     6.由于請求有多個,需要調用 ros::spin()
          ros::spin();
          return 0;
      }
      
      • 創建服務對象時的回調函數的返回值必須是布爾類型

      3.4 客戶端cpp

      示例如下:

      /*
          需求:
              編寫兩個節點實現服務通信,客戶端節點需要提交兩個整數到服務器
              服務器需要解析客戶端提交的數據,相加后,將結果響應回客戶端,
              客戶端再解析
      
          服務器實現:
              1.包含頭文件
              2.初始化 ROS 節點
              3.創建 ROS 句柄
              4.創建 客戶端 對象
              5.請求服務,接收響應
      
      */
      // 1.包含頭文件
      #include "ros/ros.h"
      #include "serve/AddInt.h"
      
      int main(int argc, char *argv[])
      {
          //設置編碼
          setlocale(LC_ALL,"");
      
          // 調用時動態傳值,如果通過 launch 的 args 傳參,需要傳遞的參數個數 +3
          if (argc != 3)
              // if (argc != 5)//launch 傳參(0-文件路徑 1傳入的參數 2傳入的參數 3節點名稱 4日志路徑)
          {
              ROS_ERROR("請提交兩個整數");
              return 1;
          }
      
      
          // 2.初始化 ROS 節點
          ros::init(argc,argv,"client");
          // 3.創建 ROS 句柄
          ros::NodeHandle nh;
          // 4.創建 客戶端 對象
          ros::ServiceClient client = nh.serviceClient<serve::AddInt>("AddInt");
          //等待服務啟動成功
          //方式1
          ros::service::waitForService("AddInt");
          //方式2
          // client.waitForExistence();
          // 5.組織請求數據
          serve::AddInt ai;
          ai.request.num1 = atoi(argv[1]);
          ai.request.num2 = atoi(argv[2]);
          // 6.發送請求,返回 bool 值,標記是否成功
          bool flag = client.call(ai);
          // 7.處理響應
          if (flag)
          {
              ROS_INFO("請求正常處理,響應結果:%d",ai.response.sum);
          }
          else
          {
              ROS_ERROR("請求處理失敗....");
              return 1;
          }
      
          return 0;
      }
      

      4.效果

      在這里插入圖片描述

      在這里插入圖片描述

      在這里插入圖片描述

      在這里插入圖片描述

      本文由博客一文多發平臺 OpenWrite 發布!

      posted @ 2024-08-29 13:33  UnderTurrets  閱讀(186)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日本国产精品第一页久久| 无码福利写真片视频在线播放| 欧美激情一区二区三区成人| 国产中文字幕精品在线| 精品人妻一区二区三区蜜臀| 精品999日本久久久影院| 国产丰满乱子伦午夜福利| 亚洲精中文字幕二区三区| 一区二区三区四区自拍视频| A级毛片100部免费看| 国产色视频一区二区三区qq号| 日本55丰满熟妇厨房伦| 国产一精品一av一免费| 国产国产午夜福利视频| 人妻一区二区三区三区| 色吊丝中文字幕在线观看| 久久香蕉国产线看观看怡红院妓院| 性色av不卡一区二区三区| 曲阳县| 国产精品中文字幕一二三| 亚洲另类激情专区小说图片| 久久精品国产清自在天天线| 亚洲一区二区三区四区| 亚洲AV美女在线播放啊| 亚洲高清国产成人精品久久| 精品无码一区二区三区爱欲| 国产一区二区不卡在线视频| 国产在线精品一区二区三区直播 | 国产资源精品中文字幕| 蜜臀av一区二区三区日韩| 激情在线网| 久久这里只精品国产2| 亚洲成在人线在线播放无码| 四虎永久在线高清免费看| 沭阳县| 亚洲国产精品一区二区三| 成人午夜av在线播放| 国产日韩一区二区在线| 老师破女学生处特级毛ooo片| 亚洲三区在线观看内射后入| 国产极品尤物粉嫩在线观看|