11 #include <argos3/plugins/simulator/physics_engines/dynamics3d/dynamics3d_model.h>
14 #include <argos3/plugins/simulator/physics_engines/dynamics3d/dynamics3d_multi_body_object_model.h>
15 #include <argos3/plugins/simulator/physics_engines/dynamics3d/bullet/BulletDynamics/Featherstone/btMultiBodyLink.h>
34 std::vector<CDynamics3DModel::CAbstractBody*>& cModelBodies = c_model.
GetBodies();
40 std::vector<CDynamics3DModel::CAbstractBody*>::iterator itMagneticBody =
41 std::find_if(std::begin(cModelBodies),
42 std::end(cModelBodies),
46 return (&(s_instance.Anchor) == &(pc_body->
GetAnchor()));
48 if(itMagneticBody != std::end(cModelBodies)) {
49 btTransform cOffset(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f),
50 btVector3(s_instance.Offset.GetX(),
51 s_instance.Offset.GetZ(),
52 -s_instance.Offset.GetY()));
53 cOffset *= (*itMagneticBody)->GetData().CenterOfMassOffset;
54 m_vecDipoles.emplace_back(**itMagneticBody, s_instance.Magnet, cOffset);
64 std::vector<SMagneticDipole>::iterator itRemove =
65 std::remove_if(std::begin(m_vecDipoles),
66 std::end(m_vecDipoles),
67 [&c_model] (
const SMagneticDipole& c_magnetic_dipole) {
68 return(&(c_magnetic_dipole.Body->GetModel()) == &c_model);
70 m_vecDipoles.erase(itRemove, std::end(m_vecDipoles));
77 if(m_vecDipoles.size() < 2) {
81 for(std::vector<SMagneticDipole>::iterator itDipole0 = std::begin(m_vecDipoles);
82 itDipole0 != (std::end(m_vecDipoles) - 1);
84 for(std::vector<SMagneticDipole>::iterator itDipole1 = std::next(itDipole0, 1);
85 itDipole1 != std::end(m_vecDipoles);
87 const btTransform& cTransformDipole0 = itDipole0->Offset * itDipole0->Body->GetTransform();
88 const btTransform& cTransformDipole1 = itDipole1->Offset * itDipole1->Body->GetTransform();
89 const btVector3& cPositionDipole0 = cTransformDipole0.getOrigin();
90 const btVector3& cPositionDipole1 = cTransformDipole1.getOrigin();
92 btScalar fDistance = cPositionDipole0.distance(cPositionDipole1);
94 if(fDistance > m_fMaxDistance) {
99 const btVector3& cNormalizedSeparation =
100 btVector3(cPositionDipole0 - cPositionDipole1) / fDistance;
102 const CVector3& cFieldDipole0 = itDipole0->Magnet->GetField();
103 const btVector3& cRotatedFieldDipole0 = itDipole0->Body->GetTransform().getBasis() *
104 btVector3(cFieldDipole0.
GetX(), cFieldDipole0.
GetZ(), -cFieldDipole0.
GetY());
106 const CVector3& cFieldDipole1 = itDipole1->Magnet->GetField();
107 const btVector3& cRotatedFieldDipole1 = itDipole1->Body->GetTransform().getBasis() *
108 btVector3(cFieldDipole1.GetX(), cFieldDipole1.GetZ(), -cFieldDipole1.GetY());
121 const btVector3& cCrossProduct01 = cRotatedFieldDipole0.cross(cRotatedFieldDipole1);
122 const btVector3& cCrossProduct0 = cRotatedFieldDipole0.cross(cNormalizedSeparation);
123 const btVector3& cCrossProduct1 = cRotatedFieldDipole1.cross(cNormalizedSeparation);
124 btScalar fDotProduct01 = cRotatedFieldDipole0.dot(cRotatedFieldDipole1);
125 btScalar fDotProduct0 = cRotatedFieldDipole0.dot(cNormalizedSeparation);
126 btScalar fDotProduct1 = cRotatedFieldDipole1.dot(cNormalizedSeparation);
128 const btVector3& cTorque0 =
129 ((3 * fDotProduct1 * cCrossProduct0) - cCrossProduct01) *
130 m_fForceConstant / btPow(fDistance, 3);
131 const btVector3& cTorque1 =
132 ((3 * fDotProduct0 * cCrossProduct1) + cCrossProduct01) *
133 m_fForceConstant / btPow(fDistance, 3);
134 const btVector3& cForce = (m_fForceConstant / btPow(fDistance, 4)) *
135 ((-15 * cNormalizedSeparation * fDotProduct1 * fDotProduct0) +
136 (3 * cNormalizedSeparation * fDotProduct01) +
137 (3 * (fDotProduct1 * cRotatedFieldDipole0 + fDotProduct0 * cRotatedFieldDipole1)));
139 itDipole0->Body->ApplyForce(cForce, (itDipole0->Offset).getOrigin());
140 itDipole0->Body->ApplyTorque(cTorque0);
141 itDipole1->Body->ApplyForce(-cForce, (itDipole1->Offset).getOrigin());
142 itDipole1->Body->ApplyTorque(cTorque1);
152 "Michael Allwright [allsey87@gmail.com]",
154 "Applies forces and torques between magnetic dipoles in the simulation",
155 "For a description on how to use this plugin, please consult the documentation\n"
156 "for the dynamics3d physics engine plugin",
void GetNodeAttributeOrDefault(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer, const T &t_default)
Returns the value of a node's attribute, or the passed default value.
Real GetX() const
Returns the x coordinate of this vector.
virtual void UnregisterModel(CDynamics3DModel &c_model)
Real GetY() const
Returns the y coordinate of this vector.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
REGISTER_DYNAMICS3D_PLUGIN(CDynamics3DFloorPlugin,"floor","Michael Allwright [allsey87@gmail.com]","1.0","Inserts a floor into the 3D dynamics engine","For a description on how to use this plugin, please consult the documentation\n""for the dynamics3d physics engine plugin","Usable")
Basic class for an entity that contains other entities.
CComposableEntity & GetComposableEntity()
std::vector< SInstance > TVector
virtual void Init(TConfigurationNode &t_tree)
bool HasComponent(const std::string &str_component)
Returns true if this composable entity has a component with the given string label.
std::vector< CAbstractBody * > & GetBodies()
A container of CMagnetEntity.
The namespace containing all the ARGoS related code.
Real GetZ() const
Returns the z coordinate of this vector.
virtual void RegisterModel(CDynamics3DModel &c_model)
CEntity & GetComponent(const std::string &str_component)
Returns the component with the passed string label.