0

I want to decrease model weigth in runtime. I am currently working on a plugin but it doesn't seem to work. I am using iris model with pixhawk 4 sitl. My purpose is to simulate a liquid spraying drone like firefighter. To do that I have to decrease the weigth of the drone in time. Thank you. Here is the code that I have:

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

namespace gazebo
{
class joint_c : public ModelPlugin
{
public:
    void Load(physics::ModelPtr _parent, sdf::ElementPtr /*_sdf*/)
    {

        this->model = _parent;
        this->world= this->model->GetWorld();
        this->iris=this->world->ModelByName("iris");
        this->base_link = this->iris->GetLink("base_link");

        base_link->GetInertial()->SetMass(800000);    // Changing the mass


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

public:
    void OnUpdate(const common::UpdateInfo &_info)
    {

    }

private:

    physics::ModelPtr model;
    physics::ModelPtr iris;
    physics::WorldPtr world;
    event::ConnectionPtr updateConnection;
    physics::LinkPtr  base_link;

};

// Register this plugin with the simulator
GZ_REGISTER_MODEL_PLUGIN(joint_c)
}
kiner_shah
  • 3,939
  • 7
  • 23
  • 37
Ege Alşan
  • 21
  • 3
  • ***decrease the mass of the drone*** This should not be possible physically actually - you cannot change mass of an object. Maybe you meant weight? – kiner_shah Jan 26 '22 at 14:26
  • yes, sorry my fault. I meant weight. I am updating the question thank you. – Ege Alşan Jan 27 '22 at 11:00
  • Ok I think, it's like this: weight of drone filled with water = (mass of drone + mass of water) * g. So, when water is poured out, mass of water gets reduced due to reduction in volume and the total weight (mass) of the drone is reduced as well. So yeah, maybe you can just calculate how much mass is poured out and then set the mass of drone filled with water accordingly. (I may be wrong somewhere though). – kiner_shah Jan 27 '22 at 11:32
  • Yes, that is what I want. But unfortunately, my coding skills are not enough for it. I couldn't set the weight after starting the simulation. My plugin runs but doesn't affect it. Thank you. – Ege Alşan Jan 27 '22 at 13:44
  • I think, this has to be done in `OnUpdate` function in the posted code. Found a link which is very similar to your issue: https://answers.gazebosim.org//question/19201/how-can-i-change-a-gazebo-model-properties-in-runtime/. The solution there mentioned to use `UpdateMass()`. – kiner_shah Jan 28 '22 at 03:31
  • `UpdateMass()` is a `virtual` function which you can override and implement. Note that `UpdateMass()` is called in [Link::ProcessMsg()](https://github.com/thomas-moulard/gazebo-deb/blob/456da84cfb7b0bdac53241f6c4e86ffe1becfa7d/gazebo/physics/Link.cc#L813). – kiner_shah Jan 28 '22 at 03:39
  • Yes, I read that post. But unfortunately I am newbie in Gazebo. I couldnt figure out how to implement it. I tried to implement the plugin which I wrote to the empty_world world file. I just add . Then tried to open the empty world with iris model. It didnt affected. Can you help me or show me a good tutorial to do it. I already read the turorials about plugins in gazebo. – Ege Alşan Jan 28 '22 at 11:32
  • There are lots of examples for plugins here: https://github.com/thomas-moulard/gazebo-deb/tree/master/examples/plugins. You can check the model_push example which seems to be similar to what you are doing (`ModelPlugin`). – kiner_shah Jan 29 '22 at 06:18
  • You may have to call `base_link->GetInertial()->SetMass(new_mass)` inside `OnUpdate()` if water is poured out. – kiner_shah Jan 29 '22 at 06:24
  • I still couldn't make it work, unfortunately. I heard that SDF model properties can be set as parameters (variable) Can I use it with the plugin? Thank you – Ege Alşan Feb 04 '22 at 09:51
  • Unfortunately, I also am not aware of this much. – kiner_shah Feb 04 '22 at 10:12
  • 1
    it worked!!! Thank you I tried one more time to do in OnUpdate() as you said and it worked. It set the mass instantaneously when I start to simulate. Now all I have to is create a loop and change the mass with steps – Ege Alşan Feb 09 '22 at 11:45
  • Glad to hear that it worked :-) – kiner_shah Feb 10 '22 at 05:35
  • You can post a self-answer in order to help other developers. – kiner_shah Feb 11 '22 at 08:44
  • 1
    Yes, thank you for reminding :D – Ege Alşan Feb 11 '22 at 20:13

1 Answers1

0

I finally figured it out.

I used base_link->GetInertial()->SetMass(new_mass); configuration in OnUpdate() function as kiner_shah told in the comments. But that only changed visual value. In order to apply the change I put base_link -> UpdateMass();

Then I add the plugin path and the plugin to the model sdf file like described in here Gazebo model plugin

Here is my code:

    #include <functional>
    #include <gazebo/gazebo.hh>
    #include <gazebo/physics/physics.hh>
    #include <gazebo/common/common.hh>
    #include <unistd.h>

    float x = 25;
    int count = 0;


    namespace gazebo
    {
      class joint_c : public ModelPlugin
      {
      public: void Load(physics::ModelPtr _parent, sdf::ElementPtr /*_sdf*/)
        {   

        this->model = _parent;
        this->world= this->model->GetWorld();
        this->iris=this->world->ModelByName("iris");
        this->base_link = this->iris->GetLink("base_link");


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

    public: void OnUpdate(const common::UpdateInfo &_info)
        {
          count = count + 1;
          if(count > 10000){
            x = 22;
          }
          if(count > 13000){
            x = 19;
          }
          if(count > 16000){
            x = 17;
          }
          if(count > 18000){
            x = 15;
          }
          base_link -> GetInertial() -> SetMass(x);
          base_link -> UpdateMass();
        }

      private: 
          
          physics::ModelPtr model;
          physics::ModelPtr iris;
          physics::WorldPtr world;
          event::ConnectionPtr updateConnection;   
          physics::LinkPtr  base_link;

      };

      // Register this plugin with the simulator
      GZ_REGISTER_MODEL_PLUGIN(joint_c)
    }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Ege Alşan
  • 21
  • 3