00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include "pr2_mechanism_model/pr2_gripper_transmission.h"
00053 #include <pluginlib/class_list_macros.h>
00054 #include <algorithm>
00055 #include <numeric>
00056 #include <angles/angles.h>
00057 #include <boost/lexical_cast.hpp>
00058
00059 using namespace pr2_hardware_interface;
00060 using namespace pr2_mechanism_model;
00061
00062 PLUGINLIB_DECLARE_CLASS(pr2_mechanism_model, PR2GripperTransmission,
00063 pr2_mechanism_model::PR2GripperTransmission,
00064 pr2_mechanism_model::Transmission)
00065
00066 bool PR2GripperTransmission::initXml(TiXmlElement *config, Robot *robot)
00067 {
00068 const char *name = config->Attribute("name");
00069 name_ = name ? name : "";
00070
00071 TiXmlElement *ael = config->FirstChildElement("actuator");
00072 const char *actuator_name = ael ? ael->Attribute("name") : NULL;
00073 if (!actuator_name || !robot->getActuator(actuator_name))
00074 {
00075 ROS_ERROR("PR2GripperTransmission could not find actuator named \"%s\"", actuator_name);
00076 return false;
00077 }
00078 robot->getActuator(actuator_name)->command_.enable_ = true;
00079 actuator_names_.push_back(actuator_name);
00080
00081 for (TiXmlElement *j = config->FirstChildElement("gap_joint"); j; j = j->NextSiblingElement("gap_joint"))
00082 {
00083 const char *joint_name = j->Attribute("name");
00084 if (!joint_name)
00085 {
00086 ROS_ERROR("PR2GripperTransmission did not specify joint name");
00087 return false;
00088 }
00089
00090 const boost::shared_ptr<const urdf::Joint> joint = robot->robot_model_.getJoint(joint_name);
00091 if (!joint)
00092 {
00093 ROS_ERROR("PR2GripperTransmission could not find joint named \"%s\"", joint_name);
00094 return false;
00095 }
00096 gap_joint_ = std::string(joint_name);
00097 joint_names_.push_back(joint_name);
00098
00099
00100 const char *joint_reduction = j->Attribute("mechanical_reduction");
00101 if (!joint_reduction)
00102 {
00103 ROS_ERROR("PR2GripperTransmission's joint \"%s\" has no coefficient: mechanical reduction.", joint_name);
00104 return false;
00105 }
00106 try
00107 {
00108 gap_mechanical_reduction_ = boost::lexical_cast<double>(joint_reduction);
00109 }
00110 catch (boost::bad_lexical_cast &e)
00111 {
00112 ROS_ERROR("joint_reduction (%s) is not a float",joint_reduction);
00113 return false;
00114 }
00115
00116
00117 const char *screw_reduction_str = j->Attribute("screw_reduction");
00118 if (screw_reduction_str == NULL)
00119 {
00120 screw_reduction_ = 2.0/1000.0;
00121 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: screw drive reduction, using default for PR2 alpha2.", joint_name);
00122 }
00123 else
00124 try
00125 {
00126 screw_reduction_ = boost::lexical_cast<double>(screw_reduction_str);
00127 }
00128 catch (boost::bad_lexical_cast &e)
00129 {
00130 ROS_ERROR("screw_reduction (%s) is not a float",screw_reduction_str);
00131 return false;
00132 }
00133
00134
00135
00136 const char *gear_ratio_str = j->Attribute("gear_ratio");
00137 if (gear_ratio_str == NULL)
00138 {
00139 gear_ratio_ = 29.16;
00140 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: gear_ratio, using default for PR2 alpha2.", joint_name);
00141 }
00142 else
00143 try
00144 {
00145 gear_ratio_ = boost::lexical_cast<double>(gear_ratio_str);
00146 }
00147 catch (boost::bad_lexical_cast &e)
00148 {
00149 ROS_ERROR("gear_ratio (%s) is not a float",gear_ratio_str);
00150 return false;
00151 }
00152
00153
00154 const char *theta0_str = j->Attribute("theta0");
00155 if (theta0_str == NULL)
00156 {
00157 theta0_ = 2.97571*M_PI/180.0;
00158 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: theta0, using default for PR2 alpha2.", joint_name);
00159 }
00160 else
00161 theta0_ = atof(theta0_str);
00162 try
00163 {
00164 theta0_ = boost::lexical_cast<double>(theta0_str);
00165 }
00166 catch (boost::bad_lexical_cast &e)
00167 {
00168 ROS_ERROR("theta0 (%s) is not a float",theta0_str);
00169 return false;
00170 }
00171
00172 const char *phi0_str = j->Attribute("phi0");
00173 if (phi0_str == NULL)
00174 {
00175 phi0_ = 29.98717*M_PI/180.0;
00176 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: phi0, using default for PR2 alpha2.", joint_name);
00177 }
00178 else
00179 phi0_ = atof(phi0_str);
00180 try
00181 {
00182 phi0_ = boost::lexical_cast<double>(phi0_str);
00183 }
00184 catch (boost::bad_lexical_cast &e)
00185 {
00186 ROS_ERROR("phi0 (%s) is not a float",phi0_str);
00187 return false;
00188 }
00189
00190 const char *t0_str = j->Attribute("t0");
00191 if (t0_str == NULL)
00192 {
00193 t0_ = -0.19543/1000.0;
00194 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: t0, using default for PR2 alpha2.", joint_name);
00195 }
00196 else
00197 t0_ = atof(t0_str);
00198 try
00199 {
00200 t0_ = boost::lexical_cast<double>(t0_str);
00201 }
00202 catch (boost::bad_lexical_cast &e)
00203 {
00204 ROS_ERROR("t0 (%s) is not a float",t0_str);
00205 return false;
00206 }
00207
00208 const char *L0_str = j->Attribute("L0");
00209 if (L0_str == NULL)
00210 {
00211 L0_ = 34.70821/1000.0;
00212 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: L0, using default for PR2 alpha2.", joint_name);
00213 }
00214 else
00215 L0_ = atof(L0_str);
00216 try
00217 {
00218 L0_ = boost::lexical_cast<double>(L0_str);
00219 }
00220 catch (boost::bad_lexical_cast &e)
00221 {
00222 ROS_ERROR("L0 (%s) is not a float",L0_str);
00223 return false;
00224 }
00225
00226 const char *h_str = j->Attribute("h");
00227 if (h_str == NULL)
00228 {
00229 h_ = 5.200/1000.0;
00230 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: h, using default for PR2 alpha2.", joint_name);
00231 }
00232 else
00233 h_ = atof(h_str);
00234 try
00235 {
00236 h_ = boost::lexical_cast<double>(h_str);
00237 }
00238 catch (boost::bad_lexical_cast &e)
00239 {
00240 ROS_ERROR("h (%s) is not a float",h_str);
00241 return false;
00242 }
00243
00244 const char *a_str = j->Attribute("a");
00245 if (a_str == NULL)
00246 {
00247 a_ = 67.56801/1000.0;
00248 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: a, using default for PR2 alpha2.", joint_name);
00249 }
00250 else
00251 a_ = atof(a_str);
00252 try
00253 {
00254 a_ = boost::lexical_cast<double>(a_str);
00255 }
00256 catch (boost::bad_lexical_cast &e)
00257 {
00258 ROS_ERROR("a (%s) is not a float",a_str);
00259 return false;
00260 }
00261
00262 const char *b_str = j->Attribute("b");
00263 if (b_str == NULL)
00264 {
00265 b_ = 48.97193/1000.0;
00266 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: b, using default for PR2 alpha2.", joint_name);
00267 }
00268 else
00269 b_ = atof(b_str);
00270 try
00271 {
00272 b_ = boost::lexical_cast<double>(b_str);
00273 }
00274 catch (boost::bad_lexical_cast &e)
00275 {
00276 ROS_ERROR("b (%s) is not a float",b_str);
00277 return false;
00278 }
00279
00280 const char *r_str = j->Attribute("r");
00281 if (r_str == NULL)
00282 {
00283 r_ = 91.50000/1000.0;
00284 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: r, using default for PR2 alpha2.", joint_name);
00285 }
00286 else
00287 r_ = atof(r_str);
00288 try
00289 {
00290 r_ = boost::lexical_cast<double>(r_str);
00291 }
00292 catch (boost::bad_lexical_cast &e)
00293 {
00294 ROS_ERROR("r (%s) is not a float",r_str);
00295 return false;
00296 }
00297 }
00298
00299
00300 ROS_DEBUG("Gripper transmission parameters for %s: a=%f, b=%f, r=%f, h=%f, L0=%f, t0=%f, theta0=%f, phi0=%f, gear_ratio=%f, screw_red=%f",
00301 name_.c_str(), a_, b_, r_, h_, L0_, t0_, theta0_, phi0_, gear_ratio_, screw_reduction_);
00302
00303
00304 for (TiXmlElement *j = config->FirstChildElement("passive_joint"); j; j = j->NextSiblingElement("passive_joint"))
00305 {
00306 const char *joint_name = j->Attribute("name");
00307 if (!joint_name)
00308 {
00309 ROS_ERROR("PR2GripperTransmission did not specify joint name");
00310 return false;
00311 }
00312 const boost::shared_ptr<const urdf::Joint> joint = robot->robot_model_.getJoint(joint_name);
00313
00314 if (!joint)
00315 {
00316 ROS_ERROR("PR2GripperTransmission could not find joint named \"%s\"", joint_name);
00317 return false;
00318 }
00319
00320
00321 joint_names_.push_back(joint_name);
00322 passive_joints_.push_back(joint_name);
00323 }
00324
00325
00326 if (config->FirstChildElement("use_simulated_gripper_joint")) use_simulated_gripper_joint = true;
00327
00328 return true;
00329 }
00330
00331 bool PR2GripperTransmission::initXml(TiXmlElement *config)
00332 {
00333 const char *name = config->Attribute("name");
00334 name_ = name ? name : "";
00335
00336 TiXmlElement *ael = config->FirstChildElement("actuator");
00337 const char *actuator_name = ael ? ael->Attribute("name") : NULL;
00338 if (!actuator_name)
00339 {
00340 ROS_ERROR("PR2GripperTransmission could not find actuator named \"%s\"", actuator_name);
00341 return false;
00342 }
00343 actuator_names_.push_back(actuator_name);
00344
00345 for (TiXmlElement *j = config->FirstChildElement("gap_joint"); j; j = j->NextSiblingElement("gap_joint"))
00346 {
00347 const char *joint_name = j->Attribute("name");
00348 if (!joint_name)
00349 {
00350 ROS_ERROR("PR2GripperTransmission did not specify joint name");
00351 return false;
00352 }
00353 gap_joint_ = std::string(joint_name);
00354 joint_names_.push_back(joint_name);
00355
00356
00357 const char *joint_reduction = j->Attribute("mechanical_reduction");
00358 if (!joint_reduction)
00359 {
00360 ROS_ERROR("PR2GripperTransmission's joint \"%s\" has no coefficient: mechanical reduction.", joint_name);
00361 return false;
00362 }
00363 gap_mechanical_reduction_ = atof(joint_reduction);
00364
00365
00366 const char *screw_reduction_str = j->Attribute("screw_reduction");
00367 if (screw_reduction_str == NULL)
00368 {
00369 screw_reduction_ = 2.0/1000.0;
00370 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: screw drive reduction, using default for PR2 alpha2.", joint_name);
00371 }
00372 else
00373 screw_reduction_ = atof(screw_reduction_str);
00374
00375
00376
00377 const char *gear_ratio_str = j->Attribute("gear_ratio");
00378 if (gear_ratio_str == NULL)
00379 {
00380 gear_ratio_ = 29.16;
00381 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: gear_ratio, using default for PR2 alpha2.", joint_name);
00382 }
00383 else
00384 gear_ratio_ = atof(gear_ratio_str);
00385
00386
00387
00388 const char *theta0_str = j->Attribute("theta0");
00389 if (theta0_str == NULL)
00390 {
00391 theta0_ = 2.97571*M_PI/180.0;
00392 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: theta0, using default for PR2 alpha2.", joint_name);
00393 }
00394 else
00395 theta0_ = atof(theta0_str);
00396
00397 const char *phi0_str = j->Attribute("phi0");
00398 if (phi0_str == NULL)
00399 {
00400 phi0_ = 29.98717*M_PI/180.0;
00401 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: phi0, using default for PR2 alpha2.", joint_name);
00402 }
00403 else
00404 phi0_ = atof(phi0_str);
00405
00406 const char *t0_str = j->Attribute("t0");
00407 if (t0_str == NULL)
00408 {
00409 t0_ = -0.19543/1000.0;
00410 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: t0, using default for PR2 alpha2.", joint_name);
00411 }
00412 else
00413 t0_ = atof(t0_str);
00414
00415 const char *L0_str = j->Attribute("L0");
00416 if (L0_str == NULL)
00417 {
00418 L0_ = 34.70821/1000.0;
00419 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: L0, using default for PR2 alpha2.", joint_name);
00420 }
00421 else
00422 L0_ = atof(L0_str);
00423
00424 const char *h_str = j->Attribute("h");
00425 if (h_str == NULL)
00426 {
00427 h_ = 5.200/1000.0;
00428 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: h, using default for PR2 alpha2.", joint_name);
00429 }
00430 else
00431 h_ = atof(h_str);
00432
00433 const char *a_str = j->Attribute("a");
00434 if (a_str == NULL)
00435 {
00436 a_ = 67.56801/1000.0;
00437 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: a, using default for PR2 alpha2.", joint_name);
00438 }
00439 else
00440 a_ = atof(a_str);
00441
00442 const char *b_str = j->Attribute("b");
00443 if (b_str == NULL)
00444 {
00445 b_ = 48.97193/1000.0;
00446 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: b, using default for PR2 alpha2.", joint_name);
00447 }
00448 else
00449 b_ = atof(b_str);
00450
00451 const char *r_str = j->Attribute("r");
00452 if (r_str == NULL)
00453 {
00454 r_ = 91.50000/1000.0;
00455 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: r, using default for PR2 alpha2.", joint_name);
00456 }
00457 else
00458 r_ = atof(r_str);
00459 }
00460
00461
00462 ROS_DEBUG("Gripper transmission parameters for %s: a=%f, b=%f, r=%f, h=%f, L0=%f, t0=%f, theta0=%f, phi0=%f, gear_ratio=%f, screw_red=%f",
00463 name_.c_str(), a_, b_, r_, h_, L0_, t0_, theta0_, phi0_, gear_ratio_, screw_reduction_);
00464
00465
00466 for (TiXmlElement *j = config->FirstChildElement("passive_joint"); j; j = j->NextSiblingElement("passive_joint"))
00467 {
00468 const char *joint_name = j->Attribute("name");
00469 if (!joint_name)
00470 {
00471 ROS_ERROR("PR2GripperTransmission did not specify joint name");
00472 return false;
00473 }
00474
00475
00476 joint_names_.push_back(joint_name);
00477 passive_joints_.push_back(joint_name);
00478 }
00479
00480
00481 if (config->FirstChildElement("use_simulated_gripper_joint")) use_simulated_gripper_joint = true;
00482
00483 return true;
00484 }
00485
00488 void PR2GripperTransmission::computeGapStates(
00489 double MR,double MR_dot,double MT,
00490 double &theta,double &dtheta_dMR,double &dt_dtheta,double &dt_dMR,double &gap_size,double &gap_velocity,double &gap_effort)
00491 {
00492
00493
00494
00495 double u = (a_*a_+b_*b_-h_*h_
00496 -pow(L0_+MR*screw_reduction_/gear_ratio_,2))/(2.0*a_*b_);
00497 u = u < -1.0 ? -1.0 : u > 1.0 ? 1.0 : u;
00498 theta = theta0_ - phi0_ + acos(u);
00499
00500
00501
00502
00503
00504 gap_size = t0_ + r_ * ( sin(theta) - sin(theta0_) );
00505
00506
00507
00508
00509
00510 MR = MR >= 0.0 ? MR : 0.0;
00511
00512 u = (a_*a_+b_*b_-h_*h_
00513 -pow(L0_+MR*screw_reduction_/gear_ratio_,2))/(2.0*a_*b_);
00514 u = u < -1.0 ? -1.0 : u > 1.0 ? 1.0 : u;
00515 double tmp_theta = theta0_ - phi0_ + acos(u);
00516
00517
00518 double arg = 1.0 - pow(u,2);
00519 arg = arg > TOL ? arg : TOL;
00520
00521 double du_dMR = -(L0_ * screw_reduction_)/(gear_ratio_*a_*b_)
00522 -MR/(a_*b_)*pow(screw_reduction_/gear_ratio_,2);
00523
00524 dtheta_dMR = -1.0/sqrt(arg) * du_dMR;
00525
00526 dt_dtheta = r_ * cos( tmp_theta );
00527 dt_dMR = dt_dtheta * dtheta_dMR;
00528 gap_velocity = MR_dot * dt_dMR;
00529
00530
00531
00532
00533
00534
00535
00536
00537 gap_effort = MT / dt_dMR / RAD2MR ;
00538
00539 }
00540
00545 void PR2GripperTransmission::inverseGapStates(
00546 double theta,double &MR,double &dMR_dtheta,double &dtheta_dt,double &dMR_dt)
00547 {
00548
00549
00550
00551
00552
00553
00554 double arg = -2.0*a_*b_*cos(theta-theta0_+phi0_)
00555 -h_*h_+a_*a_+b_*b_;
00556 if (arg > 0.0)
00557 {
00558 MR = gear_ratio_/screw_reduction_ * ( sqrt(arg) - L0_ );
00559 dMR_dtheta = gear_ratio_/(2.0 * screw_reduction_) / sqrt(arg)
00560 * 2.0 * a_ * b_ * sin(theta + phi0_ - theta0_);
00561 }
00562 else
00563 {
00564 MR = gear_ratio_/screw_reduction_ * ( 0.0 - L0_ );
00565 dMR_dtheta = 0.0;
00566 }
00567
00568
00569 double gap_size = t0_ + r_ * ( sin(theta) - sin(theta0_) );
00570
00571
00572
00573
00574
00575 double tmp_dMR_dtheta = fabs(dMR_dtheta);
00576
00577 double u = (gap_size - t0_)/r_ + sin(theta0_);
00578 double arg2 = 1.0 - pow(u,2);
00579 arg2 = arg2 > TOL ? arg2 : TOL;
00580 dtheta_dt = 1.0 / sqrt( arg2 ) / r_;
00581 dMR_dt = tmp_dMR_dtheta * dtheta_dt;
00582 }
00583
00584 void PR2GripperTransmission::getRateFromMaxRateJoint(
00585 std::vector<JointState*>& js, std::vector<Actuator*>& as,
00586 int &max_rate_joint_index,double &rate)
00587 {
00588
00589
00590 double max_rate = -1.0;
00591 max_rate_joint_index = js.size();
00592
00593
00594
00595
00596 for (size_t i = 1; i < js.size(); ++i)
00597 {
00598 if (fabs(js[i]->velocity_) > max_rate)
00599 {
00600 max_rate = fabs(js[i]->velocity_);
00601 max_rate_joint_index = i;
00602
00603 }
00604 }
00605 if (max_rate_joint_index >= (int)js.size())
00606 ROS_ERROR("PR2 Gripper Transmission could not find a passive joint with minimum rate, mostly likely finger joints have exploded. js[0:4]->velocity_=(%f,%f,%f,%f,%f)",js[0]->velocity_,js[1]->velocity_,js[2]->velocity_,js[3]->velocity_,js[4]->velocity_);
00607
00608 rate = js[max_rate_joint_index]->velocity_;
00609 }
00610
00611
00615 void PR2GripperTransmission::propagatePosition(
00616 std::vector<Actuator*>& as, std::vector<JointState*>& js)
00617 {
00618
00619 ROS_ASSERT(as.size() == 1);
00620 ROS_ASSERT(js.size() == 1 + passive_joints_.size());
00621
00625 double MR = as[0]->state_.position_ / gap_mechanical_reduction_ * RAD2MR ;
00626
00628 double MR_dot = as[0]->state_.velocity_ / gap_mechanical_reduction_ * RAD2MR ;
00629
00639
00640
00641
00643 double MT = as[0]->state_.last_measured_effort_ / gap_mechanical_reduction_;
00644
00646 double theta, dtheta_dMR, dt_dtheta, dt_dMR;
00648 double gap_size,gap_velocity,gap_effort;
00649
00650
00651 computeGapStates(MR,MR_dot,MT,theta,dtheta_dMR, dt_dtheta, dt_dMR,gap_size,gap_velocity,gap_effort);
00652
00653
00654 js[0]->position_ = gap_size*2.0;
00655 js[0]->velocity_ = gap_velocity*2.0;
00656 js[0]->measured_effort_ = gap_effort/2.0;
00657
00658
00659
00660
00661 for (size_t i = 1; i < js.size(); ++i)
00662 {
00663 js[i]->position_ = theta - theta0_;
00664 js[i]->velocity_ = dtheta_dMR * MR_dot;
00665 js[i]->measured_effort_ = MT / dtheta_dMR / RAD2MR;
00666 }
00667 }
00668
00669
00670 void PR2GripperTransmission::propagatePositionBackwards(
00671 std::vector<JointState*>& js, std::vector<Actuator*>& as)
00672 {
00673 ROS_ASSERT(as.size() == 1);
00674 ROS_ASSERT(js.size() == 1 + passive_joints_.size());
00675
00676
00677 double MR,dMR_dtheta,dtheta_dt,dMR_dt;
00678 double joint_angle, joint_rate;
00679 if (use_simulated_gripper_joint)
00680 {
00681
00682
00683 double gap_size = js[0]->position_/2.0;
00684
00685 double sin_theta = (gap_size - t0_)/r_ + sin(theta0_);
00686 sin_theta = sin_theta > 1.0 ? 1.0 : sin_theta < -1.0 ? -1.0 : sin_theta;
00687 double theta = asin(sin_theta);
00688
00689
00690 inverseGapStates(theta,MR,dMR_dtheta,dtheta_dt,dMR_dt);
00691 double gap_rate = js[0]->velocity_/2.0;
00692 joint_rate = gap_rate * dtheta_dt;
00693 }
00694 else
00695 {
00696
00697 joint_angle = js[default_passive_joint_index_from_sim]->position_;
00698 joint_rate = js[default_passive_joint_index_from_sim]->velocity_;
00699
00700 double theta = angles::shortest_angular_distance(theta0_,joint_angle)+2.0*theta0_;
00701
00702 inverseGapStates(theta,MR,dMR_dtheta,dtheta_dt,dMR_dt);
00703 }
00704 double gap_effort = js[0]->commanded_effort_;
00705
00706
00707
00709 as[0]->state_.position_ = MR * gap_mechanical_reduction_ / RAD2MR ;
00710
00713 as[0]->state_.velocity_ = joint_rate * dMR_dtheta * gap_mechanical_reduction_ / RAD2MR ;
00714
00718 as[0]->state_.last_measured_effort_ = 2.0*gap_effort / dMR_dt * RAD2MR * gap_mechanical_reduction_;
00719
00720
00721 if (! simulated_actuator_timestamp_initialized_)
00722 {
00723
00724 as[0]->state_.sample_timestamp_ = ros::Duration(0);
00725
00726
00727 if (ros::isStarted())
00728 {
00729 simulated_actuator_start_time_ = ros::Time::now();
00730 simulated_actuator_timestamp_initialized_ = true;
00731 }
00732 }
00733 else
00734 {
00735
00736 as[0]->state_.sample_timestamp_ = ros::Time::now() - simulated_actuator_start_time_;
00737 }
00738
00739 as[0]->state_.timestamp_ = as[0]->state_.sample_timestamp_.toSec();
00740
00741
00742 this->joint_calibration_simulator_.simulateJointCalibration(js[0],as[0]);
00743 }
00744
00745 void PR2GripperTransmission::propagateEffort(
00746 std::vector<JointState*>& js, std::vector<Actuator*>& as)
00747 {
00748 ROS_ASSERT(as.size() == 1);
00749 ROS_ASSERT(js.size() == 1 + passive_joints_.size());
00750
00751
00752
00753
00754
00755
00756
00757 double joint_angle, joint_rate, joint_torque;
00758
00759 joint_angle = js[default_passive_joint_index_from_sim]->position_;
00760 joint_rate = js[default_passive_joint_index_from_sim]->velocity_;
00761 joint_torque = js[default_passive_joint_index_from_sim]->measured_effort_;
00762
00763
00764 double theta = angles::shortest_angular_distance(theta0_,joint_angle)+2.0*theta0_;
00765
00766
00767 double MR,dMR_dtheta,dtheta_dt,dMR_dt;
00768
00769 inverseGapStates(theta,MR,dMR_dtheta,dtheta_dt,dMR_dt);
00770
00771 double gap_effort = js[0]->commanded_effort_;
00772
00773
00774
00776 as[0]->command_.enable_ = true;
00777 as[0]->command_.effort_ = 2.0*gap_effort / dMR_dt * RAD2MR * gap_mechanical_reduction_;
00778 }
00779
00780 void PR2GripperTransmission::propagateEffortBackwards(
00781 std::vector<Actuator*>& as, std::vector<JointState*>& js)
00782 {
00783 ROS_ASSERT(as.size() == 1);
00784 ROS_ASSERT(js.size() == 1 + passive_joints_.size());
00785
00786
00787
00788
00790 double MR = as[0]->state_.position_ / gap_mechanical_reduction_ * RAD2MR ;
00791 double MR_dot = as[0]->state_.velocity_ / gap_mechanical_reduction_ * RAD2MR ;
00792 double MT = as[0]->command_.effort_ / gap_mechanical_reduction_;
00793
00795 double theta, dtheta_dMR, dt_dtheta, dt_dMR;
00797 double gap_size,gap_velocity,gap_effort;
00798
00799
00800 computeGapStates(MR,MR_dot,MT,theta,dtheta_dMR, dt_dtheta, dt_dMR,gap_size,gap_velocity,gap_effort);
00801
00802 if (use_simulated_gripper_joint)
00803 {
00804
00805 double eps=0.01;
00806 js[0]->commanded_effort_ = (1.0-eps)*js[0]->commanded_effort_ + eps*gap_effort/2.0;
00807
00808 }
00809 else
00810 for (size_t i = 1; i < js.size(); ++i)
00811 {
00812
00813
00814
00815
00816
00817
00818
00819 double joint_theta = angles::shortest_angular_distance(theta0_,js[i]->position_) + 2.0*theta0_;
00820
00821 double joint_MR,joint_dMR_dtheta,joint_dtheta_dt,joint_dMR_dt;
00822
00823 inverseGapStates(joint_theta,joint_MR,joint_dMR_dtheta,joint_dtheta_dt,joint_dMR_dt);
00824
00825
00826
00827
00828
00829 int max_joint_rate_index;
00830 double scale=1.0,rate_threshold=0.5;
00831 double max_joint_rate;
00832 getRateFromMaxRateJoint(js, as, max_joint_rate_index, max_joint_rate);
00833 if (fabs(max_joint_rate)>rate_threshold) scale /= pow(fabs(max_joint_rate/rate_threshold),2.0);
00834
00835
00836 double eps2=0.01;
00837 js[i]->commanded_effort_ = (1.0-eps2)*js[i]->commanded_effort_ + eps2*scale*MT / dtheta_dMR / RAD2MR /2.0;
00838
00839 }
00840 }
00841