Reader.cpp
Go to the documentation of this file.
1 #include "Reader.h"
2 
3 // STD / STL
4 #include <algorithm>
5 #include <cstring>
6 #include <map>
7 #include <optional>
8 #include <ostream>
9 #include <type_traits>
10 #include <utility>
11 #include <vector>
12 
13 // ICE
14 #include <IceUtil/Handle.h>
15 #include <IceUtil/Time.h>
16 
17 // Simox
18 #include <SimoxUtility/algorithm/get_map_keys_values.h>
19 
20 // ArmarXCore
24 
25 // RobotAPI Interfaces
27 #include <RobotAPI/interface/armem/mns/MemoryNameSystemInterface.h>
28 #include <RobotAPI/interface/armem/server/ReadingMemoryInterface.h>
29 #include <RobotAPI/interface/units/LaserScannerUnit.h>
30 
31 // RobotAPI Aron
34 
35 // RobotAPI Armem
43 #include <RobotAPI/libraries/armem_laser_scans/aron/LaserScan.aron.generated.h>
46 
48 {
49 
51  {
52  }
53 
54  Reader::~Reader() = default;
55 
56  void
58  {
59  ARMARX_DEBUG << "TransformReader: registerPropertyDefinitions";
60 
61  const std::string prefix = propertyPrefix;
62  }
63 
64  void
66  {
67  // Wait for the memory to become available and add it as dependency.
68  ARMARX_IMPORTANT << "MappingDataReader: Waiting for memory '" << constants::memoryName
69  << "' ...";
70  try
71  {
72  memoryReader =
73  memoryNameSystem.useReader(MemoryID().withMemoryName(constants::memoryName));
74  ARMARX_IMPORTANT << "MappingDataReader: Connected to memory '" << constants::memoryName
75  << "'";
76  }
78  {
79  ARMARX_ERROR << e.what();
80  return;
81  }
82  }
83 
85  Reader::buildQuery(const Query& query) const
86  {
88 
89  ARMARX_VERBOSE << "Query for agent: " << query.agent
90  << " memory name: " << constants::memoryName;
91 
92  if (query.sensorList.empty()) // all sensors
93  {
94  // clang-format off
95  auto& snapshots = qb
98  .entities().all()
99  .snapshots();
100  // clang-format on
101  if (query.timeRange.has_value())
102  {
103  snapshots.timeRange(query.timeRange->min, query.timeRange->max);
104  }
105  else
106  {
107  snapshots.latest();
108  }
109  }
110  else
111  {
112  // clang-format off
113  auto& snapshots = qb
116  .entities().withNames(query.sensorList)
117  .snapshots();
118  // clang-format on
119  if (query.timeRange.has_value())
120  {
121  snapshots.timeRange(query.timeRange->min, query.timeRange->max);
122  }
123  else
124  {
125  snapshots.latest();
126  }
127  }
128 
129  return qb;
130  }
131 
132  std::vector<LaserScanStamped>
133  asLaserScans(const wm::ProviderSegment& providerSegment)
134  {
135  std::vector<LaserScanStamped> outV;
136  if (providerSegment.empty())
137  {
138  ARMARX_WARNING << "No entities!";
139  }
140 
141  const auto convert = [](const auto& aronLaserScanStamped,
143  {
144  LaserScanStamped laserScanStamped;
145  fromAron(aronLaserScanStamped, laserScanStamped);
146 
147  const auto ndArrayNavigator =
148  aron::data::NDArray::DynamicCast(ei.data()->getElement("scan"));
149 
150  ARMARX_CHECK_NOT_NULL(ndArrayNavigator);
151 
152  laserScanStamped.data = fromAron<LaserScanStep>(ndArrayNavigator);
153 
154  return laserScanStamped;
155  };
156 
157  // loop over all entities and their snapshots
158  providerSegment.forEachEntity(
159  [&outV, &convert](const wm::Entity& entity)
160  {
161  // If we don't need this warning, we could directly iterate over the snapshots.
162  if (entity.empty())
163  {
164  ARMARX_WARNING << "Empty history for " << entity.id();
165  }
166  ARMARX_DEBUG << "History size: " << entity.size();
167 
168  entity.forEachInstance(
169  [&outV, &convert](const wm::EntityInstance& entityInstance)
170  {
171  if (const auto o = tryCast<arondto::LaserScanStamped>(entityInstance))
172  {
173  outV.push_back(convert(*o, entityInstance));
174  }
175  return true;
176  });
177  return true;
178  });
179 
180  return outV;
181  }
182 
183  Reader::Result
184  Reader::queryData(const Query& query) const
185  {
186  const auto qb = buildQuery(query);
187 
188  ARMARX_DEBUG << "[MappingDataReader] query ... ";
189 
190  const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
191 
192  ARMARX_DEBUG << "[MappingDataReader] result: " << qResult;
193 
194  if (not qResult.success)
195  {
196  ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
197  return {.laserScans = {},
198  .sensors = {},
199  .status = Result::Status::Error,
200  .errorMessage = qResult.errorMessage};
201  }
202 
203  // now create result from memory
204  const wm::ProviderSegment& providerSegment =
205  qResult.memory.getCoreSegment(constants::memoryName).getProviderSegment(query.agent);
206 
207  const auto laserScans = asLaserScans(providerSegment);
208  std::vector<std::string> sensors;
209  providerSegment.forEachEntity(
210  [&sensors](const wm::Entity& entity)
211  {
212  sensors.push_back(entity.name());
213  return true;
214  });
215 
216  return {.laserScans = laserScans,
217  .sensors = sensors,
218  .status = Result::Status::Success,
219  .errorMessage = ""};
220  }
221 
222 } // namespace armarx::armem::laser_scans::client
armarx::armem::client::query::EntitySelector::all
EntitySelector & all() override
Definition: selectors.cpp:96
armarx::armem::laser_scans::LaserScanStamped
Definition: types.h:40
armarx::armem::base::detail::MemoryContainerBase::empty
bool empty() const
Definition: MemoryContainerBase.h:44
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::armem::client::query::SnapshotSelector::latest
SnapshotSelector & latest()
Definition: selectors.cpp:28
armarx::armem::client::query::ProviderSegmentSelector::entities
EntitySelector & entities()
Start specifying entities.
Definition: selectors.cpp:123
Reader.h
armarx::armem::client::query::SnapshotSelector::timeRange
SnapshotSelector & timeRange(Time min, Time max)
Definition: selectors.cpp:42
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::armem::wm::EntityInstance
Client-side working entity instance.
Definition: memory_definitions.h:32
armarx::armem::laser_scans::client::Reader::connect
void connect(armem::client::MemoryNameSystem &memoryNameSystem)
Definition: Reader.cpp:65
armarx::armem::laser_scans::client::asLaserScans
std::vector< LaserScanStamped > asLaserScans(const wm::ProviderSegment &providerSegment)
Definition: Reader.cpp:133
armarx::armem::client::query::EntitySelector::snapshots
SnapshotSelector & snapshots()
Start specifying entity snapshots.
Definition: selectors.cpp:86
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::armem::laser_scans::LaserScanStamped::data
LaserScan data
Definition: types.h:43
armarx::armem::laser_scans::client::Reader::registerPropertyDefinitions
void registerPropertyDefinitions(armarx::PropertyDefinitionsPtr &def)
Definition: Reader.cpp:57
aron_conversions.h
armarx::armem::client::QueryResult
Result of a QueryInput.
Definition: Query.h:50
types.h
Query.h
armarx::convert
armem::articulated_object::ArticulatedObject convert(const VirtualRobot::Robot &obj, const armem::Time &timestamp)
Definition: ArticulatedObjectLocalizerDynamicSimulation.cpp:194
armarx::armem::server::wm::Entity
Definition: memory_definitions.h:30
armarx::aron::data::detail::SpecializedVariantBase< data::dto::NDArray, NDArray >::DynamicCast
static PointerType DynamicCast(const VariantPtr &n)
Definition: SpecializedVariant.h:117
armarx::armem::base::detail::MemoryContainerBase::size
std::size_t size() const
Definition: MemoryContainerBase.h:48
constants.h
armarx::armem::laser_scans::client::Reader::~Reader
virtual ~Reader()
armarx::armem::client::query::Builder::coreSegments
CoreSegmentSelector & coreSegments()
Start specifying core segments.
Definition: Builder.cpp:38
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
selectors.h
armarx::armem::laser_scans::fromAron
SensorHeader fromAron(const arondto::SensorHeader &aronSensorHeader)
Definition: aron_conversions.cpp:21
armarx::armem::client::query::CoreSegmentSelector::withName
CoreSegmentSelector & withName(const std::string &name) override
Definition: selectors.cpp:177
error.h
armarx::armem::client::MemoryNameSystem::useReader
Reader useReader(const MemoryID &memoryID)
Use a memory server and get a reader for it.
Definition: MemoryNameSystem.cpp:184
armarx::armem::laser_scans::client::Reader::Query
Definition: Reader.h:69
armarx::armem::laser_scans::client
Definition: Reader.cpp:47
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::armem::laser_scans::client::Reader::buildQuery
armarx::armem::client::query::Builder buildQuery(const Query &query) const
Definition: Reader.cpp:85
armarx::armem::server::wm::ProviderSegment
Definition: memory_definitions.h:60
memory_definitions.h
armarx::armem::client::query::detail::NameSelectorOps::withNames
virtual DerivedT & withNames(const std::vector< std::string > &names)
Definition: NameSelectorOps.h:23
ExpressionException.h
armarx::armem::laser_scans::client::Reader::Query::sensorList
std::vector< std::string > sensorList
Definition: Reader.h:77
Exception.h
armarx::armem::client::query::ProviderSegmentSelector::withName
ProviderSegmentSelector & withName(const std::string &name) override
Definition: selectors.cpp:140
armarx::armem::base::ProviderSegmentBase::forEachEntity
bool forEachEntity(EntityFunctionT &&func)
Definition: ProviderSegmentBase.h:189
armarx::armem::laser_scans::constants::memoryName
const std::string memoryName
Definition: constants.h:28
IceUtil::Handle< class PropertyDefinitionContainer >
LogSender.h
armarx::armem::base::detail::ForEachEntityInstanceMixin::forEachInstance
bool forEachInstance(InstanceFunctionT &&func)
Definition: iteration_mixins.h:146
Builder.h
armarx::armem::client::MemoryNameSystem
The memory name system (MNS) client.
Definition: MemoryNameSystem.h:69
armarx::armem::error::CouldNotResolveMemoryServer
Indicates that a query to the Memory Name System failed.
Definition: mns.h:26
armarx::armem::client::query::Builder
The query::Builder class provides a fluent-style specification of hierarchical queries.
Definition: Builder.h:22
armarx::armem::client::query::CoreSegmentSelector::providerSegments
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
Definition: selectors.cpp:160
armarx::armem::laser_scans::client::Reader::Reader
Reader()
Definition: Reader.cpp:50
util.h
Logging.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::armem::laser_scans::client::Reader::Query::agent
std::string agent
Definition: Reader.h:71
armarx::armem::laser_scans::client::Reader::Query::timeRange
std::optional< TimeRange > timeRange
Definition: Reader.h:74
armarx::armem::base::EntityBase::name
std::string & name()
Definition: EntityBase.h:93
NDArray.h
armarx::human::MemoryID
const armem::MemoryID MemoryID
Definition: memory_ids.cpp:29