Skip to content

Commit 986a2c0

Browse files
authored
Add parameter for deactivating dynamic_joint_states (backport #2064) (#2067)
1 parent f3f1dcd commit 986a2c0

File tree

5 files changed

+101
-49
lines changed

5 files changed

+101
-49
lines changed

doc/release_notes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ imu_sensor_broadcaster
1818
*******************************
1919
* IMU sensor broadcaster is now a chainable controller. It supports a calibration by means of a rotation, defined as euler angles, to its target frame. (`#1833 <https://github.com/ros-controls/ros2_controllers/pull/1833/files>`__).
2020

21+
joint_state_broadcaster
22+
************************
23+
* Make all parameters read-only (the never got re-evaluated after initialization anyways). (`#2064 <https://github.com/ros-controls/ros2_controllers/pull/2064>`_)
24+
* Added parameter ``publish_dynamic_joint_states`` to enable/disable publishing of dynamic joint states. (`#2064 <https://github.com/ros-controls/ros2_controllers/pull/2064>`_)
25+
2126
joint_trajectory_controller
2227
*******************************
2328
* The controller now supports the new anti-windup strategy of the PID class, which allows for more flexible control of the anti-windup behavior. (`#1759 <https://github.com/ros-controls/ros2_controllers/pull/1759>`__).

joint_state_broadcaster/src/joint_state_broadcaster.cpp

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,15 @@ controller_interface::CallbackReturn JointStateBroadcaster::on_configure(
144144
std::make_shared<realtime_tools::RealtimePublisher<sensor_msgs::msg::JointState>>(
145145
joint_state_publisher_);
146146

147-
dynamic_joint_state_publisher_ =
148-
get_node()->create_publisher<control_msgs::msg::DynamicJointState>(
149-
topic_name_prefix + "dynamic_joint_states", rclcpp::SystemDefaultsQoS());
150-
151-
realtime_dynamic_joint_state_publisher_ =
152-
std::make_shared<realtime_tools::RealtimePublisher<control_msgs::msg::DynamicJointState>>(
153-
dynamic_joint_state_publisher_);
147+
if (params_.publish_dynamic_joint_states)
148+
{
149+
dynamic_joint_state_publisher_ =
150+
get_node()->create_publisher<control_msgs::msg::DynamicJointState>(
151+
topic_name_prefix + "dynamic_joint_states", rclcpp::SystemDefaultsQoS());
152+
realtime_dynamic_joint_state_publisher_ =
153+
std::make_shared<realtime_tools::RealtimePublisher<control_msgs::msg::DynamicJointState>>(
154+
dynamic_joint_state_publisher_);
155+
}
154156
}
155157
catch (const std::exception & e)
156158
{
@@ -202,7 +204,11 @@ controller_interface::CallbackReturn JointStateBroadcaster::on_activate(
202204

203205
init_auxiliary_data();
204206
init_joint_state_msg();
205-
init_dynamic_joint_state_msg();
207+
208+
if (params_.publish_dynamic_joint_states)
209+
{
210+
init_dynamic_joint_state_msg();
211+
}
206212

207213
return CallbackReturn::SUCCESS;
208214
}
@@ -390,22 +396,6 @@ bool JointStateBroadcaster::use_all_available_interfaces() const
390396
return params_.joints.empty() || params_.interfaces.empty();
391397
}
392398

393-
double get_value(
394-
const std::unordered_map<std::string, std::unordered_map<std::string, double>> & map,
395-
const std::string & name, const std::string & interface_name)
396-
{
397-
const auto & interfaces_and_values = map.at(name);
398-
const auto interface_and_value = interfaces_and_values.find(interface_name);
399-
if (interface_and_value != interfaces_and_values.cend())
400-
{
401-
return interface_and_value->second;
402-
}
403-
else
404-
{
405-
return kUninitializedValue;
406-
}
407-
}
408-
409399
controller_interface::return_type JointStateBroadcaster::update(
410400
const rclcpp::Time & time, const rclcpp::Duration & /*period*/)
411401
{

joint_state_broadcaster/src/joint_state_broadcaster_parameters.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ joint_state_broadcaster:
22
use_local_topics: {
33
type: bool,
44
default_value: false,
5+
read_only: true,
56
description: "Defining if ``joint_states`` and ``dynamic_joint_states`` messages should be published into local namespace, e.g., ``/my_state_broadcaster/joint_states``."
67
}
78
joints: {
89
type: string_array,
910
default_value: [],
11+
read_only: true,
1012
description: "Parameter to support broadcasting of only specific joints and interfaces.
1113
It has to be used in combination with the ``interfaces`` parameter.
1214
If either ``joints`` or ``interfaces`` is left empty, all available state interfaces will be
@@ -16,11 +18,13 @@ joint_state_broadcaster:
1618
extra_joints: {
1719
type: string_array,
1820
default_value: [],
21+
read_only: true,
1922
description: "Names of extra joints to be added to ``joint_states`` and ``dynamic_joint_states`` with state set to 0."
2023
}
2124
interfaces: {
2225
type: string_array,
2326
default_value: [],
27+
read_only: true,
2428
description: "Parameter to support broadcasting of only specific joints and interfaces.
2529
It has to be used in combination with the ``joints`` parameter.
2630
If either ``joints`` or ``interfaces`` is left empty, all available state interfaces will be
@@ -30,24 +34,35 @@ joint_state_broadcaster:
3034
position: {
3135
type: string,
3236
default_value: "position",
37+
read_only: true,
3338
}
3439
velocity: {
3540
type: string,
3641
default_value: "velocity",
42+
read_only: true,
3743
}
3844
effort: {
3945
type: string,
4046
default_value: "effort",
47+
read_only: true,
4148
}
4249
use_urdf_to_filter: {
4350
type: bool,
4451
default_value: true,
52+
read_only: true,
4553
description: "Uses the robot_description to filter the ``joint_states`` topic.
4654
If true, the broadcaster will publish the data of the joints present in the URDF alone.
4755
If false, the broadcaster will publish the data of any interface that has type ``position``, ``velocity``, or ``effort``."
4856
}
4957
frame_id: {
5058
type: string,
5159
default_value: "base_link",
60+
read_only: true,
5261
description: "The frame_id to be used in the published joint states. This parameter allows rviz2 to visualize the effort of the joints."
5362
}
63+
publish_dynamic_joint_states: {
64+
type: bool,
65+
default_value: true,
66+
read_only: true,
67+
description: "Whether to publish dynamic joint states."
68+
}

joint_state_broadcaster/test/test_joint_state_broadcaster.cpp

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,28 +60,35 @@ void JointStateBroadcasterTest::SetUp()
6060
void JointStateBroadcasterTest::TearDown() { state_broadcaster_.reset(nullptr); }
6161

6262
void JointStateBroadcasterTest::SetUpStateBroadcaster(
63-
const std::vector<std::string> & joint_names, const std::vector<std::string> & interfaces)
63+
const std::vector<std::string> & joint_names, const std::vector<std::string> & interfaces,
64+
const std::vector<rclcpp::Parameter> & parameter_overrides)
6465
{
65-
init_broadcaster_and_set_parameters("", joint_names, interfaces);
66+
init_broadcaster_and_set_parameters("", joint_names, interfaces, parameter_overrides);
6667
assign_state_interfaces(joint_names, interfaces);
6768
}
6869

6970
void JointStateBroadcasterTest::init_broadcaster_and_set_parameters(
7071
const std::string & robot_description, const std::vector<std::string> & joint_names,
71-
const std::vector<std::string> & interfaces)
72+
const std::vector<std::string> & interfaces,
73+
const std::vector<rclcpp::Parameter> & parameter_overrides)
7274
{
75+
auto local_parameter_overrides = parameter_overrides;
76+
local_parameter_overrides.push_back(rclcpp::Parameter("frame_id", frame_id_));
77+
local_parameter_overrides.push_back(rclcpp::Parameter("joints", joint_names));
78+
local_parameter_overrides.push_back(rclcpp::Parameter("interfaces", interfaces));
79+
7380
controller_interface::ControllerInterfaceParams params;
7481
params.controller_name = "joint_state_broadcaster";
7582
params.robot_description = robot_description;
7683
params.update_rate = 0;
7784
params.node_namespace = "";
78-
params.node_options = state_broadcaster_->define_custom_node_options();
85+
params.node_options = state_broadcaster_->define_custom_node_options()
86+
.allow_undeclared_parameters(false)
87+
.parameter_overrides(local_parameter_overrides)
88+
.automatically_declare_parameters_from_overrides(false);
89+
;
7990
const auto result = state_broadcaster_->init(params);
8091
ASSERT_EQ(result, controller_interface::return_type::OK);
81-
82-
state_broadcaster_->get_node()->set_parameter({"joints", joint_names});
83-
state_broadcaster_->get_node()->set_parameter({"interfaces", interfaces});
84-
state_broadcaster_->get_node()->set_parameter({"frame_id", frame_id_});
8592
}
8693

8794
void JointStateBroadcasterTest::assign_state_interfaces(
@@ -205,6 +212,42 @@ TEST_F(JointStateBroadcasterTest, ActivateEmptyTest)
205212
ElementsAreArray(interface_names_));
206213
}
207214

215+
TEST_F(JointStateBroadcasterTest, ActivateEmptyWithoutDynamicJointStatesPublisherTest)
216+
{
217+
// publishers not initialized yet
218+
ASSERT_FALSE(state_broadcaster_->joint_state_publisher_);
219+
ASSERT_FALSE(state_broadcaster_->dynamic_joint_state_publisher_);
220+
221+
SetUpStateBroadcaster({}, {}, {rclcpp::Parameter("publish_dynamic_joint_states", false)});
222+
// configure ok
223+
ASSERT_EQ(state_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS);
224+
225+
ASSERT_EQ(state_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS);
226+
227+
const size_t NUM_JOINTS = joint_names_.size();
228+
229+
// check interface configuration
230+
auto cmd_if_conf = state_broadcaster_->command_interface_configuration();
231+
ASSERT_THAT(cmd_if_conf.names, IsEmpty());
232+
EXPECT_EQ(cmd_if_conf.type, controller_interface::interface_configuration_type::NONE);
233+
auto state_if_conf = state_broadcaster_->state_interface_configuration();
234+
ASSERT_THAT(state_if_conf.names, IsEmpty());
235+
EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::ALL);
236+
237+
// publisher initialized
238+
ASSERT_TRUE(state_broadcaster_->realtime_joint_state_publisher_);
239+
// dynamic joint states publisher still not initialized
240+
ASSERT_FALSE(state_broadcaster_->realtime_dynamic_joint_state_publisher_);
241+
242+
// joint state initialized
243+
const auto & joint_state_msg = state_broadcaster_->joint_state_msg_;
244+
ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_);
245+
ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_));
246+
ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS));
247+
ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS));
248+
ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS));
249+
}
250+
208251
TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfacesTest)
209252
{
210253
// publishers not initialized yet
@@ -846,10 +889,10 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMapping)
846889
{
847890
const std::vector<std::string> JOINT_NAMES = {joint_names_[0]};
848891
const std::vector<std::string> IF_NAMES = {custom_interface_name_};
849-
SetUpStateBroadcaster(JOINT_NAMES, IF_NAMES);
850-
851-
state_broadcaster_->get_node()->set_parameter(
852-
{std::string("map_interface_to_joint_state.") + HW_IF_POSITION, custom_interface_name_});
892+
SetUpStateBroadcaster(
893+
JOINT_NAMES, IF_NAMES,
894+
{rclcpp::Parameter(
895+
std::string("map_interface_to_joint_state.") + HW_IF_POSITION, custom_interface_name_)});
853896

854897
// configure ok
855898
ASSERT_EQ(state_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS);
@@ -901,10 +944,10 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMappingUpdate)
901944
{
902945
const std::vector<std::string> JOINT_NAMES = {joint_names_[0]};
903946
const std::vector<std::string> IF_NAMES = {custom_interface_name_};
904-
SetUpStateBroadcaster(JOINT_NAMES, IF_NAMES);
905-
906-
state_broadcaster_->get_node()->set_parameter(
907-
{std::string("map_interface_to_joint_state.") + HW_IF_POSITION, custom_interface_name_});
947+
SetUpStateBroadcaster(
948+
JOINT_NAMES, IF_NAMES,
949+
{rclcpp::Parameter(
950+
std::string("map_interface_to_joint_state.") + HW_IF_POSITION, custom_interface_name_)});
908951

909952
sensor_msgs::msg::JointState joint_state_msg;
910953
activate_and_get_joint_state_message("joint_states", joint_state_msg);
@@ -1164,8 +1207,7 @@ TEST_F(JointStateBroadcasterTest, JointStatePublishTest)
11641207

11651208
TEST_F(JointStateBroadcasterTest, JointStatePublishTestLocalTopic)
11661209
{
1167-
SetUpStateBroadcaster();
1168-
state_broadcaster_->get_node()->set_parameter({"use_local_topics", true});
1210+
SetUpStateBroadcaster({}, {}, {rclcpp::Parameter("use_local_topics", true)});
11691211

11701212
test_published_joint_state_message("joint_state_broadcaster/joint_states");
11711213
}
@@ -1245,8 +1287,7 @@ TEST_F(JointStateBroadcasterTest, DynamicJointStatePublishTest)
12451287

12461288
TEST_F(JointStateBroadcasterTest, DynamicJointStatePublishTestLocalTopic)
12471289
{
1248-
SetUpStateBroadcaster();
1249-
state_broadcaster_->get_node()->set_parameter({"use_local_topics", true});
1290+
SetUpStateBroadcaster({}, {}, {rclcpp::Parameter("use_local_topics", true)});
12501291

12511292
test_published_dynamic_joint_state_message("joint_state_broadcaster/dynamic_joint_states");
12521293
}
@@ -1257,11 +1298,9 @@ TEST_F(JointStateBroadcasterTest, ExtraJointStatePublishTest)
12571298
ASSERT_FALSE(state_broadcaster_->realtime_joint_state_publisher_);
12581299
ASSERT_FALSE(state_broadcaster_->realtime_dynamic_joint_state_publisher_);
12591300

1260-
SetUpStateBroadcaster();
1261-
12621301
// Add extra joints as parameters
12631302
const std::vector<std::string> extra_joint_names = {"extra1", "extra2", "extra3"};
1264-
state_broadcaster_->get_node()->set_parameter({"extra_joints", extra_joint_names});
1303+
SetUpStateBroadcaster({}, {}, {rclcpp::Parameter("extra_joints", extra_joint_names)});
12651304

12661305
// configure ok
12671306
ASSERT_EQ(state_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS);

joint_state_broadcaster/test/test_joint_state_broadcaster.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class FriendJointStateBroadcaster : public joint_state_broadcaster::JointStateBr
3434
{
3535
FRIEND_TEST(JointStateBroadcasterTest, ConfigureErrorTest);
3636
FRIEND_TEST(JointStateBroadcasterTest, ActivateEmptyTest);
37+
FRIEND_TEST(JointStateBroadcasterTest, ActivateEmptyWithoutDynamicJointStatesPublisherTest);
3738
FRIEND_TEST(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfacesTest);
3839
FRIEND_TEST(JointStateBroadcasterTest, ActivateTestWithoutJointsParameter);
3940
FRIEND_TEST(JointStateBroadcasterTest, ActivateTestWithoutJointsParameterInvalidURDF);
@@ -62,11 +63,13 @@ class JointStateBroadcasterTest : public ::testing::Test
6263

6364
void SetUpStateBroadcaster(
6465
const std::vector<std::string> & joint_names = {},
65-
const std::vector<std::string> & interfaces = {});
66+
const std::vector<std::string> & interfaces = {},
67+
const std::vector<rclcpp::Parameter> & parameter_overrides = {});
6668

6769
void init_broadcaster_and_set_parameters(
6870
const std::string & robot_description, const std::vector<std::string> & joint_names,
69-
const std::vector<std::string> & interfaces);
71+
const std::vector<std::string> & interfaces,
72+
const std::vector<rclcpp::Parameter> & parameter_overrides = {});
7073

7174
void assign_state_interfaces(
7275
const std::vector<std::string> & joint_names = {},

0 commit comments

Comments
 (0)