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 #include <pr2_gazebo_plugins/gazebo_ros_controller_manager.h>
00031 #include <fstream>
00032 #include <iostream>
00033 #include <math.h>
00034 #include <unistd.h>
00035 #include <set>
00036 #include <gazebo/Global.hh>
00037 #include <gazebo/World.hh>
00038 #include <gazebo/PhysicsEngine.hh>
00039 #include <gazebo/XMLConfig.hh>
00040 #include <gazebo/Model.hh>
00041 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00042 #include <gazebo/Joint.hh>
00043 #else
00044 #include <gazebo/HingeJoint.hh>
00045 #include <gazebo/SliderJoint.hh>
00046 #endif
00047 #include <gazebo/Simulator.hh>
00048 #include <gazebo/gazebo.h>
00049 #include <angles/angles.h>
00050 #include <gazebo/GazeboError.hh>
00051 #include <gazebo/ControllerFactory.hh>
00052 #include <urdf/model.h>
00053 #include <map>
00054
00055 namespace gazebo {
00056
00057 GZ_REGISTER_DYNAMIC_CONTROLLER("gazebo_ros_controller_manager", GazeboRosControllerManager);
00058
00059 GazeboRosControllerManager::GazeboRosControllerManager(Entity *parent)
00060 : Controller(parent), hw_(), fake_calibration_(true)
00061 {
00062 this->parent_model_ = dynamic_cast<Model*>(this->parent);
00063
00064 if (!this->parent_model_)
00065 gzthrow("GazeboRosControllerManager controller requires a Model as its parent");
00066
00067 Param::Begin(&this->parameters);
00068 this->robotParamP = new ParamT<std::string>("robotParam", "robot_description", 0);
00069 this->robotNamespaceP = new ParamT<std::string>("robotNamespace", "/", 0);
00070 this->setModelsJointsStatesServiceNameP = new ParamT<std::string>("setModelsJointsStatesServiceName","set_models_joints_states", 0);
00071 Param::End();
00072
00073 if (getenv("CHECK_SPEEDUP"))
00074 {
00075 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00076 wall_start_ = Simulator::Instance()->GetWallTime().Double();
00077 sim_start_ = Simulator::Instance()->GetSimTime().Double();
00078 #else
00079 wall_start_ = Simulator::Instance()->GetWallTime();
00080 sim_start_ = Simulator::Instance()->GetSimTime();
00081 #endif
00082 }
00083
00084
00085
00086 if (this->updatePeriod > 0 &&
00087 (gazebo::World::Instance()->GetPhysicsEngine()->GetUpdateRate() > 1.0/this->updatePeriod))
00088 ROS_ERROR("gazebo_ros_force controller update rate is less than physics update rate, wrench applied will be diluted (applied intermittently)");
00089
00090
00091 }
00092
00094 bool setModelsJointsStates(pr2_gazebo_plugins::SetModelsJointsStates::Request &req,
00095 pr2_gazebo_plugins::SetModelsJointsStates::Response &res)
00096 {
00097
00098 return true;
00099 }
00100
00101
00102 GazeboRosControllerManager::~GazeboRosControllerManager()
00103 {
00104 delete this->robotParamP;
00105 delete this->robotNamespaceP;
00106 delete this->cm_;
00107 delete this->rosnode_;
00108
00109 if (this->fake_state_)
00110 {
00111
00112
00113 delete this->fake_state_;
00114 }
00115 }
00116
00117 void GazeboRosControllerManager::LoadChild(XMLConfigNode *node)
00118 {
00119
00120 this->robotParamP->Load(node);
00121 this->robotParam = this->robotParamP->GetValue();
00122 this->robotNamespaceP->Load(node);
00123 this->robotNamespace = this->robotNamespaceP->GetValue();
00124
00125 if (!ros::isInitialized())
00126 {
00127 int argc = 0;
00128 char** argv = NULL;
00129 ros::init(argc,argv,"gazebo",ros::init_options::NoSigintHandler|ros::init_options::AnonymousName);
00130 }
00131 this->rosnode_ = new ros::NodeHandle(this->robotNamespace);
00132 ROS_INFO("starting gazebo_ros_controller_manager plugin in ns: %s",this->robotNamespace.c_str());
00133
00134 this->cm_ = new pr2_controller_manager::ControllerManager(&hw_,*this->rosnode_);
00135
00136 this->rosnode_->param("gazebo/start_robot_calibrated",this->fake_calibration_,true);
00137
00138
00139
00140 ReadPr2Xml(node);
00141
00142
00143 this->fake_state_ = new pr2_mechanism_model::RobotState(&this->cm_->model_);
00144
00145
00146 if (this->cm_->state_ != NULL)
00147 {
00148 for (unsigned int i = 0; i < this->cm_->state_->joint_states_.size(); ++i)
00149 {
00150 std::string joint_name = this->cm_->state_->joint_states_[i].joint_->name;
00151
00152
00153 gazebo::Joint *joint = this->parent_model_->GetJoint(joint_name);
00154 if (joint)
00155 {
00156 this->joints_.push_back(joint);
00157 }
00158 else
00159 {
00160
00161 this->joints_.push_back(NULL);
00162 }
00163
00164 }
00165 }
00166
00167 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00168 this->hw_.current_time_ = ros::Time(Simulator::Instance()->GetSimTime().Double());
00169 #else
00170 this->hw_.current_time_ = ros::Time(Simulator::Instance()->GetSimTime());
00171 #endif
00172 }
00173
00174 void GazeboRosControllerManager::InitChild()
00175 {
00176 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00177 this->hw_.current_time_ = ros::Time(Simulator::Instance()->GetSimTime().Double());
00178 #else
00179 this->hw_.current_time_ = ros::Time(Simulator::Instance()->GetSimTime());
00180 #endif
00181 #ifdef USE_CBQ
00182
00183 this->controller_manager_callback_queue_thread_ = boost::thread( boost::bind( &GazeboRosControllerManager::ControllerManagerQueueThread,this ) );
00184 #endif
00185
00186
00187 this->ros_spinner_thread_ = boost::thread( boost::bind( &GazeboRosControllerManager::ControllerManagerROSThread,this ) );
00188
00189 }
00190
00191 void GazeboRosControllerManager::UpdateChild()
00192 {
00193 if (getenv("CHECK_SPEEDUP"))
00194 {
00195 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00196 double wall_elapsed = Simulator::Instance()->GetWallTime().Double() - wall_start_;
00197 double sim_elapsed = Simulator::Instance()->GetSimTime().Double() - sim_start_;
00198 #else
00199 double wall_elapsed = Simulator::Instance()->GetWallTime() - wall_start_;
00200 double sim_elapsed = Simulator::Instance()->GetSimTime() - sim_start_;
00201 #endif
00202 std::cout << " real time: " << wall_elapsed
00203 << " sim time: " << sim_elapsed
00204 << " speed up: " << sim_elapsed / wall_elapsed
00205 << std::endl;
00206 }
00207 assert(this->joints_.size() == this->fake_state_->joint_states_.size());
00208
00209
00210
00211
00212
00213
00214 for (unsigned int i = 0; i < this->joints_.size(); ++i)
00215 {
00216 if (!this->joints_[i])
00217 continue;
00218
00219 double damping_coef;
00220 if (this->cm_->state_->joint_states_[i].joint_->dynamics)
00221 damping_coef = this->cm_->state_->joint_states_[i].joint_->dynamics->damping;
00222 else
00223 damping_coef = 0;
00224
00225 this->fake_state_->joint_states_[i].measured_effort_ = this->fake_state_->joint_states_[i].commanded_effort_;
00226
00227 switch(this->joints_[i]->GetType())
00228 {
00229 case Joint::HINGE: {
00230 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00231 Joint *hj = this->joints_[i];
00232 this->fake_state_->joint_states_[i].position_ = this->fake_state_->joint_states_[i].position_ +
00233 angles::shortest_angular_distance(this->fake_state_->joint_states_[i].position_,hj->GetAngle(0).GetAsRadian());
00234 this->fake_state_->joint_states_[i].velocity_ = hj->GetVelocity(0);
00235 #else
00236 HingeJoint *hj = (HingeJoint*)this->joints_[i];
00237 this->fake_state_->joint_states_[i].position_ = this->fake_state_->joint_states_[i].position_ +
00238 angles::shortest_angular_distance(this->fake_state_->joint_states_[i].position_,hj->GetAngle());
00239 this->fake_state_->joint_states_[i].velocity_ = hj->GetAngleRate();
00240 #endif
00241 break;
00242 }
00243 case Joint::SLIDER: {
00244 static double torso_hack_damping_threshold = 1000.0;
00245 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00246 Joint *sj = this->joints_[i];
00247 if (damping_coef > torso_hack_damping_threshold)
00248 {
00249 this->fake_state_->joint_states_[i].position_ *= (1.0 - torso_hack_damping_threshold / damping_coef);
00250 this->fake_state_->joint_states_[i].position_ += (torso_hack_damping_threshold/damping_coef)*sj->GetAngle(0).GetAsRadian();
00251 this->fake_state_->joint_states_[i].velocity_ *= (1.0 - torso_hack_damping_threshold / damping_coef);
00252 this->fake_state_->joint_states_[i].velocity_ += (torso_hack_damping_threshold/damping_coef)*sj->GetVelocity(0);
00253 }
00254 else
00255 {
00256 this->fake_state_->joint_states_[i].position_ = sj->GetAngle(0).GetAsRadian();
00257 this->fake_state_->joint_states_[i].velocity_ = sj->GetVelocity(0);
00258 }
00259 break;
00260 #else
00261 SliderJoint *sj = (SliderJoint*)this->joints_[i];
00262 if (damping_coef > torso_hack_damping_threshold)
00263 {
00264 this->fake_state_->joint_states_[i].position_ *= (1.0 - torso_hack_damping_threshold / damping_coef);
00265 this->fake_state_->joint_states_[i].position_ += (torso_hack_damping_threshold/damping_coef)*sj->GetPosition();
00266 this->fake_state_->joint_states_[i].velocity_ *= (1.0 - torso_hack_damping_threshold / damping_coef);
00267 this->fake_state_->joint_states_[i].velocity_ += (torso_hack_damping_threshold/damping_coef)*sj->GetPositionRate();
00268 }
00269 else
00270 {
00271 this->fake_state_->joint_states_[i].position_ = sj->GetPosition();
00272 this->fake_state_->joint_states_[i].velocity_ = sj->GetPositionRate();
00273 }
00274 break;
00275 #endif
00276 }
00277 default:
00278 abort();
00279 }
00280 }
00281
00282
00283 this->fake_state_->propagateJointPositionToActuatorPosition();
00284
00285
00286
00287
00288 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00289 this->hw_.current_time_ = ros::Time(Simulator::Instance()->GetSimTime().Double());
00290 #else
00291 this->hw_.current_time_ = ros::Time(Simulator::Instance()->GetSimTime());
00292 #endif
00293 try
00294 {
00295 if (this->cm_->state_ != NULL)
00296 this->cm_->update();
00297 }
00298 catch (const char* c)
00299 {
00300 if (strcmp(c,"dividebyzero")==0)
00301 ROS_WARN("pid controller reports divide by zero error");
00302 else
00303 ROS_WARN("unknown const char* exception: %s", c);
00304 }
00305
00306
00307
00308
00309
00310
00311 this->fake_state_->propagateActuatorEffortToJointEffort();
00312
00313
00314 for (unsigned int i = 0; i < this->joints_.size(); ++i)
00315 {
00316 if (!this->joints_[i])
00317 continue;
00318
00319 double effort = this->fake_state_->joint_states_[i].commanded_effort_;
00320
00321 double damping_coef;
00322 if (this->cm_->state_ != NULL)
00323 {
00324 if (this->cm_->state_->joint_states_[i].joint_->dynamics)
00325 damping_coef = this->cm_->state_->joint_states_[i].joint_->dynamics->damping;
00326 else
00327 damping_coef = 0;
00328 }
00329
00330 switch (this->joints_[i]->GetType())
00331 {
00332 case Joint::HINGE: {
00333 #if GAZEBO_MAJOR_VERSION >= 0 && GAZEBO_MINOR_VERSION >= 10
00334 Joint *hj = this->joints_[i];
00335 #if GAZEBO_PATCH_VERSION >= 1
00336
00337 double effort_command = effort;
00338 #else
00339 double current_velocity = hj->GetVelocity(0);
00340 double damping_force = damping_coef * current_velocity;
00341 double effort_command = effort - damping_force;
00342 #endif
00343 hj->SetForce(0,effort_command);
00344 #else
00345 HingeJoint *hj = (HingeJoint*)this->joints_[i];
00346 #if GAZEBO_PATCH_VERSION >= 1
00347
00348 double effort_command = effort;
00349 #else
00350 double current_velocity = hj->GetAngleRate();
00351 double damping_force = damping_coef * current_velocity;
00352 double effort_command = effort - damping_force;
00353 #endif
00354 hj->SetTorque(effort_command);
00355 #endif
00356 break;
00357 }
00358 case Joint::SLIDER: {
00359 #if GAZEBO_MAJOR_VERSION == 0 && GAZEBO_MINOR_VERSION >= 10
00360 Joint *sj = this->joints_[i];
00361 #if GAZEBO_PATCH_VERSION >= 1
00362 double effort_command = effort;
00363 #else
00364 double current_velocity = sj->GetVelocity(0);
00365 double damping_force = damping_coef * current_velocity;
00366 double effort_command = effort-damping_force;
00367 #endif
00368 (this->joints_[i])->SetForce(0,effort_command);
00369 #else
00370 SliderJoint *sj = (SliderJoint*)this->joints_[i];
00371 #if GAZEBO_PATCH_VERSION >= 1
00372 double effort_command = effort;
00373 #else
00374 double current_velocity = sj->GetPositionRate();
00375 double damping_force = damping_coef * current_velocity;
00376 double effort_command = effort-damping_force;
00377 #endif
00378 sj->SetSliderForce(effort_command);
00379 #endif
00380 break;
00381 }
00382 default:
00383 abort();
00384 }
00385 }
00386 }
00387
00388 void GazeboRosControllerManager::FiniChild()
00389 {
00390 ROS_DEBUG("Calling FiniChild in GazeboRosControllerManager");
00391
00392
00393
00394
00395 this->cm_->~ControllerManager();
00396 this->rosnode_->shutdown();
00397 #ifdef USE_CBQ
00398 this->controller_manager_queue_.clear();
00399 this->controller_manager_queue_.disable();
00400 this->controller_manager_callback_queue_thread_.join();
00401 #endif
00402 this->ros_spinner_thread_.join();
00403 }
00404
00405 void GazeboRosControllerManager::ReadPr2Xml(XMLConfigNode *node)
00406 {
00407
00408 std::string urdf_param_name;
00409 std::string urdf_string;
00410
00411 while(urdf_string.empty())
00412 {
00413 ROS_DEBUG("gazebo controller manager plugin is waiting for urdf: %s on the param server.", this->robotParam.c_str());
00414 if (this->rosnode_->searchParam(this->robotParam,urdf_param_name))
00415 {
00416 this->rosnode_->getParam(urdf_param_name,urdf_string);
00417 ROS_DEBUG("found upstream\n%s\n------\n%s\n------\n%s",this->robotParam.c_str(),urdf_param_name.c_str(),urdf_string.c_str());
00418 }
00419 else
00420 {
00421 this->rosnode_->getParam(this->robotParam,urdf_string);
00422 ROS_DEBUG("found in node namespace\n%s\n------\n%s\n------\n%s",this->robotParam.c_str(),urdf_param_name.c_str(),urdf_string.c_str());
00423 }
00424 usleep(100000);
00425 }
00426 ROS_DEBUG("gazebo controller manager got pr2.xml from param server, parsing it...");
00427
00428
00429 TiXmlDocument doc;
00430 if (!doc.Parse(urdf_string.c_str()) && doc.Error())
00431 {
00432 ROS_ERROR("Could not load the gazebo controller manager plugin's configuration file: %s\n",
00433 urdf_string.c_str());
00434 }
00435 else
00436 {
00437
00438
00439
00440
00441 struct GetActuators : public TiXmlVisitor
00442 {
00443 std::set<std::string> actuators;
00444 virtual bool VisitEnter(const TiXmlElement &elt, const TiXmlAttribute *)
00445 {
00446 if (elt.ValueStr() == std::string("actuator") && elt.Attribute("name"))
00447 actuators.insert(elt.Attribute("name"));
00448 else if (elt.ValueStr() == std::string("rightActuator") && elt.Attribute("name"))
00449 actuators.insert(elt.Attribute("name"));
00450 else if (elt.ValueStr() == std::string("leftActuator") && elt.Attribute("name"))
00451 actuators.insert(elt.Attribute("name"));
00452 return true;
00453 }
00454 } get_actuators;
00455 doc.RootElement()->Accept(&get_actuators);
00456
00457
00458 std::set<std::string>::iterator it;
00459 for (it = get_actuators.actuators.begin(); it != get_actuators.actuators.end(); ++it)
00460 {
00461
00462 pr2_hardware_interface::Actuator* pr2_actuator = new pr2_hardware_interface::Actuator(*it);
00463 pr2_actuator->state_.is_enabled_ = true;
00464 this->hw_.addActuator(pr2_actuator);
00465 }
00466
00467
00468 this->cm_->initXml(doc.RootElement());
00469
00470 for (unsigned int i = 0; i < this->cm_->state_->joint_states_.size(); ++i)
00471 this->cm_->state_->joint_states_[i].calibrated_ = fake_calibration_;
00472 }
00473 }
00474
00475 #ifdef USE_CBQ
00476
00477
00478 void GazeboRosControllerManager::ControllerManagerQueueThread()
00479 {
00480 ROS_INFO_STREAM("Callback thread id=" << boost::this_thread::get_id());
00481
00482 static const double timeout = 0.01;
00483
00484 while (this->rosnode_->ok())
00485 {
00486 this->controller_manager_queue_.callAvailable(ros::WallDuration(timeout));
00487 }
00488 }
00489 #endif
00490
00491 void GazeboRosControllerManager::ControllerManagerROSThread()
00492 {
00493 ROS_INFO_STREAM("Callback thread id=" << boost::this_thread::get_id());
00494
00495
00496
00497 while (this->rosnode_->ok())
00498 {
00499
00500 usleep(1000);
00501 ros::spinOnce();
00502 }
00503 }
00504 }