ARGoS 3
A parallel, multi-engine simulator for swarm robotics
dynamics2d_gripping.cpp
Go to the documentation of this file.
1
8#include "dynamics2d_engine.h"
9
10#include <argos3/core/simulator/entity/embodied_entity.h>
11
12#include <algorithm>
13
14namespace 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
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
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)
CEmbodiedEntity & GetEmbodiedEntity()
CDynamics2DGrippable(CEmbodiedEntity &c_entity, cpShape *pt_shape)