Home | Tutorials | Wiki | Issues
Ask Your Question
0

gazebo without ros + urdf file

asked 2015-09-04 07:00:35 -0600

matthieu637 gravatar image

Hello,

1) I would like to know if it is possible to control a robot (applying force on joints with a c++ algorithm) in gazebo without ros to make a lot a simulations. In order to try evolutionary or reinforcement learning algorithms (could requires 500 000 simulations for instance). Usually, I use only a low level physic engine like ODE in C++ to skip any unnecessary computations.

2) I have access to an URDF model. Is it possible to import it in gazebo without ROS ?

It is not clear to me how to apply force/torque on a robot. I saw that I can use Player or ROS in tutorials. However I also saw that there is an external API on physics engines.

What would be the fastest/lightweight method?

Thank you.

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
0

answered 2015-09-07 02:13:44 -0600

Hi,

you can just load an urdf as normal model. You just have to load an URDF instead of SDF. But loading URDFs can be tricky from time to time so you should use an SDF when you can.

Here is an example model.config:

<?xml version="1.0"?>

<model>
  <name>YOUR_MODEL</name>
  <version>1.0</version>
  <sdf>YOUR_MODEL.urdf</sdf>
  <author>
    <name>Your Name</name>
    <email>your@mail.com</email>
  </author>

  <description>
    Small description of the model 
  </description>
</model>

Have a look at this tutorial series if you do not know how to set up a robot

http://gazebosim.org/tutorials?cat=build_robot

for your first question a model plugin is the right way to go...

edit flag offensive delete link more
0

answered 2015-11-06 09:12:20 -0600

djou07 gravatar image

I am also using an evolution of robots in Gazebo, There are some points that you have to take into account:

  1. you can run gazebo in headless mode, meaning without visualization, this will reduce computing time.
  2. For the simulation of robots (to evaluate them) you can:

    2.1. for each generation run on simulation (one world) that will contain the population, each robot in a unique position

    2.2. evaluate each robot independently in parallel, for example if you have an 8 core cpu you can run 8 at once. (not sure but this will probably reduce computing time and this depending on complexity of morphology)

  3. Reset the simulation do not work, I mean that if we restart the initial conditions and position of robot it will not give the same behavior (robot with the same ANN), so this will not help for optimization. So I suggest to quit and restart the simulation at each generation

  4. Communication between plugins is with publishers and subscribers. But there is some problem here that will affect evolution. When you publish something in time x, the listener will not receive the message instantly. it will receive it in time x or x+1 or x+2 or ... So, sometimes, when you want to use the message sent, and at this time the message is not arrived yet you will read the previous message.

I hope that you get what I mean, and if you have any other question do not hesitate

ps:I encountered those issues in Gazebo version 4.

edit flag offensive delete link more
0

answered 2015-09-04 15:22:41 -0600

debz gravatar image

updated 2015-09-04 17:10:36 -0600

Hi Matthieu,

First I'm not an expert, I started to work with gazebo one month ago for the same reason as you. I need to run multiple simulations of an arm robot to use reinforcement learning. So basically I asked a similar question here some weeks ago.

I can't answer to your second question even if URDF and SDF look close enough such that you should be able to transform one to another (SDF is actually more complete than URDF). Then for your first question:

  • I made a SDF world file that contains a simple arm robot model and some basic objects. In this file I link the arm to a ModelPlugin and the world to a WorldPlugin. To do so, the tutorials of gazebo are clear and straight forward.

  • In the ModelController, which is a C++ class, I use a class called JointController, you can find the class reference but impossible to find any example on the web. To move a joint you can then use a PID, it would be something like this (in this case I make a pointer to the JointController as a property of the RobotControl class to be able to call it at each iteration):


#include <boost/bind.hpp>
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/common/common.hh>
#include <stdio.h>
#include <math.h>

namespace gazebo
{
  class RobotControl : public ModelPlugin
  {
    // Pointer to the model
    private: physics::ModelPtr model;

    // Pointer to the world
    private: physics::WorldPtr world;

    // Pointer to the update event connection
    private: event::ConnectionPtr updateConnection;

    private: physics::JointControllerPtr jointsController;

    // When the simulation starts
    public: void Load(physics::ModelPtr _parent, sdf::ElementPtr /*_sdf*/)
    {
      // Store the pointer to the model
      this->model = _parent;
      // Store the world
      this->world = this->model->GetWorld();
      // Create the joint controller
      this->jointsController =  boost::shared_ptr<physics::jointcontroller>(new physics::JointController(this->model));
      // Create a PID
      common::PID PID = common::PID(100, 100, 100, 1, -1, 1000, -1000);         
      // Get all the joints of the model
      std::vector<physics::jointptr> joints = this->model->GetJoints();
      // For each one of these joints
      for (unsigned i=0; i < joints.size(); i++) 
      {
        // Add it to the joint controller
        this->jointsController->AddJoint(joints[i]);
        // Set its PID values
        this->jointsController->SetPositionPID(joints[i]->GetScopedName(),PID); 
      }
      // Listen to the update event. This event is broadcast every
      // simulation iteration.
      this->updateConnection = event::Events::ConnectWorldUpdateBegin(boost::bind(&ArmControl::OnUpdate, this, _1));
    }

    // Called at each update of the simulation
    public: void OnUpdate(const common::UpdateInfo & /*_info*/)
    {
       // Set an angle (here it is stupid since the angle doesn't change)
      float angle = 0.5 // gradient angle
      this->jointsController->SetPositionTarget(this->model->GetJoint("jointName")->GetScopedName(),angle);
    }
  };
  // Register this plugin with the simulator
  GZ_REGISTER_MODEL_PLUGIN(RobotControl)
}

The WorldPlugin is useful to add/remove objects in your simulation, or access/change the properties of the simulation.

I hope this helps.

Cheers

edit flag offensive delete link more

Comments

Hi debs, I'm facing a similar issue: I need to set the position of a joint, but i'm unable to use the PID. do you have anyother example? I tried this one but the position simply doesn't change, even though this->jointsController->SetPositionTarget returns true (meaning it found the joint) thanks! Enrique

ellerenad gravatar imageellerenad ( 2015-11-13 18:24:44 -0600 )edit
Login/Signup to Answer

Question Tools

Stats

Asked: 2015-09-04 07:00:35 -0600

Seen: 2,406 times

Last updated: Nov 06 '15