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()) {
29 case CPrototypeLinkEntity::EGeometry::BOX:
32 case CPrototypeLinkEntity::EGeometry::CYLINDER:
35 case CPrototypeLinkEntity::EGeometry::SPHERE:
38 case CPrototypeLinkEntity::EGeometry::CONVEX_HULL:
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(),
444 CDynamics3DPrototypeModel::SActuator::SActuator(CDynamics3DPrototypeModel& c_model,
445 CPrototypeJointEntity::SActuator& s_actuator,
448 Actuator(s_actuator),
449 JointIndex(n_joint_index),
450 Motor(&c_model.GetMultiBody(),
454 s_actuator.MaxImpulse) {}
459 void CDynamics3DPrototypeModel::SActuator::Reset() {
460 Motor.~btMultiBodyJointMotor();
461 new (&Motor) btMultiBodyJointMotor(&Model.GetMultiBody(),
465 Actuator.MaxImpulse);
471 void CDynamics3DPrototypeModel::SActuator::Update() {
473 Motor.setPositionTarget(Actuator.Target);
476 Motor.setVelocityTarget(Actuator.Target);
483 CDynamics3DPrototypeModel::SSensor::SSensor(CDynamics3DPrototypeModel& c_model,
484 CPrototypeJointEntity::SSensor& s_sensor,
488 JointIndex(n_joint_index) {}
493 void CDynamics3DPrototypeModel::SSensor::Update() {
495 Sensor.Value = Model.GetMultiBody().getJointPos(JointIndex);
498 Sensor.Value = Model.GetMultiBody().getJointVel(JointIndex);
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
signed int SInt32
32-bit signed integer.
unsigned int UInt32
32-bit unsigned integer.
float Real
Collects all ARGoS code.
The namespace containing all the ARGoS related code.
REGISTER_STANDARD_DYNAMICS3D_OPERATIONS_ON_ENTITY(CEPuckEntity, CDynamics3DEPuckModel)
const std::string & GetId() const
Returns the id of this entity.
UInt32 Index
The index of the anchor assigned by the embodied 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.
bool HasMagnetEquippedEntity() const
CMagnetEquippedEntity & GetMagnetEquippedEntity()
CPrototypeLinkEquippedEntity & GetLinkEquippedEntity()
CPrototypeLinkEntity & GetChildLink()
const CVector3 & GetChildLinkJointPosition() const
const CVector3 & GetParentLinkJointPosition() const
SActuator & GetActuator()
const CVector3 & GetJointAxis() const
std::vector< CPrototypeJointEntity * > TVector
bool GetDisableCollision() const
CPrototypeLinkEntity & GetParentLink()
const ULimit & GetLimit() const
const CQuaternion & GetParentLinkJointOrientation() const
const CQuaternion & GetChildLinkJointOrientation() const
CRange< CRadians > Revolute
CPrototypeJointEntity::TVector & GetJoints()
CPrototypeLinkEntity & GetReferenceLink()
CPrototypeLinkEntity::TVector & GetLinks()
SInstance::TVector & GetInstances()
std::vector< SInstance > TVector
btScalar GetDefaultFriction() const
std::vector< std::shared_ptr< CAbstractBody > > m_vecBodies
virtual void UpdateEntityStatus()
Updates the status of the associated entity.
CDynamics3DEngine & GetEngine()
virtual void RemoveFromWorld(btMultiBodyDynamicsWorld &c_world)
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)