(訳注:最新の情報は[[ROS/Tutorials/WritingServiceClient(c++)|原文]]を参照してください.) #################################### ##FILL ME IN #################################### ## links to any required tutorials ## note.0= [[ja/ROS/Tutorials/ExaminingPublisherSubscriber|シンプルなPublisherとSubscriberを実行してみる]] ## descriptive title for the tutorial ## title = C++でシンプルなサービスとクライアントを書く ## multi-line description to be displayed in search ## description = このチュートリアルではサービスとクライアントノードのC++での書き方を学びます ## the next tutorial description ## next = ## links to next tutorial ## next.0.link= [[ja/ROS/Tutorials/ExaminingServiceClient|シンプルなサービスとクライアントを実行してみる]] ## next.1.link= ## what level user is this tutorial for ## level= BeginnerCategory #################################### <<IncludeCSTemplate(TutorialCSHeaderTemplate)>> == シンプルなサービスとクライアントを書く (C++) == <<TableOfContents(4)>> <<Buildsystem()>> === サービスノードを書く === さてここでは、("add_two_ints_server")という二つのintegerを受け取りその合計を戻り値にもつサービスノードを作っていきます。 {{{{#!wiki buildsystem rosbuild ディレクトリを以前のチュートリアル([[ja/ROS/Tutorials/CreatingPackage|ROSパッケージを作る]])で作成したbeginner_tutorialsのパッケージの中に移動させましょう。 {{{ roscd beginner_tutorials }}} }}}} {{{{#!wiki buildsystem catkin 以前catkinワークスペースで作成したbeginner_tutorialsパッケージに移動してください。 {{{ cd ~/catkin_ws/src/beginner_tutorials }}} }}}} このチュートリアルで必要なサービスを作る以前のチュートリアル([[ja/ROS/Tutorials/CreatingMsgAndSrv|ROSのmsgやsrvなどを作る]])の指示に従ったことを確認してください。 ==== コード ==== '''src/add_two_ints_server.cpp'''というファイルをbeginner_tutorialsの中につくり以下のコードを書き込んでください: {{{ #!cplusplus block=service #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; } }}} ==== コード解説 ==== さてコードを読み解いていきましょう。 ##Now, let's break the code down. <<CodeRef(service,1,2)>> `beginner_tutorials/AddTwoInts.h`は以前作ったsrvファイルを作成したときに生成されたヘッダーファイルです。 <<CodeRef(service,4,5)>> この関数は、2つのint型を足し合わせる働きのサービスで、srvファイルに定義されたリクエストとレスポンスのタイプを読み込み、booleanを返します。 <<CodeRef(service,6,11)>> ここでは、2つのintegerは加えられ、レスポンスの中に保管されます。その後、リクエストとレスポンスのいくらかの情報が、ログに残されます。最後に、サービスは完了したタイミングでtrueを返します。 <<CodeRef(service,18,18)>> ここでは、サービスが生成され、ROSにこのサービスが登録されます。 === クライアントNodeを書く === ==== コード ==== '''src/add_two_ints_client.cpp'''というファイルをbeginner_tutorialsの中につくり以下のコードを書き込んでください: {{{ #!cplusplus block=client #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; } }}} ==== コード解説 ==== さて、コードを読み解いていきましょう。 <<CodeRef(client,15,15)>> これは、`add_two_ints`サービスのためのクライアントを作成しています。 `ros::ServiceClient`オブジェクトは、サービスを後で呼び出すために使用します。 <<CodeRef(client,16,18)>> ここで、自動生成されたサービスのクラスをインスタンス化し、そのリクエストのフィールドに値を代入します。サービスクラスは、二つのメンバー`request` と`response`を持ちます。 これは二つのクラスの定義 `Request` と `Response`も内包しています。 <<CodeRef(client,19,19)>> これは、実際は、サービスを呼び出します。サービスの呼び出しは待機させられ、呼び出しが終わるとreturnします。サービスコールがうまくいけば、`call()`は、trueを返却し、`srv.response`の中の値が使えます。もし呼び出しが失敗していたら、`call()`はfalseを返却し、`srv.response`の中の値は、使えません。 {{{{#!wiki buildsystem rosbuild === nodeをビルドする === また、beginner_tutorialsのCMakeLists.txtを編集しましょう。 {{{ $ rosed beginner_tutorials CMakeLists.txt }}} 最後に以下を加えます。 {{{ rosbuild_add_executable(add_two_ints_server src/add_two_ints_server.cpp) rosbuild_add_executable(add_two_ints_client src/add_two_ints_client.cpp) }}} これは、デフォルトでは、binディレクトリに格納される二つの実行ファイル"add_two_ints_server"と"add_two_ints_client"を生成します。 ROSでCMakeを利用するに当たりさらに情報がほしい場合は、[[CMakeLists]]をご覧ください。 さて、makeをしましょう。 {{{ $ make }}} }}}} {{{{#!wiki buildsystem catkin === サービスとクライアントのノードをビルドする === また、`~/catkin_ws/src/beginner_tutorials/CMakeLists.txt`にあるCMakeLists.txtを編集します。そして以下を最後に加えます: <<GetTaggedCode(https://raw.github.com/ros/catkin_tutorials/master/create_package_srvclient/catkin_ws/src/beginner_tutorials/CMakeLists.txt,xml,SRVCLIENT,show_uri,no_tag_newlines,global_lines)>> これは、デフォルトでは[[catkin/workspaces#Development_.28Devel.29_Space|devel space]]の下のパッケージディレクトリに行く二つの実行ファイル"add_two_ints_server" と "add_two_ints_client"を生成します。 これは、デフォルトでは`~/catkin_ws/devel/lib/share/<package name>`にある[[catkin/workspaces#Development_.28Devel.29_Space|devel space]]の下のパッケージディレクトリに行く二つの実行ファイル"add_two_ints_server" と "add_two_ints_client"を生成します。実行ファイルを直接実行することも、rosrunを使って実行することもできます。それらは、ROSのシステムにあなたのパッケージをインストールするときにPATHの邪魔になってしまうので、'<prefix>/bin'の中には、置かれていません。インストール時に、PATHのなかに実行ファイルを入れたい場合は、インストール対象を準備することもできます。方法については[[catkin/CMakeLists.txt]]を確認してください。 より[[catkin/CMakeLists.txt|CMakeLists.txt]]ファイルについて詳細を知りたい場合は、[[catkin/CMakeLists.txt]]を参照してください。 さて`catkin_make`をしましょう: {{{ #catkin ワークスペースで cd ~/catkin_ws catkin_make }}} }}}} もし、なんらかの理由でビルドが失敗したなら、 * 以前の[[ja/ROS/Tutorials/CreatingMsgAndSrv#Creating_a_srv|ROSのmsgやsrvなどを作る]]のチュートリアルの指示通りに行ってきたことを確認する {{{#!wiki buildsystem rosbuild * `rosls beginner_tutorials/srv_gen/cpp/include/beginner_tutorials/`と打ち、`.h`ファイルが、クライアントやサーバーの.cppファイルでインクルードしたものと一致するかを確認する }}} ##endpage ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE ここではシンプルなサービスとクライアントを書きました.次は[[ja/ROS/Tutorials/ExaminingServiceClient|シンプルなサービスとクライアントをテストしましょう]].