00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 package edu.tum.cs.ias.knowrob;
00019
00020 import ros.*;
00021 import ros.pkg.vision_msgs.msg.aposteriori_position;
00022 import ros.pkg.vision_msgs.msg.cop_answer;
00023 import ros.pkg.vision_msgs.msg.cop_descriptor;
00024 import ros.pkg.vision_srvs.srv.cop_call;
00025 import ros.pkg.vision_srvs.srv.srvjlo;
00026 import ros.pkg.vision_srvs.srv.srvjlo.Response;
00027 import ros.pkg.vision_srvs.srv.srvjlo.Request;
00028 import ros.pkg.vision_msgs.msg.partial_lo;
00029
00030 import java.util.concurrent.ExecutionException;
00031 import java.util.HashMap;
00032 import java.util.Hashtable;
00033 import java.util.Queue;
00034 import java.util.Vector;
00035 import java.lang.Exception;
00036 import java.util.concurrent.ConcurrentLinkedQueue;
00037 import java.lang.Runnable;
00038
00039 import jpl.Query;
00040
00041
00042
00043 public class CopROSClient {
00044
00045 static Boolean rosInitialized = false;
00046 static Ros ros;
00047 static NodeHandle n;
00048
00049
00050 static Subscriber.QueueingCallback<cop_answer> copObjectDetectionsCallback;
00051 static Subscriber.QueueingCallback<cop_answer> copModelDBCallback;
00052
00053 Thread listenToCopDB;
00054 Thread updateKnowRobModelDB;
00055 Thread listenToCopObjDetections;
00056 Thread updateKnowRobObjDetections;
00057
00065 public CopROSClient(String node_name) throws InterruptedException, RosException, ExecutionException {
00066
00067 initRos(node_name);
00068
00069 copObjectDetectionsCallback = new Subscriber.QueueingCallback<cop_answer>();
00070 copModelDBCallback = new Subscriber.QueueingCallback<cop_answer>();
00071
00072 }
00073
00074
00075 public void startCopModelDBListener(String cop_topic, String cop_service) {
00076
00077
00078 listenToCopDB = new Thread( new CopModelDBListenerThread(cop_topic, cop_service) );
00079 listenToCopDB.start();
00080 updateKnowRobModelDB = new Thread( new UpdateKnowRobModelDBThread() );
00081 updateKnowRobModelDB.start();
00082
00083 }
00084
00085 public void startCopObjDetectionsListener(String cop_topic) {
00086
00087
00088 listenToCopObjDetections = new Thread( new CopObjListenerThread(cop_topic) );
00089 listenToCopObjDetections.start();
00090 updateKnowRobObjDetections = new Thread( new UpdateKnowRobObjectsThread() );
00091 updateKnowRobObjDetections.start();
00092 }
00093
00094
00095
00096
00100 protected static void initRos(String node_name) {
00101
00102 ros = Ros.getInstance();
00103
00104 if(!Ros.getInstance().isInitialized()) {
00105 ros.init(node_name);
00106 }
00107 n = ros.createNodeHandle();
00108
00109 }
00110
00120 public static class CopObjListenerThread implements Runnable {
00121
00122 String topic;
00123
00124 public CopObjListenerThread() {
00125 this("/kipla/cop_reply");
00126 }
00127
00128 public CopObjListenerThread(String t) {
00129 topic=t;
00130 }
00131
00132 @Override public void run() {
00133
00134 try {
00135
00136 Subscriber<cop_answer> sub = n.subscribe(topic, new cop_answer(), copObjectDetectionsCallback, 10);
00137
00138 n.spin();
00139 sub.shutdown();
00140
00141 } catch(RosException e) {
00142 e.printStackTrace();
00143 }
00144 }
00145 }
00146
00154 public static class UpdateKnowRobObjectsThread implements Runnable {
00155
00156 @Override public void run() {
00157
00158 try {
00159
00160 cop_answer res;
00161 HashMap<String, Vector<Object>> solutions;
00162 while(true) {
00163
00164 res = copObjectDetectionsCallback.pop();
00165
00166 System.err.println("UpdateKnowRobObjectsThread: received data");
00167
00168
00169 for(aposteriori_position pose : res.found_poses) {
00170
00171 long p_id = pose.objectId;
00172
00173 long p_lo_id = pose.position;
00174 HashMap<String, String> m_types_classes = new HashMap<String, String>();
00175
00176
00177
00178 for(cop_descriptor model : pose.models) {
00179
00180
00181
00182 m_types_classes.put(model.type, copToKnowrob(model.sem_class));
00183
00184 }
00185
00186
00187 System.err.println("comp_cop:cop_create_perception_instance("+objectArrayToPlList(m_types_classes.keySet().toArray())+", Perception)");
00188 solutions = executeQuery("comp_cop:cop_create_perception_instance("+objectArrayToPlList(m_types_classes.keySet().toArray())+", Perception)");
00189 if(solutions.get("Perception").size()>1) {throw new Exception("ERROR: More than one Perception instance created.");}
00190 String perception = solutions.get("Perception").get(0).toString();
00191
00192
00193
00194 System.err.println("comp_cop:cop_create_object_instance("+objectArrayToPlList(m_types_classes.values().toArray())+", "+p_id+", Obj)");
00195 solutions = executeQuery("comp_cop:cop_create_object_instance("+objectArrayToPlList(m_types_classes.values().toArray())+", "+p_id+", Obj)");
00196 if(solutions.get("Obj").size()>1) {throw new Exception("ERROR: More than one Object instance created:"+objectArrayToPlList(solutions.get("Obj").toArray()));}
00197 String obj = solutions.get("Obj").get(0).toString();
00198
00199
00200
00201
00202 if(p_lo_id!=0) {
00203 synchronized(jpl.Query.class) {
00204 new Query("comp_cop:cop_set_loid("+perception+", "+p_lo_id+")").allSolutions();
00205 partial_lo lo_pose = loQuery("framequery", "", (int)p_lo_id, 1);
00206 new Query("comp_cop:cop_set_perception_pose("+perception+","+doubleArrayToPlList(lo_pose.pose)+")").allSolutions();
00207 new Query("comp_cop:cop_set_perception_cov("+ perception+","+doubleArrayToPlList(lo_pose.cov) +")").allSolutions();
00208 }
00209 }
00210
00211 synchronized(jpl.Query.class) {
00212
00213 new Query("comp_cop:cop_set_object_perception("+obj+", "+perception+")").allSolutions();
00214 }
00215 }
00216 n.spinOnce();
00217
00218 }
00219
00220 } catch(Exception e) {
00221 e.printStackTrace();
00222 }
00223 }
00224 }
00225
00226
00227
00237 public static class CopModelDBListenerThread implements Runnable {
00238
00239 String topic;
00240 String service;
00241
00242 public CopModelDBListenerThread() {
00243 this("/knowrob/cop_db", "/cop/in");
00244 }
00245
00246 public CopModelDBListenerThread(String t, String s) {
00247 topic=t;
00248 service=s;
00249 }
00250 @Override public void run() {
00251
00252 try {
00253
00254 Subscriber<cop_answer> sub = n.subscribe(topic, new cop_answer(), copModelDBCallback, 10);
00255
00256
00257 cop_call copcall = new cop_call();
00258 cop_call.Request cop_req = copcall.createRequest();
00259
00260 cop_req.outputtopic="/knowrob/cop_db";
00261 cop_req.action_type=25601;
00262 cop_req.number_of_objects=1;
00263
00264
00265
00266
00267
00268
00269
00270 cop_req.object_ids = new long[1];
00271 cop_req.object_ids[0] = 1;
00272
00273 ServiceClient<cop_call.Request, cop_call.Response, cop_call> cl = n.serviceClient(service, new cop_call());
00274 cl.call(cop_req);
00275
00276 n.spin();
00277 sub.shutdown();
00278
00279 } catch(RosException e) {
00280 e.printStackTrace();
00281 }
00282 }
00283 }
00284
00291 public static class UpdateKnowRobModelDBThread implements Runnable {
00292
00293 @Override public void run() {
00294
00295 try {
00296
00297 cop_answer res;
00298 while(true) {
00299
00300 res = copModelDBCallback.pop();
00301
00302 System.err.println("GOT RESULT IN KNOWROB UPDATE");
00303
00304
00305 for(aposteriori_position pose : res.found_poses) {
00306
00307
00308 for(cop_descriptor model : pose.models) {
00309
00310
00311 System.out.println("comp_cop:cop_create_model_instance('"+model.type+"', "+copToKnowrob(model.sem_class)+")");
00312 executeQuery("comp_cop:cop_create_model_instance('"+model.type+"', "+copToKnowrob(model.sem_class)+")");
00313
00314 }
00315
00316
00317 }
00318 n.spinOnce();
00319
00320 }
00321
00322 } catch(Exception e) {
00323 e.printStackTrace();
00324 }
00325 }
00326 }
00327
00328
00335 protected static String objectArrayToPlList(Object[] a) {
00336 String res="[";
00337 for(int i=0;i<a.length;i++) {
00338
00339 if(a[i].toString().startsWith("'"))
00340 res+=a[i].toString();
00341 else
00342 res+="'"+a[i].toString()+"'";
00343
00344 if(i<a.length-1)
00345 res+=",";
00346 }
00347 return res+="]";
00348 }
00349
00350 protected static String doubleArrayToPlList(double[] a) {
00351 String res="[";
00352 for(int i=0;i<a.length;i++) {
00353 res+="'"+a[i]+"'";
00354 if(i<a.length-1)
00355 res+=",";
00356 }
00357 return res+="]";
00358 }
00359
00360
00369 private static String copToKnowrob(String copIdentifier) {
00370
00371 HashMap<String, Vector<Object>> solutions =
00372 executeQuery("downcase_atom('"+copIdentifier+"', CopID),cop_to_knowrob(CopID, KnowRobID)");
00373
00374 if(solutions !=null) {
00375 Vector<Object> mappings = solutions.get("KnowRobID");
00376
00377 if(mappings!=null && mappings.size()>0) {
00378 return mappings.get(0).toString();
00379 }
00380 }
00381 return "";
00382 }
00383
00384
00397 public static partial_lo loQuery(String command, String objName, int objID, int refFrame) throws RosException {
00398
00399 ServiceClient<Request, Response, srvjlo> client = n.serviceClient("/located_object", new ros.pkg.vision_srvs.srv.srvjlo());
00400
00401 srvjlo srv = new srvjlo();
00402 Request rq = srv.createRequest();
00403
00404 rq.command=command;
00405
00406 if(command.equals("namequery")) {
00407 rq.query.name=objName;
00408 }
00409 else if(command.equals("framequery")) {
00410 rq.query.id=objID;
00411
00412 if(refFrame>0)
00413 rq.query.parent_id=refFrame;
00414 }
00415
00416 return client.call(rq).answer;
00417 }
00418
00425 public static HashMap<String, Vector<Object>> executeQuery(String query) {
00426
00427 HashMap<String, Vector<Object>> result = new HashMap< String, Vector<Object> >();
00428 Hashtable[] solutions;
00429
00430 synchronized(jpl.Query.class) {
00431
00432 Query q = new Query( "expand_goal(("+query+"),_9), call(_9)" );
00433
00434 if(!q.hasSolution())
00435 return new HashMap<String, Vector<Object>>();
00436
00437
00438 solutions = q.allSolutions();
00439 for (Object key: solutions[0].keySet()) {
00440 result.put(key.toString(), new Vector<Object>());
00441 }
00442
00443
00444 for (int i=0; i<solutions.length; i++) {
00445 Hashtable solution = solutions[i];
00446 for (Object key: solution.keySet()) {
00447 String keyStr = key.toString();
00448 if (!result.containsKey( keyStr )) {
00449
00450
00451 Vector<Object> resultVector = new Vector<Object>();
00452 resultVector.add( i, solution.get( key ).toString() );
00453 result.put(keyStr, resultVector);
00454
00455 }
00456
00457 Vector<Object> resultVector = result.get( keyStr );
00458 resultVector.add( i, solution.get( key ).toString() );
00459 }
00460 }
00461 }
00462
00463 return result;
00464 }
00465
00466
00467
00475 public static String[] copModelTypeSemClassForID(long id) {
00476
00477
00478 cop_call copcall = new cop_call();
00479 cop_call.Request cop_req = copcall.createRequest();
00480
00481 cop_req.outputtopic="/knowrob/cop_client";
00482 cop_req.action_type=25600;
00483 cop_req.number_of_objects=1;
00484
00485
00486
00487
00488
00489
00490
00491 cop_req.object_ids = new long[1];
00492 cop_req.object_ids[0] = id;
00493
00494 cop_answer r = copOneResult(cop_req, "/knowrob/cop_client");
00495
00496 String[] res = null;
00497 if(r!=null) {
00498 String modelType=""; String objClass="";
00499 for(aposteriori_position pose : r.found_poses) {
00500
00501
00502 if(pose.models.size() > 0) {
00503 modelType=pose.models.get(0).type;
00504 objClass=pose.models.get(0).sem_class;
00505 }
00506 }
00507 res = new String[2];
00508 res[0]=modelType;
00509 res[1]=objClass;
00510 }
00511 return res;
00512 }
00513
00514
00515
00522 public static cop_answer copOneResult(cop_call.Request cop_req, String output_topic) {
00523
00524 initRos("knowrob_cop_one_result");
00525
00526
00527 ServiceClient<cop_call.Request, cop_call.Response, cop_call> cl = n.serviceClient("/cop/in", new cop_call());
00528 cop_answer r=null;
00529
00530 try {
00531
00532
00533 Subscriber.QueueingCallback<cop_answer> cop_callback = new Subscriber.QueueingCallback<cop_answer>();
00534 Subscriber<cop_answer> sub = n.subscribe(output_topic, new cop_answer(), cop_callback, 10);
00535
00536
00537
00538 cop_callback.clear();
00539 ros.spinOnce();
00540
00541
00542 cl.call(cop_req);
00543 while (cop_callback.isEmpty()) {
00544 ros.spinOnce();
00545 }
00546
00547
00548 r = cop_callback.pop();
00549 sub.shutdown();
00550
00551 } catch (RosException e) {
00552 ros.logError("CopROSClient: Call to service /cop/in failed");
00553 } catch (InterruptedException e) {
00554 e.printStackTrace();
00555 }
00556
00557 cl.shutdown();
00558 return r;
00559 }
00560
00561
00562 }