Move several joints of an Object with ROS in Gazebo
Hello guys,
i have created my own robot arm in Gazebo. Now i want to move several joints and not the whole object is there a way to do that ?
I use a SDF Model some Tut i found was for a URDF but i need one for SDF Models.
Asked by Baumboon on 2017-10-24 07:53:44 UTC
Answers
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)
}
Asked by josephcoombe on 2017-10-24 08:42:11 UTC
Comments
The plugin seems to be more complex as the ros Control. I will try out both and look what fits better for me.
Asked by Baumboon on 2017-10-24 08:57:20 UTC
Sounds good. I've only used custom plugins so far, so let me know if you run into issues with those and I'll try to help!
Asked by josephcoombe on 2017-10-24 09:10:40 UTC
I looked for the Ros Controller but it is only described for URDF Models do u know if it will fit for sdf models too?
Asked by Baumboon on 2017-10-25 03:53:44 UTC
Comments