Skip to content

Commit d2876cb

Browse files
authored
Use pose_broadcaster to publish the TCP pose (backport of #1108)
Adds a broadcaster for the robot's TCP pose.
1 parent 1b2b846 commit d2876cb

File tree

5 files changed

+65
-16
lines changed

5 files changed

+65
-16
lines changed

ur_robot_driver/config/ur_controllers.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ controller_manager:
2424
forward_position_controller:
2525
type: position_controllers/JointGroupPositionController
2626

27+
tcp_pose_broadcaster:
28+
type: pose_broadcaster/PoseBroadcaster
29+
2730
ur_configuration_controller:
2831
type: ur_controllers/URConfigurationController
2932

@@ -130,3 +133,10 @@ forward_position_controller:
130133
- $(var tf_prefix)wrist_1_joint
131134
- $(var tf_prefix)wrist_2_joint
132135
- $(var tf_prefix)wrist_3_joint
136+
137+
tcp_pose_broadcaster:
138+
ros__parameters:
139+
frame_id: $(var tf_prefix)base
140+
pose_name: $(var tf_prefix)tcp_pose
141+
tf:
142+
child_frame_id: $(var tf_prefix)tool0_controller

ur_robot_driver/include/ur_robot_driver/hardware_interface.hpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,28 @@ enum StoppingInterface
8080
STOP_VELOCITY
8181
};
8282

83+
// We define our own quaternion to use it as a buffer, since we need to pass pointers to the state
84+
// interfaces.
85+
struct Quaternion
86+
{
87+
Quaternion() : x(0), y(0), z(0), w(0)
88+
{
89+
}
90+
91+
void set(const tf2::Quaternion& q)
92+
{
93+
x = q.x();
94+
y = q.y();
95+
z = q.z();
96+
w = q.w();
97+
}
98+
99+
double x;
100+
double y;
101+
double z;
102+
double w;
103+
};
104+
83105
/*!
84106
* \brief The HardwareInterface class handles the interface between the ROS system and the main
85107
* driver. It contains the read and write methods of the main control loop and registers various ROS
@@ -144,6 +166,8 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
144166
urcl::vector6d_t urcl_joint_efforts_;
145167
urcl::vector6d_t urcl_ft_sensor_measurements_;
146168
urcl::vector6d_t urcl_tcp_pose_;
169+
tf2::Quaternion tcp_rotation_quat_;
170+
Quaternion tcp_rotation_buffer;
147171

148172
bool packet_read_;
149173

@@ -172,7 +196,6 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
172196
// transform stuff
173197
tf2::Vector3 tcp_force_;
174198
tf2::Vector3 tcp_torque_;
175-
geometry_msgs::msg::TransformStamped tcp_transform_;
176199

177200
// asynchronous commands
178201
std::array<double, 18> standard_dig_out_bits_cmd_;

ur_robot_driver/launch/ur_control.launch.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ def launch_setup(context, *args, **kwargs):
295295
"force_torque_sensor_broadcaster",
296296
"joint_state_broadcaster",
297297
"speed_scaling_state_broadcaster",
298+
"tcp_pose_broadcaster",
298299
"ur_configuration_controller",
299300
]
300301
},
@@ -338,6 +339,7 @@ def controller_spawner(controllers, active=True):
338339
"io_and_status_controller",
339340
"speed_scaling_state_broadcaster",
340341
"force_torque_sensor_broadcaster",
342+
"tcp_pose_broadcaster",
341343
"ur_configuration_controller",
342344
]
343345
controllers_inactive = ["forward_position_controller"]

ur_robot_driver/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
<exec_depend>joint_trajectory_controller</exec_depend>
5151
<exec_depend>launch</exec_depend>
5252
<exec_depend>launch_ros</exec_depend>
53+
<exec_depend>pose_broadcaster</exec_depend>
5354
<exec_depend>position_controllers</exec_depend>
5455
<exec_depend>robot_state_publisher</exec_depend>
5556
<exec_depend>ros2_controllers_test_nodes</exec_depend>

ur_robot_driver/src/hardware_interface.cpp

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,14 @@ std::vector<hardware_interface::StateInterface> URPositionHardwareInterface::exp
170170
&speed_scaling_combined_));
171171

172172
for (auto& sensor : info_.sensors) {
173-
for (uint j = 0; j < sensor.state_interfaces.size(); ++j) {
174-
state_interfaces.emplace_back(hardware_interface::StateInterface(sensor.name, sensor.state_interfaces[j].name,
175-
&urcl_ft_sensor_measurements_[j]));
173+
if (sensor.name == tf_prefix + "tcp_fts_sensor") {
174+
const std::vector<std::string> fts_names = {
175+
"force.x", "force.y", "force.z", "torque.x", "torque.y", "torque.z"
176+
};
177+
for (uint j = 0; j < 6; ++j) {
178+
state_interfaces.emplace_back(
179+
hardware_interface::StateInterface(sensor.name, fts_names[j], &urcl_ft_sensor_measurements_[j]));
180+
}
176181
}
177182
}
178183

@@ -232,6 +237,21 @@ std::vector<hardware_interface::StateInterface> URPositionHardwareInterface::exp
232237
state_interfaces.emplace_back(
233238
hardware_interface::StateInterface(tf_prefix + "gpio", "program_running", &robot_program_running_copy_));
234239

240+
state_interfaces.emplace_back(
241+
hardware_interface::StateInterface(tf_prefix + "tcp_pose", "position.x", &urcl_tcp_pose_[0]));
242+
state_interfaces.emplace_back(
243+
hardware_interface::StateInterface(tf_prefix + "tcp_pose", "position.y", &urcl_tcp_pose_[1]));
244+
state_interfaces.emplace_back(
245+
hardware_interface::StateInterface(tf_prefix + "tcp_pose", "position.z", &urcl_tcp_pose_[2]));
246+
state_interfaces.emplace_back(
247+
hardware_interface::StateInterface(tf_prefix + "tcp_pose", "orientation.x", &tcp_rotation_buffer.x));
248+
state_interfaces.emplace_back(
249+
hardware_interface::StateInterface(tf_prefix + "tcp_pose", "orientation.y", &tcp_rotation_buffer.y));
250+
state_interfaces.emplace_back(
251+
hardware_interface::StateInterface(tf_prefix + "tcp_pose", "orientation.z", &tcp_rotation_buffer.z));
252+
state_interfaces.emplace_back(
253+
hardware_interface::StateInterface(tf_prefix + "tcp_pose", "orientation.w", &tcp_rotation_buffer.w));
254+
235255
state_interfaces.emplace_back(hardware_interface::StateInterface(
236256
tf_prefix + "get_robot_software_version", "get_version_major", &get_robot_software_version_major_));
237257

@@ -796,10 +816,8 @@ void URPositionHardwareInterface::transformForceTorque()
796816
tcp_torque_.setValue(urcl_ft_sensor_measurements_[3], urcl_ft_sensor_measurements_[4],
797817
urcl_ft_sensor_measurements_[5]);
798818

799-
tf2::Quaternion rotation_quat;
800-
tf2::fromMsg(tcp_transform_.transform.rotation, rotation_quat);
801-
tcp_force_ = tf2::quatRotate(rotation_quat.inverse(), tcp_force_);
802-
tcp_torque_ = tf2::quatRotate(rotation_quat.inverse(), tcp_torque_);
819+
tcp_force_ = tf2::quatRotate(tcp_rotation_quat_.inverse(), tcp_force_);
820+
tcp_torque_ = tf2::quatRotate(tcp_rotation_quat_.inverse(), tcp_torque_);
803821

804822
urcl_ft_sensor_measurements_ = { tcp_force_.x(), tcp_force_.y(), tcp_force_.z(),
805823
tcp_torque_.x(), tcp_torque_.y(), tcp_torque_.z() };
@@ -812,17 +830,12 @@ void URPositionHardwareInterface::extractToolPose()
812830
std::sqrt(std::pow(urcl_tcp_pose_[3], 2) + std::pow(urcl_tcp_pose_[4], 2) + std::pow(urcl_tcp_pose_[5], 2));
813831

814832
tf2::Vector3 rotation_vec(urcl_tcp_pose_[3], urcl_tcp_pose_[4], urcl_tcp_pose_[5]);
815-
tf2::Quaternion rotation;
816833
if (tcp_angle > 1e-16) {
817-
rotation.setRotation(rotation_vec.normalized(), tcp_angle);
834+
tcp_rotation_quat_.setRotation(rotation_vec.normalized(), tcp_angle);
818835
} else {
819-
rotation.setValue(0.0, 0.0, 0.0, 1.0); // default Quaternion is 0,0,0,0 which is invalid
836+
tcp_rotation_quat_.setValue(0.0, 0.0, 0.0, 1.0); // default Quaternion is 0,0,0,0 which is invalid
820837
}
821-
tcp_transform_.transform.translation.x = urcl_tcp_pose_[0];
822-
tcp_transform_.transform.translation.y = urcl_tcp_pose_[1];
823-
tcp_transform_.transform.translation.z = urcl_tcp_pose_[2];
824-
825-
tcp_transform_.transform.rotation = tf2::toMsg(rotation);
838+
tcp_rotation_buffer.set(tcp_rotation_quat_);
826839
}
827840

828841
hardware_interface::return_type URPositionHardwareInterface::prepare_command_mode_switch(

0 commit comments

Comments
 (0)