diff --git a/source/RobotAPI/components/CMakeLists.txt b/source/RobotAPI/components/CMakeLists.txt index 587924113b9bc807ebe084a342ce210bc9e13e28..4a6fbed267afc454f8d65c305270ea7ba0105f05 100644 --- a/source/RobotAPI/components/CMakeLists.txt +++ b/source/RobotAPI/components/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(units) add_subdirectory(armem) +add_subdirectory(skills) add_subdirectory(ArViz) diff --git a/source/RobotAPI/components/armem/client/CMakeLists.txt b/source/RobotAPI/components/armem/client/CMakeLists.txt index 8a54ead2f9081f20f2319998835c98507798c282..258a28ea0b2f07d6a65c0a4b7b8085592aa98797 100644 --- a/source/RobotAPI/components/armem/client/CMakeLists.txt +++ b/source/RobotAPI/components/armem/client/CMakeLists.txt @@ -3,5 +3,3 @@ add_subdirectory(ExampleMemoryClient) add_subdirectory(GraspProviderExample) add_subdirectory(VirtualRobotReaderExampleClient) - -add_subdirectory(SkillProviderExample) diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp index a11304d70db709c3bf641c414d8f78216d5e0ef5..3fbb33eaccbcd2962e44d65c124e124fc6bae846 100644 --- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp +++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.cpp @@ -96,13 +96,14 @@ namespace armarx } - armem::data::CommitResult SkillsMemory::commit(const armem::data::Commit& commit, const Ice::Current&) + armem::data::CommitResult SkillsMemory::commit(const armem::data::Commit& commit, const Ice::Current& current) { // This function is overloaded to check for skill executions // First pass arg to parent func to ensure that data is written into memory and that clients are notified armem::data::CommitResult result = ReadWritePluginUser::commit(commit); - auto myPrx = getProxy<skills::SkillManagerInterfacePrx>(getName()); + skills::callback::dti::SkillProviderCallbackInterfacePrx myPrx; + getProxy(myPrx, -1); for (const auto& up : commit.updates) { @@ -112,15 +113,8 @@ namespace armarx { ARMARX_CHECK_NOT_NULL(instance); - auto dict = std::make_shared<aron::data::Dict>(instance); - - // we got a skill execution request - skills::arondto::SkillExecutionRequest request; - request.fromAron(dict); - - auto params = aron::data::Dict::DynamicCastAndCheck(dict->at("params")); // ToDo remov and add to request - - executableSkillCoreSegment.directlyExecuteSkill(request, myPrx, params); + skills::manager::dto::SkillExecutionInfo exInfo = skillExecutionRequestCoreSegment.convertCommit(instance); + SkillManagerComponentPluginUser::executeSkill(exInfo, current); } } } @@ -128,95 +122,31 @@ namespace armarx return result; } - void SkillsMemory::addProvider(const std::string& skillProviderName, const skills::SkillProviderInterfacePrx& provider, const Ice::Current ¤t) + void SkillsMemory::addProvider(const skills::manager::dto::ProviderInfo& info, const Ice::Current ¤t) { - SkillManagerComponentPluginUser::addProvider(skillProviderName, provider, current); + SkillManagerComponentPluginUser::addProvider(info, current); - executableSkillCoreSegment.addSkillProvider(skillProviderName, provider); + // log skills to memory + executableSkillCoreSegment.addSkillProvider(info); } void SkillsMemory::removeProvider(const std::string& skillProviderName, const Ice::Current ¤t) { executableSkillCoreSegment.removeSkillProvider(skillProviderName); + // remove skills from memory SkillManagerComponentPluginUser::removeProvider(skillProviderName, current); } - void SkillsMemory::executeSkill(const std::string& skillProviderName, const skills::SkillParametrization& params, const Ice::Current ¤t) + void SkillsMemory::executeSkill(const skills::manager::dto::SkillExecutionInfo& info, const Ice::Current ¤t) { - // override directly execution to add a request to the memory - armem::Commit comm; - auto& entityUpdate = comm.add(); - - skills::arondto::SkillExecutionRequest request; - request.clientId = ""; - request.providerName = skillProviderName; - request.skillName = params.skillName; - - auto aron = request.toAron(); - - aron::data::DictPtr aron_params = nullptr; - if (params.params) aron_params = std::make_shared<aron::data::Dict>(params.params); - - aron->addElement("params", aron_params); // todo add as any type - - armem::MemoryID skillExecutionMemID = skillExecutionRequestCoreSegment.getCoreSegment().id(); - skillExecutionMemID.providerSegmentName = request.providerName; - skillExecutionMemID.entityName = request.skillName; - - entityUpdate.entityID = skillExecutionMemID; - entityUpdate.instancesData = { aron }; - entityUpdate.confidence = 1.0; - entityUpdate.timeCreated = armem::Time::now(); - - armem::data::Commit iceCommit; - armarx::armem::toIce(iceCommit, comm); - commit(iceCommit, current); // commit and notify + skillExecutionRequestCoreSegment.addSkillExecutionRequest(info); + SkillManagerComponentPluginUser::executeSkill(info, current); } - void SkillsMemory::updateStatusForSkill(const std::string& providerName, const skills::SkillStatus& statusUpdate, const Ice::Current ¤t) + void SkillsMemory::updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update, const Ice::Current ¤t) { - // add update for skill to memory - static std::map<armarx::skills::Execution::Status, std::string> ExecutionStatus2String = { - {armarx::skills::Execution::Status::Idle, "Idle"}, - {armarx::skills::Execution::Status::Scheduled, "Scheduled"}, - {armarx::skills::Execution::Status::Running, "Running"}, - {armarx::skills::Execution::Status::RunningButWaitingForDependencies, "RunningButWaitingForDependencies"}, - {armarx::skills::Execution::Status::Aborted, "Aborted"}, - {armarx::skills::Execution::Status::Failed, "Failed"}, - {armarx::skills::Execution::Status::Succeeded, "Succeeded"} - }; - - // create commit about new update - armarx::skills::arondto::SkillExecutionEvent event; - event.providerName = providerName; - event.skillName = statusUpdate.usedParameterization.skillName; - event.status = ExecutionStatus2String.at(statusUpdate.status); - - aron::data::DictPtr aron_params = nullptr; - if (statusUpdate.usedParameterization.params) aron_params = std::make_shared<aron::data::Dict>(statusUpdate.usedParameterization.params); - - aron::data::DictPtr aron_result = nullptr; - if (statusUpdate.returnValue) aron_result = std::make_shared<aron::data::Dict>(statusUpdate.returnValue); - - armem::MemoryID commitId = skillEventCoreSegment.getCoreSegment().id(); - commitId.providerSegmentName = event.providerName; - commitId.entityName = event.skillName; - - auto aron = event.toAron(); - aron->addElement("result", aron_result); - aron->addElement("params", aron_params); - - armem::Commit comm; - auto& entityUpdate = comm.add(); - entityUpdate.confidence = 1.0; - entityUpdate.timeCreated = armem::Time::now(); - entityUpdate.instancesData = { aron }; - entityUpdate.entityID = commitId; - - armem::data::Commit iceCommit; - armarx::armem::toIce(iceCommit, comm); - commit(iceCommit, current); // commit and notify + skillEventCoreSegment.addSkillUpdateEvent(update); } diff --git a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h index 42e19e753092c9cd01b776a754b509d74ca8c7b2..d609be37f133c2bd6e5603069f884abab33dd555 100644 --- a/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h +++ b/source/RobotAPI/components/armem/server/SkillsMemory/SkillsMemory.h @@ -31,7 +31,7 @@ #include <RobotAPI/interface/skills/SkillMemoryInterface.h> -#include <RobotAPI/libraries/armem_skills/server/SkillManagerComponentPlugin.h> +#include <RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h> #include <RobotAPI/libraries/armem_skills/server/StatechartListenerComponentPlugin.h> #include <RobotAPI/libraries/armem/server/plugins/ReadWritePluginUser.h> @@ -56,7 +56,8 @@ namespace armarx */ class SkillsMemory : virtual public armarx::Component, - virtual public skills::SkillMemoryInterface, + virtual public skills::dti::SkillMemoryInterface, + virtual public armem::server::ReadWritePluginUser, virtual public StatechartListenerComponentPluginUser, virtual public SkillManagerComponentPluginUser @@ -73,10 +74,10 @@ namespace armarx void reportStatechartTransitionWithParametersList(const ProfilerStatechartTransitionWithParametersList&, const Ice::Current&) override; // Override SkillManager to add memory functions - void addProvider(const std::string&, const skills::SkillProviderInterfacePrx& provider, const Ice::Current ¤t) override; + void addProvider(const skills::manager::dto::ProviderInfo& info, const Ice::Current ¤t) override; void removeProvider(const std::string&, const Ice::Current ¤t) override; - void executeSkill(const std::string&, const skills::SkillParametrization& params, const Ice::Current ¤t) override; - void updateStatusForSkill(const std::string& providerName, const skills::SkillStatus& statusUpdate, const Ice::Current ¤t) override; + void executeSkill(const skills::manager::dto::SkillExecutionInfo& info, const Ice::Current ¤t) override; + void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& statusUpdate, const Ice::Current ¤t) override; // WritingInterface interface armem::data::CommitResult commit(const armem::data::Commit& commit, const Ice::Current&) override; diff --git a/source/RobotAPI/components/skills/CMakeLists.txt b/source/RobotAPI/components/skills/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5150c5aa2d5d6fe45ed126a1f14a785d05cb4d2c --- /dev/null +++ b/source/RobotAPI/components/skills/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(SkillProviderExample) diff --git a/source/RobotAPI/components/armem/client/SkillProviderExample/CMakeLists.txt b/source/RobotAPI/components/skills/SkillProviderExample/CMakeLists.txt similarity index 90% rename from source/RobotAPI/components/armem/client/SkillProviderExample/CMakeLists.txt rename to source/RobotAPI/components/skills/SkillProviderExample/CMakeLists.txt index 012e47bbd040601bf2eccb77b9bb09a53b2ee9da..f3215ba1d02972ba2ce76353b681017601f71881 100644 --- a/source/RobotAPI/components/armem/client/SkillProviderExample/CMakeLists.txt +++ b/source/RobotAPI/components/skills/SkillProviderExample/CMakeLists.txt @@ -6,8 +6,8 @@ set(COMPONENT_LIBS ArmarXGuiComponentPlugins RobotAPICore RobotAPIInterfaces + RobotAPI::skills aron - armem_skills aronjsonconverter ) @@ -22,4 +22,4 @@ set(HEADERS armarx_add_component("${SOURCES}" "${HEADERS}") #generate the application -armarx_generate_and_add_component_executable(COMPONENT_NAMESPACE "armarx::skills::example") +armarx_generate_and_add_component_executable(COMPONENT_NAMESPACE "armarx::skills::provider") diff --git a/source/RobotAPI/components/armem/client/SkillProviderExample/SkillProviderExample.cpp b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp similarity index 63% rename from source/RobotAPI/components/armem/client/SkillProviderExample/SkillProviderExample.cpp rename to source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp index c22bf43ed4eefe3f949a315d9504b39dca3b70a2..804b8d68002b2c43b8423015f466900e5ccb29eb 100644 --- a/source/RobotAPI/components/armem/client/SkillProviderExample/SkillProviderExample.cpp +++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.cpp @@ -6,18 +6,32 @@ #include <RobotAPI/libraries/aron/core/type/variant/primitive/String.h> #include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h> -namespace armarx::skills::example +namespace armarx::skills::provider { - SkillImplementation::Status HelloWorldSkill::execute(const aron::data::DictPtr& d, const CallbackT&) + Skill::Status HelloWorldSkill::execute(const aron::data::DictPtr& d, const CallbackT&) { ARMARX_IMPORTANT << "Hi, from the Hello World Skill.\n" << "I received the following data: \n" << aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(d).dump(2) << "\n" << "(executed at: " << IceUtil::Time::now() << ")"; - return SkillImplementation::Status::Succeeded; + return Skill::Status::Succeeded; } - SkillImplementation::Status CallbackSkill::execute(const aron::data::DictPtr& d, const CallbackT& callback) + Skill::Status TimeoutSkill::execute(const aron::data::DictPtr& d, const CallbackT&) + { + int i = 0; + while (!timeoutReached) + { + // do heavy work + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + // check if work is done + if(i++ > 15) return Skill::Status::Succeeded; + } + return Skill::Status::TimeoutReached; + } + + Skill::Status CallbackSkill::execute(const aron::data::DictPtr& d, const CallbackT& callback) { ARMARX_IMPORTANT << "Logging three updates via the callback"; auto up1 = std::make_shared<aron::data::Dict>(); @@ -32,7 +46,7 @@ namespace armarx::skills::example up3->addElement("updateInfo", std::make_shared<aron::data::String>("Update 3")); callback(up3); - return SkillImplementation::Status::Succeeded; + return Skill::Status::Succeeded; } @@ -59,10 +73,13 @@ namespace armarx::skills::example auto helloWorldAcceptedTypeText = std::make_shared<aron::type::String>(aron::Path({"text"})); helloWorldAcceptedType->addMemberType("text", helloWorldAcceptedTypeText); + auto helloWorldAcceptedTypeInt = std::make_shared<aron::type::Int>(aron::Path({"int"})); + helloWorldAcceptedType->addMemberType("int", helloWorldAcceptedTypeInt); + skills::SkillDescription helloWorldDesc; - helloWorldDesc.documentation = "This skill logs a message on ARMARX_IMPORTANT"; - helloWorldDesc.name = "HelloWorld"; - helloWorldDesc.acceptedType = helloWorldAcceptedType->toObjectDTO(); + helloWorldDesc.description = "This skill logs a message on ARMARX_IMPORTANT"; + helloWorldDesc.skillName = "HelloWorld"; + helloWorldDesc.acceptedType = helloWorldAcceptedType; helloWorldDesc.timeoutMs = 1000; addSkill(std::make_shared<HelloWorldSkill>(), helloWorldDesc); } @@ -71,8 +88,9 @@ namespace armarx::skills::example { skills::SkillDescription fooDesc; fooDesc.acceptedType = nullptr; // accept everything - fooDesc.documentation = "This skill does exactly nothing."; - fooDesc.name = "Foo"; + fooDesc.description = "This skill does exactly nothing."; + fooDesc.skillName = "Foo"; + fooDesc.timeoutMs = 1000; addSkill([](const aron::data::DictPtr&){ std::cout << "Hello from Foo" << std::endl; return true; }, fooDesc); } @@ -80,10 +98,21 @@ namespace armarx::skills::example { skills::SkillDescription cbDesc; cbDesc.acceptedType = nullptr; // accept everything - cbDesc.documentation = "This skill does shows callbacks."; - cbDesc.name = "ShowMeCallbacks"; + cbDesc.description = "This skill does shows callbacks."; + cbDesc.skillName = "ShowMeCallbacks"; + cbDesc.timeoutMs = 1000; addSkill(std::make_shared<CallbackSkill>(), cbDesc); } + + // Add timeout skill + { + skills::SkillDescription tDesc; + tDesc.acceptedType = nullptr; // accept everything + tDesc.description = "This fails with timeout reached."; + tDesc.skillName = "Timeout"; + tDesc.timeoutMs = 1000; + addSkill(std::make_shared<TimeoutSkill>(), tDesc); + } } void SkillProviderExample::onConnectComponent() diff --git a/source/RobotAPI/components/armem/client/SkillProviderExample/SkillProviderExample.h b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h similarity index 84% rename from source/RobotAPI/components/armem/client/SkillProviderExample/SkillProviderExample.h rename to source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h index a6a9374a907d0e66cd403efe56c5924ad57c5262..42ad812f103cd230e0d6bd73c4a1c65a1dded774 100644 --- a/source/RobotAPI/components/armem/client/SkillProviderExample/SkillProviderExample.h +++ b/source/RobotAPI/components/skills/SkillProviderExample/SkillProviderExample.h @@ -27,22 +27,29 @@ #include <ArmarXCore/core/Component.h> // RobotAPI -#include <RobotAPI/libraries/armem_skills/client/SkillProviderComponentPlugin.h> +#include <RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h> -namespace armarx::skills::example +namespace armarx::skills::provider { // Skills: - class HelloWorldSkill : public SkillImplementation + class HelloWorldSkill : public Skill { public: - Status execute(const aron::data::DictPtr&, const CallbackT&) override; + Status execute(const aron::data::DictPtr&, const CallbackT&) final; }; - class CallbackSkill : public SkillImplementation + class TimeoutSkill : public Skill { public: - Status execute(const aron::data::DictPtr&, const CallbackT&) override; + Status execute(const aron::data::DictPtr&, const CallbackT&) final; + }; + + + class CallbackSkill : public Skill + { + public: + Status execute(const aron::data::DictPtr&, const CallbackT&) final; }; /** diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetEditor.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetEditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0df59db31a93124f7ec5b776fe7e876afe2fb414 --- /dev/null +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetEditor.cpp @@ -0,0 +1,349 @@ +/* + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * \package RobotAPI::gui-plugins::SkillManagerMonitorWidgetController + * \author Raphael Grimm ( raphael dot grimm at kit dot edu ) + * \date 2020 + * \copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include <string> + +#include <ArmarXCore/util/CPPUtility/Iterator.h> + +#include "AronTreeWidgetEditor.h" + +// debug +#include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h> + +//visitors +namespace armarx +{ + + void + AronTreeViewWidgetCreatorVisitor::createSimpleTreeViewWidget(Input& i) + { + ARMARX_CHECK_NOT_NULL(i); + ARMARX_CHECK_NOT_NULL(parentItem); + + auto key = i->getPath().getLastElement(); + createdQWidgetItem = new QTreeWidgetItem(parentItem); + createdQWidgetItem->setText(0, QString::fromStdString(key)); + createdQWidgetItem->setText(2, QString::fromStdString(i->getShortName())); + createdQWidgetItem->setText(3, QString::fromStdString(i->getDefaultFromString())); + createdQWidgetItem->setFlags(createdQWidgetItem->flags() | Qt::ItemIsEditable); + } + + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::ObjectPtr& i) + { + ARMARX_CHECK_NOT_NULL(i); + ARMARX_CHECK_NOT_NULL(parentItem); + + auto key = i->getObjectName(); + if (i->getPath().hasElement()) + { + key = i->getPath().getLastElement(); + } + + createdQWidgetItem = new QTreeWidgetItem(parentItem); + createdQWidgetItem->setText(0, QString::fromStdString(key)); + + for (const auto& [key, value] : i->getMemberTypes()) + { + AronTreeViewWidgetCreatorVisitor v(createdQWidgetItem); + aron::type::visit(v, value); + + if (v.createdQWidgetItem) + { + createdQWidgetItem->addChild(v.createdQWidgetItem); + } + } + } + + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::DictPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::PairPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::TuplePtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::ListPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::NDArrayPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::MatrixPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::QuaternionPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::PositionPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::OrientationPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::PosePtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::ImagePtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::PointCloudPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::IntEnumPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::IntPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::LongPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::FloatPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::DoublePtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::BoolPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::StringPtr& i) + { createSimpleTreeViewWidget(i); } + void + AronTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::TimePtr& i) + { createSimpleTreeViewWidget(i); } + + void AronTreeViewWidgetCreatorVisitor::visitUnknown(Input&) + { + ARMARX_WARNING_S << "Received an unknown type when trying to create a tree view widget for a skill argument type."; + } + + + + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::ObjectPtr& i) + { + auto createdAronDict = std::make_shared<aron::data::Dict>(); + createdAron = createdAronDict; + QTreeWidgetItem* el = parentItem->child(index); + + unsigned int x = 0; + for (const auto& [key, value] : i->getMemberTypes()) + { + AronTreeViewWidgetConverterVisitor v(el, x++); + aron::type::visit(v, value); + + if (v.createdAron) + { + createdAronDict->addElement(key, v.createdAron); + } + } + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::DictPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::PairPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::TuplePtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::ListPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::NDArrayPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::MatrixPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::QuaternionPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::PositionPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::OrientationPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::PosePtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::ImagePtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::PointCloudPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::IntEnumPtr& i) + { + // TODO + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::IntPtr& i) + { + auto createdAronInt = std::make_shared<aron::data::Int>(); + createdAron = createdAronInt; + QTreeWidgetItem* el = parentItem->child(index); + + std::string str = el->text(1).toStdString(); + if (str.empty()) + { + createdAronInt->setValue(0); + return; + } + + int val = std::stoi(str); + createdAronInt->setValue(val); + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::LongPtr& i) + { + auto createdAronLong = std::make_shared<aron::data::Long>(); + createdAron = createdAronLong; + QTreeWidgetItem* el = parentItem->child(index); + + std::string str = el->text(1).toStdString(); + if (str.empty()) + { + str = el->text(3).toStdString(); + } + + createdAronLong->fromString(str); + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::FloatPtr& i) + { + auto createdAronFloat = std::make_shared<aron::data::Float>(); + createdAron = createdAronFloat; + QTreeWidgetItem* el = parentItem->child(index); + + std::string str = el->text(1).toStdString(); + if (str.empty()) + { + str = el->text(3).toStdString(); + } + + createdAronFloat->fromString(str); + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::DoublePtr& i) + { + auto createdAronDouble = std::make_shared<aron::data::Double>(); + createdAron = createdAronDouble; + QTreeWidgetItem* el = parentItem->child(index); + + std::string str = el->text(1).toStdString(); + if (str.empty()) + { + str = el->text(3).toStdString(); + } + + createdAronDouble->fromString(str); + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::BoolPtr& i) + { + auto createdAronBool = std::make_shared<aron::data::Bool>(); + createdAron = createdAronBool; + QTreeWidgetItem* el = parentItem->child(index); + + std::string str = el->text(1).toStdString(); + if (str.empty()) + { + str = el->text(3).toStdString(); + } + + createdAronBool->fromString(str); + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::StringPtr& i) + { + auto createdAronString = std::make_shared<aron::data::String>(); + createdAron = createdAronString; + QTreeWidgetItem* el = parentItem->child(index); + + std::string str = el->text(1).toStdString(); + createdAronString->fromString(str); + } + + void + AronTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::TimePtr& i) + { + auto l = std::make_shared<aron::type::Long>(); + visitLong(l); + } + + void AronTreeViewWidgetConverterVisitor::visitUnknown(Input&) + { + ARMARX_WARNING_S << "Received an unknown type when trying to convert a skill argument type to an aron data object."; + } +} + diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetEditor.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetEditor.h new file mode 100644 index 0000000000000000000000000000000000000000..3d391783077458df2e9257d40e188cd81bf36188 --- /dev/null +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetEditor.h @@ -0,0 +1,121 @@ +/* + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @package RobotAPI::gui-plugins::SkillManagerMonitorWidgetController + * @author Raphael Grimm ( raphael dot grimm at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ +#pragma once + +#include <stack> +#include <ArmarXCore/core/system/ImportExportComponent.h> + +#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h> +#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h> +#include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h> + +#include <RobotAPI/interface/skills/SkillMemoryInterface.h> + +#include <RobotAPI/gui-plugins/SkillManagerPlugin/ui_SkillManagerMonitorWidget.h> + + +#include <RobotAPI/libraries/aron/core/type/variant/All.h> +#include <RobotAPI/libraries/aron/core/data/variant/All.h> +#include <RobotAPI/libraries/aron/core/type/visitor/variant/VariantVisitor.h> + +namespace armarx +{ + // Convert aron type to tree widget + class AronTreeViewWidgetCreatorVisitor : + public armarx::aron::type::ConstVariantVisitor + { + public: + QTreeWidgetItem* parentItem; + QTreeWidgetItem* createdQWidgetItem; + + AronTreeViewWidgetCreatorVisitor() = delete; + AronTreeViewWidgetCreatorVisitor(QTreeWidgetItem* i) : + parentItem(i) + {} + + void createSimpleTreeViewWidget(Input& i); + + void visitAronVariant(const aron::type::ObjectPtr&) override; + void visitAronVariant(const aron::type::DictPtr& i) override; + void visitAronVariant(const aron::type::PairPtr& i) override; + void visitAronVariant(const aron::type::TuplePtr& i) override; + void visitAronVariant(const aron::type::ListPtr& i) override; + void visitAronVariant(const aron::type::NDArrayPtr& i) override; + void visitAronVariant(const aron::type::MatrixPtr& i) override; + void visitAronVariant(const aron::type::QuaternionPtr& i) override; + void visitAronVariant(const aron::type::PositionPtr& i) override; + void visitAronVariant(const aron::type::OrientationPtr& i) override; + void visitAronVariant(const aron::type::PosePtr& i) override; + void visitAronVariant(const aron::type::ImagePtr& i) override; + void visitAronVariant(const aron::type::PointCloudPtr& i) override; + void visitAronVariant(const aron::type::IntEnumPtr& i) override; + void visitAronVariant(const aron::type::IntPtr& i) override; + void visitAronVariant(const aron::type::LongPtr& i) override; + void visitAronVariant(const aron::type::FloatPtr& i) override; + void visitAronVariant(const aron::type::DoublePtr& i) override; + void visitAronVariant(const aron::type::BoolPtr& i) override; + void visitAronVariant(const aron::type::StringPtr& i) override; + void visitAronVariant(const aron::type::TimePtr& i) override; + void visitUnknown(Input&) override; + }; + + + // Conversion from TreeView to aron data + class AronTreeViewWidgetConverterVisitor : + public armarx::aron::type::ConstVariantVisitor + { + public: + QTreeWidgetItem* parentItem; + int index; + aron::data::VariantPtr createdAron; + + AronTreeViewWidgetConverterVisitor() = delete; + AronTreeViewWidgetConverterVisitor(QTreeWidgetItem* i, int x) : + parentItem(i), index(x) + {} + + void visitAronVariant(const aron::type::ObjectPtr&) override; + void visitAronVariant(const aron::type::DictPtr&) override; + void visitAronVariant(const aron::type::PairPtr&) override; + void visitAronVariant(const aron::type::TuplePtr&) override; + void visitAronVariant(const aron::type::ListPtr&) override; + void visitAronVariant(const aron::type::NDArrayPtr&) override; + void visitAronVariant(const aron::type::MatrixPtr&) override; + void visitAronVariant(const aron::type::QuaternionPtr&) override; + void visitAronVariant(const aron::type::PositionPtr&) override; + void visitAronVariant(const aron::type::OrientationPtr&) override; + void visitAronVariant(const aron::type::PosePtr&) override; + void visitAronVariant(const aron::type::ImagePtr&) override; + void visitAronVariant(const aron::type::PointCloudPtr&) override; + void visitAronVariant(const aron::type::IntEnumPtr&) override; + void visitAronVariant(const aron::type::IntPtr&) override; + void visitAronVariant(const aron::type::LongPtr&) override; + void visitAronVariant(const aron::type::FloatPtr&) override; + void visitAronVariant(const aron::type::DoublePtr&) override; + void visitAronVariant(const aron::type::BoolPtr&) override; + void visitAronVariant(const aron::type::StringPtr&) override; + void visitAronVariant(const aron::type::TimePtr&) override; + void visitUnknown(Input&) override; + }; +} + + diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModal.ui b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModal.ui new file mode 100644 index 0000000000000000000000000000000000000000..baec62815f1b8b7f2c6b46b7e2f3847130a9509e --- /dev/null +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModal.ui @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AronTreeWidgetInputModalWidget</class> + <widget class="QWidget" name="AronTreeWidgetInputModalWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1015</width> + <height>498</height> + </rect> + </property> + <property name="windowTitle"> + <string>SkillManagerMonitorWidget</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QGroupBox" name="groupBoxInput"> + <property name="title"> + <string>InputField</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <widget class="QPushButton" name="pushButtonReset"> + <property name="text"> + <string>Reset</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="pushButtonSubmit"> + <property name="text"> + <string>Submit</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QTextEdit" name="textEditInput"/> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModalController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModalController.cpp new file mode 100644 index 0000000000000000000000000000000000000000..25ec39a7056226f53ae8882e60877f1c512d551c --- /dev/null +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModalController.cpp @@ -0,0 +1,38 @@ +#include "AronTreeWidgetInputModalController.h" + +namespace armarx +{ + AronTreeWidgetInputModalController::AronTreeWidgetInputModalController(const std::string& name, const std::string& placeholder, QWidget * parent) : + QDialog(parent), + placeholder(placeholder) + { + widget.setupUi(this); + + // set header + widget.groupBoxInput->setTitle(QString::fromStdString(name)); + widget.textEditInput->setPlainText(QString::fromStdString(placeholder)); + + // connect signals + connect(widget.pushButtonReset, &QPushButton::clicked, + this, &AronTreeWidgetInputModalController::reset); + connect(widget.pushButtonSubmit, &QPushButton::clicked, + this, &AronTreeWidgetInputModalController::submit); + } + + QString AronTreeWidgetInputModalController::getInput() const + { + return widget.textEditInput->toPlainText(); + } + + + void AronTreeWidgetInputModalController::reset() + { + // reset to initial value + widget.textEditInput->setPlainText(QString::fromStdString(placeholder)); + } + + void AronTreeWidgetInputModalController::submit() + { + accept(); + } +} diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModalController.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModalController.h new file mode 100644 index 0000000000000000000000000000000000000000..1f4a0d0f93f4cc1cece3468070dd1e3721633473 --- /dev/null +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/AronTreeWidgetInputModalController.h @@ -0,0 +1,34 @@ +#pragma once + +#include <stack> +#include <ArmarXCore/core/system/ImportExportComponent.h> + +#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXGuiPlugin.h> +#include <ArmarXGui/libraries/ArmarXGuiBase/ArmarXComponentWidgetController.h> +#include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h> + +#include <RobotAPI/gui-plugins/SkillManagerPlugin/ui_AronTreeWidgetInputModal.h> + +#include <QDialog> + +namespace armarx +{ + class ARMARXCOMPONENT_IMPORT_EXPORT + AronTreeWidgetInputModalController : + public QDialog + { + Q_OBJECT + public: + AronTreeWidgetInputModalController(const std::string& label, const std::string& placeholder = "", QWidget * parent = 0); + + QString getInput() const; + + private slots: + void reset(); + void submit(); + + private: + std::string placeholder; + Ui::AronTreeWidgetInputModalWidget widget; + }; +} diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt b/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt index 445d668cface0e4ab1ceefddfe1fedfea59b5635..b23252198252a9799bc69de20581a675057cf26e 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt @@ -4,12 +4,22 @@ armarx_set_target("${LIB_NAME}") armarx_build_if(ArmarXGui_FOUND "ArmarXGui not available") # do not rename this variable, it is used in armarx_gui_library()... -set(SOURCES SkillManagerMonitorWidgetController.cpp) -set(HEADERS SkillManagerMonitorWidgetController.h) -set(GUI_UIS SkillManagerMonitorWidget.ui) +set(SOURCES + AronTreeWidgetEditor.cpp + AronTreeWidgetInputModalController.cpp + SkillManagerMonitorWidgetController.cpp +) + +set(HEADERS + AronTreeWidgetEditor.h + AronTreeWidgetInputModalController.h + SkillManagerMonitorWidgetController.h +) + +set(GUI_UIS SkillManagerMonitorWidget.ui AronTreeWidgetInputModal.ui) # Add more libraries you depend on here, e.g. ${QT_LIBRARIES}. -set(COMPONENT_LIBS RobotAPIInterfaces aron aronjsonconverter SimpleConfigDialog) +set(COMPONENT_LIBS RobotAPIInterfaces aron skills aronjsonconverter SimpleConfigDialog) if(ArmarXGui_FOUND) armarx_gui_plugin("${LIB_NAME}" "${SOURCES}" "" "${GUI_UIS}" "" "${COMPONENT_LIBS}") diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui index 258061d25801519558f84ee3abb36c26b9f86ffc..927d6daf0431c4988ab05bb62171910aac25dbe8 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidget.ui @@ -88,21 +88,13 @@ <string>Type</string> </property> </column> + <column> + <property name="text"> + <string>defaultValue</string> + </property> + </column> </widget> </item> - <item row="6" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> </layout> </widget> </widget> diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp index 2405e456112e1db15936f85aa35bba7ae2254d01..212869ba6eec58b2c10643eb00daba8ae2f4be54 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.cpp @@ -26,6 +26,9 @@ #include "SkillManagerMonitorWidgetController.h" +#include "AronTreeWidgetEditor.h" +#include "AronTreeWidgetInputModalController.h" + // debug #include <RobotAPI/libraries/aron/converter/json/NLohmannJSONConverter.h> @@ -37,7 +40,7 @@ namespace armarx if (!dialog) { dialog = new SimpleConfigDialog(parent); - dialog->addProxyFinder<skills::SkillManagerInterfacePrx>("SkillManager", "", "Skill*"); + dialog->addProxyFinder<skills::manager::dti::SkillManagerInterfacePrx>("SkillManager", "", "Skill*"); } return qobject_cast<SimpleConfigDialog*>(dialog); } @@ -55,337 +58,7 @@ namespace armarx } } -//visitors -namespace armarx -{ - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::createSimpleTreeViewWidget(Input& i) - { - ARMARX_CHECK_NOT_NULL(i); - ARMARX_CHECK_NOT_NULL(parentItem); - - auto key = i->getPath().getLastElement(); - createdQWidgetItem = new QTreeWidgetItem(parentItem); - createdQWidgetItem->setText(0, QString::fromStdString(key)); - createdQWidgetItem->setText(2, QString::fromStdString(i->getShortName())); - createdQWidgetItem->setFlags(createdQWidgetItem->flags() | Qt::ItemIsEditable); - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::ObjectPtr& i) - { - ARMARX_CHECK_NOT_NULL(i); - ARMARX_CHECK_NOT_NULL(parentItem); - - auto key = i->getObjectName(); - if (i->getPath().hasElement()) - { - key = i->getPath().getLastElement(); - } - - createdQWidgetItem = new QTreeWidgetItem(parentItem); - createdQWidgetItem->setText(0, QString::fromStdString(key)); - - for (const auto& [key, value] : i->getMemberTypes()) - { - SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor v(createdQWidgetItem); - aron::type::visit(v, value); - - if (v.createdQWidgetItem) - { - createdQWidgetItem->addChild(v.createdQWidgetItem); - } - } - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::DictPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::PairPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::TuplePtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::ListPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::NDArrayPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::MatrixPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::QuaternionPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::PositionPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::OrientationPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::PosePtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::ImagePtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::PointCloudPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::IntEnumPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::IntPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::LongPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::FloatPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::DoublePtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::BoolPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::StringPtr& i) - { createSimpleTreeViewWidget(i); } - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitAronVariant(const aron::type::TimePtr& i) - { createSimpleTreeViewWidget(i); } - - void SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor::visitUnknown(Input&) - { - ARMARX_WARNING_S << "Received an unknown type when trying to create a tree view widget for a skill argument type."; - } - - - - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::ObjectPtr& i) - { - auto createdAronDict = std::make_shared<aron::data::Dict>(); - createdAron = createdAronDict; - QTreeWidgetItem* el = parentItem->child(index); - - unsigned int x = 0; - for (const auto& [key, value] : i->getMemberTypes()) - { - SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor v(el, x++); - aron::type::visit(v, value); - - if (v.createdAron) - { - createdAronDict->addElement(key, v.createdAron); - } - } - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::DictPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::PairPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::TuplePtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::ListPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::NDArrayPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::MatrixPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::QuaternionPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::PositionPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::OrientationPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::PosePtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::ImagePtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::PointCloudPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::IntEnumPtr& i) - { - // TODO - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::IntPtr& i) - { - auto createdAronInt = std::make_shared<aron::data::Int>(); - createdAron = createdAronInt; - QTreeWidgetItem* el = parentItem->child(index); - - std::string str = el->text(1).toStdString(); - if (str.empty()) - { - createdAronInt->setValue(0); - return; - } - - int val = std::stoi(str); - createdAronInt->setValue(val); - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::LongPtr& i) - { - auto createdAronLong = std::make_shared<aron::data::Long>(); - createdAron = createdAronLong; - QTreeWidgetItem* el = parentItem->child(index); - - std::string str = el->text(1).toStdString(); - if (str.empty()) - { - createdAronLong->setValue(0); - return; - } - - long val = std::stol(str); - createdAronLong->setValue(val); - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::FloatPtr& i) - { - auto createdAronFloat = std::make_shared<aron::data::Float>(); - createdAron = createdAronFloat; - QTreeWidgetItem* el = parentItem->child(index); - - std::string str = el->text(1).toStdString(); - if (str.empty()) - { - createdAronFloat->setValue(0.0); - return; - } - - float val = std::stof(str); - createdAronFloat->setValue(val); - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::DoublePtr& i) - { - auto createdAronDouble = std::make_shared<aron::data::Double>(); - createdAron = createdAronDouble; - QTreeWidgetItem* el = parentItem->child(index); - - std::string str = el->text(1).toStdString(); - if (str.empty()) - { - createdAronDouble->setValue(0.0); - return; - } - - float val = std::stod(str); - createdAronDouble->setValue(val); - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::BoolPtr& i) - { - auto createdAronBool = std::make_shared<aron::data::Bool>(); - createdAron = createdAronBool; - QTreeWidgetItem* el = parentItem->child(index); - - std::string str = el->text(1).toStdString(); - if (str.empty() || str == "false" || str == "no") - { - createdAronBool->setValue(false); - return; - } - - if (str == "true" || str == "yes") - { - createdAronBool->setValue(true); - return; - } - - bool val = std::stoi(str); - createdAronBool->setValue(val); - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::StringPtr& i) - { - auto createdAronString = std::make_shared<aron::data::String>(); - createdAron = createdAronString; - QTreeWidgetItem* el = parentItem->child(index); - - std::string str = el->text(1).toStdString(); - createdAronString->setValue(str); - } - - void - SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitAronVariant(const aron::type::TimePtr& i) - { - auto l = std::make_shared<aron::type::Long>(); - visitLong(l); - } - - void SkillManagerMonitorWidgetController::SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor::visitUnknown(Input&) - { - ARMARX_WARNING_S << "Received an unknown type when trying to convert a skill argument type to an aron data object."; - } -} - +// Others namespace armarx { SkillManagerMonitorWidgetController::SkillManagerMonitorWidgetController() @@ -418,9 +91,10 @@ namespace armarx void SkillManagerMonitorWidgetController::onConnectComponent() - { getProxy(observer, observerName); + { getProxy(manager, observerName); widget.groupBoxSkills->setTitle(QString::fromStdString(observerName)); widget.treeWidgetSkillDetails->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers); + widget.treeWidgetSkillDetails->setColumnHidden(3, true); } void SkillManagerMonitorWidgetController::onDisconnectComponent() @@ -438,7 +112,7 @@ namespace armarx { // get all skills skills.clear(); - for (const auto& [providerName, provider] : observer->getSkillProviders()) + for (const auto& [providerName, provider] : manager->getSkillProviders()) { SkillProviderData providerData; providerData.providerName = providerName; @@ -475,23 +149,24 @@ namespace armarx } const auto& skillDescription = prv.skillDescriptions.at(selectedSkill.skillName); - skills::SkillParametrization params; - params.skillName = selectedSkill.skillName; + skills::manager::dto::SkillExecutionInfo exInfo; + exInfo.providerName = selectedSkill.providerName; + exInfo.skillName = selectedSkill.skillName; // create argument aron (if there is an accepted type set) if (skillsArgumentsTreeWidgetItem) { auto aron_accepted_type = std::make_shared<aron::type::Object>(*skillDescription.acceptedType); - SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor v(skillsArgumentsTreeWidgetItem, 0); + AronTreeViewWidgetConverterVisitor v(skillsArgumentsTreeWidgetItem, 0); aron::type::visit(v, aron_accepted_type); auto aron_args = aron::data::Dict::DynamicCastAndCheck(v.createdAron); - params.params = aron_args->toAronDictPtr(); + exInfo.parameterization.params = aron_args->toAronDictPtr(); } ARMARX_INFO << "Executing skill from GUI: " << selectedSkill.providerName << "/" << selectedSkill.skillName; - observer->executeSkill(selectedSkill.providerName, params); + manager->executeSkill(exInfo); } void SkillManagerMonitorWidgetController::stopSkill() @@ -552,19 +227,19 @@ namespace armarx { auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails, - {QString::fromStdString("Name"), QString::fromStdString(skillDesc.name)}); + {QString::fromStdString("Name"), QString::fromStdString(skillDesc.skillName)}); widget.treeWidgetSkillDetails->addTopLevelItem(it); } { auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails, - {QString::fromStdString("Robot"), QString::fromStdString(simox::alg::join(skillDesc.robots, ", "))}); + {QString::fromStdString("Robot"), QString::fromStdString(simox::alg::join(skillDesc.targets, ", "))}); widget.treeWidgetSkillDetails->addTopLevelItem(it); } { auto it = new QTreeWidgetItem(widget.treeWidgetSkillDetails, - {QString::fromStdString("Description"), QString::fromStdString(skillDesc.documentation)}); + {QString::fromStdString("Description"), QString::fromStdString(skillDesc.description)}); widget.treeWidgetSkillDetails->addTopLevelItem(it); } @@ -581,7 +256,7 @@ namespace armarx skillsArgumentsTreeWidgetItem = new QTreeWidgetItem(widget.treeWidgetSkillDetails, {QString::fromStdString("Arguments")}); - SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor v(skillsArgumentsTreeWidgetItem); + AronTreeViewWidgetCreatorVisitor v(skillsArgumentsTreeWidgetItem); aron::type::visit(v, aron_args); if (v.createdQWidgetItem) @@ -600,7 +275,21 @@ namespace armarx { if (column == 1) { - widget.treeWidgetSkillDetails->editItem(item, column); + if (item->flags() & Qt::ItemIsEditable) // we use the flag to indicate whether the item is editable or not + { + std::string name = item->text(0).toStdString(); + std::string placeholder = item->text(1).toStdString(); + if (placeholder.empty()) + { + placeholder = item->text(3).toStdString(); + ARMARX_IMPORTANT << "Setting placeholder to " << placeholder; + } + + auto modal = AronTreeWidgetInputModalController(name, placeholder, getWidget()); + modal.exec(); + + item->setText(1, modal.getInput()); + } } } } diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h index 48ace9548977105d7293100247602c84f28fa30c..ae65fcbcbfac3b839163244015174d3bfdbb2e59 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/SkillManagerMonitorWidgetController.h @@ -47,85 +47,6 @@ namespace armarx public: - // Convert aron type to tree widget - class SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor : - public armarx::aron::type::ConstVariantVisitor - { - public: - QTreeWidgetItem* parentItem; - QTreeWidgetItem* createdQWidgetItem; - - SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor() = delete; - SkillManagerMonitorArgumentTreeViewWidgetCreatorVisitor(QTreeWidgetItem* i) : - parentItem(i) - {} - - void createSimpleTreeViewWidget(Input& i); - - void visitAronVariant(const aron::type::ObjectPtr&) override; - void visitAronVariant(const aron::type::DictPtr& i) override; - void visitAronVariant(const aron::type::PairPtr& i) override; - void visitAronVariant(const aron::type::TuplePtr& i) override; - void visitAronVariant(const aron::type::ListPtr& i) override; - void visitAronVariant(const aron::type::NDArrayPtr& i) override; - void visitAronVariant(const aron::type::MatrixPtr& i) override; - void visitAronVariant(const aron::type::QuaternionPtr& i) override; - void visitAronVariant(const aron::type::PositionPtr& i) override; - void visitAronVariant(const aron::type::OrientationPtr& i) override; - void visitAronVariant(const aron::type::PosePtr& i) override; - void visitAronVariant(const aron::type::ImagePtr& i) override; - void visitAronVariant(const aron::type::PointCloudPtr& i) override; - void visitAronVariant(const aron::type::IntEnumPtr& i) override; - void visitAronVariant(const aron::type::IntPtr& i) override; - void visitAronVariant(const aron::type::LongPtr& i) override; - void visitAronVariant(const aron::type::FloatPtr& i) override; - void visitAronVariant(const aron::type::DoublePtr& i) override; - void visitAronVariant(const aron::type::BoolPtr& i) override; - void visitAronVariant(const aron::type::StringPtr& i) override; - void visitAronVariant(const aron::type::TimePtr& i) override; - void visitUnknown(Input&) override; - }; - - - // Conversion from TreeView to aron data - class SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor : - public armarx::aron::type::ConstVariantVisitor - { - public: - QTreeWidgetItem* parentItem; - int index; - aron::data::VariantPtr createdAron; - - SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor() = delete; - SkillManagerMonitorArgumentTreeViewWidgetConverterVisitor(QTreeWidgetItem* i, int x) : - parentItem(i), index(x) - {} - - void visitAronVariant(const aron::type::ObjectPtr&) override; - void visitAronVariant(const aron::type::DictPtr&) override; - void visitAronVariant(const aron::type::PairPtr&) override; - void visitAronVariant(const aron::type::TuplePtr&) override; - void visitAronVariant(const aron::type::ListPtr&) override; - void visitAronVariant(const aron::type::NDArrayPtr&) override; - void visitAronVariant(const aron::type::MatrixPtr&) override; - void visitAronVariant(const aron::type::QuaternionPtr&) override; - void visitAronVariant(const aron::type::PositionPtr&) override; - void visitAronVariant(const aron::type::OrientationPtr&) override; - void visitAronVariant(const aron::type::PosePtr&) override; - void visitAronVariant(const aron::type::ImagePtr&) override; - void visitAronVariant(const aron::type::PointCloudPtr&) override; - void visitAronVariant(const aron::type::IntEnumPtr&) override; - void visitAronVariant(const aron::type::IntPtr&) override; - void visitAronVariant(const aron::type::LongPtr&) override; - void visitAronVariant(const aron::type::FloatPtr&) override; - void visitAronVariant(const aron::type::DoublePtr&) override; - void visitAronVariant(const aron::type::BoolPtr&) override; - void visitAronVariant(const aron::type::StringPtr&) override; - void visitAronVariant(const aron::type::TimePtr&) override; - void visitUnknown(Input&) override; - }; - - /// Controller Constructor explicit SkillManagerMonitorWidgetController(); /// Controller destructor @@ -167,7 +88,7 @@ namespace armarx QPointer<SimpleConfigDialog> dialog; std::string observerName = "SkillManager"; - skills::SkillManagerInterfacePrx observer = nullptr; + skills::manager::dti::SkillManagerInterfacePrx manager = nullptr; struct SelectedSkill { @@ -178,7 +99,7 @@ namespace armarx struct SkillProviderData { std::string providerName; - skills::SkillDescriptionMap skillDescriptions; + skills::provider::dto::SkillDescriptionMap skillDescriptions; }; // Data taken from observer diff --git a/source/RobotAPI/interface/skills/SkillManagerInterface.ice b/source/RobotAPI/interface/skills/SkillManagerInterface.ice index 48c538cc6f853ad273dc9ccfbd2dd637e849dabf..5798328217b497e30f0f75849cd1f6ec15de1880 100644 --- a/source/RobotAPI/interface/skills/SkillManagerInterface.ice +++ b/source/RobotAPI/interface/skills/SkillManagerInterface.ice @@ -28,16 +28,48 @@ module armarx { module skills { - interface SkillManagerInterface // rename to manager + module callback { - void addProvider(string providerName, SkillProviderInterface* provider); - void removeProvider(string providerName); - SkillProviderMap getSkillProviders(); + module dti + { + interface SkillProviderCallbackInterface + { + // used for callbacks from providers to update their skill execution status + void updateStatusForSkill(provider::dto::SkillStatusUpdate statusUpdate); + } + } + } - void executeSkill(string providerName, SkillParametrization skill); + module manager + { + module dto + { + // Inputs + struct SkillExecutionInfo + { + string providerName; + string skillName; + provider::dto::SkillParameterization parameterization; + }; + + struct ProviderInfo + { + string providerName; + provider::dti::SkillProviderInterface* provider; + provider::dto::SkillDescriptionMap providedSkills; + }; + } - // used for callbacks from providers to update their skill execution status - void updateStatusForSkill(string providerName, SkillStatus statusUpdate); - }; + module dti + { + interface SkillManagerInterface extends callback::dti::SkillProviderCallbackInterface + { + void addProvider(dto::ProviderInfo providerInfo); + void removeProvider(string providerName); + provider::dti::SkillProviderMap getSkillProviders(); + void executeSkill(dto::SkillExecutionInfo skillExecutionInfo); + }; + } + } } } diff --git a/source/RobotAPI/interface/skills/SkillMemoryInterface.ice b/source/RobotAPI/interface/skills/SkillMemoryInterface.ice index 8025d4cdb5ec9feb2e59f295dde2e9f2830e7607..c8e3212efa1b0ae3bf2768a124a53441898cd6de 100644 --- a/source/RobotAPI/interface/skills/SkillMemoryInterface.ice +++ b/source/RobotAPI/interface/skills/SkillMemoryInterface.ice @@ -33,8 +33,11 @@ module armarx { module skills { - interface SkillMemoryInterface extends armem::server::MemoryInterface, StatechartListenerInterface, SkillManagerInterface + module dti { - }; + interface SkillMemoryInterface extends armem::server::MemoryInterface, dti::StatechartListenerInterface, manager::dti::SkillManagerInterface + { + }; + } } } diff --git a/source/RobotAPI/interface/skills/SkillProviderInterface.ice b/source/RobotAPI/interface/skills/SkillProviderInterface.ice index 24c4f4e4e0e6ae6af8942b383a26e20e7f5a90ce..0a1649753c7a50ad2103c1c7e3c6fe4441c90b48 100644 --- a/source/RobotAPI/interface/skills/SkillProviderInterface.ice +++ b/source/RobotAPI/interface/skills/SkillProviderInterface.ice @@ -28,62 +28,86 @@ module armarx { module skills { - sequence<string> StringList; - - // Description of a skill. Needs to be sent to a skill observer or memory - struct SkillDescription + module callback { - string name; - StringList robots; - string documentation; // rename to what? - long timeoutMs; // Millisecs - - aron::type::dto::AronObject acceptedType; // the name of the object is irrelevant and only used in GUI - }; - dictionary<string, SkillDescription> SkillDescriptionMap; + module dti + { + interface SkillProviderCallbackInterface; + } + } - module Execution + module provider { - enum Status + module dto { - Idle, - Scheduled, - RunningButWaitingForDependencies, - Running, + sequence<string> StringList; - // terminating values - Failed, - Succeeded, - Aborted - }; - }; + // Description of a skill. Needs to be sent to a skill manager or memory + // A skill is nothing but a executable thing, which can be executed on one or more 'targets' (empty means all) + struct SkillDescription + { + string skillName; // the name of the skill + string description; // a human readable description of what the skill does + StringList targets; // see above + long timeoutMs; // in milliseconds + aron::type::dto::AronObject acceptedType; // the name of the object is irrelevant and only used in GUI + }; + dictionary<string, SkillDescription> SkillDescriptionMap; - interface SkillManagerInterface; - struct SkillParametrization - { - string skillName; - aron::data::dto::Dict params; - }; + // The status enum of a skill + enum ExecutionStatus + { + Idle, + Scheduled, + Running, - struct SkillStatus - { - Execution::Status status; - SkillParametrization usedParameterization; - aron::data::dto::Dict returnValue; // can be anything - //string message; - //string error; - }; + // terminating values + Failed, + Succeeded, + Aborted + }; - dictionary<string, SkillStatus> SkillStatusMap; + // execute a skill with the following parameterization + struct SkillParameterization + { + aron::data::dto::Dict params; + }; - interface SkillProviderInterface - { - SkillDescriptionMap getSkills(); - SkillStatus getSkillExecutionStatus(string name); - void executeSkill(SkillParametrization skill, SkillManagerInterface* callbackInterface); // use nullptr if you do not want to have callbacks - SkillStatus abortSkill(string skill); - }; + // Status updates of a skill + struct SkillStatusUpdate + { + string providerName; + string skillName; + SkillParameterization usedParameterization; + callback::dti::SkillProviderCallbackInterface* usedCallbackInterface; + ExecutionStatus status; + aron::data::dto::Dict data; // can be anything + }; + + dictionary<string, SkillStatusUpdate> SkillStatusUpdateMap; + + // Inputs + struct SkillExecutionInfo + { + string skillName; + SkillParameterization parameterization; + callback::dti::SkillProviderCallbackInterface* callbackInterface; // use nullptr if you do not want to have callbacks + }; + }; + + module dti + { + + interface SkillProviderInterface + { + dto::SkillDescriptionMap getSkills(); + dto::SkillStatusUpdate getSkillExecutionStatus(string name); + void executeSkill(dto::SkillExecutionInfo executionInfo); + dto::SkillStatusUpdate abortSkill(string skill); + }; - dictionary<string, SkillProviderInterface*> SkillProviderMap; + dictionary<string, SkillProviderInterface*> SkillProviderMap; + } + } } } diff --git a/source/RobotAPI/interface/skills/StatechartListenerInterface.ice b/source/RobotAPI/interface/skills/StatechartListenerInterface.ice index abcd88398016368eef91091877ab980ab8456696..084633cdcdc1772c7f8f960b3119707dc612373f 100644 --- a/source/RobotAPI/interface/skills/StatechartListenerInterface.ice +++ b/source/RobotAPI/interface/skills/StatechartListenerInterface.ice @@ -26,7 +26,10 @@ module armarx { - interface StatechartListenerInterface extends armarx::ProfilerListener + module dti { - }; + interface StatechartListenerInterface extends armarx::ProfilerListener + { + }; + } } diff --git a/source/RobotAPI/libraries/CMakeLists.txt b/source/RobotAPI/libraries/CMakeLists.txt index 1add633dda134d6ac07dc20032a7e184b334bf48..86bdc8fa48e612b256365f1beb1c43bfd1d09ec2 100644 --- a/source/RobotAPI/libraries/CMakeLists.txt +++ b/source/RobotAPI/libraries/CMakeLists.txt @@ -29,6 +29,8 @@ add_subdirectory(armem_skills) add_subdirectory(armem_system_state) add_subdirectory(armem_vision) +add_subdirectory(skills) + add_subdirectory(RobotUnitDataStreamingReceiver) add_subdirectory(GraspingUtility) diff --git a/source/RobotAPI/libraries/armem/server/segment/detail/SpecializedSegment.cpp b/source/RobotAPI/libraries/armem/server/segment/detail/SpecializedSegment.cpp index d55f3427d3070d4af4f556a4e0b8db2312d984f3..8180bce582e2f105a870e71d0063c7fba3a9387b 100644 --- a/source/RobotAPI/libraries/armem/server/segment/detail/SpecializedSegment.cpp +++ b/source/RobotAPI/libraries/armem/server/segment/detail/SpecializedSegment.cpp @@ -1,6 +1,6 @@ #include "SpecializedSegment.h" -namespace armarx::armem::server::segment +namespace armarx::armem::server::segment::detail { } diff --git a/source/RobotAPI/libraries/armem/server/segment/detail/SpecializedSegment.h b/source/RobotAPI/libraries/armem/server/segment/detail/SpecializedSegment.h index f739c0dd3dd7a6b1a2196013f1500e2c4bbd52b5..b82402f556eaec531720809ff61825ab6da09eed 100644 --- a/source/RobotAPI/libraries/armem/server/segment/detail/SpecializedSegment.h +++ b/source/RobotAPI/libraries/armem/server/segment/detail/SpecializedSegment.h @@ -32,6 +32,18 @@ namespace armarx::armem::server::segment Logging::setTag("armarx::armem::Segment"); } + MemoryID& id() + { + ARMARX_CHECK_NOT_NULL(segmentPtr); + return segmentPtr->id(); + } + + const MemoryID& id() const + { + ARMARX_CHECK_NOT_NULL(segmentPtr); + return segmentPtr->id(); + } + virtual ~SegmentBase() = default; virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "") = 0; diff --git a/source/RobotAPI/libraries/armem_skills/CMakeLists.txt b/source/RobotAPI/libraries/armem_skills/CMakeLists.txt index 19e4c5a56d5bee812656e9d484661841b7d36310..40e112f8b56f762ff8da6c57f1995b09bc5243bf 100644 --- a/source/RobotAPI/libraries/armem_skills/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem_skills/CMakeLists.txt @@ -11,29 +11,26 @@ armarx_add_library( RobotAPI::Core RobotAPI::armem_server + RobotAPI::skills aronjsonconverter SOURCES ./aron_conversions.cpp ./server/StatechartListenerComponentPlugin.cpp - ./server/SkillManagerComponentPlugin.cpp + ./server/segment/StatechartListenerSegment.cpp ./server/segment/ExecutableSkillLibrarySegment.cpp ./server/segment/SkillExecutionRequestSegment.cpp ./server/segment/SkillEventSegment.cpp - - ./client/SkillProviderComponentPlugin.cpp HEADERS ./aron_conversions.h ./server/StatechartListenerComponentPlugin.h - ./server/SkillManagerComponentPlugin.h + ./server/segment/StatechartListenerSegment.h ./server/segment/ExecutableSkillLibrarySegment.h ./server/segment/SkillExecutionRequestSegment.h ./server/segment/SkillEventSegment.h - - ./client/SkillProviderComponentPlugin.h ) armarx_enable_aron_file_generation_for_target( diff --git a/source/RobotAPI/libraries/armem_skills/aron/Skill.xml b/source/RobotAPI/libraries/armem_skills/aron/Skill.xml index 838960afb96daeb639bb6b601598013fe355e7de..0e539ff08a436fee457a773a7dad2700ca19e8a2 100644 --- a/source/RobotAPI/libraries/armem_skills/aron/Skill.xml +++ b/source/RobotAPI/libraries/armem_skills/aron/Skill.xml @@ -12,17 +12,17 @@ The memory should look like the following: <AronTypeDefinition> <GenerateTypes> <Object name='armarx::skills::arondto::SkillDescription'> - <ObjectChild key='name'> + <ObjectChild key='skillName'> <String /> </ObjectChild> - <ObjectChild key='robots'> + <ObjectChild key='targets'> <List> <String /> </List> </ObjectChild> - <ObjectChild key='documentation'> + <ObjectChild key='description'> <String /> </ObjectChild> @@ -30,9 +30,11 @@ The memory should look like the following: <String /> </ObjectChild> - <ObjectChild key='acceptedTypeJson'> - <String /> + <ObjectChild key='timeoutMs'> + <long /> </ObjectChild> + + <!-- accepted type as any type --> </Object> <Object name='armarx::skills::arondto::SkillExecutionRequest'> diff --git a/source/RobotAPI/libraries/armem_skills/client/SkillProviderComponentPlugin.cpp b/source/RobotAPI/libraries/armem_skills/client/SkillProviderComponentPlugin.cpp deleted file mode 100644 index 35b128e5311395d1d7f850fed9d7ecdedc208987..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem_skills/client/SkillProviderComponentPlugin.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include "SkillProviderComponentPlugin.h" - -#include <ArmarXCore/core/Component.h> - -#include <RobotAPI/libraries/aron/core/data/variant/primitive/All.h> - -namespace armarx::plugins -{ - void SkillProviderComponentPlugin::preOnInitComponent() - { - - } - - void SkillProviderComponentPlugin::preOnConnectComponent() - { - auto& p = parent<SkillProviderComponentPluginUser>(); - p.getProxy(skillProvider, -1); - } - - void SkillProviderComponentPlugin::postOnConnectComponent() - { - auto& p = parent<SkillProviderComponentPluginUser>(); - std::string providerName = p.getName(); - SkillManager->addProvider(providerName, skillProvider); - } - - void SkillProviderComponentPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) - { - std::string prefix = "skill."; - properties->component(SkillManager, "SkillMemory", prefix + "SkillManager", "The name of the SkillManager (or SkillMemory) proxy."); - } -} - - -namespace armarx -{ - SkillProviderComponentPluginUser::SkillProviderComponentPluginUser() - { - addPlugin(plugin); - } - - void SkillProviderComponentPluginUser::addSkill(const skills::SkillImplementationPtr& fun, const skills::SkillDescription& desc) - { - std::lock_guard l(skillsMutex); - std::string providerName = getName(); - std::string skillName = desc.name; - - if (skillImplementations.find(skillName) != skillImplementations.end()) - { - ARMARX_WARNING << "Try to add a skill '" + skillName + "' which already exists in list. Ignore this skill."; - return; - } - - ARMARX_DEBUG << "Adding skill " << skillName << " to list"; - SkillImplementationWrapper skill(fun, providerName, desc); - skillImplementations.insert({skillName, skill}); - } - - void SkillProviderComponentPluginUser::addSkill(const skills::LambdaSkillImplementation::FunT& f, const skills::SkillDescription& desc) - { - auto lmbda = std::make_shared<skills::LambdaSkillImplementation>(f); - addSkill(lmbda, desc); - } - - skills::SkillDescriptionMap SkillProviderComponentPluginUser::getSkills(const Ice::Current ¤t) - { - std::lock_guard l(skillsMutex); - skills::SkillDescriptionMap skillDesciptions; - for (const auto& [key, skillImplementation] : skillImplementations) - { - skillDesciptions.insert({key, skillImplementation.description}); - } - return skillDesciptions; - } - - skills::SkillStatus SkillProviderComponentPluginUser::getSkillExecutionStatus(const std::string& skill, const Ice::Current ¤t) - { - std::lock_guard l(skillsMutex); - auto& skillImplementation = skillImplementations.at(skill); - - std::lock_guard l2(skillImplementation.skillStatusMutex); - return skillImplementation.status; - } - - void SkillProviderComponentPluginUser::executeSkill(const skills::SkillParametrization& params, const skills::SkillManagerInterfacePrx& callbackInterface, const Ice::Current ¤t) - { - std::lock_guard l(skillsMutex); - std::string skillName = params.skillName; - ARMARX_CHECK_EXPRESSION(skillImplementations.count(skillName) > 0); - - auto& impl = skillImplementations.at(skillName); - - if (impl.task.joinable()) - { - impl.task.join(); - } - - // update input params - impl.reset(); - impl.callbackInterface = callbackInterface; - impl.status.usedParameterization = params; - - // recreate thread and execute skill - impl.task = std::thread{ [&] { impl.execute(); } }; - } - - skills::SkillStatus SkillProviderComponentPluginUser::abortSkill(const std::string& skillName, const Ice::Current ¤t) - { - std::lock_guard l(skillsMutex); - ARMARX_CHECK_EXPRESSION(skillImplementations.count(skillName) > 0); - auto& impl = skillImplementations.at(skillName); - impl.stop = true; - if (impl.task.joinable()) - { - impl.task.join(); - - std::lock_guard l(impl.skillStatusMutex); - impl.status.status = skills::Execution::Aborted; - } - - return skillImplementations.at(skillName).status; - } - - void SkillProviderComponentPluginUser::SkillImplementationWrapper::reset() - { - std::lock_guard l(skillStatusMutex); - stop = false; - status.status = skills::Execution::Status::Idle; - status.returnValue = nullptr; - skillStarted = 0; - } - - void SkillProviderComponentPluginUser::SkillImplementationWrapper::execute() - { - ARMARX_INFO_S << "Executing skill: " << description.name; - try - { - // set scheduled and reset skill - { - std::lock_guard l(skillStatusMutex); - status.status = skills::Execution::Scheduled; - - // do callback - if (callbackInterface) - { - callbackInterface->updateStatusForSkill(providerName, status); - } - } - - // wait for dependencies - { - std::lock_guard l(skillStatusMutex); - status.status = skills::Execution::RunningButWaitingForDependencies; - if (callbackInterface) - { - callbackInterface->updateStatusForSkill(providerName, status); - } - } - - if (stop) return; - auto initialized = skill->init(); - if (stop) return; - - if (initialized != skills::SkillImplementation::Status::Succeeded) - { - // create message to return - auto returnDict = std::make_shared<aron::data::Dict>(); - auto message = std::make_shared<aron::data::String>("Could not initialize the skill."); - returnDict->addElement("message", message); - status.returnValue = returnDict->toAronDictPtr(); - - throw armarx::LocalException("The Skill '"+description.name+"' failed during initialization."); - } - - // execute - { - std::lock_guard l(skillStatusMutex); - status.status = skills::Execution::Running; - if (callbackInterface) - { - callbackInterface->updateStatusForSkill(providerName, status); - } - } - - if (stop) return; - aron::data::DictPtr aron_params = nullptr; - if (status.usedParameterization.params) // check if params are set. - { - aron_params = std::make_shared<aron::data::Dict>(status.usedParameterization.params); - } - else - { - if (description.acceptedType) - { - throw armarx::LocalException("The Skill '"+description.name+"' requires a type but no params are NULL."); - } - } - - auto updateCallback = [&](const aron::data::DictPtr& update) - { - if (update) - { - status.returnValue = update->toAronDictPtr(); - callbackInterface->updateStatusForSkill(providerName, status); - } - }; - auto result = skill->execute(aron_params, updateCallback); - if (stop) return; - - { - if (result == skills::SkillImplementation::Status::Failed) - { - throw armarx::LocalException("The Skill '"+description.name+"' failed during execution."); - } - if (result == skills::SkillImplementation::Status::TimeoutReached) - { - throw armarx::LocalException("The Skill '"+description.name+"' reached timeout during execution."); - } - - std::lock_guard l(skillStatusMutex); - status.status = skills::Execution::Succeeded; - if (callbackInterface) - { - callbackInterface->updateStatusForSkill(providerName, status); - } - } - } - catch (const std::exception& ex) - { - ARMARX_WARNING_S << "Skill " << description.name << " died with exception:\n" << ex.what(); - - std::lock_guard l(skillStatusMutex); - status.status = skills::Execution::Failed; - if (callbackInterface) - { - callbackInterface->updateStatusForSkill(providerName, status); - } - } - } -} diff --git a/source/RobotAPI/libraries/armem_skills/client/SkillProviderComponentPlugin.h b/source/RobotAPI/libraries/armem_skills/client/SkillProviderComponentPlugin.h deleted file mode 100644 index 8f5cc81fb83f241bbc522af16bd2fa102151b986..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem_skills/client/SkillProviderComponentPlugin.h +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include <mutex> -#include <queue> -#include <thread> -#include <functional> - -#include <ArmarXCore/core/ComponentPlugin.h> -#include <ArmarXCore/core/ManagedIceObject.h> - -#include <ArmarXCore/core/services/tasks/RunningTask.h> - -#include <RobotAPI/interface/skills/SkillManagerInterface.h> -#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> - -namespace armarx::plugins -{ - class SkillProviderComponentPlugin : public ComponentPlugin - { - public: - using ComponentPlugin::ComponentPlugin; - - void preOnInitComponent() override; - - void preOnConnectComponent() override; - void postOnConnectComponent() override; - - void postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) override; - - private: - skills::SkillManagerInterfacePrx SkillManager; - skills::SkillProviderInterfacePrx skillProvider; - }; -} - -namespace armarx -{ - namespace skills - { - class SkillImplementation - { - public: - using CallbackT = std::function<void(const aron::data::DictPtr&)>; - - enum class Status - { - Succeeded, - TimeoutReached, - Failed - }; - - virtual Status init() - { - return Status::Succeeded; - } - - /// Override this method with the actual implementation. The callback is for status updates - virtual Status execute(const aron::data::DictPtr& params, const CallbackT& callback) - { - ARMARX_WARNING_S << "You have to override this method!"; - return Status::Succeeded; - } - - /// Use this if you do not need a callback - Status execute(const aron::data::DictPtr& params) - { - auto fun = [](const aron::data::DictPtr&) {}; - return execute(params, fun); - } - }; - - class LambdaSkillImplementation : public SkillImplementation - { - public: - using FunT = std::function<bool(const aron::data::DictPtr&)>; - - LambdaSkillImplementation() = delete; - LambdaSkillImplementation(const FunT& f) : fun(f) {}; - - SkillImplementation::Status execute(const aron::data::DictPtr& data, const CallbackT& callback) override - { - bool res = fun(data); - return res ? Status::Succeeded : Status::Failed; - } - - private: - FunT fun; - }; - - using SkillImplementationPtr = std::shared_ptr<SkillImplementation>; - using LambdaSkillImplementationPtr = std::shared_ptr<LambdaSkillImplementation>; - } - - - class SkillProviderComponentPluginUser : - virtual public ManagedIceObject, - virtual public skills::SkillProviderInterface - { - public: - struct SkillImplementationWrapper - { - // fixed values. Do not change after skill instantiation - const std::string providerName; - const skills::SkillDescription description; - const skills::SkillImplementationPtr skill; - - // Current execution status. Changes during execution - skills::SkillStatus status; - - // Used callback interface. May change on start - skills::SkillManagerInterfacePrx callbackInterface = nullptr; - - // Info - long skillStarted = 0; - - // Task information. task is recreated every time the skill restarts - mutable std::mutex skillStatusMutex; - std::atomic_bool stop = false; - std::thread task; - - SkillImplementationWrapper(const skills::SkillImplementationPtr& fun, const std::string& providerName, const skills::SkillDescription& desc) : - providerName(providerName), description(desc), skill(fun) - { - reset(); - } - - SkillImplementationWrapper(const SkillImplementationWrapper& s) : - SkillImplementationWrapper(s.skill, s.providerName, s.description) - {} - - void execute(); - void reset(); - - private: - bool isTimeoutReached() const - { - if (description.timeoutMs < 0) - { - return false; - } - - auto now = IceUtil::Time::now().toMilliSeconds(); - return (now - skillStarted) >= description.timeoutMs; - } - }; - - SkillProviderComponentPluginUser(); - - skills::SkillDescriptionMap getSkills(const Ice::Current ¤t) override; - skills::SkillStatus getSkillExecutionStatus(const std::string& skill, const Ice::Current ¤t) override; - void executeSkill(const skills::SkillParametrization &skill, const skills::SkillManagerInterfacePrx& callbackInterface, const Ice::Current ¤t) override; - skills::SkillStatus abortSkill(const std::string &skill, const Ice::Current ¤t) override; - - protected: - void addSkill(const skills::LambdaSkillImplementation::FunT&, const skills::SkillDescription&); - void addSkill(const skills::SkillImplementationPtr&, const skills::SkillDescription&); - - private: - armarx::plugins::SkillProviderComponentPlugin* plugin = nullptr; - - protected: - mutable std::mutex skillsMutex; - std::map<std::string, SkillImplementationWrapper> skillImplementations; - }; -} diff --git a/source/RobotAPI/libraries/armem_skills/server/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/armem_skills/server/SkillManagerComponentPlugin.cpp deleted file mode 100644 index ee2445911873ae8a0af1e522caa3711cb8561cdc..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/armem_skills/server/SkillManagerComponentPlugin.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "SkillManagerComponentPlugin.h" - -#include <ArmarXCore/core/Component.h> - -namespace armarx::plugins -{ - void SkillManagerComponentPlugin::preOnInitComponent() - {} - - void SkillManagerComponentPlugin::preOnConnectComponent() - {} - - void SkillManagerComponentPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) - {} -} - - -namespace armarx -{ - SkillManagerComponentPluginUser::SkillManagerComponentPluginUser() - { - addPlugin(plugin); - } - - void SkillManagerComponentPluginUser::addProvider(const std::string& providerName, const skills::SkillProviderInterfacePrx& provider, const Ice::Current&) - { - std::lock_guard l(skillProviderMapMutex); - if (skillProviderMap.find(providerName) == skillProviderMap.end()) - { - ARMARX_INFO << "Adding a provider with name '" << providerName << "'."; - skillProviderMap.insert({providerName, provider}); - } - } - - void SkillManagerComponentPluginUser::removeProvider(const std::string& providerName, const Ice::Current&) - { - std::lock_guard l(skillProviderMapMutex); - if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end()) - { - skillProviderMap.erase(it); - } - } - - skills::SkillProviderMap SkillManagerComponentPluginUser::getSkillProviders(const Ice::Current&) - { - return skillProviderMap; - } - - void SkillManagerComponentPluginUser::executeSkill(const std::string& providerName, const skills::SkillParametrization& params, const Ice::Current&) - { - if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end()) - { - auto myPrx = getProxy<skills::SkillManagerInterfacePrx>(getName()); - it->second->executeSkill(params, myPrx); - } - throw LocalException("Could not execute a skill of provider '" + providerName + "' because the provider does not exist."); - } - - void SkillManagerComponentPluginUser::updateStatusForSkill(const std::string& providerName, const skills::SkillStatus& statusUpdate, const Ice::Current&) - { - (void) providerName; - (void) statusUpdate; - // If you want to use the status, implement this method! - } -} diff --git a/source/RobotAPI/libraries/armem_skills/server/StatechartListenerComponentPlugin.h b/source/RobotAPI/libraries/armem_skills/server/StatechartListenerComponentPlugin.h index 9379c5008b6786db92d47a3605f53210290b910e..4f62bfdfe806ea69ccd9b758974b288511152bad 100644 --- a/source/RobotAPI/libraries/armem_skills/server/StatechartListenerComponentPlugin.h +++ b/source/RobotAPI/libraries/armem_skills/server/StatechartListenerComponentPlugin.h @@ -25,7 +25,7 @@ namespace armarx { class StatechartListenerComponentPluginUser : virtual public ManagedIceObject, - virtual public StatechartListenerInterface + virtual public dti::StatechartListenerInterface { public: StatechartListenerComponentPluginUser(); diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp index d5bd93058d843fc095f9dc03f1f56816689f9ed1..3c9d18f33ad2e7a07b38913795b385b77a9e7f91 100644 --- a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp +++ b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.cpp @@ -7,112 +7,53 @@ #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h> - namespace armarx::skills::segment { - ExecutableSkillLibraryProviderSegment::ExecutableSkillLibraryProviderSegment(const std::string& provName, const SkillProviderInterfacePrx& prx, armem::server::MemoryToIceAdapter& iceMemory): - Base(iceMemory, provName, ExecutableSkillLibraryCoreSegment::CoreSegmentName, skills::arondto::SkillDescription::toAronType()), - skillProvider(prx) + ExecutableSkillLibraryCoreSegment::ExecutableSkillLibraryCoreSegment(armem::server::MemoryToIceAdapter& iceMemory): + Base(iceMemory, CoreSegmentName, skills::arondto::SkillDescription::toAronType()) { } - void ExecutableSkillLibraryProviderSegment::defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix) + void ExecutableSkillLibraryCoreSegment::defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix) { // No properties! (meaning no name and no max size) } - void ExecutableSkillLibraryProviderSegment::init() + void ExecutableSkillLibraryCoreSegment::init() { Base::init(); + } + void ExecutableSkillLibraryCoreSegment::addSkillProvider(const skills::manager::dto::ProviderInfo& info) + { // add skills - auto skills = skillProvider->getSkills(); + auto skills = info.providedSkills; + + auto provId = id().withProviderSegmentName(info.providerName); - ARMARX_INFO << "During init the providerSegment '" << getProviderSegment().id().providerSegmentName << "' has " << skills.size() << " skills."; for (const auto& [key, desc] : skills) { - skills::arondto::SkillDescription skillDescription; - skillDescription.name = desc.name; - skillDescription.documentation = desc.documentation; - skillDescription.iceInfo = skillProvider->ice_toString(); - skillDescription.robots = desc.robots; - if (desc.acceptedType) - { - aron::type::VariantPtr t = aron::type::Variant::FromAronDTO(*desc.acceptedType); - skillDescription.acceptedTypeJson = aron::converter::AronNlohmannJSONConverter::ConvertToNlohmannJSON(t).dump(2); - } + armarx::skills::arondto::SkillDescription skillDescription; + skillDescription.skillName = desc.skillName; + skillDescription.description = desc.description; + skillDescription.iceInfo = info.provider->ice_toString(); + skillDescription.targets = desc.targets; + skillDescription.timeoutMs = desc.timeoutMs; armem::Commit commit; auto& entityUpdate = commit.add(); entityUpdate.confidence = 1.0; entityUpdate.timeCreated = armem::Time::now(); entityUpdate.instancesData = {skillDescription.toAron()}; - entityUpdate.entityID = getProviderSegment().id().withEntityName(key); + entityUpdate.entityID = provId.withEntityName(skillDescription.skillName); // Commit data to memory and notify iceMemory.commit(commit); } } - void ExecutableSkillLibraryProviderSegment::directlyExecuteSkill(const skills::arondto::SkillExecutionRequest& req, const skills::SkillManagerInterfacePrx& callbackInterface, const aron::data::DictPtr& params) - { - skills::SkillParametrization parameterization; - parameterization.skillName = req.skillName; - if (params) // may be null - { - parameterization.params = params->toAronDictPtr(); - } - skillProvider->executeSkill(parameterization, callbackInterface); - } - - ExecutableSkillLibraryCoreSegment::ExecutableSkillLibraryCoreSegment(armem::server::MemoryToIceAdapter& iceMemory): - Base(iceMemory, CoreSegmentName, skills::arondto::SkillDescription::toAronType()) - { - } - - void ExecutableSkillLibraryCoreSegment::defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix) - { - // No properties! (meaning no name and no max size) - } - - void ExecutableSkillLibraryCoreSegment::init() - { - Base::init(); - } - - void ExecutableSkillLibraryCoreSegment::addSkillProvider(const std::string& providerSegmentName, const SkillProviderInterfacePrx& provider) - { - auto it = providerSegments.emplace(providerSegmentName, ExecutableSkillLibraryProviderSegment{providerSegmentName, provider, iceMemory}); - if (it.second) - { - it.first->second.init(); - } - else - { - ARMARX_WARNING << "Could not insert a skillProvider '"<<providerSegmentName<<"' to the segment '" << getCoreSegment().id().str() << "'. This may leave the SkillManager and the memory unsynchronized."; - } - } - - SkillProviderInterfacePrx ExecutableSkillLibraryCoreSegment::getSkillProvider(const std::string& providerName) const - { - return providerSegments.at(providerName).skillProvider; - } - void ExecutableSkillLibraryCoreSegment::removeSkillProvider(const std::string& providerName) { - providerSegments.erase(providerName); - } - - void ExecutableSkillLibraryCoreSegment::directlyExecuteSkill(const skills::arondto::SkillExecutionRequest& req, const skills::SkillManagerInterfacePrx& callbackInterface, const aron::data::DictPtr& params) - { - if (const auto& it = providerSegments.find(req.providerName); it != providerSegments.end()) - { - it->second.directlyExecuteSkill(req, callbackInterface, params); - } - } - - size_t ExecutableSkillLibraryCoreSegment::size() const - { - return providerSegments.size(); + skills.erase(providerName); } } diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.h b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.h index dd2dba322de8b7516faee98e72dbd388dcae58c3..a2d4227bb2c0789c028b31ef47beb21b68891ee4 100644 --- a/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.h +++ b/source/RobotAPI/libraries/armem_skills/server/segment/ExecutableSkillLibrarySegment.h @@ -8,29 +8,13 @@ #include <ArmarXCore/observers/ObserverObjectFactories.h> #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h> +#include <RobotAPI/interface/skills/SkillManagerInterface.h> #include <RobotAPI/interface/skills/SkillProviderInterface.h> #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h> namespace armarx::skills::segment { - class ExecutableSkillLibraryProviderSegment : - public armem::server::segment::SpecializedProviderSegment - { - using Base = armem::server::segment::SpecializedProviderSegment; - - public: - ExecutableSkillLibraryProviderSegment(const std::string& provName, const SkillProviderInterfacePrx&, armem::server::MemoryToIceAdapter& iceMemory); - - void defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix); - void init(); - - void directlyExecuteSkill(const skills::arondto::SkillExecutionRequest&, const skills::SkillManagerInterfacePrx& callbackInterface, const aron::data::DictPtr& params); - - public: - SkillProviderInterfacePrx skillProvider; - }; - class ExecutableSkillLibraryCoreSegment : public armem::server::segment::SpecializedCoreSegment { @@ -44,14 +28,12 @@ namespace armarx::skills::segment void defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix); void init(); - void addSkillProvider(const std::string& providerName, const SkillProviderInterfacePrx& provider); - SkillProviderInterfacePrx getSkillProvider(const std::string& providerName) const; + void addSkillProvider(const skills::manager::dto::ProviderInfo& info); void removeSkillProvider(const std::string& providerName); - void directlyExecuteSkill(const skills::arondto::SkillExecutionRequest&, const skills::SkillManagerInterfacePrx& callbackInterface, const aron::data::DictPtr& params); size_t size() const; private: - std::map<std::string, ExecutableSkillLibraryProviderSegment> providerSegments; + std::map<std::string, std::map<std::string, skills::manager::dto::ProviderInfo>> skills; }; } diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp index 012a2c0add408b3a3520b2d74c823494186c61df..e0e833c35df85b6eee53e32d39269b9da42260c9 100644 --- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp +++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.cpp @@ -24,4 +24,46 @@ namespace armarx::skills::segment { Base::init(); } + + void SkillEventCoreSegment::addSkillUpdateEvent(const skills::provider::dto::SkillStatusUpdate& update) + { + // add update for skill to memory + static std::map<armarx::skills::provider::dto::ExecutionStatus, std::string> ExecutionStatus2String = { + {armarx::skills::provider::dto::ExecutionStatus::Idle, "Idle"}, + {armarx::skills::provider::dto::ExecutionStatus::Scheduled, "Scheduled"}, + {armarx::skills::provider::dto::ExecutionStatus::Running, "Running"}, + {armarx::skills::provider::dto::ExecutionStatus::Aborted, "Aborted"}, + {armarx::skills::provider::dto::ExecutionStatus::Failed, "Failed"}, + {armarx::skills::provider::dto::ExecutionStatus::Succeeded, "Succeeded"} + }; + + // create commit about new update + armarx::skills::arondto::SkillExecutionEvent event; + event.providerName = update.providerName; + event.skillName = update.skillName; + event.status = ExecutionStatus2String.at(update.status); + + aron::data::DictPtr aron_params = nullptr; + if (update.usedParameterization.params) aron_params = std::make_shared<aron::data::Dict>(update.usedParameterization.params); + + aron::data::DictPtr aron_data = nullptr; + if (update.data) aron_data = std::make_shared<aron::data::Dict>(update.data); + + armem::MemoryID commitId = id(); + commitId.providerSegmentName = event.providerName; + commitId.entityName = event.skillName; + + auto aron = event.toAron(); + aron->addElement("return", aron_data); // how to name?!? + aron->addElement("params", aron_params); + + armem::Commit comm; + auto& entityUpdate = comm.add(); + entityUpdate.confidence = 1.0; + entityUpdate.timeCreated = armem::Time::now(); + entityUpdate.instancesData = { aron }; + entityUpdate.entityID = commitId; + + iceMemory.commit(comm); + } } diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h index 7867bc9349d1153ac47da0688aeef49b35b829e2..93df4bf7a429a459ccd51603af035d96f3f9e3d6 100644 --- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h +++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillEventSegment.h @@ -6,6 +6,7 @@ #include <RobotAPI/libraries/armem/server/segment/SpecializedSegment.h> // ArmarX +#include <RobotAPI/interface/skills/SkillManagerInterface.h> #include <RobotAPI/interface/skills/SkillProviderInterface.h> #include <RobotAPI/libraries/armem_skills/aron/Skill.aron.generated.h> @@ -25,7 +26,8 @@ namespace armarx::skills::segment void defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix); void init(); + void addSkillUpdateEvent(const skills::provider::dto::SkillStatusUpdate& update); + private: - std::map<std::string, std::map<std::string, std::thread>> pollers; }; } diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp index a4a02d913cd041a174e8acb24492e939dbf83638..1f6e8c377662ed19e5abcd557e0f8095ae87d1b8 100644 --- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp +++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.cpp @@ -11,33 +11,67 @@ namespace armarx::skills::segment { - SkillExecutionRequestProviderSegment::SkillExecutionRequestProviderSegment(const std::string& provName, const SkillProviderInterfacePrx& prx, armem::server::MemoryToIceAdapter& iceMemory): - Base(iceMemory, provName, SkillExecutionRequestCoreSegment::CoreSegmentName/*, skills::arondto::SkillExecutionRequest::toAronType()*/) + SkillExecutionRequestCoreSegment::SkillExecutionRequestCoreSegment(armem::server::MemoryToIceAdapter& iceMemory): + Base(iceMemory, CoreSegmentName/*, skills::arondto::SkillExecutionRequest::toAronType()*/) { } - void SkillExecutionRequestProviderSegment::defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix) + void SkillExecutionRequestCoreSegment::defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix) { // No properties! (meaning no name and no max size) } - void SkillExecutionRequestProviderSegment::init() + void SkillExecutionRequestCoreSegment::init() { Base::init(); } - SkillExecutionRequestCoreSegment::SkillExecutionRequestCoreSegment(armem::server::MemoryToIceAdapter& iceMemory): - Base(iceMemory, CoreSegmentName/*, skills::arondto::SkillExecutionRequest::toAronType()*/) - { - } - void SkillExecutionRequestCoreSegment::defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix) + skills::manager::dto::SkillExecutionInfo SkillExecutionRequestCoreSegment::convertCommit(const aron::data::dto::DictPtr& commitData) { - // No properties! (meaning no name and no max size) + // convert ice commitData to aron + auto commitDataAron = std::make_shared<aron::data::Dict>(commitData); + + // we got a skill execution request + skills::arondto::SkillExecutionRequest request; + request.fromAron(commitDataAron); + auto params = aron::data::Dict::DynamicCastAndCheck(commitDataAron->at("params")); // ToDo remov and add to request + + skills::manager::dto::SkillExecutionInfo info; + info.providerName = request.providerName; + info.skillName = request.skillName; + info.parameterization.params = params->toAronDictPtr(); + return info; } - void SkillExecutionRequestCoreSegment::init() + + void SkillExecutionRequestCoreSegment::addSkillExecutionRequest(const skills::manager::dto::SkillExecutionInfo& info) { - Base::init(); + // override directly execution to add a request to the memory + armem::Commit comm; + auto& entityUpdate = comm.add(); + + skills::arondto::SkillExecutionRequest request; + request.clientId = ""; + request.providerName = info.providerName; + request.skillName = info.skillName; + + auto aron = request.toAron(); + + aron::data::DictPtr aron_params = nullptr; + if (info.parameterization.params) aron_params = std::make_shared<aron::data::Dict>(info.parameterization.params); + + aron->addElement("params", aron_params); // todo add as any type + + armem::MemoryID skillExecutionMemID = id(); + skillExecutionMemID.providerSegmentName = request.providerName; + skillExecutionMemID.entityName = request.skillName; + + entityUpdate.entityID = skillExecutionMemID; + entityUpdate.instancesData = { aron }; + entityUpdate.confidence = 1.0; + entityUpdate.timeCreated = armem::Time::now(); + + iceMemory.commit(comm); } } diff --git a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.h b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.h index d4e8ba98f35d2eb7fba8369370e914d330f226f2..08b6f6b56b913491f29746e60481079562764afb 100644 --- a/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.h +++ b/source/RobotAPI/libraries/armem_skills/server/segment/SkillExecutionRequestSegment.h @@ -8,22 +8,11 @@ #include <ArmarXCore/observers/ObserverObjectFactories.h> #include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h> +#include <RobotAPI/interface/skills/SkillManagerInterface.h> #include <RobotAPI/interface/skills/SkillProviderInterface.h> namespace armarx::skills::segment { - class SkillExecutionRequestProviderSegment : - public armem::server::segment::SpecializedProviderSegment - { - using Base = armem::server::segment::SpecializedProviderSegment; - - public: - SkillExecutionRequestProviderSegment(const std::string& provName, const SkillProviderInterfacePrx&, armem::server::MemoryToIceAdapter& iceMemory); - - void defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix); - void init(); - }; - class SkillExecutionRequestCoreSegment : public armem::server::segment::SpecializedCoreSegment { @@ -37,7 +26,8 @@ namespace armarx::skills::segment void defineProperties(PropertyDefinitionsPtr defs, const std::string &prefix); void init(); - private: - std::map<std::string, SkillExecutionRequestProviderSegment> providerSegments; + skills::manager::dto::SkillExecutionInfo convertCommit(const aron::data::dto::DictPtr& commitData); + + void addSkillExecutionRequest(const skills::manager::dto::SkillExecutionInfo& info); }; } diff --git a/source/RobotAPI/libraries/aron/core/data/variant/Variant.h b/source/RobotAPI/libraries/aron/core/data/variant/Variant.h index aee8c55fc02d07395e67ff7fd907a8fb5b207999..04c39ea84332665c56269b7e8d16c17aacd83aa4 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/Variant.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/Variant.h @@ -144,6 +144,9 @@ namespace armarx::aron::data /// convert the variant to the ice representation virtual data::dto::GenericDataPtr toAronDTO() const = 0; + /// set a variant from a std string + virtual void fromString(const std::string& setter) = 0; + protected: const data::Descriptor descriptor; const Path path; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.cpp b/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.cpp index dda38b2d0cd94a3bf51e9e9d25964a1ba3371299..c5a8b08ab2b68ded38ca90859c77a0168fb3887d 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.cpp @@ -156,6 +156,11 @@ namespace armarx::aron::data } // virtual implementations + void NDArray::fromString(const std::string& setter) + { + // TODO! + } + std::string NDArray::getShortName() const { return "NDArray"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h b/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h index 31677060acad93fe7fbbbe949b4439d434392931..92dbed05e7433e90fd9725690413687bda908c31 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/complex/NDArray.h @@ -90,6 +90,8 @@ namespace armarx::aron::data return ret; } + void fromString(const std::string& setter) override; + virtual std::string getShortName() const override; virtual std::string getFullName() const override; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp index e2d53ad044d9288b66793b2c18bddf4e088630cc..ef895067b7b299f89be4e031b5d86d69cc8d3182 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.cpp @@ -186,6 +186,11 @@ namespace armarx::aron::data } // virtual implementations + void Dict::fromString(const std::string& setter) + { + // TODO! + } + std::string Dict::getShortName() const { return "Dict"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h index 69315653a29fb12fe403fe9068f6fdf7e09d51bd..99d7a368293c3d3613937a0316c208261bfa3caf 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/container/Dict.h @@ -49,7 +49,7 @@ namespace armarx::aron::data Dict(const std::map<std::string, VariantPtr>&, const Path& path = Path()); // operators - virtual bool operator==(const Dict&) const override; + bool operator==(const Dict&) const override; bool operator==(const DictPtr&) const override; VariantPtr operator[](const std::string&) const; @@ -82,6 +82,8 @@ namespace armarx::aron::data return ret; } + void fromString(const std::string& setter) override; + std::string getShortName() const override; std::string getFullName() const override; std::vector<VariantPtr> getChildren() const override; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp b/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp index 2389e7ad51b10aa342f27208a3903db2629045bf..0d4dffe9bc20479e12c03797964dc4ccba4a42f0 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/container/List.cpp @@ -189,6 +189,11 @@ namespace armarx::aron::data } // virtual implementations + void List::fromString(const std::string& setter) + { + // TODO! + } + std::string List::getShortName() const { return "List"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/container/List.h b/source/RobotAPI/libraries/aron/core/data/variant/container/List.h index 70a1f81d0317e5cae7333246cbfc3d5e425cc71e..cab6a38e5fd1ff8bd85a996fe3336a7ddff16504 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/container/List.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/container/List.h @@ -50,7 +50,7 @@ namespace armarx::aron::data List(const std::vector<VariantPtr>&, const Path& path = Path()); // operators - virtual bool operator==(const List&) const override; + bool operator==(const List&) const override; bool operator==(const ListPtr&) const override; // static methods @@ -82,6 +82,9 @@ namespace armarx::aron::data } return ret; } + + void fromString(const std::string& setter) override; + std::string getShortName() const override; std::string getFullName() const override; std::vector<VariantPtr> getChildren() const override; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.cpp b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.cpp index 463815cb5a8366136f67ba2e5c3aa11233f49d1a..59f8ffa1602955de4f00c60346b3c0b480d24683 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.cpp @@ -79,6 +79,22 @@ namespace armarx::aron::data } /* virtual implementations */ + void Bool::fromString(const std::string& setter) + { + if (setter == "true" || setter == "1" || setter == "yes") + { + setValue(true); + } + else if (setter == "false" || setter == "0" || setter == "no") + { + setValue(false); + } + else + { + throw error::AronException(__PRETTY_FUNCTION__, "Could not set from string. Got: '" + setter + "'"); + } + } + std::string Bool::getShortName() const { return "Bool"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.h b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.h index b598517a1f0e72f62548d1d2cc8e4fdbdef9026f..f76f9396ce4a640e18b9c16d46b9d6383cbee8ba 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Bool.h @@ -59,6 +59,8 @@ namespace armarx::aron::data data::dto::AronBoolPtr toAronBoolPtr() const; /* virtual implementations */ + void fromString(const std::string& setter) override; + std::string getShortName() const override; std::string getFullName() const override; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Double.cpp b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Double.cpp index 829a5b7a37c85fad1afeb34bcf75ecf06fad6624..e96cd84855419855414946958162f3370a7adba8 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Double.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Double.cpp @@ -83,6 +83,11 @@ namespace armarx::aron::data } /* virtual implementations */ + void Double::fromString(const std::string& setter) + { + setValue(std::stod(setter)); + } + std::string Double::getShortName() const { return "Double"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Double.h b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Double.h index 3149e996133279215e7d8d76d0ac5ab8c5113707..fdaba984aa6583523062995451ce062db3a56123 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Double.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Double.h @@ -59,6 +59,8 @@ namespace armarx::aron::data data::dto::AronDoublePtr toAronDoublePtr() const; /* virtual implementations */ + void fromString(const std::string& setter) override; + std::string getShortName() const override; std::string getFullName() const override; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Float.cpp b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Float.cpp index 712e5bf686a6403831a9212861fda202b04d0843..35fd408454f77d91c3e45a260ead10d2a23ae037 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Float.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Float.cpp @@ -80,6 +80,11 @@ namespace armarx::aron::data /* virtual implementations */ + void Float::fromString(const std::string& setter) + { + setValue(std::stof(setter)); + } + std::string Float::getShortName() const { return "Float"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Float.h b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Float.h index 71187edf435a052d875ad8ae6c8ed3f6c6d6dd02..52f3f41cfc0ef98bc13fa47a17c5a160d95ae992 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Float.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Float.h @@ -59,6 +59,8 @@ namespace armarx::aron::data data::dto::AronFloatPtr toAronFloatPtr() const; /* virtual implementations */ + void fromString(const std::string& setter) override; + std::string getShortName() const override; std::string getFullName() const override; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Int.cpp b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Int.cpp index f2670889c9c2310a788fdab0ceeac9bdd768b8cc..ba774f9e5b498f2546b231f795e644a79d39ec35 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Int.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Int.cpp @@ -83,6 +83,11 @@ namespace armarx::aron::data /* virtual implementations */ + void Int::fromString(const std::string& setter) + { + setValue(std::stoi(setter)); + } + std::string Int::getShortName() const { return "Int"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Int.h b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Int.h index f2324a7e040828a5917dfcad8cbe69e1277b4fef..7cf20562d95eeadd431eb27c35b19de39d57e02f 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Int.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Int.h @@ -60,6 +60,8 @@ namespace armarx::aron::data data::dto::AronIntPtr toAronIntPtr() const; /* virtual implementations */ + void fromString(const std::string& setter) override; + std::string getShortName() const override; std::string getFullName() const override; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Long.cpp b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Long.cpp index 8393743c71497be7470f81e5444210fc6dc226f0..4a65a39333df0f16e02e5db7eb9b5d6cbb036bb8 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Long.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Long.cpp @@ -84,6 +84,11 @@ namespace armarx::aron::data /* virtual implementations */ + void Long::fromString(const std::string& setter) + { + setValue(std::stol(setter)); + } + std::string Long::getShortName() const { return "Long"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Long.h b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Long.h index 813a63228051b9e29b87ee69fb2d029a5c1d0198..e8136ed7b3e08a1015c3cc8013105ef1ebb39f2c 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/Long.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/Long.h @@ -60,6 +60,8 @@ namespace armarx::aron::data data::dto::AronLongPtr toAronLongPtr() const; /* virtual implementations */ + void fromString(const std::string& setter) override; + std::string getShortName() const override; std::string getFullName() const override; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/String.cpp b/source/RobotAPI/libraries/aron/core/data/variant/primitive/String.cpp index 878a75f306804a6b3a5dcc25935f46c1ddd014cc..4ca2ff4d854a4ac028792aa166be41172640f992 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/String.cpp +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/String.cpp @@ -80,6 +80,11 @@ namespace armarx::aron::data /* virtual implementations */ + void String::fromString(const std::string& setter) + { + setValue(setter); + } + std::string String::getShortName() const { return "String"; diff --git a/source/RobotAPI/libraries/aron/core/data/variant/primitive/String.h b/source/RobotAPI/libraries/aron/core/data/variant/primitive/String.h index b049fd36e067e83766436e868fba1044d939b281..b8ec3ec038c459f37a907e3526ba7cdd034a9f1f 100644 --- a/source/RobotAPI/libraries/aron/core/data/variant/primitive/String.h +++ b/source/RobotAPI/libraries/aron/core/data/variant/primitive/String.h @@ -59,6 +59,8 @@ namespace armarx::aron::data data::dto::AronStringPtr toAronStringPtr() const; /* virtual implementations */ + void fromString(const std::string& setter) override; + std::string getShortName() const override; std::string getFullName() const override; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/Variant.h b/source/RobotAPI/libraries/aron/core/type/variant/Variant.h index ab996582c630a9083bafb45bc7ec19755e59bb67..aba2fdd514cc43a18281e349de0a63e378ad8264 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/Variant.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/Variant.h @@ -115,6 +115,9 @@ namespace armarx::aron::type /// get the full name of this specific type virtual std::string getFullName() const = 0; + /// the default string to set the corresponding data object from string + virtual std::string getDefaultFromString() const = 0; + /// get all child elements virtual std::vector<VariantPtr> getChildren() const = 0; virtual size_t childrenSize() const = 0; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/type/variant/container/Dict.cpp index 3919bf8447c76e594ca0873277b24626ae4d4ffb..c58669203698b39693ce57fd7e1b8efb4bfc03f8 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/Dict.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Dict.cpp @@ -80,6 +80,15 @@ namespace armarx::aron::type return "armarx::aron::type::Dict<" + acceptedType->getFullName() + ">"; } + std::string Dict::getDefaultFromString() const + { + std::stringstream ss; + ss << "{" << "\n"; + ss << "\t" << "\"key\": " << acceptedType->getDefaultFromString() << "\n"; + ss << "}"; + return ss.str(); + } + VariantPtr Dict::navigateAbsolute(const Path& path) const { if (!path.hasElement()) diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Dict.h b/source/RobotAPI/libraries/aron/core/type/variant/container/Dict.h index 4dfdd35e238b39b729d67c583ec9378fc19f5c0e..0c2e11ee5c58391e0ba2d0a349d5fe1d27071a71 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/Dict.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Dict.h @@ -56,6 +56,7 @@ namespace armarx::aron::type std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; std::vector<VariantPtr> getChildren() const override; size_t childrenSize() const override; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/List.cpp b/source/RobotAPI/libraries/aron/core/type/variant/container/List.cpp index 807d64fedf211b1d14949ece0409ab2baea952bb..d019192030891998cbb89c5de371357e6c0f6344 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/List.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/List.cpp @@ -80,6 +80,15 @@ namespace armarx::aron::type return "armarx::aron::type::List<" + acceptedType->getFullName() + ">"; } + std::string List::getDefaultFromString() const + { + std::stringstream ss; + ss << "[" << "\n"; + ss << "\t" << acceptedType->getDefaultFromString() << "\n"; + ss << "]"; + return ss.str(); + } + VariantPtr List::navigateAbsolute(const Path& path) const { if (!path.hasElement()) diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/List.h b/source/RobotAPI/libraries/aron/core/type/variant/container/List.h index 532146e010bf8217c4669649ee2da9771c0623ec..c739d069449fcbdcc599c0862f44148d806293d0 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/List.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/List.h @@ -55,6 +55,7 @@ namespace armarx::aron::type std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; std::vector<VariantPtr> getChildren() const override; size_t childrenSize() const override; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Object.cpp b/source/RobotAPI/libraries/aron/core/type/variant/container/Object.cpp index 52eb6ed43582ba24e780e6b170fd987ed710156e..ee9ab1195b302832d096e64e970f6811a840091a 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/Object.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Object.cpp @@ -197,6 +197,13 @@ namespace armarx::aron::type return "armarx::aron::type::Object<" + this->aron->objectName + (extends ? (" : " + extends->getFullName()) : "") + ">"; } + std::string Object::getDefaultFromString() const + { + std::stringstream ss; + ss << "TODO!"; + return ss.str(); + } + VariantPtr Object::navigateAbsolute(const Path& path) const { if (!path.hasElement()) diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Object.h b/source/RobotAPI/libraries/aron/core/type/variant/container/Object.h index 4c2f58738858024221e27ffd3bff014cefb54723..15a3273a0d7077af1d2ab313e45e13598b598229 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/Object.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Object.h @@ -72,6 +72,7 @@ namespace armarx::aron::type std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; std::vector<VariantPtr> getChildren() const override; size_t childrenSize() const override; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Pair.cpp b/source/RobotAPI/libraries/aron/core/type/variant/container/Pair.cpp index 48e0c6f4dea325fc7e58ecc0cede68cbb8138854..fb938e302a9fba89bd3be70c1643645db7b7e987 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/Pair.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Pair.cpp @@ -115,6 +115,13 @@ namespace armarx::aron::type return "armarx::aron::type::Pair<" + acceptedType1->getFullName() + ", " + acceptedType2->getFullName() + ">"; } + std::string Pair::getDefaultFromString() const + { + std::stringstream ss; + ss << "TODO!"; + return ss.str(); + } + VariantPtr Pair::navigateAbsolute(const Path& path) const { if (!path.hasElement()) diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Pair.h b/source/RobotAPI/libraries/aron/core/type/variant/container/Pair.h index a63f6819406ce2b328e97a4026aeae21127d7b09..9798548d0c95fea7a9568563d4191077cbaec90c 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/Pair.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Pair.h @@ -59,6 +59,7 @@ namespace armarx::aron::type std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; std::vector<VariantPtr> getChildren() const override; size_t childrenSize() const override; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.cpp b/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.cpp index 9fdca45e77972d2e58066e4fe47b0d9b492f9f44..c06d9d1c8ad61053240658f1786ddd8faf75e46a 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.cpp @@ -107,6 +107,13 @@ namespace armarx::aron::type return "armarx::aron::type::Tuple<" + simox::alg::to_string(names, ", ") + ">"; } + std::string Tuple::getDefaultFromString() const + { + std::stringstream ss; + ss << "TODO!"; + return ss.str(); + } + VariantPtr Tuple::navigateAbsolute(const Path& path) const { if (!path.hasElement()) diff --git a/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.h b/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.h index d464f83269d5074e1ec6e759119b433c76de0f7d..d17df06b74a59b83176424cbbdf6e23a4692d956 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/container/Tuple.h @@ -56,6 +56,7 @@ namespace armarx::aron::type std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; std::vector<VariantPtr> getChildren() const override; size_t childrenSize() const override; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/enum/IntEnum.cpp b/source/RobotAPI/libraries/aron/core/type/variant/enum/IntEnum.cpp index 734509d9e3272271c0ca3baece597c6e5b1b8d7a..d425e0af8bf802dc1aebc6f0ae4563bf626eb329 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/enum/IntEnum.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/enum/IntEnum.cpp @@ -111,5 +111,10 @@ namespace armarx::aron::type { return "armarx::aron::type::IntEnum"; } + + std::string IntEnum::getDefaultFromString() const + { + return "0"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/enum/IntEnum.h b/source/RobotAPI/libraries/aron/core/type/variant/enum/IntEnum.h index cf652d23cfb225d1ba4efde9c7d48af7c0e34966..1fd5661e3fde44db8d94d71db13383308e90aeab 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/enum/IntEnum.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/enum/IntEnum.h @@ -64,5 +64,6 @@ namespace armarx::aron::type // virtual implementations std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Image.cpp b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Image.cpp index b4efd4c8ca3a0e414460d4506f7db75f18865b01..4ea9d7c9333cc8bc646cc12a52bc713bf5a6bf68 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Image.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Image.cpp @@ -78,5 +78,9 @@ namespace armarx::aron::type return "armarx::aron::type::Image<" + Pixeltype2String.at(this->aron->pixelType) + ">"; } + std::string Image::getDefaultFromString() const + { + return "TODO!"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Image.h b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Image.h index 0b9f9dd0992c79187368a7136b7fa957a42cacae..e6bdee312e17b0800827301b26b983d1481b5f84 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Image.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Image.h @@ -53,6 +53,7 @@ namespace armarx::aron::type // virtual implementations std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; static const std::map<image::PixelType, std::string> Pixeltype2String; static const std::map<std::string, image::PixelType> String2Pixeltype; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.cpp b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.cpp index 62eabd986890eb92cd5bf9b050c887ff985da6d6..f471b23989280e2d479efbcc0910a69dec2dca8b 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.cpp @@ -104,5 +104,10 @@ namespace armarx::aron::type { return "armarx::aron::type::Matrix<" + std::to_string(this->aron->rows) + ", " + std::to_string(this->aron->cols) + ", " + Elementtype2String.at(this->aron->elementType) + ">"; } + + std::string Matrix::getDefaultFromString() const + { + return "TODO!"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.h b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.h index da9fd537dbcf62f9e17e54b9c42815009d408e8a..fa2a7cabe82c931d7b87ce377dd589edee132cc1 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Matrix.h @@ -57,6 +57,7 @@ namespace armarx::aron::type // virtual implementations std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; static const std::map<matrix::ElementType, std::string> Elementtype2String; static const std::map<std::string, matrix::ElementType> String2Elementtype; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/NDArray.cpp b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/NDArray.cpp index cbbf517ba53d9e3d50342298b1c34b2652662216..e30a71b2cdf544bf368918554a105b0c9cc14c71 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/NDArray.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/NDArray.cpp @@ -77,5 +77,10 @@ namespace armarx::aron::type { return "armarx::aron::type::NDArray"; } + + std::string NDArray::getDefaultFromString() const + { + return "TODO!"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/NDArray.h b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/NDArray.h index d04d218eb5ce19a1d53b8d1851b00d3a9ba7925a..b17f6f7ea68db4182db6ac83eddb96956e639dff 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/NDArray.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/NDArray.h @@ -56,5 +56,6 @@ namespace armarx::aron::type // virtual implementations std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Orientation.cpp b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Orientation.cpp index 031fd6f73e7d2f924d8723107325cb16c3b57d46..58b7f948c6b43465cd05671f0d1393d92ad1702c 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Orientation.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Orientation.cpp @@ -52,5 +52,10 @@ namespace armarx::aron::type { return "armarx::aron::type::Orientation"; } + + std::string Orientation::getDefaultFromString() const + { + return "TODO!"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Orientation.h b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Orientation.h index b4bebb8ca5e40d782681e88bed6f9bad30afd128..3a8107a261f2f6804e1e8f0a80de13acbef03a89 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Orientation.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Orientation.h @@ -50,5 +50,6 @@ namespace armarx::aron::type // virtual implementations std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/PointCloud.cpp b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/PointCloud.cpp index 10a3473021b616c78cc7e88b2e45dc94226663bb..8278b017d810244005e21b3c537d965e22136046 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/PointCloud.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/PointCloud.cpp @@ -75,5 +75,10 @@ namespace armarx::aron::type { return "armarx::aron::type::PointCloud<" + Voxeltype2String.at(this->aron->voxelType) + ">"; } + + std::string PointCloud::getDefaultFromString() const + { + return "TODO!"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/PointCloud.h b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/PointCloud.h index 37d3aacdbed11c396cdc7351f8e7077705f2e2a6..bec4627de7ecf9fa2b2fa707243773b4bf04f281 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/PointCloud.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/PointCloud.h @@ -54,6 +54,7 @@ namespace armarx::aron::type // virtual implementations std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; static const std::map<pointcloud::VoxelType, std::string> Voxeltype2String; static const std::map<std::string, pointcloud::VoxelType> String2Voxeltype; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Pose.cpp b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Pose.cpp index c6965c12ba714ef01242c4e1420a9579ec11aa4e..8ac9dc88699886788a58125198028d1abb81d363 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Pose.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Pose.cpp @@ -52,5 +52,15 @@ namespace armarx::aron::type { return "armarx::aron::type::Pose"; } + + std::string Pose::getDefaultFromString() const + { + std::stringstream ss; + ss << "0, 0, 0, 0" << "\n"; + ss << "0, 0, 0, 0" << "\n"; + ss << "0, 0, 0, 0" << "\n"; + ss << "0, 0, 0, 0"; + return ss.str(); + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Pose.h b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Pose.h index fa2c1f184799004ab64f875cfe3cb749d743b6c9..20037341ddb6b7928f907efbe5b48a4100c11df7 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Pose.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Pose.h @@ -50,5 +50,6 @@ namespace armarx::aron::type // virtual implementations std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Position.cpp b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Position.cpp index 68effb684d71d5745e02df03e4a396ac00cc2551..8a169dbf223c7431bf08860e982d85200ee23b0f 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Position.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Position.cpp @@ -52,5 +52,10 @@ namespace armarx::aron::type { return "armarx::aron::type::Position"; } + + std::string Position::getDefaultFromString() const + { + return "[0, 0, 0]"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Position.h b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Position.h index 427f0f43a6f5c32dd7b7d16950cbc301de3f309a..1ed5a040c521c942e56d412e6e5504d686b5120e 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Position.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Position.h @@ -50,5 +50,6 @@ namespace armarx::aron::type // virtual implementations std::string getShortName() const override; std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Quaternion.cpp b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Quaternion.cpp index 5457ee84421cc570dda07881070f6f9249359b73..4d439844fbefcdfda9567efc91eb5fdd651b85b8 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Quaternion.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Quaternion.cpp @@ -71,5 +71,10 @@ namespace armarx::aron::type { return "armarx::aron::type::Quaternion<" + Elementtype2String.at(this->aron->elementType) + ">"; } + + std::string Quaternion::getDefaultFromString() const + { + return "[0, 0, 0]"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Quaternion.h b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Quaternion.h index f660702be8c84613877d164763914bcf4cd57bc9..77f181907a092db2959738608da2aae133a2f932 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Quaternion.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/ndarray/Quaternion.h @@ -53,6 +53,7 @@ namespace armarx::aron::type // virtual implementations virtual std::string getShortName() const override; virtual std::string getFullName() const override; + std::string getDefaultFromString() const override; static const std::map<quaternion::ElementType, std::string> Elementtype2String; static const std::map<std::string, quaternion::ElementType> String2Elementtype; diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Bool.cpp b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Bool.cpp index 9eca559042cb6d38e575399b604e51f194f8aec7..4ab368a3472a5cadf07319d89ad23f55864dce0e 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Bool.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Bool.cpp @@ -57,4 +57,9 @@ namespace armarx::aron::type { return "armarx::aron::type::Bool"; } + + std::string Bool::getDefaultFromString() const + { + return "true|false"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Bool.h b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Bool.h index eac4aeaea068387ba065a98376a64212a2fc2307..104849a7146979ec9c54cadd98aafc8de7e3488f 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Bool.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Bool.h @@ -47,5 +47,6 @@ namespace armarx::aron::type /* virtual implementations */ virtual std::string getShortName() const override; virtual std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Double.cpp b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Double.cpp index 256e0a61fa70bb46f1580553de206f16ef2fbddd..9e2f558b3cb913b0bc71e3b78d2f3c2bae074a97 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Double.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Double.cpp @@ -57,4 +57,9 @@ namespace armarx::aron::type { return "armarx::aron::type::Double"; } + + std::string Double::getDefaultFromString() const + { + return "0.0"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Double.h b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Double.h index 17aa98ad764ac8081cfcd2e23aad38f388749d18..998a2cdf7a2063b94067416d002583a0f2937557 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Double.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Double.h @@ -47,5 +47,6 @@ namespace armarx::aron::type /* virtual implementations */ virtual std::string getShortName() const override; virtual std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Float.cpp b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Float.cpp index 3d08b5bdaae4aa689761bb181aee1d688e0dd8a2..f98587a18166c76f70d70d081b0de7d2ce1db2d1 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Float.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Float.cpp @@ -57,4 +57,9 @@ namespace armarx::aron::type { return "armarx::aron::type::Float"; } + + std::string Float::getDefaultFromString() const + { + return "0.0"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Float.h b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Float.h index 2dedfb1739b6f000baddc8bb13306781a3d34a99..77ff6e4a39f234a369646463fa19f3c8d5324efa 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Float.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Float.h @@ -47,5 +47,6 @@ namespace armarx::aron::type /* virtual implementations */ virtual std::string getShortName() const override; virtual std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Int.cpp b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Int.cpp index b371f53ddf1f82275d334e0752367e01fec57c93..511512cfda190fa912898990e1d8849a25f025ef 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Int.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Int.cpp @@ -57,4 +57,9 @@ namespace armarx::aron::type { return "armarx::aron::type::Int"; } + + std::string Int::getDefaultFromString() const + { + return "0"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Int.h b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Int.h index 240cd4a50df8687f8cdba2ff15c040d21ec27fbe..6a20a43a458c99649a6974aa4952ded887c27ebd 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Int.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Int.h @@ -47,5 +47,6 @@ namespace armarx::aron::type /* virtual implementations */ virtual std::string getShortName() const override; virtual std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Long.cpp b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Long.cpp index 2654a773d6f00f2552e7246007294baa161de1bf..9d945e717e5cc5bb155415694b370dafbab40273 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Long.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Long.cpp @@ -57,4 +57,9 @@ namespace armarx::aron::type { return "armarx::aron::type::Long"; } + + std::string Long::getDefaultFromString() const + { + return "0"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Long.h b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Long.h index 710df1a421e5ff684ac85b70839ff7cff513378e..eca05833e02c6732bb63aa68eefd473604dd49a1 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Long.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Long.h @@ -47,5 +47,6 @@ namespace armarx::aron::type /* virtual implementations */ virtual std::string getShortName() const override; virtual std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/String.cpp b/source/RobotAPI/libraries/aron/core/type/variant/primitive/String.cpp index 1cced6991fa157d23638241f1e012c2c0e7a4589..1ac6a3c0bc490be4959d145b58d414aeef1f71f4 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/String.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/String.cpp @@ -58,4 +58,9 @@ namespace armarx::aron::type { return "armarx::aron::type::String"; } + + std::string String::getDefaultFromString() const + { + return ""; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/String.h b/source/RobotAPI/libraries/aron/core/type/variant/primitive/String.h index 54dedab7b228d2262097d0cbe59675c4f721eb39..b5da234237a140b681e47445487a9f2ce46cdbb5 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/String.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/String.h @@ -47,5 +47,6 @@ namespace armarx::aron::type /* virtual implementations */ virtual std::string getShortName() const override; virtual std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Time.cpp b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Time.cpp index 76ba1e55c0c2d7d65c12760e6c66ef725ffbbd5c..1a0e19d856c85ece58c792b31df8ef1a87c10ae6 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Time.cpp +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Time.cpp @@ -58,4 +58,9 @@ namespace armarx::aron::type { return "armarx::aron::type::Time"; } + + std::string Time::getDefaultFromString() const + { + return "0"; + } } diff --git a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Time.h b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Time.h index bd92b965d9c280979732d1f8d54389153a13573f..d460e792132d6cb759b4457c82f40cceb1ef6aa3 100644 --- a/source/RobotAPI/libraries/aron/core/type/variant/primitive/Time.h +++ b/source/RobotAPI/libraries/aron/core/type/variant/primitive/Time.h @@ -47,5 +47,6 @@ namespace armarx::aron::type /* virtual implementations */ virtual std::string getShortName() const override; virtual std::string getFullName() const override; + std::string getDefaultFromString() const override; }; } diff --git a/source/RobotAPI/libraries/aron/core/typereader/xml/Factory.cpp b/source/RobotAPI/libraries/aron/core/typereader/xml/Factory.cpp index 3d2ba252cbff89b33c88034093207db0780f808c..da30a7e70d7996e4b53970f7ee44299560ef08c1 100644 --- a/source/RobotAPI/libraries/aron/core/typereader/xml/Factory.cpp +++ b/source/RobotAPI/libraries/aron/core/typereader/xml/Factory.cpp @@ -96,9 +96,8 @@ namespace armarx::aron::typereader::xml } } - type::VariantPtr ReaderFactory::findExistingObject(const std::string& n) const + type::VariantPtr ReaderFactory::findExistingObject(const std::string& name) const { - auto name = simox::alg::to_lower(n); const auto public_intenum_it = AllGeneratedPublicIntEnums.find(name); if (public_intenum_it != AllGeneratedPublicIntEnums.end()) { @@ -198,12 +197,12 @@ namespace armarx::aron::typereader::xml if (extends != "") { - auto parentObj = type::Object::DynamicCastAndCheck(findExistingObject(simox::alg::to_lower(extends))); + auto parentObj = type::Object::DynamicCastAndCheck(findExistingObject(extends)); aronObjectType->setExtends(parentObj); } newObject.correspondingType = aronObjectType; - AllGeneratedPublicObjects.emplace(simox::alg::to_lower(newObject.typeName), newObject); + AllGeneratedPublicObjects.emplace(newObject.typeName, newObject); return aronObjectType; } @@ -460,7 +459,7 @@ namespace armarx::aron::typereader::xml auto o = std::make_shared<type::IntEnum>(name, acceptedValues, path); newEnumInfo.correspondingType = o; - AllGeneratedPublicIntEnums.emplace(simox::alg::to_lower(newEnumInfo.typeName), newEnumInfo); + AllGeneratedPublicIntEnums.emplace(newEnumInfo.typeName, newEnumInfo); return o; diff --git a/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.cpp b/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.cpp index 33ef52d8fb5f7cf1405a2c60361dacca7c7bf3bc..a8f2f0cc48ca7eca0354fe9782e425ebeb2fea05 100644 --- a/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.cpp +++ b/source/RobotAPI/libraries/aron/core/typereader/xml/Reader.cpp @@ -125,14 +125,14 @@ namespace armarx::aron::typereader::xml if (util::HasTagName(generateType, constantes::OBJECT_TAG)) { const auto nav = readGenerateObject(generateType); - generateObjects.push_back(factory.AllGeneratedPublicObjects.at(simox::alg::to_lower(nav->getObjectName()))); + generateObjects.push_back(factory.AllGeneratedPublicObjects.at(nav->getObjectName())); continue; } if (util::HasTagName(generateType, constantes::INT_ENUM_TAG)) { const auto nav = readGenerateIntEnum(generateType); - generateIntEnums.push_back(factory.AllGeneratedPublicIntEnums.at(simox::alg::to_lower(nav->getEnumName()))); + generateIntEnums.push_back(factory.AllGeneratedPublicIntEnums.at(nav->getEnumName())); continue; } throw error::ValueNotValidException("XMLReader", "parse", "Could not find a valid tag inside generatetypes", generateType.name()); diff --git a/source/RobotAPI/libraries/skills/CMakeLists.txt b/source/RobotAPI/libraries/skills/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..21406094ee27a92de936a9d2844eef0100f46020 --- /dev/null +++ b/source/RobotAPI/libraries/skills/CMakeLists.txt @@ -0,0 +1,36 @@ +set(LIB_NAME skills) + +armarx_component_set_name("${LIB_NAME}") +armarx_set_target("Library: ${LIB_NAME}") + +armarx_add_library( + LIBS + ArmarXCoreInterfaces + ArmarXCore + ArmarXCoreObservers + + RobotAPI::Core + aronjsonconverter + SOURCES + ./manager/SkillManagerComponentPlugin.cpp + ./provider/SkillProviderComponentPlugin.cpp + ./provider/Skill.cpp + ./provider/SpecializedSkill.cpp + ./provider/SkillDescription.cpp + ./provider/SkillParameterization.cpp + ./provider/SkillStatusUpdate.cpp + ./provider/helper/LambdaSkillImplementation.cpp + ./provider/detail/SkillImplementationWrapper.cpp + HEADERS + ./manager/SkillManagerComponentPlugin.h + ./provider/SkillProviderComponentPlugin.h + ./provider/Skill.h + ./provider/SpecializedSkill.h + ./provider/SkillDescription.h + ./provider/SkillParameterization.h + ./provider/SkillStatusUpdate.h + ./provider/helper/LambdaSkillImplementation.h + ./provider/detail/SkillImplementationWrapper.h +) + +add_library(RobotAPI::skills ALIAS skills) diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..038ed5999e34f691c2c2c6d1b12400471726deb1 --- /dev/null +++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp @@ -0,0 +1,73 @@ +#include "SkillManagerComponentPlugin.h" + +#include <ArmarXCore/core/Component.h> + +namespace armarx::plugins +{ + void SkillManagerComponentPlugin::preOnInitComponent() + {} + + void SkillManagerComponentPlugin::preOnConnectComponent() + {} + + void SkillManagerComponentPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) + {} +} + + +namespace armarx +{ + SkillManagerComponentPluginUser::SkillManagerComponentPluginUser() + { + addPlugin(plugin); + } + + void SkillManagerComponentPluginUser::addProvider(const skills::manager::dto::ProviderInfo& info, const Ice::Current&) + { + std::lock_guard l(skillProviderMapMutex); + if (skillProviderMap.find(info.providerName) == skillProviderMap.end()) + { + ARMARX_INFO << "Adding a provider with name '" << info.providerName << "'."; + skillProviderMap.insert({info.providerName, info.provider}); + } + } + + void SkillManagerComponentPluginUser::removeProvider(const std::string& providerName, const Ice::Current&) + { + std::lock_guard l(skillProviderMapMutex); + if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end()) + { + skillProviderMap.erase(it); + } + } + + skills::provider::dti::SkillProviderMap SkillManagerComponentPluginUser::getSkillProviders(const Ice::Current&) + { + return skillProviderMap; + } + + void SkillManagerComponentPluginUser::executeSkill(const skills::manager::dto::SkillExecutionInfo& info, const Ice::Current&) + { + if (auto it = skillProviderMap.find(info.providerName); it != skillProviderMap.end()) + { + skills::callback::dti::SkillProviderCallbackInterfacePrx myPrx; + getProxy(myPrx, -1); + + skills::provider::dto::SkillExecutionInfo exInfo; + exInfo.skillName = info.skillName; + exInfo.callbackInterface = myPrx; + exInfo.parameterization = info.parameterization; + it->second->executeSkill(exInfo); + } + else + { + throw LocalException("Could not execute a skill of provider '" + info.providerName + "' because the provider does not exist."); + } + } + + void SkillManagerComponentPluginUser::updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& statusUpdate, const Ice::Current&) + { + (void) statusUpdate; + // If you want to use the status, implement this method! + } +} diff --git a/source/RobotAPI/libraries/armem_skills/server/SkillManagerComponentPlugin.h b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h similarity index 60% rename from source/RobotAPI/libraries/armem_skills/server/SkillManagerComponentPlugin.h rename to source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h index 8e976fbf033b2a400f890974166e84e27049c8f1..6fd40f3eb99345a837161c5ffced3161889c28b6 100644 --- a/source/RobotAPI/libraries/armem_skills/server/SkillManagerComponentPlugin.h +++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h @@ -26,16 +26,16 @@ namespace armarx { class SkillManagerComponentPluginUser : virtual public ManagedIceObject, - virtual public skills::SkillManagerInterface + virtual public skills::manager::dti::SkillManagerInterface { public: SkillManagerComponentPluginUser(); - void addProvider(const std::string&, const skills::SkillProviderInterfacePrx& provider, const Ice::Current ¤t) override; + void addProvider(const skills::manager::dto::ProviderInfo& providerInfo, const Ice::Current ¤t) override; void removeProvider(const std::string&, const Ice::Current ¤t) override; - skills::SkillProviderMap getSkillProviders(const Ice::Current ¤t) override; - void executeSkill(const std::string&, const skills::SkillParametrization& params, const Ice::Current ¤t) override; - void updateStatusForSkill(const std::string& providerName, const skills::SkillStatus& statusUpdate, const Ice::Current ¤t) override; + skills::provider::dti::SkillProviderMap getSkillProviders(const Ice::Current ¤t) override; + void executeSkill(const skills::manager::dto::SkillExecutionInfo& info, const Ice::Current ¤t) override; + void updateStatusForSkill(const skills::provider::dto::SkillStatusUpdate& update, const Ice::Current ¤t) override; private: @@ -43,6 +43,6 @@ namespace armarx protected: std::mutex skillProviderMapMutex; - skills::SkillProviderMap skillProviderMap; + skills::provider::dti::SkillProviderMap skillProviderMap; }; } diff --git a/source/RobotAPI/libraries/skills/provider/Skill.cpp b/source/RobotAPI/libraries/skills/provider/Skill.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5cac4402ff144b92bde79a2464a50f7b48e8b4ad --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/Skill.cpp @@ -0,0 +1,38 @@ +#include "Skill.h" + +namespace armarx +{ + namespace skills + { + Skill::Skill() + { + // replace constructor if you want to have a specific logging tag + Logging::setTag("armarx::skills::Skill"); + } + + Skill::Status Skill::execute(const aron::data::DictPtr& params, const CallbackT& callback) + { + (void) params; + + ARMARX_WARNING_S << "You have to override this method!"; + return Status::Succeeded; + } + + void Skill::reset() + { + stopped = false; + timeoutReached = false; + } + + void Skill::notifyStopped() + { + stopped = true; + } + + void Skill::notifyTimeoutReached() + { + timeoutReached = true; + } + + } +} diff --git a/source/RobotAPI/libraries/skills/provider/Skill.h b/source/RobotAPI/libraries/skills/provider/Skill.h new file mode 100644 index 0000000000000000000000000000000000000000..f4ed57787e770a3b7f842e575331778e0d44e199 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/Skill.h @@ -0,0 +1,49 @@ +#pragma once + +#include <mutex> +#include <queue> +#include <thread> +#include <functional> + +#include <ArmarXCore/core/ComponentPlugin.h> +#include <ArmarXCore/core/ManagedIceObject.h> + +#include <ArmarXCore/core/services/tasks/RunningTask.h> + +#include <RobotAPI/interface/skills/SkillManagerInterface.h> +#include <RobotAPI/libraries/aron/core/data/variant/All.h> + +namespace armarx +{ + namespace skills + { + class Skill : public armarx::Logging + { + public: + using CallbackT = std::function<void(const aron::data::DictPtr&)>; + + enum class Status + { + Succeeded, + TimeoutReached, + Failed + }; + + Skill(); + virtual ~Skill() = default; + + virtual void notifyStopped(); + virtual void notifyTimeoutReached(); + + /// Override this method with the actual implementation. The callback is for status updates to the calling instance to the calling instance + virtual Status execute(const aron::data::DictPtr& params, const CallbackT& callback = [](const aron::data::DictPtr& returnValue) { (void) returnValue; }); + + /// Reset all parameters before starting a skill. Override if you have special members that needs to be resetted + virtual void reset(); + + protected: + std::atomic_bool stopped = false; + std::atomic_bool timeoutReached = false; + }; + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SkillDescription.cpp b/source/RobotAPI/libraries/skills/provider/SkillDescription.cpp new file mode 100644 index 0000000000000000000000000000000000000000..844249f0e46f5075d044ed0bb4bb8cffc75b0846 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SkillDescription.cpp @@ -0,0 +1,21 @@ +#include "SkillDescription.h" + +namespace armarx +{ + namespace skills + { + provider::dto::SkillDescription SkillDescription::toIce() const + { + provider::dto::SkillDescription ret; + if (acceptedType) + { + ret.acceptedType = acceptedType->toObjectDTO(); + } + ret.description = description; + ret.skillName = skillName; + ret.targets = targets; + ret.timeoutMs = timeoutMs; + return ret; + } + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SkillDescription.h b/source/RobotAPI/libraries/skills/provider/SkillDescription.h new file mode 100644 index 0000000000000000000000000000000000000000..2bf9707c25fe61df7a0d5a3ba3b6448d91814098 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SkillDescription.h @@ -0,0 +1,24 @@ +#pragma once + +#include <string> +#include <vector> + +#include <RobotAPI/interface/skills/SkillProviderInterface.h> +#include <RobotAPI/libraries/aron/core/type/variant/container/Object.h> + +namespace armarx +{ + namespace skills + { + struct SkillDescription + { + std::string skillName; + std::string description; + std::vector<std::string> targets; + long timeoutMs; + aron::type::ObjectPtr acceptedType; + + provider::dto::SkillDescription toIce() const; + }; + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SkillParameterization.cpp b/source/RobotAPI/libraries/skills/provider/SkillParameterization.cpp new file mode 100644 index 0000000000000000000000000000000000000000..222c860e47082fc8ea812ac90979738dcf7feb10 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SkillParameterization.cpp @@ -0,0 +1,17 @@ +#include "SkillParameterization.h" + +namespace armarx +{ + namespace skills + { + provider::dto::SkillParameterization SkillParameterization::toIce() const + { + provider::dto::SkillParameterization ret; + if (params) + { + ret.params = params->toAronDictPtr(); + } + return ret; + } + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SkillParameterization.h b/source/RobotAPI/libraries/skills/provider/SkillParameterization.h new file mode 100644 index 0000000000000000000000000000000000000000..b42c0e927e2bddf1db91cfc0c54c7f3383ce452a --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SkillParameterization.h @@ -0,0 +1,20 @@ +#pragma once + +#include <string> +#include <vector> + +#include <RobotAPI/interface/skills/SkillProviderInterface.h> +#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> + +namespace armarx +{ + namespace skills + { + struct SkillParameterization + { + aron::data::DictPtr params; + + provider::dto::SkillParameterization toIce() const; + }; + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..321273b10e2228efe206fd0424a40d0215a0fbfb --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.cpp @@ -0,0 +1,171 @@ +#include "SkillProviderComponentPlugin.h" + +#include <ArmarXCore/core/Component.h> + +#include <RobotAPI/libraries/aron/core/data/variant/primitive/All.h> + +namespace armarx::plugins +{ + void SkillProviderComponentPlugin::preOnInitComponent() + { + + } + + void SkillProviderComponentPlugin::preOnConnectComponent() + { + auto& p = parent<SkillProviderComponentPluginUser>(); + p.getProxy(myPrx, -1); + } + + void SkillProviderComponentPlugin::postOnConnectComponent() + { + auto& p = parent<SkillProviderComponentPluginUser>(); + std::string providerName = p.getName(); + + skills::manager::dto::ProviderInfo i; + i.provider = myPrx; + i.providerName = providerName; + i.providedSkills = p.getSkills(); + skillManager->addProvider(i); + } + + void SkillProviderComponentPlugin::preOnDisconnectComponent() + { + auto& p = parent<SkillProviderComponentPluginUser>(); + std::string providerName = p.getName(); + + skillManager->removeProvider(providerName); + } + + void SkillProviderComponentPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) + { + std::string prefix = "skill."; + properties->component(skillManager, "SkillMemory", prefix + "SkillManager", "The name of the SkillManager (or SkillMemory) proxy."); + } +} + + +namespace armarx +{ + SkillProviderComponentPluginUser::SkillProviderComponentPluginUser() + { + addPlugin(plugin); + } + + void SkillProviderComponentPluginUser::addSkill(const std::shared_ptr<skills::Skill>& skill, const skills::SkillDescription& desc) + { + std::lock_guard l(skillsMutex); + std::string skillName = desc.skillName; + + if (skillImplementations.find(skillName) != skillImplementations.end()) + { + ARMARX_WARNING << "Try to add a skill '" + skillName + "' which already exists in list. Ignore this skill."; + return; + } + + ARMARX_DEBUG << "Adding skill " << skillName << " to list"; + skills::detail::SkillImplementationWrapper s(desc, skill); + skillImplementations.insert({skillName, s}); + } + + void SkillProviderComponentPluginUser::addSkill(const skills::helper::LambdaSkill::FunT& f, const skills::SkillDescription& desc) + { + auto lambda = std::make_shared<skills::helper::LambdaSkill>(f); + addSkill(lambda, desc); + } + + skills::provider::dto::SkillDescriptionMap SkillProviderComponentPluginUser::getSkills(const Ice::Current ¤t) + { + std::lock_guard l(skillsMutex); + skills::provider::dto::SkillDescriptionMap skillDesciptions; + for (const auto& [key, skillImplementation] : skillImplementations) + { + skillDesciptions.insert({key, skillImplementation.description.toIce()}); + } + return skillDesciptions; + } + + skills::provider::dto::SkillStatusUpdate SkillProviderComponentPluginUser::getSkillExecutionStatus(const std::string& skill, const Ice::Current ¤t) + { + std::lock_guard l(skillsMutex); + auto& skillImplementation = skillImplementations.at(skill); + + std::lock_guard l2(skillImplementation.statusInfo.skillStatusMutex); + return skillImplementation.statusInfo.statusUpdate.toIce(); + } + + void SkillProviderComponentPluginUser::executeSkill(const skills::provider::dto::SkillExecutionInfo& info, const Ice::Current ¤t) + { + std::lock_guard l(skillsMutex); + std::string skillName = info.skillName; + ARMARX_CHECK_EXPRESSION(skillImplementations.count(skillName) > 0); + + auto& impl = skillImplementations.at(skillName); + + if (impl.task.joinable()) + { + impl.task.join(); + } + if (impl.timeoutCheck.joinable()) + { + impl.timeoutCheck.join(); + } + if (impl.stoppedCheck.joinable()) + { + impl.stoppedCheck.join(); + } + + // update input params + impl.reset(); + impl.statusInfo.statusUpdate.usedCallbackInterface = info.callbackInterface; + impl.statusInfo.statusUpdate.skillName = info.skillName; + impl.statusInfo.statusUpdate.providerName = getName(); + if (info.parameterization.params) + { + impl.statusInfo.statusUpdate.usedParameterization.params = std::make_shared<aron::data::Dict>(info.parameterization.params); + } + + // make sure thread is started + impl.statusInfo.started = true; + + // recreate thread and execute skill + impl.timeoutCheck = std::thread{ [&](){ impl.constantlyCheckForTimeoutReached();}}; + impl.stoppedCheck = std::thread{ [&](){ impl.constantlyCheckForStopped();}}; + impl.task = std::thread{ [&] { impl.execute();}}; + } + + skills::provider::dto::SkillStatusUpdate SkillProviderComponentPluginUser::abortSkill(const std::string& skillName, const Ice::Current ¤t) + { + std::lock_guard l(skillsMutex); + ARMARX_CHECK_EXPRESSION(skillImplementations.count(skillName) > 0); + + auto& impl = skillImplementations.at(skillName); + auto& statusInfo = impl.statusInfo; + + std::lock_guard l2(statusInfo.skillStatusMutex); + auto& statusUpdate = statusInfo.statusUpdate; + + impl.statusInfo.stopped = true; + impl.statusInfo.started = false; + if (impl.task.joinable()) + { + impl.task.join(); + } + if (impl.timeoutCheck.joinable()) + { + impl.timeoutCheck.join(); + } + if (impl.stoppedCheck.joinable()) + { + impl.stoppedCheck.join(); + } + + if (statusUpdate.status != skills::provider::dto::ExecutionStatus::Succeeded && + statusUpdate.status != skills::provider::dto::ExecutionStatus::Failed) + { + impl.statusInfo.statusUpdate.status = skills::provider::dto::ExecutionStatus::Aborted; + } + + return statusUpdate.toIce(); + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h new file mode 100644 index 0000000000000000000000000000000000000000..14b3ce55ec587254aa8d2627231266453ac9d4f3 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SkillProviderComponentPlugin.h @@ -0,0 +1,66 @@ +#pragma once + +#include <mutex> +#include <queue> +#include <thread> +#include <functional> + +#include <ArmarXCore/core/ComponentPlugin.h> +#include <ArmarXCore/core/ManagedIceObject.h> + +#include <ArmarXCore/core/services/tasks/RunningTask.h> + +#include <RobotAPI/interface/skills/SkillManagerInterface.h> +#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> + +#include "helper/LambdaSkillImplementation.h" +#include "detail/SkillImplementationWrapper.h" + +namespace armarx::plugins +{ + class SkillProviderComponentPlugin : public ComponentPlugin + { + public: + using ComponentPlugin::ComponentPlugin; + + void preOnInitComponent() override; + + void preOnConnectComponent() override; + void postOnConnectComponent() override; + + void postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) override; + + void preOnDisconnectComponent() override; + + private: + skills::manager::dti::SkillManagerInterfacePrx skillManager; + skills::provider::dti::SkillProviderInterfacePrx myPrx; + }; +} + +namespace armarx +{ + class SkillProviderComponentPluginUser : + virtual public ManagedIceObject, + virtual public skills::provider::dti::SkillProviderInterface + { + public: + SkillProviderComponentPluginUser(); + + skills::provider::dto::SkillDescriptionMap getSkills(const Ice::Current ¤t = Ice::Current()) override; + skills::provider::dto::SkillStatusUpdate getSkillExecutionStatus(const std::string& skill, const Ice::Current ¤t = Ice::Current()) override; + void executeSkill(const skills::provider::dto::SkillExecutionInfo& executionInfo, const Ice::Current ¤t = Ice::Current()) override; + skills::provider::dto::SkillStatusUpdate abortSkill(const std::string &skill, const Ice::Current ¤t = Ice::Current()) override; + + protected: + void addSkill(const skills::helper::LambdaSkill::FunT&, const skills::SkillDescription&); + void addSkill(const std::shared_ptr<skills::Skill>&, const skills::SkillDescription&); + + private: + armarx::plugins::SkillProviderComponentPlugin* plugin = nullptr; + + protected: + mutable std::mutex skillsMutex; + std::map<std::string, skills::detail::SkillImplementationWrapper> skillImplementations; + }; +} diff --git a/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.cpp b/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c55eaf973e7d7e8c833e11f23351894c45c630d2 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.cpp @@ -0,0 +1,22 @@ +#include "SkillStatusUpdate.h" + +namespace armarx +{ + namespace skills + { + provider::dto::SkillStatusUpdate SkillStatusUpdate::toIce() const + { + provider::dto::SkillStatusUpdate ret; + ret.providerName = providerName; + ret.skillName = skillName; + if (data) + { + ret.data = data->toAronDictPtr(); + } + ret.status = status; + ret.usedCallbackInterface = usedCallbackInterface; + ret.usedParameterization = usedParameterization.toIce(); + return ret; + } + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.h b/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.h new file mode 100644 index 0000000000000000000000000000000000000000..439adf1150fe472b83af8aba81e33039be57d3b1 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SkillStatusUpdate.h @@ -0,0 +1,26 @@ +#pragma once + +#include <string> +#include <vector> + +#include "SkillParameterization.h" + +#include <RobotAPI/interface/skills/SkillProviderInterface.h> + +namespace armarx +{ + namespace skills + { + struct SkillStatusUpdate + { + std::string providerName; + std::string skillName; + SkillParameterization usedParameterization; + callback::dti::SkillProviderCallbackInterfacePrx usedCallbackInterface; + provider::dto::ExecutionStatus status; + aron::data::DictPtr data; + + provider::dto::SkillStatusUpdate toIce() const; + }; + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SpecializedSkill.cpp b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9a42436eadec5f4c9297830ea31de73e19446d2 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.cpp @@ -0,0 +1,9 @@ +#include "SpecializedSkill.h" + +namespace armarx +{ + namespace skills + { + + } +} diff --git a/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h new file mode 100644 index 0000000000000000000000000000000000000000..f4107af41c8fd2ae111845507c2700d814047142 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/SpecializedSkill.h @@ -0,0 +1,35 @@ +#pragma once + +#include "Skill.h" + +namespace armarx +{ + namespace skills + { + template <class AronT> + class SpecializedSkill : public Skill + { + public: + SpecializedSkill(); + virtual ~SpecializedSkill() = default; + + /// Override this method with the actual implementation. The callback is for status updates to the calling instance to the calling instance + virtual Status execute(const AronT& params, const CallbackT& callback = [](const aron::data::DictPtr& returnValue) { (void) returnValue; }) + { + (void) params; + + ARMARX_WARNING_S << "You have to override this method!"; + return Status::Succeeded; + } + + /// Do not use anymore + Status execute(const aron::data::DictPtr& params, const CallbackT& callback = [](const aron::data::DictPtr& returnValue) { (void) returnValue; }) final + { + AronT p; + p.fromAron(params); + + return execute(p, callback); + } + }; + } +} diff --git a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09ecd676ca321cdbbc705cef431646cc0b7a931f --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.cpp @@ -0,0 +1,130 @@ +#include "SkillImplementationWrapper.h" + +namespace armarx +{ + namespace skills::detail + { + void SkillImplementationWrapper::constantlyCheckForTimeoutReached() const + { + while(statusInfo.started) + { + if (isTimeoutReached()) + { + skill->notifyTimeoutReached(); + break; // only notify once? + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + void SkillImplementationWrapper::constantlyCheckForStopped() const + { + while(statusInfo.started) + { + if (statusInfo.stopped) + { + skill->notifyStopped(); + break; // only notify once? + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + void SkillImplementationWrapper::reset() + { + std::lock_guard l(statusInfo.skillStatusMutex); + statusInfo.started = false; + statusInfo.stopped = false; + statusInfo.statusUpdate.status = skills::provider::dto::ExecutionStatus::Idle; + statusInfo.statusUpdate.data = nullptr; + skillStarted = IceUtil::Time::now().toMilliSeconds(); + skill->reset(); + } + + void SkillImplementationWrapper::execute() + { + ARMARX_INFO_S << "Executing skill: " << description.skillName; + statusInfo.started = true; + + // get params and setup variables + auto& aron_params = statusInfo.statusUpdate.usedParameterization.params; + if (not(aron_params) && description.acceptedType) + { + throw armarx::LocalException("The Skill '" + description.skillName + "' requires a type but no params are NULL."); + } + + try + { + // set scheduled + { + std::lock_guard l(statusInfo.skillStatusMutex); + statusInfo.statusUpdate.status = skills::provider::dto::ExecutionStatus::Scheduled; + + // do callback + updateStatusCallback(); + } + + + // execute + { + std::lock_guard l(statusInfo.skillStatusMutex); + statusInfo.statusUpdate.status = skills::provider::dto::ExecutionStatus::Running; + updateStatusCallback(); + } + + auto result = skill->execute(aron_params, [&](const aron::data::DictPtr& update) + { + statusInfo.statusUpdate.data = update; + updateStatusCallback(); + } + ); + + if (result == skills::Skill::Status::Failed) + { + throw armarx::LocalException("The Skill '"+description.skillName+"' failed during execution."); + } + if (result == skills::Skill::Status::TimeoutReached) + { + throw armarx::LocalException("The Skill '"+description.skillName+"' reached timeout during execution."); + } + + { + std::lock_guard l(statusInfo.skillStatusMutex); + statusInfo.statusUpdate.status = skills::provider::dto::ExecutionStatus::Succeeded; + updateStatusCallback(); + } + } + catch (const std::exception& ex) + { + ARMARX_WARNING_S << "Skill " << description.skillName << " died with exception:\n" << ex.what(); + + std::lock_guard l(statusInfo.skillStatusMutex); + statusInfo.statusUpdate.status = skills::provider::dto::ExecutionStatus::Failed; + updateStatusCallback(); + } + + statusInfo.started = false; + } + + bool SkillImplementationWrapper::isTimeoutReached() const + { + if (description.timeoutMs < 0) + { + return false; + } + + auto now = IceUtil::Time::now().toMilliSeconds(); + return (now - skillStarted) >= description.timeoutMs; + } + + void SkillImplementationWrapper::updateStatusCallback() const + { + auto& callbackInterface = statusInfo.statusUpdate.usedCallbackInterface; + + if (callbackInterface) + { + callbackInterface->updateStatusForSkill(statusInfo.statusUpdate.toIce()); + } + } + } +} diff --git a/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..24a8637b44f634734e8ffba20809ecadf9a493ce --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/detail/SkillImplementationWrapper.h @@ -0,0 +1,63 @@ +#pragma once + +#include "../SkillDescription.h" +#include "../SkillStatusUpdate.h" +#include "../Skill.h" + +#include <RobotAPI/interface/skills/SkillManagerInterface.h> + +namespace armarx +{ + namespace skills + { + namespace detail + { + class SkillImplementationWrapper + { + public: + // fixed values. Do not change after skill instantiation + const SkillDescription description; + const std::shared_ptr<Skill> skill; + + // Current execution status. Changes during execution + // The status also holds the used parameterization + struct StatusInfo + { + mutable std::mutex skillStatusMutex; + std::atomic_bool started; + std::atomic_bool stopped; + SkillStatusUpdate statusUpdate; + } statusInfo; + + // Task information. task is recreated every time the skill restarts + std::thread task; + std::thread timeoutCheck; + std::thread stoppedCheck; + + SkillImplementationWrapper(const skills::SkillDescription& desc, const std::shared_ptr<skills::Skill> skill) : + description(desc), skill(skill) + { + reset(); + } + + SkillImplementationWrapper(const SkillImplementationWrapper& s) : + SkillImplementationWrapper(s.description, s.skill) + {} + + void execute(); + void reset(); + + // checks for interrupts + void constantlyCheckForTimeoutReached() const; + void constantlyCheckForStopped() const; + + protected: + bool isTimeoutReached() const; + void updateStatusCallback() const; + + private: + long skillStarted = 0; + }; + } + } +} diff --git a/source/RobotAPI/libraries/skills/provider/helper/LambdaSkillImplementation.cpp b/source/RobotAPI/libraries/skills/provider/helper/LambdaSkillImplementation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9b761b403f51552235b690d601137ff1c11a002b --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/helper/LambdaSkillImplementation.cpp @@ -0,0 +1,15 @@ +#include "LambdaSkillImplementation.h" + +namespace armarx +{ + namespace skills::helper + { + + Skill::Status LambdaSkill::execute(const aron::data::DictPtr& data, const CallbackT& callback) + { + (void) callback; + bool res = fun(data); + return res ? Status::Succeeded : Status::Failed; + } + } +} diff --git a/source/RobotAPI/libraries/skills/provider/helper/LambdaSkillImplementation.h b/source/RobotAPI/libraries/skills/provider/helper/LambdaSkillImplementation.h new file mode 100644 index 0000000000000000000000000000000000000000..bb422b1bda029935f54ac94bd7cca0289ac799e0 --- /dev/null +++ b/source/RobotAPI/libraries/skills/provider/helper/LambdaSkillImplementation.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../Skill.h" + +namespace armarx +{ + namespace skills::helper + { + class LambdaSkill : public Skill + { + public: + using FunT = std::function<bool(const aron::data::DictPtr&)>; + + LambdaSkill() = delete; + LambdaSkill(const FunT& f) : fun(f) {}; + + Skill::Status execute(const aron::data::DictPtr& data, const CallbackT& callback = [](const aron::data::DictPtr& returnValue) { (void) returnValue; }) override; + + private: + FunT fun; + }; + } +}