Ask Your Question
2

Gazebo magnet simulation

asked 2011-10-19 21:56:42 -0500

erkmns gravatar image

Hi,

Is there a way to make two objects exert forces on each other in gazebo, to simulate for instance a magnet or vacuum gripper?

If not, is it possible to dynamically connect and disconnect object frames?

Kind regards, Eli

edit retag flag offensive close merge delete

Comments

Good question !
Arkapravo gravatar image Arkapravo  ( 2011-10-20 06:40:46 -0500 )edit
We came up with a work-around, making external forces interact with both objects, using the apply_body_wrench service. The reference frame being the frame of the other object, and the wrench defined as a negative force in direction z.
erkmns gravatar image erkmns  ( 2011-10-27 21:37:43 -0500 )edit
Can you put your result in some website or video ? Should be very interesting.
Arkapravo gravatar image Arkapravo  ( 2011-11-04 22:32:10 -0500 )edit

4 Answers

Sort by » oldest newest most voted
1

answered 2012-04-13 00:27:39 -0500

Usually, it is much better to use Gazebo plugins instead of the apply_body_wrench service. The reason is that a Gazebo plugin is run exactly once for every simulation cycle, while the apply_body_wrench service interacts with the simulation in irregular intervals, leading to instabilities.

To do this:

  • specify each cubelet in an URDF file
  • add a Gazebo controller which excerts the magnetic forces

As an example of how to do this, you can look at the package manipulation_worlds, where they use a Plugin called gazebo_ros_grasp_hack to magically attach a grasped object to the PR2 gripper when both fingers make contact, in order to stop it from jittering out.

edit flag offensive delete link more

Comments

Hi there, I saw your answer was written in 2012, I hope you are still there following gazebo, I have been trying to use this gazebo_ros_grasp_hack for so long and I couldnt figure out how to use it, may be because there isnt much of tutorials around for this plugin. I would be really really grateful

Abdullah gravatar image Abdullah  ( 2016-08-28 06:51:47 -0500 )edit
0

answered 2012-04-11 19:21:10 -0500

mcevoyandy gravatar image

I'll have to check out trinighost's post...

BUT... I did try the apply_body_wrench method for what I'm working on and I don't think it will work.

youtube video of trying to get cubelets to stick together. My end goal is running a simulation with the PR2 putting them together. Right now I'm trying to figure out the best way to make the cubelets attach to each other.

edit flag offensive delete link more

Comments

(posted as comment here since I don't have enough karma to comment below)

Thanks Martin, that's actually what I'm trying now. Thought I'd at least try since the first post said they got something useful out of it and I haven't been able to find good documentation on gazebo plugins.

mcevoyandy gravatar image mcevoyandy  ( 2012-04-13 04:08:46 -0500 )edit
0

answered 2012-04-10 07:52:37 -0500

SL Remy gravatar image

This patch was for an older version of Gazebo, but should be what you need to get started. This patch permits a gripper to be used to turn the magnet on, and whatever is connected that isn't already connected will attach itself (I do not recall if only the first body or any body that's connected).

Hopefully you can complete the ROS Gazebo changes and add it here. Good luck!

Index: server/sensors/contact/ContactSensor.hh
===================================================================
--- server/sensors/contact/ContactSensor.hh (revision 7322)
+++ server/sensors/contact/ContactSensor.hh (working copy)
@@ -62,12 +62,18 @@
     /// \brief Return the number of contacts
     public: unsigned int GetContactCount() const;

+    /// \brief Return the sensor's body
+    public: Body* GetBody() const;
+
     /// \brief Get a contact time
     public: double GetContactTime(unsigned int index) const;

     /// \brief Return a contact state
     public: uint8_t GetContactState(unsigned int index) const;

+    /// \brief Return a contact GeomID
+    public: Body* GetContactBody(unsigned int index) const;
+
     /// \brief Reset the contact states
     public: void ResetContactStates();

@@ -96,6 +102,8 @@
     private: uint8_t *contactStates;
     private: double *contactTimes;
     private: unsigned int contactCount;
+    private: Body**  contactBody; //added by gte
+
   };
   /// \}
   /// \}
Index: server/sensors/contact/ContactSensor.cc
===================================================================
--- server/sensors/contact/ContactSensor.cc (revision 7322)
+++ server/sensors/contact/ContactSensor.cc (working copy)
@@ -37,6 +37,7 @@
 #include "Simulator.hh"
 #include "SensorFactory.hh"
 #include "Geom.hh"
+#include "Body.hh"
 #include "ContactParams.hh"
 #include "ContactSensor.hh"

@@ -57,6 +58,7 @@

   this->contactCount = 0;
   this->contactStates = NULL;
+  this->contactBody = NULL; 
 }


@@ -69,6 +71,9 @@
   if (this->contactStates)
     delete [] this->contactStates;

+  if (this->contactBody)  
+    delete [] this->contactBody;
+
   if (this->contactTimes)
     delete [] this->contactTimes;

@@ -90,6 +95,16 @@
 }

 //////////////////////////////////////////////////////////////////////////////
+/// Get the contact Geom
+Body * ContactSensor::GetContactBody(unsigned int index) const
+{
+  if (index < this->contactCount)
+    return this->contactBody[ index ];
+
+  return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
 /// Return the number of contacts
 unsigned int ContactSensor::GetContactCount() const
 {
@@ -97,6 +112,13 @@
 }

 //////////////////////////////////////////////////////////////////////////////
+/// Return the number of contacts
+Body* ContactSensor::GetBody() const
+{
+  return this->body;
+}
+
+//////////////////////////////////////////////////////////////////////////////
 /// Return the contact states
 uint8_t ContactSensor::GetContactState(unsigned int index) const
 {
@@ -111,6 +133,7 @@
 void ContactSensor::ResetContactStates()
 {
   memset(this->contactStates, 0, sizeof(uint8_t) * this->contactCount);
+  memset(this->contactBody, 0, sizeof(Body*) * this->contactCount); 
 }

 //////////////////////////////////////////////////////////////////////////////
@@ -138,9 +161,11 @@
   this->contactCount = this->geomNamesP.size();
   this->contactTimes = new double[ this->contactCount ];
   this->contactStates = new uint8_t[ this->contactCount ];
+  this->contactBody = new Body* [ this->contactCount ];  

+
   memset(this->contactStates,0, sizeof(uint8_t) * this->contactCount);
-  memset(this->contactStates,0, sizeof(double) * this->contactCount);
+//  memset(this->contactStates,0, sizeof(double) * this->contactCount);
 }

 //////////////////////////////////////////////////////////////////////////////
@@ -197,8 +222,34 @@
 {
   std::vector< ParamT<std::string> *>::iterator iter;
   int i = 0;
+  for (iter = this->geomNamesP.begin(); iter != this->geomNamesP.end(); 
+       iter++, i++)
+  {
+    if ( **(*iter) == g1->GetName())
+    {
+      this->contactStates[i] = 1;
+      this->contactBody[i] = (Body*)g2->GetParent(); 
+      this->contactTimes[i] = Simulator::Instance()->GetRealTime();
+    }else if (**(*iter) == g2->GetName() )
+    {
+      this->contactStates[i] = 1;
+      this->contactBody[i] = (Body*)g1->GetParent(); 
+      this->contactTimes[i] = Simulator::Instance()->GetRealTime();

+    }
+  }
+}

+
+/*
+//////////////////////////////////////////////////////////////////////////////
+/// Contact callback
+void ContactSensor::ContactCallback(Geom *g1, Geom *g2)
+{
+  std::vector< ParamT<std::string> *>::iterator iter;
+  int i = 0;
+
+
   for (iter = this->geomNamesP.begin(); iter != this->geomNamesP.end(); 
        iter++, i++)
   {
@@ -209,4 +260,4 @@
     }
   }

-}
+}*/
Index: server/controllers/contactMagnet/SConscript
===================================================================
--- server ...
(more)
edit flag offensive delete link more
0

answered 2012-04-09 16:57:01 -0500

this post is marked as community wiki

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

From @erkmns We came up with a work-around, making external forces interact with both objects, using the apply_body_wrench service. The reference frame being the frame of the other object, and the wrench defined as a negative force in direction

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2011-10-19 21:56:42 -0500

Seen: 1,423 times

Last updated: Apr 13 '12