checkerboard_detector2.cpp
Go to the documentation of this file.
00001 // Software License Agreement (BSD License)
00002 // Copyright (c) 2008, Willow Garage, Inc.
00003 // Redistribution and use in source and binary forms, with or without
00004 // modification, are permitted provided that the following conditions are met:
00005 //   * Redistributions of source code must retain the above copyright notice,
00006 //     this list of conditions and the following disclaimer.
00007 //   * Redistributions in binary form must reproduce the above copyright
00008 //     notice, this list of conditions and the following disclaimer in the
00009 //     documentation and/or other materials provided with the distribution.
00010 //   * The name of the author may not be used to endorse or promote products
00011 //     derived from this software without specific prior written permission.
00012 //
00013 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00014 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00015 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00016 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00017 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00018 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00019 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00020 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00021 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00022 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00023 // POSSIBILITY OF SUCH DAMAGE.
00024 //
00025 // author: Rosen Diankov
00026 #include <cstdio>
00027 #include <vector>
00028 #include <sstream>
00029 #include <ros/ros.h>
00030 
00031 #include <boost/thread/mutex.hpp>
00032 #include <boost/format.hpp>
00033 #include "opencv/cv.h"
00034 #include "opencv/highgui.h"
00035 #include "cv_bridge/CvBridge.h"
00036 #include "sensor_msgs/CameraInfo.h"
00037 #include "sensor_msgs/Image.h"
00038 #include "geometry_msgs/PoseStamped.h"
00039 #include "geometry_msgs/PoseArray.h"
00040 #include "checkerboard_detector2/ObjectDetection.h"
00041 #include "checkerboard_detector2/Detect.h"
00042 #include "checkerboard_detector2/Set.h"
00043 #include "math.h"
00044 #include <image_transport/image_transport.h>
00045 #include <tf/transform_broadcaster.h>
00046 
00047 #include <sys/timeb.h>    // ftime(), struct timeb
00048 #include <sys/time.h>
00049 
00050 #define sqr(a) ((a)*(a))
00051 
00052 using namespace std;
00053 using namespace ros;
00054 using namespace boost;
00055 
00056 class CheckerboardDetector
00057 {
00058     template <typename T>
00059     static vector<T> tokenizevector(const string& s)
00060     {
00061         stringstream ss(s);
00062         return vector<T>((istream_iterator<T>(ss)), istream_iterator<T>());
00063     }
00064 
00065 public:
00066     struct CHECKERBOARD
00067     {
00068         CvSize griddims; 
00069         vector<Vector> grid3d;
00070         vector<CvPoint2D32f> corners;
00071         TransformMatrix tlocaltrans;
00072         TransformMatrix previous_pose;
00073         double cellwidth;
00074         double cellheight;
00075     };
00076 
00077     checkerboard_detector2::ObjectDetection _objdetmsg;
00078     sensor_msgs::CvBridge _cvbridge;
00079     sensor_msgs::CameraInfo _camInfoMsg;
00080 
00081     ros::Subscriber camInfoSubscriber;
00082     image_transport::Subscriber  imageSubscriber;
00083 //    ros::Publisher _pubDetection;
00084     ros::Publisher _pubPoseArray;
00085     std::vector<ros::Publisher> _pubPose;
00086 
00087     ros::ServiceServer service_;
00088 
00089     string frame_id; // tf frame id
00090 
00091     int display, verbose;
00092     vector<CHECKERBOARD> vcheckers; // grid points for every checkerboard
00093     vector< string > vstrtypes; // type names for every grid point
00094     map<string,int> maptypes;
00095     ros::Time lasttime;
00096     CvMat *intrinsic_matrix; // intrinsic matrices
00097     boost::mutex mutexcalib;
00098     IplImage* frame;
00099 
00100     ros::NodeHandle _node_private;
00101     ros::NodeHandle _node_pub;
00102 
00103     bool _active;
00104     tf::TransformBroadcaster br_;
00105 
00107     // Constructor
00108     CheckerboardDetector() : intrinsic_matrix(NULL), frame(NULL), _node_private("~"), _active(true)
00109     {
00110         _node_private.param("display", display, 0);
00111         _node_private.param("verbose", verbose, 1);
00112         _node_private.param("start_active", _active, _active);
00113         
00114         char str[32];
00115         int index = 0;
00116 
00117         while(1) {
00118             int dimx, dimy;
00119             double fRectSize[2];
00120             string type;
00121 
00122             sprintf(str,"grid%d_size_x",index);
00123             if( !_node_private.getParam(str,dimx) )
00124                 break;
00125             if (dimx < 3) {
00126                 ROS_ERROR("Param: %s must be greater than 2",str);
00127                 return;
00128             }
00129 
00130             sprintf(str,"grid%d_size_y",index);
00131             if( !_node_private.getParam(str,dimy) )
00132                 break;
00133             if (dimy < 3) {
00134                 ROS_ERROR("Param: %s must be greater than 2",str);
00135                 return;
00136             }
00137 
00138             sprintf(str,"rect%d_size_x",index);
00139             if( !_node_private.getParam(str,fRectSize[0]) )
00140                 break;
00141 
00142             sprintf(str,"rect%d_size_y",index);
00143             if( !_node_private.getParam(str,fRectSize[1]) )
00144                 break;
00145 
00146             sprintf(str,"type%d",index);
00147             if( !_node_private.getParam(str,type) ) {
00148                 sprintf(str,"checker%dx%d", dimx, dimy);
00149                 type = str;
00150             }
00151 
00152             string strtranslation,strrotation;
00153             sprintf(str,"translation%d",index);
00154             _node_private.param(str,strtranslation,string());
00155 
00156             vector<float> vtranslation = tokenizevector<float>(strtranslation);
00157             sprintf(str,"rotation%d",index);
00158             _node_private.param(str,strrotation,string());
00159 
00160             vector<float> vrotation = tokenizevector<float>(strrotation);
00161 
00162             CHECKERBOARD cb;
00163             cb.griddims = cvSize(dimx,dimy);
00164             cb.cellwidth = fRectSize[0];
00165             cb.cellheight = fRectSize[0];
00166 
00167             cb.grid3d.resize(dimx*dimy);
00168             int j=0;
00169             for(int y=0; y<dimy; ++y)
00170                 for(int x=0; x<dimx; ++x)
00171                     cb.grid3d[j++] = Vector(x*fRectSize[0], y*fRectSize[1], 0);
00172 
00173             if( vtranslation.size() == 3 )
00174                 cb.tlocaltrans.trans = 
00175                     Vector(vtranslation[0],vtranslation[1],vtranslation[2]);
00176 
00177             if( vrotation.size() == 9 )  {
00178                 for(int k = 0; k < 3; ++k) {
00179                     cb.tlocaltrans.m[4*k+0] = vrotation[3*k+0];
00180                     cb.tlocaltrans.m[4*k+1] = vrotation[3*k+1];
00181                     cb.tlocaltrans.m[4*k+2] = vrotation[3*k+2];
00182                 }
00183             }
00184 
00185             vcheckers.push_back(cb);
00186             vstrtypes.push_back(type);
00187             maptypes[vstrtypes.back()] = index;
00188             index++;
00189         }
00190 
00191         _node_private.param("frame_id", frame_id,string(""));
00192 
00193         if( maptypes.size() == 0 ) {
00194             ROS_ERROR("no checkerboards to detect");
00195             return;
00196         }
00197 
00198         if( display ) {
00199             cvNamedWindow("Checkerboard Detector", CV_WINDOW_AUTOSIZE);
00200             cvStartWindowThread();
00201         }
00202 
00203         lasttime = ros::Time::now();
00204 //        _pubDetection = _node_pub.advertise<checkerboard_detector2::ObjectDetection>("ObjectDetection",1);
00205         _pubPoseArray = _node_pub.advertise<geometry_msgs::PoseArray>("pose_array",1);
00206 
00207         cout <<"vcheckers.size()=="<<vcheckers.size()<<endl;
00208         for(size_t i=0;i<vcheckers.size();i++) {
00209                 _pubPose.push_back( _node_pub.advertise<geometry_msgs::PoseStamped>( boost::str(format("pose%d")%i),1) );
00210         }
00211 
00212 
00213         service_ =_node_pub.advertiseService("set_detect_checkerboard", &CheckerboardDetector::serviceCallback, this);
00214         if(_active) this->activate(true);
00215     }
00216 
00218     // Destructor
00219     virtual ~CheckerboardDetector()
00220     {
00221         if( frame )
00222             cvReleaseImage(&frame);
00223         if( this->intrinsic_matrix )
00224             cvReleaseMat(&this->intrinsic_matrix);
00225         this->camInfoSubscriber.shutdown();
00226         this->imageSubscriber.shutdown();
00227     }
00228 
00230     // Camera info callback
00231     void caminfo_cb(const sensor_msgs::CameraInfoConstPtr &msg)
00232     {
00233         boost::mutex::scoped_lock lock(this->mutexcalib);
00234 
00235         this->_camInfoMsg = *msg;
00236 
00237         // only get the camera info once <- this is dumb
00238         //this->camInfoSubscriber.shutdown();
00239         //this->camInfoSubscriber2.shutdown();
00240     }
00241 
00242 
00244     // Image data callback
00245     void image_cb(const sensor_msgs::ImageConstPtr &msg)
00246     {
00247         boost::mutex::scoped_lock lock(this->mutexcalib);
00248         if( Detect(_objdetmsg,*msg,this->_camInfoMsg) ) {
00249                 _objdetmsg.header = msg->header;
00250 //            _pubDetection.publish(_objdetmsg);
00251             geometry_msgs::PoseArray array;
00252             array.header = _objdetmsg.header;
00253             array.poses.resize(vcheckers.size());
00254             for(size_t i=0;i<_objdetmsg.objects.size();i++) {
00255                 array.poses[_objdetmsg.objects[i].id] = _objdetmsg.objects[i].pose;
00256             }
00257             _pubPoseArray.publish(array);
00258             vector<tf::StampedTransform> transforms;
00259             for(size_t i=0;i<_objdetmsg.objects.size();i++) {
00260                 geometry_msgs::PoseStamped pose;
00261                 pose.header = _objdetmsg.header;
00262                 pose.pose = _objdetmsg.objects[i].pose;
00263                 _pubPose[_objdetmsg.objects[i].id].publish( pose );
00264 
00265               tf::Stamped<tf::Transform> trnsfm;
00266               poseStampedMsgToTF (pose, trnsfm);
00267               char cb_frame_id[100];
00268               sprintf(cb_frame_id, "/checkerboard_%lu", i);
00269 
00270               transforms.push_back(tf::StampedTransform(trnsfm, trnsfm.stamp_, trnsfm.frame_id_, cb_frame_id));
00271             }
00272             br_.sendTransform(transforms);
00273         }
00274     }
00275 
00276     bool detect_cb(checkerboard_detector2::Detect::Request& req, checkerboard_detector2::Detect::Response& res)
00277     {
00278         if(!_active)
00279           return true;
00280         else 
00281           return Detect(res.object_detection,req.image,req.camera_info);
00282     }
00283 
00284     bool Detect(checkerboard_detector2::ObjectDetection& objdetmsg, const sensor_msgs::Image& imagemsg, const sensor_msgs::CameraInfo& camInfoMsg)
00285     {
00286         if( this->intrinsic_matrix == NULL )
00287             this->intrinsic_matrix = cvCreateMat(3,3,CV_32FC1);
00288 
00289         for(int i = 0; i < 3; ++i)
00290             for(int j = 0; j < 3; ++j)
00291                 this->intrinsic_matrix->data.fl[3*i+j] = camInfoMsg.P[4*i+j];
00292 
00293         if( !_cvbridge.fromImage(imagemsg, "mono8") ) {
00294             ROS_ERROR("failed to get image");
00295             return false;
00296         }
00297 
00298         IplImage *pimggray = _cvbridge.toIpl();
00299         if( display ) {
00300             // copy the raw image
00301             if( frame != NULL && (frame->width != (int)imagemsg.width || frame->height != (int)imagemsg.height) ) {
00302                 cvReleaseImage(&frame);
00303                 frame = NULL;
00304             }
00305 
00306             if( frame == NULL ) 
00307                 frame = cvCreateImage(cvSize(imagemsg.width,imagemsg.height),IPL_DEPTH_8U, 3);
00308 
00309             cvCvtColor(pimggray,frame,CV_GRAY2RGB);
00310         }
00311 
00312         vector<checkerboard_detector2::Object6DPose> vobjects;
00313 
00314 //#pragma omp parallel for schedule(dynamic,1)
00315         for(int i = 0; i < (int)vcheckers.size(); ++i) {
00316             CHECKERBOARD& cb = vcheckers[i];
00317             int ncorners;
00318             checkerboard_detector2::Object6DPose objpose;
00319 
00320             // do until no more checkerboards detected
00321             while(1) {
00322                 cb.corners.resize(200);
00323                 int allfound = cvFindChessboardCorners( pimggray, cb.griddims, &cb.corners[0], &ncorners,
00324                                                         CV_CALIB_CB_ADAPTIVE_THRESH );
00325                 cb.corners.resize(ncorners);
00326 
00327                 //cvDrawChessboardCorners(pimgGray, itbox->second.griddims, &corners[0], ncorners, allfound);
00328                 //cvSaveImage("temp.jpg", pimgGray);
00329 
00330                 if(!allfound || ncorners != (int)cb.grid3d.size())
00331                     break;
00332 
00333                 // remove any corners that are close to the border
00334                 const int borderthresh = 30;
00335         
00336                 for(int j = 0; j < ncorners; ++j) {
00337                     int x = cb.corners[j].x;
00338                     int y = cb.corners[j].y;
00339                     if( x < borderthresh || x > pimggray->width-borderthresh ||
00340                         y < borderthresh || y > pimggray->height-borderthresh ) 
00341                     {
00342                         allfound = 0;
00343                         break;
00344                     }
00345                 }
00346 
00347                 // mark out the image
00348                 CvPoint upperleft, lowerright;
00349                 upperleft.x = lowerright.x = cb.corners[0].x; 
00350                 upperleft.y = lowerright.y = cb.corners[0].y; 
00351                 for(int j = 1; j < (int)cb.corners.size(); ++j) {
00352                     if( upperleft.x > cb.corners[j].x ) upperleft.x = cb.corners[j].x;
00353                     if( upperleft.y > cb.corners[j].y ) upperleft.y = cb.corners[j].y;
00354                     if( lowerright.x < cb.corners[j].x ) lowerright.x = cb.corners[j].x;
00355                     if( lowerright.y < cb.corners[j].y ) lowerright.y = cb.corners[j].y;
00356                 }
00357 
00358                 if( allfound ) {
00359                     cvFindCornerSubPix(pimggray, &cb.corners[0], cb.corners.size(), cvSize(5,5),cvSize(-1,-1),
00360                                        cvTermCriteria(CV_TERMCRIT_ITER,20,1e-2));
00361                     CHECKERBOARD cb_copy = cb;
00362                     objpose.pose = FindTransformation(cb.corners, cb.grid3d, cb.tlocaltrans,cb_copy);
00363 
00364                     // now check for proximity of other previously markers, outliers are bad for tracking
00365                         double mindist2 =  sqr(cb.cellwidth*cb.griddims.width) + sqr(cb.cellheight*cb.griddims.height);
00366                     for(int j = 0; j < (int)vcheckers.size(); ++j) {
00367                         if(j != i) {
00368                                 double dist2 = sqr(objpose.pose.position.x - vcheckers[j].previous_pose.trans.x) +
00369                                                           sqr(objpose.pose.position.y - vcheckers[j].previous_pose.trans.y) +
00370                                                           sqr(objpose.pose.position.z - vcheckers[j].previous_pose.trans.z);
00371                                 if(dist2 < mindist2) {
00372                                         cout << "skipping marker, because "<<dist2<<" < "<<mindist2<<endl;
00373                                         allfound = false; // ignore this detection, too close to another previously seen marker
00374                                 }
00375                         }
00376                     }
00377                     if(allfound) {
00378                         cb = cb_copy;
00379                     }
00380                 }
00381 
00382 //#pragma omp critical
00383                 {
00384                     if( allfound ) {
00385                         vobjects.push_back(objpose);
00386                         vobjects.back().type = vstrtypes[i];
00387                         vobjects.back().id = i;
00388                     }
00389 
00390                     cvRectangle(pimggray, upperleft, lowerright, CV_RGB(0,0,0),CV_FILLED);
00391                 }
00392             }
00393 
00394             //cvSaveImage("temp.jpg", pimggray);
00395         }
00396 
00397         objdetmsg.objects = vobjects;
00398         objdetmsg.header.stamp = imagemsg.header.stamp;
00399         if( frame_id.size() > 0 )
00400             objdetmsg.header.frame_id = frame_id;
00401         else
00402             objdetmsg.header.frame_id = imagemsg.header.frame_id;
00403 
00404         if( verbose > 0 )
00405             ROS_INFO("checkerboard: image: %ux%u (size=%u), num: %u, total: %.3fs",imagemsg.width,imagemsg.height,
00406                      (unsigned int)imagemsg.data.size(), (unsigned int)objdetmsg.objects.size(),
00407                      (float)(ros::Time::now()-lasttime).toSec());
00408         lasttime = ros::Time::now();
00409 
00410         if( display ) {
00411             // draw each found checkerboard
00412             for(size_t i = 0; i < vobjects.size(); ++i) {
00413                 int itype = maptypes[vobjects[i].type];
00414                 CHECKERBOARD& cb = vcheckers[itype];
00415                 Transform tglobal;
00416                 tglobal.trans = Vector(vobjects[i].pose.position.x,vobjects[i].pose.position.y,vobjects[i].pose.position.z);
00417                 tglobal.rot = Vector(vobjects[i].pose.orientation.w,vobjects[i].pose.orientation.x,vobjects[i].pose.orientation.y, vobjects[i].pose.orientation.z);
00418                 Transform tlocal = tglobal * cb.tlocaltrans.inverse();
00419 
00420                 CvPoint X[4];
00421 
00422                 Vector vaxes[4];
00423                 vaxes[0] = Vector(0,0,0);
00424                 vaxes[1] = Vector(0.05f,0,0);
00425                 vaxes[2] = Vector(0,0.05f,0);
00426                 vaxes[3] = Vector(0,0,0.05f);
00427 
00428                 for(int i = 0; i < 4; ++i) {
00429                     Vector p = tglobal*vaxes[i];
00430                     dReal fx = p.x*camInfoMsg.P[0] + p.y*camInfoMsg.P[1] + p.z*camInfoMsg.P[2] + camInfoMsg.P[3];
00431                     dReal fy = p.x*camInfoMsg.P[4] + p.y*camInfoMsg.P[5] + p.z*camInfoMsg.P[6] + camInfoMsg.P[7];
00432                     dReal fz = p.x*camInfoMsg.P[8] + p.y*camInfoMsg.P[9] + p.z*camInfoMsg.P[10] + camInfoMsg.P[11];
00433                     X[i].x = (int)(fx/fz);
00434                     X[i].y = (int)(fy/fz);
00435                 }
00436 
00437                 // draw three lines
00438                 CvScalar col0 = CV_RGB(255,0,(64*itype)%256);
00439                 CvScalar col1 = CV_RGB(0,255,(64*itype)%256);
00440                 CvScalar col2 = CV_RGB((64*itype)%256,(64*itype)%256,255);
00441                 cvLine(frame, X[0], X[1], col0, 1);
00442                 cvLine(frame, X[0], X[2], col1, 1);
00443                 cvLine(frame, X[0], X[3], col2, 1);
00444 
00445                 // draw all the points
00446                 for(size_t i = 0; i < cb.grid3d.size(); ++i) {
00447                     Vector p = tlocal * cb.grid3d[i];
00448                     dReal fx = p.x*camInfoMsg.P[0] + p.y*camInfoMsg.P[1] + p.z*camInfoMsg.P[2] + camInfoMsg.P[3];
00449                     dReal fy = p.x*camInfoMsg.P[4] + p.y*camInfoMsg.P[5] + p.z*camInfoMsg.P[6] + camInfoMsg.P[7];
00450                     dReal fz = p.x*camInfoMsg.P[8] + p.y*camInfoMsg.P[9] + p.z*camInfoMsg.P[10] + camInfoMsg.P[11];
00451                     int x = (int)(fx/fz);
00452                     int y = (int)(fy/fz);
00453                     cvCircle(frame, cvPoint(x,y), 6, CV_RGB(0,0,0), 2);
00454                     cvCircle(frame, cvPoint(x,y), 2, CV_RGB(0,0,0), 2);
00455                     cvCircle(frame, cvPoint(x,y), 4, CV_RGB(128,128,64*itype), 3);
00456                 }
00457 
00458                 cvCircle(frame, X[0], 3, CV_RGB(255,255,128), 3);
00459             }
00460 
00461             cvShowImage("Checkerboard Detector",frame);
00462         }
00463 
00464         return true;
00465     }
00466 
00467 
00469     // FindTransformation
00470     geometry_msgs::Pose FindTransformation(const vector<CvPoint2D32f> &imgpts, const vector<Vector> &objpts, const Transform& tlocal, CHECKERBOARD &cb)
00471     {
00472         CvMat *objpoints = cvCreateMat(3,objpts.size(),CV_32FC1);
00473         for(size_t i=0; i<objpts.size(); ++i) {
00474             cvSetReal2D(objpoints, 0,i, objpts[i].x);
00475             cvSetReal2D(objpoints, 1,i, objpts[i].y);
00476             cvSetReal2D(objpoints, 2,i, objpts[i].z);
00477         }
00478 
00479         geometry_msgs::Pose pose;
00480         Transform tchecker;
00481         assert(sizeof(tchecker.trans.x)==sizeof(float));
00482         float fR3[3];
00483         CvMat R3, T3;
00484         assert(sizeof(pose.position.x) == sizeof(double));
00485         cvInitMatHeader(&R3, 3, 1, CV_32FC1, fR3);
00486         cvInitMatHeader(&T3, 3, 1, CV_32FC1, &tchecker.trans.x);
00487 
00488         float kc[4] = {0};
00489         CvMat kcmat;
00490         cvInitMatHeader(&kcmat,1,4,CV_32FC1,kc);
00491 
00492         CvMat img_points;
00493         cvInitMatHeader(&img_points, 1,imgpts.size(), CV_32FC2, const_cast<CvPoint2D32f*>(&imgpts[0]));
00494 
00495         cvFindExtrinsicCameraParams2(objpoints, &img_points, this->intrinsic_matrix, &kcmat, &R3, &T3);
00496         cvReleaseMat(&objpoints);
00497 
00498         double fang = sqrt(fR3[0]*fR3[0] + fR3[1]*fR3[1] + fR3[2]*fR3[2]);
00499         if( fang >= 1e-6 ) {
00500             double fmult = sin(fang/2)/fang;
00501             tchecker.rot = Vector(cos(fang/2),fR3[0]*fmult, fR3[1]*fmult, fR3[2]*fmult);
00502         }
00503 
00504         // move pose to center of marker
00505         Transform center(Vector(1,0,0,0),Vector(
00506                         cb.cellwidth*(cb.griddims.width-1)/2.0,
00507                         cb.cellheight*(cb.griddims.height-1)/2.0,
00508                         0));
00509 
00510         // disambiguate by tracking..
00511         Transform rot180(Vector(1,0,0,0),Vector(0,0,0));
00512         rot180.rotfromaxisangle(Vector(0,0,1),(float)M_PI);
00513 
00514         Transform tglobal1 = tchecker*center*tlocal;
00515         Transform tglobal2 = tchecker*center*rot180*tlocal;
00516         TransformMatrix diff1(cb.previous_pose.inverse() * tglobal1);
00517         TransformMatrix diff2(cb.previous_pose.inverse() * tglobal2);
00518 
00519         Transform tglobal;
00520         if(diff1.m[0]>=0)
00521                 tglobal = tglobal1;
00522         else
00523                 tglobal = tglobal2;
00524 
00525         cb.previous_pose = tglobal;
00526 
00527         pose.position.x = tglobal.trans.x;
00528         pose.position.y = tglobal.trans.y;
00529         pose.position.z = tglobal.trans.z;
00530         pose.orientation.x = tglobal.rot.y;
00531         pose.orientation.y = tglobal.rot.z;
00532         pose.orientation.z = tglobal.rot.w;
00533         pose.orientation.w = tglobal.rot.x;
00534         return pose;
00535     }
00536 
00537     void activate(bool active, string image_topic = std::string(), string camera_info_topic = std::string()){
00538       if(active){
00539         image_transport::ImageTransport it(_node_pub);
00540         if(image_topic.empty() || camera_info_topic.empty())
00541         {
00542           this->camInfoSubscriber = _node_pub.subscribe("camera_info", 1, &CheckerboardDetector::caminfo_cb, this);
00543           this->imageSubscriber = it.subscribe("image_rect", 1, &CheckerboardDetector::image_cb,this);
00544         }
00545         else{
00546           this->camInfoSubscriber = _node_pub.subscribe(camera_info_topic, 1, &CheckerboardDetector::caminfo_cb, this);
00547           this->imageSubscriber = it.subscribe(image_topic, 1, &CheckerboardDetector::image_cb,this);
00548         }
00549       }
00550       else{
00551         this->camInfoSubscriber.shutdown();
00552         this->imageSubscriber.shutdown();
00553       }
00554       _active = active;
00555     }
00556 
00557     bool serviceCallback(checkerboard_detector2::Set::Request  &req,
00558                          checkerboard_detector2::Set::Response &res)
00559     {
00560       this->activate(req.active, req.image_topic, req.camera_info_topic);
00561       return true;
00562     }
00563 
00564 
00565 };
00566 
00568 // MAIN
00569 int main(int argc, char **argv)
00570 {
00571     ros::init(argc,argv,"checkerboard_detector");
00572     if( !ros::master::check() )
00573         return 1;
00574   
00575     CheckerboardDetector cd;
00576     ros::spin();
00577 
00578     return 0;
00579 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


checkerboard_detector2
Author(s): Rosen Diankov, Felix Endres
autogenerated on Wed Dec 26 2012 15:30:15