ARGoS 3
A parallel, multi-engine simulator for swarm robotics
dynamics3d_multi_body_object_model.cpp
Go to the documentation of this file.
1
8
9#include <argos3/core/simulator/entity/composable_entity.h>
10
11#include <argos3/core/utility/math/matrix/transformationmatrix3.h>
12
13namespace argos {
14
15 /****************************************/
16 /****************************************/
17
19 CComposableEntity& c_entity,
20 UInt32 un_num_links,
21 bool b_fixed_base) :
22 CDynamics3DModel(c_engine, c_entity),
23 m_cMultiBody(un_num_links, 0.0f, btVector3(0,0,0), b_fixed_base, false),
24 m_unNumLinks(un_num_links),
25 m_bFixedBase(b_fixed_base) {
26 /* Register the origin anchor update method */
27 RegisterAnchorMethod(GetEmbodiedEntity().GetOriginAnchor(),
29 }
30
31 /****************************************/
32 /****************************************/
33
35 /* Run the multi-body destructor */
36 m_cMultiBody.~btMultiBody();
37 /* Rerun the multi-body constructor */
38 new (&m_cMultiBody) btMultiBody(m_unNumLinks,
39 m_vecBodies[0]->GetData().Mass,
40 m_vecBodies[0]->GetData().Inertia,
42 false);
43 /* Disable collisions between bodies in the same model */
44 m_cMultiBody.setHasSelfCollision(false);
45 /* Reset bodies */
46 for(const std::shared_ptr<CAbstractBody>& ptr_body : m_vecBodies) {
47 ptr_body->Reset();
48 }
49 /* TODO. For the moment, we rely on the class that derives from
50 this model to call UpdateEntityStatus after the joints
51 have been configured. This is ugly and should be fixed
52 by moving the code for joints into this class */
53 /* Synchronize with the entity in the space */
54 //UpdateEntityStatus();
55 }
56
57 /****************************************/
58 /****************************************/
59
60 void CDynamics3DMultiBodyObjectModel::AddToWorld(btMultiBodyDynamicsWorld& c_world) {
61 /* Prepare the multi-body (set up internal offsets, reserve memory) */
62 m_cMultiBody.finalizeMultiDof();
63 /* Add multi-body to the world */
64 c_world.addMultiBody(&m_cMultiBody);
65 /* Add the multi-body's links (collision objects) to the world */
66 for(const std::shared_ptr<CAbstractBody>& ptr_body : m_vecBodies) {
67 ptr_body->AddToWorld(c_world);
68 }
69 }
70
71 /****************************************/
72 /****************************************/
73
74 void CDynamics3DMultiBodyObjectModel::RemoveFromWorld(btMultiBodyDynamicsWorld& c_world) {
75 /* Remove the multi-body's links (collision objects) from the world */
76 for(const std::shared_ptr<CAbstractBody>& ptr_body : m_vecBodies) {
77 ptr_body->RemoveFromWorld(c_world);
78 }
79 /* Remove multi-body from the world */
80 c_world.removeMultiBody(&m_cMultiBody);
81 }
82
83 /****************************************/
84 /****************************************/
85
87 btVector3 cModelAabbMin, cModelAabbMax, cBodyAabbMin, cBodyAabbMax;
88 /* Initialize the bounding box with the base's AABB */
89 std::shared_ptr<CAbstractBody>& ptr_base = m_vecBodies[0];
90 ptr_base->GetShape().getAabb(ptr_base->GetTransform(), cModelAabbMin, cModelAabbMax);
91 /* Extend AABB to include other bodies */
92 for(const std::shared_ptr<CAbstractBody>& ptr_body : m_vecBodies) {
93 /* Get the axis aligned bounding box for the current body */
94 ptr_body->GetShape().getAabb(ptr_body->GetTransform(), cBodyAabbMin, cBodyAabbMax);
95 /* Update minimum corner */
96 cModelAabbMin.setX(cModelAabbMin.getX() < cBodyAabbMin.getX() ? cModelAabbMin.getX() : cBodyAabbMin.getX());
97 cModelAabbMin.setY(cModelAabbMin.getY() < cBodyAabbMin.getY() ? cModelAabbMin.getY() : cBodyAabbMin.getY());
98 cModelAabbMin.setZ(cModelAabbMin.getZ() < cBodyAabbMin.getZ() ? cModelAabbMin.getZ() : cBodyAabbMin.getZ());
99 /* Update maximum corner */
100 cModelAabbMax.setX(cModelAabbMax.getX() > cBodyAabbMax.getX() ? cModelAabbMax.getX() : cBodyAabbMax.getX());
101 cModelAabbMax.setY(cModelAabbMax.getY() > cBodyAabbMax.getY() ? cModelAabbMax.getY() : cBodyAabbMax.getY());
102 cModelAabbMax.setZ(cModelAabbMax.getZ() > cBodyAabbMax.getZ() ? cModelAabbMax.getZ() : cBodyAabbMax.getZ());
103 }
104 /* Write back the bounding box swapping the coordinate systems and the Y component */
105 GetBoundingBox().MinCorner.Set(cModelAabbMin.getX(), -cModelAabbMax.getZ(), cModelAabbMin.getY());
106 GetBoundingBox().MaxCorner.Set(cModelAabbMax.getX(), -cModelAabbMin.getZ(), cModelAabbMax.getY());
107 }
108
109 /****************************************/
110 /****************************************/
111
113 const CQuaternion& c_orientation) {
114 /* Calculate the destination transform */
115 const btTransform& cMoveToTransform =
116 btTransform(btQuaternion(c_orientation.GetX(),
117 c_orientation.GetZ(),
118 -c_orientation.GetY(),
119 c_orientation.GetW()),
120 btVector3(c_position.GetX(),
121 c_position.GetZ(),
122 -c_position.GetY()));
123 /* Calculate the origin anchor transform */
124 const SAnchor& sOriginAnchor = GetEmbodiedEntity().GetOriginAnchor();
125 const btTransform& cOriginAnchorTransform =
126 btTransform(btQuaternion(sOriginAnchor.Orientation.GetX(),
127 sOriginAnchor.Orientation.GetZ(),
128 -sOriginAnchor.Orientation.GetY(),
129 sOriginAnchor.Orientation.GetW()),
130 btVector3(sOriginAnchor.Position.GetX(),
131 sOriginAnchor.Position.GetZ(),
132 -sOriginAnchor.Position.GetY()));
133 /* Move the base of the model to the destination */
134 m_cMultiBody.setBaseWorldTransform(cMoveToTransform *
135 cOriginAnchorTransform.inverse() * m_cMultiBody.getBaseWorldTransform());
136 /* Move the remaining bodies */
137 btAlignedObjectArray<btQuaternion> vecRotations;
138 btAlignedObjectArray<btVector3> vecTranslations;
139 m_cMultiBody.updateCollisionObjectWorldTransforms(vecRotations, vecTranslations);
140 /* Update entity state */
142 }
143
144 /****************************************/
145 /****************************************/
146
148 /* Calculate the origin anchor's position and orientation from the base link's anchor */
149 const SAnchor& sBaseAnchor = m_vecBodies[0]->GetAnchor();
150 /* Calculate orientation */
151 CQuaternion cOriginAnchorOrientation = sBaseAnchor.OffsetOrientation.Inverse() *
152 sBaseAnchor.Orientation;
153 /* Calculate position */
154 CVector3 cOriginAnchorPosition = -sBaseAnchor.OffsetPosition;
155 cOriginAnchorPosition.Rotate(cOriginAnchorOrientation);
156 cOriginAnchorPosition += sBaseAnchor.Position;
157 /* Transfer to origin anchor */
158 s_anchor.Position = cOriginAnchorPosition;
159 s_anchor.Orientation = cOriginAnchorOrientation;
160 }
161
162 /****************************************/
163 /****************************************/
164
166 UInt32 un_link_index,
167 SAnchor* ps_anchor,
168 const std::shared_ptr<btCollisionShape>& ptr_shape,
169 const SData& s_data) :
170 CAbstractBody(c_model, ps_anchor, ptr_shape, s_data),
171 m_cModel(c_model),
172 m_unLinkIndex(un_link_index),
173 m_cMultiBodyLink(nullptr, 0) {}
174
175 /****************************************/
176 /****************************************/
177
179 /* Call the destructor */
180 m_cMultiBodyLink.~btMultiBodyLinkCollider();
181 /* Construct a new btMultiBodyLinkCollider in its place */
182 btMultiBody& cMultiBody = m_cModel.GetMultiBody();
183 new (&m_cMultiBodyLink) btMultiBodyLinkCollider(&cMultiBody, m_unLinkIndex);
184 /* Set up the btMultiBodyLinkCollider */
185 m_cMultiBodyLink.setCollisionShape(m_ptrShape.get());
186 m_cMultiBodyLink.setWorldTransform(m_sData.StartTransform *
187 m_sData.InverseCenterOfMassOffset);
188 m_cMultiBodyLink.setFriction(m_sData.Friction);
189 m_cMultiBodyLink.setUserPointer(&m_cModel);
190 cMultiBody.getLink(m_unLinkIndex).m_collider = &m_cMultiBodyLink;
191 }
192
193 /****************************************/
194 /****************************************/
195
196 void CDynamics3DMultiBodyObjectModel::CLink::AddToWorld(btMultiBodyDynamicsWorld& c_world) {
197 c_world.addCollisionObject(&m_cMultiBodyLink,
198 btBroadphaseProxy::DefaultFilter,
199 btBroadphaseProxy::AllFilter);
200 }
201
202 /****************************************/
203 /****************************************/
204
205 void CDynamics3DMultiBodyObjectModel::CLink::RemoveFromWorld(btMultiBodyDynamicsWorld& c_world) {
206 c_world.removeCollisionObject(&m_cMultiBodyLink);
207 }
208
209 /****************************************/
210 /****************************************/
211
213 btMultiBody& cMultiBody = m_cModel.GetMultiBody();
214 cMultiBody.addLinkForce(m_unLinkIndex, c_force);
215 }
216
217 /****************************************/
218 /****************************************/
219
221 const btVector3& c_offset) {
222 btMultiBody& cMultiBody = m_cModel.GetMultiBody();
223 cMultiBody.addLinkForce(m_unLinkIndex, c_force);
224 cMultiBody.addLinkTorque(m_unLinkIndex, c_offset.cross(c_force));
225 }
226
227 /****************************************/
228 /****************************************/
229
231 btMultiBody& cMultiBody = m_cModel.GetMultiBody();
232 cMultiBody.addLinkTorque(m_unLinkIndex, c_torque);
233 }
234
235 /****************************************/
236 /****************************************/
237
239 return m_cMultiBodyLink.getWorldTransform();
240 }
241
242 /****************************************/
243 /****************************************/
244
246 return m_unLinkIndex;
247 }
248
249 /****************************************/
250 /****************************************/
251
253 SAnchor* ps_anchor,
254 const std::shared_ptr<btCollisionShape>& ptr_shape,
255 const SData& s_data) :
256 CLink(c_model, -1, ps_anchor, ptr_shape, s_data) {}
257
258 /****************************************/
259 /****************************************/
260
262 /* Call the destructor */
263 m_cMultiBodyLink.~btMultiBodyLinkCollider();
264 /* Construct a new btMultiBodyLinkCollider in its place */
265 btMultiBody& cMultiBody = m_cModel.GetMultiBody();
266 new (&m_cMultiBodyLink) btMultiBodyLinkCollider(&cMultiBody, -1);
267 /* Set up the btMultiBodyLinkCollider */
268 m_cMultiBodyLink.setCollisionShape(m_ptrShape.get());
269 m_cMultiBodyLink.setWorldTransform(m_sData.StartTransform *
270 m_sData.InverseCenterOfMassOffset);
271 m_cMultiBodyLink.setFriction(m_sData.Friction);
272 m_cMultiBodyLink.setUserPointer(&m_cModel);
273 /* Set up the base */
274 cMultiBody.setBaseWorldTransform(m_sData.StartTransform * m_sData.InverseCenterOfMassOffset);
275 cMultiBody.setBaseCollider(&m_cMultiBodyLink);
276 }
277
278 /****************************************/
279 /****************************************/
280
282 btMultiBody& cMultiBody = m_cModel.GetMultiBody();
283 cMultiBody.addBaseForce(c_force);
284 }
285
286 /****************************************/
287 /****************************************/
288
290 const btVector3& c_offset) {
291 btMultiBody& cMultiBody = m_cModel.GetMultiBody();
292 cMultiBody.addBaseForce(c_force);
293 cMultiBody.addBaseTorque(c_offset.cross(c_force));
294 }
295
296 /****************************************/
297 /****************************************/
298
300 btMultiBody& cMultiBody = m_cModel.GetMultiBody();
301 cMultiBody.addBaseTorque(c_torque);
302 }
303
304 /****************************************/
305 /****************************************/
306
307}
308
unsigned int UInt32
32-bit unsigned integer.
Definition datatypes.h:97
The namespace containing all the ARGoS related code.
Definition ci_actuator.h:12
Basic class for an entity that contains other entities.
const SAnchor & GetOriginAnchor() const
Returns a const reference to the origin anchor associated to this entity.
An anchor related to the body of an entity.
CQuaternion Orientation
The orientation of the anchor wrt the global coordinate system.
CQuaternion OffsetOrientation
The initial orientation of the anchor wrt the body coordinate system.
CVector3 Position
The position of the anchor wrt the global coordinate system.
CVector3 OffsetPosition
The initial position of the anchor wrt the body coordinate system.
void RegisterAnchorMethod(const SAnchor &s_anchor, void(MODEL::*pt_method)(SAnchor &))
Registers an anchor method.
const SBoundingBox & GetBoundingBox() const
Returns an axis-aligned box that contains the physics model.
CEmbodiedEntity & GetEmbodiedEntity()
Returns the embodied entity associated to this physics model.
CQuaternion Inverse() const
Definition quaternion.h:98
Real GetW() const
Definition quaternion.h:49
Real GetX() const
Definition quaternion.h:53
Real GetZ() const
Definition quaternion.h:61
Real GetY() const
Definition quaternion.h:57
A 3D vector class.
Definition vector3.h:31
CVector3 & Rotate(const CQuaternion &c_quaternion)
Rotates this vector by the given quaternion.
Definition vector3.cpp:23
Real GetX() const
Returns the x coordinate of this vector.
Definition vector3.h:105
void Set(const Real f_x, const Real f_y, const Real f_z)
Sets the vector contents from Cartesian coordinates.
Definition vector3.h:155
Real GetY() const
Returns the y coordinate of this vector.
Definition vector3.h:121
Real GetZ() const
Returns the z coordinate of this vector.
Definition vector3.h:137
std::vector< std::shared_ptr< CAbstractBody > > m_vecBodies
virtual void UpdateEntityStatus()
Updates the status of the associated entity.
virtual void RemoveFromWorld(btMultiBodyDynamicsWorld &c_world)
virtual void CalculateBoundingBox()
Calculates the axis-aligned box that contains the entire physics model.
virtual void AddToWorld(btMultiBodyDynamicsWorld &c_world)
virtual void MoveTo(const CVector3 &c_position, const CQuaternion &c_orientation)
CDynamics3DMultiBodyObjectModel(CDynamics3DEngine &c_engine, CComposableEntity &c_entity, UInt32 un_num_links, bool b_fixed_base)
CLink(CDynamics3DMultiBodyObjectModel &c_model, UInt32 un_link_index, SAnchor *ps_anchor, const std::shared_ptr< btCollisionShape > &ptr_shape, const SData &s_data)
virtual void RemoveFromWorld(btMultiBodyDynamicsWorld &c_world)
virtual void AddToWorld(btMultiBodyDynamicsWorld &c_world)
CBase(CDynamics3DMultiBodyObjectModel &c_model, SAnchor *ps_anchor, const std::shared_ptr< btCollisionShape > &ptr_shape, const SData &s_data)