ExampleMemory.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 RobotAPI::ArmarXObjects::ExampleMemory
17  * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu )
18  * @date 2020
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "ExampleMemory.h"
24 
27 
28 #include <SimoxUtility/algorithm/string.h>
29 
35 
36 #include <RobotAPI/components/armem/server/ExampleMemory/aron/ExampleData.aron.generated.h>
37 
38 
39 namespace armarx
40 {
42  {
44 
45  defs->topic(debugObserver);
46 
47  setMemoryName("Example");
48 
49  p.core._defaultSegmentsStr = simox::alg::join(p.core.defaultCoreSegments, ", ");
50  defs->optional(p.core._defaultSegmentsStr, "core.DefaultSegments",
51  "Core segments to add on start up (just as example).");
52  defs->optional(p.core.addOnUsage, "core.AddOnUsage",
53  "If enabled, core segments are added when required by a new provider segment."
54  "This will usually be off for most memory servers.");
55 
56  defs->optional(p.enableRemoteGui, "p.enableRemoteGui",
57  "If true, the memory cotent is shown in the remote gui."
58  "Can be very slow for high-frequency updates!");
59  return defs;
60  }
61 
62 
63  std::string ExampleMemory::getDefaultName() const
64  {
65  return "ExampleMemory";
66  }
67 
68 
70  {
71  // Usually, the memory server will specify a number of core segments with a specific aron type.
72  workingMemory().addCoreSegment("ExampleData", armem::example::ExampleData::ToAronType());
73  workingMemory().addCoreSegment("LinkedData", armem::example::LinkedData::ToAronType());
74 
75  // We support the "Latest" prediction engine for the entire memory.
77  armem::PredictionEngine{.engineID = "Latest"},
78  [this](const armem::PredictionRequest& request)
79  { return this->predictLatest(request); });
80 
81  // For illustration purposes, we add more segments (without types).
82  bool trim = true;
83  p.core.defaultCoreSegments = simox::alg::split(p.core._defaultSegmentsStr, ",", trim);
84  p.core._defaultSegmentsStr.clear();
85 
86  for (const std::string& name : p.core.defaultCoreSegments)
87  {
88  auto& c = workingMemory().addCoreSegment(name);
89  c.setMaxHistorySize(100);
90  }
91  }
92 
94  {
95  if (p.enableRemoteGui)
96  {
99  }
100  }
101 
103  {
104  }
105 
107  {
108  }
109 
110 
111 
112  // WRITING
113 
114  armem::data::AddSegmentsResult ExampleMemory::addSegments(const armem::data::AddSegmentsInput& input, const Ice::Current&)
115  {
116  // This function is overloaded to trigger the remote gui rebuild.
117  armem::data::AddSegmentsResult result = ReadWritePluginUser::addSegments(input, p.core.addOnUsage);
118  tab.rebuild = true;
119  return result;
120  }
121 
122 
123  armem::data::CommitResult ExampleMemory::commit(const armem::data::Commit& commit, const Ice::Current&)
124  {
125  // This function is overloaded to trigger the remote gui rebuild.
126  armem::data::CommitResult result = ReadWritePluginUser::commit(commit);
127  tab.rebuild = true;
128  return result;
129  }
130 
131 
132  // READING
133 
134  // Inherited from Plugin
135 
136 
137 
138  // ACTIONS
139  armem::actions::GetActionsOutputSeq
141  const armem::actions::GetActionsInputSeq& input)
142  {
143  using namespace armem::actions;
144  Action greeting{"hi", "Say hello to " + input[0].id.entityName};
145  Action failure{"fail", "Fail dramatically"};
146  Action nothing{"null", "Do nothing, but deeply nested"};
147 
148  SubMenu one{"one", "One", { nothing } };
149  SubMenu two{"two", "Two", { one } };
150  SubMenu three{"three", "Three", { two } };
151  SubMenu four{"four", "Four", { three } };
152 
153  Menu menu {
154  greeting,
155  failure,
156  four,
157  SubMenu{"mut", "Mutate", {
158  Action{"copy", "Copy latest instance"}
159  }}
160  };
161 
162  return {{ menu.toIce() }};
163  }
164 
165  armem::actions::ExecuteActionOutputSeq ExampleMemory::executeActions(
166  const armem::actions::ExecuteActionInputSeq& input)
167  {
168  using namespace armem::actions;
169 
170  ExecuteActionOutputSeq output;
171  for (const auto& [id, path] : input)
172  {
173  const armem::MemoryID memoryID = armarx::fromIce<armem::MemoryID>(id);
174  if (path == ActionPath{"hi"})
175  {
176  ARMARX_INFO << "Hello, " << memoryID.str() << "!";
177  output.emplace_back(true, "");
178  }
179  else if (path == ActionPath{"fail"})
180  {
181  ARMARX_WARNING << "Alas, I am gravely wounded!";
182  output.emplace_back(false, "Why would you do that to him?");
183  }
184  else if (not path.empty() and path.front() == "four" and path.back() == "null")
185  {
186  // Do nothing.
187  ARMARX_INFO << "Nested action (path: " << path << ")";
188  output.emplace_back(true, "");
189  }
190  else if (path == ActionPath{"mut", "copy"})
191  {
192  auto* instance = workingMemory().findLatestInstance(memoryID);
193  if (instance != nullptr)
194  {
199  update.entityID = newID;
200  update.referencedTime = armem::Time::Now();
201  update.instancesData = { instance->data() };
202 
203  armem::Commit newCommit;
204  newCommit.add(update);
205  this->commit(armarx::toIce<armem::data::Commit>(newCommit));
206 
207  tab.rebuild = true;
208  ARMARX_INFO << "Duplicated " << memoryID;
209  output.emplace_back(true, "");
210  }
211  else
212  {
213  output.emplace_back(false, "Couldn't duplicate " + memoryID.str());
214  }
215  }
216  }
217 
218  return output;
219  }
220 
221  // PREDICTING
223  ExampleMemory::predictLatest(const armem::PredictionRequest& request)
224  {
226  auto memID = request.snapshotID;
227  result.snapshotID = memID;
228 
230  builder.latestEntitySnapshot(memID);
231  auto queryResult =
232  query(armarx::toIce<armem::query::data::Input>(builder.buildQueryInput()));
233  if (queryResult.success)
234  {
235  auto readMemory = fromIce<armem::wm::Memory>(queryResult.memory);
236  auto* latest = readMemory.findLatestSnapshot(memID);
237  if (latest != nullptr)
238  {
239  auto instance = memID.hasInstanceIndex()
240  ? latest->getInstance(memID)
241  : latest->getInstance(latest->getInstanceIndices().at(0));
242  result.success = true;
243  result.prediction = instance.data();
244  }
245  else
246  {
247  result.success = false;
248  result.errorMessage =
249  "Could not find entity referenced by MemoryID '" + memID.str() + "'.";
250  }
251  }
252  else
253  {
254  result.success = false;
255  result.errorMessage =
256  "Could not find entity referenced by MemoryID '" + memID.str() + "'.";
257  }
258 
259  return result;
260  }
261 
262  // REMOTE GUI
263 
265  {
266  using namespace armarx::RemoteGui::Client;
267 
268  {
269  // Core segments are locked by MemoryRemoteGui.
271  }
272 
273  VBoxLayout root = {tab.memoryGroup, VSpacer()};
274  RemoteGui_createTab(getName(), root, &tab);
275  }
276 
277 
279  {
280  if (tab.rebuild.exchange(false))
281  {
283  }
284  }
285 
286 }
armarx::armem::base::detail::GetFindSnapshotMixin::findLatestInstance
const auto * findLatestInstance(int instanceIndex=0) const
Find the latest entity instance.
Definition: lookup_mixins.h:372
armarx::armem::PredictionRequest
Definition: Prediction.h:49
armarx::armem::PredictionResult::snapshotID
armem::MemoryID snapshotID
Definition: Prediction.h:63
armarx::armem::PredictionEngine::engineID
std::string engineID
Definition: Prediction.h:35
armarx::armem::server::plugins::ReadWritePluginUser::query
virtual armem::query::data::Result query(const armem::query::data::Input &input, const Ice::Current &=Ice::emptyCurrent) override
Definition: ReadWritePluginUser.cpp:56
armarx::armem::MemoryID::providerSegmentName
std::string providerSegmentName
Definition: MemoryID.h:52
armarx::armem::Commit
A bundle of updates to be sent to the memory.
Definition: Commit.h:89
armarx::ExampleMemory::RemoteGui_update
void RemoteGui_update() override
Definition: ExampleMemory.cpp:278
armarx::RemoteGui::Client::VBoxLayout
Definition: Widgets.h:167
armarx::armem::client::query::Builder::buildQueryInput
QueryInput buildQueryInput() const
Definition: Builder.cpp:11
armarx::armem::server::MemoryRemoteGui::makeGroupBox
GroupBox makeGroupBox(const armem::wm::Memory &memory) const
Definition: MemoryRemoteGui.cpp:125
armarx::core::time::DateTime::Now
static DateTime Now()
Definition: DateTime.cpp:55
armarx::armem::MemoryID::str
std::string str(bool escapeDelimiters=true) const
Get a string representation of this memory ID.
Definition: MemoryID.cpp:102
Prediction.h
armarx::armem::server::plugins::ReadWritePluginUser::setMemoryName
void setMemoryName(const std::string &memoryName)
Definition: ReadWritePluginUser.cpp:25
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::armem::client::query::Builder::latestEntitySnapshot
void latestEntitySnapshot(const MemoryID &entityID)
Definition: Builder.cpp:107
armarx::armem::PredictionResult
Definition: Prediction.h:58
armarx::armem::server::plugins::ReadWritePluginUser::workingMemory
server::wm::Memory & workingMemory()
Definition: ReadWritePluginUser.cpp:106
armarx::status::failure
@ failure
armarx::RemoteGui::Client::VSpacer
Definition: Widgets.h:204
armarx::ExampleMemory::commit
armem::data::CommitResult commit(const armem::data::Commit &commit, const Ice::Current &=Ice::emptyCurrent) override
Definition: ExampleMemory.cpp:123
armarx::ExampleMemory::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: ExampleMemory.cpp:69
armarx::ExampleMemory::onDisconnectComponent
void onDisconnectComponent() override
Hook for subclass.
Definition: ExampleMemory.cpp:102
armarx::armem::MemoryID::withProviderSegmentName
MemoryID withProviderSegmentName(const std::string &name) const
Definition: MemoryID.cpp:412
armarx::armem::MemoryID
A memory ID.
Definition: MemoryID.h:47
armarx::armem::PredictionResult::prediction
aron::data::DictPtr prediction
Definition: Prediction.h:64
armarx::ExampleMemory::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: ExampleMemory.cpp:93
MemoryRemoteGui.h
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:19
armarx::ExampleMemory::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: ExampleMemory.cpp:41
error.h
armarx::armem::EntityUpdate
An update of an entity for a specific point in time.
Definition: Commit.h:27
ice_conversions.h
armarx::armem::base::MemoryBase::addCoreSegment
CoreSegmentT & addCoreSegment(const std::string &name, aron::type::ObjectPtr coreSegmentType=nullptr, const std::vector< PredictionEngine > &predictionEngines={})
Add an empty core segment with the given name, type and prediction engines.
Definition: MemoryBase.h:259
armarx::ExampleMemory::addSegments
armem::data::AddSegmentsResult addSegments(const armem::data::AddSegmentsInput &input, const Ice::Current &) override
Definition: ExampleMemory.cpp:114
armarx::ExampleMemory::createRemoteGuiTab
void createRemoteGuiTab()
Definition: ExampleMemory.cpp:264
armarx::armem::server::wm::detail::Prediction::addPredictor
void addPredictor(const PredictionEngine &engine, Predictor &&predictor)
Definition: Prediction.h:68
armarx::armem::MemoryID::entityName
std::string entityName
Definition: MemoryID.h:53
armarx::armem::server::ltm::util::mongodb::detail::update
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
Definition: mongodb.cpp:67
armarx::armem::PredictionEngine
Definition: Prediction.h:33
armarx::LightweightRemoteGuiComponentPluginUser::RemoteGui_startRunningTask
void RemoteGui_startRunningTask()
Definition: LightweightRemoteGuiComponentPlugin.cpp:110
ExpressionException.h
armarx::armem::client::query_fns::latest
std::function< void(query::SnapshotSelector &)> latest()
Definition: query_fns.h:109
armarx::armem::MemoryID::getCoreSegmentID
MemoryID getCoreSegmentID() const
Definition: MemoryID.cpp:289
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
armarx::armem::MemoryID::withEntityName
MemoryID withEntityName(const std::string &name) const
Definition: MemoryID.cpp:420
armarx::ExampleMemory::onExitComponent
void onExitComponent() override
Hook for subclass.
Definition: ExampleMemory.cpp:106
armarx::armem::Commit::add
EntityUpdate & add()
Definition: Commit.cpp:81
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:70
armarx::armem::PredictionResult::errorMessage
std::string errorMessage
Definition: Prediction.h:61
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::ExampleMemory::getActions
armem::actions::GetActionsOutputSeq getActions(const armem::actions::GetActionsInputSeq &input) override
Definition: ExampleMemory.cpp:140
armarx::LightweightRemoteGuiComponentPluginUser::RemoteGui_createTab
void RemoteGui_createTab(std::string const &name, RemoteGui::Client::Widget const &rootWidget, RemoteGui::Client::Tab *tab)
Definition: LightweightRemoteGuiComponentPlugin.cpp:95
armarx::ExampleMemory::getDefaultName
std::string getDefaultName() const override
Definition: ExampleMemory.cpp:63
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::armem::index::memoryID
const MemoryID memoryID
Definition: memory_ids.cpp:29
Builder.h
ExampleMemory.h
armarx::armem::client::query::Builder
The query::Builder class provides a fluent-style specification of hierarchical queries.
Definition: Builder.h:22
ice_conversions_templates.h
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
armarx::ExampleMemory::executeActions
armem::actions::ExecuteActionOutputSeq executeActions(const armem::actions::ExecuteActionInputSeq &input) override
Definition: ExampleMemory.cpp:165
armarx::armem::PredictionResult::success
bool success
Definition: Prediction.h:60
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::RemoteGui::Client
Definition: EigenWidgets.cpp:8
armarx::armem::server::MemoryRemoteGui
Utility for memory Remote Guis.
Definition: MemoryRemoteGui.h:14
armarx::armem::PredictionRequest::snapshotID
armem::MemoryID snapshotID
Definition: Prediction.h:51
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:36