Skill.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <functional>
4 #include <mutex>
5 #include <queue>
6 #include <thread>
7 
11 
12 #include <RobotAPI/interface/skills/SkillManagerInterface.h>
14 
15 #include "SkillDescription.h"
16 #include "SkillID.h"
17 #include "SkillPreparationInput.h"
18 #include "SkillProxy.h"
19 #include "SkillStatusUpdate.h"
20 #include "error/Exception.h"
21 
22 namespace armarx
23 {
24  namespace skills
25  {
26  /**
27  * @brief Base class for skills.
28  */
29  class Skill : public armarx::Logging
30  {
31  public:
32  using CallbackT =
33  std::function<void(const SkillStatus s, const armarx::aron::data::DictPtr&)>;
34 
35  /// A result struct for skill initialization
36  struct InitResult
37  {
39  };
40 
41  /// A result struct for skill preparing
43  {
45  };
46 
47  /// A result struct for th main method of a skill
48  struct MainResult
49  {
52  };
53 
54  /// A result struct for skill exit function
55  struct ExitResult
56  {
58  };
59 
60  /// We completely remove the default constructor! A skill without a desciption cannot exist
61  Skill() = delete;
62 
63  /// Constructor of a skill for inheritance. Every skill must have a skill description
64  Skill(const SkillDescription&);
65 
66  /// Virtual destructor of a skill
67  virtual ~Skill()
68  {
69  //ARMARX_IMPORTANT << "DESTROY SKILL " << getSkillId();
70  }
71 
72  /// Get the id of the skill
73  SkillID
74  getSkillId() const
75  {
76  return description.skillId;
77  }
78 
79  /// Get the description of a skill
82  {
83  return description;
84  }
85 
86  /// Set the provider id of the description of the skill.
87  /// This method is called when creating a skill in a skill provider
88  void
90  {
92  }
93 
94  void
96  {
97  this->callback = callback;
98  }
99 
100  void
101  setManager(const manager::dti::SkillManagerInterfacePrx& manager)
102  {
103  this->manager = manager;
104  }
105 
106  void
107  setExecutorName(const std::string& executorName)
108  {
109  this->executorName = executorName;
110  }
111 
112  /// Prepare a skill once. This method is called in a loop as long as it returns RUNNING
113  /// If the loop does not terminate with SUCCEDED the skill execution is failed.
114  PrepareResult prepareSkill();
115 
116  /// Initialization of a skill. Called directly after construction.
117  /// If this method does not return SUCCEEDED the skill execution is failed.
118  InitResult initSkill();
119 
120  /// Main method of a skill.
121  MainResult mainOfSkill();
122 
123  /// Exit method of a skill. It is guaranteed that exit is always called
124  /// (unless there is a segfault or similar)
125  ExitResult exitSkill();
126 
127  /// Notify the skill from extern to stop
128  void notifySkillToStop();
129 
130  /// Returns whether the skill should terminate as soon as possible
131  bool shouldSkillTerminate() const;
132 
133  /// Merge parameters to the local parameters of the skill
134  void updateParameters(const aron::data::DictPtr& d);
135 
136  /// Hard set the parameters, ignoring everything that has been set or merged before
137  void setParameters(const aron::data::DictPtr& d);
138 
139  /// Get the parameters of a skill that have been set so far
141 
142  protected:
143  void throwIfSkillShouldTerminate(const std::string& abortedMessage = "");
144  void throwIfSkillShouldTerminate(const std::function<void()>& do_before,
145  const std::string& abortedMessage = "");
146 
147  static MainResult MakeSucceededResult(aron::data::DictPtr data = nullptr);
148  static MainResult MakeFailedResult();
149  static MainResult MakeAbortedResult();
150 
151  // fires if the skill reaches timeout
152  void notifyTimeoutReached();
153 
154  private:
155  // helper methods to do all the static initialization stuff
156  InitResult _init();
157  PrepareResult _prepare();
158  MainResult _main();
159  ExitResult _exit();
160 
161  void _onTimeoutReached();
162  void _onStopRequested();
163 
164  protected:
165  /// Override this method with the actual implementation.
166  virtual InitResult init();
167 
168  /// Override this method with the actual implementation.
169  virtual PrepareResult prepare();
170 
171  /// Override this method with the actual implementation. The callback is for status updates to the calling instance
172  virtual MainResult main();
173 
174  /// Override this method with the actual implementation.
175  virtual ExitResult exit();
176 
177  protected:
178  /// Override these methods if you want to do something special when notification comes
179  virtual void onTimeoutReached();
180  virtual void onStopRequested();
181 
182  protected:
183  /// install a condition which is frequently checked from the conditionCheckingThread
184  void installConditionWithCallback(std::function<bool()>&& f,
185  std::function<void()>&& cb);
186 
187  // Calling subskills
188 
189  /**
190  * @brief Call a subskill with default parameters and block until the subskill terminates.
191  *
192  * If you call a subskill this way it will be stopped if the current skill stops.
193  *
194  * @param proxy Skill proxy.
195  * @return Terminated skill status update.
196  * @throw armarx::skills::error::SkillAbortedException
197  * If the calling skill has been aborted.
198  * @throw armarx::skills::error::SkillFailedException
199  * If the calling skill's timeout was reached.
200  */
201  std::optional<TerminatedSkillStatusUpdate>
202  callSubskill(const skills::SkillProxy& proxy);
203 
204  /**
205  * @brief Call a subskill with given parameters and block until the subskill terminates.
206  * @param proxy Skill proxy.
207  * @param parameters Parameters passed to the skill.
208  * @return Terminated skill status update.
209  * @throw armarx::skills::error::SkillAbortedException
210  * If the calling skill has been aborted.
211  * @throw armarx::skills::error::SkillFailedException
212  * If the calling skill's timeout was reached.
213  */
214  std::optional<TerminatedSkillStatusUpdate>
216 
217  /// Similar to callSubskill but non-blocking
219 
220  /// Similar to callSubskill but non-blocking
223 
224  /**
225  * @brief Call a subskill with the given ID and its default parameters.
226  * @param skillId The subskill's ID.
227  * @return The terminated skill status update.
228  * @throw armarx::skills::error::SkillAbortedException
229  * If the calling skill has been aborted.
230  * @throw armarx::skills::error::SkillFailedException
231  * If the calling skill's timeout was reached.
232  */
233  std::optional<TerminatedSkillStatusUpdate> callSubskill(const SkillID& skillId);
234 
235  /**
236  * @brief Call a subskill with the given ID and parameters.
237  * @param skillId The subskill's ID.
238  * @param parameters The parameters.
239  * @return The terminated skill status update.
240  * @throw armarx::skills::error::SkillAbortedException
241  * If the calling skill has been aborted.
242  * @throw armarx::skills::error::SkillFailedException
243  * If the calling skill's timeout was reached.
244  */
245  std::optional<TerminatedSkillStatusUpdate>
246  callSubskill(const SkillID& skillId, const aron::data::DictPtr& parameters);
247 
248  /**
249  * @brief Call a subskill with the given ID and parameters.
250  * @param skillId The subskill's ID.
251  * @param parameters The parameters.
252  * @return The terminated skill status update.
253  * @throw armarx::skills::error::SkillAbortedException
254  * If the calling skill has been aborted.
255  * @throw armarx::skills::error::SkillFailedException
256  * If the calling skill's timeout was reached.
257  */
258  template <class ParameterT>
259  std::optional<TerminatedSkillStatusUpdate>
260  callSubskill(const SkillID& skillId, const ParameterT& parameters)
261  {
262  return callSubskill(skillId, parameters.toAron());
263  }
264 
265  /**
266  * @brief Call a subskill with parameters based on the default parameters.
267  *
268  * Creates the skill's default parameters, and calls `parametersFunction` on them.
269  * This allows the caller to modify the parameters before executing the skill.
270  *
271  * @param skillId The subskill's ID.
272  * @param parametersFunction Function which edits the parameters.
273  * @return The terminated skill status update.
274  * @throw armarx::skills::error::SkillAbortedException
275  * If the calling skill has been aborted.
276  * @throw armarx::skills::error::SkillFailedException
277  * If the calling skill's timeout was reached.
278  */
279  std::optional<TerminatedSkillStatusUpdate>
280  callSubskill(const SkillID& skillId,
281  std::function<void(aron::data::DictPtr& parameters)> parametersFunction);
282 
283  /**
284  * @brief Call a subskill with parameters based on the default parameters.
285  *
286  * Creates the skill's default parameters, converts them to `ParameterT`,
287  * and calls `parametersFunction` on them.
288  * This allows the caller to modify the parameters as `ParameterT` before executing
289  * the skill.
290  *
291  * @param skillId The subskill's ID.
292  * @param parametersFunction Function which edits the parameters.
293  * @return The terminated skill status update.
294  * @throw armarx::skills::error::SkillAbortedException
295  * If the calling skill has been aborted.
296  * @throw armarx::skills::error::SkillFailedException
297  * If the calling skill's timeout was reached.
298  */
299  template <class ParameterT>
300  std::optional<TerminatedSkillStatusUpdate>
301  callSubskill(const SkillID& skillId,
302  std::function<void(ParameterT& parameters)> parametersFunction)
303  {
304  SkillProxy proxy(manager, skillId);
305 
306  ParameterT parameters;
307  if (auto parametersAron = proxy.getRootProfileParameters())
308  {
309  parameters = ParameterT::FromAron(parametersAron);
310  }
311 
312  parametersFunction(parameters);
313 
314  return callSubskill(proxy, parameters.toAron());
315  }
316 
317 
318  public:
319  // running params
322 
323  protected:
324  // parameterization. Will be set from implementation wrapper. No getters available
325  // const after construction!!
327  manager::dti::SkillManagerInterfacePrx manager = nullptr;
328  std::string executorName = "";
329 
330  protected:
331  // non-const params. Const after preparation. Getters are available
332  mutable std::mutex parametersMutex;
334 
335  // The descripion of the skill
337 
338  // Status variables
339  std::atomic_bool constructing = true;
340  std::atomic_bool initializing = false;
341  std::atomic_bool preparing = false;
342  std::atomic_bool running = false;
343  std::atomic_bool exiting = false;
344  std::atomic_bool finished = false;
345 
346  // Conditionals to indicate that an event has occured. Use conditions this way
347  std::atomic_bool stopped = false;
348  std::atomic_bool timeoutReached = false;
349 
350 
351  private:
352  // active conditions. First is condition (bool return func)
353  mutable std::mutex conditionCallbacksMutex;
354  std::vector<std::pair<std::function<bool()>, std::function<void()>>>
355  conditionCallbacks = {};
356 
357  std::thread conditionCheckingThread; // A thread that checks the conditions frequently
358  armarx::Frequency conditionCheckingThreadFrequency = armarx::Frequency::Hertz(20);
359 
360  mutable std::mutex subskillsMutex;
361  std::vector<skills::SkillExecutionID> subskills;
362  };
363 
364  template <class T>
366 
367  } // namespace skills
368 } // namespace armarx
armarx::skills::Skill::getParameters
aron::data::DictPtr getParameters() const
Get the parameters of a skill that have been set so far.
Definition: Skill.cpp:121
armarx::skills::Skill::exitSkill
ExitResult exitSkill()
Exit method of a skill.
Definition: Skill.cpp:271
armarx::skills::SkillProxy::getRootProfileParameters
aron::data::DictPtr getRootProfileParameters() const
get the default parameters of the skill. TODO: Skill profiles in memory!
Definition: SkillProxy.cpp:123
armarx::skills::Skill::constructing
std::atomic_bool constructing
Definition: Skill.h:339
armarx::skills::Skill::setParameters
void setParameters(const aron::data::DictPtr &d)
Hard set the parameters, ignoring everything that has been set or merged before.
Definition: Skill.cpp:108
armarx::skills::TerminatedSkillStatus
TerminatedSkillStatus
Definition: SkillStatusUpdate.h:39
armarx::skills::Skill::ExitResult::status
TerminatedSkillStatus status
Definition: Skill.h:57
armarx::skills::SkillExecutionID
Definition: SkillExecutionID.h:19
armarx::skills::Skill::notifySkillToStop
void notifySkillToStop()
Notify the skill from extern to stop.
Definition: Skill.cpp:342
armarx::skills::Skill::manager
manager::dti::SkillManagerInterfacePrx manager
Definition: Skill.h:327
armarx::skills::Skill::exiting
std::atomic_bool exiting
Definition: Skill.h:343
skills
This file is part of ArmarX.
armarx::skills::Skill::updateParameters
void updateParameters(const aron::data::DictPtr &d)
Merge parameters to the local parameters of the skill.
Definition: Skill.cpp:92
Exception.h
SkillStatusUpdate.h
armarx::skills::Skill::prepare
virtual PrepareResult prepare()
Override this method with the actual implementation.
Definition: Skill.cpp:429
armarx::skills::Skill::PrepareResult
A result struct for skill preparing.
Definition: Skill.h:42
SkillID.h
armarx::skills::Skill::parameters
armarx::aron::data::DictPtr parameters
Definition: Skill.h:333
armarx::skills::SkillDescription
Definition: SkillDescription.h:18
armarx::skills::Skill::Skill
Skill()=delete
We completely remove the default constructor! A skill without a desciption cannot exist.
armarx::core::time::DateTime::Now
static DateTime Now()
Definition: DateTime.cpp:55
armarx::skills::Skill::onStopRequested
virtual void onStopRequested()
Definition: Skill.cpp:415
armarx::skills::Skill::preparing
std::atomic_bool preparing
Definition: Skill.h:341
DateTime.h
armarx::skills::Skill::setExecutorName
void setExecutorName(const std::string &executorName)
Definition: Skill.h:107
armarx::skills::Skill::getSkillDescription
SkillDescription getSkillDescription() const
Get the description of a skill.
Definition: Skill.h:81
armarx::skills::Skill::running
std::atomic_bool running
Definition: Skill.h:342
armarx::skills::SkillID::providerId
std::optional< ProviderID > providerId
Definition: SkillID.h:59
armarx::core::time::Frequency
Represents a frequency.
Definition: Frequency.h:17
armarx::skills::Skill::callSubskill
std::optional< TerminatedSkillStatusUpdate > callSubskill(const SkillID &skillId, std::function< void(ParameterT &parameters)> parametersFunction)
Call a subskill with parameters based on the default parameters.
Definition: Skill.h:301
armarx::skills::Skill::setCallback
void setCallback(const CallbackT &callback)
Definition: Skill.h:95
armarx::skills::Skill::CallbackT
std::function< void(const SkillStatus s, const armarx::aron::data::DictPtr &)> CallbackT
Definition: Skill.h:33
armarx::skills::Skill::callSubskillAsync
skills::SkillExecutionID callSubskillAsync(const skills::SkillProxy &proxy)
Similar to callSubskill but non-blocking.
Definition: Skill.cpp:43
armarx::skills::Skill::timeoutReached
std::atomic_bool timeoutReached
Definition: Skill.h:348
armarx::skills::Skill::callSubskill
std::optional< TerminatedSkillStatusUpdate > callSubskill(const skills::SkillProxy &proxy)
Call a subskill with default parameters and block until the subskill terminates.
Definition: Skill.cpp:22
armarx::skills::Skill::onTimeoutReached
virtual void onTimeoutReached()
Override these methods if you want to do something special when notification comes.
Definition: Skill.cpp:410
armarx::skills::Skill::init
virtual InitResult init()
Override this method with the actual implementation.
Definition: Skill.cpp:421
armarx::skills::Skill::stopped
std::atomic_bool stopped
Definition: Skill.h:347
armarx::skills::SkillProxy
Definition: SkillProxy.h:11
armarx::skills::Skill::installConditionWithCallback
void installConditionWithCallback(std::function< bool()> &&f, std::function< void()> &&cb)
install a condition which is frequently checked from the conditionCheckingThread
Definition: Skill.cpp:15
armarx::skills::Skill::PrepareResult::status
ActiveOrTerminatedSkillStatus status
Definition: Skill.h:44
armarx::skills::Skill::MakeFailedResult
static MainResult MakeFailedResult()
Definition: Skill.cpp:324
armarx::skills::ActiveOrTerminatedSkillStatus
ActiveOrTerminatedSkillStatus
Definition: SkillStatusUpdate.h:31
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::skills::ProviderID
Definition: ProviderID.h:15
armarx::skills::Skill::notifyTimeoutReached
void notifyTimeoutReached()
Definition: Skill.cpp:356
armarx::skills::Skill::initSkill
InitResult initSkill()
Initialization of a skill.
Definition: Skill.cpp:243
armarx::skills::Skill::finished
std::atomic_bool finished
Definition: Skill.h:344
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::skills::Skill::parametersMutex
std::mutex parametersMutex
Definition: Skill.h:332
armarx::skills::Skill::description
SkillDescription description
Definition: Skill.h:336
armarx::skills::SkillDescription::skillId
SkillID skillId
Definition: SkillDescription.h:20
All.h
armarx::skills::Skill::mainOfSkill
MainResult mainOfSkill()
Main method of a skill.
Definition: Skill.cpp:261
Metronome.h
armarx::skills::Skill::started
armarx::core::time::DateTime started
Definition: Skill.h:320
armarx::skills::Skill::MakeAbortedResult
static MainResult MakeAbortedResult()
Definition: Skill.cpp:333
armarx::skills::Skill::MakeSucceededResult
static MainResult MakeSucceededResult(aron::data::DictPtr data=nullptr)
Definition: Skill.cpp:315
armarx::skills::Skill::MainResult
A result struct for th main method of a skill.
Definition: Skill.h:48
armarx::skills::Skill::initializing
std::atomic_bool initializing
Definition: Skill.h:340
armarx::skills::Skill::setProviderId
void setProviderId(const skills::ProviderID &pid)
Set the provider id of the description of the skill.
Definition: Skill.h:89
SkillProxy.h
armarx::skills::Skill::ExitResult
A result struct for skill exit function.
Definition: Skill.h:55
armarx::skills::Skill::executorName
std::string executorName
Definition: Skill.h:328
armarx::skills::Skill::exit
virtual ExitResult exit()
Override this method with the actual implementation.
Definition: Skill.cpp:437
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
armarx::skills::Skill::callback
CallbackT callback
Definition: Skill.h:326
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
armarx::skills::Skill::MainResult::status
TerminatedSkillStatus status
Definition: Skill.h:50
armarx::skills::Skill::callSubskill
std::optional< TerminatedSkillStatusUpdate > callSubskill(const SkillID &skillId, const ParameterT &parameters)
Call a subskill with the given ID and parameters.
Definition: Skill.h:260
armarx::Logging
Base Class for all Logging classes.
Definition: Logging.h:232
armarx::skills::Skill::InitResult::status
TerminatedSkillStatus status
Definition: Skill.h:38
armarx::skills::Skill::shouldSkillTerminate
bool shouldSkillTerminate() const
Returns whether the skill should terminate as soon as possible.
Definition: Skill.cpp:371
armarx::skills::Skill::MainResult::data
aron::data::DictPtr data
Definition: Skill.h:51
armarx::skills::Skill::InitResult
A result struct for skill initialization.
Definition: Skill.h:36
armarx::skills::Skill
Base class for skills.
Definition: Skill.h:29
armarx::skills::Skill::~Skill
virtual ~Skill()
Virtual destructor of a skill.
Definition: Skill.h:67
armarx::skills::Skill::main
virtual MainResult main()
Override this method with the actual implementation. The callback is for status updates to the callin...
Definition: Skill.cpp:444
SkillPreparationInput.h
armarx::core::time::Frequency::Hertz
static Frequency Hertz(std::int64_t hertz)
Definition: Frequency.cpp:23
armarx::skills::Skill::throwIfSkillShouldTerminate
void throwIfSkillShouldTerminate(const std::string &abortedMessage="")
Definition: Skill.cpp:291
armarx::skills::Skill::prepareSkill
PrepareResult prepareSkill()
Prepare a skill once.
Definition: Skill.cpp:252
Logging.h
armarx::skills::Skill::setManager
void setManager(const manager::dti::SkillManagerInterfacePrx &manager)
Definition: Skill.h:101
armarx::skills::SkillID
Definition: SkillID.h:17
armarx::skills::isSkill
concept isSkill
Definition: Skill.h:365
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx::core::time::DateTime::Invalid
static DateTime Invalid()
Definition: DateTime.cpp:60
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::skills::Skill::getSkillId
SkillID getSkillId() const
Get the id of the skill.
Definition: Skill.h:74
armarx::skills::Skill::exited
armarx::core::time::DateTime exited
Definition: Skill.h:321
armarx::skills::SkillStatus
SkillStatus
Definition: SkillStatusUpdate.h:20
SkillDescription.h