7 #include <Eigen/Geometry>
9 #include <SimoxUtility/algorithm/apply.hpp>
10 #include <SimoxUtility/algorithm/get_map_keys_values.h>
11 #include <SimoxUtility/color/Color.h>
12 #include <SimoxUtility/color/ColorMap.h>
13 #include <SimoxUtility/color/hsv.h>
14 #include <SimoxUtility/math/pose.h>
19 #include <ArmarXCore/interface/core/PackagePath.h>
27 #include <RobotAPI/interface/components/TrajectoryPlayerInterface.h>
29 #include <RobotAPI/libraries/armem_laser_scans/aron/LaserScan.aron.generated.h>
46 p.enabled, prefix +
"enabled",
"Enable or disable visualization of objects.");
47 defs->optional(p.frequencyHz, prefix +
"frequenzyHz",
"Frequency of visualization.");
49 p.uniformColor, prefix +
"uniformColor",
"If enabled, points will be drawn in red.");
50 defs->optional(p.maxRobotAgeMs,
51 prefix +
"maxRobotAgeMs",
52 "Maximum age of robot state before a new one is retrieved in milliseconds.");
53 defs->optional(p.colorByIntensity,
"colorByIntensity",
"");
60 this->coreSegment = coreSegment;
61 this->virtualRobotReader = virtualRobotReader;
70 bool batchMode =
true;
87 CycleUtil cycle(
static_cast<int>(1000 / p.frequencyHz));
88 while (updateTask and not updateTask->isStopped())
97 visualizeOnce(timestamp);
99 catch (
const std::exception& e)
101 ARMARX_WARNING <<
"Caught exception while visualizing robots: \n" << e.what();
105 ARMARX_WARNING <<
"Caught unknown exception while visualizing robots.";
108 if (debugObserver.has_value())
110 debugObserver->sendDebugObserverBatch();
113 cycle.waitForCycleDuration();
118 Visu::visualizeScan(
const std::vector<ScanPoint>& points,
119 const std::string& sensorName,
120 const std::string& agentName,
125 ARMARX_VERBOSE <<
"Point cloud with " << points.size() <<
" points";
127 for (
const auto& point : points)
133 if (p.colorByIntensity)
135 Eigen::Vector3f hsv = simox::color::rgb_to_hsv(
136 Eigen::Vector3f(
static_cast<float>(color.r) / 255.f,
137 static_cast<float>(color.g) / 255.f,
138 static_cast<float>(color.b) / 255.f));
142 hsv(2) = std::clamp<float>(point.intensity, 0., 1.);
144 const Eigen::Vector3f rgb = simox::color::hsv_to_rgb(hsv);
152 pointCloud.addPoint(point.point.x(), point.point.y(), point.point.z(), specificColor);
155 pointCloud.pointSizeInPixels(3);
163 std::vector<ScanPoint>
165 const Eigen::Isometry3f& global_T_sensor)
167 const auto scanCartesian =
168 armarx::armem::laser_scans::util::toCartesian<Eigen::Vector3f>(scan.
data);
170 std::vector<ScanPoint> points;
171 points.reserve(scan.
data.size());
173 for (std::size_t i = 0; i < scan.
data.size(); i++)
175 const auto& point = scanCartesian.at(i);
176 const auto& raw = scan.
data.at(i);
178 const Eigen::Vector3f pointGlobal = global_T_sensor * point;
179 points.push_back(
ScanPoint{.
point = pointGlobal, .intensity = raw.intensity});
227 std::map<std::string, armem::laser_scans::LaserScanStamped>
228 Visu::getCurrentLaserScans()
235 const std::optional<armarx::armem::laser_scans::arondto::LaserScanStamped> dto =
236 tryCast<armarx::armem::laser_scans::arondto::LaserScanStamped>(entityInstance);
241 fromAron(dto.value(), laserScanStamped);
243 const auto ndArrayNavigator =
248 laserScanStamped.
data =
249 armarx::armem::laser_scans::fromAron<LaserScanStep>(ndArrayNavigator);
253 return laserScanStamped;
256 std::map<std::string, armem::laser_scans::LaserScanStamped> scans;
260 const auto scan =
convert(instance);
261 scans[instance.id().providerSegmentName +
"/" + instance.id().entityName] = scan;
264 const auto applyToEntity = [&](
const wm::Entity& entity)
271 const auto& snapshot = entity.getLatestSnapshot();
273 snapshot.forEachInstance(applyToInstance);
276 const auto applyToProviderSegment = [&](
const auto& providerSegment)
277 { providerSegment.forEachEntity(applyToEntity); };
286 Visu::visualizeOnce(
const Time& timestamp)
288 std::map<std::string, armem::laser_scans::LaserScanStamped> currentLaserScans =
289 getCurrentLaserScans();
293 for (
const auto& [provider, scan] : currentLaserScans)
297 const auto global_T_sensor = [&]() -> Eigen::Isometry3f
299 const auto robot = getSynchronizedRobot(scan.header.agent, scan.header.timestamp);
307 const auto sensorNode = robot->getRobotNode(scan.header.frame);
309 <<
"` for robot `" << scan.header.agent <<
"`";
311 ARMARX_VERBOSE <<
"Sensor position for sensor `" << scan.header.frame <<
"` is "
312 << sensorNode->getGlobalPosition();
313 return Eigen::Isometry3f{sensorNode->getGlobalPose()};
326 return simox::color::GlasbeyLUT::at(i++);
329 visualizeScan(points, scan.header.frame, scan.header.agent, color);
334 Visu::getSynchronizedRobot(
const std::string& name,
const DateTime& timestamp)
336 if (robots.count(name) == 0)
339 const auto robot = virtualRobotReader->
getRobot(name);
351 auto& entry = robots.at(name);
352 if (entry.second.isInvalid() ||
357 entry.second = timestamp;