diff --git a/source/RobotAPI/components/SkillObserver/SkillObserver.h b/source/RobotAPI/components/SkillObserver/SkillObserver.h index 54fc0ca89f9d57cba62f2a5ca2a65b452db3d8ca..b9f927312888048a01bedcfdc53dadce6b6902ba 100644 --- a/source/RobotAPI/components/SkillObserver/SkillObserver.h +++ b/source/RobotAPI/components/SkillObserver/SkillObserver.h @@ -24,6 +24,10 @@ #include <mutex> #include <thread> +#include <string> +#include <vector> +#include <mutex> +#include <map> #include <ArmarXCore/core/Component.h> diff --git a/source/RobotAPI/components/armem/server/CMakeLists.txt b/source/RobotAPI/components/armem/server/CMakeLists.txt index 48313a312edc1c6d4e6c19ee18f62e4f3072d87f..824eaa4937df6f7f06fa2d5ce7144020feb6097f 100644 --- a/source/RobotAPI/components/armem/server/CMakeLists.txt +++ b/source/RobotAPI/components/armem/server/CMakeLists.txt @@ -3,3 +3,5 @@ add_subdirectory(GeneralPurposeMemory) add_subdirectory(ObjectMemory) add_subdirectory(RobotStateMemory) add_subdirectory(SkillsMemory) +#add_subdirectory(SubjectMemory) +add_subdirectory(MotionMemory) diff --git a/source/RobotAPI/components/armem/server/MotionMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/MotionMemory/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..10c1fe81155dcfd44d499809b5940e0c7bb41193 --- /dev/null +++ b/source/RobotAPI/components/armem/server/MotionMemory/CMakeLists.txt @@ -0,0 +1,26 @@ +armarx_component_set_name("MotionMemory") + +armarx_add_component( + LIBS + ArmarXCore + ArmarXCoreInterfaces + ArmarXGuiComponentPlugins + RobotAPICore + RobotAPIInterfaces + RobotAPI::ArMem + RobotAPI::ArMemMotions + SOURCES + MotionMemory.cpp + HEADERS + MotionMemory.h +) + + +# add unit tests +add_subdirectory(test) + +#generate the application +armarx_generate_and_add_component_executable() + + + diff --git a/source/RobotAPI/components/armem/server/MotionMemory/MotionMemory.cpp b/source/RobotAPI/components/armem/server/MotionMemory/MotionMemory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef176a8ffe85af763135febb8ac3af45f317af4f --- /dev/null +++ b/source/RobotAPI/components/armem/server/MotionMemory/MotionMemory.cpp @@ -0,0 +1,76 @@ +/* + * 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::ArmarXObjects::ExampleMemory + * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include "MotionMemory.h" + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + +#include <SimoxUtility/algorithm/string.h> + +#include <RobotAPI/libraries/armem/core/error.h> + + +namespace armarx +{ + armarx::PropertyDefinitionsPtr MotionMemory::createPropertyDefinitions() + { + armarx::PropertyDefinitionsPtr defs = new ComponentPropertyDefinitions(getConfigIdentifier()); + + const std::string prefix = "mem."; + defs->optional(memoryName, prefix + "MemoryName", "Name of this memory (server)."); + mdbMotions.defineProperties(defs, prefix + "mdbmotions."); + return defs; + } + + MotionMemory::MotionMemory() : + mdbMotions(armem::server::ComponentPluginUser::iceMemory, armem::server::ComponentPluginUser::workingMemoryMutex) + { + + } + + + std::string MotionMemory::getDefaultName() const + { + return "MotionMemory"; + } + + void MotionMemory::onInitComponent() + { + workingMemory.name() = memoryName; + longtermMemory.name() = memoryName; + + mdbMotions.onInit(); + } + + void MotionMemory::onConnectComponent() + { + mdbMotions.onConnect(); + } + + void MotionMemory::onDisconnectComponent() + { + } + + void MotionMemory::onExitComponent() + { + } +} diff --git a/source/RobotAPI/components/armem/server/MotionMemory/MotionMemory.h b/source/RobotAPI/components/armem/server/MotionMemory/MotionMemory.h new file mode 100644 index 0000000000000000000000000000000000000000..0218f010631a8f752985dce148c892bed145f5b3 --- /dev/null +++ b/source/RobotAPI/components/armem/server/MotionMemory/MotionMemory.h @@ -0,0 +1,72 @@ +/* + * 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::ArmarXObjects::ExampleMemory + * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + + +#include <ArmarXCore/core/Component.h> +#include <RobotAPI/libraries/armem/server/ComponentPlugin.h> + +#include <RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.h> + +namespace armarx +{ + /** + * @defgroup Component-ExampleMemory ExampleMemory + * @ingroup RobotAPI-Components + * A description of the component ExampleMemory. + * + * @class ExampleMemory + * @ingroup Component-ExampleMemory + * @brief Brief description of class ExampleMemory. + * + * Detailed description of class ExampleMemory. + */ + class MotionMemory : + virtual public armarx::Component + , virtual public armem::server::ComponentPluginUser + { + public: + + MotionMemory(); + + /// @see armarx::ManagedIceObject::getDefaultName() + std::string getDefaultName() const override; + + protected: + + armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; + + void onInitComponent() override; + void onConnectComponent() override; + void onDisconnectComponent() override; + void onExitComponent() override; + + + private: + std::string memoryName = "Motion"; + + armem::server::motions::mdb::Segment mdbMotions; + // TODO: mdt Segment + + }; +} diff --git a/source/RobotAPI/components/armem/server/MotionMemory/test/CMakeLists.txt b/source/RobotAPI/components/armem/server/MotionMemory/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..42be84a2ddaa31c11bb54e8ec853031dcb833ee7 --- /dev/null +++ b/source/RobotAPI/components/armem/server/MotionMemory/test/CMakeLists.txt @@ -0,0 +1,5 @@ + +# Libs required for the tests +SET(LIBS ${LIBS} ArmarXCore MotionMemory) + +armarx_add_test(MotionMemoryTest MotionMemoryTest.cpp "${LIBS}") diff --git a/source/RobotAPI/components/armem/server/MotionMemory/test/MotionMemoryTest.cpp b/source/RobotAPI/components/armem/server/MotionMemory/test/MotionMemoryTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5eda6d831d1768ec5f8975eddcf88ed07e3fc60e --- /dev/null +++ b/source/RobotAPI/components/armem/server/MotionMemory/test/MotionMemoryTest.cpp @@ -0,0 +1,40 @@ +/* + * 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::ArmarXObjects::ExampleMemory + * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#define BOOST_TEST_MODULE RobotAPI::ArmarXObjects::ExampleMemory + +#define ARMARX_BOOST_TEST + +#include <RobotAPI/Test.h> +#include "../MotionMemory.h" + +#include <RobotAPI/libraries/armem/core.h> + +#include <iostream> + +namespace armem = armarx::armem; + + +BOOST_AUTO_TEST_CASE(test_ExampleData_type) +{ + +} diff --git a/source/RobotAPI/components/armem/server/SubjectMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/SubjectMemory/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..bf9a3ba660d9bcb9e0a39f0075c1dedd8a146c2d --- /dev/null +++ b/source/RobotAPI/components/armem/server/SubjectMemory/CMakeLists.txt @@ -0,0 +1,28 @@ +armarx_component_set_name("SubjectMemory") + + +set(COMPONENT_LIBS + ArmarXCore ArmarXCoreInterfaces # for DebugObserverInterface + ArmarXGuiComponentPlugins + RobotAPICore RobotAPIInterfaces armem armem_motions + # RobotAPIComponentPlugins # for ArViz and other plugins +) + +set(SOURCES + SubjectMemory.cpp +) +set(HEADERS + SubjectMemory.h +) + +armarx_add_component("${SOURCES}" "${HEADERS}") + + +# add unit tests +add_subdirectory(test) + +#generate the application +armarx_generate_and_add_component_executable() + + + diff --git a/source/RobotAPI/components/armem/server/SubjectMemory/SubjectMemory.cpp b/source/RobotAPI/components/armem/server/SubjectMemory/SubjectMemory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d23b8cd13ea3fcb807d969d860805d3552cdaa6e --- /dev/null +++ b/source/RobotAPI/components/armem/server/SubjectMemory/SubjectMemory.cpp @@ -0,0 +1,73 @@ +/* + * 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::ArmarXObjects::ExampleMemory + * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include "SubjectMemory.h" + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + +#include <SimoxUtility/algorithm/string.h> + +#include <RobotAPI/libraries/armem/core/error.h> + + +namespace armarx +{ + armarx::PropertyDefinitionsPtr SubjectMemory::createPropertyDefinitions() + { + armarx::PropertyDefinitionsPtr defs = new ComponentPropertyDefinitions(getConfigIdentifier()); + + const std::string prefix = "mem."; + defs->optional(memoryName, prefix + "MemoryName", "Name of this memory (server)."); + mdbMotions.defineProperties(defs, prefix + "mdb."); + return defs; + } + + SubjectMemory::SubjectMemory() : + mdbMotions(armem::server::ComponentPluginUser::iceMemory, armem::server::ComponentPluginUser::workingMemoryMutex) + { + + } + + + std::string SubjectMemory::getDefaultName() const + { + return "MotionMemory"; + } + + void SubjectMemory::onInitComponent() + { + workingMemory.name() = memoryName; + longtermMemory.name() = memoryName; + } + + void SubjectMemory::onConnectComponent() + { + } + + void SubjectMemory::onDisconnectComponent() + { + } + + void SubjectMemory::onExitComponent() + { + } +} diff --git a/source/RobotAPI/components/armem/server/SubjectMemory/SubjectMemory.h b/source/RobotAPI/components/armem/server/SubjectMemory/SubjectMemory.h new file mode 100644 index 0000000000000000000000000000000000000000..2382459ee2fa0ad5bd52300c25cbad0562ed5921 --- /dev/null +++ b/source/RobotAPI/components/armem/server/SubjectMemory/SubjectMemory.h @@ -0,0 +1,71 @@ +/* + * 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::ArmarXObjects::ExampleMemory + * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + + +#include <ArmarXCore/core/Component.h> +#include <RobotAPI/libraries/armem/server/ComponentPlugin.h> + +#include <RobotAPI/libraries/armem_subjects/server/MotionDatabase/Segment.h> + +namespace armarx +{ + /** + * @defgroup Component-ExampleMemory ExampleMemory + * @ingroup RobotAPI-Components + * A description of the component ExampleMemory. + * + * @class ExampleMemory + * @ingroup Component-ExampleMemory + * @brief Brief description of class ExampleMemory. + * + * Detailed description of class ExampleMemory. + */ + class SubjectMemory : + virtual public armarx::Component + , virtual public armem::server::ComponentPluginUser + { + public: + + SubjectMemory(); + + /// @see armarx::ManagedIceObject::getDefaultName() + std::string getDefaultName() const override; + + protected: + + armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; + + void onInitComponent() override; + void onConnectComponent() override; + void onDisconnectComponent() override; + void onExitComponent() override; + + + private: + std::string memoryName = "Subject"; + + armem::server::subjects::mdb::Segment mdbSubjects; + + }; +} diff --git a/source/RobotAPI/components/armem/server/SubjectMemory/test/CMakeLists.txt b/source/RobotAPI/components/armem/server/SubjectMemory/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c5f60466c709733431b4efd82c9f9a36d35c0f8d --- /dev/null +++ b/source/RobotAPI/components/armem/server/SubjectMemory/test/CMakeLists.txt @@ -0,0 +1,5 @@ + +# Libs required for the tests +SET(LIBS ${LIBS} ArmarXCore SubjectMemory) + +armarx_add_test(SubjectMemoryTest SubjectMemoryTest.cpp "${LIBS}") diff --git a/source/RobotAPI/components/armem/server/SubjectMemory/test/SubjectMemoryTest.cpp b/source/RobotAPI/components/armem/server/SubjectMemory/test/SubjectMemoryTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5eda6d831d1768ec5f8975eddcf88ed07e3fc60e --- /dev/null +++ b/source/RobotAPI/components/armem/server/SubjectMemory/test/SubjectMemoryTest.cpp @@ -0,0 +1,40 @@ +/* + * 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::ArmarXObjects::ExampleMemory + * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * @date 2020 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#define BOOST_TEST_MODULE RobotAPI::ArmarXObjects::ExampleMemory + +#define ARMARX_BOOST_TEST + +#include <RobotAPI/Test.h> +#include "../MotionMemory.h" + +#include <RobotAPI/libraries/armem/core.h> + +#include <iostream> + +namespace armem = armarx::armem; + + +BOOST_AUTO_TEST_CASE(test_ExampleData_type) +{ + +} diff --git a/source/RobotAPI/interface/CMakeLists.txt b/source/RobotAPI/interface/CMakeLists.txt index b2913fb4c0f39035f94b284a52ac7f32295f73b8..a026e17c6b4a4f036aa600c4b37d6f4e2aadd1c4 100644 --- a/source/RobotAPI/interface/CMakeLists.txt +++ b/source/RobotAPI/interface/CMakeLists.txt @@ -136,6 +136,8 @@ set(SLICE_FILES skills/SkillObserverInterface.ice skills/SkillProviderInterface.ice + + mdb/MotionDatabase.ice ) #core/RobotIK.ice set(SLICE_FILES_ADDITIONAL_HEADERS diff --git a/source/RobotAPI/interface/armem/query.ice b/source/RobotAPI/interface/armem/query.ice index 2a0eb6e217a769fe4bab33dd0ab896e2faeda8e5..2a1586fece346e89cbe491cd21c026ddab603e0e 100644 --- a/source/RobotAPI/interface/armem/query.ice +++ b/source/RobotAPI/interface/armem/query.ice @@ -13,15 +13,16 @@ module armarx { enum QueryTarget { - WMAndLTM, WM, - LTM // only for debug. remove later + LTM, + Disk }; + sequence<QueryTarget> QueryTargets; /// Which entity snapshots to get from an entity? class EntityQuery { - QueryTarget target = QueryTarget::WMAndLTM; + QueryTargets targets; }; sequence<EntityQuery> EntityQuerySeq; @@ -115,7 +116,7 @@ module armarx class ProviderSegmentQuery { EntityQuerySeq entityQueries; - QueryTarget target = QueryTarget::WMAndLTM; + QueryTargets targets; }; sequence<ProviderSegmentQuery> ProviderSegmentQuerySeq; module provider @@ -138,7 +139,7 @@ module armarx class CoreSegmentQuery { ProviderSegmentQuerySeq providerSegmentQueries; - QueryTarget target = QueryTarget::WMAndLTM; + QueryTargets targets; }; sequence<CoreSegmentQuery> CoreSegmentQuerySeq; @@ -162,7 +163,7 @@ module armarx class MemoryQuery { CoreSegmentQuerySeq coreSegmentQueries; - QueryTarget target = QueryTarget::WMAndLTM; + QueryTargets targets; }; sequence<MemoryQuery> MemoryQuerySeq; dictionary<string, MemoryQuerySeq> MemoryQueriesDict; @@ -188,7 +189,6 @@ module armarx { /// Dict of memory name to MemoryQueriesDict memoryQueries; - QueryTarget target = QueryTarget::WMAndLTM; }; struct Input diff --git a/source/RobotAPI/interface/mdb/MotionDatabase.ice b/source/RobotAPI/interface/mdb/MotionDatabase.ice new file mode 100644 index 0000000000000000000000000000000000000000..2ca77b0b92f86b2945925949fd239678e35a78ba --- /dev/null +++ b/source/RobotAPI/interface/mdb/MotionDatabase.ice @@ -0,0 +1,146 @@ +#include <Glacier2/Session.ice> + +module MotionDatabase { + exception InternalErrorException { + string errorMessage; + }; + + exception InvalidParameterException { + string parameterName; + }; + + exception NotAuthorizedException {}; + exception TooManyOpenFilesException {}; + + class Institution; + class MotionDescriptionTreeNode; + class File; + class Motion; + class Project; + class Subject; + class MoCapObject; + + sequence<byte> ByteSequence; + sequence<long> LongSequence; + sequence<string> StringSequence; + sequence<Institution> InstitutionList; + sequence<MotionDescriptionTreeNode> MotionDescriptionTreeNodeList; + sequence<File> FileList; + sequence<Motion> MotionList; + sequence<Project> ProjectList; + sequence<Subject> SubjectList; + sequence<MoCapObject> MoCapObjectList; + + dictionary<string, short> StringShortDictionary; + + enum VisibilityLevel { Public, Protected, Internal }; + + class Institution { + long id; + string acronym; + string name; + }; + + class MotionDescriptionTreeNode { + long id; + string label; + MotionDescriptionTreeNodeList children; + }; + + class DatabaseObject { + long id; + long createdDate; + string createdUser; + long modifiedDate; + string modifiedUser; + StringSequence writeGroups; + StringSequence readProtectedGroups; + StringShortDictionary fileTypeCounts; + }; + + class File { + long id; + long createdDate; + string createdUser; + string fileName; + string fileType; + long attachedToId; + string description; + VisibilityLevel visibility; + File originatedFrom; + }; + + class Motion extends DatabaseObject { + Institution associatedInstitution; + MotionDescriptionTreeNodeList motionDescriptions; + Project associatedProject; + SubjectList associatedSubjects; + MoCapObjectList associatedObjects; + string date; + string comment; + }; + + class Project extends DatabaseObject { + string name; + string comment; + }; + + class Subject extends DatabaseObject { + string firstName; + string lastName; + string comment; + byte gender; + short age; + short weight; + short height; + StringShortDictionary anthropometricsTable; + }; + + class MoCapObject extends DatabaseObject { + string label; + string comment; + string modelSettingsJSON; + }; + + interface FileReader { + void destroy(); + + idempotent long getSize() throws InternalErrorException; + ByteSequence readChunk(long length) throws InternalErrorException, InvalidParameterException; + idempotent void seek(long pos) throws InternalErrorException, InvalidParameterException; + }; + + interface FileWriter { + void destroy(); + + void writeChunk(ByteSequence data) throws InternalErrorException; + }; + + interface MotionDatabaseSession extends Glacier2::Session { + idempotent string pingServer(string echoString); + + idempotent InstitutionList listInstitutions() throws InternalErrorException; + idempotent MotionDescriptionTreeNodeList getMotionDescriptionTree() throws InternalErrorException; + + idempotent Motion getMotion(long motionId) throws InternalErrorException, InvalidParameterException; + idempotent long countMotions(LongSequence filterMotionDescription, LongSequence filterProject, LongSequence filterInstitution, + LongSequence filterSubject, LongSequence filterObject, string motionDescriptionSearchTerm) throws InternalErrorException, + InvalidParameterException; + idempotent MotionList listMotions(LongSequence filterMotionDescription, LongSequence filterProject, LongSequence filterInstitution, + LongSequence filterSubject, LongSequence filterObject, string motionDescriptionSearchTerm, string sortField, long limit, + long offset) throws InternalErrorException, InvalidParameterException; + idempotent ProjectList listProjects() throws InternalErrorException; + idempotent SubjectList listSubjects() throws InternalErrorException; + idempotent MoCapObjectList listObjects() throws InternalErrorException; + + idempotent File getFile(long fileId) throws InternalErrorException, InvalidParameterException; + idempotent FileList listFiles(long databaseObjectId) throws InternalErrorException, InvalidParameterException; + idempotent FileReader* getFileReader(long fileId) throws InternalErrorException, InvalidParameterException, NotAuthorizedException, + TooManyOpenFilesException; + + FileWriter* getFileWriter(long databaseObjectId, string fileName, string fileType, string description, VisibilityLevel visibility, + optional(1) long originatedFromId) throws InternalErrorException, InvalidParameterException, NotAuthorizedException, + TooManyOpenFilesException; + void deleteFile(long fileId) throws InternalErrorException, InvalidParameterException, NotAuthorizedException; + }; +}; diff --git a/source/RobotAPI/libraries/CMakeLists.txt b/source/RobotAPI/libraries/CMakeLists.txt index 02e5c638bfdfc145c271a995e016ce0c5f15ba01..c5f89815a7052571a06815781e69147750febd0c 100644 --- a/source/RobotAPI/libraries/CMakeLists.txt +++ b/source/RobotAPI/libraries/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(ArmarXEtherCAT) add_subdirectory(ArmarXObjects) +add_subdirectory(PriorKnowledge) add_subdirectory(ControllerUIUtility) add_subdirectory(core) add_subdirectory(DebugDrawerConfigWidget) @@ -24,6 +25,7 @@ add_subdirectory(armem_robot) add_subdirectory(armem_robot_state) add_subdirectory(armem_vision) add_subdirectory(armem_skills) +add_subdirectory(armem_motions) add_subdirectory(aron) add_subdirectory(NJointControllerGuiPluginUtility) diff --git a/source/RobotAPI/libraries/PriorKnowledge/CMakeLists.txt b/source/RobotAPI/libraries/PriorKnowledge/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..596f554c1f0ec2689d12cc9776539b0d4fd7377f --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(core) +add_subdirectory(motions) +#add_subdirectory(subjects) + diff --git a/source/RobotAPI/libraries/PriorKnowledge/core/CMakeLists.txt b/source/RobotAPI/libraries/PriorKnowledge/core/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d9adff9e0ec67014af674e12ec170a5a465d75cc --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/core/CMakeLists.txt @@ -0,0 +1,21 @@ +set(LIB_NAME ${PROJECT_NAME}PriorKnowledgeCore) + +armarx_component_set_name("${LIB_NAME}") +armarx_set_target("Library: ${LIB_NAME}") + +armarx_add_library( + LIBS + RobotAPI::Core + RobotAPI::Aron::Common + SOURCES + FinderBase.cpp + FinderInfoBase.cpp + HEADERS + FinderBase.h + FinderInfoBase.h +) + +add_library(${PROJECT_NAME}::PriorKnowledge::Core ALIAS ${PROJECT_NAME}PriorKnowledgeCore) + +# add unit tests +#add_subdirectory(test) diff --git a/source/RobotAPI/libraries/PriorKnowledge/core/FinderBase.cpp b/source/RobotAPI/libraries/PriorKnowledge/core/FinderBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6b7847a515fbce64b9cfc853bf33ed1bcb6448e9 --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/core/FinderBase.cpp @@ -0,0 +1 @@ +#include "FinderBase.h" diff --git a/source/RobotAPI/libraries/PriorKnowledge/core/FinderBase.h b/source/RobotAPI/libraries/PriorKnowledge/core/FinderBase.h new file mode 100644 index 0000000000000000000000000000000000000000..3dc38a1814850c68c977986ec059494dd8901a9f --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/core/FinderBase.h @@ -0,0 +1,120 @@ +#pragma once + +// STD/STL +#include <string> +#include <filesystem> +#include <optional> + +// Base Class +#include <ArmarXCore/core/logging/Logging.h> + +// ArmarX +#include <ArmarXCore/core/system/ArmarXDataPath.h> +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include <ArmarXCore/core/system/cmake/CMakePackageFinder.h> + + +namespace armarx::priorknowledge::core +{ + template <class IDType, class FinderInfoType> + class FinderBase : public Logging + { + public: + FinderBase() = delete; + FinderBase(const std::string& packageName, const std::filesystem::path& relDir) : + packageName(packageName), + relPackageDataPath(relDir) + { + CMakePackageFinder packageFinder(packageName); + absPackageDataDir = packageFinder.getDataDir(); + if (absPackageDataDir.empty()) + { + ARMARX_WARNING << "Could not find package '" << packageName << "'."; + throw LocalException() << "Could not find package '" << packageName << "'."; + } + else + { + ARMARX_INFO << "PriorKnowledgeFinder root directory: " << absPackageDataDir; + + // make sure this data path is available => e.g. for findArticulatedObjects + armarx::ArmarXDataPath::addDataPaths(std::vector<std::string> {absPackageDataDir}); + } + } + + FinderBase(FinderBase&&) = default; + FinderBase(const FinderBase&) = default; + FinderBase& operator=(FinderBase&&) = default; + FinderBase& operator=(const FinderBase&) = default; + + void setRelativePath(const std::filesystem::path& p) + { + relPackageDataPath = p; + } + + std::string getPackageName() const + { + return packageName; + } + + std::filesystem::path getRelativePath() const + { + return relPackageDataPath; + } + + std::filesystem::path getAbsolutePackagePath() const + { + checkAbsolutePathIsValid(); + return absPackageDataDir; + } + + std::filesystem::path getFullPath() const + { + checkAbsolutePathIsValid(); + return absPackageDataDir / packageName / relPackageDataPath; + } + + virtual bool checkAll() const = 0; + virtual bool check(const IDType& id) const = 0; + virtual std::optional<FinderInfoType> find(const IDType& id) const = 0; + virtual std::vector<FinderInfoType> findAll() const = 0; + + protected: + void checkAbsolutePathIsValid() const + { + if (!std::filesystem::exists(absPackageDataDir)) + { + ARMARX_ERROR << "PriorKnowledgeFinder is not initialized yet. Could not resolve absolute path for package '" << packageName << "'."; + } + } + + protected: + + private: + std::string packageName; + std::filesystem::path relPackageDataPath; + std::filesystem::path absPackageDataDir; + }; + + + template <class IDType, class DatasetType, class FinderInfoType> // TODO: concept DatasetFinderInfoType + class DatasetFinderBase : public FinderBase<IDType, FinderInfoType> + { + + public: + using Base = FinderBase<IDType, FinderInfoType>; + + DatasetFinderBase(const std::string& packageName, const std::filesystem::path& relDir) : + Base(packageName, relDir) + {} + + std::filesystem::path getFullPath(const std::filesystem::path& relDatasetPath) const + { + return Base::getFullPath() / relDatasetPath; + } + + virtual bool checkAll(const DatasetType& dataset) const = 0; + virtual bool check(const DatasetType& dataset, const IDType& id) const = 0; + virtual std::optional<FinderInfoType> find(const DatasetType& dataset, const IDType& id) const = 0; + virtual std::vector<FinderInfoType> findAll(const DatasetType& dataset) const = 0; + }; +} diff --git a/source/RobotAPI/libraries/PriorKnowledge/core/FinderInfoBase.cpp b/source/RobotAPI/libraries/PriorKnowledge/core/FinderInfoBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46ed5497bca16ff12efa941657857feffa5e0111 --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/core/FinderInfoBase.cpp @@ -0,0 +1 @@ +#include "FinderInfoBase.h" diff --git a/source/RobotAPI/libraries/PriorKnowledge/core/FinderInfoBase.h b/source/RobotAPI/libraries/PriorKnowledge/core/FinderInfoBase.h new file mode 100644 index 0000000000000000000000000000000000000000..c28130755133bd903a5d7cdf6d3f0474d1db25f6 --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/core/FinderInfoBase.h @@ -0,0 +1,116 @@ +#pragma once + +// STD/STL +#include <string> +#include <filesystem> +#include <optional> + +// Base Class +#include <ArmarXCore/core/logging/Logging.h> + +// ArmarX +#include <ArmarXCore/core/system/ArmarXDataPath.h> +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + + +namespace armarx::priorknowledge::core +{ + + struct PackageFileLocation + { + /// Name of the ArmarX package. + std::string package; + + /// Relative to the package's data directory. + std::filesystem::path relativePath; + + /// The absolute path (in the host's file system). + std::filesystem::path absolutePath; + }; + + template <class IDType> + class FinderInfoBase + { + public: + FinderInfoBase(const std::string& packageName, const std::filesystem::path& absPackageDataDir, const std::filesystem::path& relPackageDataPath, const IDType& id) : + packageName(packageName), + absPackageDataDir(absPackageDataDir), + relPackageDataPath(relPackageDataPath), + id(id) + {} + + std::string getPackageName() const + { + return packageName; + } + + std::filesystem::path getRelativePath() const + { + return relPackageDataPath; + } + + std::filesystem::path getAbsolutePackagePath() const + { + checkAbsolutePathIsValid(); + return absPackageDataDir; + } + + virtual std::filesystem::path getFullPath() const + { + checkAbsolutePathIsValid(); + return absPackageDataDir / packageName / relPackageDataPath; + } + + IDType getID() const + { + return id; + } + + protected: + void checkAbsolutePathIsValid() const + { + if (!std::filesystem::exists(absPackageDataDir)) + { + ARMARX_ERROR << "Could not resolve absolute path for package '" << packageName << "'."; + } + } + + + protected: + bool logError = true; + + private: + std::string packageName; + std::filesystem::path absPackageDataDir; + std::filesystem::path relPackageDataPath; + IDType id; + }; + + template <class IDType, class DatasetType> + class DatasetFinderInfoBase : public FinderInfoBase<IDType> + { + + public: + using Base = FinderInfoBase<IDType>; + + DatasetFinderInfoBase(const std::string& packageName, const std::filesystem::path& absPackageDataDir, const std::filesystem::path& relPackageDataPath, const std::filesystem::path& relDatasetPath, const DatasetType& dataset, const IDType& id) : + Base(packageName, absPackageDataDir, relPackageDataPath, id), + dataset(dataset), + relDatasetPath(relDatasetPath) + {} + + virtual std::filesystem::path getFullPath() const override + { + return Base::getFullPath() / relDatasetPath; + } + + DatasetType getDataset() const + { + return dataset; + } + + private: + DatasetType dataset; + std::filesystem::path relDatasetPath; + }; +} diff --git a/source/RobotAPI/libraries/PriorKnowledge/motions/CMakeLists.txt b/source/RobotAPI/libraries/PriorKnowledge/motions/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7f4b2c007e00ea4a575056598ec7f6f25ab3fe8c --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/motions/CMakeLists.txt @@ -0,0 +1,19 @@ +set(LIB_NAME ${PROJECT_NAME}PriorKnowledgeMotions) + +armarx_component_set_name("${LIB_NAME}") +armarx_set_target("Library: ${LIB_NAME}") + +armarx_add_library( + LIBS + RobotAPI::Core + RobotAPI::Aron::Common + SOURCES + MotionFinder.cpp + HEADERS + MotionFinder.h +) + +add_library(${PROJECT_NAME}::PriorKnowledge::Motions ALIAS ${PROJECT_NAME}PriorKnowledgeMotions) + +# add unit tests +#add_subdirectory(test) diff --git a/source/RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.cpp b/source/RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8fa71a62b6bcbd49141eb355ab45f124a8943808 --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.cpp @@ -0,0 +1,133 @@ +// Simox +#include <SimoxUtility/algorithm/vector.hpp> + +// BaseClass +#include "MotionFinder.h" + +// ArmarX + +namespace armarx::priorknowledge::motions +{ + bool MotionFinder::checkAll() const + { + return true; + } + + bool MotionFinder::check(const std::string &id) const + { + return true; + } + + std::optional<MotionFinderInfo> MotionFinder::find(const std::string &id) const + { + const std::filesystem::path absPath = Base::Base::getFullPath(); + if (std::filesystem::is_regular_file(absPath)) + { + ARMARX_WARNING << "The entered path is leading to a file!"; + return std::nullopt; + } + + for (const auto& d : std::filesystem::directory_iterator(absPath)) + { + if (!d.is_directory()) + { + ARMARX_WARNING << "Found invalid path: " << d.path(); + continue; + } + std::string k = d.path().filename(); + if (simox::alg::contains(DATASET_FOLDERS_BLACKLIST, k)) + { + continue; + } + + if (const auto op = this->find(k, id); op.has_value()) + { + return op; + } + } + return std::nullopt; + } + + std::vector<MotionFinderInfo> MotionFinder::findAll() const + { + const std::filesystem::path absPath = Base::Base::getFullPath(); + if (std::filesystem::is_regular_file(absPath)) + { + ARMARX_WARNING << "The entered path is leading to a file!"; + return {}; + } + + std::vector<MotionFinderInfo> ret; + for (const auto& d : std::filesystem::directory_iterator(absPath)) + { + if (!d.is_directory()) + { + ARMARX_WARNING << "Found invalid path: " << d.path(); + continue; + } + std::string k = d.path().filename(); + if (simox::alg::contains(DATASET_FOLDERS_BLACKLIST, k)) + { + continue; + } + + auto motionsForDataset = this->findAll(k); + simox::alg::append(ret, motionsForDataset); + } + return ret; + } + + bool MotionFinder::checkAll(const std::string &dataset) const + { + return true; + } + + bool MotionFinder::check(const std::string &dataset, const std::string &id) const + { + return true; + } + + std::optional<MotionFinderInfo> MotionFinder::find(const std::string &dataset, const std::string &id) const + { + const std::filesystem::path absPathToMotion = this->getFullPath(dataset) / id; + if (std::filesystem::is_regular_file(absPathToMotion)) + { + ARMARX_WARNING << "The entered path is leading to a file!"; + return std::nullopt; + } + + return std::make_optional(MotionFinderInfo(this->getPackageName(), this->getAbsolutePackagePath(), this->getRelativePath(), dataset, dataset, id)); + } + + std::vector<MotionFinderInfo> MotionFinder::findAll(const std::string &dataset) const + { + const std::filesystem::path absPathToDataset = this->getFullPath(dataset); + if (std::filesystem::is_regular_file(absPathToDataset)) + { + ARMARX_WARNING << "The entered path is leading to a file!"; + return {}; + } + + std::vector<MotionFinderInfo> ret; + for (const auto& d : std::filesystem::directory_iterator(absPathToDataset)) + { + if (!d.is_directory()) + { + ARMARX_WARNING << "Found invalid path: " << d.path(); + continue; + } + std::string k = d.path().filename(); + if (simox::alg::contains(MOTION_ID_FOLDERS_BLACKLIST, k)) + { + continue; + } + + if(auto op = this->find(dataset, k); op.has_value()) + { + ret.emplace_back(op.value()); + } + } + return ret; + } + +} diff --git a/source/RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.h b/source/RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.h new file mode 100644 index 0000000000000000000000000000000000000000..9315ab34581341bdd34f404643f1ddda55c3aa62 --- /dev/null +++ b/source/RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.h @@ -0,0 +1,47 @@ +#include <RobotAPI/libraries/PriorKnowledge/core/FinderBase.h> +#include <RobotAPI/libraries/PriorKnowledge/core/FinderInfoBase.h> + + +namespace armarx::priorknowledge::motions +{ + class MotionFinderInfo : public core::DatasetFinderInfoBase<std::string, std::string> + { + using Base = core::DatasetFinderInfoBase<std::string, std::string>; + + public: + MotionFinderInfo(const std::string& packageName, + const std::filesystem::path& absPackageDataDir, + const std::filesystem::path& relPackageDataPath, + const std::filesystem::path& relDatasetPath, + const std::string& dataset, + const std::string& id) : + Base(packageName, absPackageDataDir, relPackageDataPath, relDatasetPath, dataset, id) + { + } + }; + + class MotionFinder : public core::DatasetFinderBase<std::string, std::string, MotionFinderInfo> + { + using Base = core::DatasetFinderBase<std::string, std::string, MotionFinderInfo>; + + public: + MotionFinder(const std::string& packageName, const std::filesystem::path& relDir) : + Base(packageName, relDir) + {} + + bool checkAll() const; + bool check(const std::string& id) const; + std::optional<MotionFinderInfo> find(const std::string& id) const; + std::vector<MotionFinderInfo> findAll() const; + + bool checkAll(const std::string& dataset) const; + bool check(const std::string& dataset, const std::string& id) const; + std::optional<MotionFinderInfo> find(const std::string& dataset, const std::string& id) const; + std::vector<MotionFinderInfo> findAll(const std::string& dataset) const; + + private: + std::vector<std::string> DATASET_FOLDERS_BLACKLIST = {}; + std::vector<std::string> MOTION_ID_FOLDERS_BLACKLIST = {"script"}; + }; + +} diff --git a/source/RobotAPI/libraries/armem/CMakeLists.txt b/source/RobotAPI/libraries/armem/CMakeLists.txt index 38d9515cc25818652636ca4b8c5e969eaaf9519a..eb53706cb8836fc40891372811738240b3522aa0 100644 --- a/source/RobotAPI/libraries/armem/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem/CMakeLists.txt @@ -13,12 +13,6 @@ find_package(libbsoncxx QUIET) armarx_build_if(libbsoncxx_FOUND "libbsoncxx not available. ${INSTALL_SCRIPT_MSG}") -#message("LIBMONGOCXX:") -#message("${LIBMONGOCXX_FOUND}") -#message("${LIBMONGOCXX_INCLUDE_DIRS}") -#message("${LIBMONGOCXX_LIBRARIES}") - - set(LIBS ArmarXCoreInterfaces ArmarXCore RemoteGui @@ -103,6 +97,7 @@ set(LIB_FILES server/ComponentPlugin.cpp server/MemoryRemoteGui.cpp server/RemoteGuiAronDataVisitor.cpp + server/Segment.cpp server/query_proc/base/BaseQueryProcessorBase.cpp server/query_proc/base/EntityQueryProcessorBase.cpp @@ -122,6 +117,12 @@ set(LIB_FILES server/query_proc/longtermmemory/CoreSegmentQueryProcessor.cpp server/query_proc/longtermmemory/MemoryQueryProcessor.cpp + server/query_proc/diskmemory/BaseQueryProcessor.cpp + server/query_proc/diskmemory/EntityQueryProcessor.cpp + server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp + server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp + server/query_proc/diskmemory/MemoryQueryProcessor.cpp + mns/MemoryNameSystem.cpp mns/ComponentPlugin.cpp @@ -217,6 +218,7 @@ set(LIB_HEADERS server/MemoryToIceAdapter.h server/MemoryRemoteGui.h server/RemoteGuiAronDataVisitor.h + server/Segment.h server/query_proc.h server/query_proc/base/BaseQueryProcessorBase.h @@ -237,6 +239,12 @@ set(LIB_HEADERS server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h server/query_proc/longtermmemory/MemoryQueryProcessor.h + server/query_proc/diskmemory/BaseQueryProcessor.h + server/query_proc/diskmemory/EntityQueryProcessor.h + server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h + server/query_proc/diskmemory/CoreSegmentQueryProcessor.h + server/query_proc/diskmemory/MemoryQueryProcessor.h + mns.h mns/MemoryNameSystem.h mns/ComponentPlugin.h @@ -256,18 +264,11 @@ armarx_add_library( "${LIBS}" ARON_FILES aron/MemoryID.xml - ) - - -#armarx_enable_aron_file_generation_for_target( -# TARGET_NAME -# ${LIB_NAME} -# ARON_FILES -# aron/MemoryID.xml -#) +) add_library(RobotAPI::armem ALIAS "${LIB_NAME}") +add_library(RobotAPI::ArMem ALIAS "${LIB_NAME}") target_include_directories("${LIB_NAME}" PUBLIC ${LIBMONGOCXX_INCLUDE_DIRS}) target_include_directories("${LIB_NAME}" PUBLIC ${LIBBSONCXX_INCLUDE_DIRS}) diff --git a/source/RobotAPI/libraries/armem/client/Query.h b/source/RobotAPI/libraries/armem/client/Query.h index 4f5a87bdccfc84458210d0811b02d99275b54ae4..916278a8fcde1679545ed39d59531f5772852c13 100644 --- a/source/RobotAPI/libraries/armem/client/Query.h +++ b/source/RobotAPI/libraries/armem/client/Query.h @@ -28,6 +28,37 @@ namespace armarx::armem::client armem::query::data::MemoryQuerySeq memoryQueries; DataMode dataMode; + void addQueryTargetToAll(const armem::query::data::QueryTarget t) + { + for (const auto& memoryQuery : memoryQueries) + { + if (std::find(memoryQuery->targets.begin(), memoryQuery->targets.end(), t) == memoryQuery->targets.end()) + { + memoryQuery->targets.push_back(t); + } + for (const auto& coreSegmentQuery : memoryQuery->coreSegmentQueries) + { + if (std::find(coreSegmentQuery->targets.begin(), coreSegmentQuery->targets.end(), t) == coreSegmentQuery->targets.end()) + { + coreSegmentQuery->targets.push_back(t); + } + for (const auto& providerSegmentQuery : coreSegmentQuery->providerSegmentQueries) + { + if (std::find(providerSegmentQuery->targets.begin(), providerSegmentQuery->targets.end(), t) == providerSegmentQuery->targets.end()) + { + providerSegmentQuery->targets.push_back(t); + } + for (const auto& entityQuery : providerSegmentQuery->entityQueries) + { + if (std::find(entityQuery->targets.begin(), entityQuery->targets.end(), t) == entityQuery->targets.end()) + { + entityQuery->targets.push_back(t); + } + } + } + } + } + } static QueryInput fromIce(const armem::query::data::Input& ice); armem::query::data::Input toIce() const; diff --git a/source/RobotAPI/libraries/armem/client/query/Builder.cpp b/source/RobotAPI/libraries/armem/client/query/Builder.cpp index 5979ea365a863dc0ce1c0c0b91a0d77fc3f331e9..59ae0b7c082bc25a8b1084f8ac49611df107d132 100644 --- a/source/RobotAPI/libraries/armem/client/query/Builder.cpp +++ b/source/RobotAPI/libraries/armem/client/query/Builder.cpp @@ -8,12 +8,6 @@ namespace armarx::armem::client::query { } - Builder& Builder::queryTarget(const armem::query::data::QueryTarget target) - { - this->_target = target; - return *this; - } - QueryInput Builder::buildQueryInput() const { QueryInput input; @@ -31,9 +25,9 @@ namespace armarx::armem::client::query armem::query::data::MemoryQuerySeq memoryQueries; for (const CoreSegmentSelector& child : _children) { - for (const armem::query::data::MemoryQueryPtr& query : child.buildQueries()) + for (armem::query::data::MemoryQueryPtr& query : child.buildQueries()) { - query->target = _target; + query->targets = _targets; memoryQueries.push_back(query); } } diff --git a/source/RobotAPI/libraries/armem/client/query/Builder.h b/source/RobotAPI/libraries/armem/client/query/Builder.h index eae09294320f216aa3e996821c429376ff7675a0..dc6147ef03e7de81518e64bddc9bb486f0062b07 100644 --- a/source/RobotAPI/libraries/armem/client/query/Builder.h +++ b/source/RobotAPI/libraries/armem/client/query/Builder.h @@ -28,7 +28,6 @@ namespace armarx::armem::client::query public: Builder(DataMode dataMode = DataMode::WithData); - Builder& queryTarget(const armem::query::data::QueryTarget target); /// Start specifying core segments. CoreSegmentSelector& coreSegments(); @@ -66,7 +65,6 @@ namespace armarx::armem::client::query public: - armem::query::data::QueryTarget _target = armem::query::data::QueryTarget::WMAndLTM; DataMode dataMode; }; diff --git a/source/RobotAPI/libraries/armem/client/query/detail/SelectorOps.h b/source/RobotAPI/libraries/armem/client/query/detail/SelectorOps.h index 0a0e89e0ab7f651aa40ff3e2f564d48293f64a40..c6e153f0d7358b318c6966f2c9d5c9c2c35579a4 100644 --- a/source/RobotAPI/libraries/armem/client/query/detail/SelectorOps.h +++ b/source/RobotAPI/libraries/armem/client/query/detail/SelectorOps.h @@ -5,6 +5,7 @@ #include <Ice/Handle.h> #include <RobotAPI/libraries/armem/core/MemoryID.h> +#include <RobotAPI/interface/armem/query.h> namespace armarx::armem::client::query::detail @@ -17,7 +18,11 @@ namespace armarx::armem::client::query::detail using DerivedT = _DerivedT; using QueryT = _QueryT; - virtual ~ChildSelectorOps() = default; + ChildSelectorOps() = delete; + + ChildSelectorOps(const armem::query::data::QueryTargets& p) : + _parentTargets(p) + {} virtual DerivedT& all() = 0; @@ -36,6 +41,9 @@ namespace armarx::armem::client::query::detail } } + protected: + armem::query::data::QueryTargets _parentTargets; + protected: @@ -81,11 +89,21 @@ namespace armarx::armem::client::query::detail using ChildT = _ChildT; + public: + virtual ~ParentSelectorOps() = default; + + /// QueryTargets for this query + DerivedT& queryTargets(const armem::query::data::QueryTargets& targets) + { + this->_targets = targets; + return dynamic_cast<DerivedT&>(*this); + } + protected: ChildT& _addChild() { - return _children.emplace_back(); + return _children.emplace_back(_targets); } ChildT& _addChild(const ChildT& child) { @@ -102,7 +120,7 @@ namespace armarx::armem::client::query::detail std::vector<ChildT> _children; - + armem::query::data::QueryTargets _targets = {armem::query::data::QueryTarget::WM}; // if not specified we only query the WM }; @@ -114,17 +132,27 @@ namespace armarx::armem::client::query::detail { public: - virtual ~InnerSelectorOps() + InnerSelectorOps(const armem::query::data::QueryTargets& p) : + ChildSelectorOps<DerivedT, QueryT>(p) {} - virtual std::vector<QueryT> buildQueries() const { + // check own query targets and parent query targets + for (const auto& target : this->_targets) + { + if (std::find(this->_parentTargets.begin(), this->_parentTargets.end(), target) == this->_parentTargets.end()) + { + // TODO: Error, this makes no sense! or just ignore? + } + } + std::vector<typename ChildT::QueryT> childQueries; for (const auto& child : this->_children) { - for (const auto& query : child.buildQueries()) + for (auto& query : child.buildQueries()) { + query->targets = this->_targets; childQueries.push_back(query); } } diff --git a/source/RobotAPI/libraries/armem/client/query/selectors.cpp b/source/RobotAPI/libraries/armem/client/query/selectors.cpp index cc3a73829ab7c79eabc96c30b55c4ca350ac33ad..98e79d06ab3642b25bee40e89daf728ab3dfee2b 100644 --- a/source/RobotAPI/libraries/armem/client/query/selectors.cpp +++ b/source/RobotAPI/libraries/armem/client/query/selectors.cpp @@ -77,7 +77,6 @@ namespace armarx::armem::client::query return *this; } - SnapshotSelector& EntitySelector::snapshots() { return _addChild(); @@ -115,7 +114,6 @@ namespace armarx::armem::client::query } - EntitySelector& ProviderSegmentSelector::entities() { return _addChild(); @@ -153,7 +151,6 @@ namespace armarx::armem::client::query } - ProviderSegmentSelector& CoreSegmentSelector::providerSegments() { return _addChild(); diff --git a/source/RobotAPI/libraries/armem/client/query/selectors.h b/source/RobotAPI/libraries/armem/client/query/selectors.h index df642ded9a70ea2688eaca5865f730e8e99ee6de..b9c257dc6dd5ae1ec07fd7850322d8babef829e4 100644 --- a/source/RobotAPI/libraries/armem/client/query/selectors.h +++ b/source/RobotAPI/libraries/armem/client/query/selectors.h @@ -15,6 +15,10 @@ namespace armarx::armem::client::query { public: + SnapshotSelector(const armem::query::data::QueryTargets& p) : + detail::ChildSelectorOps<SnapshotSelector, armem::query::data::EntityQueryPtr>(p) + {} + armem::query::data::EntityQuerySeq buildQueries() const; @@ -44,6 +48,10 @@ namespace armarx::armem::client::query { public: + EntitySelector(const armem::query::data::QueryTargets& p) : + detail::InnerSelectorOps<EntitySelector, armem::query::data::ProviderSegmentQueryPtr, SnapshotSelector>(p) + {} + /// Start specifying entity snapshots. SnapshotSelector& snapshots(); SnapshotSelector& snapshots(const SnapshotSelector& selector); @@ -79,6 +87,10 @@ namespace armarx::armem::client::query { public: + ProviderSegmentSelector(const armem::query::data::QueryTargets& p) : + detail::InnerSelectorOps<ProviderSegmentSelector, armem::query::data::CoreSegmentQueryPtr, EntitySelector>(p) + {} + /// Start specifying entities. EntitySelector& entities(); EntitySelector& entities(const EntitySelector& selector); @@ -114,6 +126,10 @@ namespace armarx::armem::client::query { public: + CoreSegmentSelector(const armem::query::data::QueryTargets& p) : + detail::InnerSelectorOps<CoreSegmentSelector, armem::query::data::MemoryQueryPtr, ProviderSegmentSelector>(p) + {} + /// Start specifying provider segments. ProviderSegmentSelector& providerSegments(); ProviderSegmentSelector& providerSegments(const ProviderSegmentSelector& selector); diff --git a/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h b/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h index a74f41d3c0a9efd34d00b2f6fa6849bafd9dca1e..cf68286be26368cb4821fecbbe241e3ef33e0fbe 100644 --- a/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h +++ b/source/RobotAPI/libraries/armem/core/base/EntitySnapshotBase.h @@ -187,6 +187,15 @@ namespace armarx::armem::base return it; } + EntityInstanceT& addInstance() + { + int new_index = this->_container.size(); + auto& it = this->_container.emplace_back(EntityInstanceT());; + it.index() = new_index; + it.id() = this->id().withInstanceIndex(new_index); + return it; + } + std::string getKeyString() const override { return toDateTimeMilliSeconds(this->time()); diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.cpp index dd25b0219a6e0b7559c875ab98446d86ec3fa60f..0f1bd0be881f477908464bcda5a4a858afb54488 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.cpp +++ b/source/RobotAPI/libraries/armem/core/diskmemory/CoreSegment.cpp @@ -24,7 +24,7 @@ namespace armarx::armem::d_ltm wm::CoreSegment CoreSegment::convert() const { - wm::CoreSegment m; + wm::CoreSegment m(id()); for (const auto& [_, s] : _container) { m.addProviderSegment(s.convert(_aronType)); @@ -86,8 +86,17 @@ namespace armarx::armem::d_ltm } else { - std::filesystem::create_directory(_fullPath() / k); - auto wms = _container.emplace(k, id().withProviderSegmentName(k)); + try + { + std::filesystem::create_directory(_fullPath() / k); + } + catch (...) + { + ARMARX_WARNING << GetHandledExceptionString(); + return; + } + + auto wms = _container.emplace(std::make_pair(k, id().withProviderSegmentName(k))); wms.first->second.path = path; wms.first->second.append(s); } diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp index a616914ede5c279d11daea7afcfe81a681b0c460..5d784a097de4ef68ec2df0bdc1adce94fa737809 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp +++ b/source/RobotAPI/libraries/armem/core/diskmemory/Entity.cpp @@ -18,7 +18,7 @@ namespace armarx::armem::d_ltm wm::Entity Entity::convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const { - wm::Entity m; + wm::Entity m(id()); for (const auto& [_, s] : _container) { m.addSnapshot(s.convert(expectedStructure)); @@ -67,7 +67,8 @@ namespace armarx::armem::d_ltm { if (const auto& it = _container.find(k); it != _container.end()) { - it->second.setTo(s); + // timestamp already exists + // We assume that a snapshot does not change, so ignore } else { diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.cpp index 4da151bd537f98e0e5693d948f202d68859f0d76..dd0458b83bbb8ed461ddeab50af42181fda843e4 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.cpp +++ b/source/RobotAPI/libraries/armem/core/diskmemory/EntityInstance.cpp @@ -41,6 +41,7 @@ namespace armarx::armem::d_ltm void EntityInstance::_copySelf(EntityInstance& other) const { EntityInstanceBase<EntityInstance>::_copySelf(other); + other.path = path; } std::filesystem::path EntityInstance::_fullPath() const @@ -49,6 +50,7 @@ namespace armarx::armem::d_ltm { return _fullPath(*path); } + ARMARX_WARNING << "The path of the disk memory instance with id '" << id().str() << "' is not set. This may lead to errors."; return std::filesystem::path(); } @@ -59,7 +61,7 @@ namespace armarx::armem::d_ltm wm::EntityInstance EntityInstance::convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const { - std::filesystem::path p = _fullPath(); + std::filesystem::path p = _fullPath(); // here we assume that "reload" has been called first std::filesystem::path d = p / (std::string(DATA_FILENAME) + ".json"); if (std::filesystem::is_regular_file(d)) @@ -67,7 +69,7 @@ namespace armarx::armem::d_ltm std::ifstream ifs(d); std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); - nlohmann::json j(file_content); + nlohmann::json j = nlohmann::json::parse(file_content); auto aron = std::make_shared<aron::datanavigator::DictNavigator>(); to_aron(aron, j, expectedStructure); wm::EntityInstance e(id()); @@ -76,7 +78,7 @@ namespace armarx::armem::d_ltm } else { - throw error::ArMemError("An diskMemory EntityInstance is not leading to a regular file."); + throw error::ArMemError("An diskMemory EntityInstance is not leading to a regular file. The path was: " + d.string()); } } @@ -84,7 +86,7 @@ namespace armarx::armem::d_ltm { if (!p_ptr) { - ARMARX_WARNING << "The entered is NULL."; + ARMARX_WARNING << "The entered path is NULL."; } std::filesystem::path p = _fullPath(*p_ptr); if (!std::filesystem::is_directory(p)) diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp index cc1124ab2335d1acf69550350a0bc980c0af7b7f..ab5b56d2274f78c350818693c269af18f0a4a979 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp +++ b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.cpp @@ -26,7 +26,7 @@ namespace armarx::armem::d_ltm wm::EntitySnapshot EntitySnapshot::convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const { - wm::EntitySnapshot m; + wm::EntitySnapshot m(id()); for (const auto& s : _container) { m.addInstance(s.convert(expectedStructure)); @@ -56,7 +56,7 @@ namespace armarx::armem::d_ltm std::filesystem::path d = p / std::to_string(i); if (std::filesystem::is_directory(d)) { - auto wms = _container.emplace_back(id().withInstanceIndex(i)); + auto& wms = _container.emplace_back(id().withInstanceIndex(i)); wms.reload(p_ptr); } else @@ -79,7 +79,7 @@ namespace armarx::armem::d_ltm return; } - // We remove the contente here and reset it with new values + // We remove the content here and reset it with new values _container.clear(); int i = 0; @@ -95,7 +95,7 @@ namespace armarx::armem::d_ltm continue;; } - auto wms = _container.emplace_back(id().withInstanceIndex(i++)); + auto& wms = _container.emplace_back(id().withInstanceIndex(i++)); wms.path = path; wms.setTo(s); } diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.h b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.h index f73702857fc6700e5cfae5f6d08b369240d08f79..545a8c0d64641c65e7faf7aa26dea77ee9865e0c 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.h +++ b/source/RobotAPI/libraries/armem/core/diskmemory/EntitySnapshot.h @@ -29,7 +29,7 @@ namespace armarx::armem::d_ltm void reload(const std::shared_ptr<std::filesystem::path>&); wm::EntitySnapshot convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const; - // MongoDB connection + // FS connection void setTo(const wm::EntitySnapshot&); private: diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/Memory.cpp index 1038f5bfbed5d2f19b06819471e65cb5d0aab042..0fb6fba92b2ebc116787bffba2d7ed5bc743227b 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/Memory.cpp +++ b/source/RobotAPI/libraries/armem/core/diskmemory/Memory.cpp @@ -24,8 +24,8 @@ namespace armarx::armem::d_ltm wm::Memory Memory::convert() const { - wm::Memory m; - for (const auto& [_, s] : _container) + wm::Memory m(id()); + for (const auto& [k, s] : _container) { m.addCoreSegment(s.convert()); } @@ -44,7 +44,7 @@ namespace armarx::armem::d_ltm if (!std::filesystem::exists(p)) { - ARMARX_INFO << "The entered path does not exist. Assuming an empty container."; + ARMARX_INFO << "The entered path does not exist. Returning empty memory."; } else { @@ -73,7 +73,15 @@ namespace armarx::armem::d_ltm } else { - std::filesystem::create_directory(_fullPath() / k); + try + { + std::filesystem::create_directory(_fullPath() / k); + } + catch (...) + { + ARMARX_WARNING << GetHandledExceptionString(); + return; + } auto wms = _container.emplace(k, id().withCoreSegmentName(k)); wms.first->second.path = path; diff --git a/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.cpp b/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.cpp index 1132b2fca64d906276c60886e5d50486b7126c8b..620e819f6b1fc05d4aeadc285edb087f5ea0e119 100644 --- a/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.cpp +++ b/source/RobotAPI/libraries/armem/core/diskmemory/ProviderSegment.cpp @@ -23,7 +23,7 @@ namespace armarx::armem::d_ltm wm::ProviderSegment ProviderSegment::convert(const aron::typenavigator::NavigatorPtr& expectedStructure) const { - wm::ProviderSegment m; + wm::ProviderSegment m(id()); for (const auto& [_, s] : _container) { if (hasAronType()) @@ -107,8 +107,6 @@ namespace armarx::armem::d_ltm try { std::filesystem::create_directory(_fullPath() / k); - continue; - } catch (...) { diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp index 3865e6df0dfb2112d14d5ee23c40e3a740626307..153852eaf50f4d71573c1bafdc44b052c0e1317c 100644 --- a/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp +++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Entity.cpp @@ -63,7 +63,7 @@ namespace armarx::armem::ltm { if (const auto& it = _container.find(k); it != _container.end()) { - // segment already exists + // timestamp already exists // We assume that a snapshot does not change, so ignore } else diff --git a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp index ebfaa65cb2874649dc5f737998cefee3a02ff6ea..a846cffac89c6118b6c476d3531e47cd49f96f8a 100644 --- a/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp +++ b/source/RobotAPI/libraries/armem/server/MemoryToIceAdapter.cpp @@ -29,7 +29,6 @@ namespace armarx::armem::server data::AddSegmentResult MemoryToIceAdapter::addSegment(const data::AddSegmentInput& input, bool addCoreSegments) { - ARMARX_DEBUG << "Adding segment '" << input.coreSegmentName << "/" << input.providerSegmentName << "'."; ARMARX_CHECK_NOT_NULL(workingMemory); data::AddSegmentResult output; @@ -206,10 +205,10 @@ namespace armarx::armem::server : armem::DataMode::NoData); armem::query::data::Result result; - wm::Memory wm_result = wm_processor.process(input, *workingMemory, /* ignore if: */ { query::data::QueryTarget::LTM }); + wm::Memory wm_result = wm_processor.process(input, *workingMemory, /* execute if: */ { query::data::QueryTarget::WM }); armem::ltm::query_proc::MemoryQueryProcessor ltm_processor; - ltm::Memory ltm_result = ltm_processor.process(input, *longtermMemory, /* ignore if: */ { query::data::QueryTarget::WM }); + ltm::Memory ltm_result = ltm_processor.process(input, *longtermMemory, /* execute if: */ { query::data::QueryTarget::LTM }); if (ltm_result.hasData()) @@ -238,6 +237,11 @@ namespace armarx::armem::server } result.success = true; + if (result.memory->coreSegments.size() == 0) + { + ARMARX_DEBUG << "No data in memory found after query."; + } + return result; } @@ -262,7 +266,7 @@ namespace armarx::armem::server { // force query to only query WM // TODO: Think about other query class (fabian.peller) - query->target = query::data::QueryTarget::WM; + query->targets = {query::data::QueryTarget::WM}; } armem::query::data::Result queryResult = this->query(input.query); diff --git a/source/RobotAPI/libraries/armem/server/Segment.cpp b/source/RobotAPI/libraries/armem/server/Segment.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec25ce7843a6cca3555dc9789f3570e0bfb51425 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/Segment.cpp @@ -0,0 +1 @@ +#include "Segment.h" diff --git a/source/RobotAPI/libraries/armem/server/Segment.h b/source/RobotAPI/libraries/armem/server/Segment.h new file mode 100644 index 0000000000000000000000000000000000000000..5d1c31f4179773a5fa2e96d9ebd211507e91893d --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/Segment.h @@ -0,0 +1,160 @@ +#pragma once + +// STD/STL +#include <mutex> +#include <string> + +// ArmarX +#include <ArmarXCore/core/logging/Logging.h> +#include <ArmarXCore/core/application/properties/PropertyDefinitionContainer.h> + +#include "MemoryToIceAdapter.h" + + +namespace armarx::armem::server +{ + /** + * @brief A base class for memory servers to manage their segments. + * A segment can inherit this base class and add segment specific code. + * TODO (fabian.peller): add concept to only accept coresegments, providersegments or entitysegments + */ + template <class SegmentType> + class SegmentBase : public armarx::Logging + { + public: + SegmentBase() = delete; + SegmentBase(armem::server::MemoryToIceAdapter& iceMemory, std::mutex& memoryMutex) : + iceMemory(iceMemory), + memoryMutex(memoryMutex) + { + Logging::setTag("armarx::armem::Segment"); + } + + virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "") = 0; + virtual void onInit() = 0; + virtual void onConnect() = 0; + + protected: + private: + + public: + protected: + // Memory connection + armem::server::MemoryToIceAdapter& iceMemory; + std::mutex& memoryMutex; + + SegmentType* segment; + + private: + }; + + namespace wm + { + template <class BusinessClassObject> + class CoreSegmentBase : public SegmentBase<armarx::armem::wm::CoreSegment> + { + using Base = SegmentBase<armarx::armem::wm::CoreSegment>; + + public: + CoreSegmentBase(armem::server::MemoryToIceAdapter& iceMemory, std::mutex& memoryMutex): + Base(iceMemory, memoryMutex) + { + Logging::setTag("armarx::armem::wm::Segment"); + } + + virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "") override + { + ARMARX_CHECK_NOT_NULL(defs); + + defs->optional(p.coreSegmentName, prefix + "CoreSegmentName", "Name of the '" + p.coreSegmentName + "' core segment."); + defs->optional(p.maxHistorySize, prefix + "MaxHistorySize", "Maximal size of '" + p.coreSegmentName + "' history (-1 for infinite)."); + } + + virtual void onInit() override + { + ARMARX_CHECK_NOT_NULL(iceMemory.workingMemory); + + segment = &iceMemory.workingMemory->addCoreSegment(p.coreSegmentName, BusinessClassObject::toAronType()); + segment->setMaxHistorySize(p.maxHistorySize); + } + + virtual void onConnect() override + { + + } + + protected: + private: + + public: + protected: + struct Properties + { + std::string coreSegmentName = ""; + int maxHistorySize = -1; + }; + Properties p; + }; + + + template <class BusinessClassObject> + class ProviderSegmentBase : public SegmentBase<armarx::armem::wm::ProviderSegment> + { + using Base = SegmentBase<armarx::armem::wm::ProviderSegment>; + + public: + ProviderSegmentBase(armem::server::MemoryToIceAdapter& iceMemory, std::mutex& memoryMutex): + Base(iceMemory, memoryMutex) + { + Logging::setTag("armarx::armem::wm::Segment"); + } + + virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "") override + { + ARMARX_CHECK_NOT_NULL(defs); + + defs->optional(p.coreSegmentName, prefix + "CoreSegmentName", "Name of the core segment."); + defs->optional(p.providerSegmentName, prefix + "ProviderSegmentName", "Name of the provider segment."); + defs->optional(p.maxHistorySize, prefix + "MaxHistorySize", "Maximal size of history (-1 for infinite)."); + } + + virtual void onInit() override + { + ARMARX_CHECK_NOT_NULL(iceMemory.workingMemory); + + if (!iceMemory.workingMemory->hasCoreSegment(p.coreSegmentName)) + { + coreSegment = &iceMemory.workingMemory->addCoreSegment(p.coreSegmentName); + coreSegment->setMaxHistorySize(p.maxHistorySize); + } + else + { + coreSegment = &iceMemory.workingMemory->getCoreSegment(p.coreSegmentName); + } + + segment = &coreSegment->addProviderSegment(p.providerSegmentName, BusinessClassObject::toAronType()); + segment->setMaxHistorySize(p.maxHistorySize); + } + + virtual void onConnect() override + { + + } + + protected: + private: + + public: + protected: + struct Properties + { + std::string coreSegmentName = ""; + std::string providerSegmentName = ""; + int maxHistorySize = -1; + }; + Properties p; + + armarx::armem::wm::CoreSegment* coreSegment; + }; + } +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h index 69a305e45befca5a9189c6fb264985126d16fbf3..f71aede29731259471cf5e8dd660917b3e848bb1 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/BaseQueryProcessorBase.h @@ -1,5 +1,6 @@ #pragma once +#include <ArmarXCore/core/logging/Logging.h> #include <RobotAPI/interface/armem/query.h> @@ -18,39 +19,67 @@ namespace armarx::armem::base::query_proc public: - DataT process(const QueryT& query, const DataT& data, const std::vector<query::data::QueryTarget>& ignoreTargets = {}) const + DataT process(const QueryT& query, const DataT& data, const query::data::QueryTargets& executeIf = {}) const { DataT result = data.copyEmpty(); - if (std::find(ignoreTargets.begin(), ignoreTargets.end(), query.target) != ignoreTargets.end()) + for (const auto queryTarget : query.targets) { - return result; + if (std::find(executeIf.begin(), executeIf.end(), queryTarget) != executeIf.end()) + { + this->process(result, query, data); + break; + } } - this->process(result, query, data); return result; } - DataT process(const QueryPtrT& query, const DataT& data, const std::vector<query::data::QueryTarget>& ignoreTargets = {}) const + DataT process(const QueryPtrT& query, const DataT& data, const query::data::QueryTargets& executeIf = {}) const { - return this->process(*query, *data, ignoreTargets); + return this->process(*query, *data, executeIf); } - DataT process(const QuerySeqT& queries, const DataT& data, const std::vector<query::data::QueryTarget>& ignoreTargets = {}) const + DataT process(const QuerySeqT& queries, const DataT& data, const query::data::QueryTargets& executeIf = {}) const { DataT result = data.copyEmpty(); - this->process(result, queries, data, ignoreTargets); + this->process(result, queries, data, executeIf); return result; } - void process(DataT& result, const QuerySeqT& queries, const DataT& data, const std::vector<query::data::QueryTarget>& ignoreTargets = {}) const + void process(DataT& result, const QuerySeqT& queries, const DataT& data, const query::data::QueryTargets& executeIf = {}) const { + if (queries.empty()) + { + ARMARX_DEBUG << "There are no queries to process."; + return; + } + + if (executeIf.empty()) + { + ARMARX_DEBUG << "Could not execute query. ExecuteIf s empty."; + return; + } + for (const auto& query : queries) { - if (std::find(ignoreTargets.begin(), ignoreTargets.end(), query->target) != ignoreTargets.end()) + if (query->targets.empty()) { + ARMARX_DEBUG << "The targets of a query are empty"; continue; } - this->process(result, *query, data); + + for (const auto queryTarget : query->targets) + { + if (std::find(executeIf.begin(), executeIf.end(), queryTarget) != executeIf.end()) + { + this->process(result, *query, data); + break; + } + else + { + ARMARX_DEBUG << "The query target " << queryTarget << " was not found in executeIf: " << executeIf; + } + } } } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h index 5de194d7ba2debada4ef9363005b1a7f2e927e94..cc06defc93976ea018ab8a7d3823a00d6121543d 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/base/MemoryQueryProcessorBase.h @@ -34,9 +34,9 @@ namespace armarx::armem::base::query_proc using Base::process; - _MemoryT process(const armem::query::data::Input& input, const _MemoryT& memory, const std::vector<query::data::QueryTarget>& ignoreTargets = {}) const + _MemoryT process(const armem::query::data::Input& input, const _MemoryT& memory, const std::vector<query::data::QueryTarget>& executeIf = {}) const { - return this->process(input.memoryQueries, memory, ignoreTargets); + return this->process(input.memoryQueries, memory, executeIf); } void process(_MemoryT& result, diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..68821bcd95cdf2aaccf7126d4055495d39d0393d --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.cpp @@ -0,0 +1 @@ +#include "BaseQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..84f967795fd26d79d173a14e71498dbec7d56ee1 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/BaseQueryProcessor.h @@ -0,0 +1,26 @@ +#pragma once + +#include <RobotAPI/interface/armem/query.h> +#include <RobotAPI/libraries/armem/core/DataMode.h> + +#include "../base/BaseQueryProcessorBase.h" + + +namespace armarx::armem::d_ltm::query_proc +{ + /** + * @brief Base class for memory query processors. + */ + template <class DataT, class QueryT> + class BaseQueryProcessor : + virtual public base::query_proc::BaseQueryProcessorBase<DataT, QueryT> + { + using Base = base::query_proc::BaseQueryProcessorBase<DataT, QueryT>; + + public: + BaseQueryProcessor() + {} + + protected: + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afbe35ad15eea0342b0b0d4df0200aaf0d32aa2a --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.cpp @@ -0,0 +1 @@ +#include "CoreSegmentQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..1c40f7fc64b0a2c59fdc3e54d968c6627480cbb0 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/CoreSegmentQueryProcessor.h @@ -0,0 +1,36 @@ +#pragma once + +#include "BaseQueryProcessor.h" +#include "../base/CoreSegmentQueryProcessorBase.h" + +#include "../../../core/diskmemory/CoreSegment.h" + +#include "ProviderSegmentQueryProcessor.h" + + +namespace armarx::armem::d_ltm::query_proc +{ + /** + * @brief Handles memory queries. + */ + class CoreSegmentQueryProcessor : + virtual public BaseQueryProcessor<d_ltm::CoreSegment, armem::query::data::CoreSegmentQuery>, + virtual public base::query_proc::CoreSegmentQueryProcessorBase<d_ltm::CoreSegment> + { + using Base = BaseQueryProcessor<d_ltm::CoreSegment, armem::query::data::CoreSegmentQuery>; + + public: + CoreSegmentQueryProcessor() : + Base() + {} + + protected: + virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override + { + return providerSegmentProcessor.process(q, s, {armem::query::data::QueryTarget::Disk}); + } + + private: + ProviderSegmentQueryProcessor providerSegmentProcessor; + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1c321b026b173c6552758fb9d8b9fdf722ea5a4 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.cpp @@ -0,0 +1 @@ +#include "EntityQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..4d1b9e14e21804f1e44f1a2fd6456da37a113c03 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/EntityQueryProcessor.h @@ -0,0 +1,39 @@ +#pragma once + +#include "BaseQueryProcessor.h" +#include "../base/EntityQueryProcessorBase.h" + +#include "../../../core/diskmemory/Entity.h" + +#include "EntityQueryProcessor.h" + +namespace armarx::armem::d_ltm::query_proc +{ + /** + * @brief Handles memory queries. + */ + class EntityQueryProcessor : + virtual public BaseQueryProcessor<d_ltm::Entity, armem::query::data::EntityQuery>, + virtual public base::query_proc::EntityQueryProcessorBase<d_ltm::Entity> + { + using Base = BaseQueryProcessor<d_ltm::Entity, armem::query::data::EntityQuery>; + + public: + EntityQueryProcessor() : + Base() + {} + + private: + void addResultSnapshot(d_ltm::Entity& result, d_ltm::Entity::ContainerT::const_iterator it) const override + { + addResultSnapshot(result, it->second); + } + + void addResultSnapshot(d_ltm::Entity& result, const d_ltm::EntitySnapshot& snapshot) const override + { + result.addSnapshot(snapshot.copy()); + } + + }; + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69b04de6c9e623286a5bda836dddfdc8b551b64a --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.cpp @@ -0,0 +1 @@ +#include "MemoryQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..2abdcc1ccc7c25a317edc67e36835cb4a4df2f9b --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h @@ -0,0 +1,35 @@ +#pragma once + +#include "BaseQueryProcessor.h" +#include "../base/MemoryQueryProcessorBase.h" + +#include "../../../core/diskmemory/Memory.h" + +#include "CoreSegmentQueryProcessor.h" + +namespace armarx::armem::d_ltm::query_proc +{ + /** + * @brief Handles memory queries. + */ + class MemoryQueryProcessor : + virtual public BaseQueryProcessor<d_ltm::Memory, armem::query::data::MemoryQuery>, + virtual public base::query_proc::MemoryQueryProcessorBase<d_ltm::Memory> + { + using Base = BaseQueryProcessor<d_ltm::Memory, armem::query::data::MemoryQuery>; + + public: + MemoryQueryProcessor() : + Base() + {} + + protected: + virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override + { + return coreSegmentProcessor.process(q, s, {armem::query::data::QueryTarget::Disk}); + } + + private: + CoreSegmentQueryProcessor coreSegmentProcessor; + }; +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a2a4405001f0904b74fc6afcf96813eef0879cd --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.cpp @@ -0,0 +1 @@ +#include "ProviderSegmentQueryProcessor.h" diff --git a/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..94c2e756875c1152f8018f70c5e0d691a5704582 --- /dev/null +++ b/source/RobotAPI/libraries/armem/server/query_proc/diskmemory/ProviderSegmentQueryProcessor.h @@ -0,0 +1,37 @@ +#pragma once + +#include "BaseQueryProcessor.h" +#include "../base/ProviderSegmentQueryProcessorBase.h" + +#include "../../../core/diskmemory/ProviderSegment.h" + +#include "EntityQueryProcessor.h" + +namespace armarx::armem::d_ltm::query_proc +{ + /** + * @brief Handles memory queries. + */ + class ProviderSegmentQueryProcessor : + virtual public BaseQueryProcessor<d_ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>, + virtual public base::query_proc::ProviderSegmentQueryProcessorBase<d_ltm::ProviderSegment> + { + using Base = BaseQueryProcessor<d_ltm::ProviderSegment, armem::query::data::ProviderSegmentQuery>; + + public: + ProviderSegmentQueryProcessor() : + Base() + {} + + protected: + virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override + { + return entityProcessor.process(q, s, {armem::query::data::QueryTarget::Disk}); + } + + private: + EntityQueryProcessor entityProcessor; + + }; + +} diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h index dc379f1d88fa82bbe886e412e0341079fa43fce9..e333dd816aedabbb8dfa7209c687caf727d9ccf9 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/CoreSegmentQueryProcessor.h @@ -27,7 +27,7 @@ namespace armarx::armem::ltm::query_proc protected: virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override { - return providerSegmentProcessor.process(q, s); + return providerSegmentProcessor.process(q, s, {armem::query::data::QueryTarget::LTM}); } private: diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h index 952d759c8552c7939f6e08266e7feb880a85438e..5ec4c5dde481e16f0af30589d57ff2a447d81221 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/EntityQueryProcessor.h @@ -31,7 +31,6 @@ namespace armarx::armem::ltm::query_proc void addResultSnapshot(ltm::Entity& result, const ltm::EntitySnapshot& snapshot) const override { - ARMARX_INFO << "addResultSnapshot" << __LINE__; result.addSnapshot(snapshot.copy()); } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h index a5129417262515975efa247398602272865ee5ec..569014d6579eeb6c99996e4be5b7cb68f65457b1 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/MemoryQueryProcessor.h @@ -26,7 +26,7 @@ namespace armarx::armem::ltm::query_proc protected: virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override { - return coreSegmentProcessor.process(q, s); + return coreSegmentProcessor.process(q, s, {armem::query::data::QueryTarget::LTM}); } private: diff --git a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h index e0c6db9e3ef06e6241e9af8c572bb7fc78eec452..5443acfd6594b98250711cf2acfd434a98414066 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/longtermmemory/ProviderSegmentQueryProcessor.h @@ -26,7 +26,7 @@ namespace armarx::armem::ltm::query_proc protected: virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override { - return entityProcessor.process(q, s); + return entityProcessor.process(q, s, {armem::query::data::QueryTarget::LTM}); } private: diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h index 079f63ac59928f2bd4ace9ab7ab033bef93c04a1..390ab66f656ece6010457f12f09917d9fca413f6 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/CoreSegmentQueryProcessor.h @@ -31,7 +31,7 @@ namespace armarx::armem::wm::query_proc protected: virtual ProviderSegmentT providerSegmentProcessorProcess(const armem::query::data::ProviderSegmentQuerySeq& q, const ProviderSegmentT& s) const override { - return providerSegmentProcessor.process(q, s); + return providerSegmentProcessor.process(q, s, {armem::query::data::QueryTarget::WM}); } private: diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h index b0616c658a7915568fd910a8f35c9d4701aa1d0b..8284df202bbcf602e2433639fe85388ca13d75ff 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h @@ -24,7 +24,7 @@ namespace armarx::armem::wm::query_proc protected: virtual CoreSegmentT coreSegmentProcessorProcess(const armem::query::data::CoreSegmentQuerySeq& q, const CoreSegmentT& s) const override { - return coreSegmentProcessor.process(q, s); + return coreSegmentProcessor.process(q, s, {armem::query::data::QueryTarget::WM}); } diff --git a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h index 1b2e9ba97850ed1f62f2d761a51996f3b2bb2665..468138d9e2bbd526db3632019beca6a5a29f8269 100644 --- a/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h +++ b/source/RobotAPI/libraries/armem/server/query_proc/workingmemory/ProviderSegmentQueryProcessor.h @@ -30,7 +30,7 @@ namespace armarx::armem::wm::query_proc protected: virtual EntityT entityProcessorProcess(const armem::query::data::EntityQuerySeq& q, const EntityT& s) const override { - return entityProcessor.process(q, s); + return entityProcessor.process(q, s, {armem::query::data::QueryTarget::WM}); } private: diff --git a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp index b2d07571d619531f45381d1238ca8201b8e0175e..4b83fd43261e1d97da45495f5da94279931e606f 100644 --- a/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp +++ b/source/RobotAPI/libraries/armem/test/ArMemQueryTest.cpp @@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(test_entity_Single_latest) BOOST_AUTO_TEST_CASE(test_entity_Single_existing) { - addResults(query::entity::Single { query::QueryTarget::WMAndLTM, 3000 }); + addResults(query::entity::Single({query::QueryTarget::WM, query::QueryTarget::LTM}, 3000)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(test_entity_Single_existing) BOOST_AUTO_TEST_CASE(test_entity_Single_non_existing) { - addResults(query::entity::Single { query::QueryTarget::WMAndLTM, 3500 }); + addResults(query::entity::Single({query::QueryTarget::WM, query::QueryTarget::LTM}, 3500)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(test_entity_All) BOOST_AUTO_TEST_CASE(test_entity_TimeRange_slice) { - addResults(query::entity::TimeRange{ query::QueryTarget::WMAndLTM, 1500, 3500 }); + addResults(query::entity::TimeRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 1500, 3500)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_slice) BOOST_AUTO_TEST_CASE(test_entity_TimeRange_exact) { - addResults(query::entity::TimeRange{ query::QueryTarget::WMAndLTM, 2000, 4000 }); + addResults(query::entity::TimeRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 2000, 4000)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -223,8 +223,8 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_exact) BOOST_AUTO_TEST_CASE(test_entity_TimeRange_all) { - addResults(query::entity::TimeRange{ query::QueryTarget::WMAndLTM, 0, 10000 }); - addResults(query::entity::TimeRange{ query::QueryTarget::WMAndLTM, -1, -1 }); + addResults(query::entity::TimeRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 0, 10000)); + addResults(query::entity::TimeRange({query::QueryTarget::WM, query::QueryTarget::LTM}, -1, -1)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -242,8 +242,8 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_all) BOOST_AUTO_TEST_CASE(test_entity_TimeRange_empty) { - addResults(query::entity::TimeRange{ query::QueryTarget::WMAndLTM, 2400, 2600 }); - addResults(query::entity::TimeRange{ query::QueryTarget::WMAndLTM, 6000, 1000 }); + addResults(query::entity::TimeRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 2400, 2600)); + addResults(query::entity::TimeRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 6000, 1000)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -257,7 +257,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_empty) BOOST_AUTO_TEST_CASE(test_entity_TimeRange_from_start) { - addResults(query::entity::TimeRange{ query::QueryTarget::WMAndLTM, -1, 2500 }); + addResults(query::entity::TimeRange({query::QueryTarget::WM, query::QueryTarget::LTM}, -1, 2500)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_from_start) BOOST_AUTO_TEST_CASE(test_entity_TimeRange_to_end) { - addResults(query::entity::TimeRange{ query::QueryTarget::WMAndLTM, 2500, -1 }); + addResults(query::entity::TimeRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 2500, -1)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeRange_to_end) BOOST_AUTO_TEST_CASE(test_entity_BeforeTime_1) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::BeforeTime{ query::QueryTarget::WMAndLTM, 3500, 1 }); + addResults(query::entity::BeforeTime({query::QueryTarget::WM, query::QueryTarget::LTM}, 3500, 1)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(test_entity_BeforeTime_1) BOOST_AUTO_TEST_CASE(test_entity_BeforeTime_2) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::BeforeTime{ query::QueryTarget::WMAndLTM, 3500, 2}); + addResults(query::entity::BeforeTime({query::QueryTarget::WM, query::QueryTarget::LTM}, 3500, 2)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(test_entity_BeforeTime_2) BOOST_AUTO_TEST_CASE(test_entity_BeforeOrAtTime_before) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::BeforeOrAtTime{ query::QueryTarget::WMAndLTM, 3500 }); + addResults(query::entity::BeforeOrAtTime({query::QueryTarget::WM, query::QueryTarget::LTM}, 3500)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -358,7 +358,7 @@ BOOST_AUTO_TEST_CASE(test_entity_BeforeOrAtTime_before) BOOST_AUTO_TEST_CASE(test_entity_BeforeOrAtTime_at) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::BeforeOrAtTime{ query::QueryTarget::WMAndLTM, 3000 }); + addResults(query::entity::BeforeOrAtTime({query::QueryTarget::WM, query::QueryTarget::LTM}, 3000)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -373,7 +373,7 @@ BOOST_AUTO_TEST_CASE(test_entity_BeforeOrAtTime_at) BOOST_AUTO_TEST_CASE(test_entity_BeforeOrAtTime_lookup_past) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::BeforeOrAtTime{ query::QueryTarget::WMAndLTM, 1 }); + addResults(query::entity::BeforeOrAtTime({query::QueryTarget::WM, query::QueryTarget::LTM}, 1)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -393,7 +393,7 @@ BOOST_AUTO_TEST_CASE(test_entity_BeforeOrAtTime_lookup_past) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_no_limit) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 3500, -1}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 3500, -1)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -419,7 +419,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_no_limit) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_600) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 3500, 600}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 3500, 600)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -445,7 +445,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_600) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_too_small) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 3500, 100}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 3500, 100)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -464,7 +464,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_too_small) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_only_next) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 3700, 400}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 3700, 400)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -489,7 +489,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_only_next) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_only_previous) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 3300, 400}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 3300, 400)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -514,7 +514,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_limit_only_previous) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_perfect_match) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 3000, -1}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 3000, -1)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -539,7 +539,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_perfect_match) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_past) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 1, 1}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 1, 1)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -557,7 +557,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_past) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_future) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 10'000, 1}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 10'000, 1)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -575,7 +575,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_future) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_future_valid) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, 10'000, -1}); + addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, 10'000, -1)); BOOST_REQUIRE_EQUAL(results.size(), 2); for (const auto& result : results) @@ -594,7 +594,7 @@ BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_future_valid) BOOST_AUTO_TEST_CASE(test_entity_TimeApprox_lookup_invalid_timestamp) { - BOOST_REQUIRE_THROW(addResults(query::entity::TimeApprox{ query::QueryTarget::WMAndLTM, -1, 1}), ::armarx::LocalException); + BOOST_REQUIRE_THROW(addResults(query::entity::TimeApprox({query::QueryTarget::WM, query::QueryTarget::LTM}, -1, 1)), ::armarx::LocalException); } @@ -634,7 +634,7 @@ BOOST_AUTO_TEST_CASE(test_negative_index_semantics) BOOST_AUTO_TEST_CASE(test_entity_IndexRange_all_default) { addResults(query::entity::IndexRange()); - addResults(query::entity::IndexRange(query::QueryTarget::WMAndLTM, 0, -1)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 0, -1)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -654,10 +654,10 @@ BOOST_AUTO_TEST_CASE(test_entity_IndexRange_all_default) BOOST_AUTO_TEST_CASE(test_entity_IndexRange_slice) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 1, 3 }); // => [1, 2, 3] - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 1, -2 }); // 5 - 2 = 3 - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, -4, 3 }); // 5 - 4 = 1 - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, -4, -2 }); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 1, 3)); // => [1, 2, 3] + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 1, -2)); // 5 - 2 = 3 + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, -4, 3)); // 5 - 4 = 1 + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, -4, -2)); BOOST_REQUIRE_GT(results.size(), 0); for (const armem::wm::Entity& result : results) @@ -679,12 +679,12 @@ BOOST_AUTO_TEST_CASE(test_entity_IndexRange_slice) BOOST_AUTO_TEST_CASE(test_entity_IndexRange_empty_range) { BOOST_REQUIRE_EQUAL(entity.size(), 5); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 1, 0 }); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 2, 1 }); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 5, 3 }); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 4, -3 }); // 5-3 = 2 - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 3, -3 }); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 1, -5 }); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 1, 0)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 2, 1)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 5, 3)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 4, -3)); // 5-3 = 2 + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 3, -3)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 1, -5)); BOOST_REQUIRE_GT(results.size(), 0); @@ -701,12 +701,12 @@ BOOST_AUTO_TEST_CASE(test_entity_IndexRange_empty_entity) { entity.clear(); BOOST_REQUIRE_EQUAL(entity.size(), 0); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 0, 0 }); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 0, 10 }); - addResults(query::entity::IndexRange{query::QueryTarget::WMAndLTM, -10, -1 }); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 2, 5 }); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, 3, -3 }); - addResults(query::entity::IndexRange{ query::QueryTarget::WMAndLTM, -1, 10 }); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 0, 0)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 0, 10)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, -10, -1)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 2, 5)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, 3, -3)); + addResults(query::entity::IndexRange({query::QueryTarget::WM, query::QueryTarget::LTM}, -1, 10)); BOOST_REQUIRE_GT(results.size(), 0); diff --git a/source/RobotAPI/libraries/armem/util/util.h b/source/RobotAPI/libraries/armem/util/util.h index f160efcd49b3f3ddc3ec93aa98b07e5ff80c8dc6..35fc1538b78df0b817e7ae0676be68e9675d1f0f 100644 --- a/source/RobotAPI/libraries/armem/util/util.h +++ b/source/RobotAPI/libraries/armem/util/util.h @@ -46,6 +46,17 @@ namespace armarx::armem static_assert(std::is_base_of<armarx::aron::cppserializer::AronCppClass, AronClass>::value); + + if (!item.data()) + { + return std::nullopt; + } + + if (item.data()->getDescriptor() != aron::data::Descriptor::eDict) + { + return std::nullopt; + } + try { AronClass t; diff --git a/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.cpp b/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.cpp index c68673377563e83019640755699187ebee39a418..5016db50bf5da8dc10d0fac5b5c004b9178ddc40 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.cpp +++ b/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.cpp @@ -15,26 +15,31 @@ namespace armarx::armem::gui { setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Fixed); - QLayout* layout = new QHBoxLayout(); - this->setLayout(layout); + auto vlayout = new QVBoxLayout(); + auto hlayout = new QHBoxLayout(); const int margin = 0; - layout->setContentsMargins(margin, margin, margin, margin); + vlayout->setContentsMargins(margin, margin, margin, margin); _lineEdit = new QLineEdit("/tmp/MemoryExport", this); - _exportHereButton = new QPushButton("Export here", this); + _lineEdit->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); + _lineEdit->setMinimumWidth(400); - _storeButton = new QPushButton("Store in LTM", this); + _storeOnDiskButton = new QPushButton("Store current result on local Disk", this); - layout->addWidget(_lineEdit); - layout->addWidget(_exportHereButton); - layout->addWidget(_storeButton); + _storeInLTMButton = new QPushButton("Store current result in LTM", this); + vlayout->addWidget(_lineEdit); + hlayout->addWidget(_storeOnDiskButton); + hlayout->addWidget(_storeInLTMButton); + vlayout->addItem(hlayout); + + this->setLayout(vlayout); // Private connections. // Public connections. - connect(_storeButton, &QPushButton::pressed, this, &This::store); - connect(_exportHereButton, &QPushButton::pressed, this, &This::exportHere); + connect(_storeInLTMButton, &QPushButton::pressed, this, &This::storeInLTM); + connect(_storeOnDiskButton, &QPushButton::pressed, this, &This::storeOnDisk); } QLineEdit* MemoryControlWidget::pathInputBox() @@ -47,14 +52,14 @@ namespace armarx::armem::gui return _lineEdit->text(); } - QPushButton* MemoryControlWidget::storeButton() + QPushButton* MemoryControlWidget::storeInLTMButton() { - return _storeButton; + return _storeInLTMButton; } - QPushButton* MemoryControlWidget::exportHereButton() + QPushButton* MemoryControlWidget::storeOnDiskButton() { - return _exportHereButton; + return _storeOnDiskButton; } } diff --git a/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.h b/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.h index 4f8acc62ac9c8918f887703d9188e76cfc9f8584..19831694acc7b9251c7d372b8381f755df1bc292 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.h +++ b/source/RobotAPI/libraries/armem_gui/MemoryControlWidget.h @@ -20,17 +20,15 @@ namespace armarx::armem::gui QLineEdit* pathInputBox(); QString getEnteredPath(); - QPushButton* storeButton(); - QPushButton* loadButton(); - QPushButton* exportHereButton(); + QPushButton* storeInLTMButton(); + QPushButton* storeOnDiskButton(); public slots: signals: - void store(); - void load(); - void exportHere(); + void storeInLTM(); + void storeOnDisk(); private slots: @@ -42,9 +40,8 @@ namespace armarx::armem::gui QLineEdit* _lineEdit; - QPushButton* _storeButton; - QPushButton* _loadButton; - QPushButton* _exportHereButton; + QPushButton* _storeInLTMButton; + QPushButton* _storeOnDiskButton; }; diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp index 6d711ac1dfee696b069a0408a001f5d98a08f2cd..5037bad396c0e7a83b7704b4895a25225ae8106f 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp +++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp @@ -5,6 +5,9 @@ #include <RobotAPI/libraries/armem/core/diskmemory/Memory.h> +#include <RobotAPI/libraries/armem/server/query_proc/diskmemory/MemoryQueryProcessor.h> +#include <RobotAPI/libraries/armem/server/query_proc/workingmemory/MemoryQueryProcessor.h> + #include <ArmarXGui/libraries/SimpleConfigDialog/SimpleConfigDialog.h> #include <ArmarXCore/core/ManagedIceObject.h> @@ -24,7 +27,6 @@ #include <filesystem> - namespace armarx::armem::gui { MemoryViewer::MemoryViewer( @@ -79,8 +81,8 @@ namespace armarx::armem::gui // Connections //connect(this, &This::connected, this, &This::updateMemory); - connect(memoryControlWidget, &armem::gui::MemoryControlWidget::exportHere, this, &This::exportHere); - connect(memoryControlWidget, &armem::gui::MemoryControlWidget::store, this, &This::store); + connect(memoryControlWidget, &armem::gui::MemoryControlWidget::storeOnDisk, this, &This::storeOnDisk); + connect(memoryControlWidget, &armem::gui::MemoryControlWidget::storeInLTM, this, &This::storeInLTM); connect(this, &This::connected, this, &This::updateMemories); connect(updateWidget, &armem::gui::PeriodicUpdateWidget::update, this, &This::updateMemories); @@ -151,17 +153,18 @@ namespace armarx::armem::gui statusLabel->setText(QString::fromStdString(ss.str())); return nullptr; } - else if (not it->second.has_value()) + /*else if (not it->second.has_value()) { return nullptr; - } + }*/ else { - return &it->second.value(); + //return &it->second.value(); + return &it->second; } } - void MemoryViewer::store() + void MemoryViewer::storeInLTM() { TIMING_START(MemoryStore); @@ -175,32 +178,37 @@ namespace armarx::armem::gui TIMING_END_STREAM(MemoryStore, ARMARX_VERBOSE); } - void MemoryViewer::exportHere() + void MemoryViewer::storeOnDisk() { TIMING_START(MemoryExport); QString qs = memoryControlWidget->getEnteredPath(); std::string utf8_text = qs.toUtf8().constData(); - ARMARX_IMPORTANT << "Exporting all memories at '" << utf8_text << "'."; - - std::filesystem::path p(utf8_text); - if (std::filesystem::is_regular_file(p)) + if (not utf8_text.empty()) { - ARMARX_WARNING << "Could not export a memory at '" << utf8_text << "'. Skipping export."; - return; - } + ARMARX_IMPORTANT << "Exporting all memories at '" << utf8_text << "'."; - std::filesystem::create_directories(p); - for (auto& [name, reader] : memoryReaders) + std::filesystem::path p(utf8_text); + if (std::filesystem::is_regular_file(p)) + { + ARMARX_WARNING << "Could not export a memory at '" << utf8_text << "'. Skipping export."; + return; + } + + std::filesystem::create_directories(p); + for (auto& [name, reader] : memoryReaders) + { + armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput(); + armem::client::QueryResult result = reader.query(input); + + armem::d_ltm::Memory dMem(name); + dMem.reload(p / name); + dMem.append(result.memory); + } + } + else { - armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput(); - armem::client::QueryResult result = reader.query(input); - - armem::d_ltm::Memory dMem(name); - ARMARX_IMPORTANT << "RELOAD"; - dMem.reload(p / name); - ARMARX_IMPORTANT << "APPEND"; - dMem.append(result.memory); + ARMARX_WARNING << "The path is empty. Could not export the memory in nirvana."; } TIMING_END_STREAM(MemoryExport, ARMARX_VERBOSE); @@ -215,18 +223,77 @@ namespace armarx::armem::gui bool dataChanged = false; + QString qs = memoryControlWidget->getEnteredPath(); + std::string utf8_text = qs.toUtf8().constData(); + + std::filesystem::path p(utf8_text); + + // first check if the local file system should be queried + if (memoryGroup->queryWidget()->alsoQueryLocalDisk()) + { + if (std::filesystem::is_directory(p)) + { + for (const auto& d : std::filesystem::directory_iterator(p)) + { + if (d.is_directory()) + { + std::string k = d.path().filename(); + armem::d_ltm::Memory dMem(k); + dMem.reload(p / k); + + armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput(); + input.addQueryTargetToAll(armem::query::data::QueryTarget::Disk); + + armem::d_ltm::query_proc::MemoryQueryProcessor d_ltm_processor; + dMem = d_ltm_processor.process(input.toIce(), dMem, /* execute if: */ { query::data::QueryTarget::Disk }); + + wm::Memory converted = dMem.convert(); + memoryData[k] = std::move(converted); + dataChanged = true; + } + } + } + else + { + ARMARX_WARNING << "Could not import a memory from '" << utf8_text << "'. Skipping import."; + } + } + + armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput(); for (auto& [name, reader] : memoryReaders) { TIMING_START(MemoryQuery); { - armem::client::QueryInput input = memoryGroup->queryWidget()->queryInput(); armem::client::QueryResult result = reader.query(input); if (result) { - memoryData[name] = std::move(result.memory); + if (result.memory.hasData()) + { + if (const auto& it = memoryData.find(name); it != memoryData.end()) + { + result.memory.append(it->second); + + // requery (e.g. to get only the last n values instead of the last n from disk and the last n from wm) + armem::wm::query_proc::MemoryQueryProcessor wm_processor; + result.memory = wm_processor.process(input.toIce(), result.memory, /* execute if: */ { query::data::QueryTarget::WM }); + + if (!result.memory.hasData()) + { + ARMARX_ERROR << "A memory which had data before lost data. This indicates that there is something wrong."; + } + } + + dataChanged = true; + memoryData[name] = std::move(result.memory); + } + else + { + ARMARX_INFO << "The memory " << name << " has no data after querying."; + } } else { + ARMARX_WARNING << "A query for memory '" + name + "' produced an error: " << result.errorMessage; if (statusLabel) { statusLabel->setText(QString::fromStdString(result.errorMessage)); @@ -239,24 +306,19 @@ namespace armarx::armem::gui { debugObserver->setDebugDatafield(Logging::tag.tagName, "Memory Query [ms]", new Variant(MemoryQuery.toMilliSecondsDouble())); } - - if (memoryData[name]) - { - dataChanged = true; - } - else - { - if (statusLabel) - { - statusLabel->setText("No query result."); - } - } } if (dataChanged) { emit memoryDataChanged(); } + else + { + if (statusLabel) + { + statusLabel->setText("No query result."); + } + } } @@ -382,10 +444,11 @@ namespace armarx::armem::gui std::map<std::string, const armem::wm::Memory*> convMap; for (auto& [name, data] : memoryData) { - if (data.has_value()) + /*if (data.has_value()) { convMap[name] = &data.value(); - } + }*/ + convMap[name] = &data; } if (convMap.empty()) diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.h b/source/RobotAPI/libraries/armem_gui/MemoryViewer.h index 22455503637f55114516bf6e93c6772cd18c179e..71870bdd565b0b8a585808f5f0e9f0f43c93d315 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.h +++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.h @@ -71,8 +71,8 @@ namespace armarx::armem::gui void resolveMemoryID(const MemoryID& id); // LTMControlWidget - void store(); - void exportHere(); + void storeInLTM(); + void storeOnDisk(); signals: @@ -109,7 +109,7 @@ namespace armarx::armem::gui armem::client::MemoryNameSystem mns; std::map<std::string, armem::client::Reader> memoryReaders; - std::map<std::string, std::optional<armem::wm::Memory>> memoryData; + std::map<std::string, armem::wm::Memory> memoryData; QLayout* updateWidgetLayout = nullptr; armem::gui::PeriodicUpdateWidget* updateWidget = nullptr; diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.cpp b/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.cpp index ae9af3c213fbbea4d4a44852e8e02d0af15b8de9..dbb3d3fcabfa2ccf0034d1ba72027664bebe6ebc 100644 --- a/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.cpp +++ b/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.cpp @@ -41,14 +41,18 @@ namespace armarx::armem::gui : armem::DataMode::NoData; } + bool QueryWidget::alsoQueryLocalDisk() const + { + return _snapshotSelectorWidget->queryTargetContainsLocalDisk(); + } + armem::client::QueryInput QueryWidget::queryInput() { armem::client::query::Builder qb(dataMode()); - qb - .queryTarget(_snapshotSelectorWidget->queryTarget()) - .coreSegments().all() - .providerSegments().all() - .entities().all() + qb.queryTargets(_snapshotSelectorWidget->queryTargets()) + .coreSegments().all().queryTargets(_snapshotSelectorWidget->queryTargets()) + .providerSegments().all().queryTargets(_snapshotSelectorWidget->queryTargets()) + .entities().all().queryTargets(_snapshotSelectorWidget->queryTargets()) .snapshots(_snapshotSelectorWidget->selector()); return qb.buildQueryInput(); diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.h b/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.h index 37e5fca58b80d54592d4eb6443e8e624bd0a613d..d2c3fecd6198ad2ad5c3f37077eb07f4f365dea9 100644 --- a/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.h +++ b/source/RobotAPI/libraries/armem_gui/query_widgets/QueryWidget.h @@ -21,6 +21,7 @@ namespace armarx::armem::gui armem::DataMode dataMode() const; + bool alsoQueryLocalDisk() const; armem::client::QueryInput queryInput(); diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotForm.cpp b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotForm.cpp index 8d60c2252d4e9d6593a228cad75075cc41a21e5c..1d6c0cff39fd69da5e7f29844c64fabc1843f9a4 100644 --- a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotForm.cpp +++ b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotForm.cpp @@ -20,9 +20,9 @@ namespace armarx::armem::gui { - client::query::SnapshotSelector SnapshotForm::makeEntitySelector() + client::query::SnapshotSelector SnapshotForm::makeEntitySelector(const armem::query::data::QueryTargets& targets) { - client::query::SnapshotSelector s; + client::query::SnapshotSelector s(targets); fillEntitySelector(s); return s; } diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotForm.h b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotForm.h index 0ca9950b33a0585c97a8157bf17ad3c272fc8abc..f2f9ba1940d268d06f3383374d01893ea2d3dea4 100644 --- a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotForm.h +++ b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotForm.h @@ -19,7 +19,7 @@ namespace armarx::armem::gui Q_OBJECT public: - virtual client::query::SnapshotSelector makeEntitySelector(); + virtual client::query::SnapshotSelector makeEntitySelector(const armem::query::data::QueryTargets& targets); signals: @@ -30,10 +30,6 @@ namespace armarx::armem::gui virtual void fillEntitySelector(client::query::SnapshotSelector& selector) = 0; void setDateTimeDisplayFormat(QDateTimeEdit* dt); - - public: - client::query::SnapshotSelector selector; - }; diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.cpp b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.cpp index 87d94376e673492d07a7fe2f0206359259ea327a..e41bed15cecbc599c7c97b4266a04e0e9a70e47e 100644 --- a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.cpp +++ b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.cpp @@ -10,25 +10,39 @@ namespace armarx::armem::gui { - client::query::SnapshotSelector& SnapshotSelectorWidget::selector() + client::query::SnapshotSelector SnapshotSelectorWidget::selector() { - return _selector; + return _queryForms.at(_queryComboBox->currentText())->makeEntitySelector(queryTargets()); } - query::data::QueryTarget SnapshotSelectorWidget::queryTarget() const + query::data::QueryTargets SnapshotSelectorWidget::queryTargets() const { - return _queryTarget; + query::data::QueryTargets targets; + if (_WMQueryTargetCheckBox->isChecked()) + { + targets.push_back(query::data::QueryTarget::WM); + } + if (_LTMQueryTargetCheckBox->isChecked()) + { + targets.push_back(query::data::QueryTarget::LTM); + } + if (_DiskMemoryQueryTargetCheckBox->isChecked()) + { + targets.push_back(query::data::QueryTarget::Disk); + } + return targets; } + bool SnapshotSelectorWidget::queryTargetContainsLocalDisk() const + { + return _LocalDiskMemoryQueryTargetCheckBox->isChecked(); + } SnapshotSelectorWidget::SnapshotSelectorWidget() { _pageLayout = new QVBoxLayout(); setLayout(_pageLayout); - connect(this, &This::queryOutdated, this, &This::updateSelector); - connect(this, &This::queryTargetOutdated, this, &This::updateQueryTarget); - { QHBoxLayout* typeLayout = new QHBoxLayout(); @@ -40,16 +54,23 @@ namespace armarx::armem::gui typeLayout->addWidget(_queryComboBox); connect(_queryComboBox, &QComboBox::currentTextChanged, this, &This::showSelectedFormForQuery); - connect(_queryComboBox, &QComboBox::currentTextChanged, this, &This::queryOutdated); + connect(_queryComboBox, &QComboBox::currentTextChanged, this, &This::queryChanged); // query type select box - _queryTargetComboBox = new QComboBox(); - _queryTargetComboBox->addItems({"WM", "WM & LTM", "LTM (debug only)"}); - _queryTargetComboBox->setCurrentIndex(0); + auto queryTargetLayout = new QHBoxLayout(); + _WMQueryTargetCheckBox = new QCheckBox("WM"); + _LTMQueryTargetCheckBox = new QCheckBox("LTM (MongoDB)"); + _DiskMemoryQueryTargetCheckBox = new QCheckBox("LTM (Disk)"); + _LocalDiskMemoryQueryTargetCheckBox = new QCheckBox("Local Disk"); - typeLayout->addWidget(_queryTargetComboBox); + queryTargetLayout->addWidget(_WMQueryTargetCheckBox); + queryTargetLayout->addWidget(_LTMQueryTargetCheckBox); + queryTargetLayout->addWidget(_DiskMemoryQueryTargetCheckBox); + queryTargetLayout->addWidget(_LocalDiskMemoryQueryTargetCheckBox); - connect(_queryTargetComboBox, &QComboBox::currentTextChanged, this, &This::queryTargetOutdated); + _WMQueryTargetCheckBox->setChecked(true); + + typeLayout->addLayout(queryTargetLayout); _pageLayout->addLayout(typeLayout); } @@ -61,26 +82,7 @@ namespace armarx::armem::gui addForm("Time Range", new SnapshotFormTimeRange()); addForm("Index Range", new SnapshotFormIndexRange()); - // Add query targets - _queryTargets.insert({"WM", query::data::QueryTarget::WM}); - _queryTargets.insert({"WM & LTM", query::data::QueryTarget::WMAndLTM}); - _queryTargets.insert({"LTM (debug only)", query::data::QueryTarget::LTM}); - showSelectedFormForQuery(_queryComboBox->currentText()); - updateSelector(); - updateQueryTarget(); - } - - void SnapshotSelectorWidget::updateSelector() - { - this->_selector = _queryForms.at(_queryComboBox->currentText())->makeEntitySelector(); - emit queryChanged(); - } - - void SnapshotSelectorWidget::updateQueryTarget() - { - this->_queryTarget = _queryTargets.at(_queryTargetComboBox->currentText()); - emit queryTargetChanged(); } void SnapshotSelectorWidget::showSelectedFormForQuery(QString selected) @@ -95,7 +97,7 @@ namespace armarx::armem::gui { auto r = _queryForms.emplace(key, form); _pageLayout->addWidget(r.first->second); - connect(r.first->second, &SnapshotForm::queryChanged, this, &This::updateSelector); + //connect(r.first->second, &SnapshotForm::queryChanged, this, &This::updateSelector); } void SnapshotSelectorWidget::hideAllForms() diff --git a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.h b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.h index 92db5fbb13c74b011ca0f36a64fbf82a58536717..6f6422c3cdbc7fd0e1899bce47efbaaa32589062 100644 --- a/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.h +++ b/source/RobotAPI/libraries/armem_gui/query_widgets/SnapshotSelectorWidget.h @@ -35,31 +35,27 @@ namespace armarx::armem::gui armem::DataMode dataMode() const; - client::query::SnapshotSelector& selector(); - query::data::QueryTarget queryTarget() const; + client::query::SnapshotSelector selector(); + query::data::QueryTargets queryTargets() const; + bool queryTargetContainsLocalDisk() const; public slots: signals: - void queryChanged(); - void queryTargetChanged(); private slots: - void updateSelector(); - void updateQueryTarget(); + //void updateSelector(); void hideAllForms(); void showSelectedFormForQuery(QString selected); signals: - void queryOutdated(); - void queryTargetOutdated(); private: @@ -68,16 +64,14 @@ namespace armarx::armem::gui public: - - client::query::SnapshotSelector _selector; - query::data::QueryTarget _queryTarget; - QVBoxLayout* _pageLayout; QComboBox* _queryComboBox; - QComboBox* _queryTargetComboBox; + QCheckBox* _WMQueryTargetCheckBox; + QCheckBox* _LTMQueryTargetCheckBox; + QCheckBox* _DiskMemoryQueryTargetCheckBox; + QCheckBox* _LocalDiskMemoryQueryTargetCheckBox; /// The forms for the different query types. Hidden when not selected. std::map<QString, SnapshotForm*> _queryForms; - std::map<QString, query::data::QueryTarget> _queryTargets; }; diff --git a/source/RobotAPI/libraries/armem_motions/CMakeLists.txt b/source/RobotAPI/libraries/armem_motions/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a72d610f0891ba50588bf8744439172b0851b17f --- /dev/null +++ b/source/RobotAPI/libraries/armem_motions/CMakeLists.txt @@ -0,0 +1,27 @@ +set(LIB_NAME armem_motions) + +armarx_component_set_name("${LIB_NAME}") +armarx_set_target("Library: ${LIB_NAME}") + +armarx_add_library( + LIBS + ArmarXCoreInterfaces + ArmarXCore + ArmarXCoreObservers + + RobotAPI::Core + RobotAPI::armem + RobotAPI::PriorKnowledge::Motions + SOURCES + ./server/MotionDatabase/MDBMotions/MotionConverter.cpp + ./server/MotionDatabase/MDBMotions/Segment.cpp + HEADERS + ./server/MotionDatabase/MDBMotions/MotionConverter.h + ./server/MotionDatabase/MDBMotions/Segment.h + ARON_FILES + ./aron/MDBReference.xml +) + + +add_library(RobotAPI::ArMemMotions ALIAS armem_motions) +add_library(RobotAPI::armem_motions ALIAS armem_motions) diff --git a/source/RobotAPI/libraries/armem_motions/aron/MDBReference.xml b/source/RobotAPI/libraries/armem_motions/aron/MDBReference.xml new file mode 100644 index 0000000000000000000000000000000000000000..20f01a891b0f368ef3c350afb53dfe5f70116c22 --- /dev/null +++ b/source/RobotAPI/libraries/armem_motions/aron/MDBReference.xml @@ -0,0 +1,122 @@ +<!--Some fancy comment --> +<?xml version="1.0" encoding="UTF-8" ?> +<AronTypeDefinition> + + <CodeIncludes> + <Include include="<Eigen/Core>" /> + </CodeIncludes> + + <AronIncludes> + <Include include="<RobotAPI/libraries/armem/aron/MemoryID.xml>" autoinclude="true"/> + </AronIncludes> + + <GenerateTypes> + <Object name='armarx::armem::mdb::FileReference'> + + <ObjectChild key='createdDate'> + <time /> + </ObjectChild> + + <ObjectChild key='createdUser'> + <string /> + </ObjectChild> + + <ObjectChild key='fileName'> + <string /> + </ObjectChild> + + <ObjectChild key='attachedToId'> + <int /> + </ObjectChild> + + <ObjectChild key='description'> + <string /> + </ObjectChild> + + <ObjectChild key='visibility'> + <string /> + </ObjectChild> + + <ObjectChild key='originatedFrom'> + <string /> + </ObjectChild> + + </Object> + <Object name='armarx::armem::mdb::MDBReference'> + + <ObjectChild key='id'> + <int /> + </ObjectChild> + + <ObjectChild key='associatedInstitution'> + <int /> + </ObjectChild> + + <ObjectChild key='motionDescriptions'> + <List> + <int /> + </List> + </ObjectChild> + + <ObjectChild key='associatedProject'> + <int /> + </ObjectChild> + + <ObjectChild key='date'> + <string /> + </ObjectChild> + + <ObjectChild key='associatedProject'> + <int /> + </ObjectChild> + + <ObjectChild key='createdDate'> + <time /> + </ObjectChild> + + <ObjectChild key='createdUser'> + <string /> + </ObjectChild> + + <ObjectChild key='modifiedDate'> + <time /> + </ObjectChild> + + <ObjectChild key='modifiedUser'> + <string /> + </ObjectChild> + + <ObjectChild key='writeGroups'> + <List> + <string /> + </List> + </ObjectChild> + + <ObjectChild key='readProtectedGroups'> + <List> + <string /> + </List> + </ObjectChild> + + <ObjectChild key='fileTypeCounts'> + <Dict> + <string /> + </Dict> + </ObjectChild> + + <ObjectChild key='attachedFiles'> + <Dict> + <List> + <armarx::armem::mdb::FileReference /> + </List> + </Dict> + </ObjectChild> + + <ObjectChild key='comment'> + <string /> + </ObjectChild> + + </Object> + </GenerateTypes> + +</AronTypeDefinition> diff --git a/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/MotionConverter.cpp b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/MotionConverter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..31f28ea09b62d687fbcb3871941bc3ab9bd329a1 --- /dev/null +++ b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/MotionConverter.cpp @@ -0,0 +1,51 @@ +// Header +#include "MotionConverter.h" + +namespace armarx::armem::server::motions::mdb::conversion +{ + std::optional<armem::mdb::MDBReference> createFromFile(const std::filesystem::path& pathToInfoJson) + { + if (std::filesystem::exists(pathToInfoJson) && std::filesystem::is_regular_file(pathToInfoJson)) + { + std::ifstream ifs(pathToInfoJson); + std::string file_content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); + + armarx::armem::mdb::MDBReference motionReference; + auto json = nlohmann::json::parse(file_content); + + motionReference.id = json["id"]; + motionReference.associatedInstitution = json["associatedInstitution"]; + motionReference.associatedProject = json["associatedProject"]; + motionReference.comment = json["comment"]; + motionReference.createdDate = IceUtil::Time::seconds(json["createdDate"]); + motionReference.createdUser = json["createdUser"]; + motionReference.modifiedDate = IceUtil::Time::seconds(json["modifiedDate"]); + motionReference.modifiedUser = json["modifiedUser"]; + motionReference.date = json["date"]; + for (auto it = json["attachedFiles"].begin(); it != json["attachedFiles"].end(); ++it) + { + const auto& key = it.key(); + const auto& value = it.value(); + + for (const auto& attachedFile : value) + { + armarx::armem::mdb::FileReference fileRef; + fileRef.attachedToId = attachedFile["attachedToId"]; + fileRef.createdDate = IceUtil::Time::microSeconds(attachedFile["createdDate"]); + fileRef.createdUser = attachedFile["createdUser"]; + fileRef.description = attachedFile["description"]; + fileRef.fileName = attachedFile["fileName"]; + + motionReference.attachedFiles[key].emplace_back(fileRef); + } + } + + + return motionReference; + } + else + { + return std::nullopt; + } + } +} diff --git a/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/MotionConverter.h b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/MotionConverter.h new file mode 100644 index 0000000000000000000000000000000000000000..5dae00e335b8ee31e41052848413b70d3518e6bd --- /dev/null +++ b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/MotionConverter.h @@ -0,0 +1,13 @@ +// STD / STL +#include <filesystem> +#include <iostream> +#include <fstream> +#include <optional> + +// ArmarX +#include <RobotAPI/libraries/armem_motions/aron/MDBReference.aron.generated.h> + +namespace armarx::armem::server::motions::mdb::conversion +{ + std::optional<armem::mdb::MDBReference> createFromFile(const std::filesystem::path& pathToInfoJson); +} diff --git a/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9aec94015f490d7c992919b96fdbce33b4f1718 --- /dev/null +++ b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.cpp @@ -0,0 +1,88 @@ +// STD / STL +#include <iostream> +#include <fstream> +#include <sstream> + +// BaseClass +#include "Segment.h" + +// ArmarX +#include "MotionConverter.h" +#include <RobotAPI/libraries/PriorKnowledge/motions/MotionFinder.h> + +namespace armarx::armem::server::motions::mdb +{ + Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter, std::mutex& memoryMutex) : + Base(memoryToIceAdapter, memoryMutex) + { + } + + void Segment::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix) + { + Base::defineProperties(defs, prefix); + + defs->optional(p.motionsPackage, prefix + "MotionsPackage", "Name of the prior knowledge package to load from."); + defs->optional(p.loadFromMotionsPackage, prefix + "LoadFromMotionsPackage", "If true, load the motions from the motions package on startup."); + } + + void Segment::onInit() + { + Base::onInit(); + + if (p.loadFromMotionsPackage) + { + loadByMotionFinder(p.motionsPackage); + } + } + + void Segment::onConnect() + { + + } + + int Segment::loadByMotionFinder(const std::string& packageName) + { + priorknowledge::motions::MotionFinder motionFinder(packageName, "motions/"); + int loadedMotions = 0; + + std::cout << "Load Motions from package" << std::endl; + { + // Load MDB Motions + auto allMotions = motionFinder.findAll("mdb"); + for (const auto& motionFinderInfo : allMotions) + { + auto pathToInfoJson = motionFinderInfo.getFullPath() / motionFinderInfo.getID() / (motionFinderInfo.getID() + ".json"); + if (auto op = conversion::createFromFile(pathToInfoJson); op.has_value()) + { + std::stringstream ss; + ss << "Found valid instance at: " << pathToInfoJson << ". The motionID is: "; + for (const auto& [key, attachedFiles] : op->attachedFiles) + { + for (const auto& attachedFile : attachedFiles) + { + ss << "\n" << attachedFile.fileName << " (" << key << ")"; + } + } + ARMARX_INFO << ss.str(); + auto& entity = this->segment->addEntity(std::to_string(op->id)); + auto& snapshot = entity.addSnapshot(op->createdDate); + + armem::wm::EntityInstance& instance = snapshot.addInstance(); + instance.metadata().timeCreated = op->createdDate; + instance.metadata().timeSent = IceUtil::Time::now(); + instance.metadata().timeArrived = IceUtil::Time::now(); + instance.metadata().confidence = 1.0; + instance.setData(op->toAron()); + } + else + { + ARMARX_WARNING << "Found an invalid path to a motion file: " << pathToInfoJson; + } + }IceUtil::Time::now(); + + loadedMotions += allMotions.size(); + } + + return loadedMotions; + } +} diff --git a/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.h b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.h new file mode 100644 index 0000000000000000000000000000000000000000..10dd57dee5f3c7c177a980ac29ed6dc45c845905 --- /dev/null +++ b/source/RobotAPI/libraries/armem_motions/server/MotionDatabase/MDBMotions/Segment.h @@ -0,0 +1,38 @@ +#pragma once + +// STD/STL +#include <mutex> +#include <string> + +// BaseClass +#include <RobotAPI/libraries/armem/server/Segment.h> + +// ArmarX +#include <RobotAPI/libraries/armem_motions/aron/MDBReference.aron.generated.h> + + +namespace armarx::armem::server::motions::mdb +{ + class Segment : public armem::server::wm::ProviderSegmentBase<armarx::armem::mdb::MDBReference> + { + using Base = armem::server::wm::ProviderSegmentBase<armarx::armem::mdb::MDBReference>; + + public: + Segment(armem::server::MemoryToIceAdapter& iceMemory, std::mutex& memoryMutex); + + virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "") override; + virtual void onInit() override; + virtual void onConnect() override; + + private: + int loadByMotionFinder(const std::string&); + + private: + struct Properties + { + std::string motionsPackage = "PriorKnowledgeData"; + bool loadFromMotionsPackage = true; + }; + Properties p; + }; +} diff --git a/source/RobotAPI/libraries/aron/common/CMakeLists.txt b/source/RobotAPI/libraries/aron/common/CMakeLists.txt index ec6c74d9e669f9effb5825afda1cc1645aadf547..491e3dec396e706dcacea61955ec59eb19a97245 100644 --- a/source/RobotAPI/libraries/aron/common/CMakeLists.txt +++ b/source/RobotAPI/libraries/aron/common/CMakeLists.txt @@ -25,19 +25,20 @@ armarx_add_library( aron_conversions/simox.cpp aron_conversions/stl.cpp aron_conversions/eigen.cpp -) - -armarx_enable_aron_file_generation_for_target( - TARGET_NAME - "${LIB_NAME}" ARON_FILES + #aron/SimplePosition.xml + #aron/SimplePose.xml + #aron/SimpleTrajectory.xml aron/AxisAlignedBoundingBox.xml aron/OrientedBox.xml aron/PackagePath.xml - ) +add_library(aron::common ALIAS aroncommon) +add_library(Aron::Common ALIAS aroncommon) +add_library(${PROJECT_NAME}::Aron::Common ALIAS aroncommon) +add_library(${PROJECT_NAME}::aron::common ALIAS aroncommon) # add unit tests add_subdirectory(test) diff --git a/source/RobotAPI/libraries/aron/common/aron/SimplePose.xml b/source/RobotAPI/libraries/aron/common/aron/SimplePose.xml new file mode 100644 index 0000000000000000000000000000000000000000..add970d136c4a1b3dee7349a01fdc0496ebd6396 --- /dev/null +++ b/source/RobotAPI/libraries/aron/common/aron/SimplePose.xml @@ -0,0 +1,27 @@ +<!--Some fancy comment +<?xml version="1.0" encoding="UTF-8" ?> +<AronTypeDefinition> + + <CodeIncludes> + <Include include="<Eigen/Core>" /> + </CodeIncludes> + + <AronIncludes> + <Include include="<RobotAPI/libraries/armem/aron/MemoryID.xml>" autoinclude="true"/> + </AronIncludes> + + <GenerateTypes> + <Object name='armarx::armem::mmm::KeyPoint'> + + </Object> + <Object name='armarx::armem::mmm::SingleKeyPointTrajectory'> + + <ObjectChild key='name'> + < /> + </ObjectChild> + + </Object> + </GenerateTypes> + +</AronTypeDefinition> +--> diff --git a/source/RobotAPI/libraries/aron/common/aron/SimplePosition.xml b/source/RobotAPI/libraries/aron/common/aron/SimplePosition.xml new file mode 100644 index 0000000000000000000000000000000000000000..42faeef90f3c58888c9cb34ba5d7778d2a31a722 --- /dev/null +++ b/source/RobotAPI/libraries/aron/common/aron/SimplePosition.xml @@ -0,0 +1,26 @@ +<!--Some fancy comment +<?xml version="1.0" encoding="UTF-8" ?> +<AronTypeDefinition> + + <CodeIncludes> + <Include include="<Eigen/Core>" /> + </CodeIncludes> + + <AronIncludes> + <Include include="<RobotAPI/libraries/armem/aron/MemoryID.xml>" autoinclude="true"/> + </AronIncludes> + + <GenerateTypes> + <Object name='armarx::armem::mmm::KeyPoint'> + + </Object> + <Object name='armarx::armem::mmm::SingleKeyPointTrajectory'> + + <ObjectChild key='name'> + < /> + </ObjectChild> + + </Object> + </GenerateTypes> + +</AronTypeDefinition>--> diff --git a/source/RobotAPI/libraries/aron/common/aron/SimpleTrajectory.xml b/source/RobotAPI/libraries/aron/common/aron/SimpleTrajectory.xml new file mode 100644 index 0000000000000000000000000000000000000000..42faeef90f3c58888c9cb34ba5d7778d2a31a722 --- /dev/null +++ b/source/RobotAPI/libraries/aron/common/aron/SimpleTrajectory.xml @@ -0,0 +1,26 @@ +<!--Some fancy comment +<?xml version="1.0" encoding="UTF-8" ?> +<AronTypeDefinition> + + <CodeIncludes> + <Include include="<Eigen/Core>" /> + </CodeIncludes> + + <AronIncludes> + <Include include="<RobotAPI/libraries/armem/aron/MemoryID.xml>" autoinclude="true"/> + </AronIncludes> + + <GenerateTypes> + <Object name='armarx::armem::mmm::KeyPoint'> + + </Object> + <Object name='armarx::armem::mmm::SingleKeyPointTrajectory'> + + <ObjectChild key='name'> + < /> + </ObjectChild> + + </Object> + </GenerateTypes> + +</AronTypeDefinition>--> diff --git a/source/RobotAPI/libraries/aron/converter/CMakeLists.txt b/source/RobotAPI/libraries/aron/converter/CMakeLists.txt index a99bfccfd49d736dc8d4c1ff55e41decb06029ee..5f8db702e460cbb2e729862458314920823be780 100644 --- a/source/RobotAPI/libraries/aron/converter/CMakeLists.txt +++ b/source/RobotAPI/libraries/aron/converter/CMakeLists.txt @@ -16,4 +16,7 @@ target_link_libraries(AronConverter RobotAPI::aron::converter::opencv ) -add_library(RobotAPI::aron::converter ALIAS AronConverter) +add_library(aron::converter ALIAS AronConverter) +add_library(Aron::Converter ALIAS AronConverter) +add_library(${PROJECT_NAME}::Aron::Converter ALIAS AronConverter) +add_library(${PROJECT_NAME}::aron::converter ALIAS AronConverter) diff --git a/source/RobotAPI/libraries/aron/core/CMakeLists.txt b/source/RobotAPI/libraries/aron/core/CMakeLists.txt index af2caf05737aec188ccae47c5554f7776a27defd..62548c29719f3942afee49a45e9a3f24a4232634 100644 --- a/source/RobotAPI/libraries/aron/core/CMakeLists.txt +++ b/source/RobotAPI/libraries/aron/core/CMakeLists.txt @@ -281,6 +281,8 @@ armarx_add_library( "${LIBS}" ) +add_library(Aron ALIAS "${LIB_NAME}") +add_library(RobotAPI::Aron ALIAS "${LIB_NAME}") add_library(RobotAPI::aron ALIAS "${LIB_NAME}") # add unit tests diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/GenerateIntEnumInfo.h b/source/RobotAPI/libraries/aron/core/codegenerator/GenerateIntEnumInfo.h index 832c3e47d08766a565ddb4dc297239da472d1d9a..e382b24225fc051ce7f8b402d73a640ec783b5ab 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/GenerateIntEnumInfo.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/GenerateIntEnumInfo.h @@ -40,6 +40,9 @@ namespace armarx::aron::codegeneratorhelper public: std::string typeName; std::string definedIn; + std::string doc_brief; + std::string doc_author; + std::map<std::string, std::string> doc_values; typenavigator::IntEnumNavigatorPtr correspondingType; }; } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/GenerateTypeInfo.h b/source/RobotAPI/libraries/aron/core/codegenerator/GenerateTypeInfo.h index a029bca09d634f3565e89e7ef7d39eaee3af1201..c168b059222c9cbe3811b4c7bf4454647138b89f 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/GenerateTypeInfo.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/GenerateTypeInfo.h @@ -41,7 +41,11 @@ namespace armarx::aron::codegeneratorhelper public: std::string typeName; std::string definedIn; + std::string doc_brief; + std::string doc_author; + std::map<std::string, std::string> doc_members; typenavigator::ObjectNavigatorPtr correspondingType; + std::map<std::string, GenerateObjectInfoPtr> nestedObjects; std::map<std::string, GenerateIntEnumInfoPtr> nestedIntEnums; }; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/WriterInfo.h b/source/RobotAPI/libraries/aron/core/codegenerator/WriterInfo.h index 375b3c0d51ff24ed0d671878be9feead7a59998c..a9d99d424959ca94f454005a9663fc51e78ecfe0 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/WriterInfo.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/WriterInfo.h @@ -39,5 +39,6 @@ namespace armarx::aron::codegeneratorhelper std::string returnType; std::string writerClassType; std::string include; + std::string enforceConversion = ""; }; } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/CodeWriter.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/CodeWriter.h index eec1b3db30bf39bf726f24b7c150e8102d409e60..d879b7178132274b2c1c9d50e55529b5d4beb7bb 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/CodeWriter.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/CodeWriter.h @@ -59,9 +59,8 @@ namespace armarx::aron::codegenerator } protected: - virtual void addFromAronMethod() = 0; - virtual void addToAronMethod() = 0; - virtual void addToAronTypeMethod() = 0; + virtual void addSpecificReaderMethods() = 0; + virtual void addSpecificWriterMethods() = 0; protected: std::vector<MetaClassPtr> typeClasses; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h index 7249a77170fd0f5c5e930d3d41ae465502ad3e96..790bb1e62538da3cdd0c25908118514f9be3cddd 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/AronCppClass.h @@ -55,9 +55,9 @@ namespace armarx::aron::cppserializer virtual void resetSoft() = 0; /// Set members according to loaded data in ReaderInterface. If skip_first_readStartDict is true, we skip the first call of r.readStartDict() (It was already called outside. This is important for nested classes) - virtual void read(armarx::aron::dataIO::ReaderInterface& r, bool skip_first_readStartDict) = 0; + virtual void read(armarx::aron::dataIO::ReaderInterface& r, bool __aronIsMember) = 0; /// Set the data in WriterInterface to the values of this class. If a maybe type is null or false, this method calls w.writeNull(). - virtual void write(armarx::aron::dataIO::WriterInterface& w) const = 0; + virtual void write(armarx::aron::dataIO::WriterInterface& w, bool __aronExtends) const = 0; }; } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/Writer.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/Writer.cpp index 86dc2874398a8bde89ae9224e4cdb8a6f47a83c7..4a41ea28147c96625a8129e74d9db9be7e9e8b4f 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/Writer.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/Writer.cpp @@ -35,12 +35,11 @@ namespace armarx::aron::cppserializer Writer::Writer(const std::string& producerName, const std::vector<std::string>& additionalIncludesFromXMLFile) : CodeWriter(producerName, additionalIncludesFromXMLFile) { - addToAronMethod(); - addFromAronMethod(); - addToAronTypeMethod(); + addSpecificWriterMethods(); + addSpecificReaderMethods(); } - void Writer::addToAronMethod() + void Writer::addSpecificWriterMethods() { // The toAron Serializer is visible by default { @@ -49,11 +48,33 @@ namespace armarx::aron::cppserializer toAron->returnType = "armarx::aron::datanavigator::DictNavigatorPtr"; toAron->writerClassType = "armarx::aron::dataIO::writer::NavigatorWriter"; toAron->include = "<RobotAPI/libraries/aron/core/io/dataIO/writer/navigator/NavigatorWriter.h>"; + toAron->enforceConversion = "armarx::aron::datanavigator::DictNavigator::DynamicCast"; dataWriters.push_back(toAron); } + + { + // The toAron Serializer is visible by default + codegeneratorhelper::WriterInfoPtr toAronType = codegeneratorhelper::WriterInfoPtr(new codegeneratorhelper::WriterInfo()); + toAronType->methodName = "toAronType"; + toAronType->returnType = "armarx::aron::typenavigator::ObjectNavigatorPtr"; + toAronType->writerClassType = "armarx::aron::typeIO::writer::NavigatorWriter"; + toAronType->include = "<RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h>"; + toAronType->enforceConversion = "armarx::aron::typenavigator::ObjectNavigator::DynamicCast"; + initialTypeWriters.push_back(toAronType); + } + + // toJSON Method + { + codegeneratorhelper::WriterInfoPtr toJSON = codegeneratorhelper::WriterInfoPtr(new codegeneratorhelper::WriterInfo()); + toJSON->methodName = "toJSON"; + toJSON->returnType = "nlohmann::json"; + toJSON->writerClassType = "armarx::aron::dataIO::writer::NlohmannJSONWriter"; + toJSON->include = "<RobotAPI/libraries/aron/core/io/dataIO/writer/nlohmannJSON/NlohmannJSONWriter.h>"; + dataWriters.push_back(toJSON); + } } - void Writer::addFromAronMethod() + void Writer::addSpecificReaderMethods() { // The toAron Serializer is visible by default { @@ -71,19 +92,19 @@ namespace armarx::aron::cppserializer fromAron->readerClassType = "armarx::aron::dataIO::reader::NavigatorReader"; dataReaders.push_back(fromAron); } - } - void Writer::addToAronTypeMethod() - { - // The toAron Serializer is visible by default - codegeneratorhelper::WriterInfoPtr toAronType = codegeneratorhelper::WriterInfoPtr(new codegeneratorhelper::WriterInfo()); - toAronType->methodName = "toAronType"; - toAronType->returnType = "armarx::aron::typenavigator::ObjectNavigatorPtr"; - toAronType->writerClassType = "armarx::aron::typeIO::writer::NavigatorWriter"; - toAronType->include = "<RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h>"; - initialTypeWriters.push_back(toAronType); + // fromJSON Method + { + codegeneratorhelper::ReaderInfoPtr fromJSON = codegeneratorhelper::ReaderInfoPtr(new codegeneratorhelper::ReaderInfo()); + fromJSON->methodName = "fromJSON"; + fromJSON->argumentType = "nlohmann::json"; + fromJSON->readerClassType = "armarx::aron::dataIO::reader::NlohmannJSONReader"; + fromJSON->include = "<RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.h>"; + dataReaders.push_back(fromJSON); + } } + void Writer::generateTypeObjects(const std::vector<codegeneratorhelper::GenerateObjectInfoPtr>& generateObjects) { for (const auto& publicGenerateObjectType : generateObjects) @@ -101,12 +122,12 @@ namespace armarx::aron::cppserializer auto serializer = std::make_shared<serializer::ObjectClassSerializer>(nav); CppClassPtr c = setupBasicCppClass(serializer->getFullCppTypename()); - setupMemberFields(c, serializer); + setupMemberFields(c, publicGenerateObjectType->doc_members, serializer); if (nav->getExtends() != nullptr) { auto extendsSerializer = std::make_shared<serializer::ObjectClassSerializer>(nav->getExtends()); - c->addInherit(extendsSerializer->getFullCppTypename()); + c->addInherit("public " + extendsSerializer->getFullCppTypename()); } else { @@ -115,9 +136,15 @@ namespace armarx::aron::cppserializer } // Add includes and guard - c->addClassDoc("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" - "!!!!!!AUTOGENERATED CLASS. Please do NOT edit. Instead, edit the corresponding .xml file!!!!!!\n" - "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + std::string classDoc = "******************************************\n" + "* AUTOGENERATED CLASS. Please do NOT edit.\n" + "******************************************\n"; + if (!publicGenerateObjectType->doc_author.empty() or !publicGenerateObjectType->doc_brief.empty()) + { + classDoc += (publicGenerateObjectType->doc_brief.empty() ? "" : " * @brief " + publicGenerateObjectType->doc_brief + "\n"); + classDoc += (publicGenerateObjectType->doc_author.empty() ? "" : " * @author " + publicGenerateObjectType->doc_author + "\n"); + } + c->addClassDoc(classDoc); c->setPragmaOnceIncludeGuard(true); c->addInclude("<memory>"); c->addInclude("<string>"); @@ -170,7 +197,7 @@ namespace armarx::aron::cppserializer { c->addInclude(info->include); } - CppMethodPtr convert = serializer->toSpecializedDataWriterMethod(info->returnType, info->methodName, info->writerClassType, "armarx::aron::datanavigator::DictNavigator::DynamicCast"); + CppMethodPtr convert = serializer->toSpecializedDataWriterMethod(info->returnType, info->methodName, info->writerClassType, info->enforceConversion); c->addMethod(convert); } @@ -196,7 +223,7 @@ namespace armarx::aron::cppserializer { c->addInclude(info->include); } - CppMethodPtr convert = serializer->toSpecializedTypeWriterMethod(info->returnType, info->methodName, info->writerClassType, "armarx::aron::typenavigator::ObjectNavigator::DynamicCast"); + CppMethodPtr convert = serializer->toSpecializedTypeWriterMethod(info->returnType, info->methodName, info->writerClassType, info->enforceConversion); c->addMethod(convert); } @@ -219,12 +246,20 @@ namespace armarx::aron::cppserializer auto serializer = std::make_shared<serializer::IntEnumClassSerializer>(nav); CppClassPtr c = setupBasicCppClass(serializer->getFullCppTypename()); - setupMemberFields(c, serializer); + setupMemberFields(c, publicGenerateIntEnumType->doc_values, serializer); // Add includes and guard - c->addClassDoc("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" - "!!!!!!AUTOGENERATED CLASS. Please do NOT edit. Instead, edit the corresponding .xml file!!!!!!\n" - "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + std::string classDoc = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" + "!!!!!!AUTOGENERATED CLASS. Please do NOT edit. Instead, edit the corresponding .xml file!!!!!!\n" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; + if (!publicGenerateIntEnumType->doc_author.empty() or !publicGenerateIntEnumType->doc_brief.empty()) + { + classDoc += "\n/**\n"; + classDoc += (publicGenerateIntEnumType->doc_brief.empty() ? "" : " * @brief " + publicGenerateIntEnumType->doc_brief + "\n"); + classDoc += (publicGenerateIntEnumType->doc_author.empty() ? "" : " * @author " + publicGenerateIntEnumType->doc_author + "\n"); + classDoc += " */"; + } + c->addClassDoc(classDoc); c->setPragmaOnceIncludeGuard(true); c->addInclude("<memory>"); c->addInclude("<string>"); @@ -301,17 +336,27 @@ namespace armarx::aron::cppserializer auto serializer = std::make_shared<serializer::ObjectClassSerializer>(nav); CppClassPtr c = setupBasicCppClass(serializer->getFullCppTypename()); - setupMemberFields(c, serializer); + setupMemberFields(c, localGenerateObjectType->doc_members, serializer); if (nav->getExtends() != nullptr) { auto extendsSerializer = std::make_shared<serializer::ObjectClassSerializer>(nav->getExtends()); - c->addInherit(extendsSerializer->getFullCppTypename()); + c->addInherit("public " + extendsSerializer->getFullCppTypename()); } else { - c->addInherit("virtual public armarx::aron::cppserializer::AronCppClass"); + c->addInherit("public armarx::aron::cppserializer::AronCppClass"); + } + + std::string classDoc = ""; + if (!localGenerateObjectType->doc_author.empty() or !localGenerateObjectType->doc_brief.empty()) + { + classDoc += "/**\n"; + classDoc += (localGenerateObjectType->doc_brief.empty() ? "" : " * @brief " + localGenerateObjectType->doc_brief + "\n"); + classDoc += (localGenerateObjectType->doc_author.empty() ? "" : " * @author " + localGenerateObjectType->doc_author + "\n"); + classDoc += " */"; } + c->addClassDoc(classDoc); CppMethodPtr equals = serializer->toEqualsMethod(); c->addMethod(equals); @@ -351,20 +396,28 @@ namespace armarx::aron::cppserializer return c; } - void Writer::setupMemberFields(CppClassPtr& c, const serializer::ObjectClassSerializerPtr& o) const + void Writer::setupMemberFields(CppClassPtr& c, const std::map<std::string, std::string>& doc_members, const serializer::ObjectClassSerializerPtr& o) const { auto publicFields = o->getPublicVariableDeclarations(""); for (const auto& f : publicFields) { + if (auto it = doc_members.find(f->getName()); it != doc_members.end()) + { + f->setDoc("@brief " + it->second); + } c->addPublicField(f); } } - void Writer::setupMemberFields(CppClassPtr& c, const serializer::IntEnumClassSerializerPtr& o) const + void Writer::setupMemberFields(CppClassPtr& c, const std::map<std::string, std::string>& doc_members, const serializer::IntEnumClassSerializerPtr& o) const { auto publicFields = o->getPublicVariableDeclarations(""); for (const auto& f : publicFields) { + if (auto it = doc_members.find(f->getName()); it != doc_members.end()) + { + f->setDoc("@brief " + it->second); + } c->addPublicField(f); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/Writer.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/Writer.h index d9b27c9fe82987a78724f7d837d9d3343a4af943..27812b01d4d8374ff108c294404dad4385f6b236 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/Writer.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/Writer.h @@ -56,16 +56,15 @@ namespace armarx::aron::cppserializer virtual void generateTypeIntEnums(const std::vector<codegeneratorhelper::GenerateIntEnumInfoPtr>&) override; protected: - virtual void addToAronMethod() override; - virtual void addFromAronMethod() override; - virtual void addToAronTypeMethod() override; + virtual void addSpecificWriterMethods() override; + virtual void addSpecificReaderMethods() override; private: void generateInnerTypeObjects(CppClassPtr& classToAdd, const std::map<std::string, codegeneratorhelper::GenerateObjectInfoPtr>& localGenerateTypes); CppClassPtr setupBasicCppClass(const std::string&) const; - void setupMemberFields(CppClassPtr&, const serializer::ObjectClassSerializerPtr&) const; - void setupMemberFields(CppClassPtr&, const serializer::IntEnumClassSerializerPtr&) const; + void setupMemberFields(CppClassPtr&, const std::map<std::string, std::string>& doc_members, const serializer::ObjectClassSerializerPtr&) const; + void setupMemberFields(CppClassPtr&, const std::map<std::string, std::string>& doc_members, const serializer::IntEnumClassSerializerPtr&) const; private: }; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.cpp index 19220470403b00537971203580f336acb6105aa2..5169a4fcc46d3142ce61df9d717cc03942f62781 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.cpp @@ -130,7 +130,7 @@ namespace armarx::aron::cppserializer return b; } - CppBlockPtr Serializer::ResolveMaybeReadBlock(const std::string& accessor, const std::string& readElement, const CppBlockPtr& block_if_data, const typenavigator::NavigatorPtr& typenavigator) + CppBlockPtr Serializer::ResolveMaybeReadBlock(const std::string& accessor, const std::string& readElement, const CppBlockPtr& block_if_data, const typenavigator::NavigatorPtr& typenavigator, bool enforce_return_type) { std::string escaped_accessor = EscapeAccessor(accessor); std::string read_start_result_accessor = escaped_accessor + READ_START_RETURN_TYPE_ACCESSOR; @@ -148,7 +148,14 @@ namespace armarx::aron::cppserializer if (!readElement.empty()) { - resolved_block->addLine("auto " + read_start_result_accessor + " = " + readElement + "; // of " + accessor); + if (enforce_return_type or typenavigator->getMaybe() != type::Maybe::eNone) + { + resolved_block->addLine("auto " + read_start_result_accessor + " = " + readElement + "; // of " + accessor); + } + else + { + resolved_block->addLine(readElement + "; // of " + accessor); + } } if (typenavigator->getMaybe() != type::Maybe::eNone) @@ -443,7 +450,7 @@ namespace armarx::aron::cppserializer doc << "@brief writeType() - This method returns a new type from the class structure using a type writer implementation. This function is static. \n"; doc << "@return - the result of the writer implementation"; - CppMethodPtr m = CppMethodPtr(new CppMethod("static void writeType(armarx::aron::typeIO::WriterInterface& w, armarx::aron::type::Maybe __aronMaybeType = armarx::aron::type::Maybe::eNone)", doc.str())); + CppMethodPtr m = CppMethodPtr(new CppMethod("static void writeType(armarx::aron::typeIO::WriterInterface& w, armarx::aron::type::Maybe __aronMaybeType = armarx::aron::type::Maybe::eNone, bool __aronExtends = false)", doc.str())); CppBlockPtr b = this->getWriteTypeBlock(""); m->setBlock(b); return m; @@ -456,7 +463,7 @@ namespace armarx::aron::cppserializer doc << "@param w - The writer implementation\n"; doc << "@return - the result of the writer implementation"; - CppMethodPtr m = CppMethodPtr(new CppMethod("virtual void write(armarx::aron::dataIO::WriterInterface& w) const override", doc.str())); + CppMethodPtr m = CppMethodPtr(new CppMethod("virtual void write(armarx::aron::dataIO::WriterInterface& w, bool __aronExtends = false) const override", doc.str())); CppBlockPtr b = this->getWriteBlock(""); m->setBlock(b); return m; @@ -469,7 +476,7 @@ namespace armarx::aron::cppserializer doc << "@param r - The reader implementation\n"; doc << "@return - nothing"; - CppMethodPtr m = CppMethodPtr(new CppMethod("virtual void read(armarx::aron::dataIO::ReaderInterface& r, bool skip_first_readStartDict = false) override", doc.str())); + CppMethodPtr m = CppMethodPtr(new CppMethod("virtual void read(armarx::aron::dataIO::ReaderInterface& r, bool __aronIsMember = false) override", doc.str())); CppBlockPtr b = std::make_shared<CppBlock>(); b->addLine("this->resetSoft();"); b->appendBlock(this->getReadBlock("")); diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h index ce4f11e9bc22d06d9d075f69d123127d50b9c70a..e7a544b8fb8342c0b83b0c27e4ecaf35e82ba933 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/Serializer.h @@ -115,7 +115,7 @@ namespace armarx::aron::cppserializer static std::string ResolveMaybeAccessor(const std::string&, const typenavigator::NavigatorPtr&); static CppBlockPtr ResolveMaybeWriteBlock(const std::string&, const CppBlockPtr&, const typenavigator::NavigatorPtr&); - static CppBlockPtr ResolveMaybeReadBlock(const std::string&, const std::string&, const CppBlockPtr&, const typenavigator::NavigatorPtr&); + static CppBlockPtr ResolveMaybeReadBlock(const std::string&, const std::string&, const CppBlockPtr&, const typenavigator::NavigatorPtr&, bool enforce_return_type = false); static CppBlockPtr ResolveMaybeEqualsBlock(const std::string&, const std::string&, const CppBlockPtr&, const typenavigator::NavigatorPtr&); static CppBlockPtr ResolveMaybeResetSoftBlock(const std::string&, const CppBlockPtr&, const typenavigator::NavigatorPtr&); static CppBlockPtr ResolveMaybeResetHardBlock(const std::string&, const CppBlockPtr&, const typenavigator::NavigatorPtr&); diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.cpp index 10b3470db62c07bad810b95099bfab57568674b2..f494c591c7828dbd4435a02336a03d52361620ad 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Dict.cpp @@ -113,7 +113,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + " == " + otherInstanceAccessor + "))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/List.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/List.cpp index b0fb56473b5f2bb435365c45d9a5040f104bba24..8483320c75efeca4c8cf573358d04d0539fb36d4 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/List.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/List.cpp @@ -103,7 +103,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + " == " + otherInstanceAccessor + "))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.cpp index 1ffbe7db264f0e27a4b74da7c9e5533193003af1..49e06676e286dc773da88d6c12ab50062e2f1eb5 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Object.cpp @@ -77,7 +77,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + " == " + otherInstanceAccessor + "))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Pair.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Pair.cpp index 6f78c29962573fb4c617392fa2b48398637e5bef..c465862acc74bac36c8f9f8e1c1cbf3b341890e3 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Pair.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Pair.cpp @@ -117,7 +117,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + " == " + otherInstanceAccessor + "))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp index dab5b33a01a7bb3d12817645b60688ab930e8b2b..a6b5e2080e97d0514cbb4bbda9131adb68a3a860 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/container/Tuple.cpp @@ -115,7 +115,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + " == " + otherInstanceAccessor + "))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/detail/NDArraySerializerBase.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/detail/NDArraySerializerBase.h index 67b6c0435617cc7b4fcbebfe6bcadd604850794a..f0af4cfdd143da41629057e68a1291643b079eec 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/detail/NDArraySerializerBase.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/detail/NDArraySerializerBase.h @@ -43,5 +43,19 @@ namespace armarx::aron::cppserializer::detail NDArraySerializerBase(const std::string& cppName, const std::string& aronDataTypename, const std::string& aronTypeTypename, const typename TypenavigatorT::PointerType& t) : SerializerBase<TypenavigatorT, DerivedT>(cppName, aronDataTypename, aronTypeTypename, t) {} + + virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override + { + CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); + block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); + return this->ResolveMaybeResetHardBlock(accessor, block_if_data, this->typenavigator); + } + + virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override + { + CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); + block_if_data->addLine(accessor + " = " + this->getFullCppTypename() + "();"); + return this->ResolveMaybeResetSoftBlock(accessor, block_if_data, this->typenavigator); + } }; } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/detail/PrimitiveSerializerBase.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/detail/PrimitiveSerializerBase.h index 171f4defb27cff9a51217805f71d76fb58ca0da5..cf84eec049e341a83318dd3544fca0684e64236a 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/detail/PrimitiveSerializerBase.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/detail/PrimitiveSerializerBase.h @@ -79,7 +79,7 @@ namespace armarx::aron::cppserializer::detail { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + " == " + otherInstanceAccessor + "))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return this->ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, this->typenavigator); } }; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.cpp index e412f52b59bb3b53397439c7068338131493d60d..2ae444db3f04f48865dc7e9842d5ae521e17cd0b 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/enum/IntEnum.cpp @@ -83,7 +83,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr b = CppBlockPtr(new CppBlock()); b->addLine("if (not (" + accessor + " == " + otherInstanceAccessor + "))"); - b->addLine("\t return false;"); + b->addLineAsBlock("return false;"); return b; } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp index 790d6157d4f28a33e983d0394a09448d818c6158..c59e70d713528f0db11d4bf0d2212f3f3b53de77 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.cpp @@ -47,20 +47,6 @@ namespace armarx::aron::cppserializer::serializer ARMARX_CHECK_NOT_NULL(typenavigator); } - CppBlockPtr EigenMatrixSerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - - CppBlockPtr EigenMatrixSerializer::getResetSoftBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullCppTypename() + "();"); - return ResolveMaybeResetSoftBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr EigenMatrixSerializer::getWriteTypeBlock(const std::string& accessor) const { CppBlockPtr b = CppBlockPtr(new CppBlock()); @@ -87,7 +73,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + nextEl() + "isApprox(" + ResolveMaybeAccessor(otherInstanceAccessor, typenavigator) + ")))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.h index 9c2ecd36e588238923f539ebe364af57c3681f42..13e435bfeed1161f6a349eae2507828b6a39a31c 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenMatrix.h @@ -46,8 +46,6 @@ namespace armarx::aron::cppserializer::serializer EigenMatrixSerializer(const typenavigator::EigenMatrixNavigatorPtr&); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; - virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; virtual CppBlockPtr getReadBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp index 8e697ab6d64c9e425310b6927842d756ff96cae3..6594fd20bc9d0915cfb95ed45a1fe821f44a58eb 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.cpp @@ -42,20 +42,6 @@ namespace armarx::aron::cppserializer::serializer ARMARX_CHECK_NOT_NULL(typenavigator); } - CppBlockPtr EigenQuaternionSerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - - CppBlockPtr EigenQuaternionSerializer::getResetSoftBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullCppTypename() + "();"); - return ResolveMaybeResetSoftBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr EigenQuaternionSerializer::getWriteTypeBlock(const std::string& accessor) const { CppBlockPtr b = CppBlockPtr(new CppBlock()); @@ -82,7 +68,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.h index 3d756220f32d541d7f01fbadc11d597028322e3f..9a42c8cf67b3c67f9cb5664bd69a8ae2fc8d24dd 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/EigenQuaternion.h @@ -40,7 +40,7 @@ namespace armarx::aron::cppserializer::serializer typedef std::shared_ptr<EigenQuaternionSerializer> EigenQuaternionSerializerPtr; class EigenQuaternionSerializer : - virtual public detail::NDArraySerializerBase<typenavigator::EigenQuaternionNavigator, EigenQuaternionSerializer> + virtual public detail::NDArraySerializerBase<typenavigator::EigenQuaternionNavigator, EigenQuaternionSerializer> { public: using PointerType = EigenQuaternionSerializerPtr; @@ -50,8 +50,6 @@ namespace armarx::aron::cppserializer::serializer EigenQuaternionSerializer(const typenavigator::EigenQuaternionNavigatorPtr&); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; - virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; virtual CppBlockPtr getReadBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp index e33934d359e63943bea3a194f0a739ae5adf471b..4a986761bd57f9b7b2a2810fab8c19e5ffb43067 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.cpp @@ -47,13 +47,6 @@ namespace armarx::aron::cppserializer::serializer } } - CppBlockPtr IVTCByteImageSerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr IVTCByteImageSerializer::getResetSoftBlock(const std::string& accessor) const { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); @@ -84,16 +77,16 @@ namespace armarx::aron::cppserializer::serializer block_if_data->addLine(accessor + nextEl() + "Set(" + read_start_result_accessor + ".dims[0], " + read_start_result_accessor + ".dims[1], static_cast<CByteImage::ImageType>(std::stoi(" + read_start_result_accessor + ".type)));"); block_if_data->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "pixels)); // of " + accessor); - return ResolveMaybeReadBlock(accessor, "r.readStartNDArray()", block_if_data, typenavigator); + return ResolveMaybeReadBlock(accessor, "r.readStartNDArray()", block_if_data, typenavigator, true); } CppBlockPtr IVTCByteImageSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + nextEl() + "IsCompatible(" + toPointerAccessor(otherInstanceAccessor) + ")))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); block_if_data->addLine("if (not (memcmp(" + accessor + nextEl() + "pixels, " + otherInstanceAccessor + nextEl() + "pixels, " + accessor + nextEl() + "width * " + accessor + nextEl() + "height * " + accessor + nextEl() + "bytesPerPixel) == 0))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.h index 07e61842942c67a10bdef419596ae5580c352dfd..1be69bdef6815d3c09f7d0cf16a06d2dda5cd81e 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/IVTCByteImage.h @@ -40,7 +40,7 @@ namespace armarx::aron::cppserializer::serializer typedef std::shared_ptr<IVTCByteImageSerializer> AronIVTCByteImageTypeCppSerializerPtr; class IVTCByteImageSerializer : - virtual public detail::NDArraySerializerBase<typenavigator::IVTCByteImageNavigator, IVTCByteImageSerializer> + virtual public detail::NDArraySerializerBase<typenavigator::IVTCByteImageNavigator, IVTCByteImageSerializer> { public: using PointerType = AronIVTCByteImageTypeCppSerializerPtr; @@ -50,7 +50,6 @@ namespace armarx::aron::cppserializer::serializer IVTCByteImageSerializer(const typenavigator::IVTCByteImageNavigatorPtr&); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp index 67eb03720ef2650e14be2f0b4e0713dca4e2a010..dfd9e90c390c358aa1aba0fa6af2c3f843f6013a 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.cpp @@ -35,20 +35,6 @@ namespace armarx::aron::cppserializer::serializer ARMARX_CHECK_NOT_NULL(typenavigator); } - CppBlockPtr NDArraySerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - - CppBlockPtr NDArraySerializer::getResetSoftBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullCppTypename() + "();"); - return ResolveMaybeResetSoftBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr NDArraySerializer::getWriteTypeBlock(const std::string&) const { CppBlockPtr b = CppBlockPtr(new CppBlock()); diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h index 7785a7b0c30f6c3a34c6708f67b577d4cc27fd26..540b38d930ec9a2911c8bb058b856031cc430683 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/NDArray.h @@ -39,7 +39,7 @@ namespace armarx::aron::cppserializer::serializer typedef std::shared_ptr<NDArraySerializer> AronNDArrayTypeCppSerializerPtr; class NDArraySerializer : - virtual public detail::NDArraySerializerBase<typenavigator::NDArrayNavigator, NDArraySerializer> + virtual public detail::NDArraySerializerBase<typenavigator::NDArrayNavigator, NDArraySerializer> { public: using PointerType = AronNDArrayTypeCppSerializerPtr; @@ -49,8 +49,6 @@ namespace armarx::aron::cppserializer::serializer NDArraySerializer(const typenavigator::NDArrayNavigatorPtr&); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; - virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; virtual CppBlockPtr getReadBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.cpp index da0e3c01389ef54f1d3afbd97f6767112db70a24..37de66674278dc5a8439a2b06d3e634dab7e42ba 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.cpp @@ -63,13 +63,6 @@ namespace armarx::aron::cppserializer::serializer return {b, accessor_dimensions}; } - CppBlockPtr OpenCVMatSerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr OpenCVMatSerializer::getResetSoftBlock(const std::string& accessor) const { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); @@ -117,14 +110,14 @@ namespace armarx::aron::cppserializer::serializer b2->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "data)); // of " + accessor); block_if_data->addBlock(b2); - return ResolveMaybeReadBlock(accessor, "r.readStartNDArray()", block_if_data, typenavigator); + return ResolveMaybeReadBlock(accessor, "r.readStartNDArray()", block_if_data, typenavigator, true); } CppBlockPtr OpenCVMatSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (cv::countNonZero(" + accessor + " != " + otherInstanceAccessor + ") != 0)"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.h index 4ed162490b73187359eecd5546115a37c0d4b01f..27ec677b25d20dab8d2e966ac6e0065ad1db98dd 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/OpenCVMat.h @@ -50,7 +50,6 @@ namespace armarx::aron::cppserializer::serializer OpenCVMatSerializer(const typenavigator::OpenCVMatNavigatorPtr& n); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.cpp index c10d1adfb26b3462639d2aed861d0f2d22be2fca..c908a0c44a8b0d1d940b9a64be5e79558b1dc949 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.cpp @@ -35,20 +35,6 @@ namespace armarx::aron::cppserializer::serializer ARMARX_CHECK_NOT_NULL(typenavigator); } - CppBlockPtr OrientationSerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - - CppBlockPtr OrientationSerializer::getResetSoftBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullCppTypename() + "();"); - return ResolveMaybeResetSoftBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr OrientationSerializer::getWriteTypeBlock(const std::string& accessor) const { CppBlockPtr b = CppBlockPtr(new CppBlock()); @@ -75,7 +61,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.h index df2349ca6ccb488131be4524eb17a63cc16874bd..ece7bb620a16d40184518585ed0b0592a8264639 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Orientation.h @@ -39,7 +39,7 @@ namespace armarx::aron::cppserializer::serializer typedef std::shared_ptr<OrientationSerializer> AronOrientationTypeCppSerializerPtr; class OrientationSerializer : - virtual public detail::NDArraySerializerBase<typenavigator::OrientationNavigator, OrientationSerializer> + virtual public detail::NDArraySerializerBase<typenavigator::OrientationNavigator, OrientationSerializer> { public: using PointerType = AronOrientationTypeCppSerializerPtr; @@ -49,8 +49,6 @@ namespace armarx::aron::cppserializer::serializer OrientationSerializer(const typenavigator::OrientationNavigatorPtr&); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; - virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; virtual CppBlockPtr getReadBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.cpp index 8229554f6542ce0fb91509ed32837df20e076ca4..5a6155b230e3fd5267ef30dcf665ca60df97ab1f 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.cpp @@ -48,13 +48,6 @@ namespace armarx::aron::cppserializer::serializer ARMARX_CHECK_NOT_NULL(typenavigator); } - CppBlockPtr PCLPointCloudSerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr PCLPointCloudSerializer::getResetSoftBlock(const std::string& accessor) const { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); @@ -85,16 +78,17 @@ namespace armarx::aron::cppserializer::serializer block_if_data->addLine(accessor + " = " + getCoreCppTypename() + "(" + read_start_result_accessor + ".dims[0], " + read_start_result_accessor + ".dims[1]);"); block_if_data->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "points.data())); // of " + accessor); - return ResolveMaybeReadBlock(accessor, "r.readStartNDArray()", block_if_data, typenavigator); + return ResolveMaybeReadBlock(accessor, "r.readStartNDArray()", block_if_data, typenavigator, true); } CppBlockPtr PCLPointCloudSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (" + accessor + nextEl() + "width != " + otherInstanceAccessor + nextEl() + "width || " + accessor + nextEl() + "height != " + otherInstanceAccessor + nextEl() + "height)"); - block_if_data->addLine("\t return false;"); - //b->addLine("if (" + accessor + "->points != " + otherInstanceAccessor + "->points)"); - //b->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); + + //block_if_data->addLine("if (" + accessor + nextEl() + "points != " + otherInstanceAccessor + nextEl() + "points)"); + //block_if_data->addLine("\t return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.h index 88d9b337b727e9f421a518e62ed7bc7df0f41284..3f182f4e24f775166a4e64d12f8933fffa771fc6 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/PCLPointCloud.h @@ -39,7 +39,7 @@ namespace armarx::aron::cppserializer::serializer typedef std::shared_ptr<PCLPointCloudSerializer> AronPCLPointCloudTypeCppSerializerPtr; class PCLPointCloudSerializer : - virtual public detail::NDArraySerializerBase<typenavigator::PCLPointCloudNavigator, PCLPointCloudSerializer> + virtual public detail::NDArraySerializerBase<typenavigator::PCLPointCloudNavigator, PCLPointCloudSerializer> { public: using PointerType = AronPCLPointCloudTypeCppSerializerPtr; @@ -49,7 +49,6 @@ namespace armarx::aron::cppserializer::serializer PCLPointCloudSerializer(const typenavigator::PCLPointCloudNavigatorPtr&); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.cpp index 93e340f51c049d3cd1d6913ea74c32b1505f1e08..eccbbca04eeeced4c106707d5963222f0250db54 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.cpp @@ -35,20 +35,6 @@ namespace armarx::aron::cppserializer::serializer ARMARX_CHECK_NOT_NULL(typenavigator); } - CppBlockPtr PoseSerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - - CppBlockPtr PoseSerializer::getResetSoftBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullCppTypename() + "();"); - return ResolveMaybeResetSoftBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr PoseSerializer::getWriteTypeBlock(const std::string& accessor) const { CppBlockPtr b = CppBlockPtr(new CppBlock()); @@ -75,7 +61,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.h index 46e7b82a51ff696f2f1b853a2dc4b5deb2e29acd..45b8eb78c64e62a2ea7713ac977c9fb3e675de05 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Pose.h @@ -39,7 +39,7 @@ namespace armarx::aron::cppserializer::serializer typedef std::shared_ptr<PoseSerializer> AronPoseTypeCppSerializerPtr; class PoseSerializer : - virtual public detail::NDArraySerializerBase<typenavigator::PoseNavigator, PoseSerializer> + virtual public detail::NDArraySerializerBase<typenavigator::PoseNavigator, PoseSerializer> { public: using PointerType = AronPoseTypeCppSerializerPtr; @@ -49,8 +49,6 @@ namespace armarx::aron::cppserializer::serializer PoseSerializer(const typenavigator::PoseNavigatorPtr&); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; - virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; virtual CppBlockPtr getReadBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.cpp index b4409c2f9f226995c118deb33a8cb298462997cb..199c7e3053af9cc84016d14a320092667ce87c71 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.cpp @@ -35,20 +35,6 @@ namespace armarx::aron::cppserializer::serializer ARMARX_CHECK_NOT_NULL(typenavigator); } - CppBlockPtr PositionSerializer::getResetHardBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullTypenameGenerator() + "();"); - return ResolveMaybeResetHardBlock(accessor, block_if_data, typenavigator); - } - - CppBlockPtr PositionSerializer::getResetSoftBlock(const std::string& accessor) const - { - CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); - block_if_data->addLine(accessor + " = " + this->getFullCppTypename() + "();"); - return ResolveMaybeResetSoftBlock(accessor, block_if_data, typenavigator); - } - CppBlockPtr PositionSerializer::getWriteTypeBlock(const std::string& accessor) const { CppBlockPtr b = CppBlockPtr(new CppBlock()); @@ -75,7 +61,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (" + accessor + nextEl() + "isApprox(" + otherInstanceAccessor + ")))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.h b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.h index 1c2f17b9028670e8aa87b79aa30a50b55941baaf..acb8f9912f8169b161ccd5b6d80c30e546b7ec75 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Position.h @@ -39,7 +39,7 @@ namespace armarx::aron::cppserializer::serializer typedef std::shared_ptr<PositionSerializer> AronPositionTypeCppSerializerPtr; class PositionSerializer : - virtual public detail::NDArraySerializerBase<typenavigator::PositionNavigator, PositionSerializer> + virtual public detail::NDArraySerializerBase<typenavigator::PositionNavigator, PositionSerializer> { public: using PointerType = AronPositionTypeCppSerializerPtr; @@ -49,8 +49,6 @@ namespace armarx::aron::cppserializer::serializer PositionSerializer(const typenavigator::PositionNavigatorPtr&); // virtual implementations - virtual CppBlockPtr getResetHardBlock(const std::string& accessor) const override; - virtual CppBlockPtr getResetSoftBlock(const std::string& accessor) const override; virtual CppBlockPtr getWriteTypeBlock(const std::string&) const override; virtual CppBlockPtr getWriteBlock(const std::string&) const override; virtual CppBlockPtr getReadBlock(const std::string&) const override; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.cpp index 6998d81b564e532f5f174c8c07db8b4b79b1f703..39f178fd00661fe78478ee3e74fe0872b2e762a5 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/IntEnumClass.cpp @@ -117,7 +117,7 @@ namespace armarx::aron::cppserializer::serializer { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); block_if_data->addLine("if (not (value == " + otherInstanceAccessor + ".value))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator); } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/ObjectClass.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/ObjectClass.cpp index e674c2445e24fa91af875bb81fbcd76e1d6d39d6..7653acba47e178b6337f8fbc9602037070b76836 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/ObjectClass.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/toplevel/ObjectClass.cpp @@ -100,13 +100,15 @@ namespace armarx::aron::cppserializer::serializer CppBlockPtr ObjectClassSerializer::getWriteTypeBlock(const std::string&) const { CppBlockPtr b = CppBlockPtr(new CppBlock()); + b->addLine("w.writeStartObject({\"" + typenavigator->getObjectName() + "\", __aronMaybeType}); // of top level object " + getCoreCppTypename()); + if (typenavigator->getExtends() != nullptr) { const auto extends_s = FromAronTypeNaviagtorPtr(typenavigator->getExtends()); - b->addLine(extends_s->getFullCppTypename() + "::writeType(w);"); + b->addLine(extends_s->getFullCppTypename() + "::writeType(w, armarx::aron::type::Maybe::eNone, true);"); + b->addLine("w.writeExtends();"); } - b->addLine("w.writeStartObject({\"" + typenavigator->getObjectName() + "\", __aronMaybeType}); // of top level object " + getCoreCppTypename()); for (const auto& [key, child] : typenavigator->getMemberTypes()) { const auto child_s = FromAronTypeNaviagtorPtr(child); @@ -115,20 +117,25 @@ namespace armarx::aron::cppserializer::serializer b->appendBlock(b2); } - b->addLine("w.writeEndObject(); // of top level object " + getCoreCppTypename()); + b->addLine("if (!__aronExtends)"); + b->addLineAsBlock("w.writeEndObject(); // of top level object " + getCoreCppTypename()); + return b; } CppBlockPtr ObjectClassSerializer::getWriteBlock(const std::string& accessor) const { CppBlockPtr block_if_data = CppBlockPtr(new CppBlock()); + + block_if_data->addLine("if (!__aronExtends)"); + block_if_data->addLineAsBlock("w.writeStartDict(); // of top level object " + getCoreCppTypename()); + if (typenavigator->getExtends() != nullptr) { const auto extends_s = FromAronTypeNaviagtorPtr(typenavigator->getExtends()); - block_if_data->addLine(extends_s->getFullCppTypename() + "::write(w, aron_type);"); + block_if_data->addLine(extends_s->getFullCppTypename() + "::write(w, true);"); } - block_if_data->addLine("w.writeStartDict(); // of top level object " + getCoreCppTypename()); for (const auto& [key, child] : typenavigator->getMemberTypes()) { const auto child_s = FromAronTypeNaviagtorPtr(child); @@ -138,7 +145,9 @@ namespace armarx::aron::cppserializer::serializer child_b->appendBlock(child_s->getWriteBlock(key)); block_if_data->appendBlock(child_b); } - block_if_data->addLine("w.writeEndDict(); // of top level object " + getCoreCppTypename()); + + block_if_data->addLine("if (!__aronExtends)"); + block_if_data->addLineAsBlock("w.writeEndDict(); // of top level object " + getCoreCppTypename()); return ResolveMaybeWriteBlock(accessor, block_if_data, typenavigator); } @@ -151,10 +160,8 @@ namespace armarx::aron::cppserializer::serializer block_if_data->addLine(extends_s->getFullCppTypename() + "::read(r);"); } - block_if_data->addLine("if(!skip_first_readStartDict)"); - auto readStartDict = std::make_shared<CppBlock>(); - readStartDict->addLine("r.readStartDict(); // of top level object " + getCoreCppTypename()); - block_if_data->addBlock(readStartDict); + block_if_data->addLine("if(!__aronIsMember)"); + block_if_data->addLineAsBlock("r.readStartDict(); // of top level object " + getCoreCppTypename()); for (const auto& [key, child] : typenavigator->getMemberTypes()) { @@ -173,7 +180,7 @@ namespace armarx::aron::cppserializer::serializer { const auto extends_s = FromAronTypeNaviagtorPtr(typenavigator->getExtends()); block_if_data->addLine("if (not (" + extends_s->getFullCppTypename() + "::operator== (" + otherInstanceAccessor + ")))"); - block_if_data->addLine("\t return false;"); + block_if_data->addLineAsBlock("return false;"); } for (const auto& [key, child] : typenavigator->getMemberTypes()) { diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Data.h b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Data.h index 4950d51f77149b7f192766d79144bfdfb7fea3c6..695050d69d765585b3192e9a2874c721afe8693c 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Data.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Data.h @@ -78,6 +78,10 @@ namespace armarx::aron::xmltypereader static constexpr const char* RAW_PTR_NAME = "raw_ptr"; static constexpr const char* SHARED_PTR_NAME = "shared_ptr"; static constexpr const char* UNIQUE_PTR_NAME = "unique_ptr"; + static constexpr const char* PACKAGE_NAME = "package"; + static constexpr const char* DOC_BRIEF_NAME = "doc-brief"; + static constexpr const char* DOC_AUTHOR_NAME = "doc-author"; + static constexpr const char* DOC_PARAM_NAME = "doc-param"; // Second level tags. Only important if in specific top level tag static constexpr const char* OBJECT_CHILD_TAG = "objectchild"; diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.cpp index 944f755f4ffdac48ae204903c0047a39c45e828f..7a89bb039550822a81f61e4ee1716f1e9c39688a 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.cpp @@ -53,20 +53,13 @@ namespace armarx::aron::xmltypereader void Reader::parseFile(const std::filesystem::path& _file) { fs::path file = _file; - if (!file.empty() && file.is_relative()) - { - if (std::optional<fs::path> resolved = detail::resolveRelativePackagePath(file)) - { - file = resolved.value(); - } - } RapidXmlReaderPtr reader = RapidXmlReader::FromFile(file.string()); - parse(reader); + parse(reader, _file); } // private method reading nodes - void Reader::parse(const RapidXmlReaderPtr& reader) + void Reader::parse(const RapidXmlReaderPtr& reader, const std::filesystem::path& filePath) { RapidXmlReaderNode root = reader->getRoot(); @@ -129,7 +122,7 @@ namespace armarx::aron::xmltypereader std::vector<RapidXmlReaderNode> includes = children[cpp_includes_index].nodes(); for (const auto& include : includes) { - this->codeIncludes.push_back(readCodeInclude(include)); + this->codeIncludes.push_back(readCodeInclude(include, filePath)); } } @@ -139,7 +132,7 @@ namespace armarx::aron::xmltypereader for (const auto& aronInclude : children[include_aron_file_index].nodes()) { // right now unused - this->aronIncludes.push_back(readAronInclude(aronInclude)); + this->aronIncludes.push_back(readAronInclude(aronInclude, filePath)); } } @@ -169,7 +162,7 @@ namespace armarx::aron::xmltypereader } } - std::string Reader::readCodeInclude(const RapidXmlReaderNode& node) + std::string Reader::readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath) { Data::EnforceTagName(node, Data::INCLUDE_TAG); Data::EnforceAttribute(node, Data::INCLUDE_ATTRIBUTE_NAME); @@ -177,22 +170,52 @@ namespace armarx::aron::xmltypereader return include; } - std::string Reader::readAronInclude(const RapidXmlReaderNode& node) + std::string Reader::readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath) { Data::EnforceTagName(node, Data::INCLUDE_TAG); - const std::string xmlinclude = Data::GetAttribute(node, Data::INCLUDE_ATTRIBUTE_NAME); + std::string specifiedPath = Data::GetAttribute(node, Data::INCLUDE_ATTRIBUTE_NAME); + specifiedPath = simox::alg::replace_all(specifiedPath, "<", ""); + specifiedPath = simox::alg::replace_all(specifiedPath, ">", ""); + const std::filesystem::path xmlincludepath(specifiedPath); + + // add logic to allow relative paths: + std::filesystem::path resolved_absolute_path(xmlincludepath); + std::filesystem::path resolved_relative_path(xmlincludepath); + + if (!xmlincludepath.empty() && xmlincludepath.is_relative()) + { + if (std::optional<fs::path> resolvedPackagePath = resolveRelativePackagePath(xmlincludepath); resolvedPackagePath.has_value()) + { + // check if relative path belongs to a package + resolved_absolute_path = resolvedPackagePath.value(); + resolved_relative_path = xmlincludepath; + } + else + { + // perhaps the relative path is relative from file position? + // TODO: FixMe + resolved_absolute_path = filePath.parent_path() / xmlincludepath; + resolved_relative_path = filePath.parent_path() / xmlincludepath; + + if (!fs::is_regular_file(resolved_absolute_path)) + { + throw error::AronException("Reader", "readAronInclude", "Could not find an aron XML file. Last path tried was: " + resolved_absolute_path.string()); + } + } + } + // else path is absolute // parse parent xml file and add objects to alreday known Reader anotherReader; - anotherReader.parseFile(xmlinclude); + anotherReader.parseFile(resolved_absolute_path); if (Data::HasAttribute(node, Data::AUTO_CODE_INCLUDE)) { - std::string codeinclude = simox::alg::replace_last(xmlinclude, ".xml", ".aron.generated.h"); - this->codeIncludes.push_back(codeinclude); + std::string codeinclude = simox::alg::replace_last(resolved_relative_path, ".xml", ".aron.generated.h"); + this->codeIncludes.push_back("<" + codeinclude + ">"); } - return xmlinclude; + return resolved_absolute_path.string(); } typenavigator::ObjectNavigatorPtr Reader::readGenerateObject(const RapidXmlReaderNode& node) const @@ -208,7 +231,7 @@ namespace armarx::aron::xmltypereader } - std::optional<fs::path> detail::resolveRelativePackagePath(const fs::path& path) + std::optional<fs::path> Reader::resolveRelativePackagePath(const fs::path& path) { const std::string package = *path.begin(); armarx::CMakePackageFinder finder(package); @@ -219,6 +242,7 @@ namespace armarx::aron::xmltypereader fs::path absPath = includePath / path; if (fs::is_regular_file(absPath)) { + // path is valid return absPath; } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.h b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.h index 387b2888dc23a44f3efebe832163a9888be249bc..c44f7d629fff62d5fb284dfe28445f4f7c4b9f5d 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.h +++ b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/Reader.h @@ -54,21 +54,17 @@ namespace armarx::aron::xmltypereader virtual void parseFile(const std::filesystem::path&) override; private: - void parse(const RapidXmlReaderPtr& node); + void parse(const RapidXmlReaderPtr& node, const std::filesystem::path& filePath); - std::string readCodeInclude(const RapidXmlReaderNode& node); - std::string readAronInclude(const RapidXmlReaderNode& node); + std::string readCodeInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath); + std::string readAronInclude(const RapidXmlReaderNode& node, const std::filesystem::path& filePath); typenavigator::ObjectNavigatorPtr readGenerateObject(const RapidXmlReaderNode& node) const; typenavigator::IntEnumNavigatorPtr readGenerateIntEnum(const RapidXmlReaderNode& node) const; + std::optional<std::filesystem::path> resolveRelativePackagePath(const std::filesystem::path& path); + private: ReaderFactory factory; }; - - - namespace detail - { - std::optional<std::filesystem::path> resolveRelativePackagePath(const std::filesystem::path& path); - } } diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/ReaderFactory.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/ReaderFactory.cpp index 6bc140e98a8d8ae555490e9c2b07b3360ac176cc..42c4ae9eea4efcd7dc3688164aec22bb49507959 100644 --- a/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/ReaderFactory.cpp +++ b/source/RobotAPI/libraries/aron/core/codegenerator/typeReader/xml/ReaderFactory.cpp @@ -135,6 +135,8 @@ namespace armarx::aron::xmltypereader auto newObject = std::make_shared<codegeneratorhelper::GenerateObjectInfo>(); newObject->typeName = name; newObject->correspondingType = aronObjectType; + newObject->doc_brief = Data::GetAttributeWithDefault(node, Data::DOC_BRIEF_NAME, ""); + newObject->doc_author = Data::GetAttributeWithDefault(node, Data::DOC_AUTHOR_NAME, ""); if (extends != "") { @@ -151,6 +153,11 @@ namespace armarx::aron::xmltypereader Data::EnforceAttribute(objectChild, Data::KEY_ATTRIBUTE_NAME); const std::string key = objectChild.attribute_value(Data::KEY_ATTRIBUTE_NAME); + if (Data::HasAttribute(objectChild, Data::DOC_BRIEF_NAME)) + { + newObject->doc_members.insert({key, Data::GetAttribute(objectChild, Data::DOC_BRIEF_NAME)}); + } + std::vector<RapidXmlReaderNode> children = objectChild.nodes(); auto maybe = GetMaybe(children[0]); @@ -394,16 +401,21 @@ namespace armarx::aron::xmltypereader newEnumInfo->typeName = name; newEnumInfo->correspondingType = aronIntEnumType; - for (const RapidXmlReaderNode& objectChild : node.nodes()) + for (const RapidXmlReaderNode& valueChild : node.nodes()) { - Data::EnforceTagName(objectChild, Data::ENUM_VALUE_TAG); - Data::EnforceChildSize(objectChild, 0); + Data::EnforceTagName(valueChild, Data::ENUM_VALUE_TAG); + Data::EnforceChildSize(valueChild, 0); - Data::EnforceAttribute(objectChild, Data::KEY_ATTRIBUTE_NAME); - const std::string key = objectChild.attribute_value(Data::KEY_ATTRIBUTE_NAME); + Data::EnforceAttribute(valueChild, Data::KEY_ATTRIBUTE_NAME); + const std::string key = valueChild.attribute_value(Data::KEY_ATTRIBUTE_NAME); + + if (Data::HasAttribute(valueChild, Data::DOC_BRIEF_NAME)) + { + newEnumInfo->doc_values.insert({key, Data::GetAttribute(valueChild, Data::DOC_BRIEF_NAME)}); + } - Data::EnforceAttribute(objectChild, Data::VALUE_ATTRIBUTE_NAME); - const std::string value = objectChild.attribute_value(Data::VALUE_ATTRIBUTE_NAME); + Data::EnforceAttribute(valueChild, Data::VALUE_ATTRIBUTE_NAME); + const std::string value = valueChild.attribute_value(Data::VALUE_ATTRIBUTE_NAME); aronIntEnumType->addAcceptedValue(key, std::stoi(value)); } diff --git a/source/RobotAPI/libraries/aron/core/io/Data.h b/source/RobotAPI/libraries/aron/core/io/Data.h index 6f9fe8ca878a6f7a8f697af1295fd6f0ccbe581b..e1c3cfcf026ba5019d5147e9c00cc2335c717065 100644 --- a/source/RobotAPI/libraries/aron/core/io/Data.h +++ b/source/RobotAPI/libraries/aron/core/io/Data.h @@ -46,6 +46,7 @@ namespace armarx::aron::io static constexpr const char* READER_WRITER_VALUE_SLUG = "__ARON_VALUE"; static constexpr const char* READER_WRITER_OBJECT_NAME_SLUG = "__ARON_OBJECT_NAME"; + static constexpr const char* READER_WRITER_OBJECT_EXTENDS_SLUG = "__ARON_OBJECT_EXTENDS"; static constexpr const char* READER_WRITER_DICT_ACCEPTED_TYPE_SLUG = "__ARON_DICT_ACCEPTED_TYPE"; static constexpr const char* READER_WRITER_LIST_ACCEPTED_TYPE_SLUG = "__ARON_LIST_ACCEPTED_TYPE"; diff --git a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp index 5d614b7025a52239be1ecc9933202c5a5aa3d26f..a17cc3ed151006531771e31e4639db4a972d34d5 100644 --- a/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp +++ b/source/RobotAPI/libraries/aron/core/io/dataIO/reader/nlohmannJSON/NlohmannJSONReader.cpp @@ -43,7 +43,7 @@ namespace armarx::aron::dataIO::reader { if (!n.is_object()) { - throw error::AronException("NlohmannJSONReader", "NlohmannJSONReader", "Allowed are only objects in reader"); + throw error::AronException("NlohmannJSONReader", "NlohmannJSONReader", "Allowed are only objects in reader. Got as json: " + n.dump(2)); } if (n.at(io::Data::READER_WRITER_TYPE_SLUG) != io::Data::READER_WRITER_DICT_TYPENAME_SLUG) diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.h b/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.h index 7dc762492105af180e30773518b3b8ef1eaae963..db7b4ed1adc62ea9962bd14ce9993be51bb0cbec 100644 --- a/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.h +++ b/source/RobotAPI/libraries/aron/core/io/typeIO/Writer.h @@ -141,5 +141,6 @@ namespace armarx::aron::typeIO virtual void writeTime(const WritePrimitiveInput&) = 0; virtual void writeKey(const std::string&) = 0; + virtual void writeExtends() = 0; }; } diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.cpp index 9693eb6851131add3d419b8ecb55c15cc43518db..6a23d549a4ea915cfecc8e7645c88c7945355797 100644 --- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.cpp +++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.cpp @@ -299,4 +299,20 @@ namespace armarx::aron::typeIO::writer auto token = stack.top(); token->setCurrentKey(k); } + + void NavigatorWriter::writeExtends() + { + if (stack.size() < 2) + { + throw error::SizeNotValidException("NavigatorWriter", "writeExtends", "The stacksize must at least be 2 (one for base, one for derived)", stack.size(), 2); + } + + auto base = stack.top(); + stack.pop(); + auto derived = stack.top(); + + auto base_obj = typenavigator::ObjectNavigator::DynamicCastAndCheck(base->getElement()); + auto derived_obj = typenavigator::ObjectNavigator::DynamicCastAndCheck(derived->getElement()); + derived_obj->setExtends(base_obj); + } } diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h index b15ab9e9b35fb140869017c2399f4e7345eda226..2586935e519799b7f7dd9c3f971a45bc4ab45d8f 100644 --- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h +++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/navigator/NavigatorWriter.h @@ -72,6 +72,7 @@ namespace armarx::aron::typeIO::writer virtual void writeTime(const WritePrimitiveInput&) override; virtual void writeKey(const std::string&) override; + virtual void writeExtends() override; typenavigator::NavigatorPtr getResult() const { diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp index 1ce3afe2394a3a20aa89948db49f97493d45865f..7a4359559aaf5169ef1bdac195937d540e8b3646 100644 --- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp +++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.cpp @@ -271,4 +271,28 @@ namespace armarx::aron::typeIO::writer auto token = stack.top(); token->setCurrentKey(k); } + + void NlohmannJSONWriter::writeExtends() + { + if (stack.size() < 2) + { + throw error::SizeNotValidException("NavigatorWriter", "writeExtends", "The stacksize must at least be 2 (one for base, one for derived)", stack.size(), 2); + } + + auto base = stack.top(); + stack.pop(); + auto derived = stack.top(); + + if (!base->getElement().is_object()) + { + throw error::AronException("NlohmannJSONWriter", "writeExtends", "Could not inherit from a non-object."); + } + + if (!derived->getElement().is_object()) + { + throw error::AronException("NlohmannJSONWriter", "writeExtends", "Could not inherit a non-object."); + } + + derived->getElement()[io::Data::READER_WRITER_OBJECT_EXTENDS_SLUG] = base->getElement(); + } } diff --git a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h index 3be0f4a1329aca74ad3c19710736a86f1c542582..055a493c878fbb76b4fed7dc41d08e680a71d976 100644 --- a/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h +++ b/source/RobotAPI/libraries/aron/core/io/typeIO/writer/nlohmannJSON/NlohmannJSONWriter.h @@ -69,6 +69,7 @@ namespace armarx::aron::typeIO::writer virtual void writeTime(const WritePrimitiveInput&) override; virtual void writeKey(const std::string&) override; + virtual void writeExtends() override; nlohmann::json getResult() const { diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp index 410ecaedd54896288b2c6d399b3d3994040632c7..d5e028477cb93837e70cedf95d321652e8a14db6 100644 --- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp +++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.cpp @@ -75,6 +75,19 @@ namespace armarx::aron::typenavigator } // public member functions + std::map<std::string, NavigatorPtr> ObjectNavigator::getAllMemberTypes() const + { + std::map<std::string, NavigatorPtr> ret = memberTypes; + if (extends) + { + for (const auto& [key, t] : extends->getMemberTypes()) + { + ret.insert({key, t}); + } + } + return ret; + } + std::map<std::string, NavigatorPtr> ObjectNavigator::getMemberTypes() const { return memberTypes; @@ -82,10 +95,14 @@ namespace armarx::aron::typenavigator NavigatorPtr ObjectNavigator::getMemberType(const std::string& s) const { - if (memberTypes.find(s) == memberTypes.end()) + if (memberTypes.find(s) == memberTypes.end() and !extends->hasMemberType(s)) { throw error::StringNotValidException("ObjectNavigator", "getMemberType", "Member not set. The list of all members is: " + simox::alg::to_string(simox::alg::get_keys(memberTypes)), s); } + if (memberTypes.find(s) == memberTypes.end()) + { + return extends->getMemberType(s); + } return memberTypes.at(s); } @@ -118,7 +135,7 @@ namespace armarx::aron::typenavigator bool ObjectNavigator::hasMemberType(const std::string& k) const { - return memberTypes.count(k) > 0; + return memberTypes.count(k) > 0 or (extends && extends->hasMemberType(k)); } std::string ObjectNavigator::getObjectName() const @@ -138,6 +155,13 @@ namespace armarx::aron::typenavigator { ret.push_back(k); } + if (extends) + { + for (const auto& s : extends->getAllKeys()) + { + ret.push_back(s); + } + } return ret; } @@ -159,6 +183,13 @@ namespace armarx::aron::typenavigator { ret.push_back(t); } + if (extends) + { + for (const auto& t : extends->getChildren()) + { + ret.push_back(t); + } + } return ret; } @@ -169,7 +200,7 @@ namespace armarx::aron::typenavigator std::string ObjectNavigator::getName() const { - return "AronObjectType<" + this->aron->objectName + ">"; + return "AronObjectType<" + this->aron->objectName + (extends ? (" : " + extends->getName()) : "") + ">"; } } diff --git a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.h b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.h index f3f9255646e22b826909ecc460a920a0b6071f97..71268a91ebf928b13a1347c778f758c43e756ace 100644 --- a/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.h +++ b/source/RobotAPI/libraries/aron/core/navigator/type/container/Object.h @@ -37,7 +37,7 @@ namespace armarx::aron::typenavigator typedef std::shared_ptr<ObjectNavigator> ObjectNavigatorPtr; class ObjectNavigator : - virtual public detail::ContainerNavigatorBase<type::AronObject, ObjectNavigator> + virtual public detail::ContainerNavigatorBase<type::AronObject, ObjectNavigator> { public: // constructors @@ -51,6 +51,7 @@ namespace armarx::aron::typenavigator // public member functions bool checkObjectName(const std::string&) const; + std::map<std::string, NavigatorPtr> getAllMemberTypes() const; std::map<std::string, NavigatorPtr> getMemberTypes() const; NavigatorPtr getMemberType(const std::string&) const; std::string getObjectName() const; diff --git a/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt b/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt index 239c92ecff42e75ea7be37b5e43c8d442983f678..9ea4438bbe3381ee9c92ae3cd4d6c656606e916c 100644 --- a/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt +++ b/source/RobotAPI/libraries/aron/core/test/CMakeLists.txt @@ -44,22 +44,22 @@ armarx_add_test( ARON_FILES # xmls/BaseClass.xml # xmls/DerivedClassTest.xml - xmls/DictTest.xml - xmls/EigenMatrixTest.xml - xmls/EigenQuaternionTest.xml - xmls/EnumTest.xml - xmls/HumanPoseTest.xml - xmls/IVTCByteImageTest.xml - xmls/ListTest.xml - xmls/NaturalIKTest.xml - xmls/ObjectTest.xml - xmls/OpenCVMatTest.xml - xmls/OrientationTest.xml - xmls/PCLPointCloudTest.xml - xmls/PoseTest.xml - xmls/PositionTest.xml - xmls/PrimitiveTest.xml - xmls/OptionalTest.xml + aron/DictTest.xml + aron/EigenMatrixTest.xml + aron/EigenQuaternionTest.xml + aron/EnumTest.xml + aron/HumanPoseTest.xml + aron/IVTCByteImageTest.xml + aron/ListTest.xml + aron/NaturalIKTest.xml + aron/ObjectTest.xml + aron/OpenCVMatTest.xml + aron/OrientationTest.xml + aron/PCLPointCloudTest.xml + aron/PoseTest.xml + aron/PositionTest.xml + aron/PrimitiveTest.xml + aron/OptionalTest.xml INCLUDE_DIRECTORIES ${Simox_INCLUDE_DIR} ${Eigen3_INCLUDE_DIR} @@ -81,11 +81,29 @@ armarx_add_test( ArmarXCore RobotAPI::aron ARON_FILES - xmls/NaturalIKTest.xml + aron/NaturalIKTest.xml INCLUDE_DIRECTORIES ${Simox_INCLUDE_DIR} ) +###################### +# ARON EXTENDS TEST # +###################### +armarx_add_test( + TEST_NAME + aronExtendsTest + TEST_FILE + aronExtendsTest.cpp + LIBS + Simox::SimoxUtility + ArmarXCore + RobotAPI::aron + ARON_FILES + aron/BaseClassTest.xml + aron/DerivedClassTest.xml + INCLUDE_DIRECTORIES + ${Simox_INCLUDE_DIR} +) ######################## # ARON RANDOMIZED TEST # @@ -103,24 +121,22 @@ armarx_add_test( ivtopencv ${PCL_COMMON_LIBRARIES} ARON_FILES - # xmls/BaseClass.xml - # xmls/DerivedClassTest.xml - xmls/DictTest.xml - xmls/EigenMatrixTest.xml - xmls/EigenQuaternionTest.xml - xmls/EnumTest.xml - xmls/HumanPoseTest.xml - xmls/IVTCByteImageTest.xml - xmls/ListTest.xml - xmls/NaturalIKTest.xml - xmls/ObjectTest.xml - xmls/OpenCVMatTest.xml - xmls/OrientationTest.xml - xmls/PCLPointCloudTest.xml - xmls/PoseTest.xml - xmls/PositionTest.xml - xmls/PrimitiveTest.xml - xmls/OptionalTest.xml + aron/DictTest.xml + aron/EigenMatrixTest.xml + aron/EigenQuaternionTest.xml + aron/EnumTest.xml + aron/HumanPoseTest.xml + aron/IVTCByteImageTest.xml + aron/ListTest.xml + aron/NaturalIKTest.xml + aron/ObjectTest.xml + aron/OpenCVMatTest.xml + aron/OrientationTest.xml + aron/PCLPointCloudTest.xml + aron/PoseTest.xml + aron/PositionTest.xml + aron/PrimitiveTest.xml + aron/OptionalTest.xml INCLUDE_DIRECTORIES ${Simox_INCLUDE_DIR} ${Eigen3_INCLUDE_DIR} diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/BaseClass.xml b/source/RobotAPI/libraries/aron/core/test/aron/BaseClassTest.xml similarity index 66% rename from source/RobotAPI/libraries/aron/core/test/xmls/BaseClass.xml rename to source/RobotAPI/libraries/aron/core/test/aron/BaseClassTest.xml index 57d4e6951e98ccb690b8e2c61e6730c067cf01e0..089b6fdfe8b56088c2b74ce2afd7717933cd7fc8 100644 --- a/source/RobotAPI/libraries/aron/core/test/xmls/BaseClass.xml +++ b/source/RobotAPI/libraries/aron/core/test/aron/BaseClassTest.xml @@ -2,28 +2,25 @@ <?xml version="1.0" encoding="UTF-8" ?> <AronTypeDefinition> <GenerateTypes> - <GenerateObject name='armarx::BaseClassTest'> - - <ObjectChild key='base_class_member1'> + <Object name='armarx::BaseClassTest' doc-brief="A base class for the tests" doc-author="fabian.peller-konrad@kit.edu"> + <ObjectChild key='base_class_member1' doc-brief="This is a a fancy bool. Only set this if needed..."> <Bool /> </ObjectChild> <ObjectChild key='base_class_member2'> <List> - <Type> - <Float /> - </Type> + <Float /> </List> </ObjectChild> - + <ObjectChild key='base_class_member3'> <Object name="InnerClass"> <ObjectChild key="inner_class_member"> <Bool /> </ObjectChild> - </List> + </Object> </ObjectChild> - </GenerateObject> + </Object> </GenerateTypes> </AronTypeDefinition> diff --git a/source/RobotAPI/libraries/aron/core/test/aron/DerivedClassTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/DerivedClassTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..fba1b8461bb41ffe9af7b62d044f6adf5aaea130 --- /dev/null +++ b/source/RobotAPI/libraries/aron/core/test/aron/DerivedClassTest.xml @@ -0,0 +1,16 @@ +<!--This class contains the data structure for NaturalIKResults --> +<?xml version="1.0" encoding="UTF-8" ?> +<AronTypeDefinition> + <AronIncludes> + <Include include="<RobotAPI/libraries/aron/core/test/aron/BaseClassTest.xml>" autoinclude="true" /> + </AronIncludes> + <GenerateTypes> + <Object name='armarx::DerivedClassTest' extends="armarx::BaseClassTest" doc-brief="This is a brief doc" doc-author="Itse me, Mario!"> + + <ObjectChild key='derived_class_member1' doc-brief="This is a member doc string"> + <Int /> + </ObjectChild> + + </Object> + </GenerateTypes> +</AronTypeDefinition> diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/DictTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/DictTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/DictTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/DictTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/EigenMatrixTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/EigenMatrixTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/EigenMatrixTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/EigenMatrixTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/EigenQuaternionTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/EigenQuaternionTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/EigenQuaternionTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/EigenQuaternionTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/EnumTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/EnumTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/EnumTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/EnumTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/HumanPoseTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/HumanPoseTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/HumanPoseTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/HumanPoseTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/aron/IKResult.xml b/source/RobotAPI/libraries/aron/core/test/aron/IKResult.xml new file mode 100644 index 0000000000000000000000000000000000000000..b382f9e9369e6833c88b10da32734f67bf5ccb7e --- /dev/null +++ b/source/RobotAPI/libraries/aron/core/test/aron/IKResult.xml @@ -0,0 +1,17 @@ +<!--This class contains the data structure for NaturalIKResults --> +<?xml version="1.0" encoding="UTF-8" ?> +<AronTypeDefinition> + <GenerateTypes> + <Object name='armarx::IKResult'> + + <ObjectChild key='name'> + <String /> + </ObjectChild> + + </Object> + </GenerateTypes> +</AronTypeDefinition> + + + + diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/IVTCByteImageTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/IVTCByteImageTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/IVTCByteImageTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/IVTCByteImageTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/ListTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/ListTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/ListTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/ListTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/NaturalIKTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/NaturalIKTest.xml similarity index 57% rename from source/RobotAPI/libraries/aron/core/test/xmls/NaturalIKTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/NaturalIKTest.xml index 06dc659d12d955b30b2113ffe7125e2320d96127..769a899a51e82d2c25e533b96bd1054f66565eef 100644 --- a/source/RobotAPI/libraries/aron/core/test/xmls/NaturalIKTest.xml +++ b/source/RobotAPI/libraries/aron/core/test/aron/NaturalIKTest.xml @@ -2,7 +2,16 @@ <?xml version="1.0" encoding="UTF-8" ?> <AronTypeDefinition> <GenerateTypes> + <IntEnum name="armarx::NaturalIKControlMode"> + <EnumValue key="CONTROL_MODE_0" value="0" /> + <EnumValue key="CONTROL_MODE_1" value="1" /> + <EnumValue key="CONTROL_MODE_2" value="2" /> + </IntEnum> + <Object name='armarx::NaturalIKResult'> + <ObjectChild key='control_mode'> + <armarx::NaturalIKControlMode /> + </ObjectChild> <ObjectChild key='reached'> <Bool /> @@ -13,7 +22,10 @@ <Float /> </List> </ObjectChild> - </Object> </GenerateTypes> </AronTypeDefinition> + + + + diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/ObjectTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/ObjectTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/ObjectTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/ObjectTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/OpenCVMatTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/OpenCVMatTest.xml similarity index 95% rename from source/RobotAPI/libraries/aron/core/test/xmls/OpenCVMatTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/OpenCVMatTest.xml index c5cfb1e95c41d72790a7a6a65b5d028adbeb0576..f4179798c6ed36ee9f48373ebe57c921bfcf448d 100644 --- a/source/RobotAPI/libraries/aron/core/test/xmls/OpenCVMatTest.xml +++ b/source/RobotAPI/libraries/aron/core/test/aron/OpenCVMatTest.xml @@ -4,8 +4,6 @@ <CodeIncludes> <Include include="<opencv2/core/core.hpp>" /> </CodeIncludes> - <AronIncludes> - </AronIncludes> <GenerateTypes> <Object name='armarx::OpenCVMatTest'> <ObjectChild key='the_2d_opencv_matrix'> diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/OptionalTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/OptionalTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/OptionalTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/OptionalTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/OrientationTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/OrientationTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/OrientationTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/OrientationTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/PCLPointCloudTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/PCLPointCloudTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/PCLPointCloudTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/PCLPointCloudTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/PoseTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/PoseTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/PoseTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/PoseTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/PositionTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/PositionTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/PositionTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/PositionTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/PrimitiveTest.xml b/source/RobotAPI/libraries/aron/core/test/aron/PrimitiveTest.xml similarity index 100% rename from source/RobotAPI/libraries/aron/core/test/xmls/PrimitiveTest.xml rename to source/RobotAPI/libraries/aron/core/test/aron/PrimitiveTest.xml diff --git a/source/RobotAPI/libraries/aron/core/test/aronExtendsTest.cpp b/source/RobotAPI/libraries/aron/core/test/aronExtendsTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9feaee398008091d3ef9e97161fec750e0b95ac --- /dev/null +++ b/source/RobotAPI/libraries/aron/core/test/aronExtendsTest.cpp @@ -0,0 +1,85 @@ +/* + * 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::ArmarXObjects::aron + * @author Simon Ottenhaus ( simon dot ottenhaus at kit dot edu ) + * @date 2019 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#define BOOST_TEST_MODULE RobotAPI::ArmarXLibraries::aron + +#define ARMARX_BOOST_TEST + +// STD/STL +#include <iostream> +#include <cstdlib> +#include <ctime> +#include <numeric> + +// Boost +#include <boost/algorithm/string.hpp> + +// Test +#include <RobotAPI/Test.h> + +// ArmarX +#include <ArmarXCore/libraries/cppgen/CppMethod.h> +#include <ArmarXCore/libraries/cppgen/CppClass.h> +#include <RobotAPI/libraries/aron/core/Exception.h> + +// Aron +#include <RobotAPI/libraries/aron/core/Debug.h> +#include <RobotAPI/libraries/aron/core/navigator/data/AllNavigators.h> + +// Generated File +#include <RobotAPI/libraries/aron/core/test/aron/BaseClassTest.aron.generated.h> +#include <RobotAPI/libraries/aron/core/test/aron/DerivedClassTest.aron.generated.h> + +using namespace armarx; +using namespace aron; + +BOOST_AUTO_TEST_CASE(AronExtendsTest) +{ + std::cout << "Aron extends test" << std::endl; + BaseClassTest base; + auto baseType = base.toAronType(); + + DerivedClassTest derived; + auto derivedType = derived.toAronType(); + + for (const auto& [key, value] : baseType->getMemberTypes()) + { + BOOST_CHECK_EQUAL(derivedType->hasMemberType(key), true); + //BOOST_CHECK_EQUAL(value == derivedType->getMemberType(key), true); + } + + derived.base_class_member1 = false; + derived.base_class_member2 = {1.0, 2.5, 3.8}; + derived.base_class_member3.inner_class_member = true; + + auto derivedAron = derived.toAron(); + //BOOST_CHECK_EQUAL(derivedAron->fullfillsType(baseType), true); + + BaseClassTest& casted = static_cast<BaseClassTest&>(derived); + BOOST_CHECK_EQUAL(casted.base_class_member1 == derived.base_class_member1, true); + BOOST_CHECK_EQUAL(casted.base_class_member2 == derived.base_class_member2, true); + BOOST_CHECK_EQUAL(casted.base_class_member3.inner_class_member == derived.base_class_member3.inner_class_member, true); + + DerivedClassTest& casted_back = dynamic_cast<DerivedClassTest&>(casted); + BOOST_CHECK_EQUAL(casted_back == derived, true); +} + diff --git a/source/RobotAPI/libraries/aron/core/test/xmls/DerivedClassTest.xml b/source/RobotAPI/libraries/aron/core/test/xmls/DerivedClassTest.xml deleted file mode 100644 index de4be250d23c90f27d8198d890e7ef0576d672cb..0000000000000000000000000000000000000000 --- a/source/RobotAPI/libraries/aron/core/test/xmls/DerivedClassTest.xml +++ /dev/null @@ -1,19 +0,0 @@ -<!--This class contains the data structure for NaturalIKResults --> -<?xml version="1.0" encoding="UTF-8" ?> -<AronTypeDefinition> - <CodeIncludes> - <Include include="<RobotAPI/libraries/aron/test/aron/BaseClass.aron.generated.h>" /> - </CodeIncludes> - <AronIncludes> - <Include include="/home/fabian/Software/ArmarX/RobotAPI/source/RobotAPI/libraries/aron/test/xmls/BaseClass.xml" /> - </AronIncludes> - <GenerateTypes> - <GenerateObject name='armarx::DerivedClass' extends="armarx::BaseClassTest"> - - <ObjectChild key='derived_class_member1'> - <Bool /> - </ObjectChild> - - </GenerateObject> - </GenerateTypes> -</AronTypeDefinition>