ArVizDrawer.cpp
Go to the documentation of this file.
1#include "ArVizDrawer.h"
2
3#include <Eigen/Core>
4#include <Eigen/Geometry>
5
6#include <pcl/point_cloud.h>
7#include <pcl/point_types.h>
8
9#include <SimoxUtility/iterator/xy_index_range_iterator.h>
10#include <SimoxUtility/shapes/OrientedBox.h>
11
13
17
19{
20
21 template <typename EigenVectorT>
22 EigenVectorT
23 toCartesian(const LaserScanStep& laserScanStep)
24 {
25 EigenVectorT point = EigenVectorT::Zero();
26
27 point.x() = laserScanStep.distance * std::cos(laserScanStep.angle);
28 point.y() = laserScanStep.distance * std::sin(laserScanStep.angle);
29
30 return point;
31 }
32
33 void
34 ArVizDrawer::drawBoundingBoxes(const std::vector<VirtualRobot::BoundingBox>& boundingBoxes)
35 {
36
37 auto layer = this->layer("bounding_boxes");
38 int i = 0;
39
40 for (const VirtualRobot::BoundingBox& bb : boundingBoxes)
41 {
42 const Eigen::Vector3f center((bb.getMin() + bb.getMax()) / 2);
43 const Eigen::Vector3f extents = (bb.getMax() - bb.getMin());
44
45 const auto box = viz::Box("bb_" + std::to_string(i++))
46 .position(center)
47 .size(extents)
48 .color(0, 255, 0, 255);
49 layer.add(box);
50 }
51
53 }
54
56 {
57 public:
58 using Color = Eigen::Vector4i;
59 using Position = Eigen::Vector3f;
60
61 using ColorGrid = std::vector<std::vector<Color>>;
62 using VertexGrid = std::vector<std::vector<Position>>;
63
64 ColoredMeshGrid(Eigen::Array2i numCells) :
65 numCells(numCells),
66 vertices(numCells.x(), std::vector<Position>(numCells.y(), Position::Zero())),
67 colors(numCells.x(), std::vector<Color>(numCells.y(), Color::Zero()))
68 {
69 }
70
71 void
72 setColoredVertex(const Eigen::Array2i& idx, const Position& position, const Color& color)
73 {
74 vertices.at(idx.x()).at(idx.y()) = position;
75 colors.at(idx.x()).at(idx.y()) = color;
76 }
77
78 void
79 apply(const auto& posFn, const auto& colorFn)
80 {
81 for (int x = 0; x < numCells.x(); x++)
82 {
83 for (int y = 0; y < numCells.y(); y++)
84 {
85 const Eigen::Array2i idx{x, y};
86 setColoredVertex(idx, posFn(idx), colorFn(idx));
87 }
88 }
89 }
90
91 std::vector<std::vector<viz::data::Color>>
93 {
94 std::vector<std::vector<viz::data::Color>> colors(
95 numCells.x(), std::vector<viz::data::Color>(numCells.y(), viz::Color::black()));
96
97 auto toVizColor = [](const ColoredMeshGrid::Color& c)
98 { return viz::Color(c.x(), c.y(), c.z(), c.w()); };
99
100 auto xyIter = simox::iterator::XYIndexRangeIterator({numCells.x(), numCells.y()});
101 std::for_each(xyIter.begin(),
102 xyIter.end(),
103 [&](const auto& p)
104 {
105 const auto& [x, y] = p;
106 colors[x][y] = toVizColor(this->colors[x][y]);
107 });
108
109 return colors;
110 }
111
112 const VertexGrid&
114 {
115 return vertices;
116 }
117
118 private:
119 Eigen::Array2i numCells;
120
121 VertexGrid vertices;
122 ColorGrid colors;
123 };
124
125 void
126 ArVizDrawer::drawOccupancyGrid(const OccupancyGrid& grid, const float boxPosZ)
127 {
128 ARMARX_INFO << "Occupancy grid size " << Eigen::Array2i{grid.sizeX, grid.sizeY};
129
130 auto layer = this->layer("occupancy_grid");
131
132 ColoredMeshGrid meshGrid(Eigen::Array2i{grid.sizeX, grid.sizeY});
133
134 const auto posFn = [&](const Eigen::Array2i& idx) -> ColoredMeshGrid::Position
135 {
136 const auto pos2d = grid.getCentralPosition(idx.x(), idx.y());
137 return {pos2d.x(), pos2d.y(), 0.F};
138 };
139
140 const ColoredMeshGrid::Color colorBlack{0, 0, 0, 255};
141 const ColoredMeshGrid::Color colorWhite{255, 255, 255, 255};
142
143 const auto colorFn = [&](const Eigen::Array2i& idx) -> ColoredMeshGrid::Color
144 {
145 if (grid.isOccupied(static_cast<std::size_t>(idx.x()),
146 static_cast<std::size_t>(idx.y())))
147 {
148 ARMARX_IMPORTANT << "Cell is occupied";
149 }
150 return grid.isOccupied(static_cast<std::size_t>(idx.x()),
151 static_cast<std::size_t>(idx.y()))
152 ? colorBlack
153 : colorWhite;
154 };
155
156 meshGrid.apply(posFn, colorFn);
157
158 const auto mesh = viz::Mesh("grid")
159 .position(Eigen::Vector3f{0.F, 0.F, boxPosZ})
160 .grid2D(meshGrid.getVertices(), meshGrid.getColors());
161
162 layer.add(mesh);
163 commit(layer);
164 }
165
166 pcl::PointCloud<pcl::PointXYZ>
167 toPointCloud(const LaserScan& scan)
168 {
169 pcl::PointCloud<pcl::PointXYZ> cloud;
170 cloud.points.reserve(scan.size());
171
172 std::transform(scan.begin(),
173 scan.end(),
174 std::back_inserter(cloud.points),
175 [&](const auto& scanStep) -> pcl::PointXYZ
176 {
177 const auto rangePoint = toCartesian<Eigen::Vector3f>(scanStep); // [mm]
178
179 pcl::PointXYZ pt;
180 pt.x = rangePoint.x();
181 pt.y = rangePoint.y();
182 pt.z = rangePoint.z();
183
184 return pt;
185 });
186
187 cloud.width = scan.size();
188 cloud.height = 1;
189 cloud.is_dense = true;
190
191 return cloud;
192 }
193
194 void
195 ArVizDrawer::prepareScan(const LaserScan& scan,
196 const std::string& frame,
197 const Eigen::Affine3f& scannerPose)
198 {
199
200 const auto pointCloud = toPointCloud(scan);
201
202 frames.insert(frame);
203
204 // skip the first two colors as they are 'black' and 'white'
205 const int id = std::distance(std::begin(frames), frames.find(frame)) + 2;
206
207 clouds.emplace(
208 frame,
209 viz::PointCloud(frame)
210 .pose(scannerPose)
211 .pointSizeInPixels(5)
212 .pointCloud(pointCloud.points, viz::Color(simox::color::GlasbeyLUT::at(id))));
213 }
214
215 void
217 {
218 auto layer = this->layer("scans");
219
220 for (const auto& [_, pc] : clouds)
221 {
222 layer.add(pc);
223 }
224
225 commit(layer);
226
227 // remove all
228 clouds.clear();
229 }
230
231} // namespace armarx::laser_scanner_simulation
constexpr T c
void drawBoundingBoxes(const std::vector< VirtualRobot::BoundingBox > &boundingBoxes)
void drawOccupancyGrid(const OccupancyGrid &grid, float boxPosZ)
void prepareScan(const LaserScan &scan, const std::string &frame, const Eigen::Affine3f &scannerPose)
std::vector< std::vector< Color > > ColorGrid
void apply(const auto &posFn, const auto &colorFn)
void setColoredVertex(const Eigen::Array2i &idx, const Position &position, const Color &color)
std::vector< std::vector< Position > > VertexGrid
std::vector< std::vector< viz::data::Color > > getColors()
CommitResult commit(StagedCommit const &commit)
Definition Client.cpp:89
DerivedT & color(Color color)
Definition ElementOps.h:218
DerivedT & position(float x, float y, float z)
Definition ElementOps.h:136
Layer layer(std::string const &name) const override
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
pcl::PointCloud< pcl::PointXYZ > toPointCloud(const LaserScan &scan)
EigenVectorT toCartesian(const LaserScanStep &laserScanStep)
This file offers overloads of toIce() and fromIce() functions for STL container types.
Box & size(Eigen::Vector3f const &s)
Definition Elements.h:52