From 52b8c46d7708b4b97cd885e45b6ded007c8b0b45 Mon Sep 17 00:00:00 2001 From: Rainer Kartmann <rainer.kartmann@kit.edu> Date: Thu, 29 Jul 2021 12:25:53 +0200 Subject: [PATCH] Add RobotUnitConverter base class and Armar6 version --- .../Armar6RobotUnitConverter.cpp | 252 ++++++++++++++++++ .../Armar6RobotUnitConverter.h | 70 +++++ .../server/RobotStateMemory/CMakeLists.txt | 6 + .../RobotUnitConverterInterface.cpp | 12 + .../RobotUnitConverterInterface.h | 29 ++ 5 files changed, 369 insertions(+) create mode 100644 source/RobotAPI/components/armem/server/RobotStateMemory/Armar6RobotUnitConverter.cpp create mode 100644 source/RobotAPI/components/armem/server/RobotStateMemory/Armar6RobotUnitConverter.h create mode 100644 source/RobotAPI/components/armem/server/RobotStateMemory/RobotUnitConverterInterface.cpp create mode 100644 source/RobotAPI/components/armem/server/RobotStateMemory/RobotUnitConverterInterface.h diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/Armar6RobotUnitConverter.cpp b/source/RobotAPI/components/armem/server/RobotStateMemory/Armar6RobotUnitConverter.cpp new file mode 100644 index 000000000..d85e38be8 --- /dev/null +++ b/source/RobotAPI/components/armem/server/RobotStateMemory/Armar6RobotUnitConverter.cpp @@ -0,0 +1,252 @@ +#include "Armar6RobotUnitConverter.h" + +#include <RobotAPI/libraries/RobotUnitDataStreamingReceiver/RobotUnitDataStreamingReceiver.h> + + +namespace armarx::armem::server::robot_state +{ + + Armar6RobotUnitConverter::Armar6RobotUnitConverter() + { + { + 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["absolutePosition"] = [](prop::arondto::Platform & p) + { + return &p.absolutePosition; + }; + platformPoseGetters["relativePosition"] = [](prop::arondto::Platform & p) + { + return &p.relativePosition; + }; + platformPoseGetters["velocity"] = [](prop::arondto::Platform & p) + { + return &p.velocity; + }; + } + { + 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.accellerations; + }; + jointGetters["gravityTorque"] = [](prop::arondto::Joints & j) + { + return &j.gravityTorques; + }; + jointGetters["inertiaTorque"] = [](prop::arondto::Joints & j) + { + return &j.inertiaTorques; + }; + jointGetters["inverseDynamicsTorque"] = [](prop::arondto::Joints & j) + { + return &j.inverseDynamicsTorques; + }; + jointGetters["position"] = [](prop::arondto::Joints & j) + { + return &j.positions; + }; + jointGetters["torque"] = [](prop::arondto::Joints & j) + { + return &j.torques; + }; + jointGetters["velocity"] = [](prop::arondto::Joints & j) + { + return &j.velocities; + }; + } + } + + + Armar6RobotUnitConverter::~Armar6RobotUnitConverter() + { + } + + + arondto::Proprioception Armar6RobotUnitConverter::convert( + const RobotUnitDataStreaming::TimeStep& data, + const RobotUnitDataStreaming::DataStreamingDescription& description) + { + arondto::Proprioception dto; + dto.iterationID = data.iterationId; + + for (const auto& [dataEntryName, dataEntry] : description.entries) + { + switch (dataEntry.type) + { + case RobotUnitDataStreaming::NodeTypeFloat: + { + const float value = RobotUnitDataStreamingReceiver::GetAs<float>(data, dataEntry); + + const std::vector<std::string> split = simox::alg::split(dataEntryName, ".", false, false); + ARMARX_CHECK_EQUAL(split.size(), 3) << 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 << " | " << dataEntryName; + + if (name == "Platform") + { + // Platform + processPlatformEntry(dto.platform, field, value); + } + else if (simox::alg::starts_with(name, "FT")) + { + // Force Torque + processForceTorqueEntry(dto.forceTorque, name, field, value); + } + else + { + // Joint + processJointEntry(dto.joints, name, field, value); + } + } + break; + + default: + { + ARMARX_DEBUG << "Ignoring non-float entry '" << dataEntryName << "'."; + } + break; + } + } + return dto; + } + + + 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; + } + + + void Armar6RobotUnitConverter::processPlatformEntry( + prop::arondto::Platform& dto, + const std::string& fieldName, + float value) + { + if (auto getter = findByPrefix(fieldName, platformPoseGetters)) + { + if (Eigen::Vector3f* dst = getter(dto)) + { + if (auto setter = findBySuffix(fieldName, vector3fSetters)) + { + setter(*dst, value); + } + } + } + } + + + void Armar6RobotUnitConverter::processForceTorqueEntry( + std::map<std::string, prop::arondto::ForceTorque>& fts, + const std::string& name, + const std::string& fieldName, + float value) + { + std::vector<std::string> split = simox::alg::split(name, " ", false, false); + ARMARX_CHECK_EQUAL(split.size(), 2); + ARMARX_CHECK_EQUAL(split.at(0), "FT"); + + auto it = sidePrefixMap.find(split.at(1)); + ARMARX_CHECK(it != sidePrefixMap.end()) << split.at(1); + + const std::string& side = it->second; + processForceTorqueEntry(fts[side], fieldName, value); + } + + + void Armar6RobotUnitConverter::processForceTorqueEntry( + prop::arondto::ForceTorque& dto, + const std::string& fieldName, + float value) + { + if (auto getter = findByPrefix(fieldName, ftGetters)) + { + if (Eigen::Vector3f* dst = getter(dto)) + { + if (auto setter = findBySuffix(fieldName, vector3fSetters)) + { + setter(*dst, value); + } + } + } + } + + + void Armar6RobotUnitConverter::processJointEntry( + prop::arondto::Joints& dto, + const std::string& name, + const std::string& fieldName, + float value) + { + if (auto getter = findByPrefix(fieldName, jointGetters)) + { + if (std::map<std::string, float>* map = getter(dto)) + { + (*map)[name] = value; + } + } + } + +} diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/Armar6RobotUnitConverter.h b/source/RobotAPI/components/armem/server/RobotStateMemory/Armar6RobotUnitConverter.h new file mode 100644 index 000000000..d365edbe0 --- /dev/null +++ b/source/RobotAPI/components/armem/server/RobotStateMemory/Armar6RobotUnitConverter.h @@ -0,0 +1,70 @@ +#pragma once + +#include <map> +#include <string> + +#include <Eigen/Core> + +#include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h> + +#include "RobotUnitConverterInterface.h" + + +namespace armarx::armem::server::robot_state +{ + + class Armar6RobotUnitConverter : public RobotUnitConverterInterface + { + public: + + Armar6RobotUnitConverter(); + virtual ~Armar6RobotUnitConverter() override; + + + arondto::Proprioception convert( + const RobotUnitDataStreaming::TimeStep& data, + const RobotUnitDataStreaming::DataStreamingDescription& description) override; + + + private: + + void processPlatformEntry( + prop::arondto::Platform& dto, + const std::string& fieldName, + float value); + + void processForceTorqueEntry( + std::map<std::string, prop::arondto::ForceTorque>& fts, + const std::string& name, + const std::string& fieldName, + float value); + + void processForceTorqueEntry( + prop::arondto::ForceTorque& ft, + const std::string& fieldName, + float value); + + void processJointEntry( + prop::arondto::Joints& dto, + const std::string& name, + const std::string& fieldName, + float value); + + + private: + + std::map<std::string, std::function<void(Eigen::Vector3f&, float)> > vector3fSetters; + + std::map<std::string, std::function<Eigen::Vector3f*(prop::arondto::Platform&)> > platformPoseGetters; + std::map<std::string, std::function<Eigen::Vector3f*(prop::arondto::ForceTorque&)> > ftGetters; + std::map<std::string, std::function<std::map<std::string, float>*(prop::arondto::Joints&)> > jointGetters; + + std::map<std::string, std::string> sidePrefixMap + { + { "R", "Right" }, + { "L", "Left" }, + }; + + }; +} + diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/CMakeLists.txt b/source/RobotAPI/components/armem/server/RobotStateMemory/CMakeLists.txt index a25161ff2..e4cfc53a9 100644 --- a/source/RobotAPI/components/armem/server/RobotStateMemory/CMakeLists.txt +++ b/source/RobotAPI/components/armem/server/RobotStateMemory/CMakeLists.txt @@ -20,6 +20,9 @@ set(SOURCES RobotStateWriter.cpp RobotUnitData.cpp RobotUnitReader.cpp + + RobotUnitConverterInterface.cpp + Armar6RobotUnitConverter.cpp ) set(HEADERS aron_conversions.h @@ -27,6 +30,9 @@ set(HEADERS RobotStateWriter.h RobotUnitData.h RobotUnitReader.h + + RobotUnitConverterInterface.h + Armar6RobotUnitConverter.h ) armarx_add_component("${SOURCES}" "${HEADERS}") diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotUnitConverterInterface.cpp b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotUnitConverterInterface.cpp new file mode 100644 index 000000000..b72742bbc --- /dev/null +++ b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotUnitConverterInterface.cpp @@ -0,0 +1,12 @@ +#include "RobotUnitConverterInterface.h" + + +namespace armarx::armem::server::robot_state +{ + + RobotUnitConverterInterface::~RobotUnitConverterInterface() + { + + } + +} diff --git a/source/RobotAPI/components/armem/server/RobotStateMemory/RobotUnitConverterInterface.h b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotUnitConverterInterface.h new file mode 100644 index 000000000..f7ba3fcbf --- /dev/null +++ b/source/RobotAPI/components/armem/server/RobotStateMemory/RobotUnitConverterInterface.h @@ -0,0 +1,29 @@ +#pragma once + + +namespace armarx::RobotUnitDataStreaming +{ + struct TimeStep; + struct DataStreamingDescription; + struct DataEntry; +} +namespace armarx::armem::arondto +{ + class Proprioception; +} + +namespace armarx::armem::server::robot_state +{ + class RobotUnitConverterInterface + { + public: + + virtual ~RobotUnitConverterInterface(); + + virtual arondto::Proprioception convert( + const RobotUnitDataStreaming::TimeStep& data, + const RobotUnitDataStreaming::DataStreamingDescription& description) = 0; + + }; +} + -- GitLab