allegroNode.cpp
Go to the documentation of this file.
00001 /*
00002  * allegroNode.cpp
00003  *
00004  *  Created on: Nov 14, 2012
00005  *  Authors: Alex ALSPACH, Seungsu KIM
00006  */
00007  
00008 // GRASP LIBRARY INTERFACE
00009 // Using  sleep function  
00010  
00011 #include <iostream>
00012 #include <boost/thread/thread.hpp>
00013 #include <boost/date_time.hpp>
00014 #include <boost/thread/locks.hpp>
00015 
00016 #include "ros/ros.h"
00017 #include "ros/service.h"
00018 #include "ros/service_server.h"
00019 #include "sensor_msgs/JointState.h"
00020 #include "std_msgs/String.h"
00021 
00022 #include <stdio.h>
00023 #include <iostream>
00024 #include <string>
00025 
00026 #include "BHand/BHand.h"
00027 #include "controlAllegroHand.h"
00028 
00029 // Topics
00030 #define JOINT_STATE_TOPIC "/allegroHand/joint_states"
00031 #define JOINT_CMD_TOPIC "/allegroHand/joint_cmd"
00032 #define LIB_CMD_TOPIC "/allegroHand/lib_cmd"
00033 
00034 
00035 double desired_position[DOF_JOINTS]                     = {0.0};
00036 double current_position[DOF_JOINTS]                     = {0.0};
00037 double previous_position[DOF_JOINTS]                    = {0.0};
00038 double current_position_filtered[DOF_JOINTS]    = {0.0};
00039 double previous_position_filtered[DOF_JOINTS]   = {0.0};
00040 
00041 double current_velocity[DOF_JOINTS]                     = {0.0};
00042 double previous_velocity[DOF_JOINTS]                    = {0.0};
00043 double current_velocity_filtered[DOF_JOINTS]    = {0.0};
00044 
00045 double desired_torque[DOF_JOINTS]                               = {0.0};
00046 
00047 std::string  lib_cmd;
00048 
00049 
00050 std::string jointNames[DOF_JOINTS]      = {    "joint_0.0",    "joint_1.0",    "joint_2.0",   "joint_3.0" , 
00051                                                                                    "joint_4.0",    "joint_5.0",    "joint_6.0",   "joint_7.0" , 
00052                                                                                    "joint_8.0",    "joint_9.0",    "joint_10.0",  "joint_11.0", 
00053                                                                                    "joint_12.0",   "joint_13.0",   "joint_14.0",  "joint_15.0" };
00054 
00055 int frame = 0;
00056 
00057 // Flags
00058 bool lIsBegin = false;
00059 bool kill = false;      
00060 bool pdControl = true;
00061 int lEmergencyStop = 0;
00062 
00063 boost::mutex *mutex;
00064 
00065 // ROS Messages
00066 ros::Publisher joint_state_pub;
00067 ros::Subscriber joint_cmd_sub;
00068 ros::Subscriber lib_cmd_sub;
00069 sensor_msgs::JointState msgJoint;
00070 
00071 // ROS Time
00072 ros::Time tstart;
00073 ros::Time tnow;
00074 double secs;
00075 double dt;
00076 
00077 // Initialize BHand 
00078 eMotionType gMotionType = eMotionType_NONE ;
00079 BHand* pBHand = NULL;
00080 //BHand lBHand(eHandType_Right);
00081 
00082 
00083 // Initialize CAN device                
00084 controlAllegroHand *canDevice;
00085 
00086 
00087 
00088 // Called when a desired joint position message is received
00089 void SetjointCallback(const sensor_msgs::JointState& msg)
00090 {
00091         // TODO check joint limits
00092         pdControl=true;
00093 
00094         mutex->lock();
00095         for(int i=0;i<DOF_JOINTS;i++) desired_position[i] = msg.position[i];
00096         mutex->unlock();
00097 
00098         pBHand->SetMotionType(eMotionType_JOINT_PD);
00099 }
00100 
00101 void libCmdCallback(const std_msgs::String::ConstPtr& msg)
00102 {
00103 ROS_INFO("I heard: [%s]", msg->data.c_str());
00104 lib_cmd = msg->data.c_str();
00105 
00106 // If PD Control is commanded, pdControl is set true
00107 // so that the controll loop has access to desired position.
00108 if (lib_cmd.compare("pdControl") == 0)
00109 {
00110         pBHand->SetMotionType(eMotionType_JOINT_PD);
00111         pdControl = true;
00112 }    
00113 else
00114     pdControl = false;  
00115 
00116 if (lib_cmd.compare("home") == 0) 
00117         pBHand->SetMotionType(eMotionType_HOME);
00118     
00119 if (lib_cmd.compare("ready") == 0) 
00120         pBHand->SetMotionType(eMotionType_READY);
00121 
00122 if (lib_cmd.compare("grasp_3") == 0) 
00123         pBHand->SetMotionType(eMotionType_GRASP_3);
00124 
00125 if (lib_cmd.compare("grasp_4") == 0) 
00126         pBHand->SetMotionType(eMotionType_GRASP_4);
00127     
00128 if (lib_cmd.compare("pinch_it") == 0) 
00129         pBHand->SetMotionType(eMotionType_PINCH_IT);
00130 
00131 if (lib_cmd.compare("pinch_mt") == 0) 
00132         pBHand->SetMotionType(eMotionType_PINCH_MT);     
00133 
00134 if (lib_cmd.compare("envelop") == 0) 
00135         pBHand->SetMotionType(eMotionType_ENVELOP); 
00136 
00137 if (lib_cmd.compare("off") == 0) 
00138         pBHand->SetMotionType(eMotionType_NONE);
00139 
00140 if (lib_cmd.compare("save") == 0) 
00141         for(int i=0; i<DOF_JOINTS; i++) desired_position[i] = current_position[i];
00142 
00143 /*
00144 eMotionType_NONE,                               // motor power off
00145 eMotionType_HOME,                               // go to home position
00146 eMotionType_READY,                              // ready position for grasping
00147 eMotionType_GRASP_3,                    // grasping using 3 fingers
00148 eMotionType_GRASP_4,                    // grasping using 4 fingers
00149 eMotionType_PINCH_IT,                   // pinching using index finger and thumb
00150 eMotionType_PINCH_MT,                   // pinching using middle finger and thumb
00151 eMotionType_ENVELOP,                    // enveloping
00152 eMotionType_JOINT_PD,                   // joint pd control
00153 eMotionType_OBJECT_MOVING,              //
00154 eMotionType_PRE_SHAPE,                  //
00155 */      
00156 
00157 }
00158 
00159 
00160 
00161 int main(int argc, char** argv)
00162 {
00163         using namespace std;
00164 
00165         ros::init(argc, argv, "allegro_hand_core_grasp");
00166         ros::Time::init();
00167 
00168         ros::NodeHandle nh;
00169 
00170         // Setup sleep rate
00171         ros::Rate rate(1./ALLEGRO_CONTROL_TIME_INTERVAL);
00172 
00173         mutex = new boost::mutex();
00174 
00175         // Publisher and Subscribers
00176         joint_state_pub = nh.advertise<sensor_msgs::JointState>(JOINT_STATE_TOPIC, 3);
00177         joint_cmd_sub = nh.subscribe(JOINT_CMD_TOPIC, 3, SetjointCallback);
00178         lib_cmd_sub = nh.subscribe(LIB_CMD_TOPIC, 1000, libCmdCallback);
00179 
00180         // Create arrays 16 long for each of the four joint state components
00181         msgJoint.position.resize(DOF_JOINTS);
00182         msgJoint.velocity.resize(DOF_JOINTS);
00183         msgJoint.effort.resize(DOF_JOINTS);
00184         msgJoint.name.resize(DOF_JOINTS);
00185 
00186         // Joint names (for use with joint_state_publisher GUI - matches URDF)
00187         for(int i=0; i<DOF_JOINTS; i++) msgJoint.name[i] = jointNames[i];       
00188 
00189         
00190         // Get Allegro Hand information from parameter server
00191         // This information is found in the Hand-specific "zero.yaml" file from the allegro_hand_description package    
00192         string robot_name, whichHand, manufacturer, origin, serial;
00193         double version;
00194         ros::param::get("~hand_info/robot_name",robot_name);
00195         ros::param::get("~hand_info/which_hand",whichHand);
00196         ros::param::get("~hand_info/manufacturer",manufacturer);
00197         ros::param::get("~hand_info/origin",origin);
00198         ros::param::get("~hand_info/serial",serial);
00199         ros::param::get("~hand_info/version",version);
00200 
00201         // Initialize BHand controller
00202         if (whichHand.compare("left") == 0)
00203         {
00204                 pBHand = new BHand(eHandType_Left);
00205                 ROS_WARN("CTRL: Left Allegro Hand controller initialized.");
00206         }
00207         else
00208         {
00209                 pBHand = new BHand(eHandType_Right);
00210                 ROS_WARN("CTRL: Right Allegro Hand controller initialized.");
00211         }
00212         pBHand->SetTimeInterval(ALLEGRO_CONTROL_TIME_INTERVAL);
00213 
00214         // Initialize CAN device
00215         canDevice = new controlAllegroHand();
00216         canDevice->init();
00217         usleep(3000);
00218         
00219         // Dump Allegro Hand information to the terminal        
00220         cout << endl << endl << robot_name << " v" << version << endl << serial << " (" << whichHand << ")" << endl << manufacturer << endl << origin << endl << endl;
00221         
00222 
00223         // Initialize torque at zero
00224         for(int i=0; i<16; i++) desired_torque[i] = 0.0;
00225 
00226         // Set to false for first iteration of control loop (sets PD control at start pose)
00227         lIsBegin = false;
00228 
00229         // Start ROS time
00230         tstart = ros::Time::now();
00231 
00232 
00233 
00234 
00235         while(ros::ok())
00236         {
00237                 // Calculate loop time;
00238                 tnow = ros::Time::now();
00239                 dt = 1e-9*(tnow - tstart).nsec;
00240                 tstart = tnow;
00241 
00242                 // save last iteration info
00243                 for(int i=0; i<DOF_JOINTS; i++)
00244                 {
00245                         previous_position[i] = current_position[i];
00246                         previous_position_filtered[i] = current_position_filtered[i];
00247                         previous_velocity[i] = current_velocity[i];
00248                 }
00249 
00250                 /* ================================== 
00251                  =        CAN COMMUNICATION         =   
00252                  ================================== */
00253                 canDevice->setTorque(desired_torque);
00254                 lEmergencyStop = canDevice->update();
00255         canDevice->getJointInfo(current_position);
00256                 
00257                 
00258                 /* ================================== 
00259                  =         LOWPASS FILTERING        =   
00260                  ================================== */
00261                 for(int i=0; i<DOF_JOINTS; i++)    
00262                 {
00263                         current_position_filtered[i] = (0.6*current_position_filtered[i]) + (0.198*previous_position[i]) + (0.198*current_position[i]);
00264                         current_velocity[i] = (current_position_filtered[i] - previous_position_filtered[i]) / dt;
00265                         current_velocity_filtered[i] = (0.6*current_velocity_filtered[i]) + (0.198*previous_velocity[i]) + (0.198*current_velocity[i]);
00266                 }                       
00267 
00268 
00269                 if( lEmergencyStop < 0 )
00270                 {
00271                         // Stop program when Allegro Hand is switched off
00272                         printf("\n\n\nEMERGENCY STOP.\n\n");
00273                         ros::shutdown();
00274                 }
00275 
00276                 // compute control torque using Bhand library
00277                 pBHand->SetJointPosition(current_position_filtered);
00278 
00279                 // Run on FIRST iteration (sets PD control of intitial position)
00280                 if( lIsBegin == false ){
00281                         if(frame > 10){
00282                                 mutex->lock();
00283                                 for(int i=0; i<DOF_JOINTS; i++) desired_position[i] = current_position[i];
00284                                 mutex->unlock();
00285 
00286                                 lIsBegin = true;
00287                                 }
00288 
00289                                 // Start joint position control (Bhand) in initial position
00290                                 // Commented out for safety incase the joint offsets or directions are incorrect
00291                                 //pBHand->SetMotionType(eMotionType_JOINT_PD);
00292 
00293                                 // Starts with motors off but encoder data is read and can be visualized
00294                                 pBHand->SetMotionType(eMotionType_NONE);
00295 
00296                                 pBHand->UpdateControl((double)frame*ALLEGRO_CONTROL_TIME_INTERVAL);
00297                                 for(int i=0; i<DOF_JOINTS; i++) desired_torque[i] = 0.0;
00298                         }
00299                         else{                   
00300 
00301                                 // BHAND Communication
00302                                 // desired joint positions are obtained from subscriber "joint_cmd_sub"
00303                                 // or maintatined as the initial positions from program start (PD control)
00304                                 // Also, other motions/grasps can be executed (envoked via "lib_cmd_sub")
00305 
00306                                 // Desired position only necessary if in PD Control mode        
00307                                 if (pdControl==true)
00308                                         pBHand->SetJointDesiredPosition(desired_position);
00309 
00310                                 // BHand lib control updated with time stamp    
00311                                 pBHand->UpdateControl((double)frame*ALLEGRO_CONTROL_TIME_INTERVAL);
00312 
00313                                 // Necessary torque obtained from Bhand lib
00314                                 pBHand->GetJointTorque(desired_torque);
00315 
00316                                 // Calculate joint velocity
00317                                 for(int i=0; i<DOF_JOINTS; i++)
00318                                         current_velocity[i] = (current_position[i] - previous_position[i])/dt;
00319 
00320                                 // current position, velocity and effort (torque) published
00321                                 msgJoint.header.stamp                                                                   = tnow;
00322                                 for(int i=0; i<DOF_JOINTS; i++) msgJoint.position[i]    = current_position_filtered[i];
00323                                 for(int i=0; i<DOF_JOINTS; i++) msgJoint.velocity[i]    = current_velocity_filtered[i];
00324                                 for(int i=0; i<DOF_JOINTS; i++) msgJoint.effort[i]              = desired_torque[i];
00325                                 joint_state_pub.publish(msgJoint);
00326                         }
00327 
00328                         frame++;        
00329 
00330                         ros::spinOnce();
00331                         rate.sleep();   
00332         }
00333 
00334         // Clean shutdown: shutdown node, shutdown can, be polite.
00335         nh.shutdown();
00336         delete canDevice;
00337         printf("\nBye.\n");
00338         return 0;
00339 }
00340 


allegro_hand_core_grasp_slp
Author(s): Alex Alspach (SimLab), Seungsu Kim (EPFL)
autogenerated on Sun Oct 5 2014 22:09:40