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
25 
26 // 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>
31 
32 // RobotAPI Aron
33 #include <RobotAPI/libraries/armem_vision/aron/OccupancyGrid.aron.generated.h>
36 
37 // RobotAPI Armem
46 
48 {
49  Reader::~Reader() = default;
50 
52  Reader::buildQuery(const Query& query) const
53  {
55 
56  // clang-format off
57  qb
58  .coreSegments().withName(properties().coreSegmentName)
59  .providerSegments().withName(query.providerName)
60  .entities().all()
61  .snapshots().beforeOrAtTime(query.timestamp);
62  // clang-format on
63 
64  return qb;
65  }
66 
67  std::string
69  {
70  return "mem.vision.occupancy_grid.";
71  }
72 
75  {
76  return {.memoryName = "Vision", .coreSegmentName = "OccupancyGrid"};
77  }
78 
80  asOccupancyGrid(const wm::ProviderSegment& providerSegment)
81  {
82  ARMARX_CHECK(not providerSegment.empty()) << "No entities";
83  ARMARX_CHECK(providerSegment.size() == 1) << "There should be only one entity!";
84 
85  const wm::EntityInstance* entityInstance = nullptr;
86  providerSegment.forEachEntity(
87  [&entityInstance](const wm::Entity& entity)
88  {
89  const auto& entitySnapshot = entity.getLatestSnapshot();
90  ARMARX_CHECK(not entitySnapshot.empty()) << "No entity snapshot instances";
91 
92  entityInstance = &entitySnapshot.getInstance(0);
93  return false;
94  });
95  ARMARX_CHECK_NOT_NULL(entityInstance);
96 
97  const auto aronDto = tryCast<arondto::OccupancyGrid>(*entityInstance);
98  ARMARX_CHECK(aronDto) << "Failed casting to OccupancyGrid";
99 
100  OccupancyGrid occupancyGrid;
101  fromAron(*aronDto, occupancyGrid);
102 
103  // direct access to grid data
104  const auto ndArrayNavigator =
105  aron::data::NDArray::DynamicCast(entityInstance->data()->getElement("grid"));
106  ARMARX_CHECK_NOT_NULL(ndArrayNavigator);
107 
108  occupancyGrid.grid =
109  aron::data::converter::AronEigenConverter::ConvertToArray<float>(*ndArrayNavigator);
110 
111  return occupancyGrid;
112  }
113 
114  Reader::Result
115  Reader::query(const Query& query) const
116  {
117  const auto qb = buildQuery(query);
118 
119  ARMARX_DEBUG << "[MappingDataReader] query ... ";
120 
121  const armem::client::QueryResult qResult = memoryReader().query(qb.buildQueryInput());
122 
123  ARMARX_DEBUG << "[MappingDataReader] result: " << qResult;
124 
125  if (not qResult.success)
126  {
127  ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
128  return {.occupancyGrid = std::nullopt,
129  .status = Result::Status::Error,
130  .errorMessage = qResult.errorMessage};
131  }
132 
133  const auto coreSegment = qResult.memory.getCoreSegment(properties().coreSegmentName);
134 
135  if (not coreSegment.hasProviderSegment(query.providerName))
136  {
137  ARMARX_WARNING << "Provider segment `" << query.providerName
138  << "` does not exist (yet).";
139  return {.occupancyGrid = std::nullopt, .status = Result::Status::NoData};
140  }
141 
142  const wm::ProviderSegment& providerSegment =
143  coreSegment.getProviderSegment(query.providerName);
144 
145  if (providerSegment.empty())
146  {
147  ARMARX_WARNING << "No entities.";
148  return {.occupancyGrid = std::nullopt,
149  .status = Result::Status::NoData,
150  .errorMessage = "No entities"};
151  }
152 
153  try
154  {
155  const auto occupancyGrid = asOccupancyGrid(providerSegment);
156  return Result{.occupancyGrid = occupancyGrid, .status = Result::Status::Success};
157  }
158  catch (...)
159  {
160  return Result{.status = Result::Status::Error,
161  .errorMessage = GetHandledExceptionString()};
162  }
163  }
164 
165 } // namespace armarx::armem::vision::occupancy_grid::client
armarx::armem::client::query::EntitySelector::all
EntitySelector & all() override
Definition: selectors.cpp:96
armarx::armem::base::detail::MemoryContainerBase::empty
bool empty() const
Definition: MemoryContainerBase.h:44
armarx::armem::vision::occupancy_grid::client::Reader::defaultProperties
Properties defaultProperties() const override
Definition: Reader.cpp:74
armarx::armem::client::util::SimpleReaderBase::properties
const Properties & properties() const
Definition: SimpleReaderBase.cpp:55
armarx::armem::client::query::ProviderSegmentSelector::entities
EntitySelector & entities()
Start specifying entities.
Definition: selectors.cpp:123
Reader.h
armarx::armem::vision::occupancy_grid::client::Reader::Result::occupancyGrid
std::optional< OccupancyGrid > occupancyGrid
Definition: Reader.h:48
armarx::armem::vision::OccupancyGrid
Definition: types.h:36
LocalException.h
armarx::armem::wm::EntityInstance
Client-side working entity instance.
Definition: memory_definitions.h:32
armarx::armem::base::detail::GetLatestSnapshotMixin::getLatestSnapshot
auto & getLatestSnapshot(int snapshotIndex=0)
Retrieve the latest entity snapshot.
Definition: lookup_mixins.h:199
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::client::QueryResult
Result of a QueryInput.
Definition: Query.h:50
armarx::armem::vision::occupancy_grid::client::Reader::~Reader
~Reader() override
Query.h
armarx::armem::client::util::SimpleReaderBase::Properties::memoryName
std::string memoryName
Definition: SimpleReaderBase.h:45
armarx::armem::server::wm::Entity
Definition: memory_definitions.h:30
armarx::armem::vision::occupancy_grid::client::Reader::propertyPrefix
std::string propertyPrefix() const override
Definition: Reader.cpp:68
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::armem::vision::occupancy_grid::client
Definition: Reader.cpp:47
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
armarx::GetHandledExceptionString
std::string GetHandledExceptionString()
Definition: Exception.cpp:147
armarx::armem::vision::occupancy_grid::client::Reader::Result
Definition: Reader.h:46
aron_conversions.h
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::client::query::CoreSegmentSelector::withName
CoreSegmentSelector & withName(const std::string &name) override
Definition: selectors.cpp:177
armarx::armem::vision::occupancy_grid::client::Reader::buildQuery
::armarx::armem::client::query::Builder buildQuery(const Query &query) const
Definition: Reader.cpp:52
armarx::armem::client::util::SimpleReaderBase::memoryReader
const armem::client::Reader & memoryReader() const
Definition: SimpleReaderBase.cpp:49
EigenConverter.h
armarx::armem::server::wm::ProviderSegment
Definition: memory_definitions.h:60
memory_definitions.h
armarx::armem::vision::occupancy_grid::client::Reader::Query
Definition: Reader.h:40
ExpressionException.h
Exception.h
armarx::armem::client::util::SimpleReaderBase::Properties
Definition: SimpleReaderBase.h:43
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::client::query::SnapshotSelector::beforeOrAtTime
SnapshotSelector & beforeOrAtTime(Time timestamp)
Definition: selectors.cpp:68
armarx::armem::vision::occupancy_grid::client::Reader::Result::status
enum armarx::armem::vision::occupancy_grid::client::Reader::Result::Status status
armarx::armem::vision::occupancy_grid::client::Reader::query
Result query(const Query &query) const
Definition: Reader.cpp:115
armarx::armem::vision::OccupancyGrid::grid
Grid grid
Definition: types.h:47
types.h
LogSender.h
Builder.h
armarx::armem::vision::occupancy_grid::client::asOccupancyGrid
OccupancyGrid asOccupancyGrid(const wm::ProviderSegment &providerSegment)
Definition: Reader.cpp:80
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
util.h
Logging.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::armem::base::EntityInstanceBase::data
const DataT & data() const
Definition: EntityInstanceBase.h:129
armarx::armem::client::Reader::query
QueryResult query(const QueryInput &input) const
Perform a query.
Definition: Reader.cpp:33
armarx::armem::vision::fromAron
void fromAron(const arondto::OccupancyGrid &dto, OccupancyGrid &bo)
Definition: aron_conversions.cpp:29
NDArray.h