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 #include <limits>
00035
00036 #include <gazebo/Global.hh>
00037 #include <gazebo/XMLConfig.hh>
00038 #include <gazebo/Simulator.hh>
00039 #include <gazebo/gazebo.h>
00040 #include <gazebo/GazeboError.hh>
00041 #include <gazebo/ControllerFactory.hh>
00042
00043 #include <angles/angles.h>
00044 #include <urdf/model.h>
00045
00046 #include <actuator_array_gazebo_plugin/gazebo_ros_actuator_array.h>
00047
00048 namespace gazebo
00049 {
00050
00051 GZ_REGISTER_DYNAMIC_CONTROLLER("gazebo_ros_actuator_array", GazeboRosActuatorArray);
00052
00054
00055 GazeboRosActuatorArray::GazeboRosActuatorArray(Entity *parent) :
00056 Controller(parent)
00057 {
00058 this->myParent = dynamic_cast<Model*> (this->parent);
00059
00060 if (!this->myParent)
00061 gzthrow("GazeboRosActuatorArray controller requires a Model as its parent");
00062
00063 Param::Begin(&this->parameters);
00064 this->robotNamespaceP = new ParamT<std::string> ("robotNamespace", "/", 0);
00065 this->robotParamP = new ParamT<std::string> ("robotParam", "robot_description", 1);
00066 Param::End();
00067 }
00068
00070
00071 GazeboRosActuatorArray::~GazeboRosActuatorArray()
00072 {
00073 delete this->robotNamespaceP;
00074 delete this->robotParamP;
00075 }
00076
00078
00079 void GazeboRosActuatorArray::LoadChild(XMLConfigNode *node)
00080 {
00081 this->robotNamespaceP->Load(node);
00082 this->robot_namespace_ = this->robotNamespaceP->GetValue();
00083 this->robotParamP->Load(node);
00084 this->robot_description_parameter_ = this->robotParamP->GetValue();
00085
00086 int argc = 0;
00087 char** argv = NULL;
00088 ros::init(argc, argv, "gazebo", ros::init_options::NoSigintHandler | ros::init_options::AnonymousName);
00089 ros::NodeHandle ros_node = ros::NodeHandle(this->robot_namespace_);
00090
00091
00092
00093
00094 std::string joint_name;
00095 unsigned int joint_index = 0;
00096 double kp, ki, kd, imax, imin;
00097 gazebo::XMLConfigNode *child_node;
00098 child_node = node->GetChild("joint");
00099 while (child_node)
00100 {
00101 joint_name = child_node->GetString("name", "", 1);
00102 kp = child_node->GetDouble("p", 1.0, 0);
00103 ki = child_node->GetDouble("i", 0.0, 0);
00104 kd = child_node->GetDouble("d", 0.0, 0);
00105 imax = child_node->GetDouble("iClamp", 0.0, 0);
00106 imin = -imax;
00107
00108
00109 if (dynamic_cast<gazebo::Joint*> (this->myParent->GetJoint(joint_name)) == NULL)
00110 {
00111 ROS_FATAL("GazeboRosActuatorArray plugin error: joint: %s does not exist\n", joint_name.c_str());
00112 }
00113 else
00114 {
00115 GazeboJointProperties joint;
00116 joint.joint_index = joint_index++;
00117 joint.joint_ptr = dynamic_cast<gazebo::Joint*> (this->myParent->GetJoint(joint_name));
00118 joint.pid.initPid(kp, ki, kd, imax, imin);
00119 joint.position = 0.0;
00120 joint.home_position = child_node->GetDouble("home", 0.0, 0);
00121
00122
00123 this->joints_[joint_name] = joint;
00124 }
00125
00126 child_node = child_node->GetNext("joint");
00127 }
00128
00129
00130 parse_urdf(ros_node);
00131
00132
00133 unsigned int joint_count = this->joints_.size();
00134 this->joint_state_msg_.name.resize(joint_count);
00135 this->joint_state_msg_.position.resize(joint_count);
00136 this->joint_state_msg_.velocity.resize(joint_count);
00137 this->joint_state_msg_.effort.resize(joint_count);
00138 this->command_msg_.name.resize(joint_count);
00139 this->command_msg_.position.resize(joint_count);
00140 this->command_msg_.velocity.resize(joint_count);
00141 this->command_msg_.effort.resize(joint_count);
00142 for(std::map<std::string, GazeboJointProperties>::iterator joint = joints_.begin(); joint != joints_.end(); ++joint)
00143 {
00144 const std::string& joint_name = joint->first;
00145 GazeboJointProperties& joint_properties = joint->second;
00146
00147
00148 update_joint_from_urdf(joint_name, joint_properties);
00149
00150
00151 this->command_msg_.position[joint_properties.joint_index] = joint_properties.home_position;
00152
00153
00154 this->joint_state_msg_.name[joint_properties.joint_index] = joint_name;
00155 this->command_msg_.name[joint_properties.joint_index] = joint_name;
00156 }
00157
00158
00159 parse_mimic_joints(ros_node);
00160
00161
00162
00163
00164 #ifdef USE_CBQ
00165
00166
00167 ros::SubscribeOptions so = ros::SubscribeOptions::create<sensor_msgs::JointState>("command", 1,
00168 boost::bind(&GazeboRosActuatorArray::command_callback, this, _1),
00169 ros::VoidPtr(), &this->queue_);
00170 this->command_sub_ = ros_node.subscribe(so);
00171
00172
00173 ros::AdvertiseServiceOptions stop_aso = ros::AdvertiseServiceOptions::create<std_srvs::Empty>("stop",
00174 boost::bind(&GazeboRosActuatorArray::stop_callback, this, _1, _2),
00175 ros::VoidPtr(), &this->queue_);
00176 this->stop_srv_ = ros_node.advertiseService(stop_aso);
00177
00178
00179 ros::AdvertiseServiceOptions home_aso = ros::AdvertiseServiceOptions::create<std_srvs::Empty>("home",
00180 boost::bind(&GazeboRosActuatorArray::home_callback, this, _1, _2),
00181 ros::VoidPtr(), &this->queue_);
00182 this->home_srv_ = ros_node.advertiseService(home_aso);
00183
00184
00185 ros::AdvertiseOptions joint_state_ao = ros::AdvertiseOptions::create<sensor_msgs::JointState>("joint_states", 1,
00186 ros::SubscriberStatusCallback(),
00187 ros::SubscriberStatusCallback(),
00188 ros::VoidPtr(), &this->queue_);
00189 this->joint_state_pub_ = ros_node.advertise(joint_state_ao);
00190
00191 #else
00192 this->command_sub_ = ros_node.subscribe<sensor_msgs::JointState>("command", 1, boost::bind(&GazeboRosActuatorArray::command_callback, this, _1));
00193 this->stop_srv_ = ros_node.advertiseService<std_srvs::Empty>("stop", boost::bind(&GazeboRosActuatorArray::stop_callback, this, _1, _2));
00194 this->home_srv_ = ros_node.advertiseService<std_srvs::Empty>("home", boost::bind(&GazeboRosActuatorArray::home_callback, this, _1, _2));
00195 this->joint_state_pub_ = ros_node.advertise<sensor_msgs::JointState>("joint_states", 1);
00196 #endif
00197
00198 }
00199
00201
00202 void GazeboRosActuatorArray::InitChild()
00203 {
00204
00205 this->last_time_ = Simulator::Instance()->GetSimTime();
00206
00207 #ifdef USE_CBQ
00208
00209 this->callback_queue_thread_ = boost::thread(boost::bind(&GazeboRosActuatorArray::QueueThread, this));
00210 #endif
00211 }
00212
00214
00215 void GazeboRosActuatorArray::UpdateChild()
00216 {
00217
00218 gazebo::Time current_time = Simulator::Instance()->GetSimTime();
00219 double dt = (current_time - this->last_time_).Double();
00220
00221
00222 this->lock_.lock();
00223
00224
00225 this->joint_state_msg_.header.stamp.sec = current_time.sec;
00226 this->joint_state_msg_.header.stamp.nsec = current_time.nsec;
00227
00228
00229 for(std::map<std::string, GazeboJointProperties>::iterator joint = this->joints_.begin(); joint != this->joints_.end(); ++joint)
00230 {
00231 GazeboJointProperties& joint_properties = joint->second;
00232
00233 if (!joint_properties.joint_ptr)
00234 continue;
00235
00236
00237 update_joint(joint_properties, this->command_msg_.position[joint_properties.joint_index], this->command_msg_.velocity[joint_properties.joint_index], this->command_msg_.effort[joint_properties.joint_index], dt);
00238
00239
00240 this->joint_state_msg_.position[joint_properties.joint_index] = joint_properties.position;
00241 this->joint_state_msg_.velocity[joint_properties.joint_index] = joint_properties.joint_ptr->GetVelocity(0);
00242 this->joint_state_msg_.effort[joint_properties.joint_index] = joint_properties.joint_ptr->GetForce(0);
00243 }
00244
00245
00246 for(std::map<std::string, MimicJointProperties>::iterator joint = this->mimic_joints_.begin(); joint != this->mimic_joints_.end(); ++joint)
00247 {
00248 MimicJointProperties& joint_properties = joint->second;
00249
00250 if (!joint_properties.joint_ptr)
00251 continue;
00252
00253
00254 double command_position = joint_properties.multiplier*(this->command_msg_.position[joint_properties.master_joint_index] - joint_properties.offset);
00255 double command_velocity = joint_properties.multiplier*(this->command_msg_.velocity[joint_properties.master_joint_index]);
00256
00257
00258 update_joint(joint_properties, command_position, command_velocity, 0, dt);
00259 }
00260
00261
00262 if(this->joint_state_pub_.getNumSubscribers() > 0)
00263 {
00264 this->joint_state_pub_.publish(this->joint_state_msg_);
00265 }
00266
00267 this->lock_.unlock();
00268
00269
00270
00271 this->last_time_ = current_time;
00272 }
00273
00275
00276 void GazeboRosActuatorArray::FiniChild()
00277 {
00278 #ifdef USE_CBQ
00279 this->queue_.clear();
00280 this->queue_.disable();
00281 this->callback_queue_thread_.join();
00282 #endif
00283 }
00284
00285 #ifdef USE_CBQ
00286
00287
00288 void GazeboRosActuatorArray::QueueThread()
00289 {
00290 static const double timeout = 0.01;
00291
00292 ros::NodeHandle node;
00293 while (node.ok())
00294 {
00295 this->queue_.callAvailable(ros::WallDuration(timeout));
00296 }
00297 }
00298 #endif
00299
00301
00302 void GazeboRosActuatorArray::update_joint(GazeboJointProperties& joint, double command_position, double command_velocity, double command_effort, double dt)
00303 {
00304
00305 double error = 0.0;
00306 switch(joint.joint_ptr->GetType())
00307 {
00308
00309 case gazebo::Joint::HINGE:
00310 {
00311 joint.position = joint.position + angles::shortest_angular_distance(joint.position, joint.joint_ptr->GetAngle(0).GetAsRadian());
00312 angles::shortest_angular_distance_with_limits(command_position, joint.position, joint.min_position, joint.max_position, error);
00313 break;
00314 }
00315 case gazebo::Joint::SLIDER:
00316 {
00317 joint.position = joint.joint_ptr->GetAngle(0).GetAsRadian();
00318 error = joint.position - command_position;
00319 break;
00320 }
00321 default:
00322 {
00323 abort();
00324 }
00325 }
00326
00327
00328 joint.pid.setCurrentCmd(command_position);
00329 double velocity = joint.pid.updatePid(error, ros::Duration(dt));
00330
00331
00332 if(joint.has_velocity_limits)
00333 {
00334 if(velocity > joint.max_velocity)
00335 {
00336 velocity = joint.max_velocity;
00337 }
00338 else if(velocity < -joint.max_velocity)
00339 {
00340 velocity = -joint.max_velocity;
00341 }
00342 }
00343
00344
00345 if(command_velocity > 0)
00346 {
00347 if(velocity > command_velocity)
00348 {
00349 velocity = command_velocity;
00350 }
00351 else if(velocity < -command_velocity)
00352 {
00353 velocity = -command_velocity;
00354 }
00355 }
00356
00357
00358 double effort = std::numeric_limits<float>::max();
00359 if(joint.has_effort_limits)
00360 {
00361 effort = std::min(effort, joint.max_effort);
00362 }
00363 if(command_effort > 0)
00364 {
00365 effort = std::min(effort, command_effort);
00366 }
00367
00368
00369 joint.joint_ptr->SetVelocity(0, velocity);
00370 joint.joint_ptr->SetMaxForce(0, effort);
00371 }
00372
00374
00375
00376
00377
00378
00379
00380 void GazeboRosActuatorArray::parse_mimic_joints(const ros::NodeHandle& node)
00381 {
00382
00383 std::string full_name = node.resolveName(this->robot_description_parameter_);
00384 urdf::Model urdf_model;
00385 while(!node.hasParam(full_name))
00386 {
00387 ROS_INFO("ActuatorArrayDriver: waiting for robot_description at %s on the parameter server.", full_name.c_str());
00388 usleep(100000);
00389 }
00390 urdf_model.initParam(full_name);
00391
00392
00393 std::map< std::string, boost::shared_ptr< urdf::Joint > >::const_iterator urdf_joint_map;
00394 for(urdf_joint_map = urdf_model.joints_.begin(); urdf_joint_map != urdf_model.joints_.end(); ++urdf_joint_map)
00395 {
00396
00397 const boost::shared_ptr< urdf::Joint >& urdf_joint = urdf_joint_map->second;
00398 if(urdf_joint->mimic)
00399 {
00400
00401 std::map<std::string, GazeboJointProperties>::iterator parent_joint = joints_.find(urdf_joint->mimic->joint_name);
00402
00403
00404 if((parent_joint != joints_.end()) && (dynamic_cast<gazebo::Joint*> (this->myParent->GetJoint(urdf_joint->name))))
00405 {
00406 const std::string& parent_name = parent_joint->first;
00407 GazeboJointProperties& parent_properties = parent_joint->second;
00408
00409 std::string mimic_name = urdf_joint->name;
00410 MimicJointProperties mimic_properties;
00411
00412
00413 if(urdf_joint->limits)
00414 {
00415 mimic_properties.min_position = urdf_joint->limits->lower;
00416 mimic_properties.max_position = urdf_joint->limits->upper;
00417 mimic_properties.has_position_limits = (mimic_properties.max_position > mimic_properties.min_position);
00418 mimic_properties.max_velocity = urdf_joint->limits->velocity;
00419 mimic_properties.has_velocity_limits = (mimic_properties.max_velocity > 0.0);
00420 mimic_properties.max_effort = urdf_joint->limits->effort;
00421 mimic_properties.has_effort_limits = (mimic_properties.max_effort > 0.0);
00422 }
00423
00424 if(urdf_joint->dynamics)
00425 {
00426 mimic_properties.damping = urdf_joint->dynamics->damping;
00427 mimic_properties.friction = urdf_joint->dynamics->friction;
00428 }
00429
00430
00431 double kp, ki, kd, imax, imin;
00432 parent_properties.pid.getGains(kp, ki, kd, imax, imin);
00433 mimic_properties.joint_ptr = dynamic_cast<gazebo::Joint*> (this->myParent->GetJoint(mimic_name));
00434 mimic_properties.pid.initPid(kp, ki, kd, imax, imin);
00435 mimic_properties.position = 0.0;
00436 mimic_properties.master_joint_index = parent_properties.joint_index;
00437 mimic_properties.master_joint_name = parent_name;
00438 mimic_properties.multiplier = urdf_joint->mimic->multiplier;
00439 mimic_properties.offset = urdf_joint->mimic->offset;
00440
00441
00442 this->mimic_joints_[mimic_name] = mimic_properties;
00443
00444 }
00445 }
00446 }
00447
00448 }
00449
00451
00452 bool GazeboRosActuatorArray::command_()
00453 {
00454
00455 return true;
00456 }
00457
00459
00460 bool GazeboRosActuatorArray::stop_()
00461 {
00462 for(unsigned int i = 0; i < this->command_msg_.name.size(); ++i)
00463 {
00464 const GazeboJointProperties& joint_properties = joints_[this->command_msg_.name[i]];
00465
00466 this->command_msg_.position[i] = joint_properties.position;
00467 this->command_msg_.velocity[i] = 0.0;
00468 this->command_msg_.effort[i] = 0.0;
00469 }
00470
00471 return true;
00472 }
00473
00475
00476 bool GazeboRosActuatorArray::home_()
00477 {
00478 for(unsigned int i = 0; i < this->command_msg_.name.size(); ++i)
00479 {
00480 const GazeboJointProperties& joint_properties = joints_[this->command_msg_.name[i]];
00481
00482 this->command_msg_.position[i] = joint_properties.home_position;
00483 this->command_msg_.velocity[i] = 0.0;
00484 this->command_msg_.effort[i] = 0.0;
00485 }
00486
00487 return true;
00488 }
00489
00491
00492 bool GazeboRosActuatorArray::read_(ros::Time ts)
00493 {
00494
00495 return true;
00496 }
00497
00498 }