11 #include <argos3/plugins/simulator/physics_engines/dynamics3d/dynamics3d_model.h>
29 for(std::shared_ptr<CDynamics3DModel::CAbstractBody>& ptr_body : c_model.
GetBodies()) {
31 ptr_body->GetData().Dipoles) {
32 m_vecDipoles.emplace_back(ptr_body,
44 std::remove_if(std::begin(m_vecDipoles),
45 std::end(m_vecDipoles),
46 [&c_model] (
const SMagneticDipole& c_magnetic_dipole) {
47 return(&(c_magnetic_dipole.Body->GetModel()) == &c_model);
49 m_vecDipoles.erase(itRemove, std::end(m_vecDipoles));
56 if(m_vecDipoles.size() < 2) {
60 for(
auto itDipole0 = std::begin(m_vecDipoles);
61 itDipole0 != (std::end(m_vecDipoles) - 1);
63 for(
auto itDipole1 = std::next(itDipole0, 1);
64 itDipole1 != std::end(m_vecDipoles);
66 const btTransform& cTransformDipole0 = itDipole0->Offset * itDipole0->Body->GetTransform();
67 const btTransform& cTransformDipole1 = itDipole1->Offset * itDipole1->Body->GetTransform();
68 const btVector3& cPositionDipole0 = cTransformDipole0.getOrigin();
69 const btVector3& cPositionDipole1 = cTransformDipole1.getOrigin();
71 btScalar fDistance = cPositionDipole0.distance(cPositionDipole1);
73 if(fDistance > m_fMaxDistance) {
78 const btVector3& cNormalizedSeparation =
79 btVector3(cPositionDipole0 - cPositionDipole1) / fDistance;
81 const btVector3& cRotatedFieldDipole0 =
82 itDipole0->Body->GetTransform().getBasis() * itDipole0->GetField();
84 const btVector3& cRotatedFieldDipole1 =
85 itDipole1->Body->GetTransform().getBasis() * itDipole1->GetField();
98 const btVector3& cCrossProduct01 = cRotatedFieldDipole0.cross(cRotatedFieldDipole1);
99 const btVector3& cCrossProduct0 = cRotatedFieldDipole0.cross(cNormalizedSeparation);
100 const btVector3& cCrossProduct1 = cRotatedFieldDipole1.cross(cNormalizedSeparation);
101 btScalar fDotProduct01 = cRotatedFieldDipole0.dot(cRotatedFieldDipole1);
102 btScalar fDotProduct0 = cRotatedFieldDipole0.dot(cNormalizedSeparation);
103 btScalar fDotProduct1 = cRotatedFieldDipole1.dot(cNormalizedSeparation);
105 const btVector3& cTorque0 =
106 ((3 * fDotProduct1 * cCrossProduct0) - cCrossProduct01) *
107 m_fForceConstant / btPow(fDistance, 3);
108 const btVector3& cTorque1 =
109 ((3 * fDotProduct0 * cCrossProduct1) + cCrossProduct01) *
110 m_fForceConstant / btPow(fDistance, 3);
111 const btVector3& cForce = (m_fForceConstant / btPow(fDistance, 4)) *
112 ((-15 * cNormalizedSeparation * fDotProduct1 * fDotProduct0) +
113 (3 * cNormalizedSeparation * fDotProduct01) +
114 (3 * (fDotProduct1 * cRotatedFieldDipole0 + fDotProduct0 * cRotatedFieldDipole1)));
116 itDipole0->Body->ApplyForce(cForce, (itDipole0->Offset).getOrigin());
117 itDipole0->Body->ApplyTorque(cTorque0);
118 itDipole1->Body->ApplyForce(-cForce, (itDipole1->Offset).getOrigin());
119 itDipole1->Body->ApplyTorque(cTorque1);
129 "Michael Allwright [allsey87@gmail.com]",
131 "Applies forces and torques between magnetic dipoles in the simulation",
132 "For a description on how to use this plugin, please consult the documentation\n"
133 "for the dynamics3d physics engine plugin",
The namespace containing all the ARGoS related code.
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")
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.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
virtual void RegisterModel(CDynamics3DModel &c_model)
virtual void UnregisterModel(CDynamics3DModel &c_model)
virtual void Init(TConfigurationNode &t_tree)
std::vector< std::shared_ptr< CAbstractBody > > & GetBodies()