6 #include <boost/filesystem.hpp> 7 #include <boost/filesystem/fstream.hpp> 8 #include <boost/format.hpp> 9 #include <boost/optional.hpp> 10 #include <boost/version.hpp> 15 #include <dynamic_reconfigure/server.h> 16 #include <geometry_msgs/PoseWithCovarianceStamped.h> 19 #include <visp_tracker/Init.h> 20 #include <visp_tracker/ModelBasedSettingsConfig.h> 22 #include <visp/vpMe.h> 23 #include <visp/vpPixelMeterConversion.h> 24 #include <visp/vpPose.h> 26 #define protected public 27 #include <visp/vpMbEdgeTracker.h> 28 #include <visp/vpMbKltTracker.h> 29 #include <visp/vpMbEdgeKltTracker.h> 32 #include <visp/vpDisplayX.h> 33 #include <visp/vpImageIo.h> 34 #include <visp/vpIoTools.h> 48 volatile bool& exiting,
51 queueSize_(queueSize),
53 nodeHandlePrivate_(privateNh),
54 imageTransport_(nodeHandle_),
60 rectifiedImageTopic_(),
68 reconfigureSrv_(NULL),
69 reconfigureKltSrv_(NULL),
70 reconfigureEdgeSrv_(NULL),
75 startFromSavedPose_(),
91 if(trackerType_==
"mbt")
93 else if(trackerType_==
"klt")
102 if (modelName_.empty ())
103 throw std::runtime_error
105 "Relaunch the client while setting the model_name parameter, i.e.\n" 106 "$ rosrun visp_tracker client _model_name:=my-model" 117 (
"the camera_prefix parameter does not exist.\n" 118 "This may mean that:\n" 119 "- the tracker is not launched,\n" 120 "- the tracker and viewer are not running in the same namespace." 126 (
"tracker is not yet initialized, waiting...\n" 127 "You may want to launch the client to initialize the tracker.");
170 if(trackerType_==
"mbt+klt"){
175 boost::ref(
mutex_), _1, _2);
178 else if(trackerType_==
"mbt"){
183 boost::ref(
mutex_), _1, _2);
191 boost::ref(
mutex_), _1, _2);
200 throw std::runtime_error(
"failed to retrieve image");
210 if(trackerType_!=
"klt"){
219 if(trackerType_!=
"mbt"){
242 boost::format fmtWindowTitle (
"ViSP MBT tracker initialization - [ns: %s]");
246 fmtWindowTitle.str().c_str());
250 vpHomogeneousMatrix cMo;
251 vpImagePoint point (10, 10);
257 vpDisplay::display(
image_);
269 ROS_INFO_STREAM(
"initial pose [tx,ty,tz,tux,tuy,tuz]:\n" << vpPoseVector(cMo).t());
275 vpMouseButton::vpMouseButtonType button =
276 vpMouseButton::button1;
279 vpDisplay::display(
image_);
287 vpDisplay::displayCharString
288 (
image_, point,
"tracking, click to initialize tracker",
293 loop_rate_tracking.sleep();
297 while(!vpDisplay::getClick(
image_, ip, button,
false));
303 catch(
const std::runtime_error& e)
307 << e.what() <<
", retrying...");
309 catch(
const std::string& str)
313 << str <<
", retrying...");
318 ROS_ERROR(
"failed to initialize, retrying...");
327 catch(std::exception& e)
333 ROS_ERROR(
"unknown error happened while sending the cMo, retrying...");
360 visp_tracker::Init srv;
382 (
"Waiting for the initialization service to become available.");
386 if (client.
call(srv))
388 if (srv.response.initialization_succeed)
389 ROS_INFO(
"Tracker initialized with success.");
391 throw std::runtime_error(
"failed to initialize tracker.");
394 throw std::runtime_error(
"failed to call service init");
396 if (clientViewer.call(srv))
398 if (srv.response.initialization_succeed)
399 ROS_INFO(
"Tracker Viewer initialized with success.");
401 throw std::runtime_error(
"failed to initialize tracker viewer.");
404 ROS_INFO(
"No Tracker Viewer node to initialize from service");
415 std::string modelPath;
416 boost::filesystem::ofstream modelStream;
420 throw std::runtime_error (
"failed to retrieve model");
423 ROS_INFO(
"Model has been successfully loaded.");
426 vpMbEdgeTracker* t =
dynamic_cast<vpMbEdgeTracker*
>(
tracker_);
428 << t->getFaces().getPolygon().size());
429 ROS_DEBUG_STREAM(
"Nb visible faces: " << t->getFaces().getNbVisiblePolygon());
431 std::list<vpMbtDistanceLine *> linesList;
432 t->getLline(linesList);
437 vpMbKltTracker* t =
dynamic_cast<vpMbKltTracker*
>(
tracker_);
439 << t->getFaces().getPolygon().size());
440 ROS_DEBUG_STREAM(
"Nb visible faces: " << t->getFaces().getNbVisiblePolygon());
444 vpMbEdgeKltTracker* t =
dynamic_cast<vpMbEdgeKltTracker*
>(
tracker_);
446 << t->getFaces().getPolygon().size());
447 ROS_DEBUG_STREAM(
"Nb visible faces: " << t->getFaces().getNbVisiblePolygon());
450 std::list<vpMbtDistanceLine *> linesList;
451 t->getLline(linesList);
459 (
"Failed to load the model %1%\n" 460 "Do you use resource_retriever syntax?\n" 461 "I.e. replace /my/model/path by file:///my/model/path");
463 throw std::runtime_error(fmt.str());
470 vpHomogeneousMatrix cMo;
474 std::string resource;
478 std::stringstream file;
484 <<
"using identity as initial pose");
489 for (
unsigned i = 0; i < 6; ++i) {
494 ROS_WARN(
"failed to parse initial pose file");
505 std::string username;
506 vpIoTools::getUserName(username);
510 filename =
"C:/temp/" + username;
512 filename =
"/tmp/" + username;
516 if (vpIoTools::checkFilename(filename)) {
518 std::ifstream in( filename.c_str() );
533 boost::filesystem::ofstream file(initialPose);
538 std::string username;
539 vpIoTools::getUserName(username);
542 std::string logdirname;
544 logdirname =
"C:/temp/" + username;
546 logdirname =
"/tmp/" + username;
549 if (vpIoTools::checkDirectory(logdirname) ==
false) {
551 vpIoTools::makeDirectory(logdirname);
554 ROS_WARN_STREAM(
"Unable to create the folder " << logdirname <<
" to save the initial pose");
560 std::fstream finitpos ;
561 finitpos.open(filename.c_str(), std::ios::out) ;
584 std::stringstream file;
589 boost::format fmt(
"failed to load initialization points: %1");
591 throw std::runtime_error(fmt.str());
597 while (!file.fail() && (c ==
'#')) {
598 file.ignore(256,
'\n');
603 unsigned int npoints;
605 file.ignore(256,
'\n');
608 if (npoints > 100000) {
609 throw vpException(vpException::badValue,
610 "Exceed the max number of points.");
614 double X = 0., Y = 0., Z = 0.;
615 for (
unsigned int i=0 ; i < npoints ; i++){
618 while (!file.fail() && (c ==
'#')) {
619 file.ignore(256,
'\n');
624 file >> X >> Y >> Z ;
625 file.ignore(256,
'\n');
627 point.setWorldCoordinates(X,Y,Z) ;
628 points.push_back(point);
638 vpMouseButton::vpMouseButtonType button = vpMouseButton::button1;
639 vpDisplay::display(
image_);
640 tracker_->setDisplayFeatures(
false);
643 vpDisplay::displayCharString(
image_, 15, 10,
644 "Left click to validate, right click to modify initial pose",
656 while(
ros::ok() && !vpDisplay::getClick(
image_, ip, button,
false));
658 if(button == vpMouseButton::button1)
668 vpHomogeneousMatrix cMo;
669 vpImagePoint point (10, 10);
676 vpMouseButton::vpMouseButtonType button = vpMouseButton::button1;
682 vpDisplayX *initHelpDisplay = NULL;
684 std::string helpImagePath;
686 if (helpImagePath.empty()){
692 char* tmpname = strdup(
"/tmp/tmpXXXXXX");
693 if (mkdtemp(tmpname) == NULL) {
694 ROS_ERROR_STREAM(
"Failed to create the temporary directory: " << strerror(errno));
697 boost::filesystem::path path(tmpname);
698 path /= (
"help.ppm");
701 helpImagePath = path.native();
703 helpImagePath.c_str());
706 FILE*
f = fopen(helpImagePath.c_str(),
"w");
707 fwrite(resource.
data.get(), resource.
size, 1, f);
717 if (!helpImagePath.empty()){
720 if (! vpIoTools::checkFilename(helpImagePath)) {
721 ROS_WARN(
"Error tracker initialization help image file \"%s\" doesn't exist", helpImagePath.c_str());
727 #if VISP_VERSION_INT >= VP_VERSION_INT(2,10,0) 728 winx =
image_.display->getWindowXPosition();
729 winy =
image_.display->getWindowYPosition();
731 initHelpDisplay =
new vpDisplayX (winx+
image_.getWidth()+20, winy,
"Init help image");
733 vpImage<vpRGBa> initHelpImage;
734 vpImageIo::read(initHelpImage, helpImagePath);
735 initHelpDisplay->init(initHelpImage);
736 vpDisplay::display(initHelpImage);
737 vpDisplay::flush(initHelpImage);
739 }
catch(vpException &e) {
740 ROS_WARN(
"Error diplaying tracker initialization help image file \"%s\":\n%s", helpImagePath.c_str(), e.what());
749 vpDisplay::display(
image_);
753 for(
unsigned i = 0; i < points.size(); ++i)
762 while(
ros::ok() && !vpDisplay::getClick(
image_, ip, button,
false));
764 imagePoints.push_back(ip);
765 vpDisplay::displayCross(
image_, imagePoints.back(), 5, vpColor::green);
776 if (initHelpDisplay != NULL)
777 delete initHelpDisplay;
788 double x = 0.,
y = 0.;
789 boost::format fmt(
"click on point %u/%u");
790 fmt % (i + 1) % points.size();
793 vpMouseButton::vpMouseButtonType button = vpMouseButton::button1;
796 vpDisplay::display(
image_);
797 vpDisplay::displayCharString
802 for (
unsigned j = 0; j < imagePoints.size(); ++j)
803 vpDisplay::displayCross(
image_, imagePoints[j], 5, vpColor::green);
811 while(!vpDisplay::getClick(
image_, ip, button,
false));
813 imagePoints.push_back(ip);
817 pose.addPoint(points[i]);
839 result.resize(resource.
size);
841 for (; i < resource.
size; ++i)
842 result[i] = resource.
data.get()[i];
848 const std::string& resourcePath,
849 std::string& fullModelPath)
851 std::string modelExt_ =
".wrl";
852 bool vrmlWorked =
true;
879 result.resize(resource.
size);
881 for (; i < resource.
size; ++i)
882 result[i] = resource.
data.get()[i];
883 result[resource.
size];
885 char* tmpname = strdup(
"/tmp/tmpXXXXXX");
886 if (mkdtemp(tmpname) == NULL)
889 (
"Failed to create the temporary directory: " << strerror(errno));
892 boost::filesystem::path path(tmpname);
893 path /= (
"model" + modelExt_);
896 fullModelPath = path.native();
901 modelStream.open(path);
902 if (!modelStream.good())
905 (
"Failed to create the temporary file: " << path);
908 modelStream << result;
boost::filesystem::path bInitPath_
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
std::string convertVpMeToRosMessage(const vpMbTracker *tracker, const vpMe &moving_edge)
TrackerClient(ros::NodeHandle &nh, ros::NodeHandle &privateNh, volatile bool &exiting, unsigned queueSize=5u)
void reconfigureCallback(vpMbTracker *tracker, vpImage< unsigned char > &I, vpMe &moving_edge, vpKltOpencv &kltTracker, boost::recursive_mutex &mutex, visp_tracker::ModelBasedSettingsConfig &config, uint32_t level)
image_transport::CameraSubscriber::Callback bindImageCallback(vpImage< unsigned char > &image)
void convertVpMeToInitRequest(const vpMe &moving_edge, const vpMbTracker *tracker, visp_tracker::Init &srv)
std::string getHelpImageFileFromModelName(const std::string &modelName, const std::string &defaultPath)
CameraSubscriber subscribeCamera(const std::string &base_topic, uint32_t queue_size, const CameraSubscriber::Callback &callback, const ros::VoidPtr &tracked_object=ros::VoidPtr(), const TransportHints &transport_hints=TransportHints())
void start(const ros::V_string &topics, double duration)
std::string cameraInfoTopic_
void checkInputs()
Make sure the topics we subscribe already exist.
void saveInitialPose(const vpHomogeneousMatrix &cMo)
ros::NodeHandle & nodeHandle_
std::string convertVpKltOpencvToRosMessage(const vpMbTracker *tracker, const vpKltOpencv &klt)
bool call(MReq &req, MRes &res)
image_transport::ImageTransport imageTransport_
void convertVpMbTrackerToInitRequest(const vpMbTracker *tracker, visp_tracker::Init &srv)
reconfigureSrvStruct< visp_tracker::ModelBasedSettingsEdgeConfig >::reconfigureSrv_t * reconfigureEdgeSrv_
ROSCPP_DECL std::string resolve(const std::string &name, bool remap=true)
ros::NodeHandle & nodeHandlePrivate_
points_t loadInitializationPoints()
TFSIMD_FORCE_INLINE const tfScalar & y() const
std::vector< vpPoint > points_t
resource_retriever::Retriever resourceRetriever_
bool validatePose(const vpHomogeneousMatrix &cMo)
vpHomogeneousMatrix loadInitialPose()
std::string getModelFileFromModelName(const std::string &modelName, const std::string &defaultPath)
image_proc::AdvertisementChecker checkInputs_
Helper used to check that subscribed topics exist.
std::string getInitFileFromModelName(const std::string &modelName, const std::string &defaultPath)
void initPoint(unsigned &i, points_t &points, imagePoints_t &imagePoints, ros::Rate &rate, vpPose &pose)
std::vector< std::string > V_string
#define ROS_INFO_THROTTLE(period,...)
std::string modelPathAndExt_
ROSCPP_DECL const std::string & getNamespace()
boost::shared_array< uint8_t > data
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
ROSCPP_DECL bool get(const std::string &key, std::string &s)
std::string getInitialPoseFileFromModelName(const std::string &modelName, const std::string &defaultPath)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
std::string model_description_param
image_transport::CameraSubscriber cameraSubscriber_
std::string cameraPrefix_
TFSIMD_FORCE_INLINE const tfScalar & x() const
void sendcMo(const vpHomogeneousMatrix &cMo)
void reconfigureEdgeCallback(vpMbTracker *tracker, vpImage< unsigned char > &I, vpMe &moving_edge, boost::recursive_mutex &mutex, visp_tracker::ModelBasedSettingsEdgeConfig &config, uint32_t level)
void reconfigureKltCallback(vpMbTracker *tracker, vpImage< unsigned char > &I, vpKltOpencv &kltTracker, boost::recursive_mutex &mutex, visp_tracker::ModelBasedSettingsKltConfig &config, uint32_t level)
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
MemoryResource get(const std::string &url)
sensor_msgs::CameraInfoConstPtr info_
reconfigureSrvStruct< visp_tracker::ModelBasedSettingsConfig >::reconfigureSrv_t * reconfigureSrv_
#define ROS_INFO_STREAM(args)
std::string rectifiedImageTopic_
void convertVpKltOpencvToInitRequest(const vpKltOpencv &klt, const vpMbTracker *tracker, visp_tracker::Init &srv)
reconfigureSrvStruct< visp_tracker::ModelBasedSettingsKltConfig >::reconfigureSrv_t * reconfigureKltSrv_
bool getParam(const std::string &key, std::string &s) const
boost::filesystem::path bModelPath_
void initializeVpCameraFromCameraInfo(vpCameraParameters &cam, sensor_msgs::CameraInfoConstPtr info)
std::string default_model_path
std::string init_service_viewer
#define ROS_ERROR_STREAM(args)
vpCameraParameters cameraParameters_
void vpHomogeneousMatrixToTransform(geometry_msgs::Transform &dst, const vpHomogeneousMatrix &src)
std::string convertVpMbTrackerToRosMessage(const vpMbTracker *tracker)
ROSCPP_DECL void spinOnce()
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
std::vector< vpImagePoint > imagePoints_t
bool makeModelFile(boost::filesystem::ofstream &modelStream, const std::string &resourcePath, std::string &fullModelPath)
boost::recursive_mutex mutex_
std::string fetchResource(const std::string &)