dynamics2d_gripping.cpp
Go to the documentation of this file.
1 
7 #include "dynamics2d_gripping.h"
8 #include "dynamics2d_engine.h"
9 
10 #include <argos3/core/simulator/entity/embodied_entity.h>
11 
12 #include <algorithm>
13 
14 namespace argos {
15 
16  /****************************************/
17  /****************************************/
18 
20  CGripperEquippedEntity& c_gripper_entity,
21  cpShape* pt_gripper_shape) :
22  m_cEngine(c_engine),
23  m_cGripperEntity(c_gripper_entity),
24  m_ptGripperShape(pt_gripper_shape),
25  m_pcGrippee(nullptr),
26  m_tConstraint(nullptr) {
27  m_ptGripperShape->sensor = 1;
28  m_ptGripperShape->collision_type = CDynamics2DEngine::SHAPE_GRIPPER;
29  m_ptGripperShape->data = this;
30  m_tGrippeeAnchor = cpvzero;
31  }
32 
33  /****************************************/
34  /****************************************/
35 
37  Release();
38  }
39 
40  /****************************************/
41  /****************************************/
42 
44  return
45  cpvdist(cpBodyGetPos(cpShapeGetBody(m_ptGripperShape)),
46  cpBodyGetPos(cpShapeGetBody(m_pcGrippee->GetShape()))) /
47  m_fRestLength - 1.0;
48 
49  }
50 
51  /****************************************/
52  /****************************************/
53 
54  void CDynamics2DGripper::CalculateAnchor(cpArbiter* pt_arb) {
55  /* Calculate the anchor point on the grippable body
56  as the centroid of the contact points */
57  m_tGrippeeAnchor = cpvzero;
58  for(SInt32 i = 0; i < cpArbiterGetCount(pt_arb); ++i) {
59  m_tGrippeeAnchor = cpvadd(m_tGrippeeAnchor, cpArbiterGetPoint(pt_arb, i));
60  }
61  m_tGrippeeAnchor = cpvmult(m_tGrippeeAnchor, 1.0f / cpArbiterGetCount(pt_arb));
62  /* Calculate rest length */
63  CP_ARBITER_GET_BODIES(pt_arb, ptGripperBody, ptGrippeeBody);
64  m_fRestLength = cpvdist(cpBodyGetPos(ptGripperBody),
65  m_tGrippeeAnchor);
66  }
67 
68  /****************************************/
69  /****************************************/
70 
71  static cpFloat GRIPPING_SPRING_DAMPING = 0.99;
72 
74  m_tConstraint =
75  cpSpaceAddConstraint(m_cEngine.GetPhysicsSpace(),
76  cpDampedSpringNew(
77  cpShapeGetBody(m_ptGripperShape),
78  cpShapeGetBody(pc_grippee->GetShape()),
79  cpvzero,
80  cpBodyWorld2Local(cpShapeGetBody(pc_grippee->GetShape()),
81  m_tGrippeeAnchor),
82  m_fRestLength,
83  m_cEngine.GetGrippingRigidity(),
84  GRIPPING_SPRING_DAMPING));
85  m_tConstraint->maxBias = 0.95f; // Correct overlap
86  m_tConstraint->maxForce = 10000.0f; // Max correction speed
87  m_cGripperEntity.SetGrippedEntity(pc_grippee->GetEmbodiedEntity());
88  m_pcGrippee = pc_grippee;
89  m_pcGrippee->Attach(*this);
90  }
91 
92  /****************************************/
93  /****************************************/
94 
96  if(IsGripping()) {
97  cpSpaceRemoveConstraint(m_cEngine.GetPhysicsSpace(), m_tConstraint);
98  cpConstraintFree(m_tConstraint);
99  m_tConstraint = nullptr;
100  m_cGripperEntity.ClearGrippedEntity();
101  m_pcGrippee->Remove(*this);
102  m_pcGrippee = nullptr;
103  }
104  }
105 
106  /****************************************/
107  /****************************************/
108 
110  cpShape* pt_shape) :
111  m_cEmbodiedEntity(c_entity),
112  m_ptShape(pt_shape) {
113  m_ptShape->collision_type = CDynamics2DEngine::SHAPE_GRIPPABLE;
114  m_ptShape->data = this;
115  }
116 
117  /****************************************/
118  /****************************************/
119 
121  ReleaseAll();
122  }
123 
124  /****************************************/
125  /****************************************/
126 
128  m_listGrippers.push_back(&c_gripper);
129  }
130 
131  /****************************************/
132  /****************************************/
133 
135  auto it =
136  std::find(m_listGrippers.begin(), m_listGrippers.end(), &c_gripper);
137  if(it != m_listGrippers.end()) {
138  m_listGrippers.erase(it);
139  }
140  }
141 
142  /****************************************/
143  /****************************************/
144 
146  auto it =
147  std::find(m_listGrippers.begin(), m_listGrippers.end(), &c_gripper);
148  if(it != m_listGrippers.end()) {
149  (*it)->Release();
150  }
151  }
152 
153  /****************************************/
154  /****************************************/
155 
157  while(!m_listGrippers.empty()) {
158  m_listGrippers.back()->Release();
159  }
160  }
161 
162  /****************************************/
163  /****************************************/
164 
166  cpSpace* pt_space,
167  void* p_data) {
168  /* Get the shapes involved */
169  CP_ARBITER_GET_SHAPES(pt_arb, ptGripperShape, ptGrippableShape);
170  /* Get a reference to the gripper data */
171  auto* pcGripper = reinterpret_cast<CDynamics2DGripper*>(ptGripperShape->data);
172  /* Get a reference to the grippable entity */
173  auto* pcGrippable = reinterpret_cast<CDynamics2DGrippable*>(ptGrippableShape->data);
174  /* If the entities match, ignore the collision forever */
175  return (&(pcGripper->GetGripperEntity().GetParent()) != &(pcGrippable->GetEmbodiedEntity().GetParent()));
176  }
177 
178  /****************************************/
179  /****************************************/
180 
182  cpSpace* pt_space,
183  void* p_data) {
184  /* Get the shapes involved */
185  CP_ARBITER_GET_SHAPES(pt_arb, ptGripperShape, ptGrippableShape);
186  /* Get a reference to the gripper data */
187  auto* pcGripper = reinterpret_cast<CDynamics2DGripper*>(ptGripperShape->data);
188  /*
189  * When to process gripping:
190  * 1. when the robot was gripping and it just unlocked the gripper
191  * 2. when the robot was not gripping and it just locked the gripper
192  * in this case, also precalculate the anchor point
193  * Otherwise ignore it
194  */
195  if(pcGripper->IsGripping() && !pcGripper->IsLocked()) {
196  /* Instruct the engine to remove the constraint in a post-step callback */
197  cpSpaceAddPostStepCallback(
198  pt_space,
200  pcGripper,
201  ptGrippableShape->data);
202  return false;
203  }
204  if(!pcGripper->IsGripping() && pcGripper->IsLocked()) {
205  pcGripper->CalculateAnchor(pt_arb);
206  /* Instruct the engine to add the constraint in a post-step callback */
207  cpSpaceAddPostStepCallback(
208  pt_space,
210  pcGripper,
211  reinterpret_cast<CDynamics2DGrippable*>(ptGrippableShape->data));
212  return false;
213  }
214  /* Always return false, anyway the gripper is a sensor shape */
215  return false;
216  }
217 
218  /****************************************/
219  /****************************************/
220 
222  void* p_obj,
223  void* p_data) {
224  /* Get the objects involved */
225  auto pcGripper = reinterpret_cast<CDynamics2DGripper*> (p_obj);
226  auto pcGrippable = reinterpret_cast<CDynamics2DGrippable*>(p_data);
227  /* Connect the objects */
228  pcGripper->Grip(pcGrippable);
229  }
230 
231  /****************************************/
232  /****************************************/
233 
235  void* p_obj,
236  void* p_data) {
237  /* Get the gripper objects */
238  auto pcGripper = reinterpret_cast<CDynamics2DGripper*> (p_obj);
239  /* Disconnect the objects */
240  pcGripper->Release();
241  }
242 
243  /****************************************/
244  /****************************************/
245 
246 }
signed int SInt32
32-bit signed integer.
Definition: datatypes.h:93
float Real
Collects all ARGoS code.
Definition: datatypes.h:39
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
int BeginCollisionBetweenGripperAndGrippable(cpArbiter *pt_arb, cpSpace *pt_space, void *p_data)
void AddConstraintBetweenGripperAndGrippable(cpSpace *pt_space, void *p_obj, void *p_data)
void RemoveConstraintBetweenGripperAndGrippable(cpSpace *pt_space, void *p_obj, void *p_data)
int ManageCollisionBetweenGripperAndGrippable(cpArbiter *pt_arb, cpSpace *pt_space, void *p_data)
This entity is a link to a body in the physics engine.
An entity that stores the state of a robot gripper.
void SetGrippedEntity(CEmbodiedEntity &c_entity)
Sets the embodied entity currently gripped by this gripper.
void ClearGrippedEntity()
Clears the reference to the embodied entity currently gripped by this gripper.
void CalculateAnchor(cpArbiter *pt_arb)
void Grip(CDynamics2DGrippable *pc_grippee)
Real GetExtension() const
Returns the extension of the constraint.
CDynamics2DGripper(CDynamics2DEngine &c_engine, CGripperEquippedEntity &c_gripper_entity, cpShape *pt_gripper_shape)
void Release(CDynamics2DGripper &c_gripper)
void Remove(CDynamics2DGripper &c_gripper)
void Attach(CDynamics2DGripper &c_gripper)
CDynamics2DGrippable(CEmbodiedEntity &c_entity, cpShape *pt_shape)
CEmbodiedEntity & GetEmbodiedEntity()