dynamics2d_engine.cpp
Go to the documentation of this file.
1 
7 #include "dynamics2d_engine.h"
8 #include "dynamics2d_model.h"
9 #include "dynamics2d_gripping.h"
10 
11 #include <argos3/core/simulator/simulator.h>
12 #include <argos3/core/simulator/entity/embodied_entity.h>
13 
14 #include <cmath>
15 
16 namespace argos {
17 
18  /****************************************/
19  /****************************************/
20 
22  m_fBoxLinearFriction(1.49),
23  m_fBoxAngularFriction(1.49),
24  m_fCylinderLinearFriction(1.49),
25  m_fCylinderAngularFriction(1.49),
26  m_ptSpace(nullptr),
27  m_ptGroundBody(nullptr),
28  m_fGrippingRigidity(10000.0),
29  m_fElevation(0.0f) {
30  }
31 
32  /****************************************/
33  /****************************************/
34 
36  try {
37  /* Init parent */
38  CPhysicsEngine::Init(t_tree);
39  /* Parse XML */
40  GetNodeAttributeOrDefault(t_tree, "elevation", m_fElevation, m_fElevation);
41  if(NodeExists(t_tree, "friction")) {
42  TConfigurationNode& tNode = GetNode(t_tree, "friction");
43  GetNodeAttributeOrDefault(tNode, "box_linear_friction", m_fBoxLinearFriction, m_fBoxLinearFriction);
44  GetNodeAttributeOrDefault(tNode, "box_angular_friction", m_fBoxAngularFriction, m_fBoxAngularFriction);
45  GetNodeAttributeOrDefault(tNode, "cylinder_linear_friction", m_fCylinderLinearFriction, m_fCylinderLinearFriction);
46  GetNodeAttributeOrDefault(tNode, "cylinder_angular_friction", m_fCylinderAngularFriction, m_fCylinderAngularFriction);
47  }
48  GetNodeAttributeOrDefault(t_tree, "gripping_rigidity", m_fGrippingRigidity, m_fGrippingRigidity);
49  /* Override volume top and bottom with the value of m_fElevation */
50  if(!GetVolume().TopFace) GetVolume().TopFace = new SHorizontalFace;
51  if(!GetVolume().BottomFace) GetVolume().BottomFace = new SHorizontalFace;
52  GetVolume().TopFace->Height = m_fElevation;
53  GetVolume().BottomFace->Height = m_fElevation;
54  /* Initialize physics */
55  cpInitChipmunk();
56  cpResetShapeIdCounter();
57  /* Used to attach static geometries so that they won't move and to simulate friction */
58  m_ptGroundBody = cpBodyNew(INFINITY, INFINITY);
59  /* Create the space to contain the movable objects */
60  m_ptSpace = cpSpaceNew();
61  /* Subiterations to solve constraints.
62  The more, the better for precision but the worse for speed
63  */
64  m_ptSpace->iterations = GetIterations();
65  /* Spatial hash */
66  if(NodeExists(t_tree, "spatial_hash")) {
67  TConfigurationNode& tNode = GetNode(t_tree, "spatial_hash");
68  cpFloat fSize;
69  UInt32 unNum;
70  GetNodeAttribute(tNode, "cell_size", fSize);
71  GetNodeAttribute(tNode, "cell_num", unNum);
72  cpSpaceUseSpatialHash(m_ptSpace, fSize, unNum);
73  }
74  /* Gripper-Gripped callback functions */
75  cpSpaceAddCollisionHandler(
76  m_ptSpace,
81  nullptr,
82  nullptr,
83  nullptr);
84  }
85  catch(CARGoSException& ex) {
86  THROW_ARGOSEXCEPTION_NESTED("Error initializing the dynamics 2D engine \"" << GetId() << "\"", ex);
87  }
88  }
89 
90  /****************************************/
91  /****************************************/
92 
94  for(auto it = m_tPhysicsModels.begin();
95  it != m_tPhysicsModels.end(); ++it) {
96  it->second->Reset();
97  }
98  cpSpaceReindexStatic(m_ptSpace);
99  }
100 
101  /****************************************/
102  /****************************************/
103 
105  /* Update the physics state from the entities */
106  for(auto it = m_tPhysicsModels.begin();
107  it != m_tPhysicsModels.end(); ++it) {
108  it->second->UpdateFromEntityStatus();
109  }
110  /* Perform the step */
111  for(size_t i = 0; i < GetIterations(); ++i) {
112  for(auto it = m_tPhysicsModels.begin();
113  it != m_tPhysicsModels.end(); ++it) {
114  it->second->UpdatePhysics();
115  }
116  cpSpaceStep(m_ptSpace, GetPhysicsClockTick());
117  }
118  /* Update the simulated space */
119  for(auto it = m_tPhysicsModels.begin();
120  it != m_tPhysicsModels.end(); ++it) {
121  it->second->UpdateEntityStatus();
122  }
123  }
124 
125  /****************************************/
126  /****************************************/
127 
129  /* Empty the physics model map */
130  for(auto it = m_tPhysicsModels.begin();
131  it != m_tPhysicsModels.end(); ++it) {
132  delete it->second;
133  }
134  m_tPhysicsModels.clear();
135  /* Get rid of the physics space */
136  cpSpaceFree(m_ptSpace);
137  cpBodyFree(m_ptGroundBody);
138  }
139 
140  /****************************************/
141  /****************************************/
142 
144  return m_tPhysicsModels.size();
145  }
146 
147  /****************************************/
148  /****************************************/
149 
151  SOperationOutcome cOutcome =
152  CallEntityOperation<CDynamics2DOperationAddEntity, CDynamics2DEngine, SOperationOutcome>
153  (*this, c_entity);
154  cpResetShapeIdCounter();
155  return cOutcome.Value;
156  }
157 
158  /****************************************/
159  /****************************************/
160 
162  SOperationOutcome cOutcome =
163  CallEntityOperation<CDynamics2DOperationRemoveEntity, CDynamics2DEngine, SOperationOutcome>
164  (*this, c_entity);
165  return cOutcome.Value;
166  }
167 
168  /****************************************/
169  /****************************************/
170 
173  const CRay3& Ray;
174 
176  const CRay3& c_ray) :
177  Intersections(t_data),
178  Ray(c_ray) {}
179  };
180 
181  static void Dynamics2DSegmentQueryFunc(cpShape* pt_shape, cpFloat f_t, cpVect, void* pt_data) {
182  /* Get the data associated to this query */
183  SDynamics2DSegmentHitData& sData = *reinterpret_cast<SDynamics2DSegmentHitData*>(pt_data);
184  /* Hit found, is f_t it within the limits on Z? */
185  CDynamics2DModel& cModel = *reinterpret_cast<CDynamics2DModel*>(pt_shape->body->data);
186  CVector3 cIntersectionPoint;
187  sData.Ray.GetPoint(cIntersectionPoint, f_t);
188  if((cIntersectionPoint.GetZ() >= cModel.GetBoundingBox().MinCorner.GetZ()) &&
189  (cIntersectionPoint.GetZ() <= cModel.GetBoundingBox().MaxCorner.GetZ()) ) {
190  /* Side hit */
191  sData.Intersections.push_back(
192  SEmbodiedEntityIntersectionItem(
193  &cModel.GetEmbodiedEntity(),
194  f_t));
195  }
196  else {
197  /* Check top surface */
198  if(cIntersectionPoint.GetZ() > cModel.GetBoundingBox().MaxCorner.GetZ()) {
199  Real fZDiff = sData.Ray.GetStart().GetZ() - cModel.GetBoundingBox().MaxCorner.GetZ();
200  Real fRayZDiff = sData.Ray.GetStart().GetZ() - sData.Ray.GetEnd().GetZ();
201  f_t = fZDiff / fRayZDiff;
202  sData.Ray.GetPoint(cIntersectionPoint, f_t);
203  if(cpShapePointQuery(pt_shape, cpv(cIntersectionPoint.GetX(), cIntersectionPoint.GetY()))) {
204  sData.Intersections.push_back(
205  SEmbodiedEntityIntersectionItem(
206  &cModel.GetEmbodiedEntity(),
207  f_t));
208  }
209  }
210  /* Technically I should check the bottom surface, too, but this case never came up so far */
211  /* TODO */
212  }
213  }
214 
216  const CRay3& c_ray) const {
217  /* Query all hits along the ray */
218  SDynamics2DSegmentHitData sHitData(t_data, c_ray);
219  cpSpaceSegmentQuery(
220  m_ptSpace,
221  cpv(c_ray.GetStart().GetX(), c_ray.GetStart().GetY()),
222  cpv(c_ray.GetEnd().GetX() , c_ray.GetEnd().GetY() ),
223  CP_ALL_LAYERS,
224  CP_NO_GROUP,
225  Dynamics2DSegmentQueryFunc,
226  &sHitData);
227  }
228 
229  /****************************************/
230  /****************************************/
231 
233  const CVector3& c_original_pos,
234  const cpBody* pt_body) {
235  c_new_pos.SetX(pt_body->p.x);
236  c_new_pos.SetY(pt_body->p.y);
237  c_new_pos.SetZ(c_original_pos.GetZ());
238  }
239 
240  /****************************************/
241  /****************************************/
242 
244  cpBody* pt_body) {
245  c_new_orient.FromAngleAxis(CRadians(pt_body->a), CVector3::Z);
246  }
247 
248  /****************************************/
249  /****************************************/
250 
251  void CDynamics2DEngine::AddPhysicsModel(const std::string& str_id,
252  CDynamics2DModel& c_model) {
253  m_tPhysicsModels[str_id] = &c_model;
254  }
255 
256  /****************************************/
257  /****************************************/
258 
259  void CDynamics2DEngine::RemovePhysicsModel(const std::string& str_id) {
260  auto it = m_tPhysicsModels.find(str_id);
261  if(it != m_tPhysicsModels.end()) {
262  delete it->second;
263  m_tPhysicsModels.erase(it);
264  }
265  else {
266  THROW_ARGOSEXCEPTION("Dynamics2D model id \"" << str_id << "\" not found in dynamics 2D engine \"" << GetId() << "\"");
267  }
268  }
269 
270  /****************************************/
271  /****************************************/
272 
274  "dynamics2d",
275  "Carlo Pinciroli [ilpincy@gmail.com]",
276  "1.0",
277  "A 2D dynamics physics engine.",
278  "This physics engine is a 2D dynamics engine based on the Chipmunk library\n"
279  "(http://code.google.com/p/chipmunk-physics) version 6.0.1.\n\n"
280  "REQUIRED XML CONFIGURATION\n\n"
281  " <physics_engines>\n"
282  " ...\n"
283  " <dynamics2d id=\"dyn2d\" />\n"
284  " ...\n"
285  " </physics_engines>\n\n"
286  "The 'id' attribute is necessary and must be unique among the physics engines.\n"
287  "If two engines share the same id, initialization aborts.\n\n"
288  "OPTIONAL XML CONFIGURATION\n\n"
289  "It is possible to set how many iterations this physics engine performs between\n"
290  "each simulation step. By default, this physics engine performs 10 steps every\n"
291  "two simulation steps. This means that, if the simulation step is 100ms, the\n"
292  "physics engine step is, by default, 10ms. Sometimes, collisions and joints are\n"
293  "not simulated with sufficient precision using these parameters. By increasing\n"
294  "the number of iterations, the temporal granularity of the solver increases and\n"
295  "with it its accuracy, at the cost of higher computational cost. To change the\n"
296  "number of iterations per simulation step use this syntax:\n\n"
297  " <physics_engines>\n"
298  " ...\n"
299  " <dynamics2d id=\"dyn2d\"\n"
300  " iterations=\"20\" />\n"
301  " ...\n"
302  " </physics_engines>\n\n"
303  "The plane of the physics engine can be translated on the Z axis, to simulate\n"
304  "for example hovering objects, such as flying robots. To translate the plane\n"
305  "2m up the Z axis, use the 'elevation' attribute as follows:\n\n"
306  " <physics_engines>\n"
307  " ...\n"
308  " <dynamics2d id=\"dyn2d\"\n"
309  " elevation=\"2.0\" />\n"
310  " ...\n"
311  " </physics_engines>\n\n"
312  "When not specified, the elevation is zero, which means that the plane\n"
313  "corresponds to the XY plane.\n\n"
314  "The friction parameters between the ground and movable boxes and cylinders can\n"
315  "be overridden. You can set both the linear and angular friction parameters.\n"
316  "The default value is 1.49 for each of them. To override the values, use this\n"
317  "syntax (all attributes are optional):\n\n"
318  " <physics_engines>\n"
319  " ...\n"
320  " <dynamics2d id=\"dyn2d\">\n"
321  " <friction box_linear_friction=\"1.0\"\n"
322  " box_angular_friction=\"2.0\"\n"
323  " cylinder_linear_friction=\"3.0\"\n"
324  " cylinder_angular_friction=\"4.0\" />\n"
325  " </dynamics2d>\n"
326  " ...\n"
327  " </physics_engines>\n\n"
328  "For the the robots that use velocity-based control, such as ground robots with\n"
329  "the differential_steering actuator (e.g. the foot-bot and the e-puck), it is\n"
330  "possible to customize robot-specific attributes that set the maximum force and\n"
331  "torque the robot has. The syntax is as follows, taking a foot-bot as example:\n\n"
332  " <arena ...>\n"
333  " ...\n"
334  " <foot-bot id=\"fb0\">\n"
335  " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n"
336  " <controller config=\"mycntrl\" />\n"
337  " <!-- Specify new value for max_force and max_torque -->\n"
338  " <dynamics2d>\n"
339  " <differential_steering max_force=\"0.1\" max_torque=\"0.1\"/>\n"
340  " </dynamics2d>\n"
341  " </foot-bot>\n"
342  " ...\n"
343  " </arena>\n\n"
344  "The attributes 'max_force' and 'max_torque' are both optional, and they take the\n"
345  "robot-specific default if not set. Check the code of the dynamics2d model of the\n"
346  "robot you're using to know the default values.\n\n"
347  "Multiple physics engines can also be used. If multiple physics engines are used,\n"
348  "the disjoint union of the area within the arena assigned to each engine must cover\n"
349  "the entire arena without overlapping. If the entire arena is not covered, robots can\n"
350  "\"escape\" the configured physics engines and cause a fatal exception (this is not an\n"
351  "issue when a single physics engine is used, because the engine covers the entire arena\n"
352  "by default). To use multiple physics engines, use the following syntax (all attributes\n"
353  "are mandatory):\n\n"
354 
355  " <physics_engines>\n"
356  " ...\n"
357  " <dynamics2d id=\"dyn2d0\">\n"
358  " <boundaries>\n"
359  " <top height=\"1.0\"/>\n"
360  " <botton height=\"0.0\"/>\n"
361  " <sides>\n"
362  " <vertex point=\"0.0, 0.0\"/>\n"
363  " <vertex point=\"4.0, 0.0\"/>\n"
364  " <vertex point=\"4.0, 4.0\"/>\n"
365  " <vertex point=\"0.0, 4.0\"/>\n"
366  " </sides>\n"
367  " </boundaries>\n"
368  " </dynamics2d>\n"
369  " <dynamics2d id=\"dyn2d1\">\n"
370  " ..."
371  " </dynamics2d>\n"
372  " ...\n"
373  " </physics_engines>\n\n"
374 
375  "The 'top' and 'bottom' nodes are relevant for 3D physics engines. For 2D\n"
376  "engines, it safe to set their height to 1.0 and 0.0, respectively. A physics\n"
377  "engine can be defined having any number of sides >= 3, as long as the sides form\n"
378  "a closed polygon in the 2D plane. The vertices must be declared in\n"
379  "counter-clockwise order. In the above example, the physics engine \"dyn2d0\" is\n"
380  "assigned to the area within the arena with lower-left coordinates (0,0) and\n"
381  "upper-right coordinates (4,4) and vertices are specified in counter clockwise\n"
382  "order: south-east, south-west, north-west, north-east.\n\n"
383  "OPTIMIZATION HINTS\n\n"
384  "1. A single physics engine is generally sufficient for small swarms (say <= 50\n"
385  " robots) within a reasonably small arena to obtain faster than real-time\n"
386  " performance with optimized code. For larger swarms and/or large arenas,\n"
387  " multiple engines should be used for maximum performance.\n\n"
388  "2. In general, using the same number of ARGoS threads as physics engines gives\n"
389  " maximum performance (1-thread per engine per CPU core).\n\n"
390  "3. Using multiple engines in simulations with any of the following\n"
391  " characteristics generally incurs more overhead (due to thread context\n"
392  " switching) than the performance benefits from multiple engines:\n"
393  " - Small swarms\n"
394  " - Small arenas\n"
395  " - Less available ARGoS threads than assigned physics engines\n"
396  " - Less available CPU cores than assigned ARGoS threads\n\n"
397  "4. A good starting strategy for physics engine boundary assignment is to assign\n"
398  " each physics engine the same amount of area within the arena. This will be\n"
399  " sufficient for most cases. Depending on the nature of the simulation, using\n"
400  " non-homogeneous physics engine sizes may yield increased performance. An\n"
401  " example would be a narrow hallway between larger open areas in the arena--the\n"
402  " hallway will likely experience increased robot density and assigning more\n"
403  " physics engines to that area than the relatively unpopulated open areas may\n"
404  " increase performance.\n\n"
405  "5. By default, this engine uses the bounding-box tree method for collision shape\n"
406  " indexing. This method is the default in Chipmunk and it works well most of\n"
407  " the times. However, if you are running simulations with hundreds or thousands\n"
408  " of identical robots, a different shape collision indexing is available: the\n"
409  " spatial hash. The spatial hash is a grid stored in a hashmap. To get the max\n"
410  " out of this indexing method, you must set two parameters: the cell size and\n"
411  " the suggested minimum number of cells in the space. According to the\n"
412  " documentation of Chipmunk, the cell size should correspond to the size of the\n"
413  " bounding box of the most common object in the simulation; the minimum number\n"
414  " of cells should be at least 10x the number of objects managed by the physics\n"
415  " engine. To use this indexing method, use this syntax (all attributes are\n"
416  " mandatory):\n\n"
417  " <physics_engines>\n"
418  " ...\n"
419  " <dynamics2d id=\"dyn2d\">\n"
420  " <spatial_hash>\n"
421  " <cell_size=\"1.0\"/>\n"
422  " <cell_num=\"2.0\"/>\n"
423  " </spatial_hash>\n"
424  " </dynamics2d>\n"
425  " ...\n"
426  " </physics_engines>\n"
427  ,
428  "Usable"
429  );
430 
431 }
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception.
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
unsigned int UInt32
32-bit unsigned integer.
Definition: datatypes.h:97
float Real
Collects all ARGoS code.
Definition: datatypes.h:39
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
int BeginCollisionBetweenGripperAndGrippable(cpArbiter *pt_arb, cpSpace *pt_space, void *p_data)
TConfigurationNode & GetNode(TConfigurationNode &t_node, const std::string &str_tag)
Given a tree root node, returns the first of its child nodes with the wanted name.
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.
bool NodeExists(TConfigurationNode &t_node, const std::string &str_tag)
Given a tree root node, returns true if one of its child nodes has the wanted name.
REGISTER_PHYSICS_ENGINE(CDynamics2DEngine, "dynamics2d", "Carlo Pinciroli [ilpincy@gmail.com]", "1.0", "A 2D dynamics physics engine.", "This physics engine is a 2D dynamics engine based on the Chipmunk library\n" "(http://code.google.com/p/chipmunk-physics) version 6.0.1.\n\n" "REQUIRED XML CONFIGURATION\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\" />\n" " ...\n" " </physics_engines>\n\n" "The 'id' attribute is necessary and must be unique among the physics engines.\n" "If two engines share the same id, initialization aborts.\n\n" "OPTIONAL XML CONFIGURATION\n\n" "It is possible to set how many iterations this physics engine performs between\n" "each simulation step. By default, this physics engine performs 10 steps every\n" "two simulation steps. This means that, if the simulation step is 100ms, the\n" "physics engine step is, by default, 10ms. Sometimes, collisions and joints are\n" "not simulated with sufficient precision using these parameters. By increasing\n" "the number of iterations, the temporal granularity of the solver increases and\n" "with it its accuracy, at the cost of higher computational cost. To change the\n" "number of iterations per simulation step use this syntax:\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\"\n" " iterations=\"20\" />\n" " ...\n" " </physics_engines>\n\n" "The plane of the physics engine can be translated on the Z axis, to simulate\n" "for example hovering objects, such as flying robots. To translate the plane\n" "2m up the Z axis, use the 'elevation' attribute as follows:\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\"\n" " elevation=\"2.0\" />\n" " ...\n" " </physics_engines>\n\n" "When not specified, the elevation is zero, which means that the plane\n" "corresponds to the XY plane.\n\n" "The friction parameters between the ground and movable boxes and cylinders can\n" "be overridden. You can set both the linear and angular friction parameters.\n" "The default value is 1.49 for each of them. To override the values, use this\n" "syntax (all attributes are optional):\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\">\n" " <friction box_linear_friction=\"1.0\"\n" " box_angular_friction=\"2.0\"\n" " cylinder_linear_friction=\"3.0\"\n" " cylinder_angular_friction=\"4.0\" />\n" " </dynamics2d>\n" " ...\n" " </physics_engines>\n\n" "For the the robots that use velocity-based control, such as ground robots with\n" "the differential_steering actuator (e.g. the foot-bot and the e-puck), it is\n" "possible to customize robot-specific attributes that set the maximum force and\n" "torque the robot has. The syntax is as follows, taking a foot-bot as example:\n\n" " <arena ...>\n" " ...\n" " <foot-bot id=\"fb0\">\n" " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n" " <controller config=\"mycntrl\" />\n" " <!-- Specify new value for max_force and max_torque -->\n" " <dynamics2d>\n" " <differential_steering max_force=\"0.1\" max_torque=\"0.1\"/>\n" " </dynamics2d>\n" " </foot-bot>\n" " ...\n" " </arena>\n\n" "The attributes 'max_force' and 'max_torque' are both optional, and they take the\n" "robot-specific default if not set. Check the code of the dynamics2d model of the\n" "robot you're using to know the default values.\n\n" "Multiple physics engines can also be used. If multiple physics engines are used,\n" "the disjoint union of the area within the arena assigned to each engine must cover\n" "the entire arena without overlapping. If the entire arena is not covered, robots can\n" "\"escape\" the configured physics engines and cause a fatal exception (this is not an\n" "issue when a single physics engine is used, because the engine covers the entire arena\n" "by default). To use multiple physics engines, use the following syntax (all attributes\n" "are mandatory):\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d0\">\n" " <boundaries>\n" " <top height=\"1.0\"/>\n" " <botton height=\"0.0\"/>\n" " <sides>\n" " <vertex point=\"0.0, 0.0\"/>\n" " <vertex point=\"4.0, 0.0\"/>\n" " <vertex point=\"4.0, 4.0\"/>\n" " <vertex point=\"0.0, 4.0\"/>\n" " </sides>\n" " </boundaries>\n" " </dynamics2d>\n" " <dynamics2d id=\"dyn2d1\">\n" " ..." " </dynamics2d>\n" " ...\n" " </physics_engines>\n\n" "The 'top' and 'bottom' nodes are relevant for 3D physics engines. For 2D\n" "engines, it safe to set their height to 1.0 and 0.0, respectively. A physics\n" "engine can be defined having any number of sides >= 3, as long as the sides form\n" "a closed polygon in the 2D plane. The vertices must be declared in\n" "counter-clockwise order. In the above example, the physics engine \"dyn2d0\" is\n" "assigned to the area within the arena with lower-left coordinates (0,0) and\n" "upper-right coordinates (4,4) and vertices are specified in counter clockwise\n" "order: south-east, south-west, north-west, north-east.\n\n" "OPTIMIZATION HINTS\n\n" "1. A single physics engine is generally sufficient for small swarms (say <= 50\n" " robots) within a reasonably small arena to obtain faster than real-time\n" " performance with optimized code. For larger swarms and/or large arenas,\n" " multiple engines should be used for maximum performance.\n\n" "2. In general, using the same number of ARGoS threads as physics engines gives\n" " maximum performance (1-thread per engine per CPU core).\n\n" "3. Using multiple engines in simulations with any of the following\n" " characteristics generally incurs more overhead (due to thread context\n" " switching) than the performance benefits from multiple engines:\n" " - Small swarms\n" " - Small arenas\n" " - Less available ARGoS threads than assigned physics engines\n" " - Less available CPU cores than assigned ARGoS threads\n\n" "4. A good starting strategy for physics engine boundary assignment is to assign\n" " each physics engine the same amount of area within the arena. This will be\n" " sufficient for most cases. Depending on the nature of the simulation, using\n" " non-homogeneous physics engine sizes may yield increased performance. An\n" " example would be a narrow hallway between larger open areas in the arena--the\n" " hallway will likely experience increased robot density and assigning more\n" " physics engines to that area than the relatively unpopulated open areas may\n" " increase performance.\n\n" "5. By default, this engine uses the bounding-box tree method for collision shape\n" " indexing. This method is the default in Chipmunk and it works well most of\n" " the times. However, if you are running simulations with hundreds or thousands\n" " of identical robots, a different shape collision indexing is available: the\n" " spatial hash. The spatial hash is a grid stored in a hashmap. To get the max\n" " out of this indexing method, you must set two parameters: the cell size and\n" " the suggested minimum number of cells in the space. According to the\n" " documentation of Chipmunk, the cell size should correspond to the size of the\n" " bounding box of the most common object in the simulation; the minimum number\n" " of cells should be at least 10x the number of objects managed by the physics\n" " engine. To use this indexing method, use this syntax (all attributes are\n" " mandatory):\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\">\n" " <spatial_hash>\n" " <cell_size=\"1.0\"/>\n" " <cell_num=\"2.0\"/>\n" " </spatial_hash>\n" " </dynamics2d>\n" " ...\n" " </physics_engines>\n", "Usable")
int ManageCollisionBetweenGripperAndGrippable(cpArbiter *pt_arb, cpSpace *pt_space, void *p_data)
std::vector< SEmbodiedEntityIntersectionItem > TEmbodiedEntityIntersectionData
void GetNodeAttribute(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer)
Returns the value of a node's attribute.
The basic entity type.
Definition: entity.h:90
Type to use as return value for operation outcome.
Definition: entity.h:352
SVolume & GetVolume()
Returns the boundary faces for the volume associated to this engine.
const std::string & GetId() const
Returns the id of this physics engine.
virtual void Init(TConfigurationNode &t_tree)
Initializes the resource.
Real GetPhysicsClockTick() const
Returns the length of the physics engine tick.
UInt32 GetIterations() const
Returns the number of iterations per simulation clock tick.
A boundary face for top/bottom parts of the volume.
The exception that wraps all errors in ARGoS.
It defines the basic type CRadians, used to store an angle value in radians.
Definition: angles.h:42
CQuaternion & FromAngleAxis(const CRadians &c_angle, const CVector3 &c_vector)
Definition: quaternion.h:126
CVector3 & GetEnd()
Definition: ray3.h:45
CVector3 & GetStart()
Definition: ray3.h:37
A 3D vector class.
Definition: vector3.h:31
void SetY(const Real f_y)
Sets the y coordinate of this vector.
Definition: vector3.h:129
Real GetX() const
Returns the x coordinate of this vector.
Definition: vector3.h:105
void SetX(const Real f_x)
Sets the x coordinate of this vector.
Definition: vector3.h:113
void SetZ(const Real f_z)
Sets the z coordinate of this vector.
Definition: vector3.h:145
Real GetY() const
Returns the y coordinate of this vector.
Definition: vector3.h:121
static const CVector3 Z
The z axis.
Definition: vector3.h:42
Real GetZ() const
Returns the z coordinate of this vector.
Definition: vector3.h:137
SDynamics2DSegmentHitData(TEmbodiedEntityIntersectionData &t_data, const CRay3 &c_ray)
TEmbodiedEntityIntersectionData & Intersections
virtual void Reset()
Resets the resource.
void RemovePhysicsModel(const std::string &str_id)
void PositionPhysicsToSpace(CVector3 &c_new_pos, const CVector3 &c_original_pos, const cpBody *pt_body)
virtual size_t GetNumPhysicsModels()
virtual void Init(TConfigurationNode &t_tree)
Initializes the resource.
virtual void Destroy()
Undoes whatever was done by Init().
virtual void CheckIntersectionWithRay(TEmbodiedEntityIntersectionData &t_data, const CRay3 &c_ray) const
Check which objects in this engine intersect the given ray.
void AddPhysicsModel(const std::string &str_id, CDynamics2DModel &c_model)
void OrientationPhysicsToSpace(CQuaternion &c_new_orient, cpBody *pt_body)
virtual bool RemoveEntity(CEntity &c_entity)
Removes an entity from the physics engine.
virtual bool AddEntity(CEntity &c_entity)
Adds an entity to the physics engine.
The base class for models in the dynamics 2D engine.