00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ros/ros.h"
00021 #include "std_msgs/String.h"
00022 #include "SWI-cpp.h"
00023 #include <sys/stat.h>
00024 #include <boost/thread/condition.hpp>
00025 #include <termios.h>
00026 #include <unistd.h>
00027 #include <ros/package.h>
00028 #include "tinyxml.h"
00029 #include <fstream>
00030 #include "retalis/AddOutputSubscription.h"
00031 #include "retalis/AddMemory.h"
00032 #include "retalis/DeleteOutputSubscription.h"
00033 #include "retalis/DeleteMemory.h"
00034
00035 #include "tf/tfMessage.h"
00036 #include "ar_pose/ARMarkers.h"
00038 #include <string>
00039 #include <sstream>
00040
00041 #define SSTR( x ) dynamic_cast< std::ostringstream & >( \
00042 ( std::ostringstream() << std::dec << x ) ).str()
00043
00044
00045 bool subscribe_tf_and_ar_pose_ = true;
00046
00047 using namespace std;
00048 const string pkgPath = ros::package::getPath("retalis");
00049 const string etalisSource = "consult('"+pkgPath+"/prolog_source/etalis.P"+"')";
00050 const string retalisSource = "consult('"+pkgPath+"/prolog_source/retalis.P"+"')";
00051
00052 class Retalis
00053 {
00054 public:
00055 Retalis(char **argv):
00056 swipl_(argv[0])
00057 {
00058 try
00059 {
00060 PlCall("use_foreign_library(foreign(retalis_output_interface))");
00061 PlCall("retalis_output_initialize(1)");
00062 PlCall(etalisSource.c_str());
00063 PlCall(retalisSource.c_str());
00064 string goalPredicatesFilePath = pkgPath+"/application_source/goalPredicates.txt";
00065 std::ifstream goalPredicatesFile(goalPredicatesFilePath.c_str());
00066 for( string line; getline( goalPredicatesFile, line ); )
00067 {
00068 if(!line.empty())
00069 {
00070 PlCall(line.c_str());
00071
00072 }
00073 }
00074 }
00075 catch ( PlException &ex )
00076 {
00077 std::cerr << (char *) ex << std::endl;
00078 }
00079
00080 inputEventsSub_ = nh_.subscribe("retalisInputEvents", 5000, &Retalis::inputEventsCB,this);
00081 subscribeToTopics_ = nh_.advertiseService("add_output_subscription", &Retalis::subscribeSrv,this);
00082 memorizeEvents_ = nh_.advertiseService("add_memory", &Retalis::memorizeSrv,this);
00083 unSubscribeToTopics_ = nh_.advertiseService("delete_output_subscription", &Retalis::unSubscribeSrv,this);
00084 unMemorizeEvents_ = nh_.advertiseService("delete_memory", &Retalis::unMemorizeSrv,this);
00085
00086
00087
00088 if(subscribe_tf_and_ar_pose_)
00089 {
00090 inputTFSub_ = nh_.subscribe("tf", 500, &Retalis::inputTFCB,this);
00091 inputARPoseSub_ = nh_.subscribe("ar_pose_marker",100,&Retalis::inputMarkersCB,this);
00092 }
00093
00095
00096 }
00097
00098 ~Retalis(void){
00099 }
00100
00101 bool subscribeSrv(retalis::AddOutputSubscription::Request &req, retalis::AddOutputSubscription::Response &res)
00102 {
00103 string conditions = "["+req.conditions+"]";
00104 string query = "subscribe("+req.event +", "+ conditions +", "+ req.format +", "+ req.topic+", "+req.id+")";
00105 mutex_.lock();
00106 try
00107 {
00108 PlCall(query.c_str());
00109 }
00110 catch ( PlException &ex )
00111 {
00112 std::cerr << (char *) ex << std::endl;
00113 }
00114 mutex_.unlock();
00115 res.result = "ok";
00116 return true;
00117 }
00118 bool memorizeSrv(retalis::AddMemory::Request &req, retalis::AddMemory::Response &res)
00119 {
00120 string conditions = "["+req.conditions+"]";
00121 string query = "memorize("+req.event +", "+ conditions +", "+ req.format +", "+ req.id+", "+SSTR(req.size)+")";
00122 mutex_.lock();
00123 try
00124 {
00125 PlCall(query.c_str());
00126 }
00127 catch ( PlException &ex )
00128 {
00129 std::cerr << (char *) ex << std::endl;
00130 }
00131 mutex_.unlock();
00132 res.result = "ok";
00133 return true;
00134 }
00135
00136 bool unSubscribeSrv(retalis::DeleteOutputSubscription::Request &req, retalis::DeleteOutputSubscription::Response &res)
00137 {
00138
00139 string query = "delete_subscription("+req.topic+req.id+")";
00140 mutex_.lock();
00141 try
00142 {
00143 PlCall(query.c_str());
00144 }
00145 catch ( PlException &ex )
00146 {
00147 std::cerr << (char *) ex << std::endl;
00148 }
00149 mutex_.unlock();
00150 res.result = "ok";
00151 return true;
00152 }
00153 bool unMemorizeSrv(retalis::DeleteMemory::Request &req, retalis::DeleteMemory::Response &res)
00154 {
00155
00156 string query = "delete_memory("+ req.id+")";
00157 mutex_.lock();
00158 try
00159 {
00160 PlCall(query.c_str());
00161 }
00162 catch ( PlException &ex )
00163 {
00164 std::cerr << (char *) ex << std::endl;
00165 }
00166 mutex_.unlock();
00167 res.result = "ok";
00168 return true;
00169 }
00170 void inputEventsCB(const std_msgs::String::ConstPtr& event)
00171 { PlFrame fr;
00172 mutex_.lock();
00173 try
00174 {
00175 PlCall(event->data.c_str());
00176 }
00177 catch ( PlException &ex )
00178 {
00179 std::cerr << (char *) ex << std::endl;
00180 }
00181 mutex_.unlock();
00182
00183 }
00184
00185
00186 void inputTFCB(const tf::tfMessage::ConstPtr& msg)
00187 {
00188 PlFrame fr;
00189 PlTermv transforms(1);
00190 PlTail transformsA(transforms[0]);
00191
00192 std::vector<geometry_msgs::TransformStamped>::const_iterator iter;
00193 for (iter = msg->transforms.begin(); iter != msg->transforms.end(); iter++)
00194 {
00195 PlTermv trans(3);
00196
00197 PlTermv header(3);
00198 header[0] = PlTerm((long) (*iter).header.seq);
00199 PlTermv time(1);
00200 PlTail timeA(time[0]);
00201 timeA.append((long)(*iter).header.stamp.sec);
00202 timeA.append((long)(*iter).header.stamp.nsec);
00203 timeA.close();
00204 header[1] = time[0];
00205 string frameIDRetalis = "\""+(*iter).header.frame_id+"\"";
00206 header[2] = PlTerm(frameIDRetalis.c_str());
00207
00208 PlCompound head("std_msgs__0__Header",header);
00209 trans[0] = head;
00210
00211 string childframeIDRetalis = "\""+(*iter).child_frame_id+"\"";
00212 trans[1] = PlTerm(childframeIDRetalis.c_str());
00213
00214 PlTermv vector(3);
00215 vector[0] = PlTerm( (double)(*iter).transform.translation.x);
00216 vector[1] = PlTerm( (double)(*iter).transform.translation.y);
00217 vector[2] = PlTerm( (double)(*iter).transform.translation.z);
00218 PlCompound vec("geometry_msgs__0__Vector3",vector);
00219 PlTermv quaternion(4);
00220 quaternion[0] = PlTerm( (double)(*iter).transform.rotation.x);
00221 quaternion[1] = PlTerm( (double)(*iter).transform.rotation.y);
00222 quaternion[2] = PlTerm( (double)(*iter).transform.rotation.z);
00223 quaternion[3] = PlTerm( (double)(*iter).transform.rotation.w);
00224 PlCompound quat("geometry_msgs__0__Quaternion",quaternion);
00225 PlTermv vq(2);
00226 vq[0] = vec;
00227 vq[1] = quat;
00228 PlCompound vecquat("geometry_msgs__0__Transform",vq);
00229 trans[2] = vecquat;
00230
00231 PlCompound transform("geometry_msgs__0__TransformStamped",trans);
00232 transformsA.append(transform);
00233 }
00234 transformsA.close();
00235 PlCompound tf("tf__0__tfMessage",transforms);
00236
00237 mutex_.lock();
00238 try
00239 {
00240 PlCall("event", tf);
00241 }
00242 catch ( PlException &ex )
00243 {
00244 std::cerr << (char *) ex << std::endl;
00245 }
00246 mutex_.unlock();
00247 }
00248
00249
00250
00251 void inputMarkersCB(const ar_pose::ARMarkers::ConstPtr& msg)
00252 {
00253 PlFrame fr;
00254 PlTermv markers(1);
00255 PlTail markersA(markers[0]);
00256
00257 std::vector<ar_pose::ARMarker>::const_iterator iter;
00258 for (iter = msg->markers.begin(); iter != msg->markers.end(); iter++)
00259 {
00260 PlTermv marker(4);
00261
00262 PlTermv header(3);
00263 header[0] = PlTerm((long) (*iter).header.seq);
00264 PlTermv time(1);
00265 PlTail timeA(time[0]);
00266 timeA.append((long)(*iter).header.stamp.sec);
00267 timeA.append((long)(*iter).header.stamp.nsec);
00268 timeA.close();
00269 header[1] = time[0];
00270 string frameIDRetalis = "\""+(*iter).header.frame_id+"\"";
00271 header[2] = PlTerm(frameIDRetalis.c_str());
00272 PlCompound head("std_msgs__0__Header",header);
00273 marker[0] = head;
00274
00275 marker[1] = PlTerm((long) (*iter).id);
00276
00277 PlTermv vector(3);
00278 vector[0] = PlTerm( (double)(*iter).pose.pose.position.x);
00279 vector[1] = PlTerm( (double)(*iter).pose.pose.position.y);
00280 vector[2] = PlTerm( (double)(*iter).pose.pose.position.z);
00281 PlCompound vec("geometry_msgs__0__Point",vector);
00282 PlTermv quaternion(4);
00283 quaternion[0] = PlTerm( (double)(*iter).pose.pose.orientation.x);
00284 quaternion[1] = PlTerm( (double)(*iter).pose.pose.orientation.y);
00285 quaternion[2] = PlTerm( (double)(*iter).pose.pose.orientation.z);
00286 quaternion[3] = PlTerm( (double)(*iter).pose.pose.orientation.w);
00287 PlCompound quat("geometry_msgs__0__Quaternion",quaternion);
00288 PlTermv vq(2);
00289 vq[0] = vec;
00290 vq[1] = quat;
00291 PlCompound vecquat("geometry_msgs__0__Pose",vq);
00292
00293 PlTermv cov(1);
00294 PlTail covA(cov[0]);
00295 for (int i =0; i<36; i++)
00296 {
00297 covA.append((double)(*iter).pose.covariance[i]);
00298
00299 }
00300 covA.close();
00301 PlTermv pos(2);
00302 pos[0] = vecquat;
00303 pos[1] = cov[0];
00304 PlCompound posWithCov("geometry_msgs__0__PoseWithCovariance",pos);
00305 marker[2] = posWithCov;
00306
00307
00308 marker[3] = PlTerm((long) (*iter).confidence);
00309
00310 PlCompound finalMarker("ar_pose__0__ARMarker",marker);
00311 markersA.append(finalMarker);
00312 }
00313 markersA.close();
00314
00315
00316 PlTermv headerTop(3);
00317 headerTop[0] = PlTerm((long) msg->header.seq);
00318 PlTermv timeTop(1);
00319 PlTail timeTopA(timeTop[0]);
00320 timeTopA.append((long)msg->header.stamp.sec);
00321 timeTopA.append((long)msg->header.stamp.nsec);
00322 timeTopA.close();
00323 headerTop[1] = timeTop[0];
00324 string frameIDRetalisTop = "\""+msg->header.frame_id+"\"";
00325 headerTop[2] = PlTerm(frameIDRetalisTop.c_str());
00326 PlCompound headTop("std_msgs__0__Header",headerTop);
00327
00328 PlTermv markerMsg(2);
00329 markerMsg[0] = headTop;
00330 markerMsg[1] = markers[0];
00331 PlCompound markerMsgFinal("ar_pose__0__ARMarkers",markerMsg);
00332
00333 PlTermv event(3);
00334 event[0] = markerMsgFinal;
00335 event[1] = PlTerm( (long)msg->header.stamp.sec);
00336 event[2] = PlTerm( (long)msg->header.stamp.nsec);
00337 mutex_.lock();
00338 try
00339 {
00340 PlCall("new_event", event);
00341 }
00342 catch ( PlException &ex )
00343 {
00344 std::cerr << (char *) ex << std::endl;
00345 }
00346 mutex_.unlock();
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00372
00373
00374 protected:
00375 ros::NodeHandle nh_;
00376 PlEngine swipl_;
00377 ros::Subscriber inputEventsSub_;
00378 boost::mutex mutex_;
00379 ros::ServiceServer subscribeToTopics_;
00380 ros::ServiceServer memorizeEvents_;
00381 ros::ServiceServer unSubscribeToTopics_;
00382 ros::ServiceServer unMemorizeEvents_;
00383
00384 ros::Subscriber inputTFSub_;
00385 ros::Subscriber inputARPoseSub_;
00386
00388
00389 };
00390
00391
00392
00393
00394 int main(int argc, char **argv)
00395 {
00396
00397 ros::init(argc, argv, "retalis");
00398 Retalis retalis(argv);
00399 ros::spin();
00400 return 0;
00401 }
00402
00403