11 #include <Eigen/Geometry>
13 #include <SimoxUtility/algorithm/apply.hpp>
14 #include <SimoxUtility/algorithm/get_map_keys_values.h>
15 #include <SimoxUtility/algorithm/string/string_tools.h>
16 #include <SimoxUtility/color/Color.h>
17 #include <SimoxUtility/color/ColorMap.h>
18 #include <SimoxUtility/color/cmaps/colormaps.h>
19 #include <VirtualRobot/Robot.h>
20 #include <VirtualRobot/VirtualRobot.h>
43 #include <range/v3/algorithm/max_element.hpp>
44 #include <range/v3/view/enumerate.hpp>
52 const std::vector<std::string> packages =
54 const std::string
package = armarx::ArmarXDataPath::getProject(packages, absfilepath);
57 const std::string relPath = [&absfilepath, &package]() -> std::string
62 return absfilepath.substr(package.size() + 1, -1);
68 return {package, relPath};
74 arviz(arviz), robot(robot), objClient(objClient)
78 robotPosesLayer = arviz.
layer(
"robot_poses");
86 ARMARX_DEBUG <<
"ArvizIntrospector::onGlobalPlannerResult";
89 arviz.
commit(simox::alg::get_values(layers));
97 const std::optional<local_planning::LocalPlannerResult>& result)
101 drawLocalTrajectory(result.value().trajectory);
105 drawLocalTrajectory(std::nullopt);
108 arviz.
commit(simox::alg::get_values(layers));
131 auto layer = arviz.
layer(
"goal");
134 robotPosesLayer.
clear();
146 constexpr
float eps = 50;
155 if ((lastPose->translation() - pose.translation()).norm() < eps)
164 arviz.
commit(robotPosesLayer);
170 auto layer = arviz.
layer(
"graph_shortest_path");
173 {
return pose.translation(); };
176 std::vector<core::Position> pts;
177 pts.reserve(path.size());
178 std::transform(path.begin(), path.end(), std::back_inserter(pts), toPosition);
183 for (
size_t i = 0; i < (pts.size() - 1); i++)
186 .
fromTo(pts.at(i), pts.at(i + 1))
199 auto layer = arviz.
layer(
"global_planner");
204 const auto cmap = simox::color::cmaps::viridis();
206 const float maxVelocity = ranges::max_element(trajectory.
points(),
207 [](
const auto&
a,
const auto& b)
208 { return a.velocity < b.velocity; })
212 for (
const auto& [idx, tp] : trajectory.
points() | ranges::views::enumerate)
214 const float scale = tp.velocity;
216 const Eigen::Vector3f
target =
217 scale * tp.waypoint.pose.linear() * Eigen::Vector3f::UnitY();
221 .fromTo(tp.waypoint.pose.translation(), tp.waypoint.pose.translation() +
target)
222 .
color(cmap.at(tp.velocity / maxVelocity)));
225 layers[layer.data_.name] = std::move(layer);
229 ArvizIntrospector::drawLocalTrajectory(
const std::optional<core::LocalTrajectory>&
input)
234 auto layer = arviz.
layer(
"local_planner");
235 auto velLayer = arviz.
layer(
"local_planner_velocity");
237 layers[layer.data_.name] = std::move(layer);
238 layers[velLayer.data_.name] = std::move(velLayer);
242 const auto trajectory =
input.value();
244 auto layer = arviz.
layer(
"local_planner");
246 const std::vector<Eigen::Vector3f> points =
247 simox::alg::apply(trajectory.
points(),
248 [](
const core::LocalTrajectoryPoint& pt) -> Eigen::Vector3f
249 { return pt.pose.translation(); });
255 auto velLayer = arviz.
layer(
"local_planner_velocity");
257 simox::ColorMap cm = simox::color::cmaps::inferno();
261 for (
size_t i = 0; i < trajectory.
points().size() - 1; i++)
263 const core::LocalTrajectoryPoint start = trajectory.
points().at(i);
264 const core::LocalTrajectoryPoint end = trajectory.
points().at(i + 1);
266 const Duration dT = end.timestamp - start.timestamp;
267 const Eigen::Vector3f
distance = end.pose.translation() - start.pose.translation();
268 const float speed =
distance.norm() / 1000 / dT.toSecondsDouble();
270 const Eigen::Vector3f pos = start.pose.translation() +
distance / 2;
277 layers[layer.data_.name] = std::move(layer);
278 layers[velLayer.data_.name] = std::move(velLayer);
282 ArvizIntrospector::drawRawVelocity(
const core::Twist& twist)
284 auto layer = arviz.
layer(
"trajectory_controller");
287 .fromTo(robot->getGlobalPosition(),
288 core::Pose(robot->getGlobalPose()) * twist.linear)
291 layers[layer.data_.name] = std::move(layer);
295 ArvizIntrospector::drawSafeVelocity(
const core::Twist& twist)
297 auto layer = arviz.
layer(
"safety_guard");
300 .fromTo(robot->getGlobalPosition(),
301 core::Pose(robot->getGlobalPose()) * twist.linear)
304 layers[layer.data_.name] = std::move(layer);
308 arviz{other.arviz}, robot{other.robot}, layers(std::move(other.layers))
317 for (
auto& [name, layer] : layers)
319 layer.markForDeletion();
321 arviz.
commit(simox::alg::get_values(layers));
339 auto layer = arviz.
layer(
"global_planning_graph");
344 for (
const auto& edge : graph.edges())
347 const auto sourcePose = graph.vertex(edge.sourceDescriptor()).attrib().getPose();
348 const auto targetPose = graph.vertex(edge.targetDescriptor()).attrib().getPose();
353 if (edge.attrib().cost() > 100
'000) // "NaN check"
355 return viz::Color::red();
358 return viz::Color::green();
361 const auto from = core::resolveLocation(objects, info, sourcePose);
362 const auto to = core::resolveLocation(objects, info, sourcePose);
364 if (from.pose.has_value() && to.pose.has_value())
367 viz::Arrow(std::to_string(edge.sourceObjectID().t) + " -> " +
368 std::to_string(edge.targetObjectID().t))
369 .fromTo(from.pose.value().translation(), to.pose.value().translation())
378 ArvizIntrospector::success()
382 // visualization.success();
386 ArvizIntrospector::failure()
390 // visualization.failed();
394 } // namespace armarx::navigation::server