MemorySubscriber.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include <mutex>
3 #include <string>
4 #include <type_traits>
5 #include <vector>
6 
10 
18 
20 #include <armarx/navigation/core/aron/Events.aron.generated.h>
23 
25 {
26 
27  MemorySubscriber::MemorySubscriber(const std::string& callerId,
29  callerId(callerId), memoryNameSystem(mns), lastMemoryPoll(armem::Time::Now())
30  {
31  const std::string memoryName = "Navigation";
32 
34  memoryReader = memoryNameSystem.getReader(armem::MemoryID().withMemoryName(memoryName));
35 
36  ARMARX_INFO << "MemorySubscriber: will handle all events newer than " << lastMemoryPoll
37  << ".";
38 
39  // subscription api
40  subscriptionID.memoryName = memoryName;
41  subscriptionID.coreSegmentName = "Events";
42  subscriptionID.providerSegmentName = callerId;
43 
45  memoryNameSystem.subscribe(subscriptionID, this, &MemorySubscriber::onEntityUpdate);
46  }
47 
48  void
49  MemorySubscriber::onEntityUpdate(const std::vector<armem::MemoryID>& snapshotIDs)
50  {
51  ARMARX_VERBOSE << "Received " << snapshotIDs.size() << " events from memory";
52  const armem::client::QueryResult qResult = memoryReader.queryMemoryIDs(snapshotIDs);
53 
54  if (not qResult.success) /* c++20 [[unlikely]] */
55  {
56  ARMARX_WARNING << deactivateSpam(0.1F) << "Memory lookup failed.";
57  return;
58  }
59 
61  handleEvents(qResult.memory);
62  }
63 
64  template <typename AronEventT, typename EventT>
65  auto
66  fromAron(const armem::wm::EntityInstance& entity, EventT& bo)
67  {
68  static_assert(std::is_base_of<armarx::aron::codegenerator::cpp::AronGeneratedClass,
69  AronEventT>::value);
70 
71  // see events::Writer::storeImpl
72  const auto dataDict =
73  aron::data::Dict::DynamicCastAndCheck(entity.data()->getElement("data"));
74  ARMARX_CHECK_NOT_NULL(dataDict);
75  const auto dto = AronEventT::FromAron(dataDict);
76 
77  core::fromAron(dto, bo);
78  return bo;
79  }
80 
81  void
83  {
85 
86  // only one event will be handled at a time
87  std::lock_guard g{eventHandlingMtx};
88 
89  ARMARX_CHECK(memoryEntity.id().hasEntityName());
90  const auto& eventName = memoryEntity.id().entityName;
91 
92  ARMARX_VERBOSE << "Handling event `" << eventName << "`";
93 
94  // factory
96  {
98  fromAron<core::arondto::GlobalPlanningFailedEvent>(memoryEntity, evt);
99 
101  }
102  else if (eventName == core::event_names::LocalPlanningFailed)
103  {
105  fromAron<core::arondto::LocalPlanningFailedEvent>(memoryEntity, evt);
106 
107  localPlanningFailed(evt);
108  }
109  else if (eventName == core::event_names::MovementStarted)
110  {
112  fromAron<core::arondto::MovementStartedEvent>(memoryEntity, evt);
113 
114  movementStarted(evt);
115  }
116  else if (eventName == core::event_names::GoalReached)
117  {
119  fromAron<core::arondto::GoalReachedEvent>(memoryEntity, evt);
120 
121  goalReached(evt);
122  }
123  else if (eventName == core::event_names::WaypointReached)
124  {
126  fromAron<core::arondto::WaypointReachedEvent>(memoryEntity, evt);
127 
128  waypointReached(evt);
129  }
130  else if (eventName == core::event_names::SafetyThrottlingTriggered)
131  {
133  fromAron<core::arondto::SafetyThrottlingTriggeredEvent>(memoryEntity, evt);
134 
136  }
137  else if (eventName == core::event_names::SafetyStopTriggered)
138  {
140  fromAron<core::arondto::SafetyStopTriggeredEvent>(memoryEntity, evt);
141 
142  safetyStopTriggered(evt);
143  }
144  else if (eventName == core::event_names::UserAbortTriggered)
145  {
147  fromAron<core::arondto::UserAbortTriggeredEvent>(memoryEntity, evt);
148 
149  userAbortTriggered(evt);
150  }
151  else if (eventName == core::event_names::InternalError)
152  {
154  fromAron<core::arondto::InternalErrorEvent>(memoryEntity, evt);
155 
156  internalError(evt);
157  }
158  else if (eventName == core::event_names::GlobalTrajectoryUpdated)
159  {
161  fromAron<core::arondto::GlobalTrajectoryUpdatedEvent>(memoryEntity, evt);
162 
164  }
165  else if (eventName == core::event_names::LocalTrajectoryUpdated)
166  {
168  fromAron<core::arondto::LocalTrajectoryUpdatedEvent>(memoryEntity, evt);
169 
171  }
172  else
173  {
174  ARMARX_WARNING << "Unknown event `" << eventName << "`";
175  }
176  }
177 
179  {
180  // ARMARX_INFO << "Removing event subscription";
181 
182  ARMARX_TRACE;
183  // memoryNameSystem.unsubscribe(subscriptionID, this, &MemorySubscriber::onEntityUpdate);
184 
185  ARMARX_INFO << "done.";
186  }
187 
188  void
190  {
191  ARMARX_TRACE;
192 
193  // clang-format off
194  const armem::wm::CoreSegment& coreSegment = memory
195  .getCoreSegment("Events");
196  // clang-format on
197 
198  std::vector<armem::wm::EntityInstance> events;
199 
200  coreSegment.forEachInstance([&](const armem::wm::EntityInstance& instance)
201  { events.push_back(instance); });
202 
203  const auto sortByTimestampAsc = [](const armem::wm::EntityInstance& a,
204  const armem::wm::EntityInstance& b) -> bool
205  {
206  ARMARX_CHECK(a.id().hasTimestamp());
207  ARMARX_CHECK(b.id().hasTimestamp());
208 
209  return a.id().timestamp < b.id().timestamp;
210  };
211 
212  std::sort(events.begin(), events.end(), sortByTimestampAsc);
213 
214  std::for_each(events.begin(), events.end(), [&](const auto& event) { handleEvent(event); });
215  }
216 
217 
218 } // namespace armarx::navigation::client
armarx::armem::detail::SuccessHeader::success
bool success
Definition: SuccessHeader.h:19
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::navigation::client::MemorySubscriber::~MemorySubscriber
~MemorySubscriber() override
Definition: MemorySubscriber.cpp:178
armarx::armem::client::QueryResult::memory
wm::Memory memory
The slice of the memory that matched the query.
Definition: Query.h:58
armarx::navigation::client::SimpleEventHandler::safetyStopTriggered
void safetyStopTriggered(const core::SafetyStopTriggeredEvent &event) override
Will be called whenever a safety stop is triggered.
Definition: SimpleEventHandler.cpp:105
armarx::navigation::core::event_names::MovementStarted
const std::string MovementStarted
Definition: events.h:20
armarx::armem::MemoryID::providerSegmentName
std::string providerSegmentName
Definition: MemoryID.h:52
armarx::navigation::client::SimpleEventHandler::movementStarted
void movementStarted(const core::MovementStartedEvent &event) override
Definition: SimpleEventHandler.cpp:178
armarx::armem::wm::EntityInstance
Client-side working entity instance.
Definition: memory_definitions.h:32
armarx::navigation::client::SimpleEventHandler::safetyThrottlingTriggered
void safetyThrottlingTriggered(const core::SafetyThrottlingTriggeredEvent &event) override
Will be called whenever safety throttling is triggered to a certain degree (configurable).
Definition: SimpleEventHandler.cpp:96
armarx::navigation::core::fromAron
void fromAron(const arondto::GlobalTrajectoryPoint &dto, GlobalTrajectoryPoint &bo)
Definition: aron_conversions.cpp:31
MemoryID.h
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::navigation::client::MemorySubscriber::handleEvent
void handleEvent(const armem::wm::EntityInstance &memoryEntity)
Definition: MemorySubscriber.cpp:82
armarx::navigation::core::InternalErrorEvent
Event describing the occurance of an internal unhandled error.
Definition: events.h:104
forward_declarations.h
armarx::navigation::core::SafetyThrottlingTriggeredEvent
Event desciribing that a significant safety throttling factor was reached.
Definition: events.h:71
trace.h
armarx::armem
Definition: LegacyRobotStateMemoryAdapter.cpp:32
armarx::navigation::core::event_names::UserAbortTriggered
const std::string UserAbortTriggered
Definition: events.h:25
armarx::navigation::client::SimpleEventHandler::globalPlanningFailed
void globalPlanningFailed(const core::GlobalPlanningFailedEvent &event) override
Definition: SimpleEventHandler.cpp:160
armarx::navigation::client::MemorySubscriber::MemorySubscriber
MemorySubscriber(const std::string &callerId, armem::client::MemoryNameSystem &mns)
Definition: MemorySubscriber.cpp:27
armarx::navigation::client::SimpleEventHandler::internalError
void internalError(const core::InternalErrorEvent &event) override
Will be called whenever an internal error occurs.
Definition: SimpleEventHandler.cpp:123
armarx::navigation::core::event_names::WaypointReached
const std::string WaypointReached
Definition: events.h:22
armarx::navigation::core::event_names::GlobalTrajectoryUpdated
const std::string GlobalTrajectoryUpdated
Definition: events.h:16
armarx::navigation::client
This file is part of ArmarX.
Definition: ComponentPlugin.cpp:21
armarx::armem::client::QueryResult
Result of a QueryInput.
Definition: Query.h:50
Query.h
armarx::navigation::client::SimpleEventHandler::localTrajectoryUpdated
void localTrajectoryUpdated(const core::LocalTrajectoryUpdatedEvent &event) override
Definition: SimpleEventHandler.cpp:141
armarx::aron::data::detail::SpecializedVariantBase< data::dto::Dict, Dict >::DynamicCastAndCheck
static PointerType DynamicCastAndCheck(const VariantPtr &n)
Definition: SpecializedVariant.h:134
Dict.h
armarx::memory
Brief description of class memory.
Definition: memory.h:38
armarx::armem::MemoryID::coreSegmentName
std::string coreSegmentName
Definition: MemoryID.h:51
armarx::navigation::client::fromAron
auto fromAron(const armem::wm::EntityInstance &entity, EventT &bo)
Definition: MemoryPolling.cpp:72
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
events.h
armarx::navigation::core::event_names::SafetyStopTriggered
const std::string SafetyStopTriggered
Definition: events.h:24
armarx::armem::client::Reader::queryMemoryIDs
QueryResult queryMemoryIDs(const std::vector< MemoryID > &ids, armem::query::DataMode dataMode=armem::query::DataMode::WithData) const
Query a specific set of memory IDs.
Definition: Reader.cpp:287
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
MemorySubscriber.h
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:77
armarx::navigation::core::event_names::SafetyThrottlingTriggered
const std::string SafetyThrottlingTriggered
Definition: events.h:23
armarx::navigation::client::SimpleEventHandler::localPlanningFailed
void localPlanningFailed(const core::LocalPlanningFailedEvent &event) override
Definition: SimpleEventHandler.cpp:169
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::navigation::core::event_names::GlobalPlanningFailed
const std::string GlobalPlanningFailed
Definition: events.h:18
armarx::armem::MemoryID
A memory ID.
Definition: MemoryID.h:47
armarx::navigation::client::SimpleEventHandler::userAbortTriggered
void userAbortTriggered(const core::UserAbortTriggeredEvent &event) override
Will be called whenever the user aborts the current navigation.
Definition: SimpleEventHandler.cpp:114
armarx::navigation::client::MemorySubscriber::onEntityUpdate
void onEntityUpdate(const std::vector< armem::MemoryID > &snapshotIDs)
Definition: MemorySubscriber.cpp:49
armarx::navigation::core::SafetyStopTriggeredEvent
Event describing that for security reasons, the robot was stopped completely.
Definition: events.h:87
armarx::armem::wm::CoreSegment
Client-side working memory core segment.
Definition: memory_definitions.h:119
armarx::armem::wm::Memory
Client-side working memory.
Definition: memory_definitions.h:133
armarx::aron::cpp::AronGeneratedClass
Definition: AronGeneratedClass.h:46
armarx::navigation::core::UserAbortTriggeredEvent
Event describing that the user aborted the current execution.
Definition: events.h:96
armarx::armem::client::util::MemoryListener::subscribe
SubscriptionHandle subscribe(const MemoryID &subscriptionID, Callback Callback)
Definition: MemoryListener.cpp:116
armarx::navigation::core::LocalTrajectoryUpdatedEvent
Event describing that the local trajectory was updated.
Definition: events.h:121
armarx::armem::base::detail::MemoryItem::id
MemoryID & id()
Definition: MemoryItem.h:25
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::navigation::core::GlobalPlanningFailedEvent
Definition: events.h:34
armarx::armem::MemoryID::entityName
std::string entityName
Definition: MemoryID.h:53
armarx::navigation::core::GoalReachedEvent
Event describing that the targeted goal was successfully reached.
Definition: events.h:52
armarx::navigation::core::event_names::GoalReached
const std::string GoalReached
Definition: events.h:21
armarx::navigation::core::event_names::InternalError
const std::string InternalError
Definition: events.h:26
memory_definitions.h
armarx::armem::MemoryID::hasEntityName
bool hasEntityName() const
Definition: MemoryID.h:121
armarx::armem::MemoryID::memoryName
std::string memoryName
Definition: MemoryID.h:50
ExpressionException.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
aron_conversions.h
armarx::navigation::client::SimpleEventHandler::goalReached
void goalReached(const core::GoalReachedEvent &event) override
Will be called whenever the navigator reached the goal.
Definition: SimpleEventHandler.cpp:78
armarx::armem::laser_scans::constants::memoryName
const std::string memoryName
Definition: constants.h:28
armarx::navigation::core::GlobalTrajectoryUpdatedEvent
Event describing that the global trajectory was updated.
Definition: events.h:113
armarx::armem::base::detail::ForEachEntityInstanceMixin::forEachInstance
bool forEachInstance(InstanceFunctionT &&func)
Definition: iteration_mixins.h:147
F
Definition: ExportDialogControllerTest.cpp:18
armarx::navigation::client::SimpleEventHandler::waypointReached
void waypointReached(const core::WaypointReachedEvent &event) override
Will be called whenever the navigator reached a user-defined waypoint.
Definition: SimpleEventHandler.cpp:87
armarx::navigation::client::SimpleEventHandler::globalTrajectoryUpdated
void globalTrajectoryUpdated(const core::GlobalTrajectoryUpdatedEvent &event) override
Definition: SimpleEventHandler.cpp:132
armarx::armem::client::MemoryNameSystem
The memory name system (MNS) client.
Definition: MemoryNameSystem.h:68
armarx::navigation::core::WaypointReachedEvent
Event describing that a user-defined waypoint was successfully reached.
Definition: events.h:60
MemoryNameSystem.h
Logging.h
armarx::navigation::client::MemorySubscriber::handleEvents
void handleEvents(const armem::wm::Memory &memory)
Definition: MemorySubscriber.cpp:189
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::armem::client::MemoryNameSystem::getReader
Reader getReader(const MemoryID &memoryID)
Get a reader to the given memory name.
Definition: MemoryNameSystem.cpp:191
armarx::armem::base::EntityInstanceBase::data
const DataT & data() const
Definition: EntityInstanceBase.h:129
AronGeneratedClass.h
armarx::navigation::core::LocalPlanningFailedEvent
Definition: events.h:39
armarx::aron::bo
const std::optional< BoT > & bo
Definition: aron_conversions.h:174
armarx::navigation::core::event_names::LocalPlanningFailed
const std::string LocalPlanningFailed
Definition: events.h:19
armarx::navigation::core::MovementStartedEvent
Definition: events.h:44
armarx::navigation::core::event_names::LocalTrajectoryUpdated
const std::string LocalTrajectoryUpdated
Definition: events.h:17