node.cpp
Go to the documentation of this file.
1 #include "node.h"
2 #include "names.h"
3 
4 //command line parameters
5 #include "cmd_line/cmd_line.h"
6 
7 
8 //tracking
11 #include "libauto_tracker/events.h"
12 
13 #include "visp_tracker/MovingEdgeSites.h"
14 #include "visp_tracker/KltPoints.h"
15 
16 //visp includes
17 #include <visp3/gui/vpDisplayX.h>
18 #include <visp3/mbt/vpMbGenericTracker.h>
19 #include <visp3/core/vpTime.h>
20 
21 //detectors
22 #if VISP_VERSION_INT < VP_VERSION_INT(2,10,0)
25 #else
26 # include <visp3/detection/vpDetectorDataMatrixCode.h>
27 # include <visp3/detection/vpDetectorQRCode.h>
28 #endif
29 
30 #include <visp_bridge/camera.h>
31 #include <visp_bridge/image.h>
32 #include <visp_bridge/3dpose.h>
33 
35 
37 
38 #include "std_msgs/Int8.h"
39 #include "std_msgs/String.h"
40 
41 namespace visp_auto_tracker{
43  n_("~"),
44  queue_size_(1),
45  tracker_config_path_(),
46  model_description_(),
47  model_path_(),
48  model_name_(),
49  code_message_(),
50  tracker_ref_frame_(),
51  debug_display_(false),
52  I_(),
53  image_header_(),
54  got_image_(false),
55  cam_(),
56  t_(NULL) {
57  //get the tracker configuration file
58  //this file contains all of the tracker's parameters, they are not passed to ros directly.
59  n_.param<std::string>("tracker_config_path", tracker_config_path_, "");
60  n_.param<bool>("debug_display", debug_display_, false);
61  std::string model_full_path;
62  n_.param<std::string>("model_path", model_path_, "");
63  n_.param<std::string>("model_name", model_name_, "");
64  n_.param<std::string>("code_message", code_message_, "");
65  n_.param<std::string>("tracker_ref_frame", tracker_ref_frame_, "/map");
66  model_path_= model_path_[model_path_.length()-1]=='/'?model_path_:model_path_+std::string("/");
67  model_full_path = model_path_+model_name_;
68  tracker_config_path_ = model_full_path+".cfg";
69  ROS_INFO("model full path=%s",model_full_path.c_str());
70 
71  //Parse command line arguments from config file (as ros param)
72  cmd_.init(tracker_config_path_);
73  cmd_.set_data_directory(model_path_); //force data path
74  cmd_.set_pattern_name(model_name_); //force model name
75  cmd_.set_show_fps(false);
76  if (! code_message_.empty()) {
77  ROS_WARN_STREAM("Track only code with message: \"" << code_message_ << "\"");
78  cmd_.set_code_message(code_message_);
79  }
80 
83  try {
84  res = r.get(std::string("file://")+cmd_.get_mbt_cad_file());
85  }
86  catch(...) {
87  ROS_ERROR_STREAM("Unable to read wrl or cao model file as resource: " << std::string("file://")+cmd_.get_mbt_cad_file());
88  }
89 
90  model_description_.resize(res.size);
91  for (unsigned int i=0; i < res.size; ++i)
92  model_description_[i] = res.data.get()[i];
93 
94  ROS_INFO("Model content=%s",model_description_.c_str());
95 
96  n_.setParam ("/model_description", model_description_);
97  }
98 
100  while ( ros::ok ()){
101  if(got_image_) return;
102  ros::spinOnce();
103  }
104  }
105 
106  //records last recieved image
107  void Node::frameCallback(const sensor_msgs::ImageConstPtr& image, const sensor_msgs::CameraInfoConstPtr& cam_info){
108  boost::mutex::scoped_lock(lock_);
109  image_header_ = image->header;
110  I_ = visp_bridge::toVispImageRGBa(*image); //make sure the image isn't worked on by locking a mutex
112 
113  got_image_ = true;
114  }
115 
116  void Node::spin(){
117 
118  if(cmd_.should_exit()) return; //exit if needed
119 
120  vpMbTracker* tracker; //mb-tracker will be chosen according to config
121 
122  //create display
123  vpDisplayX* d = NULL;
124  if(debug_display_)
125  d = new vpDisplayX();
126 
127  //init detector based on user preference
128 #if VISP_VERSION_INT < VP_VERSION_INT(2,10,0)
129  detectors::DetectorBase* detector = NULL;
131  detector = new detectors::qrcode::Detector;
132  else if(cmd_.get_detector_type() == CmdLine::DMTX)
133  detector = new detectors::datamatrix::Detector;
134 #else // ViSP >= 2.10.0. In that case we use the detectors from ViSP
135  vpDetectorBase *detector = NULL;
137  detector = new vpDetectorQRCode;
138  else if(cmd_.get_detector_type() == CmdLine::DMTX)
139  detector = new vpDetectorDataMatrixCode;
140 #endif
141 
142  // Use the best tracker
143  int trackerType = vpMbGenericTracker::EDGE_TRACKER | vpMbGenericTracker::KLT_TRACKER;
144  tracker = new vpMbGenericTracker(1, trackerType);
145  tracker->setCameraParameters(cam_);
146  tracker->setDisplayFeatures(true);
147 
148  //compile detectors and paramters into the automatic tracker.
149  t_ = new tracking::Tracker(cmd_, detector, tracker, debug_display_);
150  t_->start(); //start the state machine
151 
152  //subscribe to ros topics and prepare a publisher that will publish the pose
155  message_filters::TimeSynchronizer<sensor_msgs::Image, sensor_msgs::CameraInfo> image_info_sync(raw_image_subscriber, camera_info_subscriber, queue_size_);
156  image_info_sync.registerCallback(boost::bind(&Node::frameCallback,this, _1, _2));
157  ros::Publisher object_pose_publisher = n_.advertise<geometry_msgs::PoseStamped>(object_position_topic, queue_size_);
158  ros::Publisher object_pose_covariance_publisher = n_.advertise<geometry_msgs::PoseWithCovarianceStamped>(object_position_covariance_topic, queue_size_);
159  ros::Publisher moving_edge_sites_publisher = n_.advertise<visp_tracker::MovingEdgeSites>(moving_edge_sites_topic, queue_size_);
160  ros::Publisher klt_points_publisher = n_.advertise<visp_tracker::KltPoints>(klt_points_topic, queue_size_);
161  ros::Publisher status_publisher = n_.advertise<std_msgs::Int8>(status_topic, queue_size_);
162  ros::Publisher code_message_publisher = n_.advertise<std_msgs::String>(code_message_topic, queue_size_);
163 
164  //wait for an image to be ready
165  waitForImage();
166  {
167  //when an image is ready tell the tracker to start searching for patterns
168  boost::mutex::scoped_lock(lock_);
169  if(debug_display_) {
170  d->init(I_); //also init display
171  vpDisplay::setTitle(I_, "visp_auto_tracker debug display");
172  }
173 
174  t_->process_event(tracking::select_input(I_));
175  }
176 
177  unsigned int iter=0;
178  geometry_msgs::PoseStamped ps;
179  geometry_msgs::PoseWithCovarianceStamped ps_cov;
180 
181  ros::Rate rate(30); //init 25fps publishing frequency
182  while(ros::ok()){
183  double t = vpTime::measureTimeMs();
184  boost::mutex::scoped_lock(lock_);
185  //process the new frame with the tracker
186  t_->process_event(tracking::input_ready(I_,cam_,iter));
187  //When the tracker is tracking, it's in the tracking::TrackModel state
188  //Access this state and broadcast the pose
189  tracking::TrackModel& track_model = t_->get_state<tracking::TrackModel&>();
190 
191  ps.pose = visp_bridge::toGeometryMsgsPose(track_model.cMo); //convert
192 
193  // Publish resulting pose.
194  if (object_pose_publisher.getNumSubscribers () > 0)
195  {
196  ps.header = image_header_;
197  ps.header.frame_id = tracker_ref_frame_;
198  object_pose_publisher.publish(ps);
199  }
200 
201  // Publish resulting pose covariance matrix.
202  if (object_pose_covariance_publisher.getNumSubscribers () > 0)
203  {
204  ps_cov.pose.pose = ps.pose;
205  ps_cov.header = image_header_;
206  ps_cov.header.frame_id = tracker_ref_frame_;
207 
208  for (unsigned i = 0; i < track_model.covariance.getRows(); ++i)
209  {
210  for (unsigned j = 0; j < track_model.covariance.getCols(); ++j)
211  {
212  unsigned idx = i * track_model.covariance.getCols() + j;
213  if (idx >= 36)
214  continue;
215  ps_cov.pose.covariance[idx] = track_model.covariance[i][j];
216  }
217  }
218 
219  object_pose_covariance_publisher.publish(ps_cov);
220  }
221 
222  // Publish state machine status.
223  if (status_publisher.getNumSubscribers () > 0)
224  {
225  std_msgs::Int8 status;
226  status.data = (unsigned char)(*(t_->current_state()));
227  status_publisher.publish(status);
228  }
229 
230  // Publish moving edge sites.
231  if (moving_edge_sites_publisher.getNumSubscribers () > 0)
232  {
233  visp_tracker::MovingEdgeSitesPtr sites (new visp_tracker::MovingEdgeSites);
234  // Test if we are in the state tracking::TrackModel. In that case the pose is good;
235  // we can send the moving edges. Otherwise we send an empty list of features
236  if (*(t_->current_state()) == 3) {
237  t_->updateMovingEdgeSites(sites);
238  }
239 
240  sites->header = image_header_;
241  moving_edge_sites_publisher.publish(sites);
242  }
243 
244  // Publish KLT points.
245  if (klt_points_publisher.getNumSubscribers () > 0)
246  {
247  visp_tracker::KltPointsPtr klt (new visp_tracker::KltPoints);
248  // Test if we are in the state tracking::TrackModel. In that case the pose is good;
249  // we can send the klt points. Otherwise we send an empty list of features
250  if (*(t_->current_state()) == 3) {
251  t_->updateKltPoints(klt);
252  }
253  klt->header = image_header_;
254  klt_points_publisher.publish(klt);
255  }
256 
257  if (code_message_publisher.getNumSubscribers() > 0)
258  {
259  std_msgs::String message;
260  if (*(t_->current_state()) == 3) { // Tracking successful
261 #if VISP_VERSION_INT < VP_VERSION_INT(2,10,0)
262  message.data = detector->get_message();
263 #else
264  message.data = detector->getMessage( cmd_.get_code_message_index() );
265 #endif
266  }
267  else {
268  message.data = std::string();
269  }
270  code_message_publisher.publish(message);
271  ROS_INFO_STREAM("Code with message \"" << message.data << "\" under tracking");
272  }
273 
274  ros::spinOnce();
275  rate.sleep();
276  if (cmd_.show_fps())
277  std::cout << "Tracking done in " << vpTime::measureTimeMs() - t << " ms" << std::endl;
278  }
279  t_->process_event(tracking::finished());
280  if(debug_display_) {
281  delete d;
282  }
283  delete tracker;
284  }
285 }
d
std::string klt_points_topic
size_t get_code_message_index() const
Definition: cmd_line.cpp:343
void publish(const boost::shared_ptr< M > &message) const
vpCameraParameters toVispCameraParameters(const sensor_msgs::CameraInfo &cam_info)
std::string tracker_config_path_
Definition: node.h:24
tracking::Tracker * t_
Definition: node.h:38
std::string object_position_covariance_topic
std::string camera_info_topic
msm::back::state_machine< Tracker_ > Tracker
Definition: tracking.h:182
ros::NodeHandle n_
Definition: node.h:22
std::string status_topic
std::string model_name_
Definition: node.h:27
void init(std::string &config_file)
Definition: cmd_line.cpp:135
bool should_exit() const
Definition: cmd_line.cpp:226
geometry_msgs::Pose toGeometryMsgsPose(const vpHomogeneousMatrix &mat)
std::string code_message_topic
Connection registerCallback(C &callback)
boost::shared_array< uint8_t > data
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
vpCameraParameters cam_
Definition: node.h:36
std::string code_message_
Definition: node.h:28
ROSCPP_DECL bool ok()
void set_pattern_name(std::string &name)
Definition: cmd_line.cpp:363
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_WARN_STREAM(args)
std::string object_position_topic
bool sleep()
std::string model_path_
Definition: node.h:26
MemoryResource get(const std::string &url)
void set_show_fps(bool show_fps)
Definition: cmd_line.cpp:366
boost::mutex lock_
Definition: node.h:21
vpImage< vpRGBa > I_
Definition: node.h:33
uint32_t getNumSubscribers() const
#define ROS_INFO_STREAM(args)
void set_data_directory(std::string &dir)
Definition: cmd_line.cpp:359
std::string image_topic
std::string model_description_
Definition: node.h:25
bool show_fps() const
Definition: cmd_line.cpp:234
#define ROS_ERROR_STREAM(args)
ROSCPP_DECL void spinOnce()
r
void set_code_message(const std::string &msg)
Definition: cmd_line.cpp:370
std::string moving_edge_sites_topic
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
std::string tracker_ref_frame_
Definition: node.h:29
vpImage< vpRGBa > toVispImageRGBa(const sensor_msgs::Image &src)
unsigned long queue_size_
Definition: node.h:23
DETECTOR_TYPE get_detector_type() const
Definition: cmd_line.cpp:307
std_msgs::Header image_header_
Definition: node.h:34
void frameCallback(const sensor_msgs::ImageConstPtr &image, const sensor_msgs::CameraInfoConstPtr &cam_info)
Definition: node.cpp:107
std::string get_mbt_cad_file() const
Definition: cmd_line.cpp:270


visp_auto_tracker
Author(s): Filip Novotny
autogenerated on Sat Mar 13 2021 03:20:08