Visualization.cpp
Go to the documentation of this file.
1 #include "Visualization.h"
2 
3 #include <algorithm>
4 #include <exception>
5 #include <string>
6 
7 #include <Eigen/Geometry>
8 
9 #include <SimoxUtility/algorithm/get_map_keys_values.h>
10 #include <SimoxUtility/math/pose.h>
11 
16 #include <ArmarXCore/interface/core/PackagePath.h>
17 
23 
25 
27 {
28 
29  Visu::Visu(const PoseSegment& poseSegment,
30  const FaceRecognitionSegment& faceRecognitionSegment,
31  const PersonInstanceSegment& personInstanceSegment) :
32  poseSegment(poseSegment),
33  faceRecognitionSegment(faceRecognitionSegment),
34  personInstanceSegment(personInstanceSegment)
35  {
36  Logging::setTag("HumanVisualization");
37  }
38 
39  void
40  Visu::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
41  {
42  defs->optional(p.enabled, prefix + "enabled", "Enable or disable visualization of humans.");
43  defs->optional(p.frequencyHz, prefix + "frequenzyHz", "Frequency of visualization.");
44  }
45 
46  void
48  {
49  ;
50  }
51 
52  void
54  {
55  this->arviz = arviz;
56  if (debugObserver)
57  {
58  bool batchMode = true;
59  this->debugObserver = DebugObserverHelper("HumanMemory", debugObserver, batchMode);
60  }
61 
62  if (updateTask)
63  {
64  updateTask->stop();
65  updateTask->join();
66  updateTask = nullptr;
67  }
68  updateTask = new SimpleRunningTask<>([this]() { this->visualizeRun(); });
69  updateTask->start();
70  }
71 
72  void
73  Visu::visualizeHumanPoses(armarx::viz::HumanPoseLayers& layers,
74  const std::vector<armarx::armem::human::HumanPose>& humanPoses)
75  {
76  std::string providerName = "azure_kinect"; // TODO: Get actual value.
77 
78  std::map<std::string, armarx::armem::human::HumanPose> poseMap;
79  int unknown = 0;
80  for (const armarx::armem::human::HumanPose& humanPose : humanPoses)
81  {
82  if (humanPose.humanTrackingId.has_value())
83  {
84  poseMap[humanPose.humanTrackingId.value()] = humanPose;
85  }
86  else
87  {
88  // ARMARX_WARNING << "Found unknown human id...";
89  poseMap["unknown_human_" + std::to_string(unknown++)] = humanPose;
90  }
91  }
92 
93  armarx::viz::addPosesToLayer(poseMap, layers, providerName);
94  }
95 
96  void
97  Visu::visualizeFaceRecognitions(
98  armarx::viz::Layer& faceRecognitionLayer,
99  const std::vector<armarx::armem::human::FaceRecognition>& faceRecognitions)
100  {
101  std::string providerName = "azure_kinect"; // TODO: Get actual value.
102 
103  std::map<std::string, armarx::armem::human::FaceRecognition> faceRecognitionMap;
104  int unknown = 0;
105  for (const armarx::armem::human::FaceRecognition& faceRecognition : faceRecognitions)
106  {
107  if (faceRecognition.profileID.has_value())
108  {
109  faceRecognitionMap[faceRecognition.profileID.value().entityName] = faceRecognition;
110  }
111  else
112  {
113  // ARMARX_WARNING << "Found unknown human id...";
114  faceRecognitionMap["unknown_face_" + std::to_string(unknown++)] = faceRecognition;
115  }
116  }
117  if (faceRecognitionMap.size() == 0)
118  {
119  return;
120  }
121 
123  faceRecognitionMap, faceRecognitionLayer, providerName);
124  }
125 
126  void
127  Visu::visualizePersonInstances(
128  armarx::viz::Layer& personInstanceLayer,
129  const std::vector<armarx::armem::human::PersonInstance>& personInstances)
130  {
131  std::string providerName = "person_instanciator"; // TODO: Get actual value.
132 
133  std::map<std::string, armarx::armem::human::PersonInstance> personInstanceMap;
134  for (const armarx::armem::human::PersonInstance& personInstance : personInstances)
135  {
136  personInstanceMap[personInstance.profileID.entityName] = personInstance;
137  }
138  if (personInstanceMap.size() == 0)
139  {
140  return;
141  }
142  for (const auto& [name, personInstance] : personInstanceMap)
143  {
145  faceRecognitionSegment.getFaceRecognition(personInstance.faceRecognitionID);
147  faceReco, name, personInstanceLayer, providerName);
148  }
149  }
150 
151  void
152  Visu::visualizeRun()
153  {
154  armarx::Metronome metronome{armarx::Frequency::Hertz(p.frequencyHz)};
155  while (updateTask and not updateTask->isStopped())
156  {
157  if (p.enabled)
158  {
159  const Time timestamp = Time::Now();
160  ARMARX_DEBUG << "Visu task at " << armem::toStringMilliSeconds(timestamp);
161 
162  try
163  {
164  visualizeOnce(timestamp);
165  }
166  catch (const std::exception& e)
167  {
168  ARMARX_WARNING << "Caught exception while visualizing robots: \n" << e.what();
169  }
170  catch (...)
171  {
172  ARMARX_WARNING << "Caught unknown exception while visualizing robots.";
173  }
174 
175  if (debugObserver.has_value())
176  {
177  debugObserver->sendDebugObserverBatch();
178  }
179  }
180  metronome.waitForNextTick();
181  }
182  }
183 
184  void
185  Visu::visualizeOnce(const Time& timestamp)
186  {
187  TIMING_START(tVisuTotal);
188 
189  // TODO(fabian.reister): use timestamp
190 
191  const Duration maxAge = Duration::MilliSeconds(2000);
192 
193  // Get data.
194  TIMING_START(tVisuGetData);
195 
196  TIMING_START(tRobotDescriptions);
197  const std::map<std::string, std::vector<armarx::armem::human::HumanPose>>
198  humanPosesPerProvider = poseSegment.getHumanPoseEntities(maxAge);
199  const std::map<std::string, std::vector<armarx::armem::human::FaceRecognition>>
200  faceRecognitionsPerProvider = faceRecognitionSegment.getFaceRecognitionEntities(maxAge);
201  const std::map<std::string, std::vector<armarx::armem::human::PersonInstance>>
202  personInstancesPerProvider = personInstanceSegment.getPersonInstanceEntities(maxAge);
203  TIMING_END_STREAM(tRobotDescriptions, ARMARX_DEBUG);
204 
205  TIMING_END_STREAM(tVisuGetData, ARMARX_DEBUG);
206 
207  // Build layers.
208  TIMING_START(tVisuBuildLayers);
209 
210  std::vector<viz::Layer> providerLayers;
211  for (const auto& [providerName, humanPoses] : humanPosesPerProvider)
212  {
213  viz::Layer layerSkeleton = arviz.layer("HumanPoses_" + providerName);
214  viz::Layer layerFrames = arviz.layer("HumanPoses_" + providerName + "_Frames");
215  armarx::viz::HumanPoseLayers layers{.skeleton = layerSkeleton, .frames = layerFrames};
216 
217  visualizeHumanPoses(layers, humanPoses);
218  providerLayers.push_back(layerSkeleton);
219  providerLayers.push_back(layerFrames);
220  }
221  for (const auto& [providerName, faceRecognitions] : faceRecognitionsPerProvider)
222  {
223  viz::Layer faceRecognitionLayer = arviz.layer("FaceRecognitions_" + providerName);
224  visualizeFaceRecognitions(faceRecognitionLayer, faceRecognitions);
225  providerLayers.push_back(faceRecognitionLayer);
226  }
227  for (const auto& [providerName, personInstances] : personInstancesPerProvider)
228  {
229  viz::Layer personInstanceLayer = arviz.layer("PersonInstances_" + providerName);
230  visualizePersonInstances(personInstanceLayer, personInstances);
231  providerLayers.push_back(personInstanceLayer);
232  }
233 
234  TIMING_END_STREAM(tVisuBuildLayers, ARMARX_DEBUG);
235 
236  // Commit layers.
237 
238  ARMARX_DEBUG << "Commit visualization ...";
239  TIMING_START(tVisuCommit);
240  arviz.commit(providerLayers);
241  TIMING_END_STREAM(tVisuCommit, ARMARX_DEBUG);
242 
243  TIMING_END_STREAM(tVisuTotal, ARMARX_DEBUG);
244 
245  if (debugObserver.has_value())
246  {
247  const std::string p = "Visu | ";
248  debugObserver->setDebugObserverDatafield(p + "t Total (ms)",
249  tVisuTotal.toMilliSecondsDouble());
250  debugObserver->setDebugObserverDatafield(p + "t 1 Get Data (ms)",
251  tVisuGetData.toMilliSecondsDouble());
252  debugObserver->setDebugObserverDatafield(p + "t 1.1 Descriptions (ms)",
253  tRobotDescriptions.toMilliSecondsDouble());
254 
255  debugObserver->setDebugObserverDatafield(p + "t 2 Build Layers (ms)",
256  tVisuBuildLayers.toMilliSecondsDouble());
257  debugObserver->setDebugObserverDatafield(p + "t 3 Commit (ms)",
258  tVisuCommit.toMilliSecondsDouble());
259  }
260  }
261 
262 } // namespace armarx::armem::server::human
armarx::SimpleRunningTask
Usage:
Definition: TaskUtil.h:70
armarx::viz::Client::commit
CommitResult commit(StagedCommit const &commit)
Definition: Client.cpp:80
TIMING_START
#define TIMING_START(name)
Definition: TimeUtil.h:280
armarx::armem::server::human::PoseSegment::getHumanPoseEntities
std::map< std::string, std::vector< armarx::armem::human::HumanPose > > getHumanPoseEntities(const Duration &maxAge) const
Definition: PoseSegment.cpp:51
armarx::armem::server::human::Visu::connect
void connect(const viz::Client &arviz, DebugObserverInterfacePrx debugObserver=nullptr)
Definition: Visualization.cpp:53
armarx::core::time::DateTime::Now
static DateTime Now()
Definition: DateTime.cpp:55
armarx::armem::human::FaceRecognition
Definition: types.h:59
armarx::viz::addPosesToLayer
void addPosesToLayer(const std::map< std::string, armarx::armem::human::HumanPose > &poses, HumanPoseLayers &layers, const std::string &prefix)
Definition: HumanPose.cpp:46
armarx::armem::server::human::PoseSegment
Definition: PoseSegment.h:37
armarx::armem::server::human::Visu::defineProperties
void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="visu.")
Definition: Visualization.cpp:40
Elements.h
armarx::viz::HumanPoseLayers::skeleton
viz::Layer & skeleton
Definition: HumanPose.h:17
TIMING_END_STREAM
#define TIMING_END_STREAM(name, os)
Definition: TimeUtil.h:300
armarx::armem::server::human::Visu::init
void init()
Definition: Visualization.cpp:47
armarx::armem::server::human::PersonInstanceSegment::getPersonInstanceEntities
std::map< std::string, std::vector< armarx::armem::human::PersonInstance > > getPersonInstanceEntities(const Duration &maxAge) const
Definition: PersonInstanceSegment.cpp:52
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::armem::human::PersonInstance
Definition: types.h:73
Segment.h
armarx::armem::toStringMilliSeconds
std::string toStringMilliSeconds(const Time &time, int decimals=3)
Returns time as e.g.
Definition: Time.cpp:11
Metronome.h
HumanPose.h
armarx::viz::addPersonInstanceToLayer
void addPersonInstanceToLayer(const armarx::armem::human::FaceRecognition &faceReco, const std::string &name, armarx::viz::Layer &personInstanceLayer, const std::string &prefix)
Definition: PersonInstance.cpp:12
armarx::armem::human::HumanPose
Definition: types.h:30
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::armem::server::human::facerecog::Segment::getFaceRecognitionEntities
std::map< std::string, std::vector< armarx::armem::human::FaceRecognition > > getFaceRecognitionEntities(const Duration &maxAge) const
Definition: Segment.cpp:102
CycleUtil.h
armarx::viz::addFaceRecognitionsToLayer
void addFaceRecognitionsToLayer(const std::map< std::string, armarx::armem::human::FaceRecognition > &faceRecognitions, armarx::viz::Layer &faceRecognitionLayer, const std::string &prefix)
Definition: FaceRecognition.cpp:8
armarx::armem::server::human::PersonInstanceSegment
Definition: PersonInstanceSegment.h:33
armarx::armem::server::human::facerecog::Segment
Definition: Segment.h:34
Segment.h
armarx::armem::server::human
Definition: aron_conversions.cpp:11
TimeUtil.h
Segment.h
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::core::time::Metronome
Simple rate limiter for use in loops to maintain a certain frequency given a clock.
Definition: Metronome.h:35
IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface >
Time.h
armarx::armem::server::human::facerecog::Segment::getFaceRecognition
armarx::armem::human::FaceRecognition getFaceRecognition(armarx::armem::MemoryID memoryID) const
Definition: Segment.cpp:147
armarx::core::time::Frequency::Hertz
static Frequency Hertz(std::int64_t hertz)
Definition: Frequency.cpp:23
armarx::viz::HumanPoseLayers
Definition: HumanPose.h:15
armarx::Logging::setTag
void setTag(const LogTag &tag)
Definition: Logging.cpp:55
armarx::armem::server::human::Visu::Visu
Visu(const PoseSegment &poseSegment, const FaceRecognitionSegment &faceRecognitionSegment, const PersonInstanceSegment &personInstanceSegment)
Definition: Visualization.cpp:29
Logging.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::viz::Client::layer
Layer layer(std::string const &name) const
Definition: Client.cpp:73
armarx::viz::Client
Definition: Client.h:109
Visualization.h
armarx::viz::Layer
Definition: Layer.h:12
armarx::DebugObserverHelper
Brief description of class DebugObserverHelper.
Definition: DebugObserverHelper.h:50
armarx::armem::Duration
armarx::core::time::Duration Duration
Definition: forward_declarations.h:14
armarx::core::time::Duration::MilliSeconds
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition: Duration.cpp:55