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  /**
189  * @brief Call a subskill with the given ID and its default parameters.
190  * @param skillId The subskill's ID.
191  * @return The terminated skill status update.
192  * @throw armarx::skills::error::SkillAbortedException
193  * If the calling skill has been aborted.
194  * @throw armarx::skills::error::SkillFailedException
195  * If the calling skill's timeout was reached.
196  */
197  std::optional<TerminatedSkillStatusUpdate> callSubskill(const SkillID& skillId);
198 
199  /**
200  * @brief Call a subskill with the given ID and parameters.
201  * @param skillId The subskill's ID.
202  * @param parameters The parameters.
203  * @return The terminated skill status update.
204  * @throw armarx::skills::error::SkillAbortedException
205  * If the calling skill has been aborted.
206  * @throw armarx::skills::error::SkillFailedException
207  * If the calling skill's timeout was reached.
208  */
209  std::optional<TerminatedSkillStatusUpdate>
210  callSubskill(const SkillID& skillId, const aron::data::DictPtr& parameters);
211 
212  /**
213  * @brief Call a subskill with the given ID and parameters.
214  * @param skillId The subskill's ID.
215  * @param parameters The parameters.
216  * @return The terminated skill status update.
217  * @throw armarx::skills::error::SkillAbortedException
218  * If the calling skill has been aborted.
219  * @throw armarx::skills::error::SkillFailedException
220  * If the calling skill's timeout was reached.
221  */
222  template <class ParameterT>
223  std::optional<TerminatedSkillStatusUpdate>
224  callSubskill(const SkillID& skillId, const ParameterT& parameters)
225  {
226  return callSubskill(skillId, parameters.toAron());
227  }
228 
229  /**
230  * @brief Call a subskill with parameters based on the default parameters.
231  *
232  * Creates the skill's default parameters, and calls `parametersFunction` on them.
233  * This allows the caller to modify the parameters before executing the skill.
234  *
235  * @param skillId The subskill's ID.
236  * @param parametersFunction Function which edits the parameters.
237  * @return The terminated skill status update.
238  * @throw armarx::skills::error::SkillAbortedException
239  * If the calling skill has been aborted.
240  * @throw armarx::skills::error::SkillFailedException
241  * If the calling skill's timeout was reached.
242  */
243  std::optional<TerminatedSkillStatusUpdate>
244  callSubskill(const SkillID& skillId,
245  std::function<void(aron::data::DictPtr& parameters)> parametersFunction);
246 
247  /**
248  * @brief Call a subskill with parameters based on the default parameters.
249  *
250  * Creates the skill's default parameters, converts them to `ParameterT`,
251  * and calls `parametersFunction` on them.
252  * This allows the caller to modify the parameters as `ParameterT` before executing
253  * the skill.
254  *
255  * @param skillId The subskill's ID.
256  * @param parametersFunction Function which edits the parameters.
257  * @return The terminated skill status update.
258  * @throw armarx::skills::error::SkillAbortedException
259  * If the calling skill has been aborted.
260  * @throw armarx::skills::error::SkillFailedException
261  * If the calling skill's timeout was reached.
262  */
263  template <class ParameterT>
264  std::optional<TerminatedSkillStatusUpdate>
265  callSubskill(const SkillID& skillId,
266  std::function<void(ParameterT& parameters)> parametersFunction)
267  {
268  SkillProxy proxy(manager, skillId);
269 
270  ParameterT parameters;
271  if (auto parametersAron = proxy.getRootProfileParameters())
272  {
273  parameters = ParameterT::FromAron(parametersAron);
274  }
275 
276  parametersFunction(parameters);
277 
278  return callSubskill(proxy, parameters.toAron());
279  }
280 
281 
282  public:
283  // running params
286 
287  protected:
288  // parameterization. Will be set from implementation wrapper. No getters available
289  // const after construction!!
291  manager::dti::SkillManagerInterfacePrx manager = nullptr;
292  std::string executorName = "";
293 
294  protected:
295  // non-const params. Const after preparation. Getters are available
296  mutable std::mutex parametersMutex;
298 
299  // The descripion of the skill
301 
302  // Status variables
303  std::atomic_bool constructing = true;
304  std::atomic_bool initializing = false;
305  std::atomic_bool preparing = false;
306  std::atomic_bool running = false;
307  std::atomic_bool exiting = false;
308  std::atomic_bool finished = false;
309 
310  // Conditionals to indicate that an event has occured. Use conditions this way
311  std::atomic_bool stopped = false;
312  std::atomic_bool timeoutReached = false;
313 
314 
315  private:
316  // active conditions. First is condition (bool return func)
317  mutable std::mutex conditionCallbacksMutex;
318  std::vector<std::pair<std::function<bool()>, std::function<void()>>>
319  conditionCallbacks = {};
320 
321  std::thread conditionCheckingThread; // A thread that checks the conditions frequently
322  armarx::Frequency conditionCheckingThreadFrequency = armarx::Frequency::Hertz(20);
323 
324  mutable std::mutex subskillsMutex;
325  std::vector<skills::SkillExecutionID> subskills;
326  };
327 
328  template <class T>
330 
331  } // namespace skills
332 } // 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:134
armarx::skills::Skill::exitSkill
ExitResult exitSkill()
Exit method of a skill.
Definition: Skill.cpp:285
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:303
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:121
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:356
armarx::skills::Skill::manager
manager::dti::SkillManagerInterfacePrx manager
Definition: Skill.h:291
armarx::skills::Skill::exiting
std::atomic_bool exiting
Definition: Skill.h:307
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:105
SkillStatusUpdate.h
armarx::skills::Skill::prepare
virtual PrepareResult prepare()
Override this method with the actual implementation.
Definition: Skill.cpp:443
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:297
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:429
armarx::skills::Skill::preparing
std::atomic_bool preparing
Definition: Skill.h:305
Frequency.h
armarx::skills::Skill::setExecutorName
void setExecutorName(const std::string &executorName)
Definition: Skill.cpp:485
armarx::skills::Skill::getSkillDescription
SkillDescription getSkillDescription() const
Get the description of a skill.
Definition: Skill.cpp:491
armarx::skills::Skill::running
std::atomic_bool running
Definition: Skill.h:306
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:265
armarx::skills::Skill::setCallback
void setCallback(const CallbackT &callback)
Definition: Skill.cpp:473
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:312
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:424
armarx::skills::Skill::init
virtual InitResult init()
Override this method with the actual implementation.
Definition: Skill.cpp:435
armarx::skills::Skill::stopped
std::atomic_bool stopped
Definition: Skill.h:311
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:338
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:370
armarx::skills::Skill::initSkill
InitResult initSkill()
Initialization of a skill.
Definition: Skill.cpp:257
armarx::skills::Skill::finished
std::atomic_bool finished
Definition: Skill.h:308
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::skills::Skill::parametersMutex
std::mutex parametersMutex
Definition: Skill.h:296
armarx::skills::Skill::description
SkillDescription description
Definition: Skill.h:300
armarx::skills::Skill::mainOfSkill
MainResult mainOfSkill()
Main method of a skill.
Definition: Skill.cpp:275
armarx::skills::Skill::started
armarx::core::time::DateTime started
Definition: Skill.h:284
armarx::skills::Skill::MakeAbortedResult
static MainResult MakeAbortedResult()
Definition: Skill.cpp:347
armarx::skills::Skill::MakeSucceededResult
static MainResult MakeSucceededResult(aron::data::DictPtr data=nullptr)
Definition: Skill.cpp:329
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:304
armarx::skills::Skill::setProviderId
void setProviderId(const skills::ProviderID &pid)
Set the provider id of the description of the skill.
Definition: Skill.cpp:467
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:292
armarx::skills::Skill::exit
virtual ExitResult exit()
Override this method with the actual implementation.
Definition: Skill.cpp:451
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
armarx::skills::Skill::callback
CallbackT callback
Definition: Skill.h:290
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:224
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:385
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:458
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:305
armarx::skills::Skill::prepareSkill
PrepareResult prepareSkill()
Prepare a skill once.
Definition: Skill.cpp:266
armarx::skills::Skill::setManager
void setManager(const manager::dti::SkillManagerInterfacePrx &manager)
Definition: Skill.cpp:479
armarx::skills::Skill::~Skill
virtual ~Skill()
Virtual destructor of a skill.
Definition: Skill.cpp:502
armarx::skills::SkillID
Definition: SkillID.h:14
armarx::skills::isSkill
concept isSkill
Definition: Skill.h:329
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:497
armarx::skills::Skill::exited
armarx::core::time::DateTime exited
Definition: Skill.h:285
armarx::skills::SkillStatus
SkillStatus
Definition: SkillStatusUpdate.h:15
SkillDescription.h