Go to the documentation of this file.00001 #ifndef __YUMI_HW_RAPID_H
00002 #define __YUMI_HW_RAPID_H
00003
00004 #include "yumi_hw/yumi_hw.h"
00005
00006 #include <boost/thread/mutex.hpp>
00007 #include <boost/thread.hpp>
00008
00009 #include <ros/ros.h>
00010 #include "simple_message/message_handler.h"
00011 #include "simple_message/message_manager.h"
00012 #include "simple_message/messages/joint_message.h"
00013 #include "simple_message/smpl_msg_connection.h"
00014 #include "simple_message/socket/tcp_socket.h"
00015 #include "simple_message/socket/tcp_client.h"
00016
00017 #ifndef N_YUMI_JOINTS
00018 #define N_YUMI_JOINTS 14
00019 #endif
00020
00024 class YumiJointStateHandler : public industrial::message_handler::MessageHandler {
00025 using industrial::message_handler::MessageHandler::init;
00026
00027 private:
00028 float joint_positions[N_YUMI_JOINTS];
00029 float joint_command[N_YUMI_JOINTS];
00030 bool first_iteration;
00031 boost::mutex data_buffer_mutex, t_m;
00032 boost::condition_variable joint_state_received, joint_commands_set;
00033 bool b_joint_state_received, b_joint_commands_set;
00034 int mode;
00035
00036 public:
00037 bool getJointStates(float (&jnts)[N_YUMI_JOINTS]) {
00038 boost::mutex::scoped_lock lock(data_buffer_mutex);
00039 while(!b_joint_state_received) {
00040 joint_state_received.wait(lock);
00041 }
00042 b_joint_state_received = false;
00043 memcpy(&jnts,&joint_positions,sizeof(jnts));
00044 }
00045
00046 bool setJointCommands(float (&jnts)[N_YUMI_JOINTS], int mode_) {
00047 boost::mutex::scoped_lock lock(data_buffer_mutex);
00048 memcpy(&joint_command,&jnts,sizeof(jnts));
00049 b_joint_commands_set=true;
00050 mode = mode_;
00051 joint_commands_set.notify_all();
00052 }
00053
00054 bool init(industrial::smpl_msg_connection::SmplMsgConnection* connection)
00055 {
00056 first_iteration = true;
00057 b_joint_state_received = false;
00058 b_joint_commands_set = false;
00059
00060 return init((int)industrial::simple_message::StandardMsgTypes::JOINT, connection);
00061 }
00062
00063 protected:
00064
00065
00066 bool internalCB(industrial::simple_message::SimpleMessage& in)
00067 {
00068 boost::mutex::scoped_lock lock(data_buffer_mutex);
00069
00070
00071 industrial::joint_message::JointMessage joint_msg;
00072 bool rtn = true;
00073
00074 if (!joint_msg.init(in))
00075 {
00076 ROS_ERROR("Failed to initialize joint message");
00077 return false;
00078 }
00079
00080
00081 industrial::shared_types::shared_real joint_value_from_msg;
00082
00083 for(int i=0; i<N_YUMI_JOINTS; i++) {
00084
00085 if (joint_msg.getJoints().getJoint(i, joint_value_from_msg))
00086 {
00087 joint_positions[i] = joint_value_from_msg;
00088
00089 }
00090 else
00091 {
00092
00093 rtn = false;
00094 }
00095 }
00096
00097
00098
00099 if (industrial::simple_message::CommTypes::SERVICE_REQUEST == joint_msg.getMessageType())
00100 {
00101
00102 industrial::simple_message::SimpleMessage reply;
00103 joint_msg.toReply(reply, rtn ? industrial::simple_message::ReplyTypes::SUCCESS : industrial::simple_message::ReplyTypes::FAILURE);
00104 this->getConnection()->sendMsg(reply);
00105 }
00106
00107 b_joint_state_received=true;
00108 joint_state_received.notify_all();
00109
00110 while(!b_joint_commands_set) {
00111 joint_commands_set.wait(lock);
00112 }
00113 b_joint_commands_set = false;
00114
00115
00116 if(first_iteration) {
00117 ROS_INFO("Mirroring to command");
00118 memcpy(&joint_command,&joint_positions,sizeof(joint_command));
00119 first_iteration = false;
00120 }
00121
00122
00123 industrial::shared_types::shared_real joint_value_to_msg;
00124
00125 for(int i=0; i<N_YUMI_JOINTS; i++) {
00126 joint_value_to_msg = joint_command[i];
00127
00128 if (!joint_msg.getJoints().setJoint(i, joint_value_to_msg))
00129 {
00130 rtn = false;
00131 }
00132 }
00133 if (!joint_msg.getJoints().setJoint(N_YUMI_JOINTS, mode))
00134 {
00135 rtn = false;
00136 }
00137
00138
00139
00140 industrial::simple_message::SimpleMessage next_point;
00141 joint_msg.toRequest(next_point);
00142 this->getConnection()->sendMsg(next_point);
00143
00144
00145
00146 return rtn;
00147 }
00148
00149 };
00150
00154 class YumiRapidInterface {
00155 private:
00156 boost::thread RapidCommThread_;
00157
00159 industrial::tcp_client::TcpClient default_tcp_connection_;
00160
00161
00162 industrial::smpl_msg_connection::SmplMsgConnection* connection_;
00163 industrial::message_manager::MessageManager manager_;
00164 YumiJointStateHandler js_handler;
00165
00166 bool stopComm_;
00167
00168 virtual void RapidCommThreadCallback()
00169 {
00170 while(!stopComm_) {
00171 manager_.spinOnce();
00172 }
00173 return;
00174 }
00175
00176 public:
00177 YumiRapidInterface() {
00178 this->connection_ = NULL;
00179 stopComm_ = true;
00180 }
00181
00182 ~YumiRapidInterface() {
00183 stopThreads();
00184 }
00185
00186 void stopThreads() {
00187 stopComm_ = true;
00188 RapidCommThread_.join();
00189 }
00190
00191 void startThreads() {
00192 if(!stopComm_) {
00193 boost::thread(boost::bind(&YumiRapidInterface::RapidCommThreadCallback,this ));
00194 }
00195 }
00196
00197 void getCurrentJointStates(float (&joints)[N_YUMI_JOINTS]) {
00198 js_handler.getJointStates(joints);
00199 }
00200
00201 void setJointTargets(float (&joints)[N_YUMI_JOINTS], int mode) {
00202 js_handler.setJointCommands(joints, mode);
00203 }
00204
00205
00206 bool init(std::string ip = "", int port = industrial::simple_socket::StandardSocketPorts::STATE) {
00207
00208 char* ip_addr = strdup(ip.c_str());
00209 ROS_INFO("Robot state connecting to IP address: '%s:%d'", ip_addr, port);
00210 default_tcp_connection_.init(ip_addr, port);
00211 free(ip_addr);
00212
00213 connection_ = &default_tcp_connection_;
00214 connection_->makeConnect();
00215
00216 ROS_INFO("Connection established");
00217
00218 manager_.init(connection_);
00219
00220
00221 js_handler.init(connection_);
00222
00223
00224 manager_.add(&js_handler,false);
00225
00226 ROS_INFO("Callbacks and handlers set up");
00227 stopComm_ = false;
00228 }
00229
00230 };
00231
00232 class YumiHWRapid : public YumiHW
00233 {
00234
00235 public:
00236 YumiHWRapid() : YumiHW() {
00237 isInited = false;
00238 isSetup = false;
00239 firstRunInPositionMode = true;
00240 sampling_rate_ = 0.1;
00241 }
00242
00243 ~YumiHWRapid() {
00244 robot_interface.stopThreads();
00245 }
00246
00247 float getSampleTime(){return sampling_rate_;};
00248
00249 void setup(std::string ip_ = "", int port_ = industrial::simple_socket::StandardSocketPorts::STATE) {
00250 ip = ip_;
00251 port = port_;
00252 isSetup = true;
00253 }
00254
00255
00256 bool init()
00257 {
00258 if (isInited) return false;
00259 if(!isSetup) {
00260 ROS_ERROR("IP and port of controller are not set up!");
00261 return false;
00262 }
00263
00264 robot_interface.init(ip,port);
00265 robot_interface.startThreads();
00266 isInited = true;
00267
00268 return true;
00269 }
00270
00272 void read(ros::Time time, ros::Duration period)
00273 {
00274 if(!isInited) return;
00275
00276
00277 data_buffer_mutex.lock();
00278 robot_interface.getCurrentJointStates(readJntPosition);
00279
00280 for (int j = 0; j < n_joints_; j++)
00281 {
00282 joint_position_prev_[j] = joint_position_[j];
00283 joint_position_[j] = readJntPosition[j];
00284
00285 joint_velocity_[j] = filters::exponentialSmoothing((joint_position_[j]-joint_position_prev_[j])/period.toSec(), joint_velocity_[j], 0.04);
00286 if(firstRunInPositionMode) {
00287 joint_position_command_[j] = readJntPosition[j];
00288 }
00289 }
00290 firstRunInPositionMode = false;
00291 data_buffer_mutex.unlock();
00292
00293
00294 return;
00295 }
00296
00298 void write(ros::Time time, ros::Duration period)
00299 {
00300 if(!isInited) return;
00301 enforceLimits(period);
00302
00303
00304 data_buffer_mutex.lock();
00305 switch (getControlStrategy())
00306 {
00307 case JOINT_POSITION:
00308 for (int j = 0; j < n_joints_; j++)
00309 {
00310 newJntPosition[j] = joint_position_command_[j];
00311 }
00312 break;
00313
00314 case JOINT_VELOCITY:
00315
00316 for (int j = 0; j < n_joints_; j++)
00317 {
00318
00319 newJntPosition[j] = joint_velocity_command_[j];
00320 }
00321
00322 firstRunInPositionMode = true;
00323 break;
00324
00325
00326 default:
00327 break;
00328 }
00329
00330 robot_interface.setJointTargets(newJntPosition, getControlStrategy());
00331 data_buffer_mutex.unlock();
00332
00333
00334 return;
00335 }
00336
00337 private:
00338
00340 YumiRapidInterface robot_interface;
00342 float last_comm[N_YUMI_JOINTS];
00344 std::string hintToRemoteHost_;
00346 bool isInited, isSetup, firstRunInPositionMode;
00348 float sampling_rate_;
00350 boost::mutex data_buffer_mutex;
00352 float newJntPosition[N_YUMI_JOINTS];
00354 float readJntPosition[N_YUMI_JOINTS];
00355
00356 std::string ip;
00357 int port;
00358
00359
00360 };
00361
00362 #endif