9#include <argos3/plugins/robots/prototype/simulator/prototype_entity.h>
10#include <argos3/plugins/robots/prototype/simulator/prototype_joint_equipped_entity.h>
11#include <argos3/plugins/robots/prototype/simulator/prototype_link_equipped_entity.h>
12#include <argos3/plugins/simulator/entities/magnet_equipped_entity.h>
13#include <argos3/plugins/simulator/physics_engines/dynamics3d/dynamics3d_multi_body_object_model.h>
14#include <argos3/plugins/simulator/physics_engines/dynamics3d/dynamics3d_shape_manager.h>
15#include <argos3/plugins/simulator/physics_engines/dynamics3d/dynamics3d_engine.h>
22 std::shared_ptr<btCollisionShape> CDynamics3DPrototypeModel::RequestShape(
const CPrototypeLinkEntity& c_link_entity) {
23 btVector3 cHalfExtents(c_link_entity.GetExtents().GetX() * 0.5f,
24 c_link_entity.GetExtents().GetZ() * 0.5f,
25 c_link_entity.GetExtents().GetY() * 0.5f);
26 std::vector<btVector3> vecConvexHullPoints;
27 std::shared_ptr<btCollisionShape> ptrShape;
28 switch(c_link_entity.GetGeometry()) {
39 vecConvexHullPoints.reserve(c_link_entity.GetConvexHullPoints().size());
40 for(
const CVector3& c_point : c_link_entity.GetConvexHullPoints()) {
41 vecConvexHullPoints.emplace_back(c_point.GetX(),
57 CDynamics3DMultiBodyObjectModel::CAbstractBody::SData
58 CDynamics3DPrototypeModel::CreateBodyData(
const CPrototypeLinkEntity& c_link_entity) {
62 btScalar fMass = c_link_entity.GetMass();
64 RequestShape(c_link_entity)->calculateLocalInertia(fMass, cInertia);
66 const CVector3& cPosition = c_link_entity.GetAnchor().Position;
67 const CQuaternion& cOrientation = c_link_entity.GetAnchor().Orientation;
68 btTransform cStartTransform(btQuaternion(cOrientation.GetX(),
72 btVector3(cPosition.GetX(),
76 btTransform cCenterOfMassOffset(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f),
77 btVector3(0.0f, -c_link_entity.GetExtents().GetZ() * 0.5f, 0.0f));
78 std::vector<CAbstractBody::SData::SDipole> vecDipoles;
83 for(CMagnetEquippedEntity::SInstance& s_instance : vecInstances) {
85 if(s_instance.Anchor.Index == c_link_entity.GetAnchor().Index) {
86 btTransform cOffset(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f),
87 btVector3(s_instance.Offset.GetX(),
88 s_instance.Offset.GetZ(),
89 -s_instance.Offset.GetY()));
90 cOffset *= cCenterOfMassOffset;
91 std::function<btVector3()> fnGetField = [&s_instance] () {
92 const CVector3& cField = s_instance.Magnet.GetField();
93 return btVector3(cField.GetX(), cField.GetZ(), -cField.GetY());
95 vecDipoles.emplace_back(fnGetField, cOffset);
100 return CAbstractBody::SData(cStartTransform, cCenterOfMassOffset, cInertia, fMass, fFriction, vecDipoles);
111 c_entity.GetLinkEquippedEntity().GetLinks().size() - 1,
112 !c_entity.GetEmbodiedEntity().IsMovable()),
114 m_cJointEquippedEntity(c_entity.GetJointEquippedEntity()) {
118 std::shared_ptr<btCollisionShape> ptrBaseLinkShape = RequestShape(cBaseLink);
120 std::shared_ptr<CBase> ptrBase =
121 std::make_shared<CBase>(*
this, &cBaseLink.
GetAnchor(), ptrBaseLinkShape, CreateBodyData(cBaseLink));
130 while(! vecJointsToAdd.empty()) {
131 size_t unRemainingJoints = vecJointsToAdd.size();
132 for(
auto it_joint = std::begin(vecJointsToAdd);
133 it_joint != std::end(vecJointsToAdd);
140 auto itParentLinkBody =
143 [&cParentLink] (
const std::shared_ptr<CAbstractBody>& ptr_body) {
144 return (cParentLink.
GetAnchor().
Index == ptr_body->GetAnchor().Index);
151 std::shared_ptr<CLink> ptrParentLinkBody =
152 std::static_pointer_cast<CLink>(*itParentLinkBody);
156 std::shared_ptr<btCollisionShape> ptrChildLinkShape =
157 RequestShape(cChildLink);
159 std::shared_ptr<CLink> ptrChildLinkBody =
160 std::make_shared<CLink>(*
this,
164 CreateBodyData(cChildLink));
170 btTransform cParentOffsetTransform =
171 btTransform(btQuaternion(cParentOffsetOrientation.
GetX(),
172 cParentOffsetOrientation.
GetZ(),
173 -cParentOffsetOrientation.
GetY(),
174 cParentOffsetOrientation.
GetW()),
175 btVector3(cParentOffsetPosition.
GetX(),
176 cParentOffsetPosition.
GetZ(),
177 -cParentOffsetPosition.
GetY()));
178 cParentOffsetTransform = ptrParentLinkBody->GetData().CenterOfMassOffset * cParentOffsetTransform;
182 btTransform cChildOffsetTransform =
183 btTransform(btQuaternion(cChildOffsetOrientation.
GetX(),
184 cChildOffsetOrientation.
GetZ(),
185 -cChildOffsetOrientation.
GetY(),
186 cChildOffsetOrientation.
GetW()),
187 btVector3(cChildOffsetPosition.
GetX(),
188 cChildOffsetPosition.
GetZ(),
189 -cChildOffsetPosition.
GetY()));
190 cChildOffsetTransform = ptrChildLinkBody->GetData().CenterOfMassOffset * cChildOffsetTransform;
201 btQuaternion cParentToChildRotation = cChildOffsetTransform.getRotation() *
202 cParentOffsetTransform.inverse().getRotation();
204 m_vecJoints.emplace_back(cJoint.
GetType(),
207 cParentOffsetTransform.getOrigin(),
208 -cChildOffsetTransform.getOrigin(),
209 cParentToChildRotation,
218 m_vecActuators.emplace_back(*
this, sActuator, ptrChildLinkBody->GetIndex());
223 m_vecSensors.emplace_back(*
this, sSensor, ptrChildLinkBody->GetIndex());
230 m_vecLimits.emplace_back(*
this,
231 cLimit.
GetMin().GetValue(),
232 cLimit.
GetMax().GetValue(),
233 ptrChildLinkBody->GetIndex());
237 m_vecLimits.emplace_back(*
this,
240 ptrChildLinkBody->GetIndex());
245 vecJointsToAdd.erase(it_joint);
248 if(unRemainingJoints == vecJointsToAdd.size()) {
252 "\" to the model before its parent link \"" <<
254 "\" has been added.");
260 [pc_link] (std::shared_ptr<CAbstractBody>& ptr_body) {
261 return (pc_link->GetAnchor().Index == ptr_body->GetAnchor().Index);
264 "\" is not connected to the model.");
279 for(SActuator& s_actuator : m_vecActuators) {
280 c_world.addMultiBodyConstraint(&s_actuator.Motor);
283 for(SLimit& s_limit : m_vecLimits) {
284 c_world.addMultiBodyConstraint(&s_limit.Constraint);
293 for(SLimit& s_limit : m_vecLimits) {
294 c_world.removeMultiBodyConstraint(&s_limit.Constraint);
297 for(SActuator& s_actuator : m_vecActuators) {
298 c_world.removeMultiBodyConstraint(&s_actuator.Motor);
311 for(SJoint& s_joint : m_vecJoints) {
312 switch(s_joint.Type) {
315 s_joint.Child->GetData().Mass,
316 s_joint.Child->GetData().Inertia,
317 s_joint.Parent->GetIndex(),
318 s_joint.ParentToChildRotation,
319 s_joint.ParentOffset,
320 s_joint.ChildOffset);
324 s_joint.Child->GetData().Mass,
325 s_joint.Child->GetData().Inertia,
326 s_joint.Parent->GetIndex(),
327 s_joint.ParentToChildRotation,
328 s_joint.ParentOffset,
330 s_joint.DisableCollision);
334 s_joint.Child->GetData().Mass,
335 s_joint.Child->GetData().Inertia,
336 s_joint.Parent->GetIndex(),
337 s_joint.ParentToChildRotation,
339 s_joint.ParentOffset,
341 s_joint.DisableCollision);
345 s_joint.Child->GetData().Mass,
346 s_joint.Child->GetData().Inertia,
347 s_joint.Parent->GetIndex(),
348 s_joint.ParentToChildRotation,
350 s_joint.ParentOffset,
352 s_joint.DisableCollision);
359 for(SActuator& s_actuator : m_vecActuators) {
363 for(SLimit& s_limit : m_vecLimits) {
377 for(SSensor& s_sensor : m_vecSensors) {
389 for(SActuator& s_actuator : m_vecActuators) {
398 std::shared_ptr<CLink>& ptr_parent,
399 std::shared_ptr<CLink>& ptr_child,
400 const btVector3& c_parent_offset,
401 const btVector3& c_child_offset,
402 const btQuaternion& c_parent_to_child_rotation,
403 const btVector3& c_axis,
404 bool b_disable_collision) :
408 ParentOffset(c_parent_offset),
409 ChildOffset(c_child_offset),
410 ParentToChildRotation(c_parent_to_child_rotation),
412 DisableCollision(b_disable_collision) {}
417 CDynamics3DPrototypeModel::SLimit::SLimit(CDynamics3DPrototypeModel& c_model,
422 LowerLimit(f_lower_limit),
423 UpperLimit(f_upper_limit),
424 JointIndex(n_joint_index),
425 Constraint(&c_model.GetMultiBody(),
433 void CDynamics3DPrototypeModel::SLimit::Reset() {
434 Constraint.~btMultiBodyJointLimitConstraint();
435 new (&Constraint) btMultiBodyJointLimitConstraint(&Model.
GetMultiBody(),
445 CPrototypeJointEntity::SActuator& s_actuator,
448 Actuator(s_actuator),
449 JointIndex(n_joint_index),
454 s_actuator.MaxImpulse) {}
459 void CDynamics3DPrototypeModel::SActuator::Reset() {
460 Motor.~btMultiBodyJointMotor();
461 new (&Motor) btMultiBodyJointMotor(&Model.
GetMultiBody(),
471 void CDynamics3DPrototypeModel::SActuator::Update() {
473 Motor.setPositionTarget(Actuator.Target);
476 Motor.setVelocityTarget(Actuator.Target);
484 CPrototypeJointEntity::SSensor& s_sensor,
488 JointIndex(n_joint_index) {}
493 void CDynamics3DPrototypeModel::SSensor::Update() {
#define REGISTER_STANDARD_DYNAMICS3D_OPERATIONS_ON_ENTITY(SPACE_ENTITY, DYN3D_ENTITY)
signed int SInt32
32-bit signed integer.
unsigned int UInt32
32-bit unsigned integer.
float Real
Collects all ARGoS code.
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
The namespace containing all the ARGoS related code.
const std::string & GetId() const
Returns the id of this entity.
UInt32 Index
The index of the anchor assigned by the embodied entity.
virtual void UpdateEntityStatus()
Updates the status of the associated entity.
Real GetX() const
Returns the x coordinate of this vector.
Real GetY() const
Returns the y coordinate of this vector.
Real GetZ() const
Returns the z coordinate of this vector.
virtual void RemoveFromWorld(btMultiBodyDynamicsWorld &c_world)
virtual void AddToWorld(btMultiBodyDynamicsWorld &c_world)
virtual void UpdateEntityStatus()
Updates the status of the associated entity.
CDynamics3DPrototypeModel(CDynamics3DEngine &c_engine, CPrototypeEntity &c_entity)
virtual void UpdateFromEntityStatus()
Updates the state of this model from the status of the associated entity.
CMagnetEquippedEntity & GetMagnetEquippedEntity()
bool HasMagnetEquippedEntity() const
CPrototypeLinkEquippedEntity & GetLinkEquippedEntity()
const ULimit & GetLimit() const
const CVector3 & GetJointAxis() const
const CVector3 & GetChildLinkJointPosition() const
CPrototypeLinkEntity & GetParentLink()
SActuator & GetActuator()
std::vector< CPrototypeJointEntity * > TVector
bool GetDisableCollision() const
const CVector3 & GetParentLinkJointPosition() const
CPrototypeLinkEntity & GetChildLink()
const CQuaternion & GetChildLinkJointOrientation() const
const CQuaternion & GetParentLinkJointOrientation() const
CRange< CRadians > Revolute
CPrototypeJointEntity::TVector & GetJoints()
CPrototypeLinkEntity::TVector & GetLinks()
SInstance::TVector & GetInstances()
std::vector< SInstance > TVector
btScalar GetDefaultFriction() const
std::vector< std::shared_ptr< CAbstractBody > > m_vecBodies
CDynamics3DEngine & GetEngine()
virtual void RemoveFromWorld(btMultiBodyDynamicsWorld &c_world)
btMultiBody & GetMultiBody()
virtual void AddToWorld(btMultiBodyDynamicsWorld &c_world)
static std::shared_ptr< btCollisionShape > RequestBox(const btVector3 &c_half_extents)
static std::shared_ptr< btCollisionShape > RequestSphere(btScalar f_radius)
static std::shared_ptr< btCollisionShape > RequestConvexHull(const std::vector< btVector3 > &vec_points)
static std::shared_ptr< btCollisionShape > RequestCylinder(const btVector3 &c_half_extents)