mecanum_plugin.cpp
Go to the documentation of this file.
00001 
00026 #include <gazebo/common/Events.hh>
00027 #include <gazebo/common/Plugin.hh>
00028 #include <gazebo/physics/ode/ODESurfaceParams.hh>
00029 #include <gazebo/physics/physics.hh>
00030 #include <ros/console.h>
00031 
00032 #include <string>
00033 
00034 
00035 namespace gazebo
00036 {
00037 
00038 class MecanumPlugin : public ModelPlugin
00039 {
00040 public:
00041   void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf);
00042 
00043 protected:
00044   virtual void GazeboUpdate();
00045 
00046 private:
00047   event::ConnectionPtr update_connection_;
00048   physics::ModelPtr model_;
00049   physics::LinkPtr wheel_link_;
00050   physics::LinkPtr fixed_link_;
00051   double roller_angle_;
00052   double roller_friction_;
00053   double roller_skid_friction_;
00054 };
00055 
00056 // Register this plugin with the simulator
00057 GZ_REGISTER_MODEL_PLUGIN(MecanumPlugin);
00058 
00059 void MecanumPlugin::Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
00060 {
00061   // Store the model
00062   model_ = _parent;
00063 
00064   std::string link_name;
00065 
00066   if (_sdf->HasElement("wheelLinkName"))
00067   {
00068     link_name = _sdf->Get<std::string>("wheelLinkName");
00069     wheel_link_ = model_->GetLink(link_name);
00070     if (!wheel_link_)
00071     {
00072       ROS_FATAL_STREAM("Wheel link [" << link_name << "] not found!");
00073       return;
00074     }
00075   }
00076   else
00077   {
00078     ROS_FATAL("The mecanum plugin requires a `wheelLinkName` parameter.");
00079     return;
00080   }
00081 
00082   if (_sdf->HasElement("fixedLinkName"))
00083   {
00084     link_name = _sdf->Get<std::string>("fixedLinkName");
00085     fixed_link_ = model_->GetLink(link_name);
00086     if (!fixed_link_)
00087     {
00088       ROS_FATAL_STREAM("Fixed link [" << link_name << "] not found!");
00089       return;
00090     }
00091   }
00092   else
00093   {
00094     ROS_FATAL("The mecanum plugin requires a `fixedLinkName` parameter.");
00095     return;
00096   }
00097 
00098   if (_sdf->HasElement("rollerAngle"))
00099   {
00100     roller_angle_ = _sdf->Get<double>("rollerAngle");
00101   }
00102   else
00103   {
00104     roller_angle_ = M_PI / 4;
00105   }
00106 
00107   if (_sdf->HasElement("rollerFriction"))
00108   {
00109     roller_friction_ = _sdf->Get<double>("rollerFriction");
00110   }
00111   else
00112   {
00113     roller_friction_ = 100;
00114   }
00115 
00116   if (_sdf->HasElement("rollerSkidFriction"))
00117   {
00118     roller_skid_friction_ = _sdf->Get<double>("rollerSkidFriction");
00119   }
00120   else
00121   {
00122     roller_skid_friction_ = 100000;
00123   }
00124 
00125   ROS_INFO_STREAM("Mecanum plugin initialized for " << wheel_link_->GetName() <<
00126                   ", referenced to " << fixed_link_->GetName() << ", with a roller " <<
00127                   "angle of " << roller_angle_ << " radians.");
00128 
00129   // Register update event handler
00130   this->update_connection_ = event::Events::ConnectWorldUpdateBegin(
00131       boost::bind(&MecanumPlugin::GazeboUpdate, this));
00132 }
00133 
00134 void MecanumPlugin::GazeboUpdate()
00135 {
00136   math::Pose wheel_pose = wheel_link_->GetWorldCoGPose();
00137   math::Pose fixed_pose = fixed_link_->GetWorldCoGPose();
00138   math::Quaternion wheel_orientation = wheel_pose.CoordRotationSub(fixed_pose.rot);
00139   double wheel_angle = wheel_orientation.GetPitch();
00140   ROS_DEBUG_STREAM(wheel_link_->GetName() << " angle is " << wheel_angle << " radians.");
00141 
00142   // TODO: Understand better what the deal is with multiple collisions on a link.
00143   unsigned int collision_index = 0;
00144   physics::SurfaceParamsPtr surface = wheel_link_->GetCollision(collision_index)->GetSurface();
00145 
00146   // TODO: Check that the physics engine is ODE to avoid a segfault here.
00147   physics::ODESurfaceParams* ode_surface = dynamic_cast<physics::ODESurfaceParams*>(surface.get());
00148   physics::FrictionPyramid& fric(ode_surface->frictionPyramid);
00149 
00150   // TODO: Parameterize these.
00151   fric.SetMuPrimary(roller_skid_friction_);
00152   fric.SetMuSecondary(roller_friction_);
00153 
00154   // TODO: Investigate replacing this manual trigonometry with Pose::rot::RotateVector. Doing this
00155   // would also make it easier to support wheels which rotate about an axis other than Y.
00156   fric.direction1.x = cos(roller_angle_) * cos(wheel_angle);
00157   fric.direction1.y = sin(roller_angle_);
00158   fric.direction1.z = cos(roller_angle_) * sin(wheel_angle);
00159 }
00160 
00161 }  // namespace gazebo


mecanum_gazebo_plugin
Author(s): Mike Purvis
autogenerated on Thu Jun 6 2019 21:14:41