Main MRPT website > C++ reference for MRPT 1.9.9
COpenNI2Sensor.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "hwdrivers-precomp.h" // Precompiled header
11 
15 #include <mrpt/utils/CTimeLogger.h>
17 
18 // Universal include for all versions of OpenCV
19 #include <mrpt/otherlibs/do_opencv_includes.h>
20 
21 using namespace mrpt::hwdrivers;
22 using namespace mrpt::system;
23 using namespace mrpt::obs;
24 using namespace mrpt::math;
25 using namespace std;
27 
29 {
30  return param.ncols > 0 && param.nrows > 0;
31 }
32 
34 
35 /*-------------------------------------------------------------
36 ctor
37 -------------------------------------------------------------*/
39  : m_sensorPoseOnRobot(),
40  m_preview_window(false),
41  m_preview_window_decimation(1),
42  m_preview_decim_counter_range(0),
43  m_preview_decim_counter_rgb(0),
44 
45  m_relativePoseIntensityWRTDepth(
46  0, 0, 0, DEG2RAD(-90), DEG2RAD(0), DEG2RAD(-90)),
47  m_user_device_number(0),
48  m_serial_number(0)
49 {
50  // Default label:
51  m_sensorLabel = "OPENNI2";
52 
53  // =========== Default params ===========
54  // ----- RGB -----
55  m_cameraParamsRGB.ncols = 0;
56  m_cameraParamsRGB.nrows = 0;
57 
58  m_cameraParamsRGB.cx(-1);
59  m_cameraParamsRGB.cy(-1);
60  m_cameraParamsRGB.fx(-1);
61  m_cameraParamsRGB.fy(-1);
62 
63  m_cameraParamsRGB.dist.zeros();
64 
65  // ----- Depth -----
66  m_cameraParamsDepth.ncols = 0;
67  m_cameraParamsDepth.nrows = 0;
68 
69  m_cameraParamsDepth.cx(-1);
70  m_cameraParamsDepth.cy(-1);
71  m_cameraParamsDepth.fx(-1);
72  m_cameraParamsDepth.fy(-1);
73 
74  m_cameraParamsDepth.dist.zeros();
75 }
76 
77 /*-------------------------------------------------------------
78 dtor
79 -------------------------------------------------------------*/
81 {
82 #if MRPT_HAS_OPENNI2
83  close(m_user_device_number);
84 #endif // MRPT_HAS_OPENNI2
85 }
86 
87 /** This method can or cannot be implemented in the derived class, depending on
88 * the need for it.
89 * \exception This method must throw an exception with a descriptive message if
90 * some critical error is found.
91 */
93 {
94 #if MRPT_HAS_OPENNI2
95  try
96  {
97  if (getConnectedDevices() <= 0)
98  { // Check and list the available devices. If there is at least one
99  // device connected, open the first in the list.
100  return;
101  }
102  {
103  if (m_serial_number != 0)
104  {
105  openDeviceBySerial(m_serial_number);
106  if (getDeviceIDFromSerialNum(
107  m_serial_number, m_user_device_number) == false)
108  {
110  mrpt::format(
111  "Failed to find sensor_id from serial number(%d).",
112  m_serial_number))
113  }
114  }
115  else
116  open(m_user_device_number);
117  }
118  if (isOpen(m_user_device_number) == false)
119  {
121  mrpt::format(
122  "Failed to open OpenNI2 device(%d).", m_user_device_number))
123  }
124  /* If camera parameter is not read from ini file, we get the parameters
125  * from OpenNI2. */
126  if (isValidParameter(m_cameraParamsDepth) == false)
127  {
128  if (getDepthSensorParam(
129  m_cameraParamsDepth, m_user_device_number) == false)
130  {
131  THROW_EXCEPTION("Failed to get Depth camera parameters.")
132  }
133  }
134  if (isValidParameter(m_cameraParamsRGB) == false)
135  {
136  if (getColorSensorParam(m_cameraParamsRGB, m_user_device_number) ==
137  false)
138  {
139  THROW_EXCEPTION("Failed to get RGB camera parameters.")
140  }
141  }
142  }
143  catch (std::logic_error& e)
144  {
145  throw(e);
146  }
147 #else
148  THROW_EXCEPTION("MRPT was built without OpenNI2 support")
149 #endif // MRPT_HAS_OPENNI2
150 }
151 
152 /** This method will be invoked at a minimum rate of "process_rate" (Hz)
153 * \exception This method must throw an exception with a descriptive message if
154 * some critical error is found.
155 */
157 {
158 #if MRPT_HAS_OPENNI2
159  // cout << "COpenNI2Sensor::doProcess...\n";
160 
161  bool thereIs, hwError;
162 
164  mrpt::make_aligned_shared<CObservation3DRangeScan>();
165 
166  assert(getNumDevices() > 0);
167  getNextObservation(*newObs, thereIs, hwError);
168 
169  if (hwError)
170  {
171  m_state = ssError;
172  THROW_EXCEPTION("Couldn't communicate to the OpenNI2 sensor!");
173  }
174 
175  if (thereIs)
176  {
177  m_state = ssWorking;
178 
179  std::vector<mrpt::utils::CSerializable::Ptr> objs;
180  if (m_grab_image || m_grab_depth || m_grab_3D_points)
181  objs.push_back(newObs);
182 
183  appendObservations(objs);
184  }
185 #else
186  THROW_EXCEPTION("MRPT was built without OpenNI2 support")
187 #endif // MRPT_HAS_OPENNI2
188 }
189 
190 /** Loads specific configuration for the device from a given source of
191 * configuration parameters, for example, an ".ini" file, loading from the
192 * section "[iniSection]" (see utils::CConfigFileBase and derived classes)
193 * \exception This method must throw an exception with a descriptive message if
194 * some critical parameter is missing or has an invalid value.
195 */
197  const mrpt::utils::CConfigFileBase& configSource,
198  const std::string& iniSection)
199 {
200  cout << "COpenNI2Sensor::loadConfig_sensorSpecific...\n";
201 
202  m_sensorPoseOnRobot.setFromValues(
203  configSource.read_float(iniSection, "pose_x", 0),
204  configSource.read_float(iniSection, "pose_y", 0),
205  configSource.read_float(iniSection, "pose_z", 0),
206  DEG2RAD(configSource.read_float(iniSection, "pose_yaw", 0)),
207  DEG2RAD(configSource.read_float(iniSection, "pose_pitch", 0)),
208  DEG2RAD(configSource.read_float(iniSection, "pose_roll", 0)));
209 
210  m_preview_window =
211  configSource.read_bool(iniSection, "preview_window", m_preview_window);
212 
213  m_width = configSource.read_int(iniSection, "width", 0);
214  m_height = configSource.read_int(iniSection, "height", 0);
215  m_fps = configSource.read_float(iniSection, "fps", 0);
216  std::cout << "width " << m_width << " height " << m_height << " fps "
217  << m_fps << endl;
218 
219  bool hasRightCameraSection =
220  configSource.sectionExists(iniSection + string("_RIGHT"));
221  bool hasLeftCameraSection =
222  configSource.sectionExists(iniSection + string("_LEFT"));
223  bool hasLeft2RightPose =
224  configSource.sectionExists(iniSection + string("_LEFT2RIGHT_POSE"));
225 
227 
228  try
229  {
230  sc.loadFromConfigFile(iniSection, configSource);
231  }
232  catch (std::exception& e)
233  {
234  std::cout << "[COpenNI2Sensor::loadConfig_sensorSpecific] Warning: "
235  "Ignoring error loading calibration parameters:\n"
236  << e.what();
237  }
238  if (hasRightCameraSection)
239  {
240  m_cameraParamsRGB = sc.rightCamera;
241  }
242  if (hasLeftCameraSection)
243  {
244  m_cameraParamsDepth = sc.leftCamera;
245  }
246  if (hasLeft2RightPose)
247  {
248  const mrpt::poses::CPose3D twist(
249  0, 0, 0, DEG2RAD(-90), DEG2RAD(0), DEG2RAD(-90));
250  m_relativePoseIntensityWRTDepth =
252  }
253 
254  // Id:
255  m_user_device_number = configSource.read_int(
256  iniSection, "device_number", m_user_device_number);
257  // cout << "LOAD m_user_device_number " << m_user_device_number << endl;
258  m_serial_number =
259  configSource.read_int(iniSection, "serial_number", m_serial_number);
260 
261  m_grab_image =
262  configSource.read_bool(iniSection, "grab_image", m_grab_image);
263  m_grab_depth =
264  configSource.read_bool(iniSection, "grab_depth", m_grab_depth);
265  m_grab_3D_points =
266  configSource.read_bool(iniSection, "grab_3D_points", m_grab_3D_points);
267 
268  {
269  std::string s = configSource.read_string(
270  iniSection, "relativePoseIntensityWRTDepth", "");
271  if (!s.empty()) m_relativePoseIntensityWRTDepth.fromString(s);
272  }
273 }
274 
275 /** The main data retrieving function, to be called after calling loadConfig()
276 * and initialize().
277 * \param out_obs The output retrieved observation (only if there_is_obs=true).
278 * \param there_is_obs If set to false, there was no new observation.
279 * \param hardware_error True on hardware/comms error.
280 *
281 * \sa doProcess
282 */
284  mrpt::obs::CObservation3DRangeScan& out_obs, bool& there_is_obs,
285  bool& hardware_error)
286 {
287 #if MRPT_HAS_OPENNI2
288  // cout << "COpenNI2Sensor::getNextObservation \n";
289 
290  // Read a frame (depth + rgb)
291  getNextFrameRGBD(
292  out_obs, there_is_obs, hardware_error, m_user_device_number);
293 
294  // Set common data into observation:
295  // --------------------------------------
296  out_obs.sensorLabel = m_sensorLabel;
297  out_obs.sensorPose = m_sensorPoseOnRobot;
298  out_obs.relativePoseIntensityWRTDepth = m_relativePoseIntensityWRTDepth;
299 
300  out_obs.cameraParams = m_cameraParamsDepth;
301  out_obs.cameraParamsIntensity = m_cameraParamsRGB;
302 
303  // 3D point cloud:
304  if (out_obs.hasRangeImage && m_grab_3D_points)
305  {
307 
308  if (!m_grab_depth)
309  {
310  out_obs.hasRangeImage = false;
311  out_obs.rangeImage.resize(0, 0);
312  }
313  }
314 
315  // preview in real-time?
316  if (m_preview_window)
317  {
318  if (out_obs.hasRangeImage)
319  {
320  if (++m_preview_decim_counter_range > m_preview_window_decimation)
321  {
322  m_preview_decim_counter_range = 0;
323  if (!m_win_range)
324  {
325  m_win_range =
326  mrpt::make_aligned_shared<mrpt::gui::CDisplayWindow>(
327  "Preview RANGE");
328  m_win_range->setPos(5, 5);
329  }
330 
331  // Normalize the image
333  img.setFromMatrix(out_obs.rangeImage);
334  CMatrixFloat r =
335  out_obs.rangeImage * float(1.0 / this->m_maxRange);
336  m_win_range->showImage(img);
337  }
338  }
339  if (out_obs.hasIntensityImage)
340  {
341  if (++m_preview_decim_counter_rgb > m_preview_window_decimation)
342  {
343  m_preview_decim_counter_rgb = 0;
344  if (!m_win_int)
345  {
346  m_win_int =
347  mrpt::make_aligned_shared<mrpt::gui::CDisplayWindow>(
348  "Preview INTENSITY");
349  m_win_int->setPos(300, 5);
350  }
351  m_win_int->showImage(out_obs.intensityImage);
352  }
353  }
354  }
355  else
356  {
357  if (m_win_range) m_win_range.reset();
358  if (m_win_int) m_win_int.reset();
359  }
360 
361 // cout << "COpenNI2Sensor::getNextObservation finish\n";
362 #else
363  MRPT_UNUSED_PARAM(out_obs);
364  MRPT_UNUSED_PARAM(there_is_obs);
365  MRPT_UNUSED_PARAM(hardware_error);
366  THROW_EXCEPTION("MRPT was built without OpenNI2 support")
367 #endif // MRPT_HAS_OPENNI2
368 }
369 
370 /* -----------------------------------------------------
371 setPathForExternalImages
372 ----------------------------------------------------- */
374 {
375  MRPT_UNUSED_PARAM(directory);
376  // Ignore for now. It seems performance is better grabbing everything
377  // to a single big file than creating hundreds of smaller files per
378  // second...
379  return;
380 
381  // if (!mrpt::system::createDirectory( directory ))
382  // {
383  // THROW_EXCEPTION_FMT("Error: Cannot create the directory for
384  // externally
385  // saved images: %s",directory.c_str() )
386  // }
387  // m_path_for_external_images = directory;
388 }
virtual void doProcess()
To be called at a high rate (>XX Hz), this method populates the internal buffer of received observati...
bool read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
bool sectionExists(const std::string &section_name) const
Checks if a given section exists (name is case insensitive)
bool isValidParameter(const mrpt::utils::TCamera &param)
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
double DEG2RAD(const double x)
Degrees to radians.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
float read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound=false) const
mrpt::utils::TCamera cameraParamsIntensity
Projection parameters of the intensity (graylevel or RGB) camera.
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:118
#define THROW_EXCEPTION(msg)
void project3DPointsFromDepthImage(const bool PROJ3D_USE_LUT=true)
This method is equivalent to project3DPointsFromDepthImageInto() storing the projected 3D points (wit...
virtual void loadConfig_sensorSpecific(const mrpt::utils::CConfigFileBase &configSource, const std::string &section)
Loads specific configuration for the device from a given source of configuration parameters, for example, an ".ini" file, loading from the section "[iniSection]" (see utils::CConfigFileBase and derived classes)
void getNextObservation(mrpt::obs::CObservation3DRangeScan &out_obs, bool &there_is_obs, bool &hardware_error)
The main data retrieving function, to be called after calling loadConfig() and initialize().
Declares a class derived from "CObservation" that encapsules a 3D range scan measurement, as from a time-of-flight range camera or any other RGBD sensor.
std::shared_ptr< CObservation3DRangeScan > Ptr
Contains classes for various device interfaces.
std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
virtual void initialize()
Initializes the 3D camera - should be invoked after calling loadConfig() or setting the different par...
STL namespace.
GLdouble s
Definition: glext.h:3676
A class for grabing "range images", intensity images (either RGB or IR) and other information from an...
Structure to hold the parameters of a pinhole stereo camera model.
Definition: TStereoCamera.h:25
This class allows loading and storing values and vectors of different types from a configuration text...
mrpt::math::CMatrix rangeImage
If hasRangeImage=true, a matrix of floats with the range data as captured by the camera (in meters) ...
mrpt::utils::TCamera cameraParams
Projection parameters of the depth camera.
int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound=false) const
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
mrpt::poses::CPose3D relativePoseIntensityWRTDepth
Relative pose of the intensity camera wrt the depth camera (which is the coordinates origin for this ...
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
GLint GLvoid * img
Definition: glext.h:3763
virtual void setPathForExternalImages(const std::string &directory)
Set the path where to save off-rawlog image files (this class DOES take into account this path)...
This namespace contains representation of robot actions and observations.
bool hasRangeImage
true means the field rangeImage contains valid data
#define DEG2RAD
GLsizei const GLchar ** string
Definition: glext.h:4101
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
Definition: CObservation.h:60
void loadFromConfigFile(const std::string &section, const mrpt::utils::CConfigFileBase &cfg)
Load all the params from a config source, in the same format that used in saveToConfigFile().
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
TCamera leftCamera
Intrinsic and distortion parameters of the left and right cameras.
Definition: TStereoCamera.h:30
bool hasIntensityImage
true means the field intensityImage contains valid data
mrpt::utils::CImage intensityImage
If hasIntensityImage=true, a color or gray-level intensity image of the same size than "rangeImage"...
GLfloat param
Definition: glext.h:3831
mrpt::poses::CPose3DQuat rightCameraPose
Pose of the right camera with respect to the coordinate origin of the left camera.
Definition: TStereoCamera.h:33
Structure to hold the parameters of a pinhole camera model.
Definition: TCamera.h:32



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019