00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
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
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
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
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
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
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 }