$search
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2008, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 */ 00034 00035 // author: Jason Wolfe 00036 00037 00038 package ros.roscpp; 00039 00040 import java.util.ArrayList; 00041 import java.util.Arrays; 00042 import java.util.Collection; 00043 import java.util.LinkedList; 00044 import java.util.List; 00045 import java.util.Map; 00046 import java.util.concurrent.ExecutorService; 00047 import java.util.concurrent.Executors; 00048 import java.util.concurrent.FutureTask; 00049 00050 import ros.NodeHandle; 00051 import ros.Publisher; 00052 import ros.RosException; 00053 import ros.ServiceClient; 00054 import ros.ServiceServer; 00055 import ros.Subscriber; 00056 import ros.Topic; 00057 import ros.ServiceServer.Callback; 00058 import ros.communication.Message; 00059 import ros.communication.Service; 00060 // TODO: see why we get messages out of order? 00061 import ros.communication.Time; 00062 00063 public class CppNodeHandle extends NodeHandle { 00064 private RosCpp ros; 00065 private long cppHandle; 00066 private boolean isValid; 00067 String nsArg; 00068 private Map<String, String> remappingArgs; 00069 private List<CppPublisher<Message> > publishers; 00070 private List<CppSubscriber<Message> > subscribers; 00071 private List<CppServiceServer<Message,Message,Service<Message, Message> > > serviceServers; 00072 private List<CppServiceClient<Message,Message,Service<Message, Message> > > serviceClients; 00073 00074 private ExecutorService threadPool; 00075 00076 protected <V> void submitFuture(FutureTask<V> f) { 00077 if (threadPool == null) threadPool = Executors.newCachedThreadPool(); 00078 threadPool.submit(f); 00079 } 00080 00081 00082 /************************************************************ 00083 * Node Handle creation, destruction, and features 00084 ************************************************************/ 00085 00086 protected CppNodeHandle(RosCpp ros, String ns, Map<String, String> remappings) { 00087 this.ros = ros; 00088 nsArg = ns; 00089 remappingArgs = remappings; 00090 publishers = new LinkedList<CppPublisher<Message> > (); 00091 subscribers = new LinkedList<CppSubscriber<Message> > (); 00092 serviceServers = new LinkedList<CppServiceServer<Message,Message,Service<Message, Message> > >(); 00093 serviceClients = new LinkedList<CppServiceClient<Message,Message,Service<Message, Message> > >(); 00094 cppHandle = JNI.createNodeHandle(ns, Util.mapToArray(remappings)); 00095 if (cppHandle == 0) throw new RuntimeException("Could not create node handle (should never happen)."); 00096 00097 isValid = true; 00098 } 00099 00100 protected void finalize() { shutdown(); } 00101 00102 public NodeHandle copy() { return new CppNodeHandle(ros, nsArg, remappingArgs); } 00103 00104 public void shutdown() { 00105 if (!isValid()) throw new RuntimeException("Node has already been shutdown"); 00106 for (CppPublisher<Message> pub : publishers) pub.shutdown(); 00107 for (CppSubscriber<Message> sub : subscribers) sub.shutdown(); 00108 for (CppServiceServer<Message,Message,Service<Message, Message> > ss : serviceServers) ss.shutdown(); 00109 for (CppServiceClient<Message,Message,Service<Message, Message> > sc : serviceClients) sc.shutdown(); 00110 JNI.shutdown(cppHandle); 00111 cppHandle = 0; 00112 if (threadPool != null) threadPool.shutdownNow(); 00113 isValid = false; 00114 } 00115 00116 public boolean ok() { return JNI.nhOk(cppHandle); } 00117 00118 public boolean isValid() { return isValid; } 00119 00120 00121 public boolean checkMaster() { return JNI.checkMaster(cppHandle); } 00122 public String getMasterHost() { return JNI.getMasterHost(cppHandle); } 00123 public int getMasterPort() { return JNI.getMasterPort(cppHandle); } 00124 public void setMasterRetryTimeout(int ms) { JNI.setMasterRetryTimeout(cppHandle, ms); } 00125 00126 public String getName() { return JNI.getName(cppHandle); } 00127 public String getNamespace() { return nsArg;} 00128 public String resolveName(String name) { return JNI.mapName(cppHandle, name); } 00129 00130 00131 00132 /************************************************************ 00133 * Misc. getters 00134 ************************************************************/ 00135 00136 public Collection<Topic> getTopics() { 00137 String [] topics = JNI.getPublishedTopics(cppHandle); 00138 int len = topics.length / 3; 00139 if (len * 3 != topics.length) throw new RuntimeException("Unexpected output from getPublishedTopics"); 00140 List<Topic> ret = new ArrayList<Topic>(); 00141 for(int i = 0; i < len; i++) { 00142 ret.add(new Topic(topics[i*3 + 0], topics[i*3 + 1], topics[i*3 + 2])); 00143 } 00144 return ret; 00145 } 00146 00147 public Collection<String> getSubscribedTopics() { 00148 return (List<String>)Arrays.asList(JNI.getSubscribedTopics(cppHandle)); 00149 } 00150 00151 public Collection<String> getAdvertisedTopics() { 00152 return (List<String>)Arrays.asList(JNI.getAdvertisedTopics(cppHandle)); 00153 } 00154 00155 /************************************************************ 00156 * Parameter server calls 00157 ************************************************************/ 00158 00159 public boolean hasParam(String param) { 00160 return JNI.hasParam(cppHandle, param); 00161 } 00162 00163 public boolean getBooleanParam(String param, boolean useCache) throws RosException { 00164 return JNI.getBooleanParam(cppHandle, param, useCache); 00165 } 00166 public int getIntParam(String param, boolean useCache) throws RosException { 00167 return JNI.getIntParam(cppHandle, param, useCache); 00168 } 00169 public double getDoubleParam(String param, boolean useCache) throws RosException { 00170 return JNI.getDoubleParam(cppHandle, param, useCache); 00171 } 00172 public String getStringParam(String param, boolean useCache) throws RosException { 00173 return JNI.getStringParam(cppHandle, param, useCache); 00174 } 00175 00176 public void setParam(String param, boolean value) {JNI.setParam(cppHandle, param, value);} 00177 public void setParam(String param, int value) {JNI.setParam(cppHandle, param, value);} 00178 public void setParam(String param, double value) {JNI.setParam(cppHandle, param, value);} 00179 public void setParam(String param, String value) { 00180 if (param == null) throw new IllegalArgumentException("Can't set string parameter " + param + " to null"); 00181 JNI.setParam(cppHandle, param, value); 00182 } 00183 00184 00185 /************************************************************ 00186 * Publications and Subscriptions 00187 ************************************************************/ 00188 00189 @SuppressWarnings("unchecked") 00190 public <M extends Message> Subscriber<M> subscribe(String topic, M messageTemplate, 00191 ros.Subscriber.Callback<M> callback, int queueSize) throws RosException { 00192 Subscriber<M> ret = CppSubscriber.create(cppHandle, topic, messageTemplate, callback,queueSize); 00193 subscribers.add((CppSubscriber<Message>) ret); 00194 return ret; 00195 } 00196 00197 @SuppressWarnings("unchecked") 00198 public <M extends Message> Publisher<M> advertise(String newTopic, M messageTemplate, int queueSize, boolean latch) throws RosException { 00199 Publisher<M> ret = CppPublisher.create(cppHandle, newTopic, messageTemplate, queueSize, latch); 00200 publishers.add((CppPublisher<Message>) ret); 00201 return ret; 00202 } 00203 00204 00205 /************************************************************ 00206 * Service Clients and Servers 00207 ************************************************************/ 00208 00209 @SuppressWarnings("unchecked") 00210 public <Q extends Message, A extends Message, S extends Service<Q, A>> ServiceClient<Q, A, S> serviceClient( 00211 String serviceName, S serviceTemplate, boolean isPersistant, Map<String, String> headerValues) { 00212 CppServiceClient<Q,A,S> ret = CppServiceClient.create(this, cppHandle, serviceName, serviceTemplate, isPersistant, headerValues); 00213 serviceClients.add((CppServiceClient)ret); 00214 return ret; 00215 } 00216 00217 00218 @SuppressWarnings("unchecked") 00219 public <Q extends Message, A extends Message, S extends Service<Q, A>> ServiceServer<Q, A, S> advertiseService( 00220 String serviceName, S serviceTemplate, Callback<Q, A> callback) throws RosException { 00221 CppServiceServer<Q,A,S> ret = CppServiceServer.create(cppHandle, serviceName, serviceTemplate, callback); 00222 serviceServers.add((CppServiceServer) ret); 00223 return ret; 00224 } 00225 00226 00227 00228 /************************************************************ 00229 * Convenience methods copied from Ros 00230 ************************************************************/ 00231 00232 public Time now() { return ros.now(); } 00233 00234 public void spin() { ros.spin(); } 00235 public void spinOnce() { ros.spinOnce(); } 00236 00237 public void logDebug(String message) { ros.logDebug(message); } 00238 public void logInfo(String message) { ros.logInfo(message); } 00239 public void logWarn(String message) { ros.logWarn(message); } 00240 public void logError(String message) { ros.logError(message); } 00241 public void logFatal(String message) { ros.logFatal(message); } 00242 00243 00244 }