6 #include <Eigen/Geometry>
8 #include <SimoxUtility/algorithm/apply.hpp>
9 #include <SimoxUtility/algorithm/get_map_keys_values.h>
10 #include <SimoxUtility/color/Color.h>
11 #include <SimoxUtility/color/ColorMap.h>
12 #include <SimoxUtility/color/cmaps/colormaps.h>
13 #include <VirtualRobot/Robot.h>
31 #include <range/v3/algorithm/max.hpp>
32 #include <range/v3/algorithm/max_element.hpp>
33 #include <range/v3/view/enumerate.hpp>
41 const std::vector<std::string> packages =
43 const std::string
package = armarx::ArmarXDataPath::getProject(packages, absfilepath);
46 const std::string relPath = [&absfilepath, &package]() -> std::string
51 return absfilepath.substr(package.size() + 1, -1);
57 return {package, relPath};
63 arviz(arviz), robot(robot), objClient(objClient)
67 robotPosesLayer = arviz.
layer(
"robot_poses");
75 ARMARX_DEBUG <<
"ArvizIntrospector::onGlobalPlannerResult";
78 arviz.
commit(simox::alg::get_values(layers));
86 const std::optional<local_planning::LocalPlannerResult>& result)
90 drawLocalTrajectory(result.value().trajectory);
94 drawLocalTrajectory(std::nullopt);
97 arviz.
commit(simox::alg::get_values(layers));
120 auto layer = arviz.
layer(
"goal");
123 robotPosesLayer.
clear();
135 constexpr
float eps = 50;
144 if ((lastPose->translation() - pose.translation()).norm() < eps)
153 arviz.
commit(robotPosesLayer);
159 auto layer = arviz.
layer(
"graph_shortest_path");
162 {
return pose.translation(); };
165 std::vector<core::Position> pts;
166 pts.reserve(path.size());
167 std::transform(path.begin(), path.end(), std::back_inserter(pts), toPosition);
172 for (
size_t i = 0; i < (pts.size() - 1); i++)
175 .
fromTo(pts.at(i), pts.at(i + 1))
188 auto layer = arviz.
layer(
"global_planner");
193 const auto cmap = simox::color::cmaps::viridis();
195 const float maxVelocity = ranges::max_element(trajectory.
points(),
196 [](
const auto&
a,
const auto& b)
197 { return a.velocity < b.velocity; })
201 for (
const auto& [idx, tp] : trajectory.
points() | ranges::views::enumerate)
203 const float scale = tp.velocity;
205 const Eigen::Vector3f
target =
206 scale * tp.waypoint.pose.linear() * Eigen::Vector3f::UnitY();
210 .fromTo(tp.waypoint.pose.translation(), tp.waypoint.pose.translation() +
target)
211 .
color(cmap.at(tp.velocity / maxVelocity)));
214 layers[layer.data_.name] = std::move(layer);
218 ArvizIntrospector::drawLocalTrajectory(
const std::optional<core::LocalTrajectory>&
input)
223 auto layer = arviz.
layer(
"local_planner");
224 auto velLayer = arviz.
layer(
"local_planner_velocity");
226 layers[layer.data_.name] = std::move(layer);
227 layers[velLayer.data_.name] = std::move(velLayer);
231 const auto trajectory =
input.value();
233 auto layer = arviz.
layer(
"local_planner");
235 const std::vector<Eigen::Vector3f> points =
236 simox::alg::apply(trajectory.
points(),
237 [](
const core::LocalTrajectoryPoint& pt) -> Eigen::Vector3f
238 { return pt.pose.translation(); });
244 auto velLayer = arviz.
layer(
"local_planner_velocity");
246 simox::ColorMap cm = simox::color::cmaps::inferno();
250 for (
size_t i = 0; i < trajectory.
points().size() - 1; i++)
252 const core::LocalTrajectoryPoint start = trajectory.
points().at(i);
253 const core::LocalTrajectoryPoint end = trajectory.
points().at(i + 1);
255 const Duration dT = end.timestamp - start.timestamp;
256 const Eigen::Vector3f
distance = end.pose.translation() - start.pose.translation();
257 const float speed =
distance.norm() / 1000 / dT.toSecondsDouble();
259 const Eigen::Vector3f pos = start.pose.translation() +
distance / 2;
266 layers[layer.data_.name] = std::move(layer);
267 layers[velLayer.data_.name] = std::move(velLayer);
271 ArvizIntrospector::drawRawVelocity(
const core::Twist& twist)
273 auto layer = arviz.
layer(
"trajectory_controller");
276 .fromTo(robot->getGlobalPosition(),
277 core::Pose(robot->getGlobalPose()) * twist.linear)
280 layers[layer.data_.name] = std::move(layer);
284 ArvizIntrospector::drawSafeVelocity(
const core::Twist& twist)
286 auto layer = arviz.
layer(
"safety_controller");
289 .fromTo(robot->getGlobalPosition(),
290 core::Pose(robot->getGlobalPose()) * twist.linear)
293 layers[layer.data_.name] = std::move(layer);
297 arviz{other.arviz}, robot{other.robot}, layers(std::move(other.layers))
306 for (
auto& [name, layer] : layers)
308 layer.markForDeletion();
310 arviz.
commit(simox::alg::get_values(layers));
328 auto layer = arviz.
layer(
"global_planning_graph");
333 for (
const auto& edge : graph.edges())
336 const auto sourcePose = graph.vertex(edge.sourceDescriptor()).attrib().getPose();
337 const auto targetPose = graph.vertex(edge.targetDescriptor()).attrib().getPose();
342 if (edge.attrib().cost() > 100
'000) // "NaN check"
344 return viz::Color::red();
347 return viz::Color::green();
350 const auto from = core::resolveLocation(objects, info, sourcePose);
351 const auto to = core::resolveLocation(objects, info, sourcePose);
353 if (from.pose.has_value() && to.pose.has_value())
356 viz::Arrow(std::to_string(edge.sourceObjectID().t) + " -> " +
357 std::to_string(edge.targetObjectID().t))
358 .fromTo(from.pose.value().translation(), to.pose.value().translation())
367 ArvizIntrospector::success()
371 // visualization.success();
375 ArvizIntrospector::failure()
379 // visualization.failed();
383 } // namespace armarx::navigation::server