sdh.cpp
Go to the documentation of this file.
00001 
00060 //##################
00061 //#### includes ####
00062 
00063 // standard includes
00064 #include <unistd.h>
00065 
00066 // ROS includes
00067 #include <ros/ros.h>
00068 #include <urdf/model.h>
00069 #include <actionlib/server/simple_action_server.h>
00070 
00071 // ROS message includes
00072 #include <std_msgs/Float32MultiArray.h>
00073 #include <trajectory_msgs/JointTrajectory.h>
00074 #include <sensor_msgs/JointState.h>
00075 //#include <pr2_controllers_msgs/JointTrajectoryAction.h>
00076 #include <control_msgs/FollowJointTrajectoryAction.h>
00077 #include <pr2_controllers_msgs/JointTrajectoryControllerState.h>
00078 #include <schunk_sdh/TactileSensor.h>
00079 #include <schunk_sdh/TactileMatrix.h>
00080 #include <brics_actuator/JointVelocities.h>
00081 #include <brics_actuator/JointValue.h>
00082 
00083 // ROS service includes
00084 #include <cob_srvs/Trigger.h>
00085 #include <cob_srvs/SetOperationMode.h>
00086 
00087 // ROS diagnostic msgs
00088 #include <diagnostic_msgs/DiagnosticArray.h>
00089 
00090 // external includes
00091 #include <schunk_sdh/sdh.h>
00092 #include <schunk_sdh/dsa.h>
00093 
00099 class SdhNode
00100 {
00101         public:
00103                 ros::NodeHandle nh_;
00104         private:
00105                 // declaration of topics to publish
00106                 ros::Publisher topicPub_JointState_;
00107                 ros::Publisher topicPub_ControllerState_;
00108                 ros::Publisher topicPub_TactileSensor_;
00109                 ros::Publisher topicPub_Diagnostics_;
00110                 
00111                 // topic subscribers
00112                 ros::Subscriber subSetVelocitiesRaw_;
00113                 ros::Subscriber subSetVelocities_;
00114 
00115                 // service servers
00116                 ros::ServiceServer srvServer_Init_;
00117                 ros::ServiceServer srvServer_Stop_;
00118                 ros::ServiceServer srvServer_Recover_;
00119                 ros::ServiceServer srvServer_SetOperationMode_;
00120 
00121                 // actionlib server
00122                 //actionlib::SimpleActionServer<pr2_controllers_msgs::JointTrajectoryAction> as_;
00123                 actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> as_;
00124                 std::string action_name_;
00125 
00126                 // service clients
00127                 //--
00128 
00129                 // other variables
00130                 SDH::cSDH *sdh_;
00131                 SDH::cDSA *dsa_;
00132                 std::vector<SDH::cSDH::eAxisState> state_;
00133 
00134                 std::string sdhdevicetype_;
00135                 std::string sdhdevicestring_;
00136                 int sdhdevicenum_;
00137                 std::string dsadevicestring_;
00138                 int dsadevicenum_;
00139                 int baudrate_, id_read_, id_write_;
00140                 double timeout_;
00141 
00142                 bool isInitialized_;
00143                 bool isDSAInitialized_;
00144                 bool isError_;
00145                 int DOF_;
00146                 double pi_;
00147                 
00148                 trajectory_msgs::JointTrajectory traj_;
00149                 
00150                 std::vector<std::string> joint_names_;
00151                 std::vector<int> axes_;
00152                 std::vector<double> targetAngles_; // in degrees
00153                 std::vector<double> velocities_; // in rad/s
00154                 bool hasNewGoal_;
00155                 std::string operationMode_; 
00156                 
00157         public:
00163                 SdhNode(std::string name):
00164                         as_(nh_, name, boost::bind(&SdhNode::executeCB, this, _1),true),
00165                         action_name_(name)
00166                 {
00167                         pi_ = 3.1415926;
00168                         
00169                         nh_ = ros::NodeHandle ("~");
00170                         isError_ = false;
00171                         // diagnostics
00172                         topicPub_Diagnostics_ = nh_.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1);
00173 
00174                 }
00175 
00179                 ~SdhNode() 
00180                 {
00181                         if(isDSAInitialized_)
00182                                 dsa_->Close();
00183                         if(isInitialized_)
00184                                 sdh_->Close();
00185                         delete sdh_;
00186                 }
00187 
00188 
00192                 bool init()
00193                 {
00194                         // initialize member variables
00195                         isInitialized_ = false;
00196                         isDSAInitialized_ = false;
00197                         hasNewGoal_ = false;
00198 
00199                         // implementation of topics to publish
00200                         topicPub_JointState_ = nh_.advertise<sensor_msgs::JointState>("/joint_states", 1);
00201                         topicPub_ControllerState_ = nh_.advertise<pr2_controllers_msgs::JointTrajectoryControllerState>("state", 1);
00202                         topicPub_TactileSensor_ = nh_.advertise<schunk_sdh::TactileSensor>("tactile_data", 1);
00203 
00204                         // pointer to sdh
00205                         sdh_ = new SDH::cSDH(false, false, 0); //(_use_radians=false, bool _use_fahrenheit=false, int _debug_level=0)
00206 
00207                         // implementation of service servers
00208                         srvServer_Init_ = nh_.advertiseService("init", &SdhNode::srvCallback_Init, this);
00209                         srvServer_Stop_ = nh_.advertiseService("stop", &SdhNode::srvCallback_Stop, this);
00210                         srvServer_Recover_ = nh_.advertiseService("recover", &SdhNode::srvCallback_Init, this); //HACK: There is no recover implemented yet, so we execute a init
00211                         srvServer_SetOperationMode_ = nh_.advertiseService("set_operation_mode", &SdhNode::srvCallback_SetOperationMode, this);
00212                         
00213                         subSetVelocitiesRaw_ = nh_.subscribe("set_velocities_raw", 1, &SdhNode::topicCallback_setVelocitiesRaw, this);
00214                         subSetVelocities_ = nh_.subscribe("set_velocities", 1, &SdhNode::topicCallback_setVelocities, this);
00215 
00216                         // getting hardware parameters from parameter server
00217                         nh_.param("sdhdevicetype", sdhdevicetype_, std::string("PCAN"));
00218                         nh_.param("sdhdevicestring", sdhdevicestring_, std::string("/dev/pcan0"));
00219                         nh_.param("sdhdevicenum", sdhdevicenum_, 0);
00220                         
00221                         nh_.param("dsadevicestring", dsadevicestring_, std::string(""));
00222                         nh_.param("dsadevicenum", dsadevicenum_, 0);
00223                         
00224                         nh_.param("baudrate", baudrate_, 1000000);
00225                         nh_.param("timeout", timeout_, (double)0.04);
00226                         nh_.param("id_read", id_read_, 43);
00227                         nh_.param("id_write", id_write_, 42);
00228 
00229                         // get joint_names from parameter server
00230                         ROS_INFO("getting joint_names from parameter server");
00231                         XmlRpc::XmlRpcValue joint_names_param;
00232                         if (nh_.hasParam("joint_names"))
00233                         {
00234                                 nh_.getParam("joint_names", joint_names_param);
00235                         }
00236                         else
00237                         {
00238                                 ROS_ERROR("Parameter joint_names not set, shutting down node...");
00239                                 nh_.shutdown();
00240                                 return false;
00241                         }
00242                         DOF_ = joint_names_param.size();
00243                         joint_names_.resize(DOF_);
00244                         for (int i = 0; i<DOF_; i++ )
00245                         {
00246                                 joint_names_[i] = (std::string)joint_names_param[i];
00247                         }
00248                         std::cout << "joint_names = " << joint_names_param << std::endl;
00249                         
00250                         // define axes to send to sdh
00251                         axes_.resize(DOF_);
00252                         velocities_.resize(DOF_);
00253                         for(int i=0; i<DOF_; i++)
00254                         {
00255                                 axes_[i] = i;
00256                         }
00257                         ROS_INFO("DOF = %d",DOF_);
00258                         
00259                         state_.resize(axes_.size());
00260 
00261                         nh_.param("OperationMode", operationMode_, std::string("position"));
00262                         return true;
00263                 }
00264 
00271                 //void executeCB(const pr2_controllers_msgs::JointTrajectoryGoalConstPtr &goal)
00272                 void executeCB(const control_msgs::FollowJointTrajectoryGoalConstPtr &goal)
00273                 {                       
00274                         ROS_INFO("sdh: executeCB");
00275                         if (operationMode_ != "position")
00276                         {
00277                                 ROS_ERROR("%s: Rejected, sdh not in position mode", action_name_.c_str());
00278                                 as_.setAborted();
00279                                 return;
00280                         }
00281                         if (!isInitialized_)
00282                         {
00283                                 ROS_ERROR("%s: Rejected, sdh not initialized", action_name_.c_str());
00284                                 as_.setAborted();
00285                                 return;
00286                         }
00287 
00288                         if (goal->trajectory.points.empty() || goal->trajectory.points[0].positions.size() != size_t(DOF_))
00289                         {
00290                                 ROS_ERROR("%s: Rejected, malformed FollowJointTrajectoryGoal", action_name_.c_str());
00291                                 as_.setAborted();
00292                                 return;
00293                         }
00294                         while (hasNewGoal_ == true ) usleep(10000);
00295 
00296                         std::map<std::string,int> dict;
00297                         for (int idx=0; idx<goal->trajectory.joint_names.size(); idx++)
00298                         {
00299                                 dict[goal->trajectory.joint_names[idx]] = idx;
00300                         }
00301 
00302                         targetAngles_.resize(DOF_);
00303                         targetAngles_[0] = goal->trajectory.points[0].positions[dict["sdh_knuckle_joint"]]*180.0/pi_; // sdh_knuckle_joint
00304                         targetAngles_[1] = goal->trajectory.points[0].positions[dict["sdh_finger_22_joint"]]*180.0/pi_; // sdh_finger22_joint
00305                         targetAngles_[2] = goal->trajectory.points[0].positions[dict["sdh_finger_23_joint"]]*180.0/pi_; // sdh_finger23_joint
00306                         targetAngles_[3] = goal->trajectory.points[0].positions[dict["sdh_thumb_2_joint"]]*180.0/pi_; // sdh_thumb2_joint
00307                         targetAngles_[4] = goal->trajectory.points[0].positions[dict["sdh_thumb_3_joint"]]*180.0/pi_; // sdh_thumb3_joint
00308                         targetAngles_[5] = goal->trajectory.points[0].positions[dict["sdh_finger_12_joint"]]*180.0/pi_; // sdh_finger12_joint
00309                         targetAngles_[6] = goal->trajectory.points[0].positions[dict["sdh_finger_13_joint"]]*180.0/pi_; // sdh_finger13_joint
00310                         ROS_INFO("received position goal: [['sdh_knuckle_joint', 'sdh_thumb_2_joint', 'sdh_thumb_3_joint', 'sdh_finger_12_joint', 'sdh_finger_13_joint', 'sdh_finger_22_joint', 'sdh_finger_23_joint']] = [%f,%f,%f,%f,%f,%f,%f]",goal->trajectory.points[0].positions[dict["sdh_knuckle_joint"]],goal->trajectory.points[0].positions[dict["sdh_thumb_2_joint"]],goal->trajectory.points[0].positions[dict["sdh_thumb_3_joint"]],goal->trajectory.points[0].positions[dict["sdh_finger_12_joint"]],goal->trajectory.points[0].positions[dict["sdh_finger_13_joint"]],goal->trajectory.points[0].positions[dict["sdh_finger_22_joint"]],goal->trajectory.points[0].positions[dict["sdh_finger_23_joint"]]);
00311                 
00312                         hasNewGoal_ = true;
00313                         
00314                         usleep(500000); // needed sleep until sdh starts to change status from idle to moving
00315                         
00316                         bool finished = false;
00317                         while(finished == false)
00318                         {
00319                                 if (as_.isNewGoalAvailable())
00320                                 {
00321                                         ROS_WARN("%s: Aborted", action_name_.c_str());
00322                                         as_.setAborted();
00323                                         return;
00324                                 }
00325                                 for ( unsigned int i = 0; i < state_.size(); i++ )
00326                                 {
00327                                         ROS_DEBUG("state[%d] = %d",i,state_[i]);
00328                                         if (state_[i] == 0)
00329                                         {
00330                                                 finished = true;
00331                                         }
00332                                         else
00333                                         {       
00334                                                 finished = false;
00335                                         }
00336                                 }
00337                                 usleep(10000);
00338                                 //feedback_ = 
00339                                 //as_.send feedback_
00340                         }
00341 
00342                         // set the action state to succeeded                    
00343                         ROS_INFO("%s: Succeeded", action_name_.c_str());
00344                         //result_.result.data = "succesfully received new goal";
00345                         //result_.success = 1;
00346                         //as_.setSucceeded(result_);
00347                         as_.setSucceeded();
00348                 }
00349 
00350                 void topicCallback_setVelocitiesRaw(const std_msgs::Float32MultiArrayPtr& velocities)
00351                 {
00352                         if (!isInitialized_)
00353                         {
00354                                 ROS_ERROR("%s: Rejected, sdh not initialized", action_name_.c_str());
00355                                 return;
00356                         }
00357                         if(velocities->data.size() != velocities_.size()){
00358                                 ROS_ERROR("Velocity array dimension mismatch");
00359                                 return;
00360                         }
00361                         if (operationMode_ != "velocity")
00362                         {
00363                                 ROS_ERROR("%s: Rejected, sdh not in velocity mode", action_name_.c_str());
00364                                 return;
00365                         }
00366 
00367                         // TODO: write proper lock!
00368                         while (hasNewGoal_ == true ) usleep(10000);
00369 
00370                         velocities_[0] = velocities->data[0] * 180.0 / pi_; // sdh_knuckle_joint
00371                         velocities_[1] = velocities->data[5] * 180.0 / pi_; // sdh_finger22_joint
00372                         velocities_[2] = velocities->data[6] * 180.0 / pi_; // sdh_finger23_joint
00373                         velocities_[3] = velocities->data[1] * 180.0 / pi_; // sdh_thumb2_joint
00374                         velocities_[4] = velocities->data[2] * 180.0 / pi_; // sdh_thumb3_joint
00375                         velocities_[5] = velocities->data[3] * 180.0 / pi_; // sdh_finger12_joint
00376                         velocities_[6] = velocities->data[4] * 180.0 / pi_; // sdh_finger13_joint
00377 
00378                         hasNewGoal_ = true;
00379                 }
00380                 bool parseDegFromJointValue(const brics_actuator::JointValue& val, double &deg_val){
00381                     if (val.unit == "rad/s"){
00382                         deg_val = val.value  * 180.0 / pi_;
00383                         return true;
00384                     }else if (val.unit == "deg/s"){
00385                         deg_val = val.value;
00386                         return true;
00387                     }else {
00388                         ROS_ERROR_STREAM("Rejected message, unit '" << val.unit << "' not supported");
00389                         return false;
00390                     }
00391                 }
00392                 void topicCallback_setVelocities(const brics_actuator::JointVelocities::ConstPtr& msg)
00393                 {
00394                         if (!isInitialized_)
00395                         {
00396                                 ROS_ERROR("%s: Rejected, sdh not initialized", action_name_.c_str());
00397                                 return;
00398                         }
00399                         if(msg->velocities.size() != velocities_.size()){
00400                                 ROS_ERROR("Velocity array dimension mismatch");
00401                                 return;
00402                         }
00403                         if (operationMode_ != "velocity")
00404                         {
00405                                 ROS_ERROR("%s: Rejected, sdh not in velocity mode", action_name_.c_str());
00406                                 return;
00407                         }
00408 
00409                         // TODO: write proper lock!
00410                         while (hasNewGoal_ == true ) usleep(10000);
00411                         bool valid = true;
00412 
00413                         valid = valid && parseDegFromJointValue(msg->velocities[0], velocities_[0]); // sdh_knuckle_joint
00414                         valid = valid && parseDegFromJointValue(msg->velocities[5], velocities_[1]); // sdh_finger22_joint
00415                         valid = valid && parseDegFromJointValue(msg->velocities[6], velocities_[2]); // sdh_finger23_joint
00416                         valid = valid && parseDegFromJointValue(msg->velocities[1], velocities_[3]); // sdh_thumb2_joint
00417                         valid = valid && parseDegFromJointValue(msg->velocities[2], velocities_[4]); // sdh_thumb3_joint
00418                         valid = valid && parseDegFromJointValue(msg->velocities[3], velocities_[5]); // sdh_finger12_joint
00419                         valid = valid && parseDegFromJointValue(msg->velocities[4], velocities_[6]); // sdh_finger13_joint
00420 
00421                         if (valid) hasNewGoal_ = true;
00422                 }               
00430                 bool srvCallback_Init(cob_srvs::Trigger::Request &req,
00431                                                         cob_srvs::Trigger::Response &res )
00432                 {
00433 
00434                         if (isInitialized_ == false)
00435                         {
00436                                 //Init Hand connection  
00437                                 
00438                                 try
00439                                 {
00440                                         if(sdhdevicetype_.compare("RS232")==0)
00441                                         {
00442                                                 sdh_->OpenRS232( sdhdevicenum_, 115200, 1, sdhdevicestring_.c_str());
00443                                                 ROS_INFO("Initialized RS232 for SDH");
00444                                                 isInitialized_ = true;
00445                                         }
00446                                         if(sdhdevicetype_.compare("PCAN")==0)
00447                                         {
00448                                                 ROS_INFO("Starting initializing PEAKCAN");
00449                                                 sdh_->OpenCAN_PEAK(baudrate_, timeout_, id_read_, id_write_, sdhdevicestring_.c_str());
00450                                                 ROS_INFO("Initialized PEAK CAN for SDH");
00451                                                 isInitialized_ = true;
00452                                         }
00453                                         if(sdhdevicetype_.compare("ESD")==0)
00454                                         {
00455                                                 ROS_INFO("Starting initializing ESD");
00456                                                 if(strcmp(sdhdevicestring_.c_str(), "/dev/can0") == 0)
00457                                                 {
00458                                                         ROS_INFO("Initializing ESD on device %s",sdhdevicestring_.c_str());
00459                                                         sdh_->OpenCAN_ESD(0, baudrate_, timeout_, id_read_, id_write_ );
00460                                                 }
00461                                                 else if(strcmp(sdhdevicestring_.c_str(), "/dev/can1") == 0)
00462                                                 {
00463                                                         ROS_INFO("Initializin ESD on device %s",sdhdevicestring_.c_str());
00464                                                         sdh_->OpenCAN_ESD(1, baudrate_, timeout_, id_read_, id_write_ );
00465                                                 }
00466                                                 else
00467                                                 {
00468                                                         ROS_ERROR("Currently only support for /dev/can0 and /dev/can1");
00469                                                         res.success.data = false;
00470                                                         res.error_message.data = "Currently only support for /dev/can0 and /dev/can1";
00471                                                         return true;
00472                                                 }
00473                                                 ROS_INFO("Initialized ESDCAN for SDH"); 
00474                                                 isInitialized_ = true;
00475                                         }
00476                                 }
00477                                 catch (SDH::cSDHLibraryException* e)
00478                                 {
00479                                         ROS_ERROR("An exception was caught: %s", e->what());
00480                                         res.success.data = false;
00481                                         res.error_message.data = e->what();
00482                                         delete e;
00483                                         return true;
00484                                 }
00485                                 
00486                                 //Init tactile data
00487                                 if(!dsadevicestring_.empty())  {
00488                                         try
00489                                         {
00490                                                 dsa_ = new SDH::cDSA(0, dsadevicenum_, dsadevicestring_.c_str());
00491                                                 //dsa_->SetFramerate( 0, true, false );
00492                                                 dsa_->SetFramerate( 1, true );
00493                                                 ROS_INFO("Initialized RS232 for DSA Tactile Sensors on device %s",dsadevicestring_.c_str());
00494                                                 // ROS_INFO("Set sensitivity to 1.0");
00495                                                 // for(int i=0; i<6; i++)
00496                                                 //      dsa_->SetMatrixSensitivity(i, 1.0);
00497                                                 isDSAInitialized_ = true;
00498                                         }
00499                                         catch (SDH::cSDHLibraryException* e)
00500                                         {
00501                                                 isDSAInitialized_ = false;
00502                                                 ROS_ERROR("An exception was caught: %s", e->what());
00503                                                 res.success.data = false;
00504                                                 res.error_message.data = e->what();
00505                                                 delete e;
00506                                                 return true;
00507                                         }
00508                                 }
00509                         }
00510                         else
00511                         {
00512                                 ROS_WARN("...sdh already initialized...");
00513                                 res.success.data = true;
00514                                 res.error_message.data = "sdh already initialized";
00515                         }
00516                         
00517                         res.success.data = true;
00518                         return true;
00519                 }
00520 
00528                 bool srvCallback_Stop(cob_srvs::Trigger::Request &req,
00529                                                         cob_srvs::Trigger::Response &res )
00530                 {
00531                         ROS_INFO("Stopping sdh");
00532 
00533                         // stopping all arm movements
00534                         try
00535                         {
00536                                 sdh_->Stop();
00537                         }
00538                         catch (SDH::cSDHLibraryException* e)
00539                         {
00540                                 ROS_ERROR("An exception was caught: %s", e->what());
00541                                 delete e;
00542                         }
00543 
00544                 ROS_INFO("Stopping sdh succesfull");
00545                 res.success.data = true;
00546                 return true;
00547         }
00548 
00556         bool srvCallback_Recover(cob_srvs::Trigger::Request &req,
00557                                                         cob_srvs::Trigger::Response &res )
00558         {
00559                 ROS_WARN("Service recover not implemented yet");
00560                 res.success.data = true;
00561                 res.error_message.data = "Service recover not implemented yet";
00562                 return true;
00563         }
00564         
00572         bool srvCallback_SetOperationMode(cob_srvs::SetOperationMode::Request &req,
00573                                                                         cob_srvs::SetOperationMode::Response &res )
00574         {
00575                 hasNewGoal_ = false;
00576                 sdh_->Stop();
00577                 ROS_INFO("Set operation mode to [%s]", req.operation_mode.data.c_str());
00578                 operationMode_ = req.operation_mode.data;
00579                 res.success.data = true;
00580                 if( operationMode_ == "position"){
00581                         sdh_->SetController(SDH::cSDH::eCT_POSE);
00582                 }else if( operationMode_ == "velocity"){
00583                         try{
00584                                 sdh_->SetController(SDH::cSDH::eCT_VELOCITY);
00585                                 sdh_->SetAxisEnable(sdh_->All, 1.0);
00586                         }
00587                         catch (SDH::cSDHLibraryException* e)
00588                         {
00589                                 ROS_ERROR("An exception was caught: %s", e->what());
00590                                 delete e;
00591                         }
00592                 }else{
00593                         ROS_ERROR_STREAM("Operation mode '" << req.operation_mode.data << "'  not supported");
00594                 }
00595                 return true;
00596         }
00597 
00603         void updateSdh()
00604         {
00605                 ROS_DEBUG("updateJointState");
00606                 if (isInitialized_ == true)
00607                 {
00608                         if (hasNewGoal_ == true)
00609                         {
00610                                 // stop sdh first when new goal arrived
00611                                 try
00612                                 {
00613                                         sdh_->Stop();
00614                                 }
00615                                 catch (SDH::cSDHLibraryException* e)
00616                                 {
00617                                         ROS_ERROR("An exception was caught: %s", e->what());
00618                                         delete e;
00619                                 }
00620                 
00621                                 if (operationMode_ == "position")
00622                                 {
00623                                         ROS_DEBUG("moving sdh in position mode");
00624 
00625                                         try
00626                                         {
00627                                                 sdh_->SetAxisTargetAngle( axes_, targetAngles_ );
00628                                                 sdh_->MoveHand(false);
00629                                         }
00630                                         catch (SDH::cSDHLibraryException* e)
00631                                         {
00632                                                 ROS_ERROR("An exception was caught: %s", e->what());
00633                                                 delete e;
00634                                         }
00635                                 }
00636                                 else if (operationMode_ == "velocity")
00637                                 {
00638                                         ROS_DEBUG("moving sdh in velocity mode");
00639                                         try
00640                                         {
00641                                                 sdh_->SetAxisTargetVelocity(axes_,velocities_);
00642                                                 // ROS_DEBUG_STREAM("velocities: " << velocities_[0] << " "<< velocities_[1] << " "<< velocities_[2] << " "<< velocities_[3] << " "<< velocities_[4] << " "<< velocities_[5] << " "<< velocities_[6]);
00643                                         }
00644                                         catch (SDH::cSDHLibraryException* e)
00645                                         {
00646                                                 ROS_ERROR("An exception was caught: %s", e->what());
00647                                                 delete e;
00648                                         }
00649                                 }
00650                                 else if (operationMode_ == "effort")
00651                                 {
00652                                         ROS_DEBUG("moving sdh in effort mode");
00653                                         //sdh_->MoveVel(goal->trajectory.points[0].velocities);
00654                                         ROS_WARN("Moving in effort mode currently disabled");
00655                                 }
00656                                 else
00657                                 {
00658                                         ROS_ERROR("sdh neither in position nor in velocity nor in effort mode. OperationMode = [%s]", operationMode_.c_str());
00659                                 }
00660                                 
00661                                 hasNewGoal_ = false;
00662                         }
00663 
00664                         // read and publish joint angles and velocities
00665                         std::vector<double> actualAngles;
00666                         try
00667                         {
00668                                 actualAngles = sdh_->GetAxisActualAngle( axes_ );
00669                         }
00670                         catch (SDH::cSDHLibraryException* e)
00671                         {
00672                                 ROS_ERROR("An exception was caught: %s", e->what());
00673                                 delete e;
00674                         }
00675                         std::vector<double> actualVelocities;
00676                         try
00677                         {
00678                                 actualVelocities = sdh_->GetAxisActualVelocity( axes_ );
00679                         }
00680                         catch (SDH::cSDHLibraryException* e)
00681                         {
00682                                 ROS_ERROR("An exception was caught: %s", e->what());
00683                                 delete e;
00684                         }
00685                         
00686                         ROS_DEBUG("received %d angles from sdh",(int)actualAngles.size());
00687                         
00688                         ros::Time time = ros::Time::now();
00689                         
00690                         // create joint_state message
00691                         sensor_msgs::JointState msg;
00692                         msg.header.stamp = time;
00693                         msg.name.resize(DOF_);
00694                         msg.position.resize(DOF_);
00695                         msg.velocity.resize(DOF_);
00696                         msg.effort.resize(DOF_);
00697                         // set joint names and map them to angles
00698                         msg.name = joint_names_;
00699                         //['sdh_knuckle_joint', 'sdh_thumb_2_joint', 'sdh_thumb_3_joint', 'sdh_finger_12_joint', 'sdh_finger_13_joint', 'sdh_finger_22_joint', 'sdh_finger_23_joint']
00700                         // pos
00701                         msg.position[0] = actualAngles[0]*pi_/180.0; // sdh_knuckle_joint
00702                         msg.position[1] = actualAngles[3]*pi_/180.0; // sdh_thumb_2_joint
00703                         msg.position[2] = actualAngles[4]*pi_/180.0; // sdh_thumb_3_joint
00704                         msg.position[3] = actualAngles[5]*pi_/180.0; // sdh_finger_12_joint
00705                         msg.position[4] = actualAngles[6]*pi_/180.0; // sdh_finger_13_joint
00706                         msg.position[5] = actualAngles[1]*pi_/180.0; // sdh_finger_22_joint
00707                         msg.position[6] = actualAngles[2]*pi_/180.0; // sdh_finger_23_joint
00708                         // vel                  
00709                         msg.velocity[0] = actualVelocities[0]*pi_/180.0; // sdh_knuckle_joint
00710                         msg.velocity[1] = actualVelocities[3]*pi_/180.0; // sdh_thumb_2_joint
00711                         msg.velocity[2] = actualVelocities[4]*pi_/180.0; // sdh_thumb_3_joint
00712                         msg.velocity[3] = actualVelocities[5]*pi_/180.0; // sdh_finger_12_joint
00713                         msg.velocity[4] = actualVelocities[6]*pi_/180.0; // sdh_finger_13_joint
00714                         msg.velocity[5] = actualVelocities[1]*pi_/180.0; // sdh_finger_22_joint
00715                         msg.velocity[6] = actualVelocities[2]*pi_/180.0; // sdh_finger_23_joint
00716                         // publish message
00717                         topicPub_JointState_.publish(msg);
00718                         
00719                         
00720                         // because the robot_state_publisher doen't know about the mimic joint, we have to publish the coupled joint separately
00721                         sensor_msgs::JointState  mimicjointmsg;
00722                         mimicjointmsg.header.stamp = time;
00723                         mimicjointmsg.name.resize(1);
00724                         mimicjointmsg.position.resize(1);
00725                         mimicjointmsg.velocity.resize(1);
00726                         mimicjointmsg.name[0] = "sdh_finger_21_joint";
00727                         mimicjointmsg.position[0] = msg.position[0]; // sdh_knuckle_joint = sdh_finger_21_joint
00728                         mimicjointmsg.velocity[0] = msg.velocity[0]; // sdh_knuckle_joint = sdh_finger_21_joint
00729                         topicPub_JointState_.publish(mimicjointmsg);
00730                         
00731                         
00732                         // publish controller state message
00733                         pr2_controllers_msgs::JointTrajectoryControllerState controllermsg;
00734                         controllermsg.header.stamp = time;
00735                         controllermsg.joint_names.resize(DOF_);
00736                         controllermsg.desired.positions.resize(DOF_);
00737                         controllermsg.desired.velocities.resize(DOF_);
00738                         controllermsg.actual.positions.resize(DOF_);
00739                         controllermsg.actual.velocities.resize(DOF_);
00740                         controllermsg.error.positions.resize(DOF_);
00741                         controllermsg.error.velocities.resize(DOF_);
00742                         // set joint names and map them to angles
00743                         controllermsg.joint_names = joint_names_;
00744                         //['sdh_knuckle_joint', 'sdh_thumb_2_joint', 'sdh_thumb_3_joint', 'sdh_finger_12_joint', 'sdh_finger_13_joint', 'sdh_finger_22_joint', 'sdh_finger_23_joint']
00745                         // desired pos
00746                         if (targetAngles_.size() != 0)
00747                         {
00748                                 controllermsg.desired.positions[0] = targetAngles_[0]*pi_/180.0; // sdh_knuckle_joint
00749                                 controllermsg.desired.positions[1] = targetAngles_[3]*pi_/180.0; // sdh_thumb_2_joint
00750                                 controllermsg.desired.positions[2] = targetAngles_[4]*pi_/180.0; // sdh_thumb_3_joint
00751                                 controllermsg.desired.positions[3] = targetAngles_[5]*pi_/180.0; // sdh_finger_12_joint
00752                                 controllermsg.desired.positions[4] = targetAngles_[6]*pi_/180.0; // sdh_finger_13_joint
00753                                 controllermsg.desired.positions[5] = targetAngles_[1]*pi_/180.0; // sdh_finger_22_joint
00754                                 controllermsg.desired.positions[6] = targetAngles_[2]*pi_/180.0; // sdh_finger_23_joint
00755                         }
00756                         // desired vel
00757                                 // they are all zero
00758                         // actual pos                   
00759                         controllermsg.actual.positions = msg.position;
00760                         // actual vel
00761                         controllermsg.actual.velocities = msg.velocity;
00762                         // error, calculated out of desired and actual values
00763                         for (int i = 0; i<DOF_; i++ )
00764                         {
00765                                 controllermsg.error.positions[i] = controllermsg.desired.positions[i] - controllermsg.actual.positions[i];
00766                                 controllermsg.error.velocities[i] = controllermsg.desired.velocities[i] - controllermsg.actual.velocities[i];
00767                         }
00768                         // publish controller message
00769                         topicPub_ControllerState_.publish(controllermsg);
00770 
00771                         // read sdh status
00772                         state_ = sdh_->GetAxisActualState(axes_);
00773                 }
00774                 else
00775                 {
00776                         ROS_DEBUG("sdh not initialized");
00777                 }
00778                 // publishing diagnotic messages
00779             diagnostic_msgs::DiagnosticArray diagnostics;
00780             diagnostics.status.resize(1);
00781             // set data to diagnostics
00782             if(isError_)
00783             {
00784               diagnostics.status[0].level = 2;
00785               diagnostics.status[0].name = "schunk_powercube_chain";
00786               diagnostics.status[0].message = "one or more drives are in Error mode";
00787             }
00788             else
00789             {
00790               if (isInitialized_)
00791               {
00792                 diagnostics.status[0].level = 0;
00793                 diagnostics.status[0].name = nh_.getNamespace(); //"schunk_powercube_chain";
00794                 if(isDSAInitialized_)
00795                         diagnostics.status[0].message = "sdh with tactile sensing initialized and running";
00796                 else
00797                         diagnostics.status[0].message = "sdh initialized and running, tactile sensors not connected";   
00798               }
00799               else
00800               {
00801                 diagnostics.status[0].level = 1;
00802                 diagnostics.status[0].name = nh_.getNamespace(); //"schunk_powercube_chain";
00803                 diagnostics.status[0].message = "sdh not initialized";
00804               }
00805             }
00806             // publish diagnostic message
00807             topicPub_Diagnostics_.publish(diagnostics);
00808 
00809         }
00810 
00816         void updateDsa()
00817         {
00818                 static const int dsa_reorder[6] = { 2 ,3, 4, 5, 0 , 1 }; // t1,t2,f11,f12,f21,f22
00819                 ROS_DEBUG("updateTactileData");
00820 
00821                 if(isDSAInitialized_)
00822                 {
00823                         // read tactile data
00824                         for(int i=0; i<7; i++)
00825                         {
00826                                 try
00827                                 {
00828                                         //dsa_->SetFramerate( 0, true, true );
00829                                         dsa_->UpdateFrame();
00830                                 }
00831                                 catch (SDH::cSDHLibraryException* e)
00832                                 {
00833                                         ROS_ERROR("An exception was caught: %s", e->what());
00834                                         delete e;
00835                                 }
00836                         }
00837 
00838                         schunk_sdh::TactileSensor msg;
00839                         msg.header.stamp = ros::Time::now();
00840                         int m, x, y;
00841                         msg.tactile_matrix.resize(dsa_->GetSensorInfo().nb_matrices);
00842                         for ( int i = 0; i < dsa_->GetSensorInfo().nb_matrices; i++ )
00843                         {
00844                                 m = dsa_reorder[i];                                  
00845                                 schunk_sdh::TactileMatrix &tm = msg.tactile_matrix[i];
00846                                 tm.matrix_id = i;
00847                                 tm.cells_x = dsa_->GetMatrixInfo( m ).cells_x;
00848                                 tm.cells_y = dsa_->GetMatrixInfo( m ).cells_y;
00849                                 tm.tactile_array.resize(tm.cells_x * tm.cells_y);
00850                                 for ( y = 0; y < tm.cells_y; y++ )
00851                                 {
00852                                         for ( x = 0; x < tm.cells_x; x++ )
00853                                                 tm.tactile_array[tm.cells_x*y + x] = dsa_->GetTexel( m, x, y );
00854                                 }
00855                         }
00856                         //publish matrix
00857                         topicPub_TactileSensor_.publish(msg);
00858                 }
00859         }        
00860 }; //SdhNode
00861 
00867 int main(int argc, char** argv)
00868 {
00869         // initialize ROS, spezify name of node
00870         ros::init(argc, argv, "schunk_sdh");
00871 
00872         //SdhNode sdh_node(ros::this_node::getName() + "/joint_trajectory_action");
00873         SdhNode sdh_node(ros::this_node::getName() + "/follow_joint_trajectory");
00874         if (!sdh_node.init()) return 0;
00875         
00876         ROS_INFO("...sdh node running...");
00877 
00878         double frequency;
00879         if (sdh_node.nh_.hasParam("frequency"))
00880         {
00881                 sdh_node.nh_.getParam("frequency", frequency);
00882         }
00883         else
00884         {
00885                 frequency = 5; //Hz
00886                 ROS_WARN("Parameter frequency not available, setting to default value: %f Hz", frequency);
00887         }
00888 
00889         //sleep(1);
00890         ros::Rate loop_rate(frequency); // Hz
00891         while(sdh_node.nh_.ok())
00892         {
00893                 // publish JointState
00894                 sdh_node.updateSdh();
00895                 
00896                 // publish TactileData
00897                 sdh_node.updateDsa();
00898                 
00899                 // sleep and waiting for messages, callbacks
00900                 ros::spinOnce();
00901                 loop_rate.sleep();
00902         }
00903 
00904         return 0;
00905 }
00906 


schunk_sdh
Author(s): Florian Weisshardt
autogenerated on Mon Oct 6 2014 07:29:15