From 4ac136c55295f5befb1293005eaba5e7685082f8 Mon Sep 17 00:00:00 2001 From: Johann Mantel <j-mantel@gmx.net> Date: Thu, 17 Jun 2021 15:02:40 +0200 Subject: [PATCH] create new armarx package for Sick TIM581 LaserScanner driver --- source/RobotAPI/components/CMakeLists.txt | 3 +- .../drivers/SickLaserUnit/CMakeLists.txt | 69 ++++++ .../drivers/SickLaserUnit/SickLaserUnit.cpp | 196 ++++++++++++++++++ .../drivers/SickLaserUnit/SickLaserUnit.h | 145 +++++++++++++ .../drivers/SickLaserUnit/test/CMakeLists.txt | 5 + .../SickLaserUnit/test/SickLaserUnitTest.cpp | 37 ++++ 6 files changed, 454 insertions(+), 1 deletion(-) create mode 100644 source/RobotAPI/drivers/SickLaserUnit/CMakeLists.txt create mode 100644 source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.cpp create mode 100644 source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.h create mode 100644 source/RobotAPI/drivers/SickLaserUnit/test/CMakeLists.txt create mode 100644 source/RobotAPI/drivers/SickLaserUnit/test/SickLaserUnitTest.cpp diff --git a/source/RobotAPI/components/CMakeLists.txt b/source/RobotAPI/components/CMakeLists.txt index 97d8648b4..0c3653739 100644 --- a/source/RobotAPI/components/CMakeLists.txt +++ b/source/RobotAPI/components/CMakeLists.txt @@ -31,4 +31,5 @@ add_subdirectory(ViewSelection) add_subdirectory(SkillObserver) -add_subdirectory(ArticulatedObjectLocalizerExample) \ No newline at end of file +add_subdirectory(ArticulatedObjectLocalizerExample) +add_subdirectory(drivers/SickLaserUnit) \ No newline at end of file diff --git a/source/RobotAPI/drivers/SickLaserUnit/CMakeLists.txt b/source/RobotAPI/drivers/SickLaserUnit/CMakeLists.txt new file mode 100644 index 000000000..2ff404a3f --- /dev/null +++ b/source/RobotAPI/drivers/SickLaserUnit/CMakeLists.txt @@ -0,0 +1,69 @@ +set(LIB_NAME SickLaserUnit) + +armarx_component_set_name("${LIB_NAME}") +armarx_set_target("Library: ${LIB_NAME}") + + +# If your component needs a special ice interface, define it here: +# armarx_add_component_interface_lib( +# SLICE_FILES +# SickLaserUnit.ice +# ICE_LIBS +# # RobotAPI +#) + + +# Add the component +armarx_add_component( + COMPONENT_LIBS + # ArmarXCore + ArmarXCore + ## ArmarXCoreComponentPlugins # For DebugObserver plugin. + # ArmarXGui + ## ArmarXGuiComponentPlugins # For RemoteGui plugin. + # RobotAPI + ## RobotAPICore + ## RobotAPIInterfaces + ## RobotAPIComponentPlugins # For ArViz and other plugins. + + # This project + ## ${PROJECT_NAME}Interfaces # For ice interfaces from this package. + # This component + ## SickLaserUnitInterfaces # If you defined a component ice interface above. + + SOURCES + SickLaserUnit.cpp + + HEADERS + SickLaserUnit.h +) + + +# Add dependencies +#find_package(MyLib QUIET) +#armarx_build_if(MyLib_FOUND "MyLib not available") + +# All target_include_directories must be guarded by if(Xyz_FOUND) +# For multiple libraries write: if(X_FOUND AND Y_FOUND) ... +#if(MyLib_FOUND) +# target_include_directories(SickLaserUnit PUBLIC ${MyLib_INCLUDE_DIRS}) +#endif() + + +# Add ARON files +#armarx_enable_aron_file_generation_for_target( +# TARGET_NAME +# ${ARMARX_COMPONENT_NAME} +# ARON_FILES +# aron/ExampleData.xml +#) + + +# Add unit tests +add_subdirectory(test) + +# Generate the application +armarx_generate_and_add_component_executable( + # If your component is not defined in ::armarx, specify its namespace here: + # COMPONENT_NAMESPACE "armarx::mynamespace" +) diff --git a/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.cpp b/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.cpp new file mode 100644 index 000000000..024eda12b --- /dev/null +++ b/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.cpp @@ -0,0 +1,196 @@ +/* + * 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::SickLaserUnit + * @author Johann Mantel ( j-mantel at gmx dot net ) + * @date 2021 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include "SickLaserUnit.h" + +// Include headers you only need in function definitions in the .cpp. + +// #include <Eigen/Core> + +// #include <SimoxUtility/color/Color.h> + + +namespace armarx +{ + + armarx::PropertyDefinitionsPtr SickLaserUnit::createPropertyDefinitions() + { + armarx::PropertyDefinitionsPtr def = new ComponentPropertyDefinitions(getConfigIdentifier()); + + // Publish to a topic (passing the TopicListenerPrx). + // def->topic(myTopicListener); + + // Subscribe to a topic (passing the topic name). + // def->topic<PlatformUnitListener>("MyTopic"); + + // Use (and depend on) another component (passing the ComponentInterfacePrx). + // def->component(myComponentProxy) + + + // Add a required property. + def->required(properties.boxLayerName, "p.box.LayerName", "Name of the box layer in ArViz."); + + // Add an optionalproperty. + def->optional(properties.numBoxes, "p.box.Number", "Number of boxes to draw in ArViz."); + + + return def; + } + + + void SickLaserUnit::onInitComponent() + { + // Topics and properties defined above are automagically registered. + + // Keep debug observer data until calling `sendDebugObserverBatch()`. + // (Requies the armarx::DebugObserverComponentPluginUser.) + // setDebugObserverBatchModeEnabled(true); + } + + + void SickLaserUnit::onConnectComponent() + { + // Do things after connecting to topics and components. + + + /* (Requies the armarx::DebugObserverComponentPluginUser.) + // Use the debug observer to log data over time. + // The data can be viewed in the ObserverView and the LivePlotter. + // (Before starting any threads, we don't need to lock mutexes.) + { + setDebugObserverDatafield("numBoxes", properties.numBoxes); + setDebugObserverDatafield("boxLayerName", properties.boxLayerName); + sendDebugObserverBatch(); + } + */ + + /* (Requires the armarx::ArVizComponentPluginUser.) + // Draw boxes in ArViz. + // (Before starting any threads, we don't need to lock mutexes.) + drawBoxes(properties, arviz); + */ + + /* (Requires the armarx::LightweightRemoteGuiComponentPluginUser.) + // Setup the remote GUI. + { + createRemoteGuiTab(); + RemoteGui_startRunningTask(); + } + */ + } + + + void SickLaserUnit::onDisconnectComponent() + { + + } + + + void SickLaserUnit::onExitComponent() + { + + } + + + std::string SickLaserUnit::getDefaultName() const + { + return "SickLaserUnit"; + } + + + /* (Requires the armarx::LightweightRemoteGuiComponentPluginUser.) + void SickLaserUnit::createRemoteGuiTab() + { + using namespace armarx::RemoteGui::Client; + + // Setup the widgets. + + tab.boxLayerName.setValue(properties.boxLayerName); + + tab.numBoxes.setValue(properties.numBoxes); + tab.numBoxes.setRange(0, 100); + + tab.drawBoxes.setLabel("Draw Boxes"); + + // Setup the layout. + + GridLayout grid; + int row = 0; + { + grid.add(Label("Box Layer"), {row, 0}).add(tab.boxLayerName, {row, 1}); + ++row; + + grid.add(Label("Num Boxes"), {row, 0}).add(tab.numBoxes, {row, 1}); + ++row; + + grid.add(tab.drawBoxes, {row, 0}, {2, 1}); + ++row; + } + + VBoxLayout root = {grid, VSpacer()}; + RemoteGui_createTab(getName(), root, &tab); + } + + + void SickLaserUnit::RemoteGui_update() + { + if (tab.boxLayerName.hasValueChanged() || tab.numBoxes.hasValueChanged()) + { + std::scoped_lock lock(propertiesMutex); + properties.boxLayerName = tab.boxLayerName.getValue(); + properties.numBoxes = tab.numBoxes.getValue(); + + { + setDebugObserverDatafield("numBoxes", properties.numBoxes); + setDebugObserverDatafield("boxLayerName", properties.boxLayerName); + sendDebugObserverBatch(); + } + } + if (tab.drawBoxes.wasClicked()) + { + // Lock shared variables in methods running in seperate threads + // and pass them to functions. This way, the called functions do + // not need to think about locking. + std::scoped_lock lock(propertiesMutex, arvizMutex); + drawBoxes(properties, arviz); + } + } + */ + + /* (Requires the armarx::ArVizComponentPluginUser.) + void SickLaserUnit::drawBoxes(const SickLaserUnit::Properties& p, viz::Client& arviz) + { + // Draw something in ArViz (requires the armarx::ArVizComponentPluginUser. + // See the ArVizExample in RobotAPI for more examples. + + viz::Layer layer = arviz.layer(p.boxLayerName); + for (int i = 0; i < p.numBoxes; ++i) + { + layer.add(viz::Box("box_" + std::to_string(i)) + .position(Eigen::Vector3f(i * 100, 0, 0)) + .size(20).color(simox::Color::blue())); + } + arviz.commit(layer); + } + */ + +} diff --git a/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.h b/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.h new file mode 100644 index 000000000..8b681b1f5 --- /dev/null +++ b/source/RobotAPI/drivers/SickLaserUnit/SickLaserUnit.h @@ -0,0 +1,145 @@ +/* + * 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::SickLaserUnit + * @author Johann Mantel ( j-mantel at gmx dot net ) + * @date 2021 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + + +// #include <mutex> + +#include <ArmarXCore/core/Component.h> + +// #include <ArmarXCore/libraries/ArmarXCoreComponentPlugins/DebugObserverComponentPlugin.h> + +// #include <ArmarXGui/libraries/ArmarXGuiComponentPlugins/LightweightRemoteGuiComponentPlugin.h> + +// #include <RobotAPI/libraries/RobotAPIComponentPlugins/ArVizComponentPlugin.h> + + +namespace armarx +{ + + /** + * @defgroup Component-SickLaserUnit SickLaserUnit + * @ingroup RobotAPI-Components + * A description of the component SickLaserUnit. + * + * @class SickLaserUnit + * @ingroup Component-SickLaserUnit + * @brief Brief description of class SickLaserUnit. + * + * Detailed description of class SickLaserUnit. + */ + class SickLaserUnit : + virtual public armarx::Component + // , virtual public armarx::DebugObserverComponentPluginUser + // , virtual public armarx::LightweightRemoteGuiComponentPluginUser + // , virtual public armarx::ArVizComponentPluginUser + { + public: + + /// @see armarx::ManagedIceObject::getDefaultName() + std::string getDefaultName() const override; + + + protected: + + /// @see PropertyUser::createPropertyDefinitions() + armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; + + /// @see armarx::ManagedIceObject::onInitComponent() + void onInitComponent() override; + + /// @see armarx::ManagedIceObject::onConnectComponent() + void onConnectComponent() override; + + /// @see armarx::ManagedIceObject::onDisconnectComponent() + void onDisconnectComponent() override; + + /// @see armarx::ManagedIceObject::onExitComponent() + void onExitComponent() override; + + + /* (Requires armarx::LightweightRemoteGuiComponentPluginUser.) + /// This function should be called once in onConnect() or when you + /// need to re-create the Remote GUI tab. + void createRemoteGuiTab(); + + /// After calling `RemoteGui_startRunningTask`, this function is + /// called periodically in a separate thread. If you update variables, + /// make sure to synchronize access to them. + void RemoteGui_update() override; + */ + + + private: + + // Private methods go here. + + // Forward declare `Properties` if you used it before its defined. + // struct Properties; + + /* (Requires the armarx::ArVizComponentPluginUser.) + /// Draw some boxes in ArViz. + void drawBoxes(const Properties& p, viz::Client& arviz); + */ + + + private: + + // Private member variables go here. + + + /// Properties shown in the Scenario GUI. + struct Properties + { + std::string boxLayerName; + int numBoxes = 10; + }; + Properties properties; + /* Use a mutex if you access variables from different threads + * (e.g. ice functions and RemoteGui_update()). + std::mutex propertiesMutex; + */ + + + /* (Requires the armarx::LightweightRemoteGuiComponentPluginUser.) + /// Tab shown in the Remote GUI. + struct RemoteGuiTab : armarx::RemoteGui::Client::Tab + { + armarx::RemoteGui::Client::LineEdit boxLayerName; + armarx::RemoteGui::Client::IntSpinBox numBoxes; + + armarx::RemoteGui::Client::Button drawBoxes; + }; + RemoteGuiTab tab; + */ + + + /* (Requires the armarx::ArVizComponentPluginUser.) + * When used from different threads, an ArViz client needs to be synchronized. + /// Protects the arviz client inherited from the ArViz plugin. + std::mutex arvizMutex; + */ + + + }; +} diff --git a/source/RobotAPI/drivers/SickLaserUnit/test/CMakeLists.txt b/source/RobotAPI/drivers/SickLaserUnit/test/CMakeLists.txt new file mode 100644 index 000000000..0e9585259 --- /dev/null +++ b/source/RobotAPI/drivers/SickLaserUnit/test/CMakeLists.txt @@ -0,0 +1,5 @@ + +# Libs required for the tests +SET(LIBS ${LIBS} ArmarXCore SickLaserUnit) + +armarx_add_test(SickLaserUnitTest SickLaserUnitTest.cpp "${LIBS}") diff --git a/source/RobotAPI/drivers/SickLaserUnit/test/SickLaserUnitTest.cpp b/source/RobotAPI/drivers/SickLaserUnit/test/SickLaserUnitTest.cpp new file mode 100644 index 000000000..d6a69c168 --- /dev/null +++ b/source/RobotAPI/drivers/SickLaserUnit/test/SickLaserUnitTest.cpp @@ -0,0 +1,37 @@ +/* + * 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::SickLaserUnit + * @author Johann Mantel ( j-mantel at gmx dot net ) + * @date 2021 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#define BOOST_TEST_MODULE RobotAPI::ArmarXObjects::SickLaserUnit + +#define ARMARX_BOOST_TEST + +#include <RobotAPI/Test.h> +#include "../SickLaserUnit.h" + +#include <iostream> + +BOOST_AUTO_TEST_CASE(testExample) +{ + armarx::SickLaserUnit instance; + + BOOST_CHECK_EQUAL(true, true); +} -- GitLab