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 try
00162 {
00163 theta0_ = boost::lexical_cast<double>(theta0_str);
00164 }
00165 catch (boost::bad_lexical_cast &e)
00166 {
00167 ROS_ERROR("theta0 (%s) is not a float",theta0_str);
00168 return false;
00169 }
00170
00171 const char *phi0_str = j->Attribute("phi0");
00172 if (phi0_str == NULL)
00173 {
00174 phi0_ = 29.98717*M_PI/180.0;
00175 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: phi0, using default for PR2 alpha2.", joint_name);
00176 }
00177 else
00178 try
00179 {
00180 phi0_ = boost::lexical_cast<double>(phi0_str);
00181 }
00182 catch (boost::bad_lexical_cast &e)
00183 {
00184 ROS_ERROR("phi0 (%s) is not a float",phi0_str);
00185 return false;
00186 }
00187
00188 const char *t0_str = j->Attribute("t0");
00189 if (t0_str == NULL)
00190 {
00191 t0_ = -0.19543/1000.0;
00192 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: t0, using default for PR2 alpha2.", joint_name);
00193 }
00194 else
00195 try
00196 {
00197 t0_ = boost::lexical_cast<double>(t0_str);
00198 }
00199 catch (boost::bad_lexical_cast &e)
00200 {
00201 ROS_ERROR("t0 (%s) is not a float",t0_str);
00202 return false;
00203 }
00204
00205 const char *L0_str = j->Attribute("L0");
00206 if (L0_str == NULL)
00207 {
00208 L0_ = 34.70821/1000.0;
00209 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: L0, using default for PR2 alpha2.", joint_name);
00210 }
00211 else
00212 try
00213 {
00214 L0_ = boost::lexical_cast<double>(L0_str);
00215 }
00216 catch (boost::bad_lexical_cast &e)
00217 {
00218 ROS_ERROR("L0 (%s) is not a float",L0_str);
00219 return false;
00220 }
00221
00222 const char *h_str = j->Attribute("h");
00223 if (h_str == NULL)
00224 {
00225 h_ = 5.200/1000.0;
00226 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: h, using default for PR2 alpha2.", joint_name);
00227 }
00228 else
00229 try
00230 {
00231 h_ = boost::lexical_cast<double>(h_str);
00232 }
00233 catch (boost::bad_lexical_cast &e)
00234 {
00235 ROS_ERROR("h (%s) is not a float",h_str);
00236 return false;
00237 }
00238
00239 const char *a_str = j->Attribute("a");
00240 if (a_str == NULL)
00241 {
00242 a_ = 67.56801/1000.0;
00243 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: a, using default for PR2 alpha2.", joint_name);
00244 }
00245 else
00246 try
00247 {
00248 a_ = boost::lexical_cast<double>(a_str);
00249 }
00250 catch (boost::bad_lexical_cast &e)
00251 {
00252 ROS_ERROR("a (%s) is not a float",a_str);
00253 return false;
00254 }
00255
00256 const char *b_str = j->Attribute("b");
00257 if (b_str == NULL)
00258 {
00259 b_ = 48.97193/1000.0;
00260 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: b, using default for PR2 alpha2.", joint_name);
00261 }
00262 else
00263 try
00264 {
00265 b_ = boost::lexical_cast<double>(b_str);
00266 }
00267 catch (boost::bad_lexical_cast &e)
00268 {
00269 ROS_ERROR("b (%s) is not a float",b_str);
00270 return false;
00271 }
00272
00273 const char *r_str = j->Attribute("r");
00274 if (r_str == NULL)
00275 {
00276 r_ = 91.50000/1000.0;
00277 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: r, using default for PR2 alpha2.", joint_name);
00278 }
00279 else
00280 try
00281 {
00282 r_ = boost::lexical_cast<double>(r_str);
00283 }
00284 catch (boost::bad_lexical_cast &e)
00285 {
00286 ROS_ERROR("r (%s) is not a float",r_str);
00287 return false;
00288 }
00289 }
00290
00291
00292 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",
00293 name_.c_str(), a_, b_, r_, h_, L0_, t0_, theta0_, phi0_, gear_ratio_, screw_reduction_);
00294
00295
00296 for (TiXmlElement *j = config->FirstChildElement("passive_joint"); j; j = j->NextSiblingElement("passive_joint"))
00297 {
00298 const char *joint_name = j->Attribute("name");
00299 if (!joint_name)
00300 {
00301 ROS_ERROR("PR2GripperTransmission did not specify joint name");
00302 return false;
00303 }
00304 const boost::shared_ptr<const urdf::Joint> joint = robot->robot_model_.getJoint(joint_name);
00305
00306 if (!joint)
00307 {
00308 ROS_ERROR("PR2GripperTransmission could not find joint named \"%s\"", joint_name);
00309 return false;
00310 }
00311
00312
00313 joint_names_.push_back(joint_name);
00314 passive_joints_.push_back(joint_name);
00315 }
00316
00317
00318 for (TiXmlElement *j = config->FirstChildElement("simulated_actuated_joint"); j; j = j->NextSiblingElement("simulated_actuated_joint"))
00319 {
00320 const char *joint_name = j->Attribute("name");
00321 if (!joint_name)
00322 {
00323 ROS_ERROR("PR2GripperTransmission simulated_actuated_joint did snot specify joint name");
00324 use_simulated_actuated_joint_=false;
00325 }
00326 else
00327 {
00328 const boost::shared_ptr<const urdf::Joint> joint = robot->robot_model_.getJoint(joint_name);
00329 if (!joint)
00330 {
00331 ROS_ERROR("PR2GripperTransmission could not find joint named \"%s\"", joint_name);
00332 use_simulated_actuated_joint_=false;
00333 }
00334 else
00335 {
00336 use_simulated_actuated_joint_=true;
00337 joint_names_.push_back(joint_name);
00338
00339
00340 const char *simulated_reduction = j->Attribute("simulated_reduction");
00341 if (!simulated_reduction)
00342 {
00343 ROS_ERROR("PR2GripperTransmission's joint \"%s\" has no coefficient: simulated_reduction.", joint_name);
00344 return false;
00345 }
00346 try
00347 {
00348 simulated_reduction_ = boost::lexical_cast<double>(simulated_reduction);
00349 }
00350 catch (boost::bad_lexical_cast &e)
00351 {
00352 ROS_ERROR("simulated_reduction (%s) is not a float",simulated_reduction);
00353 return false;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362 const char *passive_actuated_joint_name = j->Attribute("passive_actuated_joint");
00363 if (passive_actuated_joint_name)
00364 {
00365 const boost::shared_ptr<const urdf::Joint> passive_actuated_joint = robot->robot_model_.getJoint(passive_actuated_joint_name);
00366 if (passive_actuated_joint)
00367 {
00368 has_simulated_passive_actuated_joint_ = true;
00369 joint_names_.push_back(passive_actuated_joint_name);
00370 }
00371 }
00372
00373 }
00374 }
00375 }
00376
00377
00378
00379 return true;
00380 }
00381
00382 bool PR2GripperTransmission::initXml(TiXmlElement *config)
00383 {
00384 const char *name = config->Attribute("name");
00385 name_ = name ? name : "";
00386
00387 TiXmlElement *ael = config->FirstChildElement("actuator");
00388 const char *actuator_name = ael ? ael->Attribute("name") : NULL;
00389 if (!actuator_name)
00390 {
00391 ROS_ERROR("PR2GripperTransmission could not find actuator named \"%s\"", actuator_name);
00392 return false;
00393 }
00394 actuator_names_.push_back(actuator_name);
00395
00396 for (TiXmlElement *j = config->FirstChildElement("gap_joint"); j; j = j->NextSiblingElement("gap_joint"))
00397 {
00398 const char *joint_name = j->Attribute("name");
00399 if (!joint_name)
00400 {
00401 ROS_ERROR("PR2GripperTransmission did not specify joint name");
00402 return false;
00403 }
00404 gap_joint_ = std::string(joint_name);
00405 joint_names_.push_back(joint_name);
00406
00407
00408 const char *joint_reduction = j->Attribute("mechanical_reduction");
00409 if (!joint_reduction)
00410 {
00411 ROS_ERROR("PR2GripperTransmission's joint \"%s\" has no coefficient: mechanical reduction.", joint_name);
00412 return false;
00413 }
00414 try
00415 {
00416 gap_mechanical_reduction_ = boost::lexical_cast<double>(joint_reduction);
00417 }
00418 catch (boost::bad_lexical_cast &e)
00419 {
00420 ROS_ERROR("joint_reduction (%s) is not a float",joint_reduction);
00421 return false;
00422 }
00423
00424
00425 const char *screw_reduction_str = j->Attribute("screw_reduction");
00426 if (screw_reduction_str == NULL)
00427 {
00428 screw_reduction_ = 2.0/1000.0;
00429 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: screw drive reduction, using default for PR2 alpha2.", joint_name);
00430 }
00431 else
00432 try
00433 {
00434 screw_reduction_ = boost::lexical_cast<double>(screw_reduction_str);
00435 }
00436 catch (boost::bad_lexical_cast &e)
00437 {
00438 ROS_ERROR("screw_reduction (%s) is not a float",screw_reduction_str);
00439 return false;
00440 }
00441
00442
00443
00444 const char *gear_ratio_str = j->Attribute("gear_ratio");
00445 if (gear_ratio_str == NULL)
00446 {
00447 gear_ratio_ = 29.16;
00448 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: gear_ratio, using default for PR2 alpha2.", joint_name);
00449 }
00450 else
00451 try
00452 {
00453 gear_ratio_ = boost::lexical_cast<double>(gear_ratio_str);
00454 }
00455 catch (boost::bad_lexical_cast &e)
00456 {
00457 ROS_ERROR("gear_ratio (%s) is not a float",gear_ratio_str);
00458 return false;
00459 }
00460
00461
00462
00463 const char *theta0_str = j->Attribute("theta0");
00464 if (theta0_str == NULL)
00465 {
00466 theta0_ = 2.97571*M_PI/180.0;
00467 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: theta0, using default for PR2 alpha2.", joint_name);
00468 }
00469 else
00470 try
00471 {
00472 theta0_ = boost::lexical_cast<double>(theta0_str);
00473 }
00474 catch (boost::bad_lexical_cast &e)
00475 {
00476 ROS_ERROR("theta0 (%s) is not a float",theta0_str);
00477 return false;
00478 }
00479
00480 const char *phi0_str = j->Attribute("phi0");
00481 if (phi0_str == NULL)
00482 {
00483 phi0_ = 29.98717*M_PI/180.0;
00484 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: phi0, using default for PR2 alpha2.", joint_name);
00485 }
00486 else
00487 try
00488 {
00489 phi0_ = boost::lexical_cast<double>(phi0_str);
00490 }
00491 catch (boost::bad_lexical_cast &e)
00492 {
00493 ROS_ERROR("phi0 (%s) is not a float",phi0_str);
00494 return false;
00495 }
00496
00497 const char *t0_str = j->Attribute("t0");
00498 if (t0_str == NULL)
00499 {
00500 t0_ = -0.19543/1000.0;
00501 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: t0, using default for PR2 alpha2.", joint_name);
00502 }
00503 else
00504 try
00505 {
00506 t0_ = boost::lexical_cast<double>(t0_str);
00507 }
00508 catch (boost::bad_lexical_cast &e)
00509 {
00510 ROS_ERROR("t0 (%s) is not a float",t0_str);
00511 return false;
00512 }
00513
00514 const char *L0_str = j->Attribute("L0");
00515 if (L0_str == NULL)
00516 {
00517 L0_ = 34.70821/1000.0;
00518 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: L0, using default for PR2 alpha2.", joint_name);
00519 }
00520 else
00521 try
00522 {
00523 L0_ = boost::lexical_cast<double>(L0_str);
00524 }
00525 catch (boost::bad_lexical_cast &e)
00526 {
00527 ROS_ERROR("L0 (%s) is not a float",L0_str);
00528 return false;
00529 }
00530
00531 const char *h_str = j->Attribute("h");
00532 if (h_str == NULL)
00533 {
00534 h_ = 5.200/1000.0;
00535 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: h, using default for PR2 alpha2.", joint_name);
00536 }
00537 else
00538 try
00539 {
00540 h_ = boost::lexical_cast<double>(h_str);
00541 }
00542 catch (boost::bad_lexical_cast &e)
00543 {
00544 ROS_ERROR("h (%s) is not a float",h_str);
00545 return false;
00546 }
00547
00548 const char *a_str = j->Attribute("a");
00549 if (a_str == NULL)
00550 {
00551 a_ = 67.56801/1000.0;
00552 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: a, using default for PR2 alpha2.", joint_name);
00553 }
00554 else
00555 try
00556 {
00557 a_ = boost::lexical_cast<double>(a_str);
00558 }
00559 catch (boost::bad_lexical_cast &e)
00560 {
00561 ROS_ERROR("a (%s) is not a float",a_str);
00562 return false;
00563 }
00564
00565 const char *b_str = j->Attribute("b");
00566 if (b_str == NULL)
00567 {
00568 b_ = 48.97193/1000.0;
00569 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: b, using default for PR2 alpha2.", joint_name);
00570 }
00571 else
00572 try
00573 {
00574 b_ = boost::lexical_cast<double>(b_str);
00575 }
00576 catch (boost::bad_lexical_cast &e)
00577 {
00578 ROS_ERROR("b (%s) is not a float",b_str);
00579 return false;
00580 }
00581
00582 const char *r_str = j->Attribute("r");
00583 if (r_str == NULL)
00584 {
00585 r_ = 91.50000/1000.0;
00586 ROS_WARN("PR2GripperTransmission's joint \"%s\" has no coefficient: r, using default for PR2 alpha2.", joint_name);
00587 }
00588 else
00589 try
00590 {
00591 r_ = boost::lexical_cast<double>(r_str);
00592 }
00593 catch (boost::bad_lexical_cast &e)
00594 {
00595 ROS_ERROR("r (%s) is not a float",r_str);
00596 return false;
00597 }
00598 }
00599
00600
00601 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",
00602 name_.c_str(), a_, b_, r_, h_, L0_, t0_, theta0_, phi0_, gear_ratio_, screw_reduction_);
00603
00604
00605 for (TiXmlElement *j = config->FirstChildElement("passive_joint"); j; j = j->NextSiblingElement("passive_joint"))
00606 {
00607 const char *joint_name = j->Attribute("name");
00608 if (!joint_name)
00609 {
00610 ROS_ERROR("PR2GripperTransmission did not specify joint name");
00611 return false;
00612 }
00613
00614
00615 joint_names_.push_back(joint_name);
00616 passive_joints_.push_back(joint_name);
00617 }
00618
00619
00620 for (TiXmlElement *j = config->FirstChildElement("simulated_actuated_joint"); j; j = j->NextSiblingElement("simulated_actuated_joint"))
00621 {
00622 const char *joint_name = j->Attribute("name");
00623 if (!joint_name)
00624 {
00625 ROS_ERROR("PR2GripperTransmission screw joint did not specify joint name");
00626 use_simulated_actuated_joint_=false;
00627 }
00628 else
00629 {
00630 use_simulated_actuated_joint_=true;
00631 joint_names_.push_back(joint_name);
00632
00633
00634 const char *simulated_reduction = j->Attribute("simulated_reduction");
00635 if (!simulated_reduction)
00636 {
00637 ROS_ERROR("PR2GripperTransmission's joint \"%s\" has no coefficient: simulated_reduction.", joint_name);
00638 return false;
00639 }
00640 try
00641 {
00642 simulated_reduction_ = boost::lexical_cast<double>(simulated_reduction);
00643 }
00644 catch (boost::bad_lexical_cast &e)
00645 {
00646 ROS_ERROR("simulated_reduction (%s) is not a float",simulated_reduction);
00647 return false;
00648 }
00649
00650
00651
00652
00653
00654
00655
00656 const char *passive_actuated_joint_name = j->Attribute("passive_actuated_joint");
00657 if (passive_actuated_joint_name)
00658 {
00659 has_simulated_passive_actuated_joint_ = true;
00660 joint_names_.push_back(passive_actuated_joint_name);
00661 }
00662
00663 }
00664 }
00665
00666
00667
00668 return true;
00669 }
00670
00673 void PR2GripperTransmission::computeGapStates(
00674 double MR,double MR_dot,double MT,
00675 double &theta,double &dtheta_dMR,double &dt_dtheta,double &dt_dMR,double &gap_size,double &gap_velocity,double &gap_effort)
00676 {
00677
00678
00679
00680 double u = (a_*a_+b_*b_-h_*h_
00681 -pow(L0_+MR*screw_reduction_/gear_ratio_,2))/(2.0*a_*b_);
00682 u = u < -1.0 ? -1.0 : u > 1.0 ? 1.0 : u;
00683 theta = theta0_ - phi0_ + acos(u);
00684
00685
00686
00687
00688
00689 gap_size = t0_ + r_ * ( sin(theta) - sin(theta0_) );
00690
00691
00692
00693
00694
00695 MR = MR >= 0.0 ? MR : 0.0;
00696
00697 u = (a_*a_+b_*b_-h_*h_
00698 -pow(L0_+MR*screw_reduction_/gear_ratio_,2))/(2.0*a_*b_);
00699 u = u < -1.0 ? -1.0 : u > 1.0 ? 1.0 : u;
00700 double tmp_theta = theta0_ - phi0_ + acos(u);
00701
00702
00703 double arg = 1.0 - pow(u,2);
00704 arg = arg > TOL ? arg : TOL;
00705
00706 double du_dMR = -(L0_ * screw_reduction_)/(gear_ratio_*a_*b_)
00707 -MR/(a_*b_)*pow(screw_reduction_/gear_ratio_,2);
00708
00709 dtheta_dMR = -1.0/sqrt(arg) * du_dMR;
00710
00711 dt_dtheta = r_ * cos( tmp_theta );
00712 dt_dMR = dt_dtheta * dtheta_dMR;
00713 gap_velocity = MR_dot * dt_dMR;
00714
00715
00716
00717
00718
00719
00720
00721
00722 gap_effort = MT / dt_dMR / RAD2MR ;
00723
00724 }
00725
00730 void PR2GripperTransmission::inverseGapStates(
00731 double gap_size,double &MR,double &dMR_dtheta,double &dtheta_dt,double &dMR_dt)
00732 {
00733
00734 double sin_theta = (gap_size - t0_)/r_ + sin(theta0_);
00735 sin_theta = sin_theta > 1.0 ? 1.0 : sin_theta < -1.0 ? -1.0 : sin_theta;
00736 double theta = asin(sin_theta);
00737
00738
00739 inverseGapStates1(theta,MR,dMR_dtheta,dtheta_dt,dMR_dt);
00740 }
00741
00746 void PR2GripperTransmission::inverseGapStates1(
00747 double theta,double &MR,double &dMR_dtheta,double &dtheta_dt,double &dMR_dt)
00748 {
00749
00750
00751
00752
00753
00754
00755 double arg = -2.0*a_*b_*cos(theta-theta0_+phi0_)
00756 -h_*h_+a_*a_+b_*b_;
00757 if (arg > 0.0)
00758 {
00759 MR = gear_ratio_/screw_reduction_ * ( sqrt(arg) - L0_ );
00760 dMR_dtheta = gear_ratio_/(2.0 * screw_reduction_) / sqrt(arg)
00761 * 2.0 * a_ * b_ * sin(theta + phi0_ - theta0_);
00762 }
00763 else
00764 {
00765 MR = gear_ratio_/screw_reduction_ * ( 0.0 - L0_ );
00766 dMR_dtheta = 0.0;
00767 }
00768
00769
00770 double gap_size = t0_ + r_ * ( sin(theta) - sin(theta0_) );
00771
00772
00773
00774
00775
00776 double tmp_dMR_dtheta = fabs(dMR_dtheta);
00777
00778 double u = (gap_size - t0_)/r_ + sin(theta0_);
00779 double arg2 = 1.0 - pow(u,2);
00780 arg2 = arg2 > TOL ? arg2 : TOL;
00781 dtheta_dt = 1.0 / sqrt( arg2 ) / r_;
00782 dMR_dt = tmp_dMR_dtheta * dtheta_dt;
00783 }
00784
00785
00789 void PR2GripperTransmission::propagatePosition(
00790 std::vector<Actuator*>& as, std::vector<JointState*>& js)
00791 {
00792
00793 ROS_ASSERT(as.size() == 1);
00794
00795 if (use_simulated_actuated_joint_ && has_simulated_passive_actuated_joint_)
00796 {ROS_ASSERT(js.size() == 1 + passive_joints_.size() + 2);}
00797 else if (use_simulated_actuated_joint_) {ROS_ASSERT(js.size() == 1 + passive_joints_.size() + 1);}
00798 else {ROS_ASSERT(js.size() == 1 + passive_joints_.size());}
00799
00803 double MR = as[0]->state_.position_ / gap_mechanical_reduction_ * RAD2MR ;
00804
00806 double MR_dot = as[0]->state_.velocity_ / gap_mechanical_reduction_ * RAD2MR ;
00807
00817
00818
00819
00821 double MT = as[0]->state_.last_measured_effort_ / gap_mechanical_reduction_;
00822
00824 double theta, dtheta_dMR, dt_dtheta, dt_dMR;
00826 double gap_size,gap_velocity,gap_effort;
00827
00828
00829 computeGapStates(MR,MR_dot,MT,theta,dtheta_dMR, dt_dtheta, dt_dMR,gap_size,gap_velocity,gap_effort);
00830
00831
00832 js[0]->position_ = gap_size*2.0;
00833 js[0]->velocity_ = gap_velocity*2.0;
00834 js[0]->measured_effort_ = gap_effort/2.0;
00835
00836
00837
00838
00839 for (size_t i = 1; i < passive_joints_.size()+1; ++i)
00840 {
00841 js[i]->position_ = theta - theta0_;
00842 js[i]->velocity_ = dtheta_dMR * MR_dot;
00843 js[i]->measured_effort_ = MT / dtheta_dMR / RAD2MR;
00844 js[i]->reference_position_ = MT / dtheta_dMR / RAD2MR;
00845 }
00846
00847 if (use_simulated_actuated_joint_)
00848 {
00849
00850 js[passive_joints_.size()+1]->position_ = 0.0;
00851 js[passive_joints_.size()+1]->velocity_ = 0.0;
00852 js[passive_joints_.size()+1]->measured_effort_ = 0.0;
00853 js[passive_joints_.size()+1]->reference_position_ = 0.0;
00854 js[passive_joints_.size()+1]->calibrated_ = true;
00855 }
00856 if (has_simulated_passive_actuated_joint_)
00857 {
00858
00859 js[passive_joints_.size()+2]->position_ = 0.0;
00860 js[passive_joints_.size()+2]->velocity_ = 0.0;
00861 js[passive_joints_.size()+2]->measured_effort_ = 0.0;
00862 js[passive_joints_.size()+2]->reference_position_ = 0.0;
00863 js[passive_joints_.size()+2]->calibrated_ = true;
00864 }
00865 }
00866
00867
00868 void PR2GripperTransmission::propagatePositionBackwards(
00869 std::vector<JointState*>& js, std::vector<Actuator*>& as)
00870 {
00871 ROS_ASSERT(as.size() == 1);
00872 if (use_simulated_actuated_joint_) {ROS_ASSERT(js.size() == 1 + passive_joints_.size() + 1);}
00873 else {ROS_ASSERT(js.size() == 1 + passive_joints_.size());}
00874
00875
00876 double MR,dMR_dtheta,dtheta_dt,dMR_dt;
00877 double joint_rate;
00878 {
00879
00880
00881 double gap_size = js[0]->position_/2.0;
00882
00883 inverseGapStates(gap_size,MR,dMR_dtheta,dtheta_dt,dMR_dt);
00884 double gap_rate = js[0]->velocity_/2.0;
00885 joint_rate = gap_rate * dtheta_dt;
00886 }
00887 double gap_effort = js[0]->commanded_effort_;
00888
00889
00890
00892 as[0]->state_.position_ = MR * gap_mechanical_reduction_ / RAD2MR ;
00893
00896 as[0]->state_.velocity_ = joint_rate * dMR_dtheta * gap_mechanical_reduction_ / RAD2MR ;
00897
00901 as[0]->state_.last_measured_effort_ = 2.0*gap_effort / dMR_dt * RAD2MR * gap_mechanical_reduction_;
00902
00903
00904 if (! simulated_actuator_timestamp_initialized_)
00905 {
00906
00907 as[0]->state_.sample_timestamp_ = ros::Duration(0);
00908
00909
00910 if (ros::isStarted())
00911 {
00912 simulated_actuator_start_time_ = ros::Time::now();
00913 simulated_actuator_timestamp_initialized_ = true;
00914 }
00915 }
00916 else
00917 {
00918
00919 as[0]->state_.sample_timestamp_ = ros::Time::now() - simulated_actuator_start_time_;
00920 }
00921
00922 as[0]->state_.timestamp_ = as[0]->state_.sample_timestamp_.toSec();
00923
00924
00925 this->joint_calibration_simulator_.simulateJointCalibration(js[0],as[0]);
00926 }
00927
00928 void PR2GripperTransmission::propagateEffort(
00929 std::vector<JointState*>& js, std::vector<Actuator*>& as)
00930 {
00931 ROS_ASSERT(as.size() == 1);
00932 if (use_simulated_actuated_joint_ && has_simulated_passive_actuated_joint_)
00933 {ROS_ASSERT(js.size() == 1 + passive_joints_.size() + 2);}
00934 else if (use_simulated_actuated_joint_) {ROS_ASSERT(js.size() == 1 + passive_joints_.size() + 1);}
00935 else {ROS_ASSERT(js.size() == 1 + passive_joints_.size());}
00936
00937
00938
00939
00940
00941
00942
00943 double gap_size = js[0]->position_/2.0;
00944
00945
00946 double MR,dMR_dtheta,dtheta_dt,dMR_dt;
00947
00948 inverseGapStates(gap_size,MR,dMR_dtheta,dtheta_dt,dMR_dt);
00949
00950 double gap_effort = js[0]->commanded_effort_;
00951
00952
00953
00955 as[0]->command_.enable_ = true;
00956 as[0]->command_.effort_ = 2.0*gap_effort / dMR_dt * RAD2MR * gap_mechanical_reduction_;
00957 }
00958
00959 void PR2GripperTransmission::propagateEffortBackwards(
00960 std::vector<Actuator*>& as, std::vector<JointState*>& js)
00961 {
00962 ROS_ASSERT(as.size() == 1);
00963 if (use_simulated_actuated_joint_) {ROS_ASSERT(js.size() == 1 + passive_joints_.size() + 1);}
00964 else {ROS_ASSERT(js.size() == 1 + passive_joints_.size());}
00965 ROS_ASSERT(simulated_reduction_>0.0);
00966
00967
00968
00969
00971 double MR = as[0]->state_.position_ / gap_mechanical_reduction_ * RAD2MR ;
00972 double MR_dot = as[0]->state_.velocity_ / gap_mechanical_reduction_ * RAD2MR ;
00973 double MT = as[0]->command_.effort_ / gap_mechanical_reduction_;
00974
00976 double theta, dtheta_dMR, dt_dtheta, dt_dMR;
00978 double gap_size,gap_velocity,gap_effort;
00979
00980
00981 computeGapStates(MR,MR_dot,MT,theta,dtheta_dMR, dt_dtheta, dt_dMR,gap_size,gap_velocity,gap_effort);
00982
00983 {
00984
00985
00986 if (use_simulated_actuated_joint_)
00987 {
00988
00989 js[passive_joints_.size()+1]->commanded_effort_ = gap_effort/simulated_reduction_;
00990 }
00991 else
00992 {
00993
00994 double eps=0.01;
00995 js[0]->commanded_effort_ = (1.0-eps)*js[0]->commanded_effort_ + eps*gap_effort/2.0;
00996 }
00997 }
00998 }
00999