diff --git a/source/RobotAPI/components/ArViz/Client/Elements.cpp b/source/RobotAPI/components/ArViz/Client/Elements.cpp index f479f4ef5456fc7a88d0f3a0fa87d2e77e9aab66..d97fea3b03d55ddb82a379628197a5f04ffc3d74 100644 --- a/source/RobotAPI/components/ArViz/Client/Elements.cpp +++ b/source/RobotAPI/components/ArViz/Client/Elements.cpp @@ -107,9 +107,9 @@ namespace armarx::viz float angle = std::acos(naturalDir.dot(dir)); if (cross.squaredNorm() < 1.0e-12f) { - // Directions are almost colinear ==> Do no rotation + // Directions are almost colinear ==> Angle is either 0 or 180 deg cross = Eigen::Vector3f::UnitX(); - angle = 0.0f; + // Keep angle } Eigen::Vector3f axis = cross.normalized(); Eigen::Quaternionf ori(Eigen::AngleAxisf(angle, axis)); diff --git a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp index 2c93faf7fa4a464909bd6dea214c74022571474f..e52609fa085feac2dc4ef8fc93f68127aef8b040 100644 --- a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp +++ b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp @@ -275,13 +275,18 @@ namespace armarx void fillExampleLayer(viz::Layer& layer, double timeInSeconds) { + for (int i = 0; i < 6; ++i) { - Eigen::Vector3f pos = Eigen::Vector3f::Zero(); - pos.z() = +300.0f; + Eigen::Vector3f pos = Eigen::Vector3f(-200.0, 200.0, 300); + pos.x() += -300 * i; + + Eigen::Vector3f normal = Eigen::Vector3f::Zero(); + normal(i / 2) = (i % 2 == 0 ? 1.0 : -1.0); - viz::ArrowCircle circle = viz::ArrowCircle("circle") + viz::ArrowCircle circle = viz::ArrowCircle("circle " + std::to_string(i)) .position(pos) .radius(100.0f) + .normal(normal) .width(10.0f) .color(viz::Color::fromRGBA(255, 0, 255)); diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt b/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt index d62a96eddf76d69b562c196d487354d81607c116..b40d5a2fcf9c480a71f0576d049ad0a311813815 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/CMakeLists.txt @@ -19,6 +19,10 @@ set(SOURCES aronTreeWidget/AronTreeWidgetItem.cpp aronTreeWidget/AronTreeWidgetController.cpp aronTreeWidget/modal/text/AronTreeWidgetTextInputModalController.cpp + aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp + aronTreeWidget/modal/float_double/AronTreeWidgetFloatInputModalController.cpp + aronTreeWidget/modal/int_long/AronTreeWidgetIntInputModalController.cpp + aronTreeWidget/modal/bool/AronTreeWidgetBoolInputModalController.cpp aronTreeWidget/modal/AronTreeWidgetModal.cpp ColorPalettes.cpp SkillManagerMonitorWidgetController.cpp @@ -41,6 +45,10 @@ set(HEADERS aronTreeWidget/AronTreeWidgetController.h aronTreeWidget/modal/AronTreeWidgetModal.h aronTreeWidget/modal/text/AronTreeWidgetTextInputModalController.h + aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.h + aronTreeWidget/modal/float_double/AronTreeWidgetFloatInputModalController.h + aronTreeWidget/modal/int_long/AronTreeWidgetIntInputModalController.h + aronTreeWidget/modal/bool/AronTreeWidgetBoolInputModalController.h ColorPalettes.h SkillManagerMonitorWidgetController.h ) diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp index 0e96cb6245384234e01f6d312866495f619e51f8..71a88e54fcf49d77ea5de6804ef06a11e90e6ae8 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/modal/dict/AronTreeWidgetDictInputModalController.cpp @@ -30,7 +30,7 @@ namespace armarx { for (const auto& added : addedItems) { - item->addChild(added->copy()); + //item->addChild(added->copy()); } AronTreeWidgetModal::submit(); diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp index bb76232a8adb1dfd78792d24a9eb145f9b78e033..fc58634bb9bc02834d4e72663e3c16ffe36d6de6 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetModalCreator.cpp @@ -28,7 +28,7 @@ // modals #include "../modal/text/AronTreeWidgetTextInputModalController.h" -#include "../modal/dict/AronTreeWidgetDictInputModalController.h" +//#include "../modal/dict/AronTreeWidgetDictInputModalController.h" // qt #include <QTreeWidget> diff --git a/source/RobotAPI/interface/CMakeLists.txt b/source/RobotAPI/interface/CMakeLists.txt index 5d9d3c04b278f8032125f98cf82d63aaa8253155..9e290598fee8047f853044e54ea3775b62ab49f7 100644 --- a/source/RobotAPI/interface/CMakeLists.txt +++ b/source/RobotAPI/interface/CMakeLists.txt @@ -108,6 +108,7 @@ set(SLICE_FILES aron.ice aron/Aron.ice + aron/test/AronConversionTestInterface.ice armem.ice diff --git a/source/RobotAPI/interface/aron/test/AronConversionTestInterface.ice b/source/RobotAPI/interface/aron/test/AronConversionTestInterface.ice new file mode 100644 index 0000000000000000000000000000000000000000..924f40c6d8664123c822eb9f7eb338d8d50b52d5 --- /dev/null +++ b/source/RobotAPI/interface/aron/test/AronConversionTestInterface.ice @@ -0,0 +1,61 @@ +/* + * 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 SpeechX::aron_cpp_to_python_conv_test + * author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * date 2023 + * copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + + +#pragma once + +#include <RobotAPI/interface/aron/Aron.ice> + + +module armarx { module aron { module test +{ + +module dto +{ + + struct TestAronConversionRequest + { + string aronClassName; + ::armarx::aron::data::dto::Dict probe; + }; + struct TestAronConversionResponse + { + bool success; + string errorMessage; + + ::armarx::aron::data::dto::Dict probe; + }; + +}; + + +module dti +{ + + interface AronConversionTestInterface + { + dto::TestAronConversionResponse testAronConversion(dto::TestAronConversionRequest req); + }; + +}; + +};};}; diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.cpp b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.cpp index dbc68923c98f1974c7fbd224f09ad94c625ff6b7..d5318e1f1e6ec9933ddc7e6b50f3894044111917 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.cpp +++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.cpp @@ -34,8 +34,8 @@ namespace armarx::armem::server::ltm return _id.getLeafItem(); } - void MemoryItem::setMemoryName(const std::string& m) + void MemoryItem::setMemoryName(const std::string& memoryName) { - _id.memoryName = m; + _id.memoryName = memoryName; } } // namespace armarx::armem::server::ltm diff --git a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.h b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.h index 586d4d0e51dcb546eaae28d7cbc984893c548ca8..b8d17fe471c17e62aa188406648515e5a32f384a 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.h +++ b/source/RobotAPI/libraries/armem/server/ltm/base/detail/MemoryItem.h @@ -21,7 +21,7 @@ namespace armarx::armem::server::ltm std::string name() const; virtual void setMemoryID(const MemoryID&); - void setMemoryName(const std::string&); + void setMemoryName(const std::string& memoryName); protected: std::shared_ptr<Processors> processors; diff --git a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/util/filesystem_util.cpp b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/util/filesystem_util.cpp index 6b6bfdc1be88e30507e2a5d865b94c44abfb090d..1a40e26a04923bccb123b4b07f00ab9be190efa9 100644 --- a/source/RobotAPI/libraries/armem/server/ltm/disk/detail/util/filesystem_util.cpp +++ b/source/RobotAPI/libraries/armem/server/ltm/disk/detail/util/filesystem_util.cpp @@ -1,5 +1,7 @@ #include "filesystem_util.h" +#include <algorithm> + #include <RobotAPI/libraries/armem/core/error/ArMemError.h> diff --git a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp index 8253755604e04e1d65c4f7a67e6c04857eb52669..b9c789398b0d8ce5c6fb17e0c2cb44fb5bc5b531 100644 --- a/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp +++ b/source/RobotAPI/libraries/armem_gui/MemoryViewer.cpp @@ -267,7 +267,7 @@ namespace armarx::armem::gui { std::stringstream ss; ss << "Memory name '" << memoryName - << "' is unknown. Known are: " << simox::alg::to_string(simox::alg::get_keys(memoryData), ", "); + << "' is unknown. Known are: " << simox::alg::join(simox::alg::get_keys(memoryData), ", "); statusLabel->setText(QString::fromStdString(ss.str())); return nullptr; } @@ -406,10 +406,7 @@ namespace armarx::armem::gui TIMING_START(MemoryExport) std::string status; - std::vector<wm::Memory> memoryDataVec; - std::transform(memoryData.begin(), memoryData.end(), std::back_inserter(memoryDataVec), - [](auto& el) { return el.second; }); - + std::vector<wm::Memory> memoryDataVec = simox::alg::get_values(memoryData); diskControl->storeOnDisk(directory, memoryDataVec, &status); statusLabel->setText(QString::fromStdString(status)); @@ -436,11 +433,11 @@ namespace armarx::armem::gui } else { - ARMARX_INFO << "No memory with name " << name << " available for commit. Create new virtual memory."; + ARMARX_INFO << "No memory with name '" << name << "' available for commit. Create new virtual memory."; // Please note: Here we assume that a memory server with the same name does not exist. // I think this assumption is ok, since nobody should use filepaths as memory name. - // Nontheless, we did not restrict the user to do so... + // Nonetheless, we did not restrict the user to do so... std::string virtualMemoryName = name + " (at " + path.string() + ")"; wm::Memory virtualMemory(virtualMemoryName); virtualMemory.update(commit, true, false); diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp index de7848b7fa00ea312ee99cea77608645e39bd1e7..c17ce69020b2b7f2c363219339754919fc805723 100644 --- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp +++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp @@ -1317,7 +1317,7 @@ namespace armarx::armem::server::obj::instance if (robot) { - reader->synchronizeRobot(*robot, Clock::Now()); + ARMARX_CHECK(reader->synchronizeRobot(*robot, Clock::Now())); // Store robot if valid. loaded.emplace(robotName, robot); } diff --git a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h index 19a184e8c4cee71e2a7866206f2ae55cd51f0d27..ab30cbc1317d98f802dc24cbe5d844da02b038e9 100644 --- a/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h +++ b/source/RobotAPI/libraries/armem_robot_state/client/common/VirtualRobotReader.h @@ -27,7 +27,6 @@ #include "RobotReader.h" - namespace armarx::armem::robot_state { /** @@ -47,7 +46,8 @@ namespace armarx::armem::robot_state void connect(); void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr& def); - bool synchronizeRobot(VirtualRobot::Robot& robot, const armem::Time& timestamp); + [[nodiscard]] bool synchronizeRobot(VirtualRobot::Robot& robot, + const armem::Time& timestamp); [[nodiscard]] VirtualRobot::RobotPtr getRobot(const std::string& name, @@ -70,14 +70,12 @@ namespace armarx::armem::robot_state private: - [[nodiscard]] VirtualRobot::RobotPtr _getSynchronizedRobot(const std::string& name, const armem::Time& timestamp = armem::Time::Invalid(), const VirtualRobot::RobotIO::RobotDescription& loadMode = - VirtualRobot::RobotIO::RobotDescription::eStructure, + VirtualRobot::RobotIO::RobotDescription::eStructure, bool blocking = true); - }; } // namespace armarx::armem::robot_state diff --git a/source/RobotAPI/libraries/aron/CMakeLists.txt b/source/RobotAPI/libraries/aron/CMakeLists.txt index ce4f7bc99cb8d923decfdd7fdb79390837e79150..e1ccc8560ff75b018fbc958d0f1febf0512d9590 100644 --- a/source/RobotAPI/libraries/aron/CMakeLists.txt +++ b/source/RobotAPI/libraries/aron/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(core) add_subdirectory(converter) add_subdirectory(codegeneration) add_subdirectory(common) +add_subdirectory(test) diff --git a/source/RobotAPI/libraries/aron/core/aron_conversions.h b/source/RobotAPI/libraries/aron/core/aron_conversions.h index d0f88cab840be59b86bbeb22d7229afb9f9f0b48..d27d6415877d4c15f9ddf36310e656590f8efd7e 100644 --- a/source/RobotAPI/libraries/aron/core/aron_conversions.h +++ b/source/RobotAPI/libraries/aron/core/aron_conversions.h @@ -3,12 +3,29 @@ #include <map> #include <memory> #include <optional> +#include <type_traits> #include <vector> #include "Path.h" namespace armarx::aron { + +namespace detail +{ + + // Helper concept to avoid ambiguities + template<typename DtoT, typename BoT> + concept DtoAndBoAreSame = std::is_same<DtoT, BoT>::value; + + template <class ...> + struct is_optional : public std::false_type {}; + + template <class ...Ts> + struct is_optional<std::optional<Ts...>> : public std::true_type {}; + +} + /** * Framework for converting ARON DTOs (Data Transfer Objects) to C++ BOs * (Business Objects) and back. @@ -51,12 +68,6 @@ namespace armarx::aron * } * @endcode */ - - // Helper concept to avoid ambiguities - template<typename DtoT, typename BoT> - concept DtoAndBoAreSame = std::is_same<DtoT, BoT>::value; - - // Same type template <class T> void toAron(T& dto, const T& bo) @@ -139,6 +150,24 @@ namespace armarx::aron } } + + // One-sided optional + template <class DtoT, class BoT> + requires (not detail::is_optional<BoT>::value) + void toAron(std::optional<DtoT>& dto, const BoT& bo) + { + dto = DtoT{}; + toAron(*dto, bo); + } + template <class DtoT, class BoT> + requires (not detail::is_optional<DtoT>::value) + void fromAron(DtoT& dto, const std::optional<BoT>& bo) + { + bo = BoT{}; + fromAron(dto, *bo); + } + + // Flag-controlled optional template <class DtoT, class BoT> void toAron(DtoT& dto, bool& dtoValid, const BoT& bo, bool boValid) @@ -154,6 +183,7 @@ namespace armarx::aron } } + template <class DtoT, class BoT> void fromAron(const DtoT& dto, bool dtoValid, BoT& bo, bool& boValid) { @@ -222,7 +252,7 @@ namespace armarx::aron // std::map template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT> - requires (!(DtoAndBoAreSame<DtoKeyT, BoKeyT> and DtoAndBoAreSame<DtoValueT, BoValueT>)) + requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>)) void toAron(std::map<DtoKeyT, DtoValueT>& dtoMap, const std::map<BoKeyT, BoValueT>& boMap) { @@ -236,7 +266,7 @@ namespace armarx::aron } } template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT> - requires (!(DtoAndBoAreSame<DtoKeyT, BoKeyT> and DtoAndBoAreSame<DtoValueT, BoValueT>)) + requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>)) void fromAron(const std::map<DtoKeyT, DtoValueT>& dtoMap, std::map<BoKeyT, BoValueT>& boMap) { @@ -252,7 +282,7 @@ namespace armarx::aron template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT> - requires (!(DtoAndBoAreSame<DtoKeyT, BoKeyT> and DtoAndBoAreSame<DtoValueT, BoValueT>)) + requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>)) std::map<DtoKeyT, DtoValueT> toAron(const std::map<BoKeyT, BoValueT>& boMap) { std::map<DtoKeyT, DtoValueT> dtoMap; @@ -343,20 +373,20 @@ namespace armarx // std::vector template <class DtoT, class BoT> - requires (!aron::DtoAndBoAreSame<DtoT, BoT>) + requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>) void toAron(std::vector<DtoT>& dtos, const std::vector<BoT>& bos) { armarx::aron::toAron(dtos, bos); } template <class DtoT, class BoT> - requires (!aron::DtoAndBoAreSame<DtoT, BoT>) + requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>) void fromAron(const std::vector<DtoT>& dtos, std::vector<BoT>& bos) { armarx::aron::fromAron(dtos, bos); } template <class DtoT, class BoT> - requires (!aron::DtoAndBoAreSame<DtoT, BoT>) + requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>) std::vector<DtoT> toAron(const std::vector<BoT>& bos) { return armarx::aron::toAron<DtoT, BoT>(bos); @@ -365,13 +395,13 @@ namespace armarx // std::map template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT> - requires (!(aron::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::DtoAndBoAreSame<DtoValueT, BoValueT>)) + requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>)) void toAron(std::map<DtoKeyT, DtoValueT>& dtoMap, const std::map<BoKeyT, BoValueT>& boMap) { armarx::aron::toAron(dtoMap, boMap); } template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT> - requires (!(aron::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::DtoAndBoAreSame<DtoValueT, BoValueT>)) + requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>)) void fromAron(const std::map<DtoKeyT, DtoValueT>& dtoMap, std::map<BoKeyT, BoValueT>& boMap) { armarx::aron::fromAron(dtoMap, boMap); @@ -379,7 +409,7 @@ namespace armarx template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT> - requires (!(aron::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::DtoAndBoAreSame<DtoValueT, BoValueT>)) + requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>)) std::map<DtoKeyT, DtoValueT> toAron(const std::map<BoKeyT, BoValueT>& boMap) { armarx::aron::toAron<DtoKeyT, DtoValueT, BoKeyT, BoValueT>(boMap); diff --git a/source/RobotAPI/libraries/aron/core/rw.h b/source/RobotAPI/libraries/aron/core/rw.h index 6257f2422687591b0991afed8a0577ee127207ef..95b6aac606f47d3c46de34ac5ec077ded28c41a4 100644 --- a/source/RobotAPI/libraries/aron/core/rw.h +++ b/source/RobotAPI/libraries/aron/core/rw.h @@ -26,7 +26,7 @@ namespace armarx::aron } template<class ReaderT, class DtoT, class BoT> - requires (data::isReader<ReaderT> && !DtoAndBoAreSame<DtoT, BoT>) + requires (data::isReader<ReaderT> && !detail::DtoAndBoAreSame<DtoT, BoT>) inline void read(ReaderT& aron_r, typename ReaderT::InputType& input, BoT& ret) { DtoT aron; @@ -36,7 +36,7 @@ namespace armarx::aron } template<class WriterT, class DtoT, class BoT> - requires (data::isWriter<WriterT> && !DtoAndBoAreSame<DtoT, BoT>) + requires (data::isWriter<WriterT> && !detail::DtoAndBoAreSame<DtoT, BoT>) inline void write(WriterT& aron_w, const BoT& input, typename WriterT::ReturnType& ret, const armarx::aron::Path& aron_p = armarx::aron::Path()) { DtoT aron; diff --git a/source/RobotAPI/libraries/aron/test/AronConversionTester.cpp b/source/RobotAPI/libraries/aron/test/AronConversionTester.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aac543a04b6ba1696dedc7a21c7d4ea125896e4e --- /dev/null +++ b/source/RobotAPI/libraries/aron/test/AronConversionTester.cpp @@ -0,0 +1,38 @@ +/** + * 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_cpp_to_python_conv_test + * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * @date 2023 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + + +#include "AronConversionTester.h" + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + + +namespace armarx::aron::test +{ + + AronConversionTester::AronConversionTester(dti::AronConversionTestInterfacePrx python) : interface(python) + { + ARMARX_CHECK(python); + } + + +} // namespace armarx::aron::test diff --git a/source/RobotAPI/libraries/aron/test/AronConversionTester.h b/source/RobotAPI/libraries/aron/test/AronConversionTester.h new file mode 100644 index 0000000000000000000000000000000000000000..b7ad4b8dfdcf55a37f8efc3116c27440d925d428 --- /dev/null +++ b/source/RobotAPI/libraries/aron/test/AronConversionTester.h @@ -0,0 +1,111 @@ +/** + * 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_cpp_to_python_conv_test + * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu ) + * @date 2023 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + + +#pragma once + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include <ArmarXCore/core/logging/Logging.h> + +#include <RobotAPI/interface/aron/test/AronConversionTestInterface.h> + + +namespace armarx::aron::test +{ + + /** + * @brief Helper class for implementing distributed ARON conversion tests + * based on the `dti::AronConversionTestInterfacePrx`. + * + * Example usage: + * + * @code + * + * armarx::aron::test::dti::AronConversionTestInterfacePrx pythonComponent = ...; + * + * auto myAronClassProbeFn = []() + * { + * my::arondto::MyAronClass probe; + * probe.data = "42"; + * return probe, + * }; + * + * armarx::aron::test::AronConversionTester tester(pythonComponent); + * + * tester.test<my::arondto::MyAronClass>(myAronClassProbeFn, "MyAronClass"); + * + * @endcode + * + * Note that the `pythonComponent` must point to a corresponding + * implementation of the `AronConversionTestInterfacePrx`. + */ + class AronConversionTester + { + public: + template <class AronClassT> + using ProbeFn = std::function<AronClassT()>; + + + public: + AronConversionTester(dti::AronConversionTestInterfacePrx interface); + + /** + * @brief Test the conversion of a specific ARON class. + * + * @param probeFn A factory function creating a test instance of the + * ARON class. + * @param aronClassName The name of the ARON class. Can be used by the + * other component to decide which class to convert to. + */ + template <class AronClassT> + void + test(ProbeFn<AronClassT> probeFn, const std::string& aronClassName) + { + std::stringstream ss; + ss << "Test for ARON class '" << aronClassName << "': "; + + const AronClassT probe = probeFn(); + + dto::TestAronConversionRequest req; + req.aronClassName = aronClassName; + req.probe = probe.toAronDTO(); + + dto::TestAronConversionResponse res = interface->testAronConversion(req); + + if (res.success) + { + const AronClassT probeOut = AronClassT::FromAron(res.probe); + ARMARX_CHECK(probeOut == probe); + + ARMARX_IMPORTANT << ss.str() << "Success"; + } + else + { + ARMARX_WARNING << ss.str() << "Conversion in Python component failed: \n" << res.errorMessage; + } + } + + public: + dti::AronConversionTestInterfacePrx interface; + }; + +} // namespace armarx::aron::test diff --git a/source/RobotAPI/libraries/aron/test/CMakeLists.txt b/source/RobotAPI/libraries/aron/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3a199acf0f19c13f6253e66947e540bfe3950efd --- /dev/null +++ b/source/RobotAPI/libraries/aron/test/CMakeLists.txt @@ -0,0 +1,25 @@ +set(LIB_NAME arontest) + +armarx_component_set_name("${LIB_NAME}") +armarx_set_target("Library: ${LIB_NAME}") + + +armarx_add_library( + LIBS + # ArmarXCore + ArmarXCore + # RobotAPI + RobotAPICore + RobotAPIInterfaces + aron + + HEADERS + AronConversionTester.h + + SOURCES + AronConversionTester.cpp +) + + +add_library(aron::test ALIAS arontest) +add_library(${PROJECT_NAME}::Aron::test ALIAS arontest)