SkillManagerWrapper.cpp
Go to the documentation of this file.
1 #include "SkillManagerWrapper.h"
2 
3 #include <mutex>
4 
6 
7 namespace armarx::skills::gui
8 {
9  using StatusMap = std::map<skills::SkillExecutionID, skills::SkillStatusUpdate>;
10  using SkillMap =
11  std::map<skills::ProviderID, std::map<skills::SkillID, skills::SkillDescription>>;
12 
13  const StatusMap
15  {
16  if (!memory)
17  {
18  // check if null
19  return {};
20  }
21 
22  try
23  {
24  std::scoped_lock l(mutex_memory);
25 
26  // we return this map
27  StatusMap statusMap;
28 
29  auto currentManagerStatuses = memory->getSkillExecutionStatuses();
30 
31  // iterate over raw data and convert to common types
32  for (const auto& [k, v] : currentManagerStatuses)
33  {
34  auto executionId = skills::SkillExecutionID::FromIce(k);
35  auto statusUpdate = skills::SkillStatusUpdate::FromIce(v);
36 
37  // update maps
38  statusMap[executionId] = statusUpdate;
39  }
40  return statusMap;
41  }
42  catch (Ice::Exception const& e)
43  {
45  << "Unhandled Ice exception encountered while updating executions. Exception was: "
46  << e;
47  emit connectionUpdate("Could not fetch executions", e.what());
48  return {};
49  }
50  catch (...)
51  {
52  ARMARX_WARNING << "Unknown exception encountered while updating executions.";
53  return {};
54  }
55  }
56 
57  // check if search strings occur in the skill name in order
58  bool
59  matches(std::string skillName, std::vector<std::string>& searches)
60  {
61  size_t index = 0;
62  for (std::string& substring : searches)
63  {
64  size_t occurance = skillName.find(substring, index);
65  if (occurance == std::string::npos)
66  {
67  return false;
68  }
69 
70 
71  // we found an occurance
72  index = occurance;
73  }
74  return true;
75  }
76 
77  void
78  SkillManagerWrapper::filterSkillUpdate(
79  std::map<skills::manager::dto::SkillID, skills::manager::dto::SkillDescription>& update)
80  {
81  // empty search => do not filter
82  if (this->currentSkillSearch.empty())
83  {
84  return;
85  }
86 
87  std::vector<std::string> substrings;
88 
89  {
90  std::vector<std::string> rawSubstrings = simox::alg::split(currentSkillSearch);
91  for (auto& string : rawSubstrings)
92  {
93  substrings.push_back(simox::alg::to_lower(string));
94  }
95  }
96 
97 
98  for (auto it = update.begin(); it != update.end();)
99  {
100  if (not matches(simox::alg::to_lower(skills::SkillID::FromIce(it->first).skillName),
101  substrings))
102  {
103  it = update.erase(it);
104  }
105  else
106  {
107  ++it;
108  }
109  }
110  }
111 
112  const SkillMap
114  {
115  if (!memory)
116  {
117  return {};
118  }
119 
120  try
121  {
122  std::scoped_lock l(mutex_memory);
123 
125 
126  auto managerSkills = memory->getSkillDescriptions();
127 
128  this->filterSkillUpdate(managerSkills);
129 
130 
131  for (const auto& [sid, desc] : managerSkills)
132  {
133  auto description = skills::SkillDescription::FromIce(desc);
134  auto skillId = skills::SkillID::FromIce(sid);
135  auto providerId = skillId.providerId.value_or(
136  skills::ProviderID{.providerName = "UNKNOWN PROVIDER NAME"});
137 
138  ARMARX_CHECK(skillId.isFullySpecified());
139 
140  auto& providedSkillsMap = skills[providerId]; // create new if not existing
141  providedSkillsMap.insert({skillId, description});
142  }
143 
144  return skills;
145  }
146  catch (Ice::Exception const& e)
147  {
149  << "Unhandled Ice exception encountered while updating skills. Exception was: "
150  << e;
151  emit connectionUpdate("Could not fetch skills", e.what());
152  return {};
153  }
154  catch (...)
155  {
156  ARMARX_WARNING << "Unknown exception encountered while updating skills.";
157  return {};
158  }
159  }
160 
161  void
163  skills::manager::dti::SkillManagerInterfacePrx const& updatedMemory)
164  {
165  std::scoped_lock l(mutex_memory);
166  this->memory = updatedMemory;
167  }
168 
169  void
171  {
172  // clear memory
173 
174  std::scoped_lock l(mutex_memory);
175  this->memory = nullptr;
176  }
177 
178  void
179  SkillManagerWrapper::acceptSearchRequest(std::string const& search)
180  {
181  this->currentSkillSearch = search;
182  }
183 
184  void
186  {
187  ARMARX_IMPORTANT << "Stopping all running executions.";
188  const auto& executions = this->fetchExecutions();
189  for (auto& [executionId, status] : executions)
190  {
191  // select all running executions...
192  if (!status.hasBeenTerminated())
193  {
194  // ... and kill them.
195  this->stopExecution(executionId, 3);
196  }
197  }
198  }
199 
200  const std::optional<ProviderID>
202  {
203  // check if id already contains a provider. If so, this function should not have been called!
204  if (skillId.isProviderSpecified())
205  {
206  ARMARX_WARNING << "The memory snapshot was searched for any provider, when a provider "
207  "was specified.";
208  // we continue, but this might result in unexpected behaviour...
209  }
210 
211  for (auto& [prov, skillMap] : map)
212  {
213  for (auto& [skill, desc] : skillMap)
214  {
215  if (skill == skillId)
216  {
217  return prov;
218  }
219  }
220  }
221  return std::nullopt;
222  }
223 
224  void
226  const unsigned int max_retries)
227  {
228  // memory???
229  if (!memory)
230  {
231  return;
232  }
233 
234  unsigned int retries = max_retries;
235  bool retry = false;
236 
237  do
238  {
239  try
240  {
241  ARMARX_INFO << "Aborting skill '" << executionId.skillId.skillName << "'...";
242  std::scoped_lock l(mutex_memory);
243  this->memory->abortSkillAsync(executionId.toManagerIce());
244  }
245  catch (Ice::Exception const& e)
246  {
247  retry = true;
248  ARMARX_ERROR << "Unhandeled Ice exception while aborting skill '"
249  << executionId.skillId.skillName << "'.";
250  emit connectionUpdate("Could not abort skill " + executionId.skillId.skillName,
251  e.what());
252  }
253  catch (...)
254  {
255  retry = true;
256  ARMARX_ERROR << "Unhandled error while aborting skill '"
257  << executionId.skillId.skillName << "'.";
258  }
259 
260  if (retry)
261  {
262  retries -= 1;
263 
264  if (retries > 0)
265  {
266  ARMARX_WARNING << "There where errors aborting skills. Retrying...";
267  }
268  else
269  {
270  ARMARX_ERROR << "Couldn't abort all skills after " << max_retries
271  << " tries. Giving up.";
272  retry = false;
273  }
274  }
275  } while (retry);
276  }
277 
278  void
280  aron::data::DictPtr const params)
281  {
282  // Memory???
283  if (!memory)
284  {
285  return;
286  }
287 
288  auto providerId = skillId.providerId;
289  if (!providerId.has_value())
290  {
291  ARMARX_IMPORTANT << "The skill: '" << skillId.skillName
292  << "' has been requested to be executed, but no provider was "
293  "given. Aborting...";
294  return;
295  }
296 
297  std::map<skills::SkillID, skills::SkillDescription> skillDescriptions;
298  {
299  skillDescriptions = this->fetchSkills().at(providerId.value());
300  }
301 
302  if (skillDescriptions.find(skillId) == skillDescriptions.end())
303  {
304  ARMARX_IMPORTANT << "The Skill: '" << skillId.skillName
305  << "' has been requested to be executed, but no skill description was "
306  "found. Aborting...";
307  return;
308  }
309 
310  char hostname[HOST_NAME_MAX];
311  gethostname(hostname, HOST_NAME_MAX);
312 
314  .skillId = skillId,
315  .executorName = "Skills.Manager GUI (hostname: " + std::string(hostname) + ")",
316  .parameters = params};
317 
318  ARMARX_CHECK(skillId.isFullySpecified()); // sanity check
319  ARMARX_IMPORTANT << "Executing skill from GUI: " << skillId << ".";
320 
321  try
322  {
323  std::scoped_lock l(mutex_memory);
324  memory->executeSkillAsync(req.toManagerIce());
325  }
326  catch (Ice::Exception const& e)
327  {
328  ARMARX_ERROR << "Unhandeled Ice exception while executing skill '" << skillId.skillName
329  << "'. Aborting...";
330  emit connectionUpdate("Execution failed of skill " + skillId.skillName, e.what());
331  }
332  catch (...)
333  {
334  ARMARX_ERROR << "Unhandled error while executing skill '" << skillId.skillName
335  << "'. Aborting...";
336  }
337  }
338 
339 
340 } // namespace armarx::skills::gui
armarx::skills::SkillExecutionID
Definition: SkillExecutionID.h:19
skills
This file is part of ArmarX.
armarx::skills::gui::SkillManagerWrapper::startExecutionWithParams
void startExecutionWithParams(skills::SkillID &skillId, aron::data::DictPtr const params)
Attempts to start an execution with given parameters.
Definition: SkillManagerWrapper.cpp:279
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::skills::SkillStatusUpdate::FromIce
static SkillStatusUpdate FromIce(const provider::dto::SkillStatusUpdate &update, const std::optional< skills::ProviderID > &providerId=std::nullopt)
Definition: SkillStatusUpdate.cpp:367
armarx::skills::SkillExecutionRequest::skillId
skills::SkillID skillId
Definition: SkillExecutionRequest.h:33
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::skills::gui::StatusMap
std::map< skills::SkillExecutionID, skills::SkillStatusUpdate > StatusMap
Definition: SkillManagerWrapper.cpp:9
armarx::skills::SkillID::skillName
std::string skillName
Definition: SkillID.h:60
armarx::skills::gui::SkillManagerWrapper::disconnectMemory
void disconnectMemory()
Disconnects the interface from memory.
Definition: SkillManagerWrapper.cpp:170
armarx::skills::ProviderID::providerName
std::string providerName
Definition: ProviderID.h:31
armarx::skills::gui::SkillManagerWrapper::connectionUpdate
void connectionUpdate(std::string const &message, std::string const &error)
armarx::skills::SkillID::providerId
std::optional< ProviderID > providerId
Definition: SkillID.h:59
armarx::skills::gui::SkillManagerWrapper::fetchExecutions
const StatusMap fetchExecutions()
Fetches and returns the latest status update from memory.
Definition: SkillManagerWrapper.cpp:14
armarx::memory
Brief description of class memory.
Definition: memory.h:39
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::skills::gui::SkillManagerWrapper::findFirstProvider
static const std::optional< skills::ProviderID > findFirstProvider(SkillMap const &map, SkillID const &skillId)
Definition: SkillManagerWrapper.cpp:201
armarx::skills::SkillID::isProviderSpecified
bool isProviderSpecified() const
Definition: SkillID.h:41
armarx::skills::SkillExecutionID::toManagerIce
skills::manager::dto::SkillExecutionID toManagerIce() const
Definition: SkillExecutionID.cpp:9
SkillManagerWrapper.h
armarx::skills::SkillExecutionRequest
Definition: SkillExecutionRequest.h:21
armarx::status
status
Definition: FiniteStateMachine.h:259
armarx::skills::ProviderID
Definition: ProviderID.h:15
armarx::skills::gui::SkillMap
std::map< skills::ProviderID, std::map< skills::SkillID, skills::SkillDescription > > SkillMap
Definition: SkillManagerWrapper.cpp:11
armarx::skills::SkillID::FromIce
static SkillID FromIce(const manager::dto::SkillID &)
Definition: SkillID.cpp:32
armarx::skills::gui
Definition: PeriodicUpdateWidget.cpp:11
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
SkillExecutionRequest.h
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::skills::gui::SkillManagerWrapper::fetchSkills
const SkillMap fetchSkills()
Fetches and returns the latest skills update from memory.
Definition: SkillManagerWrapper.cpp:113
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::skills::gui::matches
bool matches(std::string skillName, std::vector< std::string > &searches)
Definition: SkillManagerWrapper.cpp:59
armarx::skills::SkillExecutionID::skillId
SkillID skillId
Definition: SkillExecutionID.h:21
armarx::skills::SkillExecutionID::FromIce
static SkillExecutionID FromIce(const skills::manager::dto::SkillExecutionID &)
Definition: SkillExecutionID.cpp:29
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::skills::gui::SkillManagerWrapper::stopAllExecutions
void stopAllExecutions()
Stops all available (and running) executions.
Definition: SkillManagerWrapper.cpp:185
armarx::skills::SkillDescription::FromIce
static SkillDescription FromIce(const provider::dto::SkillDescription &i, const std::optional< ProviderID > &=std::nullopt)
Definition: SkillDescription.cpp:39
armarx::skills::SkillID
Definition: SkillID.h:17
armarx::skills::SkillID::isFullySpecified
bool isFullySpecified() const
Definition: SkillID.h:29
armarx::skills::gui::SkillManagerWrapper::acceptSearchRequest
void acceptSearchRequest(std::string const &search)
Applies the search word to the update filter.
Definition: SkillManagerWrapper.cpp:179
armarx::skills::gui::SkillManagerWrapper::connectMemory
void connectMemory(skills::manager::dti::SkillManagerInterfacePrx const &updatedMemory)
Updates the memory pointer.
Definition: SkillManagerWrapper.cpp:162
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
armarx::skills::gui::SkillManagerWrapper::stopExecution
void stopExecution(skills::SkillExecutionID const &executionId, const unsigned int max_retries=0)
Attempts to stop an execution.
Definition: SkillManagerWrapper.cpp:225