gltracker.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Modified BSD License)
00003  *
00004  *  Copyright (c) 2012, PAL Robotics, S.L.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of PAL Robotics, S.L. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * @file gltracker.cpp
00035  * @author Bence Magyar
00036  * @date June 2012
00037  * @version 0.1
00038  * @brief Class of GLTracker which wraps the tracker core of BLORT.
00039  */
00040 
00041 #include "gltracker.h"
00042 #include <blort/Tracker/utilities.hpp>
00043 #include <blort/TomGine/tgModelLoader.h>
00044 #include <sstream>
00045 #include <iostream>
00046 #include <blort/blort/pal_util.h>
00047 #include <ros/console.h>
00048 
00049 using namespace blort_ros;
00050 
00051 GLTracker::GLTracker(const sensor_msgs::CameraInfo camera_info,
00052                      const std::string& config_root,
00053                      bool visualize_obj_pose)
00054 {
00055     //this line should force opengl to run software rendering == no GPU
00056     //putenv("LIBGL_ALWAYS_INDIRECT=1");
00057     config_root_ = config_root;
00058     conf_threshold = 0.4;
00059     recovery_conf_threshold = 0.05;
00060     publish_mode = 1;
00061     this->visualize_obj_pose = visualize_obj_pose;
00062 
00063     printf("\n Blort detection node\n\n");
00064     printf(" There is a dynamic_reconfigure interface for your convenience. \n");
00065     printf(" Control commands received via ROS service: tracker_control. \n");
00066     printf(" --------------------------\n");
00067     printf(" [0] Lock/Unlock tracking\n");
00068     printf(" [1] Reset tracker to initial pose\n");
00069     printf(" [2] Switch display mode of model\n");
00070     printf(" [3] Show particles\n");
00071     printf(" [4] Texture edge tracking\n");
00072     printf(" [5] Texture color tracking\n");
00073     printf(" [6] Show edges of image\n");
00074     printf(" [7] Print tracking information to console\n");
00075     printf(" \n\n ");
00076 
00077     // File names
00078     pose_cal = pal_blort::addRoot("bin/pose.cal", config_root);
00079     //FIXME: make these ROS parameters or eliminate them and use the content as parameters
00080     std::string tracking_ini(pal_blort::addRoot("bin/tracking.ini", config_root));
00081     std::string ply_model;
00082 
00083     GetPlySiftFilenames(tracking_ini.c_str(), ply_model, sift_file, model_name);
00084     ply_model_ = ply_model;
00085     GetTrackingParameter(track_params, tracking_ini.c_str(), config_root);
00086 
00087     tgcam_params = TomGine::tgCamera::Parameter(camera_info);
00088     getCamPose(pose_cal.c_str(), cam_pose); // should get this from a TF call
00089     setCameraPose(tgcam_params, pose_cal.c_str()); // camPose and tgCamParams share a lot of stuff
00090     track_params.camPar = tgcam_params;
00091 
00092     tracker.init(track_params);
00093     trPose.t = vec3(0.0, 0.1, 0.0);
00094     trPose.Rotate(0.0f, 0.0f, 0.5f);
00095 
00096     model_id = tracker.addModelFromFile(pal_blort::addRoot(ply_model, config_root).c_str(), trPose, model_name.c_str(), true);
00097     tracker.setLockFlag(true);
00098 
00099     image = cvCreateImage( cvSize(tgcam_params.width, tgcam_params.height), 8, 3 );
00100 
00101     movement = Tracking::ST_SLOW;
00102     quality = Tracking::ST_LOST;
00103     tracker_confidence = Tracking::ST_BAD;
00104 
00105     // define the constant cam_pose to be published
00106     fixed_cam_pose = pal_blort::tgPose2RosPose(cam_pose);
00107 }
00108 
00109 //2012-11-27: added by Jordi
00110 void GLTracker::resetParticleFilter()
00111 {
00112   tracker.removeModel(model_id);  
00113   model_id = tracker.addModelFromFile(pal_blort::addRoot(ply_model_, config_root_).c_str(), trPose, model_name.c_str(), true);
00114   movement = Tracking::ST_SLOW;
00115   quality  = Tracking::ST_LOST;
00116   tracker_confidence = Tracking::ST_BAD;  
00117 }
00118 
00119 void GLTracker::track()
00120 {
00121     *image = last_image;
00122 
00123     // Track object
00124     tracker.image_processing((unsigned char*)image->imageData);
00125 
00126     ROS_INFO_STREAM("GLTracker::track: quality before TextureTracker::track is " << quality);
00127     tracker.track();
00128     ROS_INFO_STREAM("GLTracker::track: quality after TextureTracker::track is " << quality);
00129 
00130     tracker.drawImage(0);
00131     tracker.drawCoordinates();
00132     tracker.getModelPose(model_id, trPose);
00133     tracker.drawResult(2.0f);
00134 
00135     // visualize current object pose if needed. moving this piece of code is troublesome,
00136     // has to stay right after drawImage(), because of OpenGL
00137     if( 1 || visualize_obj_pose)
00138     {
00139         trPose.Activate();
00140         glBegin(GL_LINES);
00141         glColor3f(1.0f, 0.0f, 0.0f);
00142         glVertex3f(0.0f, 0.0f, 0.0f);
00143         glVertex3f(1.0f, 0.0f, 0.0f);
00144 
00145         glColor3f(0.0f, 1.0f, 0.0f);
00146         glVertex3f(0.0f, 0.0f, 0.0f);
00147         glVertex3f(0.0f, 1.0f, 0.0f);
00148 
00149         glColor3f(0.0f, 0.0f, 1.0f);
00150         glVertex3f(0.0f, 0.0f, 0.0f);
00151         glVertex3f(0.0f, 0.0f, 1.0f);
00152         glEnd();
00153         trPose.Deactivate();
00154     }
00155 
00156     update();
00157 
00158     if(quality == Tracking::ST_LOCKED)
00159     {
00160         this->current_mode = blort_ros::TRACKER_LOCKED_MODE;
00161     }
00162     else if(quality == Tracking::ST_LOST)
00163     {
00164       ROS_INFO("GLTracker::track: switching tracker to RECOVERY_MODE because object LOST\n");
00165       switchToRecovery();
00166     }
00167 
00168     if(tracker_confidence == Tracking::ST_GOOD && movement == Tracking::ST_STILL && quality != Tracking::ST_LOCKED)
00169     {
00170       ROS_DEBUG_STREAM("Tracker is really confident (edge conf: " << tracker_confidences.edgeConf <<
00171                       " lost conf: " << tracker_confidences.lostConf << ". Sorry, no learning with this node.");
00172     }
00173 }
00174 
00175 void GLTracker::resetWithPose(const geometry_msgs::Pose& new_pose)
00176 {
00177     ConvertCam2World(pal_blort::rosPose2TgPose(new_pose), cam_pose, trPose);
00178     tracker.setModelInitialPose(model_id, trPose);
00179     //2012-11-28: commented by Jordi because the resetParticleFilter will reset the ModelEntry
00180     //tracker.resetUnlockLock(); // this does one run of the tracker to update the probabilities
00181 
00182     //2012-11-27: added by Jordi
00183     resetParticleFilter();
00184 
00185     switchToTracking();
00186 
00187     //2012-11-27: commented by Jordi
00188     //update();
00189 
00190     // make sure that the tracker will start tracking after a recovery,
00191     // not standing still in locked mode
00192     tracker.setLockFlag(false);
00193 }
00194 
00195 void GLTracker::reconfigure(blort_ros::TrackerConfig config)
00196 {
00197     tracker.setLockFlag(config.lock);
00198     tracker.setModelModeFlag(config.render_mode);
00199     tracker.setEdgesImageFlag(config.edge);
00200     visualize_obj_pose = config.visualize_obj_pose;
00201     publish_mode = config.publish_mode;
00202 
00203     //only reset the tracker when the checkbox was clicked, not depending on the act value
00204     if(last_reset != config.reset)
00205     {
00206         last_reset = config.reset;
00207         switchToRecovery();
00208     }
00209 }
00210 
00211 void GLTracker::trackerControl(int code, int param)
00212 {
00213     switch(code)
00214     {
00215     case 0: //l
00216         tracker.setLockFlag( !tracker.getLockFlag() );
00217         break;
00218     case 1: //r
00219         //tracker.reset();
00220         this->reset();
00221         break;
00222     case 2: //m
00223         if ( param != -1 )
00224           tracker.setModelModeFlag( param );
00225         else
00226           tracker.setModelModeFlag( tracker.getModelModeFlag()+1 );
00227         break;
00228     case 3: //p
00229         tracker.setDrawParticlesFlag( !tracker.getDrawParticlesFlag() );
00230         break;
00231     case 4: //4
00232         tracker.setEdgeShader();
00233         break;
00234     case 5: //5
00235         tracker.setColorShader();
00236         break;
00237     case 6: //e
00238         tracker.setEdgesImageFlag( !tracker.getEdgesImageFlag() );
00239         break;
00240     case 7: //i
00241         tracker.printStatistics();
00242         break;
00243     }
00244 }
00245 
00246 std::string GLTracker::getStatusString()
00247 {
00248     std::stringstream ss;
00249     ss << "GLTracker, mode: ";
00250     if(current_mode == blort_ros::TRACKER_TRACKING_MODE)
00251         ss << "tracking";
00252     else
00253         ss << "recovery";
00254 
00255     ss << " with target named: " << model_name << std::endl;
00256     return ss.str();
00257 }
00258 
00259 cv::Mat GLTracker::getImage()
00260 {
00261     cv::Mat tmp;
00262     switch(current_mode)
00263     {
00264     case TRACKER_RECOVERY_MODE:
00265         return tmp.empty()?last_image.clone():tmp; // do we need a copy?
00266         break;
00267     case TRACKER_TRACKING_MODE:
00268         return tracker.getImage().clone();
00269         break;
00270     case TRACKER_LOCKED_MODE:
00271         return tracker.getImage().clone();
00272         break;
00273     }
00274     return tmp;
00275 }
00276 
00277 void GLTracker::updatePoseResult()
00278 {
00279     result.clear();
00280     TomGine::tgPose pose;
00281     tracker.getModelPose(model_id, pose);
00282 
00283     geometry_msgs::Pose detection;
00284     detection.position.x = pose.t.x;
00285     detection.position.y = pose.t.y;
00286     detection.position.z = pose.t.z;
00287     //ALERT!!! inverse needed on the rotation quaternion because the blort orientation
00288     //output is computed differently than what rviz expects. they compute the inverse orientation
00289     detection.orientation.x = -pose.q.x;
00290     detection.orientation.y = -pose.q.y;
00291     detection.orientation.z = -pose.q.z;
00292     detection.orientation.w = pose.q.w;
00293 
00294     result.push_back(detection);
00295 }
00296 
00297 void GLTracker::update()
00298 {
00299     //update confidences for output
00300     Tracking::ModelEntry* myModelEntry = tracker.getModelEntry(model_id);
00301     tracker_confidences.edgeConf = myModelEntry->c_edge;
00302     tracker_confidences.confThreshold = myModelEntry->c_th;
00303     tracker_confidences.lostConf = myModelEntry->c_lost;
00304     tracker_confidences.distance = myModelEntry->t;
00305 
00306     //update confidences based on the currently tracked model
00307     // !!! the tracker state is now defined by the ONLY object tracked.
00308     // although the implementation would allow it, at several places, lacks this at several other.
00309     tracker.getModelMovementState(model_id, movement);
00310     tracker.getModelQualityState(model_id, quality);
00311     ROS_INFO_STREAM("GLTracker::update: the tracked model has set quality to " << quality);
00312     tracker.getModelConfidenceState(model_id, tracker_confidence);
00313 
00314     switch(tracker_confidence)
00315     {
00316     case Tracking::ST_GOOD:
00317         this->current_conf = blort_ros::TRACKER_CONF_GOOD;
00318         updatePoseResult();
00319         break;
00320     case Tracking::ST_FAIR:      
00321         this->current_conf = blort_ros::TRACKER_CONF_FAIR;
00322         if(publish_mode == TRACKER_PUBLISH_GOOD_AND_FAIR ||
00323            publish_mode == TRACKER_PUBLISH_ALL)
00324         {
00325             updatePoseResult();
00326             this->current_conf = blort_ros::TRACKER_CONF_GOOD;
00327         }
00328         break;
00329     case Tracking::ST_BAD:
00330         this->current_conf = blort_ros::TRACKER_CONF_FAIR;
00331         if(publish_mode == TRACKER_PUBLISH_ALL)
00332             updatePoseResult();
00333         break;
00334     default:
00335         ROS_ERROR("Unknown confidence value: %d", tracker_confidence);
00336         break;
00337     }
00338 }
00339 
00340 void GLTracker::reset()
00341 {
00342   ROS_INFO("GLTracker::reset: switching tracker to RECOVERY_MODE\n");
00343   switchToRecovery();
00344 }
00345 
00346 GLTracker::~GLTracker()
00347 {
00348 }


blort_ros
Author(s): Bence Magyar
autogenerated on Thu Jan 2 2014 11:39:12