From 0305f9936b23a1469a9ad513bafb2c19efb10938 Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Wed, 1 Mar 2023 17:12:03 +0100 Subject: [PATCH] exteroception core segment + converters etc --- .../RobotStateMemory/RobotStateMemory.cpp | 3 + .../RobotStateMemory/RobotStateMemory.h | 4 + .../armem_robot_state/CMakeLists.txt | 1 + .../armem_robot_state/aron/Exteroception.xml | 35 +++ .../armem_robot_state/aron/Proprioception.xml | 16 - .../armem_robot_state/aron_conversions.cpp | 5 +- .../armem_robot_state/aron_conversions.h | 9 +- .../client/common/RobotReader.cpp | 11 +- .../client/common/constants.h | 1 + .../armem_robot_state/memory_ids.cpp | 1 + .../libraries/armem_robot_state/memory_ids.h | 1 + .../armem_robot_state/server/CMakeLists.txt | 16 +- .../server/exteroception/Segment.cpp | 50 +++ .../server/exteroception/Segment.h | 55 ++++ .../converters/ArmarDEConverter.cpp | 130 ++++++++ .../converters/ArmarDEConverter.h | 51 +++ .../converters/ConverterInterface.cpp | 11 + .../converters/ConverterInterface.h | 32 ++ .../converters/ConverterRegistry.cpp | 31 ++ .../converters/ConverterRegistry.h | 36 +++ .../converters/ConverterTools.cpp | 179 +++++++++++ .../exteroception/converters/ConverterTools.h | 106 +++++++ .../proprioception/RobotStateWriter.cpp | 27 +- .../server/proprioception/RobotStateWriter.h | 1 + .../server/proprioception/RobotUnitData.h | 1 + .../server/proprioception/RobotUnitReader.cpp | 18 +- .../server/proprioception/RobotUnitReader.h | 7 +- .../converters/ArmarDEConverter.cpp | 296 ------------------ .../converters/ArmarDEConverter.h | 78 ----- .../converters/ConverterRegistry.cpp | 3 +- 30 files changed, 800 insertions(+), 415 deletions(-) create mode 100644 source/RobotAPI/libraries/armem_robot_state/aron/Exteroception.xml create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.cpp create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.h create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ArmarDEConverter.cpp create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ArmarDEConverter.h create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterInterface.cpp create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterInterface.h create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterRegistry.cpp create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterRegistry.h create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterTools.cpp create mode 100644 source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterTools.h delete mode 100644 source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ArmarDEConverter.cpp delete mode 100644 source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ArmarDEConverter.h diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.cpp b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.cpp index eab8bf5e6..f77e01607 100644 --- a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.cpp +++ b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.cpp @@ -47,6 +47,7 @@ namespace armarx::armem::server::robot_state RobotStateMemory::RobotStateMemory() : descriptionSegment(iceAdapter()), proprioceptionSegment(iceAdapter()), + exteroceptionSegment(iceAdapter()), localizationSegment(iceAdapter()), commonVisu(descriptionSegment, proprioceptionSegment, localizationSegment) { @@ -86,6 +87,7 @@ namespace armarx::armem::server::robot_state setMemoryName(armem::robot_state::memoryID.memoryName); descriptionSegment.defineProperties(defs, prefix + "desc."); + exteroceptionSegment.defineProperties(defs, prefix + "ext."); proprioceptionSegment.defineProperties(defs, prefix + "prop."); localizationSegment.defineProperties(defs, prefix + "loc."); commonVisu.defineProperties(defs, prefix + "visu."); @@ -104,6 +106,7 @@ namespace armarx::armem::server::robot_state { descriptionSegment.init(); proprioceptionSegment.init(); + exteroceptionSegment.init(); localizationSegment.init(); commonVisu.init(); diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.h b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.h index aed5fec80..70513a0cf 100644 --- a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.h +++ b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotStateMemory.h @@ -38,6 +38,7 @@ #include <RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitData.h> #include <RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.h> #include <RobotAPI/libraries/armem_robot_state/server/proprioception/Segment.h> +#include <RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.h> namespace armarx::plugins @@ -105,6 +106,9 @@ namespace armarx::armem::server::robot_state proprioception::Segment proprioceptionSegment; armem::data::MemoryID robotUnitProviderID; + // - exteroception + exteroception::Segment exteroceptionSegment; + // - localization localization::Segment localizationSegment; diff --git a/source/RobotAPI/libraries/armem_robot_state/CMakeLists.txt b/source/RobotAPI/libraries/armem_robot_state/CMakeLists.txt index a9c0ceb1b..8dda90015 100644 --- a/source/RobotAPI/libraries/armem_robot_state/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem_robot_state/CMakeLists.txt @@ -65,6 +65,7 @@ armarx_enable_aron_file_generation_for_target( ARON_FILES aron/JointState.xml aron/Proprioception.xml + aron/Exteroception.xml aron/TransformHeader.xml aron/Transform.xml ) diff --git a/source/RobotAPI/libraries/armem_robot_state/aron/Exteroception.xml b/source/RobotAPI/libraries/armem_robot_state/aron/Exteroception.xml new file mode 100644 index 000000000..80f72e060 --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/aron/Exteroception.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<AronTypeDefinition> + <CodeIncludes> + <SystemInclude include="Eigen/Core" /> + <SystemInclude include="Eigen/Geometry" /> + </CodeIncludes> + + <GenerateTypes> + + <Object name="armarx::armem::exteroception::arondto::ToF"> + + <ObjectChild key="array"> + <Matrix rows="-1" cols="-1" type="float32" /> + </ObjectChild> + + </Object> + + + <Object name="armarx::armem::arondto::Exteroception"> + + <ObjectChild key="iterationID"> + <long /> + </ObjectChild> + + <ObjectChild key="tof"> + <Dict> + <armarx::armem::exteroception::arondto::ToF/> + </Dict> + </ObjectChild> + + </Object> + + + </GenerateTypes> +</AronTypeDefinition> diff --git a/source/RobotAPI/libraries/armem_robot_state/aron/Proprioception.xml b/source/RobotAPI/libraries/armem_robot_state/aron/Proprioception.xml index e84ccf382..d5472cbde 100644 --- a/source/RobotAPI/libraries/armem_robot_state/aron/Proprioception.xml +++ b/source/RobotAPI/libraries/armem_robot_state/aron/Proprioception.xml @@ -234,15 +234,6 @@ </ObjectChild> </Object> - - <Object name="armarx::armem::prop::arondto::ToF"> - - <ObjectChild key="array"> - <Matrix rows="-1" cols="-1" type="float32" /> - </ObjectChild> - - </Object> - <Object name="armarx::armem::arondto::Proprioception"> @@ -264,13 +255,6 @@ </Dict> </ObjectChild> - <!-- TODO move to separate segment --> - <ObjectChild key="tof"> - <Dict> - <armarx::armem::prop::arondto::ToF/> - </Dict> - </ObjectChild> - <ObjectChild key="extraFloats"> <Dict> <Float /> diff --git a/source/RobotAPI/libraries/armem_robot_state/aron_conversions.cpp b/source/RobotAPI/libraries/armem_robot_state/aron_conversions.cpp index b079cec2e..3749c892d 100644 --- a/source/RobotAPI/libraries/armem_robot_state/aron_conversions.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/aron_conversions.cpp @@ -6,6 +6,7 @@ #include <RobotAPI/libraries/armem_robot_state/aron/JointState.aron.generated.h> #include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h> +#include <RobotAPI/libraries/armem_robot_state/aron/Exteroception.aron.generated.h> #include <RobotAPI/libraries/armem_robot_state/aron/Transform.aron.generated.h> #include <RobotAPI/libraries/armem_robot_state/types.h> #include <RobotAPI/libraries/aron/common/aron_conversions.h> @@ -98,11 +99,11 @@ namespace armarx::armem } - void fromAron(const armarx::armem::prop::arondto::ToF& dto, robot::ToFArray& bo){ + void fromAron(const armarx::armem::exteroception::arondto::ToF& dto, robot::ToFArray& bo){ bo = dto.array; } - void toAron(armarx::armem::prop::arondto::ToF& dto, const robot::ToFArray& bo){ + void toAron(armarx::armem::exteroception::arondto::ToF& dto, const robot::ToFArray& bo){ dto.array = bo; } diff --git a/source/RobotAPI/libraries/armem_robot_state/aron_conversions.h b/source/RobotAPI/libraries/armem_robot_state/aron_conversions.h index 1912e6c69..f78efc200 100644 --- a/source/RobotAPI/libraries/armem_robot_state/aron_conversions.h +++ b/source/RobotAPI/libraries/armem_robot_state/aron_conversions.h @@ -38,6 +38,10 @@ namespace armarx::armem { struct Platform; struct ForceTorque; + } + + namespace exteroception::arondto + { struct ToF; } @@ -66,9 +70,8 @@ namespace armarx::armem void fromAron(const armarx::armem::prop::arondto::ForceTorque& dto, robot::ForceTorque& bo); void toAron(armarx::armem::prop::arondto::ForceTorque& dto, const robot::ForceTorque& bo); - - void fromAron(const armarx::armem::prop::arondto::ToF& dto, robot::ToFArray& bo); - void toAron(armarx::armem::prop::arondto::ToF& dto, const robot::ToFArray& bo); + void fromAron(const armarx::armem::exteroception::arondto::ToF& dto, robot::ToFArray& bo); + void toAron(armarx::armem::exteroception::arondto::ToF& dto, const robot::ToFArray& bo); } // namespace armarx::armem diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp index d5f4844b5..cb55df698 100644 --- a/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/client/common/RobotReader.cpp @@ -24,6 +24,7 @@ #include <RobotAPI/libraries/armem_robot/types.h> #include <RobotAPI/libraries/armem_robot_state/aron/JointState.aron.generated.h> #include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h> +#include <RobotAPI/libraries/armem_robot_state/aron/Exteroception.aron.generated.h> #include <RobotAPI/libraries/armem_robot_state/aron_conversions.h> @@ -722,7 +723,7 @@ namespace armarx::armem::robot_state // clang-format off const armem::wm::CoreSegment& coreSegment = memory - .getCoreSegment(constants::proprioceptionCoreSegment); + .getCoreSegment(constants::exteroceptionCoreSegment); // clang-format on coreSegment.forEachEntity( @@ -736,12 +737,12 @@ namespace armarx::armem::robot_state } const auto& entityInstance = entity.getLatestSnapshot().getInstance(0); - const auto proprioception = - tryCast<::armarx::armem::arondto::Proprioception>(entityInstance); - ARMARX_CHECK(proprioception.has_value()); + const auto exteroception = + tryCast<::armarx::armem::arondto::Exteroception>(entityInstance); + ARMARX_CHECK(exteroception.has_value()); - for (const auto& [handName, dtoFt] : proprioception->tof) + for (const auto& [handName, dtoFt] : exteroception->tof) { ARMARX_DEBUG << "Processing ToF element for hand `" << handName << "`"; diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/constants.h b/source/RobotAPI/libraries/armem_robot_state/client/common/constants.h index d9efcbcf7..5d093c195 100644 --- a/source/RobotAPI/libraries/armem_robot_state/client/common/constants.h +++ b/source/RobotAPI/libraries/armem_robot_state/client/common/constants.h @@ -28,6 +28,7 @@ namespace armarx::armem::robot_state::constants inline const std::string descriptionCoreSegment = "Description"; inline const std::string localizationCoreSegment = "Localization"; inline const std::string proprioceptionCoreSegment = "Proprioception"; + inline const std::string exteroceptionCoreSegment = "Exteroception"; inline const std::string descriptionEntityName = "description"; diff --git a/source/RobotAPI/libraries/armem_robot_state/memory_ids.cpp b/source/RobotAPI/libraries/armem_robot_state/memory_ids.cpp index 926c2e843..2f219eff3 100644 --- a/source/RobotAPI/libraries/armem_robot_state/memory_ids.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/memory_ids.cpp @@ -30,6 +30,7 @@ namespace armarx::armem const MemoryID robot_state::descriptionSegmentID { memoryID.withCoreSegmentName("Description") }; const MemoryID robot_state::proprioceptionSegmentID { memoryID.withCoreSegmentName("Proprioception") }; + const MemoryID robot_state::exteroceptionSegmentID { memoryID.withCoreSegmentName("Exteroception") }; const MemoryID robot_state::localizationSegmentID { memoryID.withCoreSegmentName("Localization") }; diff --git a/source/RobotAPI/libraries/armem_robot_state/memory_ids.h b/source/RobotAPI/libraries/armem_robot_state/memory_ids.h index 1d8008d4d..f653236b1 100644 --- a/source/RobotAPI/libraries/armem_robot_state/memory_ids.h +++ b/source/RobotAPI/libraries/armem_robot_state/memory_ids.h @@ -32,6 +32,7 @@ namespace armarx::armem::robot_state extern const MemoryID descriptionSegmentID; extern const MemoryID proprioceptionSegmentID; + extern const MemoryID exteroceptionSegmentID; extern const MemoryID localizationSegmentID; } // namespace armarx::armem::objects diff --git a/source/RobotAPI/libraries/armem_robot_state/server/CMakeLists.txt b/source/RobotAPI/libraries/armem_robot_state/server/CMakeLists.txt index 887cc2eec..3ad1d5068 100644 --- a/source/RobotAPI/libraries/armem_robot_state/server/CMakeLists.txt +++ b/source/RobotAPI/libraries/armem_robot_state/server/CMakeLists.txt @@ -43,11 +43,16 @@ armarx_add_library( proprioception/RobotUnitData.h proprioception/RobotUnitReader.h + proprioception/converters/ConverterInterface.h proprioception/converters/Armar6Converter.h - proprioception/converters/ArmarDEConverter.h proprioception/converters/ConverterTools.h proprioception/converters/ConverterRegistry.h - proprioception/converters/ConverterInterface.h + + exteroception/converters/ConverterInterface.h + exteroception/converters/ConverterTools.h + exteroception/converters/ConverterRegistry.h + exteroception/converters/ArmarDEConverter.h + exteroception/Segment.h description/Segment.h @@ -64,11 +69,16 @@ armarx_add_library( proprioception/RobotUnitReader.cpp proprioception/converters/Armar6Converter.cpp - proprioception/converters/ArmarDEConverter.cpp proprioception/converters/ConverterTools.cpp proprioception/converters/ConverterRegistry.cpp proprioception/converters/ConverterInterface.cpp + exteroception/converters/ConverterInterface.cpp + exteroception/converters/ConverterTools.cpp + exteroception/converters/ConverterRegistry.cpp + exteroception/converters/ArmarDEConverter.cpp + exteroception/Segment.cpp + description/Segment.cpp ) diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.cpp b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.cpp new file mode 100644 index 000000000..63f24d0f4 --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.cpp @@ -0,0 +1,50 @@ +#include "Segment.h" + +#include <filesystem> + +#include <SimoxUtility/algorithm/string/string_tools.h> + +#include <ArmarXCore/core/application/properties/PluginAll.h> +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include <ArmarXCore/core/system/ArmarXDataPath.h> +#include <ArmarXCore/core/system/cmake/CMakePackageFinder.h> +#include <ArmarXCore/core/time/TimeUtil.h> + +#include <RobotAPI/libraries/armem/client/Writer.h> +#include <RobotAPI/libraries/armem/client/query/Builder.h> +#include <RobotAPI/libraries/armem/client/query/query_fns.h> +#include <RobotAPI/libraries/armem/core/MemoryID.h> +#include <RobotAPI/libraries/armem/core/aron_conversions.h> +#include <RobotAPI/libraries/armem/server/MemoryToIceAdapter.h> +#include <RobotAPI/libraries/armem_robot/aron/Robot.aron.generated.h> +#include <RobotAPI/libraries/armem_robot/aron_conversions.h> +#include <RobotAPI/libraries/armem_robot/robot_conversions.h> +#include <RobotAPI/libraries/armem_robot/types.h> +#include <RobotAPI/libraries/armem_robot_state/aron/Exteroception.aron.generated.h> +#include <RobotAPI/libraries/armem_robot_state/memory_ids.h> +#include <RobotAPI/libraries/aron/common/aron_conversions.h> + + +namespace armarx::armem::server::robot_state::exteroception +{ + + Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter) : + Base(memoryToIceAdapter, + armem::robot_state::exteroceptionSegmentID.coreSegmentName, + arondto::Exteroception::ToAronType()) + { + } + + Segment::~Segment() = default; + + + // void + // Segment::onConnect(const RobotUnitInterfacePrx& robotUnitPrx) + // { + // robotUnit = robotUnitPrx; + + // // store the robot description linked to the robot unit in this segment + // } + + +} // namespace armarx::armem::server::robot_state::exteroception diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.h b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.h new file mode 100644 index 000000000..e8471563d --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/Segment.h @@ -0,0 +1,55 @@ +/* + * 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/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2023 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include <mutex> +#include <optional> +#include <string> +#include <unordered_map> + +#include <RobotAPI/interface/units/RobotUnit/RobotUnitInterface.h> +#include <RobotAPI/libraries/armem/server/segment/SpecializedCoreSegment.h> +#include <RobotAPI/libraries/armem/server/segment/SpecializedProviderSegment.h> +#include <RobotAPI/libraries/armem_robot/aron/RobotDescription.aron.generated.h> +#include <RobotAPI/libraries/armem_robot_state/server/forward_declarations.h> + + +namespace armarx::armem::server::robot_state::exteroception +{ + + class Segment : public segment::SpecializedCoreSegment + { + using Base = segment::SpecializedCoreSegment; + + public: + Segment(server::MemoryToIceAdapter& iceMemory); + ~Segment() override; + + + // void onConnect(const RobotUnitInterfacePrx& robotUnitPrx); + + + private: + // RobotUnitInterfacePrx robotUnit; + }; + +} // namespace armarx::armem::server::robot_state::exteroception diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ArmarDEConverter.cpp b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ArmarDEConverter.cpp new file mode 100644 index 000000000..d71bb045b --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ArmarDEConverter.cpp @@ -0,0 +1,130 @@ +#include "ArmarDEConverter.h" +#include <cmath> +#include <string> + +#include <SimoxUtility/algorithm/get_map_keys_values.h> +#include <SimoxUtility/algorithm/advanced.h> +#include "ArmarXCore/core/exceptions/local/ExpressionException.h" + +#include <RobotAPI/libraries/RobotUnitDataStreamingReceiver/RobotUnitDataStreamingReceiver.h> +#include <RobotAPI/libraries/armem_robot_state/aron/Exteroception.aron.generated.h> +#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> + +#include <RobotAPI/libraries/armem_robot_state/server/proprioception/aron_conversions.h> + +#include "ConverterTools.h" + + +namespace armarx::armem::server::robot_state::exteroception +{ + + ArmarDEConverter::ArmarDEConverter() = default; + ArmarDEConverter::~ArmarDEConverter() = default; + + + aron::data::DictPtr + ArmarDEConverter::convert( + const RobotUnitDataStreaming::TimeStep& data, + const RobotUnitDataStreaming::DataStreamingDescription& description) + { + arondto::Exteroception dto; + dto.iterationID = data.iterationId; + + for (const auto& [dataEntryName, dataEntry] : description.entries) + { + process(dto, dataEntryName, {data, dataEntry}); + } + + // resize to square + for(auto& [_, tof] : dto.tof) + { + const int sr = std::sqrt(tof.array.size()); + const bool isSquare = (sr * sr == tof.array.size()); + + if(tof.array.size() > 0 and isSquare) + { + tof.array.resize(sr, sr); + } + } + + + return dto.toAron(); + } + + + void ArmarDEConverter::process( + arondto::Exteroception& dto, + const std::string& entryName, + const ConverterValue& value) + { + const std::vector<std::string> split = simox::alg::split(entryName, ".", false, false); + ARMARX_CHECK_GREATER_EQUAL(split.size(), 3); + const std::set<size_t> acceptedSizes{3, 4, 5}; + ARMARX_CHECK_GREATER(acceptedSizes.count(split.size()), 0) + << "Data entry name could not be parsed (exected 3 or 4 or 5 components between '.'): " + << "\n- split: '" << split << "'"; + + const std::string& category = split.at(0); + // const std::string& name = split.at(1); + const std::string& field = split.at(2); + ARMARX_CHECK_EQUAL(category, "sens") << category << " | " << entryName; + + if (simox::alg::contains(field, "tofDepth")) + { + // ARMARX_DEBUG << "Processing ToF sensor data"; + processToFEntry(dto.tof, split, value); + } + + } + + + + + void ArmarDEConverter::processToFEntry( + std::map<std::string, armarx::armem::exteroception::arondto::ToF>& tofs, + const std::vector<std::string>& split, + const ConverterValue& value) + { + // split e.g. "sens.LeftHand.tofDepth.element_15" (split at dot) + + ARMARX_CHECK_EQUAL(split.size(), 4); + ARMARX_CHECK_EQUAL(split.at(2), "tofDepth"); + + const std::string& name = split.at(1); + + // element 0 sens + // element 1 is either LeftHand or RightHand + + const std::map<std::string, std::string> sidePrefixMap + { + {"LeftHand", "Left"}, + {"RightHand", "Right"} + }; + + auto it = sidePrefixMap.find(name); + ARMARX_CHECK(it != sidePrefixMap.end()) << name; + + const std::string& side = it->second; + processToFEntry(tofs[side], split, value); + } + + void ArmarDEConverter::processToFEntry(armarx::armem::exteroception::arondto::ToF& tof, + const std::vector<std::string>& split, + const ConverterValue& value) + { + // split, e.g., element_12 + const std::vector<std::string> elements = simox::alg::split(split.back(), "_"); + ARMARX_CHECK_EQUAL(elements.size(), 2); + + const int idx = std::stoi(elements.at(1)); + + if(tof.array.size() < (idx +1)) + { + tof.array.resize(idx+1, 1); + } + + tof.array(idx) = getValueAs<float>(value); + } + + +} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ArmarDEConverter.h b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ArmarDEConverter.h new file mode 100644 index 000000000..bf6c482a0 --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ArmarDEConverter.h @@ -0,0 +1,51 @@ +#pragma once + +#include <map> +#include <string> + +#include <Eigen/Core> + +#include <RobotAPI/libraries/armem_robot_state/aron/Exteroception.aron.generated.h> + +#include "ConverterInterface.h" + + +namespace armarx::armem::server::robot_state::exteroception +{ + struct ConverterValue; + // class ConverterTools; + + + class ArmarDEConverter : public ConverterInterface + { + public: + ArmarDEConverter(); + ~ArmarDEConverter() override; + + + aron::data::DictPtr + convert(const RobotUnitDataStreaming::TimeStep& data, + const RobotUnitDataStreaming::DataStreamingDescription& description) override; + + + protected: + void process(arondto::Exteroception& dtoExteroception, + const std::string& entryName, + const ConverterValue& value); + + + private: + + + void processToFEntry(std::map<std::string, armarx::armem::exteroception::arondto::ToF>& fts, + const std::vector<std::string>& split, + const ConverterValue& value); + + void processToFEntry(armarx::armem::exteroception::arondto::ToF& tof, + const std::vector<std::string>& split, + const ConverterValue& value); + + + // std::unique_ptr<ConverterTools> tools; + }; +} // namespace armarx::armem::server::robot_state::exteroception diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterInterface.cpp b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterInterface.cpp new file mode 100644 index 000000000..4ba33e6c5 --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterInterface.cpp @@ -0,0 +1,11 @@ +#include "ConverterInterface.h" + + +namespace armarx::armem::server::robot_state::exteroception +{ + + ConverterInterface::~ConverterInterface() + { + } + +} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterInterface.h b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterInterface.h new file mode 100644 index 000000000..5ba0ecc3c --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterInterface.h @@ -0,0 +1,32 @@ +#pragma once + +#include <memory> + +#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> + +namespace armarx::RobotUnitDataStreaming +{ + struct TimeStep; + struct DataStreamingDescription; + struct DataEntry; +} +namespace armarx::armem::arondto +{ + class Proprioception; +} + +namespace armarx::armem::server::robot_state::exteroception +{ + class ConverterInterface + { + public: + + virtual ~ConverterInterface(); + + virtual + aron::data::DictPtr convert( + const RobotUnitDataStreaming::TimeStep& data, + const RobotUnitDataStreaming::DataStreamingDescription& description) = 0; + + }; +} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterRegistry.cpp b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterRegistry.cpp new file mode 100644 index 000000000..ef7296b66 --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterRegistry.cpp @@ -0,0 +1,31 @@ +#include "ConverterRegistry.h" + +#include "ArmarDEConverter.h" + +#include <SimoxUtility/algorithm/get_map_keys_values.h> + + +namespace armarx::armem::server::robot_state::exteroception +{ + + ConverterRegistry::ConverterRegistry() + { + add<ArmarDEConverter>("ArmarDE"); + // add<Armar7Converter>("Armar7"); + } + + + ConverterInterface* + ConverterRegistry::get(const std::string& key) const + { + auto it = converters.find(key); + return it != converters.end() ? it->second.get() : nullptr; + } + + + std::vector<std::string> ConverterRegistry::getKeys() const + { + return simox::alg::get_keys(converters); + } + +} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterRegistry.h b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterRegistry.h new file mode 100644 index 000000000..1e1cac9a1 --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterRegistry.h @@ -0,0 +1,36 @@ +#pragma once + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "ConverterInterface.h" + + +namespace armarx::armem::server::robot_state::exteroception +{ + class ConverterRegistry + { + public: + + ConverterRegistry(); + + + template <class ConverterT, class ...Args> + void add(const std::string& key, Args... args) + { + converters[key].reset(new ConverterT(args...)); + } + + + ConverterInterface* get(const std::string& key) const; + std::vector<std::string> getKeys() const; + + + private: + + std::map<std::string, std::unique_ptr<ConverterInterface>> converters; + + }; +} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterTools.cpp b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterTools.cpp new file mode 100644 index 000000000..6086a9aee --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterTools.cpp @@ -0,0 +1,179 @@ +#include "ConverterTools.h" + +#include <SimoxUtility/algorithm/get_map_keys_values.h> +#include <SimoxUtility/algorithm/advanced.h> + +#include <RobotAPI/libraries/RobotUnitDataStreamingReceiver/RobotUnitDataStreamingReceiver.h> +#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> + + +namespace armarx::armem::server::robot_state +{ + + std::optional<std::string> + exteroception::findByPrefix(const std::string& key, const std::set<std::string>& prefixes) + { + for (const auto& prefix : prefixes) + { + if (simox::alg::starts_with(key, prefix)) + { + return prefix; + } + } + return std::nullopt; + } +} + + +namespace armarx::armem::server::robot_state::exteroception +{ + ConverterTools::ConverterTools() + { + { + vector3fSetters["X"] = [](Eigen::Vector3f & v, float f) + { + v.x() = f; + }; + vector3fSetters["Y"] = [](Eigen::Vector3f & v, float f) + { + v.y() = f; + }; + vector3fSetters["Z"] = [](Eigen::Vector3f & v, float f) + { + v.z() = f; + }; + vector3fSetters["x"] = vector3fSetters["X"]; + vector3fSetters["y"] = vector3fSetters["Y"]; + vector3fSetters["z"] = vector3fSetters["Z"]; + vector3fSetters["Rotation"] = vector3fSetters["Z"]; + } + { + platformPoseGetters["acceleration"] = [](prop::arondto::Platform & p) + { + return &p.acceleration; + }; + platformPoseGetters["relativePosition"] = [](prop::arondto::Platform & p) + { + return &p.relativePosition; + }; + platformPoseGetters["velocity"] = [](prop::arondto::Platform & p) + { + return &p.velocity; + }; + platformIgnored.insert("absolutePosition"); + } + { + ftGetters["gravCompF"] = [](prop::arondto::ForceTorque & ft) + { + return &ft.gravityCompensationForce; + }; + ftGetters["gravCompT"] = [](prop::arondto::ForceTorque & ft) + { + return &ft.gravityCompensationTorque; + }; + ftGetters["f"] = [](prop::arondto::ForceTorque & ft) + { + return &ft.force; + }; + ftGetters["t"] = [](prop::arondto::ForceTorque & ft) + { + return &ft.torque; + }; + } + { + jointGetters["acceleration"] = [](prop::arondto::Joints & j) + { + return &j.acceleration; + }; + jointGetters["gravityTorque"] = [](prop::arondto::Joints & j) + { + return &j.gravityTorque; + }; + jointGetters["inertiaTorque"] = [](prop::arondto::Joints & j) + { + return &j.inertiaTorque; + }; + jointGetters["inverseDynamicsTorque"] = [](prop::arondto::Joints & j) + { + return &j.inverseDynamicsTorque; + }; + jointGetters["position"] = [](prop::arondto::Joints & j) + { + return &j.position; + }; + jointGetters["torque"] = [](prop::arondto::Joints & j) + { + return &j.torque; + }; + jointGetters["velocity"] = [](prop::arondto::Joints & j) + { + return &j.velocity; + }; + } + { + +#define ADD_SCALAR_SETTER(container, name, type) \ + container [ #name ] = []( \ + prop::arondto::Joints & dto, \ + const std::vector<std::string>& split, \ + const ConverterValue & value) \ + { \ + dto. name [split.at(1)] = getValueAs< type >(value); \ + } + + ADD_SCALAR_SETTER(jointSetters, position, float); + ADD_SCALAR_SETTER(jointSetters, velocity, float); + ADD_SCALAR_SETTER(jointSetters, acceleration, float); + + ADD_SCALAR_SETTER(jointSetters, relativePosition, float); + ADD_SCALAR_SETTER(jointSetters, filteredVelocity, float); + + ADD_SCALAR_SETTER(jointSetters, currentTarget, float); + ADD_SCALAR_SETTER(jointSetters, positionTarget, float); + ADD_SCALAR_SETTER(jointSetters, velocityTarget, float); + + ADD_SCALAR_SETTER(jointSetters, torque, float); + ADD_SCALAR_SETTER(jointSetters, inertiaTorque, float); + ADD_SCALAR_SETTER(jointSetters, gravityTorque, float); + ADD_SCALAR_SETTER(jointSetters, gravityCompensatedTorque, float); + ADD_SCALAR_SETTER(jointSetters, inverseDynamicsTorque, float); + ADD_SCALAR_SETTER(jointSetters, torqueTicks, int); + + ADD_SCALAR_SETTER(jointSetters, positionTarget, float); + ADD_SCALAR_SETTER(jointSetters, currentTarget, float); + ADD_SCALAR_SETTER(jointSetters, positionTarget, float); + + // "temperature" handled below + // ADD_SCALAR_SETTER(jointSetters, temperature, float); + + ADD_SCALAR_SETTER(jointSetters, motorCurrent, float); + ADD_SCALAR_SETTER(jointSetters, maxTargetCurrent, float); + + ADD_SCALAR_SETTER(jointSetters, sensorBoardUpdateRate, float); + ADD_SCALAR_SETTER(jointSetters, I2CUpdateRate, float); + + ADD_SCALAR_SETTER(jointSetters, JointStatusEmergencyStop, bool); + ADD_SCALAR_SETTER(jointSetters, JointStatusEnabled, bool); + ADD_SCALAR_SETTER(jointSetters, JointStatusError, int); + ADD_SCALAR_SETTER(jointSetters, JointStatusOperation, int); + + +#define ADD_VECTOR3_SETTER(container, name, type) \ + container [ #name ] = [this]( \ + prop::arondto::Joints & dto, \ + const std::vector<std::string>& split, \ + const ConverterValue & value) \ + { \ + auto& vec = dto. name [split.at(1)]; \ + auto& setter = this->vector3fSetters.at(split.at(3)); \ + setter(vec, getValueAs< type >(value)); \ + } + + ADD_VECTOR3_SETTER(jointSetters, angularVelocity, float); + ADD_VECTOR3_SETTER(jointSetters, linearAcceleration, float); + + // ADD_GETTER(jointVectorGetters, orientation, float); + } + } + +} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterTools.h b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterTools.h new file mode 100644 index 000000000..7460ebb13 --- /dev/null +++ b/source/RobotAPI/libraries/armem_robot_state/server/exteroception/converters/ConverterTools.h @@ -0,0 +1,106 @@ +#pragma once + +#include <map> +#include <set> +#include <string> + +#include <Eigen/Core> + +#include <SimoxUtility/algorithm/string/string_tools.h> + +#include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h> +#include <RobotAPI/libraries/RobotUnitDataStreamingReceiver/RobotUnitDataStreamingReceiver.h> + +#include "ConverterInterface.h" + + +namespace armarx::armem::server::robot_state::exteroception +{ + + struct ConverterValue + { + const RobotUnitDataStreaming::TimeStep& data; + const RobotUnitDataStreaming::DataEntry& entry; + }; + + + template <class T> + T + getValueAs(const ConverterValue& value) + { + return RobotUnitDataStreamingReceiver::GetAs<T>(value.data, value.entry); + } + + + /** + * @brief Search + * @param key + * @param prefixes + * @return + */ + std::optional<std::string> + findByPrefix(const std::string& key, const std::set<std::string>& prefixes); + + + template <class ValueT> + ValueT + findByPrefix(const std::string& key, const std::map<std::string, ValueT>& map) + { + for (const auto& [prefix, value] : map) + { + if (simox::alg::starts_with(key, prefix)) + { + return value; + } + } + return nullptr; + } + + + template <class ValueT> + ValueT + findBySuffix(const std::string& key, const std::map<std::string, ValueT>& map) + { + for (const auto& [suffix, value] : map) + { + if (simox::alg::ends_with(key, suffix)) + { + return value; + } + } + return nullptr; + } + + + + class ConverterTools + { + public: + + ConverterTools(); + + + public: + + std::map<std::string, std::function<void(Eigen::Vector3f&, float)> > vector3fSetters; + + std::map<std::string, std::function<std::map<std::string, float>*(prop::arondto::Joints&)> > jointGetters; + std::map<std::string, std::function<std::map<std::string, Eigen::Vector3f>*(prop::arondto::Joints&)> > jointVectorGetters; + + using JointSetter = std::function<void(prop::arondto::Joints& dto, const std::vector<std::string>& split, const ConverterValue& value)>; + std::map<std::string, JointSetter> jointSetters; + + std::map<std::string, std::function<Eigen::Vector3f*(prop::arondto::Platform&)> > platformPoseGetters; + std::set<std::string> platformIgnored; + + std::map<std::string, std::function<Eigen::Vector3f*(prop::arondto::ForceTorque&)> > ftGetters; + + + std::map<std::string, std::string> sidePrefixMap + { + { "R", "Right" }, + { "L", "Left" }, + }; + + }; +} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotStateWriter.cpp b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotStateWriter.cpp index 52de49d14..cf1a5a8ab 100644 --- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotStateWriter.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotStateWriter.cpp @@ -87,8 +87,9 @@ namespace armarx::armem::server::robot_state::proprioception // Commits lock the core segments. - // Proprioception - armem::CommitResult result = memory.commitLocking(update.proprioception); + // Proprioception + Exteroception + armem::CommitResult resultProprioception = memory.commitLocking(update.proprioception); + armem::CommitResult resultExteroception = memory.commitLocking(update.exteroception); endProprioception = std::chrono::high_resolution_clock::now(); // Localization @@ -100,11 +101,18 @@ namespace armarx::armem::server::robot_state::proprioception } endLocalization = std::chrono::high_resolution_clock::now(); - if (not result.allSuccess()) + if (not resultProprioception.allSuccess()) { - ARMARX_WARNING << "Could not commit data to memory. Error message: " - << result.allErrorMessages(); + ARMARX_WARNING << "Could not commit data to proprioception segment in memory. Error message: " + << resultProprioception.allErrorMessages(); } + + if (not resultExteroception.allSuccess()) + { + ARMARX_WARNING << "Could not commit data to exteroception segment in memory. Error message: " + << resultExteroception.allErrorMessages(); + } + if (debugObserver) { auto end = std::chrono::high_resolution_clock::now(); @@ -151,6 +159,15 @@ namespace armarx::armem::server::robot_state::proprioception up.instancesData = {data.proprioception}; } + // Exteroception + { + armem::EntityUpdate& up = update.exteroception.add(); + up.entityID = properties.robotUnitProviderID.withEntityName( + properties.robotUnitProviderID.providerSegmentName); + up.timeCreated = data.timestamp; + up.instancesData = {data.exteroception}; + } + // Extract odometry data. const std::string platformKey = "platform"; if (data.proprioception->hasElement(platformKey)) diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotStateWriter.h b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotStateWriter.h index f911d43fc..78863697a 100644 --- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotStateWriter.h +++ b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotStateWriter.h @@ -71,6 +71,7 @@ namespace armarx::armem::server::robot_state::proprioception struct Update { armem::Commit proprioception; + armem::Commit exteroception; std::vector<armem::robot_state::Transform> localization; }; Update buildUpdate(const RobotUnitData& dataQueue); diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitData.h b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitData.h index f62d0b0c9..8d904f249 100644 --- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitData.h +++ b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitData.h @@ -14,6 +14,7 @@ namespace armarx::armem::server::robot_state::proprioception { Time timestamp; aron::data::DictPtr proprioception; + aron::data::DictPtr exteroception; }; using Queue = boost::sync_queue<RobotUnitData>; diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.cpp b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.cpp index c74f355c2..e2107e09a 100644 --- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.cpp @@ -24,8 +24,8 @@ namespace armarx::armem::server::robot_state::proprioception const std::string& robotTypeName) { { - converter = converterRegistry.get(robotTypeName); - ARMARX_CHECK_NOT_NULL(converter) + converterProprioception = converterRegistry.get(robotTypeName); + ARMARX_CHECK_NOT_NULL(converterProprioception) << "No converter for robot type '" << robotTypeName << "' available. \n" << "Known are: " << converterRegistry.getKeys(); @@ -67,7 +67,7 @@ namespace armarx::armem::server::robot_state::proprioception std::optional<RobotUnitData> RobotUnitReader::fetchAndConvertLatestRobotUnitData() { - ARMARX_CHECK_NOT_NULL(converter); + ARMARX_CHECK_NOT_NULL(converterProprioception); const std::optional<RobotUnitDataStreaming::TimeStep> data = fetchLatestData(); if (not data.has_value()) @@ -79,7 +79,17 @@ namespace armarx::armem::server::robot_state::proprioception auto start = std::chrono::high_resolution_clock::now(); RobotUnitData result; - result.proprioception = converter->convert(data.value(), description); + + if(converterProprioception != nullptr) + { + result.proprioception = converterProprioception->convert(data.value(), description); + } + + if(converterExteroception != nullptr) + { + result.exteroception = converterExteroception->convert(data.value(), description); + } + result.timestamp = Time(Duration::MicroSeconds(data->timestampUSec)); auto stop = std::chrono::high_resolution_clock::now(); diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.h b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.h index cc3cd2758..7dd485b90 100644 --- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.h +++ b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/RobotUnitReader.h @@ -15,7 +15,9 @@ #include "RobotUnitData.h" #include "converters/ConverterInterface.h" +#include "../exteroception/converters/ConverterInterface.h" #include "converters/ConverterRegistry.h" +#include "../exteroception/converters/ConverterRegistry.h" namespace armarx::plugins @@ -28,6 +30,8 @@ namespace armarx using RobotUnitDataStreamingReceiverPtr = std::shared_ptr<class RobotUnitDataStreamingReceiver>; } + +// TODO move this out of proprioception. it is now for proprioception and exteroception namespace armarx::armem::server::robot_state::proprioception { class RobotUnitReader : public armarx::Logging @@ -69,7 +73,8 @@ namespace armarx::armem::server::robot_state::proprioception RobotUnitDataStreaming::DataStreamingDescription description; ConverterRegistry converterRegistry; - ConverterInterface* converter = nullptr; + proprioception::ConverterInterface* converterProprioception = nullptr; + exteroception::ConverterInterface* converterExteroception = nullptr; armarx::SimpleRunningTask<>::pointer_type task = nullptr; }; diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ArmarDEConverter.cpp b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ArmarDEConverter.cpp deleted file mode 100644 index a4ac7a8c3..000000000 --- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ArmarDEConverter.cpp +++ /dev/null @@ -1,296 +0,0 @@ -#include "ArmarDEConverter.h" -#include <cmath> -#include <string> - -#include <SimoxUtility/algorithm/get_map_keys_values.h> -#include <SimoxUtility/algorithm/advanced.h> -#include "ArmarXCore/core/exceptions/local/ExpressionException.h" - -#include <RobotAPI/libraries/RobotUnitDataStreamingReceiver/RobotUnitDataStreamingReceiver.h> -#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> - -#include <RobotAPI/libraries/armem_robot_state/server/proprioception/aron_conversions.h> - -#include "ConverterTools.h" - - -namespace armarx::armem::server::robot_state::proprioception -{ - - ArmarDEConverter::ArmarDEConverter() : - tools(std::make_unique<ConverterTools>()) - { - } - - - ArmarDEConverter::~ArmarDEConverter() - { - } - - - aron::data::DictPtr - ArmarDEConverter::convert( - const RobotUnitDataStreaming::TimeStep& data, - const RobotUnitDataStreaming::DataStreamingDescription& description) - { - arondto::Proprioception dto; - dto.iterationID = data.iterationId; - - for (const auto& [dataEntryName, dataEntry] : description.entries) - { - process(dto, dataEntryName, {data, dataEntry}); - } - - // resize to square - for(auto& [_, tof] : dto.tof) - { - const int sr = std::sqrt(tof.array.size()); - const bool isSquare = (sr * sr == tof.array.size()); - - if(tof.array.size() > 0 and isSquare) - { - tof.array.resize(sr, sr); - } - } - - - return dto.toAron(); - } - - - void ArmarDEConverter::process( - arondto::Proprioception& dto, - const std::string& entryName, - const ConverterValue& value) - { - const std::vector<std::string> split = simox::alg::split(entryName, ".", false, false); - ARMARX_CHECK_GREATER_EQUAL(split.size(), 3); - const std::set<size_t> acceptedSizes{3, 4, 5}; - ARMARX_CHECK_GREATER(acceptedSizes.count(split.size()), 0) - << "Data entry name could not be parsed (exected 3 or 4 or 5 components between '.'): " - << "\n- split: '" << split << "'"; - - const std::string& category = split.at(0); - const std::string& name = split.at(1); - const std::string& field = split.at(2); - ARMARX_CHECK_EQUAL(category, "sens") << category << " | " << entryName; - - if (name == "Platform") - { - // Platform - processPlatformEntry(dto.platform, field, value); - } - else if (simox::alg::starts_with(name, "FT")) - { - // Force Torque - processForceTorqueEntry(dto.forceTorque, split, value); - } - else if (simox::alg::contains(field, "tofDepth")) - { - // ARMARX_DEBUG << "Processing ToF sensor data"; - processToFEntry(dto.tof, split, value); - } - else - { - // Joint - bool processed = processJointEntry(dto.joints, split, value); - if (not processed) - { - // Fallback: Put in extra. - const std::vector<std::string> comps{simox::alg::advanced(split.begin(), 1), split.end()}; - const std::string key = simox::alg::join(comps, "."); - - switch (value.entry.type) - { - case RobotUnitDataStreaming::NodeTypeFloat: - dto.extraFloats[key] = getValueAs<float>(value); - break; - case RobotUnitDataStreaming::NodeTypeLong: - dto.extraLongs[key] = getValueAs<long>(value); - break; - default: - ARMARX_DEBUG << "Cannot handle extra field '" << key << "' of type " - << RobotUnitDataStreaming::DataEntryNames.to_name(value.entry.type); - break; - } - } - } - } - - - - void ArmarDEConverter::processPlatformEntry( - prop::arondto::Platform& dto, - const std::string& fieldName, - const ConverterValue& value) - { - if (findByPrefix(fieldName, tools->platformIgnored)) - { - return; - } - else if (auto getter = findByPrefix(fieldName, tools->platformPoseGetters)) - { - if (Eigen::Vector3f* dst = getter(dto)) - { - if (auto setter = findBySuffix(fieldName, tools->vector3fSetters)) - { - setter(*dst, getValueAs<float>(value)); - } - } - } - else - { - // No setter for this field. Put in extra. - dto.extra[fieldName] = getValueAs<float>(value); - } - } - - - void ArmarDEConverter::processForceTorqueEntry( - std::map<std::string, prop::arondto::ForceTorque>& fts, - const std::vector<std::string>& split, - const ConverterValue& value) - { - const std::string& name = split.at(1); - std::vector<std::string> splitName = simox::alg::split(name, " ", false, false); - ARMARX_CHECK_EQUAL(splitName.size(), 2); - ARMARX_CHECK_EQUAL(splitName.at(0), "FT"); - - auto it = tools->sidePrefixMap.find(splitName.at(1)); - ARMARX_CHECK(it != tools->sidePrefixMap.end()) << splitName.at(1); - - const std::string& side = it->second; - processForceTorqueEntry(fts[side], split, value); - } - - void ArmarDEConverter::processToFEntry( - std::map<std::string, prop::arondto::ToF>& tofs, - const std::vector<std::string>& split, - const ConverterValue& value) - { - // split e.g. "sens.LeftHand.tofDepth.element_15" (split at dot) - - ARMARX_CHECK_EQUAL(split.size(), 4); - ARMARX_CHECK_EQUAL(split.at(2), "tofDepth"); - - const std::string& name = split.at(1); - - // element 0 sens - // element 1 is either LeftHand or RightHand - - const std::map<std::string, std::string> sidePrefixMap - { - {"LeftHand", "Left"}, - {"RightHand", "Right"} - }; - - auto it = sidePrefixMap.find(name); - ARMARX_CHECK(it != sidePrefixMap.end()) << name; - - const std::string& side = it->second; - processToFEntry(tofs[side], split, value); - } - - void ArmarDEConverter::processToFEntry(prop::arondto::ToF& tof, - const std::vector<std::string>& split, - const ConverterValue& value) - { - // split, e.g., element_12 - const std::vector<std::string> elements = simox::alg::split(split.back(), "_"); - ARMARX_CHECK_EQUAL(elements.size(), 2); - - const int idx = std::stoi(elements.at(1)); - - if(tof.array.size() < (idx +1)) - { - tof.array.resize(idx+1, 1); - } - - tof.array(idx) = getValueAs<float>(value); - } - - - void ArmarDEConverter::processForceTorqueEntry( - prop::arondto::ForceTorque& dto, - const std::vector<std::string>& split, - const ConverterValue& value) - { - const std::string& fieldName = split.at(2); - if (auto getter = findByPrefix(fieldName, tools->ftGetters)) - { - if (Eigen::Vector3f* dst = getter(dto)) - { - if (auto setter = findBySuffix(fieldName, tools->vector3fSetters)) - { - setter(*dst, getValueAs<float>(value)); - } - } - } - else - { - // No setter for this field. Put in extra. - std::string key = split.size() == 4 - ? (fieldName + "." + split.at(3)) - : fieldName; - - switch (value.entry.type) - { - case RobotUnitDataStreaming::NodeTypeFloat: - dto.extra[key] = getValueAs<float>(value); - break; - case RobotUnitDataStreaming::NodeTypeInt: - dto.extra[key] = getValueAs<int>(value); - break; - case RobotUnitDataStreaming::NodeTypeLong: - dto.extra[key] = getValueAs<long>(value); - break; - default: - ARMARX_DEBUG << "Cannot handle extra field '" << key << "' of type " - << RobotUnitDataStreaming::DataEntryNames.to_name(value.entry.type); - break; - } - } - } - - - bool ArmarDEConverter::processJointEntry( - prop::arondto::Joints& dto, - const std::vector<std::string>& split, - const ConverterValue& value) - { - const std::string& jointName = split.at(1); - const std::string& fieldName = split.at(2); - if (false) - { - // Only in simulation. - if (auto getter = findByPrefix(fieldName, tools->jointGetters)) - { - if (std::map<std::string, float>* map = getter(dto)) - { - (*map)[jointName] = getValueAs<float>(value); - } - } - } - - const std::string tempSuffix = "Temperature"; - if (simox::alg::ends_with(split.at(2), tempSuffix)) - { - // Handle "dieTemperature" etc - const std::string name = split.at(2).substr(0, split.at(2).size() - tempSuffix.size()); - dto.temperature[split.at(1)][name] = getValueAs<float>(value); - return true; - } - else if (auto it = tools->jointSetters.find(fieldName); it != tools->jointSetters.end()) - { - const ConverterTools::JointSetter& setter = it->second; - setter(dto, split, value); - return true; - } - else - { - // ARMARX_DEBUG << "Ignoring unhandled field: '" << simox::alg::join(split, ".") << "'"; - return false; - } - } - -} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ArmarDEConverter.h b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ArmarDEConverter.h deleted file mode 100644 index 6f5c28715..000000000 --- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ArmarDEConverter.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include <map> -#include <string> - -#include <Eigen/Core> - -#include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h> - -#include "ConverterInterface.h" - - - -namespace armarx::armem::server::robot_state::proprioception -{ - struct ConverterValue; - class ConverterTools; - - - class ArmarDEConverter : public ConverterInterface - { - public: - - ArmarDEConverter(); - virtual ~ArmarDEConverter() override; - - - aron::data::DictPtr - convert( - const RobotUnitDataStreaming::TimeStep& data, - const RobotUnitDataStreaming::DataStreamingDescription& description) override; - - - protected: - - void process(arondto::Proprioception& dto, const std::string& entryName, const ConverterValue& value); - - - - private: - - void processPlatformEntry( - prop::arondto::Platform& dto, - const std::string& fieldName, - const ConverterValue& value); - - void processForceTorqueEntry( - std::map<std::string, prop::arondto::ForceTorque>& fts, - const std::vector<std::string>& split, - const ConverterValue& value); - - void processForceTorqueEntry( - prop::arondto::ForceTorque& ft, - const std::vector<std::string>& split, - const ConverterValue& value); - - void processToFEntry( - std::map<std::string, prop::arondto::ToF>& fts, - const std::vector<std::string>& split, - const ConverterValue& value); - - void processToFEntry( - prop::arondto::ToF& tof, - const std::vector<std::string>& split, - const ConverterValue& value); - - bool processJointEntry( - prop::arondto::Joints& dto, - const std::vector<std::string>& split, - const ConverterValue& value); - - - private: - - std::unique_ptr<ConverterTools> tools; - - }; -} diff --git a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ConverterRegistry.cpp b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ConverterRegistry.cpp index 48ea15375..0c6baa3b7 100644 --- a/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ConverterRegistry.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/server/proprioception/converters/ConverterRegistry.cpp @@ -1,7 +1,6 @@ #include "ConverterRegistry.h" #include "Armar6Converter.h" -#include "ArmarDEConverter.h" #include <SimoxUtility/algorithm/get_map_keys_values.h> @@ -12,7 +11,7 @@ namespace armarx::armem::server::robot_state::proprioception ConverterRegistry::ConverterRegistry() { add<Armar6Converter>("Armar6"); - add<ArmarDEConverter>("ArmarDE"); + add<Armar6Converter>("ArmarDE"); add<Armar6Converter>("Armar7"); } -- GitLab