これまでにrosjavaのインストール、rosjavaチュートリアル(pub/sub)の実行、
Publisher、Subscriberを見てきました。
今回からrosjavaのサービスを利用してみます。
まずはパッケージの準備です。
rosjavaはビルドシステムを作るのがめんどうなので、rosjava_tutorial_pubsubをコピーします。
roscd rosjava_core次にmanifest.xmlのrosjava-pathelementを修正します。
cp -r rosjava_tutorial_pubsub rosjava_tutorial_service
また、test_rosパッケージのAddTwoIntsサービスを利用するので、dependに追加しておきます。
- <package>
- <description brief="rosjava_tutorial_service">
- rosjava_tutorial_service
- </description>
- <author>OTL</author>
- <license>BSD</license>
- <review status="unreviewed" notes=""/>
- <url>http://ros.org/wiki/rosjava_tutorial_service</url>
- <depend package="rosjava" />
- <depend package="test_ros" />
- <export>
- <rosjava-src location="src/main/java" />
- <rosjava-pathelement location="target/" groupId="org.ros" artifactId="org.ros.rosjava.tutorials.service" version="0.0.0" built="true" />
- </export>
- </package>
src/main/java/org/ros/tutorials/pubsubを削除して、
src/main/java/org/ros/tutorials/service/以下にソースを書きましょう。
サービスサーバは以下のような感じ。Server.javaとして保存しましょう。
- /* rosjava service server sample*/
- package org.ros.tutorials.service;
- import org.apache.commons.logging.Log;
- import org.ros.message.MessageListener;
- import org.ros.namespace.GraphName;
- import org.ros.node.Node;
- import org.ros.node.NodeMain;
- import org.ros.node.service.ServiceServer;
- import org.ros.internal.node.service.ServiceResponseBuilder;
- import org.ros.service.test_ros.AddTwoInts;
- public class Server implements NodeMain {
- @Override
- public GraphName getDefaultNodeName() {
- return new GraphName("rosjava_tutorial_service/server");
- }
- @Override
- public void onStart(Node node) {
- final Log log = node.getLog();
- ServiceServer<AddTwoInts.Request, AddTwoInts.Response>
- server = node.newServiceServer("/add_two_ints",
- "test_ros/AddTwoInts",
- new ServiceResponseBuilder<AddTwoInts.Request, AddTwoInts.Response>() {
- @Override
- public AddTwoInts.Response build(AddTwoInts.Request request) {
- AddTwoInts.Response res = new AddTwoInts.Response();
- res.sum = request.a + request.b;
- log.info("add " + request.a + ", " + request.b);
- return res;
- }
- });
- }
- @Override
- public void onShutdown(Node node) {
- }
- @Override
- public void onShutdownComplete(Node node) {
- }
- }
ServiceServerの型にRequestとResponseの両方を入れないといけないところがC++と違いますね。
また、ServiceResponseBuilderというものを使ってコールバックを書くようです。
(なぜか現在org.ros.internal.node.service.ServiceResponseBuilderという、internalなところにあるクラスです)
次は呼び出す方、Client.javaです。
こちらもRequestとResponseの両方の型をいれますね。
そして、callの成否時の処理をServiceResponseListenerに書くようです。
- /* rosjava service client sample
- */
- package org.ros.tutorials.service;
- import com.google.common.base.Preconditions;
- import org.apache.commons.logging.Log;
- import org.ros.node.Node;
- import org.ros.node.NodeMain;
- import org.ros.namespace.GraphName;
- import org.ros.node.service.ServiceClient;
- import org.ros.node.service.ServiceResponseListener;
- import org.ros.exception.RemoteException;
- import org.ros.service.test_ros.AddTwoInts;
- /*
- * @author OTL
- */
- public class Client implements NodeMain {
- @Override
- public GraphName getDefaultNodeName() {
- return new GraphName("rosjava_tutorial_service/client");
- }
- @Override
- public void onStart(Node node) {
- final Log log = node.getLog();
- try {
- ServiceClient<AddTwoInts.Request, AddTwoInts.Response> client =
- node.newServiceClient("/add_two_ints", "test_ros/AddTwoInts");
- Thread.sleep(100);
- AddTwoInts.Request srv = new AddTwoInts.Request();
- srv.a = 5;
- srv.b = 1;
- client.call(srv, new ServiceResponseListener<AddTwoInts.Response>() {
- @Override
- public void onSuccess(AddTwoInts.Response res) {
- log.info("call service success! " + res.sum);
- }
- @Override
- public void onFailure(RemoteException arg) {
- log.info("call service fail");
- }
- });
- } catch (Exception e) {
- if (node != null) {
- node.getLog().fatal(e);
- } else {
- e.printStackTrace();
- }
- }
- }
- @Override
- public void onShutdown(Node node) {
- }
- @Override
- public void onShutdownComplete(Node node) {
- }
- }
こちらもRequestとResponseの両方の型をいれますね。
そして、callの成否時の処理をServiceResponseListenerに書くようです。
あとは普通にmakeすればできあがりです。
実行するにはroscoreを上げて、
サーバは
rosrun rosjava_bootstrap run.py rosjava_tutorial_service org.ros.tutorials.service.Server
クライアントは
rosrun rosjava_bootstrap run.py rosjava_tutorial_service org.ros.tutorials.service.Client
のように実行します。
ちなみにサーバをテストしようとして、
rosservice call /add_two_ints 1 2
とするとエラーになります。どうやらrosservice args /add_two_intsがうまく動いていないようです。
rosserviceが使えないので、サーバだけ動作確認したい場合は
rosrun test_ros add_two_ints_client
とするといいと思います。
実行するにはroscoreを上げて、
サーバは
rosrun rosjava_bootstrap run.py rosjava_tutorial_service org.ros.tutorials.service.Server
クライアントは
rosrun rosjava_bootstrap run.py rosjava_tutorial_service org.ros.tutorials.service.Client
のように実行します。
ちなみにサーバをテストしようとして、
rosservice call /add_two_ints 1 2
とするとエラーになります。どうやらrosservice args /add_two_intsがうまく動いていないようです。
rosserviceが使えないので、サーバだけ動作確認したい場合は
rosrun test_ros add_two_ints_client
とするといいと思います。
0 件のコメント:
コメントを投稿