00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <blort_ros/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
00056
00057 config_root_ = config_root;
00058 conf_threshold = 0.4;
00059 recovery_conf_threshold = 0.05;
00060 publish_mode = blort_ros::TRACKER_PUBLISH_GOOD_AND_FAIR;
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
00078 pose_cal = blort_ros::addRoot("config/pose.cal", config_root);
00079
00080 std::string tracking_ini(blort_ros::addRoot("config/tracking.ini", config_root));
00081
00082 std::vector<std::string> ply_models(0), sift_files(0), model_names(0);
00083 GetPlySiftFilenames(tracking_ini.c_str(), ply_models, sift_files, model_names);
00084
00085 blort::buildFromFiles(ply_models, sift_files, model_names, objects_);
00086
00087 GetTrackingParameter(track_params, tracking_ini.c_str(), config_root);
00088
00089 tgcam_params = TomGine::tgCamera::Parameter(camera_info);
00090 getCamPose(pose_cal.c_str(), cam_pose);
00091 setCameraPose(tgcam_params, pose_cal.c_str());
00092 track_params.camPar = tgcam_params;
00093
00094 tracker.init(track_params);
00095
00096 for(size_t i = 0; i < objects_.size(); ++i)
00097 {
00098 objects_[i].tr_pose = boost::shared_ptr<TomGine::tgPose>(new TomGine::tgPose);
00099 objects_[i].tr_pose->t = vec3(0.0, 0.1, 0.0);
00100 objects_[i].tr_pose->Rotate(0.0f, 0.0f, 0.5f);
00101 model_ids[objects_[i].name] = tracker.addModelFromFile(
00102 blort_ros::addRoot(objects_[i].ply_model, config_root).c_str(),
00103 *(objects_[i].tr_pose), objects_[i].name.c_str(), true);
00104 objects_[i].movement = Tracking::ST_SLOW;
00105 objects_[i].quality = Tracking::ST_LOST;
00106 objects_[i].tracking_conf = Tracking::ST_BAD;
00107 current_modes[objects_[i].name] = blort_ros::TRACKER_RECOVERY_MODE;
00108 current_confs[objects_[i].name] = blort_ros::TRACKER_CONF_LOST;
00109
00110
00111 }
00112
00113 tracker.setLockFlag(true);
00114
00115 image = cvCreateImage( cvSize(tgcam_params.width, tgcam_params.height), 8, 3 );
00116
00117
00118 fixed_cam_pose = blort_ros::tgPose2RosPose(cam_pose);
00119 }
00120
00121
00122 void GLTracker::resetParticleFilter(std::string obj_i)
00123 {
00124
00125 BOOST_FOREACH(blort::ObjectEntry& obj, objects_)
00126 {
00127 if(obj.name == obj_i)
00128 {
00129 tracker.removeModel(model_ids[obj_i]);
00130 model_ids[obj_i] = tracker.addModelFromFile(
00131 blort_ros::addRoot(obj.ply_model, config_root_).c_str(),
00132 *(obj.tr_pose), obj.name.c_str(), true);
00133 obj.movement = Tracking::ST_SLOW;
00134 obj.quality = Tracking::ST_LOST;
00135 obj.tracking_conf = Tracking::ST_BAD;
00136 obj.is_tracked = true;
00137 break;
00138 }
00139 }
00140 }
00141
00142 void GLTracker::track()
00143 {
00144 boost::mutex::scoped_lock lock(models_mutex);
00145 *image = last_image;
00146
00147
00148 tracker.image_processing((unsigned char*)image->imageData);
00149
00150
00151 BOOST_FOREACH(const blort::ObjectEntry& obj, objects_)
00152 {
00153 if(obj.is_tracked)
00154 tracker.track(model_ids[obj.name]);
00155 }
00156 tracker.drawImage(0);
00157 tracker.drawCoordinates();
00158 BOOST_FOREACH(const blort::ObjectEntry& obj, objects_)
00159 {
00160 if(obj.is_tracked)
00161 {
00162 tracker.getModelPose(model_ids[obj.name], *(obj.tr_pose));
00163 tracker.drawResult(model_ids[obj.name], 2.0);
00164 }
00165 }
00166
00167
00168
00169
00170 if( 1 || visualize_obj_pose)
00171 {
00172 for(size_t i = 0; i < objects_.size(); ++i)
00173 {
00174 if(current_modes[objects_[i].name] != TRACKER_RECOVERY_MODE && objects_[i].is_tracked)
00175 {
00176 objects_[i].tr_pose->Activate();
00177 glBegin(GL_LINES);
00178 glColor3f(1.0f, 0.0f, 0.0f);
00179 glVertex3f(0.0f, 0.0f, 0.0f);
00180 glVertex3f(1.0f, 0.0f, 0.0f);
00181
00182 glColor3f(0.0f, 1.0f, 0.0f);
00183 glVertex3f(0.0f, 0.0f, 0.0f);
00184 glVertex3f(0.0f, 1.0f, 0.0f);
00185
00186 glColor3f(0.0f, 0.0f, 1.0f);
00187 glVertex3f(0.0f, 0.0f, 0.0f);
00188 glVertex3f(0.0f, 0.0f, 1.0f);
00189 glEnd();
00190 objects_[i].tr_pose->Deactivate();
00191 }
00192 }
00193 }
00194
00195 update();
00196
00197 for(size_t i = 0; i < objects_.size(); ++i)
00198 {
00199 if(objects_[i].is_tracked)
00200 {
00201 if(objects_[i].quality == Tracking::ST_LOCKED)
00202 {
00203 this->current_modes[objects_[i].name] = blort_ros::TRACKER_LOCKED_MODE;
00204 }
00205 else if(objects_[i].quality == Tracking::ST_LOST)
00206 {
00207 ROS_INFO_STREAM("GLTracker::track: switching tracker to RECOVERY_MODE because object " << objects_[i].name << "LOST");
00208 switchToRecovery(objects_[i].name);
00209 }
00210
00211 if(objects_[i].tracking_conf == Tracking::ST_GOOD
00212 && objects_[i].movement == Tracking::ST_STILL
00213 && objects_[i].quality != Tracking::ST_LOCKED)
00214 {
00215 ROS_DEBUG_STREAM("Tracker is really confident (edge conf: " << objects_[i].edgeConf);
00216 }
00217 }
00218 }
00219 }
00220
00221 void GLTracker::resetWithPose(std::string id, const geometry_msgs::Pose& new_pose)
00222 {
00223 boost::mutex::scoped_lock lock(models_mutex);
00224 blort::ObjectEntry& obj = getObjEntryByName(id);
00225 ConvertCam2World(blort_ros::rosPose2TgPose(new_pose), cam_pose, *(obj.tr_pose));
00226 tracker.setModelInitialPose(model_ids[id], *(obj.tr_pose));
00227 resetParticleFilter(id);
00228 switchToTracking(id);
00229
00230
00231
00232 tracker.setLockFlag(false);
00233 }
00234
00235 void GLTracker::reconfigure(blort_ros::TrackerConfig config)
00236 {
00237 tracker.setLockFlag(config.lock);
00238 tracker.setModelModeFlag(config.render_mode);
00239 tracker.setEdgesImageFlag(config.edge);
00240 visualize_obj_pose = config.visualize_obj_pose;
00241 publish_mode = config.publish_mode;
00242
00243
00244 if(last_reset != config.reset)
00245 {
00246 last_reset = config.reset;
00247 reset();
00248 }
00249 }
00250
00251 void GLTracker::trackerControl(uint8_t code, const std::vector<std::string> & params)
00252 {
00253 std::string param = "";
00254 if(params.empty())
00255 {
00256 param = objects_.begin()->name;
00257 }
00258 switch(code)
00259 {
00260 case 0:
00261 tracker.setLockFlag( !tracker.getLockFlag() );
00262 break;
00263 case 1:
00264
00265 this->reset();
00266 break;
00267 case 2:
00268 if ( param != "" )
00269 tracker.setModelModeFlag( model_ids[param] );
00270 else
00271 tracker.setModelModeFlag( tracker.getModelModeFlag()+1 );
00272 break;
00273 case 3:
00274 tracker.setDrawParticlesFlag( !tracker.getDrawParticlesFlag() );
00275 break;
00276 case 4:
00277 tracker.setEdgeShader();
00278 break;
00279 case 5:
00280 tracker.setColorShader();
00281 break;
00282 case 6:
00283 tracker.setEdgesImageFlag( !tracker.getEdgesImageFlag() );
00284 break;
00285 case 7:
00286 tracker.printStatistics();
00287 break;
00288 case 8:
00289 switchTracking(params);
00290 break;
00291 }
00292 }
00293
00294 void GLTracker::switchTracking(const std::vector<std::string> & params)
00295 {
00296 if(params.size() == 0)
00297 {
00298 BOOST_FOREACH(blort::ObjectEntry& obj, objects_)
00299 {
00300 obj.is_tracked = true;
00301 }
00302 }
00303 else
00304 {
00305 for(size_t i = 0; i < params.size(); ++i)
00306 {
00307 blort::ObjectEntry& obj = getObjEntryByName(params[i]);
00308 obj.is_tracked = !obj.is_tracked;
00309 }
00310 }
00311 }
00312
00313 cv::Mat GLTracker::getImage()
00314 {
00315 cv::Mat tmp;
00316
00317
00318 blort_ros::tracker_mode current_mode = TRACKER_RECOVERY_MODE;
00319 typedef std::pair<std::string, blort_ros::tracker_mode> NameModePair_t;
00320 BOOST_FOREACH(NameModePair_t item, current_modes)
00321 {
00322 if(item.second != TRACKER_RECOVERY_MODE)
00323 {
00324 current_mode = item.second;
00325 break;
00326 }
00327 }
00328 switch(current_mode)
00329 {
00330 case TRACKER_RECOVERY_MODE:
00331
00332 return last_image.clone();
00333 break;
00334 case TRACKER_TRACKING_MODE:
00335 case TRACKER_LOCKED_MODE:
00336
00337 return tracker.getImage().clone();
00338 break;
00339 default:
00340 break;
00341 }
00342 return tmp;
00343 }
00344
00345 void GLTracker::updatePoseResult(std::string i)
00346 {
00347 TomGine::tgPose pose;
00348 tracker.getModelPose(model_ids[i], pose);
00349
00350 geometry_msgs::Pose detection;
00351 detection.position.x = pose.t.x;
00352 detection.position.y = pose.t.y;
00353 detection.position.z = pose.t.z;
00354
00355
00356 detection.orientation.x = -pose.q.x;
00357 detection.orientation.y = -pose.q.y;
00358 detection.orientation.z = -pose.q.z;
00359 detection.orientation.w = pose.q.w;
00360
00361 result[i] = detection;
00362 }
00363
00364 void GLTracker::update()
00365 {
00366 BOOST_FOREACH(blort::ObjectEntry& obj, objects_)
00367 {
00368 if(obj.is_tracked)
00369 {
00370
00371 Tracking::ModelEntry* myModelEntry = tracker.getModelEntry(model_ids[obj.name]);
00372 obj.edgeConf = myModelEntry->c_edge;
00373 obj.confThreshold = myModelEntry->c_th;
00374 obj.lostConf = myModelEntry->c_lost;
00375 obj.distance = myModelEntry->t;
00376
00377
00378 tracker.getModelMovementState(model_ids[obj.name], obj.movement);
00379 tracker.getModelQualityState(model_ids[obj.name], obj.quality);
00380 ROS_INFO_STREAM("GLTracker::update: the tracked model for " << obj.name << " has set quality to " << obj.quality);
00381 tracker.getModelConfidenceState(model_ids[obj.name], obj.tracking_conf);
00382
00383 switch(obj.tracking_conf)
00384 {
00385 case Tracking::ST_GOOD:
00386 this->current_confs[obj.name] = blort_ros::TRACKER_CONF_GOOD;
00387 updatePoseResult(obj.name);
00388 break;
00389 case Tracking::ST_FAIR:
00390 this->current_confs[obj.name] = blort_ros::TRACKER_CONF_FAIR;
00391 if(publish_mode == TRACKER_PUBLISH_GOOD_AND_FAIR ||
00392 publish_mode == TRACKER_PUBLISH_ALL)
00393 {
00394 updatePoseResult(obj.name);
00395 this->current_confs[obj.name] = blort_ros::TRACKER_CONF_GOOD;
00396 }
00397 break;
00398 case Tracking::ST_BAD:
00399 this->current_confs[obj.name] = blort_ros::TRACKER_CONF_FAIR;
00400 if(publish_mode == TRACKER_PUBLISH_ALL)
00401 updatePoseResult(obj.name);
00402 break;
00403 default:
00404 ROS_ERROR("Unknown confidence value: %d", obj.tracking_conf);
00405 break;
00406 }
00407 }
00408 }
00409 }
00410
00411 void GLTracker::reset(const std::vector<std::string> & params)
00412 {
00413 ROS_INFO("GLTracker::reset: switching tracker to RECOVERY_MODE");
00414 if(!params.empty())
00415 {
00416 for(size_t i = 0; i < model_ids.size(); ++i)
00417 {
00418 switchToRecovery(objects_[i].name);
00419 }
00420 }
00421 else
00422 {
00423 for(size_t i = 0; i < params.size(); ++i)
00424 {
00425
00426 switchToRecovery(params[i]);
00427 }
00428 }
00429 }
00430
00431 void GLTracker::switchToTracking(const std::string& id)
00432 {
00433 TrackerInterface::switchToTracking(id);
00434 tracker.getModelEntry(model_ids[id])->st_quality = Tracking::ST_OK;
00435 }
00436
00437 void GLTracker::switchToRecovery(const std::string& id)
00438 {
00439 TrackerInterface::switchToRecovery(id);
00440 tracker.getModelEntry(model_ids[id])->st_quality = Tracking::ST_LOST;
00441 getObjEntryByName(id).quality = Tracking::ST_LOST;
00442 typedef std::pair<std::string, blort_ros::tracker_mode> NameModePair_t;
00443 BOOST_FOREACH(NameModePair_t item, current_modes)
00444 {
00445 item.second = blort_ros::TRACKER_RECOVERY_MODE;
00446 }
00447 }
00448
00449 GLTracker::~GLTracker()
00450 {
00451 }
00452
00453 blort::ObjectEntry& GLTracker::getObjEntryByName(const std::string& name)
00454 {
00455 BOOST_FOREACH(blort::ObjectEntry& obj, objects_)
00456 {
00457 if(obj.name == name)
00458 return obj;
00459 }
00460 assert(false);
00461 ROS_ERROR_STREAM("GLTracker::reset: No object that coincides with name '" << name << "'', RETURNING FIRST ONE, THIS IS WRONG (but fixes compilation)");
00462 return objects_[0];
00463 }
00464
00465 const std::vector<blort::ObjectEntry>& GLTracker::getObjects() const
00466 {
00467 return objects_;
00468 }
00469
00470 bool GLTracker::isTracked(const std::string& id)
00471 {
00472 return getObjEntryByName(id).is_tracked;
00473 }
00474
00475 void GLTracker::setTracked(const std::string& id, bool tracked)
00476 {
00477 getObjEntryByName(id).is_tracked = tracked;
00478 }
00479
00480 void GLTracker::enableAllTracking(bool enable)
00481 {
00482 BOOST_FOREACH(blort::ObjectEntry& obj, objects_)
00483 {
00484 obj.is_tracked = enable;
00485 }
00486 }