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