ConcertChecker.java
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  * Copyright (c) 2011, Willow Garage, Inc.
00005  * Copyright (c) 2013, OSRF.
00006  * Copyright (c) 2013, Yujin Robot.
00007  *
00008  * All rights reserved.
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  *
00013  *  * Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  *  * Redistributions in binary form must reproduce the above
00016  *    copyright notice, this list of conditions and the following
00017  *    disclaimer in the documentation and/or other materials provided
00018  *    with the distribution.
00019  *  * Neither the name of Willow Garage, Inc. nor the names of its
00020  *    contributors may be used to endorse or promote products derived
00021  *    from this software without specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  * POSSIBILITY OF SUCH DAMAGE.
00035  */
00036 
00037 package com.github.rosjava.android_remocons.common_tools.master;
00038 
00039 import android.util.Log;
00040 
00041 import com.github.robotics_in_concert.rocon_rosjava_core.master_info.MasterInfo;
00042 import com.github.robotics_in_concert.rocon_rosjava_core.master_info.MasterInfoException;
00043 import com.github.robotics_in_concert.rocon_rosjava_core.rocon_interactions.InteractionsException;
00044 import com.github.robotics_in_concert.rocon_rosjava_core.rocon_interactions.RoconInteractions;
00045 import com.github.rosjava.android_remocons.common_tools.rocon.Constants;
00046 
00047 import org.ros.address.InetAddressFactory;
00048 import org.ros.android.NodeMainExecutorService;
00049 import org.ros.internal.node.client.ParameterClient;
00050 import org.ros.internal.node.server.NodeIdentifier;
00051 import org.ros.internal.node.xmlrpc.XmlRpcTimeoutException;
00052 import org.ros.namespace.GraphName;
00053 import org.ros.node.NodeConfiguration;
00054 
00055 import java.net.URI;
00056 import java.net.URISyntaxException;
00057 import java.util.Date;
00058 
00068 public class ConcertChecker {
00069     public interface ConcertDescriptionReceiver {
00073         void receive(RoconDescription roconDescription);
00074     }
00075 
00076     public interface FailureHandler {
00081         void handleFailure(String reason);
00082     }
00083 
00084     private CheckerThread checkerThread;
00085     private ConcertDescriptionReceiver foundConcertCallback;
00086     private FailureHandler failureCallback;
00087 
00091     public ConcertChecker(ConcertDescriptionReceiver foundConcertCallback, FailureHandler failureCallback) {
00092         this.foundConcertCallback = foundConcertCallback;
00093         this.failureCallback = failureCallback;
00094     }
00095 
00100     public void beginChecking(MasterId masterId) {
00101         stopChecking();
00102         if (masterId.getMasterUri() == null) {
00103             failureCallback.handleFailure("empty concert URI");
00104             return;
00105         }
00106         URI uri;
00107         try {
00108             uri = new URI(masterId.getMasterUri());
00109         } catch (URISyntaxException e) {
00110             failureCallback.handleFailure("invalid concert URI");
00111             return;
00112         }
00113         checkerThread = new CheckerThread(masterId, uri);
00114         checkerThread.start();
00115     }
00116 
00120     public void stopChecking() {
00121         if (checkerThread != null && checkerThread.isAlive()) {
00122             checkerThread.interrupt();
00123         }
00124     }
00125 
00126     private class CheckerThread extends Thread {
00127         private URI concertUri;
00128         private MasterId masterId;
00129 
00130         public CheckerThread(MasterId masterId, URI concertUri) {
00131             this.concertUri = concertUri;
00132             this.masterId = masterId;
00133             setDaemon(true);
00134             // don't require callers to explicitly kill all the old checker threads.
00135             setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
00136                 @Override
00137                 public void uncaughtException(Thread thread, Throwable ex) {
00138                     failureCallback.handleFailure("exception: " + ex.getMessage());
00139                 }
00140             });
00141         }
00142 
00143         @Override
00144         public void run() {
00145             try {
00146                 // Check if the master exists by looking for the rosversion parameter.
00147                 // getParam throws when it can't find the parameter (DJS: what does it throw?).
00148                 // Could get it to look for a hardcoded rocon parameter for extra guarantees
00149                 // (e.g. /rocon/version) however we'd still have to do some checking below
00150                 // when the info is there but interactions not.
00151                 ParameterClient paramClient = new ParameterClient(
00152                         NodeIdentifier.forNameAndUri("/concert_checker", concertUri.toString()), concertUri);
00153                 String version = (String) paramClient.getParam(GraphName.of("/rosversion")).getResult();
00154                 Log.i("Remocon", "r ros master found [" + version + "]");
00155 
00156                 NodeMainExecutorService nodeMainExecutorService = new NodeMainExecutorService();
00157                 NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(
00158                         InetAddressFactory.newNonLoopback().getHostAddress(), concertUri);
00159 
00160                 // Check for the concert information topic
00161                 MasterInfo masterInfo = new MasterInfo();
00162                 RoconInteractions roconInteractions = new RoconInteractions(Constants.ANDROID_PLATFORM_INFO.getUri());
00163 
00164                 nodeMainExecutorService.execute(
00165                         masterInfo,
00166                         nodeConfiguration.setNodeName("master_info_node")
00167                 );
00168                 masterInfo.waitForResponse(); // MasterInfoExc. on timeout, listener or ros runtime errors
00169                 Log.i("Remocon", "master info found");
00170                 nodeMainExecutorService.execute(
00171                         roconInteractions,
00172                         nodeConfiguration.setNodeName("rocon_interactions_node")
00173                 );
00174                 roconInteractions.waitForResponse(); // InteractionsExc. on timeout, service or ros runtime errors
00175                 Log.i("Remocon", "rocon interactions found");
00176 
00177                 // configure concert description
00178                 Date timeLastSeen = new Date();
00179                 RoconDescription description = new RoconDescription(
00180                         masterId,
00181                         masterInfo.getName(),
00182                         masterInfo.getDescription(),
00183                         masterInfo.getIcon(),
00184                         roconInteractions.getNamespace(),
00185                         timeLastSeen);
00186 
00187                 description.setConnectionStatus(RoconDescription.OK);
00188                 description.setUserRoles(roconInteractions.getRoles());
00189                 foundConcertCallback.receive(description);
00190 
00191                 nodeMainExecutorService.shutdownNodeMain(masterInfo);
00192                 nodeMainExecutorService.shutdownNodeMain(roconInteractions);
00193                 return;
00194             } catch (XmlRpcTimeoutException e) {
00195                 Log.w("Remocon", "timed out trying to connect to the master [" + concertUri + "][" + e.toString() + "]");
00196                 failureCallback.handleFailure("Timed out trying to connect to the master. Is your network interface up?");
00197             } catch (RuntimeException e) {
00198                 // thrown if there is no master at that url (from java.net.ConnectException)
00199                 Log.w("Remocon", "connection refused. Is the master running? [" + concertUri + "][" + e.toString() + "]");
00200                 failureCallback.handleFailure("Connection refused. Is the master running?");
00201             } catch (InteractionsException e) {
00202                 Log.w("Remocon", "rocon interactions unavailable [" + concertUri + "][" + e.toString() + "]");
00203                 failureCallback.handleFailure("Rocon interactions unavailable [" + e.toString() + "]");
00204             } catch (MasterInfoException e) {
00205                 Log.w("Remocon", "master info unavailable [" + concertUri + "][" + e.toString() + "]");
00206                 failureCallback.handleFailure("Rocon master info unavailable. Is your ROS_IP set? Is the rocon_master_info node running?");
00207             } catch (Throwable e) {
00208                 Log.w("Remocon", "exception while creating node in concert checker for URI " + concertUri, e);
00209                 failureCallback.handleFailure("unknown exception in the rocon checker [" + e.toString() + "]");
00210             }
00211         }
00212     }
00213 }


android_remocons
Author(s): Daniel Stonier, Kazuto Murase
autogenerated on Sat Jun 8 2019 19:32:24