diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dc3b3e837d..067da02ba4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: args: ["--ignore=D100,D101,D102,D103,D104,D105,D106,D107,D203,D212,D404"] - repo: https://github.com/psf/black - rev: 24.2.0 + rev: 24.3.0 hooks: - id: black args: ["--line-length=99"] @@ -62,7 +62,7 @@ repos: # CPP hooks - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.0 + rev: v18.1.2 hooks: - id: clang-format args: ['-fallback-style=none', '-i'] diff --git a/controller_interface/CHANGELOG.rst b/controller_interface/CHANGELOG.rst index f7364fb893..3ed820dfe5 100644 --- a/controller_interface/CHANGELOG.rst +++ b/controller_interface/CHANGELOG.rst @@ -2,6 +2,17 @@ Changelog for package controller_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ +* generate version.h file per package using the ament_generate_version_header (`#1449 `_) +* Use ament_cmake generated rclcpp version header (`#1448 `_) +* Contributors: Sai Kishor Kothakota + +4.7.0 (2024-03-22) +------------------ +* add missing compiler definitions of RCLCPP_VERSION_MAJOR (`#1440 `_) +* Contributors: Sai Kishor Kothakota + 4.6.0 (2024-03-02) ------------------ * Add -Werror=missing-braces to compile options (`#1423 `_) diff --git a/controller_interface/CMakeLists.txt b/controller_interface/CMakeLists.txt index 917da0a8c9..2b7ccb9203 100644 --- a/controller_interface/CMakeLists.txt +++ b/controller_interface/CMakeLists.txt @@ -89,3 +89,4 @@ install(TARGETS controller_interface ament_export_targets(export_controller_interface HAS_LIBRARY_TARGET) ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/controller_interface/include/controller_interface/controller_interface_base.hpp b/controller_interface/include/controller_interface/controller_interface_base.hpp index 2de57d3f83..182ffa7fec 100644 --- a/controller_interface/include/controller_interface/controller_interface_base.hpp +++ b/controller_interface/include/controller_interface/controller_interface_base.hpp @@ -26,6 +26,7 @@ #include "hardware_interface/loaned_state_interface.hpp" #include "rclcpp/rclcpp.hpp" +#include "rclcpp/version.h" #include "rclcpp_lifecycle/lifecycle_node.hpp" namespace controller_interface diff --git a/controller_interface/package.xml b/controller_interface/package.xml index 72988af672..8143d8f9c5 100644 --- a/controller_interface/package.xml +++ b/controller_interface/package.xml @@ -2,13 +2,14 @@ controller_interface - 4.6.0 + 4.8.0 Description of controller_interface Bence Magyar Denis Štogl Apache License 2.0 ament_cmake + ament_cmake_gen_version_h hardware_interface rclcpp_lifecycle diff --git a/controller_manager/CHANGELOG.rst b/controller_manager/CHANGELOG.rst index ea48f05f6f..53005b3800 100644 --- a/controller_manager/CHANGELOG.rst +++ b/controller_manager/CHANGELOG.rst @@ -2,6 +2,21 @@ Changelog for package controller_manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ +* generate version.h file per package using the ament_generate_version_header (`#1449 `_) +* Use ament_cmake generated rclcpp version header (`#1448 `_) +* Replace random_shuffle with shuffle. (`#1446 `_) +* Contributors: Chris Lalancette, Sai Kishor Kothakota + +4.7.0 (2024-03-22) +------------------ +* add missing compiler definitions of RCLCPP_VERSION_MAJOR (`#1440 `_) +* Codeformat from new pre-commit config (`#1433 `_) +* add conditioning to get_parameter_value method import (`#1428 `_) +* Change the controller sorting with an approach similar to directed acyclic graphs (`#1384 `_) +* Contributors: Christoph Fröhlich, Sai Kishor Kothakota + 4.6.0 (2024-03-02) ------------------ * Add -Werror=missing-braces to compile options (`#1423 `_) diff --git a/controller_manager/CMakeLists.txt b/controller_manager/CMakeLists.txt index 1d6c76b5d5..e267856eb1 100644 --- a/controller_manager/CMakeLists.txt +++ b/controller_manager/CMakeLists.txt @@ -225,3 +225,4 @@ ament_python_install_package(controller_manager ament_export_targets(export_controller_manager HAS_LIBRARY_TARGET) ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/controller_manager/doc/userdoc.rst b/controller_manager/doc/userdoc.rst index 46781d461c..c8aa68d774 100644 --- a/controller_manager/doc/userdoc.rst +++ b/controller_manager/doc/userdoc.rst @@ -45,6 +45,15 @@ Alternatives to the standard kernel include Though installing a realtime-kernel will definitely get the best results when it comes to low jitter, using a lowlatency kernel can improve things a lot with being really easy to install. +Subscribers +----------- + +~/robot_description [std_msgs::msg::String] + String with the URDF xml, e.g., from ``robot_state_publisher``. + Reloading of the URDF is not supported yet. + All joints defined in the ````-tag have to be present in the URDF. + + Parameters ----------- @@ -74,18 +83,10 @@ update_rate (mandatory; integer) The frequency of controller manager's real-time update loop. This loop reads states from hardware, updates controller and writes commands to hardware. - .type Name of a plugin exported using ``pluginlib`` for a controller. This is a class from which controller's instance with name "``controller_name``" is created. -Subscribers ------------ - -robot_description (std_msgs/msg/String) - The URDF string as robot description. - This is usually published by the ``robot_state_publisher`` node. - Handling Multiple Controller Managers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/controller_manager/package.xml b/controller_manager/package.xml index 4b29ada792..7de94fc053 100644 --- a/controller_manager/package.xml +++ b/controller_manager/package.xml @@ -2,13 +2,14 @@ controller_manager - 4.6.0 + 4.8.0 Description of controller_manager Bence Magyar Denis Štogl Apache License 2.0 ament_cmake + ament_cmake_gen_version_h ament_cmake_python ament_index_cpp diff --git a/controller_manager/src/controller_manager.cpp b/controller_manager/src/controller_manager.cpp index 37f5d8a657..aae141bc97 100644 --- a/controller_manager/src/controller_manager.cpp +++ b/controller_manager/src/controller_manager.cpp @@ -25,6 +25,7 @@ #include "hardware_interface/types/lifecycle_state_names.hpp" #include "lifecycle_msgs/msg/state.hpp" #include "rclcpp/rclcpp.hpp" +#include "rclcpp/version.h" #include "rclcpp_lifecycle/state.hpp" namespace // utility diff --git a/controller_manager/test/test_controller_manager_srvs.cpp b/controller_manager/test/test_controller_manager_srvs.cpp index f42c155e6d..24cd30bc06 100644 --- a/controller_manager/test/test_controller_manager_srvs.cpp +++ b/controller_manager/test/test_controller_manager_srvs.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -1503,7 +1504,9 @@ TEST_F(TestControllerManagerSrvs, list_sorted_large_chained_controller_tree) } // Now shuffle the list to be able to configure controller later randomly - std::random_shuffle(controllers_list.begin(), controllers_list.end()); + std::random_device rnd; + std::mt19937 mers(rnd()); + std::shuffle(controllers_list.begin(), controllers_list.end(), mers); { ControllerManagerRunner cm_runner(this); diff --git a/controller_manager_msgs/CHANGELOG.rst b/controller_manager_msgs/CHANGELOG.rst index d9fea91eaa..11d3ba2989 100644 --- a/controller_manager_msgs/CHANGELOG.rst +++ b/controller_manager_msgs/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package controller_manager_msgs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ + +4.7.0 (2024-03-22) +------------------ + 4.6.0 (2024-03-02) ------------------ diff --git a/controller_manager_msgs/package.xml b/controller_manager_msgs/package.xml index fe17dfc6df..db64f0c28d 100644 --- a/controller_manager_msgs/package.xml +++ b/controller_manager_msgs/package.xml @@ -2,7 +2,7 @@ controller_manager_msgs - 4.6.0 + 4.8.0 Messages and services for the controller manager. Bence Magyar Denis Štogl diff --git a/doc/migration/Foxy.rst b/doc/migration/Foxy.rst new file mode 100644 index 0000000000..a1afeddc70 --- /dev/null +++ b/doc/migration/Foxy.rst @@ -0,0 +1,51 @@ +Foxy to Galactic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +hardware_interface +************************************** +Between Foxy and Galactic we made substantial changes to the interface of hardware components to enable management of their lifecycle. +The following list shows a set of quick changes to port existing hardware components to Galactic: + +1. Rename ``configure`` to ``on_init`` and change return type to ``CallbackReturn`` + +2. If using BaseInterface as base class then you should remove it. Specifically, change: + + .. code-block:: c++ + + hardware_interface::BaseInterface + + to + + .. code-block:: c++ + + hardware_interface::[Actuator|Sensor|System]Interface + +3. Remove include of headers ``base_interface.hpp`` and ``hardware_interface_status_values.hpp`` + +4. Add include of header ``rclcpp_lifecycle/state.hpp`` although this may not be strictly necessary + +5. replace first three lines in ``on_init`` to + + .. code-block:: c++ + + if (hardware_interface::[Actuator|Sensor|System]Interface::on_init(info) != CallbackReturn::SUCCESS) + { + return CallbackReturn::ERROR; + } + + +6. Change last return of ``on_init`` to ``return CallbackReturn::SUCCESS;`` + +7. Remove all lines with ``status_ = ...`` or ``status::...`` + +8. Rename ``start()`` to ``on_activate(const rclcpp_lifecycle::State & previous_state)`` and + ``stop()`` to ``on_deactivate(const rclcpp_lifecycle::State & previous_state)`` + +9. Change return type of ``on_activate`` and ``on_deactivate`` to ``CallbackReturn`` + +10. Change last return of ``on_activate`` and ``on_deactivate`` to ``return CallbackReturn::SUCCESS;`` + +11. If you have any ``return_type::ERROR`` in ``on_init``, ``on_activate``, or ``in_deactivate`` change to ``CallbackReturn::ERROR`` + +12. If you get link errors with undefined refernences to symbols in ``rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface``, then add + ``rclcpp_lifecyle`` package dependency to ``CMakeLists.txt`` and ``package.xml`` diff --git a/doc/migration/Iron.rst b/doc/migration/Iron.rst new file mode 100644 index 0000000000..21e28fc43f --- /dev/null +++ b/doc/migration/Iron.rst @@ -0,0 +1,50 @@ +Iron to Jazzy +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +component parser +***************** +Changes from `(PR #1256) `__ + +* All ``joints`` defined in the ````-tag have to be present in the URDF received :ref:`by the controller manager `, otherwise a ``std::runtime_error`` is thrown. This is to ensure that the URDF and the ````-tag are consistent. E.g., for configuration ports use ``gpio`` tags instead. +* The syntax for mimic joints is changed to the `official URDF specification `__. The parameters within the ``ros2_control`` tag are not supported any more. Instead of + + .. code-block:: xml + + + + + + 0.15 + + + + + + right_finger_joint + 1 + + + + + + + + define your mimic joints directly in the joint definitions: + + .. code-block:: xml + + + + + + + + + + + + + + + + diff --git a/hardware_interface/CHANGELOG.rst b/hardware_interface/CHANGELOG.rst index fc4fc02aa2..1cb22a501a 100644 --- a/hardware_interface/CHANGELOG.rst +++ b/hardware_interface/CHANGELOG.rst @@ -2,6 +2,16 @@ Changelog for package hardware_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ +* generate version.h file per package using the ament_generate_version_header (`#1449 `_) +* Contributors: Sai Kishor Kothakota + +4.7.0 (2024-03-22) +------------------ +* Codeformat from new pre-commit config (`#1433 `_) +* Contributors: Christoph Fröhlich + 4.6.0 (2024-03-02) ------------------ * Add -Werror=missing-braces to compile options (`#1423 `_) diff --git a/hardware_interface/CMakeLists.txt b/hardware_interface/CMakeLists.txt index 94eaa6a050..4ea7fdc2f7 100644 --- a/hardware_interface/CMakeLists.txt +++ b/hardware_interface/CMakeLists.txt @@ -15,6 +15,7 @@ set(THIS_PACKAGE_INCLUDE_DEPENDS rcutils TinyXML2 tinyxml2_vendor + urdf ) find_package(ament_cmake REQUIRED) @@ -122,3 +123,4 @@ install( ament_export_targets(export_hardware_interface HAS_LIBRARY_TARGET) ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/hardware_interface/doc/hardware_components_userdoc.rst b/hardware_interface/doc/hardware_components_userdoc.rst index 404e90ee03..0a980cad4e 100644 --- a/hardware_interface/doc/hardware_components_userdoc.rst +++ b/hardware_interface/doc/hardware_components_userdoc.rst @@ -27,53 +27,3 @@ If ``hardware_interface::return_type::ERROR`` is returned from ``read()`` or ``w Error handling follows the `node lifecycle `_. If successful ``CallbackReturn::SUCCESS`` is returned and hardware is again in ``UNCONFIGURED`` state, if any ``ERROR`` or ``FAILURE`` happens the hardware ends in ``FINALIZED`` state and can not be recovered. The only option is to reload the complete plugin, but there is currently no service for this in the Controller Manager. - -Migration from Foxy to newer versions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Between Foxy and Galactic we made substantial changes to the interface of hardware components to enable management of their lifecycle. -The following list shows a set of quick changes to port existing hardware components to Galactic: - -1. Rename ``configure`` to ``on_init`` and change return type to ``CallbackReturn`` - -2. If using BaseInterface as base class then you should remove it. Specifically, change: - - .. code-block:: c++ - - hardware_interface::BaseInterface - - to - - .. code-block:: c++ - - hardware_interface::[Actuator|Sensor|System]Interface - -3. Remove include of headers ``base_interface.hpp`` and ``hardware_interface_status_values.hpp`` - -4. Add include of header ``rclcpp_lifecycle/state.hpp`` although this may not be strictly necessary - -5. replace first three lines in ``on_init`` to - - .. code-block:: c++ - - if (hardware_interface::[Actuator|Sensor|System]Interface::on_init(info) != CallbackReturn::SUCCESS) - { - return CallbackReturn::ERROR; - } - - -6. Change last return of ``on_init`` to ``return CallbackReturn::SUCCESS;`` - -7. Remove all lines with ``status_ = ...`` or ``status::...`` - -8. Rename ``start()`` to ``on_activate(const rclcpp_lifecycle::State & previous_state)`` and - ``stop()`` to ``on_deactivate(const rclcpp_lifecycle::State & previous_state)`` - -9. Change return type of ``on_activate`` and ``on_deactivate`` to ``CallbackReturn`` - -10. Change last return of ``on_activate`` and ``on_deactivate`` to ``return CallbackReturn::SUCCESS;`` - -11. If you have any ``return_type::ERROR`` in ``on_init``, ``on_activate``, or ``in_deactivate`` change to ``CallbackReturn::ERROR`` - -12. If you get link errors with undefined refernences to symbols in ``rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface``, then add - ``rclcpp_lifecyle`` package dependency to ``CMakeLists.txt`` and ``package.xml`` diff --git a/hardware_interface/doc/hardware_interface_types_userdoc.rst b/hardware_interface/doc/hardware_interface_types_userdoc.rst index cd1e475b20..ecf852cb94 100644 --- a/hardware_interface/doc/hardware_interface_types_userdoc.rst +++ b/hardware_interface/doc/hardware_interface_types_userdoc.rst @@ -14,6 +14,8 @@ Joints ````-tag groups the interfaces associated with the joints of physical robots and actuators. They have command and state interfaces to set the goal values for hardware and read its current state. +All joints defined in the ````-tag have to be present in the URDF received :ref:`by the controller manager `. + State interfaces of joints can be published as a ROS topic by means of the :ref:`joint_state_broadcaster ` Sensors diff --git a/hardware_interface/doc/mock_components_userdoc.rst b/hardware_interface/doc/mock_components_userdoc.rst index c075fdeafc..782d3e01ea 100644 --- a/hardware_interface/doc/mock_components_userdoc.rst +++ b/hardware_interface/doc/mock_components_userdoc.rst @@ -19,9 +19,10 @@ For more information about hardware components check :ref:`detailed documentatio Features: - - support for mimic joints + - support for mimic joints, which is parsed from the URDF (see the `URDF wiki `__) - mirroring commands to states with and without offset - fake command interfaces for setting sensor data from an external node (combined with a :ref:`forward controller `) + - fake gpio interfaces for setting sensor data from an external node (combined with a :ref:`forward controller `) Parameters @@ -36,24 +37,16 @@ mock_sensor_commands (optional; boolean; default: false) Creates fake command interfaces for faking sensor measurements with an external command. Those interfaces are usually used by a :ref:`forward controller ` to provide access from ROS-world. +mock_gpio_commands (optional; boolean; default: false) + Creates fake command interfaces for faking GPIO states with an external command. + Those interfaces are usually used by a :ref:`forward controller ` to provide access from ROS-world. + position_state_following_offset (optional; double; default: 0.0) Following offset added to the commanded values when mirrored to states. - custom_interface_with_following_offset (optional; string; default: "") Mapping of offsetted commands to a custom interface. - -Per-joint Parameters -,,,,,,,,,,,,,,,,,,,, - -mimic (optional; string) - Defined name of the joint to mimic. This is often used concept with parallel grippers. Example: ``joint1``. - - -multiplier (optional; double; default: 1; used if mimic joint is defined) - Multiplier of values for mimicking joint defined in ``mimic`` parameter. Example: ``-2``. - Per-interface Parameters ,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/hardware_interface/include/hardware_interface/hardware_info.hpp b/hardware_interface/include/hardware_interface/hardware_info.hpp index eb6b63cfc3..97abc00438 100644 --- a/hardware_interface/include/hardware_interface/hardware_info.hpp +++ b/hardware_interface/include/hardware_interface/hardware_info.hpp @@ -44,6 +44,23 @@ struct InterfaceInfo int size; }; +/// @brief This structure stores information about a joint that is mimicking another joint +struct MimicJoint +{ + std::size_t joint_index; + std::size_t mimicked_joint_index; + double multiplier = 1.0; + double offset = 0.0; +}; + +/// @brief This enum is used to store the mimic attribute of a joint +enum class MimicAttribute +{ + NOT_SET, + TRUE, + FALSE +}; + /** * This structure stores information about components defined for a specific hardware * in robot's URDF. @@ -55,6 +72,9 @@ struct ComponentInfo /// Type of the component: sensor, joint, or GPIO. std::string type; + /// Hold the value of the mimic attribute if given, NOT_SET otherwise + MimicAttribute is_mimic = MimicAttribute::NOT_SET; + /** * Name of the command interfaces that can be set, e.g. "position", "velocity", etc. * Used by joints and GPIOs. @@ -116,22 +136,26 @@ struct HardwareInfo /// (Optional) Key-value pairs for hardware parameters. std::unordered_map hardware_parameters; /** - * Map of joints provided by the hardware where the key is the joint name. + * Vector of joints provided by the hardware. * Required for Actuator and System Hardware. */ std::vector joints; /** - * Map of sensors provided by the hardware where the key is the joint or link name. + * Vector of mimic joints. + */ + std::vector mimic_joints; + /** + * Vector of sensors provided by the hardware. * Required for Sensor and optional for System Hardware. */ std::vector sensors; /** - * Map of GPIO provided by the hardware where the key is a descriptive name of the GPIO. + * Vector of GPIOs provided by the hardware. * Optional for any hardware components. */ std::vector gpios; /** - * Map of transmissions to calculate ration between joints and physical actuators. + * Vector of transmissions to calculate ratio between joints and physical actuators. * Optional for Actuator and System Hardware. */ std::vector transmissions; diff --git a/hardware_interface/include/mock_components/generic_system.hpp b/hardware_interface/include/mock_components/generic_system.hpp index e9b38de65d..fbb8547ab1 100644 --- a/hardware_interface/include/mock_components/generic_system.hpp +++ b/hardware_interface/include/mock_components/generic_system.hpp @@ -72,14 +72,6 @@ class HARDWARE_INTERFACE_PUBLIC GenericSystem : public hardware_interface::Syste hardware_interface::HW_IF_POSITION, hardware_interface::HW_IF_VELOCITY, hardware_interface::HW_IF_ACCELERATION, hardware_interface::HW_IF_EFFORT}; - struct MimicJoint - { - std::size_t joint_index; - std::size_t mimicked_joint_index; - double multiplier = 1.0; - }; - std::vector mimic_joints_; - /// The size of this vector is (standard_interfaces_.size() x nr_joints) std::vector> joint_commands_; std::vector> joint_states_; diff --git a/hardware_interface/package.xml b/hardware_interface/package.xml index f782faf76a..41daac50cd 100644 --- a/hardware_interface/package.xml +++ b/hardware_interface/package.xml @@ -1,13 +1,14 @@ hardware_interface - 4.6.0 + 4.8.0 ros2_control hardware interface Bence Magyar Denis Štogl Apache License 2.0 ament_cmake + ament_cmake_gen_version_h control_msgs lifecycle_msgs @@ -15,6 +16,7 @@ rclcpp_lifecycle rcpputils tinyxml2_vendor + urdf rcutils rcutils diff --git a/hardware_interface/src/component_parser.cpp b/hardware_interface/src/component_parser.cpp index 4f67d3e8b6..0841265e81 100644 --- a/hardware_interface/src/component_parser.cpp +++ b/hardware_interface/src/component_parser.cpp @@ -21,6 +21,8 @@ #include #include +#include "urdf/model.h" + #include "hardware_interface/component_parser.hpp" #include "hardware_interface/hardware_info.hpp" #include "hardware_interface/lexical_casts.hpp" @@ -42,6 +44,7 @@ constexpr const auto kStateInterfaceTag = "state_interface"; constexpr const auto kMinTag = "min"; constexpr const auto kMaxTag = "max"; constexpr const auto kInitialValueTag = "initial_value"; +constexpr const auto kMimicAttribute = "mimic"; constexpr const auto kDataTypeAttribute = "data_type"; constexpr const auto kSizeAttribute = "size"; constexpr const auto kNameAttribute = "name"; @@ -315,6 +318,21 @@ ComponentInfo parse_component_from_xml(const tinyxml2::XMLElement * component_it component.type = component_it->Name(); component.name = get_attribute_value(component_it, kNameAttribute, component.type); + if (std::string(kJointTag) == component.type) + { + try + { + component.is_mimic = parse_bool(get_attribute_value(component_it, kMimicAttribute, kJointTag)) + ? MimicAttribute::TRUE + : MimicAttribute::FALSE; + } + catch (const std::runtime_error & e) + { + // mimic attribute not set + component.is_mimic = MimicAttribute::NOT_SET; + } + } + // Parse all command interfaces const auto * command_interfaces_it = component_it->FirstChildElement(kCommandInterfaceTag); while (command_interfaces_it) @@ -347,7 +365,7 @@ ComponentInfo parse_component_from_xml(const tinyxml2::XMLElement * component_it * and the interface may be an array of a fixed size of the data type. * * \param[in] component_it pointer to the iterator where component - * info should befound + * info should be found * \throws std::runtime_error if a required component attribute or tag is not found. */ ComponentInfo parse_complex_component_from_xml(const tinyxml2::XMLElement * component_it) @@ -530,7 +548,7 @@ HardwareInfo parse_resource_from_xml( const auto * ros2_control_child_it = ros2_control_it->FirstChildElement(); while (ros2_control_child_it) { - if (!std::string(kHardwareTag).compare(ros2_control_child_it->Name())) + if (std::string(kHardwareTag) == ros2_control_child_it->Name()) { const auto * type_it = ros2_control_child_it->FirstChildElement(kPluginNameTag); hardware.hardware_plugin_name = @@ -541,19 +559,19 @@ HardwareInfo parse_resource_from_xml( hardware.hardware_parameters = parse_parameters_from_xml(params_it); } } - else if (!std::string(kJointTag).compare(ros2_control_child_it->Name())) + else if (std::string(kJointTag) == ros2_control_child_it->Name()) { hardware.joints.push_back(parse_component_from_xml(ros2_control_child_it)); } - else if (!std::string(kSensorTag).compare(ros2_control_child_it->Name())) + else if (std::string(kSensorTag) == ros2_control_child_it->Name()) { hardware.sensors.push_back(parse_component_from_xml(ros2_control_child_it)); } - else if (!std::string(kGPIOTag).compare(ros2_control_child_it->Name())) + else if (std::string(kGPIOTag) == ros2_control_child_it->Name()) { hardware.gpios.push_back(parse_complex_component_from_xml(ros2_control_child_it)); } - else if (!std::string(kTransmissionTag).compare(ros2_control_child_it->Name())) + else if (std::string(kTransmissionTag) == ros2_control_child_it->Name()) { hardware.transmissions.push_back(parse_transmission_from_xml(ros2_control_child_it)); } @@ -593,7 +611,7 @@ std::vector parse_control_resources_from_urdf(const std::string & // Find robot tag const tinyxml2::XMLElement * robot_it = doc.RootElement(); - if (std::string(kRobotTag).compare(robot_it->Name())) + if (std::string(kRobotTag) != robot_it->Name()) { throw std::runtime_error("the robot tag is not root element in URDF"); } @@ -611,6 +629,96 @@ std::vector parse_control_resources_from_urdf(const std::string & ros2_control_it = ros2_control_it->NextSiblingElement(kROS2ControlTag); } + // parse full URDF for mimic options + urdf::Model model; + if (!model.initString(urdf)) + { + throw std::runtime_error("Failed to parse URDF file"); + } + for (auto & hw_info : hardware_info) + { + for (auto i = 0u; i < hw_info.joints.size(); ++i) + { + const auto & joint = hw_info.joints.at(i); + + // Search for mimic joints defined in ros2_control tag (deprecated) + // TODO(christophfroehlich) delete deprecated config with ROS-J + if (joint.parameters.find("mimic") != joint.parameters.cend()) + { + std::cerr << "Warning: Mimic joints defined in ros2_control tag are deprecated. " + << "Please define mimic joints in URDF." << std::endl; + const auto mimicked_joint_it = std::find_if( + hw_info.joints.begin(), hw_info.joints.end(), + [&mimicked_joint = + joint.parameters.at("mimic")](const hardware_interface::ComponentInfo & joint_info) + { return joint_info.name == mimicked_joint; }); + if (mimicked_joint_it == hw_info.joints.cend()) + { + throw std::runtime_error( + "Mimicked joint '" + joint.parameters.at("mimic") + "' not found"); + } + hardware_interface::MimicJoint mimic_joint; + mimic_joint.joint_index = i; + mimic_joint.multiplier = 1.0; + mimic_joint.offset = 0.0; + mimic_joint.mimicked_joint_index = std::distance(hw_info.joints.begin(), mimicked_joint_it); + auto param_it = joint.parameters.find("multiplier"); + if (param_it != joint.parameters.end()) + { + mimic_joint.multiplier = hardware_interface::stod(joint.parameters.at("multiplier")); + } + param_it = joint.parameters.find("offset"); + if (param_it != joint.parameters.end()) + { + mimic_joint.offset = hardware_interface::stod(joint.parameters.at("offset")); + } + hw_info.mimic_joints.push_back(mimic_joint); + } + else + { + auto urdf_joint = model.getJoint(joint.name); + if (!urdf_joint) + { + throw std::runtime_error("Joint " + joint.name + " not found in URDF"); + } + if (!urdf_joint->mimic && joint.is_mimic == MimicAttribute::TRUE) + { + throw std::runtime_error( + "Joint '" + joint.name + "' has no mimic information in the URDF."); + } + if (urdf_joint->mimic && joint.is_mimic != MimicAttribute::FALSE) + { + if (joint.command_interfaces.size() > 0) + { + throw std::runtime_error( + "Joint '" + joint.name + + "' has mimic attribute not set to false: Activated mimic joints cannot have command " + "interfaces."); + } + auto find_joint = [&hw_info](const std::string & name) + { + auto it = std::find_if( + hw_info.joints.begin(), hw_info.joints.end(), + [&name](const auto & j) { return j.name == name; }); + if (it == hw_info.joints.end()) + { + throw std::runtime_error( + "Mimic joint '" + name + "' not found in tag"); + } + return std::distance(hw_info.joints.begin(), it); + }; + + MimicJoint mimic_joint; + mimic_joint.joint_index = i; + mimic_joint.mimicked_joint_index = find_joint(urdf_joint->mimic->joint_name); + mimic_joint.multiplier = urdf_joint->mimic->multiplier; + mimic_joint.offset = urdf_joint->mimic->offset; + hw_info.mimic_joints.push_back(mimic_joint); + } + } + } + } + return hardware_info; } diff --git a/hardware_interface/src/mock_components/generic_system.cpp b/hardware_interface/src/mock_components/generic_system.cpp index 22d8aa573c..2d8a01a34f 100644 --- a/hardware_interface/src/mock_components/generic_system.cpp +++ b/hardware_interface/src/mock_components/generic_system.cpp @@ -17,7 +17,6 @@ #include "mock_components/generic_system.hpp" #include -#include #include #include #include @@ -137,34 +136,6 @@ CallbackReturn GenericSystem::on_init(const hardware_interface::HardwareInfo & i } } - // Search for mimic joints - for (auto i = 0u; i < info_.joints.size(); ++i) - { - const auto & joint = info_.joints.at(i); - if (joint.parameters.find("mimic") != joint.parameters.cend()) - { - const auto mimicked_joint_it = std::find_if( - info_.joints.begin(), info_.joints.end(), - [&mimicked_joint = - joint.parameters.at("mimic")](const hardware_interface::ComponentInfo & joint_info) - { return joint_info.name == mimicked_joint; }); - if (mimicked_joint_it == info_.joints.cend()) - { - throw std::runtime_error( - std::string("Mimicked joint '") + joint.parameters.at("mimic") + "' not found"); - } - MimicJoint mimic_joint; - mimic_joint.joint_index = i; - mimic_joint.mimicked_joint_index = std::distance(info_.joints.begin(), mimicked_joint_it); - auto param_it = joint.parameters.find("multiplier"); - if (param_it != joint.parameters.end()) - { - mimic_joint.multiplier = hardware_interface::stod(joint.parameters.at("multiplier")); - } - mimic_joints_.push_back(mimic_joint); - } - } - // search for non-standard joint interfaces for (const auto & joint : info_.joints) { @@ -594,11 +565,12 @@ return_type GenericSystem::read(const rclcpp::Time & /*time*/, const rclcpp::Dur mirror_command_to_state(joint_states_, joint_commands_, 1); } - for (const auto & mimic_joint : mimic_joints_) + for (const auto & mimic_joint : info_.mimic_joints) { for (auto i = 0u; i < joint_states_.size(); ++i) { joint_states_[i][mimic_joint.joint_index] = + mimic_joint.offset + mimic_joint.multiplier * joint_states_[i][mimic_joint.mimicked_joint_index]; } } @@ -626,13 +598,13 @@ return_type GenericSystem::read(const rclcpp::Time & /*time*/, const rclcpp::Dur mirror_command_to_state(sensor_states_, sensor_mock_commands_); } - // do loopback on all gpio interfaces if (use_mock_gpio_command_interfaces_) { mirror_command_to_state(gpio_states_, gpio_mock_commands_); } else { + // do loopback on all gpio interfaces mirror_command_to_state(gpio_states_, gpio_commands_); } diff --git a/hardware_interface/test/mock_components/test_generic_system.cpp b/hardware_interface/test/mock_components/test_generic_system.cpp index a6b578d6c5..835041f7dc 100644 --- a/hardware_interface/test/mock_components/test_generic_system.cpp +++ b/hardware_interface/test/mock_components/test_generic_system.cpp @@ -142,12 +142,12 @@ class TestGenericSystem : public ::testing::Test 0.2 - + 0.5 - + )"; @@ -251,11 +251,7 @@ class TestGenericSystem : public ::testing::Test - - joint1 - -2 - - + @@ -1206,11 +1202,9 @@ void TestGenericSystem::test_generic_system_with_mimic_joint( EXPECT_TRUE(rm.state_interface_exists("joint2/position")); EXPECT_TRUE(rm.state_interface_exists("joint2/velocity")); - ASSERT_EQ(4u, rm.command_interface_keys().size()); + ASSERT_EQ(2u, rm.command_interface_keys().size()); EXPECT_TRUE(rm.command_interface_exists("joint1/position")); EXPECT_TRUE(rm.command_interface_exists("joint1/velocity")); - EXPECT_TRUE(rm.command_interface_exists("joint2/position")); - EXPECT_TRUE(rm.command_interface_exists("joint2/velocity")); // Check initial values hardware_interface::LoanedStateInterface j1p_s = rm.claim_state_interface("joint1/position"); @@ -1260,7 +1254,7 @@ void TestGenericSystem::test_generic_system_with_mimic_joint( TEST_F(TestGenericSystem, hardware_system_2dof_with_mimic_joint) { - auto urdf = ros2_control_test_assets::urdf_head + hardware_system_2dof_with_mimic_joint_ + + auto urdf = ros2_control_test_assets::urdf_head_mimic + hardware_system_2dof_with_mimic_joint_ + ros2_control_test_assets::urdf_tail; test_generic_system_with_mimic_joint(urdf, "MockHardwareSystem"); @@ -1917,10 +1911,11 @@ TEST_F(TestGenericSystem, disabled_commands_flag_is_active) TEST_F(TestGenericSystem, prepare_command_mode_switch_works_with_all_example_tags) { - auto check_prepare_command_mode_switch = [&](const std::string & urdf) + auto check_prepare_command_mode_switch = + [&]( + const std::string & urdf, const std::string & urdf_head = ros2_control_test_assets::urdf_head) { - TestableResourceManager rm( - ros2_control_test_assets::urdf_head + urdf + ros2_control_test_assets::urdf_tail); + TestableResourceManager rm(urdf_head + urdf + ros2_control_test_assets::urdf_tail); rclcpp_lifecycle::State state(lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE, "active"); rm.set_component_state("MockHardwareSystem", state); auto start_interfaces = rm.command_interface_keys(); @@ -1936,7 +1931,8 @@ TEST_F(TestGenericSystem, prepare_command_mode_switch_works_with_all_example_tag ASSERT_TRUE(check_prepare_command_mode_switch(hardware_system_2dof_with_sensor_mock_command_)); ASSERT_TRUE( check_prepare_command_mode_switch(hardware_system_2dof_with_sensor_mock_command_True_)); - ASSERT_TRUE(check_prepare_command_mode_switch(hardware_system_2dof_with_mimic_joint_)); + ASSERT_TRUE(check_prepare_command_mode_switch( + hardware_system_2dof_with_mimic_joint_, ros2_control_test_assets::urdf_head_mimic)); ASSERT_TRUE( check_prepare_command_mode_switch(hardware_system_2dof_standard_interfaces_with_offset_)); ASSERT_TRUE(check_prepare_command_mode_switch( diff --git a/hardware_interface/test/test_component_parser.cpp b/hardware_interface/test/test_component_parser.cpp index b0c7c5a16d..968d41ed97 100644 --- a/hardware_interface/test/test_component_parser.cpp +++ b/hardware_interface/test/test_component_parser.cpp @@ -564,6 +564,7 @@ TEST_F(TestComponentParser, successfully_parse_valid_urdf_system_robot_with_gpio EXPECT_THAT(hardware_info.gpios[1].state_interfaces, SizeIs(1)); EXPECT_THAT(hardware_info.gpios[1].command_interfaces, SizeIs(1)); EXPECT_EQ(hardware_info.gpios[1].state_interfaces[0].name, "vacuum"); + EXPECT_EQ(hardware_info.gpios[1].state_interfaces[0].initial_value, "1.0"); EXPECT_EQ(hardware_info.gpios[1].command_interfaces[0].name, "vacuum"); EXPECT_THAT(hardware_info.transmissions, IsEmpty()); @@ -674,3 +675,128 @@ TEST_F(TestComponentParser, transmission_given_too_many_joints_throws_error) ros2_control_test_assets::urdf_tail; ASSERT_THROW(parse_control_resources_from_urdf(urdf_to_test), std::runtime_error); } + +TEST_F(TestComponentParser, gripper_mimic_true_valid_config) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head) + + std::string(ros2_control_test_assets::gripper_hardware_resources_mimic_true_no_command_if) + + std::string(ros2_control_test_assets::urdf_tail); + std::vector hw_info; + ASSERT_NO_THROW(hw_info = parse_control_resources_from_urdf(urdf_to_test)); + ASSERT_THAT(hw_info, SizeIs(1)); + ASSERT_THAT(hw_info[0].mimic_joints, SizeIs(1)); + EXPECT_DOUBLE_EQ(hw_info[0].mimic_joints[0].multiplier, 2.0); + EXPECT_DOUBLE_EQ(hw_info[0].mimic_joints[0].offset, 1.0); + EXPECT_EQ(hw_info[0].mimic_joints[0].mimicked_joint_index, 0); + EXPECT_EQ(hw_info[0].mimic_joints[0].joint_index, 1); +} + +TEST_F(TestComponentParser, gripper_no_mimic_valid_config) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head) + + std::string(ros2_control_test_assets::gripper_hardware_resources_no_command_if) + + std::string(ros2_control_test_assets::urdf_tail); + std::vector hw_info; + ASSERT_NO_THROW(hw_info = parse_control_resources_from_urdf(urdf_to_test)); + ASSERT_THAT(hw_info, SizeIs(1)); + ASSERT_THAT(hw_info[0].mimic_joints, SizeIs(1)); + EXPECT_DOUBLE_EQ(hw_info[0].mimic_joints[0].multiplier, 2.0); + EXPECT_DOUBLE_EQ(hw_info[0].mimic_joints[0].offset, 1.0); + EXPECT_EQ(hw_info[0].mimic_joints[0].mimicked_joint_index, 0); + EXPECT_EQ(hw_info[0].mimic_joints[0].joint_index, 1); +} + +// TODO(christophfroehlich) delete deprecated config test +TEST_F(TestComponentParser, gripper_mimic_deprecated_valid_config) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head) + + std::string(ros2_control_test_assets::gripper_hardware_resources_mimic_deprecated) + + std::string(ros2_control_test_assets::urdf_tail); + std::vector hw_info; + ASSERT_NO_THROW(hw_info = parse_control_resources_from_urdf(urdf_to_test)); + ASSERT_THAT(hw_info, SizeIs(1)); + ASSERT_THAT(hw_info[0].mimic_joints, SizeIs(1)); + EXPECT_DOUBLE_EQ(hw_info[0].mimic_joints[0].multiplier, 2.0); + EXPECT_DOUBLE_EQ(hw_info[0].mimic_joints[0].offset, 1.0); + EXPECT_EQ(hw_info[0].mimic_joints[0].mimicked_joint_index, 0); + EXPECT_EQ(hw_info[0].mimic_joints[0].joint_index, 1); +} + +TEST_F(TestComponentParser, gripper_mimic_deprecated_unknown_joint_throws_error) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head) + + std::string( + ros2_control_test_assets::gripper_hardware_resources_mimic_deprecated_unknown_joint) + + std::string(ros2_control_test_assets::urdf_tail); + std::vector hw_info; + ASSERT_THROW(parse_control_resources_from_urdf(urdf_to_test), std::runtime_error); +} +// end delete deprecated config test + +TEST_F(TestComponentParser, gripper_mimic_with_unknown_joint_throws_error) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head_unknown_joint) + + std::string(ros2_control_test_assets::gripper_hardware_resources_mimic_true_no_command_if) + + std::string(ros2_control_test_assets::urdf_tail); + ASSERT_THROW(parse_control_resources_from_urdf(urdf_to_test), std::runtime_error); +} + +TEST_F(TestComponentParser, gripper_mimic_true_without_mimic_info_throws_error) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head_no_mimic) + + std::string(ros2_control_test_assets::gripper_hardware_resources_mimic_true_no_command_if) + + std::string(ros2_control_test_assets::urdf_tail); + ASSERT_THROW(parse_control_resources_from_urdf(urdf_to_test), std::runtime_error); +} + +TEST_F(TestComponentParser, gripper_mimic_true_invalid_config_throws_error) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head) + + std::string(ros2_control_test_assets::gripper_hardware_resources_mimic_true_command_if) + + std::string(ros2_control_test_assets::urdf_tail); + ASSERT_THROW(parse_control_resources_from_urdf(urdf_to_test), std::runtime_error); +} + +TEST_F(TestComponentParser, gripper_mimic_false_valid_config) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head) + + std::string(ros2_control_test_assets::gripper_hardware_resources_mimic_false_command_if) + + std::string(ros2_control_test_assets::urdf_tail); + std::vector hw_info; + ASSERT_NO_THROW(hw_info = parse_control_resources_from_urdf(urdf_to_test)); + ASSERT_THAT(hw_info, SizeIs(1)); + ASSERT_THAT(hw_info[0].mimic_joints, SizeIs(0)); +} + +/** + * @brief Test that the parser throws an error if the URDF contains a link with no parent. + */ +TEST_F(TestComponentParser, urdf_two_root_links_throws_error) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head_invalid_two_root_links) + + std::string(ros2_control_test_assets::gripper_hardware_resources_mimic_true_no_command_if) + + std::string(ros2_control_test_assets::urdf_tail); + ASSERT_THROW(parse_control_resources_from_urdf(urdf_to_test), std::runtime_error); +} + +/** + * @brief Test that the parser throws an error if a joint defined in the ros2_control tag is missing + * in the URDF + */ +TEST_F(TestComponentParser, urdf_incomplete_throws_error) +{ + const auto urdf_to_test = + std::string(ros2_control_test_assets::gripper_urdf_head_incomplete) + + std::string(ros2_control_test_assets::gripper_hardware_resources_mimic_true_no_command_if) + + std::string(ros2_control_test_assets::urdf_tail); + ASSERT_THROW(parse_control_resources_from_urdf(urdf_to_test), std::runtime_error); +} diff --git a/hardware_interface_testing/CHANGELOG.rst b/hardware_interface_testing/CHANGELOG.rst index f2593fd886..58f6edbcdb 100644 --- a/hardware_interface_testing/CHANGELOG.rst +++ b/hardware_interface_testing/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package hardware_interface_testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ + +4.7.0 (2024-03-22) +------------------ + 4.6.0 (2024-03-02) ------------------ * Add -Werror=missing-braces to compile options (`#1423 `_) diff --git a/hardware_interface_testing/package.xml b/hardware_interface_testing/package.xml index f2ad18d54e..49968cfd56 100644 --- a/hardware_interface_testing/package.xml +++ b/hardware_interface_testing/package.xml @@ -1,7 +1,7 @@ hardware_interface_testing - 4.6.0 + 4.8.0 ros2_control hardware interface testing Bence Magyar Denis Štogl diff --git a/hardware_interface_testing/test/test_components/test_actuator.cpp b/hardware_interface_testing/test/test_components/test_actuator.cpp index bb54ea9443..1277fecfb6 100644 --- a/hardware_interface_testing/test/test_components/test_actuator.cpp +++ b/hardware_interface_testing/test/test_components/test_actuator.cpp @@ -43,9 +43,11 @@ class TestActuator : public ActuatorInterface * // can only control one joint * if (info_.joints.size() != 1) {return CallbackReturn::ERROR;} * // can only control in position - * if (info_.joints[0].command_interfaces.size() != 1) {return CallbackReturn::ERROR;} + * if (info_.joints[0].command_interfaces.size() != 1) {return + * CallbackReturn::ERROR;} * // can only give feedback state for position and velocity - * if (info_.joints[0].state_interfaces.size() != 2) {return CallbackReturn::ERROR;} + * if (info_.joints[0].state_interfaces.size() != 2) {return + * CallbackReturn::ERROR;} */ return CallbackReturn::SUCCESS; @@ -100,7 +102,8 @@ class TestActuator : public ActuatorInterface // simulate error on read if (velocity_command_ == test_constants::READ_FAIL_VALUE) { - // reset value to get out from error on the next call - simplifies CM tests + // reset value to get out from error on the next call - simplifies CM + // tests velocity_command_ = 0.0; return return_type::ERROR; } @@ -109,10 +112,11 @@ class TestActuator : public ActuatorInterface { return return_type::DEACTIVATE; } - // The next line is for the testing purposes. We need value to be changed to be sure that - // the feedback from hardware to controllers in the chain is working as it should. - // This makes value checks clearer and confirms there is no "state = command" line or some - // other mixture of interfaces somewhere in the test stack. + // The next line is for the testing purposes. We need value to be changed to + // be sure that the feedback from hardware to controllers in the chain is + // working as it should. This makes value checks clearer and confirms there + // is no "state = command" line or some other mixture of interfaces + // somewhere in the test stack. velocity_state_ = velocity_command_ / 2; return return_type::OK; } @@ -122,7 +126,8 @@ class TestActuator : public ActuatorInterface // simulate error on write if (velocity_command_ == test_constants::WRITE_FAIL_VALUE) { - // reset value to get out from error on the next call - simplifies CM tests + // reset value to get out from error on the next call - simplifies CM + // tests velocity_command_ = 0.0; return return_type::ERROR; } @@ -141,7 +146,7 @@ class TestActuator : public ActuatorInterface double max_velocity_command_ = 0.0; }; -class TestUnitilizableActuator : public TestActuator +class TestUninitializableActuator : public TestActuator { CallbackReturn on_init(const hardware_interface::HardwareInfo & info) override { @@ -152,4 +157,4 @@ class TestUnitilizableActuator : public TestActuator #include "pluginlib/class_list_macros.hpp" // NOLINT PLUGINLIB_EXPORT_CLASS(TestActuator, hardware_interface::ActuatorInterface) -PLUGINLIB_EXPORT_CLASS(TestUnitilizableActuator, hardware_interface::ActuatorInterface) +PLUGINLIB_EXPORT_CLASS(TestUninitializableActuator, hardware_interface::ActuatorInterface) diff --git a/hardware_interface_testing/test/test_components/test_components.xml b/hardware_interface_testing/test/test_components/test_components.xml index f029d3dd37..e24ee28317 100644 --- a/hardware_interface_testing/test/test_components/test_components.xml +++ b/hardware_interface_testing/test/test_components/test_components.xml @@ -18,21 +18,21 @@ - + - Test Unitilizable Actuator + Test Uninitializable Actuator - + - Test Unitilizable Sensor + Test Uninitializable Sensor - + - Test Unitilizable System + Test Uninitializable System diff --git a/hardware_interface_testing/test/test_components/test_sensor.cpp b/hardware_interface_testing/test/test_components/test_sensor.cpp index 2c414aebb4..3fc2ef2445 100644 --- a/hardware_interface_testing/test/test_components/test_sensor.cpp +++ b/hardware_interface_testing/test/test_components/test_sensor.cpp @@ -55,7 +55,7 @@ class TestSensor : public SensorInterface double velocity_state_ = 0.0; }; -class TestUnitilizableSensor : public TestSensor +class TestUninitializableSensor : public TestSensor { CallbackReturn on_init(const hardware_interface::HardwareInfo & info) override { @@ -66,4 +66,4 @@ class TestUnitilizableSensor : public TestSensor #include "pluginlib/class_list_macros.hpp" // NOLINT PLUGINLIB_EXPORT_CLASS(TestSensor, hardware_interface::SensorInterface) -PLUGINLIB_EXPORT_CLASS(TestUnitilizableSensor, hardware_interface::SensorInterface) +PLUGINLIB_EXPORT_CLASS(TestUninitializableSensor, hardware_interface::SensorInterface) diff --git a/hardware_interface_testing/test/test_components/test_system.cpp b/hardware_interface_testing/test/test_components/test_system.cpp index 88f514c24e..502f5b4c21 100644 --- a/hardware_interface_testing/test/test_components/test_system.cpp +++ b/hardware_interface_testing/test/test_components/test_system.cpp @@ -48,22 +48,19 @@ class TestSystem : public SystemInterface std::vector state_interfaces; for (auto i = 0u; i < info_.joints.size(); ++i) { - if (info_.joints[i].name != "configuration") - { - state_interfaces.emplace_back(hardware_interface::StateInterface( - info_.joints[i].name, hardware_interface::HW_IF_POSITION, &position_state_[i])); - state_interfaces.emplace_back(hardware_interface::StateInterface( - info_.joints[i].name, hardware_interface::HW_IF_VELOCITY, &velocity_state_[i])); - state_interfaces.emplace_back(hardware_interface::StateInterface( - info_.joints[i].name, hardware_interface::HW_IF_ACCELERATION, &acceleration_state_[i])); - } + state_interfaces.emplace_back(hardware_interface::StateInterface( + info_.joints[i].name, hardware_interface::HW_IF_POSITION, &position_state_[i])); + state_interfaces.emplace_back(hardware_interface::StateInterface( + info_.joints[i].name, hardware_interface::HW_IF_VELOCITY, &velocity_state_[i])); + state_interfaces.emplace_back(hardware_interface::StateInterface( + info_.joints[i].name, hardware_interface::HW_IF_ACCELERATION, &acceleration_state_[i])); } - if (info_.joints.size() > 2) + if (info_.gpios.size() > 0) { // Add configuration/max_tcp_jerk interface state_interfaces.emplace_back(hardware_interface::StateInterface( - info_.joints[2].name, info_.joints[2].state_interfaces[0].name, &configuration_state_)); + info_.gpios[0].name, info_.gpios[0].state_interfaces[0].name, &configuration_state_)); } return state_interfaces; @@ -74,22 +71,19 @@ class TestSystem : public SystemInterface std::vector command_interfaces; for (auto i = 0u; i < info_.joints.size(); ++i) { - if (info_.joints[i].name != "configuration") - { - command_interfaces.emplace_back(hardware_interface::CommandInterface( - info_.joints[i].name, hardware_interface::HW_IF_VELOCITY, &velocity_command_[i])); - } + command_interfaces.emplace_back(hardware_interface::CommandInterface( + info_.joints[i].name, hardware_interface::HW_IF_VELOCITY, &velocity_command_[i])); } // Add max_acceleration command interface command_interfaces.emplace_back(hardware_interface::CommandInterface( info_.joints[0].name, info_.joints[0].command_interfaces[1].name, &max_acceleration_command_)); - if (info_.joints.size() > 2) + if (info_.gpios.size() > 0) { // Add configuration/max_tcp_jerk interface command_interfaces.emplace_back(hardware_interface::CommandInterface( - info_.joints[2].name, info_.joints[2].command_interfaces[0].name, &configuration_command_)); + info_.gpios[0].name, info_.gpios[0].command_interfaces[0].name, &configuration_command_)); } return command_interfaces; @@ -100,7 +94,8 @@ class TestSystem : public SystemInterface // simulate error on read if (velocity_command_[0] == test_constants::READ_FAIL_VALUE) { - // reset value to get out from error on the next call - simplifies CM tests + // reset value to get out from error on the next call - simplifies CM + // tests velocity_command_[0] = 0.0; return return_type::ERROR; } @@ -117,7 +112,8 @@ class TestSystem : public SystemInterface // simulate error on write if (velocity_command_[0] == test_constants::WRITE_FAIL_VALUE) { - // reset value to get out from error on the next call - simplifies CM tests + // reset value to get out from error on the next call - simplifies CM + // tests velocity_command_[0] = 0.0; return return_type::ERROR; } @@ -139,7 +135,7 @@ class TestSystem : public SystemInterface double configuration_command_ = 0.0; }; -class TestUnitilizableSystem : public TestSystem +class TestUninitializableSystem : public TestSystem { CallbackReturn on_init(const hardware_interface::HardwareInfo & info) override { @@ -150,4 +146,4 @@ class TestUnitilizableSystem : public TestSystem #include "pluginlib/class_list_macros.hpp" // NOLINT PLUGINLIB_EXPORT_CLASS(TestSystem, hardware_interface::SystemInterface) -PLUGINLIB_EXPORT_CLASS(TestUnitilizableSystem, hardware_interface::SystemInterface) +PLUGINLIB_EXPORT_CLASS(TestUninitializableSystem, hardware_interface::SystemInterface) diff --git a/hardware_interface_testing/test/test_resource_manager.cpp b/hardware_interface_testing/test/test_resource_manager.cpp index d9c1f3b933..e57be2b4d3 100644 --- a/hardware_interface_testing/test/test_resource_manager.cpp +++ b/hardware_interface_testing/test/test_resource_manager.cpp @@ -44,6 +44,7 @@ using ros2_control_test_assets::TEST_SYSTEM_HARDWARE_NAME; using ros2_control_test_assets::TEST_SYSTEM_HARDWARE_PLUGIN_NAME; using ros2_control_test_assets::TEST_SYSTEM_HARDWARE_STATE_INTERFACES; using ros2_control_test_assets::TEST_SYSTEM_HARDWARE_TYPE; +using testing::SizeIs; auto configure_components = [](TestableResourceManager & rm, const std::vector & components = {}) @@ -101,13 +102,13 @@ TEST_F(ResourceManagerTest, post_initialization_with_urdf) ASSERT_NO_THROW(rm.load_and_initialize_components(ros2_control_test_assets::minimal_robot_urdf)); } -TEST_F(ResourceManagerTest, test_unitilizable_hardware_validation) +TEST_F(ResourceManagerTest, test_uninitializable_hardware_validation) { // If the the hardware can not be initialized and load_and_initialize_components tried to validate // the interfaces a runtime exception is thrown TestableResourceManager rm; EXPECT_FALSE( - rm.load_and_initialize_components(ros2_control_test_assets::minimal_unitilizable_robot_urdf)); + rm.load_and_initialize_components(ros2_control_test_assets::uninitializable_hardware_resources)); } void test_load_and_initialized_components_failure(const std::string & urdf) @@ -163,7 +164,7 @@ TEST_F(ResourceManagerTest, initialization_with_urdf_and_manual_validation) EXPECT_EQ(1u, rm.system_components_size()); auto state_interface_keys = rm.state_interface_keys(); - ASSERT_EQ(11u, state_interface_keys.size()); + ASSERT_THAT(state_interface_keys, SizeIs(11)); EXPECT_TRUE(rm.state_interface_exists("joint1/position")); EXPECT_TRUE(rm.state_interface_exists("joint1/velocity")); EXPECT_TRUE(rm.state_interface_exists("sensor1/velocity")); @@ -171,7 +172,7 @@ TEST_F(ResourceManagerTest, initialization_with_urdf_and_manual_validation) EXPECT_TRUE(rm.state_interface_exists("joint3/position")); auto command_interface_keys = rm.command_interface_keys(); - ASSERT_EQ(6u, command_interface_keys.size()); + ASSERT_THAT(command_interface_keys, SizeIs(6)); EXPECT_TRUE(rm.command_interface_exists("joint1/position")); EXPECT_TRUE(rm.command_interface_exists("joint2/velocity")); EXPECT_TRUE(rm.command_interface_exists("joint3/velocity")); @@ -404,8 +405,8 @@ TEST_F(ResourceManagerTest, post_initialization_add_components) EXPECT_EQ(1u, rm.sensor_components_size()); EXPECT_EQ(1u, rm.system_components_size()); - ASSERT_EQ(11u, rm.state_interface_keys().size()); - ASSERT_EQ(6u, rm.command_interface_keys().size()); + ASSERT_THAT(rm.state_interface_keys(), SizeIs(11)); + ASSERT_THAT(rm.command_interface_keys(), SizeIs(6)); hardware_interface::HardwareInfo external_component_hw_info; external_component_hw_info.name = "ExternalComponent"; @@ -414,9 +415,9 @@ TEST_F(ResourceManagerTest, post_initialization_add_components) rm.import_component(std::make_unique(), external_component_hw_info); EXPECT_EQ(2u, rm.actuator_components_size()); - ASSERT_EQ(12u, rm.state_interface_keys().size()); + ASSERT_THAT(rm.state_interface_keys(), SizeIs(12)); EXPECT_TRUE(rm.state_interface_exists("external_joint/external_state_interface")); - ASSERT_EQ(7u, rm.command_interface_keys().size()); + ASSERT_THAT(rm.command_interface_keys(), SizeIs(7)); EXPECT_TRUE(rm.command_interface_exists("external_joint/external_command_interface")); auto status_map = rm.get_components_status(); @@ -927,7 +928,8 @@ TEST_F(ResourceManagerTest, resource_availability_and_claiming_in_lifecycle) std::bind(&TestableResourceManager::command_interface_is_claimed, &rm, _1), expected_result); }; - // All resources start as UNCONFIGURED - All interfaces are imported but not available + // All resources start as UNCONFIGURED - All interfaces are imported but not + // available { check_interfaces( TEST_ACTUATOR_HARDWARE_COMMAND_INTERFACES, @@ -1007,7 +1009,8 @@ TEST_F(ResourceManagerTest, resource_availability_and_claiming_in_lifecycle) TEST_SYSTEM_HARDWARE_STATE_INTERFACES, TEST_SYSTEM_HARDWARE_COMMAND_INTERFACES, false); } - // When actuator is activated all state- and command- interfaces become available + // When actuator is activated all state- and command- interfaces become + // available activate_components(rm, {TEST_ACTUATOR_HARDWARE_NAME}); { check_interfaces( @@ -1483,7 +1486,8 @@ class ResourceManagerTestReadWriteError : public ResourceManagerTest check_if_interface_available(true, true); } - // read failure for both, TEST_ACTUATOR_HARDWARE_NAME and TEST_SYSTEM_HARDWARE_NAME + // read failure for both, TEST_ACTUATOR_HARDWARE_NAME and + // TEST_SYSTEM_HARDWARE_NAME claimed_itfs[0].set_value(fail_value); claimed_itfs[1].set_value(fail_value); { @@ -1600,7 +1604,8 @@ class ResourceManagerTestReadWriteError : public ResourceManagerTest check_if_interface_available(true, true); } - // deactivate both, TEST_ACTUATOR_HARDWARE_NAME and TEST_SYSTEM_HARDWARE_NAME + // deactivate both, TEST_ACTUATOR_HARDWARE_NAME and + // TEST_SYSTEM_HARDWARE_NAME claimed_itfs[0].set_value(deactivate_value); claimed_itfs[1].set_value(deactivate_value); { diff --git a/hardware_interface_testing/test/test_resource_manager.hpp b/hardware_interface_testing/test/test_resource_manager.hpp index 72cf9e941b..4eb7b8a799 100644 --- a/hardware_interface_testing/test/test_resource_manager.hpp +++ b/hardware_interface_testing/test/test_resource_manager.hpp @@ -48,7 +48,7 @@ class TestableResourceManager : public hardware_interface::ResourceManager FRIEND_TEST(ResourceManagerTest, post_initialization_add_components); FRIEND_TEST(ResourceManagerTest, managing_controllers_reference_interfaces); FRIEND_TEST(ResourceManagerTest, resource_availability_and_claiming_in_lifecycle); - FRIEND_TEST(ResourceManagerTest, test_unitilizable_hardware_no_validation); + FRIEND_TEST(ResourceManagerTest, test_uninitializable_hardware_no_validation); TestableResourceManager() : hardware_interface::ResourceManager() {} diff --git a/joint_limits/CHANGELOG.rst b/joint_limits/CHANGELOG.rst index f7ef260375..e318e1d3c0 100644 --- a/joint_limits/CHANGELOG.rst +++ b/joint_limits/CHANGELOG.rst @@ -2,6 +2,16 @@ Changelog for package joint_limits ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ +* generate version.h file per package using the ament_generate_version_header (`#1449 `_) +* Contributors: Sai Kishor Kothakota + +4.7.0 (2024-03-22) +------------------ +* Codeformat from new pre-commit config (`#1433 `_) +* Contributors: Christoph Fröhlich + 4.6.0 (2024-03-02) ------------------ * Add -Werror=missing-braces to compile options (`#1423 `_) diff --git a/joint_limits/CMakeLists.txt b/joint_limits/CMakeLists.txt index f0ad3de6fc..1139a5248e 100644 --- a/joint_limits/CMakeLists.txt +++ b/joint_limits/CMakeLists.txt @@ -61,3 +61,4 @@ install(TARGETS joint_limits ament_export_targets(export_joint_limits HAS_LIBRARY_TARGET) ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/joint_limits/package.xml b/joint_limits/package.xml index 1d1e8e5123..a9a1d54dfd 100644 --- a/joint_limits/package.xml +++ b/joint_limits/package.xml @@ -1,6 +1,6 @@ joint_limits - 4.6.0 + 4.8.0 Interfaces for handling of joint limits for controllers or hardware. Bence Magyar @@ -13,6 +13,7 @@ https://github.com/ros-controls/ros2_control ament_cmake + ament_cmake_gen_version_h rclcpp rclcpp_lifecycle diff --git a/ros2_control/CHANGELOG.rst b/ros2_control/CHANGELOG.rst index 16b155c1fb..1ee75204b3 100644 --- a/ros2_control/CHANGELOG.rst +++ b/ros2_control/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package ros2_control ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ + +4.7.0 (2024-03-22) +------------------ + 4.6.0 (2024-03-02) ------------------ diff --git a/ros2_control/package.xml b/ros2_control/package.xml index 2d98544c12..e6716e478d 100644 --- a/ros2_control/package.xml +++ b/ros2_control/package.xml @@ -1,7 +1,7 @@ ros2_control - 4.6.0 + 4.8.0 Metapackage for ROS2 control related packages Bence Magyar Denis Štogl diff --git a/ros2_control_test_assets/CHANGELOG.rst b/ros2_control_test_assets/CHANGELOG.rst index 9438d48922..43250ac2d4 100644 --- a/ros2_control_test_assets/CHANGELOG.rst +++ b/ros2_control_test_assets/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package ros2_control_test_assets ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ + +4.7.0 (2024-03-22) +------------------ + 4.6.0 (2024-03-02) ------------------ diff --git a/ros2_control_test_assets/include/ros2_control_test_assets/components_urdfs.hpp b/ros2_control_test_assets/include/ros2_control_test_assets/components_urdfs.hpp index a42d39a241..7b2dd46e7a 100644 --- a/ros2_control_test_assets/include/ros2_control_test_assets/components_urdfs.hpp +++ b/ros2_control_test_assets/include/ros2_control_test_assets/components_urdfs.hpp @@ -372,7 +372,9 @@ const auto valid_urdf_ros2_control_system_robot_with_gpio = - + + 1.0 + )"; diff --git a/ros2_control_test_assets/include/ros2_control_test_assets/descriptions.hpp b/ros2_control_test_assets/include/ros2_control_test_assets/descriptions.hpp index d70f9c0869..527e4db1df 100644 --- a/ros2_control_test_assets/include/ros2_control_test_assets/descriptions.hpp +++ b/ros2_control_test_assets/include/ros2_control_test_assets/descriptions.hpp @@ -113,6 +113,136 @@ const auto urdf_head = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)"; +const auto urdf_head_mimic = + R"( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -169,10 +299,10 @@ const auto hardware_resources = - + - + )"; @@ -225,11 +355,11 @@ const auto async_hardware_resources = )"; -const auto unitilizable_hardware_resources = +const auto uninitializable_hardware_resources = R"( - + - test_unitilizable_actuator + test_uninitializable_actuator @@ -238,9 +368,9 @@ const auto unitilizable_hardware_resources = - + - test_unitilizable_sensor + test_uninitializable_sensor 2 2 @@ -248,9 +378,9 @@ const auto unitilizable_hardware_resources = - + - test_unitilizable_system + test_uninitializable_system 2 2 @@ -267,10 +397,6 @@ const auto unitilizable_hardware_resources = - - - - )"; @@ -746,16 +872,16 @@ const auto diffbot_urdf = - + - - - + + + 1 1 @@ -781,16 +907,16 @@ const auto diffbot_urdf = - + - - - + + + 1 1 @@ -827,12 +953,442 @@ const auto diffbot_urdf = )"; +const auto gripper_urdf_head = + R"( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)"; + +const auto gripper_urdf_head_no_mimic = + R"( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)"; + +const auto gripper_urdf_head_unknown_joint = + R"( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)"; + +const auto gripper_urdf_head_incomplete = + R"( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)"; + +const auto gripper_urdf_head_invalid_two_root_links = + R"( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)"; + +const auto gripper_hardware_resources_no_command_if = + R"( + + + + + + + + + + + + + )"; + +const auto gripper_hardware_resources_mimic_true_no_command_if = + R"( + + + + + + + + + + + + + )"; + +// TODO(christophfroehlich) delete deprecated config test +const auto gripper_hardware_resources_mimic_deprecated = + R"( + + + + + + + + + right_finger_joint + 2 + 1 + + + + + + )"; + +const auto gripper_hardware_resources_mimic_deprecated_unknown_joint = + R"( + + + + + + + + + middle_finger_joint + 1 + + + + + + )"; +// end delete deprecated config test + +const auto gripper_hardware_resources_mimic_true_command_if = + R"( + + + + + + + + + + + + + + )"; + +const auto gripper_hardware_resources_mimic_false_command_if = + R"( + + + + + + + + + + + + + + )"; + const auto minimal_robot_urdf = std::string(urdf_head) + std::string(hardware_resources) + std::string(urdf_tail); const auto minimal_async_robot_urdf = std::string(urdf_head) + std::string(async_hardware_resources) + std::string(urdf_tail); -const auto minimal_unitilizable_robot_urdf = - std::string(urdf_head) + std::string(unitilizable_hardware_resources) + std::string(urdf_tail); +const auto minimal_uninitializable_robot_urdf = + std::string(urdf_head) + std::string(uninitializable_hardware_resources) + std::string(urdf_tail); const auto minimal_robot_not_existing_actuator_plugin = std::string(urdf_head) + std::string(hardware_resources_not_existing_actuator_plugin) + diff --git a/ros2_control_test_assets/package.xml b/ros2_control_test_assets/package.xml index 1a96f64470..ecf8d57490 100644 --- a/ros2_control_test_assets/package.xml +++ b/ros2_control_test_assets/package.xml @@ -2,7 +2,7 @@ ros2_control_test_assets - 4.6.0 + 4.8.0 The package provides shared test resources for ros2_control stack Bence Magyar diff --git a/ros2controlcli/CHANGELOG.rst b/ros2controlcli/CHANGELOG.rst index c26ac9f276..19ff351c64 100644 --- a/ros2controlcli/CHANGELOG.rst +++ b/ros2controlcli/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package ros2controlcli ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ + +4.7.0 (2024-03-22) +------------------ + 4.6.0 (2024-03-02) ------------------ * Added spawner colours to `list_controllers` depending upon active or inactive (`#1409 `_) diff --git a/ros2controlcli/package.xml b/ros2controlcli/package.xml index 220f33c9d8..c8c9ae3dc7 100644 --- a/ros2controlcli/package.xml +++ b/ros2controlcli/package.xml @@ -2,7 +2,7 @@ ros2controlcli - 4.6.0 + 4.8.0 The ROS 2 command line tools for ROS2 Control. diff --git a/ros2controlcli/setup.py b/ros2controlcli/setup.py index 65469af3c0..034f58add8 100644 --- a/ros2controlcli/setup.py +++ b/ros2controlcli/setup.py @@ -19,7 +19,7 @@ setup( name=package_name, - version="4.6.0", + version="4.8.0", packages=find_packages(exclude=["test"]), data_files=[ ("share/" + package_name, ["package.xml"]), diff --git a/rqt_controller_manager/CHANGELOG.rst b/rqt_controller_manager/CHANGELOG.rst index 0150fac8dc..a96091ae2a 100644 --- a/rqt_controller_manager/CHANGELOG.rst +++ b/rqt_controller_manager/CHANGELOG.rst @@ -2,6 +2,18 @@ Changelog for package rqt_controller_manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ +* Fix rqt_controller_manager for non-humble (`#1454 `_) +* Add cm as dependency to rqt_cm (`#1447 `_) +* Contributors: Christoph Fröhlich + +4.7.0 (2024-03-22) +------------------ +* Codeformat from new pre-commit config (`#1433 `_) +* rqt_controller_manager compatibility for humble (`#1429 `_) +* Contributors: Christoph Fröhlich + 4.6.0 (2024-03-02) ------------------ * [CI] Code coverage + pre-commit (`#1413 `_) diff --git a/rqt_controller_manager/package.xml b/rqt_controller_manager/package.xml index fe2a23d45c..61b92653a9 100644 --- a/rqt_controller_manager/package.xml +++ b/rqt_controller_manager/package.xml @@ -2,7 +2,7 @@ rqt_controller_manager - 4.6.0 + 4.8.0 Graphical frontend for interacting with the controller manager. Bence Magyar Denis Štogl @@ -18,6 +18,7 @@ Kelsey Hawkins Adolfo Rodríguez Tsouroukdissian + controller_manager controller_manager_msgs rclpy rqt_gui diff --git a/rqt_controller_manager/rqt_controller_manager/controller_manager.py b/rqt_controller_manager/rqt_controller_manager/controller_manager.py index 371eefd845..4a89b3cb97 100644 --- a/rqt_controller_manager/rqt_controller_manager/controller_manager.py +++ b/rqt_controller_manager/rqt_controller_manager/controller_manager.py @@ -415,10 +415,10 @@ def _get_parameter_controller_names(node, node_name): parameter_names = call_list_parameters(node=node, node_name=node_name) suffix = ".type" # @note: The versions conditioning is added here to support the source-compatibility with Humble - try: + if os.environ.get("ROS_DISTRO") == "humble": + # for humble, ros2param < 0.20.0 + return [n[: -len(suffix)] for n in parameter_names if n.endswith(suffix)] + else: return [ n[: -len(suffix)] for n in parameter_names.result().result.names if n.endswith(suffix) ] - finally: - # for humble, ros2param < 0.20.0 - return [n[: -len(suffix)] for n in parameter_names if n.endswith(suffix)] diff --git a/rqt_controller_manager/setup.py b/rqt_controller_manager/setup.py index 9e739e132a..c314d30353 100644 --- a/rqt_controller_manager/setup.py +++ b/rqt_controller_manager/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.6.0", + version="4.8.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/transmission_interface/CHANGELOG.rst b/transmission_interface/CHANGELOG.rst index ace4cbe665..70ac550955 100644 --- a/transmission_interface/CHANGELOG.rst +++ b/transmission_interface/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog for package transmission_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +4.8.0 (2024-03-27) +------------------ +* generate version.h file per package using the ament_generate_version_header (`#1449 `_) +* Contributors: Sai Kishor Kothakota + +4.7.0 (2024-03-22) +------------------ + 4.6.0 (2024-03-02) ------------------ * Add -Werror=missing-braces to compile options (`#1423 `_) diff --git a/transmission_interface/CMakeLists.txt b/transmission_interface/CMakeLists.txt index fc55c483d0..98dcdcd192 100644 --- a/transmission_interface/CMakeLists.txt +++ b/transmission_interface/CMakeLists.txt @@ -31,6 +31,7 @@ pluginlib_export_plugin_description_file(transmission_interface ros2_control_plu if(BUILD_TESTING) find_package(ament_cmake_gmock REQUIRED) + find_package(ros2_control_test_assets REQUIRED) ament_add_gmock(test_simple_transmission test/simple_transmission_test.cpp @@ -51,16 +52,19 @@ if(BUILD_TESTING) test/simple_transmission_loader_test.cpp ) target_link_libraries(test_simple_transmission_loader transmission_interface) + ament_target_dependencies(test_simple_transmission_loader ros2_control_test_assets) ament_add_gmock(test_four_bar_linkage_transmission_loader test/four_bar_linkage_transmission_loader_test.cpp ) target_link_libraries(test_four_bar_linkage_transmission_loader transmission_interface) + ament_target_dependencies(test_four_bar_linkage_transmission_loader ros2_control_test_assets) ament_add_gmock(test_differential_transmission_loader test/differential_transmission_loader_test.cpp ) target_link_libraries(test_differential_transmission_loader transmission_interface) + ament_target_dependencies(test_differential_transmission_loader ros2_control_test_assets) ament_add_gmock( test_utils @@ -84,3 +88,4 @@ install(TARGETS transmission_interface ament_export_targets(export_transmission_interface HAS_LIBRARY_TARGET) ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/transmission_interface/package.xml b/transmission_interface/package.xml index f940e04b53..2ca9d43928 100644 --- a/transmission_interface/package.xml +++ b/transmission_interface/package.xml @@ -2,18 +2,20 @@ transmission_interface - 4.6.0 + 4.8.0 transmission_interface contains data structures for representing mechanical transmissions, methods for propagating values between actuator and joint spaces and tooling to support this. Bence Magyar Denis Štogl Apache License 2.0 ament_cmake + ament_cmake_gen_version_h hardware_interface pluginlib ament_cmake_gmock + ros2_control_test_assets ament_cmake diff --git a/transmission_interface/test/differential_transmission_loader_test.cpp b/transmission_interface/test/differential_transmission_loader_test.cpp index 70d0adf2cd..946c4703b5 100644 --- a/transmission_interface/test/differential_transmission_loader_test.cpp +++ b/transmission_interface/test/differential_transmission_loader_test.cpp @@ -22,6 +22,7 @@ #include "hardware_interface/hardware_info.hpp" #include "hardware_interface/types/hardware_interface_type_values.hpp" #include "pluginlib/class_loader.hpp" +#include "ros2_control_test_assets/descriptions.hpp" #include "transmission_interface/differential_transmission.hpp" #include "transmission_interface/differential_transmission_loader.hpp" #include "transmission_interface/transmission_loader.hpp" @@ -57,9 +58,7 @@ class TransmissionPluginLoader TEST(DifferentialTransmissionLoaderTest, FullSpec) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -132,9 +131,7 @@ TEST(DifferentialTransmissionLoaderTest, FullSpec) TEST(DifferentialTransmissionLoaderTest, only_mech_red_specified) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -203,9 +200,7 @@ TEST(DifferentialTransmissionLoaderTest, only_mech_red_specified) TEST(SimpleTransmissionLoaderTest, offset_and_mech_red_not_specified) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -266,9 +261,7 @@ TEST(SimpleTransmissionLoaderTest, offset_and_mech_red_not_specified) TEST(DifferentialTransmissionLoaderTest, mechanical_reduction_not_a_number) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -338,9 +331,7 @@ TEST(DifferentialTransmissionLoaderTest, mechanical_reduction_not_a_number) TEST(DifferentialTransmissionLoaderTest, offset_ill_defined) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -413,9 +404,7 @@ TEST(DifferentialTransmissionLoaderTest, offset_ill_defined) TEST(DifferentialTransmissionLoaderTest, mech_red_invalid_value) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( diff --git a/transmission_interface/test/four_bar_linkage_transmission_loader_test.cpp b/transmission_interface/test/four_bar_linkage_transmission_loader_test.cpp index 53b584b7b5..720cad68b4 100644 --- a/transmission_interface/test/four_bar_linkage_transmission_loader_test.cpp +++ b/transmission_interface/test/four_bar_linkage_transmission_loader_test.cpp @@ -22,6 +22,7 @@ #include "hardware_interface/hardware_info.hpp" #include "hardware_interface/types/hardware_interface_type_values.hpp" #include "pluginlib/class_loader.hpp" +#include "ros2_control_test_assets/descriptions.hpp" #include "transmission_interface/four_bar_linkage_transmission.hpp" #include "transmission_interface/four_bar_linkage_transmission_loader.hpp" #include "transmission_interface/transmission_loader.hpp" @@ -57,9 +58,7 @@ class TransmissionPluginLoader TEST(FourBarLinkageTransmissionLoaderTest, FullSpec) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -133,9 +132,7 @@ TEST(FourBarLinkageTransmissionLoaderTest, FullSpec) TEST(FourBarLinkageTransmissionLoaderTest, only_mech_red_specified) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -205,9 +202,7 @@ TEST(FourBarLinkageTransmissionLoaderTest, only_mech_red_specified) TEST(DifferentialTransmissionLoaderTest, offset_and_mech_red_not_specified) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -269,9 +264,7 @@ TEST(DifferentialTransmissionLoaderTest, offset_and_mech_red_not_specified) TEST(FourBarLinkageTransmissionLoaderTest, mechanical_reduction_not_a_number) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -342,9 +335,7 @@ TEST(FourBarLinkageTransmissionLoaderTest, mechanical_reduction_not_a_number) TEST(FourBarLinkageTransmissionLoaderTest, offset_ill_defined) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -418,9 +409,7 @@ TEST(FourBarLinkageTransmissionLoaderTest, offset_ill_defined) TEST(FourBarLinkageTransmissionLoaderTest, mech_red_invalid_value) { // Parse transmission info - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( diff --git a/transmission_interface/test/simple_transmission_loader_test.cpp b/transmission_interface/test/simple_transmission_loader_test.cpp index 4623d8c409..968f64c6e8 100644 --- a/transmission_interface/test/simple_transmission_loader_test.cpp +++ b/transmission_interface/test/simple_transmission_loader_test.cpp @@ -22,6 +22,7 @@ #include "hardware_interface/hardware_info.hpp" #include "hardware_interface/types/hardware_interface_type_values.hpp" #include "pluginlib/class_loader.hpp" +#include "ros2_control_test_assets/descriptions.hpp" #include "transmission_interface/simple_transmission.hpp" #include "transmission_interface/simple_transmission_loader.hpp" #include "transmission_interface/transmission_loader.hpp" @@ -58,106 +59,8 @@ TEST(SimpleTransmissionLoaderTest, FullSpec) { // Parse transmission info - std::string urdf_to_test = - R"( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + + R"( ros2_control_demo_hardware/VelocityActuatorHardware @@ -239,9 +142,7 @@ TEST(SimpleTransmissionLoaderTest, FullSpec) TEST(SimpleTransmissionLoaderTest, only_mech_red_specified) { - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -285,9 +186,7 @@ TEST(SimpleTransmissionLoaderTest, only_mech_red_specified) TEST(SimpleTransmissionLoaderTest, offset_and_mech_red_not_specified) { - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -327,9 +226,7 @@ TEST(SimpleTransmissionLoaderTest, offset_and_mech_red_not_specified) TEST(SimpleTransmissionLoaderTest, mechanical_reduction_not_a_number) { - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -369,9 +266,7 @@ TEST(SimpleTransmissionLoaderTest, mechanical_reduction_not_a_number) TEST(SimpleTransmissionLoaderTest, offset_ill_defined) { - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( @@ -413,11 +308,9 @@ TEST(SimpleTransmissionLoaderTest, offset_ill_defined) TEST(SimpleTransmissionLoaderTest, mech_red_invalid_value) { - std::string urdf_to_test = R"( - - + std::string urdf_to_test = std::string(ros2_control_test_assets::urdf_head) + R"( - + -1 1 @@ -426,7 +319,7 @@ TEST(SimpleTransmissionLoaderTest, mech_red_invalid_value) transmission_interface/SimpleTransmission - + 0