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 #include <math.h>
00038 #include <pluginlib/class_list_macros.h>
00039 #include "pr2_mechanism_model/robot.h"
00040 #include "pr2_mechanism_model/simple_transmission.h"
00041
00042 using namespace pr2_mechanism_model;
00043 using namespace pr2_hardware_interface;
00044
00045 PLUGINLIB_DECLARE_CLASS(pr2_mechanism_model, SimpleTransmission,
00046 pr2_mechanism_model::SimpleTransmission,
00047 pr2_mechanism_model::Transmission)
00048
00049
00050 bool SimpleTransmission::initXml(TiXmlElement *elt, Robot *robot)
00051 {
00052 const char *name = elt->Attribute("name");
00053 name_ = name ? name : "";
00054
00055 TiXmlElement *jel = elt->FirstChildElement("joint");
00056 const char *joint_name = jel ? jel->Attribute("name") : NULL;
00057 if (!joint_name)
00058 {
00059 ROS_ERROR("SimpleTransmission did not specify joint name");
00060 return false;
00061 }
00062
00063 const boost::shared_ptr<const urdf::Joint> joint = robot->robot_model_.getJoint(joint_name);
00064 if (!joint)
00065 {
00066 ROS_ERROR("SimpleTransmission could not find joint named \"%s\"", joint_name);
00067 return false;
00068 }
00069 joint_names_.push_back(joint_name);
00070
00071 TiXmlElement *ael = elt->FirstChildElement("actuator");
00072 const char *actuator_name = ael ? ael->Attribute("name") : NULL;
00073 Actuator *a;
00074 if (!actuator_name || (a = robot->getActuator(actuator_name)) == NULL )
00075 {
00076 ROS_ERROR("SimpleTransmission could not find actuator named \"%s\"", actuator_name);
00077 return false;
00078 }
00079 a->command_.enable_ = true;
00080 actuator_names_.push_back(actuator_name);
00081
00082 mechanical_reduction_ = atof(elt->FirstChildElement("mechanicalReduction")->GetText());
00083
00084
00085 for (TiXmlElement *j = elt->FirstChildElement("simulated_actuated_joint"); j; j = j->NextSiblingElement("simulated_actuated_joint"))
00086 {
00087 const char *joint_name = j->Attribute("name");
00088 if (!joint_name)
00089 {
00090 ROS_ERROR("SimpleTransmission did not specify screw joint name");
00091 use_simulated_actuated_joint_=false;
00092 }
00093 else
00094 {
00095 const boost::shared_ptr<const urdf::Joint> joint = robot->robot_model_.getJoint(joint_name);
00096 if (!joint)
00097 {
00098 ROS_ERROR("SimpleTransmission could not find screw joint named \"%s\"", joint_name);
00099 use_simulated_actuated_joint_=false;
00100 }
00101 else
00102 {
00103 use_simulated_actuated_joint_=true;
00104 joint_names_.push_back(joint_name);
00105
00106
00107 const char *simulated_reduction = j->Attribute("simulated_reduction");
00108 if (!simulated_reduction)
00109 {
00110 ROS_ERROR("SimpleTransmission's joint \"%s\" has no coefficient: simulated_reduction.", joint_name);
00111 return false;
00112 }
00113 try
00114 {
00115 simulated_reduction_ = boost::lexical_cast<double>(simulated_reduction);
00116 }
00117 catch (boost::bad_lexical_cast &e)
00118 {
00119 ROS_ERROR("simulated_reduction (%s) is not a float",simulated_reduction);
00120 return false;
00121 }
00122 }
00123 }
00124 }
00125 return true;
00126 }
00127
00128 bool SimpleTransmission::initXml(TiXmlElement *elt)
00129 {
00130 const char *name = elt->Attribute("name");
00131 name_ = name ? name : "";
00132
00133 TiXmlElement *jel = elt->FirstChildElement("joint");
00134 const char *joint_name = jel ? jel->Attribute("name") : NULL;
00135 if (!joint_name)
00136 {
00137 ROS_ERROR("SimpleTransmission did not specify joint name");
00138 return false;
00139 }
00140 joint_names_.push_back(joint_name);
00141
00142 TiXmlElement *ael = elt->FirstChildElement("actuator");
00143 const char *actuator_name = ael ? ael->Attribute("name") : NULL;
00144 if (!actuator_name)
00145 {
00146 ROS_ERROR("SimpleTransmission could not find actuator named \"%s\"", actuator_name);
00147 return false;
00148 }
00149 actuator_names_.push_back(actuator_name);
00150
00151 mechanical_reduction_ = atof(elt->FirstChildElement("mechanicalReduction")->GetText());
00152
00153
00154 for (TiXmlElement *j = elt->FirstChildElement("simulated_actuated_joint"); j; j = j->NextSiblingElement("simulated_actuated_joint"))
00155 {
00156 const char *joint_name = j->Attribute("name");
00157 if (!joint_name)
00158 {
00159 ROS_ERROR("SimpleTransmission screw joint did not specify joint name");
00160 use_simulated_actuated_joint_=false;
00161 }
00162 else
00163 {
00164 use_simulated_actuated_joint_=true;
00165 joint_names_.push_back(joint_name);
00166
00167
00168 const char *simulated_reduction = j->Attribute("simulated_reduction");
00169 if (!simulated_reduction)
00170 {
00171 ROS_ERROR("SimpleTransmission's joint \"%s\" has no coefficient: simulated_reduction.", joint_name);
00172 return false;
00173 }
00174 try
00175 {
00176 simulated_reduction_ = boost::lexical_cast<double>(simulated_reduction);
00177 }
00178 catch (boost::bad_lexical_cast &e)
00179 {
00180 ROS_ERROR("simulated_reduction (%s) is not a float",simulated_reduction);
00181 return false;
00182 }
00183 }
00184 }
00185 return true;
00186 }
00187
00188 void SimpleTransmission::propagatePosition(
00189 std::vector<Actuator*>& as, std::vector<JointState*>& js)
00190 {
00191 assert(as.size() == 1);
00192 if (use_simulated_actuated_joint_) {assert(js.size() == 2);}
00193 else {assert(js.size() == 1);}
00194 js[0]->position_ = (as[0]->state_.position_ / mechanical_reduction_) + js[0]->reference_position_;
00195 js[0]->velocity_ = as[0]->state_.velocity_ / mechanical_reduction_;
00196 js[0]->measured_effort_ = as[0]->state_.last_measured_effort_ * mechanical_reduction_;
00197
00198 if (use_simulated_actuated_joint_)
00199 {
00200
00201 js[1]->position_ = 0;
00202 js[1]->velocity_ = 0;
00203 js[1]->measured_effort_ = 0;
00204 js[1]->reference_position_ = 0;
00205 js[1]->calibrated_ = true;
00206 }
00207 }
00208
00209 void SimpleTransmission::propagatePositionBackwards(
00210 std::vector<JointState*>& js, std::vector<Actuator*>& as)
00211 {
00212 assert(as.size() == 1);
00213 if (use_simulated_actuated_joint_) {assert(js.size() == 2);}
00214 else {assert(js.size() == 1);}
00215 as[0]->state_.position_ = (js[0]->position_ - js[0]->reference_position_) * mechanical_reduction_;
00216 as[0]->state_.velocity_ = js[0]->velocity_ * mechanical_reduction_;
00217 as[0]->state_.last_measured_effort_ = js[0]->measured_effort_ / mechanical_reduction_;
00218
00219
00220 if (! simulated_actuator_timestamp_initialized_)
00221 {
00222
00223 as[0]->state_.sample_timestamp_ = ros::Duration(0);
00224
00225
00226 if (ros::isStarted())
00227 {
00228 simulated_actuator_start_time_ = ros::Time::now();
00229 simulated_actuator_timestamp_initialized_ = true;
00230 }
00231 }
00232 else
00233 {
00234
00235 as[0]->state_.sample_timestamp_ = ros::Time::now() - simulated_actuator_start_time_;
00236 }
00237
00238 as[0]->state_.timestamp_ = as[0]->state_.sample_timestamp_.toSec();
00239
00240
00241 this->joint_calibration_simulator_.simulateJointCalibration(js[0],as[0]);
00242 }
00243
00244 void SimpleTransmission::propagateEffort(
00245 std::vector<JointState*>& js, std::vector<Actuator*>& as)
00246 {
00247 assert(as.size() == 1);
00248 if (use_simulated_actuated_joint_) {assert(js.size() == 2);}
00249 else {assert(js.size() == 1);}
00250 as[0]->command_.enable_ = true;
00251 as[0]->command_.effort_ = js[0]->commanded_effort_ / mechanical_reduction_;
00252 }
00253
00254 void SimpleTransmission::propagateEffortBackwards(
00255 std::vector<Actuator*>& as, std::vector<JointState*>& js)
00256 {
00257 assert(as.size() == 1);
00258 if (use_simulated_actuated_joint_) {assert(js.size() == 2);}
00259 else {assert(js.size() == 1);}
00260 if (use_simulated_actuated_joint_)
00261 {
00262
00263 js[1]->commanded_effort_ = as[0]->command_.effort_ * mechanical_reduction_/simulated_reduction_;
00264 }
00265 else
00266 js[0]->commanded_effort_ = as[0]->command_.effort_ * mechanical_reduction_;
00267 }
00268