diff --git a/cmake/YarpDeviceParamsParserGenerator.cmake b/cmake/YarpDeviceParamsParserGenerator.cmake index 6edebf4846e..4f09c0fd070 100644 --- a/cmake/YarpDeviceParamsParserGenerator.cmake +++ b/cmake/YarpDeviceParamsParserGenerator.cmake @@ -2,8 +2,8 @@ # SPDX-License-Identifier: BSD-3-Clause # Here is an example of how the YarpDeviceParamParserGenerator should be invoked: -# YarpDeviceParamParserGenerator --class_name className --input_filename_md filename.md [--input_extra_comments comments.md] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir output_path] -# YarpDeviceParamParserGenerator --class_name className --input_filename_ini filename.ini [--input_extra_comments comments.md] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir output_path] +# YarpDeviceParamParserGenerator --class_name className --module_name deviceName --input_filename_md filename.md [--input_extra_comments comments.md] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir output_path] +# YarpDeviceParamParserGenerator --class_name className --module_name deviceName --input_filename_ini filename.ini [--input_extra_comments comments.md] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir output_path] function(generateDeviceParamsParser_commandline COMMANDLINE) option(ALLOW_DEVICE_PARAM_PARSER_GENERATION "Allow YARP to (re)build device param parsers" OFF) @@ -37,33 +37,33 @@ function(generateDeviceParamsParser_commandline COMMANDLINE) endfunction() -function(generateDeviceParamsParser_fromMdFile CLASSNAME FILEMD EXTRACOMMENTS) +function(generateDeviceParamsParser_fromMdFile CLASSNAME DEVICENAME FILEMD EXTRACOMMENTS) if (EXTRACOMMENTS) - set (COMMAND "--class_name ${CLASSNAME} --input_filename_md ${FILEMD} --input_extra_comments ${EXTRACOMMENTS}") + set (COMMAND "--class_name ${CLASSNAME} --module_name ${DEVICENAME} --input_filename_md ${FILEMD} --input_extra_comments ${EXTRACOMMENTS}") else() - set (COMMAND "--class_name ${CLASSNAME} --input_filename_md ${FILEMD}") + set (COMMAND "--class_name ${CLASSNAME} --module_name ${DEVICENAME} --input_filename_md ${FILEMD}") endif() generateDeviceParamsParser_commandline (${COMMAND}) endfunction() -function(generateDeviceParamsParser_fromIniFile CLASSNAME FILEINI EXTRACOMMENTS) +function(generateDeviceParamsParser_fromIniFile CLASSNAME DEVICENAME FILEINI EXTRACOMMENTS) if (EXTRACOMMENTS) - set (COMMAND "--class_name ${CLASSNAME} --input_filename_ini ${FILEINI} --input_extra_comments ${EXTRACOMMENTS}") + set (COMMAND "--class_name ${CLASSNAME} --module_name ${DEVICENAME} --input_filename_ini ${FILEINI} --input_extra_comments ${EXTRACOMMENTS}") else() - set (COMMAND "--class_name ${CLASSNAME} --input_filename_ini ${FILEINI}") + set (COMMAND "--class_name ${CLASSNAME} --module_name ${DEVICENAME} --input_filename_ini ${FILEINI}") endif() generateDeviceParamsParser_commandline (${COMMAND}) endfunction() -function(generateDeviceParamsParser CLASSNAME) +function(generateDeviceParamsParser CLASSNAME DEVICENAME) set (INPUTFILENAME_INI "${CMAKE_CURRENT_SOURCE_DIR}/${CLASSNAME}_params.ini") set (INPUTFILENAME_MD "${CMAKE_CURRENT_SOURCE_DIR}/${CLASSNAME}_params.md") set (INPUTFILENAME_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/${CLASSNAME}_params_extracomments.md") if (EXISTS ${INPUTFILENAME_INI}) - set (COMMAND "--class_name ${CLASSNAME} --input_filename_ini ${INPUTFILENAME_INI}") + set (COMMAND "--class_name ${CLASSNAME} --module_name ${DEVICENAME} --input_filename_ini ${INPUTFILENAME_INI}") elseif (EXISTS ${INPUTFILENAME_MD}) - set (COMMAND "--class_name ${CLASSNAME} --input_filename_md ${INPUTFILENAME_MD}") + set (COMMAND "--class_name ${CLASSNAME} --module_name ${DEVICENAME} --input_filename_md ${INPUTFILENAME_MD}") else() message(FATAL_ERROR "Cannot find input file ${INPUTFILENAME_INI} or ${INPUTFILENAME_MD}") endif() diff --git a/cmake/YarpPlugin.cmake b/cmake/YarpPlugin.cmake index a2f700f4b42..0d100f1e0d7 100644 --- a/cmake/YarpPlugin.cmake +++ b/cmake/YarpPlugin.cmake @@ -59,7 +59,7 @@ include(CMakeParseArguments) include(CMakeDependentOption) include(${CMAKE_CURRENT_LIST_DIR}/YarpInstallationHelpers.cmake) include(${CMAKE_CURRENT_LIST_DIR}/YarpPrintFeature.cmake) - +include(${CMAKE_CURRENT_LIST_DIR}/YarpDeviceParamsParserGenerator.cmake) ################################################################################ #.rst: @@ -169,6 +169,7 @@ endmacro() # [DOC ""] # [ADVANCED] # [INTERNAL] +# [GENERATE_PARSER] # [DEPENDS ] # [TEMPLATE ] # [TEMPLATE_DIR ] @@ -218,6 +219,8 @@ endmacro() # The ``DOC`` argument can be used to set a description for this option. # If the``ADVANCED`` option is enabled, this option is marked as advanced in # CMake. +# If the ``GENERATE_PARSER`` option is enabled, a parameter parser will be generated +# for the plugin. See documentation of: generateDeviceParamsParser() # If the ``INTERNAL`` option is enabled, this option is marked as internal in # CMake, and therefore not displayed in CMake gui. This also implies # `DEFAULT=ON` unless explicitly specified. @@ -250,6 +253,7 @@ macro(YARP_PREPARE_PLUGIN _plugin_name) ADVANCED INTERNAL QUIET + GENERATE_PARSER ) set(_oneValueArgs TYPE @@ -567,6 +571,12 @@ YARP_DEFINE_SHARED_SUBCLASS(\@YARPPLUG_NAME\@, \@YARPPLUG_TYPE\@, \@YARPPLUG_PAR add_feature_info(${_plugin_fullname} ${_YPP_OPTION} "${_feature_doc}.") endif() + if (NOT SKIP_${_plugin_name}) + if(_YPP_GENERATE_PARSER) + message ("Invoking generateDeviceParamsParser (${_YPP_TYPE} ${_plugin_name})") + generateDeviceParamsParser(${_YPP_TYPE} ${_plugin_name}) + endif() + endif() endmacro() diff --git a/doc/module_executables/cmd_yarpDeviceParamParserGenerator.dox b/doc/module_executables/cmd_yarpDeviceParamParserGenerator.dox index 8ecbb6cf057..a8cd0896a06 100644 --- a/doc/module_executables/cmd_yarpDeviceParamParserGenerator.dox +++ b/doc/module_executables/cmd_yarpDeviceParamParserGenerator.dox @@ -98,9 +98,67 @@ depending on the meaning of specific parameters (e.g. when a real hardware is in \section yarpDeviceParamParserGenerator_cmake CMake Usage yarpDeviceParamParserGenerator usage can be integrated in the CMakeLists.txt of a device. -The usage is very simple: user has to add the generateDeviceParamsParser() command, whose input parameter must match the name of the class -of the device, in this case ChatBot_nws_yarp. yarpDeviceParamParserGenerator will generate the two files ChatBot_nws_yarp_ParamsParser.cpp, + +\subsection yarpDeviceParamParserGenerator_cmake_basic Basic cmake + +The usage is very simple: user has to add the `GENERATE_PARSER` option to the `yarp_prepare_plugin` macro. yarpDeviceParamParserGenerator will generate the two files ChatBot_nws_yarp_ParamsParser.cpp, ChatBot_nws_yarp_ParamsParser.h which must be added to target_sources. +The name of the generated files depends on the `TYPE` keyword, to which the `_ParamsParser` suffix is added. + +\code{.cmake} +include(YarpDeviceParamsParserGenerator) + +yarp_prepare_plugin(chatBot_nws_yarp + CATEGORY device + TYPE ChatBot_nws_yarp + INCLUDE ChatBot_nws_yarp.h + DEFAULT ON + GENERATE_PARSER +) + +if(NOT SKIP_chatBot_nws_yarp) + yarp_add_plugin(yarp_chatBot_nws_yarp) + + target_sources(yarp_chatBot_nws_yarp + PRIVATE + ChatBot_nws_yarp.cpp + ChatBot_nws_yarp.h + ChatBot_nws_yarp_ParamsParser.cpp + ChatBot_nws_yarp_ParamsParser.h + ) + + target_link_libraries(yarp_chatBot_nws_yarp + PRIVATE + YARP::YARP_os + YARP::YARP_sig + YARP::YARP_dev + ) + + list(APPEND YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS + YARP_os + YARP_sig + YARP_dev + ) + + yarp_install( + TARGETS yarp_chatBot_nws_yarp + EXPORT YARP_${YARP_PLUGIN_MASTER} + COMPONENT ${YARP_PLUGIN_MASTER} + LIBRARY DESTINATION ${YARP_DYNAMIC_PLUGINS_INSTALL_DIR} + ARCHIVE DESTINATION ${YARP_STATIC_PLUGINS_INSTALL_DIR} + YARP_INI DESTINATION ${YARP_PLUGIN_MANIFESTS_INSTALL_DIR} + ) + + set(YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS ${YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS} PARENT_SCOPE) +endif() +\endcode + +\subsection yarpDeviceParamParserGenerator_cmake_advanced Advanced cmake + +It is also possible to provide a customized control command by using the `generateDeviceParamsParser()` function (see documentation +in file YarpDeviceParamsParserGenerator.cmake). The minimum number of accepted parameters is two: +the name of the device class and the name of the plugin. It is not mandatory, but in Yarp the convention typically followed is to have +the class name upper camel case and the plugin name lower camel case. \code{.cmake} include(YarpDeviceParamsParserGenerator) @@ -114,7 +172,7 @@ yarp_prepare_plugin(chatBot_nws_yarp if(NOT SKIP_chatBot_nws_yarp) yarp_add_plugin(yarp_chatBot_nws_yarp) - generateDeviceParamsParser(ChatBot_nws_yarp) + generateDeviceParamsParser(ChatBot_nws_yarp chatBot_nws_yarp) target_sources(yarp_chatBot_nws_yarp PRIVATE @@ -160,15 +218,20 @@ file YarpDeviceParamsParserGenerator.cmake - nested groups can be specified using the :: operator. For example: myGroup::mySubGroup1::mySubGroup2::myVariable - only the following values are supported for the Type field in the input files: \code{.unparsed} -| Parameter type | c++ type | yarp::os::Value call | -|:--------------:|:--------------:|:--------------------:| -| "bool" | bool | .asBool() | -| "string" | std::string | .asString() | -| "int" | int | .asInt64() | -| "size_t" | size_t | .asInt64() | -| "float" | float | .asFloat32() | -| "double" | double | .asFloat64() | +| Parameter type | c++ type | yarp::os::Value call | .md file example | +|:--------------:|:--------------------:|:--------------------:|:----------------:| +| "bool" | bool | .asBool() | true | +| "string" | std::string | .asString() | "hello" | +| "int" | int | .asInt64() | 10 | +| "size_t" | size_t | .asInt64() | 10 | +| "float" | float | .asFloat32() | 10.0 | +| "double" | double | .asFloat64() | 10.0 | +| "char" | char | .asInt8() | 'c' | +| vector | std::vector | - | 10 10 | +| vector | std::vector | - | 10.0 10.0 | +| vector | std::vector | - | "hello" "hello" | \endcode +- Be careful with the vector type: invoking the device from the command line requires additional escape quotes (e.g. "10 10", "\"hello\" \"hello\"") - The generated .cpp file also include a function ::getDocumentationOfDeviceParams() which will output a documentation string which will be displayed on user request (for example invoking the --help option) diff --git a/src/devices/audioToFileDevice/AudioToFileDevice_ParamsParser.cpp b/src/devices/audioToFileDevice/AudioToFileDevice_ParamsParser.cpp index 7b4acea6bb2..93c917df9d4 100644 --- a/src/devices/audioToFileDevice/AudioToFileDevice_ParamsParser.cpp +++ b/src/devices/audioToFileDevice/AudioToFileDevice_ParamsParser.cpp @@ -8,7 +8,7 @@ // This is an automatically generated file. Please do not edit it. // It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. -// Generated on: Fri Feb 9 16:59:13 2024 +// Generated on: Mon Feb 19 16:28:03 2024 #include "AudioToFileDevice_ParamsParser.h" @@ -20,6 +20,11 @@ namespace { } +AudioToFileDevice_ParamsParser::AudioToFileDevice_ParamsParser() +{ +} + + std::vector AudioToFileDevice_ParamsParser::getListOfParams() const { std::vector params; @@ -123,8 +128,8 @@ std::string AudioToFileDevice_ParamsParser::getDocumentationOfDeviceParams( doc = doc + std::string("'add_marker': If set, it will add a marker at the beginning and at the ending of each received waveform.\n"); doc = doc + std::string("\n"); doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); - doc = doc + " yarpdev --device AudioToFileDevice --file_name audio_out.wav --save_mode overwrite_file --add_marker false\n"; + doc = doc + " yarpdev --device audioToFileDevice --file_name audio_out.wav --save_mode overwrite_file --add_marker false\n"; doc = doc + std::string("Using only mandatory params:\n"); - doc = doc + " yarpdev --device AudioToFileDevice\n"; + doc = doc + " yarpdev --device audioToFileDevice\n"; doc = doc + std::string("=============================================\n\n"); return doc; } diff --git a/src/devices/audioToFileDevice/AudioToFileDevice_ParamsParser.h b/src/devices/audioToFileDevice/AudioToFileDevice_ParamsParser.h index f0267ac65b1..a4f7cf6a5d7 100644 --- a/src/devices/audioToFileDevice/AudioToFileDevice_ParamsParser.h +++ b/src/devices/audioToFileDevice/AudioToFileDevice_ParamsParser.h @@ -8,7 +8,7 @@ // This is an automatically generated file. Please do not edit it. // It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. -// Generated on: Sun Feb 11 01:26:28 2024 +// Generated on: Mon Feb 19 16:28:03 2024 #ifndef AUDIOTOFILEDEVICE_PARAMSPARSER_H @@ -31,11 +31,11 @@ * * The device can be launched by yarpdev using one of the following examples: * \code{.unparsed} -* yarpdev --device AudioToFileDevice --file_name audio_out.wav --save_mode overwrite_file --add_marker false +* yarpdev --device audioToFileDevice --file_name audio_out.wav --save_mode overwrite_file --add_marker false * \endcode * * \code{.unparsed} -* yarpdev --device AudioToFileDevice +* yarpdev --device audioToFileDevice * \endcode * */ @@ -43,11 +43,12 @@ class AudioToFileDevice_ParamsParser : public yarp::dev::IDeviceDriverParams { public: - AudioToFileDevice_ParamsParser() = default; + AudioToFileDevice_ParamsParser(); ~AudioToFileDevice_ParamsParser() override = default; public: - const std::string m_device_type = {"AudioToFileDevice"}; + const std::string m_device_classname = {"AudioToFileDevice"}; + const std::string m_device_name = {"audioToFileDevice"}; bool m_parser_is_strict = false; struct parser_version_type { @@ -55,12 +56,18 @@ class AudioToFileDevice_ParamsParser : public yarp::dev::IDeviceDriverParams int minor = 0; }; const parser_version_type m_parser_version = {}; + + const std::string m_file_name_defaultValue = {"audio_out.wav"}; + const std::string m_save_mode_defaultValue = {"overwrite_file"}; + const std::string m_add_marker_defaultValue = {"false"}; + std::string m_file_name = {"audio_out.wav"}; std::string m_save_mode = {"overwrite_file"}; bool m_add_marker = {false}; bool parseParams(const yarp::os::Searchable & config) override; - std::string getDeviceType() const override { return m_device_type; } + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } std::string getDocumentationOfDeviceParams() const override; std::vector getListOfParams() const override; }; diff --git a/src/devices/audioToFileDevice/CMakeLists.txt b/src/devices/audioToFileDevice/CMakeLists.txt index 87bdd08ae17..01f6102e654 100644 --- a/src/devices/audioToFileDevice/CMakeLists.txt +++ b/src/devices/audioToFileDevice/CMakeLists.txt @@ -5,6 +5,7 @@ yarp_prepare_plugin(audioToFileDevice CATEGORY device TYPE AudioToFileDevice INCLUDE AudioToFileDevice.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=AudioPlayerWrapper DEFAULT ON @@ -12,7 +13,6 @@ yarp_prepare_plugin(audioToFileDevice if(NOT SKIP_audioToFileDevice) yarp_add_plugin(yarp_audioToFileDevice) - generateDeviceParamsParser(AudioToFileDevice) target_sources(yarp_audioToFileDevice PRIVATE diff --git a/src/devices/controlBoardRemapper/tests/controlBoardRemapper_t1_test.cpp b/src/devices/controlBoardRemapper/tests/controlBoardRemapper_t1_test.cpp index 021f3bf9662..848bb3203d5 100644 --- a/src/devices/controlBoardRemapper/tests/controlBoardRemapper_t1_test.cpp +++ b/src/devices/controlBoardRemapper/tests/controlBoardRemapper_t1_test.cpp @@ -22,40 +22,31 @@ const char *fmcA_file_content = "device fakeMotionControl\n" "[GENERAL]\n" "Joints 2\n" "\n" - "AxisName \"axisA1\" \"axisA2\" \n"; + "AxisName (\"axisA1\" \"axisA2\") \n"; const char *fmcB_file_content = "device fakeMotionControl\n" "[GENERAL]\n" "Joints 3\n" "\n" - "AxisName \"axisB1\" \"axisB2\" \"axisB3\"\n"; + "AxisName (\"axisB1\" \"axisB2\" \"axisB3\") \n"; const char *fmcC_file_content = "device fakeMotionControl\n" "[GENERAL]\n" "Joints 4\n" "\n" - "AxisName \"axisC1\" \"axisC2\" \"axisC3\" \"axisC4\" \n"; + "AxisName (\"axisC1\" \"axisC2\" \"axisC3\" \"axisC4\") \n"; const char *wrapperA_file_content = "device controlBoard_nws_yarp\n" "name /testRemapperRobot/a\n" - "period 0.01\n" - "networks (net_a)\n" - "joints 2\n" - "net_a 0 1 0 1\n"; + "period 0.01\n"; const char *wrapperB_file_content = "device controlBoard_nws_yarp\n" "name /testRemapperRobot/b\n" - "period 0.01\n" - "networks (net_b)\n" - "joints 3\n" - "net_b 0 2 0 2\n"; + "period 0.01\n"; const char *wrapperC_file_content = "device controlBoard_nws_yarp\n" "name /testRemapperRobot/c\n" - "period 0.01\n" - "networks (net_c)\n" - "joints 4\n" - "net_c 0 3 0 3\n"; + "period 0.01\n"; static void checkRemapper(yarp::dev::PolyDriver & ddRemapper, int rand, size_t nrOfRemappedAxes) @@ -220,7 +211,7 @@ TEST_CASE("dev::ControlBoardRemapperTest", "[yarp::dev]") PolyDriverList pdList; pdList.push(fmcbs[i],wrapperNetworks[i].c_str()); - CHECK(iwrap->attachAll(pdList)); // controlBoard_nws_yarp attached successfully to the device + REQUIRE(iwrap->attachAll(pdList)); // controlBoard_nws_yarp attached successfully to the device } // Create a list containing all the fake controlboards @@ -252,7 +243,7 @@ TEST_CASE("dev::ControlBoardRemapperTest", "[yarp::dev]") REQUIRE(ddRemapperWN.view(imultwrapWN)); // interface for multiple wrapper with wrong names correctly opened REQUIRE(imultwrapWN); - CHECK_FALSE(imultwrapWN->attachAll(fmcList)); // attachAll for controlboardremapper with wrong names successful + REQUIRE_FALSE(imultwrapWN->attachAll(fmcList)); // attachAll for controlboardremapper with wrong names successful // Make sure that a controlboard in which attachAll is not successfull // closes correctly @@ -278,7 +269,7 @@ TEST_CASE("dev::ControlBoardRemapperTest", "[yarp::dev]") REQUIRE(ddRemapper.view(imultwrap)); // interface for multiple wrapper correctly opened REQUIRE(imultwrap); - CHECK(imultwrap->attachAll(fmcList)); // attachAll for controlboardremapper successful + REQUIRE(imultwrap->attachAll(fmcList)); // attachAll for controlboardremapper successful // Test the controlboardremapper diff --git a/src/devices/deviceBundler/CMakeLists.txt b/src/devices/deviceBundler/CMakeLists.txt index 0bf7de2efb5..502384ad49e 100644 --- a/src/devices/deviceBundler/CMakeLists.txt +++ b/src/devices/deviceBundler/CMakeLists.txt @@ -6,13 +6,12 @@ yarp_prepare_plugin(deviceBundler TYPE DeviceBundler INCLUDE DeviceBundler.h DEFAULT ON + GENERATE_PARSER ) if(NOT SKIP_deviceBundler) yarp_add_plugin(yarp_deviceBundler) - generateDeviceParamsParser(DeviceBundler) - target_sources(yarp_deviceBundler PRIVATE DeviceBundler.cpp diff --git a/src/devices/deviceBundler/DeviceBundler.cpp b/src/devices/deviceBundler/DeviceBundler.cpp index 010b379aa91..7900a4930b4 100644 --- a/src/devices/deviceBundler/DeviceBundler.cpp +++ b/src/devices/deviceBundler/DeviceBundler.cpp @@ -30,8 +30,12 @@ bool DeviceBundler::open(yarp::os::Searchable& config) bool ret = true; //open wrapper device + yCInfo(DEVICEBUNDLER, "Opening device: %s", m_wrapper_device.c_str()); yarp::os::Property config_wrap (config.toString().c_str()); config_wrap.unput("device"); + config_wrap.unput("wrapper_device"); + config_wrap.unput("attached_device"); + config_wrap.unput("wrapping_enabled"); config_wrap.put("device", m_wrapper_device); std::string sw = config_wrap.toString(); ret = m_pdev_wrapper.open(config_wrap); @@ -42,8 +46,12 @@ bool DeviceBundler::open(yarp::os::Searchable& config) } //open secondary device + yCInfo(DEVICEBUNDLER, "Opening device: %s", m_attached_device.c_str()); yarp::os::Property config_sub(config.toString().c_str()); config_sub.unput("device"); + config_sub.unput("wrapper_device"); + config_sub.unput("attached_device"); + config_sub.unput("wrapping_enabled"); config_sub.put("device", m_attached_device); std::string ss = config_sub.toString(); ret = m_pdev_subdevice.open(config_sub); @@ -60,6 +68,7 @@ bool DeviceBundler::open(yarp::os::Searchable& config) } //Attach operations below + yCInfo(DEVICEBUNDLER, "Attaching devices %s and %s.", m_wrapper_device.c_str(), m_attached_device.c_str()); ret = m_pdev_wrapper.view(m_iWrapper); if (!ret) { @@ -74,7 +83,7 @@ bool DeviceBundler::open(yarp::os::Searchable& config) return false; } - yCDebug(DEVICEBUNDLER, "Attach operation between %s and %s completed.", m_wrapper_device.c_str(), m_attached_device.c_str()); + yCInfo(DEVICEBUNDLER, "Attach operation between %s and %s completed.", m_wrapper_device.c_str(), m_attached_device.c_str()); return true; } diff --git a/src/devices/deviceBundler/DeviceBundler_ParamsParser.cpp b/src/devices/deviceBundler/DeviceBundler_ParamsParser.cpp index 46664a352ed..a9d9b853f50 100644 --- a/src/devices/deviceBundler/DeviceBundler_ParamsParser.cpp +++ b/src/devices/deviceBundler/DeviceBundler_ParamsParser.cpp @@ -8,7 +8,7 @@ // This is an automatically generated file. Please do not edit it. // It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. -// Generated on: Fri Feb 9 16:59:13 2024 +// Generated on: Mon Feb 19 16:28:03 2024 #include "DeviceBundler_ParamsParser.h" @@ -20,6 +20,11 @@ namespace { } +DeviceBundler_ParamsParser::DeviceBundler_ParamsParser() +{ +} + + std::vector DeviceBundler_ParamsParser::getListOfParams() const { std::vector params; @@ -127,8 +132,8 @@ std::string DeviceBundler_ParamsParser::getDocumentationOfDeviceParams() co doc = doc + std::string("'doNotAttach': If set to true, the two devices are opened, but not attached\n"); doc = doc + std::string("\n"); doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); - doc = doc + " yarpdev --device DeviceBundler --wrapper_device device_name1 --attached_device device_name2 --doNotAttach false\n"; + doc = doc + " yarpdev --device deviceBundler --wrapper_device device_name1 --attached_device device_name2 --doNotAttach false\n"; doc = doc + std::string("Using only mandatory params:\n"); - doc = doc + " yarpdev --device DeviceBundler --wrapper_device device_name1 --attached_device device_name2\n"; + doc = doc + " yarpdev --device deviceBundler --wrapper_device device_name1 --attached_device device_name2\n"; doc = doc + std::string("=============================================\n\n"); return doc; } diff --git a/src/devices/deviceBundler/DeviceBundler_ParamsParser.h b/src/devices/deviceBundler/DeviceBundler_ParamsParser.h index b9201c69331..b0aba9309ed 100644 --- a/src/devices/deviceBundler/DeviceBundler_ParamsParser.h +++ b/src/devices/deviceBundler/DeviceBundler_ParamsParser.h @@ -8,7 +8,7 @@ // This is an automatically generated file. Please do not edit it. // It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. -// Generated on: Sun Feb 11 01:26:28 2024 +// Generated on: Mon Feb 19 16:28:03 2024 #ifndef DEVICEBUNDLER_PARAMSPARSER_H @@ -31,11 +31,11 @@ * * The device can be launched by yarpdev using one of the following examples: * \code{.unparsed} -* yarpdev --device DeviceBundler --wrapper_device device_name1 --attached_device device_name2 --doNotAttach false +* yarpdev --device deviceBundler --wrapper_device device_name1 --attached_device device_name2 --doNotAttach false * \endcode * * \code{.unparsed} -* yarpdev --device DeviceBundler --wrapper_device device_name1 --attached_device device_name2 +* yarpdev --device deviceBundler --wrapper_device device_name1 --attached_device device_name2 * \endcode * */ @@ -43,11 +43,12 @@ class DeviceBundler_ParamsParser : public yarp::dev::IDeviceDriverParams { public: - DeviceBundler_ParamsParser() = default; + DeviceBundler_ParamsParser(); ~DeviceBundler_ParamsParser() override = default; public: - const std::string m_device_type = {"DeviceBundler"}; + const std::string m_device_classname = {"DeviceBundler"}; + const std::string m_device_name = {"deviceBundler"}; bool m_parser_is_strict = false; struct parser_version_type { @@ -55,12 +56,18 @@ class DeviceBundler_ParamsParser : public yarp::dev::IDeviceDriverParams int minor = 0; }; const parser_version_type m_parser_version = {}; + + const std::string m_wrapper_device_defaultValue = {"device_name1"}; + const std::string m_attached_device_defaultValue = {"device_name2"}; + const std::string m_doNotAttach_defaultValue = {"false"}; + std::string m_wrapper_device = {"device_name1"}; std::string m_attached_device = {"device_name2"}; bool m_doNotAttach = {false}; bool parseParams(const yarp::os::Searchable & config) override; - std::string getDeviceType() const override { return m_device_type; } + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } std::string getDocumentationOfDeviceParams() const override; std::vector getListOfParams() const override; }; diff --git a/src/devices/fake/fakeAnalogSensor/CMakeLists.txt b/src/devices/fake/fakeAnalogSensor/CMakeLists.txt index 70cf9780649..d9a0f58dc53 100644 --- a/src/devices/fake/fakeAnalogSensor/CMakeLists.txt +++ b/src/devices/fake/fakeAnalogSensor/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeAnalogSensor CATEGORY device TYPE FakeAnalogSensor - INCLUDE fakeAnalogSensor.h + INCLUDE FakeAnalogSensor.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=analogServer ) @@ -18,8 +19,10 @@ if(ENABLE_fakeAnalogSensor) target_sources(yarp_fakeAnalogSensor PRIVATE - fakeAnalogSensor.cpp - fakeAnalogSensor.h + FakeAnalogSensor.cpp + FakeAnalogSensor.h + FakeAnalogSensor_ParamsParser.cpp + FakeAnalogSensor_ParamsParser.h ) target_link_libraries(yarp_fakeAnalogSensor diff --git a/src/devices/fake/fakeAnalogSensor/fakeAnalogSensor.cpp b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor.cpp similarity index 75% rename from src/devices/fake/fakeAnalogSensor/fakeAnalogSensor.cpp rename to src/devices/fake/fakeAnalogSensor/FakeAnalogSensor.cpp index 0b306019cfa..ed4eefaf664 100644 --- a/src/devices/fake/fakeAnalogSensor/fakeAnalogSensor.cpp +++ b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeAnalogSensor.h" +#include "FakeAnalogSensor.h" #include #include @@ -17,7 +17,6 @@ YARP_LOG_COMPONENT(FAKEANALOGSENSOR, "yarp.device.fakeAnalogSensor") FakeAnalogSensor::FakeAnalogSensor(double period) : PeriodicThread(period), mutex(), - channelsNum(0), status(IAnalogSensor::AS_OK) { yCTrace(FAKEANALOGSENSOR); @@ -32,37 +31,15 @@ FakeAnalogSensor::~FakeAnalogSensor() bool FakeAnalogSensor::open(yarp::os::Searchable& config) { - yCTrace(FAKEANALOGSENSOR); - bool correct=true; - - //debug - fprintf(stderr, "%s\n", config.toString().c_str()); - - // Check parameters first -// if(!config.check("channels")) -// { -// correct = false; -// yCError(FAKEANALOGSENSOR) << "Parameter 'channels' missing"; -// } - - if(!config.check("period")) - { - correct = false; - yCError(FAKEANALOGSENSOR) << "Parameter 'period' missing"; - } + if (!this->parseParams(config)) {return false;} - if (!correct) - { - yCError(FAKEANALOGSENSOR) << "Insufficient parameters to FakeAnalogSensor\n"; - return false; - } + yCTrace(FAKEANALOGSENSOR); - double period=config.find("period").asInt32() / 1000.0; + double period= m_period / 1000.0; setPeriod(period); //create the data vector: - this->channelsNum = 1; - data.resize(channelsNum); + data.resize(m_channelsNum); data.zero(); return PeriodicThread::start(); @@ -96,7 +73,7 @@ int FakeAnalogSensor::getState(int ch) int FakeAnalogSensor::getChannels() { yCTrace(FAKEANALOGSENSOR); - return channelsNum; + return m_channelsNum; } int FakeAnalogSensor::calibrateSensor() diff --git a/src/devices/fake/fakeAnalogSensor/fakeAnalogSensor.h b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor.h similarity index 82% rename from src/devices/fake/fakeAnalogSensor/fakeAnalogSensor.h rename to src/devices/fake/fakeAnalogSensor/FakeAnalogSensor.h index 2f8840180bb..fba561d7a97 100644 --- a/src/devices/fake/fakeAnalogSensor/fakeAnalogSensor.h +++ b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor.h @@ -12,6 +12,7 @@ #include #include +#include "FakeAnalogSensor_ParamsParser.h" /** * @@ -19,23 +20,20 @@ * * \brief `fakeAnalogSensor`: Fake analog sensor device for testing purpose and reference for new analog devices * -* Parameters accepted in the config argument of the open method: -* | Parameter name | Type | Units | Default Value | Required | Description | Notes | -* |:--------------:|:------:|:-----:|:-------------:|:--------:|:-----------:|:-----:| -* | +* Parameters required by this device are shown in class: FakeAnalogSensor_ParamsParser */ class FakeAnalogSensor : public yarp::dev::DeviceDriver, public yarp::os::PeriodicThread, - public yarp::dev::IAnalogSensor + public yarp::dev::IAnalogSensor, + public FakeAnalogSensor_ParamsParser { private: std::mutex mutex; std::string name; // device name - unsigned int channelsNum; short status; double timeStamp; yarp::sig::Vector data; diff --git a/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_ParamsParser.cpp b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_ParamsParser.cpp new file mode 100644 index 00000000000..3c6a82e4a68 --- /dev/null +++ b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_ParamsParser.cpp @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#include "FakeAnalogSensor_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeAnalogSensorParamsCOMPONENT, "yarp.device.FakeAnalogSensor") +} + + +FakeAnalogSensor_ParamsParser::FakeAnalogSensor_ParamsParser() +{ +} + + +std::vector FakeAnalogSensor_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("period"); + params.push_back("channelsNum"); + return params; +} + + +bool FakeAnalogSensor_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeAnalogSensorParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asFloat64(); + yCInfo(FakeAnalogSensorParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakeAnalogSensorParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + //Parser of parameter channelsNum + { + if (config.check("channelsNum")) + { + m_channelsNum = config.find("channelsNum").asInt64(); + yCInfo(FakeAnalogSensorParamsCOMPONENT) << "Parameter 'channelsNum' using value:" << m_channelsNum; + } + else + { + yCInfo(FakeAnalogSensorParamsCOMPONENT) << "Parameter 'channelsNum' using DEFAULT value:" << m_channelsNum; + } + prop_check.unput("channelsNum"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeAnalogSensorParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeAnalogSensorParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeAnalogSensor_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeAnalogSensor\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'period': thread period\n"); + doc = doc + std::string("'channelsNum': Number of channels\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeAnalogSensor --period 1.0 --channelsNum 1\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeAnalogSensor\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_ParamsParser.h b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_ParamsParser.h new file mode 100644 index 00000000000..403e442f9d0 --- /dev/null +++ b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_ParamsParser.h @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#ifndef FAKEANALOGSENSOR_PARAMSPARSER_H +#define FAKEANALOGSENSOR_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeAnalogSensor. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:------------------:|:-----:| +* | - | period | double | s | 1.0 | 0 | thread period | - | +* | - | channelsNum | int | - | 1 | 0 | Number of channels | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeAnalogSensor --period 1.0 --channelsNum 1 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeAnalogSensor +* \endcode +* +*/ + +class FakeAnalogSensor_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeAnalogSensor_ParamsParser(); + ~FakeAnalogSensor_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeAnalogSensor"}; + const std::string m_device_name = {"fakeAnalogSensor"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_period_defaultValue = {"1.0"}; + const std::string m_channelsNum_defaultValue = {"1"}; + + double m_period = {1.0}; + int m_channelsNum = {1}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_params.md b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_params.md new file mode 100644 index 00000000000..c3209c631e8 --- /dev/null +++ b/src/devices/fake/fakeAnalogSensor/FakeAnalogSensor_params.md @@ -0,0 +1,2 @@ + * | | period | double | s | 1.0 | No | thread period | | + * | | channelsNum | int | - | 1 | No | Number of channels | | diff --git a/src/devices/fake/fakeBattery/CMakeLists.txt b/src/devices/fake/fakeBattery/CMakeLists.txt index 2d7d7647180..0ef7bb5cfc3 100644 --- a/src/devices/fake/fakeBattery/CMakeLists.txt +++ b/src/devices/fake/fakeBattery/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeBattery CATEGORY device TYPE FakeBattery - INCLUDE fakeBattery.h + INCLUDE FakeBattery.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=batteryWrapper ) @@ -21,8 +22,10 @@ if(NOT SKIP_fakeBattery) target_sources(yarp_fakeBattery PRIVATE - fakeBattery.cpp - fakeBattery.h + FakeBattery.cpp + FakeBattery.h + FakeBattery_ParamsParser.cpp + FakeBattery_ParamsParser.h ${IDL_GEN_FILES} ) diff --git a/src/devices/fake/fakeBattery/fakeBattery.cpp b/src/devices/fake/fakeBattery/FakeBattery.cpp similarity index 83% rename from src/devices/fake/fakeBattery/fakeBattery.cpp rename to src/devices/fake/fakeBattery/FakeBattery.cpp index 55013607a38..a622a7f1cbb 100644 --- a/src/devices/fake/fakeBattery/fakeBattery.cpp +++ b/src/devices/fake/fakeBattery/FakeBattery.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeBattery.h" +#include "FakeBattery.h" #include #include @@ -34,31 +34,24 @@ FakeBattery::FakeBattery() : bool FakeBattery::open(yarp::os::Searchable& config) { - double period = config.check("thread_period", Value(default_period), "Thread period (smaller implies faster charge/discharge)").asFloat64(); - setPeriod(period); - - double charge = config.check("charge", Value(default_charge), "Initial charge (%)").asFloat64(); - double voltage = config.check("voltage", Value(default_voltage), "Initial voltage (V)").asFloat64(); - double current = config.check("current", Value(default_current), "Initial current (A)").asFloat64(); - double temperature = config.check("temperature", Value(default_temperature), "Initial temperature (°C)").asFloat64(); - std::string info = config.check("info", Value(default_info), "Initial battery information").asString(); - { - std::lock_guard lock(m_mutex); - battery_charge = charge; - battery_voltage = voltage; - battery_current = current; - battery_temperature = temperature; - battery_info = std::move(info); - updateStatus(); - } + if (!this->parseParams(config)) {return false;} - std::string name = config.find("name").asString(); - this->yarp().attachAsServer(ctrl_port); - if (!ctrl_port.open(name + "/control/rpc:i")) { + setPeriod(m_period); + + std::lock_guard lock(m_mutex); + battery_charge = m_charge; + battery_voltage = m_voltage; + battery_current = m_current; + battery_temperature = m_temperature; + battery_info = std::move(m_info); + updateStatus(); + + if (!ctrl_port.open(m_rpc_port_name)) { yCError(FAKEBATTERY, "Could not open rpc port"); close(); return false; } + this->yarp().attachAsServer(ctrl_port); PeriodicThread::start(); diff --git a/src/devices/fake/fakeBattery/fakeBattery.h b/src/devices/fake/fakeBattery/FakeBattery.h similarity index 89% rename from src/devices/fake/fakeBattery/fakeBattery.h rename to src/devices/fake/fakeBattery/FakeBattery.h index e27f23bcae7..d2d6b4078ac 100644 --- a/src/devices/fake/fakeBattery/fakeBattery.h +++ b/src/devices/fake/fakeBattery/FakeBattery.h @@ -15,17 +15,21 @@ #include #include "FakeBatteryService.h" +#include "FakeBattery_ParamsParser.h" /** - * @ingroup dev_impl_fake - * - * \brief `fakeBattery`: Documentation to be added - */ + * @ingroup dev_impl_fake + * + * \brief `fakeBattery`: Documentation to be added + * + * Parameters required by this device are shown in class: FakeBattery_ParamsParser + */ class FakeBattery : public yarp::os::PeriodicThread, public yarp::dev::IBattery, public yarp::dev::DeviceDriver, - public FakeBatteryService + public FakeBatteryService, + public FakeBattery_ParamsParser { protected: std::mutex m_mutex; diff --git a/src/devices/fake/fakeBattery/FakeBattery_ParamsParser.cpp b/src/devices/fake/fakeBattery/FakeBattery_ParamsParser.cpp new file mode 100644 index 00000000000..838ef3d48ae --- /dev/null +++ b/src/devices/fake/fakeBattery/FakeBattery_ParamsParser.cpp @@ -0,0 +1,199 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#include "FakeBattery_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeBatteryParamsCOMPONENT, "yarp.device.FakeBattery") +} + + +FakeBattery_ParamsParser::FakeBattery_ParamsParser() +{ +} + + +std::vector FakeBattery_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("period"); + params.push_back("charge"); + params.push_back("voltage"); + params.push_back("current"); + params.push_back("temperature"); + params.push_back("info"); + params.push_back("rpc_port_name"); + return params; +} + + +bool FakeBattery_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeBatteryParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asFloat64(); + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + //Parser of parameter charge + { + if (config.check("charge")) + { + m_charge = config.find("charge").asFloat64(); + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'charge' using value:" << m_charge; + } + else + { + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'charge' using DEFAULT value:" << m_charge; + } + prop_check.unput("charge"); + } + + //Parser of parameter voltage + { + if (config.check("voltage")) + { + m_voltage = config.find("voltage").asFloat64(); + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'voltage' using value:" << m_voltage; + } + else + { + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'voltage' using DEFAULT value:" << m_voltage; + } + prop_check.unput("voltage"); + } + + //Parser of parameter current + { + if (config.check("current")) + { + m_current = config.find("current").asFloat64(); + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'current' using value:" << m_current; + } + else + { + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'current' using DEFAULT value:" << m_current; + } + prop_check.unput("current"); + } + + //Parser of parameter temperature + { + if (config.check("temperature")) + { + m_temperature = config.find("temperature").asFloat64(); + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'temperature' using value:" << m_temperature; + } + else + { + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'temperature' using DEFAULT value:" << m_temperature; + } + prop_check.unput("temperature"); + } + + //Parser of parameter info + { + if (config.check("info")) + { + m_info = config.find("info").asString(); + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'info' using value:" << m_info; + } + else + { + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'info' using DEFAULT value:" << m_info; + } + prop_check.unput("info"); + } + + //Parser of parameter rpc_port_name + { + if (config.check("rpc_port_name")) + { + m_rpc_port_name = config.find("rpc_port_name").asString(); + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'rpc_port_name' using value:" << m_rpc_port_name; + } + else + { + yCInfo(FakeBatteryParamsCOMPONENT) << "Parameter 'rpc_port_name' using DEFAULT value:" << m_rpc_port_name; + } + prop_check.unput("rpc_port_name"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeBatteryParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeBatteryParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeBattery_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeBattery\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'period': thread period\n"); + doc = doc + std::string("'charge': Initial charge\n"); + doc = doc + std::string("'voltage': Initial voltage\n"); + doc = doc + std::string("'current': Initial current\n"); + doc = doc + std::string("'temperature': Initial temperature\n"); + doc = doc + std::string("'info': Initial battery information\n"); + doc = doc + std::string("'rpc_port_name': Full rpc port name\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeBattery --period 0.02 --charge 50.0 --voltage 30.0 --current 3.0 --temperature 20.0 --info Fake battery system v2.0 --rpc_port_name /fakeBattery/rpc\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeBattery\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeBattery/FakeBattery_ParamsParser.h b/src/devices/fake/fakeBattery/FakeBattery_ParamsParser.h new file mode 100644 index 00000000000..da136182f91 --- /dev/null +++ b/src/devices/fake/fakeBattery/FakeBattery_ParamsParser.h @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#ifndef FAKEBATTERY_PARAMSPARSER_H +#define FAKEBATTERY_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeBattery. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:------------------------:|:--------:|:---------------------------:|:-----:| +* | - | period | double | s | 0.02 | 0 | thread period | - | +* | - | charge | double | - | 50.0 | 0 | Initial charge | - | +* | - | voltage | double | V | 30.0 | 0 | Initial voltage | - | +* | - | current | double | A | 3.0 | 0 | Initial current | - | +* | - | temperature | double | C | 20.0 | 0 | Initial temperature | - | +* | - | info | string | - | Fake battery system v2.0 | 0 | Initial battery information | - | +* | - | rpc_port_name | string | - | /fakeBattery/rpc | 0 | Full rpc port name | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeBattery --period 0.02 --charge 50.0 --voltage 30.0 --current 3.0 --temperature 20.0 --info Fake battery system v2.0 --rpc_port_name /fakeBattery/rpc +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeBattery +* \endcode +* +*/ + +class FakeBattery_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeBattery_ParamsParser(); + ~FakeBattery_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeBattery"}; + const std::string m_device_name = {"fakeBattery"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_period_defaultValue = {"0.02"}; + const std::string m_charge_defaultValue = {"50.0"}; + const std::string m_voltage_defaultValue = {"30.0"}; + const std::string m_current_defaultValue = {"3.0"}; + const std::string m_temperature_defaultValue = {"20.0"}; + const std::string m_info_defaultValue = {"Fake battery system v2.0"}; + const std::string m_rpc_port_name_defaultValue = {"/fakeBattery/rpc"}; + + double m_period = {0.02}; + double m_charge = {50.0}; + double m_voltage = {30.0}; + double m_current = {3.0}; + double m_temperature = {20.0}; + std::string m_info = {"Fake battery system v2.0"}; + std::string m_rpc_port_name = {"/fakeBattery/rpc"}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeBattery/FakeBattery_params.md b/src/devices/fake/fakeBattery/FakeBattery_params.md new file mode 100644 index 00000000000..e96a466b3b6 --- /dev/null +++ b/src/devices/fake/fakeBattery/FakeBattery_params.md @@ -0,0 +1,7 @@ + * | | period | double | s | 0.02 | No | thread period | | + * | | charge | double | % | 50.0 | No | Initial charge | | + * | | voltage | double | V | 30.0 | No | Initial voltage | | + * | | current | double | A | 3.0 | No | Initial current | | + * | | temperature | double | C | 20.0 | No | Initial temperature | | + * | | info | string | - | Fake battery system v2.0 | No | Initial battery information | | + * | | rpc_port_name | string | - | /fakeBattery/rpc | No | Full rpc port name | | diff --git a/src/devices/fake/fakeChatBotDevice/CMakeLists.txt b/src/devices/fake/fakeChatBotDevice/CMakeLists.txt index c4b5a01d7e1..e12100440f7 100644 --- a/src/devices/fake/fakeChatBotDevice/CMakeLists.txt +++ b/src/devices/fake/fakeChatBotDevice/CMakeLists.txt @@ -9,8 +9,9 @@ yarp_prepare_plugin(fakeChatBotDevice CATEGORY device TYPE FakeChatBotDevice INCLUDE FakeChatBotDevice.h - + GENERATE_PARSER ) + if(NOT SKIP_fakeChatBotDevice) yarp_add_plugin(yarp_fakeChatBotDevice) @@ -19,6 +20,8 @@ if(NOT SKIP_fakeChatBotDevice) PRIVATE FakeChatBotDevice.cpp FakeChatBotDevice.h + FakeChatBotDevice_ParamsParser.cpp + FakeChatBotDevice_ParamsParser.h ) target_link_libraries(yarp_fakeChatBotDevice diff --git a/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice.cpp b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice.cpp index 311dea7923f..074708e993f 100644 --- a/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice.cpp +++ b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice.cpp @@ -10,7 +10,6 @@ YARP_LOG_COMPONENT(FAKECHATBOTDEVICE, "yarp.devices.FakeChatBotDevice") FakeChatBotDevice::FakeChatBotDevice() : - m_lang{"eng"}, m_fallback{"Sorry, I did not get that. Can you repeat?"}, m_noInput{"I heard nothing. Can you please speak up?"}, m_status{"greetings"}, @@ -56,14 +55,14 @@ bool FakeChatBotDevice::setLanguage(const std::string& language) yCError(FAKECHATBOTDEVICE) << "Unsopported language. Only English is supported for the moment being"; return false; } - m_lang = language; + m_language = language; return true; } bool FakeChatBotDevice::getLanguage(std::string& language) { - language = m_lang; + language = m_language; return true; } @@ -79,3 +78,14 @@ bool FakeChatBotDevice::resetBot() m_status = "greetings"; return true; } + +bool FakeChatBotDevice::open(yarp::os::Searchable& config) +{ + if (!this->parseParams(config)) {return false;} + return true; +} + +bool FakeChatBotDevice::close() +{ + return true; +} diff --git a/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice.h b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice.h index af8660716d2..21721b42a91 100644 --- a/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice.h +++ b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice.h @@ -10,15 +10,19 @@ #include #include #include +#include "FakeChatBotDevice_ParamsParser.h" /** * @ingroup dev_impl_fake dev_impl_other * * @brief `fakeChatBotDevice` : a fake device which implements the IChatBot interface for testing purposes. * +* Parameters required by this device are shown in class: FakeChatBotDevice_ParamsParser +* */ class FakeChatBotDevice : public yarp::dev::IChatBot, - public yarp::dev::DeviceDriver + public yarp::dev::DeviceDriver, + public FakeChatBotDevice_ParamsParser { public: @@ -29,9 +33,11 @@ class FakeChatBotDevice : public yarp::dev::IChatBot, bool getStatus(std::string& status) override; bool resetBot() override; + bool open(yarp::os::Searchable& config) override; + bool close() override; + private: std::string m_currBot; - std::string m_lang; std::string m_fallback; std::string m_noInput; std::string m_status; diff --git a/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_ParamsParser.cpp b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_ParamsParser.cpp new file mode 100644 index 00000000000..8e7266740f5 --- /dev/null +++ b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:29 2024 + + +#include "FakeChatBotDevice_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeChatBotDeviceParamsCOMPONENT, "yarp.device.FakeChatBotDevice") +} + + +FakeChatBotDevice_ParamsParser::FakeChatBotDevice_ParamsParser() +{ +} + + +std::vector FakeChatBotDevice_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("language"); + return params; +} + + +bool FakeChatBotDevice_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeChatBotDeviceParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter language + { + if (config.check("language")) + { + m_language = config.find("language").asString(); + yCInfo(FakeChatBotDeviceParamsCOMPONENT) << "Parameter 'language' using value:" << m_language; + } + else + { + yCInfo(FakeChatBotDeviceParamsCOMPONENT) << "Parameter 'language' using DEFAULT value:" << m_language; + } + prop_check.unput("language"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeChatBotDeviceParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeChatBotDeviceParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeChatBotDevice_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeChatBotDevice\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'language': language code\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeChatBotDevice --language eng\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeChatBotDevice\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_ParamsParser.h b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_ParamsParser.h new file mode 100644 index 00000000000..4b69fd2d2d6 --- /dev/null +++ b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:29 2024 + + +#ifndef FAKECHATBOTDEVICE_PARAMSPARSER_H +#define FAKECHATBOTDEVICE_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeChatBotDevice. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-------------:|:-----:| +* | - | language | string | - | eng | 0 | language code | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeChatBotDevice --language eng +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeChatBotDevice +* \endcode +* +*/ + +class FakeChatBotDevice_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeChatBotDevice_ParamsParser(); + ~FakeChatBotDevice_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeChatBotDevice"}; + const std::string m_device_name = {"fakeChatBotDevice"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_language_defaultValue = {"eng"}; + + std::string m_language = {"eng"}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_params.md b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_params.md new file mode 100644 index 00000000000..dafbeb7e6d0 --- /dev/null +++ b/src/devices/fake/fakeChatBotDevice/FakeChatBotDevice_params.md @@ -0,0 +1 @@ + * | | language | string | - | eng | No | language code | | diff --git a/src/devices/fake/fakeDepthCamera/CMakeLists.txt b/src/devices/fake/fakeDepthCamera/CMakeLists.txt index 83ec92d081e..c7bc02104dd 100644 --- a/src/devices/fake/fakeDepthCamera/CMakeLists.txt +++ b/src/devices/fake/fakeDepthCamera/CMakeLists.txt @@ -7,8 +7,9 @@ endif() yarp_prepare_plugin(fakeDepthCamera CATEGORY device - TYPE fakeDepthCameraDriver - INCLUDE fakeDepthCameraDriver.h + TYPE FakeDepthCameraDriver + INCLUDE FakeDepthCameraDriver.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=RGBDSensorWrapper ) @@ -18,8 +19,10 @@ if(ENABLE_fakeDepthCamera) target_sources(yarp_fakeDepthCamera PRIVATE - fakeDepthCameraDriver.cpp - fakeDepthCameraDriver.h + FakeDepthCameraDriver.cpp + FakeDepthCameraDriver.h + FakeDepthCameraDriver_ParamsParser.cpp + FakeDepthCameraDriver_ParamsParser.h ) target_link_libraries(yarp_fakeDepthCamera diff --git a/src/devices/fake/fakeDepthCamera/fakeDepthCameraDriver.cpp b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver.cpp similarity index 53% rename from src/devices/fake/fakeDepthCamera/fakeDepthCameraDriver.cpp rename to src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver.cpp index 727f59aee36..0b1485e6920 100644 --- a/src/devices/fake/fakeDepthCamera/fakeDepthCameraDriver.cpp +++ b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeDepthCameraDriver.h" +#include "FakeDepthCameraDriver.h" #include #include @@ -21,23 +21,16 @@ namespace { YARP_LOG_COMPONENT(FAKEDEPTHCAMERA, "yarp.device.fakeDepthCamera") } -fakeDepthCameraDriver::fakeDepthCameraDriver() : - rgb_h(480), - rgb_w(640), - dep_h(480), - dep_w(640), - rgb_Vfov(36), - rgb_Hfov(50), - dep_Vfov(36), - dep_Hfov(50), - dep_far(6), +FakeDepthCameraDriver::FakeDepthCameraDriver() : image(nullptr) {} -fakeDepthCameraDriver::~fakeDepthCameraDriver() = default; +FakeDepthCameraDriver::~FakeDepthCameraDriver() = default; -bool fakeDepthCameraDriver::open(Searchable& config) +bool FakeDepthCameraDriver::open(Searchable& config) { + if (!this->parseParams(config)) {return false;} + Property cfg; cfg.fromString(config.toString()); cfg.unput("device"); @@ -45,111 +38,86 @@ bool fakeDepthCameraDriver::open(Searchable& config) testgrabber.open(cfg); testgrabber.view(image); - std::vector > param; - param.emplace_back(&rgb_h, "rgb_h", 480.0); - param.emplace_back(&rgb_w, "rgb_w", 640.0); - param.emplace_back(&dep_h, "rgb_h", 480.0); - param.emplace_back(&dep_w, "rgb_w", 640.0); - param.emplace_back(&accuracy, "accuracy", 0.001); - param.emplace_back(&rgb_Vfov, "rgb_Vfov", 50.0); - param.emplace_back(&rgb_Hfov, "rgb_Hfov", 36.0); - param.emplace_back(&dep_Vfov, "dep_Vfov", 50.0); - param.emplace_back(&dep_Hfov, "dep_Hfov", 36.0); - param.emplace_back(&dep_near, "dep_near", 0.2); - param.emplace_back(&dep_far, "dep_far", 6.0); - for (auto p : param) - { - if (config.check(std::get<1>(p))) - { - *std::get<0>(p) = config.find(std::get<1>(p)).asFloat64(); - } - else - { - *std::get<0>(p) = std::get<2>(p); - } - - } - return true; } -bool fakeDepthCameraDriver::close() +bool FakeDepthCameraDriver::close() { return true; } -int fakeDepthCameraDriver::getRgbHeight() +int FakeDepthCameraDriver::getRgbHeight() { return image->height(); } -int fakeDepthCameraDriver::getRgbWidth() +int FakeDepthCameraDriver::getRgbWidth() { return image->width(); } -bool fakeDepthCameraDriver::getRgbSupportedConfigurations(yarp::sig::VectorOf &configurations) +bool FakeDepthCameraDriver::getRgbSupportedConfigurations(yarp::sig::VectorOf &configurations) { yCWarning(FAKEDEPTHCAMERA) << "getRgbSupportedConfigurations not implemented yet"; return false; } -bool fakeDepthCameraDriver::getRgbResolution(int &width, int &height) +bool FakeDepthCameraDriver::getRgbResolution(int &width, int &height) { width = image->width(); height = image->height(); return true; } -bool fakeDepthCameraDriver::setRgbResolution(int width, int height) +bool FakeDepthCameraDriver::setRgbResolution(int width, int height) { return false; } -bool fakeDepthCameraDriver::setDepthResolution(int width, int height) +bool FakeDepthCameraDriver::setDepthResolution(int width, int height) { return false; } -bool fakeDepthCameraDriver::setRgbFOV(double horizontalFov, double verticalFov) +bool FakeDepthCameraDriver::setRgbFOV(double horizontalFov, double verticalFov) { - rgb_Hfov = horizontalFov; - rgb_Vfov = verticalFov; + m_rgb_Hfov = horizontalFov; + m_rgb_Vfov = verticalFov; return true; } -bool fakeDepthCameraDriver::setDepthFOV(double horizontalFov, double verticalFov) +bool FakeDepthCameraDriver::setDepthFOV(double horizontalFov, double verticalFov) { - dep_Hfov = horizontalFov; - dep_Vfov = verticalFov; + m_dep_Hfov = horizontalFov; + m_dep_Vfov = verticalFov; return true; } -bool fakeDepthCameraDriver::setDepthAccuracy(double in_accuracy) +bool FakeDepthCameraDriver::setDepthAccuracy(double in_accuracy) { - accuracy = in_accuracy; + m_accuracy = in_accuracy; return true; } -bool fakeDepthCameraDriver::getRgbFOV(double &horizontalFov, double &verticalFov) +bool FakeDepthCameraDriver::getRgbFOV(double &horizontalFov, double &verticalFov) { - horizontalFov = rgb_Hfov; - verticalFov = rgb_Vfov; + horizontalFov = m_rgb_Hfov; + verticalFov = m_rgb_Vfov; return false; } -bool fakeDepthCameraDriver::getRgbMirroring(bool& mirror) +bool FakeDepthCameraDriver::getRgbMirroring(bool& mirror) { mirror = false; return true; } -bool fakeDepthCameraDriver::setRgbMirroring(bool mirror) +bool FakeDepthCameraDriver::setRgbMirroring(bool mirror) { return false; } -bool fakeDepthCameraDriver::getRgbIntrinsicParam(Property& intrinsic) +bool FakeDepthCameraDriver::getRgbIntrinsicParam(Property& intrinsic) { intrinsic.put("physFocalLength", 0.5); intrinsic.put("focalLengthX", 512); @@ -167,24 +135,24 @@ bool fakeDepthCameraDriver::getRgbIntrinsicParam(Property& intrinsic) return true; } -int fakeDepthCameraDriver::getDepthHeight() +int FakeDepthCameraDriver::getDepthHeight() { return image->height(); } -int fakeDepthCameraDriver::getDepthWidth() +int FakeDepthCameraDriver::getDepthWidth() { return image->width(); } -bool fakeDepthCameraDriver::getDepthFOV(double& horizontalFov, double& verticalFov) +bool FakeDepthCameraDriver::getDepthFOV(double& horizontalFov, double& verticalFov) { - horizontalFov = dep_Hfov; - verticalFov = dep_Vfov; + horizontalFov = m_dep_Hfov; + verticalFov = m_dep_Vfov; return false; } -bool fakeDepthCameraDriver::getDepthIntrinsicParam(Property& intrinsic) +bool FakeDepthCameraDriver::getDepthIntrinsicParam(Property& intrinsic) { intrinsic.put("physFocalLength", 0.5); intrinsic.put("focalLengthX", 512); @@ -202,37 +170,37 @@ bool fakeDepthCameraDriver::getDepthIntrinsicParam(Property& intrinsic) return true; } -double fakeDepthCameraDriver::getDepthAccuracy() +double FakeDepthCameraDriver::getDepthAccuracy() { - return accuracy; + return m_accuracy; } -bool fakeDepthCameraDriver::getDepthClipPlanes(double& nearPlane, double& farPlane) +bool FakeDepthCameraDriver::getDepthClipPlanes(double& nearPlane, double& farPlane) { - nearPlane = dep_near; - farPlane = dep_far; + nearPlane = m_dep_near; + farPlane = m_dep_far; return true; } -bool fakeDepthCameraDriver::setDepthClipPlanes(double nearPlane, double farPlane) +bool FakeDepthCameraDriver::setDepthClipPlanes(double nearPlane, double farPlane) { - dep_near = nearPlane; - dep_far = farPlane; + m_dep_near = nearPlane; + m_dep_far = farPlane; return true; } -bool fakeDepthCameraDriver::getDepthMirroring(bool& mirror) +bool FakeDepthCameraDriver::getDepthMirroring(bool& mirror) { mirror = false; return true; } -bool fakeDepthCameraDriver::setDepthMirroring(bool mirror) +bool FakeDepthCameraDriver::setDepthMirroring(bool mirror) { return false; } -bool fakeDepthCameraDriver::getExtrinsicParam(Matrix& extrinsic) +bool FakeDepthCameraDriver::getExtrinsicParam(Matrix& extrinsic) { extrinsic.resize(4, 4); extrinsic.zero(); @@ -244,7 +212,7 @@ bool fakeDepthCameraDriver::getExtrinsicParam(Matrix& extrinsic) return true; } -bool fakeDepthCameraDriver::getRgbImage(FlexImage& rgbImage, Stamp* timeStamp) +bool FakeDepthCameraDriver::getRgbImage(FlexImage& rgbImage, Stamp* timeStamp) { if (!image->getImage(imageof)) {return false;} rgbImage.setPixelCode(VOCAB_PIXEL_RGB); @@ -256,7 +224,7 @@ bool fakeDepthCameraDriver::getRgbImage(FlexImage& rgbImage, Stamp* timeStamp) return true; } -bool fakeDepthCameraDriver::getDepthImage(ImageOf& depthImage, Stamp* timeStamp) +bool FakeDepthCameraDriver::getDepthImage(ImageOf& depthImage, Stamp* timeStamp) { if (!image->getImage(imageof)) {return false;} depthImage.resize(imageof); @@ -274,17 +242,17 @@ bool fakeDepthCameraDriver::getDepthImage(ImageOf& depthImage, Stamp return true; } -bool fakeDepthCameraDriver::getImages(FlexImage& colorFrame, ImageOf& depthFrame, Stamp* colorStamp, Stamp* depthStamp) +bool FakeDepthCameraDriver::getImages(FlexImage& colorFrame, ImageOf& depthFrame, Stamp* colorStamp, Stamp* depthStamp) { return getRgbImage(colorFrame, colorStamp) & getDepthImage(depthFrame, depthStamp); } -IRGBDSensor::RGBDSensor_status fakeDepthCameraDriver::getSensorStatus() +IRGBDSensor::RGBDSensor_status FakeDepthCameraDriver::getSensorStatus() { return RGBD_SENSOR_OK_IN_USE; } -std::string fakeDepthCameraDriver::getLastErrorMsg(Stamp* timeStamp) +std::string FakeDepthCameraDriver::getLastErrorMsg(Stamp* timeStamp) { return "no error"; } diff --git a/src/devices/fake/fakeDepthCamera/fakeDepthCameraDriver.h b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver.h similarity index 84% rename from src/devices/fake/fakeDepthCamera/fakeDepthCameraDriver.h rename to src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver.h index 0f818e1b557..8b18aceab92 100644 --- a/src/devices/fake/fakeDepthCamera/fakeDepthCameraDriver.h +++ b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver.h @@ -14,15 +14,22 @@ #include #include #include +#include "FakeDepthCameraDriver_ParamsParser.h" - /** - * @ingroup dev_impl_fake - * - * \brief `fakeDepthCamera`: Documentation to be added - */ -class fakeDepthCameraDriver : +/** + * @ingroup dev_impl_fake + * + * \brief `fakeDepthCamera`: Documentation to be added + * + * Parameters required by this device are shown in class: FakeDepthCameraDriver_ParamsParser + * + * The device internally opens a fakeFrameGrabber, so check also FakeFrameGrabber_ParamsParser + */ + +class FakeDepthCameraDriver : public yarp::dev::DeviceDriver, - public yarp::dev::IRGBDSensor + public yarp::dev::IRGBDSensor, + public FakeDepthCameraDriver_ParamsParser { private: typedef yarp::sig::ImageOf depthImage; @@ -31,8 +38,8 @@ class fakeDepthCameraDriver : typedef yarp::sig::FlexImage FlexImage; public: - fakeDepthCameraDriver(); - ~fakeDepthCameraDriver() override; + FakeDepthCameraDriver(); + ~FakeDepthCameraDriver() override; // DeviceDriver bool open(yarp::os::Searchable& config) override; @@ -73,18 +80,6 @@ class fakeDepthCameraDriver : std::string getLastErrorMsg(Stamp* timeStamp = nullptr) override; private: - double rgb_h{480}; - double rgb_w{640}; - double dep_h{480}; - double dep_w{640}; - double accuracy{0.001}; - double rgb_Vfov{36}; - double rgb_Hfov{50}; - double dep_Vfov{36}; - double dep_Hfov{50}; - double dep_near{0.4}; - double dep_far{6}; - yarp::sig::ImageOf imageof; yarp::dev::PolyDriver testgrabber; yarp::dev::IFrameGrabberImage* image; diff --git a/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_ParamsParser.cpp b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_ParamsParser.cpp new file mode 100644 index 00000000000..ea2b113530f --- /dev/null +++ b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_ParamsParser.cpp @@ -0,0 +1,263 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:29 2024 + + +#include "FakeDepthCameraDriver_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeDepthCameraDriverParamsCOMPONENT, "yarp.device.FakeDepthCameraDriver") +} + + +FakeDepthCameraDriver_ParamsParser::FakeDepthCameraDriver_ParamsParser() +{ +} + + +std::vector FakeDepthCameraDriver_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("rgb_h"); + params.push_back("rgb_w"); + params.push_back("dep_h"); + params.push_back("dep_w"); + params.push_back("accuracy"); + params.push_back("rgb_Vfov"); + params.push_back("rgb_Hfov"); + params.push_back("dep_Vfov"); + params.push_back("dep_Hfov"); + params.push_back("dep_near"); + params.push_back("dep_far"); + return params; +} + + +bool FakeDepthCameraDriver_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter rgb_h + { + if (config.check("rgb_h")) + { + m_rgb_h = config.find("rgb_h").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'rgb_h' using value:" << m_rgb_h; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'rgb_h' using DEFAULT value:" << m_rgb_h; + } + prop_check.unput("rgb_h"); + } + + //Parser of parameter rgb_w + { + if (config.check("rgb_w")) + { + m_rgb_w = config.find("rgb_w").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'rgb_w' using value:" << m_rgb_w; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'rgb_w' using DEFAULT value:" << m_rgb_w; + } + prop_check.unput("rgb_w"); + } + + //Parser of parameter dep_h + { + if (config.check("dep_h")) + { + m_dep_h = config.find("dep_h").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_h' using value:" << m_dep_h; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_h' using DEFAULT value:" << m_dep_h; + } + prop_check.unput("dep_h"); + } + + //Parser of parameter dep_w + { + if (config.check("dep_w")) + { + m_dep_w = config.find("dep_w").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_w' using value:" << m_dep_w; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_w' using DEFAULT value:" << m_dep_w; + } + prop_check.unput("dep_w"); + } + + //Parser of parameter accuracy + { + if (config.check("accuracy")) + { + m_accuracy = config.find("accuracy").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'accuracy' using value:" << m_accuracy; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'accuracy' using DEFAULT value:" << m_accuracy; + } + prop_check.unput("accuracy"); + } + + //Parser of parameter rgb_Vfov + { + if (config.check("rgb_Vfov")) + { + m_rgb_Vfov = config.find("rgb_Vfov").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'rgb_Vfov' using value:" << m_rgb_Vfov; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'rgb_Vfov' using DEFAULT value:" << m_rgb_Vfov; + } + prop_check.unput("rgb_Vfov"); + } + + //Parser of parameter rgb_Hfov + { + if (config.check("rgb_Hfov")) + { + m_rgb_Hfov = config.find("rgb_Hfov").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'rgb_Hfov' using value:" << m_rgb_Hfov; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'rgb_Hfov' using DEFAULT value:" << m_rgb_Hfov; + } + prop_check.unput("rgb_Hfov"); + } + + //Parser of parameter dep_Vfov + { + if (config.check("dep_Vfov")) + { + m_dep_Vfov = config.find("dep_Vfov").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_Vfov' using value:" << m_dep_Vfov; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_Vfov' using DEFAULT value:" << m_dep_Vfov; + } + prop_check.unput("dep_Vfov"); + } + + //Parser of parameter dep_Hfov + { + if (config.check("dep_Hfov")) + { + m_dep_Hfov = config.find("dep_Hfov").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_Hfov' using value:" << m_dep_Hfov; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_Hfov' using DEFAULT value:" << m_dep_Hfov; + } + prop_check.unput("dep_Hfov"); + } + + //Parser of parameter dep_near + { + if (config.check("dep_near")) + { + m_dep_near = config.find("dep_near").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_near' using value:" << m_dep_near; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_near' using DEFAULT value:" << m_dep_near; + } + prop_check.unput("dep_near"); + } + + //Parser of parameter dep_far + { + if (config.check("dep_far")) + { + m_dep_far = config.find("dep_far").asFloat64(); + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_far' using value:" << m_dep_far; + } + else + { + yCInfo(FakeDepthCameraDriverParamsCOMPONENT) << "Parameter 'dep_far' using DEFAULT value:" << m_dep_far; + } + prop_check.unput("dep_far"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeDepthCameraDriverParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeDepthCameraDriverParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeDepthCameraDriver_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeDepthCameraDriver\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'rgb_h': rgb_h\n"); + doc = doc + std::string("'rgb_w': rgb_w\n"); + doc = doc + std::string("'dep_h': dep_h\n"); + doc = doc + std::string("'dep_w': dep_w\n"); + doc = doc + std::string("'accuracy': accuracy\n"); + doc = doc + std::string("'rgb_Vfov': rgb_Vfov\n"); + doc = doc + std::string("'rgb_Hfov': rgb_Hfov\n"); + doc = doc + std::string("'dep_Vfov': dep_Vfov\n"); + doc = doc + std::string("'dep_Hfov': dep_Hfov\n"); + doc = doc + std::string("'dep_near': dep_near\n"); + doc = doc + std::string("'dep_far': dep_far\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeDepthCamera --rgb_h 480.0 --rgb_w 640.0 --dep_h 480.0 --dep_w 640.0 --accuracy 0.001 --rgb_Vfov 50.0 --rgb_Hfov 36.0 --dep_Vfov 50.0 --dep_Hfov 36.0 --dep_near 0.2 --dep_far 6.0\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeDepthCamera\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_ParamsParser.h b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_ParamsParser.h new file mode 100644 index 00000000000..96e4fddc79c --- /dev/null +++ b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_ParamsParser.h @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:29 2024 + + +#ifndef FAKEDEPTHCAMERADRIVER_PARAMSPARSER_H +#define FAKEDEPTHCAMERADRIVER_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeDepthCameraDriver. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-----------:|:----------------------------------------:| +* | - | rgb_h | double | - | 480.0 | 0 | rgb_h | - | +* | - | rgb_w | double | - | 640.0 | 0 | rgb_w | - | +* | - | dep_h | double | - | 480.0 | 0 | dep_h | probably it should be identical to rgb_h | +* | - | dep_w | double | - | 640.0 | 0 | dep_w | probably it should be identical to rgb_w | +* | - | accuracy | double | - | 0.001 | 0 | accuracy | - | +* | - | rgb_Vfov | double | - | 50.0 | 0 | rgb_Vfov | - | +* | - | rgb_Hfov | double | - | 36.0 | 0 | rgb_Hfov | - | +* | - | dep_Vfov | double | - | 50.0 | 0 | dep_Vfov | - | +* | - | dep_Hfov | double | - | 36.0 | 0 | dep_Hfov | - | +* | - | dep_near | double | - | 0.2 | 0 | dep_near | - | +* | - | dep_far | double | - | 6.0 | 0 | dep_far | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeDepthCamera --rgb_h 480.0 --rgb_w 640.0 --dep_h 480.0 --dep_w 640.0 --accuracy 0.001 --rgb_Vfov 50.0 --rgb_Hfov 36.0 --dep_Vfov 50.0 --dep_Hfov 36.0 --dep_near 0.2 --dep_far 6.0 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeDepthCamera +* \endcode +* +*/ + +class FakeDepthCameraDriver_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeDepthCameraDriver_ParamsParser(); + ~FakeDepthCameraDriver_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeDepthCameraDriver"}; + const std::string m_device_name = {"fakeDepthCamera"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_rgb_h_defaultValue = {"480.0"}; + const std::string m_rgb_w_defaultValue = {"640.0"}; + const std::string m_dep_h_defaultValue = {"480.0"}; + const std::string m_dep_w_defaultValue = {"640.0"}; + const std::string m_accuracy_defaultValue = {"0.001"}; + const std::string m_rgb_Vfov_defaultValue = {"50.0"}; + const std::string m_rgb_Hfov_defaultValue = {"36.0"}; + const std::string m_dep_Vfov_defaultValue = {"50.0"}; + const std::string m_dep_Hfov_defaultValue = {"36.0"}; + const std::string m_dep_near_defaultValue = {"0.2"}; + const std::string m_dep_far_defaultValue = {"6.0"}; + + double m_rgb_h = {480.0}; + double m_rgb_w = {640.0}; + double m_dep_h = {480.0}; + double m_dep_w = {640.0}; + double m_accuracy = {0.001}; + double m_rgb_Vfov = {50.0}; + double m_rgb_Hfov = {36.0}; + double m_dep_Vfov = {50.0}; + double m_dep_Hfov = {36.0}; + double m_dep_near = {0.2}; + double m_dep_far = {6.0}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_params.md b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_params.md new file mode 100644 index 00000000000..ae22bd7e274 --- /dev/null +++ b/src/devices/fake/fakeDepthCamera/FakeDepthCameraDriver_params.md @@ -0,0 +1,11 @@ + * | | rgb_h | double | - | 480.0 | No | rgb_h | | + * | | rgb_w | double | - | 640.0 | No | rgb_w | | + * | | dep_h | double | - | 480.0 | No | dep_h | probably it should be identical to rgb_h | + * | | dep_w | double | - | 640.0 | No | dep_w | probably it should be identical to rgb_w | + * | | accuracy | double | - | 0.001 | No | accuracy | | + * | | rgb_Vfov | double | - | 50.0 | No | rgb_Vfov | | + * | | rgb_Hfov | double | - | 36.0 | No | rgb_Hfov | | + * | | dep_Vfov | double | - | 50.0 | No | dep_Vfov | | + * | | dep_Hfov | double | - | 36.0 | No | dep_Hfov | | + * | | dep_near | double | - | 0.2 | No | dep_near | | + * | | dep_far | double | - | 6.0 | No | dep_far | | diff --git a/src/devices/fake/fakeFrameGrabber/CMakeLists.txt b/src/devices/fake/fakeFrameGrabber/CMakeLists.txt index 8a457985595..326b3a0c90e 100644 --- a/src/devices/fake/fakeFrameGrabber/CMakeLists.txt +++ b/src/devices/fake/fakeFrameGrabber/CMakeLists.txt @@ -9,6 +9,7 @@ yarp_prepare_plugin(fakeFrameGrabber CATEGORY device TYPE FakeFrameGrabber INCLUDE FakeFrameGrabber.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=frameGrabber_nws_yarp ) @@ -20,6 +21,8 @@ if(ENABLE_fakeFrameGrabber) PRIVATE FakeFrameGrabber.cpp FakeFrameGrabber.h + FakeFrameGrabber_ParamsParser.cpp + FakeFrameGrabber_ParamsParser.h ) target_link_libraries(yarp_fakeFrameGrabber diff --git a/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber.cpp b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber.cpp index 47825395add..eb696187eae 100644 --- a/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber.cpp +++ b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber.cpp @@ -21,13 +21,6 @@ using namespace yarp::sig::draw; namespace { YARP_LOG_COMPONENT(FAKEFRAMEGRABBER, "yarp.device.fakeFrameGrabber") -constexpr yarp::conf::vocab32_t VOCAB_LINE = yarp::os::createVocab32('l','i','n','e'); -constexpr yarp::conf::vocab32_t VOCAB_BALL = yarp::os::createVocab32('b','a','l','l'); -constexpr yarp::conf::vocab32_t VOCAB_GRID = yarp::os::createVocab32('g','r','i','d'); -constexpr yarp::conf::vocab32_t VOCAB_RAND = yarp::os::createVocab32('r','a','n','d'); -constexpr yarp::conf::vocab32_t VOCAB_NONE = yarp::os::createVocab32('n','o','n','e'); -constexpr yarp::conf::vocab32_t VOCAB_GRID_MULTISIZE = yarp::os::createVocab32('s','i','z','e'); -constexpr yarp::conf::vocab32_t VOCAB_TIMETEXT = yarp::os::createVocab32('t','i','m','e'); //the following data are used by [time] test constexpr char num[12][16] @@ -144,7 +137,7 @@ bool FakeFrameGrabber::read(yarp::os::ConnectionReader& connection) } else if (command.get(0).asString() == "set_mode") { - mode= command.get(1).asVocab32(); + m_mode= command.get(1).asString(); reply.addString("ack"); } else if (command.get(0).asString() == "set_image") @@ -158,8 +151,8 @@ bool FakeFrameGrabber::read(yarp::os::ConnectionReader& connection) { if (yarp::sig::file::read(background, command.get(1).asString())) { - w = background.width(); - h = background.height(); + m_width = background.width(); + m_height = background.height(); have_bg = true; reply.addString("ack"); } @@ -173,10 +166,10 @@ bool FakeFrameGrabber::read(yarp::os::ConnectionReader& connection) else if (command.get(0).asString() == "set_topIsLow") { if (command.get(1).asString() == "off") { - topIsLow = false; + m_topIsLow = false; reply.addString("ack"); } else if (command.get(1).asString() == "on") { - topIsLow = true; + m_topIsLow = true; reply.addString("ack"); } else { reply.addString("err"); @@ -185,10 +178,10 @@ bool FakeFrameGrabber::read(yarp::os::ConnectionReader& connection) else if (command.get(0).asString() == "set_noise") { if (command.get(1).asString() == "off") { - add_noise = false; + m_add_noise = false; reply.addString("ack"); } else if (command.get(1).asString() == "on") { - add_noise = true; + m_add_noise = true; reply.addString("ack"); } else { reply.addString("err"); @@ -196,7 +189,7 @@ bool FakeFrameGrabber::read(yarp::os::ConnectionReader& connection) } else if (command.get(0).asString() == "set_snr") { - snr = yarp::conf::clamp(command.get(1).asFloat64(), 0.0, 1.0); + m_snr = yarp::conf::clamp(command.get(1).asFloat64(), 0.0, 1.0); reply.addString("ack"); } else @@ -219,39 +212,28 @@ bool FakeFrameGrabber::close() { return true; } -bool FakeFrameGrabber::open(yarp::os::Searchable& config) { - m_rpcPortName = config.check("fakeFrameGrabber_rpc_port", yarp::os::Value("/fakeFrameGrabber/rpc"), "rpc port for the fakeFrameGrabber").asString(); - w = config.check("width",yarp::os::Value(320), - "desired width of test image").asInt32(); - h = config.check("height",yarp::os::Value(240), - "desired height of test image").asInt32(); - horizontalFov=config.check("horizontalFov",Value(1.0), - "desired horizontal fov of test image").asFloat64(); - verticalFov=config.check("verticalFov",Value(2.0), - "desired vertical fov of test image").asFloat64(); - mirror=config.check("mirror",Value(false), - "mirroring disabled by default").asBool(); - syncro=config.check("syncro",Value(false), - "syncronize producer and consumer, so that all images are used once and only once").asBool(); - topIsLow=config.check("topIsLow",Value(true), - "explicitly set the topIsLow field in the images").asBool(); - intrinsic.put("physFocalLength",config.check("physFocalLength",Value(3.0),"Physical focal length of the fakeFrameGrabber").asFloat64()); - intrinsic.put("focalLengthX",config.check("focalLengthX",Value(4.0),"Horizontal component of the focal length of the fakeFrameGrabber").asFloat64()); - intrinsic.put("focalLengthY",config.check("focalLengthY",Value(5.0),"Vertical component of the focal length of the fakeFrameGrabber").asFloat64()); - intrinsic.put("principalPointX",config.check("principalPointX",Value(6.0),"X coordinate of the principal point of the fakeFrameGrabber").asFloat64()); - intrinsic.put("principalPointY",config.check("principalPointY",Value(7.0),"Y coordinate of the principal point of the fakeFrameGrabber").asFloat64()); - - Value* retM; - retM=Value::makeList("1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0"); - intrinsic.put("rectificationMatrix",config.check("rectificationMatrix",*retM,"Matrix that describes the lens' distortion(fake)")); - delete retM; - - intrinsic.put("distortionModel",config.check("distortionModel",Value("FishEye"),"Reference to group of parameters describing the distortion model of the camera").asString()); - intrinsic.put("k1",config.check("k1",Value(8.0),"Radial distortion coefficient of the lens(fake)").asFloat64()); - intrinsic.put("k2",config.check("k2",Value(9.0),"Radial distortion coefficient of the lens(fake)").asFloat64()); - intrinsic.put("k3",config.check("k3",Value(10.0),"Radial distortion coefficient of the lens(fake)").asFloat64()); - intrinsic.put("t1",config.check("t1",Value(11.0),"Tangential distortion of the lens(fake)").asFloat64()); - intrinsic.put("t2",config.check("t2",Value(12.0),"Tangential distortion of the lens(fake)").asFloat64()); +bool FakeFrameGrabber::open(yarp::os::Searchable& config) +{ + if (!this->parseParams(config)) {return false;} + + m_intrinsic.put("physFocalLength",m_physFocalLength); + m_intrinsic.put("focalLengthX",m_focalLengthX); + m_intrinsic.put("focalLengthY",m_focalLengthY); + m_intrinsic.put("principalPointX",m_principalPointX); + m_intrinsic.put("principalPointY",m_principalPointY); + + Value val; + val.makeList(); + auto* bb = val.asList(); + for (double num : m_rectificationMatrix) { bb->addFloat64(num); } + m_intrinsic.put("rectificationMatrix",val); + + m_intrinsic.put("distortionModel", m_distortionModel); + m_intrinsic.put("k1",m_k1); + m_intrinsic.put("k2",m_k2); + m_intrinsic.put("k3",m_k3); + m_intrinsic.put("t1",m_t1); + m_intrinsic.put("t2",m_t2); //Only for debug CameraConfig conf1; conf1.height=128; @@ -274,74 +256,59 @@ bool FakeFrameGrabber::open(yarp::os::Searchable& config) { conf3.pixelCoding=VOCAB_PIXEL_MONO; configurations.push_back(conf3); - yarp::os::Value *val; - if (config.check("freq", val, "rate of test images in Hz")) { - freq = val->asFloat64(); - period = 1/freq; - } else if (config.check("period", val, - "period of test images in seconds")) { - period = val->asFloat64() / 1000.0; - if(period<=0) { - period =0; - freq = -1; - } + if (m_freq>0) + { + m_period = 1/ m_freq; + } + else if (m_period>0) + { + //ok + } + else + { + yCWarning(FAKEFRAMEGRABBER, "Either `period` or `freq` parameters must be a valid >0 value"); } - mode = config.check("mode", - yarp::os::Value(VOCAB_LINE, true), - "bouncy [ball], scrolly [line], grid [grid], grid multisize [size], random [rand], none [none], time test[time]").asVocab32(); - - if (config.check("src")) { - if (!yarp::sig::file::read(background, - config.check("src", - yarp::os::Value("test.ppm"), - "background image to use, if any").asString())) { + if (!m_src.empty()) + { + if (!yarp::sig::file::read(background, m_src)) + { + yCWarning(FAKEFRAMEGRABBER, "Unable to open file"); return false; } - if (background.width()>0) { - if (config.check("width") || config.check("height")) { - yCWarning(FAKEFRAMEGRABBER, "width and height option are ignored when passing a background image"); - } - w = background.width(); - h = background.height(); - have_bg = true; + } + if (background.width()>0) + { + if (m_width>0 || m_height>0) + { + yCWarning(FAKEFRAMEGRABBER, "width and height options are ignored when passing a background image"); } + m_width = background.width(); + m_height = background.height(); + have_bg = true; } - add_timestamp = config.check("timestamp", "should write the timestamp in the first bytes of the image"); - - add_noise = config.check("noise", "Should add noise to the image (uses snr)"); - - snr = yarp::conf::clamp(config.check("snr",Value(default_snr), "Signal noise ratio ([0.0-1.0] default 0.5)").asFloat64(), 0.0, 1.0); - use_bayer = config.check("bayer","should emit bayer test image?"); - use_mono = config.check("mono","should emit a monochrome image?"); - use_mono = use_mono||use_bayer; + m_snr = yarp::conf::clamp(m_snr, 0.0, 1.0); + m_mono = m_mono || m_bayer; - if (freq!=-1) { - yCInfo(FAKEFRAMEGRABBER, - "Test grabber period %g / freq %g , mode [%s]", - period, - freq, - yarp::os::Vocab32::decode(mode).c_str()); - } else { - yCInfo(FAKEFRAMEGRABBER, - "Test grabber period %g / freq [inf], mode [%s]", - period, - yarp::os::Vocab32::decode(mode).c_str()); - } + yCInfo(FAKEFRAMEGRABBER, + "Test grabber period %g / freq %g , mode %s", + m_period, + (1.0/m_period), + m_mode.c_str()); - bx = w/2; - by = h/2; + bx = m_width/2; + by = m_height/2; for (auto& buff : buffs) { - buff.resize(w, h); + buff.resize(m_width, m_height); buff.zero(); } - if (!m_rpcPort.open(m_rpcPortName.c_str())) + if (!m_rpcPort.open(m_fakeFrameGrabber_rpc_port.c_str())) { - yCError(FAKEFRAMEGRABBER, "Failed to open port %s", m_rpcPortName.c_str()); + yCError(FAKEFRAMEGRABBER, "Failed to open port %s", m_fakeFrameGrabber_rpc_port.c_str()); yCError(FAKEFRAMEGRABBER, "Do you have multiple FakeFrameGrabber devices running?"); yCError(FAKEFRAMEGRABBER, "If yes, use the `fakeFrameGrabber_rpc_port` parameter to set a different name for each of them"); return false; @@ -360,7 +327,7 @@ void FakeFrameGrabber::timing() { first = now; prev = now; } - double dt = period-(now-prev); + double dt = m_period-(now-prev); if (dt>0) { yarp::os::Time::delay(dt); @@ -368,23 +335,23 @@ void FakeFrameGrabber::timing() { // this is the controlled instant when we consider the // image as going out - prev += period; + prev += m_period; } int FakeFrameGrabber::height() const { - return h; + return m_height; } int FakeFrameGrabber::width() const { - return w; + return m_width; } int FakeFrameGrabber::getRgbHeight(){ - return h; + return m_height; } int FakeFrameGrabber::getRgbWidth(){ - return w; + return m_width; } bool FakeFrameGrabber::getRgbSupportedConfigurations(yarp::sig::VectorOf &configurations){ @@ -393,40 +360,40 @@ bool FakeFrameGrabber::getRgbSupportedConfigurations(yarp::sig::VectorOfhorizontalFov; - verticalFov=this->verticalFov; + horizontalFov=this->m_horizontalFov; + verticalFov=this->m_verticalFov; return true; } bool FakeFrameGrabber::setRgbFOV(double horizontalFov, double verticalFov){ - this->horizontalFov=horizontalFov; - this->verticalFov=verticalFov; + this->m_horizontalFov=horizontalFov; + this->m_verticalFov=verticalFov; return true; } bool FakeFrameGrabber::getRgbIntrinsicParam(yarp::os::Property &intrinsic){ - intrinsic=this->intrinsic; + intrinsic=this->m_intrinsic; return true; } bool FakeFrameGrabber::getRgbMirroring(bool &mirror){ - mirror=this->mirror; + mirror=this->m_mirror; return true;} bool FakeFrameGrabber::setRgbMirroring(bool mirror){ - this->mirror=mirror; + this->m_mirror =mirror; return true; } @@ -434,7 +401,7 @@ void FakeFrameGrabber::run() { while (!isStopping()) { for (size_t i = 0; i < 2 && !isStopping(); ++i) { - if (!syncro) { + if (!m_syncro) { std::unique_lock lk(mutex[i]); createTestImage(buffs[i], buff_ts[i]); timing(); @@ -463,7 +430,7 @@ void FakeFrameGrabber::run() void FakeFrameGrabber::onStop() { // Unlock any blocked thread. - if (syncro) { + if (m_syncro) { for (size_t i = 0; i < 2; ++i) { std::unique_lock lk(mutex[i]); img_consumed[i] = true; @@ -481,7 +448,7 @@ bool FakeFrameGrabber::getImage(yarp::sig::ImageOf& image) return false; } - if (!syncro) { + if (!m_syncro) { curr_buff_mutex.lock(); size_t cb = curr_buff; std::unique_lock lk(mutex[cb]); @@ -518,12 +485,12 @@ bool FakeFrameGrabber::getImage(yarp::sig::ImageOf& image) return false; } - if (!syncro) { + if (!m_syncro) { curr_buff_mutex.lock(); size_t cb = curr_buff; std::unique_lock lk(mutex[cb]); curr_buff_mutex.unlock(); - if (use_bayer) { + if (m_bayer) { makeSimpleBayer(buffs[cb], image); } else { image.copy(buffs[cb]); @@ -538,7 +505,7 @@ bool FakeFrameGrabber::getImage(yarp::sig::ImageOf& image) if (!isRunning()) { return false; } - if (use_bayer) { + if (m_bayer) { makeSimpleBayer(buffs[cb], image); } else { image.copy(buffs[cb]); @@ -576,10 +543,10 @@ yarp::os::Stamp FakeFrameGrabber::getLastInputStamp() { bool FakeFrameGrabber::hasAudio() { return false; } -bool FakeFrameGrabber::hasVideo() { return !use_mono; } +bool FakeFrameGrabber::hasVideo() { return !m_mono; } bool FakeFrameGrabber::hasRawVideo() { - return use_mono; + return m_mono; } bool FakeFrameGrabber::getCameraDescription(CameraDescriptor *camera) { return false; } @@ -651,10 +618,10 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& t -= (((t*1000) - static_cast(t*1000)) / 1000); t += 0.00042; timestamp = t; - image.resize(w,h); + image.resize(m_width,m_height); - switch (mode) { - case VOCAB_TIMETEXT: + if (m_mode == "[Time]") + { { if (have_bg) { image.copy(background); @@ -671,8 +638,9 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& printTime((unsigned char*)image.getRawImage(), image.width(), image.height(), 0, 0, txtbuf, len); } } - break; - case VOCAB_BALL: + } + else if (m_mode == "[ball]") + { { if (have_bg) { image.copy(background); @@ -691,16 +659,17 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& int delta_y = (rnd % 5) - 2; by += delta_y; } else { - int dx = w/2 - bx; - int dy = h/2 - by; + int dx = m_width/2 - bx; + int dy = m_height/2 - by; if (dx>0) { bx++; } if (dx<0) { bx--; } if (dy>0) { by++; } if (dy<0) { by--; } } } - break; - case VOCAB_GRID: + } + else if (m_mode == "[grid]") + { { size_t ww = image.width(); size_t hh = image.height(); @@ -718,8 +687,8 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& } } } - break; - case VOCAB_GRID_MULTISIZE: + } + else if (m_mode == "[size]") { static int count = 0; count++; @@ -740,8 +709,8 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& count = 0; } - size_t ww = w = image.width(); - size_t hh = h = image.height(); + size_t ww = m_width = image.width(); + size_t hh = m_height = image.height(); if (ww>1 && hh>1) { for (size_t x = 0; x& } } } - break; - case VOCAB_LINE: - default: + else if (m_mode == "[line]") + { { if (have_bg) { image.copy(background); @@ -769,8 +737,9 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& image.pixel(i,ct).r = 255; } } - break; - case VOCAB_RAND: + } + else if (m_mode == "[rand]") + { { static unsigned char r = 128; static unsigned char g = 128; @@ -790,8 +759,9 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& } } } - break; - case VOCAB_NONE: + } + else if (m_mode == "[none]") + { { if (have_bg) { image.copy(background); @@ -799,8 +769,12 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& image.zero(); } } - break; } + else + { + yCError(FAKEFRAMEGRABBER, "Invalid mode %s", m_mode.c_str()); + } + ct++; if (ct>=image.height()) { ct = 0; @@ -812,21 +786,21 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& bx = image.width()-1; } - if (add_noise) { - static const double nsr = 1.0 - snr; + if (m_add_noise) { + static const double nsr = 1.0 - m_snr; for (size_t x = 0; x < image.width(); ++x) { for (size_t y = 0; y < image.height(); ++y) { auto rand = ucdist(randengine); image.pixel(x,y) = PixelRgb { - static_cast(image.pixel(x,y).r * snr + (rand * nsr * 255)), - static_cast(image.pixel(x,y).g * snr + (rand * nsr * 255)), - static_cast(image.pixel(x,y).b * snr + (rand * nsr * 255)) + static_cast(image.pixel(x,y).r * m_snr + (rand * nsr * 255)), + static_cast(image.pixel(x,y).g * m_snr + (rand * nsr * 255)), + static_cast(image.pixel(x,y).b * m_snr + (rand * nsr * 255)) }; } } } - if (add_timestamp) { + if (m_add_timestamp) { char ttxt[50]; std::snprintf(ttxt, 50, "%021.10f", timestamp); image.pixel(0, 0).r = ttxt[0] - '0'; @@ -858,7 +832,7 @@ void FakeFrameGrabber::createTestImage(yarp::sig::ImageOf& image.pixel(6, 0).b = ttxt[20] - '0'; } - image.setTopIsLowIndex(topIsLow); + image.setTopIsLowIndex(m_topIsLow); } diff --git a/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber.h b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber.h index 1c7c5cd7b3c..93e48fca21c 100644 --- a/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber.h +++ b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber.h @@ -25,6 +25,7 @@ #include #include #include +#include "FakeFrameGrabber_ParamsParser.h" /** * @ingroup dev_impl_media dev_impl_fake @@ -33,6 +34,8 @@ * * Implements the IFrameGrabberImage and IFrameGrabberControls * interfaces. + * + * Parameters required by this device are shown in class: FakeFrameGrabber_ParamsParser */ class FakeFrameGrabber : #ifndef YARP_NO_DEPRECATED // Since YARP 3.5` @@ -47,7 +50,8 @@ class FakeFrameGrabber : public yarp::dev::IAudioVisualStream, public yarp::dev::IRgbVisualParams, public yarp::os::Thread, - public yarp::os::PortReader + public yarp::os::PortReader, + public FakeFrameGrabber_ParamsParser { public: FakeFrameGrabber() = default; @@ -60,19 +64,6 @@ class FakeFrameGrabber : bool close() override; /** - * Configure with a set of options. These are: - * - * - * - * - * - * - * - * - * - * - *
width Width of image (default 128).
height Height of image (default 128).
freq Frequency in Hz to generate images (default 20Hz).
period Inverse of freq - only set one of these.
mode Can be [line] (default), [ball], [grid], [rand], [nois], [none].
src Image file to read from (default: none).
bayer Emit a bayer image.
mono Emit a monochrome image.
snr Signal noise ratio ([nois] mode only) (default 0.5).
- * * @param config The options to use * @return true iff the object could be configured. */ @@ -165,32 +156,16 @@ class FakeFrameGrabber : static constexpr size_t default_freq = 30; static constexpr double default_snr = 0.5; - std::string m_rpcPortName="/fakeFrameGrabber/rpc"; yarp::os::Port m_rpcPort; size_t ct{0}; size_t bx{0}; size_t by{0}; - size_t w{default_w}; - size_t h{default_h}; unsigned long rnd{0}; - double freq{default_freq}; - double period{1/freq}; double first{0}; - double horizontalFov{0.0}; - double verticalFov{0.0}; double prev{0}; bool have_bg{false}; - int mode{0}; - bool add_timestamp{false}; - bool add_noise{false}; - double snr{default_snr}; - bool use_bayer{false}; - bool use_mono{false}; - bool mirror{false}; - bool syncro{false}; - bool topIsLow{true}; - yarp::os::Property intrinsic; + yarp::os::Property m_intrinsic; yarp::sig::VectorOf configurations; std::random_device rnddev; diff --git a/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_ParamsParser.cpp b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_ParamsParser.cpp new file mode 100644 index 00000000000..e53bb98a1fc --- /dev/null +++ b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_ParamsParser.cpp @@ -0,0 +1,585 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#include "FakeFrameGrabber_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeFrameGrabberParamsCOMPONENT, "yarp.device.FakeFrameGrabber") +} + + +FakeFrameGrabber_ParamsParser::FakeFrameGrabber_ParamsParser() +{ + //Default value of parameterrectificationMatrix + { + m_rectificationMatrix.clear(); + yarp::os::Value tempVal; + tempVal.fromString(m_rectificationMatrix_defaultValue.c_str()); + yarp::os::Bottle* tempBot = tempVal.asList(); + if (tempBot && tempBot->size()!=0) + { + for (size_t i=0; isize(); i++) + { + m_rectificationMatrix.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yError() <<"parameter 'rectificationMatrix' is not a properly formatted bottle"; + } + } + +} + + +std::vector FakeFrameGrabber_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("width"); + params.push_back("height"); + params.push_back("horizontalFov"); + params.push_back("verticalFov"); + params.push_back("fakeFrameGrabber_rpc_port"); + params.push_back("mirror"); + params.push_back("syncro"); + params.push_back("topIsLow"); + params.push_back("physFocalLength"); + params.push_back("focalLengthX"); + params.push_back("focalLengthY"); + params.push_back("principalPointX"); + params.push_back("principalPointY"); + params.push_back("distortionModel"); + params.push_back("k1"); + params.push_back("k2"); + params.push_back("k3"); + params.push_back("t1"); + params.push_back("t2"); + params.push_back("freq"); + params.push_back("period"); + params.push_back("mode"); + params.push_back("src"); + params.push_back("add_timestamp"); + params.push_back("add_noise"); + params.push_back("bayer"); + params.push_back("mono"); + params.push_back("snr"); + params.push_back("rectificationMatrix"); + return params; +} + + +bool FakeFrameGrabber_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter width + { + if (config.check("width")) + { + m_width = config.find("width").asInt64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'width' using value:" << m_width; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'width' using DEFAULT value:" << m_width; + } + prop_check.unput("width"); + } + + //Parser of parameter height + { + if (config.check("height")) + { + m_height = config.find("height").asInt64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'height' using value:" << m_height; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'height' using DEFAULT value:" << m_height; + } + prop_check.unput("height"); + } + + //Parser of parameter horizontalFov + { + if (config.check("horizontalFov")) + { + m_horizontalFov = config.find("horizontalFov").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'horizontalFov' using value:" << m_horizontalFov; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'horizontalFov' using DEFAULT value:" << m_horizontalFov; + } + prop_check.unput("horizontalFov"); + } + + //Parser of parameter verticalFov + { + if (config.check("verticalFov")) + { + m_verticalFov = config.find("verticalFov").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'verticalFov' using value:" << m_verticalFov; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'verticalFov' using DEFAULT value:" << m_verticalFov; + } + prop_check.unput("verticalFov"); + } + + //Parser of parameter fakeFrameGrabber_rpc_port + { + if (config.check("fakeFrameGrabber_rpc_port")) + { + m_fakeFrameGrabber_rpc_port = config.find("fakeFrameGrabber_rpc_port").asString(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'fakeFrameGrabber_rpc_port' using value:" << m_fakeFrameGrabber_rpc_port; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'fakeFrameGrabber_rpc_port' using DEFAULT value:" << m_fakeFrameGrabber_rpc_port; + } + prop_check.unput("fakeFrameGrabber_rpc_port"); + } + + //Parser of parameter mirror + { + if (config.check("mirror")) + { + m_mirror = config.find("mirror").asBool(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'mirror' using value:" << m_mirror; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'mirror' using DEFAULT value:" << m_mirror; + } + prop_check.unput("mirror"); + } + + //Parser of parameter syncro + { + if (config.check("syncro")) + { + m_syncro = config.find("syncro").asBool(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'syncro' using value:" << m_syncro; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'syncro' using DEFAULT value:" << m_syncro; + } + prop_check.unput("syncro"); + } + + //Parser of parameter topIsLow + { + if (config.check("topIsLow")) + { + m_topIsLow = config.find("topIsLow").asBool(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'topIsLow' using value:" << m_topIsLow; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'topIsLow' using DEFAULT value:" << m_topIsLow; + } + prop_check.unput("topIsLow"); + } + + //Parser of parameter physFocalLength + { + if (config.check("physFocalLength")) + { + m_physFocalLength = config.find("physFocalLength").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'physFocalLength' using value:" << m_physFocalLength; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'physFocalLength' using DEFAULT value:" << m_physFocalLength; + } + prop_check.unput("physFocalLength"); + } + + //Parser of parameter focalLengthX + { + if (config.check("focalLengthX")) + { + m_focalLengthX = config.find("focalLengthX").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'focalLengthX' using value:" << m_focalLengthX; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'focalLengthX' using DEFAULT value:" << m_focalLengthX; + } + prop_check.unput("focalLengthX"); + } + + //Parser of parameter focalLengthY + { + if (config.check("focalLengthY")) + { + m_focalLengthY = config.find("focalLengthY").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'focalLengthY' using value:" << m_focalLengthY; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'focalLengthY' using DEFAULT value:" << m_focalLengthY; + } + prop_check.unput("focalLengthY"); + } + + //Parser of parameter principalPointX + { + if (config.check("principalPointX")) + { + m_principalPointX = config.find("principalPointX").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'principalPointX' using value:" << m_principalPointX; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'principalPointX' using DEFAULT value:" << m_principalPointX; + } + prop_check.unput("principalPointX"); + } + + //Parser of parameter principalPointY + { + if (config.check("principalPointY")) + { + m_principalPointY = config.find("principalPointY").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'principalPointY' using value:" << m_principalPointY; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'principalPointY' using DEFAULT value:" << m_principalPointY; + } + prop_check.unput("principalPointY"); + } + + //Parser of parameter distortionModel + { + if (config.check("distortionModel")) + { + m_distortionModel = config.find("distortionModel").asString(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'distortionModel' using value:" << m_distortionModel; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'distortionModel' using DEFAULT value:" << m_distortionModel; + } + prop_check.unput("distortionModel"); + } + + //Parser of parameter k1 + { + if (config.check("k1")) + { + m_k1 = config.find("k1").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'k1' using value:" << m_k1; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'k1' using DEFAULT value:" << m_k1; + } + prop_check.unput("k1"); + } + + //Parser of parameter k2 + { + if (config.check("k2")) + { + m_k2 = config.find("k2").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'k2' using value:" << m_k2; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'k2' using DEFAULT value:" << m_k2; + } + prop_check.unput("k2"); + } + + //Parser of parameter k3 + { + if (config.check("k3")) + { + m_k3 = config.find("k3").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'k3' using value:" << m_k3; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'k3' using DEFAULT value:" << m_k3; + } + prop_check.unput("k3"); + } + + //Parser of parameter t1 + { + if (config.check("t1")) + { + m_t1 = config.find("t1").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 't1' using value:" << m_t1; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 't1' using DEFAULT value:" << m_t1; + } + prop_check.unput("t1"); + } + + //Parser of parameter t2 + { + if (config.check("t2")) + { + m_t2 = config.find("t2").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 't2' using value:" << m_t2; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 't2' using DEFAULT value:" << m_t2; + } + prop_check.unput("t2"); + } + + //Parser of parameter freq + { + if (config.check("freq")) + { + m_freq = config.find("freq").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'freq' using value:" << m_freq; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'freq' using DEFAULT value:" << m_freq; + } + prop_check.unput("freq"); + } + + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + //Parser of parameter mode + { + if (config.check("mode")) + { + m_mode = config.find("mode").asString(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'mode' using value:" << m_mode; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'mode' using DEFAULT value:" << m_mode; + } + prop_check.unput("mode"); + } + + //Parser of parameter src + { + if (config.check("src")) + { + m_src = config.find("src").asString(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'src' using value:" << m_src; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'src' using DEFAULT value:" << m_src; + } + prop_check.unput("src"); + } + + //Parser of parameter add_timestamp + { + if (config.check("add_timestamp")) + { + m_add_timestamp = config.find("add_timestamp").asBool(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'add_timestamp' using value:" << m_add_timestamp; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'add_timestamp' using DEFAULT value:" << m_add_timestamp; + } + prop_check.unput("add_timestamp"); + } + + //Parser of parameter add_noise + { + if (config.check("add_noise")) + { + m_add_noise = config.find("add_noise").asBool(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'add_noise' using value:" << m_add_noise; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'add_noise' using DEFAULT value:" << m_add_noise; + } + prop_check.unput("add_noise"); + } + + //Parser of parameter bayer + { + if (config.check("bayer")) + { + m_bayer = config.find("bayer").asBool(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'bayer' using value:" << m_bayer; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'bayer' using DEFAULT value:" << m_bayer; + } + prop_check.unput("bayer"); + } + + //Parser of parameter mono + { + if (config.check("mono")) + { + m_mono = config.find("mono").asBool(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'mono' using value:" << m_mono; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'mono' using DEFAULT value:" << m_mono; + } + prop_check.unput("mono"); + } + + //Parser of parameter snr + { + if (config.check("snr")) + { + m_snr = config.find("snr").asFloat64(); + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'snr' using value:" << m_snr; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'snr' using DEFAULT value:" << m_snr; + } + prop_check.unput("snr"); + } + + //Parser of parameter rectificationMatrix + { + if (config.check("rectificationMatrix")) + { + { + m_rectificationMatrix.clear(); + yarp::os::Bottle* tempBot = config.find("rectificationMatrix").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_rectificationMatrix.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(FakeFrameGrabberParamsCOMPONENT) <<"parameter 'rectificationMatrix' is not a properly formatted bottle"; + } + } + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'rectificationMatrix' using value:" << m_rectificationMatrix; + } + else + { + yCInfo(FakeFrameGrabberParamsCOMPONENT) << "Parameter 'rectificationMatrix' using DEFAULT value:" << m_rectificationMatrix; + } + prop_check.unput("rectificationMatrix"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeFrameGrabberParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeFrameGrabberParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeFrameGrabber_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeFrameGrabber\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'width': desired width of test image\n"); + doc = doc + std::string("'height': desired height of test image\n"); + doc = doc + std::string("'horizontalFov': desired horizontal fov of test image\n"); + doc = doc + std::string("'verticalFov': desired horizontal fov of test image\n"); + doc = doc + std::string("'fakeFrameGrabber_rpc_port': rpc port for the fakeFrameGrabber\n"); + doc = doc + std::string("'mirror': mirror height of test image\n"); + doc = doc + std::string("'syncro': synchronize producer and consumer, so that all images are used once and only once\n"); + doc = doc + std::string("'topIsLow': explicitly set the topIsLow field in the images\n"); + doc = doc + std::string("'physFocalLength': Physical focal length\n"); + doc = doc + std::string("'focalLengthX': Horizontal component of the focal length\n"); + doc = doc + std::string("'focalLengthY': Vertical component of the focal length\n"); + doc = doc + std::string("'principalPointX': X coordinate of the principal point\n"); + doc = doc + std::string("'principalPointY': Y coordinate of the principal point\n"); + doc = doc + std::string("'distortionModel': Reference to group of parameters describing the distortion model of the camera\n"); + doc = doc + std::string("'k1': Radial distortion coefficient of the lens(fake\n"); + doc = doc + std::string("'k2': Radial distortion coefficient of the lens(fake)\n"); + doc = doc + std::string("'k3': Radial distortion coefficient of the lens(fake)\n"); + doc = doc + std::string("'t1': Tangential distortion of the lens(fake)\n"); + doc = doc + std::string("'t2': Tangential distortion of the lens(fake)\n"); + doc = doc + std::string("'freq': rate of test images in Hz\n"); + doc = doc + std::string("'period': period of test images in seconds\n"); + doc = doc + std::string("'mode': bouncy [ball], scrolly [line], grid [grid], grid multisize [size], random [rand], none [none], time test[time]\n"); + doc = doc + std::string("'src': background image to use, if any\n"); + doc = doc + std::string("'add_timestamp': should write the timestamp in the first bytes of the image\n"); + doc = doc + std::string("'add_noise': should add noise to the image (uses snr parameter)\n"); + doc = doc + std::string("'bayer': should emit bayer test image\n"); + doc = doc + std::string("'mono': should emit a monochrome image\n"); + doc = doc + std::string("'snr': Signal noise ratio ([0.0-1.0]\n"); + doc = doc + std::string("'rectificationMatrix': Matrix that describes the lens' distortion\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeFrameGrabber --width 320 --height 240 --horizontalFov 1.0 --verticalFov 2.0 --fakeFrameGrabber_rpc_port /fakeFrameGrabber/rpc --mirror false --syncro false --topIsLow true --physFocalLength 3.0 --focalLengthX 4.0 --focalLengthY 5.0 --principalPointX 6.0 --principalPointY 7.0 --distortionModel FishEye --k1 8.0 --k2 9.0 --k3 10.0 --t1 11.0 --t2 12.0 --freq 0 --period 0 --mode [line] --src --add_timestamp false --add_noise false --bayer false --mono false --snr 0.5 --rectificationMatrix \" (1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0) \"\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeFrameGrabber\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_ParamsParser.h b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_ParamsParser.h new file mode 100644 index 00000000000..b08affa1eff --- /dev/null +++ b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_ParamsParser.h @@ -0,0 +1,153 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#ifndef FAKEFRAMEGRABBER_PARAMSPARSER_H +#define FAKEFRAMEGRABBER_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeFrameGrabber. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:-------------------------:|:--------------:|:-----:|:-------------------------------------:|:--------:|:--------------------------------------------------------------------------------------------------------------:|:-------------:| +* | - | width | int | - | 320 | 0 | desired width of test image | - | +* | - | height | int | - | 240 | 0 | desired height of test image | - | +* | - | horizontalFov | double | - | 1.0 | 0 | desired horizontal fov of test image | - | +* | - | verticalFov | double | - | 2.0 | 0 | desired horizontal fov of test image | - | +* | - | fakeFrameGrabber_rpc_port | string | - | /fakeFrameGrabber/rpc | 0 | rpc port for the fakeFrameGrabber | - | +* | - | mirror | bool | - | false | 0 | mirror height of test image | - | +* | - | syncro | bool | - | false | 0 | synchronize producer and consumer, so that all images are used once and only once | - | +* | - | topIsLow | bool | - | true | 0 | explicitly set the topIsLow field in the images | - | +* | - | physFocalLength | double | - | 3.0 | 0 | Physical focal length | - | +* | - | focalLengthX | double | - | 4.0 | 0 | Horizontal component of the focal length | - | +* | - | focalLengthY | double | - | 5.0 | 0 | Vertical component of the focal length | - | +* | - | principalPointX | double | - | 6.0 | 0 | X coordinate of the principal point | - | +* | - | principalPointY | double | - | 7.0 | 0 | Y coordinate of the principal point | - | +* | - | distortionModel | string | - | FishEye | 0 | Reference to group of parameters describing the distortion model of the camera | - | +* | - | k1 | double | - | 8.0 | 0 | Radial distortion coefficient of the lens(fake | - | +* | - | k2 | double | - | 9.0 | 0 | Radial distortion coefficient of the lens(fake) | - | +* | - | k3 | double | - | 10.0 | 0 | Radial distortion coefficient of the lens(fake) | - | +* | - | t1 | double | - | 11.0 | 0 | Tangential distortion of the lens(fake) | - | +* | - | t2 | double | - | 12.0 | 0 | Tangential distortion of the lens(fake) | - | +* | - | freq | double | - | 0 | 0 | rate of test images in Hz | - | +* | - | period | double | - | 0 | 0 | period of test images in seconds | - | +* | - | mode | string | - | [line] | 0 | bouncy [ball], scrolly [line], grid [grid], grid multisize [size], random [rand], none [none], time test[time] | - | +* | - | src | string | - | - | 0 | background image to use, if any | e.g. test.ppm | +* | - | add_timestamp | bool | - | false | 0 | should write the timestamp in the first bytes of the image | - | +* | - | add_noise | bool | - | false | 0 | should add noise to the image (uses snr parameter) | - | +* | - | bayer | bool | - | false | 0 | should emit bayer test image | - | +* | - | mono | bool | - | false | 0 | should emit a monochrome image | - | +* | - | snr | double | - | 0.5 | 0 | Signal noise ratio ([0.0-1.0] | - | +* | - | rectificationMatrix | vector | - | (1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0) | 0 | Matrix that describes the lens' distortion | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeFrameGrabber --width 320 --height 240 --horizontalFov 1.0 --verticalFov 2.0 --fakeFrameGrabber_rpc_port /fakeFrameGrabber/rpc --mirror false --syncro false --topIsLow true --physFocalLength 3.0 --focalLengthX 4.0 --focalLengthY 5.0 --principalPointX 6.0 --principalPointY 7.0 --distortionModel FishEye --k1 8.0 --k2 9.0 --k3 10.0 --t1 11.0 --t2 12.0 --freq 0 --period 0 --mode [line] --src --add_timestamp false --add_noise false --bayer false --mono false --snr 0.5 --rectificationMatrix \" (1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0) \" +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeFrameGrabber +* \endcode +* +*/ + +class FakeFrameGrabber_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeFrameGrabber_ParamsParser(); + ~FakeFrameGrabber_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeFrameGrabber"}; + const std::string m_device_name = {"fakeFrameGrabber"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_width_defaultValue = {"320"}; + const std::string m_height_defaultValue = {"240"}; + const std::string m_horizontalFov_defaultValue = {"1.0"}; + const std::string m_verticalFov_defaultValue = {"2.0"}; + const std::string m_fakeFrameGrabber_rpc_port_defaultValue = {"/fakeFrameGrabber/rpc"}; + const std::string m_mirror_defaultValue = {"false"}; + const std::string m_syncro_defaultValue = {"false"}; + const std::string m_topIsLow_defaultValue = {"true"}; + const std::string m_physFocalLength_defaultValue = {"3.0"}; + const std::string m_focalLengthX_defaultValue = {"4.0"}; + const std::string m_focalLengthY_defaultValue = {"5.0"}; + const std::string m_principalPointX_defaultValue = {"6.0"}; + const std::string m_principalPointY_defaultValue = {"7.0"}; + const std::string m_distortionModel_defaultValue = {"FishEye"}; + const std::string m_k1_defaultValue = {"8.0"}; + const std::string m_k2_defaultValue = {"9.0"}; + const std::string m_k3_defaultValue = {"10.0"}; + const std::string m_t1_defaultValue = {"11.0"}; + const std::string m_t2_defaultValue = {"12.0"}; + const std::string m_freq_defaultValue = {"0"}; + const std::string m_period_defaultValue = {"0"}; + const std::string m_mode_defaultValue = {"[line]"}; + const std::string m_src_defaultValue = {""}; + const std::string m_add_timestamp_defaultValue = {"false"}; + const std::string m_add_noise_defaultValue = {"false"}; + const std::string m_bayer_defaultValue = {"false"}; + const std::string m_mono_defaultValue = {"false"}; + const std::string m_snr_defaultValue = {"0.5"}; + const std::string m_rectificationMatrix_defaultValue = {"(1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0)"}; + + int m_width = {320}; + int m_height = {240}; + double m_horizontalFov = {1.0}; + double m_verticalFov = {2.0}; + std::string m_fakeFrameGrabber_rpc_port = {"/fakeFrameGrabber/rpc"}; + bool m_mirror = {false}; + bool m_syncro = {false}; + bool m_topIsLow = {true}; + double m_physFocalLength = {3.0}; + double m_focalLengthX = {4.0}; + double m_focalLengthY = {5.0}; + double m_principalPointX = {6.0}; + double m_principalPointY = {7.0}; + std::string m_distortionModel = {"FishEye"}; + double m_k1 = {8.0}; + double m_k2 = {9.0}; + double m_k3 = {10.0}; + double m_t1 = {11.0}; + double m_t2 = {12.0}; + double m_freq = {0}; + double m_period = {0}; + std::string m_mode = {"[line]"}; + std::string m_src = {}; //This default value of this string is an empty string. It is highly recommended to provide a suggested value also for optional string parameters. + bool m_add_timestamp = {false}; + bool m_add_noise = {false}; + bool m_bayer = {false}; + bool m_mono = {false}; + double m_snr = {0.5}; + std::vector m_rectificationMatrix = { }; //Default values for lists are managed in the class constructor. It is highly recommended to provide a suggested value also for optional string parameters. + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_params.md b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_params.md new file mode 100644 index 00000000000..6a48cb19057 --- /dev/null +++ b/src/devices/fake/fakeFrameGrabber/FakeFrameGrabber_params.md @@ -0,0 +1,29 @@ + * | | width | int | - | 320 | No | desired width of test image | | + * | | height | int | - | 240 | No | desired height of test image | | + * | | horizontalFov | double | - | 1.0 | No | desired horizontal fov of test image | | + * | | verticalFov | double | - | 2.0 | No | desired horizontal fov of test image | | + * | | fakeFrameGrabber_rpc_port | string | - | /fakeFrameGrabber/rpc | No | rpc port for the fakeFrameGrabber | | + * | | mirror | bool | - | false | No | mirror height of test image | | + * | | syncro | bool | - | false | No | synchronize producer and consumer, so that all images are used once and only once | | + * | | topIsLow | bool | - | true | No | explicitly set the topIsLow field in the images | | + * | | physFocalLength | double | - | 3.0 | No | Physical focal length | | + * | | focalLengthX | double | - | 4.0 | No | Horizontal component of the focal length | | + * | | focalLengthY | double | - | 5.0 | No | Vertical component of the focal length | | + * | | principalPointX | double | - | 6.0 | No | X coordinate of the principal point | | + * | | principalPointY | double | - | 7.0 | No | Y coordinate of the principal point | | + * | | distortionModel | string | - | FishEye | No | Reference to group of parameters describing the distortion model of the camera | | + * | | k1 | double | - | 8.0 | No | Radial distortion coefficient of the lens(fake | | + * | | k2 | double | - | 9.0 | No | Radial distortion coefficient of the lens(fake) | | + * | | k3 | double | - | 10.0 | No | Radial distortion coefficient of the lens(fake) | | + * | | t1 | double | - | 11.0 | No | Tangential distortion of the lens(fake) | | + * | | t2 | double | - | 12.0 | No | Tangential distortion of the lens(fake) | | + * | | freq | double | - | 0 | No | rate of test images in Hz | | + * | | period | double | - | 0 | No | period of test images in seconds | | + * | | mode | string | - | [line] | No | bouncy [ball], scrolly [line], grid [grid], grid multisize [size], random [rand], none [none], time test[time] | | + * | | src | string | - | - | No | background image to use, if any | e.g. test.ppm | + * | | add_timestamp | bool | - | false | No | should write the timestamp in the first bytes of the image | | + * | | add_noise | bool | - | false | No | should add noise to the image (uses snr parameter) | | + * | | bayer | bool | - | false | No | should emit bayer test image | | + * | | mono | bool | - | false | No | should emit a monochrome image | | + * | | snr | double | - | 0.5 | No | Signal noise ratio ([0.0-1.0] | | + * | | rectificationMatrix | vector | - | (1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0) | No | Matrix that describes the lens' distortion | | diff --git a/src/devices/fake/fakeIMU/CMakeLists.txt b/src/devices/fake/fakeIMU/CMakeLists.txt index 9bc2758367c..303ffa0ef67 100644 --- a/src/devices/fake/fakeIMU/CMakeLists.txt +++ b/src/devices/fake/fakeIMU/CMakeLists.txt @@ -7,8 +7,9 @@ endif() yarp_prepare_plugin(fakeIMU CATEGORY device - TYPE fakeIMU - INCLUDE fakeIMU.h + TYPE FakeIMU + INCLUDE FakeIMU.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=inertial DEPENDS "TARGET YARP::YARP_math" @@ -19,8 +20,10 @@ if(NOT SKIP_fakeIMU) target_sources(yarp_fakeIMU PRIVATE - fakeIMU.cpp - fakeIMU.h + FakeIMU.cpp + FakeIMU.h + FakeIMU_ParamsParser.cpp + FakeIMU_ParamsParser.h ) target_link_libraries(yarp_fakeIMU diff --git a/src/devices/fake/fakeIMU/fakeIMU.cpp b/src/devices/fake/fakeIMU/FakeIMU.cpp similarity index 64% rename from src/devices/fake/fakeIMU/fakeIMU.cpp rename to src/devices/fake/fakeIMU/FakeIMU.cpp index 6a045845cd8..60a1dedd1c6 100644 --- a/src/devices/fake/fakeIMU/fakeIMU.cpp +++ b/src/devices/fake/fakeIMU/FakeIMU.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeIMU.h" +#include "FakeIMU.h" #include #include @@ -24,8 +24,6 @@ YARP_LOG_COMPONENT(FAKEIMU, "yarp.device.fakeIMU") constexpr double DEFAULT_PERIOD = 0.01; // seconds constexpr int DEFAULT_NCHANNELS = 12; constexpr double DEFAULT_DUMMY_VALUE = 0.0; -constexpr const char* DEFAULT_SENSOR_NAME = "sensorName"; -constexpr const char* DEFAULT_FRAME_NAME = "frameName"; constexpr double EARTH_GRAVITY = -9.81; } @@ -34,58 +32,47 @@ constexpr double EARTH_GRAVITY = -9.81; * This device implements a fake analog sensor * emulating an IMU */ -fakeIMU::fakeIMU() : +FakeIMU::FakeIMU() : PeriodicThread(DEFAULT_PERIOD), rpy({0.0, 0.0, 0.0}), gravity({0.0, 0.0, EARTH_GRAVITY, 0.0}), dcm(4, 4), accels({0.0, 0.0, 0.0, 0.0}), nchannels(DEFAULT_NCHANNELS), - dummy_value(DEFAULT_DUMMY_VALUE), - m_sensorName(DEFAULT_SENSOR_NAME), - m_frameName(DEFAULT_FRAME_NAME) + dummy_value(DEFAULT_DUMMY_VALUE) { dcm.zero(); } -fakeIMU::~fakeIMU() +FakeIMU::~FakeIMU() { close(); } -bool fakeIMU::open(yarp::os::Searchable &config) +bool FakeIMU::open(yarp::os::Searchable &config) { - double period; - if( config.check("period")) { - period = config.find("period").asInt32() / 1000.0; - setPeriod(period); - } else { - yCInfo(FAKEIMU) << "Using default period of " << DEFAULT_PERIOD << " s"; - } - if (config.check("sensorName")) { - m_sensorName = config.find("sensorName").asString(); - } - yCInfo(FAKEIMU) << "sensorName: " << m_sensorName; + if (!this->parseParams(config)) {return false;} - constantValue = config.check("constantValue"); + double dperiod = m_period / 1000.0; + setPeriod(dperiod); start(); return true; } -bool fakeIMU::close() +bool FakeIMU::close() { - fakeIMU::stop(); + FakeIMU::stop(); return true; } -bool fakeIMU::threadInit() +bool FakeIMU::threadInit() { lastStamp.update(); return true; } -void fakeIMU::run() +void FakeIMU::run() { static double count=10; @@ -99,7 +86,7 @@ void fakeIMU::run() lastStamp.update(); dummy_value = count; - if (!constantValue) { + if (!m_constantValue) { count++; } @@ -108,7 +95,7 @@ void fakeIMU::run() } } -yarp::dev::MAS_status fakeIMU::genericGetStatus(size_t sens_index) const +yarp::dev::MAS_status FakeIMU::genericGetStatus(size_t sens_index) const { if (sens_index!=0) { return yarp::dev::MAS_status::MAS_ERROR; @@ -117,7 +104,7 @@ yarp::dev::MAS_status fakeIMU::genericGetStatus(size_t sens_index) const return yarp::dev::MAS_status::MAS_OK; } -bool fakeIMU::genericGetSensorName(size_t sens_index, std::string &name) const +bool FakeIMU::genericGetSensorName(size_t sens_index, std::string &name) const { if (sens_index!=0) { return false; @@ -127,7 +114,7 @@ bool fakeIMU::genericGetSensorName(size_t sens_index, std::string &name) const return true; } -bool fakeIMU::genericGetFrameName(size_t sens_index, std::string &frameName) const +bool FakeIMU::genericGetFrameName(size_t sens_index, std::string &frameName) const { if (sens_index!=0) { return false; @@ -137,27 +124,27 @@ bool fakeIMU::genericGetFrameName(size_t sens_index, std::string &frameName) con return true; } -size_t fakeIMU::getNrOfThreeAxisGyroscopes() const +size_t FakeIMU::getNrOfThreeAxisGyroscopes() const { return 1; } -yarp::dev::MAS_status fakeIMU::getThreeAxisGyroscopeStatus(size_t sens_index) const +yarp::dev::MAS_status FakeIMU::getThreeAxisGyroscopeStatus(size_t sens_index) const { return genericGetStatus(sens_index); } -bool fakeIMU::getThreeAxisGyroscopeName(size_t sens_index, std::string &name) const +bool FakeIMU::getThreeAxisGyroscopeName(size_t sens_index, std::string &name) const { return genericGetSensorName(sens_index, name); } -bool fakeIMU::getThreeAxisGyroscopeFrameName(size_t sens_index, std::string &frameName) const +bool FakeIMU::getThreeAxisGyroscopeFrameName(size_t sens_index, std::string &frameName) const { return genericGetFrameName(sens_index, frameName); } -bool fakeIMU::getThreeAxisGyroscopeMeasure(size_t sens_index, yarp::sig::Vector& out, double& timestamp) const +bool FakeIMU::getThreeAxisGyroscopeMeasure(size_t sens_index, yarp::sig::Vector& out, double& timestamp) const { if (sens_index!=0) { return false; @@ -175,27 +162,27 @@ bool fakeIMU::getThreeAxisGyroscopeMeasure(size_t sens_index, yarp::sig::Vector& return true; } -size_t fakeIMU::getNrOfThreeAxisLinearAccelerometers() const +size_t FakeIMU::getNrOfThreeAxisLinearAccelerometers() const { return 1; } -yarp::dev::MAS_status fakeIMU::getThreeAxisLinearAccelerometerStatus(size_t sens_index) const +yarp::dev::MAS_status FakeIMU::getThreeAxisLinearAccelerometerStatus(size_t sens_index) const { return genericGetStatus(sens_index); } -bool fakeIMU::getThreeAxisLinearAccelerometerName(size_t sens_index, std::string &name) const +bool FakeIMU::getThreeAxisLinearAccelerometerName(size_t sens_index, std::string &name) const { return genericGetSensorName(sens_index, name); } -bool fakeIMU::getThreeAxisLinearAccelerometerFrameName(size_t sens_index, std::string &frameName) const +bool FakeIMU::getThreeAxisLinearAccelerometerFrameName(size_t sens_index, std::string &frameName) const { return genericGetFrameName(sens_index, frameName); } -bool fakeIMU::getThreeAxisLinearAccelerometerMeasure(size_t sens_index, yarp::sig::Vector& out, double& timestamp) const +bool FakeIMU::getThreeAxisLinearAccelerometerMeasure(size_t sens_index, yarp::sig::Vector& out, double& timestamp) const { if (sens_index!=0) { return false; @@ -213,27 +200,27 @@ bool fakeIMU::getThreeAxisLinearAccelerometerMeasure(size_t sens_index, yarp::si return true; } -size_t fakeIMU::getNrOfThreeAxisMagnetometers() const +size_t FakeIMU::getNrOfThreeAxisMagnetometers() const { return 1; } -yarp::dev::MAS_status fakeIMU::getThreeAxisMagnetometerStatus(size_t sens_index) const +yarp::dev::MAS_status FakeIMU::getThreeAxisMagnetometerStatus(size_t sens_index) const { return genericGetStatus(sens_index); } -bool fakeIMU::getThreeAxisMagnetometerName(size_t sens_index, std::string &name) const +bool FakeIMU::getThreeAxisMagnetometerName(size_t sens_index, std::string &name) const { return genericGetSensorName(sens_index, name); } -bool fakeIMU::getThreeAxisMagnetometerFrameName(size_t sens_index, std::string &frameName) const +bool FakeIMU::getThreeAxisMagnetometerFrameName(size_t sens_index, std::string &frameName) const { return genericGetFrameName(sens_index, frameName); } -bool fakeIMU::getThreeAxisMagnetometerMeasure(size_t sens_index, yarp::sig::Vector& out, double& timestamp) const +bool FakeIMU::getThreeAxisMagnetometerMeasure(size_t sens_index, yarp::sig::Vector& out, double& timestamp) const { if (sens_index!=0) { return false; @@ -251,27 +238,27 @@ bool fakeIMU::getThreeAxisMagnetometerMeasure(size_t sens_index, yarp::sig::Vect return true; } -size_t fakeIMU::getNrOfOrientationSensors() const +size_t FakeIMU::getNrOfOrientationSensors() const { return 1; } -yarp::dev::MAS_status fakeIMU::getOrientationSensorStatus(size_t sens_index) const +yarp::dev::MAS_status FakeIMU::getOrientationSensorStatus(size_t sens_index) const { return genericGetStatus(sens_index); } -bool fakeIMU::getOrientationSensorName(size_t sens_index, std::string &name) const +bool FakeIMU::getOrientationSensorName(size_t sens_index, std::string &name) const { return genericGetSensorName(sens_index, name); } -bool fakeIMU::getOrientationSensorFrameName(size_t sens_index, std::string &frameName) const +bool FakeIMU::getOrientationSensorFrameName(size_t sens_index, std::string &frameName) const { return genericGetFrameName(sens_index, frameName); } -bool fakeIMU::getOrientationSensorMeasureAsRollPitchYaw(size_t sens_index, yarp::sig::Vector& rpy_out, double& timestamp) const +bool FakeIMU::getOrientationSensorMeasureAsRollPitchYaw(size_t sens_index, yarp::sig::Vector& rpy_out, double& timestamp) const { if (sens_index!=0) { return false; diff --git a/src/devices/fake/fakeIMU/fakeIMU.h b/src/devices/fake/fakeIMU/FakeIMU.h similarity index 73% rename from src/devices/fake/fakeIMU/fakeIMU.h rename to src/devices/fake/fakeIMU/FakeIMU.h index 2d8c73f4cae..88fea3e0731 100644 --- a/src/devices/fake/fakeIMU/fakeIMU.h +++ b/src/devices/fake/fakeIMU/FakeIMU.h @@ -9,39 +9,32 @@ #include #include #include +#include "FakeIMU_ParamsParser.h" /** * @ingroup dev_impl_fake * \brief `fakeIMU` : fake device implementing the device interface typically implemented by an Inertial Measurement Unit * -* | YARP device name | -* |:-----------------:| -* | `fakeIMU` | -* -* -* The parameters accepted by this device are: -* | Parameter name | SubParameter | Type | Units | Default Value | Required | Description | Notes | -* |:--------------:|:--------------:|:-------:|:--------------:|:-------------:|:--------------------------: |:-----------------------------------------------------------------:|:-----:| -* | period | - | int | millisecond | 10 | No | Period over which the measurement is updated. | | -* | constantValue | - | - | - | - | No | If the parameter is present, the fake sensor values never changes (useful for testing server/client coherence). | | +* Parameters required by this device are shown in class: FakeIMU_ParamsParser * */ -class fakeIMU : +class FakeIMU : public yarp::dev::DeviceDriver, public yarp::os::PeriodicThread, public yarp::dev::IThreeAxisGyroscopes, public yarp::dev::IThreeAxisLinearAccelerometers, public yarp::dev::IThreeAxisMagnetometers, - public yarp::dev::IOrientationSensors + public yarp::dev::IOrientationSensors, + public FakeIMU_ParamsParser { public: - fakeIMU(); - fakeIMU(const fakeIMU&) = delete; - fakeIMU(fakeIMU&&) = delete; - fakeIMU& operator=(const fakeIMU&) = delete; - fakeIMU& operator=(fakeIMU&&) = delete; + FakeIMU(); + FakeIMU(const FakeIMU&) = delete; + FakeIMU(FakeIMU&&) = delete; + FakeIMU& operator=(const FakeIMU&) = delete; + FakeIMU& operator=(FakeIMU&&) = delete; - ~fakeIMU() override; + ~FakeIMU() override; // Device Driver interface bool open(yarp::os::Searchable &config) override; @@ -91,7 +84,4 @@ class fakeIMU : unsigned int nchannels; double dummy_value; yarp::os::Stamp lastStamp; - std::string m_sensorName; - std::string m_frameName; - bool constantValue; }; diff --git a/src/devices/fake/fakeIMU/FakeIMU_ParamsParser.cpp b/src/devices/fake/fakeIMU/FakeIMU_ParamsParser.cpp new file mode 100644 index 00000000000..019d5a52e9d --- /dev/null +++ b/src/devices/fake/fakeIMU/FakeIMU_ParamsParser.cpp @@ -0,0 +1,151 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#include "FakeIMU_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeIMUParamsCOMPONENT, "yarp.device.FakeIMU") +} + + +FakeIMU_ParamsParser::FakeIMU_ParamsParser() +{ +} + + +std::vector FakeIMU_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("period"); + params.push_back("constantValue"); + params.push_back("sensorName"); + params.push_back("frameName"); + return params; +} + + +bool FakeIMU_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeIMUParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asInt64(); + yCInfo(FakeIMUParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakeIMUParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + //Parser of parameter constantValue + { + if (config.check("constantValue")) + { + m_constantValue = config.find("constantValue").asBool(); + yCInfo(FakeIMUParamsCOMPONENT) << "Parameter 'constantValue' using value:" << m_constantValue; + } + else + { + yCInfo(FakeIMUParamsCOMPONENT) << "Parameter 'constantValue' using DEFAULT value:" << m_constantValue; + } + prop_check.unput("constantValue"); + } + + //Parser of parameter sensorName + { + if (config.check("sensorName")) + { + m_sensorName = config.find("sensorName").asString(); + yCInfo(FakeIMUParamsCOMPONENT) << "Parameter 'sensorName' using value:" << m_sensorName; + } + else + { + yCInfo(FakeIMUParamsCOMPONENT) << "Parameter 'sensorName' using DEFAULT value:" << m_sensorName; + } + prop_check.unput("sensorName"); + } + + //Parser of parameter frameName + { + if (config.check("frameName")) + { + m_frameName = config.find("frameName").asString(); + yCInfo(FakeIMUParamsCOMPONENT) << "Parameter 'frameName' using value:" << m_frameName; + } + else + { + yCInfo(FakeIMUParamsCOMPONENT) << "Parameter 'frameName' using DEFAULT value:" << m_frameName; + } + prop_check.unput("frameName"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeIMUParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeIMUParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeIMU_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeIMU\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'period': Period over which the measurement is updated.\n"); + doc = doc + std::string("'constantValue': If the parameter is present, the fake sensor values never changes (useful for testing server/client coherence).\n"); + doc = doc + std::string("'sensorName': Name of the sensor\n"); + doc = doc + std::string("'frameName': Name of the frame\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeIMU --period 10 --constantValue false --sensorName sensorName --frameName frameName\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeIMU\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeIMU/FakeIMU_ParamsParser.h b/src/devices/fake/fakeIMU/FakeIMU_ParamsParser.h new file mode 100644 index 00000000000..a313246ca6c --- /dev/null +++ b/src/devices/fake/fakeIMU/FakeIMU_ParamsParser.h @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#ifndef FAKEIMU_PARAMSPARSER_H +#define FAKEIMU_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeIMU. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----------:|:-------------:|:--------:|:---------------------------------------------------------------------------------------------------------------:|:-----:| +* | - | period | int | millisecond | 10 | 0 | Period over which the measurement is updated. | - | +* | - | constantValue | bool | - | false | 0 | If the parameter is present, the fake sensor values never changes (useful for testing server/client coherence). | - | +* | - | sensorName | string | - | sensorName | 0 | Name of the sensor | - | +* | - | frameName | string | - | frameName | 0 | Name of the frame | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeIMU --period 10 --constantValue false --sensorName sensorName --frameName frameName +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeIMU +* \endcode +* +*/ + +class FakeIMU_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeIMU_ParamsParser(); + ~FakeIMU_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeIMU"}; + const std::string m_device_name = {"fakeIMU"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_period_defaultValue = {"10"}; + const std::string m_constantValue_defaultValue = {"false"}; + const std::string m_sensorName_defaultValue = {"sensorName"}; + const std::string m_frameName_defaultValue = {"frameName"}; + + int m_period = {10}; + bool m_constantValue = {false}; + std::string m_sensorName = {"sensorName"}; + std::string m_frameName = {"frameName"}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeIMU/FakeIMU_params.md b/src/devices/fake/fakeIMU/FakeIMU_params.md new file mode 100644 index 00000000000..dca7258f31b --- /dev/null +++ b/src/devices/fake/fakeIMU/FakeIMU_params.md @@ -0,0 +1,4 @@ +* | | period | int | millisecond | 10 | No | Period over which the measurement is updated. | | +* | | constantValue | bool | - | false | No | If the parameter is present, the fake sensor values never changes (useful for testing server/client coherence). | | +* | | sensorName | string | - | sensorName | No | Name of the sensor | | +* | | frameName | string | - | frameName | No | Name of the frame | | diff --git a/src/devices/fake/fakeJointCoupling/CMakeLists.txt b/src/devices/fake/fakeJointCoupling/CMakeLists.txt index a96d3804153..092ca7a3dcf 100644 --- a/src/devices/fake/fakeJointCoupling/CMakeLists.txt +++ b/src/devices/fake/fakeJointCoupling/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeJointCoupling CATEGORY device TYPE FakeJointCoupling - INCLUDE fakeJointCoupling.h + INCLUDE FakeJointCoupling.h + GENERATE_PARSER ) if(NOT SKIP_fakeJointCoupling) @@ -16,8 +17,11 @@ if(NOT SKIP_fakeJointCoupling) target_sources(yarp_fakeJointCoupling PRIVATE - fakeJointCoupling.cpp - fakeJointCoupling.h) + FakeJointCoupling.cpp + FakeJointCoupling.h + FakeJointCoupling_ParamsParser.cpp + FakeJointCoupling_ParamsParser.h + ) target_link_libraries(yarp_fakeJointCoupling PRIVATE diff --git a/src/devices/fake/fakeJointCoupling/fakeJointCoupling.cpp b/src/devices/fake/fakeJointCoupling/FakeJointCoupling.cpp similarity index 98% rename from src/devices/fake/fakeJointCoupling/fakeJointCoupling.cpp rename to src/devices/fake/fakeJointCoupling/FakeJointCoupling.cpp index 6df6ea35051..a41c1560bd4 100644 --- a/src/devices/fake/fakeJointCoupling/fakeJointCoupling.cpp +++ b/src/devices/fake/fakeJointCoupling/FakeJointCoupling.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeJointCoupling.h" +#include "FakeJointCoupling.h" #include @@ -27,7 +27,10 @@ namespace { YARP_LOG_COMPONENT(FAKEJOINTCOUPLING, "yarp.device.fakeJointCoupling") } -bool FakeJointCoupling::open(yarp::os::Searchable &par) { +bool FakeJointCoupling::open(yarp::os::Searchable &config) +{ + if (!this->parseParams(config)) {return false;} + yarp::sig::VectorOf coupled_physical_joints {2,3}; yarp::sig::VectorOf coupled_actuated_axes {2}; std::vector physical_joint_names{"phys_joint_0", "phys_joint_1", "phys_joint_2", "phys_joint_3"}; diff --git a/src/devices/fake/fakeJointCoupling/fakeJointCoupling.h b/src/devices/fake/fakeJointCoupling/FakeJointCoupling.h similarity index 91% rename from src/devices/fake/fakeJointCoupling/fakeJointCoupling.h rename to src/devices/fake/fakeJointCoupling/FakeJointCoupling.h index e9a0a049bd5..5d364ca41ca 100644 --- a/src/devices/fake/fakeJointCoupling/fakeJointCoupling.h +++ b/src/devices/fake/fakeJointCoupling/FakeJointCoupling.h @@ -14,7 +14,7 @@ #include #include - +#include "FakeJointCoupling_ParamsParser.h" /** * @ingroup dev_impl_fake dev_impl_motor @@ -25,10 +25,13 @@ * joint coupling device to help testing the high level software. * * WIP - it is very basic now, not all interfaces are implemented yet. + * + * Parameters required by this device are shown in class: FakeJointCoupling_ParamsParser */ class FakeJointCoupling : public yarp::dev::DeviceDriver, - public yarp::dev::ImplementJointCoupling + public yarp::dev::ImplementJointCoupling, + public FakeJointCoupling_ParamsParser { private: diff --git a/src/devices/fake/fakeJointCoupling/FakeJointCoupling_ParamsParser.cpp b/src/devices/fake/fakeJointCoupling/FakeJointCoupling_ParamsParser.cpp new file mode 100644 index 00000000000..45cac9cf814 --- /dev/null +++ b/src/devices/fake/fakeJointCoupling/FakeJointCoupling_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#include "FakeJointCoupling_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeJointCouplingParamsCOMPONENT, "yarp.device.FakeJointCoupling") +} + + +FakeJointCoupling_ParamsParser::FakeJointCoupling_ParamsParser() +{ +} + + +std::vector FakeJointCoupling_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("rpc_port_name"); + return params; +} + + +bool FakeJointCoupling_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeJointCouplingParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter rpc_port_name + { + if (config.check("rpc_port_name")) + { + m_rpc_port_name = config.find("rpc_port_name").asString(); + yCInfo(FakeJointCouplingParamsCOMPONENT) << "Parameter 'rpc_port_name' using value:" << m_rpc_port_name; + } + else + { + yCInfo(FakeJointCouplingParamsCOMPONENT) << "Parameter 'rpc_port_name' using DEFAULT value:" << m_rpc_port_name; + } + prop_check.unput("rpc_port_name"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeJointCouplingParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeJointCouplingParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeJointCoupling_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeJointCoupling\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'rpc_port_name': Full rpc port name\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeJointCoupling --rpc_port_name /fakeJointCoupling/rpc\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeJointCoupling\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeJointCoupling/FakeJointCoupling_ParamsParser.h b/src/devices/fake/fakeJointCoupling/FakeJointCoupling_ParamsParser.h new file mode 100644 index 00000000000..f32fa33d56d --- /dev/null +++ b/src/devices/fake/fakeJointCoupling/FakeJointCoupling_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#ifndef FAKEJOINTCOUPLING_PARAMSPARSER_H +#define FAKEJOINTCOUPLING_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeJointCoupling. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:----------------------:|:--------:|:------------------:|:-----:| +* | - | rpc_port_name | string | - | /fakeJointCoupling/rpc | 0 | Full rpc port name | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeJointCoupling --rpc_port_name /fakeJointCoupling/rpc +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeJointCoupling +* \endcode +* +*/ + +class FakeJointCoupling_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeJointCoupling_ParamsParser(); + ~FakeJointCoupling_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeJointCoupling"}; + const std::string m_device_name = {"fakeJointCoupling"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_rpc_port_name_defaultValue = {"/fakeJointCoupling/rpc"}; + + std::string m_rpc_port_name = {"/fakeJointCoupling/rpc"}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeJointCoupling/FakeJointCoupling_params.md b/src/devices/fake/fakeJointCoupling/FakeJointCoupling_params.md new file mode 100644 index 00000000000..52d203280f1 --- /dev/null +++ b/src/devices/fake/fakeJointCoupling/FakeJointCoupling_params.md @@ -0,0 +1 @@ + * | | rpc_port_name | string | - | /fakeJointCoupling/rpc | No | Full rpc port name | | diff --git a/src/devices/fake/fakeJoypad/CMakeLists.txt b/src/devices/fake/fakeJoypad/CMakeLists.txt index 956cab556b8..5b97990abc8 100644 --- a/src/devices/fake/fakeJoypad/CMakeLists.txt +++ b/src/devices/fake/fakeJoypad/CMakeLists.txt @@ -7,7 +7,8 @@ endif() yarp_prepare_plugin(fakeJoypad CATEGORY device TYPE FakeJoypad - INCLUDE fakeJoypad.h + INCLUDE FakeJoypad.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=JoypadControlServer) @@ -16,8 +17,10 @@ if(ENABLE_fakeJoypad) target_sources(yarp_fakeJoypad PRIVATE - fakeJoypad.cpp - fakeJoypad.h + FakeJoypad.cpp + FakeJoypad.h + FakeJoypad_ParamsParser.cpp + FakeJoypad_ParamsParser.h ) target_link_libraries(yarp_fakeJoypad diff --git a/src/devices/fake/fakeJoypad/fakeJoypad.cpp b/src/devices/fake/fakeJoypad/FakeJoypad.cpp similarity index 96% rename from src/devices/fake/fakeJoypad/fakeJoypad.cpp rename to src/devices/fake/fakeJoypad/FakeJoypad.cpp index fe346440741..2a6be02a324 100644 --- a/src/devices/fake/fakeJoypad/fakeJoypad.cpp +++ b/src/devices/fake/fakeJoypad/FakeJoypad.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "fakeJoypad.h" +#include "FakeJoypad.h" #include #include #include @@ -23,8 +23,10 @@ FakeJoypad::FakeJoypad() = default; FakeJoypad::~FakeJoypad() = default; -bool FakeJoypad::open(yarp::os::Searchable& rf) +bool FakeJoypad::open(yarp::os::Searchable& config) { + if (!this->parseParams(config)) {return false;} + return true; } diff --git a/src/devices/fake/fakeJoypad/fakeJoypad.h b/src/devices/fake/fakeJoypad/FakeJoypad.h similarity index 85% rename from src/devices/fake/fakeJoypad/fakeJoypad.h rename to src/devices/fake/fakeJoypad/FakeJoypad.h index adbb1746af5..a7896c4e28b 100644 --- a/src/devices/fake/fakeJoypad/fakeJoypad.h +++ b/src/devices/fake/fakeJoypad/FakeJoypad.h @@ -9,11 +9,20 @@ #include #include #include - +#include "FakeJoypad_ParamsParser.h" + + /** + * @ingroup dev_impl_fake + * \brief `FakeJoypad` : fake device implementing the device interface + * + * Parameters required by this device are shown in class: FakeJoypad_ParamsParser + * + */ class FakeJoypad : public yarp::dev::IJoypadEventDriven, //public yarp::dev::IJoypadController, - public yarp::dev::DeviceDriver + public yarp::dev::DeviceDriver, + public FakeJoypad_ParamsParser { unsigned int m_buttonCount {4}; unsigned int m_axisCount {4}; diff --git a/src/devices/fake/fakeJoypad/FakeJoypad_ParamsParser.cpp b/src/devices/fake/fakeJoypad/FakeJoypad_ParamsParser.cpp new file mode 100644 index 00000000000..901c451cc21 --- /dev/null +++ b/src/devices/fake/fakeJoypad/FakeJoypad_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#include "FakeJoypad_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeJoypadParamsCOMPONENT, "yarp.device.FakeJoypad") +} + + +FakeJoypad_ParamsParser::FakeJoypad_ParamsParser() +{ +} + + +std::vector FakeJoypad_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("rpc_port_name"); + return params; +} + + +bool FakeJoypad_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeJoypadParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter rpc_port_name + { + if (config.check("rpc_port_name")) + { + m_rpc_port_name = config.find("rpc_port_name").asString(); + yCInfo(FakeJoypadParamsCOMPONENT) << "Parameter 'rpc_port_name' using value:" << m_rpc_port_name; + } + else + { + yCInfo(FakeJoypadParamsCOMPONENT) << "Parameter 'rpc_port_name' using DEFAULT value:" << m_rpc_port_name; + } + prop_check.unput("rpc_port_name"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeJoypadParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeJoypadParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeJoypad_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeJoypad\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'rpc_port_name': Full rpc port name\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeJoypad --rpc_port_name /fakeJoypad/rpc\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeJoypad\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeJoypad/FakeJoypad_ParamsParser.h b/src/devices/fake/fakeJoypad/FakeJoypad_ParamsParser.h new file mode 100644 index 00000000000..09a8fcd8915 --- /dev/null +++ b/src/devices/fake/fakeJoypad/FakeJoypad_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#ifndef FAKEJOYPAD_PARAMSPARSER_H +#define FAKEJOYPAD_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeJoypad. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:---------------:|:--------:|:------------------:|:-----:| +* | - | rpc_port_name | string | - | /fakeJoypad/rpc | 0 | Full rpc port name | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeJoypad --rpc_port_name /fakeJoypad/rpc +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeJoypad +* \endcode +* +*/ + +class FakeJoypad_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeJoypad_ParamsParser(); + ~FakeJoypad_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeJoypad"}; + const std::string m_device_name = {"fakeJoypad"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_rpc_port_name_defaultValue = {"/fakeJoypad/rpc"}; + + std::string m_rpc_port_name = {"/fakeJoypad/rpc"}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeJoypad/FakeJoypad_params.md b/src/devices/fake/fakeJoypad/FakeJoypad_params.md new file mode 100644 index 00000000000..32fdf7ef548 --- /dev/null +++ b/src/devices/fake/fakeJoypad/FakeJoypad_params.md @@ -0,0 +1 @@ + * | | rpc_port_name | string | - | /fakeJoypad/rpc | No | Full rpc port name | | diff --git a/src/devices/fake/fakeLLMDevice/CMakeLists.txt b/src/devices/fake/fakeLLMDevice/CMakeLists.txt index 21de396a4d1..4add9a9104d 100644 --- a/src/devices/fake/fakeLLMDevice/CMakeLists.txt +++ b/src/devices/fake/fakeLLMDevice/CMakeLists.txt @@ -7,18 +7,20 @@ endif() yarp_prepare_plugin(fakeLLMDevice CATEGORY device - TYPE fakeLLMDevice - INCLUDE fakeLLMDevice.h - + TYPE FakeLLMDevice + INCLUDE FakeLLMDevice.h + GENERATE_PARSER ) -if(NOT SKIP_fakeLLMDevice) +if(NOT SKIP_fakeLLMDevice) yarp_add_plugin(yarp_fakeLLMDevice) target_sources(yarp_fakeLLMDevice PRIVATE - fakeLLMDevice.cpp - fakeLLMDevice.h + FakeLLMDevice.cpp + FakeLLMDevice.h + FakeLLMDevice_ParamsParser.cpp + FakeLLMDevice_ParamsParser.h ) target_link_libraries(yarp_fakeLLMDevice diff --git a/src/devices/fake/fakeLLMDevice/fakeLLMDevice.cpp b/src/devices/fake/fakeLLMDevice/FakeLLMDevice.cpp similarity index 76% rename from src/devices/fake/fakeLLMDevice/fakeLLMDevice.cpp rename to src/devices/fake/fakeLLMDevice/FakeLLMDevice.cpp index d98c6b3e2fa..f956306a9cf 100644 --- a/src/devices/fake/fakeLLMDevice/fakeLLMDevice.cpp +++ b/src/devices/fake/fakeLLMDevice/FakeLLMDevice.cpp @@ -3,11 +3,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeLLMDevice.h" +#include "FakeLLMDevice.h" #include #include -bool fakeLLMDevice::setPrompt(const std::string &prompt) +bool FakeLLMDevice::setPrompt(const std::string &prompt) { if(!m_conversation.empty()) { @@ -19,7 +19,7 @@ bool fakeLLMDevice::setPrompt(const std::string &prompt) return true; } -bool fakeLLMDevice::readPrompt(std::string &oPrompt) +bool FakeLLMDevice::readPrompt(std::string &oPrompt) { for (const auto &message : m_conversation) { @@ -33,7 +33,7 @@ bool fakeLLMDevice::readPrompt(std::string &oPrompt) return false; } -bool fakeLLMDevice::ask(const std::string &question, yarp::dev::LLM_Message &oAnswer) +bool FakeLLMDevice::ask(const std::string &question, yarp::dev::LLM_Message &oAnswer) { // In the fake device we ignore the question yarp::dev::LLM_Message answer; @@ -55,14 +55,25 @@ bool fakeLLMDevice::ask(const std::string &question, yarp::dev::LLM_Message &oAn return true; } -bool fakeLLMDevice::getConversation(std::vector& oConversation) +bool FakeLLMDevice::getConversation(std::vector& oConversation) { oConversation = m_conversation; return true; } -bool fakeLLMDevice::deleteConversation() noexcept +bool FakeLLMDevice::deleteConversation() noexcept { m_conversation.clear(); return true; } + +bool FakeLLMDevice::open(yarp::os::Searchable& config) +{ + if (!this->parseParams(config)) {return false;} + return true; +} + +bool FakeLLMDevice::close() +{ + return true; +} diff --git a/src/devices/fake/fakeLLMDevice/fakeLLMDevice.h b/src/devices/fake/fakeLLMDevice/FakeLLMDevice.h similarity index 66% rename from src/devices/fake/fakeLLMDevice/fakeLLMDevice.h rename to src/devices/fake/fakeLLMDevice/FakeLLMDevice.h index ff99cbf84d6..d093b80803d 100644 --- a/src/devices/fake/fakeLLMDevice/fakeLLMDevice.h +++ b/src/devices/fake/fakeLLMDevice/FakeLLMDevice.h @@ -9,25 +9,32 @@ #include #include #include +#include "FakeLLMDevice_ParamsParser.h" /** * @ingroup dev_impl_fake dev_impl_other * * @brief `fakeLLMDevice` : a fake device which implements the ILLM interface for testing purposes. * +* Parameters required by this device are shown in class: FakeLLMDevice_ParamsParser +* */ -class fakeLLMDevice : public yarp::dev::ILLM, - public yarp::dev::DeviceDriver +class FakeLLMDevice : public yarp::dev::ILLM, + public yarp::dev::DeviceDriver, + public FakeLLMDevice_ParamsParser { public: - fakeLLMDevice() : m_conversation{} {} + FakeLLMDevice() : m_conversation{} {} bool setPrompt(const std::string &prompt) override; bool readPrompt(std::string &oPromp) override; bool ask(const std::string &question, yarp::dev::LLM_Message &oAnswer) override; bool getConversation(std::vector &oConversation) override; bool deleteConversation() noexcept override; + bool open(yarp::os::Searchable& config) override; + bool close() override; + private: std::vector m_conversation; }; diff --git a/src/devices/fake/fakeLLMDevice/FakeLLMDevice_ParamsParser.cpp b/src/devices/fake/fakeLLMDevice/FakeLLMDevice_ParamsParser.cpp new file mode 100644 index 00000000000..9fde0f5d9e4 --- /dev/null +++ b/src/devices/fake/fakeLLMDevice/FakeLLMDevice_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#include "FakeLLMDevice_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeLLMDeviceParamsCOMPONENT, "yarp.device.FakeLLMDevice") +} + + +FakeLLMDevice_ParamsParser::FakeLLMDevice_ParamsParser() +{ +} + + +std::vector FakeLLMDevice_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("initial_prompt"); + return params; +} + + +bool FakeLLMDevice_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeLLMDeviceParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter initial_prompt + { + if (config.check("initial_prompt")) + { + m_initial_prompt = config.find("initial_prompt").asString(); + yCInfo(FakeLLMDeviceParamsCOMPONENT) << "Parameter 'initial_prompt' using value:" << m_initial_prompt; + } + else + { + yCInfo(FakeLLMDeviceParamsCOMPONENT) << "Parameter 'initial_prompt' using DEFAULT value:" << m_initial_prompt; + } + prop_check.unput("initial_prompt"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeLLMDeviceParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeLLMDeviceParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeLLMDevice_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeLLMDevice\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'initial_prompt': intial prompt\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeLLMDevice --initial_prompt \n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeLLMDevice\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeLLMDevice/FakeLLMDevice_ParamsParser.h b/src/devices/fake/fakeLLMDevice/FakeLLMDevice_ParamsParser.h new file mode 100644 index 00000000000..155645c828f --- /dev/null +++ b/src/devices/fake/fakeLLMDevice/FakeLLMDevice_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#ifndef FAKELLMDEVICE_PARAMSPARSER_H +#define FAKELLMDEVICE_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeLLMDevice. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-------------:|:-----:| +* | - | initial_prompt | string | - | - | 0 | intial prompt | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeLLMDevice --initial_prompt +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeLLMDevice +* \endcode +* +*/ + +class FakeLLMDevice_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeLLMDevice_ParamsParser(); + ~FakeLLMDevice_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeLLMDevice"}; + const std::string m_device_name = {"fakeLLMDevice"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_initial_prompt_defaultValue = {""}; + + std::string m_initial_prompt = {}; //This default value of this string is an empty string. It is highly recommended to provide a suggested value also for optional string parameters. + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeLLMDevice/FakeLLMDevice_params.md b/src/devices/fake/fakeLLMDevice/FakeLLMDevice_params.md new file mode 100644 index 00000000000..4dd32d70207 --- /dev/null +++ b/src/devices/fake/fakeLLMDevice/FakeLLMDevice_params.md @@ -0,0 +1 @@ + * | | initial_prompt | string | - | - | No | intial prompt | | diff --git a/src/devices/fake/fakeLaser/CMakeLists.txt b/src/devices/fake/fakeLaser/CMakeLists.txt index 874c92a22ed..f2a693b8195 100644 --- a/src/devices/fake/fakeLaser/CMakeLists.txt +++ b/src/devices/fake/fakeLaser/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeLaser CATEGORY device TYPE FakeLaser - INCLUDE fakeLaser.h + INCLUDE FakeLaser.h + GENERATE_PARSER DEPENDS "TARGET YARP::YARP_math") if(NOT SKIP_fakeLaser) @@ -16,8 +17,10 @@ if(NOT SKIP_fakeLaser) target_sources(yarp_fakeLaser PRIVATE - fakeLaser.h - fakeLaser.cpp + FakeLaser.h + FakeLaser.cpp + FakeLaser_ParamsParser.h + FakeLaser_ParamsParser.cpp ) target_link_libraries(yarp_fakeLaser diff --git a/src/devices/fake/fakeLaser/fakeLaser.cpp b/src/devices/fake/fakeLaser/FakeLaser.cpp similarity index 89% rename from src/devices/fake/fakeLaser/fakeLaser.cpp rename to src/devices/fake/fakeLaser/FakeLaser.cpp index 44e8986f3aa..e20dc70a738 100644 --- a/src/devices/fake/fakeLaser/fakeLaser.cpp +++ b/src/devices/fake/fakeLaser/FakeLaser.cpp @@ -5,7 +5,7 @@ #define _USE_MATH_DEFINES -#include "fakeLaser.h" +#include "FakeLaser.h" #include #include @@ -29,10 +29,10 @@ using namespace yarp::os; using namespace yarp::dev; using namespace yarp::dev::Nav2D; -// see FakeLaser.h for device documentation - bool FakeLaser::open(yarp::os::Searchable& config) { + if (!this->parseParams(config)) {return false;} + m_info = "Fake Laser device for test/debugging"; m_device_status = DEVICE_OK_STANDBY; @@ -44,32 +44,25 @@ bool FakeLaser::open(yarp::os::Searchable& config) { yCInfo(FAKE_LASER,"Some examples:"); yCInfo(FAKE_LASER,"yarpdev --device fakeLaser --help"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test no_obstacles"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_pattern"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_constant --const_distance 0.5"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_constant --const_distance 0.5 --SENSOR::resolution 0.5 --SKIP::min 0 50 --SKIP::max 10 60"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_file mymap.map"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_port /fakeLaser/location:i"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_server /localizationServer"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_client /fakeLaser/localizationClient --localization_server /localizationServer"); - yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 10 --name /fakeLaser:o --test use_mapfile --map_context context --map_file mymap.map"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test no_obstacles"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_pattern"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_constant --const_distance 0.5"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_constant --const_distance 0.5 --SENSOR::resolution 0.5 --SKIP::min 0 50 --SKIP::max 10 60"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_mapfile --map_file mymap.map"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_port /fakeLaser/location:i"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_server /localizationServer"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_client /fakeLaser/localizationClient --localization_server /localizationServer"); + yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_mapfile --map_context context --map_file mymap.map"); yCInfo(FAKE_LASER,"yarpdev --device rangefinder2D_nws_yarp --subdevice fakeLaser --period 0.01 --name /fakeLaser:o --test use_mapfile --map_file mymap.map --localization_client /fakeLaser/localizationClient --localization_server /localization2D_nws_yarp --localization_device localization2D_nwc_yarp"); return false; } - bool br = config.check("GENERAL"); - if (br != false) - { - yarp::os::Searchable& general_config = config.findGroup("GENERAL"); - m_period = general_config.check("period", Value(0.02), "Period of the sampling thread in s").asFloat64(); - this->setPeriod(m_period); - } - - std::string string_test_mode = config.check("test", Value(std::string("use_pattern")), "string to select test mode").asString(); + std::string string_test_mode = m_test; if (string_test_mode == "no_obstacles") { m_test_mode = NO_OBSTACLES; } else if (string_test_mode == "use_pattern") { m_test_mode = USE_PATTERN; } else if (string_test_mode == "use_mapfile") { m_test_mode = USE_MAPFILE; } else if (string_test_mode == "use_constant") { m_test_mode = USE_CONSTANT_VALUE; } + else if (string_test_mode == "use_square_trap") { m_test_mode = USE_SQUARE_TRAP; } else { yCError(FAKE_LASER) << "invalid/unknown value for param 'test'"; return false; } //parse all the parameters related to the linear/angular range of the sensor @@ -79,22 +72,36 @@ bool FakeLaser::open(yarp::os::Searchable& config) return false; } - //the different fake laser modalities - else if (m_test_mode == USE_CONSTANT_VALUE) + if (m_test_mode == USE_SQUARE_TRAP) { - if (config.check("const_distance")) - { - m_const_value = config.check("const_distance", Value(1.0), "default constant distance").asFloat64(); + m_robot_loc_x = 0; + m_robot_loc_y = 0; + m_robot_loc_t = 0; + m_map.m_map_name = "test_map_10x10m"; + m_map.m_resolution = 0.01; //m/pixel + m_map.m_origin.setOrigin(-5,-5,0); //m + m_map.setSize_in_meters(10,10); + for (size_t y = 0; y < m_map.m_height; y++) + { + for (size_t x = 0; x < m_map.m_width; x++) + { + m_map.setOccupancyData(yarp::dev::Nav2D::XYCell(x, y),0); + m_map.setMapFlag(yarp::dev::Nav2D::XYCell(x, y), MapGrid2D::map_flags::MAP_CELL_FREE); + } } + m_originally_loaded_map = m_map; + trap_the_robot(3); //3m + MapGrid2D::map_flags vv; + m_map.saveToFile("mio1"); } else if (m_test_mode == USE_MAPFILE) { std::string map_file; - if (config.check("map_context") && config.check("map_file")) + if (!m_MAP_MODE_map_context.empty() && !m_MAP_MODE_map_file.empty()) { yarp::os::ResourceFinder rf; - std::string tmp_filename = config.find("map_file").asString(); - std::string tmp_contextname = config.find("map_context").asString(); + std::string tmp_filename = m_MAP_MODE_map_file; + std::string tmp_contextname = m_MAP_MODE_map_context; rf.setDefaultContext(tmp_contextname); rf.setDefaultConfigFile(tmp_filename); bool b = rf.configure(0, nullptr); @@ -111,9 +118,9 @@ bool FakeLaser::open(yarp::os::Searchable& config) yCWarning(FAKE_LASER, "Unable to find file: %s from context: %s\n", tmp_filename.c_str(), tmp_contextname.c_str()); } } - else if (config.check("map_file")) + else if (!m_MAP_MODE_map_file.empty()) { - map_file = config.check("map_file", Value(std::string("map.yaml")), "map filename").asString(); + map_file = m_MAP_MODE_map_file; } else { @@ -134,7 +141,7 @@ bool FakeLaser::open(yarp::os::Searchable& config) } m_map = m_originally_loaded_map; - if (config.check("localization_port")) + if (!m_localization_port.empty()) { std::string localization_port_name = config.check("localization_port", Value(std::string("/fakeLaser/location:i")), "name of localization input port").asString(); m_loc_port = new yarp::os::BufferedPort; @@ -142,14 +149,14 @@ bool FakeLaser::open(yarp::os::Searchable& config) yCInfo(FAKE_LASER) << "Robot localization will be obtained from port" << localization_port_name; m_loc_mode = LOC_FROM_PORT; } - else if (config.check("localization_client") || - config.check("localization_server") || - config.check("localization_device")) + else if (!m_localization_client.empty() || + !m_localization_server.empty() || + !m_localization_device.empty()) { Property loc_options; - std::string localization_client_name = config.check("localization_client", Value(std::string("/fakeLaser/localizationClient")), "local name of localization client device").asString(); - std::string localization_server_name = config.check("localization_server", Value(std::string("/localizationServer")), "the name of the remote localization server device").asString(); - std::string localization_device_name = config.check("localization_device", Value(std::string("localization2DClient")), "the type of localization device").asString(); + std::string localization_client_name = m_localization_client; + std::string localization_server_name = m_localization_server; + std::string localization_device_name = m_localization_device; loc_options.put("device", localization_device_name); loc_options.put("local", localization_client_name); loc_options.put("remote", localization_server_name); @@ -233,7 +240,7 @@ bool FakeLaser::setHorizontalResolution(double step) bool FakeLaser::setScanRate(double rate) { m_mutex.lock(); - m_period = (1.0 / rate); + m_GENERAL_period = (1.0 / rate); m_mutex.unlock(); return false; } @@ -337,7 +344,7 @@ bool FakeLaser::acquireDataFromHW() { for (size_t i = 0; i < m_sensorsNum; i++) { - m_laser_data.push_back(m_const_value); + m_laser_data.push_back(m_CONSTANT_MODE_const_distance); } } else if (m_test_mode == USE_MAPFILE) diff --git a/src/devices/fake/fakeLaser/fakeLaser.h b/src/devices/fake/fakeLaser/FakeLaser.h similarity index 72% rename from src/devices/fake/fakeLaser/fakeLaser.h rename to src/devices/fake/fakeLaser/FakeLaser.h index 7f620233f71..1acdec9f0ed 100644 --- a/src/devices/fake/fakeLaser/fakeLaser.h +++ b/src/devices/fake/fakeLaser/FakeLaser.h @@ -22,30 +22,14 @@ #include #include +#include "FakeLaser_ParamsParser.h" + /** * @ingroup dev_impl_fake dev_impl_lidar * * @brief `fakeLaser` : fake sensor device driver for testing purposes and reference for IRangefinder2D devices. * -* | YARP device name | -* |:-----------------:| -* | `fakeLaser` | -* -* \section fakeLaser_device_parameters Description of input parameters -* -* Parameters accepted in the config argument of the open method: -* | Parameter name | Type | Units | Default Value | Required | Description | Notes | -* |:-------------------:|:------:|:-----:|:-------------:|:--------:|:-----------:|:-----:| -* | test | string | - | - | Yes | Choose the modality | It can be one of the following: no_obstacles, use_pattern, use_mapfile | -* | localization_port | string | - | - | No | Full name of the port to which device connects to receive the localization data | | -* | localization_client | string | - | - | No | Full name of the local transformClient opened by the device | It cannot be used togheter if localization_port parameter is set | -* | localization_device | string | - | - | No | Type of localization device, e.g. localization2DClient, localization2D_nwc_yarp | It cannot be used togheter if localization_port parameter is set | -* | map_file | string | - | - | No | Full path to a .map file | Mandatory if --test use_mapfile option has been set | -* | clip_max | double | m | 3.5 | No | Maximum detectable distance for an obstacle | - | -* | clip_min | double | m | 0.1 | No | Minimum detectable distance for an obstacle | - | -* | max_angle | double | deg | 360 | No | Angular range of the sensor | - | -* | min_angle | double | deg | 0 | No | Angular range of the sensor | - | -* | resolution | double | deg | 1.0 | No | Device resolution | - | +* Parameters required by this device are shown in class: FakeLaser_ParamsParser * * \section Usage examples: * yarpdev --device fakeLaser --help @@ -60,16 +44,16 @@ class FakeLaser : public yarp::os::PeriodicThread, public yarp::dev::Lidar2DDeviceBase, public yarp::dev::DeviceDriver, - public yarp::os::PortReader + public yarp::os::PortReader, + public FakeLaser_ParamsParser { protected: - enum test_mode_t { NO_OBSTACLES = 0, USE_PATTERN =1, USE_MAPFILE =2, USE_CONSTANT_VALUE =3 }; + enum test_mode_t { NO_OBSTACLES = 0, USE_PATTERN =1, USE_MAPFILE =2, USE_CONSTANT_VALUE =3, USE_SQUARE_TRAP=4 }; enum localization_mode_t { LOC_NOT_SET=0, LOC_FROM_PORT = 1, LOC_FROM_CLIENT = 2 }; test_mode_t m_test_mode; localization_mode_t m_loc_mode; - double m_period; yarp::dev::Nav2D::MapGrid2D m_originally_loaded_map; yarp::dev::Nav2D::MapGrid2D m_map; yarp::os::BufferedPort* m_loc_port; @@ -84,7 +68,6 @@ class FakeLaser : public yarp::os::PeriodicThread, std::random_device* m_rd; std::mt19937* m_gen; std::uniform_real_distribution<>* m_dis; - double m_const_value=1; yarp::os::Port m_rpcPort; diff --git a/src/devices/fake/fakeLaser/FakeLaser_ParamsParser.cpp b/src/devices/fake/fakeLaser/FakeLaser_ParamsParser.cpp new file mode 100644 index 00000000000..e776356af4a --- /dev/null +++ b/src/devices/fake/fakeLaser/FakeLaser_ParamsParser.cpp @@ -0,0 +1,273 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#include "FakeLaser_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeLaserParamsCOMPONENT, "yarp.device.FakeLaser") +} + + +FakeLaser_ParamsParser::FakeLaser_ParamsParser() +{ +} + + +std::vector FakeLaser_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("test"); + params.push_back("localization_port"); + params.push_back("localization_server"); + params.push_back("localization_client"); + params.push_back("localization_device"); + params.push_back("MAP_MODE::map_file"); + params.push_back("MAP_MODE::map_context"); + params.push_back("clip_max"); + params.push_back("clip_min"); + params.push_back("GENERAL::period"); + params.push_back("CONSTANT_MODE::const_distance"); + return params; +} + + +bool FakeLaser_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeLaserParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter test + { + if (config.check("test")) + { + m_test = config.find("test").asString(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'test' using value:" << m_test; + } + else + { + yCError(FakeLaserParamsCOMPONENT) << "Mandatory parameter 'test' not found!"; + yCError(FakeLaserParamsCOMPONENT) << "Description of the parameter: Choose the modality"; + return false; + } + prop_check.unput("test"); + } + + //Parser of parameter localization_port + { + if (config.check("localization_port")) + { + m_localization_port = config.find("localization_port").asString(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'localization_port' using value:" << m_localization_port; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'localization_port' using DEFAULT value:" << m_localization_port; + } + prop_check.unput("localization_port"); + } + + //Parser of parameter localization_server + { + if (config.check("localization_server")) + { + m_localization_server = config.find("localization_server").asString(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'localization_server' using value:" << m_localization_server; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'localization_server' using DEFAULT value:" << m_localization_server; + } + prop_check.unput("localization_server"); + } + + //Parser of parameter localization_client + { + if (config.check("localization_client")) + { + m_localization_client = config.find("localization_client").asString(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'localization_client' using value:" << m_localization_client; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'localization_client' using DEFAULT value:" << m_localization_client; + } + prop_check.unput("localization_client"); + } + + //Parser of parameter localization_device + { + if (config.check("localization_device")) + { + m_localization_device = config.find("localization_device").asString(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'localization_device' using value:" << m_localization_device; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'localization_device' using DEFAULT value:" << m_localization_device; + } + prop_check.unput("localization_device"); + } + + //Parser of parameter MAP_MODE::map_file + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("MAP_MODE"); + if (sectionp.check("map_file")) + { + m_MAP_MODE_map_file = sectionp.find("map_file").asString(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'MAP_MODE::map_file' using value:" << m_MAP_MODE_map_file; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'MAP_MODE::map_file' using DEFAULT value:" << m_MAP_MODE_map_file; + } + prop_check.unput("MAP_MODE::map_file"); + } + + //Parser of parameter MAP_MODE::map_context + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("MAP_MODE"); + if (sectionp.check("map_context")) + { + m_MAP_MODE_map_context = sectionp.find("map_context").asString(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'MAP_MODE::map_context' using value:" << m_MAP_MODE_map_context; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'MAP_MODE::map_context' using DEFAULT value:" << m_MAP_MODE_map_context; + } + prop_check.unput("MAP_MODE::map_context"); + } + + //Parser of parameter clip_max + { + if (config.check("clip_max")) + { + m_clip_max = config.find("clip_max").asFloat64(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'clip_max' using value:" << m_clip_max; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'clip_max' using DEFAULT value:" << m_clip_max; + } + prop_check.unput("clip_max"); + } + + //Parser of parameter clip_min + { + if (config.check("clip_min")) + { + m_clip_min = config.find("clip_min").asFloat64(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'clip_min' using value:" << m_clip_min; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'clip_min' using DEFAULT value:" << m_clip_min; + } + prop_check.unput("clip_min"); + } + + //Parser of parameter GENERAL::period + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("period")) + { + m_GENERAL_period = sectionp.find("period").asFloat64(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'GENERAL::period' using value:" << m_GENERAL_period; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'GENERAL::period' using DEFAULT value:" << m_GENERAL_period; + } + prop_check.unput("GENERAL::period"); + } + + //Parser of parameter CONSTANT_MODE::const_distance + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("CONSTANT_MODE"); + if (sectionp.check("const_distance")) + { + m_CONSTANT_MODE_const_distance = sectionp.find("const_distance").asFloat64(); + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'CONSTANT_MODE::const_distance' using value:" << m_CONSTANT_MODE_const_distance; + } + else + { + yCInfo(FakeLaserParamsCOMPONENT) << "Parameter 'CONSTANT_MODE::const_distance' using DEFAULT value:" << m_CONSTANT_MODE_const_distance; + } + prop_check.unput("CONSTANT_MODE::const_distance"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeLaserParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeLaserParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeLaser_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeLaser\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'test': Choose the modality\n"); + doc = doc + std::string("'localization_port': Full name of the port to which device connects to receive the localization data\n"); + doc = doc + std::string("'localization_server': Full name of the port to which device connects to receive the localization data\n"); + doc = doc + std::string("'localization_client': Full name of the local transformClient opened by the device\n"); + doc = doc + std::string("'localization_device': Type of localization device, e.g. localization2DClient, localization2D_nwc_yarp\n"); + doc = doc + std::string("'MAP_MODE::map_file': Full path to a .map file\n"); + doc = doc + std::string("'MAP_MODE::map_context': Full path to a .map file\n"); + doc = doc + std::string("'clip_max': Maximum detectable distance for an obstacle\n"); + doc = doc + std::string("'clip_min': Minimum detectable distance for an obstacle\n"); + doc = doc + std::string("'GENERAL::period': Thread period\n"); + doc = doc + std::string("'CONSTANT_MODE::const_distance': Default const distance for mode use_constant\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeLaser --test use_pattern --localization_port /fakeLaser/location:i --localization_server /localizationServer --localization_client /fakeLaser/localizationClient --localization_device localization2DClient --MAP_MODE::map_file --MAP_MODE::map_context --clip_max 3.5 --clip_min 0.1 --GENERAL::period 0.02 --CONSTANT_MODE::const_distance 1\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeLaser --test use_pattern\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeLaser/FakeLaser_ParamsParser.h b/src/devices/fake/fakeLaser/FakeLaser_ParamsParser.h new file mode 100644 index 00000000000..10830b811a4 --- /dev/null +++ b/src/devices/fake/fakeLaser/FakeLaser_ParamsParser.h @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#ifndef FAKELASER_PARAMSPARSER_H +#define FAKELASER_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeLaser. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:-------------:|:-------------------:|:------:|:-----:|:-----------------------------:|:--------:|:-------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------:| +* | - | test | string | - | use_pattern | 1 | Choose the modality | It can be one of the following: no_obstacles, use_pattern, use_mapfile, use_constant, use_square_trap | +* | - | localization_port | string | - | /fakeLaser/location:i | 0 | Full name of the port to which device connects to receive the localization data | - | +* | - | localization_server | string | - | /localizationServer | 0 | Full name of the port to which device connects to receive the localization data | - | +* | - | localization_client | string | - | /fakeLaser/localizationClient | 0 | Full name of the local transformClient opened by the device | It cannot be used togheter if localization_port parameter is set | +* | - | localization_device | string | - | localization2DClient | 0 | Type of localization device, e.g. localization2DClient, localization2D_nwc_yarp | It cannot be used togheter if localization_port parameter is set | +* | MAP_MODE | map_file | string | - | - | 0 | Full path to a .map file | Mandatory if --test use_mapfile option has been set | +* | MAP_MODE | map_context | string | - | - | 0 | Full path to a .map file | Mandatory if --test use_mapfile option has been set | +* | - | clip_max | double | m | 3.5 | 0 | Maximum detectable distance for an obstacle | - | +* | - | clip_min | double | m | 0.1 | 0 | Minimum detectable distance for an obstacle | - | +* | GENERAL | period | double | s | 0.02 | 0 | Thread period | - | +* | CONSTANT_MODE | const_distance | double | m | 1 | 0 | Default const distance for mode use_constant | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeLaser --test use_pattern --localization_port /fakeLaser/location:i --localization_server /localizationServer --localization_client /fakeLaser/localizationClient --localization_device localization2DClient --MAP_MODE::map_file --MAP_MODE::map_context --clip_max 3.5 --clip_min 0.1 --GENERAL::period 0.02 --CONSTANT_MODE::const_distance 1 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeLaser --test use_pattern +* \endcode +* +*/ + +class FakeLaser_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeLaser_ParamsParser(); + ~FakeLaser_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeLaser"}; + const std::string m_device_name = {"fakeLaser"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_test_defaultValue = {"use_pattern"}; + const std::string m_localization_port_defaultValue = {"/fakeLaser/location:i"}; + const std::string m_localization_server_defaultValue = {"/localizationServer"}; + const std::string m_localization_client_defaultValue = {"/fakeLaser/localizationClient"}; + const std::string m_localization_device_defaultValue = {"localization2DClient"}; + const std::string m_MAP_MODE_map_file_defaultValue = {""}; + const std::string m_MAP_MODE_map_context_defaultValue = {""}; + const std::string m_clip_max_defaultValue = {"3.5"}; + const std::string m_clip_min_defaultValue = {"0.1"}; + const std::string m_GENERAL_period_defaultValue = {"0.02"}; + const std::string m_CONSTANT_MODE_const_distance_defaultValue = {"1"}; + + std::string m_test = {"use_pattern"}; + std::string m_localization_port = {"/fakeLaser/location:i"}; + std::string m_localization_server = {"/localizationServer"}; + std::string m_localization_client = {"/fakeLaser/localizationClient"}; + std::string m_localization_device = {"localization2DClient"}; + std::string m_MAP_MODE_map_file = {}; //This default value of this string is an empty string. It is highly recommended to provide a suggested value also for optional string parameters. + std::string m_MAP_MODE_map_context = {}; //This default value of this string is an empty string. It is highly recommended to provide a suggested value also for optional string parameters. + double m_clip_max = {3.5}; + double m_clip_min = {0.1}; + double m_GENERAL_period = {0.02}; + double m_CONSTANT_MODE_const_distance = {1}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeLaser/FakeLaser_params.md b/src/devices/fake/fakeLaser/FakeLaser_params.md new file mode 100644 index 00000000000..5d6b16bc5e0 --- /dev/null +++ b/src/devices/fake/fakeLaser/FakeLaser_params.md @@ -0,0 +1,11 @@ +* | | test | string | - | use_pattern | Yes | Choose the modality | It can be one of the following: no_obstacles, use_pattern, use_mapfile, use_constant, use_square_trap | +* | | localization_port | string | - | /fakeLaser/location:i | No | Full name of the port to which device connects to receive the localization data | | +* | | localization_server | string | - | /localizationServer | No | Full name of the port to which device connects to receive the localization data | | +* | | localization_client | string | - | /fakeLaser/localizationClient | No | Full name of the local transformClient opened by the device | It cannot be used togheter if localization_port parameter is set | +* | | localization_device | string | - | localization2DClient | No | Type of localization device, e.g. localization2DClient, localization2D_nwc_yarp | It cannot be used togheter if localization_port parameter is set | +* | MAP_MODE | map_file | string | - | - | No | Full path to a .map file | Mandatory if --test use_mapfile option has been set | +* | MAP_MODE | map_context | string | - | - | No | Full path to a .map file | Mandatory if --test use_mapfile option has been set | +* | | clip_max | double | m | 3.5 | No | Maximum detectable distance for an obstacle | - | +* | | clip_min | double | m | 0.1 | No | Minimum detectable distance for an obstacle | - | +* | GENERAL | period | double | s | 0.02 | 0 | Thread period | - | +* | CONSTANT_MODE | const_distance |double | m | 1 | 0 | Default const distance for mode use_constant | - | diff --git a/src/devices/fake/fakeLaser/tests/fakeLaser_test.cpp b/src/devices/fake/fakeLaser/tests/fakeLaser_test.cpp index 2899b182584..4b835a311a3 100644 --- a/src/devices/fake/fakeLaser/tests/fakeLaser_test.cpp +++ b/src/devices/fake/fakeLaser/tests/fakeLaser_test.cpp @@ -32,7 +32,8 @@ TEST_CASE("dev::FakeLaserTest", "[yarp::dev]") Property las_cfg; las_cfg.put("device", "fakeLaser"); las_cfg.put("test", "use_constant"); - las_cfg.put("const_distance", 0.5); + Property& cm_cfg= las_cfg.addGroup("CONSTANT_MODE"); + cm_cfg.put("const_distance", 0.5); REQUIRE(fakelaserdev.open(las_cfg)); REQUIRE(fakelaserdev.view(irng)); } diff --git a/src/devices/fake/fakeLaserWithMotor/CMakeLists.txt b/src/devices/fake/fakeLaserWithMotor/CMakeLists.txt index 2f355330fc1..80943ec4c9e 100644 --- a/src/devices/fake/fakeLaserWithMotor/CMakeLists.txt +++ b/src/devices/fake/fakeLaserWithMotor/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeLaserWithMotor CATEGORY device TYPE FakeLaserWithMotor - INCLUDE fakeLaserWithMotor.h + INCLUDE FakeLaserWithMotor.h + GENERATE_PARSER DEPENDS "TARGET YARP::YARP_math") if(NOT SKIP_fakeLaserWithMotor) @@ -16,11 +17,13 @@ if(NOT SKIP_fakeLaserWithMotor) target_sources(yarp_fakeLaserWithMotor PRIVATE - fakeLaserWithMotor.h - fakeLaserWithMotor.cpp - fakeLaserWithMotor_laser.cpp - fakeLaserWithMotor_motors.cpp - fakeLaserWithMotor_utils.cpp + FakeLaserWithMotor.h + FakeLaserWithMotor.cpp + FakeLaserWithMotor_laser.cpp + FakeLaserWithMotor_motors.cpp + FakeLaserWithMotor_utils.cpp + FakeLaserWithMotor_ParamsParser.cpp + FakeLaserWithMotor_ParamsParser.h ) target_link_libraries(yarp_fakeLaserWithMotor diff --git a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor.cpp b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor.cpp similarity index 90% rename from src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor.cpp rename to src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor.cpp index b433c625a52..55fb771d4dd 100644 --- a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor.cpp +++ b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor.cpp @@ -5,7 +5,7 @@ #define _USE_MATH_DEFINES -#include "fakeLaserWithMotor.h" +#include "FakeLaserWithMotor.h" #include #include @@ -31,6 +31,8 @@ using namespace yarp::dev::Nav2D; bool FakeLaserWithMotor::open(yarp::os::Searchable& config) { + if (!this->parseParams(config)) {return false;} + m_info = "Fake Laser device for test/debugging"; m_device_status = DEVICE_OK_STANDBY; @@ -55,15 +57,7 @@ bool FakeLaserWithMotor::open(yarp::os::Searchable& config) return false; } - bool br = config.check("GENERAL"); - if (br != false) - { - yarp::os::Searchable& general_config = config.findGroup("GENERAL"); - m_period = general_config.check("period", Value(0.02), "Period of the sampling thread in s").asFloat64(); - this->setPeriod(m_period); - } - - std::string string_test_mode = config.check("test", Value(std::string("use_pattern")), "string to select test mode").asString(); + std::string string_test_mode = m_test; if (string_test_mode == "no_obstacles") { m_test_mode = NO_OBSTACLES; } else if (string_test_mode == "use_pattern") { m_test_mode = USE_PATTERN; } else if (string_test_mode == "use_mapfile") { m_test_mode = USE_MAPFILE; } @@ -78,15 +72,7 @@ bool FakeLaserWithMotor::open(yarp::os::Searchable& config) return false; } - //the different fake laser modalities - else if (m_test_mode == USE_CONSTANT_VALUE) - { - if (config.check("const_distance")) - { - m_const_value = config.check("const_distance", Value(1.0), "default constant distance").asFloat64(); - } - } - else if (m_test_mode == USE_SQUARE_TRAP) + if (m_test_mode == USE_SQUARE_TRAP) { m_robot_loc_x = 0; m_robot_loc_y = 0; @@ -111,11 +97,11 @@ bool FakeLaserWithMotor::open(yarp::os::Searchable& config) else if (m_test_mode == USE_MAPFILE) { std::string map_file; - if (config.check("map_context") && config.check("map_file")) + if (!m_MAP_MODE_map_context.empty() && !m_MAP_MODE_map_file.empty()) { yarp::os::ResourceFinder rf; - std::string tmp_filename = config.find("map_file").asString(); - std::string tmp_contextname = config.find("map_context").asString(); + std::string tmp_filename = m_MAP_MODE_map_file; + std::string tmp_contextname = m_MAP_MODE_map_context; rf.setDefaultContext(tmp_contextname); rf.setDefaultConfigFile(tmp_filename); bool b = rf.configure(0, nullptr); @@ -132,9 +118,9 @@ bool FakeLaserWithMotor::open(yarp::os::Searchable& config) yCWarning(FAKE_LASER, "Unable to find file: %s from context: %s\n", tmp_filename.c_str(), tmp_contextname.c_str()); } } - else if (config.check("map_file")) + else if (!m_MAP_MODE_map_file.empty()) { - map_file = config.check("map_file", Value(std::string("map.yaml")), "map filename").asString(); + map_file = m_MAP_MODE_map_file; } else { @@ -226,7 +212,7 @@ void FakeLaserWithMotor::run() { if (_controlModes[i] == VOCAB_CM_VELOCITY) { - _encoders[i] = _encoders[i] + _command_speeds[i] * m_period; + _encoders[i] = _encoders[i] + _command_speeds[i] * m_GENERAL_period; } else if (_controlModes[i] == VOCAB_CM_POSITION) { diff --git a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor.h b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor.h similarity index 87% rename from src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor.h rename to src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor.h index 622e85e1149..554e60e2d5c 100644 --- a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor.h +++ b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor.h @@ -28,27 +28,14 @@ #include #include +#include "FakeLaserWithMotor_ParamsParser.h" + /** * @ingroup dev_impl_fake dev_impl_lidar * * @brief `fakeLaserWithMotor` : fake sensor device driver for testing purposes and reference for IRangefinder2D devices. * -* | YARP device name | -* |:-----------------:| -* | `fakeLaserWithMotor` | -* -* \section fakeLaser_device_parameters Description of input parameters -* -* Parameters accepted in the config argument of the open method: -* | Parameter name | Type | Units | Default Value | Required | Description | Notes | -* |:-------------------:|:------:|:-----:|:-------------:|:--------:|:-----------:|:-----:| -* | test | string | - | - | Yes | Choose the modality | It can be one of the following: no_obstacles, use_pattern, use_mapfile | -* | map_file | string | - | - | No | Full path to a .map file | Mandatory if --test use_mapfile option has been set | -* | clip_max | double | m | 3.5 | No | Maximum detectable distance for an obstacle | - | -* | clip_min | double | m | 0.1 | No | Minimum detectable distance for an obstacle | - | -* | max_angle | double | deg | 360 | No | Angular range of the sensor | - | -* | min_angle | double | deg | 0 | No | Angular range of the sensor | - | -* | resolution | double | deg | 1.0 | No | Device resolution | - | +* Parameters required by this device are shown in class: FakeLaserWithMotor_ParamsParser * * \section Usage examples: * yarpdev --device fakeLaser --help @@ -76,14 +63,14 @@ class FakeLaserWithMotor : public yarp::os::PeriodicThread, public yarp::dev::ImplementControlMode, public yarp::dev::ImplementInteractionMode, public yarp::dev::ImplementEncodersTimed, - public yarp::dev::ImplementAxisInfo + public yarp::dev::ImplementAxisInfo, + public FakeLaserWithMotor_ParamsParser { protected: enum test_mode_t { NO_OBSTACLES = 0, USE_PATTERN =1, USE_MAPFILE =2, USE_CONSTANT_VALUE =3, USE_SQUARE_TRAP }; test_mode_t m_test_mode; - double m_period; yarp::dev::Nav2D::MapGrid2D m_originally_loaded_map; yarp::dev::Nav2D::MapGrid2D m_map; @@ -98,13 +85,11 @@ class FakeLaserWithMotor : public yarp::os::PeriodicThread, std::random_device* m_rd; std::mt19937* m_gen; std::uniform_real_distribution<>* m_dis; - double m_const_value=1; yarp::os::Port m_rpcPort; public: FakeLaserWithMotor(double period = 0.02) : PeriodicThread(period), - m_period(period), m_test_mode(test_mode_t::NO_OBSTACLES), ImplementPositionControl(this), ImplementVelocityControl(this), diff --git a/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_ParamsParser.cpp b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_ParamsParser.cpp new file mode 100644 index 00000000000..48a9d59ec27 --- /dev/null +++ b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_ParamsParser.cpp @@ -0,0 +1,273 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#include "FakeLaserWithMotor_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeLaserWithMotorParamsCOMPONENT, "yarp.device.FakeLaserWithMotor") +} + + +FakeLaserWithMotor_ParamsParser::FakeLaserWithMotor_ParamsParser() +{ +} + + +std::vector FakeLaserWithMotor_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("test"); + params.push_back("localization_port"); + params.push_back("localization_server"); + params.push_back("localization_client"); + params.push_back("localization_device"); + params.push_back("MAP_MODE::map_file"); + params.push_back("MAP_MODE::map_context"); + params.push_back("clip_max"); + params.push_back("clip_min"); + params.push_back("GENERAL::period"); + params.push_back("CONSTANT_MODE::const_distance"); + return params; +} + + +bool FakeLaserWithMotor_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter test + { + if (config.check("test")) + { + m_test = config.find("test").asString(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'test' using value:" << m_test; + } + else + { + yCError(FakeLaserWithMotorParamsCOMPONENT) << "Mandatory parameter 'test' not found!"; + yCError(FakeLaserWithMotorParamsCOMPONENT) << "Description of the parameter: Choose the modality"; + return false; + } + prop_check.unput("test"); + } + + //Parser of parameter localization_port + { + if (config.check("localization_port")) + { + m_localization_port = config.find("localization_port").asString(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'localization_port' using value:" << m_localization_port; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'localization_port' using DEFAULT value:" << m_localization_port; + } + prop_check.unput("localization_port"); + } + + //Parser of parameter localization_server + { + if (config.check("localization_server")) + { + m_localization_server = config.find("localization_server").asString(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'localization_server' using value:" << m_localization_server; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'localization_server' using DEFAULT value:" << m_localization_server; + } + prop_check.unput("localization_server"); + } + + //Parser of parameter localization_client + { + if (config.check("localization_client")) + { + m_localization_client = config.find("localization_client").asString(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'localization_client' using value:" << m_localization_client; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'localization_client' using DEFAULT value:" << m_localization_client; + } + prop_check.unput("localization_client"); + } + + //Parser of parameter localization_device + { + if (config.check("localization_device")) + { + m_localization_device = config.find("localization_device").asString(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'localization_device' using value:" << m_localization_device; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'localization_device' using DEFAULT value:" << m_localization_device; + } + prop_check.unput("localization_device"); + } + + //Parser of parameter MAP_MODE::map_file + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("MAP_MODE"); + if (sectionp.check("map_file")) + { + m_MAP_MODE_map_file = sectionp.find("map_file").asString(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'MAP_MODE::map_file' using value:" << m_MAP_MODE_map_file; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'MAP_MODE::map_file' using DEFAULT value:" << m_MAP_MODE_map_file; + } + prop_check.unput("MAP_MODE::map_file"); + } + + //Parser of parameter MAP_MODE::map_context + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("MAP_MODE"); + if (sectionp.check("map_context")) + { + m_MAP_MODE_map_context = sectionp.find("map_context").asString(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'MAP_MODE::map_context' using value:" << m_MAP_MODE_map_context; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'MAP_MODE::map_context' using DEFAULT value:" << m_MAP_MODE_map_context; + } + prop_check.unput("MAP_MODE::map_context"); + } + + //Parser of parameter clip_max + { + if (config.check("clip_max")) + { + m_clip_max = config.find("clip_max").asFloat64(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'clip_max' using value:" << m_clip_max; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'clip_max' using DEFAULT value:" << m_clip_max; + } + prop_check.unput("clip_max"); + } + + //Parser of parameter clip_min + { + if (config.check("clip_min")) + { + m_clip_min = config.find("clip_min").asFloat64(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'clip_min' using value:" << m_clip_min; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'clip_min' using DEFAULT value:" << m_clip_min; + } + prop_check.unput("clip_min"); + } + + //Parser of parameter GENERAL::period + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("period")) + { + m_GENERAL_period = sectionp.find("period").asFloat64(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'GENERAL::period' using value:" << m_GENERAL_period; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'GENERAL::period' using DEFAULT value:" << m_GENERAL_period; + } + prop_check.unput("GENERAL::period"); + } + + //Parser of parameter CONSTANT_MODE::const_distance + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("CONSTANT_MODE"); + if (sectionp.check("const_distance")) + { + m_CONSTANT_MODE_const_distance = sectionp.find("const_distance").asFloat64(); + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'CONSTANT_MODE::const_distance' using value:" << m_CONSTANT_MODE_const_distance; + } + else + { + yCInfo(FakeLaserWithMotorParamsCOMPONENT) << "Parameter 'CONSTANT_MODE::const_distance' using DEFAULT value:" << m_CONSTANT_MODE_const_distance; + } + prop_check.unput("CONSTANT_MODE::const_distance"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeLaserWithMotorParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeLaserWithMotorParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeLaserWithMotor_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeLaserWithMotor\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'test': Choose the modality\n"); + doc = doc + std::string("'localization_port': Full name of the port to which device connects to receive the localization data\n"); + doc = doc + std::string("'localization_server': Full name of the port to which device connects to receive the localization data\n"); + doc = doc + std::string("'localization_client': Full name of the local transformClient opened by the device\n"); + doc = doc + std::string("'localization_device': Type of localization device, e.g. localization2DClient, localization2D_nwc_yarp\n"); + doc = doc + std::string("'MAP_MODE::map_file': Full path to a .map file\n"); + doc = doc + std::string("'MAP_MODE::map_context': Full path to a .map file\n"); + doc = doc + std::string("'clip_max': Maximum detectable distance for an obstacle\n"); + doc = doc + std::string("'clip_min': Minimum detectable distance for an obstacle\n"); + doc = doc + std::string("'GENERAL::period': Thread period\n"); + doc = doc + std::string("'CONSTANT_MODE::const_distance': Default const distance for mode use_constant\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeLaserWithMotor --test use_pattern --localization_port /fakeLaser/location:i --localization_server /localizationServer --localization_client /fakeLaser/localizationClient --localization_device localization2DClient --MAP_MODE::map_file --MAP_MODE::map_context --clip_max 3.5 --clip_min 0.1 --GENERAL::period 0.02 --CONSTANT_MODE::const_distance 1\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeLaserWithMotor --test use_pattern\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_ParamsParser.h b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_ParamsParser.h new file mode 100644 index 00000000000..cda7ce12958 --- /dev/null +++ b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_ParamsParser.h @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#ifndef FAKELASERWITHMOTOR_PARAMSPARSER_H +#define FAKELASERWITHMOTOR_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeLaserWithMotor. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:-------------:|:-------------------:|:------:|:-----:|:-----------------------------:|:--------:|:-------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------:| +* | - | test | string | - | use_pattern | 1 | Choose the modality | It can be one of the following: no_obstacles, use_pattern, use_mapfile, use_constant, use_square_trap | +* | - | localization_port | string | - | /fakeLaser/location:i | 0 | Full name of the port to which device connects to receive the localization data | - | +* | - | localization_server | string | - | /localizationServer | 0 | Full name of the port to which device connects to receive the localization data | - | +* | - | localization_client | string | - | /fakeLaser/localizationClient | 0 | Full name of the local transformClient opened by the device | It cannot be used togheter if localization_port parameter is set | +* | - | localization_device | string | - | localization2DClient | 0 | Type of localization device, e.g. localization2DClient, localization2D_nwc_yarp | It cannot be used togheter if localization_port parameter is set | +* | MAP_MODE | map_file | string | - | - | 0 | Full path to a .map file | Mandatory if --test use_mapfile option has been set | +* | MAP_MODE | map_context | string | - | - | 0 | Full path to a .map file | Mandatory if --test use_mapfile option has been set | +* | - | clip_max | double | m | 3.5 | 0 | Maximum detectable distance for an obstacle | - | +* | - | clip_min | double | m | 0.1 | 0 | Minimum detectable distance for an obstacle | - | +* | GENERAL | period | double | s | 0.02 | 0 | Thread period | - | +* | CONSTANT_MODE | const_distance | double | m | 1 | 0 | Default const distance for mode use_constant | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeLaserWithMotor --test use_pattern --localization_port /fakeLaser/location:i --localization_server /localizationServer --localization_client /fakeLaser/localizationClient --localization_device localization2DClient --MAP_MODE::map_file --MAP_MODE::map_context --clip_max 3.5 --clip_min 0.1 --GENERAL::period 0.02 --CONSTANT_MODE::const_distance 1 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeLaserWithMotor --test use_pattern +* \endcode +* +*/ + +class FakeLaserWithMotor_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeLaserWithMotor_ParamsParser(); + ~FakeLaserWithMotor_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeLaserWithMotor"}; + const std::string m_device_name = {"fakeLaserWithMotor"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_test_defaultValue = {"use_pattern"}; + const std::string m_localization_port_defaultValue = {"/fakeLaser/location:i"}; + const std::string m_localization_server_defaultValue = {"/localizationServer"}; + const std::string m_localization_client_defaultValue = {"/fakeLaser/localizationClient"}; + const std::string m_localization_device_defaultValue = {"localization2DClient"}; + const std::string m_MAP_MODE_map_file_defaultValue = {""}; + const std::string m_MAP_MODE_map_context_defaultValue = {""}; + const std::string m_clip_max_defaultValue = {"3.5"}; + const std::string m_clip_min_defaultValue = {"0.1"}; + const std::string m_GENERAL_period_defaultValue = {"0.02"}; + const std::string m_CONSTANT_MODE_const_distance_defaultValue = {"1"}; + + std::string m_test = {"use_pattern"}; + std::string m_localization_port = {"/fakeLaser/location:i"}; + std::string m_localization_server = {"/localizationServer"}; + std::string m_localization_client = {"/fakeLaser/localizationClient"}; + std::string m_localization_device = {"localization2DClient"}; + std::string m_MAP_MODE_map_file = {}; //This default value of this string is an empty string. It is highly recommended to provide a suggested value also for optional string parameters. + std::string m_MAP_MODE_map_context = {}; //This default value of this string is an empty string. It is highly recommended to provide a suggested value also for optional string parameters. + double m_clip_max = {3.5}; + double m_clip_min = {0.1}; + double m_GENERAL_period = {0.02}; + double m_CONSTANT_MODE_const_distance = {1}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_laser.cpp b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_laser.cpp similarity index 97% rename from src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_laser.cpp rename to src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_laser.cpp index 1c59cfba4b0..86964c4d9c4 100644 --- a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_laser.cpp +++ b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_laser.cpp @@ -5,7 +5,7 @@ #define _USE_MATH_DEFINES -#include "fakeLaserWithMotor.h" +#include "FakeLaserWithMotor.h" #include #include @@ -58,7 +58,7 @@ bool FakeLaserWithMotor::setHorizontalResolution(double step) bool FakeLaserWithMotor::setScanRate(double rate) { m_mutex.lock(); - m_period = (1.0 / rate); + m_GENERAL_period = (1.0 / rate); m_mutex.unlock(); return false; } @@ -113,7 +113,7 @@ bool FakeLaserWithMotor::acquireDataFromHW() { for (size_t i = 0; i < m_sensorsNum; i++) { - m_laser_data.push_back(m_const_value); + m_laser_data.push_back(m_CONSTANT_MODE_const_distance); } } else if (m_test_mode == USE_MAPFILE || diff --git a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_motors.cpp b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_motors.cpp similarity index 99% rename from src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_motors.cpp rename to src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_motors.cpp index fc81dbe449b..3fe9f29b411 100644 --- a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_motors.cpp +++ b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_motors.cpp @@ -5,7 +5,7 @@ #define _USE_MATH_DEFINES -#include "fakeLaserWithMotor.h" +#include "FakeLaserWithMotor.h" #include #include diff --git a/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_params.md b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_params.md new file mode 100644 index 00000000000..5d6b16bc5e0 --- /dev/null +++ b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_params.md @@ -0,0 +1,11 @@ +* | | test | string | - | use_pattern | Yes | Choose the modality | It can be one of the following: no_obstacles, use_pattern, use_mapfile, use_constant, use_square_trap | +* | | localization_port | string | - | /fakeLaser/location:i | No | Full name of the port to which device connects to receive the localization data | | +* | | localization_server | string | - | /localizationServer | No | Full name of the port to which device connects to receive the localization data | | +* | | localization_client | string | - | /fakeLaser/localizationClient | No | Full name of the local transformClient opened by the device | It cannot be used togheter if localization_port parameter is set | +* | | localization_device | string | - | localization2DClient | No | Type of localization device, e.g. localization2DClient, localization2D_nwc_yarp | It cannot be used togheter if localization_port parameter is set | +* | MAP_MODE | map_file | string | - | - | No | Full path to a .map file | Mandatory if --test use_mapfile option has been set | +* | MAP_MODE | map_context | string | - | - | No | Full path to a .map file | Mandatory if --test use_mapfile option has been set | +* | | clip_max | double | m | 3.5 | No | Maximum detectable distance for an obstacle | - | +* | | clip_min | double | m | 0.1 | No | Minimum detectable distance for an obstacle | - | +* | GENERAL | period | double | s | 0.02 | 0 | Thread period | - | +* | CONSTANT_MODE | const_distance |double | m | 1 | 0 | Default const distance for mode use_constant | - | diff --git a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_utils.cpp b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_utils.cpp similarity index 99% rename from src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_utils.cpp rename to src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_utils.cpp index c26ca4024a0..21d63088fe4 100644 --- a/src/devices/fake/fakeLaserWithMotor/fakeLaserWithMotor_utils.cpp +++ b/src/devices/fake/fakeLaserWithMotor/FakeLaserWithMotor_utils.cpp @@ -5,7 +5,7 @@ #define _USE_MATH_DEFINES -#include "fakeLaserWithMotor.h" +#include "FakeLaserWithMotor.h" #include #include diff --git a/src/devices/fake/fakeLaserWithMotor/tests/fakeLaserWithMotor_test.cpp b/src/devices/fake/fakeLaserWithMotor/tests/fakeLaserWithMotor_test.cpp index b210653f7fb..fa5325050f1 100644 --- a/src/devices/fake/fakeLaserWithMotor/tests/fakeLaserWithMotor_test.cpp +++ b/src/devices/fake/fakeLaserWithMotor/tests/fakeLaserWithMotor_test.cpp @@ -36,7 +36,8 @@ TEST_CASE("dev::FakeLaserWithMotorTest", "[yarp::dev]") Property las_cfg; las_cfg.put("device", "fakeLaserWithMotor"); las_cfg.put("test", "use_constant"); - las_cfg.put("const_distance", 0.5); + Property& cm_cfg = las_cfg.addGroup("CONSTANT_MODE"); + cm_cfg.put("const_distance", 0.5); REQUIRE(fakelaserdev.open(las_cfg)); REQUIRE(fakelaserdev.view(irng)); REQUIRE(fakelaserdev.view(ipos)); diff --git a/src/devices/fake/fakeLocalizerDevice/CMakeLists.txt b/src/devices/fake/fakeLocalizerDevice/CMakeLists.txt index ea5d86cc127..98183fc295e 100644 --- a/src/devices/fake/fakeLocalizerDevice/CMakeLists.txt +++ b/src/devices/fake/fakeLocalizerDevice/CMakeLists.txt @@ -7,9 +7,10 @@ endif() yarp_prepare_plugin(fakeLocalizer CATEGORY device - TYPE fakeLocalizer - INCLUDE fakeLocalizer.h + TYPE FakeLocalizer + INCLUDE FakeLocalizer.h DEPENDS "TARGET YARP::YARP_math" + GENERATE_PARSER ) if(NOT SKIP_fakeLocalizer) @@ -17,8 +18,10 @@ if(NOT SKIP_fakeLocalizer) target_sources(yarp_fakeLocalizer PRIVATE - fakeLocalizer.h - fakeLocalizer.cpp + FakeLocalizer.h + FakeLocalizer.cpp + FakeLocalizer_ParamsParser.h + FakeLocalizer_ParamsParser.cpp ) target_link_libraries(yarp_fakeLocalizer diff --git a/src/devices/fake/fakeLocalizerDevice/fakeLocalizer.cpp b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer.cpp similarity index 89% rename from src/devices/fake/fakeLocalizerDevice/fakeLocalizer.cpp rename to src/devices/fake/fakeLocalizerDevice/FakeLocalizer.cpp index 473364be2ab..9eeaa03a3dc 100644 --- a/src/devices/fake/fakeLocalizerDevice/fakeLocalizer.cpp +++ b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "fakeLocalizer.h" +#include "FakeLocalizer.h" #include #include @@ -37,7 +37,7 @@ namespace { YARP_LOG_COMPONENT(FAKELOCALIZER, "yarp.device.fakeLocalizer") } -bool fakeLocalizer::getLocalizationStatus(yarp::dev::Nav2D::LocalizationStatusEnum& status) +bool FakeLocalizer::getLocalizationStatus(yarp::dev::Nav2D::LocalizationStatusEnum& status) { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status"; return false; } @@ -46,7 +46,7 @@ bool fakeLocalizer::getLocalizationStatus(yarp::dev::Nav2D::LocalizationStatus return true; } -bool fakeLocalizer::getEstimatedPoses(std::vector& poses) +bool FakeLocalizer::getEstimatedPoses(std::vector& poses) { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status"; return false; } @@ -77,7 +77,7 @@ bool fakeLocalizer::getEstimatedPoses(std::vector& poses) return true; } -bool fakeLocalizer::getCurrentPosition(Map2DLocation& loc) +bool FakeLocalizer::getCurrentPosition(Map2DLocation& loc) { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status"; return false; } @@ -86,7 +86,7 @@ bool fakeLocalizer::getCurrentPosition(Map2DLocation& loc) return true; } -bool fakeLocalizer::setInitialPose(const Map2DLocation& loc) +bool FakeLocalizer::setInitialPose(const Map2DLocation& loc) { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status"; return false; } @@ -95,7 +95,7 @@ bool fakeLocalizer::setInitialPose(const Map2DLocation& loc) return true; } -bool fakeLocalizer::getCurrentPosition(Map2DLocation& loc, yarp::sig::Matrix& cov) +bool FakeLocalizer::getCurrentPosition(Map2DLocation& loc, yarp::sig::Matrix& cov) { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status"; return false; } @@ -104,7 +104,7 @@ bool fakeLocalizer::getCurrentPosition(Map2DLocation& loc, yarp::sig::Matrix& return true; } -bool fakeLocalizer::setInitialPose(const Map2DLocation& loc, const yarp::sig::Matrix& cov) +bool FakeLocalizer::setInitialPose(const Map2DLocation& loc, const yarp::sig::Matrix& cov) { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status"; return false; } @@ -113,7 +113,7 @@ bool fakeLocalizer::setInitialPose(const Map2DLocation& loc, const yarp::sig:: return true; } -bool fakeLocalizer::getEstimatedOdometry(yarp::dev::OdometryData& odom) +bool FakeLocalizer::getEstimatedOdometry(yarp::dev::OdometryData& odom) { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status" ; return false; } @@ -126,10 +126,12 @@ bool fakeLocalizer::getEstimatedOdometry(yarp::dev::OdometryData& odom) return true; } -bool fakeLocalizer::open(yarp::os::Searchable& config) +bool FakeLocalizer::open(yarp::os::Searchable& config) { + if (!this->parseParams(config)) {return false;} + yarp::os::Property p; - locThread = new fakeLocalizerThread(0.010, p); + locThread = new fakeLocalizerThread(m_period); if (!locThread->start()) { @@ -141,15 +143,15 @@ bool fakeLocalizer::open(yarp::os::Searchable& config) return true; } -fakeLocalizer::fakeLocalizer() +FakeLocalizer::FakeLocalizer() { } -fakeLocalizer::~fakeLocalizer() +FakeLocalizer::~FakeLocalizer() { } -bool fakeLocalizer::startLocalizationService() +bool FakeLocalizer::startLocalizationService() { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status"; return false; } @@ -157,7 +159,7 @@ bool fakeLocalizer::startLocalizationService() return true; } -bool fakeLocalizer::stopLocalizationService() +bool FakeLocalizer::stopLocalizationService() { std::lock_guard lock(m_mutex); if (!locThread) { yCError(FAKELOCALIZER) << "Invalid status"; return false; } @@ -165,7 +167,7 @@ bool fakeLocalizer::stopLocalizationService() return true; } -bool fakeLocalizer::close() +bool FakeLocalizer::close() { std::lock_guard lock(m_mutex); if (locThread) @@ -179,7 +181,7 @@ bool fakeLocalizer::close() ////////////////////////// -fakeLocalizerThread::fakeLocalizerThread(double _period, yarp::os::Searchable& _cfg) : PeriodicThread(_period), m_cfg(_cfg) +fakeLocalizerThread::fakeLocalizerThread(double _period) : PeriodicThread(_period) { m_last_locdata_received = -1; m_last_statistics_printed = -1; diff --git a/src/devices/fake/fakeLocalizerDevice/fakeLocalizer.h b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer.h similarity index 92% rename from src/devices/fake/fakeLocalizerDevice/fakeLocalizer.h rename to src/devices/fake/fakeLocalizerDevice/FakeLocalizer.h index fbab3049777..e4f57e5801e 100644 --- a/src/devices/fake/fakeLocalizerDevice/fakeLocalizer.h +++ b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer.h @@ -17,6 +17,8 @@ #include #include +#include "FakeLocalizer_ParamsParser.h" + using namespace yarp::os; class fakeLocalizerThread : @@ -31,11 +33,10 @@ class fakeLocalizerThread : yarp::dev::Nav2D::Map2DLocation m_current_loc; yarp::dev::Nav2D::Map2DLocation m_current_odom; std::mutex m_mutex_thread; - yarp::os::Searchable& m_cfg; std::string m_local_name; public: - fakeLocalizerThread(double _period, yarp::os::Searchable& _cfg); + fakeLocalizerThread(double _period); virtual bool threadInit() override; virtual void threadRelease() override; virtual void run() override; @@ -50,10 +51,14 @@ class fakeLocalizerThread : * @ingroup dev_impl_fake dev_impl_navigation * * \brief `fakeLocalizer` Documentation to be added + * + * Parameters required by this device are shown in class: FakeLocalizer_ParamsParser + * */ -class fakeLocalizer : +class FakeLocalizer : public yarp::dev::DeviceDriver, - public yarp::dev::Nav2D::ILocalization2D + public yarp::dev::Nav2D::ILocalization2D, + public FakeLocalizer_ParamsParser { public: fakeLocalizerThread *locThread = nullptr; @@ -61,8 +66,8 @@ class fakeLocalizer : virtual bool open(yarp::os::Searchable& config) override; - fakeLocalizer(); - virtual ~fakeLocalizer(); + FakeLocalizer(); + virtual ~FakeLocalizer(); virtual bool close() override; diff --git a/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_ParamsParser.cpp b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_ParamsParser.cpp new file mode 100644 index 00000000000..cbc38fa0a11 --- /dev/null +++ b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:33 2024 + + +#include "FakeLocalizer_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeLocalizerParamsCOMPONENT, "yarp.device.FakeLocalizer") +} + + +FakeLocalizer_ParamsParser::FakeLocalizer_ParamsParser() +{ +} + + +std::vector FakeLocalizer_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("period"); + return params; +} + + +bool FakeLocalizer_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeLocalizerParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asFloat64(); + yCInfo(FakeLocalizerParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakeLocalizerParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeLocalizerParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeLocalizerParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeLocalizer_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeLocalizer\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'period': thread period\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeLocalizer --period 0.010\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeLocalizer\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_ParamsParser.h b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_ParamsParser.h new file mode 100644 index 00000000000..db60d32d524 --- /dev/null +++ b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:33 2024 + + +#ifndef FAKELOCALIZER_PARAMSPARSER_H +#define FAKELOCALIZER_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeLocalizer. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-------------:|:----------------------:| +* | - | period | double | s | 0.010 | 0 | thread period | optional, default 1.0s | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeLocalizer --period 0.010 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeLocalizer +* \endcode +* +*/ + +class FakeLocalizer_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeLocalizer_ParamsParser(); + ~FakeLocalizer_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeLocalizer"}; + const std::string m_device_name = {"fakeLocalizer"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_period_defaultValue = {"0.010"}; + + double m_period = {0.010}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_params.md b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_params.md new file mode 100644 index 00000000000..8e73b388d87 --- /dev/null +++ b/src/devices/fake/fakeLocalizerDevice/FakeLocalizer_params.md @@ -0,0 +1 @@ + * | | period | double | s | 0.010 | No | thread period | optional, default 1.0s | diff --git a/src/devices/fake/fakeMicrophone/CMakeLists.txt b/src/devices/fake/fakeMicrophone/CMakeLists.txt index f8550f02cb3..f47b432fd88 100644 --- a/src/devices/fake/fakeMicrophone/CMakeLists.txt +++ b/src/devices/fake/fakeMicrophone/CMakeLists.txt @@ -7,8 +7,9 @@ endif() yarp_prepare_plugin(fakeMicrophone CATEGORY device - TYPE fakeMicrophone - INCLUDE fakeMicrophone.h + TYPE FakeMicrophone + INCLUDE FakeMicrophone.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=AudioRecorderWrapper ) @@ -18,8 +19,10 @@ if(NOT SKIP_fakeMicrophone) target_sources(yarp_fakeMicrophone PRIVATE - fakeMicrophone.cpp - fakeMicrophone.h + FakeMicrophone.cpp + FakeMicrophone.h + FakeMicrophone_ParamsParser.cpp + FakeMicrophone_ParamsParser.h ) target_link_libraries(yarp_fakeMicrophone diff --git a/src/devices/fake/fakeMicrophone/FakeMicrophone.cpp b/src/devices/fake/fakeMicrophone/FakeMicrophone.cpp new file mode 100644 index 00000000000..12392372bfb --- /dev/null +++ b/src/devices/fake/fakeMicrophone/FakeMicrophone.cpp @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "FakeMicrophone.h" + +#include +#include +#include +#include +#include +#include + +#include +#define _USE_MATH_DEFINES +#include +#include + + +using namespace yarp::os; +using namespace yarp::dev; +using namespace yarp::sig; + +constexpr double c_DEFAULT_PERIOD=0.01; //s + +namespace { +YARP_LOG_COMPONENT(FAKEMICROPHONE, "yarp.device.fakeMicrophone") +} + +typedef unsigned short int audio_sample_16t; + +FakeMicrophone::FakeMicrophone() : + PeriodicThread(c_DEFAULT_PERIOD) +{ +} + +FakeMicrophone::~FakeMicrophone() +{ + close(); +} + +bool FakeMicrophone::open(yarp::os::Searchable &config) +{ + if (!this->parseParams(config)) {return false;} + + std::string debug_cfg_string = config.toString(); + yarp::os::Bottle& bb = config.findGroup("AUDIO_BASE"); + bool b = configureRecorderAudioDevice(bb, "fakeMicrophone"); + if (!b) { return false; } + + setPeriod(m_period); + + if (m_waveform == "sine") { m_waveform_enum = waveform_t::sine; } + else if (m_waveform == "sawtooth") { m_waveform_enum = waveform_t::sawtooth; } + else if (m_waveform == "square") { m_waveform_enum = waveform_t::square; } + else if (m_waveform == "constant") { m_waveform_enum = waveform_t::constant; } + else { yError() << "Unsupported value for waveform parameter"; return false; } + + if (m_waveform_enum == waveform_t::sine) { yCInfo(FAKEMICROPHONE) << "Using sine waveform, signal amplitude=" << m_signal_amplitude << ", signal frequency=" << m_signal_frequency; } + else if (m_waveform_enum == waveform_t::sawtooth) { yCInfo(FAKEMICROPHONE) << "Using sawtooth waveform, signal amplitude=" << m_signal_amplitude << ", signal frequency=" << m_signal_frequency; } + else if (m_waveform_enum == waveform_t::square) { yCInfo(FAKEMICROPHONE) << "Using square waveform, signal amplitude=" << m_signal_amplitude << ", signal frequency=" << m_signal_frequency; } + else if (m_waveform_enum == waveform_t::constant) { yCInfo(FAKEMICROPHONE) << "Using constant waveform, signal amplitude="<< m_signal_amplitude << ", signal frequency=" << m_signal_frequency; } + + //data structure initialization + //m_audiorecorder_cfg.numSamples = tmp_freq * 5; //5sec + //const size_t EXTRA_SPACE = 2; + //AudioBufferSize buffer_size(m_audiorecorder_cfg.numSamples*EXTRA_SPACE, m_audiorecorder_cfg.numChannels, m_audiorecorder_cfg.bytesPerSample); + //m_inputBuffer = new yarp::dev::CircularAudioBuffer_16t("fake_mic_buffer", buffer_size); + + m_max_count.resize(m_audiorecorder_cfg.numChannels); + m_counter.resize(m_audiorecorder_cfg.numChannels); + + //start the capture thread + start(); + return true; +} + +bool FakeMicrophone::close() +{ + FakeMicrophone::stop(); + + //wait until the thread is stopped... + + return true; +} + +bool FakeMicrophone::setHWGain(double gain) +{ + std::lock_guard lock(m_mutex); + if (gain > 0) + { + m_hw_gain = gain; + return true; + } + return false; +} + +bool FakeMicrophone::threadInit() +{ + return true; +} + + +void FakeMicrophone::run() +{ + // when not recording, do nothing + if (!m_recording_enabled) + { + return; + } + + //fill the buffer with a generated tone. + //each iteration, which occurs every xxx ms (thread period), I copy a fixed amount of + //samples (m_driver_frame_size) in the buffer. This operation cannot be interrupted by stopping the device + //with m_recording_enabled=false. + for (size_t i = 0; i < m_driver_frame_size; i++) + { + // Default values: + // this signal has amplitude (-32000,32000) + // the first channel has frequency 440Hz (A4 note) + // the second channel has frequency 220Hz etc. + // and so on.. + if (m_waveform_enum == waveform_t::sine) + { + for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++) + { + m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_signal_frequency / double(i + 1); + double elem1 = double(m_signal_amplitude * sin(double(m_counter[i]) / m_max_count[i] * 2 * M_PI)); + m_inputBuffer->write(elem1 * m_hw_gain); + m_counter[i]++; + if (m_counter[i] >= m_max_count[i]) { + m_counter[i] = 0; + } + } + } + else if(m_waveform_enum == waveform_t::sawtooth) + { + for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++) + { + m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_signal_frequency / double(i + 1); + double elem1 = m_signal_amplitude * 2.0 * (double(m_counter[i])/ m_max_count[i]) - m_signal_amplitude; + m_inputBuffer->write(elem1 * m_hw_gain); + m_counter[i]++; + if (m_counter[i] >= m_max_count[i]) { + m_counter[i] = 0; + } + } + } + else if (m_waveform_enum == waveform_t::square) + { + for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++) + { + m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_signal_frequency / double(i + 1); + double elem1 = m_counter[i] < m_max_count[i]/2 ? m_signal_amplitude : 0; + m_inputBuffer->write(elem1 * m_hw_gain); + m_counter[i]++; + if (m_counter[i] >= m_max_count[i]) { + m_counter[i] = 0; + } + } + } + else if (m_waveform_enum == waveform_t::constant) + { + for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++) + { + m_inputBuffer->write(m_signal_amplitude * m_hw_gain / double(i + 1)); + m_counter[i]++; + if (m_counter[i] >= m_max_count[i]) { + m_counter[i] = 0; + } + } + } + else + { + yCInfo(FAKEMICROPHONE) << "Not implemented/unreachable code"; + } + } +} diff --git a/src/devices/fake/fakeMicrophone/FakeMicrophone.h b/src/devices/fake/fakeMicrophone/FakeMicrophone.h new file mode 100644 index 00000000000..028cffc98cf --- /dev/null +++ b/src/devices/fake/fakeMicrophone/FakeMicrophone.h @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "FakeMicrophone_ParamsParser.h" + +/** +* @ingroup dev_impl_fake dev_impl_media +* +* \brief `fakeMicrophone` : fake microphone device implementing the IAudioGrabberSound interface to generate a test sound. +* It can generate various signals, i.e. sine, sawtooth, square wave, constant. +* This device driver derives from AudioRecorderDeviceBase base class. Please check its documentation for additional details. +* +* Parameters required by this device are shown in class: FakeMicrophone_ParamsParser +* This device also inherits some parameters from AudioRecorderDeviceBase +* +* See \ref AudioDoc for additional documentation on YARP audio. +*/ + +class FakeMicrophone : + public yarp::dev::DeviceDriver, + public yarp::dev::AudioRecorderDeviceBase, + public yarp::os::PeriodicThread, + public FakeMicrophone_ParamsParser +{ +public: + FakeMicrophone(); + FakeMicrophone(const FakeMicrophone&) = delete; + FakeMicrophone(FakeMicrophone&&) = delete; + FakeMicrophone& operator=(const FakeMicrophone&) = delete; + FakeMicrophone& operator=(FakeMicrophone&&) = delete; + virtual ~FakeMicrophone() override; + +public: + bool setHWGain(double gain) override; + +public: // DeviceDriver + bool open(yarp::os::Searchable &config) override; + bool close() override; + +private: + //thread + bool threadInit() override; + void run() override; + +private: + std::vector m_counter; + std::vector m_max_count; + + enum waveform_t + { + sine = 0, + sawtooth = 1, + square = 2, + constant = 3 + } m_waveform_enum = sine; +}; diff --git a/src/devices/fake/fakeMicrophone/FakeMicrophone_ParamsParser.cpp b/src/devices/fake/fakeMicrophone/FakeMicrophone_ParamsParser.cpp new file mode 100644 index 00000000000..4273b54744b --- /dev/null +++ b/src/devices/fake/fakeMicrophone/FakeMicrophone_ParamsParser.cpp @@ -0,0 +1,167 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#include "FakeMicrophone_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeMicrophoneParamsCOMPONENT, "yarp.device.FakeMicrophone") +} + + +FakeMicrophone_ParamsParser::FakeMicrophone_ParamsParser() +{ +} + + +std::vector FakeMicrophone_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("period"); + params.push_back("waveform"); + params.push_back("signal_frequency"); + params.push_back("signal_amplitude"); + params.push_back("driver_frame_size"); + return params; +} + + +bool FakeMicrophone_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeMicrophoneParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asFloat64(); + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + //Parser of parameter waveform + { + if (config.check("waveform")) + { + m_waveform = config.find("waveform").asString(); + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'waveform' using value:" << m_waveform; + } + else + { + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'waveform' using DEFAULT value:" << m_waveform; + } + prop_check.unput("waveform"); + } + + //Parser of parameter signal_frequency + { + if (config.check("signal_frequency")) + { + m_signal_frequency = config.find("signal_frequency").asInt64(); + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'signal_frequency' using value:" << m_signal_frequency; + } + else + { + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'signal_frequency' using DEFAULT value:" << m_signal_frequency; + } + prop_check.unput("signal_frequency"); + } + + //Parser of parameter signal_amplitude + { + if (config.check("signal_amplitude")) + { + m_signal_amplitude = config.find("signal_amplitude").asInt64(); + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'signal_amplitude' using value:" << m_signal_amplitude; + } + else + { + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'signal_amplitude' using DEFAULT value:" << m_signal_amplitude; + } + prop_check.unput("signal_amplitude"); + } + + //Parser of parameter driver_frame_size + { + if (config.check("driver_frame_size")) + { + m_driver_frame_size = config.find("driver_frame_size").asInt64(); + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'driver_frame_size' using value:" << m_driver_frame_size; + } + else + { + yCInfo(FakeMicrophoneParamsCOMPONENT) << "Parameter 'driver_frame_size' using DEFAULT value:" << m_driver_frame_size; + } + prop_check.unput("driver_frame_size"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeMicrophoneParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeMicrophoneParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeMicrophone_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeMicrophone\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'period': the period of processing thread\n"); + doc = doc + std::string("'waveform': Defines the shape of the waveform. Can be one of the following: sine,sawtooth,square,constant\n"); + doc = doc + std::string("'signal_frequency': Frequency of the generated signal\n"); + doc = doc + std::string("'signal_amplitude': Amplitude of the generated signal\n"); + doc = doc + std::string("'driver_frame_size': the number of samples to process on each iteration of the thread\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeMicrophone --period 0.010 --waveform sine --signal_frequency 440 --signal_amplitude 32000 --driver_frame_size 512\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeMicrophone\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeMicrophone/FakeMicrophone_ParamsParser.h b/src/devices/fake/fakeMicrophone/FakeMicrophone_ParamsParser.h new file mode 100644 index 00000000000..70b0481fe9d --- /dev/null +++ b/src/devices/fake/fakeMicrophone/FakeMicrophone_ParamsParser.h @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#ifndef FAKEMICROPHONE_PARAMSPARSER_H +#define FAKEMICROPHONE_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeMicrophone. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:-----------------:|:------:|:-------:|:-------------:|:--------:|:---------------------------------------------------------------------------------------------:|:---------------------------------------------------:| +* | - | period | double | s | 0.010 | 0 | the period of processing thread | A value of 10ms is recommended. Do to not modify it | +* | - | waveform | string | - | sine | 0 | Defines the shape of the waveform. Can be one of the following: sine,sawtooth,square,constant | - | +* | - | signal_frequency | int | Hz | 440 | 0 | Frequency of the generated signal | - | +* | - | signal_amplitude | int | - | 32000 | 0 | Amplitude of the generated signal | - | +* | - | driver_frame_size | int | samples | 512 | 0 | the number of samples to process on each iteration of the thread | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeMicrophone --period 0.010 --waveform sine --signal_frequency 440 --signal_amplitude 32000 --driver_frame_size 512 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeMicrophone +* \endcode +* +*/ + +class FakeMicrophone_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeMicrophone_ParamsParser(); + ~FakeMicrophone_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeMicrophone"}; + const std::string m_device_name = {"fakeMicrophone"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_period_defaultValue = {"0.010"}; + const std::string m_waveform_defaultValue = {"sine"}; + const std::string m_signal_frequency_defaultValue = {"440"}; + const std::string m_signal_amplitude_defaultValue = {"32000"}; + const std::string m_driver_frame_size_defaultValue = {"512"}; + + double m_period = {0.010}; + std::string m_waveform = {"sine"}; + int m_signal_frequency = {440}; + int m_signal_amplitude = {32000}; + int m_driver_frame_size = {512}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeMicrophone/FakeMicrophone_params.md b/src/devices/fake/fakeMicrophone/FakeMicrophone_params.md new file mode 100644 index 00000000000..34ec8c928dd --- /dev/null +++ b/src/devices/fake/fakeMicrophone/FakeMicrophone_params.md @@ -0,0 +1,5 @@ +* | | period | double | s | 0.010 | No | the period of processing thread | A value of 10ms is recommended. Do to not modify it | +* | | waveform | string | - | sine | No | Defines the shape of the waveform. Can be one of the following: sine,sawtooth,square,constant | - | +* | | signal_frequency | int | Hz | 440 | No | Frequency of the generated signal | - | +* | | signal_amplitude | int | | 32000 | No | Amplitude of the generated signal | - | +* | | driver_frame_size | int | samples | 512 | No | the number of samples to process on each iteration of the thread | - | diff --git a/src/devices/fake/fakeMicrophone/fakeMicrophone.cpp b/src/devices/fake/fakeMicrophone/fakeMicrophone.cpp deleted file mode 100644 index 1b4745e9329..00000000000 --- a/src/devices/fake/fakeMicrophone/fakeMicrophone.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fakeMicrophone.h" - -#include -#include -#include -#include -#include -#include - -#include -#define _USE_MATH_DEFINES -#include -#include - - -using namespace yarp::os; -using namespace yarp::dev; -using namespace yarp::sig; - -constexpr double c_DEFAULT_PERIOD=0.01; //s - -namespace { -YARP_LOG_COMPONENT(FAKEMICROPHONE, "yarp.device.fakeMicrophone") -} - -typedef unsigned short int audio_sample_16t; - -fakeMicrophone::fakeMicrophone() : - PeriodicThread(c_DEFAULT_PERIOD) -{ -} - -fakeMicrophone::~fakeMicrophone() -{ - close(); -} - -bool fakeMicrophone::open(yarp::os::Searchable &config) -{ - if (config.check("help")) - { - yCInfo(FAKEMICROPHONE, "Some examples:"); - yCInfo(FAKEMICROPHONE, "yarpdev --device fakeMicrophone --help"); - yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start"); - yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start --signal_frequency 400 --waveform sine"); - yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start --signal_frequency 400 --waveform sawtooth"); - yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start --signal_frequency 400 --waveform square"); - yCInfo(FAKEMICROPHONE, "yarpdev --device AudioRecorderWrapper --subdevice fakeMicrophone --start --waveform constant"); - return false; - } - - std::string debug_cfg_string = config.toString(); - yarp::os::Bottle& bb = config.findGroup("AUDIO_BASE"); - bool b = configureRecorderAudioDevice(bb, "fakeMicrophone"); - if (!b) { return false; } - - //sets the thread period - if(config.check("period")) - { - double period = config.find("period").asFloat64(); - setPeriod(period); - yCInfo(FAKEMICROPHONE) << "Using chosen period of " << period << " s"; - } - else - { - yCInfo(FAKEMICROPHONE) << "Using default period of " << c_DEFAULT_PERIOD << " s"; - } - - if (config.check("signal_frequency")) - { - m_sig_freq = config.find("signal_frequency").asInt32(); - } - - if (config.check("amplitude")) - { - m_wave_amplitude = config.find("amplitude").asInt32(); - } - - //sets the number of samples processed atomically every thread iteration - if (config.check("driver_frame_size")) - { - m_samples_to_be_copied = config.find("driver_frame_size").asFloat64(); - } - yCDebug(FAKEMICROPHONE) << m_samples_to_be_copied << " will be processed every iteration"; - - if (config.check("waveform")) - { - std::string waveform = config.find("waveform").asString(); - if (config.find("waveform").toString() == "sine") { m_waveform = waveform_t::sine; } - else if (config.find("waveform").toString() == "sawtooth") { m_waveform = waveform_t::sawtooth; } - else if (config.find("waveform").toString() == "square") { m_waveform = waveform_t::square; } - else if (config.find("waveform").toString() == "constant") { m_waveform = waveform_t::constant; } - else if (config.check("waveform")) { yError() << "Unsupported value for waveform parameter"; return false; } - - if (m_waveform == waveform_t::sine) { yCInfo(FAKEMICROPHONE) << "Using sine waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; } - else if (m_waveform == waveform_t::sawtooth) { yCInfo(FAKEMICROPHONE) << "Using sawtooth waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; } - else if (m_waveform == waveform_t::square) { yCInfo(FAKEMICROPHONE) << "Using square waveform, signal amplitude=" << m_wave_amplitude << ", signal frequency=" << m_sig_freq; } - else if (m_waveform == waveform_t::constant) { yCInfo(FAKEMICROPHONE) << "Using constant waveform, signal amplitude="<< m_wave_amplitude << ", signal frequency=" << m_sig_freq; } - } - - //data structure initialization - //m_audiorecorder_cfg.numSamples = tmp_freq * 5; //5sec - //const size_t EXTRA_SPACE = 2; - //AudioBufferSize buffer_size(m_audiorecorder_cfg.numSamples*EXTRA_SPACE, m_audiorecorder_cfg.numChannels, m_audiorecorder_cfg.bytesPerSample); - //m_inputBuffer = new yarp::dev::CircularAudioBuffer_16t("fake_mic_buffer", buffer_size); - - m_max_count.resize(m_audiorecorder_cfg.numChannels); - m_counter.resize(m_audiorecorder_cfg.numChannels); - - //start the capture thread - start(); - return true; -} - -bool fakeMicrophone::close() -{ - fakeMicrophone::stop(); - - //wait until the thread is stopped... - - return true; -} - -bool fakeMicrophone::setHWGain(double gain) -{ - std::lock_guard lock(m_mutex); - if (gain > 0) - { - m_hw_gain = gain; - return true; - } - return false; -} - -bool fakeMicrophone::threadInit() -{ - return true; -} - - -void fakeMicrophone::run() -{ - // when not recording, do nothing - if (!m_recording_enabled) - { - return; - } - - //fill the buffer with a generated tone. - //each iteration, which occurs every xxx ms (thread period), I copy a fixed amount of - //samples (m_samples_to_be_copied) in the buffer. This operation cannot be interrupted by stopping the device - //with m_recording_enabled=false. - for (size_t i = 0; i < m_samples_to_be_copied; i++) - { - // Default values: - // this signal has amplitude (-32000,32000) - // the first channel has frequency 440Hz (A4 note) - // the second channel has frequency 220Hz etc. - // and so on.. - if (m_waveform == waveform_t::sine) - { - for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++) - { - m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1); - double elem1 = double(m_wave_amplitude * sin(double(m_counter[i]) / m_max_count[i] * 2 * M_PI)); - m_inputBuffer->write(elem1 * m_hw_gain); - m_counter[i]++; - if (m_counter[i] >= m_max_count[i]) { - m_counter[i] = 0; - } - } - } - else if(m_waveform == waveform_t::sawtooth) - { - for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++) - { - m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1); - double elem1 = m_wave_amplitude * 2 * (double(m_counter[i])/ m_max_count[i]) - m_wave_amplitude; - m_inputBuffer->write(elem1 * m_hw_gain); - m_counter[i]++; - if (m_counter[i] >= m_max_count[i]) { - m_counter[i] = 0; - } - } - } - else if (m_waveform == waveform_t::square) - { - for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++) - { - m_max_count[i] = double(m_audiorecorder_cfg.frequency) / m_sig_freq / double(i + 1); - double elem1 = m_counter[i] < m_max_count[i]/2 ? m_wave_amplitude : 0; - m_inputBuffer->write(elem1 * m_hw_gain); - m_counter[i]++; - if (m_counter[i] >= m_max_count[i]) { - m_counter[i] = 0; - } - } - } - else if (m_waveform == waveform_t::constant) - { - for (size_t i = 0; i < m_audiorecorder_cfg.numChannels; i++) - { - m_inputBuffer->write(m_wave_amplitude * m_hw_gain / double(i + 1)); - m_counter[i]++; - if (m_counter[i] >= m_max_count[i]) { - m_counter[i] = 0; - } - } - } - else - { - yCInfo(FAKEMICROPHONE) << "Not implemented/unreachable code"; - } - } -} diff --git a/src/devices/fake/fakeMicrophone/fakeMicrophone.h b/src/devices/fake/fakeMicrophone/fakeMicrophone.h deleted file mode 100644 index 9c32f8c2e75..00000000000 --- a/src/devices/fake/fakeMicrophone/fakeMicrophone.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include - -#include -#include - -/** -* @ingroup dev_impl_fake dev_impl_media -* -* \brief `fakeMicrophone` : fake microphone device implementing the IAudioGrabberSound interface to generate a test sound. -* It can generate various signals, i.e. sine, sawtooth, square wave, constant. -* This device driver derives from AudioRecorderDeviceBase base class. Please check its documentation for additional details. -* -* Parameters used by this device are: -* | Parameter name | SubParameter | Type | Units | Default Value | Required | Description | Notes | -* |:-----------------:|:--------------:|:-------:|:--------------:|:------------------------:|:--------------------------: |:-----------------------------------------------------------------:|:-----:| -* | AUDIO_BASE | *** | | - | - | No | For the documentation of AUDIO_BASE group, please refer to the documentation of the base class AudioRecorderDeviceBase | | -* | period | - | double | s | 0.010 | No | the period of processing thread | A value of 10ms is recommended. Do to not modify it | -* | waveform | - | string | - | sine | No | Defines the shape of the waveform. Can be one of the following: sine,sawtooth,square,constant | - | -* | signal_frequency | - | int | Hz | 440 | No | Frequency of the generated signal | - | -* | signal_amplitude | - | int | | 32000 | No | Amplitude of the generated signal | - | -* | driver_frame_size | - | int | samples | 512 | No | the number of samples to process on each iteration of the thread | - | -* -* See \ref AudioDoc for additional documentation on YARP audio. -*/ - -class fakeMicrophone : - public yarp::dev::DeviceDriver, - public yarp::dev::AudioRecorderDeviceBase, - public yarp::os::PeriodicThread -{ -public: - fakeMicrophone(); - fakeMicrophone(const fakeMicrophone&) = delete; - fakeMicrophone(fakeMicrophone&&) = delete; - fakeMicrophone& operator=(const fakeMicrophone&) = delete; - fakeMicrophone& operator=(fakeMicrophone&&) = delete; - virtual ~fakeMicrophone() override; - -public: - bool setHWGain(double gain) override; - -public: // DeviceDriver - bool open(yarp::os::Searchable &config) override; - bool close() override; - -private: - //thread - bool threadInit() override; - void run() override; - -private: - std::vector m_counter; - std::vector m_max_count; - size_t m_wave_amplitude = 32000; - double m_sig_freq=440; //Hz - size_t m_samples_to_be_copied = 512; - - enum waveform_t - { - sine = 0, - sawtooth = 1, - square = 2, - constant = 3 - } m_waveform = sine; -}; diff --git a/src/devices/fake/fakeMotionControl/CMakeLists.txt b/src/devices/fake/fakeMotionControl/CMakeLists.txt index a6763209647..ff374a32ae8 100644 --- a/src/devices/fake/fakeMotionControl/CMakeLists.txt +++ b/src/devices/fake/fakeMotionControl/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeMotionControl CATEGORY device TYPE FakeMotionControl - INCLUDE fakeMotionControl.h + INCLUDE FakeMotionControl.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=controlBoard_nws_yarp ) @@ -18,8 +19,11 @@ if(NOT SKIP_fakeMotionControl) target_sources(yarp_fakeMotionControl PRIVATE - fakeMotionControl.cpp - fakeMotionControl.h) + FakeMotionControl.cpp + FakeMotionControl.h + FakeMotionControl_ParamsParser.cpp + FakeMotionControl_ParamsParser.h +) target_link_libraries(yarp_fakeMotionControl PRIVATE diff --git a/src/devices/fake/fakeMotionControl/fakeMotionControl.cpp b/src/devices/fake/fakeMotionControl/FakeMotionControl.cpp similarity index 79% rename from src/devices/fake/fakeMotionControl/fakeMotionControl.cpp rename to src/devices/fake/fakeMotionControl/FakeMotionControl.cpp index b87d03f3467..6be0ec154b7 100644 --- a/src/devices/fake/fakeMotionControl/fakeMotionControl.cpp +++ b/src/devices/fake/fakeMotionControl/FakeMotionControl.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeMotionControl.h" +#include "FakeMotionControl.h" #include @@ -131,6 +131,7 @@ std::string toString(const T& value) //generic function that check is key1 is present in input bottle and that the result has size elements // return true/false +/* bool FakeMotionControl::extractGroup(Bottle &input, Bottle &out, const std::string &key1, const std::string &txt, int size) { size++; @@ -151,6 +152,7 @@ bool FakeMotionControl::extractGroup(Bottle &input, Bottle &out, const std::stri out=tmp; return true; } +*/ void FakeMotionControl::resizeBuffers() { @@ -509,43 +511,14 @@ void FakeMotionControl::threadRelease() bool FakeMotionControl::open(yarp::os::Searchable &config) { - std::string str; - -// if (!config.findGroup("GENERAL").find("MotioncontrolVersion").isInt32()) -// { -// yCError(FAKEMOTIONCONTROL) << "Missing MotioncontrolVersion parameter. yarprobotinterface cannot start. Please contact icub-support@iit.it"; -// return false; -// } -// else -// { -// int mcv = config.findGroup("GENERAL").find("MotioncontrolVersion").asInt32(); -// if (mcv != 2) -// { -// yCError(FAKEMOTIONCONTROL) << "Wrong MotioncontrolVersion parameter. yarprobotinterface cannot start. Please contact icub-support@iit.it"; -// return false; -// } -// } + if (!this->parseParams(config)) {return false;} -// if(!config.findGroup("GENERAL").find("verbose").isBool()) -// { -// yCError(FAKEMOTIONCONTROL) << "open() detects that general->verbose bool param is different from accepted values (true / false). Assuming false"; -// str=" "; -// } -// else -// { -// if(config.findGroup("GENERAL").find("verbose").asBool()) -// str=config.toString().c_str(); -// else -// str=" "; -// } - str=config.toString(); - yCTrace(FAKEMOTIONCONTROL) << str; + std::string str; // // Read Configuration params from file // - _njoints = config.findGroup("GENERAL").check("Joints",Value(1), "Number of degrees of freedom").asInt32(); - yCInfo(FAKEMOTIONCONTROL, "Using %d joint%s", _njoints, ((_njoints != 1) ? "s" : "")); + _njoints = m_GENERAL_Joints; if(!alloc(_njoints)) { @@ -614,907 +587,179 @@ bool FakeMotionControl::open(yarp::os::Searchable &config) return true; } -bool FakeMotionControl::parseImpedanceGroup_NewFormat(Bottle& pidsGroup, ImpedanceParameters vals[]) -{ - int j=0; - Bottle xtmp; - - if (!extractGroup(pidsGroup, xtmp, "stiffness", "stiffness parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - vals[j].stiffness = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "damping", "damping parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - vals[j].damping = xtmp.get(j+1).asFloat64(); - } - - return true; -} - -bool FakeMotionControl::parsePositionPidsGroup(Bottle& pidsGroup, Pid myPid[]) +bool FakeMotionControl::fromConfig(yarp::os::Searchable &config) { - int j=0; - Bottle xtmp; - - if (!extractGroup(pidsGroup, xtmp, "kp", "Pid kp parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].kp = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "kd", "Pid kd parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].kd = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "ki", "Pid kp parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].ki = xtmp.get(j+1).asFloat64(); - } + size_t i; - if (!extractGroup(pidsGroup, xtmp, "maxInt", "Pid maxInt parameter", _njoints)) { - return false; + // AxisMap + if (!m_GENERAL_AxisMap.empty()) + { + for (i = 0; i < m_GENERAL_AxisMap.size(); i++) { + _axisMap[i] = m_GENERAL_AxisMap[i]; + } } - for (j=0; j<_njoints; j++) { - myPid[j].max_int = xtmp.get(j+1).asFloat64(); + else + { + for (i = 0; i < _njoints; i++) { + _axisMap[i] = i; + } } + for (i = 0; i < _njoints; i++) {yDebug() << "_axisMap: " << _axisMap[i] << " "; } - if (!extractGroup(pidsGroup, xtmp, "maxPwm", "Pid maxPwm parameter", _njoints)) { - return false; + // AxisName + if (!m_GENERAL_AxisName.empty()) + { + for (i = 0; i < m_GENERAL_AxisName.size(); i++) { + _axisName[_axisMap[i]] = m_GENERAL_AxisName[i]; + } } - for (j=0; j<_njoints; j++) { - myPid[j].max_output = xtmp.get(j+1).asFloat64(); + else + { + for (i = 0; i < _njoints; i++) { + _axisName[_axisMap[i]] = "joint" + toString(i); + } } + for (i = 0; i < _njoints; i++) { yDebug() << "_axisName: " << _axisName[_axisMap[i]] << " "; } - if (!extractGroup(pidsGroup, xtmp, "shift", "Pid shift parameter", _njoints)) { - return false; + // Axis Type + if (!m_GENERAL_AxisType.empty()) + { + //beware: axis type has to be remapped here because they are not set using the toHw() helper function + for (i = 0; i < m_GENERAL_AxisType.size(); i++) + { + std::string typeString = m_GENERAL_AxisType[i]; + if (typeString == "revolute") { + _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_REVOLUTE; + } + else if (typeString == "prismatic") { + _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_PRISMATIC; + } + else { + yCError(FAKEMOTIONCONTROL, "Unknown AxisType value %s!", typeString.c_str()); + _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_UNKNOWN; + return false; + } + } } - for (j=0; j<_njoints; j++) { - myPid[j].scale = xtmp.get(j+1).asFloat64(); + else + { + yCInfo(FAKEMOTIONCONTROL) << "Using default AxisType (revolute)"; + for (i = 0; i < _njoints; i++) { + _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_REVOLUTE; + } } - if (!extractGroup(pidsGroup, xtmp, "ko", "Pid ko parameter", _njoints)) { - return false; + // current conversions factor + if (!m_GENERAL_ampsToSensor.empty()) + { + for (i = 0; i < m_GENERAL_ampsToSensor.size(); i++) { + _ampsToSensor[i] = m_GENERAL_ampsToSensor[i]; + } } - for (j=0; j<_njoints; j++) { - myPid[j].offset = xtmp.get(j+1).asFloat64(); + else + { + yCInfo(FAKEMOTIONCONTROL) << "Using default ampsToSensor=1"; + for (i = 0; i < _njoints; i++) { + _ampsToSensor[i] = 1; + } } - if (!extractGroup(pidsGroup, xtmp, "stictionUp", "Pid stictionUp", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].stiction_up_val = xtmp.get(j+1).asFloat64(); - } - if (!extractGroup(pidsGroup, xtmp, "stictionDwn", "Pid stictionDwn", _njoints)) { - return false; + // pwm conversions factor + if (!m_GENERAL_fullscalePWM.empty()) + { + for (i = 0; i < m_GENERAL_fullscalePWM.size(); i++) { + _dutycycleToPWM[i] = m_GENERAL_fullscalePWM[i]/100; + } } - for (j=0; j<_njoints; j++) { - myPid[j].stiction_down_val = xtmp.get(j+1).asFloat64(); + else + { + yCInfo(FAKEMOTIONCONTROL) << "Using default fullscalePWM=1"; + for (i = 0; i < _njoints; i++) { + _dutycycleToPWM[i] = 1; + } } - if (!extractGroup(pidsGroup, xtmp, "kff", "Pid kff parameter", _njoints)) { - return false; +// double tmp_A2E; + // Encoder scales + if(!m_GENERAL_Encoder.empty()) + { + for (i = 0; i < m_GENERAL_Encoder.size(); i++) { + _angleToEncoder[i] = m_GENERAL_Encoder[i]; } } - for (j=0; j<_njoints; j++) { - myPid[j].kff = xtmp.get(j+1).asFloat64(); + else + { + yCInfo(FAKEMOTIONCONTROL) << "Using default Encoder=1"; + for (i = 0; i < _njoints; i++) { + _angleToEncoder[i] = 1; } } - //conversion from metric to machine units (if applicable) - if (_positionControlUnits==P_METRIC_UNITS) + /////// LIMITS + if (!m_LIMITS_Max.empty()) { - for (j=0; j<_njoints; j++) - { - myPid[j].kp = myPid[j].kp / _angleToEncoder[j]; //[PWM/deg] - myPid[j].ki = myPid[j].ki / _angleToEncoder[j]; //[PWM/deg] - myPid[j].kd = myPid[j].kd / _angleToEncoder[j]; //[PWM/deg] + for (i = 0; i < m_LIMITS_Max.size(); i++) { + _limitsMax[i] = m_LIMITS_Max[i]; } } else { - //do nothing + yCInfo(FAKEMOTIONCONTROL) << "Using default m_LIMITS_Max=100"; + for (i = 0; i < _njoints; i++) { + _limitsMax[i] = 100; + } } - //optional PWM limit - if(_pwmIsLimited) - { // check for value in the file - if (!extractGroup(pidsGroup, xtmp, "limPwm", "Limited PWD", _njoints)) - { - yCError(FAKEMOTIONCONTROL) << "The PID parameter limPwm was requested but was not correctly set in the configuration file, please fill it."; - return false; + if (!m_LIMITS_Min.empty()) + { + for (i = 0; i < m_LIMITS_Min.size(); i++) { + _limitsMin[i] = m_LIMITS_Min[i]; } - - yCInfo(FAKEMOTIONCONTROL) << "Using LIMITED PWM!!"; - for (j = 0; j < _njoints; j++) { - myPid[j].max_output = xtmp.get(j + 1).asFloat64(); + } + else + { + yCInfo(FAKEMOTIONCONTROL) << "Using default m_LIMITS_Min=0"; + for (i = 0; i < _njoints; i++) { + _limitsMin[i] = 0; } } return true; } -bool FakeMotionControl::parseTorquePidsGroup(Bottle& pidsGroup, Pid myPid[], double kbemf[], double ktau[], int filterType[], double viscousPos[], double viscousNeg[], double coulombPos[], double coulombNeg[], double velocityThres[]) + +bool FakeMotionControl::close() { - int j=0; - Bottle xtmp; - if (!extractGroup(pidsGroup, xtmp, "kp", "Pid kp parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].kp = xtmp.get(j+1).asFloat64(); - } + std::lock_guard lock(_mutex); - if (!extractGroup(pidsGroup, xtmp, "kd", "Pid kd parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].kd = xtmp.get(j+1).asFloat64(); - } + this->yarp::os::PeriodicThread::stop(); - if (!extractGroup(pidsGroup, xtmp, "ki", "Pid kp parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].ki = xtmp.get(j+1).asFloat64(); - } + yCTrace(FAKEMOTIONCONTROL) << " close()"; - if (!extractGroup(pidsGroup, xtmp, "maxInt", "Pid maxInt parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].max_int = xtmp.get(j+1).asFloat64(); - } + ImplementControlMode::uninitialize(); + ImplementEncodersTimed::uninitialize(); + ImplementMotorEncoders::uninitialize(); + ImplementPositionControl::uninitialize(); + ImplementVelocityControl::uninitialize(); + ImplementPidControl::uninitialize(); + ImplementControlCalibration::uninitialize(); + ImplementAmplifierControl::uninitialize(); + ImplementImpedanceControl::uninitialize(); + ImplementControlLimits::uninitialize(); + ImplementTorqueControl::uninitialize(); + ImplementPositionDirect::uninitialize(); + ImplementInteractionMode::uninitialize(); + ImplementAxisInfo::uninitialize(); + ImplementVirtualAnalogSensor::uninitialize(); - if (!extractGroup(pidsGroup, xtmp, "maxPwm", "Pid maxPwm parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].max_output = xtmp.get(j+1).asFloat64(); - } +// cleanup(); - if (!extractGroup(pidsGroup, xtmp, "shift", "Pid shift parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].scale = xtmp.get(j+1).asFloat64(); - } + return true; +} - if (!extractGroup(pidsGroup, xtmp, "ko", "Pid ko parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].offset = xtmp.get(j+1).asFloat64(); - } +void FakeMotionControl::cleanup() +{ - if (!extractGroup(pidsGroup, xtmp, "stictionUp", "Pid stictionUp", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].stiction_up_val = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "stictionDwn", "Pid stictionDwn", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].stiction_down_val = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "kff", "Pid kff parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - myPid[j].kff = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "kbemf", "kbemf parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - kbemf[j] = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "ktau", "ktau parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - ktau[j] = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "filterType", "filterType param", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - filterType[j] = xtmp.get(j+1).asInt32(); - } - - if (!extractGroup(pidsGroup, xtmp, "viscousPos", "viscous pos parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - viscousPos[j] = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "viscousNeg", "viscous neg parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - viscousNeg[j] = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "coulombPos", "coulomb pos parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - coulombPos[j] = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "coulombNeg", "coulomb neg parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - coulombNeg[j] = xtmp.get(j+1).asFloat64(); - } - - if (!extractGroup(pidsGroup, xtmp, "velocityThres", "velocity threshold parameter", _njoints)) { - return false; - } - for (j=0; j<_njoints; j++) { - velocityThres[j] = xtmp.get(j+1).asFloat64(); - } - - - //conversion from metric to machine units (if applicable) -// for (j=0; j<_njoints; j++) -// { -// myPid[j].kp = myPid[j].kp / _torqueControlHelper->getNewtonsToSensor(j); //[PWM/Nm] -// myPid[j].ki = myPid[j].ki / _torqueControlHelper->getNewtonsToSensor(j); //[PWM/Nm] -// myPid[j].kd = myPid[j].kd / _torqueControlHelper->getNewtonsToSensor(j); //[PWM/Nm] -// myPid[j].stiction_up_val = myPid[j].stiction_up_val * _torqueControlHelper->getNewtonsToSensor(j); //[Nm] -// myPid[j].stiction_down_val = myPid[j].stiction_down_val * _torqueControlHelper->getNewtonsToSensor(j); //[Nm] -// } - - //optional PWM limit - if(_pwmIsLimited) - { // check for value in the file - if (!extractGroup(pidsGroup, xtmp, "limPwm", "Limited PWM", _njoints)) - { - yCError(FAKEMOTIONCONTROL) << "The PID parameter limPwm was requested but was not correctly set in the configuration file, please fill it."; - return false; - } - - yCInfo(FAKEMOTIONCONTROL) << "Using LIMITED PWM!!"; - for (j = 0; j < _njoints; j++) { - myPid[j].max_output = xtmp.get(j + 1).asFloat64(); - } - } - - return true; -} - -bool FakeMotionControl::fromConfig(yarp::os::Searchable &config) -{ - Bottle xtmp; - int i; - Bottle general = config.findGroup("GENERAL"); - - // read AxisMap values from file - if(general.check("AxisMap")) - { - if(extractGroup(general, xtmp, "AxisMap", "a list of reordered indices for the axes", _njoints)) - { - for (i = 1; (size_t)i < xtmp.size(); i++) { - _axisMap[i - 1] = xtmp.get(i).asInt32(); - } - } else { - return false; - } - } - else - { - yCInfo(FAKEMOTIONCONTROL) << "Using default AxisMap"; - for (i = 0; i < _njoints; i++) { - _axisMap[i] = i; - } - } - - if(general.check("AxisName")) - { - if (extractGroup(general, xtmp, "AxisName", "a list of strings representing the axes names", _njoints)) - { - //beware: axis name has to be remapped here because they are not set using the toHw() helper function - for (i = 1; (size_t) i < xtmp.size(); i++) - { - _axisName[_axisMap[i - 1]] = xtmp.get(i).asString(); - } - } else { - return false; - } - } - else - { - yCInfo(FAKEMOTIONCONTROL) << "Using default AxisName"; - for (i = 0; i < _njoints; i++) - { - _axisName[_axisMap[i]] = "joint" + toString(i); - } - } - if(general.check("AxisType")) - { - if (extractGroup(general, xtmp, "AxisType", "a list of strings representing the axes type (revolute/prismatic)", _njoints)) - { - //beware: axis type has to be remapped here because they are not set using the toHw() helper function - for (i = 1; (size_t) i < xtmp.size(); i++) - { - std::string typeString = xtmp.get(i).asString(); - if (typeString == "revolute") { - _jointType[_axisMap[i - 1]] = VOCAB_JOINTTYPE_REVOLUTE; - } else if (typeString == "prismatic") { - _jointType[_axisMap[i - 1]] = VOCAB_JOINTTYPE_PRISMATIC; - } else { - yCError(FAKEMOTIONCONTROL, "Unknown AxisType value %s!", typeString.c_str()); - _jointType[_axisMap[i - 1]] = VOCAB_JOINTTYPE_UNKNOWN; - return false; - } - } - } else { - return false; - } - } - else - { - yCInfo(FAKEMOTIONCONTROL) << "Using default AxisType (revolute)"; - for (i = 0; i < _njoints; i++) - { - _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_REVOLUTE; - } - } - - // current conversions factor - if (general.check("ampsToSensor")) - { - if (extractGroup(general, xtmp, "ampsToSensor", "a list of scales for the ampsToSensor conversion factors", _njoints)) - { - for (i = 1; (size_t) i < xtmp.size(); i++) - { - if (xtmp.get(i).isFloat64()) - { - _ampsToSensor[i - 1] = xtmp.get(i).asFloat64(); - } - } - } else { - return false; - } - } - else - { - yCInfo(FAKEMOTIONCONTROL) << "Using default ampsToSensor"; - for (i = 0; i < _njoints; i++) - { - _ampsToSensor[i] = 1.0; - } - } - - // pwm conversions factor - if (general.check("fullscalePWM")) - { - if (extractGroup(general, xtmp, "fullscalePWM", "a list of scales for the fullscalePWM conversion factors", _njoints)) - { - for (i = 1; (size_t) i < xtmp.size(); i++) - { - if (xtmp.get(i).isFloat64() || xtmp.get(i).isInt32()) - { - _dutycycleToPWM[i - 1] = xtmp.get(i).asFloat64() / 100.0; - } - } - } else { - return false; - } - } - else - { - yCInfo(FAKEMOTIONCONTROL) << "Using default dutycycleToPWM=1.0"; - for (i = 0; i < _njoints; i++) { - _dutycycleToPWM[i] = 1.0; - } - } - -// double tmp_A2E; - // Encoder scales - if(general.check("Encoder")) - { - if (extractGroup(general, xtmp, "Encoder", "a list of scales for the encoders", _njoints)) - { - for (i = 1; (size_t) i < xtmp.size(); i++) - { - _angleToEncoder[i-1] = xtmp.get(i).asFloat64(); - } - } else { - return false; - } - } - else - { - yCInfo(FAKEMOTIONCONTROL) << "Using default Encoder"; - for (i = 0; i < _njoints; i++) { - _angleToEncoder[i] = 1; - } - } - - // Joint encoder resolution - /*if (!extractGroup(general, xtmp, "JointEncoderRes", "the resolution of the joint encoder", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _jointEncoderRes[i - 1] = xtmp.get(i).asInt32(); - } - - // Joint encoder type - if (!extractGroup(general, xtmp, "JointEncoderType", "JointEncoderType", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - { - uint8_t val; - std::string s = xtmp.get(i).asString(); - bool b = EncoderType_iCub2eo(&s, &val); - if (b == false) - { - yCError(FAKEMOTIONCONTROL, "Invalid JointEncoderType: %s!", s.c_str()); return false; - } -// _jointEncoderType[i - 1] = val; - } - } -*/ - - // Motor capabilities -/* if (!extractGroup(general, xtmp, "HasHallSensor", "HasHallSensor 0/1 ", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _hasHallSensor[i - 1] = xtmp.get(i).asInt32(); - } - if (!extractGroup(general, xtmp, "HasTempSensor", "HasTempSensor 0/1 ", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _hasTempSensor[i - 1] = xtmp.get(i).asInt32(); - } - if (!extractGroup(general, xtmp, "HasRotorEncoder", "HasRotorEncoder 0/1 ", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _hasRotorEncoder[i - 1] = xtmp.get(i).asInt32(); - } - if (!extractGroup(general, xtmp, "HasRotorEncoderIndex", "HasRotorEncoderIndex 0/1 ", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _hasRotorEncoderIndex[i - 1] = xtmp.get(i).asInt32(); - } - - // Rotor encoder res - if (!extractGroup(general, xtmp, "RotorEncoderRes", "a list of scales for the rotor encoders", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _rotorEncoderRes[i - 1] = xtmp.get(i).asInt32(); - } - - // joint encoder res - if (!extractGroup(general, xtmp, "JointEncoderRes", "a list of scales for the joint encoders", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _jointEncoderRes[i - 1] = xtmp.get(i).asInt32(); - } -*/ - // Number of motor poles - /*if (!extractGroup(general, xtmp, "MotorPoles", "MotorPoles", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _motorPoles[i - 1] = xtmp.get(i).asInt32(); - } - - // Rotor encoder index - if (!extractGroup(general, xtmp, "RotorIndexOffset", "RotorIndexOffset", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _rotorIndexOffset[i - 1] = xtmp.get(i).asInt32(); - } -*/ - - // Rotor encoder type -/* - if (!extractGroup(general, xtmp, "RotorEncoderType", "RotorEncoderType", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - { - uint8_t val; - std::string s = xtmp.get(i).asString(); - bool b = EncoderType_iCub2eo(&s, &val); - if (b == false) - { - yCError(FAKEMOTIONCONTROL, "Invalid RotorEncoderType: %s", s.c_str()); return false; - } - _rotorEncoderType[i - 1] = val; - } - } -*/ -/* - // Gearbox - if (!extractGroup(general, xtmp, "Gearbox", "The gearbox reduction ratio", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - { - _gearbox[i-1] = xtmp.get(i).asFloat64(); - if (_gearbox[i-1]==0) {yCError(FAKEMOTIONCONTROL) << "Using a gearbox value = 0 may cause problems! Check your configuration files"; return false;} - } - } - - // Torque sensors stuff - if (!extractGroup(general, xtmp, "TorqueId","a list of associated joint torque sensor ids", _njoints)) - { - yCWarning(FAKEMOTIONCONTROL, "Using default value = 0 (disabled)"); - for(i=1; i<_njoints+1; i++) - _torqueSensorId[i-1] = 0; - } - else - { - for (i = 1; i < xtmp.size(); i++) _torqueSensorId[i-1] = xtmp.get(i).asInt32(); - } - - - if (!extractGroup(general, xtmp, "TorqueChan","a list of associated joint torque sensor channels", _njoints)) - { - yCWarning(FAKEMOTIONCONTROL) << "fromConfig() detected that TorqueChan is not present: using default value = 0 (disabled)"; - for(i=1; i<_njoints+1; i++) - _torqueSensorChan[i-1] = 0; - } - else - { - for (i = 1; i < xtmp.size(); i++) _torqueSensorChan[i-1] = xtmp.get(i).asInt32(); - } - - - if (!extractGroup(general, xtmp, "TorqueMax","full scale value for a joint torque sensor", _njoints)) - { - return false; - } - else - { - for (i = 1; i < xtmp.size(); i++) - { - _maxTorque[i-1] = xtmp.get(i).asInt32(); - _newtonsToSensor[i-1] = 1000.0f; // conversion from Nm into milliNm - } - } -*/ - - ////// POSITION PIDS -/* - { - Bottle posPidsGroup; - posPidsGroup=config.findGroup("POSITION_CONTROL", "Position Pid parameters new format"); - if (posPidsGroup.isNull()==false) - { - Value &controlUnits=posPidsGroup.find("controlUnits"); - if (controlUnits.isNull() == false && controlUnits.isString() == true) - { - if (controlUnits.toString()==std::string("metric_units")) - { - yCDebug(FAKEMOTIONCONTROL, "POSITION_CONTROL: using metric_units"); _positionControlUnits=P_METRIC_UNITS; - } - else if (controlUnits.toString()==std::string("machine_units")) - { - yCDebug(FAKEMOTIONCONTROL, "POSITION_CONTROL: using machine_units"); _positionControlUnits=P_MACHINE_UNITS; - } - else - { - yCError(FAKEMOTIONCONTROL) << "fromConfig(): POSITION_CONTROL section: invalid controlUnits value"; - return false; - } - } - else - { - yCError(FAKEMOTIONCONTROL) << "fromConfig(): POSITION_CONTROL section: missing controlUnits parameter. Assuming machine_units. Please fix your configuration file."; - _positionControlUnits=P_MACHINE_UNITS; - } - -// Value &controlLaw=posPidsGroup.find("controlLaw"); -// if (controlLaw.isNull() == false && controlLaw.isString() == true) -// { -// std::string s_controlaw = controlLaw.toString(); -// if (s_controlaw==std::string("joint_pid_v1")) -// { -// if (!parsePositionPidsGroup (posPidsGroup, _pids)) -// { -// yCError(FAKEMOTIONCONTROL) << "fromConfig(): POSITION_CONTROL section: error detected in parameters syntax"; -// return false; -// } -// else -// { -// yCDebug(FAKEMOTIONCONTROL, "POSITION_CONTROL: using control law joint_pid_v1"); -// } -// } -// else if (s_controlaw==std::string("not_implemented")) -// { -// yCDebug(FAKEMOTIONCONTROL) << "found 'not_impelemented' in position control_law. This will terminate yarprobotinterface execution."; -// return false; -// } -// else if (s_controlaw==std::string("disabled")) -// { -// yCDebug(FAKEMOTIONCONTROL) << "found 'disabled' in position control_law. This will terminate yarprobotinterface execution."; -// return false; -// } -// else -// { -// yCError(FAKEMOTIONCONTROL) << "Unable to use control law " << s_controlaw << " por position control. Quitting."; -// return false; -// } -// } - } - else - { - yCError(FAKEMOTIONCONTROL) <<"fromConfig(): Error: no POS_PIDS group found in config file, returning"; - return false; - } - } -*/ - - - ////// TORQUE PIDS -/* - { - Bottle trqPidsGroup; - trqPidsGroup=config.findGroup("TORQUE_CONTROL", "Torque control parameters new format"); - if (trqPidsGroup.isNull()==false) - { - Value &controlUnits=trqPidsGroup.find("controlUnits"); - if (controlUnits.isNull() == false && controlUnits.isString() == true) - { - if (controlUnits.toString()==std::string("metric_units")) {yCDebug(FAKEMOTIONCONTROL, "TORQUE_CONTROL: using metric_units"); _torqueControlUnits=T_METRIC_UNITS;} - else if (controlUnits.toString()==std::string("machine_units")) {yCDebug(FAKEMOTIONCONTROL, "TORQUE_CONTROL: using metric_units"); _torqueControlUnits=T_MACHINE_UNITS;} - else {yCError(FAKEMOTIONCONTROL) << "fromConfig(): TORQUE_CONTROL section: invalid controlUnits value"; - return false;} - } - else - { - yCError(FAKEMOTIONCONTROL) << "fromConfig(): TORQUE_CONTROL section: missing controlUnits parameter. Assuming machine_units. Please fix your configuration file."; - _torqueControlUnits=T_MACHINE_UNITS; - } - - if(_torqueControlUnits==T_MACHINE_UNITS) - { - yarp::sig::Vector tmpOnes; tmpOnes.resize(_njoints,1.0); - } - else if (_torqueControlUnits==T_METRIC_UNITS) - { - } - else - { - yCError(FAKEMOTIONCONTROL) << "fromConfig(): TORQUE_CONTROL section: invalid controlUnits value (_torqueControlUnits=" << _torqueControlUnits << ")"; - return false; - } - } - else - { - yCError(FAKEMOTIONCONTROL) <<"fromConfig(): Error: no TORQUE_CONTROL group found in config file"; - _torqueControlEnabled = false; - return false; //torque control group is mandatory - } - } -*/ - - ////// IMPEDANCE LIMITS DEFAULT VALUES (UNDER TESTING) -/* - for(j=0; j<_njoints; j++) - { - // got from canBusMotionControl, ask to Randazzo Marco - _impedance_limits[j].min_damp= 0.001; - _impedance_limits[j].max_damp= 9.888; - _impedance_limits[j].min_stiff= 0.002; - _impedance_limits[j].max_stiff= 9.889; - _impedance_limits[j].param_a= 0.011; - _impedance_limits[j].param_b= 0.012; - _impedance_limits[j].param_c= 0.013; - } -*/ - - /////// JOINTS_COUPLING -/* - if (_njoints<=4) - { - Bottle &coupling=config.findGroup("JOINTS_COUPLING"); - if (coupling.isNull()) - { - yCWarning(FAKEMOTIONCONTROL) << "fromConfig() detected that Group JOINTS_COUPLING is not found in configuration file"; - //return false; - } - // current limit - if (!extractGroup(coupling, xtmp, "kinematic_mj","the kinematic matrix 4x4 which transforms from joint space to motor space", 16)) - { - for(i=1; iyarp::os::PeriodicThread::stop(); - - yCTrace(FAKEMOTIONCONTROL) << " close()"; - - ImplementControlMode::uninitialize(); - ImplementEncodersTimed::uninitialize(); - ImplementMotorEncoders::uninitialize(); - ImplementPositionControl::uninitialize(); - ImplementVelocityControl::uninitialize(); - ImplementPidControl::uninitialize(); - ImplementControlCalibration::uninitialize(); - ImplementAmplifierControl::uninitialize(); - ImplementImpedanceControl::uninitialize(); - ImplementControlLimits::uninitialize(); - ImplementTorqueControl::uninitialize(); - ImplementPositionDirect::uninitialize(); - ImplementInteractionMode::uninitialize(); - ImplementAxisInfo::uninitialize(); - ImplementVirtualAnalogSensor::uninitialize(); - -// cleanup(); - - return true; -} - -void FakeMotionControl::cleanup() -{ - -} +} @@ -3013,335 +2258,631 @@ bool FakeMotionControl::getTargetPositionsRaw(double *refs) for (int i = 0; i < _njoints; i++) { ret &= getTargetPositionRaw(i, &refs[i]); } - return ret; + return ret; +} + +bool FakeMotionControl::getTargetPositionsRaw(int nj, const int * jnts, double *refs) +{ + bool ret = true; + for (int i = 0; i VERY_VERY_VERBOSE) { + yCTrace(FAKEMOTIONCONTROL) << "j: " << j; + } + + *_mode = (yarp::dev::InteractionModeEnum)_interactMode[j]; + return true;} + +bool FakeMotionControl::getInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum* modes) +{ + bool ret = true; + for(int j=0; j< n_joints; j++) + { + ret = ret && getInteractionModeRaw(joints[j], &modes[j]); + } + return ret; + +} + +bool FakeMotionControl::getInteractionModesRaw(yarp::dev::InteractionModeEnum* modes) +{ + bool ret = true; + for (int j = 0; j < _njoints; j++) { + ret = ret && getInteractionModeRaw(j, &modes[j]); + } + return ret; +} + +// marco.accame: con alberto cardellino abbiamo parlato della correttezza di effettuare la verifica di quanto imposto (in setInteractionModeRaw() ed affini) +// andando a rileggere il valore nella scheda eth fino a che esso non sia quello atteso. si deve fare oppure no? +// con il interaction mode il can ora non lo fa. mentre lo fa per il control mode. perche' diverso? +bool FakeMotionControl::setInteractionModeRaw(int j, yarp::dev::InteractionModeEnum _mode) +{ + if (verbose >= VERY_VERBOSE) { + yCTrace(FAKEMOTIONCONTROL) << "j: " << j << " interaction mode: " << yarp::os::Vocab32::decode(_mode); + } + + _interactMode[j] = _mode; + + return true; +} + + +bool FakeMotionControl::setInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum* modes) +{ + bool ret = true; + for(int i=0; i VERY_VERY_VERBOSE) { - yCTrace(FAKEMOTIONCONTROL) << "j: " << j; - } + _mutex.lock(); + fault = _hwfault_code[j]; + message = _hwfault_message[j]; + _mutex.unlock(); + return true; +} - *_mode = (yarp::dev::InteractionModeEnum)_interactMode[j]; - return true;} -bool FakeMotionControl::getInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum* modes) +/* +bool FakeMotionControl::parseImpedanceGroup_NewFormat(Bottle& pidsGroup, ImpedanceParameters vals[]) { - bool ret = true; - for(int j=0; j< n_joints; j++) - { - ret = ret && getInteractionModeRaw(joints[j], &modes[j]); + int j=0; + Bottle xtmp; + + if (!extractGroup(pidsGroup, xtmp, "stiffness", "stiffness parameter", _njoints)) { + return false; + } + for (j=0; j<_njoints; j++) { + vals[j].stiffness = xtmp.get(j+1).asFloat64(); + } + + if (!extractGroup(pidsGroup, xtmp, "damping", "damping parameter", _njoints)) { + return false; + } + for (j=0; j<_njoints; j++) { + vals[j].damping = xtmp.get(j+1).asFloat64(); } - return ret; + return true; } +*/ -bool FakeMotionControl::getInteractionModesRaw(yarp::dev::InteractionModeEnum* modes) +/* +bool FakeMotionControl::parsePositionPidsGroup(Bottle& pidsGroup, Pid myPid[]) { - bool ret = true; - for (int j = 0; j < _njoints; j++) { - ret = ret && getInteractionModeRaw(j, &modes[j]); + int j=0; + Bottle xtmp; + + if (!extractGroup(pidsGroup, xtmp, "kp", "Pid kp parameter", _njoints)) { + return false; + } + for (j=0; j<_njoints; j++) { + myPid[j].kp = xtmp.get(j+1).asFloat64(); } - return ret; -} -// marco.accame: con alberto cardellino abbiamo parlato della correttezza di effettuare la verifica di quanto imposto (in setInteractionModeRaw() ed affini) -// andando a rileggere il valore nella scheda eth fino a che esso non sia quello atteso. si deve fare oppure no? -// con il interaction mode il can ora non lo fa. mentre lo fa per il control mode. perche' diverso? -bool FakeMotionControl::setInteractionModeRaw(int j, yarp::dev::InteractionModeEnum _mode) -{ - if (verbose >= VERY_VERBOSE) { - yCTrace(FAKEMOTIONCONTROL) << "j: " << j << " interaction mode: " << yarp::os::Vocab32::decode(_mode); + if (!extractGroup(pidsGroup, xtmp, "kd", "Pid kd parameter", _njoints)) { + return false; + } + for (j=0; j<_njoints; j++) { + myPid[j].kd = xtmp.get(j+1).asFloat64(); } - _interactMode[j] = _mode; + if (!extractGroup(pidsGroup, xtmp, "ki", "Pid kp parameter", _njoints)) { + return false; + } + for (j=0; j<_njoints; j++) { + myPid[j].ki = xtmp.get(j+1).asFloat64(); + } - return true; -} + if (!extractGroup(pidsGroup, xtmp, "maxInt", "Pid maxInt parameter", _njoints)) { + return false; + } + for (j=0; j<_njoints; j++) { + myPid[j].max_int = xtmp.get(j+1).asFloat64(); + } + if (!extractGroup(pidsGroup, xtmp, "maxPwm", "Pid maxPwm parameter", _njoints)) { + return false; + } + for (j=0; j<_njoints; j++) { + myPid[j].max_output = xtmp.get(j+1).asFloat64(); + } -bool FakeMotionControl::setInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum* modes) -{ - bool ret = true; - for(int i=0; igetNewtonsToSensor(j); //[PWM/Nm] +// myPid[j].ki = myPid[j].ki / _torqueControlHelper->getNewtonsToSensor(j); //[PWM/Nm] +// myPid[j].kd = myPid[j].kd / _torqueControlHelper->getNewtonsToSensor(j); //[PWM/Nm] +// myPid[j].stiction_up_val = myPid[j].stiction_up_val * _torqueControlHelper->getNewtonsToSensor(j); //[Nm] +// myPid[j].stiction_down_val = myPid[j].stiction_down_val * _torqueControlHelper->getNewtonsToSensor(j); //[Nm] +// } + + //optional PWM limit + if(_pwmIsLimited) + { // check for value in the file + if (!extractGroup(pidsGroup, xtmp, "limPwm", "Limited PWM", _njoints)) + { + yCError(FAKEMOTIONCONTROL) << "The PID parameter limPwm was requested but was not correctly set in the configuration file, please fill it."; + return false; + } + + yCInfo(FAKEMOTIONCONTROL) << "Using LIMITED PWM!!"; + for (j = 0; j < _njoints; j++) { + myPid[j].max_output = xtmp.get(j + 1).asFloat64(); + } + } -bool FakeMotionControl::getLastJointFaultRaw(int j, int& fault, std::string& message) -{ - _mutex.lock(); - fault = _hwfault_code[j]; - message = _hwfault_message[j]; - _mutex.unlock(); return true; } +*/ // eof diff --git a/src/devices/fake/fakeMotionControl/fakeMotionControl.h b/src/devices/fake/fakeMotionControl/FakeMotionControl.h similarity index 97% rename from src/devices/fake/fakeMotionControl/fakeMotionControl.h rename to src/devices/fake/fakeMotionControl/FakeMotionControl.h index 3d14ba93808..117a7206a26 100644 --- a/src/devices/fake/fakeMotionControl/fakeMotionControl.h +++ b/src/devices/fake/fakeMotionControl/FakeMotionControl.h @@ -20,7 +20,7 @@ #include #include - +#include "FakeMotionControl_ParamsParser.h" struct ImpedanceLimits { @@ -79,9 +79,12 @@ struct ImpedanceParameters * This device is implementing last version of interfaces and it is compatible * with controlBoard_nws_yarp device. * + * Parameters required by this device are shown in class: FakeMotionControl_ParamsParser + * * WIP - Some interfaces could be not implemented. */ class FakeMotionControl : + public FakeMotionControl_ParamsParser, public yarp::dev::DeviceDriver, public yarp::os::PeriodicThread, public yarp::dev::IPidControlRaw, @@ -508,12 +511,11 @@ class FakeMotionControl : private: void cleanup(); bool dealloc(); - bool parsePositionPidsGroup(yarp::os::Bottle& pidsGroup, yarp::dev::Pid myPid[]); - bool parseTorquePidsGroup(yarp::os::Bottle& pidsGroup, yarp::dev::Pid myPid[], double kbemf[], double ktau[], int filterType[], double viscousPos[], double viscousNeg[], double coulombPos[], double coulombNeg[], double velocityThres[]); - - bool parseImpedanceGroup_NewFormat(yarp::os::Bottle& pidsGroup, ImpedanceParameters vals[]); - bool extractGroup(yarp::os::Bottle &input, yarp::os::Bottle &out, const std::string &key1, const std::string &txt, int size); + //bool parsePositionPidsGroup(yarp::os::Bottle& pidsGroup, yarp::dev::Pid myPid[]); + //bool parseTorquePidsGroup(yarp::os::Bottle& pidsGroup, yarp::dev::Pid myPid[], double kbemf[], double ktau[], int filterType[], double viscousPos[], double viscousNeg[], double coulombPos[], double coulombNeg[], double velocityThres[]); + //bool parseImpedanceGroup_NewFormat(yarp::os::Bottle& pidsGroup, ImpedanceParameters vals[]); + //bool extractGroup(yarp::os::Bottle &input, yarp::os::Bottle &out, const std::string &key1, const std::string &txt, int size); }; #endif // YARP_DEVICE_FAKE_MOTIONCONTROL diff --git a/src/devices/fake/fakeMotionControl/FakeMotionControl_ParamsParser.cpp b/src/devices/fake/fakeMotionControl/FakeMotionControl_ParamsParser.cpp new file mode 100644 index 00000000000..29efb1e0c9a --- /dev/null +++ b/src/devices/fake/fakeMotionControl/FakeMotionControl_ParamsParser.cpp @@ -0,0 +1,369 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:29 2024 + + +#include "FakeMotionControl_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeMotionControlParamsCOMPONENT, "yarp.device.FakeMotionControl") +} + + +FakeMotionControl_ParamsParser::FakeMotionControl_ParamsParser() +{ +} + + +std::vector FakeMotionControl_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("GENERAL::Joints"); + params.push_back("GENERAL::AxisMap"); + params.push_back("GENERAL::AxisName"); + params.push_back("GENERAL::AxisType"); + params.push_back("GENERAL::ampsToSensor"); + params.push_back("GENERAL::fullscalePWM"); + params.push_back("GENERAL::Encoder"); + params.push_back("LIMITS::Max"); + params.push_back("LIMITS::Min"); + return params; +} + + +bool FakeMotionControl_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeMotionControlParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter GENERAL::Joints + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("Joints")) + { + m_GENERAL_Joints = sectionp.find("Joints").asInt64(); + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::Joints' using value:" << m_GENERAL_Joints; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::Joints' using DEFAULT value:" << m_GENERAL_Joints; + } + prop_check.unput("GENERAL::Joints"); + } + + //Parser of parameter GENERAL::AxisMap + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("AxisMap")) + { + { + m_GENERAL_AxisMap.clear(); + yarp::os::Bottle* tempBot = sectionp.find("AxisMap").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_AxisMap.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(FakeMotionControlParamsCOMPONENT) <<"parameter 'GENERAL_AxisMap' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::AxisMap' using value:" << m_GENERAL_AxisMap; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::AxisMap' using DEFAULT value:" << m_GENERAL_AxisMap; + } + prop_check.unput("GENERAL::AxisMap"); + } + + //Parser of parameter GENERAL::AxisName + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("AxisName")) + { + { + m_GENERAL_AxisName.clear(); + yarp::os::Bottle* tempBot = sectionp.find("AxisName").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_AxisName.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(FakeMotionControlParamsCOMPONENT) <<"parameter 'GENERAL_AxisName' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::AxisName' using value:" << m_GENERAL_AxisName; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::AxisName' using DEFAULT value:" << m_GENERAL_AxisName; + } + prop_check.unput("GENERAL::AxisName"); + } + + //Parser of parameter GENERAL::AxisType + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("AxisType")) + { + { + m_GENERAL_AxisType.clear(); + yarp::os::Bottle* tempBot = sectionp.find("AxisType").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_AxisType.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(FakeMotionControlParamsCOMPONENT) <<"parameter 'GENERAL_AxisType' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::AxisType' using value:" << m_GENERAL_AxisType; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::AxisType' using DEFAULT value:" << m_GENERAL_AxisType; + } + prop_check.unput("GENERAL::AxisType"); + } + + //Parser of parameter GENERAL::ampsToSensor + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("ampsToSensor")) + { + { + m_GENERAL_ampsToSensor.clear(); + yarp::os::Bottle* tempBot = sectionp.find("ampsToSensor").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_ampsToSensor.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(FakeMotionControlParamsCOMPONENT) <<"parameter 'GENERAL_ampsToSensor' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::ampsToSensor' using value:" << m_GENERAL_ampsToSensor; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::ampsToSensor' using DEFAULT value:" << m_GENERAL_ampsToSensor; + } + prop_check.unput("GENERAL::ampsToSensor"); + } + + //Parser of parameter GENERAL::fullscalePWM + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("fullscalePWM")) + { + { + m_GENERAL_fullscalePWM.clear(); + yarp::os::Bottle* tempBot = sectionp.find("fullscalePWM").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_fullscalePWM.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(FakeMotionControlParamsCOMPONENT) <<"parameter 'GENERAL_fullscalePWM' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::fullscalePWM' using value:" << m_GENERAL_fullscalePWM; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::fullscalePWM' using DEFAULT value:" << m_GENERAL_fullscalePWM; + } + prop_check.unput("GENERAL::fullscalePWM"); + } + + //Parser of parameter GENERAL::Encoder + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("Encoder")) + { + { + m_GENERAL_Encoder.clear(); + yarp::os::Bottle* tempBot = sectionp.find("Encoder").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_Encoder.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(FakeMotionControlParamsCOMPONENT) <<"parameter 'GENERAL_Encoder' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::Encoder' using value:" << m_GENERAL_Encoder; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'GENERAL::Encoder' using DEFAULT value:" << m_GENERAL_Encoder; + } + prop_check.unput("GENERAL::Encoder"); + } + + //Parser of parameter LIMITS::Max + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("LIMITS"); + if (sectionp.check("Max")) + { + { + m_LIMITS_Max.clear(); + yarp::os::Bottle* tempBot = sectionp.find("Max").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_LIMITS_Max.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(FakeMotionControlParamsCOMPONENT) <<"parameter 'LIMITS_Max' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'LIMITS::Max' using value:" << m_LIMITS_Max; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'LIMITS::Max' using DEFAULT value:" << m_LIMITS_Max; + } + prop_check.unput("LIMITS::Max"); + } + + //Parser of parameter LIMITS::Min + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("LIMITS"); + if (sectionp.check("Min")) + { + { + m_LIMITS_Min.clear(); + yarp::os::Bottle* tempBot = sectionp.find("Min").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_LIMITS_Min.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(FakeMotionControlParamsCOMPONENT) <<"parameter 'LIMITS_Min' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'LIMITS::Min' using value:" << m_LIMITS_Min; + } + else + { + yCInfo(FakeMotionControlParamsCOMPONENT) << "Parameter 'LIMITS::Min' using DEFAULT value:" << m_LIMITS_Min; + } + prop_check.unput("LIMITS::Min"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeMotionControlParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeMotionControlParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeMotionControl_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeMotionControl\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'GENERAL::Joints': Number of degrees of freedom\n"); + doc = doc + std::string("'GENERAL::AxisMap': a list of reordered indices for the axes\n"); + doc = doc + std::string("'GENERAL::AxisName': a list of strings representing the axes names\n"); + doc = doc + std::string("'GENERAL::AxisType': a list of strings representing the axes type (revolute/prismatic)\n"); + doc = doc + std::string("'GENERAL::ampsToSensor': a list of scales for the ampsToSensor conversion factors\n"); + doc = doc + std::string("'GENERAL::fullscalePWM': a list of scales for the fullscalePWM conversion factors\n"); + doc = doc + std::string("'GENERAL::Encoder': a list of scales for the encoders\n"); + doc = doc + std::string("'LIMITS::Max': max encoder position\n"); + doc = doc + std::string("'LIMITS::Min': min encoder position\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeMotionControl --GENERAL::Joints 1 --GENERAL::AxisMap --GENERAL::AxisName --GENERAL::AxisType --GENERAL::ampsToSensor --GENERAL::fullscalePWM --GENERAL::Encoder --LIMITS::Max --LIMITS::Min \n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeMotionControl\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeMotionControl/FakeMotionControl_ParamsParser.h b/src/devices/fake/fakeMotionControl/FakeMotionControl_ParamsParser.h new file mode 100644 index 00000000000..0a1d2a1afb6 --- /dev/null +++ b/src/devices/fake/fakeMotionControl/FakeMotionControl_ParamsParser.h @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:29 2024 + + +#ifndef FAKEMOTIONCONTROL_PARAMSPARSER_H +#define FAKEMOTIONCONTROL_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeMotionControl. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:--------------:|:-----:|:-------------:|:--------:|:-----------------------------------------------------------------:|:-----:| +* | GENERAL | Joints | int | - | 1 | 0 | Number of degrees of freedom | - | +* | GENERAL | AxisMap | vector | - | - | 0 | a list of reordered indices for the axes | - | +* | GENERAL | AxisName | vector | - | - | 0 | a list of strings representing the axes names | - | +* | GENERAL | AxisType | vector | - | - | 0 | a list of strings representing the axes type (revolute/prismatic) | - | +* | GENERAL | ampsToSensor | vector | - | - | 0 | a list of scales for the ampsToSensor conversion factors | - | +* | GENERAL | fullscalePWM | vector | - | - | 0 | a list of scales for the fullscalePWM conversion factors | - | +* | GENERAL | Encoder | vector | - | - | 0 | a list of scales for the encoders | - | +* | LIMITS | Max | vector | deg | - | 0 | max encoder position | - | +* | LIMITS | Min | vector | deg | - | 0 | min encoder position | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeMotionControl --GENERAL::Joints 1 --GENERAL::AxisMap --GENERAL::AxisName --GENERAL::AxisType --GENERAL::ampsToSensor --GENERAL::fullscalePWM --GENERAL::Encoder --LIMITS::Max --LIMITS::Min +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeMotionControl +* \endcode +* +*/ + +class FakeMotionControl_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeMotionControl_ParamsParser(); + ~FakeMotionControl_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeMotionControl"}; + const std::string m_device_name = {"fakeMotionControl"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_GENERAL_Joints_defaultValue = {"1"}; + const std::string m_GENERAL_AxisMap_defaultValue = {""}; + const std::string m_GENERAL_AxisName_defaultValue = {""}; + const std::string m_GENERAL_AxisType_defaultValue = {""}; + const std::string m_GENERAL_ampsToSensor_defaultValue = {""}; + const std::string m_GENERAL_fullscalePWM_defaultValue = {""}; + const std::string m_GENERAL_Encoder_defaultValue = {""}; + const std::string m_LIMITS_Max_defaultValue = {""}; + const std::string m_LIMITS_Min_defaultValue = {""}; + + int m_GENERAL_Joints = {1}; + std::vector m_GENERAL_AxisMap = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_GENERAL_AxisName = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_GENERAL_AxisType = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_GENERAL_ampsToSensor = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_GENERAL_fullscalePWM = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_GENERAL_Encoder = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_LIMITS_Max = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_LIMITS_Min = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeMotionControl/FakeMotionControl_params.md b/src/devices/fake/fakeMotionControl/FakeMotionControl_params.md new file mode 100644 index 00000000000..7575576290b --- /dev/null +++ b/src/devices/fake/fakeMotionControl/FakeMotionControl_params.md @@ -0,0 +1,9 @@ + * | GENERAL | Joints | int | - | 1 | No | Number of degrees of freedom | | + * | GENERAL | AxisMap | vector | - | - | No | a list of reordered indices for the axes | | + * | GENERAL | AxisName | vector | - | - | No | a list of strings representing the axes names | | + * | GENERAL | AxisType | vector | - | - | No | a list of strings representing the axes type (revolute/prismatic) | | + * | GENERAL | ampsToSensor | vector | - | - | No | a list of scales for the ampsToSensor conversion factors | | + * | GENERAL | fullscalePWM | vector | - | - | No | a list of scales for the fullscalePWM conversion factors | | + * | GENERAL | Encoder | vector | - | - | No | a list of scales for the encoders | | + * | LIMITS | Max | vector | deg | - | No | max encoder position | | + * | LIMITS | Min | vector | deg | - | No | min encoder position | | diff --git a/src/devices/fake/fakeMotionControlMicro/CMakeLists.txt b/src/devices/fake/fakeMotionControlMicro/CMakeLists.txt index 7eb439752d7..b94b1ecce68 100644 --- a/src/devices/fake/fakeMotionControlMicro/CMakeLists.txt +++ b/src/devices/fake/fakeMotionControlMicro/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeMotionControlMicro CATEGORY device TYPE FakeMotionControlMicro - INCLUDE fakeMotionControlMicro.h + INCLUDE FakeMotionControlMicro.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=controlBoard_nws_yarp ) @@ -18,8 +19,11 @@ if(NOT SKIP_fakeMotionControlMicro) target_sources(yarp_fakeMotionControlMicro PRIVATE - fakeMotionControlMicro.cpp - fakeMotionControlMicro.h) + FakeMotionControlMicro.cpp + FakeMotionControlMicro.h + FakeMotionControlMicro_ParamsParser.cpp + FakeMotionControlMicro_ParamsParser.h +) target_link_libraries(yarp_fakeMotionControlMicro PRIVATE diff --git a/src/devices/fake/fakeMotionControlMicro/fakeMotionControlMicro.cpp b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro.cpp similarity index 65% rename from src/devices/fake/fakeMotionControlMicro/fakeMotionControlMicro.cpp rename to src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro.cpp index 5d7fe9fec24..7fc0f586cbf 100644 --- a/src/devices/fake/fakeMotionControlMicro/fakeMotionControlMicro.cpp +++ b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeMotionControlMicro.h" +#include "FakeMotionControlMicro.h" #include @@ -194,43 +194,14 @@ void FakeMotionControlMicro::threadRelease() bool FakeMotionControlMicro::open(yarp::os::Searchable &config) { - std::string str; + if (!this->parseParams(config)) {return false;} -// if (!config.findGroup("GENERAL").find("MotioncontrolVersion").isInt32()) -// { -// yCError(FAKEMOTIONCONTROL) << "Missing MotioncontrolVersion parameter. yarprobotinterface cannot start. Please contact icub-support@iit.it"; -// return false; -// } -// else -// { -// int mcv = config.findGroup("GENERAL").find("MotioncontrolVersion").asInt32(); -// if (mcv != 2) -// { -// yCError(FAKEMOTIONCONTROL) << "Wrong MotioncontrolVersion parameter. yarprobotinterface cannot start. Please contact icub-support@iit.it"; -// return false; -// } -// } - -// if(!config.findGroup("GENERAL").find("verbose").isBool()) -// { -// yCError(FAKEMOTIONCONTROL) << "open() detects that general->verbose bool param is different from accepted values (true / false). Assuming false"; -// str=" "; -// } -// else -// { -// if(config.findGroup("GENERAL").find("verbose").asBool()) -// str=config.toString().c_str(); -// else -// str=" "; -// } - str=config.toString(); - yCTrace(FAKEMOTIONCONTROLMICRO) << str; + std::string str; // // Read Configuration params from file // - _njoints = config.findGroup("GENERAL").check("Joints",Value(1), "Number of degrees of freedom").asInt32(); - yCInfo(FAKEMOTIONCONTROLMICRO, "Using %d joint%s", _njoints, ((_njoints != 1) ? "s" : "")); + _njoints = m_GENERAL_Joints; if(!alloc(_njoints)) { @@ -275,204 +246,82 @@ bool FakeMotionControlMicro::open(yarp::os::Searchable &config) bool FakeMotionControlMicro::fromConfig(yarp::os::Searchable &config) { - Bottle xtmp; - int i; - Bottle general = config.findGroup("GENERAL"); + size_t i; - // read AxisMap values from file - if(general.check("AxisMap")) + // AxisMap + if (!m_GENERAL_AxisMap.empty()) { - if(extractGroup(general, xtmp, "AxisMap", "a list of reordered indices for the axes", _njoints)) - { - for (i = 1; (size_t)i < xtmp.size(); i++) { - _axisMap[i - 1] = xtmp.get(i).asInt32(); - } - } else { - return false; + for (i = 0; i < m_GENERAL_AxisMap.size(); i++) { + _axisMap[i] = m_GENERAL_AxisMap[i]; } } else { - yCInfo(FAKEMOTIONCONTROLMICRO) << "Using default AxisMap"; for (i = 0; i < _njoints; i++) { _axisMap[i] = i; } } - if(general.check("AxisName")) + // AxisName + if (!m_GENERAL_AxisName.empty()) { - if (extractGroup(general, xtmp, "AxisName", "a list of strings representing the axes names", _njoints)) - { - //beware: axis name has to be remapped here because they are not set using the toHw() helper function - for (i = 1; (size_t) i < xtmp.size(); i++) - { - _axisName[_axisMap[i - 1]] = xtmp.get(i).asString(); - } - } else { - return false; + for (i = 0; i < m_GENERAL_AxisName.size(); i++) { + _axisName[_axisMap[i]] = m_GENERAL_AxisName[i]; } } else { - yCInfo(FAKEMOTIONCONTROLMICRO) << "Using default AxisName"; - for (i = 0; i < _njoints; i++) - { + for (i = 0; i < _njoints; i++) { _axisName[_axisMap[i]] = "joint" + toString(i); } } - if(general.check("AxisType")) + + // Axis Type + if (!m_GENERAL_AxisType.empty()) { - if (extractGroup(general, xtmp, "AxisType", "a list of strings representing the axes type (revolute/prismatic)", _njoints)) + //beware: axis type has to be remapped here because they are not set using the toHw() helper function + for (i = 0; i < m_GENERAL_AxisType.size(); i++) { - //beware: axis type has to be remapped here because they are not set using the toHw() helper function - for (i = 1; (size_t) i < xtmp.size(); i++) - { - std::string typeString = xtmp.get(i).asString(); - if (typeString == "revolute") { - _jointType[_axisMap[i - 1]] = VOCAB_JOINTTYPE_REVOLUTE; - } else if (typeString == "prismatic") { - _jointType[_axisMap[i - 1]] = VOCAB_JOINTTYPE_PRISMATIC; - } else { - yCError(FAKEMOTIONCONTROLMICRO, "Unknown AxisType value %s!", typeString.c_str()); - _jointType[_axisMap[i - 1]] = VOCAB_JOINTTYPE_UNKNOWN; - return false; - } + std::string typeString = m_GENERAL_AxisType[i]; + if (typeString == "revolute") { + _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_REVOLUTE; + } + else if (typeString == "prismatic") { + _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_PRISMATIC; + } + else { + yCError(FAKEMOTIONCONTROLMICRO, "Unknown AxisType value %s!", typeString.c_str()); + _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_UNKNOWN; + return false; } - } else { - return false; } } else { yCInfo(FAKEMOTIONCONTROLMICRO) << "Using default AxisType (revolute)"; - for (i = 0; i < _njoints; i++) - { + for (i = 0; i < _njoints; i++) { _jointType[_axisMap[i]] = VOCAB_JOINTTYPE_REVOLUTE; } } -// double tmp_A2E; - // Encoder scales - if(general.check("Encoder")) - { - if (extractGroup(general, xtmp, "Encoder", "a list of scales for the encoders", _njoints)) - { - for (i = 1; (size_t) i < xtmp.size(); i++) - { - _angleToEncoder[i-1] = xtmp.get(i).asFloat64(); - } - } else { - return false; - } - } - else - { - yCInfo(FAKEMOTIONCONTROLMICRO) << "Using default Encoder"; - for (i = 0; i < _njoints; i++) { - _angleToEncoder[i] = 1; - } - } - // Joint encoder resolution - /*if (!extractGroup(general, xtmp, "JointEncoderRes", "the resolution of the joint encoder", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _jointEncoderRes[i - 1] = xtmp.get(i).asInt32(); - } - // Joint encoder type - if (!extractGroup(general, xtmp, "JointEncoderType", "JointEncoderType", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - { - uint8_t val; - std::string s = xtmp.get(i).asString(); - bool b = EncoderType_iCub2eo(&s, &val); - if (b == false) - { - yCError(FAKEMOTIONCONTROL, "Invalid JointEncoderType: %s!", s.c_str()); return false; - } -// _jointEncoderType[i - 1] = val; - } - } -*/ - // Motor capabilities -/* if (!extractGroup(general, xtmp, "HasHallSensor", "HasHallSensor 0/1 ", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _hasHallSensor[i - 1] = xtmp.get(i).asInt32(); - } - if (!extractGroup(general, xtmp, "HasTempSensor", "HasTempSensor 0/1 ", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _hasTempSensor[i - 1] = xtmp.get(i).asInt32(); - } - if (!extractGroup(general, xtmp, "HasRotorEncoder", "HasRotorEncoder 0/1 ", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _hasRotorEncoder[i - 1] = xtmp.get(i).asInt32(); - } - if (!extractGroup(general, xtmp, "HasRotorEncoderIndex", "HasRotorEncoderIndex 0/1 ", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _hasRotorEncoderIndex[i - 1] = xtmp.get(i).asInt32(); - } - // Rotor encoder res - if (!extractGroup(general, xtmp, "RotorEncoderRes", "a list of scales for the rotor encoders", _njoints)) - { - return false; - } - else - { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _rotorEncoderRes[i - 1] = xtmp.get(i).asInt32(); - } - // joint encoder res - if (!extractGroup(general, xtmp, "JointEncoderRes", "a list of scales for the joint encoders", _njoints)) +// double tmp_A2E; + // Encoder scales + if(!m_GENERAL_Encoder.empty()) { - return false; + for (i = 0; i < m_GENERAL_Encoder.size(); i++) { + _angleToEncoder[i] = m_GENERAL_Encoder[i]; } } else { - int test = xtmp.size(); - for (i = 1; i < xtmp.size(); i++) - _jointEncoderRes[i - 1] = xtmp.get(i).asInt32(); + yCInfo(FAKEMOTIONCONTROLMICRO) << "Using default Encoder=1"; + for (i = 0; i < _njoints; i++) { + _angleToEncoder[i] = 1; } } -*/ return true; } diff --git a/src/devices/fake/fakeMotionControlMicro/fakeMotionControlMicro.h b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro.h similarity index 95% rename from src/devices/fake/fakeMotionControlMicro/fakeMotionControlMicro.h rename to src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro.h index f7021aefb3b..d662b71084c 100644 --- a/src/devices/fake/fakeMotionControlMicro/fakeMotionControlMicro.h +++ b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro.h @@ -16,6 +16,7 @@ #include #include +#include "FakeMotionControlMicro_ParamsParser.h" /** * @ingroup dev_impl_fake dev_impl_motor @@ -23,6 +24,8 @@ * \brief `fakeMotionControlMicro`: This device implements a minimal subset of mandatory interfaces * to run with controlBoard_nws_yarp. It is thus a smaller, limited version than fakeMotionControl. * + * Parameters required by this device are shown in class: FakeMotionControlMicro_ParamsParser + * */ class FakeMotionControlMicro : public yarp::os::PeriodicThread, @@ -34,7 +37,8 @@ class FakeMotionControlMicro : public yarp::dev::ImplementJointFault, public yarp::dev::ImplementAxisInfo, public yarp::dev::ImplementEncodersTimed, - public yarp::dev::ImplementMotorEncoders + public yarp::dev::ImplementMotorEncoders, + public FakeMotionControlMicro_ParamsParser { private: enum VerboseLevel diff --git a/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_ParamsParser.cpp b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_ParamsParser.cpp new file mode 100644 index 00000000000..c28d44fe32b --- /dev/null +++ b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_ParamsParser.cpp @@ -0,0 +1,237 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#include "FakeMotionControlMicro_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeMotionControlMicroParamsCOMPONENT, "yarp.device.FakeMotionControlMicro") +} + + +FakeMotionControlMicro_ParamsParser::FakeMotionControlMicro_ParamsParser() +{ +} + + +std::vector FakeMotionControlMicro_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("GENERAL::Joints"); + params.push_back("GENERAL::AxisMap"); + params.push_back("GENERAL::AxisName"); + params.push_back("GENERAL::AxisType"); + params.push_back("GENERAL::Encoder"); + return params; +} + + +bool FakeMotionControlMicro_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter GENERAL::Joints + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("Joints")) + { + m_GENERAL_Joints = sectionp.find("Joints").asInt64(); + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::Joints' using value:" << m_GENERAL_Joints; + } + else + { + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::Joints' using DEFAULT value:" << m_GENERAL_Joints; + } + prop_check.unput("GENERAL::Joints"); + } + + //Parser of parameter GENERAL::AxisMap + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("AxisMap")) + { + { + m_GENERAL_AxisMap.clear(); + yarp::os::Bottle* tempBot = sectionp.find("AxisMap").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_AxisMap.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(FakeMotionControlMicroParamsCOMPONENT) <<"parameter 'GENERAL_AxisMap' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::AxisMap' using value:" << m_GENERAL_AxisMap; + } + else + { + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::AxisMap' using DEFAULT value:" << m_GENERAL_AxisMap; + } + prop_check.unput("GENERAL::AxisMap"); + } + + //Parser of parameter GENERAL::AxisName + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("AxisName")) + { + { + m_GENERAL_AxisName.clear(); + yarp::os::Bottle* tempBot = sectionp.find("AxisName").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_AxisName.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(FakeMotionControlMicroParamsCOMPONENT) <<"parameter 'GENERAL_AxisName' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::AxisName' using value:" << m_GENERAL_AxisName; + } + else + { + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::AxisName' using DEFAULT value:" << m_GENERAL_AxisName; + } + prop_check.unput("GENERAL::AxisName"); + } + + //Parser of parameter GENERAL::AxisType + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("AxisType")) + { + { + m_GENERAL_AxisType.clear(); + yarp::os::Bottle* tempBot = sectionp.find("AxisType").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_AxisType.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(FakeMotionControlMicroParamsCOMPONENT) <<"parameter 'GENERAL_AxisType' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::AxisType' using value:" << m_GENERAL_AxisType; + } + else + { + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::AxisType' using DEFAULT value:" << m_GENERAL_AxisType; + } + prop_check.unput("GENERAL::AxisType"); + } + + //Parser of parameter GENERAL::Encoder + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("GENERAL"); + if (sectionp.check("Encoder")) + { + { + m_GENERAL_Encoder.clear(); + yarp::os::Bottle* tempBot = sectionp.find("Encoder").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_GENERAL_Encoder.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(FakeMotionControlMicroParamsCOMPONENT) <<"parameter 'GENERAL_Encoder' is not a properly formatted bottle"; + } + } + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::Encoder' using value:" << m_GENERAL_Encoder; + } + else + { + yCInfo(FakeMotionControlMicroParamsCOMPONENT) << "Parameter 'GENERAL::Encoder' using DEFAULT value:" << m_GENERAL_Encoder; + } + prop_check.unput("GENERAL::Encoder"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeMotionControlMicroParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeMotionControlMicroParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeMotionControlMicro_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeMotionControlMicro\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'GENERAL::Joints': Number of degrees of freedom\n"); + doc = doc + std::string("'GENERAL::AxisMap': a list of reordered indices for the axes\n"); + doc = doc + std::string("'GENERAL::AxisName': a list of strings representing the axes names\n"); + doc = doc + std::string("'GENERAL::AxisType': a list of strings representing the axes type (revolute/prismatic)\n"); + doc = doc + std::string("'GENERAL::Encoder': a list of scales for the encoders\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeMotionControlMicro --GENERAL::Joints 1 --GENERAL::AxisMap --GENERAL::AxisName --GENERAL::AxisType --GENERAL::Encoder \n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeMotionControlMicro\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_ParamsParser.h b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_ParamsParser.h new file mode 100644 index 00000000000..b17e25e319a --- /dev/null +++ b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_ParamsParser.h @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:30 2024 + + +#ifndef FAKEMOTIONCONTROLMICRO_PARAMSPARSER_H +#define FAKEMOTIONCONTROLMICRO_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeMotionControlMicro. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:--------------:|:-----:|:-------------:|:--------:|:-----------------------------------------------------------------:|:-----:| +* | GENERAL | Joints | int | - | 1 | 0 | Number of degrees of freedom | - | +* | GENERAL | AxisMap | vector | - | - | 0 | a list of reordered indices for the axes | - | +* | GENERAL | AxisName | vector | - | - | 0 | a list of strings representing the axes names | - | +* | GENERAL | AxisType | vector | - | - | 0 | a list of strings representing the axes type (revolute/prismatic) | - | +* | GENERAL | Encoder | vector | - | - | 0 | a list of scales for the encoders | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeMotionControlMicro --GENERAL::Joints 1 --GENERAL::AxisMap --GENERAL::AxisName --GENERAL::AxisType --GENERAL::Encoder +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeMotionControlMicro +* \endcode +* +*/ + +class FakeMotionControlMicro_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeMotionControlMicro_ParamsParser(); + ~FakeMotionControlMicro_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeMotionControlMicro"}; + const std::string m_device_name = {"fakeMotionControlMicro"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_GENERAL_Joints_defaultValue = {"1"}; + const std::string m_GENERAL_AxisMap_defaultValue = {""}; + const std::string m_GENERAL_AxisName_defaultValue = {""}; + const std::string m_GENERAL_AxisType_defaultValue = {""}; + const std::string m_GENERAL_Encoder_defaultValue = {""}; + + int m_GENERAL_Joints = {1}; + std::vector m_GENERAL_AxisMap = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_GENERAL_AxisName = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_GENERAL_AxisType = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_GENERAL_Encoder = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_params.md b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_params.md new file mode 100644 index 00000000000..208900cbf1a --- /dev/null +++ b/src/devices/fake/fakeMotionControlMicro/FakeMotionControlMicro_params.md @@ -0,0 +1,5 @@ + * | GENERAL | Joints | int | - | 1 | No | Number of degrees of freedom | | + * | GENERAL | AxisMap | vector | - | - | No | a list of reordered indices for the axes | | + * | GENERAL | AxisName | vector | - | - | No | a list of strings representing the axes names | | + * | GENERAL | AxisType | vector | - | - | No | a list of strings representing the axes type (revolute/prismatic) | | + * | GENERAL | Encoder | vector | - | - | No | a list of scales for the encoders | | diff --git a/src/devices/fake/fakeNavigationDevice/CMakeLists.txt b/src/devices/fake/fakeNavigationDevice/CMakeLists.txt index b95964ac3f2..f124e6c5e45 100644 --- a/src/devices/fake/fakeNavigationDevice/CMakeLists.txt +++ b/src/devices/fake/fakeNavigationDevice/CMakeLists.txt @@ -7,9 +7,10 @@ endif() yarp_prepare_plugin(fakeNavigation CATEGORY device - TYPE fakeNavigation - INCLUDE fakeNavigationDev.h + TYPE FakeNavigation + INCLUDE FakeNavigation.h DEPENDS "TARGET YARP::YARP_math" + GENERATE_PARSER ) if(NOT SKIP_fakeNavigation) @@ -17,8 +18,10 @@ if(NOT SKIP_fakeNavigation) target_sources(yarp_fakeNavigation PRIVATE - fakeNavigationDev.h - fakeNavigationDev.cpp + FakeNavigation.h + FakeNavigation.cpp + FakeNavigation_ParamsParser.h + FakeNavigation_ParamsParser.cpp ) target_link_libraries(yarp_fakeNavigation diff --git a/src/devices/fake/fakeNavigationDevice/fakeNavigationDev.cpp b/src/devices/fake/fakeNavigationDevice/FakeNavigation.cpp similarity index 59% rename from src/devices/fake/fakeNavigationDevice/fakeNavigationDev.cpp rename to src/devices/fake/fakeNavigationDevice/FakeNavigation.cpp index 6eae3194874..28937a6f3af 100644 --- a/src/devices/fake/fakeNavigationDevice/fakeNavigationDev.cpp +++ b/src/devices/fake/fakeNavigationDevice/FakeNavigation.cpp @@ -10,7 +10,7 @@ #include #include #include -#include "fakeNavigationDev.h" +#include "FakeNavigation.h" #include #include @@ -22,85 +22,50 @@ YARP_LOG_COMPONENT(FAKENAVIGATION, "yarp.device.fakeNavigation") } -bool fakeNavigation :: open(yarp::os::Searchable& config) +bool FakeNavigation:: open(yarp::os::Searchable& config) { -#if 1 + if (!this->parseParams(config)) {return false;} - yCDebug(FAKENAVIGATION) << "config configuration: \n" << config.toString().c_str(); - - std::string context_name; - std::string file_name; - - if (config.check("context")) { - context_name = config.find("context").asString(); - } - if (config.check("from")) { - file_name = config.find("from").asString(); - } - - yarp::os::ResourceFinder rf; - rf.setDefaultContext(context_name.c_str()); - rf.setDefaultConfigFile(file_name.c_str()); - - yarp::os::Property p; - std::string configFile = rf.findFile("from"); - if (configFile != "") { - p.fromConfigFile(configFile.c_str()); - } - yCDebug(FAKENAVIGATION) << "device configuration: \n" << p.toString().c_str(); - -#else - Property p; - p.fromString(config.toString()); -#endif - - if (rf.check("navigation_time")) - { - m_navig_duration_param = rf.find ("navigation_time").asInt32(); - } - if (rf.check("reached_time")) - { - m_reached_duration_param = rf.find("reached_time").asInt32(); - } + m_time_counter = m_navigation_time; this->start(); return true; } -fakeNavigation::fakeNavigation() : yarp::os::PeriodicThread(0.010) +FakeNavigation::FakeNavigation() : yarp::os::PeriodicThread(0.010) { } //module cleanup -bool fakeNavigation:: close() +bool FakeNavigation:: close() { return true; } -bool fakeNavigation::gotoTargetByAbsoluteLocation(Map2DLocation loc) +bool FakeNavigation::gotoTargetByAbsoluteLocation(Map2DLocation loc) { if (m_status == NavigationStatusEnum::navigation_status_idle) { m_status = NavigationStatusEnum::navigation_status_moving; m_absgoal_loc = loc; - m_time_counter=m_navig_duration_param; + m_time_counter= this->m_navigation_time; } return true; } -bool fakeNavigation::gotoTargetByRelativeLocation(double x, double y, double theta) +bool FakeNavigation::gotoTargetByRelativeLocation(double x, double y, double theta) { yCInfo(FAKENAVIGATION) << "gotoTargetByRelativeLocation not yet implemented"; return true; } -bool fakeNavigation::gotoTargetByRelativeLocation(double x, double y) +bool FakeNavigation::gotoTargetByRelativeLocation(double x, double y) { yCInfo(FAKENAVIGATION) << "gotoTargetByRelativeLocation not yet implemented"; return true; } -bool fakeNavigation::applyVelocityCommand(double x_vel, double y_vel, double theta_vel, double timeout) +bool FakeNavigation::applyVelocityCommand(double x_vel, double y_vel, double theta_vel, double timeout) { m_control_out.linear_xvel = x_vel; m_control_out.linear_yvel = y_vel; @@ -110,7 +75,7 @@ bool fakeNavigation::applyVelocityCommand(double x_vel, double y_vel, double the return true; } -bool fakeNavigation::getLastVelocityCommand(double& x_vel, double& y_vel, double& theta_vel) +bool FakeNavigation::getLastVelocityCommand(double& x_vel, double& y_vel, double& theta_vel) { double current_time = yarp::os::Time::now(); x_vel = m_control_out.linear_xvel; @@ -119,14 +84,14 @@ bool fakeNavigation::getLastVelocityCommand(double& x_vel, double& y_vel, double return true; } -bool fakeNavigation::stopNavigation() +bool FakeNavigation::stopNavigation() { m_status=NavigationStatusEnum::navigation_status_idle; m_absgoal_loc=Map2DLocation(); return true; } -bool fakeNavigation::suspendNavigation(double time) +bool FakeNavigation::suspendNavigation(double time) { if (m_status == NavigationStatusEnum::navigation_status_moving) { @@ -135,7 +100,7 @@ bool fakeNavigation::suspendNavigation(double time) return true; } -bool fakeNavigation::resumeNavigation() +bool FakeNavigation::resumeNavigation() { if (m_status == NavigationStatusEnum::navigation_status_paused) { @@ -144,37 +109,37 @@ bool fakeNavigation::resumeNavigation() return true; } -bool fakeNavigation::getAllNavigationWaypoints(yarp::dev::Nav2D::TrajectoryTypeEnum trajectory_type, yarp::dev::Nav2D::Map2DPath& waypoints) +bool FakeNavigation::getAllNavigationWaypoints(yarp::dev::Nav2D::TrajectoryTypeEnum trajectory_type, yarp::dev::Nav2D::Map2DPath& waypoints) { yCInfo(FAKENAVIGATION) << "getAllNavigationWaypoints not yet implemented"; return true; } -bool fakeNavigation::getCurrentNavigationWaypoint(Map2DLocation& curr_waypoint) +bool FakeNavigation::getCurrentNavigationWaypoint(Map2DLocation& curr_waypoint) { yCInfo(FAKENAVIGATION) << "getCurrentNavigationWaypoint not yet implemented"; return true; } -bool fakeNavigation::getCurrentNavigationMap(yarp::dev::Nav2D::NavigationMapTypeEnum map_type, MapGrid2D& map) +bool FakeNavigation::getCurrentNavigationMap(yarp::dev::Nav2D::NavigationMapTypeEnum map_type, MapGrid2D& map) { yCInfo(FAKENAVIGATION) << "getCurrentNavigationMap not yet implemented"; return true; } -bool fakeNavigation::getNavigationStatus(yarp::dev::Nav2D::NavigationStatusEnum& status) +bool FakeNavigation::getNavigationStatus(yarp::dev::Nav2D::NavigationStatusEnum& status) { status = m_status; return true; } -bool fakeNavigation::getAbsoluteLocationOfCurrentTarget(Map2DLocation& target) +bool FakeNavigation::getAbsoluteLocationOfCurrentTarget(Map2DLocation& target) { target=m_absgoal_loc; return true; } -bool fakeNavigation::recomputeCurrentNavigationPath() +bool FakeNavigation::recomputeCurrentNavigationPath() { if (m_status == NavigationStatusEnum::navigation_status_moving) { @@ -183,23 +148,23 @@ bool fakeNavigation::recomputeCurrentNavigationPath() return true; } -bool fakeNavigation::getRelativeLocationOfCurrentTarget(double& x, double& y, double& theta) +bool FakeNavigation::getRelativeLocationOfCurrentTarget(double& x, double& y, double& theta) { yCInfo(FAKENAVIGATION) << "getRelativeLocationOfCurrentTarget not yet implemented"; return true; } -bool fakeNavigation::threadInit() +bool FakeNavigation::threadInit() { return true; } -void fakeNavigation::threadRelease() +void FakeNavigation::threadRelease() { } -void fakeNavigation::run() +void FakeNavigation::run() { if (m_status == NavigationStatusEnum::navigation_status_moving) { @@ -210,7 +175,7 @@ void fakeNavigation::run() else { m_status = NavigationStatusEnum::navigation_status_goal_reached; - m_time_counter = m_reached_duration_param; + m_time_counter = m_reached_time; } } if (m_status == NavigationStatusEnum::navigation_status_goal_reached) diff --git a/src/devices/fake/fakeNavigationDevice/fakeNavigationDev.h b/src/devices/fake/fakeNavigationDevice/FakeNavigation.h similarity index 90% rename from src/devices/fake/fakeNavigationDevice/fakeNavigationDev.h rename to src/devices/fake/fakeNavigationDevice/FakeNavigation.h index b3655d8d459..8097bb813f9 100644 --- a/src/devices/fake/fakeNavigationDevice/fakeNavigationDev.h +++ b/src/devices/fake/fakeNavigationDevice/FakeNavigation.h @@ -12,17 +12,22 @@ #include #include +#include "FakeNavigation_ParamsParser.h" + /** * @ingroup dev_impl_fake dev_impl_navigation * * \brief `fakeNavigation`: Documentation to be added + * + * Parameters required by this device are shown in class: FakeNavigation_ParamsParser */ -class fakeNavigation : +class FakeNavigation : public yarp::dev::DeviceDriver, public yarp::dev::Nav2D::INavigation2DTargetActions, public yarp::dev::Nav2D::INavigation2DControlActions, public yarp::dev::Nav2D::INavigation2DVelocityActions, - public yarp::os::PeriodicThread + public yarp::os::PeriodicThread, + public FakeNavigation_ParamsParser { private: yarp::dev::Nav2D::NavigationStatusEnum m_status = yarp::dev::Nav2D::NavigationStatusEnum::navigation_status_idle; @@ -37,14 +42,12 @@ class fakeNavigation : } m_control_out; - int m_reached_duration_param = 100; - int m_navig_duration_param = 500; - int m_time_counter= m_navig_duration_param; + int m_time_counter= 0; public: virtual bool open(yarp::os::Searchable& config) override; - fakeNavigation(); + FakeNavigation(); //module cleanup virtual bool close() override; diff --git a/src/devices/fake/fakeNavigationDevice/FakeNavigation_ParamsParser.cpp b/src/devices/fake/fakeNavigationDevice/FakeNavigation_ParamsParser.cpp new file mode 100644 index 00000000000..9f43bea2764 --- /dev/null +++ b/src/devices/fake/fakeNavigationDevice/FakeNavigation_ParamsParser.cpp @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:33 2024 + + +#include "FakeNavigation_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeNavigationParamsCOMPONENT, "yarp.device.FakeNavigation") +} + + +FakeNavigation_ParamsParser::FakeNavigation_ParamsParser() +{ +} + + +std::vector FakeNavigation_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("navigation_time"); + params.push_back("reached_time"); + return params; +} + + +bool FakeNavigation_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeNavigationParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter navigation_time + { + if (config.check("navigation_time")) + { + m_navigation_time = config.find("navigation_time").asInt64(); + yCInfo(FakeNavigationParamsCOMPONENT) << "Parameter 'navigation_time' using value:" << m_navigation_time; + } + else + { + yCInfo(FakeNavigationParamsCOMPONENT) << "Parameter 'navigation_time' using DEFAULT value:" << m_navigation_time; + } + prop_check.unput("navigation_time"); + } + + //Parser of parameter reached_time + { + if (config.check("reached_time")) + { + m_reached_time = config.find("reached_time").asInt64(); + yCInfo(FakeNavigationParamsCOMPONENT) << "Parameter 'reached_time' using value:" << m_reached_time; + } + else + { + yCInfo(FakeNavigationParamsCOMPONENT) << "Parameter 'reached_time' using DEFAULT value:" << m_reached_time; + } + prop_check.unput("reached_time"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeNavigationParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeNavigationParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeNavigation_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeNavigation\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'navigation_time': navigation_time\n"); + doc = doc + std::string("'reached_time': reached_time\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeNavigation --navigation_time 500 --reached_time 100\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeNavigation\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeNavigationDevice/FakeNavigation_ParamsParser.h b/src/devices/fake/fakeNavigationDevice/FakeNavigation_ParamsParser.h new file mode 100644 index 00000000000..09669a411d3 --- /dev/null +++ b/src/devices/fake/fakeNavigationDevice/FakeNavigation_ParamsParser.h @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:33 2024 + + +#ifndef FAKENAVIGATION_PARAMSPARSER_H +#define FAKENAVIGATION_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeNavigation. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:---------------:|:----:|:-----:|:-------------:|:--------:|:---------------:|:-----:| +* | - | navigation_time | int | - | 500 | 0 | navigation_time | - | +* | - | reached_time | int | - | 100 | 0 | reached_time | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeNavigation --navigation_time 500 --reached_time 100 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeNavigation +* \endcode +* +*/ + +class FakeNavigation_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeNavigation_ParamsParser(); + ~FakeNavigation_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeNavigation"}; + const std::string m_device_name = {"fakeNavigation"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_navigation_time_defaultValue = {"500"}; + const std::string m_reached_time_defaultValue = {"100"}; + + int m_navigation_time = {500}; + int m_reached_time = {100}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeNavigationDevice/FakeNavigation_params.md b/src/devices/fake/fakeNavigationDevice/FakeNavigation_params.md new file mode 100644 index 00000000000..8f89d44ac2a --- /dev/null +++ b/src/devices/fake/fakeNavigationDevice/FakeNavigation_params.md @@ -0,0 +1,2 @@ + * | | navigation_time | int | - | 500 | No | navigation_time | | + * | | reached_time | int | - | 100 | No | reached_time | | diff --git a/src/devices/fake/fakeOdometry2D/CMakeLists.txt b/src/devices/fake/fakeOdometry2D/CMakeLists.txt index 03b6efc369e..90222986470 100644 --- a/src/devices/fake/fakeOdometry2D/CMakeLists.txt +++ b/src/devices/fake/fakeOdometry2D/CMakeLists.txt @@ -8,8 +8,9 @@ endif() yarp_prepare_plugin(fakeOdometry2D CATEGORY device TYPE FakeOdometry2D - INCLUDE fakeOdometry2D.h + INCLUDE FakeOdometry2D.h DEPENDS "TARGET YARP::YARP_math" + GENERATE_PARSER ) if(NOT SKIP_fakeOdometry2D) @@ -17,8 +18,10 @@ if(NOT SKIP_fakeOdometry2D) target_sources(yarp_fakeOdometry2D PRIVATE - fakeOdometry2D.h - fakeOdometry2D.cpp + FakeOdometry2D.h + FakeOdometry2D.cpp + FakeOdometry2D_ParamsParser.h + FakeOdometry2D_ParamsParser.cpp ) target_link_libraries(yarp_fakeOdometry2D diff --git a/src/devices/fake/fakeOdometry2D/fakeOdometry2D.cpp b/src/devices/fake/fakeOdometry2D/FakeOdometry2D.cpp similarity index 87% rename from src/devices/fake/fakeOdometry2D/fakeOdometry2D.cpp rename to src/devices/fake/fakeOdometry2D/FakeOdometry2D.cpp index b877213b7dc..bd782778670 100644 --- a/src/devices/fake/fakeOdometry2D/fakeOdometry2D.cpp +++ b/src/devices/fake/fakeOdometry2D/FakeOdometry2D.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "fakeOdometry2D.h" +#include "FakeOdometry2D.h" #include #include @@ -53,14 +53,10 @@ void FakeOdometry2D::threadRelease() bool FakeOdometry2D::open(yarp::os::Searchable& config) { - // check period - if (!config.check("period", "refresh period of the broadcasted values in s")) { - yCInfo(FAKEODOMETRY2D) << "Using default 'period' parameter"; - } else { - m_period = config.find("period").asFloat64(); - } - yCInfo(FAKEODOMETRY2D) << "thread period set to " << m_period << "s"; - PeriodicThread::setPeriod(m_period); + if (!this->parseParams(config)) {return false;} + + setPeriod(m_period); + return PeriodicThread::start(); } diff --git a/src/devices/fake/fakeOdometry2D/FakeOdometry2D.h b/src/devices/fake/fakeOdometry2D/FakeOdometry2D.h new file mode 100644 index 00000000000..e01dcf7e7ea --- /dev/null +++ b/src/devices/fake/fakeOdometry2D/FakeOdometry2D.h @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef YARP_FAKEODOMETRY2D_H +#define YARP_FAKEODOMETRY2D_H + +#include +#include +#include +#include + +#include "FakeOdometry2D_ParamsParser.h" + +constexpr double default_period = 0.02; + +/** + * @ingroup dev_impl_fake dev_impl_navigation + * + * \section fakeOdometry_parameters Device description + * \brief `fakeOdometry2D`: A device for generating a fake odometry. + * This device will generate the odometry and then the user can retrieve it by calling `getOdometry`. + * + * Parameters required by this device are shown in class: FakeOdometry2D_ParamsParser + * + */ + +class FakeOdometry2D : + public yarp::os::PeriodicThread, + public yarp::dev::DeviceDriver, + public yarp::dev::Nav2D::IOdometry2D, + public FakeOdometry2D_ParamsParser +{ +public: + FakeOdometry2D(); + + // PeriodicThread + virtual bool threadInit() override; + virtual void threadRelease() override; + virtual void run() override; + + // DeviceDriver + bool open(yarp::os::Searchable& config) override; + bool close() override; + + // IOdometry2D + bool getOdometry(yarp::dev::OdometryData& odom, double* timestamp=nullptr) override; + bool resetOdometry() override; + +private: + yarp::dev::OdometryData m_odometryData; + + std::mutex m_odometry_mutex; + double m_period; + double m_timestamp=0; +}; + +#endif // YARP_FAKEODOMETRY2D_H diff --git a/src/devices/fake/fakeOdometry2D/FakeOdometry2D_ParamsParser.cpp b/src/devices/fake/fakeOdometry2D/FakeOdometry2D_ParamsParser.cpp new file mode 100644 index 00000000000..13d5e2ff13c --- /dev/null +++ b/src/devices/fake/fakeOdometry2D/FakeOdometry2D_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#include "FakeOdometry2D_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeOdometry2DParamsCOMPONENT, "yarp.device.FakeOdometry2D") +} + + +FakeOdometry2D_ParamsParser::FakeOdometry2D_ParamsParser() +{ +} + + +std::vector FakeOdometry2D_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("period"); + return params; +} + + +bool FakeOdometry2D_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeOdometry2DParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asFloat64(); + yCInfo(FakeOdometry2DParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakeOdometry2DParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeOdometry2DParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeOdometry2DParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeOdometry2D_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeOdometry2D\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'period': thread period\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeOdometry2D --period 0.02\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeOdometry2D\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeOdometry2D/FakeOdometry2D_ParamsParser.h b/src/devices/fake/fakeOdometry2D/FakeOdometry2D_ParamsParser.h new file mode 100644 index 00000000000..a5163c27345 --- /dev/null +++ b/src/devices/fake/fakeOdometry2D/FakeOdometry2D_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#ifndef FAKEODOMETRY2D_PARAMSPARSER_H +#define FAKEODOMETRY2D_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeOdometry2D. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-------------:|:----------------------:| +* | - | period | double | s | 0.02 | 0 | thread period | optional, default 1.0s | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeOdometry2D --period 0.02 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeOdometry2D +* \endcode +* +*/ + +class FakeOdometry2D_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeOdometry2D_ParamsParser(); + ~FakeOdometry2D_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeOdometry2D"}; + const std::string m_device_name = {"fakeOdometry2D"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_period_defaultValue = {"0.02"}; + + double m_period = {0.02}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeOdometry2D/FakeOdometry2D_params.md b/src/devices/fake/fakeOdometry2D/FakeOdometry2D_params.md new file mode 100644 index 00000000000..acaec3aba8c --- /dev/null +++ b/src/devices/fake/fakeOdometry2D/FakeOdometry2D_params.md @@ -0,0 +1 @@ + * | | period | double | s | 0.02 | No | thread period | optional, default 1.0s | diff --git a/src/devices/fake/fakeOdometry2D/fakeOdometry2D.h b/src/devices/fake/fakeOdometry2D/fakeOdometry2D.h deleted file mode 100644 index f916e6a3e96..00000000000 --- a/src/devices/fake/fakeOdometry2D/fakeOdometry2D.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef YARP_FAKEODOMETRY2D_H -#define YARP_FAKEODOMETRY2D_H - -#include -#include -#include -#include - -constexpr double default_period = 0.02; - -/** - * @ingroup dev_impl_fake dev_impl_navigation - * - * \section fakeOdometry_parameters Device description - * \brief `fakeOdometry2D`: A device for generating a fake odometry. - * This device will generate the odometry and then the user can retrieve it by calling `getOdometry`. - * - * Parameters required by this device are: - * | Parameter name | SubParameter | Type | Units | Default Value | Required | Description | Notes | - * |:--------------:|:-----------------------:|:-------:|:--------------:|:-------------:|:-----------------------------: |:---------------------------------------------------------------------------------------------------:|:-----:| - * | period | - | double | s | 0.02 | No | refresh period of the broadcasted values in s | default 0.02s | - * - * Example of configuration file using .ini format. - * - * \code{.unparsed} - * device FakeOdometry - * period 0.02 - * \endcode - * - * example of xml file - * - * \code{.unparsed} - * - * - * - * - * - * - * - * - * \endcode - * - * example of command via terminal. - * - * \code{.unparsed} - * yarpdev --device fakeOdometry - * \endcode - */ - -class FakeOdometry2D : - public yarp::os::PeriodicThread, - public yarp::dev::DeviceDriver, - public yarp::dev::Nav2D::IOdometry2D -{ -public: - FakeOdometry2D(); - - // PeriodicThread - virtual bool threadInit() override; - virtual void threadRelease() override; - virtual void run() override; - - // DeviceDriver - bool open(yarp::os::Searchable& config) override; - bool close() override; - - // IOdometry2D - bool getOdometry(yarp::dev::OdometryData& odom, double* timestamp=nullptr) override; - bool resetOdometry() override; - -private: - yarp::dev::OdometryData m_odometryData; - - std::mutex m_odometry_mutex; - double m_period; - double m_timestamp=0; -}; - -#endif // YARP_FAKEODOMETRY2D_H diff --git a/src/devices/fake/fakePositionSensor/CMakeLists.txt b/src/devices/fake/fakePositionSensor/CMakeLists.txt index 416485afc32..29c75d7976a 100644 --- a/src/devices/fake/fakePositionSensor/CMakeLists.txt +++ b/src/devices/fake/fakePositionSensor/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakePositionSensor CATEGORY device TYPE FakePositionSensor - INCLUDE fakePositionSensor.h + INCLUDE FakePositionSensor.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=multipleanalogsensorsserver ) @@ -18,8 +19,10 @@ if(ENABLE_fakePositionSensor) target_sources(yarp_fakePositionSensor PRIVATE - fakePositionSensor.cpp - fakePositionSensor.h + FakePositionSensor.cpp + FakePositionSensor.h + FakePositionSensor_ParamsParser.cpp + FakePositionSensor_ParamsParser.h ) target_link_libraries(yarp_fakePositionSensor diff --git a/src/devices/fake/fakePositionSensor/fakePositionSensor.cpp b/src/devices/fake/fakePositionSensor/FakePositionSensor.cpp similarity index 91% rename from src/devices/fake/fakePositionSensor/fakePositionSensor.cpp rename to src/devices/fake/fakePositionSensor/FakePositionSensor.cpp index 1345cbdb851..ab6d0b51920 100644 --- a/src/devices/fake/fakePositionSensor/fakePositionSensor.cpp +++ b/src/devices/fake/fakePositionSensor/FakePositionSensor.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakePositionSensor.h" +#include "FakePositionSensor.h" #include #include @@ -29,23 +29,9 @@ FakePositionSensor::~FakePositionSensor() bool FakePositionSensor::open(yarp::os::Searchable& config) { - yCTrace(FAKE_POSITION_SENSOR); - bool correct=true; - - //debug - fprintf(stderr, "%s\n", config.toString().c_str()); + if (!this->parseParams(config)) {return false;} - if (!correct) - { - yCError(FAKE_POSITION_SENSOR) << "Insufficient parameters to FakePositionSensor\n"; - return false; - } - - if (config.check("sensor_period")) - { - double period=config.find("sensor_period").asFloat32(); - setPeriod(period); - } + setPeriod(m_period); //create the data vector: this->m_channelsNum = 1; diff --git a/src/devices/fake/fakePositionSensor/fakePositionSensor.h b/src/devices/fake/fakePositionSensor/FakePositionSensor.h similarity index 86% rename from src/devices/fake/fakePositionSensor/fakePositionSensor.h rename to src/devices/fake/fakePositionSensor/FakePositionSensor.h index c2d9d378693..9c75e326def 100644 --- a/src/devices/fake/fakePositionSensor/fakePositionSensor.h +++ b/src/devices/fake/fakePositionSensor/FakePositionSensor.h @@ -13,23 +13,23 @@ #include +#include "FakePositionSensor_ParamsParser.h" + /** * * @ingroup dev_impl_fake dev_impl_media dev_impl_analog_sensors * * \brief `fakePositionSensor`: Fake position sensor device for testing purpose and reference for new similar devices * -* Parameters accepted in the config argument of the open method: -* | Parameter name | Type | Units | Default Value | Required | Description | Notes | -* |:--------------:|:------:|:-------:|:-------------:|:--------:|:-----------:|:-----:| -* | sensor_period | double | seconds | 0.01 | No | Period over which the measurement is updated. | | +* Parameters required by this device are shown in class: FakePositionSensor_ParamsParser */ class FakePositionSensor : public yarp::dev::DeviceDriver, public yarp::os::PeriodicThread, public yarp::dev::IPositionSensors, - public yarp::dev::IOrientationSensors + public yarp::dev::IOrientationSensors, + public FakePositionSensor_ParamsParser { private: diff --git a/src/devices/fake/fakePositionSensor/FakePositionSensor_ParamsParser.cpp b/src/devices/fake/fakePositionSensor/FakePositionSensor_ParamsParser.cpp new file mode 100644 index 00000000000..dcfad377166 --- /dev/null +++ b/src/devices/fake/fakePositionSensor/FakePositionSensor_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#include "FakePositionSensor_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakePositionSensorParamsCOMPONENT, "yarp.device.FakePositionSensor") +} + + +FakePositionSensor_ParamsParser::FakePositionSensor_ParamsParser() +{ +} + + +std::vector FakePositionSensor_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("period"); + return params; +} + + +bool FakePositionSensor_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakePositionSensorParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asFloat64(); + yCInfo(FakePositionSensorParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakePositionSensorParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakePositionSensorParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakePositionSensorParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakePositionSensor_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakePositionSensor\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'period': thread period\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakePositionSensor --period 0.01\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakePositionSensor\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakePositionSensor/FakePositionSensor_ParamsParser.h b/src/devices/fake/fakePositionSensor/FakePositionSensor_ParamsParser.h new file mode 100644 index 00000000000..f5c000e6002 --- /dev/null +++ b/src/devices/fake/fakePositionSensor/FakePositionSensor_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#ifndef FAKEPOSITIONSENSOR_PARAMSPARSER_H +#define FAKEPOSITIONSENSOR_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakePositionSensor. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-------------:|:----------------------:| +* | - | period | double | s | 0.01 | 0 | thread period | optional, default 1.0s | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakePositionSensor --period 0.01 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakePositionSensor +* \endcode +* +*/ + +class FakePositionSensor_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakePositionSensor_ParamsParser(); + ~FakePositionSensor_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakePositionSensor"}; + const std::string m_device_name = {"fakePositionSensor"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_period_defaultValue = {"0.01"}; + + double m_period = {0.01}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakePositionSensor/FakePositionSensor_params.md b/src/devices/fake/fakePositionSensor/FakePositionSensor_params.md new file mode 100644 index 00000000000..0b7e0f99cc0 --- /dev/null +++ b/src/devices/fake/fakePositionSensor/FakePositionSensor_params.md @@ -0,0 +1 @@ + * | | period | double | s | 0.01 | No | thread period | optional, default 1.0s | diff --git a/src/devices/fake/fakeSerialPort/CMakeLists.txt b/src/devices/fake/fakeSerialPort/CMakeLists.txt index 306504f2d02..adef79e6a4e 100644 --- a/src/devices/fake/fakeSerialPort/CMakeLists.txt +++ b/src/devices/fake/fakeSerialPort/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeSerialPort CATEGORY device TYPE FakeSerialPort - INCLUDE fakeSerialPort.h + INCLUDE FakeSerialPort.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=serialPort_nws_yarp) @@ -17,8 +18,10 @@ if(ENABLE_fakeSerialPort) target_sources(yarp_fakeSerialPort PRIVATE - fakeSerialPort.cpp - fakeSerialPort.h + FakeSerialPort.cpp + FakeSerialPort.h + FakeSerialPort_ParamsParser.cpp + FakeSerialPort_ParamsParser.h ) target_link_libraries(yarp_fakeSerialPort diff --git a/src/devices/fake/fakeSerialPort/FakeSerialPort.cpp b/src/devices/fake/fakeSerialPort/FakeSerialPort.cpp new file mode 100644 index 00000000000..c557fc41542 --- /dev/null +++ b/src/devices/fake/fakeSerialPort/FakeSerialPort.cpp @@ -0,0 +1,200 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "FakeSerialPort.h" + +#include +#include + +#include +#include + +using namespace yarp::os; +using namespace yarp::dev; + +namespace { +YARP_LOG_COMPONENT(FAKESERIALPORT, "yarp.device.FakeSerialPort") +} + +FakeSerialPort::FakeSerialPort() { +} + +FakeSerialPort::~FakeSerialPort() +{ + close(); +} + +bool FakeSerialPort::open(yarp::os::Searchable& config) +{ + if (!this->parseParams(config)) {return false;} + + return true; +} + +bool FakeSerialPort::close() +{ + return true; +} + +bool FakeSerialPort::setDTR(bool value) +{ + return true; +} + +bool FakeSerialPort::send(const Bottle& msg) +{ + if (msg.size() > 0) + { + int message_size = msg.get(0).asString().length(); + + if (message_size > 0) + { + if (verbose) + { + yCDebug(FAKESERIALPORT, "Sending string: %s", msg.get(0).asString().c_str()); + } + } + else + { + if (verbose) + { + yCDebug(FAKESERIALPORT, "The input command bottle contains an empty string."); + } + return false; + } + } + else + { + if (verbose) + { + yCDebug(FAKESERIALPORT, "The input command bottle is empty. \n"); + } + return false; + } + + return true; +} + +bool FakeSerialPort::send(const char *msg, size_t size) +{ + if (size > 0) + { + if (verbose) + { + yCDebug(FAKESERIALPORT, "Sending string: %s", msg); + } + + // Write message in the serial device + size_t bytes_written = size; + + if (bytes_written == -1) + { + yCError(FAKESERIALPORT, "Unable to write to serial port"); + return false; + } + } + else + { + if (verbose) { + yCDebug(FAKESERIALPORT, "The input message is empty. \n"); + } + return false; + } + + yCInfo (FAKESERIALPORT, "sent command: %s \n",msg); + return true; +} + +int FakeSerialPort::receiveChar(char& c) +{ + char chr='c'; + + size_t bytes_read = 1; + + if (bytes_read == -1) + { + yCError(FAKESERIALPORT, "Error in SerialDeviceDriver::receive()"); + return 0; + } + + if (bytes_read == 0) + { + return 0; + } + + c=chr; + return 1; +} + +int FakeSerialPort::flush() +{ + return 1; +} + +int FakeSerialPort::receiveBytes(unsigned char* bytes, const int size) +{ + for (size_t i=0; i< size; i++) + bytes[i]='0'+i; + return size; +} + +int FakeSerialPort::receiveLine(char* buffer, const int MaxLineLength) +{ + int i; + for (i = 0; i < MaxLineLength -1; ++i) + { + char recv_ch; + int n = receiveChar(recv_ch); + if (n <= 0) + { + //this invalidates the whole line, because no line terminator \n was found + return 0; + + //use this commented code here if you do NOT want to invalidate the line + //buffer[i] = '\0'; + //return i; + } + if ((recv_ch == m_line_terminator_char1) || (recv_ch == m_line_terminator_char2)) + { + buffer[i] = recv_ch; + i++; + break; + } + buffer[i] = recv_ch; + } + buffer[i] = '\0'; + return i; +} + +bool FakeSerialPort::receive(Bottle& msg) +{ + char message[10] = "123456789"; + + //this function call blocks + size_t bytes_read = 9; + + if (bytes_read == -1) + { + yCError(FAKESERIALPORT, "Error in SerialDeviceDriver::receive()"); + return false; + } + + if (bytes_read == 0) { //nothing there + return true; + } + + message[bytes_read] = 0; + + if (verbose) + { + yCDebug(FAKESERIALPORT, "Data received from serial device: %s", message); + } + + + // Put message in the bottle + msg.addString(message); + + return true; +} diff --git a/src/devices/fake/fakeSerialPort/FakeSerialPort.h b/src/devices/fake/fakeSerialPort/FakeSerialPort.h new file mode 100644 index 00000000000..208324c9127 --- /dev/null +++ b/src/devices/fake/fakeSerialPort/FakeSerialPort.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FAKESERIALPORT_H +#define FAKESERIALPORT_H + +#include +#include +#include + +#include + +#include "FakeSerialPort_ParamsParser.h" + +using namespace yarp::os; + +/** + * @ingroup dev_impl_other + * + * \brief `fakeSerialPort`: A fake basic Serial Communications Link (RS232, USB). + * + * Parameters required by this device are shown in class: FakeSerialPort_ParamsParser + * Beware: all parameters parsed by fakeSerialPort are actually ignored because it is a fake device + * which does not connect to any real hardware. + */ +class FakeSerialPort : + public yarp::dev::DeviceDriver, + public yarp::dev::ISerialDevice, + public FakeSerialPort_ParamsParser +{ +private: + FakeSerialPort(const FakeSerialPort&); + + bool verbose = true; + +public: + FakeSerialPort(); + + virtual ~FakeSerialPort(); + + bool open(yarp::os::Searchable& config) override; + bool close() override; + + bool send(const Bottle& msg) override; + bool send(const char *msg, size_t size) override; + bool receive(Bottle& msg) override; + int receiveChar(char& chr) override; + int receiveBytes(unsigned char* bytes, const int size) override; + int receiveLine(char* line, const int MaxLineLength) override; + bool setDTR(bool value) override; + int flush() override; +}; + +#endif diff --git a/src/devices/fake/fakeSerialPort/FakeSerialPort_ParamsParser.cpp b/src/devices/fake/fakeSerialPort/FakeSerialPort_ParamsParser.cpp new file mode 100644 index 00000000000..61f54cf7964 --- /dev/null +++ b/src/devices/fake/fakeSerialPort/FakeSerialPort_ParamsParser.cpp @@ -0,0 +1,411 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#include "FakeSerialPort_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeSerialPortParamsCOMPONENT, "yarp.device.FakeSerialPort") +} + + +FakeSerialPort_ParamsParser::FakeSerialPort_ParamsParser() +{ +} + + +std::vector FakeSerialPort_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("comport"); + params.push_back("verbose"); + params.push_back("baudrate"); + params.push_back("xonlim"); + params.push_back("xofflim"); + params.push_back("readmincharacters"); + params.push_back("readtimeoutmsec"); + params.push_back("paritymode"); + params.push_back("ctsenb"); + params.push_back("rtsenb"); + params.push_back("xinenb"); + params.push_back("xoutenb"); + params.push_back("modem"); + params.push_back("rcvenb"); + params.push_back("dsrenb"); + params.push_back("dtrdisable"); + params.push_back("databits"); + params.push_back("stopbits"); + params.push_back("line_terminator_char1"); + params.push_back("line_terminator_char2"); + return params; +} + + +bool FakeSerialPort_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeSerialPortParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter comport + { + if (config.check("comport")) + { + m_comport = config.find("comport").asString(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'comport' using value:" << m_comport; + } + else + { + yCError(FakeSerialPortParamsCOMPONENT) << "Mandatory parameter 'comport' not found!"; + yCError(FakeSerialPortParamsCOMPONENT) << "Description of the parameter: name of the serial channel"; + return false; + } + prop_check.unput("comport"); + } + + //Parser of parameter verbose + { + if (config.check("verbose")) + { + m_verbose = config.find("verbose").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'verbose' using value:" << m_verbose; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'verbose' using DEFAULT value:" << m_verbose; + } + prop_check.unput("verbose"); + } + + //Parser of parameter baudrate + { + if (config.check("baudrate")) + { + m_baudrate = config.find("baudrate").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'baudrate' using value:" << m_baudrate; + } + else + { + yCError(FakeSerialPortParamsCOMPONENT) << "Mandatory parameter 'baudrate' not found!"; + yCError(FakeSerialPortParamsCOMPONENT) << "Description of the parameter: Specifies the baudrate at which the communication port operates"; + return false; + } + prop_check.unput("baudrate"); + } + + //Parser of parameter xonlim + { + if (config.check("xonlim")) + { + m_xonlim = config.find("xonlim").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'xonlim' using value:" << m_xonlim; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'xonlim' using DEFAULT value:" << m_xonlim; + } + prop_check.unput("xonlim"); + } + + //Parser of parameter xofflim + { + if (config.check("xofflim")) + { + m_xofflim = config.find("xofflim").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'xofflim' using value:" << m_xofflim; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'xofflim' using DEFAULT value:" << m_xofflim; + } + prop_check.unput("xofflim"); + } + + //Parser of parameter readmincharacters + { + if (config.check("readmincharacters")) + { + m_readmincharacters = config.find("readmincharacters").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'readmincharacters' using value:" << m_readmincharacters; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'readmincharacters' using DEFAULT value:" << m_readmincharacters; + } + prop_check.unput("readmincharacters"); + } + + //Parser of parameter readtimeoutmsec + { + if (config.check("readtimeoutmsec")) + { + m_readtimeoutmsec = config.find("readtimeoutmsec").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'readtimeoutmsec' using value:" << m_readtimeoutmsec; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'readtimeoutmsec' using DEFAULT value:" << m_readtimeoutmsec; + } + prop_check.unput("readtimeoutmsec"); + } + + //Parser of parameter paritymode + { + if (config.check("paritymode")) + { + m_paritymode = config.find("paritymode").asString(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'paritymode' using value:" << m_paritymode; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'paritymode' using DEFAULT value:" << m_paritymode; + } + prop_check.unput("paritymode"); + } + + //Parser of parameter ctsenb + { + if (config.check("ctsenb")) + { + m_ctsenb = config.find("ctsenb").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'ctsenb' using value:" << m_ctsenb; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'ctsenb' using DEFAULT value:" << m_ctsenb; + } + prop_check.unput("ctsenb"); + } + + //Parser of parameter rtsenb + { + if (config.check("rtsenb")) + { + m_rtsenb = config.find("rtsenb").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'rtsenb' using value:" << m_rtsenb; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'rtsenb' using DEFAULT value:" << m_rtsenb; + } + prop_check.unput("rtsenb"); + } + + //Parser of parameter xinenb + { + if (config.check("xinenb")) + { + m_xinenb = config.find("xinenb").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'xinenb' using value:" << m_xinenb; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'xinenb' using DEFAULT value:" << m_xinenb; + } + prop_check.unput("xinenb"); + } + + //Parser of parameter xoutenb + { + if (config.check("xoutenb")) + { + m_xoutenb = config.find("xoutenb").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'xoutenb' using value:" << m_xoutenb; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'xoutenb' using DEFAULT value:" << m_xoutenb; + } + prop_check.unput("xoutenb"); + } + + //Parser of parameter modem + { + if (config.check("modem")) + { + m_modem = config.find("modem").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'modem' using value:" << m_modem; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'modem' using DEFAULT value:" << m_modem; + } + prop_check.unput("modem"); + } + + //Parser of parameter rcvenb + { + if (config.check("rcvenb")) + { + m_rcvenb = config.find("rcvenb").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'rcvenb' using value:" << m_rcvenb; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'rcvenb' using DEFAULT value:" << m_rcvenb; + } + prop_check.unput("rcvenb"); + } + + //Parser of parameter dsrenb + { + if (config.check("dsrenb")) + { + m_dsrenb = config.find("dsrenb").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'dsrenb' using value:" << m_dsrenb; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'dsrenb' using DEFAULT value:" << m_dsrenb; + } + prop_check.unput("dsrenb"); + } + + //Parser of parameter dtrdisable + { + if (config.check("dtrdisable")) + { + m_dtrdisable = config.find("dtrdisable").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'dtrdisable' using value:" << m_dtrdisable; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'dtrdisable' using DEFAULT value:" << m_dtrdisable; + } + prop_check.unput("dtrdisable"); + } + + //Parser of parameter databits + { + if (config.check("databits")) + { + m_databits = config.find("databits").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'databits' using value:" << m_databits; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'databits' using DEFAULT value:" << m_databits; + } + prop_check.unput("databits"); + } + + //Parser of parameter stopbits + { + if (config.check("stopbits")) + { + m_stopbits = config.find("stopbits").asInt64(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'stopbits' using value:" << m_stopbits; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'stopbits' using DEFAULT value:" << m_stopbits; + } + prop_check.unput("stopbits"); + } + + //Parser of parameter line_terminator_char1 + { + if (config.check("line_terminator_char1")) + { + m_line_terminator_char1 = config.find("line_terminator_char1").asInt8(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'line_terminator_char1' using value:" << m_line_terminator_char1; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'line_terminator_char1' using DEFAULT value:" << m_line_terminator_char1; + } + prop_check.unput("line_terminator_char1"); + } + + //Parser of parameter line_terminator_char2 + { + if (config.check("line_terminator_char2")) + { + m_line_terminator_char2 = config.find("line_terminator_char2").asInt8(); + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'line_terminator_char2' using value:" << m_line_terminator_char2; + } + else + { + yCInfo(FakeSerialPortParamsCOMPONENT) << "Parameter 'line_terminator_char2' using DEFAULT value:" << m_line_terminator_char2; + } + prop_check.unput("line_terminator_char2"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeSerialPortParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeSerialPortParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeSerialPort_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeSerialPort\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'comport': name of the serial channel\n"); + doc = doc + std::string("'verbose': Specifies if the device is in verbose mode (0/1)\n"); + doc = doc + std::string("'baudrate': Specifies the baudrate at which the communication port operates\n"); + doc = doc + std::string("'xonlim': Specifies the minimum number of bytes in input buffer before XON char is sent\n"); + doc = doc + std::string("'xofflim': Specifies the maximum number of bytes in input buffer before XOFF char is sent\n"); + doc = doc + std::string("'readmincharacters': Specifies the minimum number of characters for non-canonical read (POSIX)\n"); + doc = doc + std::string("'readtimeoutmsec': Specifies the time to wait before returning from read. Negative value means infinite timeout\n"); + doc = doc + std::string("'paritymode': Specifies the parity mode (EVEN, ODD, NONE\n"); + doc = doc + std::string("'ctsenb': Enable & set CTS mode\n"); + doc = doc + std::string("'rtsenb': Enable & set RTS mode\n"); + doc = doc + std::string("'xinenb': Enable/disable software flow control on input\n"); + doc = doc + std::string("'xoutenb': Enable/disable software flow control on output.\n"); + doc = doc + std::string("'modem': Specifies if device is a modem (POSIX). If not set modem status lines are ignored.\n"); + doc = doc + std::string("'rcvenb': Enable/disable receiver (POSIX).\n"); + doc = doc + std::string("'dsrenb': Controls whether DSR is disabled or enabled (Win32).\n"); + doc = doc + std::string("'dtrdisable': Controls whether DTR is disabled or enabled\n"); + doc = doc + std::string("'databits': Data bits. Valid values 5, 6, 7 and 8 data bits. Additionally Win32 supports 4 data bits.\n"); + doc = doc + std::string("'stopbits': Stop bits. Valid values are 1 and 2.\n"); + doc = doc + std::string("'line_terminator_char1': line terminator character for receiveLine()\n"); + doc = doc + std::string("'line_terminator_char2': line terminator character for receiveLine()\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeSerialPort --comport COM3 --verbose 1 --baudrate 9600 --xonlim 0 --xofflim 0 --readmincharacters 1 --readtimeoutmsec 100 --paritymode EVEN --ctsenb 0 --rtsenb 0 --xinenb 0 --xoutenb 0 --modem 0 --rcvenb 0 --dsrenb 0 --dtrdisable 0 --databits 7 --stopbits 1 --line_terminator_char1 '\r' --line_terminator_char2 '\n'\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeSerialPort --comport COM3 --baudrate 9600\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeSerialPort/FakeSerialPort_ParamsParser.h b/src/devices/fake/fakeSerialPort/FakeSerialPort_ParamsParser.h new file mode 100644 index 00000000000..ad1d4085fc5 --- /dev/null +++ b/src/devices/fake/fakeSerialPort/FakeSerialPort_ParamsParser.h @@ -0,0 +1,126 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#ifndef FAKESERIALPORT_PARAMSPARSER_H +#define FAKESERIALPORT_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeSerialPort. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:---------------------:|:------:|:-----:|:-------------:|:--------:|:--------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +* | - | comport | string | - | COM3 | 1 | name of the serial channel | optional, default 1.0s | +* | - | verbose | int | - | 1 | 0 | Specifies if the device is in verbose mode (0/1) | optional, default 1.0s | +* | - | baudrate | int | - | 9600 | 1 | Specifies the baudrate at which the communication port operates | optional, default 1.0s | +* | - | xonlim | int | - | 0 | 0 | Specifies the minimum number of bytes in input buffer before XON char is sent | Negative value indicates that default value should be used (Win32) | +* | - | xofflim | int | - | 0 | 0 | Specifies the maximum number of bytes in input buffer before XOFF char is sent | Negative value indicates that default value should be used (Win32) | +* | - | readmincharacters | int | ms | 1 | 0 | Specifies the minimum number of characters for non-canonical read (POSIX) | BEWARE: the exit condition for recv() function is readmincharacters && readtimeoutmsec. | +* | - | readtimeoutmsec | int | ms | 100 | 0 | Specifies the time to wait before returning from read. Negative value means infinite timeout | BEWARE: the exit condition for recv() function is readmincharacters && readtimeoutmsec. | +* | - | paritymode | string | - | EVEN | 0 | Specifies the parity mode (EVEN, ODD, NONE | POSIX supports even and odd parity. Additionally Win32 supports mark and space parity modes | +* | - | ctsenb | int | - | 0 | 0 | Enable & set CTS mode | RTS & CTS are enabled/disabled together on some systems | +* | - | rtsenb | int | - | 0 | 0 | Enable & set RTS mode | RTS & CTS are enabled/disabled together on some systems. 0 = Disable RTS. 1 = Enable RTS. 2 = Enable RTS flow-control handshaking (Win32). 3 = Specifies that RTS line will be high if bytes are available for transmission. After transmission RTS will be low (Win32) | +* | - | xinenb | int | - | 0 | 0 | Enable/disable software flow control on input | - | +* | - | xoutenb | int | - | 0 | 0 | Enable/disable software flow control on output. | - | +* | - | modem | int | - | 0 | 0 | Specifies if device is a modem (POSIX). If not set modem status lines are ignored. | - | +* | - | rcvenb | int | - | 0 | 0 | Enable/disable receiver (POSIX). | - | +* | - | dsrenb | int | - | 0 | 0 | Controls whether DSR is disabled or enabled (Win32). | - | +* | - | dtrdisable | int | - | 0 | 0 | Controls whether DTR is disabled or enabled | - | +* | - | databits | int | s | 7 | 0 | Data bits. Valid values 5, 6, 7 and 8 data bits. Additionally Win32 supports 4 data bits. | - | +* | - | stopbits | int | s | 1 | 0 | Stop bits. Valid values are 1 and 2. | - | +* | - | line_terminator_char1 | char | - | '\r' | 0 | line terminator character for receiveLine() | - | +* | - | line_terminator_char2 | char | - | '\n' | 0 | line terminator character for receiveLine() | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeSerialPort --comport COM3 --verbose 1 --baudrate 9600 --xonlim 0 --xofflim 0 --readmincharacters 1 --readtimeoutmsec 100 --paritymode EVEN --ctsenb 0 --rtsenb 0 --xinenb 0 --xoutenb 0 --modem 0 --rcvenb 0 --dsrenb 0 --dtrdisable 0 --databits 7 --stopbits 1 --line_terminator_char1 '\r' --line_terminator_char2 '\n' +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeSerialPort --comport COM3 --baudrate 9600 +* \endcode +* +*/ + +class FakeSerialPort_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeSerialPort_ParamsParser(); + ~FakeSerialPort_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeSerialPort"}; + const std::string m_device_name = {"fakeSerialPort"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_comport_defaultValue = {"COM3"}; + const std::string m_verbose_defaultValue = {"1"}; + const std::string m_baudrate_defaultValue = {"9600"}; + const std::string m_xonlim_defaultValue = {"0"}; + const std::string m_xofflim_defaultValue = {"0"}; + const std::string m_readmincharacters_defaultValue = {"1"}; + const std::string m_readtimeoutmsec_defaultValue = {"100"}; + const std::string m_paritymode_defaultValue = {"EVEN"}; + const std::string m_ctsenb_defaultValue = {"0"}; + const std::string m_rtsenb_defaultValue = {"0"}; + const std::string m_xinenb_defaultValue = {"0"}; + const std::string m_xoutenb_defaultValue = {"0"}; + const std::string m_modem_defaultValue = {"0"}; + const std::string m_rcvenb_defaultValue = {"0"}; + const std::string m_dsrenb_defaultValue = {"0"}; + const std::string m_dtrdisable_defaultValue = {"0"}; + const std::string m_databits_defaultValue = {"7"}; + const std::string m_stopbits_defaultValue = {"1"}; + const std::string m_line_terminator_char1_defaultValue = {"'\r'"}; + const std::string m_line_terminator_char2_defaultValue = {"'\n'"}; + + std::string m_comport = {"COM3"}; + int m_verbose = {1}; + int m_baudrate = {9600}; + int m_xonlim = {0}; + int m_xofflim = {0}; + int m_readmincharacters = {1}; + int m_readtimeoutmsec = {100}; + std::string m_paritymode = {"EVEN"}; + int m_ctsenb = {0}; + int m_rtsenb = {0}; + int m_xinenb = {0}; + int m_xoutenb = {0}; + int m_modem = {0}; + int m_rcvenb = {0}; + int m_dsrenb = {0}; + int m_dtrdisable = {0}; + int m_databits = {7}; + int m_stopbits = {1}; + char m_line_terminator_char1 = {'\r'}; + char m_line_terminator_char2 = {'\n'}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeSerialPort/FakeSerialPort_params.md b/src/devices/fake/fakeSerialPort/FakeSerialPort_params.md new file mode 100644 index 00000000000..edfa46e732d --- /dev/null +++ b/src/devices/fake/fakeSerialPort/FakeSerialPort_params.md @@ -0,0 +1,20 @@ + * | | comport | string | | COM3 | Yes | name of the serial channel | optional, default 1.0s | + * | | verbose | int | - | 1 | No | Specifies if the device is in verbose mode (0/1) | optional, default 1.0s | + * | | baudrate | int | - | 9600 | Yes | Specifies the baudrate at which the communication port operates | optional, default 1.0s | + * | | xonlim | int | - | 0 | No | Specifies the minimum number of bytes in input buffer before XON char is sent | Negative value indicates that default value should be used (Win32)| + * | | xofflim | int | - | 0 | No | Specifies the maximum number of bytes in input buffer before XOFF char is sent | Negative value indicates that default value should be used (Win32)| + * | | readmincharacters | int | ms | 1 | No | Specifies the minimum number of characters for non-canonical read (POSIX) | BEWARE: the exit condition for recv() function is readmincharacters && readtimeoutmsec.| + * | | readtimeoutmsec | int | ms | 100 | No | Specifies the time to wait before returning from read. Negative value means infinite timeout | BEWARE: the exit condition for recv() function is readmincharacters && readtimeoutmsec.| + * | | paritymode | string | - | EVEN | No | Specifies the parity mode (EVEN, ODD, NONE | POSIX supports even and odd parity. Additionally Win32 supports mark and space parity modes | + * | | ctsenb | int | - | 0 | No | Enable & set CTS mode | RTS & CTS are enabled/disabled together on some systems | + * | | rtsenb | int | - | 0 | No | Enable & set RTS mode | RTS & CTS are enabled/disabled together on some systems. 0 = Disable RTS. 1 = Enable RTS. 2 = Enable RTS flow-control handshaking (Win32). 3 = Specifies that RTS line will be high if bytes are available for transmission. After transmission RTS will be low (Win32) | + * | | xinenb | int | - | 0 | No | Enable/disable software flow control on input | | + * | | xoutenb | int | - | 0 | No | Enable/disable software flow control on output. | | + * | | modem | int | - | 0 | No | Specifies if device is a modem (POSIX). If not set modem status lines are ignored. | | + * | | rcvenb | int | - | 0 | No | Enable/disable receiver (POSIX). | | + * | | dsrenb | int | - | 0 | No | Controls whether DSR is disabled or enabled (Win32). | | + * | | dtrdisable | int | - | 0 | No | Controls whether DTR is disabled or enabled | | + * | | databits | int | s | 7 | No | Data bits. Valid values 5, 6, 7 and 8 data bits. Additionally Win32 supports 4 data bits. | | + * | | stopbits | int | s | 1 | No | Stop bits. Valid values are 1 and 2. | | + * | | line_terminator_char1 | char | - | '\r' | No | line terminator character for receiveLine() | | + * | | line_terminator_char2 | char | - | '\n' | No | line terminator character for receiveLine() | | diff --git a/src/devices/fake/fakeSerialPort/fakeSerialPort.cpp b/src/devices/fake/fakeSerialPort/fakeSerialPort.cpp deleted file mode 100644 index df2a24d5473..00000000000 --- a/src/devices/fake/fakeSerialPort/fakeSerialPort.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fakeSerialPort.h" - -#include -#include - -#include -#include - -using namespace yarp::os; -using namespace yarp::dev; - -namespace { -YARP_LOG_COMPONENT(FAKESERIALPORT, "yarp.device.FakeSerialPort") -} - -FakeSerialPort::FakeSerialPort() { - //system_resources = (SerialHandler*) new SerialHandler(); - line_terminator_char1 = '\r'; - line_terminator_char2 = '\n'; -} - -FakeSerialPort::~FakeSerialPort() -{ - close(); -} - -bool FakeSerialPort::open(yarp::os::Searchable& config) -{ -#if 0 - SerialDeviceDriverSettings config2; - strcpy(config2.CommChannel, config.check("comport",Value("COM3"),"name of the serial channel").asString().c_str()); - this->verbose = (config.check("verbose",Value(1),"Specifies if the device is in verbose mode (0/1).").asInt32())>0; - config2.SerialParams.baudrate = config.check("baudrate",Value(9600),"Specifies the baudrate at which the communication port operates.").asInt32(); - config2.SerialParams.xonlim = config.check("xonlim",Value(0),"Specifies the minimum number of bytes in input buffer before XON char is sent. Negative value indicates that default value should be used (Win32)").asInt32(); - config2.SerialParams.xofflim = config.check("xofflim",Value(0),"Specifies the maximum number of bytes in input buffer before XOFF char is sent. Negative value indicates that default value should be used (Win32). ").asInt32(); - //RANDAZ: as far as I undesrood, the exit condition for recv() function is NOT readmincharacters || readtimeoutmsec. It is readmincharacters && readtimeoutmsec. - //On Linux. if readmincharacters params is set !=0, recv() may still block even if readtimeoutmsec is expired. - //On Win32, for unknown reason, readmincharacters seems to be ignored, so recv () returns after readtimeoutmsec. Maybe readmincharacters is used if readtimeoutmsec is set to -1? - config2.SerialParams.readmincharacters = config.check("readmincharacters",Value(1),"Specifies the minimum number of characters for non-canonical read (POSIX).").asInt32(); - config2.SerialParams.readtimeoutmsec = config.check("readtimeoutmsec",Value(100),"Specifies the time to wait before returning from read. Negative value means infinite timeout.").asInt32(); - // config2.SerialParams.parityenb = config.check("parityenb",Value(0),"Enable/disable parity checking.").asInt32(); - std::string temp = config.check("paritymode",Value("EVEN"),"Specifies the parity mode (EVEN, ODD, NONE). POSIX supports even and odd parity. Additionally Win32 supports mark and space parity modes.").asString(); - config2.SerialParams.paritymode = temp.c_str(); - config2.SerialParams.ctsenb = config.check("ctsenb",Value(0),"Enable & set CTS mode. Note that RTS & CTS are enabled/disabled together on some systems (RTS/CTS is enabled if either ctsenb or rtsenb is set).").asInt32(); - config2.SerialParams.rtsenb = config.check("rtsenb",Value(0),"Enable & set RTS mode. Note that RTS & CTS are enabled/disabled together on some systems (RTS/CTS is enabled if either ctsenb or rtsenb is set).\n- 0 = Disable RTS.\n- 1 = Enable RTS.\n- 2 = Enable RTS flow-control handshaking (Win32).\n- 3 = Specifies that RTS line will be high if bytes are available for transmission.\nAfter transmission RTS will be low (Win32).").asInt32(); - config2.SerialParams.xinenb = config.check("xinenb",Value(0),"Enable/disable software flow control on input.").asInt32(); - config2.SerialParams.xoutenb = config.check("xoutenb",Value(0),"Enable/disable software flow control on output.").asInt32(); - config2.SerialParams.modem = config.check("modem",Value(0),"Specifies if device is a modem (POSIX). If not set modem status lines are ignored. ").asInt32(); - config2.SerialParams.rcvenb = config.check("rcvenb",Value(0),"Enable/disable receiver (POSIX).").asInt32(); - config2.SerialParams.dsrenb = config.check("dsrenb",Value(0),"Controls whether DSR is disabled or enabled (Win32).").asInt32(); - config2.SerialParams.dtrdisable = config.check("dtrdisable",Value(0),"Controls whether DTR is disabled or enabled.").asInt32(); - config2.SerialParams.databits = config.check("databits",Value(7),"Data bits. Valid values 5, 6, 7 and 8 data bits. Additionally Win32 supports 4 data bits.").asInt32(); - config2.SerialParams.stopbits = config.check("stopbits",Value(1),"Stop bits. Valid values are 1 and 2.").asInt32(); - - if (config.check("line_terminator_char1", "line terminator character for receiveLine(), default '\r'")) { - line_terminator_char1 = config.find("line_terminator_char1").asInt32(); - } - - if (config.check("line_terminator_char2", "line terminator character for receiveLine(), default '\n'")) { - line_terminator_char2 = config.find("line_terminator_char2").asInt32(); - } -#endif - return true; -} - -bool FakeSerialPort::close() -{ - return true; -} - -bool FakeSerialPort::setDTR(bool value) -{ - return true; -} - -bool FakeSerialPort::send(const Bottle& msg) -{ - if (msg.size() > 0) - { - int message_size = msg.get(0).asString().length(); - - if (message_size > 0) - { - if (verbose) - { - yCDebug(FAKESERIALPORT, "Sending string: %s", msg.get(0).asString().c_str()); - } - } - else - { - if (verbose) - { - yCDebug(FAKESERIALPORT, "The input command bottle contains an empty string."); - } - return false; - } - } - else - { - if (verbose) - { - yCDebug(FAKESERIALPORT, "The input command bottle is empty. \n"); - } - return false; - } - - return true; -} - -bool FakeSerialPort::send(const char *msg, size_t size) -{ - if (size > 0) - { - if (verbose) - { - yCDebug(FAKESERIALPORT, "Sending string: %s", msg); - } - - // Write message in the serial device - size_t bytes_written = size; - - if (bytes_written == -1) - { - yCError(FAKESERIALPORT, "Unable to write to serial port"); - return false; - } - } - else - { - if (verbose) { - yCDebug(FAKESERIALPORT, "The input message is empty. \n"); - } - return false; - } - - yCInfo (FAKESERIALPORT, "sent command: %s \n",msg); - return true; -} - -int FakeSerialPort::receiveChar(char& c) -{ - char chr='c'; - - size_t bytes_read = 1; - - if (bytes_read == -1) - { - yCError(FAKESERIALPORT, "Error in SerialDeviceDriver::receive()"); - return 0; - } - - if (bytes_read == 0) - { - return 0; - } - - c=chr; - return 1; -} - -int FakeSerialPort::flush() -{ - return 1; -} - -int FakeSerialPort::receiveBytes(unsigned char* bytes, const int size) -{ - for (size_t i=0; i< size; i++) - bytes[i]='0'+i; - return size; -} - -int FakeSerialPort::receiveLine(char* buffer, const int MaxLineLength) -{ - int i; - for (i = 0; i < MaxLineLength -1; ++i) - { - char recv_ch; - int n = receiveChar(recv_ch); - if (n <= 0) - { - //this invalidates the whole line, because no line terminator \n was found - return 0; - - //use this commented code here if you do NOT want to invalidate the line - //buffer[i] = '\0'; - //return i; - } - if ((recv_ch == line_terminator_char1) || (recv_ch == line_terminator_char2)) - { - buffer[i] = recv_ch; - i++; - break; - } - buffer[i] = recv_ch; - } - buffer[i] = '\0'; - return i; -} - -bool FakeSerialPort::receive(Bottle& msg) -{ - char message[10] = "123456789"; - - //this function call blocks - size_t bytes_read = 9; - - if (bytes_read == -1) - { - yCError(FAKESERIALPORT, "Error in SerialDeviceDriver::receive()"); - return false; - } - - if (bytes_read == 0) { //nothing there - return true; - } - - message[bytes_read] = 0; - - if (verbose) - { - yCDebug(FAKESERIALPORT, "Data received from serial device: %s", message); - } - - - // Put message in the bottle - msg.addString(message); - - return true; -} diff --git a/src/devices/fake/fakeSerialPort/fakeSerialPort.h b/src/devices/fake/fakeSerialPort/fakeSerialPort.h deleted file mode 100644 index e0242348ae2..00000000000 --- a/src/devices/fake/fakeSerialPort/fakeSerialPort.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef FAKESERIALPORT_H -#define FAKESERIALPORT_H - -#include -#include -#include - -#include - -using namespace yarp::os; - -class SerialDeviceDriverSettings -{ -public: - char CommChannel[100]; // Contains the name of the com port "COM1", "COM2" (windows) or "/etc/stty0", "/dev/stty1" (linux), etc... - /** Serial_Params contains the following variables: */ - /** int baudrate; Specifies the baudrate at which the communication port operates. */ - /** int xonlim; Specifies the minimum number of bytes in input buffer before XON char - is sent. Negative value indicates that default value should - be used (Win32). */ - /** int xofflim; Specifies the maximum number of bytes in input buffer before XOFF char - is sent. Negative value indicates that default value should - be used (Win32). */ - /** unsigned int readmincharacters; Specifies the minimum number of characters for non-canonical - read (POSIX). */ - /** int readtimeoutmsec; Specifies the time to wait before returning from read. Negative value - means infinite timeout. */ - /** const char *paritymode; Specifies the parity mode (EVEN, ODD, NONE). POSIX supports "even" and "odd" parity. - Additionally Win32 supports "mark" and "space" parity modes. */ - /** bool ctsenb; Enable & set CTS mode. Note that RTS & CTS are enabled/disabled - together on some systems (RTS/CTS is enabled if either - ctsenb or rtsenb is set). */ - /** int rtsenb; Enable & set RTS mode. Note that RTS & CTS are enabled/disabled - together on some systems (RTS/CTS is enabled if either - ctsenb or rtsenb is set). - - 0 = Disable RTS. - - 1 = Enable RTS. - - 2 = Enable RTS flow-control handshaking (Win32). - - 3 = Specifies that RTS line will be high if bytes are available - for transmission. After transmission RTS will be low (Win32). */ - /** bool xinenb; Enable/disable software flow control on input. */ - /** bool xoutenb; Enable/disable software flow control on output. */ - /** bool modem; Specifies if device is a modem (POSIX). If not set modem status - lines are ignored. */ - /** bool rcvenb; Enable/disable receiver (POSIX). */ - /** bool dsrenb; Controls whether DSR is disabled or enabled (Win32). */ - /** bool dtrdisable; Controls whether DTR is disabled or enabled. */ - /** unsigned char databits; Data bits. Valid values 5, 6, 7 and 8 data bits. - Additionally Win32 supports 4 data bits. */ - /** unsigned char stopbits; Stop bits. Valid values are 1 and 2. */ -}; - -/** - * @ingroup dev_impl_other - * - * \brief `fakeSerialPort`: A fake basic Serial Communications Link (RS232, USB). - */ -class FakeSerialPort : - public yarp::dev::DeviceDriver, - public yarp::dev::ISerialDevice -{ -private: - FakeSerialPort(const FakeSerialPort&); - void operator=(const FakeSerialPort&); - - bool verbose = true; - char line_terminator_char1; - char line_terminator_char2; - -public: - FakeSerialPort(); - - virtual ~FakeSerialPort(); - - bool open(yarp::os::Searchable& config) override; - bool close() override; - - bool send(const Bottle& msg) override; - bool send(const char *msg, size_t size) override; - bool receive(Bottle& msg) override; - int receiveChar(char& chr) override; - int receiveBytes(unsigned char* bytes, const int size) override; - int receiveLine(char* line, const int MaxLineLength) override; - bool setDTR(bool value) override; - int flush() override; -}; - -#endif diff --git a/src/devices/fake/fakeSerialPort/tests/fakeSerialPort_test.cpp b/src/devices/fake/fakeSerialPort/tests/fakeSerialPort_test.cpp index 947cfb7e261..f97ee891842 100644 --- a/src/devices/fake/fakeSerialPort/tests/fakeSerialPort_test.cpp +++ b/src/devices/fake/fakeSerialPort/tests/fakeSerialPort_test.cpp @@ -31,6 +31,8 @@ TEST_CASE("dev::fakeSerialPort", "[yarp::dev]") Property pdev_cfg; pdev_cfg.put("device", "fakeSerialPort"); + pdev_cfg.put("comport", "fakePort"); + pdev_cfg.put("baudrate", 9600); REQUIRE(ddfake.open(pdev_cfg)); REQUIRE(ddfake.view(iser)); REQUIRE(iser); diff --git a/src/devices/fake/fakeSpeaker/CMakeLists.txt b/src/devices/fake/fakeSpeaker/CMakeLists.txt index d91bff703f6..fa8e489c6c8 100644 --- a/src/devices/fake/fakeSpeaker/CMakeLists.txt +++ b/src/devices/fake/fakeSpeaker/CMakeLists.txt @@ -7,8 +7,9 @@ endif() yarp_prepare_plugin(fakeSpeaker CATEGORY device - TYPE fakeSpeaker - INCLUDE fakeSpeaker.h + TYPE FakeSpeaker + INCLUDE FakeSpeaker.h + GENERATE_PARSER EXTRA_CONFIG WRAPPER=AudioPlayerWrapper ) @@ -18,8 +19,10 @@ if(NOT SKIP_fakeSpeaker) target_sources(yarp_fakeSpeaker PRIVATE - fakeSpeaker.cpp - fakeSpeaker.h + FakeSpeaker.cpp + FakeSpeaker.h + FakeSpeaker_ParamsParser.cpp + FakeSpeaker_ParamsParser.h ) target_link_libraries(yarp_fakeSpeaker diff --git a/src/devices/fake/fakeSpeaker/fakeSpeaker.cpp b/src/devices/fake/fakeSpeaker/FakeSpeaker.cpp similarity index 70% rename from src/devices/fake/fakeSpeaker/fakeSpeaker.cpp rename to src/devices/fake/fakeSpeaker/FakeSpeaker.cpp index 49b42754658..7af68e0c8fa 100644 --- a/src/devices/fake/fakeSpeaker/fakeSpeaker.cpp +++ b/src/devices/fake/fakeSpeaker/FakeSpeaker.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeSpeaker.h" +#include "FakeSpeaker.h" #include #include @@ -25,49 +25,34 @@ YARP_LOG_COMPONENT(FAKESPEAKER, "yarp.device.fakeSpeaker") typedef unsigned short int audio_sample_16t; -fakeSpeaker::fakeSpeaker() : +FakeSpeaker::FakeSpeaker() : PeriodicThread(c_DEFAULT_PERIOD) { } -fakeSpeaker::~fakeSpeaker() +FakeSpeaker::~FakeSpeaker() { close(); } -bool fakeSpeaker::open(yarp::os::Searchable &config) +bool FakeSpeaker::open(yarp::os::Searchable &config) { - if (config.check("help")) - { - yCInfo(FAKESPEAKER, "Some examples:"); - yCInfo(FAKESPEAKER, "yarpdev --device fakeSpeaker --help"); - yCInfo(FAKESPEAKER, "yarpdev --device AudioPlayerWrapper --subdevice fakeSpeaker --start"); - return false; - } + if (!this->parseParams(config)) {return false;} bool b = configurePlayerAudioDevice(config.findGroup("AUDIO_BASE"), "fakeSpeaker"); if (!b) { return false; } //sets the thread period - if( config.check("period")) - { - double period = config.find("period").asFloat64(); - setPeriod(period); - yCInfo(FAKESPEAKER) << "Using chosen period of " << period << " s"; - } - else - { - yCInfo(FAKESPEAKER) << "Using default period of " << c_DEFAULT_PERIOD << " s"; - } + setPeriod(m_period); //start the capture thread start(); return true; } -bool fakeSpeaker::close() +bool FakeSpeaker::close() { - fakeSpeaker::stop(); + FakeSpeaker::stop(); //wait until the thread is stopped... @@ -75,12 +60,12 @@ bool fakeSpeaker::close() } -bool fakeSpeaker::threadInit() +bool FakeSpeaker::threadInit() { return true; } -void fakeSpeaker::run() +void FakeSpeaker::run() { // when not playing, do nothing if (!m_playback_enabled) @@ -114,7 +99,7 @@ void fakeSpeaker::run() } } -bool fakeSpeaker::setHWGain(double gain) +bool FakeSpeaker::setHWGain(double gain) { std::lock_guard lock(m_mutex); if (gain > 0) @@ -125,13 +110,13 @@ bool fakeSpeaker::setHWGain(double gain) return false; } -bool fakeSpeaker::configureDeviceAndStart() +bool FakeSpeaker::configureDeviceAndStart() { yCError(FAKESPEAKER, "configureDeviceAndStart() Not yet implemented"); return true; } -bool fakeSpeaker::interruptDeviceAndClose() +bool FakeSpeaker::interruptDeviceAndClose() { yCError(FAKESPEAKER, "interruptDeviceAndClose() Not yet implemented"); return true; diff --git a/src/devices/fake/fakeSpeaker/FakeSpeaker.h b/src/devices/fake/fakeSpeaker/FakeSpeaker.h new file mode 100644 index 00000000000..7d8ed078b82 --- /dev/null +++ b/src/devices/fake/fakeSpeaker/FakeSpeaker.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FakeSpeaker_ParamsParser.h" + +/** +* @ingroup dev_impl_fake dev_impl_media +* +* \brief `fakeSpeaker` : fake device implementing the IAudioRender device interface to play sound +* +* This device driver derives from AudioPlayerDeviceBase base class. Please check its documentation for additional details. +* +* Parameters required by this device are shown in class: FakeMicrophone_ParamsParser +* This device also inherits some parameters from AudioPlayerDeviceBase +* +* See \ref AudioDoc for additional documentation on YARP audio. +*/ + +class FakeSpeaker : + public yarp::dev::DeviceDriver, + public yarp::dev::AudioPlayerDeviceBase, + public yarp::os::PeriodicThread, + public FakeSpeaker_ParamsParser +{ +public: + FakeSpeaker(); + FakeSpeaker(const FakeSpeaker&) = delete; + FakeSpeaker(FakeSpeaker&&) = delete; + FakeSpeaker& operator=(const FakeSpeaker&) = delete; + FakeSpeaker& operator=(FakeSpeaker&&) = delete; + ~FakeSpeaker() override; + + // Device Driver interface + bool open(yarp::os::Searchable &config) override; + bool close() override; + + //interface + virtual bool setHWGain(double gain) override; + virtual bool configureDeviceAndStart() override; + virtual bool interruptDeviceAndClose() override; + +private: + bool threadInit() override; + void run() override; +}; diff --git a/src/devices/fake/fakeSpeaker/FakeSpeaker_ParamsParser.cpp b/src/devices/fake/fakeSpeaker/FakeSpeaker_ParamsParser.cpp new file mode 100644 index 00000000000..003bafac09a --- /dev/null +++ b/src/devices/fake/fakeSpeaker/FakeSpeaker_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#include "FakeSpeaker_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeSpeakerParamsCOMPONENT, "yarp.device.FakeSpeaker") +} + + +FakeSpeaker_ParamsParser::FakeSpeaker_ParamsParser() +{ +} + + +std::vector FakeSpeaker_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("period"); + return params; +} + + +bool FakeSpeaker_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeSpeakerParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter period + { + if (config.check("period")) + { + m_period = config.find("period").asFloat64(); + yCInfo(FakeSpeakerParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; + } + else + { + yCInfo(FakeSpeakerParamsCOMPONENT) << "Parameter 'period' using DEFAULT value:" << m_period; + } + prop_check.unput("period"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeSpeakerParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeSpeakerParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeSpeaker_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeSpeaker\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'period': the period of processing thread\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeSpeaker --period 0.010\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeSpeaker\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeSpeaker/FakeSpeaker_ParamsParser.h b/src/devices/fake/fakeSpeaker/FakeSpeaker_ParamsParser.h new file mode 100644 index 00000000000..e978793cd2e --- /dev/null +++ b/src/devices/fake/fakeSpeaker/FakeSpeaker_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#ifndef FAKESPEAKER_PARAMSPARSER_H +#define FAKESPEAKER_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeSpeaker. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-------------------------------:|:---------------------------------------------------:| +* | - | period | double | s | 0.010 | 0 | the period of processing thread | A value of 10ms is recommended. Do to not modify it | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeSpeaker --period 0.010 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeSpeaker +* \endcode +* +*/ + +class FakeSpeaker_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeSpeaker_ParamsParser(); + ~FakeSpeaker_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeSpeaker"}; + const std::string m_device_name = {"fakeSpeaker"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_period_defaultValue = {"0.010"}; + + double m_period = {0.010}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeSpeaker/FakeSpeaker_params.md b/src/devices/fake/fakeSpeaker/FakeSpeaker_params.md new file mode 100644 index 00000000000..bc3dff952a3 --- /dev/null +++ b/src/devices/fake/fakeSpeaker/FakeSpeaker_params.md @@ -0,0 +1 @@ +* | | period | double | s | 0.010 | No | the period of processing thread | A value of 10ms is recommended. Do to not modify it | diff --git a/src/devices/fake/fakeSpeaker/fakeSpeaker.h b/src/devices/fake/fakeSpeaker/fakeSpeaker.h deleted file mode 100644 index 1a407eb5867..00000000000 --- a/src/devices/fake/fakeSpeaker/fakeSpeaker.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/** -* @ingroup dev_impl_fake dev_impl_media -* -* \brief `fakeSpeaker` : fake device implementing the IAudioRender device interface to play sound -* -* This device driver derives from AudioPlayerDeviceBase base class. Please check its documentation for additional details. -* -* Parameters used by this device are: -* | Parameter name | SubParameter | Type | Units | Default Value | Required | Description | Notes | -* |:----------------:|:--------------:|:-------:|:--------------:|:------------------------:|:--------------------------: |:-----------------------------------------------------------------:|:-----:| -* | AUDIO_BASE | *** | | - | - | No | For the documentation of AUDIO_BASE group, please refer to the documentation of the base class AudioPlayerDeviceBase | | -* | period | - | double | s | 0.010 | No | the period of processing thread | A value of 10ms is recommended. Do to not modify it | -* -* See \ref AudioDoc for additional documentation on YARP audio. -*/ - -class fakeSpeaker : - public yarp::dev::DeviceDriver, - public yarp::dev::AudioPlayerDeviceBase, - public yarp::os::PeriodicThread -{ -public: - fakeSpeaker(); - fakeSpeaker(const fakeSpeaker&) = delete; - fakeSpeaker(fakeSpeaker&&) = delete; - fakeSpeaker& operator=(const fakeSpeaker&) = delete; - fakeSpeaker& operator=(fakeSpeaker&&) = delete; - ~fakeSpeaker() override; - - // Device Driver interface - bool open(yarp::os::Searchable &config) override; - bool close() override; - - //interface - virtual bool setHWGain(double gain) override; - virtual bool configureDeviceAndStart() override; - virtual bool interruptDeviceAndClose() override; - -private: - bool threadInit() override; - void run() override; -}; diff --git a/src/devices/fake/fakeSpeechSynthesizer/CMakeLists.txt b/src/devices/fake/fakeSpeechSynthesizer/CMakeLists.txt index 19ef2e6e8d5..acab599cee8 100644 --- a/src/devices/fake/fakeSpeechSynthesizer/CMakeLists.txt +++ b/src/devices/fake/fakeSpeechSynthesizer/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeSpeechSynthesizer CATEGORY device TYPE FakeSpeechSynthesizer - INCLUDE fakeSpeechSynthesizer.h + INCLUDE FakeSpeechSynthesizer.h + GENERATE_PARSER ) if(ENABLE_fakeSpeechSynthesizer) @@ -16,8 +17,10 @@ if(ENABLE_fakeSpeechSynthesizer) target_sources(yarp_fakeSpeechSynthesizer PRIVATE - fakeSpeechSynthesizer.cpp - fakeSpeechSynthesizer.h + FakeSpeechSynthesizer.cpp + FakeSpeechSynthesizer.h + FakeSpeechSynthesizer_ParamsParser.cpp + FakeSpeechSynthesizer_ParamsParser.h ) target_link_libraries(yarp_fakeSpeechSynthesizer diff --git a/src/devices/fake/fakeSpeechSynthesizer/fakeSpeechSynthesizer.cpp b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer.cpp similarity index 95% rename from src/devices/fake/fakeSpeechSynthesizer/fakeSpeechSynthesizer.cpp rename to src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer.cpp index 758af163324..015467b2a83 100644 --- a/src/devices/fake/fakeSpeechSynthesizer/fakeSpeechSynthesizer.cpp +++ b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeSpeechSynthesizer.h" +#include "FakeSpeechSynthesizer.h" #include #include @@ -30,6 +30,8 @@ FakeSpeechSynthesizer::~FakeSpeechSynthesizer() bool FakeSpeechSynthesizer::open(yarp::os::Searchable& config) { + if (!this->parseParams(config)) {return false;} + return true; } diff --git a/src/devices/fake/fakeSpeechSynthesizer/fakeSpeechSynthesizer.h b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer.h similarity index 84% rename from src/devices/fake/fakeSpeechSynthesizer/fakeSpeechSynthesizer.h rename to src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer.h index 64ffe7b7ee0..c834c175526 100644 --- a/src/devices/fake/fakeSpeechSynthesizer/fakeSpeechSynthesizer.h +++ b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer.h @@ -11,23 +11,24 @@ #include #include +#include "FakeSpeechSynthesizer_ParamsParser.h" + using namespace yarp::os; /** - * @ingroup dev_impl_other + * @ingroup dev_impl_fake dev_impl_other * * \brief `FakeSpeechSynthesizer`: A fake implementation of a speech synthesizer plugin. + * + * Parameters required by this device are shown in class: FakeSpeechSynthesizer_ParamsParser */ class FakeSpeechSynthesizer : public yarp::dev::DeviceDriver, - public yarp::dev::ISpeechSynthesizer + public yarp::dev::ISpeechSynthesizer, + public FakeSpeechSynthesizer_ParamsParser { private: bool m_verbose = true; - std::string m_language = "auto"; - std::string m_voice = "auto"; - double m_pitch = 0; - double m_speed = 0; public: FakeSpeechSynthesizer(); diff --git a/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_ParamsParser.cpp b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_ParamsParser.cpp new file mode 100644 index 00000000000..f693f8b35d4 --- /dev/null +++ b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_ParamsParser.cpp @@ -0,0 +1,151 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#include "FakeSpeechSynthesizer_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeSpeechSynthesizerParamsCOMPONENT, "yarp.device.FakeSpeechSynthesizer") +} + + +FakeSpeechSynthesizer_ParamsParser::FakeSpeechSynthesizer_ParamsParser() +{ +} + + +std::vector FakeSpeechSynthesizer_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("language"); + params.push_back("voice"); + params.push_back("speed"); + params.push_back("pitch"); + return params; +} + + +bool FakeSpeechSynthesizer_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter language + { + if (config.check("language")) + { + m_language = config.find("language").asString(); + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << "Parameter 'language' using value:" << m_language; + } + else + { + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << "Parameter 'language' using DEFAULT value:" << m_language; + } + prop_check.unput("language"); + } + + //Parser of parameter voice + { + if (config.check("voice")) + { + m_voice = config.find("voice").asString(); + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << "Parameter 'voice' using value:" << m_voice; + } + else + { + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << "Parameter 'voice' using DEFAULT value:" << m_voice; + } + prop_check.unput("voice"); + } + + //Parser of parameter speed + { + if (config.check("speed")) + { + m_speed = config.find("speed").asFloat64(); + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << "Parameter 'speed' using value:" << m_speed; + } + else + { + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << "Parameter 'speed' using DEFAULT value:" << m_speed; + } + prop_check.unput("speed"); + } + + //Parser of parameter pitch + { + if (config.check("pitch")) + { + m_pitch = config.find("pitch").asFloat64(); + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << "Parameter 'pitch' using value:" << m_pitch; + } + else + { + yCInfo(FakeSpeechSynthesizerParamsCOMPONENT) << "Parameter 'pitch' using DEFAULT value:" << m_pitch; + } + prop_check.unput("pitch"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeSpeechSynthesizerParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeSpeechSynthesizerParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeSpeechSynthesizer_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeSpeechSynthesizer\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'language': language code\n"); + doc = doc + std::string("'voice': voice code\n"); + doc = doc + std::string("'speed': speed\n"); + doc = doc + std::string("'pitch': pitch\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeSpeechSynthesizer --language auto --voice auto --speed 0.0 --pitch 0.0\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeSpeechSynthesizer\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_ParamsParser.h b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_ParamsParser.h new file mode 100644 index 00000000000..dd0f4802dae --- /dev/null +++ b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_ParamsParser.h @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:31 2024 + + +#ifndef FAKESPEECHSYNTHESIZER_PARAMSPARSER_H +#define FAKESPEECHSYNTHESIZER_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeSpeechSynthesizer. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-------------:|:-----:| +* | - | language | string | - | auto | 0 | language code | - | +* | - | voice | string | - | auto | 0 | voice code | - | +* | - | speed | double | - | 0.0 | 0 | speed | - | +* | - | pitch | double | - | 0.0 | 0 | pitch | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeSpeechSynthesizer --language auto --voice auto --speed 0.0 --pitch 0.0 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeSpeechSynthesizer +* \endcode +* +*/ + +class FakeSpeechSynthesizer_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeSpeechSynthesizer_ParamsParser(); + ~FakeSpeechSynthesizer_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeSpeechSynthesizer"}; + const std::string m_device_name = {"fakeSpeechSynthesizer"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_language_defaultValue = {"auto"}; + const std::string m_voice_defaultValue = {"auto"}; + const std::string m_speed_defaultValue = {"0.0"}; + const std::string m_pitch_defaultValue = {"0.0"}; + + std::string m_language = {"auto"}; + std::string m_voice = {"auto"}; + double m_speed = {0.0}; + double m_pitch = {0.0}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_params.md b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_params.md new file mode 100644 index 00000000000..10296c1c28c --- /dev/null +++ b/src/devices/fake/fakeSpeechSynthesizer/FakeSpeechSynthesizer_params.md @@ -0,0 +1,4 @@ + * | | language | string | - | auto | No | language code | | + * | | voice | string | - | auto | No | voice code | | + * | | speed | double | - | 0.0 | No | speed | | + * | | pitch | double | - | 0.0 | No | pitch | | diff --git a/src/devices/fake/fakeSpeechTranscription/CMakeLists.txt b/src/devices/fake/fakeSpeechTranscription/CMakeLists.txt index 430e65844fa..6d184f00d0a 100644 --- a/src/devices/fake/fakeSpeechTranscription/CMakeLists.txt +++ b/src/devices/fake/fakeSpeechTranscription/CMakeLists.txt @@ -8,7 +8,8 @@ endif() yarp_prepare_plugin(fakeSpeechTranscription CATEGORY device TYPE FakeSpeechTranscription - INCLUDE fakeSpeechTranscription.h + INCLUDE FakeSpeechTranscription.h + GENERATE_PARSER ) if(ENABLE_fakeSpeechTranscription) @@ -16,8 +17,10 @@ if(ENABLE_fakeSpeechTranscription) target_sources(yarp_fakeSpeechTranscription PRIVATE - fakeSpeechTranscription.cpp - fakeSpeechTranscription.h + FakeSpeechTranscription.cpp + FakeSpeechTranscription.h + FakeSpeechTranscription_ParamsParser.cpp + FakeSpeechTranscription_ParamsParser.h ) target_link_libraries(yarp_fakeSpeechTranscription diff --git a/src/devices/fake/fakeSpeechTranscription/fakeSpeechTranscription.cpp b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription.cpp similarity index 93% rename from src/devices/fake/fakeSpeechTranscription/fakeSpeechTranscription.cpp rename to src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription.cpp index 4e0e991defa..c4ad43b87ba 100644 --- a/src/devices/fake/fakeSpeechTranscription/fakeSpeechTranscription.cpp +++ b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fakeSpeechTranscription.h" +#include "FakeSpeechTranscription.h" #include #include @@ -30,6 +30,8 @@ FakeSpeechTranscription::~FakeSpeechTranscription() bool FakeSpeechTranscription::open(yarp::os::Searchable& config) { + if (!this->parseParams(config)) {return false;} + return true; } diff --git a/src/devices/fake/fakeSpeechTranscription/fakeSpeechTranscription.h b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription.h similarity index 81% rename from src/devices/fake/fakeSpeechTranscription/fakeSpeechTranscription.h rename to src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription.h index aa6a09706e8..561fcd4400f 100644 --- a/src/devices/fake/fakeSpeechTranscription/fakeSpeechTranscription.h +++ b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription.h @@ -11,20 +11,24 @@ #include #include +#include "FakeSpeechTranscription_ParamsParser.h" + using namespace yarp::os; /** - * @ingroup dev_impl_other + * @ingroup dev_impl_fake dev_impl_other * * \brief `FakeSpeechTranscription`: A fake implementation of a speech transcriber plugin. + * + * Parameters required by this device are shown in class: FakeSpeechTranscription_ParamsParser */ class FakeSpeechTranscription : public yarp::dev::DeviceDriver, - public yarp::dev::ISpeechTranscription + public yarp::dev::ISpeechTranscription, + public FakeSpeechTranscription_ParamsParser { private: bool m_verbose = true; - std::string m_language="auto"; public: FakeSpeechTranscription(); diff --git a/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_ParamsParser.cpp b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_ParamsParser.cpp new file mode 100644 index 00000000000..ffa351186a1 --- /dev/null +++ b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_ParamsParser.cpp @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#include "FakeSpeechTranscription_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeSpeechTranscriptionParamsCOMPONENT, "yarp.device.FakeSpeechTranscription") +} + + +FakeSpeechTranscription_ParamsParser::FakeSpeechTranscription_ParamsParser() +{ +} + + +std::vector FakeSpeechTranscription_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("language"); + return params; +} + + +bool FakeSpeechTranscription_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeSpeechTranscriptionParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter language + { + if (config.check("language")) + { + m_language = config.find("language").asString(); + yCInfo(FakeSpeechTranscriptionParamsCOMPONENT) << "Parameter 'language' using value:" << m_language; + } + else + { + yCInfo(FakeSpeechTranscriptionParamsCOMPONENT) << "Parameter 'language' using DEFAULT value:" << m_language; + } + prop_check.unput("language"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeSpeechTranscriptionParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeSpeechTranscriptionParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeSpeechTranscription_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeSpeechTranscription\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'language': language code\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakeSpeechTranscription --language auto\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakeSpeechTranscription\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_ParamsParser.h b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_ParamsParser.h new file mode 100644 index 00000000000..a31bd38803e --- /dev/null +++ b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_ParamsParser.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:32 2024 + + +#ifndef FAKESPEECHTRANSCRIPTION_PARAMSPARSER_H +#define FAKESPEECHTRANSCRIPTION_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeSpeechTranscription. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:-------------:|:-----:| +* | - | language | string | - | auto | 0 | language code | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakeSpeechTranscription --language auto +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakeSpeechTranscription +* \endcode +* +*/ + +class FakeSpeechTranscription_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeSpeechTranscription_ParamsParser(); + ~FakeSpeechTranscription_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeSpeechTranscription"}; + const std::string m_device_name = {"fakeSpeechTranscription"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_language_defaultValue = {"auto"}; + + std::string m_language = {"auto"}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_params.md b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_params.md new file mode 100644 index 00000000000..342fe2cdcbd --- /dev/null +++ b/src/devices/fake/fakeSpeechTranscription/FakeSpeechTranscription_params.md @@ -0,0 +1 @@ + * | | language | string | - | auto | No | language code | | diff --git a/src/devices/fake/fakebot/CMakeLists.txt b/src/devices/fake/fakebot/CMakeLists.txt index 8bd887a938b..15e69b9afd2 100644 --- a/src/devices/fake/fakebot/CMakeLists.txt +++ b/src/devices/fake/fakebot/CMakeLists.txt @@ -11,6 +11,7 @@ yarp_prepare_plugin(fakebot TYPE FakeBot INCLUDE FakeBot.h DEFAULT OFF + GENERATE_PARSER DEPENDS "NOT YARP_NO_DEPRECATED" # DEPRECATED Since YARP 3.5 ) @@ -21,6 +22,8 @@ if(NOT SKIP_fakebot) PRIVATE FakeBot.cpp FakeBot.h + FakeBot_ParamsParser.cpp + FakeBot_ParamsParser.h ) target_link_libraries(yarp_fakebot diff --git a/src/devices/fake/fakebot/FakeBot.cpp b/src/devices/fake/fakebot/FakeBot.cpp index 95d383fd5d2..5a401256738 100644 --- a/src/devices/fake/fakebot/FakeBot.cpp +++ b/src/devices/fake/fakebot/FakeBot.cpp @@ -86,28 +86,19 @@ void scramble(unsigned char& ch, float f) { } -bool FakeBot::open(yarp::os::Searchable& config) { - std::string backFile = config.check("background",Value("textures/back.ppm"), - "background image to use").asString(); - if (backFile!="") { - yarp::sig::file::read(back,backFile); - } - std::string foreFile = config.check("target",Value("textures/fore.ppm"), - "target image to use").asString(); - if (foreFile!="") { - yarp::sig::file::read(fore,foreFile); - } - noiseLevel = config.check("noise",Value(0.05), - "pixel noise level").asFloat64(); - - xScale = config.check("sx",Value(1.0), - "scaling for x coordinate").asFloat64(); - yScale = config.check("sy",Value(1.0), - "scaling for y coordinate").asFloat64(); - - lifetime = config.check("lifetime",Value(-1.0), - "device should exist for this length of time (in seconds)").asFloat64(); - if (lifetime>=0) { +bool FakeBot::open(yarp::os::Searchable& config) +{ + if (!this->parseParams(config)) {return false;} + + if (m_background !="") { + yarp::sig::file::read(back, m_background); + } + + if (m_target !="") { + yarp::sig::file::read(fore, m_target); + } + + if (m_lifetime>=0) { start(); } return true; @@ -149,8 +140,8 @@ bool FakeBot::getImage(yarp::sig::ImageOf& image) { loc[0] = m_dx; loc[1] = m_dy; - double m_dx_scaled = m_dx*xScale; - double m_dy_scaled = m_dy*yScale; + double m_dx_scaled = m_dx* m_sx; + double m_dy_scaled = m_dy* m_sy; IMGFOR(image,x,y) { int x0 = int(x+m_x+m_dx_scaled*0.5+0.5); int y0 = int(y+m_y+m_dy_scaled*0.5+0.5); @@ -165,7 +156,7 @@ bool FakeBot::getImage(yarp::sig::ImageOf& image) { } IMGFOR(image,x2,y2) { PixelRgb& pix = image(x2,y2); - auto f = (float)(noiseLevel); + auto f = (float)(m_noise); scramble(pix.r,f); scramble(pix.g,f); scramble(pix.b,f); @@ -175,8 +166,8 @@ bool FakeBot::getImage(yarp::sig::ImageOf& image) { } void FakeBot::run() { - if (lifetime>=0) { - Time::delay(lifetime); + if (m_lifetime>=0) { + Time::delay(m_lifetime); std::exit(0); } } diff --git a/src/devices/fake/fakebot/FakeBot.h b/src/devices/fake/fakebot/FakeBot.h index e97795a4b4c..b8919ae6e87 100644 --- a/src/devices/fake/fakebot/FakeBot.h +++ b/src/devices/fake/fakebot/FakeBot.h @@ -12,6 +12,7 @@ #include #include #include +#include "FakeBot_ParamsParser.h" YARP_DECLARE_LOG_COMPONENT(FAKEBOT) @@ -19,6 +20,8 @@ YARP_DECLARE_LOG_COMPONENT(FAKEBOT) * @ingroup dev_impl_fake dev_impl_deprecated * * \brief `fakebot` *deprecated*: Documentation to be added + * + * Parameters required by this device are shown in class: FakeBot_ParamsParser */ class FakeBot : public yarp::dev::DeprecatedDeviceDriver, @@ -29,7 +32,8 @@ class FakeBot : public yarp::dev::IFrameGrabberImage, public yarp::dev::IControlCalibration, public yarp::dev::IControlLimits, - public yarp::os::Thread + public yarp::os::Thread, + public FakeBot_ParamsParser { private: int njoints; @@ -38,22 +42,15 @@ class FakeBot : double m_tx, m_ty; double m_tdx, m_tdy; int m_w, m_h; - double xScale, yScale; - double noiseLevel; yarp::sig::Vector pos, dpos, vel, speed, acc, loc, amp; yarp::sig::ImageOf back, fore; - double lifetime; void init(); public: FakeBot() : njoints(2), m_w(128), - m_h(128), - xScale(1), - yScale(1), - noiseLevel(0), - lifetime(-1) + m_h(128) { pos.resize(njoints); dpos.resize(njoints); diff --git a/src/devices/fake/fakebot/FakeBot_ParamsParser.cpp b/src/devices/fake/fakebot/FakeBot_ParamsParser.cpp new file mode 100644 index 00000000000..e8d03e2a69f --- /dev/null +++ b/src/devices/fake/fakebot/FakeBot_ParamsParser.cpp @@ -0,0 +1,183 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:29 2024 + + +#include "FakeBot_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(FakeBotParamsCOMPONENT, "yarp.device.FakeBot") +} + + +FakeBot_ParamsParser::FakeBot_ParamsParser() +{ +} + + +std::vector FakeBot_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("background"); + params.push_back("target"); + params.push_back("noise"); + params.push_back("sx"); + params.push_back("sy"); + params.push_back("lifetime"); + return params; +} + + +bool FakeBot_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(FakeBotParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter background + { + if (config.check("background")) + { + m_background = config.find("background").asString(); + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'background' using value:" << m_background; + } + else + { + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'background' using DEFAULT value:" << m_background; + } + prop_check.unput("background"); + } + + //Parser of parameter target + { + if (config.check("target")) + { + m_target = config.find("target").asString(); + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'target' using value:" << m_target; + } + else + { + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'target' using DEFAULT value:" << m_target; + } + prop_check.unput("target"); + } + + //Parser of parameter noise + { + if (config.check("noise")) + { + m_noise = config.find("noise").asFloat64(); + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'noise' using value:" << m_noise; + } + else + { + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'noise' using DEFAULT value:" << m_noise; + } + prop_check.unput("noise"); + } + + //Parser of parameter sx + { + if (config.check("sx")) + { + m_sx = config.find("sx").asFloat64(); + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'sx' using value:" << m_sx; + } + else + { + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'sx' using DEFAULT value:" << m_sx; + } + prop_check.unput("sx"); + } + + //Parser of parameter sy + { + if (config.check("sy")) + { + m_sy = config.find("sy").asFloat64(); + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'sy' using value:" << m_sy; + } + else + { + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'sy' using DEFAULT value:" << m_sy; + } + prop_check.unput("sy"); + } + + //Parser of parameter lifetime + { + if (config.check("lifetime")) + { + m_lifetime = config.find("lifetime").asFloat64(); + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'lifetime' using value:" << m_lifetime; + } + else + { + yCInfo(FakeBotParamsCOMPONENT) << "Parameter 'lifetime' using DEFAULT value:" << m_lifetime; + } + prop_check.unput("lifetime"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(FakeBotParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(FakeBotParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string FakeBot_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: FakeBot\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'background': background image to use\n"); + doc = doc + std::string("'target': target image to use\n"); + doc = doc + std::string("'noise': pixel noise level\n"); + doc = doc + std::string("'sx': scaling for x coordinate\n"); + doc = doc + std::string("'sy': scaling for y coordinate\n"); + doc = doc + std::string("'lifetime': device should exist for this length of time\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device fakebot --background textures/back.ppm --target textures/fore.ppm --noise 0.05 --sx 1.0 --sy 1.0 --lifetime -1.0\n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device fakebot\n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/devices/fake/fakebot/FakeBot_ParamsParser.h b/src/devices/fake/fakebot/FakeBot_ParamsParser.h new file mode 100644 index 00000000000..909bf50319f --- /dev/null +++ b/src/devices/fake/fakebot/FakeBot_ParamsParser.h @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Tue Feb 27 00:56:29 2024 + + +#ifndef FAKEBOT_PARAMSPARSER_H +#define FAKEBOT_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class FakeBot. +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:------:|:-----:|:-----------------:|:--------:|:-------------------------------------------:|:-----:| +* | - | background | string | - | textures/back.ppm | 0 | background image to use | - | +* | - | target | string | - | textures/fore.ppm | 0 | target image to use | - | +* | - | noise | double | - | 0.05 | 0 | pixel noise level | - | +* | - | sx | double | - | 1.0 | 0 | scaling for x coordinate | - | +* | - | sy | double | - | 1.0 | 0 | scaling for y coordinate | - | +* | - | lifetime | double | s | -1.0 | 0 | device should exist for this length of time | - | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device fakebot --background textures/back.ppm --target textures/fore.ppm --noise 0.05 --sx 1.0 --sy 1.0 --lifetime -1.0 +* \endcode +* +* \code{.unparsed} +* yarpdev --device fakebot +* \endcode +* +*/ + +class FakeBot_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + FakeBot_ParamsParser(); + ~FakeBot_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"FakeBot"}; + const std::string m_device_name = {"fakebot"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_background_defaultValue = {"textures/back.ppm"}; + const std::string m_target_defaultValue = {"textures/fore.ppm"}; + const std::string m_noise_defaultValue = {"0.05"}; + const std::string m_sx_defaultValue = {"1.0"}; + const std::string m_sy_defaultValue = {"1.0"}; + const std::string m_lifetime_defaultValue = {"-1.0"}; + + std::string m_background = {"textures/back.ppm"}; + std::string m_target = {"textures/fore.ppm"}; + double m_noise = {0.05}; + double m_sx = {1.0}; + double m_sy = {1.0}; + double m_lifetime = {-1.0}; + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/devices/fake/fakebot/FakeBot_params.md b/src/devices/fake/fakebot/FakeBot_params.md new file mode 100644 index 00000000000..ace597d8d04 --- /dev/null +++ b/src/devices/fake/fakebot/FakeBot_params.md @@ -0,0 +1,6 @@ + * | | background | string | - | textures/back.ppm | No | background image to use | | + * | | target | string | - | textures/fore.ppm | No | target image to use | | + * | | noise | double | - | 0.05 | No | pixel noise level | | + * | | sx | double | - | 1.0 | No | scaling for x coordinate | | + * | | sy | double | - | 1.0 | No | scaling for y coordinate | | + * | | lifetime | double | s | -1.0 | No | device should exist for this length of time | | diff --git a/src/devices/networkWrappers/Rangefinder2DClient/tests/rangefinder2DClient_test.cpp b/src/devices/networkWrappers/Rangefinder2DClient/tests/rangefinder2DClient_test.cpp index 8c616a2252b..782c3dc7c35 100644 --- a/src/devices/networkWrappers/Rangefinder2DClient/tests/rangefinder2DClient_test.cpp +++ b/src/devices/networkWrappers/Rangefinder2DClient/tests/rangefinder2DClient_test.cpp @@ -36,13 +36,14 @@ TEST_CASE("dev::Rangefinder2DClientTest", "[yarp::dev]") Property plas_cfg; plas_cfg.put("device", "fakeLaser"); plas_cfg.put("test", "use_constant"); - plas_cfg.put("const_distance", 0.5); + Property& cm_cfg = plas_cfg.addGroup("CONSTANT_MODE"); + cm_cfg.put("const_distance", 0.5); REQUIRE(ddlas.open(plas_cfg)); } { Property pnws_cfg; pnws_cfg.put("device", "rangefinder2D_nws_yarp"); - pnws_cfg.put("period", "0.010"); + pnws_cfg.put("period", 0.010); pnws_cfg.put("name", "/laser"); REQUIRE(ddnws.open(pnws_cfg)); } diff --git a/src/devices/networkWrappers/Rangefinder2D_nwc_yarp/tests/rangefinder2D_nwc_yarp_test.cpp b/src/devices/networkWrappers/Rangefinder2D_nwc_yarp/tests/rangefinder2D_nwc_yarp_test.cpp index df6125f3005..12e9069b6b0 100644 --- a/src/devices/networkWrappers/Rangefinder2D_nwc_yarp/tests/rangefinder2D_nwc_yarp_test.cpp +++ b/src/devices/networkWrappers/Rangefinder2D_nwc_yarp/tests/rangefinder2D_nwc_yarp_test.cpp @@ -35,14 +35,15 @@ TEST_CASE("dev::rangefinder2D_nwc_yarp", "[yarp::dev]") { Property plas_cfg; plas_cfg.put("device", "fakeLaser"); - plas_cfg.put("test","use_constant"); - plas_cfg.put("const_distance", 0.5); + plas_cfg.put("test", "use_constant"); + Property& cm_cfg = plas_cfg.addGroup("CONSTANT_MODE"); + cm_cfg.put("const_distance", 0.5); REQUIRE(ddlas.open(plas_cfg)); } { Property pnws_cfg; pnws_cfg.put("device", "rangefinder2D_nws_yarp"); - pnws_cfg.put("period", "0.010"); + pnws_cfg.put("period", 0.010); pnws_cfg.put("name", "/laser"); REQUIRE(ddnws.open(pnws_cfg)); } diff --git a/src/devices/networkWrappers/Rangefinder2D_nws_yarp/tests/rangefinder2D_nws_yarp_test.cpp b/src/devices/networkWrappers/Rangefinder2D_nws_yarp/tests/rangefinder2D_nws_yarp_test.cpp index 3716417be10..f73e7891932 100644 --- a/src/devices/networkWrappers/Rangefinder2D_nws_yarp/tests/rangefinder2D_nws_yarp_test.cpp +++ b/src/devices/networkWrappers/Rangefinder2D_nws_yarp/tests/rangefinder2D_nws_yarp_test.cpp @@ -50,12 +50,15 @@ TEST_CASE("dev::Rangefinder2D_nws_yarpTest", "[yarp::dev]") { Property pnws_cfg; pnws_cfg.put("device", "rangefinder2D_nws_yarp"); - pnws_cfg.put("period", "0.010"); + pnws_cfg.put("period", 0.010); pnws_cfg.put("name", "/laser"); REQUIRE(ddnws.open(pnws_cfg)); Property pdev_cfg; pdev_cfg.put("device", "fakeLaser"); + pdev_cfg.put("test", "use_constant"); + Property& cm_cfg = pdev_cfg.addGroup("CONSTANT_MODE"); + cm_cfg.put("const_distance", 0.5); REQUIRE(ddfake.open(pdev_cfg)); {yarp::dev::WrapperSingle* ww_nws=nullptr; ddnws.view(ww_nws); diff --git a/src/devices/networkWrappers/serialPort_nwc_yarp/tests/serialPort_nwc_yarp_test.cpp b/src/devices/networkWrappers/serialPort_nwc_yarp/tests/serialPort_nwc_yarp_test.cpp index 2c39565228c..75ad1353777 100644 --- a/src/devices/networkWrappers/serialPort_nwc_yarp/tests/serialPort_nwc_yarp_test.cpp +++ b/src/devices/networkWrappers/serialPort_nwc_yarp/tests/serialPort_nwc_yarp_test.cpp @@ -37,6 +37,8 @@ TEST_CASE("dev::serialPort_nwc_yarp", "[yarp::dev]") Property pdev_cfg; pdev_cfg.put("device", "fakeSerialPort"); + pdev_cfg.put("comport", "fakePort"); + pdev_cfg.put("baudrate", 9600); REQUIRE(ddfake.open(pdev_cfg)); {yarp::dev::WrapperSingle* ww_nws=nullptr; ddnws.view(ww_nws); diff --git a/src/devices/networkWrappers/serialPort_nws_yarp/tests/serialPort_nws_yarp_test.cpp b/src/devices/networkWrappers/serialPort_nws_yarp/tests/serialPort_nws_yarp_test.cpp index 623972e9bea..3d28cfa939a 100644 --- a/src/devices/networkWrappers/serialPort_nws_yarp/tests/serialPort_nws_yarp_test.cpp +++ b/src/devices/networkWrappers/serialPort_nws_yarp/tests/serialPort_nws_yarp_test.cpp @@ -54,6 +54,8 @@ TEST_CASE("dev::serialPort_nws_yarp", "[yarp::dev]") Property pdev_cfg; pdev_cfg.put("device", "fakeSerialPort"); + pdev_cfg.put("comport", "fakePort"); + pdev_cfg.put("baudrate", 9600); REQUIRE(ddfake.open(pdev_cfg)); {yarp::dev::WrapperSingle* ww_nws=nullptr; ddnws.view(ww_nws); diff --git a/src/libYARP_dev/src/yarp/dev/IDeviceDriverParams.h b/src/libYARP_dev/src/yarp/dev/IDeviceDriverParams.h index d948d1c379e..28213c53aa3 100644 --- a/src/libYARP_dev/src/yarp/dev/IDeviceDriverParams.h +++ b/src/libYARP_dev/src/yarp/dev/IDeviceDriverParams.h @@ -35,9 +35,15 @@ class YARP_dev_API yarp::dev::IDeviceDriverParams /** * Get the name of the DeviceDriver class. - * @return A string containing the name of the DeviceDriver. + * @return A string containing the name of the class. */ - virtual std::string getDeviceType() const = 0; + virtual std::string getDeviceClassName() const = 0; + + /** + * Get the name of the device (i.e. the plugin name). + * @return A string containing the name of the device. + */ + virtual std::string getDeviceName() const = 0; /** * Get the documentation of the DeviceDriver's parameters. diff --git a/src/libYARP_dev/src/yarp/dev/tests/IRgbVisualParamsTest.h b/src/libYARP_dev/src/yarp/dev/tests/IRgbVisualParamsTest.h index ca8772420e7..557d4d5e148 100644 --- a/src/libYARP_dev/src/yarp/dev/tests/IRgbVisualParamsTest.h +++ b/src/libYARP_dev/src/yarp/dev/tests/IRgbVisualParamsTest.h @@ -63,7 +63,9 @@ namespace yarp::dev::tests double data[9] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 }; Vector v(9, data); Vector v2; - Portable::copyPortable(*retM, v2); + std::string retM_string = retM->toString(); + bool cpret = Portable::copyPortable(*retM, v2); + REQUIRE ((cpret && v2.size()==9)); //Otherwise the following loop will segfault for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { CHECK(retM->get(i * 3 + j).asFloat64() == v(i * 3 + j)); diff --git a/src/libYARP_os/tests/BottleTest.cpp b/src/libYARP_os/tests/BottleTest.cpp index 66d8ff7aec7..7fce6de06c5 100644 --- a/src/libYARP_os/tests/BottleTest.cpp +++ b/src/libYARP_os/tests/BottleTest.cpp @@ -112,6 +112,16 @@ TEST_CASE("os::BottleTest", "[yarp::os]") CHECK(bot10.toString() == "(1 2 3) (4 5 6)"); // "construction test 2" CHECK(bot10.get(1).isList()); // "construction test 3" CHECK(bot10.get(1).asList()->toString() == "4 5 6"); // "construction test 4" + + Bottle bot3, bot4; + bot3.fromString("aa bb cc"); + bot4.fromString("\"aa\" \"bb\" \"cc\""); + CHECK(bot3.size() == 3); + CHECK(bot4.size() == 3); + std::string bot3s = bot3.toString(); + std::string bot4s = bot4.toString(); + CHECK(bot3s == "aa bb cc"); + CHECK(bot4s == "aa bb cc"); } SECTION("testing Value interface") diff --git a/src/yarpDeviceParamParserGenerator/generate_cpp_functions.cpp b/src/yarpDeviceParamParserGenerator/generate_cpp_functions.cpp index cebe551b9e9..61d6768d3fe 100644 --- a/src/yarpDeviceParamParserGenerator/generate_cpp_functions.cpp +++ b/src/yarpDeviceParamParserGenerator/generate_cpp_functions.cpp @@ -14,6 +14,49 @@ #include "generator.h" +std::string ParamsFilesGenerator::generateConstructor() +{ + std::ostringstream s; + ADD_DEBUG_COMMENT(s) + s << "\n"; + s << m_classname << "_ParamsParser::" << m_classname << "_ParamsParser()\n";\ + s << "{\n"; + for (const auto& param : m_params) + { + if ( !param.defaultValue.empty() && + (param.type == "vector" || + param.type == "vector" || + param.type == "vector")) + { + std::string typ=""; + if (param.type == "vector") { typ = ".asInt64()"; } + else if (param.type == "vector") { typ = ".asString()"; } + else if (param.type == "vector") { typ = ".asFloat64()"; } + s << S_TAB1 << "//Default value of parameter" << param.getFullParamVariable() <<"\n"; + s << S_TAB1 << "{\n"; + s << S_TAB1 << " m_" << param.getFullParamVariable() << ".clear();\n"; + s << S_TAB1 << " yarp::os::Value tempVal;\n"; + s << S_TAB1 << " tempVal.fromString(m_" << param.getFullParamVariable() << "_defaultValue.c_str()" << ");\n"; + s << S_TAB1 << " yarp::os::Bottle* tempBot = tempVal.asList();\n"; + s << S_TAB1 << " if (tempBot && tempBot->size()!=0)\n"; + s << S_TAB1 << " {\n"; + s << S_TAB1 << " for (size_t i=0; isize(); i++)\n"; + s << S_TAB1 << " {\n"; + s << S_TAB1 << " m_" << param.getFullParamVariable() << ".push_back(tempBot->get(i)" << typ << ");\n"; + s << S_TAB1 << " }\n"; + s << S_TAB1 << " }\n"; + s << S_TAB1 << " else\n"; + s << S_TAB1 << " {\n"; + s << S_TAB1 << " yError() <<" << "\"parameter '" << param.getFullParamVariable() << "' is not a properly formatted bottle\";\n"; + s << S_TAB1 << " }\n"; + s << S_TAB1 << "}\n\n"; + } + } + s << "}\n"; + s << "\n"; + return s.str(); +}; + std::string ParamsFilesGenerator::generateFunction_getListOfParams() { std::ostringstream s; @@ -113,21 +156,92 @@ void ParamsFilesGenerator::generate_section(std::ostringstream& s, std::dequetoString();\n"; + s << S_TAB3 << " for (size_t i=0; isize(); i++)\n"; + s << S_TAB3 << " {\n"; + s << S_TAB3 << " m_" << param.getFullParamVariable() << ".push_back(tempBot->get(i)" << typ << ");\n"; + s << S_TAB3 << " }\n"; + s << S_TAB3 << " }\n"; + s << S_TAB3 << " else\n"; + s << S_TAB3 << " {\n"; + s << S_TAB3 << " yCError(" << component << ") <<" << "\"parameter '" << param.getFullParamVariable() <<"' is not a properly formatted bottle\";\n"; + s << S_TAB3 << " }\n"; + s << S_TAB3 << "}\n"; +} + +inline void BB (std::string origin, std::ostringstream& s, const Parameter& param, std::string typ, std::string component) +{ + ADD_DEBUG_COMMENT(s) + s << S_TAB3 << "{\n"; + s << S_TAB3 << " m_" << param.getFullParamVariable() << ".clear();\n"; + s << S_TAB3 << " std::string tempString = "<> val)\n"; + s << S_TAB3 << " {\n"; + s << S_TAB3 << " m_" << param.getFullParamVariable() << ".push_back(val"<0)\n"; + s << S_TAB3 << " {\n"; + s << S_TAB3 << " int sizes = tempBot.size();\n"; + s << S_TAB3 << " std::string tempBots = tempBot.toString();\n"; + s << S_TAB3 << " tempBot = tempBot.tail();\n"; + s << S_TAB3 << " for (size_t i=0; i") { AA(origin, s, param, ".asInt64()", m_component); } + else if (param.type == "vector") { AA(origin, s, param, ".asString()", m_component); } + else if (param.type == "vector") { AA(origin, s, param, ".asFloat64()", m_component); } +// else if (param.type == "vector") { BB(origin, s, param, "int"); } +// else if (param.type == "vector") { BB(origin, s, param, "std::string"); } +// else if (param.type == "vector") { BB(origin, s, param, "double"); } else { yFatal("ERROR: Unknown data type for param %s: %s",param.getFullParamName().c_str(), param.type.c_str()); //error } diff --git a/src/yarpDeviceParamParserGenerator/generate_h_functions.cpp b/src/yarpDeviceParamParserGenerator/generate_h_functions.cpp index 932f45ca841..b245a955dbc 100644 --- a/src/yarpDeviceParamParserGenerator/generate_h_functions.cpp +++ b/src/yarpDeviceParamParserGenerator/generate_h_functions.cpp @@ -69,12 +69,13 @@ std::string ParamsFilesGenerator::generateHeader() class " << m_classname << "_ParamsParser : public yarp::dev::IDeviceDriverParams\n\ {\n\ public:\n\ - " << m_classname << "_ParamsParser() = default;\n\ + " << m_classname << "_ParamsParser();\n\ ~" << m_classname << "_ParamsParser() override = default;\n\ \n\ public:\n"; - s << S_TAB1 << "const std::string m_device_type = {\"" << m_classname << "\"};\n"; + s << S_TAB1 << "const std::string m_device_classname = {\"" << m_classname << "\"};\n"; + s << S_TAB1 << "const std::string m_device_name = {\"" << m_modulename << "\"};\n"; s << S_TAB1 << "bool m_parser_is_strict = false;\n"; s << S_TAB1 << "struct parser_version_type\n"; s << S_TAB1 << "{\n"; @@ -83,25 +84,43 @@ public:\n"; s << S_TAB1 << "};\n"; s << S_TAB1 << "const parser_version_type m_parser_version = {};\n"; + s << "\n"; + for (const auto& param : m_params) + { + s << S_TAB1 << "const std::string m_" << param.getFullParamVariable() << "_defaultValue = {\"" << escapeQuotes(param.defaultValue) << "\"};\n"; + } + s << "\n"; + for (const auto& param : m_params) { std::string rmv; s << S_TAB1; - if (param.type == "bool") { s << "bool "; rmv = "false";} - else if (param.type == "string") { s << "std::string "; rmv = "";} - else if (param.type == "double") { s << "double "; rmv = "std::nan(\"1\")";} - else if (param.type == "int") { s << "int "; rmv = "0";} - else if (param.type == "size_t") { s << "size_t "; rmv = "0";} - else if (param.type == "float") { s << "float "; rmv = "std::nan(\"1\")";} + if (param.type == "bool") { s << "bool "; rmv = "false";} + else if (param.type == "string") { s << "std::string "; rmv = "";} + else if (param.type == "double") { s << "double "; rmv = "std::nan(\"1\")";} + else if (param.type == "int") { s << "int "; rmv = "0";} + else if (param.type == "size_t") { s << "size_t "; rmv = "0";} + else if (param.type == "float") { s << "float "; rmv = "std::nanf(\"1\")";} + else if (param.type == "char") { s << "char "; rmv = "0"; } + else if (param.type == "vector") { s << "std::vector "; rmv = ""; } + else if (param.type == "vector") { s << "std::vector "; rmv = ""; } + else if (param.type == "vector") { s << "std::vector "; rmv = ""; } else { s << "ERROR! Generation failed because of unknown data type.\n"; } s << "m_" << param.getFullParamVariable(); + //if the parameter has a default value... if (param.defaultValue != "") { - if (param.type == "string") + if (param.type == "vector" || + param.type == "vector" || + param.type == "vector") + { + s << " = { }; //Default values for lists are managed in the class constructor. It is highly recommended to provide a suggested value also for optional string parameters.\n"; + } + else if (param.type == "string") { s << " = {\"" << param.defaultValue << "\"};\n"; } @@ -110,12 +129,28 @@ public:\n"; s << " = {" << param.defaultValue << "};\n"; } } + //if the parameter has not a default value else { + //optional parameter must have a default value!!! if (param.required == false) { - s << " = ERROR! Generation failed because an optional param MUST have a default value!\n"; + if (param.type == "string") + { + s << " = {" << rmv << "}; //This default value of this string is an empty string. It is highly recommended to provide a suggested value also for optional string parameters.\n"; + } + else if (param.type == "vector" || + param.type == "vector" || + param.type == "vector") + { + s << " = {" << rmv << "}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters.\n"; + } + else + { + s << " = ERROR! Generation failed because this optional param MUST have a default value!\n"; + } } + //mandatory parameter might not have a default value else { s << " = {" << rmv << "}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters.\n"; @@ -125,7 +160,8 @@ public:\n"; s << "\n\ bool parseParams(const yarp::os::Searchable & config) override;\n\ - std::string getDeviceType() const override { return m_device_type; }\n\ + std::string getDeviceClassName() const override { return m_device_classname; }\n\ + std::string getDeviceName() const override { return m_device_name; }\n\ std::string getDocumentationOfDeviceParams() const override;\n\ std::vector getListOfParams() const override;\n\ };\n\ diff --git a/src/yarpDeviceParamParserGenerator/generate_yarpdev.cpp b/src/yarpDeviceParamParserGenerator/generate_yarpdev.cpp index b1de7fdb992..2e268b31f06 100644 --- a/src/yarpDeviceParamParserGenerator/generate_yarpdev.cpp +++ b/src/yarpDeviceParamParserGenerator/generate_yarpdev.cpp @@ -12,13 +12,15 @@ std::string ParamsFilesGenerator::generateYarpdevStringAllParams() { std::ostringstream s; - s << " yarpdev --device " << this->m_classname; + s << " yarpdev --device " << this->m_modulename; for (auto param : m_params) { s << " --" << param.getFullParamName(); if (!param.defaultValue.empty()) { + if (param.type == "vector" || param.type == "vector" || param.type == "vector") { s << " \"";} s << " " << param.defaultValue; + if (param.type == "vector" || param.type == "vector" || param.type == "vector") { s << " \"";} } else { @@ -32,13 +34,13 @@ std::string ParamsFilesGenerator::generateYarpdevStringAllParams() } } } - return s.str(); + return escapeQuotes(s.str()); } std::string ParamsFilesGenerator::generateYarpdevStringMandatoryParamsOnly() { std::ostringstream s; - s << " yarpdev --device " << this->m_classname; + s << " yarpdev --device " << this->m_modulename; for (auto param : m_params) { if (param.required) @@ -46,7 +48,9 @@ std::string ParamsFilesGenerator::generateYarpdevStringMandatoryParamsOnly() s << " --" << param.getFullParamName(); if (!param.defaultValue.empty()) { + if (param.type == "vector" || param.type == "vector" || param.type == "vector") { s << " \""; } s << " " << param.defaultValue; + if (param.type == "vector" || param.type == "vector" || param.type == "vector") { s << " \""; } } else { @@ -54,7 +58,7 @@ std::string ParamsFilesGenerator::generateYarpdevStringMandatoryParamsOnly() } } } - return s.str(); + return escapeQuotes(s.str()); } std::string ParamsFilesGenerator::generateYarpdevDoxyString() diff --git a/src/yarpDeviceParamParserGenerator/generate_yarprobotinterface.cpp b/src/yarpDeviceParamParserGenerator/generate_yarprobotinterface.cpp index 56dc2c4e6a1..64cba750837 100644 --- a/src/yarpDeviceParamParserGenerator/generate_yarprobotinterface.cpp +++ b/src/yarpDeviceParamParserGenerator/generate_yarprobotinterface.cpp @@ -40,7 +40,7 @@ std::string ParamsFilesGenerator::generateYarprobotinterface() \n\ \n\ \n\ - \n\ + \n\ "; m_sectionGroup.iterator_start(); diff --git a/src/yarpDeviceParamParserGenerator/generator.h b/src/yarpDeviceParamParserGenerator/generator.h index 16ca41ea0df..35ae6200118 100644 --- a/src/yarpDeviceParamParserGenerator/generator.h +++ b/src/yarpDeviceParamParserGenerator/generator.h @@ -36,6 +36,7 @@ class ParamsFilesGenerator bool m_parser_is_strict = false; std::string m_classname; + std::string m_modulename; std::string m_component; std::string m_output_header_filename; std::string m_output_cpp_filename; @@ -48,6 +49,7 @@ class ParamsFilesGenerator void printParams(); std::string generateCpp(); + std::string generateConstructor(); std::string generateFunction_getListOfParams(); std::string generateFunction_parseParams(); std::string generateFunction_getDeviceType() { return ""; }; diff --git a/src/yarpDeviceParamParserGenerator/main.cpp b/src/yarpDeviceParamParserGenerator/main.cpp index fea7140dde5..1a1e0485410 100644 --- a/src/yarpDeviceParamParserGenerator/main.cpp +++ b/src/yarpDeviceParamParserGenerator/main.cpp @@ -51,9 +51,9 @@ bool ParamsFilesGenerator::nested_sections_found() void print_help() { std::cout << "Welcome to YarpDeviceParamParserGenerator tool. Syntax:\n"; - std::cout << "1) yarpDeviceParamParserGenerator --class_name \"className\" --input_filename_md \"filename.md\" [--input_extra_comments \"comments.md\"] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir \"output_path\"] [--debug_mode]\n"; + std::cout << "1) yarpDeviceParamParserGenerator --class_name \"className\" --module_name \"moduleName\" --input_filename_md \"filename.md\" [--input_extra_comments \"comments.md\"] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir \"output_path\"] [--debug_mode]\n"; std::cout << "or:\n"; - std::cout << "2) yarpDeviceParamParserGenerator --class_name \"className\" --input_filename_ini \"filename.ini\" [--input_extra_comments \"comments.md\"] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir \"output_path\"] [--debug_mode]\n"; + std::cout << "2) yarpDeviceParamParserGenerator --class_name \"className\" --module_name \"moduleName\" --input_filename_ini \"filename.ini\" [--input_extra_comments \"comments.md\"] [--generate_md] [--generate_ini] [--generate_yarpdev] [--generate_yarprobotinterface] [--generate_all] [--output_dir \"output_path\"] [--debug_mode]\n"; } int main(int argc, char *argv[]) @@ -71,6 +71,7 @@ int main(int argc, char *argv[]) std::string input_extra_comments; std::string output_dir="."; std::string class_name; + std::string module_name; #if 0 //debug only! std::cout << "Invocation command " << argc << ":"; @@ -138,6 +139,10 @@ int main(int argc, char *argv[]) class_name = argv[i + 1]; i++; } + else if (arg == "--module_name" && i + 1 < argc && argv[i + 1][0] != '-') { + module_name = argv[i + 1]; + i++; + } else if (arg == "--debug_mode") { debug_mode = true; } @@ -158,6 +163,11 @@ int main(int argc, char *argv[]) std::cerr << "Invalid class name. Check parameter --class_name\n"; return RETURN_CODE_ERROR; } + if (module_name.empty()) + { + std::cerr << "Invalid module name. Check parameter --module_name\n"; + return RETURN_CODE_ERROR; + } ParamsFilesGenerator pgen; if (input_filename_type == "md") @@ -191,6 +201,7 @@ int main(int argc, char *argv[]) output_dir.pop_back();} output_dir += '/'; pgen.m_classname = class_name; + pgen.m_modulename = module_name; pgen.m_component = pgen.m_classname + "ParamsCOMPONENT"; std::string output_filename = class_name + "_ParamsParser"; pgen.m_output_header_filename = output_dir + output_filename + ".h"; @@ -309,6 +320,7 @@ namespace {\n\ }\n\ \n"; + s << generateConstructor(); s << generateFunction_getListOfParams(); s << generateFunction_parseParams(); s << generateFunction_getDeviceType(); diff --git a/src/yarpDeviceParamParserGenerator/tests/CMakeLists.txt b/src/yarpDeviceParamParserGenerator/tests/CMakeLists.txt index 038286840be..354dd75e824 100644 --- a/src/yarpDeviceParamParserGenerator/tests/CMakeLists.txt +++ b/src/yarpDeviceParamParserGenerator/tests/CMakeLists.txt @@ -1,68 +1,5 @@ # SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) # SPDX-License-Identifier: BSD-3-Clause -include(YarpPlugin) -include(YarpPrintFeature) -include(YarpCatchUtils) -include(YarpDeviceParamsParserGenerator) - -yarp_prepare_plugin(testDeviceWGP - CATEGORY device - TYPE TestDeviceWGP - INCLUDE TestDeviceWGP.h - DEFAULT ON -) - -#This is a test so we always want to generate the parser, regardless the value of ALLOW_DEVICE_PARAM_PARSER_GENERATION. -#With add_custom_target and add_dependencies we create a dependency so that first yarpDeviceParamParserGenerator is executed -#then the device is compiled, using the generated files. -add_custom_target(generate_parser COMMAND yarpDeviceParamParserGenerator - --class_name TestDeviceWGP - --input_filename_md test2.txt - --input_extra_comments extraComments.md - --generate all - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - -yarp_add_plugin(yarp_testDeviceWGP) - -add_dependencies(yarp_testDeviceWGP generate_parser) - -target_sources(yarp_testDeviceWGP - PRIVATE - TestDeviceWGP.cpp - TestDeviceWGP.h - TestDeviceWGP_ParamsParser.cpp - TestDeviceWGP_ParamsParser.h -) - -target_link_libraries(yarp_testDeviceWGP - PRIVATE - YARP::YARP_os - YARP::YARP_dev -) -list(APPEND YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS - YARP_os - YARP_dev -) - - yarp_install( - TARGETS yarp_testDeviceWGP - EXPORT YARP_${YARP_PLUGIN_MASTER} - COMPONENT ${YARP_PLUGIN_MASTER} - LIBRARY DESTINATION ${YARP_DYNAMIC_PLUGINS_INSTALL_DIR} - ARCHIVE DESTINATION ${YARP_STATIC_PLUGINS_INSTALL_DIR} - YARP_INI DESTINATION ${YARP_PLUGIN_MANIFESTS_INSTALL_DIR} - ) - -source_group("OtherFiles" FILES - testDeviceWGPParams.ini - testDeviceWGPParams.md - testDeviceWGPParams.xml -) - -set(YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS ${YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS} PARENT_SCOPE) - -set_property(TARGET yarp_testDeviceWGP PROPERTY FOLDER "Test") -set_property(TARGET generate_parser PROPERTY FOLDER "Test") - -create_device_test(TestDeviceWGP) +add_subdirectory(test1) +add_subdirectory(test2) diff --git a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP.cpp b/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP.cpp deleted file mode 100644 index cab88957fc4..00000000000 --- a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "TestDeviceWGP.h" - -#include -#include - -using namespace yarp::os; -using namespace yarp::dev; - -TestDeviceWGP::TestDeviceWGP() -{ -} - -TestDeviceWGP::~TestDeviceWGP() -{ -} - -bool TestDeviceWGP::open(yarp::os::Searchable &config) -{ - bool ret = parseParams(config); - return ret; -} - -bool TestDeviceWGP::close() -{ - return true; -} diff --git a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP.h b/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP.h deleted file mode 100644 index 7f76706e6ea..00000000000 --- a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include "TestDeviceWGP_ParamsParser.h" - -#include - -/** -* @ingroup dev_impl_media -* -* \brief `TestDeviceWGP` : A test device driver, for Continuous Integration purposes. -* -* Parameters required by this device are shown in class: TestDeviceWGP_ParamsParser -*/ - -class TestDeviceWGP : - public yarp::dev::DeviceDriver, - public TestDeviceWGP_ParamsParser -{ -public: - TestDeviceWGP(); - TestDeviceWGP(const TestDeviceWGP&) = delete; - TestDeviceWGP(TestDeviceWGP&&) = delete; - TestDeviceWGP& operator=(const TestDeviceWGP&) = delete; - TestDeviceWGP& operator=(TestDeviceWGP&&) = delete; - ~TestDeviceWGP() override; - - // Device Driver interface - bool open(yarp::os::Searchable &config) override; - bool close() override; -}; diff --git a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_ParamsParser.cpp b/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_ParamsParser.cpp deleted file mode 100644 index c81ea5e2d42..00000000000 --- a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_ParamsParser.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: LGPL-2.1-or-later - */ - - -// Generated by yarpDeviceParamParserGenerator (1.0) -// This is an automatically generated file. Please do not edit it. -// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. - -// Generated on: Wed Feb 7 16:19:38 2024 - - -#include "TestDeviceWGP_ParamsParser.h" -#include -#include - -namespace { - YARP_LOG_COMPONENT(TestDeviceWGPParamsCOMPONENT, "yarp.device.TestDeviceWGP") -} - - -std::vector TestDeviceWGP_ParamsParser::getListOfParams() const -{ - std::vector params; - params.push_back("file_name"); - params.push_back("mode"); - params.push_back("add_marker"); - params.push_back("group1::param_a"); - params.push_back("group2::param_a"); - params.push_back("period"); - params.push_back("initial_ref"); - params.push_back("group3::subgroup1::param_1"); - params.push_back("group3::subgroup1::param_2"); - params.push_back("group3::param_3"); - params.push_back("group3::subgroup2::param_4"); - return params; -} - - -bool TestDeviceWGP_ParamsParser::parseParams(const yarp::os::Searchable & config) -{ - //Check for --help option - if (config.check("help")) - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << getDocumentationOfDeviceParams(); - } - - std::string config_string = config.toString(); - yarp::os::Property prop_check(config_string.c_str()); - //Parser of parameter file_name - { - if (config.check("file_name")) - { - m_file_name = config.find("file_name").asString(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'file_name' using value:" << m_file_name; - } - else - { - yCError(TestDeviceWGPParamsCOMPONENT) << "Mandatory parameter 'file_name' not found!"; - yCError(TestDeviceWGPParamsCOMPONENT) << "Description of the parameter: The name of the file written by the module"; - return false; - } - prop_check.unput("file_name"); - } - - //Parser of parameter mode - { - if (config.check("mode")) - { - m_mode = config.find("mode").asString(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'mode' using value:" << m_mode; - } - else - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'mode' using DEFAULT value:" << m_mode; - } - prop_check.unput("mode"); - } - - //Parser of parameter add_marker - { - if (config.check("add_marker")) - { - m_add_marker = config.find("add_marker").asBool(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'add_marker' using value:" << m_add_marker; - } - else - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'add_marker' using DEFAULT value:" << m_add_marker; - } - prop_check.unput("add_marker"); - } - - //Parser of parameter group1::param_a - { - yarp::os::Bottle sectionp; - sectionp = config.findGroup("group1"); - if (sectionp.check("param_a")) - { - m_group1_param_a = sectionp.find("param_a").asBool(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group1::param_a' using value:" << m_group1_param_a; - } - else - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group1::param_a' using DEFAULT value:" << m_group1_param_a; - } - prop_check.unput("group1::param_a"); - } - - //Parser of parameter group2::param_a - { - yarp::os::Bottle sectionp; - sectionp = config.findGroup("group2"); - if (sectionp.check("param_a")) - { - m_group2_param_a = sectionp.find("param_a").asBool(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group2::param_a' using value:" << m_group2_param_a; - } - else - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group2::param_a' using DEFAULT value:" << m_group2_param_a; - } - prop_check.unput("group2::param_a"); - } - - //Parser of parameter period - { - if (config.check("period")) - { - m_period = config.find("period").asFloat64(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'period' using value:" << m_period; - } - else - { - yCError(TestDeviceWGPParamsCOMPONENT) << "Mandatory parameter 'period' not found!"; - yCError(TestDeviceWGPParamsCOMPONENT) << "Description of the parameter: Algorithm control loop period"; - yCError(TestDeviceWGPParamsCOMPONENT) << "Remember: Units for this parameter are: 's'"; - return false; - } - prop_check.unput("period"); - } - - //Parser of parameter initial_ref - { - if (config.check("initial_ref")) - { - m_initial_ref = config.find("initial_ref").asFloat64(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'initial_ref' using value:" << m_initial_ref; - } - else - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'initial_ref' using DEFAULT value:" << m_initial_ref; - } - prop_check.unput("initial_ref"); - } - - //Parser of parameter group3::subgroup1::param_1 - { - yarp::os::Bottle sectionp0; - sectionp0 = config.findGroup("group3"); - yarp::os::Bottle sectionp; - sectionp = sectionp0.findGroup("subgroup1"); - if (sectionp.check("param_1")) - { - m_group3_subgroup1_param_1 = sectionp.find("param_1").asBool(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group3::subgroup1::param_1' using value:" << m_group3_subgroup1_param_1; - } - else - { - yCError(TestDeviceWGPParamsCOMPONENT) << "Mandatory parameter 'group3::subgroup1::param_1' not found!"; - yCError(TestDeviceWGPParamsCOMPONENT) << "Description of the parameter: This is a parameter for testing purposes"; - return false; - } - prop_check.unput("group3::subgroup1::param_1"); - } - - //Parser of parameter group3::subgroup1::param_2 - { - yarp::os::Bottle sectionp0; - sectionp0 = config.findGroup("group3"); - yarp::os::Bottle sectionp; - sectionp = sectionp0.findGroup("subgroup1"); - if (sectionp.check("param_2")) - { - m_group3_subgroup1_param_2 = sectionp.find("param_2").asBool(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group3::subgroup1::param_2' using value:" << m_group3_subgroup1_param_2; - } - else - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group3::subgroup1::param_2' using DEFAULT value:" << m_group3_subgroup1_param_2; - } - prop_check.unput("group3::subgroup1::param_2"); - } - - //Parser of parameter group3::param_3 - { - yarp::os::Bottle sectionp; - sectionp = config.findGroup("group3"); - if (sectionp.check("param_3")) - { - m_group3_param_3 = sectionp.find("param_3").asBool(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group3::param_3' using value:" << m_group3_param_3; - } - else - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group3::param_3' using DEFAULT value:" << m_group3_param_3; - } - prop_check.unput("group3::param_3"); - } - - //Parser of parameter group3::subgroup2::param_4 - { - yarp::os::Bottle sectionp0; - sectionp0 = config.findGroup("group3"); - yarp::os::Bottle sectionp; - sectionp = sectionp0.findGroup("subgroup2"); - if (sectionp.check("param_4")) - { - m_group3_subgroup2_param_4 = sectionp.find("param_4").asBool(); - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group3::subgroup2::param_4' using value:" << m_group3_subgroup2_param_4; - } - else - { - yCInfo(TestDeviceWGPParamsCOMPONENT) << "Parameter 'group3::subgroup2::param_4' using DEFAULT value:" << m_group3_subgroup2_param_4; - } - prop_check.unput("group3::subgroup2::param_4"); - } - - /* - //This code check if the user set some parameter which are not check by the parser - //If the parser is set in strict mode, this will generate an error - if (prop_check.size() > 0) - { - bool extra_params_found = false; - for (auto it=prop_check.begin(); it!=prop_check.end(); it++) - { - if (m_parser_is_strict) - { - yCError(TestDeviceWGPParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; - extra_params_found = true; - } - else - { - yCWarning(TestDeviceWGPParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; - } - } - - if (m_parser_is_strict && extra_params_found) - { - return false; - } - } - */ - return true; -} - - -std::string TestDeviceWGP_ParamsParser::getDocumentationOfDeviceParams() const -{ - std::string doc; - doc = doc + std::string("\n=============================================\n"); - doc = doc + std::string("This is the help for device: TestDeviceWGP\n"); - doc = doc + std::string("\n"); - doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); - doc = doc + std::string("'file_name': The name of the file written by the module\n"); - doc = doc + std::string("'mode': This fake parameter chooses the fake algorithm to be used\n"); - doc = doc + std::string("'add_marker': Some description of param.\n"); - doc = doc + std::string("'group1::param_a': Some description of param.\n"); - doc = doc + std::string("'group2::param_a': Some description of param.\n"); - doc = doc + std::string("'period': Algorithm control loop period\n"); - doc = doc + std::string("'initial_ref': An initial value for the algorithm\n"); - doc = doc + std::string("'group3::subgroup1::param_1': This is a parameter for testing purposes\n"); - doc = doc + std::string("'group3::subgroup1::param_2': This is a parameter for testing purposes\n"); - doc = doc + std::string("'group3::param_3': This is a parameter for testing purposes\n"); - doc = doc + std::string("'group3::subgroup2::param_4': This is a parameter for testing purposes\n"); - doc = doc + std::string("\n"); - doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); - doc = doc + " yarpdev --device TestDeviceWGP --file_name audio_out.wav --mode mode1 --add_marker false --group1::param_a false --group2::param_a false --period --initial_ref 3 --group3::subgroup1::param_1 false --group3::subgroup1::param_2 true --group3::param_3 false --group3::subgroup2::param_4 true\n"; - doc = doc + std::string("Using only mandatory params:\n"); - doc = doc + " yarpdev --device TestDeviceWGP --file_name audio_out.wav --period --group3::subgroup1::param_1 false\n"; - doc = doc + std::string("=============================================\n\n"); return doc; -} diff --git a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_ParamsParser.h b/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_ParamsParser.h deleted file mode 100644 index dae5aed2318..00000000000 --- a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_ParamsParser.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: LGPL-2.1-or-later - */ - - -// Generated by yarpDeviceParamParserGenerator (1.0) -// This is an automatically generated file. Please do not edit it. -// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. - -// Generated on: Sun Feb 11 01:28:40 2024 - - -#ifndef TESTDEVICEWGP_PARAMSPARSER_H -#define TESTDEVICEWGP_PARAMSPARSER_H - -#include -#include -#include -#include - -/** -* This class is the parameters parser for class TestDeviceWGP. -*TestDeviceWGP is a fake device developed for testing the various functionalities of YarpDeviceParamParserGenerator tool. -*This block has been written with the purpose of testing the --input_extra_comments option. -*This last line has no specific meaning. -*Here there are some extra symbols used in the markdown format, such as the 'code' syntax. -*The **bold text** , the *italic text*, the list: -*1. First element -*2. Second element -*- unordered element 1 -*- unordered element 2 -* -* -* These are the used parameters: -* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | -* |:-----------------:|:--------------:|:------:|:-----:|:-------------:|:--------:|:---------------------------------------------------------:|:-------------------------------------:| -* | - | file_name | string | - | audio_out.wav | 1 | The name of the file written by the module | Only.wav and .mp3 files are supported | -* | - | mode | string | - | mode1 | 0 | This fake parameter chooses the fake algorithm to be used | - | -* | - | add_marker | bool | - | false | 0 | Some description of param. | - | -* | group1 | param_a | bool | - | false | 0 | Some description of param. | - | -* | group2 | param_a | bool | - | false | 0 | Some description of param. | - | -* | - | period | double | s | - | 1 | Algorithm control loop period | - | -* | - | initial_ref | double | m | 3 | 0 | An initial value for the algorithm | - | -* | group3::subgroup1 | param_1 | bool | - | false | 1 | This is a parameter for \"testing\" purposes | - | -* | group3::subgroup1 | param_2 | bool | - | true | 0 | This is a parameter for testing purposes | - | -* | group3 | param_3 | bool | - | false | 0 | This is a parameter for testing purposes | - | -* | group3::subgroup2 | param_4 | bool | - | true | 0 | This is a parameter for testing purposes | - | -* -* The device can be launched by yarpdev using one of the following examples: -* \code{.unparsed} -* yarpdev --device TestDeviceWGP --file_name audio_out.wav --mode mode1 --add_marker false --group1::param_a false --group2::param_a false --period --initial_ref 3 --group3::subgroup1::param_1 false --group3::subgroup1::param_2 true --group3::param_3 false --group3::subgroup2::param_4 true -* \endcode -* -* \code{.unparsed} -* yarpdev --device TestDeviceWGP --file_name audio_out.wav --period --group3::subgroup1::param_1 false -* \endcode -* -*/ - -class TestDeviceWGP_ParamsParser : public yarp::dev::IDeviceDriverParams -{ -public: - TestDeviceWGP_ParamsParser() = default; - ~TestDeviceWGP_ParamsParser() override = default; - -public: - const std::string m_device_type = {"TestDeviceWGP"}; - bool m_parser_is_strict = false; - struct parser_version_type - { - int major = 1; - int minor = 0; - }; - const parser_version_type m_parser_version = {}; - std::string m_file_name = {"audio_out.wav"}; - std::string m_mode = {"mode1"}; - bool m_add_marker = {false}; - bool m_group1_param_a = {false}; - bool m_group2_param_a = {false}; - double m_period = {std::nan("1")}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. - double m_initial_ref = {3}; - bool m_group3_subgroup1_param_1 = {false}; - bool m_group3_subgroup1_param_2 = {true}; - bool m_group3_param_3 = {false}; - bool m_group3_subgroup2_param_4 = {true}; - - bool parseParams(const yarp::os::Searchable & config) override; - std::string getDeviceType() const override { return m_device_type; } - std::string getDocumentationOfDeviceParams() const override; - std::vector getListOfParams() const override; -}; - -#endif diff --git a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_test.cpp b/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_test.cpp deleted file mode 100644 index 7dcb8154ddd..00000000000 --- a/src/yarpDeviceParamParserGenerator/tests/TestDeviceWGP_test.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include -#include - -using namespace yarp::dev; -using namespace yarp::os; - -TEST_CASE("dev::TestDeviceWGP", "[yarp::dev]") -{ - YARP_REQUIRE_PLUGIN("testDeviceWGP", "device"); - - Network::setLocalMode(true); - - SECTION("Checking TestDeviceWGP device") - { - PolyDriver dd; - - ////////"Checking opening polydriver with no attached device" - { - Property p_cfg; - p_cfg.put("device", "testDeviceWGP"); - p_cfg.put("file_name", "mandatory_name"); - p_cfg.put("period", 1.0); - - Property& pp_cfg = p_cfg.addGroup("group3"); - Property& ppp_cfg = pp_cfg.addGroup("subgroup1"); - ppp_cfg.put("param_1", "test_string"); - - REQUIRE(dd.open(p_cfg)); - } - - yarp::os::Time::delay(1.0); - - //"Close all polydrivers and check" - { - CHECK(dd.close()); - } - } - - Network::setLocalMode(false); -} diff --git a/src/yarpDeviceParamParserGenerator/tests/test1.txt b/src/yarpDeviceParamParserGenerator/tests/test1.txt deleted file mode 100644 index 0995b61d5aa..00000000000 --- a/src/yarpDeviceParamParserGenerator/tests/test1.txt +++ /dev/null @@ -1,11 +0,0 @@ -| - | file_name | string | - | audio_out.wav | Yes | The name of the file written by the module | Only.wav and .mp3 files are supported | -| - | mode | string | - | mode1 | No | This fake parameter chooses the fake algorithm to be used | | -| - | add_marker | bool | - | false | No | Some description of param. | | -| group1 | param_a | bool | - | false | No | Some description of param. | | -| group2 | param_a | bool | - | false | No | Some description of param. | | -| - | period | double | s | - | Yes | Algorithm control loop period | | -| - | initial_ref | double | m | 3 | No | An initial value for the algorithm | | -| group3::subgroup1 | param_1 | bool | - | false | Yes | This is a parameter for testing purposes | | -| group3::subgroup1 | param_2 | bool | - | true | No | This is a parameter for testing purposes | | -| group3 | param_3 | bool | - | false | No | This is a parameter for testing purposes | | -| group3::subgroup2 | param_4 | bool | - | true | No | This is a parameter for testing purposes | | diff --git a/src/yarpDeviceParamParserGenerator/tests/test1/CMakeLists.txt b/src/yarpDeviceParamParserGenerator/tests/test1/CMakeLists.txt new file mode 100644 index 00000000000..ec6dd48ff57 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test1/CMakeLists.txt @@ -0,0 +1,69 @@ +# SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) +# SPDX-License-Identifier: BSD-3-Clause + +include(YarpPlugin) +include(YarpPrintFeature) +include(YarpCatchUtils) +include(YarpDeviceParamsParserGenerator) + +yarp_prepare_plugin(testDeviceWGP1 + CATEGORY device + TYPE TestDeviceWGP1 + INCLUDE TestDeviceWGP1.h + DEFAULT ON +) + +#This is a test so we always want to generate the parser, regardless the value of ALLOW_DEVICE_PARAM_PARSER_GENERATION. +#With add_custom_target and add_dependencies we create a dependency so that first yarpDeviceParamParserGenerator is executed +#then the device is compiled, using the generated files. +add_custom_target(generate_parser COMMAND yarpDeviceParamParserGenerator + --class_name TestDeviceWGP1 + --module_name testDeviceWGP1 + --input_filename_md test2.txt + --input_extra_comments extraComments.md + --generate_all + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +yarp_add_plugin(yarp_testDeviceWGP1) + +add_dependencies(yarp_testDeviceWGP1 generate_parser) + +target_sources(yarp_testDeviceWGP1 + PRIVATE + TestDeviceWGP1.cpp + TestDeviceWGP1.h + TestDeviceWGP1_ParamsParser.cpp + TestDeviceWGP1_ParamsParser.h +) + +target_link_libraries(yarp_testDeviceWGP1 + PRIVATE + YARP::YARP_os + YARP::YARP_dev +) +list(APPEND YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS + YARP_os + YARP_dev +) + + yarp_install( + TARGETS yarp_testDeviceWGP1 + EXPORT YARP_${YARP_PLUGIN_MASTER} + COMPONENT ${YARP_PLUGIN_MASTER} + LIBRARY DESTINATION ${YARP_DYNAMIC_PLUGINS_INSTALL_DIR} + ARCHIVE DESTINATION ${YARP_STATIC_PLUGINS_INSTALL_DIR} + YARP_INI DESTINATION ${YARP_PLUGIN_MANIFESTS_INSTALL_DIR} + ) + +source_group("OtherFiles" FILES + testDeviceWGPParams.ini + testDeviceWGPParams.md + testDeviceWGPParams.xml +) + +set(YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS ${YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS} PARENT_SCOPE) + +set_property(TARGET yarp_testDeviceWGP1 PROPERTY FOLDER "Test") +set_property(TARGET generate_parser PROPERTY FOLDER "Test") + +create_device_test(TestDeviceWGP1) diff --git a/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1.cpp b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1.cpp new file mode 100644 index 00000000000..08099d6a3d4 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1.cpp @@ -0,0 +1,129 @@ +/* + * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "TestDeviceWGP1.h" + +#include +#include + +using namespace yarp::os; +using namespace yarp::dev; + +TestDeviceWGP1::TestDeviceWGP1() +{ +} + +TestDeviceWGP1::~TestDeviceWGP1() +{ +} + +bool TestDeviceWGP1::do_test() +{ + if (m_param_1 != "string") { yError() << "error m_param_1 "; return false; } + if (m_param_2 != 1.0) { yError() << "error m_param_2 "; return false; } + if (m_param_3 != true) { yError() << "error m_param_3 "; return false; } + if (m_param_4 != 1) { yError() << "error m_param_4 "; return false; } + if (m_param_5 != 'a') { yError() << "error m_param_5 "; return false; } + if (m_param_6 != 10) { yError() << "error m_param_6 "; return false; } + if (m_param_7 != 1.0) { yError() << "error m_param_7 "; return false; } + if (m_group1_param_1 != "def10") { yError() << "error m_group1_param_1"; return false; } + if (m_group1_param_2 != 101) { yError() << "error m_group1_param_2"; return false; } + if (m_group1_param_3 != true) { yError() << "error m_group1_param_3"; return false; } + if (m_group1_param_4 != 1001) { yError() << "error m_group1_param_4"; return false; } + if (m_group2_param_1 != "def20") { yError() << "error m_group2_param_1"; return false; } + if (m_group2_param_2 != 102) { yError() << "error m_group2_param_2"; return false; } + if (m_group2_param_3 != true) { yError() << "error m_group2_param_3"; return false; } + if (m_group2_param_4 != 1002) { yError() << "error m_group2_param_4"; return false; } + if (m_group3_param_1 != "def1") { yError() << "error m_group3_param_1"; return false; } + if (m_group3_param_2 != 1.0) { yError() << "error m_group3_param_2"; return false; } + if (m_group3_param_3 != true) { yError() << "error m_group3_param_3"; return false; } + if (m_group3_param_4 != 1000) { yError() << "error m_group3_param_4"; return false; } + if (m_group4_subgroup1_param_1 != 0) { yError() << "error m_group4_subgroup1_param_1"; return false; } + if (m_group4_subgroup1_param_2 != 1) { yError() << "error m_group4_subgroup1_param_2"; return false; } + if (m_group4_subgroup1_param_3 != 2) { yError() << "error m_group4_subgroup1_param_3"; return false; } + if (m_group4_subgroup1_param_4 != 3) { yError() << "error m_group4_subgroup1_param_4"; return false; } + if (m_group4_subgroup2_param_1 != 10) { yError() << "error m_group4_subgroup2_param_1"; return false; } + if (m_group4_subgroup2_param_2 != 11) { yError() << "error m_group4_subgroup2_param_2"; return false; } + if (m_group4_subgroup2_param_3 != 12) { yError() << "error m_group4_subgroup2_param_3"; return false; } + if (m_group4_subgroup2_param_4 != 13) { yError() << "error m_group4_subgroup2_param_4"; return false; } + if (m_group5_subgroup1_param_1 != 200) { yError() << "error m_group5_subgroup1_param_1"; return false; } + if (m_group5_subgroup1_param_2 != 210) { yError() << "error m_group5_subgroup1_param_2"; return false; } + if (m_group5_subgroup1_param_3 != 220) { yError() << "error m_group5_subgroup1_param_3"; return false; } + if (m_group5_subgroup1_param_4 != 230) { yError() << "error m_group5_subgroup1_param_4"; return false; } + if (m_group5_subgroup2_param_1 != 300) { yError() << "error m_group5_subgroup2_param_1"; return false; } + if (m_group5_subgroup2_param_2 != 310) { yError() << "error m_group5_subgroup2_param_2"; return false; } + if (m_group5_subgroup2_param_3 != 320) { yError() << "error m_group5_subgroup2_param_3"; return false; } + if (m_group5_subgroup2_param_4 != 330) { yError() << "error m_group5_subgroup2_param_4"; return false; } + + //vec1,2,3 are empty + { + if (m_param_vec1.size() != 0) { yError() << "error vec1 size"; return false; } + if (m_param_vec2.size() != 0) { yError() << "error vec2 size"; return false; } + if (m_param_vec3.size() != 0) { yError() << "error vec3 size"; return false; } + } + + { + if (m_param_vec4.size() != 3) { yError() << "error vec4 size"; return false; } + if (m_param_vec5.size() != 3) { yError() << "error vec5 size"; return false; } + if (m_param_vec6.size() != 3) { yError() << "error vec6 size"; return false; } + + if (m_param_vec4[0] != 1 || + m_param_vec4[1] != 2 || + m_param_vec4[2] != 3) { + yError() << "error vec4 content"; return false; } + + if (m_param_vec5[0] != 1 || + m_param_vec5[1] != 2 || + m_param_vec5[2] != 3) { + yError() << "error vec5 content"; return false; } + + if (m_param_vec6[0] != "sa1" || + m_param_vec6[1] != "sa2" || + m_param_vec6[2] != "sa3") { + yError() << "error vec5 content"; return false; } + } + + { + if (m_param_vec7.size() != 3) { yError() << "error vec7 size"; return false; } + if (m_param_vec8.size() != 3) { yError() << "error vec8 size"; return false; } + if (m_param_vec9.size() != 3) { yError() << "error vec9 size"; return false; } + + if (m_param_vec7[0] != 1 || + m_param_vec7[1] != 2 || + m_param_vec7[2] != 3) { + yError() << "error vec7 content"; return false; + } + + if (m_param_vec8[0] != 1.0 || + m_param_vec8[1] != 2.0 || + m_param_vec8[2] != 3.0) { + yError() << "error vec8 content"; return false; + } + + if (m_param_vec9[0] != "sa1" || + m_param_vec9[1] != "sa2" || + m_param_vec9[2] != "sa3") { + yError() << "error vec9 content"; return false; + } + } + + return true; +} + +bool TestDeviceWGP1::open(yarp::os::Searchable &config) +{ + bool ret = parseParams(config); + if (!ret) { yError() << "parseParams() failed"; return false; } + + ret = do_test(); + if (!ret) { yError() << "do_test() failed"; return false; } + + return true; +} + +bool TestDeviceWGP1::close() +{ + return true; +} diff --git a/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1.h b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1.h new file mode 100644 index 00000000000..187167d3c7b --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "TestDeviceWGP1_ParamsParser.h" + +#include + +/** +* @ingroup dev_impl_media +* +* \brief `TestDeviceWGP1` : A test device driver, for Continuous Integration purposes. +* +* Parameters required by this device are shown in class: TestDeviceWGP1_ParamsParser +*/ + +class TestDeviceWGP1 : + public yarp::dev::DeviceDriver, + public TestDeviceWGP1_ParamsParser +{ +public: + TestDeviceWGP1(); + TestDeviceWGP1(const TestDeviceWGP1&) = delete; + TestDeviceWGP1(TestDeviceWGP1&&) = delete; + TestDeviceWGP1& operator=(const TestDeviceWGP1&) = delete; + TestDeviceWGP1& operator=(TestDeviceWGP1&&) = delete; + ~TestDeviceWGP1() override; + + // Device Driver interface + bool open(yarp::os::Searchable &config) override; + bool close() override; + + private: + bool do_test(); +}; diff --git a/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_ParamsParser.cpp b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_ParamsParser.cpp new file mode 100644 index 00000000000..d9e6646319c --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_ParamsParser.cpp @@ -0,0 +1,1134 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Mon Feb 26 23:01:26 2024 + + +#include "TestDeviceWGP1_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(TestDeviceWGP1ParamsCOMPONENT, "yarp.device.TestDeviceWGP1") +} + + +TestDeviceWGP1_ParamsParser::TestDeviceWGP1_ParamsParser() +{ + //Default value of parameterparam_vec4 + { + m_param_vec4.clear(); + yarp::os::Value tempVal; + tempVal.fromString(m_param_vec4_defaultValue.c_str()); + yarp::os::Bottle* tempBot = tempVal.asList(); + if (tempBot && tempBot->size()!=0) + { + for (size_t i=0; isize(); i++) + { + m_param_vec4.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yError() <<"parameter 'param_vec4' is not a properly formatted bottle"; + } + } + + //Default value of parameterparam_vec5 + { + m_param_vec5.clear(); + yarp::os::Value tempVal; + tempVal.fromString(m_param_vec5_defaultValue.c_str()); + yarp::os::Bottle* tempBot = tempVal.asList(); + if (tempBot && tempBot->size()!=0) + { + for (size_t i=0; isize(); i++) + { + m_param_vec5.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yError() <<"parameter 'param_vec5' is not a properly formatted bottle"; + } + } + + //Default value of parameterparam_vec6 + { + m_param_vec6.clear(); + yarp::os::Value tempVal; + tempVal.fromString(m_param_vec6_defaultValue.c_str()); + yarp::os::Bottle* tempBot = tempVal.asList(); + if (tempBot && tempBot->size()!=0) + { + for (size_t i=0; isize(); i++) + { + m_param_vec6.push_back(tempBot->get(i).asString()); + } + } + else + { + yError() <<"parameter 'param_vec6' is not a properly formatted bottle"; + } + } + +} + + +std::vector TestDeviceWGP1_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("param_1"); + params.push_back("param_2"); + params.push_back("param_3"); + params.push_back("param_4"); + params.push_back("param_5"); + params.push_back("param_6"); + params.push_back("param_7"); + params.push_back("group1::param_1"); + params.push_back("group1::param_2"); + params.push_back("group1::param_3"); + params.push_back("group1::param_4"); + params.push_back("group2::param_1"); + params.push_back("group2::param_2"); + params.push_back("group2::param_3"); + params.push_back("group2::param_4"); + params.push_back("group3::param_1"); + params.push_back("group3::param_2"); + params.push_back("group3::param_3"); + params.push_back("group3::param_4"); + params.push_back("group4::subgroup1::param_1"); + params.push_back("group4::subgroup1::param_2"); + params.push_back("group4::subgroup1::param_3"); + params.push_back("group4::subgroup1::param_4"); + params.push_back("group4::subgroup2::param_1"); + params.push_back("group4::subgroup2::param_2"); + params.push_back("group4::subgroup2::param_3"); + params.push_back("group4::subgroup2::param_4"); + params.push_back("group5::subgroup1::param_1"); + params.push_back("group5::subgroup1::param_2"); + params.push_back("group5::subgroup1::param_3"); + params.push_back("group5::subgroup1::param_4"); + params.push_back("group5::subgroup2::param_1"); + params.push_back("group5::subgroup2::param_2"); + params.push_back("group5::subgroup2::param_3"); + params.push_back("group5::subgroup2::param_4"); + params.push_back("param_vec1"); + params.push_back("param_vec2"); + params.push_back("param_vec3"); + params.push_back("param_vec4"); + params.push_back("param_vec5"); + params.push_back("param_vec6"); + params.push_back("param_vec7"); + params.push_back("param_vec8"); + params.push_back("param_vec9"); + return params; +} + + +bool TestDeviceWGP1_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter param_1 + { + if (config.check("param_1")) + { + m_param_1 = config.find("param_1").asString(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_1' using value:" << m_param_1; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_1' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 01"; + return false; + } + prop_check.unput("param_1"); + } + + //Parser of parameter param_2 + { + if (config.check("param_2")) + { + m_param_2 = config.find("param_2").asFloat64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_2' using value:" << m_param_2; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_2' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 02"; + return false; + } + prop_check.unput("param_2"); + } + + //Parser of parameter param_3 + { + if (config.check("param_3")) + { + m_param_3 = config.find("param_3").asBool(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_3' using value:" << m_param_3; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_3' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 03"; + return false; + } + prop_check.unput("param_3"); + } + + //Parser of parameter param_4 + { + if (config.check("param_4")) + { + m_param_4 = config.find("param_4").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_4' using value:" << m_param_4; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_4' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 04"; + return false; + } + prop_check.unput("param_4"); + } + + //Parser of parameter param_5 + { + if (config.check("param_5")) + { + m_param_5 = config.find("param_5").asInt8(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_5' using value:" << m_param_5; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_5' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 05"; + return false; + } + prop_check.unput("param_5"); + } + + //Parser of parameter param_6 + { + if (config.check("param_6")) + { + m_param_6 = config.find("param_6").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_6' using value:" << m_param_6; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_6' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 06"; + return false; + } + prop_check.unput("param_6"); + } + + //Parser of parameter param_7 + { + if (config.check("param_7")) + { + m_param_7 = config.find("param_7").asFloat32(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_7' using value:" << m_param_7; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_7' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 07"; + return false; + } + prop_check.unput("param_7"); + } + + //Parser of parameter group1::param_1 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group1"); + if (sectionp.check("param_1")) + { + m_group1_param_1 = sectionp.find("param_1").asString(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group1::param_1' using value:" << m_group1_param_1; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group1::param_1' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 08"; + return false; + } + prop_check.unput("group1::param_1"); + } + + //Parser of parameter group1::param_2 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group1"); + if (sectionp.check("param_2")) + { + m_group1_param_2 = sectionp.find("param_2").asFloat64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group1::param_2' using value:" << m_group1_param_2; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group1::param_2' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 09"; + return false; + } + prop_check.unput("group1::param_2"); + } + + //Parser of parameter group1::param_3 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group1"); + if (sectionp.check("param_3")) + { + m_group1_param_3 = sectionp.find("param_3").asBool(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group1::param_3' using value:" << m_group1_param_3; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group1::param_3' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 10"; + return false; + } + prop_check.unput("group1::param_3"); + } + + //Parser of parameter group1::param_4 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group1"); + if (sectionp.check("param_4")) + { + m_group1_param_4 = sectionp.find("param_4").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group1::param_4' using value:" << m_group1_param_4; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group1::param_4' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 11"; + return false; + } + prop_check.unput("group1::param_4"); + } + + //Parser of parameter group2::param_1 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group2"); + if (sectionp.check("param_1")) + { + m_group2_param_1 = sectionp.find("param_1").asString(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group2::param_1' using value:" << m_group2_param_1; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group2::param_1' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 12"; + return false; + } + prop_check.unput("group2::param_1"); + } + + //Parser of parameter group2::param_2 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group2"); + if (sectionp.check("param_2")) + { + m_group2_param_2 = sectionp.find("param_2").asFloat64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group2::param_2' using value:" << m_group2_param_2; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group2::param_2' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 13"; + return false; + } + prop_check.unput("group2::param_2"); + } + + //Parser of parameter group2::param_3 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group2"); + if (sectionp.check("param_3")) + { + m_group2_param_3 = sectionp.find("param_3").asBool(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group2::param_3' using value:" << m_group2_param_3; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group2::param_3' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 14"; + return false; + } + prop_check.unput("group2::param_3"); + } + + //Parser of parameter group2::param_4 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group2"); + if (sectionp.check("param_4")) + { + m_group2_param_4 = sectionp.find("param_4").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group2::param_4' using value:" << m_group2_param_4; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group2::param_4' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 15"; + return false; + } + prop_check.unput("group2::param_4"); + } + + //Parser of parameter group3::param_1 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group3"); + if (sectionp.check("param_1")) + { + m_group3_param_1 = sectionp.find("param_1").asString(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group3::param_1' using value:" << m_group3_param_1; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group3::param_1' using DEFAULT value:" << m_group3_param_1; + } + prop_check.unput("group3::param_1"); + } + + //Parser of parameter group3::param_2 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group3"); + if (sectionp.check("param_2")) + { + m_group3_param_2 = sectionp.find("param_2").asFloat64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group3::param_2' using value:" << m_group3_param_2; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group3::param_2' using DEFAULT value:" << m_group3_param_2; + } + prop_check.unput("group3::param_2"); + } + + //Parser of parameter group3::param_3 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group3"); + if (sectionp.check("param_3")) + { + m_group3_param_3 = sectionp.find("param_3").asBool(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group3::param_3' using value:" << m_group3_param_3; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group3::param_3' using DEFAULT value:" << m_group3_param_3; + } + prop_check.unput("group3::param_3"); + } + + //Parser of parameter group3::param_4 + { + yarp::os::Bottle sectionp; + sectionp = config.findGroup("group3"); + if (sectionp.check("param_4")) + { + m_group3_param_4 = sectionp.find("param_4").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group3::param_4' using value:" << m_group3_param_4; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group3::param_4' using DEFAULT value:" << m_group3_param_4; + } + prop_check.unput("group3::param_4"); + } + + //Parser of parameter group4::subgroup1::param_1 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group4"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup1"); + if (sectionp.check("param_1")) + { + m_group4_subgroup1_param_1 = sectionp.find("param_1").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup1::param_1' using value:" << m_group4_subgroup1_param_1; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup1::param_1' using DEFAULT value:" << m_group4_subgroup1_param_1; + } + prop_check.unput("group4::subgroup1::param_1"); + } + + //Parser of parameter group4::subgroup1::param_2 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group4"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup1"); + if (sectionp.check("param_2")) + { + m_group4_subgroup1_param_2 = sectionp.find("param_2").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup1::param_2' using value:" << m_group4_subgroup1_param_2; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup1::param_2' using DEFAULT value:" << m_group4_subgroup1_param_2; + } + prop_check.unput("group4::subgroup1::param_2"); + } + + //Parser of parameter group4::subgroup1::param_3 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group4"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup1"); + if (sectionp.check("param_3")) + { + m_group4_subgroup1_param_3 = sectionp.find("param_3").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup1::param_3' using value:" << m_group4_subgroup1_param_3; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup1::param_3' using DEFAULT value:" << m_group4_subgroup1_param_3; + } + prop_check.unput("group4::subgroup1::param_3"); + } + + //Parser of parameter group4::subgroup1::param_4 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group4"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup1"); + if (sectionp.check("param_4")) + { + m_group4_subgroup1_param_4 = sectionp.find("param_4").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup1::param_4' using value:" << m_group4_subgroup1_param_4; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup1::param_4' using DEFAULT value:" << m_group4_subgroup1_param_4; + } + prop_check.unput("group4::subgroup1::param_4"); + } + + //Parser of parameter group4::subgroup2::param_1 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group4"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup2"); + if (sectionp.check("param_1")) + { + m_group4_subgroup2_param_1 = sectionp.find("param_1").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup2::param_1' using value:" << m_group4_subgroup2_param_1; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup2::param_1' using DEFAULT value:" << m_group4_subgroup2_param_1; + } + prop_check.unput("group4::subgroup2::param_1"); + } + + //Parser of parameter group4::subgroup2::param_2 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group4"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup2"); + if (sectionp.check("param_2")) + { + m_group4_subgroup2_param_2 = sectionp.find("param_2").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup2::param_2' using value:" << m_group4_subgroup2_param_2; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup2::param_2' using DEFAULT value:" << m_group4_subgroup2_param_2; + } + prop_check.unput("group4::subgroup2::param_2"); + } + + //Parser of parameter group4::subgroup2::param_3 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group4"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup2"); + if (sectionp.check("param_3")) + { + m_group4_subgroup2_param_3 = sectionp.find("param_3").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup2::param_3' using value:" << m_group4_subgroup2_param_3; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup2::param_3' using DEFAULT value:" << m_group4_subgroup2_param_3; + } + prop_check.unput("group4::subgroup2::param_3"); + } + + //Parser of parameter group4::subgroup2::param_4 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group4"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup2"); + if (sectionp.check("param_4")) + { + m_group4_subgroup2_param_4 = sectionp.find("param_4").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup2::param_4' using value:" << m_group4_subgroup2_param_4; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group4::subgroup2::param_4' using DEFAULT value:" << m_group4_subgroup2_param_4; + } + prop_check.unput("group4::subgroup2::param_4"); + } + + //Parser of parameter group5::subgroup1::param_1 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group5"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup1"); + if (sectionp.check("param_1")) + { + m_group5_subgroup1_param_1 = sectionp.find("param_1").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group5::subgroup1::param_1' using value:" << m_group5_subgroup1_param_1; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group5::subgroup1::param_1' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 28"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'N'"; + return false; + } + prop_check.unput("group5::subgroup1::param_1"); + } + + //Parser of parameter group5::subgroup1::param_2 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group5"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup1"); + if (sectionp.check("param_2")) + { + m_group5_subgroup1_param_2 = sectionp.find("param_2").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group5::subgroup1::param_2' using value:" << m_group5_subgroup1_param_2; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group5::subgroup1::param_2' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 29"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'N'"; + return false; + } + prop_check.unput("group5::subgroup1::param_2"); + } + + //Parser of parameter group5::subgroup1::param_3 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group5"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup1"); + if (sectionp.check("param_3")) + { + m_group5_subgroup1_param_3 = sectionp.find("param_3").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group5::subgroup1::param_3' using value:" << m_group5_subgroup1_param_3; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group5::subgroup1::param_3' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 30"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'N'"; + return false; + } + prop_check.unput("group5::subgroup1::param_3"); + } + + //Parser of parameter group5::subgroup1::param_4 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group5"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup1"); + if (sectionp.check("param_4")) + { + m_group5_subgroup1_param_4 = sectionp.find("param_4").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group5::subgroup1::param_4' using value:" << m_group5_subgroup1_param_4; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group5::subgroup1::param_4' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 31"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'N'"; + return false; + } + prop_check.unput("group5::subgroup1::param_4"); + } + + //Parser of parameter group5::subgroup2::param_1 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group5"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup2"); + if (sectionp.check("param_1")) + { + m_group5_subgroup2_param_1 = sectionp.find("param_1").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group5::subgroup2::param_1' using value:" << m_group5_subgroup2_param_1; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group5::subgroup2::param_1' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 32"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'mN'"; + return false; + } + prop_check.unput("group5::subgroup2::param_1"); + } + + //Parser of parameter group5::subgroup2::param_2 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group5"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup2"); + if (sectionp.check("param_2")) + { + m_group5_subgroup2_param_2 = sectionp.find("param_2").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group5::subgroup2::param_2' using value:" << m_group5_subgroup2_param_2; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group5::subgroup2::param_2' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 33"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'mN'"; + return false; + } + prop_check.unput("group5::subgroup2::param_2"); + } + + //Parser of parameter group5::subgroup2::param_3 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group5"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup2"); + if (sectionp.check("param_3")) + { + m_group5_subgroup2_param_3 = sectionp.find("param_3").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group5::subgroup2::param_3' using value:" << m_group5_subgroup2_param_3; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group5::subgroup2::param_3' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 34"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'mN'"; + return false; + } + prop_check.unput("group5::subgroup2::param_3"); + } + + //Parser of parameter group5::subgroup2::param_4 + { + yarp::os::Bottle sectionp0; + sectionp0 = config.findGroup("group5"); + yarp::os::Bottle sectionp; + sectionp = sectionp0.findGroup("subgroup2"); + if (sectionp.check("param_4")) + { + m_group5_subgroup2_param_4 = sectionp.find("param_4").asInt64(); + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'group5::subgroup2::param_4' using value:" << m_group5_subgroup2_param_4; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'group5::subgroup2::param_4' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 35"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'mN'"; + return false; + } + prop_check.unput("group5::subgroup2::param_4"); + } + + //Parser of parameter param_vec1 + { + if (config.check("param_vec1")) + { + { + m_param_vec1.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec1").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec1.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec1' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec1' using value:" << m_param_vec1; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec1' using DEFAULT value:" << m_param_vec1; + } + prop_check.unput("param_vec1"); + } + + //Parser of parameter param_vec2 + { + if (config.check("param_vec2")) + { + { + m_param_vec2.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec2").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec2.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec2' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec2' using value:" << m_param_vec2; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec2' using DEFAULT value:" << m_param_vec2; + } + prop_check.unput("param_vec2"); + } + + //Parser of parameter param_vec3 + { + if (config.check("param_vec3")) + { + { + m_param_vec3.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec3").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec3.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec3' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec3' using value:" << m_param_vec3; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec3' using DEFAULT value:" << m_param_vec3; + } + prop_check.unput("param_vec3"); + } + + //Parser of parameter param_vec4 + { + if (config.check("param_vec4")) + { + { + m_param_vec4.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec4").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec4.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec4' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec4' using value:" << m_param_vec4; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec4' using DEFAULT value:" << m_param_vec4; + } + prop_check.unput("param_vec4"); + } + + //Parser of parameter param_vec5 + { + if (config.check("param_vec5")) + { + { + m_param_vec5.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec5").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec5.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec5' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec5' using value:" << m_param_vec5; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec5' using DEFAULT value:" << m_param_vec5; + } + prop_check.unput("param_vec5"); + } + + //Parser of parameter param_vec6 + { + if (config.check("param_vec6")) + { + { + m_param_vec6.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec6").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec6.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec6' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec6' using value:" << m_param_vec6; + } + else + { + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec6' using DEFAULT value:" << m_param_vec6; + } + prop_check.unput("param_vec6"); + } + + //Parser of parameter param_vec7 + { + if (config.check("param_vec7")) + { + { + m_param_vec7.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec7").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec7.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec7' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec7' using value:" << m_param_vec7; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_vec7' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 42"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'm'"; + return false; + } + prop_check.unput("param_vec7"); + } + + //Parser of parameter param_vec8 + { + if (config.check("param_vec8")) + { + { + m_param_vec8.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec8").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec8.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec8' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec8' using value:" << m_param_vec8; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_vec8' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 43"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'm'"; + return false; + } + prop_check.unput("param_vec8"); + } + + //Parser of parameter param_vec9 + { + if (config.check("param_vec9")) + { + { + m_param_vec9.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec9").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec9.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) <<"parameter 'param_vec9' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP1ParamsCOMPONENT) << "Parameter 'param_vec9' using value:" << m_param_vec9; + } + else + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Mandatory parameter 'param_vec9' not found!"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Description of the parameter: Test param 44"; + yCError(TestDeviceWGP1ParamsCOMPONENT) << "Remember: Units for this parameter are: 'm'"; + return false; + } + prop_check.unput("param_vec9"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(TestDeviceWGP1ParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(TestDeviceWGP1ParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string TestDeviceWGP1_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: TestDeviceWGP1\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'param_1': Test param 01\n"); + doc = doc + std::string("'param_2': Test param 02\n"); + doc = doc + std::string("'param_3': Test param 03\n"); + doc = doc + std::string("'param_4': Test param 04\n"); + doc = doc + std::string("'param_5': Test param 05\n"); + doc = doc + std::string("'param_6': Test param 06\n"); + doc = doc + std::string("'param_7': Test param 07\n"); + doc = doc + std::string("'group1::param_1': Test param 08\n"); + doc = doc + std::string("'group1::param_2': Test param 09\n"); + doc = doc + std::string("'group1::param_3': Test param 10\n"); + doc = doc + std::string("'group1::param_4': Test param 11\n"); + doc = doc + std::string("'group2::param_1': Test param 12\n"); + doc = doc + std::string("'group2::param_2': Test param 13\n"); + doc = doc + std::string("'group2::param_3': Test param 14\n"); + doc = doc + std::string("'group2::param_4': Test param 15\n"); + doc = doc + std::string("'group3::param_1': Test param 16\n"); + doc = doc + std::string("'group3::param_2': Test param 17\n"); + doc = doc + std::string("'group3::param_3': Test param 18\n"); + doc = doc + std::string("'group3::param_4': Test param 19\n"); + doc = doc + std::string("'group4::subgroup1::param_1': Test param 20\n"); + doc = doc + std::string("'group4::subgroup1::param_2': Test param 21\n"); + doc = doc + std::string("'group4::subgroup1::param_3': Test param 22\n"); + doc = doc + std::string("'group4::subgroup1::param_4': Test param 23\n"); + doc = doc + std::string("'group4::subgroup2::param_1': Test param 24\n"); + doc = doc + std::string("'group4::subgroup2::param_2': Test param 25\n"); + doc = doc + std::string("'group4::subgroup2::param_3': Test param 26\n"); + doc = doc + std::string("'group4::subgroup2::param_4': Test param 27\n"); + doc = doc + std::string("'group5::subgroup1::param_1': Test param 28\n"); + doc = doc + std::string("'group5::subgroup1::param_2': Test param 29\n"); + doc = doc + std::string("'group5::subgroup1::param_3': Test param 30\n"); + doc = doc + std::string("'group5::subgroup1::param_4': Test param 31\n"); + doc = doc + std::string("'group5::subgroup2::param_1': Test param 32\n"); + doc = doc + std::string("'group5::subgroup2::param_2': Test param 33\n"); + doc = doc + std::string("'group5::subgroup2::param_3': Test param 34\n"); + doc = doc + std::string("'group5::subgroup2::param_4': Test param 35\n"); + doc = doc + std::string("'param_vec1': Test param 36\n"); + doc = doc + std::string("'param_vec2': Test param 37\n"); + doc = doc + std::string("'param_vec3': Test param 38\n"); + doc = doc + std::string("'param_vec4': Test param 39\n"); + doc = doc + std::string("'param_vec5': Test param 40\n"); + doc = doc + std::string("'param_vec6': Test param 41\n"); + doc = doc + std::string("'param_vec7': Test param 42\n"); + doc = doc + std::string("'param_vec8': Test param 43\n"); + doc = doc + std::string("'param_vec9': Test param 44\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device testDeviceWGP1 --param_1 --param_2 --param_3 --param_4 --param_5 --param_6 --param_7 --group1::param_1 --group1::param_2 --group1::param_3 --group1::param_4 --group2::param_1 def1 --group2::param_2 1.0 --group2::param_3 true --group2::param_4 1000 --group3::param_1 def1 --group3::param_2 1.0 --group3::param_3 true --group3::param_4 1000 --group4::subgroup1::param_1 0 --group4::subgroup1::param_2 1 --group4::subgroup1::param_3 2 --group4::subgroup1::param_4 3 --group4::subgroup2::param_1 10 --group4::subgroup2::param_2 11 --group4::subgroup2::param_3 12 --group4::subgroup2::param_4 13 --group5::subgroup1::param_1 20 --group5::subgroup1::param_2 21 --group5::subgroup1::param_3 22 --group5::subgroup1::param_4 23 --group5::subgroup2::param_1 30 --group5::subgroup2::param_2 31 --group5::subgroup2::param_3 32 --group5::subgroup2::param_4 33 --param_vec1 --param_vec2 --param_vec3 --param_vec4 \" (1 2 3) \" --param_vec5 \" (1.0 2.0 3.0) \" --param_vec6 \" (\"sa1\" \"sa2\" \"sa3\") \" --param_vec7 --param_vec8 --param_vec9 \n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device testDeviceWGP1 --param_1 --param_2 --param_3 --param_4 --param_5 --param_6 --param_7 --group1::param_1 --group1::param_2 --group1::param_3 --group1::param_4 --group2::param_1 def1 --group2::param_2 1.0 --group2::param_3 true --group2::param_4 1000 --group5::subgroup1::param_1 20 --group5::subgroup1::param_2 21 --group5::subgroup1::param_3 22 --group5::subgroup1::param_4 23 --group5::subgroup2::param_1 30 --group5::subgroup2::param_2 31 --group5::subgroup2::param_3 32 --group5::subgroup2::param_4 33 --param_vec7 --param_vec8 --param_vec9 \n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_ParamsParser.h b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_ParamsParser.h new file mode 100644 index 00000000000..9ad61a43d4e --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_ParamsParser.h @@ -0,0 +1,208 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Mon Feb 26 23:01:26 2024 + + +#ifndef TESTDEVICEWGP1_PARAMSPARSER_H +#define TESTDEVICEWGP1_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class TestDeviceWGP1. +*TestDeviceWGP is a fake device developed for testing the various functionalities of YarpDeviceParamParserGenerator tool. +*This block has been written with the purpose of testing the --input_extra_comments option. +*This last line has no specific meaning. +*Here there are some extra symbols used in the markdown format, such as the 'code' syntax. +*The **bold text** , the *italic text*, the list: +*1. First element +*2. Second element +*- unordered element 1 +*- unordered element 2 +* +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:-----------------:|:--------------:|:--------------:|:-----:|:-------------------:|:--------:|:-------------:|:-----:| +* | - | param_1 | string | - | - | 1 | Test param 01 | Note | +* | - | param_2 | double | - | - | 1 | Test param 02 | Note | +* | - | param_3 | bool | - | - | 1 | Test param 03 | Note | +* | - | param_4 | int | - | - | 1 | Test param 04 | Note | +* | - | param_5 | char | - | - | 1 | Test param 05 | Note | +* | - | param_6 | size_t | - | - | 1 | Test param 06 | Note | +* | - | param_7 | float | - | - | 1 | Test param 07 | Note | +* | group1 | param_1 | string | - | - | 1 | Test param 08 | Note | +* | group1 | param_2 | double | - | - | 1 | Test param 09 | Note | +* | group1 | param_3 | bool | - | - | 1 | Test param 10 | Note | +* | group1 | param_4 | int | - | - | 1 | Test param 11 | Note | +* | group2 | param_1 | string | - | def1 | 1 | Test param 12 | Note | +* | group2 | param_2 | double | - | 1.0 | 1 | Test param 13 | Note | +* | group2 | param_3 | bool | - | true | 1 | Test param 14 | Note | +* | group2 | param_4 | int | - | 1000 | 1 | Test param 15 | Note | +* | group3 | param_1 | string | - | def1 | 0 | Test param 16 | Note | +* | group3 | param_2 | double | - | 1.0 | 0 | Test param 17 | Note | +* | group3 | param_3 | bool | - | true | 0 | Test param 18 | Note | +* | group3 | param_4 | int | - | 1000 | 0 | Test param 19 | Note | +* | group4::subgroup1 | param_1 | int | s | 0 | 0 | Test param 20 | Note | +* | group4::subgroup1 | param_2 | int | s | 1 | 0 | Test param 21 | Note | +* | group4::subgroup1 | param_3 | int | s | 2 | 0 | Test param 22 | Note | +* | group4::subgroup1 | param_4 | int | s | 3 | 0 | Test param 23 | Note | +* | group4::subgroup2 | param_1 | int | ms | 10 | 0 | Test param 24 | Note | +* | group4::subgroup2 | param_2 | int | ms | 11 | 0 | Test param 25 | Note | +* | group4::subgroup2 | param_3 | int | ms | 12 | 0 | Test param 26 | Note | +* | group4::subgroup2 | param_4 | int | ms | 13 | 0 | Test param 27 | Note | +* | group5::subgroup1 | param_1 | int | N | 20 | 1 | Test param 28 | Note | +* | group5::subgroup1 | param_2 | int | N | 21 | 1 | Test param 29 | Note | +* | group5::subgroup1 | param_3 | int | N | 22 | 1 | Test param 30 | Note | +* | group5::subgroup1 | param_4 | int | N | 23 | 1 | Test param 31 | Note | +* | group5::subgroup2 | param_1 | int | mN | 30 | 1 | Test param 32 | Note | +* | group5::subgroup2 | param_2 | int | mN | 31 | 1 | Test param 33 | Note | +* | group5::subgroup2 | param_3 | int | mN | 32 | 1 | Test param 34 | Note | +* | group5::subgroup2 | param_4 | int | mN | 33 | 1 | Test param 35 | Note | +* | - | param_vec1 | vector | m | - | 0 | Test param 36 | Note | +* | - | param_vec2 | vector | m | - | 0 | Test param 37 | Note | +* | - | param_vec3 | vector | m | - | 0 | Test param 38 | Note | +* | - | param_vec4 | vector | m | (1 2 3) | 0 | Test param 39 | Note | +* | - | param_vec5 | vector | m | (1.0 2.0 3.0) | 0 | Test param 40 | Note | +* | - | param_vec6 | vector | m | ("sa1" "sa2" "sa3") | 0 | Test param 41 | Note | +* | - | param_vec7 | vector | m | - | 1 | Test param 42 | Note | +* | - | param_vec8 | vector | m | - | 1 | Test param 43 | Note | +* | - | param_vec9 | vector | m | - | 1 | Test param 44 | Note | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device testDeviceWGP1 --param_1 --param_2 --param_3 --param_4 --param_5 --param_6 --param_7 --group1::param_1 --group1::param_2 --group1::param_3 --group1::param_4 --group2::param_1 def1 --group2::param_2 1.0 --group2::param_3 true --group2::param_4 1000 --group3::param_1 def1 --group3::param_2 1.0 --group3::param_3 true --group3::param_4 1000 --group4::subgroup1::param_1 0 --group4::subgroup1::param_2 1 --group4::subgroup1::param_3 2 --group4::subgroup1::param_4 3 --group4::subgroup2::param_1 10 --group4::subgroup2::param_2 11 --group4::subgroup2::param_3 12 --group4::subgroup2::param_4 13 --group5::subgroup1::param_1 20 --group5::subgroup1::param_2 21 --group5::subgroup1::param_3 22 --group5::subgroup1::param_4 23 --group5::subgroup2::param_1 30 --group5::subgroup2::param_2 31 --group5::subgroup2::param_3 32 --group5::subgroup2::param_4 33 --param_vec1 --param_vec2 --param_vec3 --param_vec4 \" (1 2 3) \" --param_vec5 \" (1.0 2.0 3.0) \" --param_vec6 \" (\"sa1\" \"sa2\" \"sa3\") \" --param_vec7 --param_vec8 --param_vec9 +* \endcode +* +* \code{.unparsed} +* yarpdev --device testDeviceWGP1 --param_1 --param_2 --param_3 --param_4 --param_5 --param_6 --param_7 --group1::param_1 --group1::param_2 --group1::param_3 --group1::param_4 --group2::param_1 def1 --group2::param_2 1.0 --group2::param_3 true --group2::param_4 1000 --group5::subgroup1::param_1 20 --group5::subgroup1::param_2 21 --group5::subgroup1::param_3 22 --group5::subgroup1::param_4 23 --group5::subgroup2::param_1 30 --group5::subgroup2::param_2 31 --group5::subgroup2::param_3 32 --group5::subgroup2::param_4 33 --param_vec7 --param_vec8 --param_vec9 +* \endcode +* +*/ + +class TestDeviceWGP1_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + TestDeviceWGP1_ParamsParser(); + ~TestDeviceWGP1_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"TestDeviceWGP1"}; + const std::string m_device_name = {"testDeviceWGP1"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_param_1_defaultValue = {""}; + const std::string m_param_2_defaultValue = {""}; + const std::string m_param_3_defaultValue = {""}; + const std::string m_param_4_defaultValue = {""}; + const std::string m_param_5_defaultValue = {""}; + const std::string m_param_6_defaultValue = {""}; + const std::string m_param_7_defaultValue = {""}; + const std::string m_group1_param_1_defaultValue = {""}; + const std::string m_group1_param_2_defaultValue = {""}; + const std::string m_group1_param_3_defaultValue = {""}; + const std::string m_group1_param_4_defaultValue = {""}; + const std::string m_group2_param_1_defaultValue = {"def1"}; + const std::string m_group2_param_2_defaultValue = {"1.0"}; + const std::string m_group2_param_3_defaultValue = {"true"}; + const std::string m_group2_param_4_defaultValue = {"1000"}; + const std::string m_group3_param_1_defaultValue = {"def1"}; + const std::string m_group3_param_2_defaultValue = {"1.0"}; + const std::string m_group3_param_3_defaultValue = {"true"}; + const std::string m_group3_param_4_defaultValue = {"1000"}; + const std::string m_group4_subgroup1_param_1_defaultValue = {"0"}; + const std::string m_group4_subgroup1_param_2_defaultValue = {"1"}; + const std::string m_group4_subgroup1_param_3_defaultValue = {"2"}; + const std::string m_group4_subgroup1_param_4_defaultValue = {"3"}; + const std::string m_group4_subgroup2_param_1_defaultValue = {"10"}; + const std::string m_group4_subgroup2_param_2_defaultValue = {"11"}; + const std::string m_group4_subgroup2_param_3_defaultValue = {"12"}; + const std::string m_group4_subgroup2_param_4_defaultValue = {"13"}; + const std::string m_group5_subgroup1_param_1_defaultValue = {"20"}; + const std::string m_group5_subgroup1_param_2_defaultValue = {"21"}; + const std::string m_group5_subgroup1_param_3_defaultValue = {"22"}; + const std::string m_group5_subgroup1_param_4_defaultValue = {"23"}; + const std::string m_group5_subgroup2_param_1_defaultValue = {"30"}; + const std::string m_group5_subgroup2_param_2_defaultValue = {"31"}; + const std::string m_group5_subgroup2_param_3_defaultValue = {"32"}; + const std::string m_group5_subgroup2_param_4_defaultValue = {"33"}; + const std::string m_param_vec1_defaultValue = {""}; + const std::string m_param_vec2_defaultValue = {""}; + const std::string m_param_vec3_defaultValue = {""}; + const std::string m_param_vec4_defaultValue = {"(1 2 3)"}; + const std::string m_param_vec5_defaultValue = {"(1.0 2.0 3.0)"}; + const std::string m_param_vec6_defaultValue = {"(\"sa1\" \"sa2\" \"sa3\")"}; + const std::string m_param_vec7_defaultValue = {""}; + const std::string m_param_vec8_defaultValue = {""}; + const std::string m_param_vec9_defaultValue = {""}; + + std::string m_param_1 = {}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + double m_param_2 = {std::nan("1")}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + bool m_param_3 = {false}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + int m_param_4 = {0}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + char m_param_5 = {0}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + size_t m_param_6 = {0}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + float m_param_7 = {std::nanf("1")}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + std::string m_group1_param_1 = {}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + double m_group1_param_2 = {std::nan("1")}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + bool m_group1_param_3 = {false}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + int m_group1_param_4 = {0}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + std::string m_group2_param_1 = {"def1"}; + double m_group2_param_2 = {1.0}; + bool m_group2_param_3 = {true}; + int m_group2_param_4 = {1000}; + std::string m_group3_param_1 = {"def1"}; + double m_group3_param_2 = {1.0}; + bool m_group3_param_3 = {true}; + int m_group3_param_4 = {1000}; + int m_group4_subgroup1_param_1 = {0}; + int m_group4_subgroup1_param_2 = {1}; + int m_group4_subgroup1_param_3 = {2}; + int m_group4_subgroup1_param_4 = {3}; + int m_group4_subgroup2_param_1 = {10}; + int m_group4_subgroup2_param_2 = {11}; + int m_group4_subgroup2_param_3 = {12}; + int m_group4_subgroup2_param_4 = {13}; + int m_group5_subgroup1_param_1 = {20}; + int m_group5_subgroup1_param_2 = {21}; + int m_group5_subgroup1_param_3 = {22}; + int m_group5_subgroup1_param_4 = {23}; + int m_group5_subgroup2_param_1 = {30}; + int m_group5_subgroup2_param_2 = {31}; + int m_group5_subgroup2_param_3 = {32}; + int m_group5_subgroup2_param_4 = {33}; + std::vector m_param_vec1 = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec2 = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec3 = {}; //The default value of this list is an empty list. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec4 = { }; //Default values for lists are managed in the class constructor. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec5 = { }; //Default values for lists are managed in the class constructor. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec6 = { }; //Default values for lists are managed in the class constructor. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec7 = {}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + std::vector m_param_vec8 = {}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + std::vector m_param_vec9 = {}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_test.cpp b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_test.cpp new file mode 100644 index 00000000000..eb9e1c48f08 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test1/TestDeviceWGP1_test.cpp @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include +#include + +using namespace yarp::dev; +using namespace yarp::os; + +TEST_CASE("dev::TestDeviceWGP1", "[yarp::dev]") +{ + YARP_REQUIRE_PLUGIN("testDeviceWGP1", "device"); + + Network::setLocalMode(true); + + SECTION("Checking TestDeviceWGP1 help") + { + PolyDriver dd; + Property p_cfg; + p_cfg.put("device", "testDeviceWGP1"); + p_cfg.put("help",""); + REQUIRE(dd.open(p_cfg)==false); + } + + SECTION("Checking TestDeviceWGP1 device") + { + PolyDriver dd; + + ////////"Checking opening polydriver with no attached device" + { + Property p_cfg; + p_cfg.put("device", "testDeviceWGP1"); + + p_cfg.put("param_1", "string"); + p_cfg.put("param_2", 1.00000); + p_cfg.put("param_3", true); + p_cfg.put("param_4", 1); + p_cfg.put("param_5", 'a'); + p_cfg.put("param_6", 10); + p_cfg.put("param_7", 1.0); + + Property& pp_cfg1 = p_cfg.addGroup("group1"); + pp_cfg1.put ("param_1", "def10"); + pp_cfg1.put ("param_2", 101); + pp_cfg1.put ("param_3", true); + pp_cfg1.put ("param_4", 1001); + + Property& pp_cfg2 = p_cfg.addGroup("group2"); + pp_cfg2.put ("param_1", "def20"); + pp_cfg2.put ("param_2", 102); + pp_cfg2.put ("param_3", true); + pp_cfg2.put ("param_4", 1002); + + Property& pp_cfg5 = p_cfg.addGroup("group5"); + Property& ppp_cfg1 = pp_cfg5.addGroup("subgroup1"); + Property& ppp_cfg2 = pp_cfg5.addGroup("subgroup2"); + ppp_cfg1.put("param_1", 200); + ppp_cfg1.put("param_2", 210); + ppp_cfg1.put("param_3", 220); + ppp_cfg1.put("param_4", 230); + ppp_cfg2.put("param_1", 300); + ppp_cfg2.put("param_2", 310); + ppp_cfg2.put("param_3", 320); + ppp_cfg2.put("param_4", 330); + + yarp::os::Value v7; v7.fromString("(1 2 3)"); + p_cfg.put("param_vec7", v7); + + p_cfg.put("param_vec8", yarp::os::Bottle("(1.0 2.0 3.0)").get(0)); + + yarp::os::Bottle b9; b9.fromString("(sa1 sa2 sa3)"); + int i=b9.size(); + p_cfg.put("param_vec9", b9.get(0)); + + REQUIRE(dd.open(p_cfg)); + + yarp::dev::IDeviceDriverParams* idevparams = nullptr; + REQUIRE (dd.view(idevparams)); + REQUIRE (idevparams!=nullptr); + + std::string ss1 = idevparams->getDeviceClassName(); + CHECK (ss1 == "TestDeviceWGP1"); + std::string ss2 = idevparams->getDeviceName(); + CHECK (ss2 == "testDeviceWGP1"); + + std::vector vv = idevparams->getListOfParams(); + CHECK(vv.empty() == false); + } + + yarp::os::Time::delay(1.0); + + //"Close all polydrivers and check" + { + CHECK(dd.close()); + } + + } + + Network::setLocalMode(false); +} diff --git a/src/yarpDeviceParamParserGenerator/tests/extraComments.md b/src/yarpDeviceParamParserGenerator/tests/test1/extraComments.md similarity index 100% rename from src/yarpDeviceParamParserGenerator/tests/extraComments.md rename to src/yarpDeviceParamParserGenerator/tests/test1/extraComments.md diff --git a/src/yarpDeviceParamParserGenerator/tests/test1/test1.txt b/src/yarpDeviceParamParserGenerator/tests/test1/test1.txt new file mode 100644 index 00000000000..b966f348046 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test1/test1.txt @@ -0,0 +1,44 @@ +| - | param_1 | string | - | - | Yes | Test param 01 | Note | +| - | param_2 | double | - | - | Yes | Test param 02 | Note | +| - | param_3 | bool | - | - | Yes | Test param 03 | Note | +| - | param_4 | int | - | - | Yes | Test param 04 | Note | +| - | param_5 | char | - | - | Yes | Test param 05 | Note | +| - | param_6 | size_t | - | - | Yes | Test param 06 | Note | +| - | param_7 | float | - | - | Yes | Test param 07 | Note | +| group1 | param_1 | string | - | - | Yes | Test param 08 | Note | +| group1 | param_2 | double | - | - | Yes | Test param 09 | Note | +| group1 | param_3 | bool | - | - | Yes | Test param 10 | Note | +| group1 | param_4 | int | - | - | Yes | Test param 11 | Note | +| group2 | param_1 | string | - | def1 | Yes | Test param 12 | Note | +| group2 | param_2 | double | - | 1.0 | Yes | Test param 13 | Note | +| group2 | param_3 | bool | - | true | Yes | Test param 14 | Note | +| group2 | param_4 | int | - | 1000 | Yes | Test param 15 | Note | +| group3 | param_1 | string | - | def1 | No | Test param 16 | Note | +| group3 | param_2 | double | - | 1.0 | No | Test param 17 | Note | +| group3 | param_3 | bool | - | true | No | Test param 18 | Note | +| group3 | param_4 | int | - | 1000 | No | Test param 19 | Note | +| group4::subgroup1 | param_1 | int | s | 0 | No | Test param 20 | Note | +| group4::subgroup1 | param_2 | int | s | 1 | No | Test param 21 | Note | +| group4::subgroup1 | param_3 | int | s | 2 | No | Test param 22 | Note | +| group4::subgroup1 | param_4 | int | s | 3 | No | Test param 23 | Note | +| group4::subgroup2 | param_1 | int | ms | 10 | No | Test param 24 | Note | +| group4::subgroup2 | param_2 | int | ms | 11 | No | Test param 25 | Note | +| group4::subgroup2 | param_3 | int | ms | 12 | No | Test param 26 | Note | +| group4::subgroup2 | param_4 | int | ms | 13 | No | Test param 27 | Note | +| group5::subgroup1 | param_1 | int | N | 20 | Yes | Test param 28 | Note | +| group5::subgroup1 | param_2 | int | N | 21 | Yes | Test param 29 | Note | +| group5::subgroup1 | param_3 | int | N | 22 | Yes | Test param 30 | Note | +| group5::subgroup1 | param_4 | int | N | 23 | Yes | Test param 31 | Note | +| group5::subgroup2 | param_1 | int | mN | 30 | Yes | Test param 32 | Note | +| group5::subgroup2 | param_2 | int | mN | 31 | Yes | Test param 33 | Note | +| group5::subgroup2 | param_3 | int | mN | 32 | Yes | Test param 34 | Note | +| group5::subgroup2 | param_4 | int | mN | 33 | Yes | Test param 35 | Note | +| - | param_vec1 | vector | m | | No | Test param 36 | Note | +| - | param_vec2 | vector | m | | No | Test param 37 | Note | +| - | param_vec3 | vector | m | | No | Test param 38 | Note | +| - | param_vec4 | vector | m | (1 2 3) | No | Test param 39 | Note | +| - | param_vec5 | vector | m | (1.0 2.0 3.0) | No | Test param 40 | Note | +| - | param_vec6 | vector | m | ("sa1" "sa2" "sa3") | No | Test param 41 | Note | +| - | param_vec7 | vector | m | | Yes | Test param 42 | Note | +| - | param_vec8 | vector | m | | Yes | Test param 43 | Note | +| - | param_vec9 | vector | m | | Yes | Test param 44 | Note | diff --git a/src/yarpDeviceParamParserGenerator/tests/test1/test2.txt b/src/yarpDeviceParamParserGenerator/tests/test1/test2.txt new file mode 100644 index 00000000000..ef29eb088a1 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test1/test2.txt @@ -0,0 +1,46 @@ +| Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +|:--------------------:|:--------------------:|:--------------:|:-------:|:--------------------:|:--------:|:-------------:|:-----------:| +| - | param_1 | string | - | - | Yes | Test param 01 | Note | +| - | param_2 | double | - | - | Yes | Test param 02 | Note | +| - | param_3 | bool | - | - | Yes | Test param 03 | Note | +| - | param_4 | int | - | - | Yes | Test param 04 | Note | +| - | param_5 | char | - | - | Yes | Test param 05 | Note | +| - | param_6 | size_t | - | - | Yes | Test param 06 | Note | +| - | param_7 | float | - | - | Yes | Test param 07 | Note | +| group1 | param_1 | string | - | - | Yes | Test param 08 | Note | +| group1 | param_2 | double | - | - | Yes | Test param 09 | Note | +| group1 | param_3 | bool | - | - | Yes | Test param 10 | Note | +| group1 | param_4 | int | - | - | Yes | Test param 11 | Note | +| group2 | param_1 | string | - | def1 | Yes | Test param 12 | Note | +| group2 | param_2 | double | - | 1.0 | Yes | Test param 13 | Note | +| group2 | param_3 | bool | - | true | Yes | Test param 14 | Note | +| group2 | param_4 | int | - | 1000 | Yes | Test param 15 | Note | +| group3 | param_1 | string | - | def1 | No | Test param 16 | Note | +| group3 | param_2 | double | - | 1.0 | No | Test param 17 | Note | +| group3 | param_3 | bool | - | true | No | Test param 18 | Note | +| group3 | param_4 | int | - | 1000 | No | Test param 19 | Note | +| group4::subgroup1 | param_1 | int | s | 0 | No | Test param 20 | Note | +| group4::subgroup1 | param_2 | int | s | 1 | No | Test param 21 | Note | +| group4::subgroup1 | param_3 | int | s | 2 | No | Test param 22 | Note | +| group4::subgroup1 | param_4 | int | s | 3 | No | Test param 23 | Note | +| group4::subgroup2 | param_1 | int | ms | 10 | No | Test param 24 | Note | +| group4::subgroup2 | param_2 | int | ms | 11 | No | Test param 25 | Note | +| group4::subgroup2 | param_3 | int | ms | 12 | No | Test param 26 | Note | +| group4::subgroup2 | param_4 | int | ms | 13 | No | Test param 27 | Note | +| group5::subgroup1 | param_1 | int | N | 20 | Yes | Test param 28 | Note | +| group5::subgroup1 | param_2 | int | N | 21 | Yes | Test param 29 | Note | +| group5::subgroup1 | param_3 | int | N | 22 | Yes | Test param 30 | Note | +| group5::subgroup1 | param_4 | int | N | 23 | Yes | Test param 31 | Note | +| group5::subgroup2 | param_1 | int | mN | 30 | Yes | Test param 32 | Note | +| group5::subgroup2 | param_2 | int | mN | 31 | Yes | Test param 33 | Note | +| group5::subgroup2 | param_3 | int | mN | 32 | Yes | Test param 34 | Note | +| group5::subgroup2 | param_4 | int | mN | 33 | Yes | Test param 35 | Note | +| - | param_vec1 | vector | m | | No | Test param 36 | Note | +| - | param_vec2 | vector | m | | No | Test param 37 | Note | +| - | param_vec3 | vector | m | | No | Test param 38 | Note | +| - | param_vec4 | vector | m | (1 2 3) | No | Test param 39 | Note | +| - | param_vec5 | vector | m | (1.0 2.0 3.0) | No | Test param 40 | Note | +| - | param_vec6 | vector | m | ("sa1" "sa2" "sa3") | No | Test param 41 | Note | +| - | param_vec7 | vector | m | | Yes | Test param 42 | Note | +| - | param_vec8 | vector | m | | Yes | Test param 43 | Note | +| - | param_vec9 | vector | m | | Yes | Test param 44 | Note | diff --git a/src/yarpDeviceParamParserGenerator/tests/test2.txt b/src/yarpDeviceParamParserGenerator/tests/test2.txt deleted file mode 100644 index 677b9b2d288..00000000000 --- a/src/yarpDeviceParamParserGenerator/tests/test2.txt +++ /dev/null @@ -1,13 +0,0 @@ -| Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | -|:----------:|:--------------------:|:------:|:-------:|:-------------:|:--------:|:-----------------------------------------------------------------------------------------------------:|:-----------:| -| - | file_name | string | - | audio_out.wav | Yes | The name of the file written by the module | Only.wav and .mp3 files are supported | -| - | mode | string | - | mode1 | No | This fake parameter chooses the fake algorithm to be used | | -| - | add_marker | bool | - | false | No | Some description of param. | | -| group1 | param_a | bool | - | false | No | Some description of param. | | -| group2 | param_a | bool | - | false | No | Some description of param. | | -| - | period | double | s | - | Yes | Algorithm control loop period | | -| - | initial_ref | double | m | 3 | No | An initial value for the algorithm | | -| group3::subgroup1 | param_1 | bool | - | false | Yes | This is a parameter for testing purposes | | -| group3::subgroup1 | param_2 | bool | - | true | No | This is a parameter for testing purposes | | -| group3 | param_3 | bool | - | false | No | This is a parameter for testing purposes | | -| group3::subgroup2 | param_4 | bool | - | true | No | This is a parameter for testing purposes | | diff --git a/src/yarpDeviceParamParserGenerator/tests/test2/CMakeLists.txt b/src/yarpDeviceParamParserGenerator/tests/test2/CMakeLists.txt new file mode 100644 index 00000000000..d3f9ada3497 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test2/CMakeLists.txt @@ -0,0 +1,69 @@ +# SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) +# SPDX-License-Identifier: BSD-3-Clause + +include(YarpPlugin) +include(YarpPrintFeature) +include(YarpCatchUtils) +include(YarpDeviceParamsParserGenerator) + +yarp_prepare_plugin(testDeviceWGP2 + CATEGORY device + TYPE TestDeviceWGP2 + INCLUDE TestDeviceWGP2.h + DEFAULT ON +) + +#This is a test so we always want to generate the parser, regardless the value of ALLOW_DEVICE_PARAM_PARSER_GENERATION. +#With add_custom_target and add_dependencies we create a dependency so that first yarpDeviceParamParserGenerator is executed +#then the device is compiled, using the generated files. +add_custom_target(generate_parser2 COMMAND yarpDeviceParamParserGenerator + --class_name TestDeviceWGP2 + --module_name testDeviceWGP2 + --input_filename_md test.txt + --input_extra_comments extraComments.md + --generate_all + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +yarp_add_plugin(yarp_testDeviceWGP2) + +add_dependencies(yarp_testDeviceWGP2 generate_parser2) + +target_sources(yarp_testDeviceWGP2 + PRIVATE + TestDeviceWGP2.cpp + TestDeviceWGP2.h + TestDeviceWGP2_ParamsParser.cpp + TestDeviceWGP2_ParamsParser.h +) + +target_link_libraries(yarp_testDeviceWGP2 + PRIVATE + YARP::YARP_os + YARP::YARP_dev +) +list(APPEND YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS + YARP_os + YARP_dev +) + + yarp_install( + TARGETS yarp_testDeviceWGP2 + EXPORT YARP_${YARP_PLUGIN_MASTER} + COMPONENT ${YARP_PLUGIN_MASTER} + LIBRARY DESTINATION ${YARP_DYNAMIC_PLUGINS_INSTALL_DIR} + ARCHIVE DESTINATION ${YARP_STATIC_PLUGINS_INSTALL_DIR} + YARP_INI DESTINATION ${YARP_PLUGIN_MANIFESTS_INSTALL_DIR} + ) + +source_group("OtherFiles" FILES + testDeviceWGP2Params.ini + testDeviceWGP2Params.md + testDeviceWGP2Params.xml +) + +set(YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS ${YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS} PARENT_SCOPE) + +set_property(TARGET yarp_testDeviceWGP2 PROPERTY FOLDER "Test") +set_property(TARGET generate_parser2 PROPERTY FOLDER "Test") + +create_device_test(TestDeviceWGP2) diff --git a/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2.cpp b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2.cpp new file mode 100644 index 00000000000..b37b52ba691 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2.cpp @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "TestDeviceWGP2.h" + +#include +#include + +using namespace yarp::os; +using namespace yarp::dev; + +TestDeviceWGP2::TestDeviceWGP2() +{ +} + +TestDeviceWGP2::~TestDeviceWGP2() +{ +} + +bool TestDeviceWGP2::do_test() +{ + { + if (m_param_vec4.size() != 3) { yError() << "error vec4 size"; return false; } + if (m_param_vec5.size() != 3) { yError() << "error vec5 size"; return false; } + if (m_param_vec6.size() != 3) { yError() << "error vec6 size"; return false; } + + if (m_param_vec4[0] != 1 || + m_param_vec4[1] != 2 || + m_param_vec4[2] != 3) { + yError() << "error vec4 content"; return false; } + + if (m_param_vec5[0] != 1 || + m_param_vec5[1] != 2 || + m_param_vec5[2] != 3) { + yError() << "error vec5 content"; return false; } + + if (m_param_vec6[0] != "sa1" || + m_param_vec6[1] != "sa2" || + m_param_vec6[2] != "sa3") { + yError() << "error vec5 content"; return false; } + } + + { + if (m_param_vec7.size() != 3) { yError() << "error vec7 size"; return false; } + if (m_param_vec8.size() != 3) { yError() << "error vec8 size"; return false; } + if (m_param_vec9.size() != 3) { yError() << "error vec9 size"; return false; } + + if (m_param_vec7[0] != 1 || + m_param_vec7[1] != 2 || + m_param_vec7[2] != 3) { + yError() << "error vec7 content"; return false; + } + + if (m_param_vec8[0] != 1 || + m_param_vec8[1] != 2 || + m_param_vec8[2] != 3) { + yError() << "error vec8 content"; return false; + } + + if (m_param_vec9[0] != "sa1" || + m_param_vec9[1] != "sa2" || + m_param_vec9[2] != "sa3") { + yError() << "error vec9 content"; return false; + } + } + + return true; +} + +bool TestDeviceWGP2::open(yarp::os::Searchable &config) +{ + bool ret = parseParams(config); + if (!ret) { yError() << "parseParams() failed"; return false; } + + ret = do_test(); + if (!ret) { yError() << "do_test() failed"; return false; } + + return true; +} + +bool TestDeviceWGP2::close() +{ + return true; +} diff --git a/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2.h b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2.h new file mode 100644 index 00000000000..4a48ff3c7a1 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "TestDeviceWGP2_ParamsParser.h" + +#include + +/** +* @ingroup dev_impl_media +* +* \brief `TestDeviceWGP2` : A test device driver, for Continuous Integration purposes. +* +* Parameters required by this device are shown in class: TestDeviceWGP_ParamsParser +*/ + +class TestDeviceWGP2 : + public yarp::dev::DeviceDriver, + public TestDeviceWGP2_ParamsParser +{ +public: + TestDeviceWGP2(); + TestDeviceWGP2(const TestDeviceWGP2&) = delete; + TestDeviceWGP2(TestDeviceWGP2&&) = delete; + TestDeviceWGP2& operator=(const TestDeviceWGP2&) = delete; + TestDeviceWGP2& operator=(TestDeviceWGP2&&) = delete; + ~TestDeviceWGP2() override; + + // Device Driver interface + bool open(yarp::os::Searchable &config) override; + bool close() override; + + private: + bool do_test(); +}; diff --git a/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_ParamsParser.cpp b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_ParamsParser.cpp new file mode 100644 index 00000000000..57e715e1668 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_ParamsParser.cpp @@ -0,0 +1,339 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Mon Feb 26 22:51:46 2024 + + +#include "TestDeviceWGP2_ParamsParser.h" +#include +#include + +namespace { + YARP_LOG_COMPONENT(TestDeviceWGP2ParamsCOMPONENT, "yarp.device.TestDeviceWGP2") +} + + +TestDeviceWGP2_ParamsParser::TestDeviceWGP2_ParamsParser() +{ + //Default value of parameterparam_vec4 + { + m_param_vec4.clear(); + yarp::os::Value tempVal; + tempVal.fromString(m_param_vec4_defaultValue.c_str()); + yarp::os::Bottle* tempBot = tempVal.asList(); + if (tempBot && tempBot->size()!=0) + { + for (size_t i=0; isize(); i++) + { + m_param_vec4.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yError() <<"parameter 'param_vec4' is not a properly formatted bottle"; + } + } + + //Default value of parameterparam_vec5 + { + m_param_vec5.clear(); + yarp::os::Value tempVal; + tempVal.fromString(m_param_vec5_defaultValue.c_str()); + yarp::os::Bottle* tempBot = tempVal.asList(); + if (tempBot && tempBot->size()!=0) + { + for (size_t i=0; isize(); i++) + { + m_param_vec5.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yError() <<"parameter 'param_vec5' is not a properly formatted bottle"; + } + } + + //Default value of parameterparam_vec6 + { + m_param_vec6.clear(); + yarp::os::Value tempVal; + tempVal.fromString(m_param_vec6_defaultValue.c_str()); + yarp::os::Bottle* tempBot = tempVal.asList(); + if (tempBot && tempBot->size()!=0) + { + for (size_t i=0; isize(); i++) + { + m_param_vec6.push_back(tempBot->get(i).asString()); + } + } + else + { + yError() <<"parameter 'param_vec6' is not a properly formatted bottle"; + } + } + +} + + +std::vector TestDeviceWGP2_ParamsParser::getListOfParams() const +{ + std::vector params; + params.push_back("param_vec4"); + params.push_back("param_vec5"); + params.push_back("param_vec6"); + params.push_back("param_vec7"); + params.push_back("param_vec8"); + params.push_back("param_vec9"); + return params; +} + + +bool TestDeviceWGP2_ParamsParser::parseParams(const yarp::os::Searchable & config) +{ + //Check for --help option + if (config.check("help")) + { + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << getDocumentationOfDeviceParams(); + } + + std::string config_string = config.toString(); + yarp::os::Property prop_check(config_string.c_str()); + //Parser of parameter param_vec4 + { + if (config.check("param_vec4")) + { + { + m_param_vec4.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec4").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec4.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) <<"parameter 'param_vec4' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec4' using value:" << m_param_vec4; + } + else + { + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec4' using DEFAULT value:" << m_param_vec4; + } + prop_check.unput("param_vec4"); + } + + //Parser of parameter param_vec5 + { + if (config.check("param_vec5")) + { + { + m_param_vec5.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec5").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec5.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) <<"parameter 'param_vec5' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec5' using value:" << m_param_vec5; + } + else + { + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec5' using DEFAULT value:" << m_param_vec5; + } + prop_check.unput("param_vec5"); + } + + //Parser of parameter param_vec6 + { + if (config.check("param_vec6")) + { + { + m_param_vec6.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec6").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec6.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) <<"parameter 'param_vec6' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec6' using value:" << m_param_vec6; + } + else + { + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec6' using DEFAULT value:" << m_param_vec6; + } + prop_check.unput("param_vec6"); + } + + //Parser of parameter param_vec7 + { + if (config.check("param_vec7")) + { + { + m_param_vec7.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec7").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec7.push_back(tempBot->get(i).asInt64()); + } + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) <<"parameter 'param_vec7' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec7' using value:" << m_param_vec7; + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Mandatory parameter 'param_vec7' not found!"; + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Description of the parameter: Test param 42"; + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Remember: Units for this parameter are: 'm'"; + return false; + } + prop_check.unput("param_vec7"); + } + + //Parser of parameter param_vec8 + { + if (config.check("param_vec8")) + { + { + m_param_vec8.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec8").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec8.push_back(tempBot->get(i).asFloat64()); + } + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) <<"parameter 'param_vec8' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec8' using value:" << m_param_vec8; + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Mandatory parameter 'param_vec8' not found!"; + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Description of the parameter: Test param 43"; + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Remember: Units for this parameter are: 'm'"; + return false; + } + prop_check.unput("param_vec8"); + } + + //Parser of parameter param_vec9 + { + if (config.check("param_vec9")) + { + { + m_param_vec9.clear(); + yarp::os::Bottle* tempBot = config.find("param_vec9").asList(); + if (tempBot) + { + std::string tempBots = tempBot->toString(); + for (size_t i=0; isize(); i++) + { + m_param_vec9.push_back(tempBot->get(i).asString()); + } + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) <<"parameter 'param_vec9' is not a properly formatted bottle"; + } + } + yCInfo(TestDeviceWGP2ParamsCOMPONENT) << "Parameter 'param_vec9' using value:" << m_param_vec9; + } + else + { + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Mandatory parameter 'param_vec9' not found!"; + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Description of the parameter: Test param 44"; + yCError(TestDeviceWGP2ParamsCOMPONENT) << "Remember: Units for this parameter are: 'm'"; + return false; + } + prop_check.unput("param_vec9"); + } + + /* + //This code check if the user set some parameter which are not check by the parser + //If the parser is set in strict mode, this will generate an error + if (prop_check.size() > 0) + { + bool extra_params_found = false; + for (auto it=prop_check.begin(); it!=prop_check.end(); it++) + { + if (m_parser_is_strict) + { + yCError(TestDeviceWGP2ParamsCOMPONENT) << "User asking for parameter: "<name <<" which is unknown to this parser!"; + extra_params_found = true; + } + else + { + yCWarning(TestDeviceWGP2ParamsCOMPONENT) << "User asking for parameter: "<< it->name <<" which is unknown to this parser!"; + } + } + + if (m_parser_is_strict && extra_params_found) + { + return false; + } + } + */ + return true; +} + + +std::string TestDeviceWGP2_ParamsParser::getDocumentationOfDeviceParams() const +{ + std::string doc; + doc = doc + std::string("\n=============================================\n"); + doc = doc + std::string("This is the help for device: TestDeviceWGP2\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("This is the list of the parameters accepted by the device:\n"); + doc = doc + std::string("'param_vec4': Test param 39\n"); + doc = doc + std::string("'param_vec5': Test param 40\n"); + doc = doc + std::string("'param_vec6': Test param 41\n"); + doc = doc + std::string("'param_vec7': Test param 42\n"); + doc = doc + std::string("'param_vec8': Test param 43\n"); + doc = doc + std::string("'param_vec9': Test param 44\n"); + doc = doc + std::string("\n"); + doc = doc + std::string("Here are some examples of invocation command with yarpdev, with all params:\n"); + doc = doc + " yarpdev --device testDeviceWGP2 --param_vec4 \" (1 2 3) \" --param_vec5 \" (1.0 2.0 3.0) \" --param_vec6 \" (\"sa1\" \"sa2\" \"sa3\") \" --param_vec7 --param_vec8 --param_vec9 \n"; + doc = doc + std::string("Using only mandatory params:\n"); + doc = doc + " yarpdev --device testDeviceWGP2 --param_vec7 --param_vec8 --param_vec9 \n"; + doc = doc + std::string("=============================================\n\n"); return doc; +} diff --git a/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_ParamsParser.h b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_ParamsParser.h new file mode 100644 index 00000000000..496e73d175d --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_ParamsParser.h @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + + +// Generated by yarpDeviceParamParserGenerator (1.0) +// This is an automatically generated file. Please do not edit it. +// It will be re-generated if the cmake flag ALLOW_DEVICE_PARAM_PARSER_GERNERATION is ON. + +// Generated on: Mon Feb 26 22:51:46 2024 + + +#ifndef TESTDEVICEWGP2_PARAMSPARSER_H +#define TESTDEVICEWGP2_PARAMSPARSER_H + +#include +#include +#include +#include + +/** +* This class is the parameters parser for class TestDeviceWGP2. +*TestDeviceWGP is a fake device developed for testing the various functionalities of YarpDeviceParamParserGenerator tool. +*This block has been written with the purpose of testing the --input_extra_comments option. +*This last line has no specific meaning. +*Here there are some extra symbols used in the markdown format, such as the 'code' syntax. +*The **bold text** , the *italic text*, the list: +*1. First element +*2. Second element +*- unordered element 1 +*- unordered element 2 +* +* +* These are the used parameters: +* | Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +* |:----------:|:--------------:|:--------------:|:-----:|:-------------------:|:--------:|:-------------:|:-----:| +* | - | param_vec4 | vector | m | (1 2 3) | 0 | Test param 39 | Note | +* | - | param_vec5 | vector | m | (1.0 2.0 3.0) | 0 | Test param 40 | Note | +* | - | param_vec6 | vector | m | ("sa1" "sa2" "sa3") | 0 | Test param 41 | Note | +* | - | param_vec7 | vector | m | - | 1 | Test param 42 | Note | +* | - | param_vec8 | vector | m | - | 1 | Test param 43 | Note | +* | - | param_vec9 | vector | m | - | 1 | Test param 44 | Note | +* +* The device can be launched by yarpdev using one of the following examples: +* \code{.unparsed} +* yarpdev --device testDeviceWGP2 --param_vec4 \" (1 2 3) \" --param_vec5 \" (1.0 2.0 3.0) \" --param_vec6 \" (\"sa1\" \"sa2\" \"sa3\") \" --param_vec7 --param_vec8 --param_vec9 +* \endcode +* +* \code{.unparsed} +* yarpdev --device testDeviceWGP2 --param_vec7 --param_vec8 --param_vec9 +* \endcode +* +*/ + +class TestDeviceWGP2_ParamsParser : public yarp::dev::IDeviceDriverParams +{ +public: + TestDeviceWGP2_ParamsParser(); + ~TestDeviceWGP2_ParamsParser() override = default; + +public: + const std::string m_device_classname = {"TestDeviceWGP2"}; + const std::string m_device_name = {"testDeviceWGP2"}; + bool m_parser_is_strict = false; + struct parser_version_type + { + int major = 1; + int minor = 0; + }; + const parser_version_type m_parser_version = {}; + + const std::string m_param_vec4_defaultValue = {"(1 2 3)"}; + const std::string m_param_vec5_defaultValue = {"(1.0 2.0 3.0)"}; + const std::string m_param_vec6_defaultValue = {"(\"sa1\" \"sa2\" \"sa3\")"}; + const std::string m_param_vec7_defaultValue = {""}; + const std::string m_param_vec8_defaultValue = {""}; + const std::string m_param_vec9_defaultValue = {""}; + + std::vector m_param_vec4 = { }; //Default values for lists are managed in the class constructor. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec5 = { }; //Default values for lists are managed in the class constructor. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec6 = { }; //Default values for lists are managed in the class constructor. It is highly recommended to provide a suggested value also for optional string parameters. + std::vector m_param_vec7 = {}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + std::vector m_param_vec8 = {}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + std::vector m_param_vec9 = {}; //This default value is autogenerated. It is highly recommended to provide a suggested value also for mandatory parameters. + + bool parseParams(const yarp::os::Searchable & config) override; + std::string getDeviceClassName() const override { return m_device_classname; } + std::string getDeviceName() const override { return m_device_name; } + std::string getDocumentationOfDeviceParams() const override; + std::vector getListOfParams() const override; +}; + +#endif diff --git a/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_test.cpp b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_test.cpp new file mode 100644 index 00000000000..7f88f52a3cc --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test2/TestDeviceWGP2_test.cpp @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT) + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include +#include + +using namespace yarp::dev; +using namespace yarp::os; + +TEST_CASE("dev::TestDeviceWGP", "[yarp::dev]") +{ + YARP_REQUIRE_PLUGIN("testDeviceWGP2", "device"); + + Network::setLocalMode(true); + + SECTION("Checking TestDeviceWGP2 help") + { + PolyDriver dd; + Property p_cfg; + p_cfg.put("device", "testDeviceWGP2"); + p_cfg.put("help",""); + REQUIRE(dd.open(p_cfg)==false); + } + + SECTION("Checking TestDeviceWGP2 from string with parenthesis") + { + PolyDriver dd; + std::string open_string = "\ + device testDeviceWGP2\n\ + param_vec9 (\"sa1\" \"sa2\" \"sa3\")\n\ + param_vec8 (1.0 2.0 3.0)\n\ + param_vec7 (1 2 3)\n\ + param_vec6 (sa1 sa2 sa3)\n\ + param_vec5 (1.0 2.0 3.0)\n\ + param_vec4 (1 2 3)\n\ + "; + yarp::os::Property p; + p.fromConfig(open_string.c_str()); + REQUIRE(dd.open(p)); + } + + SECTION("Checking TestDeviceWGP2 from string without parenthesis (deprecated, it will fail!)") + { + PolyDriver dd; + std::string open_string = "\ + device testDeviceWGP2\n\ + param_vec9 \"sa1\" \"sa2\" \"sa3\"\n\ + param_vec8 1.0 2.0 3.0\n\ + param_vec7 1 2 3\n\ + param_vec6 sa1 sa2 sa3\n\ + param_vec5 1.0 2.0 3.0\n\ + param_vec4 1 2 3\n\ + "; + yarp::os::Property p; + p.fromConfig(open_string.c_str()); + REQUIRE(dd.open(p)==false); + } + + SECTION("Checking TestDeviceWGP2 device") + { + INFO("from c code"); + PolyDriver dd; + + ////////"Checking opening polydriver with no attached device" + { + Property p_cfg; + p_cfg.put("device", "testDeviceWGP2"); + + yarp::os::Value val7; val7.fromString("(1 2 3)"); + p_cfg.put("param_vec7", val7); + yarp::os::Value val8; val8.fromString("(1.0 2.0 3.0)"); + p_cfg.put("param_vec8", val8); + yarp::os::Value val9; val9.fromString("(sa1 sa2 sa3)"); + p_cfg.put("param_vec9", val9); + + REQUIRE(dd.open(p_cfg)); + + yarp::dev::IDeviceDriverParams* idevparams = nullptr; + REQUIRE (dd.view(idevparams)); + REQUIRE (idevparams!=nullptr); + + std::string ss1 = idevparams->getDeviceClassName(); + CHECK (ss1 == "TestDeviceWGP2"); + std::string ss2 = idevparams->getDeviceName(); + CHECK (ss2 == "testDeviceWGP2"); + + std::vector vv = idevparams->getListOfParams(); + CHECK(vv.empty() == false); + } + + yarp::os::Time::delay(1.0); + + //"Close all polydrivers and check" + { + CHECK(dd.close()); + } + } + + Network::setLocalMode(false); +} diff --git a/src/yarpDeviceParamParserGenerator/tests/test2/extraComments.md b/src/yarpDeviceParamParserGenerator/tests/test2/extraComments.md new file mode 100644 index 00000000000..374e85bc70e --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test2/extraComments.md @@ -0,0 +1,9 @@ +TestDeviceWGP is a fake device developed for testing the various functionalities of YarpDeviceParamParserGenerator tool. +This block has been written with the purpose of testing the --input_extra_comments option. +This last line has no specific meaning. +Here there are some extra symbols used in the markdown format, such as the 'code' syntax. +The **bold text** , the *italic text*, the list: +1. First element +2. Second element +- unordered element 1 +- unordered element 2 diff --git a/src/yarpDeviceParamParserGenerator/tests/test2/test.txt b/src/yarpDeviceParamParserGenerator/tests/test2/test.txt new file mode 100644 index 00000000000..f1cfdd9e878 --- /dev/null +++ b/src/yarpDeviceParamParserGenerator/tests/test2/test.txt @@ -0,0 +1,8 @@ +| Group name | Parameter name | Type | Units | Default Value | Required | Description | Notes | +|:--------------------:|:--------------------:|:--------------:|:-------:|:--------------------:|:--------:|:-------------:|:-----------:| +| - | param_vec4 | vector | m | (1 2 3) | No | Test param 39 | Note | +| - | param_vec5 | vector | m | (1.0 2.0 3.0) | No | Test param 40 | Note | +| - | param_vec6 | vector | m | ("sa1" "sa2" "sa3") | No | Test param 41 | Note | +| - | param_vec7 | vector | m | | Yes | Test param 42 | Note | +| - | param_vec8 | vector | m | | Yes | Test param 43 | Note | +| - | param_vec9 | vector | m | | Yes | Test param 44 | Note |