Visu.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package Navigation::ArmarXObjects::NavigationMemory
17  * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu )
18  * @date 2021
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "Visu.h"
24 
25 #include <Ice/LocalException.h>
26 
27 #include <SimoxUtility/color/Color.h>
28 #include <SimoxUtility/color/GlasbeyLUT.h>
29 #include <SimoxUtility/color/cmaps/colormaps.h>
30 
32 
37 
43 #include <armarx/navigation/core/aron/Graph.aron.generated.h>
44 #include <armarx/navigation/core/aron/Location.aron.generated.h>
46 #include <armarx/navigation/human/aron/Human.aron.generated.h>
48 #include <armarx/navigation/rooms/aron/Room.aron.generated.h>
50 
52 {
53 
55  const armem::server::wm::CoreSegment& locSegment,
56  const armem::server::wm::CoreSegment& graphSegment,
57  const armem::server::wm::CoreSegment& costmapSegment,
58  const armem::server::wm::CoreSegment& humanSegment,
59  const armem::server::wm::CoreSegment& roomsSegment) :
60  arviz(arviz),
61  locSegment(locSegment),
62  graphSegment(graphSegment),
63  costmapSegment(costmapSegment),
64  humanSegment(humanSegment),
65  roomsSegment(roomsSegment),
66  visu(std::make_unique<graph::GraphVisu>())
67  {
68  }
69 
71  {
72  }
73 
74  void
76  const std::vector<ObjectInfo>& info,
77  viz::Layer& layer)
78  {
79  using namespace armem::server;
80 
81  std::map<armem::MemoryID, location::arondto::Location> locations;
83  [&]()
84  {
86  [&](const wm::Entity& entity)
87  {
88  if (const wm::EntityInstance* instance = entity.findLatestInstance())
89  {
90  locations[entity.id()].fromAron(instance->data());
91  }
92  });
93  });
94 
95  for (auto& [id, location] : locations)
96  {
97  FramedPose framedPose;
98  fromAron(location.framedPose, framedPose);
99 
100  const auto res = core::resolveLocation(objects, info, framedPose);
101  if (res.pose.has_value())
102  {
103  visu->vertex->draw(layer, id.str(), res.pose.value());
104  }
105  }
106  }
107 
108  void
110  const std::vector<ObjectInfo>& info,
111  std::vector<viz::Layer>& layers,
112  bool enabled)
113  {
114  using namespace armem::server;
115 
116  std::map<armem::MemoryID, core::Graph> graphs;
118  [&]()
119  {
121  [&](const wm::Entity& entity)
122  {
123  core::Graph& graph = graphs[entity.id()];
124  if (enabled)
125  {
126  if (const wm::EntityInstance* instance = entity.findLatestInstance())
127  {
128  navigation::core::arondto::Graph aron;
129  aron.fromAron(instance->data());
130  fromAron(aron, graph);
131  }
132  }
133  // else: empty layer
134  });
135  });
136 
137  for (auto& [id, graph] : graphs)
138  {
139  viz::Layer& layer = layers.emplace_back(arviz.layer(id.str()));
140  if (enabled)
141  {
143  visu->draw(layer, graph, {objects, info});
144  }
145  // else: clear layer
146  }
147  }
148 
149  void
150  Visu::drawLocations(std::vector<viz::Layer>& layers, bool enabled)
151  {
152  viz::Layer& layer = layers.emplace_back(arviz.layer(locSegment.id().str()));
153  if (enabled)
154  {
155  const objpose::ObjectPoseMap objects;
156  const std::vector<ObjectInfo> info;
157  drawLocations(objects, info, layer);
158  }
159  }
160 
161  void
163  std::vector<viz::Layer>& layers,
164  bool enabled)
165  {
166  viz::Layer& layer = layers.emplace_back(arviz.layer(locSegment.id().str()));
167  if (enabled and objClient.isConnected())
168  {
169  try
170  {
171  // this call might fail => "no object with id 'ObjectMemory' registered."
172  const objpose::ObjectPoseMap objects = objClient.fetchObjectPosesAsMap();
173 
174  auto objectFinder = objClient.getObjectFinder();
175  objectFinder.setLogObjectDiscoveryError(false);
176  const std::vector<ObjectInfo> info = objectFinder.findAllObjects();
177 
178  drawLocations(objects, info, layer);
179  }
180  catch (::Ice::NotRegisteredException e)
181  {
182  ARMARX_VERBOSE << "Failed to retrieve objects from ObjectMemory: " << e.what();
183  }
184  }
185  }
186 
187  void
188  Visu::drawGraphs(std::vector<viz::Layer>& layers, bool enabled)
189  {
190  const objpose::ObjectPoseMap objects;
191  const std::vector<ObjectInfo> info;
192  drawGraphs(objects, info, layers, enabled);
193  }
194 
195  void
197  std::vector<viz::Layer>& layers,
198  bool enabled)
199  {
200  if (enabled and objClient.isConnected())
201  {
202  try
203  {
204  // this call might fail => "no object with id 'ObjectMemory' registered."
205  const objpose::ObjectPoseMap objects = objClient.fetchObjectPosesAsMap();
206 
207  auto objectFinder = objClient.getObjectFinder();
208  objectFinder.setLogObjectDiscoveryError(false);
209  const std::vector<ObjectInfo> info = objectFinder.findAllObjects();
210 
211  drawGraphs(objects, info, layers, enabled);
212  }
213  catch (::Ice::NotRegisteredException e)
214  {
215  ARMARX_VERBOSE << "Failed to retrieve objects from ObjectMemory: " << e.what();
216  }
217  }
218  }
219 
220  namespace
221  {
222 
223  inline void
224  visualize(const human::Humans& humans, viz::Layer& layer, const bool visuTransparent)
225  {
226 
227  const Eigen::Translation3f human_T_mmm(Eigen::Vector3f{0, 0, 1000});
228 
229  ARMARX_VERBOSE << deactivateSpam(1) << "Visualizing " << humans.size() << " humans";
230  for (const auto& human : humans)
231  {
232  // viz::Cylinder cylinder(std::to_string(layer.size()));
233  // cylinder.fromTo(conv::to3D(human.pose.translation()),
234  // conv::to3D(human.pose.translation()) + Eigen::Vector3f{0, 0, 10});
235 
236 
237  // cylinder.color(simox::Color::orange());
238  // cylinder.radius(300);
239  // layer.add(cylinder);
240 
241  core::Pose human3d = conv::to3D(human.pose) * human_T_mmm;
242 
243  viz::Robot mmm(std::to_string(layer.size()));
244  mmm.file("RobotAPI", "RobotAPI/robots/MMM/mmm.xml");
245  mmm.pose(human3d);
246  mmm.scale(1.7); // 1.7m
247  mmm.overrideColor(viz::Color::orange(255, visuTransparent ? 100 : 255));
248  layer.add(mmm);
249 
250 
251  if (human.linearVelocity != Eigen::Vector2f::Zero())
252  {
253  core::Pose vel3d = human3d;
254  vel3d.translation().head<2>() += human.linearVelocity * 2;
255  auto arrow = viz::Arrow(std::to_string(layer.size()))
256  .fromTo(human3d.translation(), vel3d.translation())
257  .color(simox::Color::red());
258  layer.add(arrow);
259  }
260  }
261  }
262 
263  } // namespace
264 
265  void
266  Visu::drawCostmaps(std::vector<viz::Layer>& layers, const bool enabled, const float zOffset)
267  {
268  if (not enabled)
269  {
270  return;
271  }
272 
273  std::map<std::string, std::vector<std::pair<std::string, algorithms::Costmap>>>
274  namedProviderCostmaps;
275 
277  [&]()
278  {
279  using namespace armem::server;
280 
282  [&](const wm::Entity& entity)
283  {
284  if (const wm::EntityInstance* instance = entity.findLatestInstance())
285  {
286  navigation::algorithms::Costmap costmap =
287  algorithms::fromAron(*instance);
288 
289  namedProviderCostmaps[instance->id().providerSegmentName].emplace_back(
290  instance->id().entityName, std::move(costmap));
291  }
292  });
293  });
294 
295  for (const auto& [providerName, namedCostmaps] : namedProviderCostmaps)
296  {
297  viz::Layer& layer = layers.emplace_back(arviz.layer("costmaps_" + providerName));
298  for (const auto& [name, costmap] : namedCostmaps)
299  {
300  algorithms::visualize(costmap, layer, name, zOffset);
301  }
302  }
303  }
304 
305  void
306  Visu::drawRooms(std::vector<viz::Layer>& layers, const bool enabled)
307  {
308  using namespace armem::server;
309 
310  std::map<armem::MemoryID, rooms::Room> rooms;
312  [&]()
313  {
315  [&](const wm::Entity& entity)
316  {
317  rooms::Room& room = rooms[entity.id()];
318  if (enabled)
319  {
320  if (const wm::EntityInstance* instance = entity.findLatestInstance())
321  {
322  navigation::rooms::arondto::Room aron;
323  aron.fromAron(instance->data());
324  fromAron(aron, room);
325  }
326  }
327  // else: empty layer
328  });
329  });
330 
331  int i = 0;
332  for (auto& [id, room] : rooms)
333  {
334  viz::Layer& layer = layers.emplace_back(arviz.layer(id.str()));
335  if (enabled)
336  {
337  const auto color = simox::color::GlasbeyLUT::at(i++);
338 
339  drawRoom(layer, room, color);
340  }
341  // else: clear layer
342  }
343  }
344 
345  void
346  Visu::drawRoom(viz::Layer& layer, const rooms::Room& room, const simox::Color& color) const
347  {
348  viz::Polygon polygon(room.name);
349  viz::Path path(room.name + "path");
350 
351  for (const auto& point : room.polygon)
352  {
353  polygon.addPoint(conv::to3D(point));
354  path.addPoint(conv::to3D(point));
355  }
356 
357  // close polygon
358  path.addPoint(conv::to3D(room.polygon.front()));
359 
360  polygon.color(color.with_alpha(50));
361  polygon.lineColor(simox::Color::black());
362  polygon.lineWidth(0);
363 
364  layer.add(polygon);
365 
366  layer.add(path);
367  }
368 
369  void
370  Visu::drawHumans(std::vector<viz::Layer>& layers,
371  const bool enabled,
372  const bool visuTransparent,
373  const Duration maxAge)
374  {
375  if (not enabled)
376  {
377  return;
378  }
379 
380  std::map<std::string, navigation::human::Humans> namedProviderHumans;
381  const DateTime timestamp = Clock::Now();
382 
384  [&]()
385  {
386  using namespace armem::server;
387 
389  [&](const wm::Entity& entity)
390  {
391  namedProviderHumans[entity.id().providerSegmentName];
392  entity.getLatestSnapshot().forEachInstance(
393  [&namedProviderHumans, &timestamp, &maxAge](
394  const armarx::armem::wm::EntityInstance& instance)
395  {
396  const Duration dtToNow =
397  timestamp - instance.metadata().referencedTime;
398 
399  if (dtToNow < maxAge and dtToNow.isPositive())
400  {
401  const auto dto = navigation::human::arondto::Human::FromAron(
402  instance.data());
403 
404  navigation::human::Human human;
405  fromAron(dto, human);
406 
407  namedProviderHumans[instance.id().providerSegmentName]
408  .emplace_back(std::move(human));
409  };
410  });
411  });
412  });
413 
414  for (const auto& [providerName, humans] : namedProviderHumans)
415  {
416  viz::Layer& layer = layers.emplace_back(arviz.layer("humans_" + providerName));
417  visualize(humans, layer, visuTransparent);
418  }
419  }
420 
421 
422 } // namespace armarx::navigation::memory
Visu.h
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::navigation::memory::Visu::drawLocations
void drawLocations(std::vector< viz::Layer > &layers, bool enabled)
Definition: Visu.cpp:150
armarx::navigation::core::resolveLocations
void resolveLocations(Graph &graph, const MemoryContainerT &locationContainer)
Definition: Graph.h:140
armarx::armem::server::wm::EntityInstance
armem::wm::EntityInstance EntityInstance
Definition: forward_declarations.h:64
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:42
Path.h
armarx::navigation::core::resolveLocation
void resolveLocation(Graph::Vertex &vertex, const aron::data::DictPtr &locationData)
Definition: Graph.cpp:244
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
framed.h
armarx::navigation::memory::fromAron
void fromAron(const arondto::Circle &dto, Circle &bo)
Definition: aron_conversions.cpp:60
armarx::navigation::memory
Definition: ComponentInterface.ice:37
armarx::armem::wm::EntityInstance
Client-side working entity instance.
Definition: memory_definitions.h:32
armarx::FramedPose
The FramedPose class.
Definition: FramedPose.h:258
aron_conversions.h
armarx::armem::base::detail::GetLatestSnapshotMixin::getLatestSnapshot
auto & getLatestSnapshot(int snapshotIndex=0)
Retrieve the latest entity snapshot.
Definition: lookup_mixins.h:199
armarx::navigation::memory::Visu::graphSegment
const armem::server::wm::CoreSegment & graphSegment
Definition: Visu.h:78
armarx::armem::MemoryID::str
std::string str(bool escapeDelimiters=true) const
Get a string representation of this memory ID.
Definition: MemoryID.cpp:102
armarx::navigation::memory::Visu::drawCostmaps
void drawCostmaps(std::vector< viz::Layer > &layers, bool enabled, float zOffset)
Definition: Visu.cpp:266
armarx::rooms
Brief description of class rooms.
Definition: rooms.h:39
armarx::viz::Arrow
Definition: Elements.h:198
armarx::navigation::memory::Visu::arviz
viz::ScopedClient arviz
Definition: Visu.h:75
armarx::viz::Layer::add
void add(ElementT const &element)
Definition: Layer.h:29
armarx::navigation::human::Humans
std::vector< Human > Humans
Definition: types.h:45
armarx::ObjectFinder::setLogObjectDiscoveryError
void setLogObjectDiscoveryError(bool logEnabled)
Definition: ObjectFinder.cpp:379
armarx::armem::server::wm::Entity
Definition: memory_definitions.h:30
armarx::objpose::ObjectPoseClient
Provides access to the armarx::objpose::ObjectPoseStorageInterface (aka the object memory).
Definition: ObjectPoseClient.h:18
armarx::armem::base::detail::ForEachEntityMixin::forEachEntity
bool forEachEntity(FunctionT &&func)
Definition: iteration_mixins.h:258
armarx::navigation::memory::Visu::humanSegment
const armem::server::wm::CoreSegment & humanSegment
Definition: Visu.h:80
armarx::core::time::Duration::isPositive
bool isPositive() const
Tests whether the duration is positive (value in µs > 0).
Definition: Duration.cpp:195
armarx::navigation::memory::Visu::drawHumans
void drawHumans(std::vector< viz::Layer > &layers, bool enabled, bool visuTransparent, Duration maxAge)
Definition: Visu.cpp:370
armarx::objpose::ObjectPoseClient::getObjectFinder
const ObjectFinder & getObjectFinder() const
Get the internal object finder.
Definition: ObjectPoseClient.cpp:111
memory_definitions.h
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:72
armarx::navigation::memory::Visu::~Visu
~Visu()
Definition: Visu.cpp:70
armarx::navigation::memory::Visu::Visu
Visu(viz::Client arviz, const armem::server::wm::CoreSegment &locSegment, const armem::server::wm::CoreSegment &graphSegment, const armem::server::wm::CoreSegment &costmapSegment, const armem::server::wm::CoreSegment &humanSegment, const armem::server::wm::CoreSegment &roomsSegment)
Definition: Visu.cpp:54
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:51
armarx::navigation::memory::Visu::locSegment
const armem::server::wm::CoreSegment & locSegment
Definition: Visu.h:77
LocationUtils.h
armarx::navigation::memory::Visu::roomsSegment
const armem::server::wm::CoreSegment & roomsSegment
Definition: Visu.h:81
armarx::navigation::memory::Visu::visu
std::unique_ptr< navigation::graph::GraphVisu > visu
Definition: Visu.h:83
Visu.h
enabled
std::atomic< bool > * enabled
Definition: RemoteGuiWidgetController.cpp:75
aron_conversions.h
armarx::viz::Robot
Definition: Robot.h:10
armarx::Graph
boost::subgraph< CloudGraph > Graph
Definition: Common.h:54
armarx::armem::base::EntityBase::findLatestInstance
auto * findLatestInstance(int instanceIndex=0)
Definition: EntityBase.h:355
armarx::viz::Polygon
Definition: Elements.h:258
armarx::armem::base::detail::MemoryItem::id
MemoryID & id()
Definition: MemoryItem.h:27
armarx::armem::server::wm::CoreSegment::doLocked
auto doLocked(FunctionT &&function) const
Definition: memory_definitions.h:120
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::red
QColor red()
Definition: StyleSheets.h:76
armarx::armem::server::wm::CoreSegment
base::CoreSegmentBase
Definition: memory_definitions.h:86
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
armarx::navigation::rooms::Room::polygon
std::vector< Eigen::Vector2f > polygon
Definition: types.h:35
Graph.h
armarx::navigation::algorithms::visualize
void visualize(const algorithms::Costmap &costmap, viz::Layer &layer, const std::string &name, const float zOffset)
Definition: visualization.cpp:20
armarx::navigation::memory::Visu::drawRooms
void drawRooms(std::vector< viz::Layer > &layers, bool enabled)
Definition: Visu.cpp:306
std
Definition: Application.h:66
armarx::navigation::rooms::Room::name
std::string name
Definition: types.h:33
armarx::core::time::Duration
Represents a duration.
Definition: Duration.h:17
armarx::viz::Color::orange
static Color orange(int o=255, int a=255)
2 Red + 1 Green
Definition: Color.h:119
armarx::navigation::conv::to3D
std::vector< Eigen::Vector3f > to3D(const std::vector< Eigen::Vector2f > &v)
Definition: eigen.cpp:11
armarx::navigation::memory::Visu::drawGraphs
void drawGraphs(std::vector< viz::Layer > &layers, bool enabled)
Definition: Visu.cpp:188
armarx::core::time::Clock::Now
static DateTime Now()
Current time on the virtual clock.
Definition: Clock.cpp:97
armarx::viz::Layer::size
std::size_t size() const noexcept
Definition: Layer.h:48
armarx::viz::ScopedClient::layer
Layer layer(std::string const &name) const
Definition: ScopedClient.cpp:34
armarx::navigation::memory::Visu::costmapSegment
const armem::server::wm::CoreSegment & costmapSegment
Definition: Visu.h:79
eigen.h
Logging.h
armarx::viz::Path
Definition: Path.h:31
armarx::armem::base::EntityInstanceBase::metadata
MetadataT & metadata()
Definition: EntityInstanceBase.h:117
armarx::viz::Client
Definition: Client.h:109
armarx::viz::Layer
Definition: Layer.h:12
armarx::navigation::rooms::Room
Definition: types.h:31
armarx::objpose::ObjectPoseClient::isConnected
bool isConnected() const
Indicate whether this client is connected to an object pose storage.
Definition: ObjectPoseClient.cpp:32
visualization.h
aron_conversions.h
ObjectFinder.h
armarx::objpose::ObjectPoseMap
std::map< ObjectID, ObjectPose > ObjectPoseMap
Definition: forward_declarations.h:21