source: pacpussensors/trunk/Vislab/lib3dv/device.h@ 136

Last change on this file since 136 was 136, checked in by ldecherf, 7 years ago

Doc

File size: 25.8 KB
Line 
1#ifndef LIB3DV_DEVICE_H
2#define LIB3DV_DEVICE_H
3
4/* lib3dv/device.h
5 *
6 * Copyright (C) 2013 VisLab
7 *
8 * This file is part of lib3dv; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <lib3dv/error.h>
23#include <lib3dv/image.h>
24#include <lib3dv/obstacle.h>
25#include <lib3dv/motion.h>
26#include <lib3dv/classification.h>
27#include <lib3dv/terrain.h>
28
29#include <lib3dv/3dv_export.h>
30
31#include <boost/any.hpp>
32#include <boost/asio/ip/address_v4.hpp>
33#include <boost/function.hpp>
34#include <boost/date_time/time_duration.hpp>
35#include <boost/uuid/uuid.hpp>
36#include <boost/shared_ptr.hpp>
37
38#include <bitset>
39#include <iostream>
40#include <string>
41#include <utility>
42#include <vector>
43
44namespace lib3dv
45{
46 namespace detail { class device_impl; }
47
48 /**
49 * @brief This class represents a 3DV device connected to the local machine.
50 *
51 */
52 class LIB3DV_EXPORT device
53 {
54 public:
55
56 /**
57 * @brief Supported mapping and detection capabilities.
58 *
59 */
60 struct capability
61 {
62 enum types
63 {
64 DEPTH_MAPPING = 0, ///< The device provides depth data.
65 TERRAIN_MAPPING, ///< The device provides the terrain reconstruction.
66 OBSTACLE_DETECTION, ///< The device provides a list of detected obstacles.
67 BASIC_OBSTACLE_DETECTION, ///< The device provides a list of detected obstacles, under flat ground assumption.
68 MOTION_ESTIMATION, ///< The device provides the motion estimation matrix.
69 CLASSIFICATION, ///< The device provides the classification candidate.
70 NUM
71 };
72 };
73
74 /**
75 * @brief Device version information.
76 *
77 */
78 struct version_info
79 {
80 enum types
81 {
82 MAJOR = 0, ///< Major version.
83 MINOR, ///< Minor version.
84 STEP ///< Patch level.
85 };
86
87 uint8_t m_protocol; ///< Network protocol version.
88 uint8_t m_framework[3]; ///< Framework version.
89 uint8_t m_application[3]; ///< 3DV application version.
90 };
91
92 /**
93 * @brief Device status information.
94 *
95 */
96 struct status
97 {
98 enum types
99 {
100 ONLINE = 0, ///< The device is available.
101 TRANSMITTING, ///< The device is streaming data to this lib3dv::device instance.
102 OFFLINE, ///< The device is no longer connected.
103 NUM,
104 };
105 };
106
107 /**
108 * @brief A configuration parameter.
109 *
110 * A property is a generic container hiding the actual data type within a boost::any. In order to recover the type information typeid() must be used.
111 *
112 * @note Currently supported data types are bool, [u]int64_t, [u]int32_t, [u]int16_t, [u]int8_t, float, double, std::string.
113 *
114 * The following example shows how to determine the property value type:
115 *
116 @code
117 lib3dv::error error;
118 lib3dv::device::property property = device.enumerate_properties(error).front();
119 const boost::any& value = property.m_value;
120 const std::type_info& type = value.type();
121
122 if(type == typeid(bool)) std::cout << boost::any_cast<bool>(value) << std::endl;
123 else if(type == typeid(int64_t)) std::cout << boost::any_cast<int64_t>(value) << std::endl;
124 else if(type == typeid(int32_t)) std::cout << boost::any_cast<int32_t>(value) << std::endl;
125 else if(type == typeid(int32_t)) std::cout << boost::any_cast<int32_t>(value) << std::endl;
126 else if(type == typeid(int16_t)) std::cout << boost::any_cast<int16_t>(value) << std::endl;
127 else if(type == typeid(int8_t)) std::cout << static_cast<int32_t>(boost::any_cast<int8_t>(value)) << std::endl;
128 else if(type == typeid(uint64_t)) std::cout << boost::any_cast<uint64_t>(value) << std::endl;
129 else if(type == typeid(uint32_t)) std::cout << boost::any_cast<uint32_t>(value) << std::endl;
130 else if(type == typeid(uint32_t)) std::cout << boost::any_cast<uint32_t>(value) << std::endl;
131 else if(type == typeid(uint16_t)) std::cout << boost::any_cast<uint16_t>(value) << std::endl;
132 else if(type == typeid(uint8_t)) std::cout << static_cast<uint32_t>(boost::any_cast<uint8_t>(value)) << std::endl;
133 else if(type == typeid(float)) std::cout << boost::any_cast<float>(value) << std::endl;
134 else if(type == typeid(double)) std::cout << boost::any_cast<double>(value) << std::endl;
135 else if(type == typeid(std::string)) std::cout << boost::any_cast<std::string>(value) << std::endl;
136 @endcode
137 */
138 struct property
139 {
140 /**
141 * @brief The parameter category.
142 *
143 * The category determines the property attributes, and is useful to generate proper UI controls.
144 */
145 enum category
146 {
147 VALUE = 0, ///< Basic property with no constraints.
148 RANGE, ///< Property values must fall in a determined interval. lib3dv::device::property::m_attributes will contain the "min", "max" and "step" entries.
149 SELECTION ///< Property value must be chosen among those listed in lib3dv::device::property::m_attributes. Each entry can optionally provide a description.
150 };
151
152 uint16_t m_address; ///< Property unique address.
153 std::string m_name; ///< Property name.
154 bool m_readonly; ///< Whether the property can be written to. @see lib3dv::error::PROPERTY_READONLY
155 category m_category; ///< Property category.
156 boost::any m_value; ///< Property value.
157 std::vector<std::pair<boost::any, std::string> > m_attributes; ///< List of attributes.
158
159 /**
160 * @brief Convenience display function.
161 *
162 * @param output The std::ostream to write to
163 * @param property The property to display
164 * @return std::ostream&
165 */
166 friend LIB3DV_EXPORT std::ostream& operator<< (std::ostream& output, const device::property& property);
167 };
168
169 static const unsigned short DEFAULT_PORT; ///< Default UDP port to connect to.
170
171 static const boost::posix_time::time_duration DEFAULT_TIMEOUT; ///< Default connection timeout.
172
173 /**
174 * @brief List available devices
175 *
176 * A broadcast UDP discovery message is sent through the specified local interface, and a lib3dv::device object is associated to every 3DV unit responding before the timeout expires.
177 * @note The call is blocking,
178 *
179 * @param [in] local_address The local IP address to bing to. Must belong to the same subnet of the 3DV devices to connect to.
180 * @param [in] log_level The log messages verbosity level.
181 * @param [out] error Result of operation.
182 * @param [in] timeout How long the function should wait for 3DV devices to answer to the discovery message. Defaults to lib3dv::device::DEFAULT_TIMEOUT.
183 * @param [in] remote_port The remote port to connect to. Defaults to lib3dv::device::DEFAULT_PORT.
184 * @return std::vector< lib3dv::device > The detected devices.
185 *
186 * Example usage:
187 @code
188 std::string address = "192.168.0.1";
189 unsigned int log_level = 1;
190 lib3dv::error error;
191
192 std::vector<lib3dv::device> devices = lib3dv::device::enumerate(boost::asio::ip::address_v4::from_string(address), log_level, error);
193 @endcode
194 */
195 static std::vector<device> enumerate(const boost::asio::ip::address_v4& local_address, uint8_t log_level, error& error, const boost::posix_time::time_duration& timeout = DEFAULT_TIMEOUT, unsigned short remote_port = DEFAULT_PORT);
196
197 /**
198 * @brief Whether the device is still in a valid state.
199 *
200 * @return bool (lib3dv::device::status() == lib3dv::device::status::ONLINE) || (lib3dv::device::status() == lib3dv::device::status::TRANSMITTING).
201 */
202 bool valid() const;
203
204 /**
205 * @brief Whether the device is still in a valid state.
206 *
207 * @return bool false if the physical device is no longer reachable, true otherwise.
208 */
209 status::types status() const;
210
211 /**
212 * @brief Set the log messages verbosity level.
213 *
214 * @param [in] level The verbosity level.
215 * @return void
216 */
217 void log_level(uint8_t level);
218
219 /**
220 * @brief Get the current log messages verbosity level.
221 *
222 * @return uint8_t The verbosity level.
223 */
224 uint8_t log_level() const;
225
226 /**
227 * @brief Set the network connection timeout threshold.
228 *
229 * After a timeout, any method invocation requiring to communicate with the device will fail with a lib3dv::error::NETWORK_FAILURE error, and no data handlers will be triggered. @see lib3dv::device::valid()
230 *
231 * @param [in] timeout The network connection timeout threshold.
232 * @return void
233 */
234 void timeout(const boost::posix_time::time_duration& timeout);
235
236 /**
237 * @brief Get the current network connection timeout threshold.
238 *
239 * @return boost::posix_time::time_duration The network connection timeout threshold.
240 */
241 boost::posix_time::time_duration timeout() const;
242
243 /**
244 * @brief Get the device unique ID.
245 *
246 * @return const boost::uuids::uuid& The device unique ID.
247 */
248 const boost::uuids::uuid& guid() const;
249
250 /**
251 * @brief Enumerate the device capabilities. @see lib3dv::device::capability
252 *
253 * @return const std::bitset< lib3dv::device::capability::NUM >&
254 */
255 const std::bitset<device::capability::NUM>& capabilities() const;
256
257 /**
258 * @brief Get version information
259 *
260 * @return const lib3dv::device::version_info&
261 */
262 const version_info& version() const;
263
264 /**
265 * @brief Enable data transmission on the device.
266 *
267 * Notify the device that it should start transmitting data. If transmission is already on it should first be stopped by calling lib3dv::device::stop_transmission, otherwise the call is ignored.
268 * @note The call is blocking,
269 * @see lib3dv::device::connect_image_callback
270 * @see lib3dv::device::connect_terrain_callback
271 * @see lib3dv::device::connect_obstacles_callback
272 *
273 * @param [out] error Result of operation.
274 * @return void
275 */
276 void start_transmission(error& error);
277
278 /**
279 * @brief Disable data transmission on the device.
280 *
281 * Notify the device that it should stop transmitting data. This method has effect even if the data transmission has been initiated by a different client.
282 * @note The call is blocking.
283 * @see lib3dv::device::disconnect_callback
284 *
285 * @param [out] error Result of operation.
286 * @return void
287 */
288 void stop_transmission(error& error);
289
290 /**
291 * @brief Enumerate the device properties.
292 * @note The call is blocking.
293 * @see lib3dv::device::property
294 *
295 * @param [out] error Result of operation.
296 * @return std::vector< lib3dv::device::property > The device properties.
297 */
298 std::vector<device::property> enumerate_properties(error& error);
299
300 /**
301 * @brief Read a property value from the device.
302 * @note The call is blocking.
303 * @see lib3dv::device::property
304 *
305 * @param [in] address The property address.
306 * @param [out] error Result of operation.
307 * @return boost::any The property value.
308 */
309 boost::any get_property_value(uint16_t address, error& error);
310
311 /**
312 * @brief Store a property value on the device.
313 *
314 * The given value is set on the device; however, changes are not permanently stored until lib3dv::device::save_properties is called.
315 * @note The call is blocking.
316 * @see lib3dv::device::property
317 * @see lib3dv::device::save_properties
318 *
319 * @param [in] address The property address.
320 * @param [in] value The value to store. If the correct type is not supplied an error will be generated.
321 * @param [out] error Result of operation.
322 * @return void
323 */
324 void set_property_value(uint16_t address, const boost::any& value, error& error);
325
326 /**
327 * @brief Permanently store the current configuration on the device.
328 * @note The call is blocking.
329 *
330 * @param [out] error Result of operation.
331 * @return void
332 */
333 void save_properties(error& error);
334
335 /**
336 * @brief Resets the device configuration to the default values.
337 * @note The call is blocking.
338 * @note A reboot is required to make the changes effective.
339 *
340 * @param [out] error Result of operation.
341 * @return void
342 */
343 void reset_properties(error& error);
344
345 /**
346 * @brief Shuts down the device.
347 * @note The call is blocking.
348 *
349 * @param [out] error Result of operation.
350 * @return void
351 */
352 void poweroff(error& error);
353
354 /**
355 * @brief Reboots the device.
356 * @note The call is blocking.
357 *
358 * @param [out] error Result of operation.
359 * @return void
360 */
361 void reboot(error& error);
362
363 /**
364 * @brief Register an image completion handler.
365 *
366 * The supplied user-defined function will be called each time a full image is received.
367 * @note The completion handler is executed in the network handling thread, so it should not perform any actual processing.
368 * Instead, it should just copy over the provided shared pointer and notify a worker thread.
369 * @note No guarantee is made on the images ordering, or that any given image will be completed at all.
370 *
371 * @param [in] function The user-defined callback function. Its signature must be <tt> void (boost::shared_ptr<cosnt lib3dv::image> image, uint32_t guid)</tt>
372 * @return uint64_t An opaque handle that can be passed to lib3dv::device::disconnect_callback to unregister the handler.
373 *
374 * Example usage, exploiting boost::asio to achieve deferred processing on a separate thread.
375 @code
376 #include <boost/asio/io_service.hpp>
377 #include <boost/bind.hpp>
378 #include <boost/ref.hpp>
379 #include <boost/thread.hpp>
380
381 // actual processing happens here
382 void process_image(boost::shared_ptr<cosnt lib3dv::image> image, uint32_t guid)
383 {
384 // do stuff
385 }
386
387 // lightweight completion handler
388 void image_completion_handler(boost::asio::io_service& io_service, boost::shared_ptr<const lib3dv::image> image, uint32_t guid)
389 {
390 io_service.post(boost::bind(process_image, image, guid)); // process_image() is scheduled for execution on the io_service::run() thread
391 }
392
393 ...
394
395 boost::asio::io_service processing_io_service;
396 boost::asio::io_service::work processing_io_service_work(processing_io_service); // this keeps the io_service from exiting when there are no handlers to execute
397 boost::thread processing_io_service_thread = boost::thread(boost::bind(&boost::asio::io_service::run, &processing_io_service)); // start the processing thread
398
399 device.connect_image_callback(boost::bind(image_completion_handler, boost::ref(processing_io_service), _1, _2)); // subscribe for images notifications
400
401 lib3dv::device::error error;
402
403 device.start_transmission(error); // notify the device it can start sending data
404 @endcode
405 */
406 uint64_t connect_image_callback(const boost::function<void (boost::shared_ptr<const image>, uint32_t)>& function);
407
408 LIB3DV_DEPRECATED uint64_t connect_image_callback(const boost::function<void (boost::shared_ptr<image>, uint32_t)>& function);
409
410 /**
411 * @brief Register a terrain completion handler.
412 *
413 * The supplied user-defined function will be called each time a terrain reconstruction is received.
414 * @note The completion handler is executed in the network handling thread, so it should not perform any actual processing.
415 * Instead, it should just copy over the provided shared pointer and notify a worker thread.
416 * @note No guarantee is made on the images ordering, or that any given image will be completed at all.
417 * @see lib3dv::device::connect_image_callback
418 *
419 * @param [in] function The user-defined callback function. Its signature must be <tt> void (boost::shared_ptr<const lib3dv::terrain> terrain, uint32_t guid)</tt>.
420 * The @c guid parameter is the same as that of the depth map that has been processed to generate the current terrain estimation.
421 * @return uint64_t An opaque handle that can be passed to lib3dv::device::disconnect_callback to unregister the handler.
422 */
423 uint64_t connect_terrain_callback(const boost::function<void (boost::shared_ptr<const terrain>, uint32_t)>& function);
424
425 LIB3DV_DEPRECATED uint64_t connect_terrain_callback(const boost::function<void (boost::shared_ptr<terrain>, uint32_t)>& function);
426
427 /**
428 * @brief Register an obstacles set completion handler.
429 *
430 * The supplied user-defined function will be called each time a set of obstacles is received.
431 * @note The completion handler is executed in the network handling thread, so it should not perform any actual processing.
432 * Instead, it should just copy over the provided shared pointer and notify a worker thread.
433 * @note No guarantee is made on the images ordering, or that any given image will be completed at all.
434 * @see lib3dv::device::connect_image_callback
435 *
436 * @param [in] function The user-defined callback function. Its signature must be <tt> void (boost::shared_ptr<const std::vector<lib3dv::obstacle> > obstacles, uint32_t guid)</tt>.
437 * The @c guid parameter is the same as that of the depth map that has been processed to generate the current set of obstacles.
438 * @return uint64_t An opaque handle that can be passed to lib3dv::device::disconnect_callback to unregister the handler.
439 */
440 uint64_t connect_obstacles_callback(const boost::function<void (boost::shared_ptr<const std::vector<obstacle> >, uint32_t)>& function);
441
442 LIB3DV_DEPRECATED uint64_t connect_obstacles_callback(const boost::function<void (boost::shared_ptr<std::vector<obstacle> >, uint32_t)>& function);
443
444 /**
445 * @brief Register a motion completion handler.
446 *
447 * The supplied user-defined function will be called each time a motion estimation is received.
448 * @note The completion handler is executed in the network handling thread, so it should not perform any actual processing.
449 * Instead, it should just copy over the provided shared pointer and notify a worker thread.
450 * @note No guarantee is made on the images ordering, or that any given image will be completed at all.
451 * @see lib3dv::device::connect_image_callback
452 *
453 * @param [in] function The user-defined callback function. Its signature must be <tt> void (boost::shared_ptr<const lib3dv::motion> motion, uint32_t guid)</tt>.
454 * The @c guid parameter is the same as that of the depth map that has been processed to generate the current motion estimation.
455 * @return uint64_t An opaque handle that can be passed to lib3dv::device::disconnect_callback to unregister the handler.
456 */
457 uint64_t connect_motion_callback(const boost::function<void (boost::shared_ptr<const motion>, uint32_t)>& function);
458
459 LIB3DV_DEPRECATED uint64_t connect_motion_callback(const boost::function<void (boost::shared_ptr<motion>, uint32_t)>& function);
460
461 /**
462 * @brief Register a classification completion handler.
463 *
464 * The supplied user-defined function will be called each time a classification is received.
465 * @note The completion handler is executed in the network handling thread, so it should not perform any actual processing.
466 * Instead, it should just copy over the provided shared pointer and notify a worker thread.
467 * @note No guarantee is made on the images ordering, or that any given image will be completed at all.
468 * @see lib3dv::device::connect_image_callback
469 *
470 * @param [in] function The user-defined callback function. Its signature must be <tt> void (boost::shared_ptr<const lib3dv::classification> classificat, uint32_t guid)</tt>.
471 * The @c guid parameter is the same as that of the depth map that has been processed to generate the current classification.
472 * @return uint64_t An opaque handle that can be passed to lib3dv::device::disconnect_callback to unregister the handler.
473 */
474 uint64_t connect_classification_callback(const boost::function<void (boost::shared_ptr<const classification>, uint32_t)>& function);
475
476 LIB3DV_DEPRECATED uint64_t connect_classification_callback(const boost::function<void (boost::shared_ptr<classification>, uint32_t)>& function);
477
478 /**
479 * @brief Register a timeout handler.
480 *
481 * The supplied user-defined function will be called each time a timeout condition is reached.
482 * @see lib3dv::device::timeout
483 * @see lib3dv::device::valid
484 *
485 * @param [in] function The user-defined callback function. Its signature must be <tt>void (void)</tt>.
486 * @return uint64_t An opaque handle that can be passed to lib3dv::device::disconnect_callback to unregister the handler.
487 */
488 uint64_t connect_timeout_callback(const boost::function<void (void)>& function);
489
490 /**
491 * @brief Unregister a given handler.
492 *
493 * @param [in] id The handler ID. No action is performed if it is invalid.
494 * @return void
495 */
496 void disconnect_callback(uint64_t id);
497
498 /**
499 * @brief Generate a textual representation of a given device and insert it into an std::ostream
500 *
501 * @param [out] output The std::ostream to use.
502 * @param [in] device The device to describe.
503 * @return std::ostream& The modified std::ostream
504 */
505 friend LIB3DV_EXPORT std::ostream& operator<< (std::ostream& output, const device& device);
506
507 private:
508
509 device(){}
510
511 friend device create(boost::shared_ptr<detail::device_impl>);
512
513 boost::shared_ptr<detail::device_impl> m_impl;
514 };
515}
516
517#endif
Note: See TracBrowser for help on using the repository browser.