Skip to content

Commit 97e6b3d

Browse files
authored
Update transformForceTorque to handle wheter it is a cb3 or an e-Series robot (UniversalRobots#1287)
The force torque is returned at the tool flange on e-series robots and at the tcp for CB3, this is now handled correctly, so that all force/torque measurements will be relative to the active TCP
1 parent 57d8fab commit 97e6b3d

File tree

3 files changed

+39
-15
lines changed

3 files changed

+39
-15
lines changed

ur_robot_driver/include/ur_robot_driver/hardware_interface.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
178178
urcl::vector6d_t urcl_joint_efforts_;
179179
urcl::vector6d_t urcl_ft_sensor_measurements_;
180180
urcl::vector6d_t urcl_tcp_pose_;
181+
urcl::vector6d_t urcl_target_tcp_pose_;
182+
urcl::vector6d_t tcp_offset_;
181183
tf2::Quaternion tcp_rotation_quat_;
182184
Quaternion tcp_rotation_buffer;
183185

@@ -205,10 +207,6 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
205207
std::bitset<4> robot_status_bits_;
206208
std::bitset<11> safety_status_bits_;
207209

208-
// transform stuff
209-
tf2::Vector3 tcp_force_;
210-
tf2::Vector3 tcp_torque_;
211-
212210
// asynchronous commands
213211
std::array<double, 18> standard_dig_out_bits_cmd_;
214212
std::array<double, 2> standard_analog_output_cmd_;

ur_robot_driver/resources/rtde_output_recipe.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ target_speed_fraction
66
runtime_state
77
actual_TCP_force
88
actual_TCP_pose
9+
target_TCP_pose
910
actual_digital_input_bits
1011
actual_digital_output_bits
1112
standard_analog_input0
@@ -25,3 +26,4 @@ safety_mode
2526
robot_status_bits
2627
safety_status_bits
2728
actual_current
29+
tcp_offset

ur_robot_driver/src/hardware_interface.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ hardware_interface::return_type URPositionHardwareInterface::read(const rclcpp::
676676
readData(data_pkg, "runtime_state", runtime_state_);
677677
readData(data_pkg, "actual_TCP_force", urcl_ft_sensor_measurements_);
678678
readData(data_pkg, "actual_TCP_pose", urcl_tcp_pose_);
679+
readData(data_pkg, "target_TCP_pose", urcl_target_tcp_pose_);
679680
readData(data_pkg, "standard_analog_input0", standard_analog_input_[0]);
680681
readData(data_pkg, "standard_analog_input1", standard_analog_input_[1]);
681682
readData(data_pkg, "standard_analog_output0", standard_analog_output_[0]);
@@ -694,6 +695,7 @@ hardware_interface::return_type URPositionHardwareInterface::read(const rclcpp::
694695
readBitsetData<uint64_t>(data_pkg, "actual_digital_output_bits", actual_dig_out_bits_);
695696
readBitsetData<uint32_t>(data_pkg, "analog_io_types", analog_io_types_);
696697
readBitsetData<uint32_t>(data_pkg, "tool_analog_input_types", tool_analog_input_types_);
698+
readData(data_pkg, "tcp_offset", tcp_offset_);
697699

698700
// required transforms
699701
extractToolPose();
@@ -934,17 +936,39 @@ void URPositionHardwareInterface::updateNonDoubleValues()
934936

935937
void URPositionHardwareInterface::transformForceTorque()
936938
{
937-
// imported from ROS1 driver - hardware_interface.cpp#L867-L876
938-
tcp_force_.setValue(urcl_ft_sensor_measurements_[0], urcl_ft_sensor_measurements_[1],
939-
urcl_ft_sensor_measurements_[2]);
940-
tcp_torque_.setValue(urcl_ft_sensor_measurements_[3], urcl_ft_sensor_measurements_[4],
941-
urcl_ft_sensor_measurements_[5]);
942-
943-
tcp_force_ = tf2::quatRotate(tcp_rotation_quat_.inverse(), tcp_force_);
944-
tcp_torque_ = tf2::quatRotate(tcp_rotation_quat_.inverse(), tcp_torque_);
945-
946-
urcl_ft_sensor_measurements_ = { tcp_force_.x(), tcp_force_.y(), tcp_force_.z(),
947-
tcp_torque_.x(), tcp_torque_.y(), tcp_torque_.z() };
939+
KDL::Wrench ft(
940+
KDL::Vector(urcl_ft_sensor_measurements_[0], urcl_ft_sensor_measurements_[1], urcl_ft_sensor_measurements_[2]),
941+
KDL::Vector(urcl_ft_sensor_measurements_[3], urcl_ft_sensor_measurements_[4], urcl_ft_sensor_measurements_[5]));
942+
if (ur_driver_->getVersion().major >= 5) // e-Series
943+
{
944+
// Setup necessary frames
945+
KDL::Vector vec = KDL::Vector(tcp_offset_[3], tcp_offset_[4], tcp_offset_[5]);
946+
double angle = vec.Normalize();
947+
KDL::Rotation rotation = KDL::Rotation::Rot(vec, angle);
948+
KDL::Frame flange_to_tcp = KDL::Frame(rotation, KDL::Vector(tcp_offset_[0], tcp_offset_[1], tcp_offset_[2]));
949+
950+
vec = KDL::Vector(urcl_target_tcp_pose_[3], urcl_target_tcp_pose_[4], urcl_target_tcp_pose_[5]);
951+
angle = vec.Normalize();
952+
rotation = KDL::Rotation::Rot(vec, angle);
953+
KDL::Frame base_to_tcp =
954+
KDL::Frame(rotation, KDL::Vector(urcl_target_tcp_pose_[0], urcl_target_tcp_pose_[1], urcl_target_tcp_pose_[2]));
955+
// Calculate transformation from base to flange, see calculation details below
956+
// `base_to_tcp = base_to_flange*flange_to_tcp -> base_to_flange = base_to_tcp * inv(flange_to_tcp)`
957+
KDL::Frame base_to_flange = base_to_tcp * flange_to_tcp.Inverse();
958+
// rotate f/t sensor output back to the flange frame
959+
ft = base_to_flange.M.Inverse() * ft;
960+
961+
// Transform the wrench to the tcp frame
962+
ft = flange_to_tcp * ft;
963+
} else { // CB3
964+
KDL::Vector vec = KDL::Vector(urcl_target_tcp_pose_[3], urcl_target_tcp_pose_[4], urcl_target_tcp_pose_[5]);
965+
double angle = vec.Normalize();
966+
KDL::Rotation base_to_tcp_rot = KDL::Rotation::Rot(vec, angle);
967+
968+
// rotate f/t sensor output back to the tcp frame
969+
ft = base_to_tcp_rot.Inverse() * ft;
970+
}
971+
urcl_ft_sensor_measurements_ = { ft[0], ft[1], ft[2], ft[3], ft[4], ft[5] };
948972
}
949973

950974
void URPositionHardwareInterface::extractToolPose()

0 commit comments

Comments
 (0)