Skip to content

Commit 7ad3cee

Browse files
Merge branch 'master' into touchup
2 parents 4fe2b6f + 7d81236 commit 7ad3cee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+398
-252
lines changed

controller_interface/CHANGELOG.rst

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Changelog for package controller_interface
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
4.28.1 (2025-04-17)
6+
-------------------
7+
58
4.28.0 (2025-04-10)
69
-------------------
710
* Make all packages use gmock, not gtest (`#2162 <https://github.com/ros-controls/ros2_control/issues/2162>`_)

controller_interface/package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
33
<package format="2">
44
<name>controller_interface</name>
5-
<version>4.28.0</version>
5+
<version>4.28.1</version>
66
<description>Base classes for controllers and syntax cookies for supporting common sensor types in controllers and broadcasters</description>
77
<maintainer email="[email protected]">Bence Magyar</maintainer>
88
<maintainer email="[email protected]">Denis Štogl</maintainer>

controller_manager/CHANGELOG.rst

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
Changelog for package controller_manager
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
4.28.1 (2025-04-17)
6+
-------------------
7+
* Fix the enforce_command_limits deactivation (`#2181 <https://github.com/ros-controls/ros2_control/issues/2181>`_)
8+
* Contributors: Sai Kishor Kothakota
9+
510
4.28.0 (2025-04-10)
611
-------------------
712
* Integrate joint limit enforcement into `ros2_control` framework functional with Async controllers and components (`#2047 <https://github.com/ros-controls/ros2_control/issues/2047>`_)

controller_manager/doc/controller_chaining.rst

+6-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@ This means the following:
4848

4949
.. note::
5050

51-
Only the controllers that exposes the reference interfaces are switched to chained mode, when their reference interfaces are used by other controllers. When their reference interfaces are not used by the other controllers, they are switched back to get references from the subscriber.
52-
However, the controllers that exposes the state interfaces are not triggered to chained mode, when their state interfaces are used by other controllers.
51+
Controllers that expose the reference interfaces are switched to chained mode only when their reference interfaces are used by other controllers. When their reference interfaces are not used by other controllers, they are switched back to get references from the subscriber.
52+
However, the controllers that expose the state interfaces are not triggered to chained mode when their state interfaces are used by other controllers.
53+
54+
.. note::
55+
56+
This document uses terms *preceding* and *following* controller. These terms refer to such ordering of controllers that controller A *precedes* controller B if A claims (*connects its output to*) B's reference interfaces (*inputs*). In the example diagram at the beginning of this section, 'diff_drive_controller' *precedes* 'pid left wheel' and 'pid right wheel'. Consequently, 'pid left wheel' and 'pid right wheel' are controllers *following* after 'diff_drive_controller'.
5357

5458
Implementation
5559
--------------

controller_manager/package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
33
<package format="2">
44
<name>controller_manager</name>
5-
<version>4.28.0</version>
5+
<version>4.28.1</version>
66
<description>The main runnable entrypoint of ros2_control and home of controller management and resource management.</description>
77
<maintainer email="[email protected]">Bence Magyar</maintainer>
88
<maintainer email="[email protected]">Denis Štogl</maintainer>

controller_manager/src/controller_manager.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,10 @@ void ControllerManager::init_controller_manager()
499499
// Get parameters needed for RT "update" loop to work
500500
if (is_resource_manager_initialized())
501501
{
502-
resource_manager_->import_joint_limiters(robot_description_);
502+
if (enforce_command_limits_)
503+
{
504+
resource_manager_->import_joint_limiters(robot_description_);
505+
}
503506
init_services();
504507
}
505508
else
@@ -621,7 +624,10 @@ void ControllerManager::robot_description_callback(const std_msgs::msg::String &
621624

622625
void ControllerManager::init_resource_manager(const std::string & robot_description)
623626
{
624-
resource_manager_->import_joint_limiters(robot_description_);
627+
if (enforce_command_limits_)
628+
{
629+
resource_manager_->import_joint_limiters(robot_description_);
630+
}
625631
if (!resource_manager_->load_and_initialize_components(robot_description, update_rate_))
626632
{
627633
RCLCPP_WARN(
@@ -2880,11 +2886,7 @@ controller_interface::return_type ControllerManager::update(
28802886
// To publish the activity of the failing controllers and the fallback controllers
28812887
publish_activity();
28822888
}
2883-
2884-
if (enforce_command_limits_)
2885-
{
2886-
resource_manager_->enforce_command_limits(period);
2887-
}
2889+
resource_manager_->enforce_command_limits(period);
28882890

28892891
// there are controllers to (de)activate
28902892
if (switch_params_.do_switch)

controller_manager_msgs/CHANGELOG.rst

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Changelog for package controller_manager_msgs
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
4.28.1 (2025-04-17)
6+
-------------------
7+
58
4.28.0 (2025-04-10)
69
-------------------
710
* [CM] Extend the list controller and hardware components messages (`#2102 <https://github.com/ros-controls/ros2_control/issues/2102>`_)

controller_manager_msgs/package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
33
<package format="3">
44
<name>controller_manager_msgs</name>
5-
<version>4.28.0</version>
5+
<version>4.28.1</version>
66
<description>Messages and services for the controller manager.</description>
77
<maintainer email="[email protected]">Bence Magyar</maintainer>
88
<maintainer email="[email protected]">Denis Štogl</maintainer>

doc/introspection.rst

+12-5
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,19 @@ Data Visualization
7070

7171
Data can be visualized with any tools that display ROS topics, but we recommend `PlotJuggler <https://plotjuggler.io/>`_ for viewing high resolution live data, or data in bags.
7272

73-
1. Open ``PlotJuggler`` running ``ros2 run plotjuggler plotjuggler``.
73+
1. Open ``PlotJuggler`` by running ``ros2 run plotjuggler plotjuggler`` from the command line.
74+
7475
.. image:: images/plotjuggler.png
75-
2. Visualize the data:
76-
- Importing from the ros2bag
77-
- Subscribing to the ROS2 topics live with the ``ROS2 Topic Subscriber`` option under ``Streaming`` header.
76+
:alt: PlotJuggler
77+
78+
2. Visualize the data by importing from the ros2bag file or subscribing to the ROS2 topics live with the ``ROS2 Topic Subscriber`` option under ``Streaming`` header.
79+
7880
3. Choose the topics ``~/introspection_data/names`` and ``~/introspection_data/values`` from the popup window.
81+
7982
.. image:: images/plotjuggler_select_topics.png
80-
4. Now, select the variables that are of your interest and drag them to the plot.
83+
:alt: PlotJuggler Select Topics
84+
85+
4. Then, select the variables that are of your interest and drag them to the plot.
86+
8187
.. image:: images/plotjuggler_visualizing_data.png
88+
:alt: PlotJuggler Visualizing Data

hardware_interface/CHANGELOG.rst

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
Changelog for package hardware_interface
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
4.28.1 (2025-04-17)
6+
-------------------
7+
* Avoid running joint limit enforcement during initialization (`#2188 <https://github.com/ros-controls/ros2_control/issues/2188>`_)
8+
* Use previous command to enforce the joint limits on position interfaces (`#2183 <https://github.com/ros-controls/ros2_control/issues/2183>`_)
9+
* Add log info for the type of joint limits being used (`#2186 <https://github.com/ros-controls/ros2_control/issues/2186>`_)
10+
* Fix the joint limits enforcement with `position` and `velocity` (`#2182 <https://github.com/ros-controls/ros2_control/issues/2182>`_)
11+
* Only log limiting error if something is limited. (`#2176 <https://github.com/ros-controls/ros2_control/issues/2176>`_)
12+
* Contributors: Felix Exner (fexner), Sai Kishor Kothakota
13+
514
4.28.0 (2025-04-10)
615
-------------------
716
* [HW Interface] Use new handle API inside the hardware components (`#2092 <https://github.com/ros-controls/ros2_control/issues/2092>`_)

hardware_interface/include/hardware_interface/handle.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ class Handle
319319
// END
320320
}
321321

322-
std::shared_mutex & get_mutex() { return handle_mutex_; }
322+
std::shared_mutex & get_mutex() const { return handle_mutex_; }
323323

324324
HandleDataType get_data_type() const { return data_type_; }
325325

hardware_interface/include/hardware_interface/resource_manager.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ class ResourceManager
527527
mutable std::recursive_mutex resource_interfaces_lock_;
528528
mutable std::recursive_mutex claimed_command_interfaces_lock_;
529529
mutable std::recursive_mutex resources_lock_;
530+
mutable std::recursive_mutex joint_limiters_lock_;
530531

531532
private:
532533
bool validate_storage(const std::vector<hardware_interface::HardwareInfo> & hardware_info) const;

hardware_interface/package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<package format="2">
33
<name>hardware_interface</name>
4-
<version>4.28.0</version>
4+
<version>4.28.1</version>
55
<description>Base classes for hardware abstraction and tooling for them</description>
66
<maintainer email="[email protected]">Bence Magyar</maintainer>
77
<maintainer email="[email protected]">Denis Štogl</maintainer>

hardware_interface/src/resource_manager.cpp

+52-9
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,15 @@ class ResourceStorage
693693
if (hw_info.soft_limits.find(joint_name) != hw_info.soft_limits.end())
694694
{
695695
soft_limits = {hw_info.soft_limits.at(joint_name)};
696+
RCLCPP_INFO(
697+
get_logger(), "Using SoftJointLimiter for joint '%s' in hardware '%s' : '%s'",
698+
joint_name.c_str(), hw_info.name.c_str(), soft_limits[0].to_string().c_str());
699+
}
700+
else
701+
{
702+
RCLCPP_INFO(
703+
get_logger(), "Using JointLimiter for joint '%s' in hardware '%s' : '%s'",
704+
joint_name.c_str(), hw_info.name.c_str(), limits.to_string().c_str());
696705
}
697706
std::unique_ptr<
698707
joint_limits::JointLimiterInterface<joint_limits::JointControlInterfacesData>>
@@ -731,14 +740,19 @@ class ResourceStorage
731740
const std::string interface_name = joint_name + "/" + interface_type;
732741
if (interface_map.find(interface_name) != interface_map.end())
733742
{
734-
// If the command interface is not claimed, then the value is not set
735-
if (is_command_itf && !claimed_command_interface_map_.at(interface_name))
743+
// If the command interface is not claimed, then the value is not set (or) if the
744+
// interface doesn't exist, then value is not set
745+
if (
746+
is_command_itf && (claimed_command_interface_map_.count(interface_name) == 0 ||
747+
!claimed_command_interface_map_.at(interface_name)))
736748
{
737749
value = std::nullopt;
738750
}
739751
else
740752
{
741-
value = interface_map.at(interface_name)->get_value();
753+
auto itf_handle = interface_map.at(interface_name);
754+
std::shared_lock<std::shared_mutex> lock(itf_handle->get_mutex());
755+
value = itf_handle->get_optional(lock).value();
742756
}
743757
}
744758
};
@@ -760,7 +774,9 @@ class ResourceStorage
760774
const std::string interface_name = limited_command.joint_name + "/" + interface_type;
761775
if (data.has_value() && interface_map.find(interface_name) != interface_map.end())
762776
{
763-
interface_map.at(interface_name)->set_value(data.value());
777+
auto itf_handle = interface_map.at(interface_name);
778+
std::unique_lock<std::shared_mutex> lock(itf_handle->get_mutex());
779+
std::ignore = itf_handle->set_value(lock, data.value());
764780
}
765781
};
766782
// update the command data of the limiters
@@ -948,7 +964,8 @@ class ResourceStorage
948964
interface_name.c_str());
949965
continue;
950966
}
951-
const auto limiter_fn = [&, interface_name](double value, bool & is_limited) -> double
967+
const auto limiter_fn = [this, joint_name, interface_name, desired_period, &limiters](
968+
double value, bool & is_limited) -> double
952969
{
953970
is_limited = false;
954971
joint_limits::JointInterfacesCommandLimiterData data;
@@ -976,10 +993,14 @@ class ResourceStorage
976993
}
977994
data.limited = data.command;
978995
is_limited = limiters[joint_name]->enforce(data.actual, data.limited, desired_period);
979-
RCLCPP_ERROR_THROTTLE(
980-
get_logger(), *rm_clock_, 1000,
981-
"Command '%s' for joint '%s' is out of limits. Command limited to %f - %d",
982-
interface_name.c_str(), joint_name.c_str(), value, is_limited);
996+
if (is_limited)
997+
{
998+
RCLCPP_ERROR_THROTTLE(
999+
get_logger(), *rm_clock_, 1000,
1000+
"Command of at least one joint is out of limits (throttled log). %s with desired "
1001+
"period : %f sec.",
1002+
data.to_string().c_str(), desired_period.seconds());
1003+
}
9831004
if (
9841005
interface_name == hardware_interface::HW_IF_POSITION &&
9851006
data.limited.position.has_value())
@@ -1428,6 +1449,7 @@ bool ResourceManager::load_and_initialize_components(
14281449

14291450
void ResourceManager::import_joint_limiters(const std::string & urdf)
14301451
{
1452+
std::lock_guard<std::recursive_mutex> guard(joint_limiters_lock_);
14311453
const auto hardware_info = hardware_interface::parse_control_resources_from_urdf(urdf);
14321454
resource_storage_->import_joint_limiters(hardware_info);
14331455
}
@@ -1949,6 +1971,21 @@ bool ResourceManager::perform_command_mode_switch(
19491971
const bool actuators_result = call_perform_mode_switch(resource_storage_->actuators_);
19501972
const bool systems_result = call_perform_mode_switch(resource_storage_->systems_);
19511973

1974+
if (actuators_result && systems_result)
1975+
{
1976+
// Reset the internals of the joint limiters
1977+
for (auto & [hw_name, limiters] : resource_storage_->joint_limiters_interface_)
1978+
{
1979+
for (const auto & [joint_name, limiter] : limiters)
1980+
{
1981+
limiter->reset_internals();
1982+
RCLCPP_DEBUG(
1983+
get_logger(), "Resetting internals of joint limiter for joint '%s' in hardware '%s'",
1984+
joint_name.c_str(), hw_name.c_str());
1985+
}
1986+
}
1987+
}
1988+
19521989
return actuators_result && systems_result;
19531990
}
19541991

@@ -2039,6 +2076,12 @@ return_type ResourceManager::set_component_state(
20392076
// CM API: Called in "update"-thread
20402077
bool ResourceManager::enforce_command_limits(const rclcpp::Duration & period)
20412078
{
2079+
std::unique_lock<std::recursive_mutex> limiters_guard(joint_limiters_lock_, std::try_to_lock);
2080+
if (!limiters_guard.owns_lock())
2081+
{
2082+
return false;
2083+
}
2084+
20422085
bool enforce_result = false;
20432086
// Joint Limiters operations
20442087
for (auto & [hw_name, limiters] : resource_storage_->joint_limiters_interface_)

hardware_interface_testing/CHANGELOG.rst

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
Changelog for package hardware_interface_testing
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
4.28.1 (2025-04-17)
6+
-------------------
7+
* Use previous command to enforce the joint limits on position interfaces (`#2183 <https://github.com/ros-controls/ros2_control/issues/2183>`_)
8+
* Contributors: Sai Kishor Kothakota
9+
510
4.28.0 (2025-04-10)
611
-------------------
712
* Integrate joint limit enforcement into `ros2_control` framework functional with Async controllers and components (`#2047 <https://github.com/ros-controls/ros2_control/issues/2047>`_)

hardware_interface_testing/package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<package format="2">
33
<name>hardware_interface_testing</name>
4-
<version>4.28.0</version>
4+
<version>4.28.1</version>
55
<description>Commonly used test fixtures for the ros2_control framework</description>
66
<maintainer email="[email protected]">Bence Magyar</maintainer>
77
<maintainer email="[email protected]">Denis Štogl</maintainer>

hardware_interface_testing/test/test_components/test_actuator.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,15 @@ class TestActuator : public ActuatorInterface
102102
const std::vector<std::string> & /*start_interfaces*/,
103103
const std::vector<std::string> & /*stop_interfaces*/) override
104104
{
105-
position_state_ += 1.0;
105+
position_state_ += 0.001;
106106
return hardware_interface::return_type::OK;
107107
}
108108

109109
hardware_interface::return_type perform_command_mode_switch(
110110
const std::vector<std::string> & /*start_interfaces*/,
111111
const std::vector<std::string> & /*stop_interfaces*/) override
112112
{
113-
position_state_ += 100.0;
113+
position_state_ += 0.1;
114114
return hardware_interface::return_type::OK;
115115
}
116116

0 commit comments

Comments
 (0)