gazebosim / gazebo-classic

Gazebo classic. For the latest version, see https://github.com/gazebosim/gz-sim
http://classic.gazebosim.org/
Other
1.19k stars 480 forks source link

Entity::SetStatic() does not work after the model is loaded #1526

Open osrf-migration opened 9 years ago

osrf-migration commented 9 years ago

Original report (archived issue) by Andrei Haidu (Bitbucket: ahaidu).

The original report had attachments: static_test.cc, static_test.world


When calling Entity::SetStatic from a plugin (in the Update loop or in the Load method) it has no effect on the model. This might be included in issue 528 (#528).

osrf-migration commented 9 years ago

Original comment by Andrei Haidu (Bitbucket: ahaidu).


world uploaded

osrf-migration commented 9 years ago

Original comment by Andrei Haidu (Bitbucket: ahaidu).


I would like to try fixing this, any pointers on how this should be done?

osrf-migration commented 9 years ago

Original comment by Nate Koenig (Bitbucket: Nathan Koenig).


This would be a great feature to implement. Just want to warn you that it may be a bit complicated.

When a model is loaded and static=true, then it does not get a dynamic body in the physics engine. See gazebo/physics/ode/ODELink.cc:Init.

You try adding a function to ODELink that assigns a body to a static object when SetStatic is set to true.

Grep for IsStatic in the physics directory to see where else the flag is used.

osrf-migration commented 9 years ago

Original comment by Steve Peters (Bitbucket: Steven Peters, GitHub: scpeters).


It is different for each physics engine as well. Bullet determines whether bodies are static by checking their mass and inertia for zero values.

osrf-migration commented 9 years ago

Original comment by Andrei Haidu (Bitbucket: ahaidu).


So, I managed to put together a way to make this work for ODE.

In the ODE user guide at 12.4 is explained is how static objects are created. Basically by not creating a dynamic body as mentioned by @nkoenig :

#!c++
this->linkId = dBodyCreate(this->odePhysics->GetWorldId());
dBodySetData(this->linkId, this);

For the implementation I re-used the on the TODO list function: Link::SetLinkStatic , more specifically ODELink::SetLinkStatic:

#!c++
//////////////////////////////////////////////////
void ODELink::SetLinkStatic(bool _static)
{
    // set static flag, the models' flag is not included
    this->SetStatic(_static);

    if(_static)
    {
      // remove dBody making the object static  
      if(this->linkId)
      {
        dBodyDestroy(this->linkId);
      }

      this->linkId = NULL;
    }
    else
    {
        // re-initialize Link, thus re-creating a dBody with a new linkId
        this->Init();
    }
}

This surprisingly worked well. I tried it with the following models: a single collision, two collisions in a link, and two links. In all cases it worked well.

Now the issues:

#!c++
//////////////////////////////////////////////////
void Entity::SetStatic(const bool &_s)
{
  Base_V::iterator iter;

  this->isStatic = _s;

  for (iter = this->children.begin(); iter != this->children.end(); ++iter)
  {
    EntityPtr e = boost::dynamic_pointer_cast<Entity>(*iter);
    if (e)
      e->SetStatic(_s);

    // check if type link
    if((*iter)->GetType == 5)
    {
        (*iter)->SetLinkStatic(_s);
    }

  }
}
osrf-migration commented 9 years ago

Original comment by Steve Peters (Bitbucket: Steven Peters, GitHub: scpeters).


Nice!

Yes, we would need some new sdformat tags to mark individual links as static. It could follow the pattern of the self_collide tags, which are defined for both links and models, and use the model's value if the link value is not specified.

osrf-migration commented 9 years ago

Original comment by Andrei Haidu (Bitbucket: ahaidu).


I did not test the functionality of joints either. However the ode user guide explains at point 12.1 and 12.4 how to use these:

12.1. How do I connect a body to the static environment with a joint?

osrf-migration commented 9 years ago

Original comment by Nate Koenig (Bitbucket: Nathan Koenig).


Excellent work.

How about we do this in two parts:

  1. Implement the whole model setstatic functionality via Entity::SetStatic.

  2. Add the ability to set each link to static. This will require a change to SDF like Steve suggested.

osrf-migration commented 9 years ago

Original comment by Andrei Haidu (Bitbucket: ahaidu).


Some updates on this issue, until I will have time to look over it in more detail (this works for basic cases).

Here are the diffs.

Known issues with this fix:

osrf-migration commented 8 years ago

Original comment by Fadri Furrer (Bitbucket: ffurrer).


Hi, is there any update on this?

osrf-migration commented 8 years ago

Original comment by Nate Koenig (Bitbucket: Nathan Koenig).


osrf-migration commented 7 years ago

Original comment by Louise Poubel (Bitbucket: chapulina, GitHub: chapulina).


Hi @ahaidu , I was thinking of taking a look at this to see if it could be implemented relatively soon. Do you have the original link to the diff you mention above by any chance? Bitbucket is currently just redirecting it to this page...

Thanks for the help!

osrf-migration commented 5 years ago

Original comment by Peter Mitrano (Bitbucket: peter_mitrano).


:thumbsup: would like to see this fixed if it isn’t already!