CopROSClient.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2010 by Moritz Tenorth
00003  * 
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 3 of the License, or
00007  * (at your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
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                 // create threads listening to /knowrob/cop_db to update the CoP database content
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                 // create threads listening to /kipla/cop_reply to receive object detections
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                                 // iterate over detected poses
00169                                 for(aposteriori_position pose : res.found_poses) {
00170                                         
00171                                         long   p_id    = pose.objectId;
00172                                         //double p_prob  = pose.probability;
00173                                         long   p_lo_id = pose.position;
00174                                         HashMap<String, String> m_types_classes = new HashMap<String, String>();
00175                                         
00176                                         
00177                                         // iterate over models used for detecting these poses
00178                                         for(cop_descriptor model : pose.models) {
00179                                                 
00180                                                 //long   m_id    = model.object_id;
00181                                                 //double m_qual  = model.quality;
00182                                                 m_types_classes.put(model.type, copToKnowrob(model.sem_class));                                         
00183                                                 
00184                                         }
00185 
00186                                         // create VisualPerception instance
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                                         // create object information
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                                         // read pose from loID, assert it (remember lo-ID)
00201 //                              System.out.println();
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                                                         // link VisualPerception instance to the object instance
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                         // call cop to get the cop_descriptor model
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 // not required any more with new rosjava: auto-initialized
00265 //                      cop_req.list_of_poses=new apriori_position[1];
00266 //                      cop_req.list_of_poses[0] = new apriori_position();
00267 //                      cop_req.list_of_poses[0].positionId=1;
00268 //                      cop_req.list_of_poses[0].probability=1.0;
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                                 // iterate over objects
00305                                 for(aposteriori_position pose : res.found_poses) {
00306                                         
00307                                         // iterate over model associated to these objects
00308                                         for(cop_descriptor model : pose.models) {
00309 
00310                                                 // create VisualPerception instance
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                         // Build the result
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                                                 // previously unknown column, add result vector
00451                                                 Vector<Object> resultVector = new Vector<Object>(); 
00452                                                 resultVector.add( i, solution.get( key ).toString() );
00453                                                 result.put(keyStr, resultVector);
00454         
00455                                         }
00456                                         // Put the solution into the correct vector
00457                                         Vector<Object> resultVector = result.get( keyStr );
00458                                         resultVector.add( i, solution.get( key ).toString() );
00459                                 }
00460                         }
00461                 }
00462                 // Generate the final QueryResult and return
00463                 return result;
00464         }
00465         
00466 
00467     
00475     public static String[] copModelTypeSemClassForID(long id) {
00476         
00477                 // call cop to get the cop_descriptor model
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 // not required any more with new rosjava: auto-initialized
00486 //              cop_req.list_of_poses=new apriori_position[1];
00487 //              cop_req.list_of_poses[0] = new apriori_position();
00488 //              cop_req.list_of_poses[0].positionId=1;
00489 //              cop_req.list_of_poses[0].probability=1.0;
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                                 // use first entry as model class
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                 // call the cop service and subscribe to the answer topic
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                         // create a queuing callback that is used for listening on the answer topic
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                         // make sure the queue is empty and wait one iteration to have everything setup up 
00538                         cop_callback.clear();
00539                         ros.spinOnce();
00540                         
00541                         // call CoP and wait until a result is received
00542                         cl.call(cop_req);                       
00543                         while (cop_callback.isEmpty()) {
00544                                 ros.spinOnce();
00545                         }
00546 
00547                         // just read the first result returned on the output_topic
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 }


comp_cop
Author(s): Moritz Tenorth
autogenerated on Sat Dec 28 2013 17:10:07