Home | Tutorials | Wiki | Issues
Ask Your Question

Revision history [back]

Yes, you can write a motor/actuator plugin (check out this tutorial: http://gazebosim.org/tutorials?cat=guided_i&tut=guided_i5). Then you can add your plugin(s)* to your URDF to control the joints you want to move.

Depends on how your write your plugin. You can either write a plugin that controls a single joint - which you'd then declare multiple instances of in your URDF - or you can write a plugin that controls multiple joints.

Also, you may want to check out ros control: http://gazebosim.org/tutorials/?tut=ros_control

Yes, you can write a motor/actuator plugin (check out this tutorial: http://gazebosim.org/tutorials?cat=guided_i&tut=guided_i5). Then you can add your plugin(s)* to your URDF to control the joints you want to move.

Depends on how your write your plugin. You can either write a plugin that controls a single joint - which you'd then declare multiple instances of in your URDF - or you can write a plugin that controls multiple joints.

Also, you may want to check out ros control: http://gazebosim.org/tutorials/?tut=ros_control


EDIT: Here's some boilerplate plugin code for a joint controller: namespace gazebo

{
  YourPlugin::YourPlugin() {}

  YourPlugin::~YourPlugin() {}

   /// \brief Load function gets called by Gazebo when the plugin is inserted in simulation 
   /// via URDF/SDF
   /// \param[in] _model A pointer to the model that this plugin is attached to.
   /// \param[in] _sdf A pointer to the plugin's SDF element.
   void YourPlugin::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
  {
      // Store the model ptr for convenience.
      this->model_ = _model;

      // Get the name of your actuator/sensor joint from the URDF/SDF
      // Assuming:
      // <gazebo reference = "SENSORLINKNAME" />
      //     <actuatorJoint>NAMEOFJOINT</actuatorJoint>
      // </gazebo>
      //
      std::string joint_name = "";
      if ( _sdf->HasElement("actuatorJoint") ) {
          joint_name = _sdf->Get<std::string>("actuatorJoint");
      } else {
          ROS_WARN_NAMED("your_plugin", "YourPlugin missing <actuatorJoint>!!!");
      }

      // Store the actuatorjoint pointer.
      this->joint_ = this->model_->GetJoint(joint_name);

      // OTHER BOILERPLATE STUFF

      // Listen to the update event. This event is broadcast every
      // simulation iteration.
      this->update_connection_ = event::Events::ConnectWorldUpdateBegin (
      boost::bind ( &YourPlugin::OnUpdate, this, _1 ) );
  }

  // SETUP GAZEBO/ROS MESSAGING

  /// \brief Function called at each simulation interation
  void YourPlugin::OnUpdate(const common::UpdateInfo & _info)
  {
      common::Time current_time = this->model_->GetWorld()->GetSimTime();
      current_joint_angle = this->joint_->GetAngle(0).Radian() // Get joint angle

      // DO COOL STUFF / PUBLISH JOINT ANGLE
      // this->target_torque_ = CALL TO PID CONTROLLER HERE

      this->joint_->SetForce(0, this->target_torque_);
  }

  // Tell Gazebo about this plugin, so that Gazebo can call Load on this plugin.
  GZ_REGISTER_MODEL_PLUGIN(YourPlugin)
}