diff --git a/CMakeLists.txt b/CMakeLists.txt
index cfd2a37..e9f3b83 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,6 +15,7 @@ find_package(catkin REQUIRED COMPONENTS
std_msgs
trajectory_msgs
ur_msgs
+ tf
)
## System dependencies are found with CMake's conventions
diff --git a/launch/ur_common.launch b/launch/ur_common.launch
index 6cd06dd..565fa86 100644
--- a/launch/ur_common.launch
+++ b/launch/ur_common.launch
@@ -12,7 +12,8 @@
-
+
+
@@ -27,5 +28,7 @@
+
+
diff --git a/package.xml b/package.xml
index 24faa14..1d45aaa 100644
--- a/package.xml
+++ b/package.xml
@@ -50,6 +50,7 @@
std_msgs
trajectory_msgs
ur_msgs
+ tf
hardware_interface
controller_manager
ros_controllers
@@ -62,6 +63,7 @@
trajectory_msgs
ur_msgs
ur_description
+ tf
diff --git a/src/ur_ros_wrapper.cpp b/src/ur_ros_wrapper.cpp
index b9f15ca..c95aa6b 100644
--- a/src/ur_ros_wrapper.cpp
+++ b/src/ur_ros_wrapper.cpp
@@ -33,6 +33,7 @@
#include
#include "sensor_msgs/JointState.h"
#include "geometry_msgs/WrenchStamped.h"
+#include "geometry_msgs/PoseStamped.h"
#include "control_msgs/FollowJointTrajectoryAction.h"
#include "actionlib/server/action_server.h"
#include "actionlib/server/server_goal_handle.h"
@@ -49,6 +50,10 @@
#include "std_msgs/String.h"
#include
+/// TF
+#include
+#include
+
class RosWrapper {
protected:
UrDriver robot_;
@@ -69,6 +74,8 @@ protected:
double io_flag_delay_;
double max_velocity_;
std::vector joint_offsets_;
+ std::string base_frame_;
+ std::string tool_frame_;
bool use_ros_control_;
std::thread* ros_control_thread_;
boost::shared_ptr hardware_interface_;
@@ -149,6 +156,18 @@ public:
}
robot_.setServojTime(servoj_time);
+ //Base and tool frames
+ base_frame_ = "base";
+ tool_frame_ = "tool0_controller";
+ if (ros::param::get("~base_frame", base_frame_)) {
+ sprintf(buf, "Base frame set to: %s", base_frame_.c_str());
+ print_debug(buf);
+ }
+ if (ros::param::get("~tool_frame", tool_frame_)) {
+ sprintf(buf, "Tool frame set to: %s", tool_frame_.c_str());
+ print_debug(buf);
+ }
+
if (robot_.start()) {
if (use_ros_control_) {
ros_control_thread_ = new std::thread(
@@ -541,10 +560,13 @@ private:
"joint_states", 1);
ros::Publisher wrench_pub = nh_.advertise(
"wrench", 1);
+ ros::Publisher tool_vel_pub = nh_.advertise("tool_velocity", 1);
+ static tf::TransformBroadcaster br;
while (ros::ok()) {
sensor_msgs::JointState joint_msg;
joint_msg.name = robot_.getJointNames();
geometry_msgs::WrenchStamped wrench_msg;
+ geometry_msgs::PoseStamped tool_pose_msg;
std::mutex msg_lock; // The values are locked for reading in the class, so just use a dummy mutex
std::unique_lock locker(msg_lock);
while (!robot_.rt_interface_->robot_state_->getDataPublished()) {
@@ -571,8 +593,42 @@ private:
wrench_msg.wrench.torque.z = tcp_force[5];
wrench_pub.publish(wrench_msg);
- robot_.rt_interface_->robot_state_->setDataPublished();
+ // Tool vector: Actual Cartesian coordinates of the tool: (x,y,z,rx,ry,rz), where rx, ry and rz is a rotation vector representation of the tool orientation
+ std::vector tool_vector_actual = robot_.rt_interface_->robot_state_->getToolVectorActual();
+ //Create quaternion
+ tf::Quaternion quat;
+ double rx = tool_vector_actual[3];
+ double ry = tool_vector_actual[4];
+ double rz = tool_vector_actual[5];
+ double angle = std::sqrt(std::pow(rx,2) + std::pow(ry,2) + std::pow(rz,2));
+ if (angle < 1e-16) {
+ quat.setValue(0, 0, 0, 1);
+ } else {
+ quat.setRotation(tf::Vector3(rx/angle, ry/angle, rz/angle), angle);
+ }
+
+ //Create and broadcast transform
+ tf::Transform transform;
+ transform.setOrigin(tf::Vector3(tool_vector_actual[0], tool_vector_actual[1], tool_vector_actual[2]));
+ transform.setRotation(quat);
+ br.sendTransform(tf::StampedTransform(transform, joint_msg.header.stamp, base_frame_, tool_frame_));
+
+ //Publish tool velocity
+ std::vector tcp_speed =
+ robot_.rt_interface_->robot_state_->getTcpSpeedActual();
+ geometry_msgs::TwistStamped tool_twist;
+ tool_twist.header.frame_id = base_frame_;
+ tool_twist.header.stamp = joint_msg.header.stamp;
+ tool_twist.twist.linear.x = tcp_speed[0];
+ tool_twist.twist.linear.y = tcp_speed[1];
+ tool_twist.twist.linear.z = tcp_speed[2];
+ tool_twist.twist.angular.x = tcp_speed[3];
+ tool_twist.twist.angular.y = tcp_speed[4];
+ tool_twist.twist.angular.z = tcp_speed[5];
+ tool_vel_pub.publish(tool_twist);
+
+ robot_.rt_interface_->robot_state_->setDataPublished();
}
}