Gazebo | Ignition | Community
Ask Your Question
0

Change radius of collision (cylinder) C++

asked 2017-11-27 09:18:29 -0500

this post is marked as community wiki

This post is a wiki. Anyone with karma >75 is welcome to improve it.

Hello Guys,

how can I change the radius of a cylinder (only collision, not the visual part) in a C++ plugin.

I load a simple model of a cylinder as a link in a world sdf file called cylinder.world.

The cylinder and also my plugin are loaded properly (i check the plugin by printing a simple message on the terminal when it is started). I would like to change the size of the cylinder (more exactly the radius) now during runtime (for example after 100 Iterations of the Simulation) by accessing the radius (collision tag) in my plugin.

As i first start with a cylinder that has the same dimensions in the visual as in the collision tag and i decrease the radius of the collision element in my plugin after some time, it should look like the cylinder is diving into the ground (although of course a closer look on the collision element shows that there is just a smaller cylinder due to the plugin).

I have tried a lot to achieve this by using functions of gazebo API, but nothing really worked. (http://gazebosim.org/api/dev/classgaz...)

I am using gazebo 7.

I hope I can get some help from you. I would be really happy about a working example showing the functionality I would like to achieve!

Thanks a lot for every kind of help!


First of all thanks for your answer!!!

Update 1:

Here is my header file called cylinder_radius_plugin.hh

#ifndef _CYLINDER_RADIUS_PLUGIN_HH__
#define _CYLINDER_RADIUS_PLUGIN_HH__

#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/common/Plugin.hh>

namespace gazebo
{
    class cylinder_radius_plugin : public ModelPlugin
    {
        public: cylinder_radius_plugin();

        public: virtual void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf);

        public: void OnUpdate(const common::UpdateInfo);        

        private: physics::ModelPtr model;
        private: sdf::ElementPtr sdf;
        private: event::ConnectionPtr updateConnection; 

        private: physics::LinkPtr link;
        private: physics::CollisionPtr cylinder_col;
        private: physics::CylinderShapePtr cylinder(physics::CylinderShape(physics::CollisionPtr));
        private: int i;

    };
}
#endif

And this is the actual source code called cylinder_radius_plugin.cc

#include <stdio.h>
#include <boost/bind.hpp>
#include <iostream>
#include <fstream>
#include <string>

#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/physics/CylinderShape.hh>
#include <gazebo/common/common.hh>
#include <gazebo/common/Plugin.hh>
#include <gazebo/common/Events.hh>
#include <gazebo/physics/Collision.hh>

#include "cylinder_radius_plugin.hh"

using namespace gazebo;

GZ_REGISTER_MODEL_PLUGIN(cylinder_radius_plugin)

cylinder_radius_plugin::cylinder_radius_plugin()
{
}

void cylinder_radius_plugin::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
{

    std::cerr << "\n";
    std::cerr << "\n The plugin is loaded correctly! \n";
    std::cerr << "\n";

    this->model = _model;
    this->sdf = _sdf;

    this->i = 0;
    this->link = this->model->GetLink("cylinder");
    this->cylinder_col = this->link->GetChildCollision("collision_cylinder");

    // I am not pretty shure how to do it, but I think I should allocate something 
    // to the CylinderShapePtr??? 


    this->updateConnection = event::Events::ConnectWorldUpdateBegin(boost::bind(&cylinder_radius_plugin::OnUpdate, this, _1));
}

void cylinder_radius_plugin::OnUpdate(const common::UpdateInfo)
{

  //something like that should be in here
  // do something after 500 iterations of the simulation
  if (this->i == 500) 
  {
      // change the radius of the **collision** of the cylinder 
      // here should be ...
(more)
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2017-11-27 09:56:45 -0500

chapulina gravatar image

If I understood well, you want to do the same as the graphical scaling tool, but only the collision should be scaled:

image description

I tracked down what the tool does:

  1. Publish SCALING to ~/user_cmd
  2. Which then publishes to ~/model/modify
  3. Which eventually goes to Model::SetScale
  4. Then Link::SetScale
  5. Which both calls Collision::SetScale and updates the visual scales, you only want the collision
  6. Then it calls Shape::SetScale (in your case, it is CylinderShape)

It looks to me that a direct call to CylinderShape::SetScale should have the same results on the physics, but it might not update the collision visual (i.e. the cylinder will sync but gzclient will still show the big collision - and big visual, as you want).

If you could update your question with a code snippet maybe we can better debug what's going on.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-11-27 09:18:29 -0500

Seen: 1,296 times

Last updated: Nov 28 '17