10 Logging::setTag(
"armarx::skills::" + description.skillId.toString());
15 Skill::installConditionWithCallback(std::function<
bool()>&& f, std::function<
void()>&& cb)
17 std::scoped_lock l(conditionCallbacksMutex);
18 conditionCallbacks.push_back({f, cb});
21 std::optional<TerminatedSkillStatusUpdate>
27 std::optional<TerminatedSkillStatusUpdate>
30 auto executionId = callSubskillAsync(proxy, parameters);
31 auto ret = proxy.
join(executionId);
37 throwIfSkillShouldTerminate();
51 std::string executorHistory = this->executorName +
"->" + getSkillId().
toString();
53 throwIfSkillShouldTerminate();
56 std::unique_lock l(subskillsMutex);
58 this->subskills.push_back(eid);
62 std::optional<TerminatedSkillStatusUpdate>
63 Skill::callSubskill(
const SkillID& skillId)
65 return callSubskill(
SkillProxy(manager, skillId));
68 std::optional<TerminatedSkillStatusUpdate>
71 return callSubskill(
SkillProxy(manager, skillId), parameters);
74 std::optional<TerminatedSkillStatusUpdate>
75 Skill::callSubskill(
const SkillID& skillId,
86 parametersFunction(parameters);
88 return callSubskill(proxy, parameters);
94 std::scoped_lock l(this->parametersMutex);
95 if (this->parameters ==
nullptr)
103 this->parameters->mergeAndReplaceCopy(d);
111 if (running or exiting or finished)
116 std::scoped_lock l(this->parametersMutex);
117 this->parameters = d;
121 Skill::getParameters()
const
123 return this->parameters;
130 this->initializing =
true;
131 this->constructing =
false;
132 this->preparing =
false;
133 this->running =
false;
134 this->exiting =
false;
135 this->finished =
false;
138 installConditionWithCallback(
142 [&]() { notifyTimeoutReached(); });
144 conditionCheckingThread = std::thread(
148 while (initializing or preparing or
152 std::scoped_lock l(conditionCallbacksMutex);
153 for (
auto& p : conditionCallbacks)
164 const auto sleepDuration = metronome.waitForNextTick();
165 if (not sleepDuration.isPositive())
168 <<
"ConditionCheckingThread: execution took too long ("
169 << -sleepDuration <<
" vs "
170 << conditionCheckingThreadFrequency.toCycleDuration()
175 return {.status = TerminatedSkillStatus::Succeeded};
181 this->preparing =
true;
182 this->initializing =
false;
183 this->constructing =
false;
184 this->running =
false;
185 this->exiting =
false;
188 if (shouldSkillTerminate())
190 return {.status = ActiveOrTerminatedSkillStatus::Aborted};
194 if (not description.parametersType)
196 return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
198 if (this->parameters && this->parameters->fullfillsType(description.parametersType))
201 return {.status = ActiveOrTerminatedSkillStatus::Succeeded};
211 this->running =
true;
212 this->initializing =
false;
213 this->constructing =
false;
214 this->preparing =
false;
215 this->exiting =
false;
217 return {.status = TerminatedSkillStatus::Succeeded};
224 this->exiting =
true;
225 this->running =
false;
226 this->initializing =
false;
227 this->constructing =
false;
228 this->preparing =
false;
231 if (conditionCheckingThread.joinable())
233 conditionCheckingThread.join();
238 this->exiting =
false;
239 return {.status = TerminatedSkillStatus::Succeeded};
245 std::scoped_lock l(parametersMutex);
246 auto _res = this->_init();
247 auto res = this->init();
252 Skill::prepareSkill()
254 std::scoped_lock l(parametersMutex);
255 auto _res = this->_prepare();
256 auto res = this->prepare();
263 std::scoped_lock l(parametersMutex);
264 auto _res = this->_main();
265 auto res = this->
main();
273 std::scoped_lock l(parametersMutex);
274 auto res = this->exit();
275 auto _res = this->_exit();
280 Skill::throwIfSkillShouldTerminate(
const std::function<
void()>& do_before,
281 const std::string& abortedMessage)
283 if (shouldSkillTerminate())
286 throwIfSkillShouldTerminate(abortedMessage);
291 Skill::throwIfSkillShouldTerminate(
const std::string& abortedMessage)
296 std::string(
"The skill '" + getSkillId().
toString() +
"' was asked to stop.");
297 message += abortedMessage.empty() ?
"" :
" Additional message: " + abortedMessage;
306 std::string(
"The skill '" + getSkillId().
toString() +
"' reached timeout.");
307 message += abortedMessage.empty() ?
"" :
" Additional message: " + abortedMessage;
318 .
status = TerminatedSkillStatus::Succeeded,
324 Skill::MakeFailedResult()
327 .
status = TerminatedSkillStatus::Failed,
333 Skill::MakeAbortedResult()
336 .
status = TerminatedSkillStatus::Aborted,
342 Skill::notifySkillToStop()
349 std::scoped_lock l(subskillsMutex);
356 Skill::notifyTimeoutReached()
358 if (stopped || timeoutReached)
364 std::scoped_lock l(subskillsMutex);
365 timeoutReached =
true;
371 Skill::shouldSkillTerminate()
const
373 return stopped || timeoutReached;
378 Skill::_onTimeoutReached()
387 for (
const auto& execId : subskills)
389 manager->abortSkillAsync(execId.toManagerIce());
394 Skill::_onStopRequested()
403 for (
const auto& execId : subskills)
405 manager->abortSkillAsync(execId.toManagerIce());
410 Skill::onTimeoutReached()
415 Skill::onStopRequested()
424 return {.
status = TerminatedSkillStatus::Succeeded};
432 return {.
status = ActiveOrTerminatedSkillStatus::Succeeded};
440 return {.
status = TerminatedSkillStatus::Succeeded};
448 <<
"'. Please overwrite this method.";
449 return {.status = TerminatedSkillStatus::Succeeded, .data =
nullptr};