10 #include <Eigen/Geometry>
11 #include <Eigen/src/Geometry/AngleAxis.h>
12 #include <Eigen/src/Geometry/Transform.h>
14 #include <pcl/PointIndices.h>
15 #include <pcl/point_cloud.h>
17 #include <opencv2/core/types.hpp>
18 #include <opencv2/imgproc.hpp>
20 #include <VirtualRobot/MathTools.h>
21 #include <VirtualRobot/VirtualRobot.h>
22 #include <VirtualRobot/math/Helpers.h>
33 #include "conversions/eigen.h"
44 std::vector<Ellipsoid>
54 const Eigen::Vector2f center = (segment.first + segment.second) / 2;
55 const Eigen::Vector2f
v = segment.second - center;
56 const float angle = math::Helpers::Angle(
v);
57 const float r =
v.norm();
60 globalPose.translation().head<2>() = center;
62 Eigen::AngleAxisf(
angle, Eigen::Vector3f::UnitZ()).toRotationMatrix();
64 return Ellipsoid{.
pose = globalPose, .radii = Eigen::Vector2f{r, axisLength}};
69 std::vector<Ellipsoid> ellipsoids;
71 segments.begin(), segments.end(), std::back_inserter(ellipsoids), asEllipsoid);
80 scanClusteringParams(scanClusteringParams),
81 chainApproximationParams(chainApproximationParams)
89 const auto clustersWithFeatures = features(
data.data);
92 return clustersWithFeatures;
96 FeatureExtractor::features(
const LaserScan& scan)
const
98 const auto clusters = detectClusters(scan);
100 std::vector<Features> fs;
103 std::back_inserter(fs),
104 [&](
const LaserScan& cluster)
106 const auto points = toCartesian<Eigen::Vector2f>(cluster);
107 const auto hull = convexHull(points);
111 .circle = circle(points),
112 .ellipsoid = std::nullopt,
113 .chain = chainApproximation(points, hull, chainApproximationParams),
120 std::vector<LaserScan>
121 FeatureExtractor::detectClusters(
const LaserScan& scan)
const
123 ScanClustering clustering(scanClusteringParams);
124 return clustering.detectClusters(scan);
127 std::optional<VirtualRobot::MathTools::ConvexHull2D>
131 if (points.size() < 3)
138 return *VirtualRobot::MathTools::createConvexHull2D(points);
140 catch (std::exception& e)
173 std::optional<Ellipsoid>
174 FeatureExtractor::ellipsoid(
const std::optional<VirtualRobot::MathTools::ConvexHull2D>& hull)
185 if (hull->vertices.size() < 5)
194 std::optional<Circle>
195 FeatureExtractor::circle(
const Points& points)
198 if (points.size() < 5)
204 const auto points2i = conversions::cast<cv::Point2i>(points2f);
208 cv::minEnclosingCircle(points2i, center, radius);
213 std::optional<FeatureExtractor::Points>
214 FeatureExtractor::chainApproximation(
216 const std::optional<VirtualRobot::MathTools::ConvexHull2D>&
convexHull,
227 if (result.condition !=