yumi_hw_rapid.h
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             //ROS_INFO("Received a message");
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             //ROS_INFO("Message parsed");
00081             industrial::shared_types::shared_real joint_value_from_msg;
00082 
00083             for(int i=0; i<N_YUMI_JOINTS; i++) {
00084                 //std::cerr<<i<<":";
00085                 if (joint_msg.getJoints().getJoint(i, joint_value_from_msg))
00086                 {
00087                     joint_positions[i] = joint_value_from_msg;
00088                     //std::cerr<<joint_positions[i]<<" ";
00089                 }
00090                 else
00091                 {
00092                     //std::cerr<<"X";
00093                     rtn = false;
00094                 }
00095             }
00096             //std::cerr<<"\n";
00097 
00098             // Reply back to the controller if the sender requested it.
00099             if (industrial::simple_message::CommTypes::SERVICE_REQUEST == joint_msg.getMessageType())
00100             {
00101                 //ROS_INFO("Reply requested, sending");
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             //if first call back, then mirror state to command
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             //TODO: format trajectory request message
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 //              std::cerr<<joint_command[i]<<" ";
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 //          std::cerr<<"\n";
00138 
00139             //TODO: send back on conncetion 
00140             industrial::simple_message::SimpleMessage next_point;
00141             joint_msg.toRequest(next_point);
00142             this->getConnection()->sendMsg(next_point);
00143 
00144             //ROS_INFO("Done processing");
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         //industrial::tcp_client::RobotStatusRelayHandler default_robot_status_handler_; //?
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             //initialize connection 
00208             char* ip_addr = strdup(ip.c_str());  // connection.init() requires "char*", not "const char*"
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             //initialize message manager
00218             manager_.init(connection_);
00219 
00220             //initialize message handler
00221             js_handler.init(connection_);
00222 
00223             //register handler to manager
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   // Init, read, and write, with FRI hooks
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     //ROS_INFO("reading joints");
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       //joint_effort_[j] = readJntEffort[j]; //TODO: read effort 
00285       joint_velocity_[j] = filters::exponentialSmoothing((joint_position_[j]-joint_position_prev_[j])/period.toSec(), joint_velocity_[j], 0.04); //exponential smoothing
00286       if(firstRunInPositionMode) {
00287           joint_position_command_[j] = readJntPosition[j];
00288       }
00289     }
00290     firstRunInPositionMode = false;
00291     data_buffer_mutex.unlock();
00292     //ROS_INFO("read joints");
00293 
00294     return;
00295   }
00296 
00298   void write(ros::Time time, ros::Duration period)
00299   {
00300     if(!isInited) return;  
00301     enforceLimits(period);
00302 
00303     //ROS_INFO("writing joints");
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         //std::cerr<<"ASS = ";
00316         for (int j = 0; j < n_joints_; j++)
00317         {
00318           //std::cerr<<joint_velocity_command_[j]<<"*"<<period.toSec()<<" + "<<joint_position_[j]<<" ::: ";  
00319           newJntPosition[j] = joint_velocity_command_[j]; //*period.toSec() + joint_position_[j]; 
00320         }
00321         //std::cerr<<std::endl;
00322         firstRunInPositionMode = true;
00323         break;
00324       //case JOINT_EFFORT:
00325       //break;
00326       default: 
00327         break;
00328     }
00329 
00330     robot_interface.setJointTargets(newJntPosition, getControlStrategy());
00331     data_buffer_mutex.unlock();
00332     //ROS_INFO("wrote joints");
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


yumi_hw
Author(s):
autogenerated on Sat Jun 8 2019 20:47:40