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