00001
00060
00061
00062
00063
00064 #include <unistd.h>
00065
00066
00067 #include <ros/ros.h>
00068 #include <urdf/model.h>
00069 #include <actionlib/server/simple_action_server.h>
00070
00071
00072 #include <trajectory_msgs/JointTrajectory.h>
00073 #include <sensor_msgs/JointState.h>
00074 #include <pr2_controllers_msgs/JointTrajectoryAction.h>
00075 #include <pr2_controllers_msgs/JointTrajectoryControllerState.h>
00076 #include <cob_sdh/TactileSensor.h>
00077 #include <cob_sdh/TactileMatrix.h>
00078
00079
00080 #include <cob_srvs/Trigger.h>
00081 #include <cob_srvs/SetOperationMode.h>
00082
00083
00084 #include <diagnostic_updater/diagnostic_updater.h>
00085
00086
00087 #include <cob_sdh/sdh.h>
00088 #include <cob_sdh/dsa.h>
00089
00095 class SdhNode
00096 {
00097 public:
00099 ros::NodeHandle nh_;
00100 private:
00101
00102 ros::Publisher topicPub_JointState_;
00103 ros::Publisher topicPub_ControllerState_;
00104 ros::Publisher topicPub_TactileSensor_;
00105
00106
00107 ros::ServiceServer srvServer_Init_;
00108 ros::ServiceServer srvServer_Stop_;
00109 ros::ServiceServer srvServer_Recover_;
00110 ros::ServiceServer srvServer_SetOperationMode_;
00111
00112
00113 actionlib::SimpleActionServer<pr2_controllers_msgs::JointTrajectoryAction> as_;
00114 std::string action_name_;
00115
00116
00117
00118
00119
00120
00121
00122 diagnostic_updater::Updater updater_;
00123
00124
00125 SDH::cSDH *sdh_;
00126 SDH::cDSA *dsa_;
00127 std::vector<SDH::cSDH::eAxisState> state_;
00128
00129 std::string sdhdevicetype_;
00130 std::string sdhdevicestring_;
00131 int sdhdevicenum_;
00132 std::string dsadevicestring_;
00133 int dsadevicenum_;
00134 int baudrate_, id_read_, id_write_;
00135 double timeout_;
00136
00137 bool isInitialized_;
00138 bool isDSAInitialized_;
00139 int DOF_;
00140 double pi_;
00141
00142 trajectory_msgs::JointTrajectory traj_;
00143
00144 std::vector<std::string> JointNames_;
00145 std::vector<int> axes_;
00146 std::vector<double> targetAngles_;
00147 bool hasNewGoal_;
00148
00149 public:
00155 SdhNode(std::string name):
00156 as_(nh_, name, boost::bind(&SdhNode::executeCB, this, _1),true),
00157 action_name_(name)
00158 {
00159 pi_ = 3.1415926;
00160
00161 updater_.setHardwareID(ros::this_node::getName());
00162 updater_.add("initialization", this, &SdhNode::diag_init);
00163
00164 }
00165
00169 ~SdhNode()
00170 {
00171 if(isDSAInitialized_)
00172 dsa_->Close();
00173 if(isInitialized_)
00174 sdh_->Close();
00175 delete sdh_;
00176 }
00177
00178 void diag_init(diagnostic_updater::DiagnosticStatusWrapper &stat)
00179 {
00180 if(isInitialized_ && isDSAInitialized_)
00181 stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "");
00182 else
00183 stat.summary(diagnostic_msgs::DiagnosticStatus::WARN, "");
00184 stat.add("Hand initialized", isInitialized_);
00185 stat.add("Tactile iInitialized", isDSAInitialized_);
00186 }
00187
00191 bool init()
00192 {
00193
00194 isInitialized_ = false;
00195 isDSAInitialized_ = false;
00196 hasNewGoal_ = false;
00197
00198
00199 topicPub_JointState_ = nh_.advertise<sensor_msgs::JointState>("/joint_states", 1);
00200 topicPub_ControllerState_ = nh_.advertise<pr2_controllers_msgs::JointTrajectoryControllerState>("state", 1);
00201 topicPub_TactileSensor_ = nh_.advertise<cob_sdh::TactileSensor>("tactile_data", 1);
00202
00203
00204 sdh_ = new SDH::cSDH(false, false, 0);
00205
00206
00207 srvServer_Init_ = nh_.advertiseService("init", &SdhNode::srvCallback_Init, this);
00208 srvServer_Stop_ = nh_.advertiseService("stop", &SdhNode::srvCallback_Stop, this);
00209 srvServer_Recover_ = nh_.advertiseService("recover", &SdhNode::srvCallback_Recover, this);
00210 srvServer_SetOperationMode_ = nh_.advertiseService("set_operation_mode", &SdhNode::srvCallback_SetOperationMode, this);
00211
00212
00213 nh_.param("sdhdevicetype", sdhdevicetype_, std::string("PCAN"));
00214 nh_.param("sdhdevicestring", sdhdevicestring_, std::string("/dev/pcan0"));
00215 nh_.param("sdhdevicenum", sdhdevicenum_, 0);
00216
00217 nh_.param("dsadevicestring", dsadevicestring_, std::string("/dev/ttyS0"));
00218 nh_.param("dsadevicenum", dsadevicenum_, 0);
00219
00220 nh_.param("baudrate", baudrate_, 1000000);
00221 nh_.param("timeout", timeout_, (double)0.04);
00222 nh_.param("id_read", id_read_, 43);
00223 nh_.param("id_write", id_write_, 42);
00224
00225
00226 ROS_INFO("getting JointNames from parameter server");
00227 XmlRpc::XmlRpcValue JointNames_param;
00228 if (nh_.hasParam("JointNames"))
00229 {
00230 nh_.getParam("JointNames", JointNames_param);
00231 }
00232 else
00233 {
00234 ROS_ERROR("Parameter JointNames not set");
00235 return false;
00236 }
00237 DOF_ = JointNames_param.size();
00238 JointNames_.resize(DOF_);
00239 for (int i = 0; i<DOF_; i++ )
00240 {
00241 JointNames_[i] = (std::string)JointNames_param[i];
00242 }
00243 std::cout << "JointNames = " << JointNames_param << std::endl;
00244
00245
00246 axes_.resize(DOF_);
00247 for(int i=0; i<DOF_; i++)
00248 {
00249 axes_[i] = i;
00250 }
00251 ROS_INFO("DOF = %d",DOF_);
00252
00253 state_.resize(axes_.size());
00254
00255 return true;
00256 }
00257
00264 void executeCB(const pr2_controllers_msgs::JointTrajectoryGoalConstPtr &goal)
00265 {
00266 ROS_INFO("sdh: executeCB");
00267 if (!isInitialized_)
00268 {
00269 ROS_ERROR("%s: Rejected, sdh not initialized", action_name_.c_str());
00270 as_.setAborted();
00271 return;
00272 }
00273
00274 while (hasNewGoal_ == true ) usleep(10000);
00275
00276
00277 targetAngles_.resize(DOF_);
00278 targetAngles_[0] = goal->trajectory.points[0].positions[0]*180.0/pi_;
00279 targetAngles_[1] = goal->trajectory.points[0].positions[5]*180.0/pi_;
00280 targetAngles_[2] = goal->trajectory.points[0].positions[6]*180.0/pi_;
00281 targetAngles_[3] = goal->trajectory.points[0].positions[1]*180.0/pi_;
00282 targetAngles_[4] = goal->trajectory.points[0].positions[2]*180.0/pi_;
00283 targetAngles_[5] = goal->trajectory.points[0].positions[3]*180.0/pi_;
00284 targetAngles_[6] = goal->trajectory.points[0].positions[4]*180.0/pi_;
00285 ROS_INFO("received new 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,%f]",goal->trajectory.points[0].positions[0],goal->trajectory.points[0].positions[1],goal->trajectory.points[0].positions[2],goal->trajectory.points[0].positions[3],goal->trajectory.points[0].positions[4],goal->trajectory.points[0].positions[5],goal->trajectory.points[0].positions[6]);
00286
00287 hasNewGoal_ = true;
00288
00289 usleep(500000);
00290
00291 bool finished = false;
00292 while(finished == false)
00293 {
00294 if (as_.isNewGoalAvailable())
00295 {
00296 ROS_WARN("%s: Aborted", action_name_.c_str());
00297 as_.setAborted();
00298 return;
00299 }
00300 for ( size_t i = 0; i < state_.size(); i++ )
00301 {
00302 ROS_DEBUG("state[%d] = %d",i,state_[i]);
00303 if (state_[i] == 0)
00304 {
00305 finished = true;
00306 }
00307 else
00308 {
00309 finished = false;
00310 }
00311 }
00312 usleep(10000);
00313
00314
00315 }
00316
00317
00318 ROS_INFO("%s: Succeeded", action_name_.c_str());
00319
00320
00321
00322 as_.setSucceeded();
00323 }
00324
00332 bool srvCallback_Init( cob_srvs::Trigger::Request &req,
00333 cob_srvs::Trigger::Response &res )
00334 {
00335
00336 if (isInitialized_ == false)
00337 {
00338
00339
00340 try
00341 {
00342 if(sdhdevicetype_.compare("RS232")==0)
00343 {
00344 sdh_->OpenRS232( sdhdevicenum_, 115200, 1, sdhdevicestring_.c_str());
00345 ROS_INFO("Initialized RS232 for SDH");
00346 isInitialized_ = true;
00347 }
00348 if(sdhdevicetype_.compare("PCAN")==0)
00349 {
00350 ROS_INFO("Starting initializing PEAKCAN");
00351 sdh_->OpenCAN_PEAK(baudrate_, timeout_, id_read_, id_write_, sdhdevicestring_.c_str());
00352 ROS_INFO("Initialized PEAK CAN for SDH");
00353 isInitialized_ = true;
00354 }
00355 if(sdhdevicetype_.compare("ESD")==0)
00356 {
00357 ROS_INFO("Starting initializing ESD");
00358 if(strcmp(sdhdevicestring_.c_str(), "/dev/can0") == 0)
00359 {
00360 ROS_INFO("Initializing ESD on device %s",sdhdevicestring_.c_str());
00361 sdh_->OpenCAN_ESD(0, baudrate_, timeout_, id_read_, id_write_ );
00362 }
00363 else if(strcmp(sdhdevicestring_.c_str(), "/dev/can1") == 0)
00364 {
00365 ROS_INFO("Initializin ESD on device %s",sdhdevicestring_.c_str());
00366 sdh_->OpenCAN_ESD(1, baudrate_, timeout_, id_read_, id_write_ );
00367 }
00368 else
00369 {
00370 ROS_ERROR("Currently only support for /dev/can0 and /dev/can1");
00371 res.success.data = false;
00372 res.error_message.data = "Currently only support for /dev/can0 and /dev/can1";
00373 return true;
00374 }
00375 ROS_INFO("Initialized ESDCAN for SDH");
00376 isInitialized_ = true;
00377 }
00378 }
00379 catch (SDH::cSDHLibraryException* e)
00380 {
00381 ROS_ERROR("An exception was caught: %s", e->what());
00382 res.success.data = false;
00383 res.error_message.data = e->what();
00384 delete e;
00385 return true;
00386 }
00387
00388
00389 try
00390 {
00391 dsa_ = new SDH::cDSA(0, dsadevicenum_, dsadevicestring_.c_str());
00392
00393 dsa_->SetFramerate( 1, true );
00394 ROS_INFO("Initialized RS232 for DSA Tactile Sensors on device %s",dsadevicestring_.c_str());
00395
00396
00397
00398 isDSAInitialized_ = true;
00399 }
00400 catch (SDH::cSDHLibraryException* e)
00401 {
00402 isDSAInitialized_ = false;
00403 ROS_ERROR("An exception was caught: %s", e->what());
00404 res.success.data = false;
00405 res.error_message.data = e->what();
00406 delete e;
00407 return true;
00408 }
00409
00410 }
00411 else
00412 {
00413 ROS_WARN("...sdh already initialized...");
00414 res.success.data = true;
00415 res.error_message.data = "sdh already initialized";
00416 }
00417
00418 res.success.data = true;
00419 return true;
00420 }
00421
00429 bool srvCallback_Stop(cob_srvs::Trigger::Request &req,
00430 cob_srvs::Trigger::Response &res )
00431 {
00432 ROS_INFO("Stopping sdh");
00433
00434
00435 try
00436 {
00437 sdh_->Stop();
00438 }
00439 catch (SDH::cSDHLibraryException* e)
00440 {
00441 ROS_ERROR("An exception was caught: %s", e->what());
00442 delete e;
00443 }
00444
00445 ROS_INFO("Stopping sdh succesfull");
00446 res.success.data = true;
00447 return true;
00448 }
00449
00457 bool srvCallback_Recover(cob_srvs::Trigger::Request &req,
00458 cob_srvs::Trigger::Response &res )
00459 {
00460 ROS_WARN("Service recover not implemented yet");
00461 res.success.data = true;
00462 res.error_message.data = "Service recover not implemented yet";
00463 return true;
00464 }
00465
00473 bool srvCallback_SetOperationMode(cob_srvs::SetOperationMode::Request &req,
00474 cob_srvs::SetOperationMode::Response &res )
00475 {
00476 ROS_INFO("Set operation mode to [%s]", req.operation_mode.data.c_str());
00477 nh_.setParam("OperationMode", req.operation_mode.data.c_str());
00478 res.success.data = true;
00479 return true;
00480 }
00481
00487 void updateSdh()
00488 {
00489 ROS_DEBUG("updateJointState");
00490 updater_.update();
00491 if (isInitialized_ == true)
00492 {
00493 if (hasNewGoal_ == true)
00494 {
00495
00496 try
00497 {
00498 sdh_->Stop();
00499 }
00500 catch (SDH::cSDHLibraryException* e)
00501 {
00502 ROS_ERROR("An exception was caught: %s", e->what());
00503 delete e;
00504 }
00505
00506 std::string operationMode;
00507 nh_.getParam("OperationMode", operationMode);
00508 if (operationMode == "position")
00509 {
00510 ROS_DEBUG("moving sdh in position mode");
00511
00512 try
00513 {
00514 sdh_->SetAxisTargetAngle( axes_, targetAngles_ );
00515 sdh_->MoveHand(false);
00516 }
00517 catch (SDH::cSDHLibraryException* e)
00518 {
00519 ROS_ERROR("An exception was caught: %s", e->what());
00520 delete e;
00521 }
00522 }
00523 else if (operationMode == "velocity")
00524 {
00525 ROS_DEBUG("moving sdh in velocity mode");
00526
00527 ROS_WARN("Moving in velocity mode currently disabled");
00528 }
00529 else if (operationMode == "effort")
00530 {
00531 ROS_DEBUG("moving sdh in effort mode");
00532
00533 ROS_WARN("Moving in effort mode currently disabled");
00534 }
00535 else
00536 {
00537 ROS_ERROR("sdh neither in position nor in velocity nor in effort mode. OperationMode = [%s]", operationMode.c_str());
00538 }
00539
00540 hasNewGoal_ = false;
00541 }
00542
00543
00544 std::vector<double> actualAngles;
00545 try
00546 {
00547 actualAngles = sdh_->GetAxisActualAngle( axes_ );
00548 }
00549 catch (SDH::cSDHLibraryException* e)
00550 {
00551 ROS_ERROR("An exception was caught: %s", e->what());
00552 delete e;
00553 }
00554 std::vector<double> actualVelocities;
00555 try
00556 {
00557 actualVelocities = sdh_->GetAxisActualVelocity( axes_ );
00558 }
00559 catch (SDH::cSDHLibraryException* e)
00560 {
00561 ROS_ERROR("An exception was caught: %s", e->what());
00562 delete e;
00563 }
00564
00565 ROS_DEBUG("received %d angles from sdh",actualAngles.size());
00566
00567
00568 sensor_msgs::JointState msg;
00569 msg.header.stamp = ros::Time::now();
00570 msg.name.resize(DOF_);
00571 msg.position.resize(DOF_);
00572 msg.velocity.resize(DOF_);
00573
00574
00575 msg.name = JointNames_;
00576
00577
00578 msg.position[0] = actualAngles[0]*pi_/180.0;
00579 msg.position[1] = actualAngles[3]*pi_/180.0;
00580 msg.position[2] = actualAngles[4]*pi_/180.0;
00581 msg.position[3] = actualAngles[5]*pi_/180.0;
00582 msg.position[4] = actualAngles[6]*pi_/180.0;
00583 msg.position[5] = actualAngles[1]*pi_/180.0;
00584 msg.position[6] = actualAngles[2]*pi_/180.0;
00585
00586 msg.velocity[0] = actualVelocities[0]*pi_/180.0;
00587 msg.velocity[1] = actualVelocities[3]*pi_/180.0;
00588 msg.velocity[2] = actualVelocities[4]*pi_/180.0;
00589 msg.velocity[3] = actualVelocities[5]*pi_/180.0;
00590 msg.velocity[4] = actualVelocities[6]*pi_/180.0;
00591 msg.velocity[5] = actualVelocities[1]*pi_/180.0;
00592 msg.velocity[6] = actualVelocities[2]*pi_/180.0;
00593
00594
00595 topicPub_JointState_.publish(msg);
00596
00597
00598 state_ = sdh_->GetAxisActualState(axes_);
00599 }
00600 else
00601 {
00602 ROS_DEBUG("sdh not initialized");
00603 }
00604 }
00605
00611 void updateDsa()
00612 {
00613 ROS_DEBUG("updateTactileData");
00614
00615 if(isDSAInitialized_)
00616 {
00617
00618 for(int i=0; i<7; i++)
00619 {
00620 try
00621 {
00622
00623 dsa_->UpdateFrame();
00624 }
00625 catch (SDH::cSDHLibraryException* e)
00626 {
00627 ROS_ERROR("An exception was caught: %s", e->what());
00628 delete e;
00629 }
00630 }
00631
00632 cob_sdh::TactileSensor msg;
00633 msg.header.stamp = ros::Time::now();
00634 int m, x, y;
00635 msg.tactile_matrix.resize(dsa_->GetSensorInfo().nb_matrices);
00636 for ( m = 0; m < dsa_->GetSensorInfo().nb_matrices; m++ )
00637 {
00638 cob_sdh::TactileMatrix &tm = msg.tactile_matrix[m];
00639 tm.matrix_id = m;
00640 tm.cells_x = dsa_->GetMatrixInfo( m ).cells_x;
00641 tm.cells_y = dsa_->GetMatrixInfo( m ).cells_y;
00642 tm.tactile_array.resize(tm.cells_x * tm.cells_y);
00643 for ( y = 0; y < tm.cells_y; y++ )
00644 {
00645 for ( x = 0; x < tm.cells_x; x++ )
00646 tm.tactile_array[tm.cells_x*y + x] = dsa_->GetTexel( m, x, y );
00647 }
00648 }
00649
00650 topicPub_TactileSensor_.publish(msg);
00651 }
00652 }
00653 };
00654
00660 int main(int argc, char** argv)
00661 {
00662
00663 ros::init(argc, argv, "cob_sdh");
00664
00665 SdhNode sdh_node("joint_trajectory_action");
00666 if (!sdh_node.init()) return 0;
00667
00668 ROS_INFO("...sdh node running...");
00669
00670 sleep(1);
00671 ros::Rate loop_rate(5);
00672 while(sdh_node.nh_.ok())
00673 {
00674
00675 sdh_node.updateSdh();
00676
00677
00678 sdh_node.updateDsa();
00679
00680
00681 ros::spinOnce();
00682 loop_rate.sleep();
00683 }
00684
00685 return 0;
00686 }
00687