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 <std_msgs/Float32MultiArray.h>
00073 #include <trajectory_msgs/JointTrajectory.h>
00074 #include <sensor_msgs/JointState.h>
00075
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
00084 #include <cob_srvs/Trigger.h>
00085 #include <cob_srvs/SetOperationMode.h>
00086
00087
00088 #include <diagnostic_msgs/DiagnosticArray.h>
00089
00090
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
00106 ros::Publisher topicPub_JointState_;
00107 ros::Publisher topicPub_ControllerState_;
00108 ros::Publisher topicPub_TactileSensor_;
00109 ros::Publisher topicPub_Diagnostics_;
00110
00111
00112 ros::Subscriber subSetVelocitiesRaw_;
00113 ros::Subscriber subSetVelocities_;
00114
00115
00116 ros::ServiceServer srvServer_Init_;
00117 ros::ServiceServer srvServer_Stop_;
00118 ros::ServiceServer srvServer_Recover_;
00119 ros::ServiceServer srvServer_SetOperationMode_;
00120
00121
00122
00123 actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> as_;
00124 std::string action_name_;
00125
00126
00127
00128
00129
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_;
00153 std::vector<double> velocities_;
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
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
00195 isInitialized_ = false;
00196 isDSAInitialized_ = false;
00197 hasNewGoal_ = false;
00198
00199
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
00205 sdh_ = new SDH::cSDH(false, false, 0);
00206
00207
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);
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
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
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
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
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_;
00304 targetAngles_[1] = goal->trajectory.points[0].positions[dict["sdh_finger_22_joint"]]*180.0/pi_;
00305 targetAngles_[2] = goal->trajectory.points[0].positions[dict["sdh_finger_23_joint"]]*180.0/pi_;
00306 targetAngles_[3] = goal->trajectory.points[0].positions[dict["sdh_thumb_2_joint"]]*180.0/pi_;
00307 targetAngles_[4] = goal->trajectory.points[0].positions[dict["sdh_thumb_3_joint"]]*180.0/pi_;
00308 targetAngles_[5] = goal->trajectory.points[0].positions[dict["sdh_finger_12_joint"]]*180.0/pi_;
00309 targetAngles_[6] = goal->trajectory.points[0].positions[dict["sdh_finger_13_joint"]]*180.0/pi_;
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);
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
00339
00340 }
00341
00342
00343 ROS_INFO("%s: Succeeded", action_name_.c_str());
00344
00345
00346
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
00368 while (hasNewGoal_ == true ) usleep(10000);
00369
00370 velocities_[0] = velocities->data[0] * 180.0 / pi_;
00371 velocities_[1] = velocities->data[5] * 180.0 / pi_;
00372 velocities_[2] = velocities->data[6] * 180.0 / pi_;
00373 velocities_[3] = velocities->data[1] * 180.0 / pi_;
00374 velocities_[4] = velocities->data[2] * 180.0 / pi_;
00375 velocities_[5] = velocities->data[3] * 180.0 / pi_;
00376 velocities_[6] = velocities->data[4] * 180.0 / pi_;
00377
00378 hasNewGoal_ = true;
00379 }
00380 bool parseDegFromJointValue(const brics_actuator::JointValue& val, double °_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
00410 while (hasNewGoal_ == true ) usleep(10000);
00411 bool valid = true;
00412
00413 valid = valid && parseDegFromJointValue(msg->velocities[0], velocities_[0]);
00414 valid = valid && parseDegFromJointValue(msg->velocities[5], velocities_[1]);
00415 valid = valid && parseDegFromJointValue(msg->velocities[6], velocities_[2]);
00416 valid = valid && parseDegFromJointValue(msg->velocities[1], velocities_[3]);
00417 valid = valid && parseDegFromJointValue(msg->velocities[2], velocities_[4]);
00418 valid = valid && parseDegFromJointValue(msg->velocities[3], velocities_[5]);
00419 valid = valid && parseDegFromJointValue(msg->velocities[4], velocities_[6]);
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
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
00487 if(!dsadevicestring_.empty()) {
00488 try
00489 {
00490 dsa_ = new SDH::cDSA(0, dsadevicenum_, dsadevicestring_.c_str());
00491
00492 dsa_->SetFramerate( 1, true );
00493 ROS_INFO("Initialized RS232 for DSA Tactile Sensors on device %s",dsadevicestring_.c_str());
00494
00495
00496
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
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
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
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
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
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
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
00698 msg.name = joint_names_;
00699
00700
00701 msg.position[0] = actualAngles[0]*pi_/180.0;
00702 msg.position[1] = actualAngles[3]*pi_/180.0;
00703 msg.position[2] = actualAngles[4]*pi_/180.0;
00704 msg.position[3] = actualAngles[5]*pi_/180.0;
00705 msg.position[4] = actualAngles[6]*pi_/180.0;
00706 msg.position[5] = actualAngles[1]*pi_/180.0;
00707 msg.position[6] = actualAngles[2]*pi_/180.0;
00708
00709 msg.velocity[0] = actualVelocities[0]*pi_/180.0;
00710 msg.velocity[1] = actualVelocities[3]*pi_/180.0;
00711 msg.velocity[2] = actualVelocities[4]*pi_/180.0;
00712 msg.velocity[3] = actualVelocities[5]*pi_/180.0;
00713 msg.velocity[4] = actualVelocities[6]*pi_/180.0;
00714 msg.velocity[5] = actualVelocities[1]*pi_/180.0;
00715 msg.velocity[6] = actualVelocities[2]*pi_/180.0;
00716
00717 topicPub_JointState_.publish(msg);
00718
00719
00720
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];
00728 mimicjointmsg.velocity[0] = msg.velocity[0];
00729 topicPub_JointState_.publish(mimicjointmsg);
00730
00731
00732
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
00743 controllermsg.joint_names = joint_names_;
00744
00745
00746 if (targetAngles_.size() != 0)
00747 {
00748 controllermsg.desired.positions[0] = targetAngles_[0]*pi_/180.0;
00749 controllermsg.desired.positions[1] = targetAngles_[3]*pi_/180.0;
00750 controllermsg.desired.positions[2] = targetAngles_[4]*pi_/180.0;
00751 controllermsg.desired.positions[3] = targetAngles_[5]*pi_/180.0;
00752 controllermsg.desired.positions[4] = targetAngles_[6]*pi_/180.0;
00753 controllermsg.desired.positions[5] = targetAngles_[1]*pi_/180.0;
00754 controllermsg.desired.positions[6] = targetAngles_[2]*pi_/180.0;
00755 }
00756
00757
00758
00759 controllermsg.actual.positions = msg.position;
00760
00761 controllermsg.actual.velocities = msg.velocity;
00762
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
00769 topicPub_ControllerState_.publish(controllermsg);
00770
00771
00772 state_ = sdh_->GetAxisActualState(axes_);
00773 }
00774 else
00775 {
00776 ROS_DEBUG("sdh not initialized");
00777 }
00778
00779 diagnostic_msgs::DiagnosticArray diagnostics;
00780 diagnostics.status.resize(1);
00781
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();
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();
00803 diagnostics.status[0].message = "sdh not initialized";
00804 }
00805 }
00806
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 };
00819 ROS_DEBUG("updateTactileData");
00820
00821 if(isDSAInitialized_)
00822 {
00823
00824 for(int i=0; i<7; i++)
00825 {
00826 try
00827 {
00828
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
00857 topicPub_TactileSensor_.publish(msg);
00858 }
00859 }
00860 };
00861
00867 int main(int argc, char** argv)
00868 {
00869
00870 ros::init(argc, argv, "schunk_sdh");
00871
00872
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;
00886 ROS_WARN("Parameter frequency not available, setting to default value: %f Hz", frequency);
00887 }
00888
00889
00890 ros::Rate loop_rate(frequency);
00891 while(sdh_node.nh_.ok())
00892 {
00893
00894 sdh_node.updateSdh();
00895
00896
00897 sdh_node.updateDsa();
00898
00899
00900 ros::spinOnce();
00901 loop_rate.sleep();
00902 }
00903
00904 return 0;
00905 }
00906