ArVizDrawerMapBuilder.cpp
Go to the documentation of this file.
2
3#include <iomanip>
4
5#include <Eigen/Core>
6#include <Eigen/Geometry>
7
8#include <SimoxUtility/algorithm/get_map_keys_values.h>
9#include <SimoxUtility/iterator.h>
10
15
19
21
23{
24
25
26 constexpr int mToMM{1000};
27
28 inline Eigen::Vector3f
29 toMM(const Eigen::Vector3f& vec)
30 {
31 return vec * 1000;
32 }
33
34 inline Eigen::Isometry3f
35 toMM(Eigen::Isometry3f pose)
36 {
37 pose.translation() *= 1000;
38 return pose;
39 }
40
41 inline std::string
42 nameWithId(const std::string& name, const int id, const unsigned int idWidth = 6)
43 {
44 std::stringstream ss;
45 ss << name << "_" << std::setw(static_cast<int>(idWidth)) << std::setfill('0') << id;
46 return ss.str();
47 }
48
49 inline std::string
50 nameWithIds(const std::string& name,
51 const int id,
52 const int subId,
53 const unsigned int idWidth = 6)
54 {
55 std::stringstream ss;
56 ss << name << "_" << std::setw(static_cast<int>(idWidth)) << std::setfill('0') << id << "_"
57 << std::setw(static_cast<int>(idWidth)) << std::setfill('0') << subId;
58 return ss.str();
59 }
60
61 auto
62 toVizColor(const ColoredMeshGrid::ColorGrid& colorGrid, const Eigen::Array2i& numCells)
63 {
64 std::vector<std::vector<viz::data::Color>> colors(
65 numCells.x(), std::vector<viz::data::Color>(numCells.y(), viz::Color::black()));
66
67 auto toVizColor = [](const ColoredMeshGrid::Color& c)
68 { return viz::Color(c.x(), c.y(), c.z(), c.w()); };
69
70 auto xyIter = simox::iterator::XYIndexRangeIterator({numCells.x(), numCells.y()});
71 std::for_each(xyIter.begin(),
72 xyIter.end(),
73 [&](const auto& p)
74 {
75 const auto& [x, y] = p;
76 colors[x][y] = toVizColor(colorGrid[x][y]);
77 });
78
79 return colors;
80 }
81
82 auto
84 {
85 // convert all from [m] to [mm]
86 for (auto& vv : vvertices)
87 {
88 for (auto& v : vv)
89 {
90 v *= 1000;
91 }
92 }
93
94 return vvertices;
95 }
96
97 /****** ***********/
98
100 armarx::viz::Client& arviz,
101 ::cartographer::mapping::MapBuilderInterface& mapBuilder,
102 const Eigen::Isometry3f& world_T_map) :
103 arviz(arviz),
104 mapBuilder(mapBuilder),
105 runningTask(new RunningTask<ArVizDrawerMapBuilder>(this, &ArVizDrawerMapBuilder::run)),
106 world_T_map(world_T_map)
107 {
109 }
110
111 void
113 {
114 ARMARX_CHECK_NOT_NULL(runningTask);
115 runningTask->start();
116 }
117
119 {
120 ARMARX_CHECK_NOT_NULL(runningTask);
121 runningTask->stop();
122 }
123
124 void
125 ArVizDrawerMapBuilder::run()
126 {
128
129 while (!runningTask->isStopped())
130 {
131 drawOnce();
132 metronome.waitForNextTick();
133 }
134 }
135
136 void
138 {
139 ARMARX_VERBOSE << "Updating visualization";
140 drawFrames();
141 // drawOptimizedPoseGraph();
142 drawGridMap();
143 }
144
145 void
146 ArVizDrawerMapBuilder::drawFrames()
147 {
148 auto framesLayer = arviz.layer("frames");
149
150 const auto mapPose =
151 viz::Pose(MapFrame).pose(world_T_map.translation(), world_T_map.linear()).scale(5.F);
152 const auto worldPose = viz::Pose(GlobalFrame).scale(5.F);
153
154 const auto arr = viz::Arrow(GlobalFrame + "/" + MapFrame)
155 .fromTo(Eigen::Vector3f::Zero(), world_T_map.translation());
156
157 framesLayer.add(worldPose);
158 framesLayer.add(mapPose);
159 framesLayer.add(arr);
160 arviz.commit(framesLayer);
161 }
162
163 void
164 ArVizDrawerMapBuilder::drawOptimizedPoseGraph()
165 {
166 auto optimizedGraphLayerGlobal = arviz.layer("optimized_graph_global");
167
168 const auto optimizedGraphData = utils::optimizedGraphData(mapBuilder);
169
170 for (const auto& nodeData : optimizedGraphData.nodes_data)
171 {
172 const Eigen::Isometry3f globalPose = world_T_map * toMM(nodeData.global_pose);
173
174 const auto globalPoseViz = viz::Pose("node_" + std::to_string(nodeData.node_id))
175 .position(globalPose.translation())
176 .orientation(globalPose.linear());
177 optimizedGraphLayerGlobal.add(globalPoseViz);
178 }
179
180 arviz.commit(optimizedGraphLayerGlobal);
181 }
182
183 void
184 ArVizDrawerMapBuilder::drawGridMap()
185 {
186 const SubMapDataVector submapData = utils::submapData(mapBuilder, 0); // TODO
187
188 std::map<int, viz::Layer> layers;
189
190 if (submapData.empty())
191 {
192 return;
193 }
194
195 for (const auto& submap : submapData)
196 {
197 if (layers.find(submap.trajectory_id) == layers.end())
198 {
199 layers[submap.trajectory_id] =
200 arviz.layer(nameWithId("grid_maps_trajectory", submap.trajectory_id));
201 }
202
203 auto& gridMapLayer = layers.at(submap.trajectory_id);
204
205 auto mesh = viz::Mesh(nameWithIds("submap", submap.trajectory_id, submap.id));
206
207 const Eigen::Isometry3f mapPose = toMM(submap.global_pose());
208 const Eigen::Isometry3f globalPose = world_T_map * mapPose;
209
210 // ARMARX_DEBUG << "arviz drawer: submap pose " << submapPose.matrix();
211
212 mesh.position(globalPose.translation() + Eigen::Vector3f{0.F, 0.F, -1.F})
213 .orientation(globalPose.linear())
214 .grid2D(toVizPoint(submap.mesh_grid.vertices),
215 toVizColor(submap.mesh_grid.colors, submap.mesh_grid.num_cells));
216
217 gridMapLayer.add(mesh);
218 }
219
220 const auto layersV = simox::alg::get_values(layers);
221 arviz.commit(layersV);
222 }
223
224} // namespace armarx::localization_and_mapping::cartographer_adapter
constexpr T c
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
Simple rate limiter for use in loops to maintain a certain frequency given a clock.
Definition Metronome.h:57
ArVizDrawerMapBuilder(armarx::viz::Client &arviz, ::cartographer::mapping::MapBuilderInterface &mapBuilder, const Eigen::Isometry3f &world_T_map)
virtual Layer layer(std::string const &name) const
Definition Client.cpp:80
CommitResult commit(StagedCommit const &commit)
Definition Client.cpp:89
DerivedT & pose(Eigen::Matrix4f const &pose)
Definition ElementOps.h:176
DerivedT & position(float x, float y, float z)
Definition ElementOps.h:136
DerivedT & orientation(Eigen::Quaternionf const &ori)
Definition ElementOps.h:152
DerivedT & scale(Eigen::Vector3f scale)
Definition ElementOps.h:254
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
SubMapDataVector submapData(::cartographer::mapping::MapBuilderInterface &mapBuilder, const int trajectoryId)
Definition utils.cpp:60
OptimizedGraphData optimizedGraphData(::cartographer::mapping::MapBuilderInterface &mapBuilder)
Definition utils.cpp:27
Eigen::Vector3f toMM(const Eigen::Vector3f &vec)
auto toVizColor(const ColoredMeshGrid::ColorGrid &colorGrid, const Eigen::Array2i &numCells)
std::string nameWithId(const std::string &name, const int id, const unsigned int idWidth=6)
std::string nameWithIds(const std::string &name, const int id, const int subId, const unsigned int idWidth=6)
auto toVizPoint(ColoredMeshGrid::VertexGrid vvertices)
std::string const MapFrame
Definition FramedPose.h:67
Arrow & fromTo(const Eigen::Vector3f &from, const Eigen::Vector3f &to)
Definition Elements.h:219
#define ARMARX_TRACE
Definition trace.h:77