Skip to content

Commit 953fec6

Browse files
authored
joint_state_broadcaster to use realtime tools (#276)
* Use RealtimePublisher for joint_states * Use RealtimePublisher for dynamic joint states
1 parent fdfab1e commit 953fec6

File tree

5 files changed

+212
-212
lines changed

5 files changed

+212
-212
lines changed

joint_state_broadcaster/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ find_package(controller_interface REQUIRED)
1616
find_package(pluginlib REQUIRED)
1717
find_package(rclcpp_lifecycle REQUIRED)
1818
find_package(rcutils REQUIRED)
19+
find_package(realtime_tools REQUIRED)
1920
find_package(sensor_msgs REQUIRED)
2021

2122
add_library(joint_state_broadcaster
@@ -30,6 +31,7 @@ ament_target_dependencies(joint_state_broadcaster
3031
pluginlib
3132
rclcpp_lifecycle
3233
rcutils
34+
realtime_tools
3335
sensor_msgs
3436
)
3537
# Causes the visibility macros to use dllexport rather than dllimport,

joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "joint_state_broadcaster/visibility_control.h"
2626
#include "rclcpp_lifecycle/lifecycle_publisher.hpp"
2727
#include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp"
28+
#include "realtime_tools/realtime_publisher.h"
2829
#include "sensor_msgs/msg/joint_state.hpp"
2930

3031
namespace joint_state_broadcaster
@@ -100,14 +101,16 @@ class JointStateBroadcaster : public controller_interface::ControllerInterface
100101
// we store the name of joints with compatible interfaces
101102
std::vector<std::string> joint_names_;
102103
std::shared_ptr<rclcpp::Publisher<sensor_msgs::msg::JointState>> joint_state_publisher_;
103-
sensor_msgs::msg::JointState joint_state_msg_;
104+
std::shared_ptr<realtime_tools::RealtimePublisher<sensor_msgs::msg::JointState>>
105+
realtime_joint_state_publisher_;
104106

105107
// For the DynamicJointState format, we use a map to buffer values in for easier lookup
106108
// This allows to preserve whatever order or names/interfaces were initialized.
107109
std::unordered_map<std::string, std::unordered_map<std::string, double>> name_if_value_mapping_;
108110
std::shared_ptr<rclcpp::Publisher<control_msgs::msg::DynamicJointState>>
109111
dynamic_joint_state_publisher_;
110-
control_msgs::msg::DynamicJointState dynamic_joint_state_msg_;
112+
std::shared_ptr<realtime_tools::RealtimePublisher<control_msgs::msg::DynamicJointState>>
113+
realtime_dynamic_joint_state_publisher_;
111114
};
112115

113116
} // namespace joint_state_broadcaster

joint_state_broadcaster/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<depend>hardware_interface</depend>
2424
<depend>rclcpp_lifecycle</depend>
2525
<depend>sensor_msgs</depend>
26+
<depend>realtime_tools</depend>
2627

2728
<test_depend>ament_cmake_gmock</test_depend>
2829
<test_depend>controller_manager</test_depend>

joint_state_broadcaster/src/joint_state_broadcaster.cpp

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,17 @@ CallbackReturn JointStateBroadcaster::on_configure(
156156
joint_state_publisher_ = get_node()->create_publisher<sensor_msgs::msg::JointState>(
157157
topic_name_prefix + "joint_states", rclcpp::SystemDefaultsQoS());
158158

159+
realtime_joint_state_publisher_ =
160+
std::make_shared<realtime_tools::RealtimePublisher<sensor_msgs::msg::JointState>>(
161+
joint_state_publisher_);
162+
159163
dynamic_joint_state_publisher_ =
160164
get_node()->create_publisher<control_msgs::msg::DynamicJointState>(
161165
topic_name_prefix + "dynamic_joint_states", rclcpp::SystemDefaultsQoS());
166+
167+
realtime_dynamic_joint_state_publisher_ =
168+
std::make_shared<realtime_tools::RealtimePublisher<control_msgs::msg::DynamicJointState>>(
169+
dynamic_joint_state_publisher_);
162170
}
163171
catch (const std::exception & e)
164172
{
@@ -281,26 +289,28 @@ void JointStateBroadcaster::init_joint_state_msg()
281289
/// with at least one of these interfaces, the rest are omitted from this message
282290

283291
// default initialization for joint state message
284-
joint_state_msg_.name = joint_names_;
285-
joint_state_msg_.position.resize(num_joints, kUninitializedValue);
286-
joint_state_msg_.velocity.resize(num_joints, kUninitializedValue);
287-
joint_state_msg_.effort.resize(num_joints, kUninitializedValue);
292+
auto & joint_state_msg = realtime_joint_state_publisher_->msg_;
293+
joint_state_msg.name = joint_names_;
294+
joint_state_msg.position.resize(num_joints, kUninitializedValue);
295+
joint_state_msg.velocity.resize(num_joints, kUninitializedValue);
296+
joint_state_msg.effort.resize(num_joints, kUninitializedValue);
288297
}
289298

290299
void JointStateBroadcaster::init_dynamic_joint_state_msg()
291300
{
301+
auto & dynamic_joint_state_msg = realtime_dynamic_joint_state_publisher_->msg_;
292302
for (const auto & name_ifv : name_if_value_mapping_)
293303
{
294304
const auto & name = name_ifv.first;
295305
const auto & interfaces_and_values = name_ifv.second;
296-
dynamic_joint_state_msg_.joint_names.push_back(name);
306+
dynamic_joint_state_msg.joint_names.push_back(name);
297307
control_msgs::msg::InterfaceValue if_value;
298308
for (const auto & interface_and_value : interfaces_and_values)
299309
{
300310
if_value.interface_names.emplace_back(interface_and_value.first);
301311
if_value.values.emplace_back(kUninitializedValue);
302312
}
303-
dynamic_joint_state_msg_.interface_values.emplace_back(if_value);
313+
dynamic_joint_state_msg.interface_values.emplace_back(if_value);
304314
}
305315
}
306316

@@ -342,37 +352,45 @@ controller_interface::return_type JointStateBroadcaster::update(
342352
state_interface.get_value());
343353
}
344354

345-
joint_state_msg_.header.stamp = time;
346-
dynamic_joint_state_msg_.header.stamp = time;
347-
348-
// update joint state message and dynamic joint state message
349-
for (size_t i = 0; i < joint_names_.size(); ++i)
355+
if (realtime_joint_state_publisher_ && realtime_joint_state_publisher_->trylock())
350356
{
351-
joint_state_msg_.position[i] =
352-
get_value(name_if_value_mapping_, joint_names_[i], HW_IF_POSITION);
353-
joint_state_msg_.velocity[i] =
354-
get_value(name_if_value_mapping_, joint_names_[i], HW_IF_VELOCITY);
355-
joint_state_msg_.effort[i] = get_value(name_if_value_mapping_, joint_names_[i], HW_IF_EFFORT);
357+
auto & joint_state_msg = realtime_joint_state_publisher_->msg_;
358+
359+
joint_state_msg.header.stamp = time;
360+
361+
// update joint state message and dynamic joint state message
362+
for (size_t i = 0; i < joint_names_.size(); ++i)
363+
{
364+
joint_state_msg.position[i] =
365+
get_value(name_if_value_mapping_, joint_names_[i], HW_IF_POSITION);
366+
joint_state_msg.velocity[i] =
367+
get_value(name_if_value_mapping_, joint_names_[i], HW_IF_VELOCITY);
368+
joint_state_msg.effort[i] = get_value(name_if_value_mapping_, joint_names_[i], HW_IF_EFFORT);
369+
}
370+
realtime_joint_state_publisher_->unlockAndPublish();
356371
}
357372

358-
for (size_t joint_index = 0; joint_index < dynamic_joint_state_msg_.joint_names.size();
359-
++joint_index)
373+
if (realtime_dynamic_joint_state_publisher_ && realtime_dynamic_joint_state_publisher_->trylock())
360374
{
361-
const auto & name = dynamic_joint_state_msg_.joint_names[joint_index];
362-
for (size_t interface_index = 0;
363-
interface_index <
364-
dynamic_joint_state_msg_.interface_values[joint_index].interface_names.size();
365-
++interface_index)
375+
auto & dynamic_joint_state_msg = realtime_dynamic_joint_state_publisher_->msg_;
376+
dynamic_joint_state_msg.header.stamp = time;
377+
for (size_t joint_index = 0; joint_index < dynamic_joint_state_msg.joint_names.size();
378+
++joint_index)
366379
{
367-
const auto & interface_name =
368-
dynamic_joint_state_msg_.interface_values[joint_index].interface_names[interface_index];
369-
dynamic_joint_state_msg_.interface_values[joint_index].values[interface_index] =
370-
name_if_value_mapping_[name][interface_name];
380+
const auto & name = dynamic_joint_state_msg.joint_names[joint_index];
381+
for (size_t interface_index = 0;
382+
interface_index <
383+
dynamic_joint_state_msg.interface_values[joint_index].interface_names.size();
384+
++interface_index)
385+
{
386+
const auto & interface_name =
387+
dynamic_joint_state_msg.interface_values[joint_index].interface_names[interface_index];
388+
dynamic_joint_state_msg.interface_values[joint_index].values[interface_index] =
389+
name_if_value_mapping_[name][interface_name];
390+
}
371391
}
392+
realtime_dynamic_joint_state_publisher_->unlockAndPublish();
372393
}
373-
// publish
374-
joint_state_publisher_->publish(joint_state_msg_);
375-
dynamic_joint_state_publisher_->publish(dynamic_joint_state_msg_);
376394

377395
return controller_interface::return_type::OK;
378396
}

0 commit comments

Comments
 (0)