00001 #ifndef YUMI_GRIPPER_NODE_H
00002 #define YUMI_GRIPPER_NODE_H
00003
00004 #include <boost/thread/mutex.hpp>
00005 #include <boost/thread.hpp>
00006
00007 #include <ros/ros.h>
00008 #include "simple_message/message_handler.h"
00009 #include "simple_message/message_manager.h"
00010 #include "simple_message/messages/joint_message.h"
00011 #include "simple_message/smpl_msg_connection.h"
00012 #include "simple_message/socket/tcp_socket.h"
00013 #include "simple_message/socket/tcp_client.h"
00014 #include <sensor_msgs/JointState.h>
00015
00016 #include <yumi_hw/YumiGrasp.h>
00017
00018 #define MSG_TYPE_GRIPPER_COMMAND 8008
00019 #define MSG_TYPE_GRIPPER_STATE 8009
00020
00021 #define DEFAULT_STATE_PORT 12002
00022 #define DEFAULT_COMMAND_PORT 12000
00023
00024 #define LEFT_GRIPPER 1
00025 #define RIGHT_GRIPPER 2
00026
00030 class YumiGripperStateHandler : public industrial::message_handler::MessageHandler {
00031 using industrial::message_handler::MessageHandler::init;
00032
00033 private:
00034 float gripper_positions[2];
00035 boost::mutex data_buffer_mutex;
00036
00037 public:
00038 bool getGripperStates(float &left, float &right) {
00039 boost::mutex::scoped_lock lock(data_buffer_mutex);
00040 left = gripper_positions[0];
00041 right = gripper_positions[1];
00042 }
00043
00044 bool init(industrial::smpl_msg_connection::SmplMsgConnection* connection)
00045 {
00046 return init((int)MSG_TYPE_GRIPPER_STATE, connection);
00047 }
00048
00049 protected:
00050
00051 bool internalCB(industrial::simple_message::SimpleMessage& in)
00052 {
00053 boost::mutex::scoped_lock lock(data_buffer_mutex);
00054
00055 bool ret;
00056 if(in.getMessageType() != MSG_TYPE_GRIPPER_STATE) {
00057 ret = false;
00058 }
00059 else
00060 {
00061 industrial::byte_array::ByteArray data = in.getData();
00062 industrial::shared_types::shared_real value_from_msg;
00063
00064 data.unload(value_from_msg);
00065 gripper_positions[0] = value_from_msg;
00066 data.unload(value_from_msg);
00067 gripper_positions[1] = value_from_msg;
00068
00069 }
00070
00071 if (industrial::simple_message::CommTypes::SERVICE_REQUEST == in.getCommType())
00072 {
00073 ROS_INFO("Reply requested, sending");
00074 industrial::simple_message::SimpleMessage reply;
00075 reply.init(MSG_TYPE_GRIPPER_STATE, industrial::simple_message::CommTypes::SERVICE_REPLY,
00076 ret ? industrial::simple_message::ReplyTypes::SUCCESS: industrial::simple_message::ReplyTypes::FAILURE) ;
00077 this->getConnection()->sendMsg(reply);
00078 }
00079
00080 return ret;
00081 }
00082
00083 };
00084
00088 class YumiGripperStateInterface {
00089 private:
00090 boost::thread RapidCommThread_;
00091
00093 industrial::tcp_client::TcpClient default_tcp_connection_;
00094 industrial::smpl_msg_connection::SmplMsgConnection* connection_;
00095
00096 industrial::tcp_client::TcpClient default_tcp_connection_command;
00097 industrial::smpl_msg_connection::SmplMsgConnection* connection_command;
00098
00099 industrial::message_manager::MessageManager manager_;
00100 YumiGripperStateHandler gripper_handler;
00101
00102 bool stopComm_;
00103
00104 virtual void RapidCommThreadCallback()
00105 {
00106 while(!stopComm_) {
00107 manager_.spinOnce();
00108 }
00109 return;
00110 }
00111
00112 public:
00113 YumiGripperStateInterface() {
00114 this->connection_ = NULL;
00115 stopComm_ = true;
00116 }
00117
00118 ~YumiGripperStateInterface() {
00119 stopThreads();
00120 }
00121
00122 void stopThreads() {
00123 stopComm_ = true;
00124 RapidCommThread_.join();
00125 }
00126
00127 void startThreads() {
00128 if(!stopComm_) {
00129 boost::thread(boost::bind(&YumiGripperStateInterface::RapidCommThreadCallback,this ));
00130 }
00131 }
00132
00133 void getCurrentJointStates(float &left, float &right) {
00134 gripper_handler.getGripperStates(right,left);
00135 }
00136
00137 void setGripperEfforts(float left, float right) {
00138
00139 industrial::simple_message::SimpleMessage grasp_msg;
00140 industrial::byte_array::ByteArray data;
00141 industrial::shared_types::shared_real value_to_msg;
00142
00143 value_to_msg = left;
00144 data.load(value_to_msg);
00145
00146 value_to_msg = right;
00147 data.load(value_to_msg);
00148
00149 grasp_msg.init(MSG_TYPE_GRIPPER_COMMAND, industrial::simple_message::CommTypes::TOPIC,
00150 industrial::simple_message::ReplyTypes::INVALID, data) ;
00151 connection_command->sendMsg(grasp_msg);
00152
00153 }
00154
00155 bool init(std::string ip = "", int port = DEFAULT_STATE_PORT, int port_command = DEFAULT_COMMAND_PORT) {
00156
00157 char* ip_addr = strdup(ip.c_str());
00158 ROS_INFO("Robot state connecting to IP address: '%s:%d'", ip_addr, port);
00159 default_tcp_connection_.init(ip_addr, port);
00160 default_tcp_connection_command.init(ip_addr, port_command);
00161 free(ip_addr);
00162
00163 connection_ = &default_tcp_connection_;
00164 connection_->makeConnect();
00165
00166 connection_command = &default_tcp_connection_command;
00167 connection_command->makeConnect();
00168
00169
00170 manager_.init(connection_);
00171
00172
00173 gripper_handler.init(connection_);
00174
00175
00176 manager_.add(&gripper_handler,false);
00177
00178 stopComm_ = false;
00179 }
00180
00181 };
00182
00183 class YumiGripperNode
00184 {
00185 public:
00186 YumiGripperNode() {
00187
00188 ROS_INFO("YumiGrippers: starting node");
00189 nh_ = ros::NodeHandle("~");
00190
00191
00192 nh_.param<std::string>("joint_state_topic", gripper_state_topic,"joint_states");
00193 nh_.param<std::string>("grasp_request_topic", grasp_request_topic,"do_grasp");
00194 nh_.param<std::string>("grasp_release_topic", grasp_release_topic,"release_grasp");
00195 nh_.param<double>("publish_period", js_rate, 0.1);
00196 nh_.param("port_stream", port_s, DEFAULT_STATE_PORT);
00197 nh_.param("port_command", port_c,DEFAULT_COMMAND_PORT);
00198 nh_.param("grasp_force", default_force, 5);
00199 nh_.param("ip", ip, std::string("192.168.125.1") );
00200
00201 heartbeat_ = nh_.createTimer(ros::Duration(js_rate), &YumiGripperNode::publishState, this);
00202 request_grasp_ = nh_.advertiseService(grasp_request_topic, &YumiGripperNode::request_grasp, this);;
00203 request_release_ = nh_.advertiseService(grasp_release_topic, &YumiGripperNode::request_release, this);;
00204 gripper_status_publisher_ = ros::NodeHandle().advertise<sensor_msgs::JointState>(gripper_state_topic, 10);
00205
00206 gripper_interface.init(ip,port_s);
00207 gripper_interface.startThreads();
00208
00209
00210 }
00211
00212 virtual ~YumiGripperNode() {
00213
00214 }
00215
00216 private:
00217 ros::NodeHandle nh_;
00218
00219 ros::Publisher gripper_status_publisher_;
00220 ros::ServiceServer request_grasp_;
00221 ros::ServiceServer request_release_;
00222 YumiGripperStateInterface gripper_interface;
00223
00224 std::string gripper_state_topic, grasp_request_topic, grasp_release_topic, ip;
00225 int port_s, port_c;
00226 double js_rate;
00227 int default_force;
00228
00229 ros::Timer heartbeat_;
00230
00231 bool request_grasp(yumi_hw::YumiGrasp::Request &req,
00232 yumi_hw::YumiGrasp::Response &res ) {
00233
00234 float left=0, right=0;
00235 if(req.gripper_id == LEFT_GRIPPER) {
00236 left = default_force;
00237 }
00238 if(req.gripper_id == RIGHT_GRIPPER) {
00239 right = default_force;
00240 }
00241 gripper_interface.setGripperEfforts(left,right);
00242 return true;
00243 }
00244
00245 bool request_release(yumi_hw::YumiGrasp::Request &req,
00246 yumi_hw::YumiGrasp::Response &res ) {
00247
00248 float left=0, right=0;
00249 if(req.gripper_id == LEFT_GRIPPER) {
00250 left = -default_force;
00251 }
00252 if(req.gripper_id == RIGHT_GRIPPER) {
00253 right = -default_force;
00254 }
00255 gripper_interface.setGripperEfforts(left,right);
00256 return true;
00257 }
00258
00259
00260 void publishState(const ros::TimerEvent& event) {
00261
00262 float left, right;
00263 gripper_interface.getCurrentJointStates(left,right);
00264
00265
00266 left *= 1e-3;
00267 right *= 1e-3;
00268
00269 sensor_msgs::JointState js;
00270 js.header.stamp = ros::Time::now();
00271 js.name.push_back("gripper_l_joint");
00272 js.position.push_back(left);
00273
00274 js.name.push_back("gripper_r_joint");
00275 js.position.push_back(right);
00276
00277 gripper_status_publisher_.publish(js);
00278
00279 }
00280 };
00281
00282
00283
00284 #endif