MapRegistration.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @author Fabian Reister ( fabian dot reister at kit dot edu )
17 * @date 2021
18 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19 * GNU General Public License
20 */
21
22#pragma once
23
24#include <array>
25#include <cmath>
26#include <cstdint>
27#include <filesystem>
28#include <memory>
29#include <vector>
30
31#include <Eigen/Geometry>
32
33#include <pcl/point_cloud.h>
34#include <pcl/point_types.h>
35
36#include <SimoxUtility/shapes/OrientedBox.h>
37
39#include <ArmarXCore/interface/serialization/Eigen/Eigen_fdi.h>
40
42
44
46#include "models.h"
47
49{
50 class MapBuilderInterface;
51}
52
54{
55
56 struct TimeRange
57 {
58 IceUtil::Time min;
59 IceUtil::Time max;
60
61 IceUtil::Time
62 duration() const noexcept
63 {
64 return max - min;
65 }
66 };
67
69 {
70 Eigen::Vector2f center;
71 float angle;
72 Eigen::Vector2f extends;
73
74 std::array<Eigen::Vector2f, 4>
75 boundary() const
76 {
77 const Eigen::Affine2f centerPose =
78 Eigen::Translation2f(center) * Eigen::Rotation2Df(angle);
79
80 const Eigen::Vector2f e2 = extends / 2.F;
81
82 return {centerPose * Eigen::Vector2f{e2.x(), e2.y()},
83 centerPose * Eigen::Vector2f{-e2.x(), e2.y()},
84 centerPose * Eigen::Vector2f{-e2.x(), -e2.y()},
85 centerPose * Eigen::Vector2f{e2.x(), -e2.y()}};
86 }
87
88 Eigen::Isometry3f
89 cornerPose(int i) const
90 {
91 const float cornerAngle = angle + (i - 2) * M_PI_2f32;
92
93 Eigen::Isometry3f ref_T_corner = Eigen::Isometry3f::Identity();
94 ref_T_corner.translation().template head<2>() = boundary().at(i);
95 ref_T_corner.linear() =
96 Eigen::AngleAxisf(cornerAngle, Eigen::Vector3f::UnitZ()).toRotationMatrix();
97
98 return ref_T_corner;
99 }
100 };
101
103 {
104 public:
105 MapRegistration(std::unique_ptr<::cartographer::mapping::MapBuilderInterface> mapBuilder);
106
108
109 using Point = pcl::PointXYZ;
110 using PointCloud = pcl::PointCloud<Point>;
111
112 struct Cluster
113 {
114 PointCloud::Ptr points;
115
116 pcl::PointXYZ centroid;
117
118 Cluster(const PointCloud::Ptr& points);
119 };
120
121 using Clusters = std::vector<Cluster>;
122
123 Clusters detectClusters(const PointCloud::ConstPtr& cloud) const;
124
126 {
127 Eigen::Affine2f pose;
129 };
130
131 // PointCloud::ConstPtr readPointClouds() const;
132
134 {
137 };
138
139 using Associations = std::vector<Association>;
140
141 Associations matchModelsToClusters(const std::vector<wykobi::Model>& models,
142 const Clusters& clusters,
143 const Eigen::Isometry3f& world_T_map) const;
144
146 {
147 Eigen::Isometry3f correction;
148
149 // fraction of points that support the hypothesis
150 float weight;
151
152 // covariance of the point-projection distance / vectors
153 Eigen::Matrix2f covariance;
154 };
155
158
160 const Cluster& cluster,
161 const Eigen::Isometry3f& world_T_map) const;
162
164 computeCombinedCorrection(const std::vector<wykobi::Model>& models,
165 const std::vector<ModelCorrection>& modelCorrections) const;
166
167 void visualizeResult(const PointCloud::ConstPtr& cloud,
168 const std::vector<wykobi::Model>& models,
169 const ModelCorrection& combinedCorrection) const;
170
171 TimeRange mapTimeRange() const;
172
173 simox::math::InterpolatingTimeQueue<simox::math::PoseStamped> robotPoseQueue() const;
174
175 std::vector<Eigen::Isometry3f> robotPoses() const;
176
177 void computeBoundingBox(const PointCloud::ConstPtr& cloud);
178
179 const RotatedRect&
181 {
182 return boundingBox;
183 }
184
185 private:
186 std::unique_ptr<::cartographer::mapping::MapBuilderInterface> mapBuilder;
187
188 const OptimizedGraphData optimizedGraphData;
189
190 RotatedRect boundingBox;
191 };
192
193} // namespace armarx::localization_and_mapping::cartographer_adapter
ModelCorrection alignModelToCluster(const wykobi::Model &model, const Cluster &cluster, const Eigen::Isometry3f &world_T_map) const
ModelCorrection computeCombinedCorrection(const std::vector< wykobi::Model > &models, const std::vector< ModelCorrection > &modelCorrections) const
Clusters detectClusters(const PointCloud::ConstPtr &cloud) const
void visualizeResult(const PointCloud::ConstPtr &cloud, const std::vector< wykobi::Model > &models, const ModelCorrection &combinedCorrection) const
MapRegistration(std::unique_ptr<::cartographer::mapping::MapBuilderInterface > mapBuilder)
MapRegistration::ModelCorrection computeCorrection(const MapRegistration::Associations &associations)
simox::math::InterpolatingTimeQueue< simox::math::PoseStamped > robotPoseQueue() const
Associations matchModelsToClusters(const std::vector< wykobi::Model > &models, const Clusters &clusters, const Eigen::Isometry3f &world_T_map) const