ROS服務與客戶端編寫詳解
阿新 • • 發佈:2021-07-15
- srv檔案
float64 init_x float64 init_y float64 init_z float64 delta_x float64 delta_y float64 delta_z --- float64 x float64 y float64 z
- 服務
// 包括了ROS常用的標頭檔案 #include "ros/ros.h" // 建立srv檔案時生成的標頭檔案,其中kinematics_demo為軟體包名稱,trans為srv檔名稱,並在其後加上.h副檔名 #include "kinematics_demo/trans.h" // 軟體包名與srv檔名共同組成一個類名(kinematics_demo::trans),此類包括兩個成員變數request、response和兩個類定義Request、Response// 服務中執行主要功能的回撥函式的原型 bool trans_pose(kinematics_demo::trans::Request &req, kinematics_demo::trans::Response &res); int main(int argc, char **argv) { // 初始化ROS,並指定節點名稱為kindmatics_sever ros::init(argc, argv, "kinematics_server"); // 為節點建立控制代碼n ros::NodeHandle n;// 建立名稱是trans_pose的服務,並註冊回撥函式trans_pose // 第一個trans_pose為服務名稱,第二個trans_pose為回撥函式名 ros::ServiceServer service = n.advertiseService("trans_pose", trans_pose); ROS_INFO("Kinematics server"); // 迴圈等待回撥函式 ros::spin(); return 0; } bool trans_pose(kinematics_demo::trans::Request &req, kinematics_demo::trans::Response&res) { res.x = req.init_x + req.delta_x; res.y = req.init_y + req.delta_y; res.z = req.init_z + req.delta_z; ROS_INFO("Pose before trans: (%f, %f, %f)", (double)req.init_x, (double)req.init_y, (double)req.init_z); ROS_INFO("Pose trans: (%f, %f, %f)", (double)req.delta_x, (double)req.delta_y, (double)req.delta_z); ROS_INFO("Pose after trans: (%f, %f, %f)", (double)res.x, (double)res.y, (double)res.z); return true; }
- 客戶端
// 包括了ROS常用的標頭檔案 #include "ros/ros.h" // 建立srv檔案時生成的標頭檔案,其中kinematics_demo為軟體包名稱,trans為srv檔名稱,並在其後加上.h副檔名 #include "kinematics_demo/trans.h" #include <cstdlib> // 第一個形參argc(argument counter)表示main函式的引數個數 // 第二個形參argv(argument value)表示main函式的引數值 // 也可寫為int main(int argc, char *argv[]),即由指標組成的陣列,陣列中每個元素都是指向char的指標 // 當不帶引數執行主函式時,作業系統向主函式傳遞的引數argc為1,而argv[0](是一個指標)指向程式的路徑及名稱 // 當帶引數執行主函式時,作業系統向主函式傳遞的引數argc為1加上引數個數,argv[0]意義不變,從arg[1]開始依次指向引數字串 int main(int argc, char **argv) { // 初始化ROS,並指定節點名稱為kindmatics_client ros::init(argc, argv, "kinematics_client"); // 當引數個數不為7(即未傳入6個引數,與預設的1個引數共7個) if (argc != 7) { ROS_INFO("usage: kinematics_client init_x, init_y, init_z, delta_x, delta_y, delta_z"); return 1; } // 為節點建立控制代碼n ros::NodeHandle n; // 為名稱是trans_pose的服務建立客戶端,並賦給名稱為client的ros::ServiceClient的物件 // 尖括號中為<軟體包名::srv檔名> // 此處或為函式模板語法,sericeClient為函式名,尖括號中內容顯式表明函式引數型別,圓括號中為引數值 ros::ServiceClient client = n.serviceClient<kinematics_demo::trans>("trans_pose"); // 例項化一個自動生成的服務類,即宣告一個kinematics_demo::trans物件srv // *注:此處服務的意義與伺服器的服務並不相同,此服務強調服務內容而非動作,與srv檔案所表示的服務相同 // 即軟體包名與srv檔名二者共同組成一個類名,用此類名宣告一個物件srv kinematics_demo::trans srv; // 上面例項化的名為srv的服務類,包括兩個成員變數request、response和兩個類定義Request、Response // 為request成員賦值 srv.request.init_x = atof(argv[1]); srv.request.init_y = atof(argv[2]); srv.request.init_z = atof(argv[3]); srv.request.delta_x = atof(argv[4]); srv.request.delta_y = atof(argv[5]); srv.request.delta_z = atof(argv[6]); // 客戶端呼叫服務 if(client.call(srv)) { ROS_INFO("Pose after trans: (%f, %f, %f)", (double)srv.response.x, (double)srv.response.y, (double)srv.response.z); } else { ROS_ERROR("Failed to call service"); return 1; } return 0; }
- 說明