YARP
Yet Another Robot Platform
RGBDSensorWrapper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #include "RGBDSensorWrapper.h"
10 #include <sstream>
11 #include <cstdio>
12 #include <cstring>
13 #include <yarp/os/LogComponent.h>
14 #include <yarp/os/LogStream.h>
15 #include <yarp/dev/GenericVocabs.h>
17 #include "rosPixelCode.h"
18 
19 using namespace RGBDImpl;
20 using namespace yarp::sig;
21 using namespace yarp::dev;
22 using namespace yarp::os;
23 using namespace std;
24 
25 
26 #define RGBD_INTERFACE_PROTOCOL_VERSION_MAJOR 1
27 #define RGBD_INTERFACE_PROTOCOL_VERSION_MINOR 0
28 
29 YARP_LOG_COMPONENT(RGBDSENSORWRAPPER, "yarp.devices.RGBDSensorWrapper")
30 
31 
33  iRGBDSensor(nullptr)
34 {
35 }
36 
38 {
39  bool ret;
40  iRGBDSensor = interface;
41  ret = rgbParser.configure(interface);
42  ret &= depthParser.configure(interface);
43  return ret;
44 }
45 
47 {
48  bool ret = rgbParser.configure(rgbInterface);
49  ret &= depthParser.configure(depthInterface);
50  return ret;
51 }
52 
54 {
55  return fgCtrlParsers.configure(_fgCtrl);
56 }
57 
58 bool RGBDSensorParser::respond(const Bottle& cmd, Bottle& response)
59 {
60  bool ret = false;
61  int interfaceType = cmd.get(0).asVocab();
62 
63  response.clear();
64  switch(interfaceType)
65  {
67  {
68  // forwarding to the proper parser.
69  ret = rgbParser.respond(cmd, response);
70  }
71  break;
72 
74  {
75  // forwarding to the proper parser.
76  ret = depthParser.respond(cmd, response);
77  }
78  break;
79 
81  {
82  // forwarding to the proper parser.
83  ret = fgCtrlParsers.respond(cmd, response);
84  }
85  break;
86 
87  case VOCAB_RGBD_SENSOR:
88  {
89  switch (cmd.get(1).asVocab())
90  {
91  case VOCAB_GET:
92  {
93  switch(cmd.get(2).asVocab())
94  {
96  {
97  yarp::sig::Matrix params;
98  ret = iRGBDSensor->getExtrinsicParam(params);
99  if(ret)
100  {
101  yarp::os::Bottle params_b;
102  response.addVocab(VOCAB_RGBD_SENSOR);
104  response.addVocab(VOCAB_IS);
105  ret &= Property::copyPortable(params, params_b); // will it really work??
106  response.append(params_b);
107  }
108  else
109  response.addVocab(VOCAB_FAILED);
110  }
111  break;
112 
113  case VOCAB_ERROR_MSG:
114  {
115  response.addVocab(VOCAB_RGBD_SENSOR);
116  response.addVocab(VOCAB_ERROR_MSG);
117  response.addVocab(VOCAB_IS);
118  response.addString(iRGBDSensor->getLastErrorMsg());
119  ret = true;
120  }
121  break;
122 
124  {
125  response.addVocab(VOCAB_RGBD_SENSOR);
127  response.addVocab(VOCAB_IS);
130  }
131  break;
132 
133  case VOCAB_STATUS:
134  {
135  response.addVocab(VOCAB_RGBD_SENSOR);
136  response.addVocab(VOCAB_STATUS);
137  response.addVocab(VOCAB_IS);
138  response.addInt32(iRGBDSensor->getSensorStatus());
139  }
140  break;
141 
142  default:
143  {
144  yCError(RGBDSENSORWRAPPER) << "RGBDSensor interface parser received an unknown GET command. Command is " << cmd.toString();
145  response.addVocab(VOCAB_FAILED);
146  }
147  break;
148  }
149  }
150  break;
151 
152  case VOCAB_SET:
153  {
154  yCError(RGBDSENSORWRAPPER) << "RGBDSensor interface parser received an unknown SET command. Command is " << cmd.toString();
155  response.addVocab(VOCAB_FAILED);
156  }
157  break;
158  }
159  }
160  break;
161 
162  default:
163  {
164  yCError(RGBDSENSORWRAPPER) << "RGBD sensor wrapper received a command for a wrong interface " << yarp::os::Vocab::decode(interfaceType);
165  return DeviceResponder::respond(cmd,response);
166  }
167  break;
168  }
169  return ret;
170 }
171 
172 
175  rosNode(nullptr),
176  nodeSeq(0),
177  period(DEFAULT_THREAD_PERIOD),
178  sensor_p(nullptr),
179  fgCtrl(nullptr),
180  sensorStatus(IRGBDSensor::RGBD_SENSOR_NOT_READY),
181  verbose(4),
182  use_YARP(true),
183  use_ROS(false),
184  forceInfoSync(true),
185  isSubdeviceOwned(false),
186  subDeviceOwned(nullptr)
187 {}
188 
190 {
191  close();
192  sensor_p = nullptr;
193  fgCtrl = nullptr;
194 }
195 
199 {
200 // DeviceResponder::makeUsage();
201 // addUsage("[set] [bri] $fBrightness", "set brightness");
202 // addUsage("[set] [expo] $fExposure", "set exposure");
203 //
204  m_conf.fromString(config.toString());
205  if(verbose >= 5)
206  yCTrace(RGBDSENSORWRAPPER) << "\nParameters are: \n" << config.toString();
207 
208  if(!fromConfig(config))
209  {
210  yCError(RGBDSENSORWRAPPER) << "Device RGBDSensorWrapper failed to open, check previous log for error messages.";
211  return false;
212  }
213 
214  setId("RGBDSensorWrapper for " + depthFrame_StreamingPort_Name);
215 
216  if(use_YARP && !initialize_YARP(config))
217  {
218  yCError(RGBDSENSORWRAPPER) << sensorId << "Error initializing YARP ports";
219  return false;
220  }
221 
222  if(use_ROS && !initialize_ROS(config))
223  {
224  yCError(RGBDSENSORWRAPPER) << sensorId << "Error initializing ROS topic";
225  return false;
226  }
227 
228  // check if we need to create subdevice or if they are
229  // passed later on thorugh attachAll()
230  if(isSubdeviceOwned)
231  {
232  if(! openAndAttachSubDevice(config))
233  {
234  yCError(RGBDSENSORWRAPPER, "RGBDSensorWrapper: error while opening subdevice");
235  return false;
236  }
237  }
238  else
239  {
240  if(!openDeferredAttach(config))
241  return false;
242  }
243 
244  return true;
245 }
246 
248 {
249  if (!config.check("period", "refresh period of the broadcasted values in ms"))
250  {
251  if(verbose >= 3)
252  yCInfo(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: using default 'period' parameter of " << DEFAULT_THREAD_PERIOD << "s";
253  }
254  else
255  period = config.find("period").asInt32() / 1000.0;
256 
257  Bottle &rosGroup = config.findGroup("ROS");
258  if(rosGroup.isNull())
259  {
260  if(verbose >= 3)
261  yCInfo(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: ROS configuration parameters are not set, skipping ROS topic initialization.";
262  use_ROS = false;
263  use_YARP = true;
264  }
265  else
266  {
267  //if(verbose >= 2)
268  // yCWarning(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: ROS topic support is not yet implemented";
269 
270  string confUseRos;
271 
272  if (!rosGroup.check("use_ROS"))
273  {
274  yCError(RGBDSENSORWRAPPER)<<"RGBDSensorWrapper: missing use_ROS parameter";
275  return false;
276  }
277 
278  confUseRos = rosGroup.find("use_ROS").asString();
279 
280  if (confUseRos == "true" || confUseRos == "only")
281  {
282  use_ROS = true;
283  use_YARP = confUseRos == "true" ? true : false;
284  }
285  else
286  {
287  use_ROS = false;
288  if (verbose >= 3 && confUseRos != "false")
289  {
290  yCInfo(RGBDSENSORWRAPPER, "'use_ROS' value not understood.. skipping ROS topic initialization");
291  }
292  }
293  }
294 
295  if (use_ROS)
296  {
297  //check if param exist and assign it to corresponding variable.. if it doesn't, initialize the variable with default value.
298  unsigned int i;
299  std::vector<param<string> > rosStringParam;
300  param<string>* prm;
301 
302  rosStringParam.emplace_back(nodeName, nodeName_param );
303  rosStringParam.emplace_back(rosFrameId, frameId_param );
304  rosStringParam.emplace_back(colorTopicName, colorTopicName_param );
305  rosStringParam.emplace_back(depthTopicName, depthTopicName_param );
306  rosStringParam.emplace_back(cInfoTopicName, colorInfoTopicName_param);
307  rosStringParam.emplace_back(dInfoTopicName, depthInfoTopicName_param);
308 
309  for (i = 0; i < rosStringParam.size(); i++)
310  {
311  prm = &rosStringParam[i];
312  if (!rosGroup.check(prm->parname))
313  {
314  if(verbose >= 3)
315  {
316  yCError(RGBDSENSORWRAPPER) << "missing " << prm->parname << "check your configuration file, not using ROS";
317  }
318  use_ROS = false;
319  return false;
320  }
321  *(prm->var) = rosGroup.find(prm->parname).asString();
322  }
323 
324  if (rosGroup.check("forceInfoSync"))
325  {
326  forceInfoSync = rosGroup.find("forceInfoSync").asBool();
327  }
328  }
329 
330  if(use_YARP)
331  {
332  std::string rootName;
333  rootName = config.check("name",Value("/"), "starting '/' if needed.").asString();
334 
335  if (!config.check("name", "Prefix name of the ports opened by the RGBD wrapper."))
336  {
337  yCError(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: missing 'name' parameter. Check you configuration file; it must be like:";
338  yCError(RGBDSENSORWRAPPER) << " name: Prefix name of the ports opened by the RGBD wrapper, e.g. /robotName/RGBD";
339  return false;
340  }
341  else
342  {
343  rootName = config.find("name").asString();
344  rpcPort_Name = rootName + "/rpc:i";
345  colorFrame_StreamingPort_Name = rootName + "/rgbImage:o";
346  depthFrame_StreamingPort_Name = rootName + "/depthImage:o";
347  }
348  }
349 
350  if(config.check("subdevice"))
351  isSubdeviceOwned=true;
352  else
353  isSubdeviceOwned=false;
354 
355  return true;
356 }
357 
358 bool RGBDSensorWrapper::openDeferredAttach(Searchable& prop)
359 {
360  // I dunno what to do here now...
361  isSubdeviceOwned = false;
362  return true;
363 }
364 
365 bool RGBDSensorWrapper::openAndAttachSubDevice(Searchable& prop)
366 {
367  Property p;
368  subDeviceOwned = new PolyDriver;
369  p.fromString(prop.toString());
370 
371  p.setMonitor(prop.getMonitor(), "subdevice"); // pass on any monitoring
372  p.unput("device");
373  p.put("device",prop.find("subdevice").asString()); // subdevice was already checked before
374 
375  // if errors occurred during open, quit here.
376  yCDebug(RGBDSENSORWRAPPER, "opening IRGBDSensor subdevice");
377  subDeviceOwned->open(p);
378 
379  if (!subDeviceOwned->isValid())
380  {
381  yCError(RGBDSENSORWRAPPER, "opening IRGBDSensor subdevice... FAILED");
382  return false;
383  }
384  isSubdeviceOwned = true;
385  if(!attach(subDeviceOwned))
386  return false;
387 
388  return true;
389 }
390 
392 {
393  yCTrace(RGBDSENSORWRAPPER, "RGBDSensorWrapper::Close");
394  detachAll();
395 
396  // close subdevice if it was created inside the open (--subdevice option)
397  if(isSubdeviceOwned)
398  {
399  if(subDeviceOwned)
400  {
401  delete subDeviceOwned;
402  subDeviceOwned=nullptr;
403  }
404  sensor_p = nullptr;
405  fgCtrl = nullptr;
406  isSubdeviceOwned = false;
407  }
408 
409  // Closing port
410  if(use_YARP)
411  {
412  rpcPort.interrupt();
413  colorFrame_StreamingPort.interrupt();
414  depthFrame_StreamingPort.interrupt();
415 
416  rpcPort.close();
417  colorFrame_StreamingPort.close();
418  depthFrame_StreamingPort.close();
419  }
420 
421  if(rosNode!=nullptr)
422  {
423  rosNode->interrupt();
424  delete rosNode;
425  rosNode = nullptr;
426  }
427 
428  // Closing ROS topic
429  if(use_ROS)
430  {
431  // bla bla bla
432  }
433  //
434  return true;
435 }
436 
437 /* Helper functions */
438 
439 bool RGBDSensorWrapper::initialize_YARP(yarp::os::Searchable &params)
440 {
441  // Open ports
442  bool bRet;
443  bRet = true;
444  if(!rpcPort.open(rpcPort_Name))
445  {
446  yCError(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: unable to open rpc Port" << rpcPort_Name.c_str();
447  bRet = false;
448  }
449  rpcPort.setReader(rgbdParser);
450 
451  if(!colorFrame_StreamingPort.open(colorFrame_StreamingPort_Name))
452  {
453  yCError(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: unable to open color streaming Port" << colorFrame_StreamingPort_Name.c_str();
454  bRet = false;
455  }
456  if(!depthFrame_StreamingPort.open(depthFrame_StreamingPort_Name))
457  {
458  yCError(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: unable to open depth streaming Port" << depthFrame_StreamingPort_Name.c_str();
459  bRet = false;
460  }
461 
462  return bRet;
463 }
464 
465 bool RGBDSensorWrapper::initialize_ROS(yarp::os::Searchable &params)
466 {
467  // open topics here if needed
468  rosNode = new yarp::os::Node(nodeName);
469  nodeSeq = 0;
470  if (!rosPublisherPort_color.topic(colorTopicName))
471  {
472  yCError(RGBDSENSORWRAPPER) << " Unable to publish data on " << colorTopicName.c_str() << " topic, check your yarp-ROS network configuration";
473  return false;
474  }
475  if (!rosPublisherPort_depth.topic(depthTopicName))
476  {
477  yCError(RGBDSENSORWRAPPER) << " Unable to publish data on " << depthTopicName.c_str() << " topic, check your yarp-ROS network configuration";
478  return false;
479  }
480  if (!rosPublisherPort_colorCaminfo.topic(cInfoTopicName))
481  {
482  yCError(RGBDSENSORWRAPPER) << " Unable to publish data on " << cInfoTopicName.c_str() << " topic, check your yarp-ROS network configuration";
483  return false;
484  }
485  if (!rosPublisherPort_depthCaminfo.topic(dInfoTopicName))
486  {
487  yCError(RGBDSENSORWRAPPER) << " Unable to publish data on " << dInfoTopicName.c_str() << " topic, check your yarp-ROS network configuration";
488  return false;
489  }
490  return true;
491 }
492 
493 void RGBDSensorWrapper::setId(const std::string &id)
494 {
495  sensorId=id;
496 }
497 
499 {
500  return sensorId;
501 }
502 
507 {
508  // First implementation only accepts devices with both the interfaces Framegrabber and IDepthSensor,
509  // on a second version maybe two different devices could be accepted, one for each interface.
510  // Yet to be defined which and how parameters shall be used in this case ... using the name of the
511  // interface to view could be a good initial guess.
512  if (device2attach.size() != 1)
513  {
514  yCError(RGBDSENSORWRAPPER, "RGBDSensorWrapper: cannot attach more than one device");
515  return false;
516  }
517 
518  yarp::dev::PolyDriver * Idevice2attach = device2attach[0]->poly;
519  if(device2attach[0]->key == "IRGBDSensor")
520  {
521  yCInfo(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: Good name!";
522  }
523  else
524  {
525  yCInfo(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: Bad name!";
526  }
527 
528  if (!Idevice2attach->isValid())
529  {
530  yCError(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: Device " << device2attach[0]->key << " to attach to is not valid ... cannot proceed";
531  return false;
532  }
533 
534  Idevice2attach->view(sensor_p);
535  Idevice2attach->view(fgCtrl);
536  if(!attach(sensor_p))
537  return false;
538 
539  PeriodicThread::setPeriod(period);
540  return PeriodicThread::start();
541 }
542 
544 {
547 
548  //check if we already instantiated a subdevice previously
549  if (isSubdeviceOwned)
550  return false;
551 
552  sensor_p = nullptr;
553  return true;
554 }
555 
557 {
558  if(s == nullptr)
559  {
560  yCError(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: attached device has no valid IRGBDSensor interface.";
561  return false;
562  }
563  sensor_p = s;
564  if(!rgbdParser.configure(sensor_p))
565  {
566  yCError(RGBDSENSORWRAPPER) << "RGBD wrapper: error configuring interfaces for parsers";
567  return false;
568  }
569  if (fgCtrl)
570  {
571  if(!rgbdParser.configure(fgCtrl))
572  {
573  yCError(RGBDSENSORWRAPPER) << "RGBD wrapper: error configuring interfaces for parsers";
574  return false;
575  }
576  }
577 
578  PeriodicThread::setPeriod(period);
579  return PeriodicThread::start();
580 }
581 
583 {
584  if(poly)
585  {
586  poly->view(sensor_p);
587  poly->view(fgCtrl);
588  }
589 
590  if(sensor_p == nullptr)
591  {
592  yCError(RGBDSENSORWRAPPER) << "RGBDSensorWrapper: attached device has no valid IRGBDSensor interface.";
593  return false;
594  }
595 
596  if(!rgbdParser.configure(sensor_p))
597  {
598  yCError(RGBDSENSORWRAPPER) << "RGBD wrapper: error configuring IRGBD interface";
599  return false;
600  }
601 
602  if (!rgbdParser.configure(fgCtrl))
603  {
604  yCWarning(RGBDSENSORWRAPPER) <<"RGBDWrapper: interface IFrameGrabberControl not implemented by the device";
605  }
606 
607  PeriodicThread::setPeriod(period);
608  return PeriodicThread::start();
609 }
610 
612 {
613  sensor_p = nullptr;
614  return true;
615 }
616 
617 /* IRateThread interface */
618 
620 {
621  // Get interface from attached device if any.
622  return true;
623 }
624 
626 {
627  // Detach() calls stop() which in turns calls this functions, therefore no calls to detach here!
628 }
629 
630 string RGBDSensorWrapper::yarp2RosPixelCode(int code)
631 {
632  switch(code)
633  {
634  case VOCAB_PIXEL_BGR:
635  return BGR8;
636  case VOCAB_PIXEL_BGRA:
637  return BGRA8;
639  return BAYER_BGGR16;
641  return BAYER_BGGR8;
643  return BAYER_GBRG16;
645  return BAYER_GBRG8;
647  return BAYER_GRBG16;
649  return BAYER_GRBG8;
651  return BAYER_RGGB16;
653  return BAYER_RGGB8;
654  case VOCAB_PIXEL_MONO:
655  return MONO8;
656  case VOCAB_PIXEL_MONO16:
657  return MONO16;
658  case VOCAB_PIXEL_RGB:
659  return RGB8;
660  case VOCAB_PIXEL_RGBA:
661  return RGBA8;
663  return TYPE_32FC1;
664  default:
665  return RGB8;
666  }
667 }
668 
669 void RGBDSensorWrapper::shallowCopyImages(const yarp::sig::FlexImage& src, yarp::sig::FlexImage& dest)
670 {
671  dest.setPixelCode(src.getPixelCode());
672  dest.setQuantum(src.getQuantum());
673  dest.setExternal(src.getRawImage(), src.width(), src.height());
674 }
675 
676 void RGBDSensorWrapper::shallowCopyImages(const ImageOf<PixelFloat>& src, ImageOf<PixelFloat>& dest)
677 {
678  dest.setQuantum(src.getQuantum());
679  dest.setExternal(src.getRawImage(), src.width(), src.height());
680 }
681 
682 
683 
684 void RGBDSensorWrapper::deepCopyImages(const yarp::sig::FlexImage& src,
686  const string& frame_id,
687  const yarp::rosmsg::TickTime& timeStamp,
688  const UInt& seq)
689 {
690  dest.data.resize(src.getRawImageSize());
691  dest.width = src.width();
692  dest.height = src.height();
693  memcpy(dest.data.data(), src.getRawImage(), src.getRawImageSize());
694  dest.encoding = yarp2RosPixelCode(src.getPixelCode());
695  dest.step = src.getRowSize();
696  dest.header.frame_id = frame_id;
697  dest.header.stamp = timeStamp;
698  dest.header.seq = seq;
699  dest.is_bigendian = 0;
700 }
701 
702 void RGBDSensorWrapper::deepCopyImages(const DepthImage& src,
704  const string& frame_id,
705  const yarp::rosmsg::TickTime& timeStamp,
706  const UInt& seq)
707 {
708  dest.data.resize(src.getRawImageSize());
709 
710  dest.width = src.width();
711  dest.height = src.height();
712 
713  memcpy(dest.data.data(), src.getRawImage(), src.getRawImageSize());
714 
715  dest.encoding = yarp2RosPixelCode(src.getPixelCode());
716  dest.step = src.getRowSize();
717  dest.header.frame_id = frame_id;
718  dest.header.stamp = timeStamp;
719  dest.header.seq = seq;
720  dest.is_bigendian = 0;
721 }
722 
723 bool RGBDSensorWrapper::setCamInfo(yarp::rosmsg::sensor_msgs::CameraInfo& cameraInfo, const string& frame_id, const UInt& seq, const SensorType& sensorType)
724 {
725  double phyF = 0.0;
726  double fx = 0.0;
727  double fy = 0.0;
728  double cx = 0.0;
729  double cy = 0.0;
730  double k1 = 0.0;
731  double k2 = 0.0;
732  double t1 = 0.0;
733  double t2 = 0.0;
734  double k3 = 0.0;
735  double stamp = 0.0;
736 
737  string distModel, currentSensor;
738  UInt i;
739  Property camData;
740  vector<param<double> > parVector;
741  param<double>* par;
742  bool ok;
743 
744  currentSensor = sensorType == COLOR_SENSOR ? "Rgb" : "Depth";
745  ok = sensorType == COLOR_SENSOR ? sensor_p->getRgbIntrinsicParam(camData) : sensor_p->getDepthIntrinsicParam(camData);
746 
747  if (!ok)
748  {
749  yCError(RGBDSENSORWRAPPER) << "unable to get intrinsic param from" << currentSensor << "sensor!";
750  return false;
751  }
752 
753  if(!camData.check("distortionModel"))
754  {
755  yCWarning(RGBDSENSORWRAPPER) << "missing distortion model";
756  return false;
757  }
758 
759  distModel = camData.find("distortionModel").asString();
760  if (distModel != "plumb_bob")
761  {
762  yCError(RGBDSENSORWRAPPER) << "distortion model not supported";
763  return false;
764  }
765 
766  //std::vector<param<string> > rosStringParam;
767  //rosStringParam.push_back(param<string>(nodeName, "asd"));
768 
769  parVector.emplace_back(phyF,"physFocalLength");
770  parVector.emplace_back(fx,"focalLengthX");
771  parVector.emplace_back(fy,"focalLengthY");
772  parVector.emplace_back(cx,"principalPointX");
773  parVector.emplace_back(cy,"principalPointY");
774  parVector.emplace_back(k1,"k1");
775  parVector.emplace_back(k2,"k2");
776  parVector.emplace_back(t1,"t1");
777  parVector.emplace_back(t2,"t2");
778  parVector.emplace_back(k3,"k3");
779  parVector.emplace_back(stamp,"stamp");
780  for(i = 0; i < parVector.size(); i++)
781  {
782  par = &parVector[i];
783 
784  if(!camData.check(par->parname))
785  {
786  yCWarning(RGBDSENSORWRAPPER) << "RGBSensorWrapper: driver has not the param:" << par->parname;
787  return false;
788  }
789  *par->var = camData.find(par->parname).asFloat64();
790  }
791 
792  cameraInfo.header.frame_id = frame_id;
793  cameraInfo.header.seq = seq;
794  cameraInfo.header.stamp = stamp;
795  cameraInfo.width = sensorType == COLOR_SENSOR ? sensor_p->getRgbWidth() : sensor_p->getDepthWidth();
796  cameraInfo.height = sensorType == COLOR_SENSOR ? sensor_p->getRgbHeight() : sensor_p->getDepthHeight();
797  cameraInfo.distortion_model = distModel;
798 
799  cameraInfo.D.resize(5);
800  cameraInfo.D[0] = k1;
801  cameraInfo.D[1] = k2;
802  cameraInfo.D[2] = t1;
803  cameraInfo.D[3] = t2;
804  cameraInfo.D[4] = k3;
805 
806  cameraInfo.K.resize(9);
807  cameraInfo.K[0] = fx; cameraInfo.K[1] = 0; cameraInfo.K[2] = cx;
808  cameraInfo.K[3] = 0; cameraInfo.K[4] = fy; cameraInfo.K[5] = cy;
809  cameraInfo.K[6] = 0; cameraInfo.K[7] = 0; cameraInfo.K[8] = 1;
810 
811  /*
812  * ROS documentation on cameraInfo message:
813  * "Rectification matrix (stereo cameras only)
814  * A rotation matrix aligning the camera coordinate system to the ideal
815  * stereo image plane so that epipolar lines in both stereo images are
816  * parallel."
817  * useless in our case, it will be an identity matrix
818  */
819 
820  cameraInfo.R.assign(9, 0);
821  cameraInfo.R.at(0) = cameraInfo.R.at(4) = cameraInfo.R.at(8) = 1;
822 
823  cameraInfo.P.resize(12);
824  cameraInfo.P[0] = fx; cameraInfo.P[1] = 0; cameraInfo.P[2] = cx; cameraInfo.P[3] = 0;
825  cameraInfo.P[4] = 0; cameraInfo.P[5] = fy; cameraInfo.P[6] = cy; cameraInfo.P[7] = 0;
826  cameraInfo.P[8] = 0; cameraInfo.P[9] = 0; cameraInfo.P[10] = 1; cameraInfo.P[11] = 0;
827 
828  cameraInfo.binning_x = cameraInfo.binning_y = 0;
829  cameraInfo.roi.height = cameraInfo.roi.width = cameraInfo.roi.x_offset = cameraInfo.roi.y_offset = 0;
830  cameraInfo.roi.do_rectify = false;
831  return true;
832 }
833 
834 bool RGBDSensorWrapper::writeData()
835 {
836 
837  //colorImage.setPixelCode(VOCAB_PIXEL_RGB);
838  // depthImage.setPixelCode(VOCAB_PIXEL_MONO_FLOAT);
839 
840  // colorImage.resize(hDim, vDim); // Has this to be done each time? If size is the same what it does?
841  // depthImage.resize(hDim, vDim);
842  if (!sensor_p->getImages(colorImage, depthImage, &colorStamp, &depthStamp))
843  {
844  return false;
845  }
846 
847  static Stamp oldColorStamp = Stamp(0, 0);
848  static Stamp oldDepthStamp = Stamp(0, 0);
849 
850  if (((colorStamp.getTime() - oldColorStamp.getTime()) > 0) == false)
851  {
852  return true;
853  }
854 
855  if (((depthStamp.getTime() - oldDepthStamp.getTime()) > 0) == false)
856  {
857  return true;
858  }
859 
860  oldDepthStamp = depthStamp;
861  oldColorStamp = colorStamp;
862 
863  if (use_YARP)
864  {
865  FlexImage& yColorImage = colorFrame_StreamingPort.prepare();
866  ImageOf<PixelFloat>& yDepthImage = depthFrame_StreamingPort.prepare();
867 
868  shallowCopyImages(colorImage, yColorImage);
869  shallowCopyImages(depthImage, yDepthImage);
870  // TBD: We should check here somehow if the timestamp was correctly updated and, if not, update it ourselves.
871 
872  colorFrame_StreamingPort.setEnvelope(colorStamp);
873  colorFrame_StreamingPort.write();
874 
875  depthFrame_StreamingPort.setEnvelope(depthStamp);
876  depthFrame_StreamingPort.write();
877 
878  }
879  if (use_ROS)
880  {
881  yarp::rosmsg::sensor_msgs::Image& rColorImage = rosPublisherPort_color.prepare();
882  yarp::rosmsg::sensor_msgs::Image& rDepthImage = rosPublisherPort_depth.prepare();
883  yarp::rosmsg::sensor_msgs::CameraInfo& camInfoC = rosPublisherPort_colorCaminfo.prepare();
884  yarp::rosmsg::sensor_msgs::CameraInfo& camInfoD = rosPublisherPort_depthCaminfo.prepare();
885  yarp::rosmsg::TickTime cRosStamp, dRosStamp;
886 
887  cRosStamp = colorStamp.getTime();
888  dRosStamp = depthStamp.getTime();
889 
890  deepCopyImages(colorImage, rColorImage, rosFrameId, cRosStamp, nodeSeq);
891  deepCopyImages(depthImage, rDepthImage, rosFrameId, dRosStamp, nodeSeq);
892  // TBD: We should check here somehow if the timestamp was correctly updated and, if not, update it ourselves.
893 
894  rosPublisherPort_color.setEnvelope(colorStamp);
895  rosPublisherPort_color.write();
896 
897  rosPublisherPort_depth.setEnvelope(depthStamp);
898  rosPublisherPort_depth.write();
899 
900  if (setCamInfo(camInfoC, rosFrameId, nodeSeq, COLOR_SENSOR))
901  {
902  if(forceInfoSync)
903  camInfoC.header.stamp = rColorImage.header.stamp;
904  rosPublisherPort_colorCaminfo.setEnvelope(colorStamp);
905  rosPublisherPort_colorCaminfo.write();
906  }
907  else
908  {
909  yCWarning(RGBDSENSORWRAPPER, "missing color camera parameters... camera info messages will be not sended");
910  }
911  if (setCamInfo(camInfoD, rosFrameId, nodeSeq, DEPTH_SENSOR))
912  {
913  if(forceInfoSync)
914  camInfoD.header.stamp = rDepthImage.header.stamp;
915  rosPublisherPort_depthCaminfo.setEnvelope(depthStamp);
916  rosPublisherPort_depthCaminfo.write();
917  }
918  else
919  {
920  yCWarning(RGBDSENSORWRAPPER, "missing depth camera parameters... camera info messages will be not sended");
921  }
922 
923  nodeSeq++;
924  }
925  return true;
926 }
927 
929 {
930  if (sensor_p!=nullptr)
931  {
932  static int i = 0;
933  sensorStatus = sensor_p->getSensorStatus();
934  switch (sensorStatus)
935  {
936  case(IRGBDSensor::RGBD_SENSOR_OK_IN_USE) :
937  {
938  if (!writeData())
939  yCError(RGBDSENSORWRAPPER, "Image not captured.. check hardware configuration");
940  i = 0;
941  }
942  break;
943  case(IRGBDSensor::RGBD_SENSOR_NOT_READY):
944  {
945  if(i < 1000)
946  {
947  if((i % 30) == 0)
948  yCInfo(RGBDSENSORWRAPPER) << "device not ready, waiting...";
949  }
950  else
951  {
952  yCWarning(RGBDSENSORWRAPPER) << "device is taking too long to start..";
953  }
954  i++;
955  }
956  break;
957  default:
958  {
959  if (verbose >= 1) // better not to print it every cycle anyway, too noisy
960  yCError(RGBDSENSORWRAPPER, "RGBDSensorWrapper: %s: Sensor returned error", sensorId.c_str());
961  }
962  }
963  }
964  else
965  {
966  if(verbose >= 6)
967  yCError(RGBDSENSORWRAPPER, "RGBDSensorWrapper: %s: Sensor interface is not valid", sensorId.c_str());
968  }
969 }
#define DEFAULT_THREAD_PERIOD
Definition: AnalogWrapper.h:46
constexpr yarp::conf::vocab32_t VOCAB_FRAMEGRABBER_CONTROL
constexpr yarp::conf::vocab32_t VOCAB_IS
Definition: GenericVocabs.h:17
constexpr yarp::conf::vocab32_t VOCAB_GET
Definition: GenericVocabs.h:16
constexpr yarp::conf::vocab32_t VOCAB_FAILED
Definition: GenericVocabs.h:19
constexpr yarp::conf::vocab32_t VOCAB_SET
Definition: GenericVocabs.h:15
constexpr yarp::conf::vocab32_t VOCAB_RGBD_SENSOR
Definition: IRGBDSensor.h:22
constexpr yarp::conf::vocab32_t VOCAB_EXTRINSIC_PARAM
Definition: IRGBDSensor.h:26
constexpr yarp::conf::vocab32_t VOCAB_RGBD_PROTOCOL_VERSION
Definition: IRGBDSensor.h:23
constexpr yarp::conf::vocab32_t VOCAB_STATUS
Definition: IRGBDSensor.h:31
constexpr yarp::conf::vocab32_t VOCAB_ERROR_MSG
Definition: IRGBDSensor.h:27
constexpr yarp::conf::vocab32_t VOCAB_DEPTH_VISUAL_PARAMS
Definition: IVisualParams.h:45
constexpr yarp::conf::vocab32_t VOCAB_RGB_VISUAL_PARAMS
Definition: IVisualParams.h:44
bool ret
const yarp::os::LogComponent & RGBDSENSORWRAPPER()
#define RGBD_INTERFACE_PROTOCOL_VERSION_MINOR
#define RGBD_INTERFACE_PROTOCOL_VERSION_MAJOR
bool configure(yarp::dev::IRGBDSensor *interface)
bool respond(const yarp::os::Bottle &cmd, yarp::os::Bottle &response) override
Respond to a message.
bool detach() override
Detach the object (you must have first called attach).
bool attachAll(const yarp::dev::PolyDriverList &p) override
Specify which sensor this thread has to read from.
bool close() override
Close the DeviceDriver.
bool fromConfig(yarp::os::Searchable &params)
void run() override
Loop function.
bool threadInit() override
Initialization method.
bool open(yarp::os::Searchable &params) override
Device driver interface.
void setId(const std::string &id)
void threadRelease() override
Release method.
bool detachAll() override
Detach the object (you must have first called attach).
bool attach(yarp::dev::PolyDriver *poly) override
Attach to another object.
bool view(T *&x)
Get an interface to the device driver.
Definition: DeviceDriver.h:77
An interface for retrieving intrinsic parameter from a depth camera.
Control interface for frame grabber devices.
A generic interface for cameras that have both color camera as well as depth camera sensor,...
Definition: IRGBDSensor.h:56
int getRgbWidth() override=0
Return the width of each frame.
bool getRgbIntrinsicParam(yarp::os::Property &intrinsic) override=0
Get the intrinsic parameters of the rgb camera.
virtual bool getImages(yarp::sig::FlexImage &colorFrame, yarp::sig::ImageOf< yarp::sig::PixelFloat > &depthFrame, yarp::os::Stamp *colorStamp=NULL, yarp::os::Stamp *depthStamp=NULL)=0
Get the both the color and depth frame in a single call.
int getDepthWidth() override=0
Return the height of each frame.
int getRgbHeight() override=0
Return the height of each frame.
virtual RGBDSensor_status getSensorStatus()=0
Get the surrent status of the sensor, using enum type.
int getDepthHeight() override=0
Return the height of each frame.
bool getDepthIntrinsicParam(yarp::os::Property &intrinsic) override=0
Get the intrinsic parameters of the depth camera.
An interface for retrieving intrinsic parameter from a rgb camera.
Definition: IVisualParams.h:73
A container for a device driver.
Definition: PolyDriver.h:27
bool isValid() const
Check if device is valid.
Definition: PolyDriver.cpp:199
bool open(const std::string &txt)
Construct and configure a device by its common name.
Definition: PolyDriver.cpp:143
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
void append(const Bottle &alt)
Append the content of the given bottle to the current list.
Definition: Bottle.cpp:383
void addVocab(int x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:167
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Bottle.cpp:280
void clear()
Empties the bottle of any objects it contains.
Definition: Bottle.cpp:124
void addInt32(std::int32_t x)
Places a 32-bit integer in the bottle, at the end of the list.
Definition: Bottle.cpp:143
bool isNull() const override
Checks if the object is invalid.
Definition: Bottle.cpp:373
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Bottle.cpp:290
void close() override
Stop port activity.
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
void interrupt() override
Interrupt any current reads or writes attached to the port.
void write(bool forceStrict=false)
Write the current object being returned by BufferedPort::prepare.
T & prepare()
Access the object which will be transmitted by the next call to yarp::os::BufferedPort::write.
The Node class.
Definition: Node.h:27
void interrupt()
interrupt delegates the call to the Node port interrupt.
Definition: Node.cpp:600
An abstraction for a periodic thread.
bool isRunning() const
Returns true when the thread is started, false otherwise.
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
void setReader(PortReader &reader) override
Set an external reader for port data.
Definition: Port.cpp:505
void interrupt() override
Interrupt any current reads or writes attached to the port.
Definition: Port.cpp:377
void close() override
Stop port activity.
Definition: Port.cpp:357
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition: Port.cpp:82
A class for storing options and configuration information.
Definition: Property.h:37
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Property.cpp:1034
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
Definition: Property.cpp:1046
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:998
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Property.cpp:1024
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
Definition: Property.cpp:1029
bool topic(const std::string &name)
Set topic to publish to.
Definition: Publisher.h:67
T & prepare()
Access the object which will be transmitted by the next call to yarp::os::Publisher::write.
Definition: Publisher.h:127
void write(bool forceStrict=false)
Write the current object being returned by Publisher::prepare.
Definition: Publisher.h:152
A base class for nested structures that can be searched.
Definition: Searchable.h:69
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
An abstraction for a time stamp and/or sequence number.
Definition: Stamp.h:25
double getTime() const
Get the time stamp.
Definition: Stamp.cpp:37
A single value (typically within a Bottle).
Definition: Value.h:47
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
Definition: Value.cpp:225
virtual bool asBool() const
Get boolean value.
Definition: Value.cpp:189
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
virtual std::int32_t asVocab() const
Get vocabulary identifier as an integer.
Definition: Value.cpp:231
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
std::vector< yarp::conf::float64_t > R
Definition: CameraInfo.h:170
std::vector< yarp::conf::float64_t > K
Definition: CameraInfo.h:169
yarp::rosmsg::sensor_msgs::RegionOfInterest roi
Definition: CameraInfo.h:174
std::vector< yarp::conf::float64_t > P
Definition: CameraInfo.h:171
yarp::rosmsg::std_msgs::Header header
Definition: CameraInfo.h:164
std::vector< yarp::conf::float64_t > D
Definition: CameraInfo.h:168
std::vector< std::uint8_t > data
Definition: Image.h:65
yarp::rosmsg::std_msgs::Header header
Definition: Image.h:59
yarp::rosmsg::TickTime stamp
Definition: Header.h:48
Image class with user control of representation details.
Definition: Image.h:403
void setQuantum(size_t imgQuantum)
Definition: Image.h:418
void setPixelCode(int imgPixelCode)
Definition: Image.h:406
Typed image class.
Definition: Image.h:647
void setQuantum(size_t imgQuantum)
Definition: Image.cpp:511
size_t width() const
Gets width of image in pixels.
Definition: Image.h:153
void setExternal(const void *data, size_t imgWidth, size_t imgHeight)
Use this to wrap an external image.
Definition: Image.cpp:883
size_t getRowSize() const
Size of the underlying image buffer rows.
Definition: Image.h:179
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition: Image.cpp:535
size_t getRawImageSize() const
Access to the internal buffer size information (this is how much memory has been allocated for the im...
Definition: Image.cpp:544
size_t getQuantum() const
The size of a row is constrained to be a multiple of the "quantum".
Definition: Image.h:186
size_t height() const
Gets height of image in pixels.
Definition: Image.h:159
virtual int getPixelCode() const
Gets pixel type identifier.
Definition: Image.cpp:455
A class for a Matrix.
Definition: Matrix.h:46
yarp::os::Node * rosNode
#define yCInfo(component,...)
Definition: LogComponent.h:135
#define yCError(component,...)
Definition: LogComponent.h:157
#define yCTrace(component,...)
Definition: LogComponent.h:88
#define yCWarning(component,...)
Definition: LogComponent.h:146
#define yCDebug(component,...)
Definition: LogComponent.h:112
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
@ VOCAB_PIXEL_ENCODING_BAYER_BGGR16
Definition: Image.h:65
@ VOCAB_PIXEL_RGBA
Definition: Image.h:51
@ VOCAB_PIXEL_MONO16
Definition: Image.h:49
@ VOCAB_PIXEL_ENCODING_BAYER_BGGR8
Definition: Image.h:64
@ VOCAB_PIXEL_BGRA
Definition: Image.h:52
@ VOCAB_PIXEL_BGR
Definition: Image.h:55
@ VOCAB_PIXEL_MONO_FLOAT
Definition: Image.h:59
@ VOCAB_PIXEL_ENCODING_BAYER_RGGB8
Definition: Image.h:68
@ VOCAB_PIXEL_ENCODING_BAYER_GRBG8
Definition: Image.h:62
@ VOCAB_PIXEL_ENCODING_BAYER_GBRG16
Definition: Image.h:67
@ VOCAB_PIXEL_ENCODING_BAYER_GRBG16
Definition: Image.h:63
@ VOCAB_PIXEL_ENCODING_BAYER_GBRG8
Definition: Image.h:66
@ VOCAB_PIXEL_MONO
Definition: Image.h:48
@ VOCAB_PIXEL_ENCODING_BAYER_RGGB16
Definition: Image.h:69
@ VOCAB_PIXEL_RGB
Definition: Image.h:50
const std::string depthInfoTopicName_param
const std::string depthTopicName_param
const std::string colorTopicName_param
const std::string nodeName_param
const std::string frameId_param
const std::string colorInfoTopicName_param
An interface for the device drivers.
std::string decode(NetInt32 code)
Convert a vocabulary identifier into a string.
Definition: Vocab.cpp:36
An interface to the operating system, including Port based communication.
Signal processing.
Definition: Image.h:25
#define BAYER_BGGR8
Definition: rosPixelCode.h:13
#define BGR8
Definition: rosPixelCode.h:21
#define BAYER_RGGB16
Definition: rosPixelCode.h:18
#define BAYER_BGGR16
Definition: rosPixelCode.h:12
#define MONO16
Definition: rosPixelCode.h:24
#define RGBA8
Definition: rosPixelCode.h:29
#define BAYER_GBRG16
Definition: rosPixelCode.h:14
#define BAYER_GBRG8
Definition: rosPixelCode.h:15
#define MONO8
Definition: rosPixelCode.h:25
#define BAYER_GRBG16
Definition: rosPixelCode.h:16
#define RGB8
Definition: rosPixelCode.h:27
#define TYPE_32FC1
Definition: rosPixelCode.h:38
#define BAYER_RGGB8
Definition: rosPixelCode.h:19
#define BAYER_GRBG8
Definition: rosPixelCode.h:17
#define BGRA8
Definition: rosPixelCode.h:23