1 #ifndef __BASE_SAMPLES_DEPTH_MAP_HPP__ 2 #define __BASE_SAMPLES_DEPTH_MAP_HPP__ 5 #include <Eigen/Geometry> 7 #include <base/Angle.hpp> 8 #include <base/Time.hpp> 9 #include <base-logging/Singleton.hpp> 13 #include <boost/cstdint.hpp> 15 namespace base {
namespace samples {
34 typedef Eigen::Matrix<scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::DontAlign | Eigen::RowMajor>
DepthMatrix;
35 typedef const Eigen::Matrix<scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::DontAlign | Eigen::RowMajor>
DepthMatrixConst;
134 vertical_size(0), horizontal_size(0) {}
188 size_t getIndex(uint32_t v_index, uint32_t h_index)
const;
202 bool use_lut =
false,
203 bool skip_invalid_measurements =
true)
const 207 skip_invalid_measurements);
224 const Eigen::Transform<typename T::Scalar,3,Eigen::Affine>& transformation,
225 bool use_lut =
false,
226 bool skip_invalid_measurements =
true)
const 232 throw std::out_of_range(
"Number of rows and columns does not match the distance array size.");
235 if(distances.empty())
239 point_cloud.reserve(distances.size());
242 std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > > rows2column;
243 std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > > columns2pointcloud;
248 convertSingleRow(point_cloud, v, rows2column[v], columns2pointcloud, transformation, skip_invalid_measurements);
265 const Eigen::Transform<typename T::Scalar,3,Eigen::Affine>& first_transformation,
266 const Eigen::Transform<typename T::Scalar,3,Eigen::Affine>& last_transformation,
267 bool use_lut =
false,
268 bool skip_invalid_measurements =
true,
269 bool apply_transforms_vertically =
true)
const 275 throw std::out_of_range(
"Number of rows and columns does not match the distance array size.");
278 if(distances.empty())
282 point_cloud.reserve(distances.size());
285 std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > > rows2column;
286 std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > > columns2pointcloud;
289 Eigen::Matrix<typename T::Scalar,3,1> translation_delta = last_transformation.translation() - first_transformation.translation();
290 Eigen::Quaternion<typename T::Scalar> first_rotation = Eigen::Quaternion<typename T::Scalar>(first_transformation.linear());
291 Eigen::Quaternion<typename T::Scalar> last_rotation = Eigen::Quaternion<typename T::Scalar>(last_transformation.linear());
294 if(!apply_transforms_vertically)
298 Eigen::Transform<typename T::Scalar,3,Eigen::Affine> transformation =
299 Eigen::Transform<typename T::Scalar,3,Eigen::Affine>(first_rotation.slerp((
double)h / (
double)(horizontal_size-1), last_rotation));
300 transformation.pretranslate(first_transformation.translation() + ((double)h / (
double)(horizontal_size-1)) * translation_delta);
301 columns2pointcloud[h] = transformation * columns2pointcloud[h];
307 Eigen::Transform<typename T::Scalar,3,Eigen::Affine>::Identity(),
308 skip_invalid_measurements);
312 std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > > pointcloud2world;
315 Eigen::Transform<typename T::Scalar,3,Eigen::Affine> transformation =
316 Eigen::Transform<typename T::Scalar,3,Eigen::Affine>(first_rotation.slerp((
double)v / (
double)(vertical_size-1), last_rotation));
317 transformation.pretranslate(first_transformation.translation() + ((double)v / (
double)(vertical_size-1)) * translation_delta);
318 pointcloud2world.push_back(transformation);
324 pointcloud2world[v], skip_invalid_measurements);
342 const std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > >& transformations,
343 bool use_lut =
false,
344 bool skip_invalid_measurements =
true,
345 bool apply_transforms_vertically =
true)
const 351 throw std::out_of_range(
"Number of rows and columns does not match the distance array size.");
354 if(distances.empty())
358 point_cloud.reserve(distances.size());
361 std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > > rows2column;
362 std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > > columns2pointcloud;
366 if(!apply_transforms_vertically)
369 throw std::out_of_range(
"Invalid amount of transformations given");
371 columns2pointcloud[h] = transformations[h] * columns2pointcloud[h];
376 Eigen::Transform<typename T::Scalar,3,Eigen::Affine>::Identity(),
377 skip_invalid_measurements);
382 throw std::out_of_range(
"Invalid amount of transformations given");
388 skip_invalid_measurements);
393 template<
typename T, UNIT_AXIS>
class RotationLUT;
400 const Eigen::Transform<typename T::Scalar,3,Eigen::Affine>& row2column,
401 const std::vector< Eigen::Transform<typename T::Scalar,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<typename T::Scalar,3,Eigen::Affine> > >& columns2pointcloud,
402 const Eigen::Transform<typename T::Scalar,3,Eigen::Affine>& pointcloud2world,
403 bool skip_invalid_measurements)
const 408 scalar distance = distances[row_index + h];
411 T point(distance, 0.0, 0.0);
412 point = pointcloud2world * (columns2pointcloud[h] * row2column * point);
413 point_cloud.push_back(point);
415 else if(!skip_invalid_measurements)
417 point_cloud.push_back(T(base::unknown<typename T::Scalar>(),
418 base::unknown<typename T::Scalar>(),
419 base::unknown<typename T::Scalar>()));
426 void computeLocalTransformations(std::vector< Eigen::Transform<T,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<T,3,Eigen::Affine> > >& rows2column,
427 std::vector< Eigen::Transform<T,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<T,3,Eigen::Affine> > >& columns2pointcloud,
428 bool use_lut =
false)
const 431 if(vertical_interval.size() > 2 && vertical_interval.size() !=
vertical_size)
433 std::string err_msg =
"Number of vertical ";
434 err_msg += vertical_projection ==
POLAR ?
"angles " :
"distances ";
435 err_msg +=
"does no match the expected number of entries.";
436 throw std::invalid_argument(err_msg);
438 if(horizontal_interval.size() > 2 && horizontal_interval.size() !=
horizontal_size)
440 std::string err_msg =
"Number of horizontal ";
441 err_msg += horizontal_projection ==
POLAR ?
"angles " :
"distances ";
442 err_msg +=
"does no match the expected number of entries.";
443 throw std::invalid_argument(err_msg);
447 rows2column.resize(vertical_size, Eigen::Transform<T,3,Eigen::Affine>::Identity());
448 if(vertical_interval.size() == 1)
451 if(vertical_projection ==
PLANAR)
452 rows2column.resize(vertical_size, Eigen::Transform<T,3,Eigen::Affine>(Eigen::AngleAxis<T>(
454 else if(vertical_projection ==
POLAR)
455 rows2column.resize(vertical_size, Eigen::Transform<T,3,Eigen::Affine>(Eigen::AngleAxis<T>(
458 throw std::invalid_argument(
"Invalid argument for vertical projection type.");
460 else if(vertical_interval.size() == 2)
463 std::vector<base::Angle> vertical_angles(vertical_size);
464 double step_resolution =
computeResolution(vertical_interval, vertical_size, vertical_projection);
465 if(vertical_projection ==
PLANAR)
468 vertical_angles[v] =
base::Angle::fromRad(atan(vertical_interval.front() + ((double)v * step_resolution)));
470 else if(vertical_projection ==
POLAR)
473 vertical_angles[v] =
base::Angle::fromRad(vertical_interval.front() + ((double)v * step_resolution));
476 throw std::invalid_argument(
"Invalid argument for vertical projection type.");
480 else if(vertical_interval.size() > 2)
483 std::vector<base::Angle> vertical_angles(vertical_size);
484 if(vertical_projection ==
PLANAR)
487 else if(vertical_projection ==
POLAR)
493 throw std::invalid_argument(
"Invalid argument for vertical projection type.");
499 columns2pointcloud.resize(horizontal_size, Eigen::Transform<T,3,Eigen::Affine>::Identity());
500 if(horizontal_interval.size() == 1)
503 if(horizontal_projection ==
PLANAR)
504 columns2pointcloud.resize(horizontal_size, Eigen::Transform<T,3,Eigen::Affine>(Eigen::AngleAxis<T>(
506 else if(horizontal_projection ==
POLAR)
507 columns2pointcloud.resize(horizontal_size, Eigen::Transform<T,3,Eigen::Affine>(Eigen::AngleAxis<T>(
510 throw std::invalid_argument(
"Invalid argument for horizontal projection type.");
512 else if(horizontal_interval.size() == 2)
515 std::vector<base::Angle> horizontal_angles(horizontal_size);
516 double step_resolution =
computeResolution(horizontal_interval, horizontal_size, horizontal_projection);
517 if(horizontal_projection ==
PLANAR)
520 horizontal_angles[h] =
base::Angle::fromRad(atan(-1.0 * (horizontal_interval.front() + ((double)h * step_resolution))));
522 else if(horizontal_projection ==
POLAR)
525 horizontal_angles[h] =
base::Angle::fromRad(horizontal_interval.front() + ((double)h * step_resolution));
528 throw std::invalid_argument(
"Invalid argument for horizontal projection type.");
532 else if(horizontal_interval.size() > 2)
535 std::vector<base::Angle> horizontal_angles(horizontal_size);
536 if(horizontal_projection ==
PLANAR)
539 else if(horizontal_projection ==
POLAR)
543 throw std::invalid_argument(
"Invalid argument for horizontal projection type.");
551 void computeRotations(std::vector< Eigen::Transform<T,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<T,3,Eigen::Affine> > >& rotations,
552 const std::vector<base::Angle>& angles,
554 bool use_lut =
false)
const 557 rotations.resize(angles.size());
563 RotationLUT<T,UNIT_X>* lut = Singleton< RotationLUT<T,UNIT_X> >::getInstance();
564 for(
unsigned i = 0; i < angles.size(); i++)
565 rotations[i] = lut->getTransformation(angles[i].getRad());
569 RotationLUT<T,UNIT_Y>* lut = Singleton< RotationLUT<T,UNIT_Y> >::getInstance();
570 for(
unsigned i = 0; i < angles.size(); i++)
571 rotations[i] = lut->getTransformation(angles[i].getRad());
575 RotationLUT<T,UNIT_Z>* lut = Singleton< RotationLUT<T,UNIT_Z> >::getInstance();
576 for(
unsigned i = 0; i < angles.size(); i++)
577 rotations[i] = lut->getTransformation(angles[i].getRad());
582 for(
unsigned i = 0; i < angles.size(); i++)
583 rotations[i] = Eigen::AngleAxis<T>(angles[i].getRad(), Eigen::Matrix<T,3,1>::Unit(axis));
590 if(interval.size() != 2)
591 throw std::invalid_argument(
"Expecting two interval values.");
593 double step_resolution = 0.0;
596 double diff = interval.back() - interval.front();
597 step_resolution = diff / (double)(elements-1);
599 else if(projection ==
POLAR)
601 if(interval.back() == interval.front())
602 step_resolution = (2.0 * M_PI) / (double)(elements-1);
604 step_resolution = (interval.back() - interval.front()) / (
double)(elements-1);
607 throw std::invalid_argument(
"Invalid argument for projection type.");
609 return step_resolution;
618 template<
typename T, UNIT_AXIS unit_axis>
621 static const unsigned resolution = 36000;
624 Eigen::Transform<T,3,Eigen::Affine> getTransformation(
double rad)
626 uint16_t deg = (uint16_t)((rad < 0.0 ? rad + 2.0*M_PI: rad) * rad2deg);
627 return transformations[deg];
630 RotationLUT() : rad2deg( ((
double)resolution) / (2.0*M_PI) ), deg2rad( (2.0*M_PI) / ((
double)resolution) )
632 transformations.resize(resolution);
633 for(
unsigned i = 0; i < resolution; i++)
634 transformations[i] = Eigen::Transform<T,3,Eigen::Affine>(Eigen::AngleAxis<T>((
double)i * deg2rad, Eigen::Matrix<T,3,1>::Unit(unit_axis)));
636 virtual ~RotationLUT() {}
641 std::vector< Eigen::Transform<T,3,Eigen::Affine>, Eigen::aligned_allocator< Eigen::Transform<T,3,Eigen::Affine> > > transformations;
Definition: DepthMap.hpp:42
const Eigen::Map< DepthMatrixConst > DepthMatrixMapConst
Definition: DepthMap.hpp:37
bool isMeasurementValid(uint32_t v_index, uint32_t h_index) const
Definition: DepthMap.cpp:68
const Eigen::Matrix< scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::DontAlign|Eigen::RowMajor > DepthMatrixConst
Definition: DepthMap.hpp:35
Definition: DepthMap.hpp:50
bool isIndexValid(size_t index) const
Definition: DepthMap.cpp:60
float scalar
Definition: DepthMap.hpp:32
double computeResolution(const std::vector< double > &interval, uint32_t elements, PROJECTION_TYPE projection) const
Definition: DepthMap.hpp:588
void computeRotations(std::vector< Eigen::Transform< T, 3, Eigen::Affine >, Eigen::aligned_allocator< Eigen::Transform< T, 3, Eigen::Affine > > > &rotations, const std::vector< base::Angle > &angles, UNIT_AXIS axis, bool use_lut=false) const
Definition: DepthMap.hpp:551
PROJECTION_TYPE
Definition: DepthMap.hpp:47
void convertDepthMapToPointCloud(std::vector< T > &point_cloud, const std::vector< Eigen::Transform< typename T::Scalar, 3, Eigen::Affine >, Eigen::aligned_allocator< Eigen::Transform< typename T::Scalar, 3, Eigen::Affine > > > &transformations, bool use_lut=false, bool skip_invalid_measurements=true, bool apply_transforms_vertically=true) const
Definition: DepthMap.hpp:341
Definition: DepthMap.hpp:57
std::vector< scalar > distances
Definition: DepthMap.hpp:124
Definition: DepthMap.hpp:44
static double normalizeRad(double rad)
Definition: Angle.hpp:75
void reset()
Definition: DepthMap.cpp:7
DEPTH_MEASUREMENT_STATE
Definition: DepthMap.hpp:39
Definition: DepthMap.hpp:49
void convertSingleRow(std::vector< T > &point_cloud, unsigned int row, const Eigen::Transform< typename T::Scalar, 3, Eigen::Affine > &row2column, const std::vector< Eigen::Transform< typename T::Scalar, 3, Eigen::Affine >, Eigen::aligned_allocator< Eigen::Transform< typename T::Scalar, 3, Eigen::Affine > > > &columns2pointcloud, const Eigen::Transform< typename T::Scalar, 3, Eigen::Affine > &pointcloud2world, bool skip_invalid_measurements) const
Definition: DepthMap.hpp:398
std::vector< base::Time > timestamps
Definition: DepthMap.hpp:71
uint32_t vertical_size
Definition: DepthMap.hpp:114
void convertDepthMapToPointCloud(std::vector< T > &point_cloud, bool use_lut=false, bool skip_invalid_measurements=true) const
Definition: DepthMap.hpp:201
size_t getIndex(uint32_t v_index, uint32_t h_index) const
Definition: DepthMap.cpp:83
std::vector< double > vertical_interval
Definition: DepthMap.hpp:97
Definition: DepthMap.hpp:29
boost::uint32_t uint32_t
Definition: DepthMap.hpp:33
static Angle fromRad(double rad)
Definition: Angle.hpp:85
Definition: DepthMap.hpp:41
UNIT_AXIS
Definition: DepthMap.hpp:53
DepthMatrixMap getDistanceMatrixMap()
Definition: DepthMap.cpp:20
uint32_t horizontal_size
Definition: DepthMap.hpp:117
Definition: LinearAngular6DCommand.hpp:8
bool checkSizeConfig() const
Definition: DepthMap.cpp:88
base::Time time
Definition: DepthMap.hpp:65
Eigen::Map< DepthMatrix > DepthMatrixMap
Definition: DepthMap.hpp:36
void computeLocalTransformations(std::vector< Eigen::Transform< T, 3, Eigen::Affine >, Eigen::aligned_allocator< Eigen::Transform< T, 3, Eigen::Affine > > > &rows2column, std::vector< Eigen::Transform< T, 3, Eigen::Affine >, Eigen::aligned_allocator< Eigen::Transform< T, 3, Eigen::Affine > > > &columns2pointcloud, bool use_lut=false) const
Definition: DepthMap.hpp:426
Eigen::Matrix< scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::DontAlign|Eigen::RowMajor > DepthMatrix
Definition: DepthMap.hpp:34
DepthMatrixMapConst getDistanceMatrixMapConst() const
Definition: DepthMap.cpp:25
Definition: DepthMap.hpp:55
DepthMap()
Definition: DepthMap.hpp:133
DEPTH_MEASUREMENT_STATE getMeasurementState(uint32_t v_index, uint32_t h_index) const
Definition: DepthMap.cpp:38
Definition: DepthMap.hpp:43
DEPTH_MEASUREMENT_STATE getIndexState(size_t index) const
Definition: DepthMap.cpp:30
PROJECTION_TYPE horizontal_projection
Definition: DepthMap.hpp:83
std::vector< double > horizontal_interval
Definition: DepthMap.hpp:111
std::vector< scalar > remissions
Definition: DepthMap.hpp:131
PROJECTION_TYPE vertical_projection
Definition: DepthMap.hpp:77
void convertDepthMapToPointCloud(std::vector< T > &point_cloud, const Eigen::Transform< typename T::Scalar, 3, Eigen::Affine > &transformation, bool use_lut=false, bool skip_invalid_measurements=true) const
Definition: DepthMap.hpp:223
Definition: DepthMap.hpp:56
void convertDepthMapToPointCloud(std::vector< T > &point_cloud, const Eigen::Transform< typename T::Scalar, 3, Eigen::Affine > &first_transformation, const Eigen::Transform< typename T::Scalar, 3, Eigen::Affine > &last_transformation, bool use_lut=false, bool skip_invalid_measurements=true, bool apply_transforms_vertically=true) const
Definition: DepthMap.hpp:264