ArvizIntrospector.cpp
Go to the documentation of this file.
1 #include "ArvizIntrospector.h"
2 
3 #include <algorithm>
4 #include <cstddef>
5 #include <iterator>
6 #include <optional>
7 #include <string>
8 #include <utility>
9 #include <vector>
10 
11 #include <Eigen/Geometry>
12 
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> // IWYU pragma: keep
20 #include <VirtualRobot/VirtualRobot.h>
21 
27 
35 
42 
43 #include <range/v3/algorithm/max_element.hpp>
44 #include <range/v3/view/enumerate.hpp>
45 
47 {
48 
49  inline armarx::PackagePath
50  asPackagePath(const std::string& absfilepath)
51  {
52  const std::vector<std::string> packages =
54  const std::string package = armarx::ArmarXDataPath::getProject(packages, absfilepath);
55 
56  // make sure that the relative path is without the 'package/' prefix
57  const std::string relPath = [&absfilepath, &package]() -> std::string
58  {
59  if (simox::alg::starts_with(absfilepath, package))
60  {
61  // remove "package" + "/"
62  return absfilepath.substr(package.size() + 1, -1);
63  }
64 
65  return absfilepath;
66  }();
67 
68  return {package, relPath};
69  }
70 
72  const VirtualRobot::RobotPtr& robot,
73  const objpose::ObjectPoseClient& objClient) :
74  arviz(arviz), robot(robot), objClient(objClient)
75  // visualization(arviz,
76  // util::Visualization::Params{.robotModelFileName = asPackagePath(robot->getFilename())})
77  {
78  robotPosesLayer = arviz.layer("robot_poses");
79  }
80 
81  // TODO maybe run with predefined frequency instead of
82 
83  void
85  {
86  ARMARX_DEBUG << "ArvizIntrospector::onGlobalPlannerResult";
87 
88  drawGlobalTrajectory(result.trajectory);
89  arviz.commit(simox::alg::get_values(layers));
90 
91 
92  // visualization.visualize(result.trajectory);
93  }
94 
95  void
97  const std::optional<local_planning::LocalPlannerResult>& result)
98  {
99  if (result)
100  {
101  drawLocalTrajectory(result.value().trajectory);
102  }
103  else
104  {
105  drawLocalTrajectory(std::nullopt);
106  }
107 
108  arviz.commit(simox::alg::get_values(layers));
109  }
110 
111  // void
112  // ArvizIntrospector::onTrajectoryControllerResult(
113  // const traj_ctrl::TrajectoryControllerResult& result)
114  // {
115  // std::lock_guard g{mtx};
116 
117  // drawRawVelocity(result.twist);
118  // }
119 
120  // void
121  // ArvizIntrospector::onSafetyGuardResult(const safety_guard::SafetyGuardResult& result)
122  // {
123  // std::lock_guard g{mtx};
124 
125  // drawSafeVelocity(result.twist);
126  // }
127 
128  void
130  {
131  auto layer = arviz.layer("goal");
132  layer.add(viz::Pose("goal").pose(goal).scale(3));
133 
134  robotPosesLayer.clear();
135 
136  // arviz.commit({layer, robotPosesLayer});
137  arviz.commit({layer});
138 
139  // visualization.setTarget(goal);
140  }
141 
142  void
144  {
145 
146  constexpr float eps = 50; // [mm]
147 
148  if (not lastPose)
149  {
150  lastPose = pose;
151  }
152  else
153  {
154  // only draw poses every `eps` mm
155  if ((lastPose->translation() - pose.translation()).norm() < eps)
156  {
157  return;
158  }
159 
160  lastPose = pose;
161  }
162 
163  robotPosesLayer.add(viz::Pose("pose" + std::to_string(robotPosesLayer.size())).pose(pose));
164  arviz.commit(robotPosesLayer);
165  }
166 
167  void
168  ArvizIntrospector::onGlobalShortestPath(const std::vector<core::Pose>& path)
169  {
170  auto layer = arviz.layer("graph_shortest_path");
171 
172  const auto toPosition = [](const core::Pose& pose) -> core::Position
173  { return pose.translation(); };
174 
175 
176  std::vector<core::Position> pts;
177  pts.reserve(path.size());
178  std::transform(path.begin(), path.end(), std::back_inserter(pts), toPosition);
179 
180 
181  // layer.add(viz::Path("shortest_path").points(pts).color(viz::Color::purple()));
182 
183  for (size_t i = 0; i < (pts.size() - 1); i++)
184  {
185  layer.add(viz::Arrow("segment_" + std::to_string(i))
186  .fromTo(pts.at(i), pts.at(i + 1))
188  }
189 
190 
191  arviz.commit(layer);
192  }
193 
194  // private methods
195 
196  void
197  ArvizIntrospector::drawGlobalTrajectory(const core::GlobalTrajectory& trajectory)
198  {
199  auto layer = arviz.layer("global_planner");
200 
201  layer.add(
202  viz::Path("path").points(trajectory.positions()).color(simox::color::Color::blue()));
203 
204  const auto cmap = simox::color::cmaps::viridis();
205 
206  const float maxVelocity = ranges::max_element(trajectory.points(),
207  [](const auto& a, const auto& b)
208  { return a.velocity < b.velocity; })
209  ->velocity;
210 
211 
212  for (const auto& [idx, tp] : trajectory.points() | ranges::views::enumerate)
213  {
214  const float scale = tp.velocity;
215 
216  const Eigen::Vector3f target =
217  scale * tp.waypoint.pose.linear() * Eigen::Vector3f::UnitY();
218 
219  layer.add(
220  viz::Arrow("velocity_" + std::to_string(idx))
221  .fromTo(tp.waypoint.pose.translation(), tp.waypoint.pose.translation() + target)
222  .color(cmap.at(tp.velocity / maxVelocity)));
223  }
224 
225  layers[layer.data_.name] = std::move(layer);
226  }
227 
228  void
229  ArvizIntrospector::drawLocalTrajectory(const std::optional<core::LocalTrajectory>& input)
230  {
231  if (!input)
232  {
233  // no local trajectory found, remove old one
234  auto layer = arviz.layer("local_planner");
235  auto velLayer = arviz.layer("local_planner_velocity");
236 
237  layers[layer.data_.name] = std::move(layer);
238  layers[velLayer.data_.name] = std::move(velLayer);
239  return;
240  }
241 
242  const auto trajectory = input.value();
243 
244  auto layer = arviz.layer("local_planner");
245 
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(); });
250 
251  layer.add(viz::Path("path").points(points).color(simox::Color::green()));
252 
253 
254  // Visualize trajectory speed
255  auto velLayer = arviz.layer("local_planner_velocity");
256 
257  simox::ColorMap cm = simox::color::cmaps::inferno();
258  cm.set_vmin(0);
259  cm.set_vmax(0.6);
260 
261  for (size_t i = 0; i < trajectory.points().size() - 1; i++)
262  {
263  const core::LocalTrajectoryPoint start = trajectory.points().at(i);
264  const core::LocalTrajectoryPoint end = trajectory.points().at(i + 1);
265 
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();
269 
270  const Eigen::Vector3f pos = start.pose.translation() + distance / 2;
271  const simox::Color color = cm.at(speed);
272 
273  velLayer.add(
274  viz::Sphere("velocity_" + std::to_string(i)).position(pos).radius(50).color(color));
275  }
276 
277  layers[layer.data_.name] = std::move(layer);
278  layers[velLayer.data_.name] = std::move(velLayer);
279  }
280 
281  void
282  ArvizIntrospector::drawRawVelocity(const core::Twist& twist)
283  {
284  auto layer = arviz.layer("trajectory_controller");
285 
286  layer.add(viz::Arrow("linear_velocity")
287  .fromTo(robot->getGlobalPosition(),
288  core::Pose(robot->getGlobalPose()) * twist.linear)
290 
291  layers[layer.data_.name] = std::move(layer);
292  }
293 
294  void
295  ArvizIntrospector::drawSafeVelocity(const core::Twist& twist)
296  {
297  auto layer = arviz.layer("safety_guard");
298 
299  layer.add(viz::Arrow("linear_velocity")
300  .fromTo(robot->getGlobalPosition(),
301  core::Pose(robot->getGlobalPose()) * twist.linear)
303 
304  layers[layer.data_.name] = std::move(layer);
305  }
306 
308  arviz{other.arviz}, robot{other.robot}, layers(std::move(other.layers)) //,
309  // visualization(std::move(other.visualization))
310  {
311  }
312 
313  void
315  {
316  // clear all layers
317  for (auto& [name, layer] : layers)
318  {
319  layer.markForDeletion();
320  }
321  arviz.commit(simox::alg::get_values(layers));
322  layers.clear();
323 
324  // some special internal layers of TEB
325  arviz.commitDeleteLayer("local_planner_obstacles");
326  arviz.commitDeleteLayer("local_planner_velocity");
327  arviz.commitDeleteLayer("local_planner_path_alternatives");
328  }
329 
332  {
333  return *this;
334  }
335 
336  void
338  {
339  auto layer = arviz.layer("global_planning_graph");
340 
341  const objpose::ObjectPoseMap objects = objClient.fetchObjectPosesAsMap();
342  const std::vector<ObjectInfo> info = objClient.getObjectFinder().findAllObjects();
343 
344  for (const auto& edge : graph.edges())
345  {
346 
347  const auto sourcePose = graph.vertex(edge.sourceDescriptor()).attrib().getPose();
348  const auto targetPose = graph.vertex(edge.targetDescriptor()).attrib().getPose();
349 
350 
351  const viz::Color color = [&]()
352  {
353  if (edge.attrib().cost() > 100'000) // "NaN check"
354  {
355  return viz::Color::red();
356  }
357 
358  return viz::Color::green();
359  }();
360 
361  const auto from = core::resolveLocation(objects, info, sourcePose);
362  const auto to = core::resolveLocation(objects, info, sourcePose);
363 
364  if (from.pose.has_value() && to.pose.has_value())
365  {
366  layer.add(
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())
370  .color(color));
371  }
372  }
373 
374  arviz.commit(layer);
375  }
376 
377  void
378  ArvizIntrospector::success()
379  {
380  clear();
381 
382  // visualization.success();
383  }
384 
385  void
386  ArvizIntrospector::failure()
387  {
388  clear();
389 
390  // visualization.failed();
391  }
392 
393 
394 } // namespace armarx::navigation::server
Client.h
armarx::navigation::core::GlobalTrajectory
Definition: Trajectory.h:70
armarx::viz::Client::commit
CommitResult commit(StagedCommit const &commit)
Definition: Client.cpp:89
armarx::navigation::server::ArvizIntrospector::onRobotPose
void onRobotPose(const core::Pose &pose) override
Definition: ArvizIntrospector.cpp:143
armarx::navigation::server::ArvizIntrospector::onGlobalShortestPath
void onGlobalShortestPath(const std::vector< core::Pose > &path) override
Definition: ArvizIntrospector.cpp:168
Path.h
armarx::navigation::server::asPackagePath
armarx::PackagePath asPackagePath(const std::string &absfilepath)
Definition: ArvizIntrospector.cpp:50
armarx::viz::Color::purple
static Color purple(int p=255, int a=255)
2 Blue + 1 Red
Definition: Color.h:167
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
armarx::ObjectFinder::findAllObjects
std::vector< ObjectInfo > findAllObjects(bool checkPaths=true) const
Definition: ObjectFinder.cpp:149
armarx::viz::Layer::clear
void clear()
Definition: Layer.h:24
basic_types.h
armarx::CMakePackageFinder::FindAllArmarXSourcePackages
static std::vector< std::string > FindAllArmarXSourcePackages()
Definition: CMakePackageFinder.cpp:461
armarx::viz::Client::commitDeleteLayer
void commitDeleteLayer(std::string const &name)
Definition: Client.h:183
armarx::navigation::global_planning::GlobalPlannerResult::trajectory
core::GlobalTrajectory trajectory
Definition: GlobalPlanner.h:40
LocalPlanner.h
armarx::navigation::server::ArvizIntrospector::ArvizIntrospector
ArvizIntrospector(armarx::viz::Client arviz, const VirtualRobot::RobotPtr &robot, const objpose::ObjectPoseClient &objClient)
Definition: ArvizIntrospector.cpp:71
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:668
Duration.h
armarx::viz::Arrow
Definition: Elements.h:196
armarx::viz::Layer::add
void add(ElementT const &element)
Definition: Layer.h:31
armarx::starts_with
bool starts_with(const std::string &haystack, const std::string &needle)
Definition: StringHelpers.cpp:47
armarx::navigation::server::ArvizIntrospector::clear
void clear()
Definition: ArvizIntrospector.cpp:314
armarx::objpose::ObjectPoseClient
Provides access to the armarx::objpose::ObjectPoseStorageInterface (aka the object memory).
Definition: ObjectPoseClient.h:17
armarx::viz::Sphere
Definition: Elements.h:133
Elements.h
armarx::navigation::server
This file is part of ArmarX.
Definition: EventPublishingInterface.h:6
armarx::objpose::ObjectPoseClient::getObjectFinder
const ObjectFinder & getObjectFinder() const
Get the internal object finder.
Definition: ObjectPoseClient.cpp:102
armarx::navigation::server::ArvizIntrospector::onLocalPlannerResult
void onLocalPlannerResult(const std::optional< local_planning::LocalPlannerResult > &result) override
Definition: ArvizIntrospector.cpp:96
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
Color
uint32_t Color
RGBA color.
Definition: color.h:8
armarx::objpose::ObjectPoseClient::fetchObjectPosesAsMap
ObjectPoseMap fetchObjectPosesAsMap() const
Fetch all known object poses.
Definition: ObjectPoseClient.cpp:45
LocationUtils.h
Color.h
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:12
armarx::navigation::core::Graph
Definition: Graph.h:89
armarx::viz::Color
Definition: Color.h:12
ObjectPoseClient.h
GlobalPlanner.h
armarx::viz::Pose
Definition: Elements.h:178
ObjectInfo.h
armarx::navigation::global_planning::GlobalPlannerResult
Definition: GlobalPlanner.h:38
armarx::navigation::server::ArvizIntrospector::onGlobalPlannerResult
void onGlobalPlannerResult(const global_planning::GlobalPlannerResult &result) override
Definition: ArvizIntrospector.cpp:84
armarx::navigation::server::ArvizIntrospector::onGoal
void onGoal(const core::Pose &goal) override
Definition: ArvizIntrospector.cpp:129
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
armarx::transform
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT >>
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition: algorithm.h:351
armarx::viz::Arrow::fromTo
Arrow & fromTo(const Eigen::Vector3f &from, const Eigen::Vector3f &to)
Definition: Elements.h:219
CMakePackageFinder.h
forward_declarations.h
Graph.h
armarx::viz::ElementOps::pose
DerivedT & pose(Eigen::Matrix4f const &pose)
Definition: ElementOps.h:176
armarx::viz::ElementOps::color
DerivedT & color(Color color)
Definition: ElementOps.h:218
armarx::navigation::server::ArvizIntrospector::operator=
ArvizIntrospector & operator=(ArvizIntrospector &&) noexcept
Definition: ArvizIntrospector.cpp:331
armarx::navigation::core::GlobalTrajectory::positions
std::vector< Position > positions() const noexcept
Definition: Trajectory.cpp:332
distance
double distance(const Point &a, const Point &b)
Definition: point.hpp:95
armarx::viz::Layer::size
std::size_t size() const noexcept
Definition: Layer.h:52
armarx::navigation::server::ArvizIntrospector::onGlobalGraph
void onGlobalGraph(const core::Graph &graph) override
Definition: ArvizIntrospector.cpp:337
armarx::viz::ScopedClient::layer
Layer layer(std::string const &name) const
Definition: ScopedClient.cpp:34
Logging.h
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
armarx::viz::Path
Definition: Path.h:31
armarx::viz::Client::layer
Layer layer(std::string const &name) const
Definition: Client.cpp:80
Trajectory.h
armarx::viz::Client
Definition: Client.h:117
ArmarXDataPath.h
armarx::PackagePath
Definition: PackagePath.h:52
armarx::navigation::server::ArvizIntrospector
Definition: ArvizIntrospector.h:54
armarx::navigation::core::GlobalTrajectory::points
const std::vector< GlobalTrajectoryPoint > & points() const
Definition: Trajectory.cpp:734
armarx::orange
QColor orange()
Definition: StyleSheets.h:84
armarx::armem::Duration
armarx::core::time::Duration Duration
Definition: forward_declarations.h:14
armarx::green
QColor green()
Definition: StyleSheets.h:72
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19
ArvizIntrospector.h
PackagePath.h
armarx::objpose::ObjectPoseMap
std::map< ObjectID, ObjectPose > ObjectPoseMap
Definition: forward_declarations.h:21