visual-tracking-control
VisualSIS.cpp
Go to the documentation of this file.
1 #include <VisualSIS.h>
2 
3 #include <exception>
4 #include <iostream>
5 #include <utility>
6 
7 #include <Eigen/Dense>
8 #include <iCub/ctrl/math.h>
9 #include <opencv2/core/core.hpp>
10 #include <opencv2/core/cuda.hpp>
11 #include <opencv2/core/eigen.hpp>
12 #include <opencv2/imgproc/imgproc.hpp>
13 #include <opencv2/cudaimgproc.hpp>
14 #include <opencv2/cudawarping.hpp>
15 #include <yarp/eigen/Eigen.h>
16 #include <yarp/math/Math.h>
17 #include <yarp/os/Time.h>
18 
19 using namespace bfl;
20 using namespace cv;
21 using namespace Eigen;
22 using namespace iCub::ctrl;
23 using namespace iCub::iKin;
24 using namespace yarp::eigen;
25 using namespace yarp::math;
26 using namespace yarp::os;
27 using yarp::sig::Vector;
28 using yarp::sig::ImageOf;
29 using yarp::sig::PixelRgb;
30 
31 
32 VisualSIS::VisualSIS(const yarp::os::ConstString& cam_sel,
33  const int img_width, const int img_height,
34  const int num_particles,
35  const double resample_ratio) :
36  cam_sel_(cam_sel),
37  img_width_(img_width),
38  img_height_(img_height),
39  num_particles_(num_particles),
40  resample_ratio_(resample_ratio)
41 {
43 
44 
45  cuda_hog_ = cuda::HOG::create(Size(img_width_, img_height_), Size(block_size_, block_size_), Size(block_size_/2, block_size_/2), Size(block_size_/2, block_size_/2), bin_number_);
46  cuda_hog_->setDescriptorFormat(cuda::HOG::DESCR_FORMAT_ROW_BY_ROW);
47  cuda_hog_->setGammaCorrection(true);
48  cuda_hog_->setWinStride(Size(img_width_, img_height_));
49 
50 
51  port_image_in_.open ("/hand-tracking/" + cam_sel_ + "/img:i");
52  port_estimates_out_.open("/hand-tracking/" + cam_sel_ + "/result/estimates:o");
53 
54  img_in_.resize(320, 240);
55  img_in_.zero();
56 
58 }
59 
60 
62 {
63  pred_particle_ = MatrixXf(7, num_particles_);
64  pred_weight_ = VectorXf(num_particles_, 1);
65 
66  cor_particle_ = MatrixXf(7, num_particles_);
67  cor_weight_ = VectorXf(num_particles_, 1);
68 
69  estimate_extraction_.clear();
70 
71  initialization_->initialize(pred_particle_, pred_weight_);
72 
73  prediction_->getExogenousModel().setProperty("ICFW_INIT");
74 
75  skip("all", false);
76 }
77 
78 
80 {
81  port_image_in_.close();
82  port_estimates_out_.close();
83 }
84 
85 
87 {
88  std::vector<float> descriptors_cam_left (descriptor_length_);
89  cuda::GpuMat cuda_img (Size(img_width_, img_height_), CV_8UC3);
90  cuda::GpuMat cuda_img_alpha (Size(img_width_, img_height_), CV_8UC4);
91  cuda::GpuMat descriptors_cam_cuda (Size(descriptor_length_, 1), CV_32F );
92 
93 
94  ImageOf<PixelRgb>* tmp_imgin = YARP_NULLPTR;
95  tmp_imgin = port_image_in_.read(false);
96  if (tmp_imgin != YARP_NULLPTR)
97  {
98  init_img_in_ = true;
99  img_in_ = *tmp_imgin;
100  }
101 
102  if (init_img_in_)
103  {
104  /* PROCESS CURRENT MEASUREMENT */
105  Mat measurement;
106 
107  measurement = cvarrToMat(img_in_.getIplImage());
108  cuda_img.upload(measurement);
109  cuda::resize(cuda_img, cuda_img, Size(img_width_, img_height_));
110  cuda::cvtColor(cuda_img, cuda_img_alpha, COLOR_BGR2BGRA, 4);
111  cuda_hog_->compute(cuda_img_alpha, descriptors_cam_cuda);
112  descriptors_cam_cuda.download(descriptors_cam_left);
113 
114  /* PREDICTION */
115  if (getFilteringStep() != 0)
116  prediction_->predict(cor_particle_, cor_weight_,
118 
119  /* CORRECTION */
120  correction_->getVisualObservationModel().setProperty("VP_PARAMS");
121  correction_->correct(pred_particle_, pred_weight_, descriptors_cam_left,
123  cor_weight_ /= cor_weight_.sum();
124 
125 
126  /* STATE ESTIMATE EXTRACTION FROM PARTICLE SET */
127  VectorXf out_particle = estimate_extraction_.extract(cor_particle_, cor_weight_);
128 
129 
130  /* RESAMPLING */
131  std::cout << "Step: " << getFilteringStep() << std::endl;
132  std::cout << "Neff: " << resampling_->neff(cor_weight_) << std::endl;
133  if (resampling_->neff(cor_weight_) < std::round(num_particles_ * resample_ratio_))
134  {
135  std::cout << "Resampling!" << std::endl;
136 
137  MatrixXf res_particle(7, num_particles_);
138  VectorXf res_weight(num_particles_, 1);
139  VectorXf res_parent(num_particles_, 1);
140 
141  resampling_->resample(cor_particle_, cor_weight_,
142  res_particle, res_weight,
143  res_parent);
144 
145  cor_particle_ = res_particle;
146  cor_weight_ = res_weight;
147  }
148 
149  /* STATE ESTIMATE OUTPUT */
150  /* INDEX FINGERTIP */
151 // Vector q = readRootToEE();
152 // icub_kin_arm_.setAng(q.subVector(0, 9) * (M_PI/180.0));
153 // Vector chainjoints;
154 // if (analogs_) icub_kin_finger_[1].getChainJoints(q.subVector(3, 18), analogs, chainjoints, right_hand_analogs_bounds_);
155 // else icub_kin_finger_[1].getChainJoints(q.subVector(3, 18), chainjoints);
156 // icub_kin_finger_[1].setAng(chainjoints * (M_PI/180.0));
157 //
158 // Vector l_ee_t(3);
159 // toEigen(l_ee_t) = out_particle.col(0).head(3).cast<double>();
160 // l_ee_t.push_back(1.0);
161 //
162 // Vector l_ee_o(3);
163 // toEigen(l_ee_o) = out_particle.col(0).tail(3).normalized().cast<double>();
164 // l_ee_o.push_back(static_cast<double>(out_particle.col(0).tail(3).norm()));
165 //
166 // yarp::sig::Matrix l_Ha = axis2dcm(l_ee_o);
167 // l_Ha.setCol(3, l_ee_t);
168 // Vector l_i_x = (l_Ha * (icub_kin_finger_[1].getH(3, true).getCol(3))).subVector(0, 2);
169 // Vector l_i_o = dcm2axis(l_Ha * icub_kin_finger_[1].getH(3, true));
170 // l_i_o.setSubvector(0, l_i_o.subVector(0, 2) * l_i_o[3]);
171 //
172 //
173 // Vector r_ee_t(3);
174 // toEigen(r_ee_t) = out_particle.col(1).head(3).cast<double>();
175 // r_ee_t.push_back(1.0);
176 //
177 // Vector r_ee_o(3);
178 // toEigen(r_ee_o) = out_particle.col(1).tail(3).normalized().cast<double>();
179 // r_ee_o.push_back(static_cast<double>(out_particle.col(1).tail(3).norm()));
180 //
181 // yarp::sig::Matrix r_Ha = axis2dcm(r_ee_o);
182 // r_Ha.setCol(3, r_ee_t);
183 // Vector r_i_x = (r_Ha * (icub_kin_finger_[1].getH(3, true).getCol(3))).subVector(0, 2);
184 // Vector r_i_o = dcm2axis(r_Ha * icub_kin_finger_[1].getH(3, true));
185 // r_i_o.setSubvector(0, r_i_o.subVector(0, 2) * r_i_o[3]);
186 //
187 //
188 // Vector& estimates_out = port_estimates_out_.prepare();
189 // estimates_out.resize(12);
190 // estimates_out.setSubvector(0, l_i_x);
191 // estimates_out.setSubvector(3, l_i_o.subVector(0, 2));
192 // estimates_out.setSubvector(6, r_i_x);
193 // estimates_out.setSubvector(9, r_i_o.subVector(0, 2));
194 // port_estimates_out_.write();
195 
196  /* PALM */
197  Vector& estimates_out = port_estimates_out_.prepare();
198  estimates_out.resize(7);
199  toEigen(estimates_out) = out_particle.cast<double>();
200  port_estimates_out_.write();
201  /* ********** */
202  }
203 }
204 
205 
207 
208 
209 bool VisualSIS::attach(yarp::os::Port &source)
210 {
211  return this->yarp().attachAsServer(source);
212 }
213 
214 
216 {
217  std::cout << "Opening RPC command port." << std::endl;
218  if (!port_rpc_command_.open("/hand-tracking/" + cam_sel_ + "/cmd:i"))
219  {
220  std::cerr << "Cannot open the RPC command port." << std::endl;
221  return false;
222  }
224  {
225  std::cerr << "Cannot attach the RPC command port." << std::endl;
226  return false;
227  }
228  std::cout << "RPC command port opened and attached. Ready to recieve commands!" << std::endl;
229 
230  return true;
231 }
232 
233 
235 {
236  run();
237 
238  return true;
239 }
240 
241 
243 {
244  reset();
245 
246  return true;
247 }
248 
249 
251 {
252  reboot();
253 
254  return true;
255 }
256 
257 
258 bool VisualSIS::skip_step(const std::string& what_step, const bool status)
259 {
260  return skip(what_step, status);
261 }
262 
263 
264 bool VisualSIS::use_analogs(const bool status)
265 {
266  if (status)
267  return correction_->getVisualObservationModel().setProperty("VP_ANALOGS_ON");
268  else
269  return correction_->getVisualObservationModel().setProperty("VP_ANALOGS_OFF");
270 }
271 
272 
273 std::vector<std::string> VisualSIS::get_info()
274 {
275  std::vector<std::string> info;
276 
277  info.push_back("<| Information about Visual SIR Particle Filter |>");
278  info.push_back("<| The Particle Filter is " + std::string(isRunning() ? "not " : "") + "running |>");
279  info.push_back("<| Filtering step: " + std::to_string(getFilteringStep()) + " |>");
280  info.push_back("<| Using " + cam_sel_ + " camera images |>");
281  info.push_back("<| Using " + std::to_string(num_particles_) + " particles |>");
282 
283  std::vector<std::string> est_ext_info = estimate_extraction_.getInfo();
284 
285  info.insert(info.end(), est_ext_info.begin(), est_ext_info.end());
286 
287  return info;
288 }
289 
290 
291 bool VisualSIS::set_estimates_extraction_method(const std::string& method)
292 {
293  if (method == "mean")
294  {
295  estimate_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::mean);
296 
297  return true;
298  }
299  else if (method == "smean")
300  {
301  estimate_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::smean);
302 
303  return true;
304  }
305  else if (method == "wmean")
306  {
307  estimate_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::wmean);
308 
309  return true;
310  }
311  else if (method == "emean")
312  {
313  estimate_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::emean);
314 
315  return true;
316  }
317  else if (method == "mode")
318  {
319  estimate_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::mode);
320 
321  return true;
322  }
323  else if (method == "smode")
324  {
325  estimate_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::smode);
326 
327  return true;
328  }
329  else if (method == "wmode")
330  {
331  estimate_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::wmode);
332 
333  return true;
334  }
335  else if (method == "emode")
336  {
337  estimate_extraction_.setMethod(EstimatesExtraction::ExtractionMethod::emode);
338 
339  return true;
340  }
341 
342  return false;
343 }
344 
345 
346 bool VisualSIS::set_mobile_average_window(const int16_t window)
347 {
348  if (window > 0)
349  return estimate_extraction_.setMobileAverageWindowSize(window);
350  else
351  return false;
352 }
353 
354 
356 {
357  return teardown();
358 }
int img_width_
Definition: VisualSIS.h:48
bool init_img_in_
Definition: VisualSIS.h:99
Eigen::MatrixXf pred_particle_
Definition: VisualSIS.h:89
bool skip_step(const std::string &what_step, const bool status) override
Enable/Disable skipping the filtering step specified in what_step.
Definition: VisualSIS.cpp:258
bool reset_filter() override
Reset the visual SIR particle filter.
Definition: VisualSIS.cpp:242
int num_particles_
Definition: VisualSIS.h:50
Eigen::VectorXf pred_weight_
Definition: VisualSIS.h:90
bool run_filter() override
Initialize and run the visual SIR particle filter.
Definition: VisualSIS.cpp:234
cv::Ptr< cv::cuda::HOG > cuda_hog_
Definition: VisualSIS.h:57
void getResult() override
Definition: VisualSIS.cpp:206
double resample_ratio_
Definition: VisualSIS.h:52
yarp::os::ConstString cam_sel_
Definition: VisualSIS.h:44
const int block_size_
Definition: VisualSIS.h:54
bool use_analogs(const bool status) override
Use/Don&#39;t use the analog values from the right hand to correct the finger poses.
Definition: VisualSIS.cpp:264
void filteringStep() override
Definition: VisualSIS.cpp:86
const int bin_number_
Definition: VisualSIS.h:55
std::vector< std::string > get_info() override
Get information about recursive Bayesian filter, like it&#39;s status, the available methods, and the current one in use, to extract the state estimate from the particle set.
Definition: VisualSIS.cpp:273
yarp::os::Port port_rpc_command_
Definition: VisualSIS.h:64
bool quit() override
Gently close the application, deallocating resources.
Definition: VisualSIS.cpp:355
int img_height_
Definition: VisualSIS.h:49
VisualSIS(const yarp::os::ConstString &cam_sel, const int img_width, const int img_height, const int num_particles, const double resample_ratio)
Definition: VisualSIS.cpp:32
yarp::sig::ImageOf< yarp::sig::PixelRgb > img_in_
Definition: VisualSIS.h:100
bool attach(yarp::os::Port &source)
Definition: VisualSIS.cpp:209
bfl::EstimatesExtraction estimate_extraction_
Definition: VisualSIS.h:96
~VisualSIS() noexcept
Definition: VisualSIS.cpp:79
Eigen::VectorXf cor_weight_
Definition: VisualSIS.h:93
Eigen::MatrixXf cor_particle_
Definition: VisualSIS.h:92
bool set_estimates_extraction_method(const std::string &method) override
Change the current method to extract the state estimates from the particle set.
Definition: VisualSIS.cpp:291
yarp::os::BufferedPort< yarp::sig::Vector > port_estimates_out_
Definition: VisualSIS.h:60
bool set_mobile_average_window(const int16_t window) override
Change the window size of mobile averages for estimates extraction.
Definition: VisualSIS.cpp:346
unsigned int descriptor_length_
Definition: VisualSIS.h:51
yarp::os::BufferedPort< yarp::sig::ImageOf< yarp::sig::PixelRgb > > port_image_in_
Definition: VisualSIS.h:61
void initialization() override
Definition: VisualSIS.cpp:61
bool setCommandPort()
Definition: VisualSIS.cpp:215
bool stop_filter() override
Stop and reset the SIR particle filter.
Definition: VisualSIS.cpp:250