Block.cpp
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2024 Jose Luis Blanco Claraco |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under 3-clause BSD License |
7  | See COPYING |
8  +-------------------------------------------------------------------------+ */
9 
10 #include <mrpt/core/bits_math.h>
11 #include <mrpt/core/format.h>
12 #include <mrpt/core/lock_helper.h>
13 #include <mrpt/math/TPose2D.h>
14 #include <mrpt/opengl/CBox.h>
15 #include <mrpt/opengl/CCylinder.h>
16 #include <mrpt/opengl/CPolyhedron.h>
17 #include <mrpt/opengl/CSetOfTriangles.h>
18 #include <mrpt/opengl/CSphere.h>
19 #include <mrpt/poses/CPose2D.h>
20 #include <mrpt/version.h>
21 #include <mvsim/Block.h>
22 #include <mvsim/World.h>
23 
24 #include <map>
25 #include <rapidxml.hpp>
26 #include <string>
27 
28 #include "JointXMLnode.h"
29 #include "XMLClassesRegistry.h"
30 #include "xml_utils.h"
31 
32 using namespace mvsim;
33 using namespace std;
34 
35 static XmlClassesRegistry block_classes_registry("block:class");
36 
37 // Protected ctor:
38 Block::Block(World* parent) : VisualObject(parent), Simulable(parent)
39 {
40  // Default shape:
41  block_poly_.emplace_back(-0.5, -0.5);
42  block_poly_.emplace_back(-0.5, 0.5);
43  block_poly_.emplace_back(0.5, 0.5);
44  block_poly_.emplace_back(0.5, -0.5);
46 }
47 
50 void Block::register_block_class(const World& parent, const rapidxml::xml_node<char>* xml_node)
51 {
52  // Sanity checks:
53  if (!xml_node) throw runtime_error("[Block::register_vehicle_class] XML node is nullptr");
54  if (0 != strcmp(xml_node->name(), "block:class"))
55  throw runtime_error(mrpt::format(
56  "[Block::register_block_class] XML element is '%s' "
57  "('block:class' expected)",
58  xml_node->name()));
59 
60  // Parse XML to solve for includes:
62 }
63 
65 {
66  using namespace std;
67  using namespace rapidxml;
68 
69  if (!root) throw runtime_error("[Block::factory] XML node is nullptr");
70  if (0 != strcmp(root->name(), "block"))
71  throw runtime_error(mrpt::format(
72  "[Block::factory] XML root element is '%s' ('block' expected)", root->name()));
73 
74  // "class": When there is a 'class="XXX"' attribute, look for each parameter
75  // in the set of "root" + "class_root" XML nodes:
76  // --------------------------------------------------------------------------------
77  JointXMLnode<> nodes;
78  const rapidxml::xml_node<char>* class_root = nullptr;
79  {
80  // Always search in root. Also in the class root, if any:
81  nodes.add(root);
82  if (const xml_attribute<>* block_class = root->first_attribute("class"); block_class)
83  {
84  const string sClassName = block_class->value();
85  if (class_root = block_classes_registry.get(sClassName); !class_root)
86  THROW_EXCEPTION_FMT(
87  "[Block::factory] Block class '%s' undefined", sClassName.c_str());
88 
89  nodes.add(class_root);
90  }
91  }
92 
93  // Build object (we don't use class factory for blocks)
94  // ----------------------------------------------------
95  Block::Ptr block = std::make_shared<Block>(parent);
96 
97  // Init params
98  // -------------------------------------------------
99  // attrib: name
100  {
101  const xml_attribute<>* attrib_name = root->first_attribute("name");
102  if (attrib_name && attrib_name->value())
103  {
104  block->name_ = attrib_name->value();
105  }
106  else
107  {
108  // Default name:
109  static int cnt = 0;
110  block->name_ = mrpt::format("block%03i", ++cnt);
111  }
112  }
113 
114  // Params:
115  // -----------------------------------------------------------
117  *root, block->params_, parent->user_defined_variables(), "[Block::factory]");
118  if (class_root)
120  *class_root, block->params_, parent->user_defined_variables(), "[Block::factory]");
121 
122  // Custom visualization 3D model:
123  // -----------------------------------------------------------
124  block->parseVisual(nodes);
125 
126  // Shape node (optional, fallback to default shape if none found)
127  if (const auto* xml_shape = nodes.first_node("shape"); xml_shape)
128  {
129  mvsim::parse_xmlnode_shape(*xml_shape, block->block_poly_, "[Block::factory]");
130  block->updateMaxRadiusFromPoly();
131  }
132  else if (const auto* xml_geom = nodes.first_node("geometry"); xml_geom)
133  {
134  block->internal_parseGeometry(*xml_geom);
135  }
136 
137  // Auto shape node from visual?
138  if (const rapidxml::xml_node<char>* xml_shape_viz = nodes.first_node("shape_from_visual");
139  xml_shape_viz)
140  {
141  const auto& bbVis = block->collisionShape();
142  if (!bbVis.has_value())
143  {
144  THROW_EXCEPTION(
145  "Error: Tag <shape_from_visual/> found but neither <visual> "
146  "nor <geometry> entries, while parsing <block>");
147  }
148  const auto& bb = bbVis.value();
149 
150  if (bb.volume() == 0)
151  {
152  THROW_EXCEPTION(
153  "Error: Tag <shape_from_visual/> found but bounding box of "
154  "visual object seems incorrect, while parsing <block>");
155  }
156 
157  // Set contour polygon:
158  block->block_poly_ = bb.getContour();
159  block->block_z_min(bb.zMin());
160  block->block_z_max(bb.zMax());
161  }
162  else
163  {
164  // set zmin/zmax to defaults, if not set explicitly by the user in the
165  // XML file, and we didn't have a "shaped_from_visual" tag:
166  if (block->default_block_z_min_max())
167  {
168  block->block_z_min(0.0);
169  block->block_z_max(1.0);
170  }
171  }
172 
173  block->updateMaxRadiusFromPoly();
174 
175  // Common setup for simulable objects:
176  // -----------------------------------------------------------
177  block->parseSimulable(nodes);
178 
179  // Register bodies, fixtures, etc. in Box2D simulator:
180  // ----------------------------------------------------
181  block->create_multibody_system(*parent->getBox2DWorld());
182 
183  if (block->b2dBody_)
184  {
185  // Init pos:
186  const auto q = parent->applyWorldRenderOffset(block->getPose());
187  const auto dq = block->getTwist();
188 
189  block->b2dBody_->SetTransform(b2Vec2(q.x, q.y), q.yaw);
190  // Init vel:
191  block->b2dBody_->SetLinearVelocity(b2Vec2(dq.vx, dq.vy));
192  block->b2dBody_->SetAngularVelocity(dq.omega);
193  }
194 
195  return block;
196 }
197 
198 Block::Ptr Block::factory(World* parent, const std::string& xml_text)
199 {
200  // Parse the string as if it was an XML file:
201  std::stringstream s;
202  s.str(xml_text);
203 
204  char* input_str = const_cast<char*>(xml_text.c_str());
206  try
207  {
208  xml.parse<0>(input_str);
209  }
210  catch (rapidxml::parse_error& e)
211  {
212  unsigned int line = static_cast<long>(std::count(input_str, e.where<char>(), '\n') + 1);
213  throw std::runtime_error(mrpt::format(
214  "[Block::factory] XML parse error (Line %u): %s", static_cast<unsigned>(line),
215  e.what()));
216  }
217  return Block::factory(parent, xml.first_node());
218 }
219 
221 {
223 }
224 
228 {
230 }
231 
233  const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& viz,
234  const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& physical, bool childrenOnly)
235 {
236  // 1st time call?? -> Create objects
237  // ----------------------------------
238  if (!childrenOnly)
239  {
240  if (!gl_block_ && viz && physical)
241  {
242  gl_block_ = mrpt::opengl::CSetOfObjects::Create();
243  gl_block_->setName(name_);
244 
245  // Block shape:
246  auto gl_poly = mrpt::opengl::CPolyhedron::CreateCustomPrism(
248  gl_poly->setLocation(0, 0, block_z_min_);
249  gl_poly->setColor_u8(block_color_);
250 
251 // Hide back faces:
252 #if MRPT_VERSION >= 0x240
253  // gl_poly->cullFaces(mrpt::opengl::TCullFace::FRONT);
254 #endif
255 
256  gl_block_->insert(gl_poly);
257 
258  viz->get().insert(gl_block_);
259  physical->get().insert(gl_block_);
260  }
261 
262  // Update them:
263  // If "viz" does not have a value, it's because we are already
264  // inside a setPose() change event, so my caller already holds the
265  // mutex and we don't need/can't acquire it again:
266  const auto objectPose = viz.has_value() ? getPose() : getPoseNoLock();
267 
268  if (gl_block_) gl_block_->setPose(parent()->applyWorldRenderOffset(objectPose));
269  }
270 
271  if (!gl_forces_ && viz)
272  {
273  // Visualization of forces:
274  gl_forces_ = mrpt::opengl::CSetOfLines::Create();
275  gl_forces_->setLineWidth(3.0);
276  gl_forces_->setColor_u8(0xff, 0xff, 0xff);
277 
278  gl_forces_->setPose(parent()->applyWorldRenderOffset(mrpt::poses::CPose3D::Identity()));
279 
280  viz->get().insert(gl_forces_); // forces are in global coords
281  }
282 
283  // Other common stuff:
284  if (viz) internal_internalGuiUpdate_forces(viz->get());
285 }
286 
288  [[maybe_unused]] mrpt::opengl::COpenGLScene& scene)
289 {
291  {
292  std::lock_guard<std::mutex> csl(force_segments_for_rendering_cs_);
293  gl_forces_->clear();
295  gl_forces_->setVisibility(true);
296  }
297  else
298  {
299  gl_forces_->setVisibility(false);
300  }
301 }
302 
304 {
305  using namespace mrpt::math;
306 
307  maxRadius_ = 0.001f;
308  for (const auto& segment : block_poly_)
309  {
310  const float n = segment.norm();
311  mrpt::keep_max(maxRadius_, n);
312  }
313 }
314 
317 {
318  if (intangible_) return;
319 
320  // Update collision shape from shape loaded from XML or set manually:
321  {
322  Shape2p5 cs;
324  setCollisionShape(cs);
325  }
326 
327  // Define the dynamic body. We set its position and call the body
328  // factory.
329  b2BodyDef bodyDef;
330  bodyDef.type = b2_dynamicBody;
331 
332  b2dBody_ = world.CreateBody(&bodyDef);
333 
334  // Define shape of block:
335  // ------------------------------
336  {
337  // Convert shape into Box2D format:
338  const size_t nPts = block_poly_.size();
339  ASSERT_(nPts >= 3);
340  ASSERT_LE_(nPts, (size_t)b2_maxPolygonVertices);
341  std::vector<b2Vec2> pts(nPts);
342  for (size_t i = 0; i < nPts; i++) pts[i] = b2Vec2(block_poly_[i].x, block_poly_[i].y);
343 
344  b2PolygonShape blockPoly;
345  blockPoly.Set(&pts[0], nPts);
346 
347  // FIXED value by design in b2Box: The "skin" depth of the body
348  blockPoly.m_radius = 2.5e-3; // b2_polygonRadius;
349 
350  // Define the dynamic body fixture.
351  b2FixtureDef fixtureDef;
352  fixtureDef.shape = &blockPoly;
353  fixtureDef.restitution = restitution_;
354 
355  // Set the box density to be non-zero, so it will be dynamic.
357  blockPoly.ComputeMass(&mass, 1); // Mass with density=1 => compute area
358  fixtureDef.density = mass_ / mass.mass;
359 
360  // Override the default friction.
361  fixtureDef.friction = lateral_friction_; // 0.3f;
362 
363  // Add the shape to the body.
364  fixture_block_ = b2dBody_->CreateFixture(&fixtureDef);
365 
366  // Static (does not move at all) vs dynamic object:
367  b2dBody_->SetType(isStatic_ ? b2_staticBody : b2_dynamicBody);
368 
369  // Compute center of mass:
370  b2MassData vehMass;
371  fixture_block_->GetMassData(&vehMass);
372  block_com_.x = vehMass.center.x;
373  block_com_.y = vehMass.center.y;
374  }
375 
376  // Create "archor points" to simulate friction with the ground:
377  // -----------------------------------------------------------------
378  const size_t nContactPoints = 2;
379  const double weight_per_contact_point = mass_ * parent()->get_gravity() / nContactPoints;
380  const double mu = groundFriction_;
381  const double max_friction = mu * weight_per_contact_point;
382 
383  // Location (local coords) of each contact-point:
384  const mrpt::math::TPoint2D pt_loc[nContactPoints] = {
385  mrpt::math::TPoint2D(maxRadius_, 0), mrpt::math::TPoint2D(-maxRadius_, 0)};
386 
387  b2FrictionJointDef fjd;
388 
390  fjd.bodyB = b2dBody_;
391 
392  for (size_t i = 0; i < nContactPoints; i++)
393  {
394  const b2Vec2 local_pt = b2Vec2(pt_loc[i].x, pt_loc[i].y);
395 
396  fjd.localAnchorA = b2dBody_->GetWorldPoint(local_pt);
397  fjd.localAnchorB = local_pt;
398  fjd.maxForce = max_friction;
399  fjd.maxTorque = 0;
400 
401  b2FrictionJoint* b2_friction =
402  dynamic_cast<b2FrictionJoint*>(world_->getBox2DWorld()->CreateJoint(&fjd));
403  friction_joints_.push_back(b2_friction);
404  }
405 }
406 
407 void Block::apply_force(const mrpt::math::TVector2D& force, const mrpt::math::TPoint2D& applyPoint)
408 {
409  if (intangible_) return;
410  ASSERT_(b2dBody_);
411  // Application point -> world coords
412  const b2Vec2 wPt = b2dBody_->GetWorldPoint(b2Vec2(applyPoint.x, applyPoint.y));
413  b2dBody_->ApplyForce(b2Vec2(force.x, force.y), wPt, true /*wake up*/);
414 }
415 
416 bool Block::isStatic() const
417 {
418  if (intangible_) return true;
419  ASSERT_(b2dBody_);
420  return b2dBody_->GetType() == b2_staticBody;
421 }
422 
423 void Block::setIsStatic(bool b)
424 {
425  if (intangible_) return;
426  ASSERT_(b2dBody_);
427  b2dBody_->SetType(b ? b2_staticBody : b2_dynamicBody);
428 }
429 
430 // Protected ctor:
432 
434  const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& viz,
435  const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& physical,
436  [[maybe_unused]] bool childrenOnly)
437 {
438  if (!viz || !physical) return;
439 
440  for (auto& s : sensors_) s->guiUpdate(viz, physical);
441 }
442 
444 {
445  using namespace mrpt::literals; // _deg
446 
447  auto& _ = geomParams_;
448 
450  xml_geom_node, _.params, world_->user_defined_variables(),
451  "[Block::internal_parseGeometry]");
452 
453  if (_.typeStr.empty())
454  {
455  THROW_EXCEPTION(
456  "Geometry type attribute is missing, i.e. <geometry type='...' ... "
457  "/>");
458  }
459  // This will throw on error:
460  _.type = mrpt::typemeta::str2enum<GeometryType>(_.typeStr);
461 
462  switch (_.type)
463  {
465  {
466  ASSERTMSG_(_.radius > 0, "Missing 'radius' attribute for cylinder geometry");
467  ASSERTMSG_(_.length > 0, "Missing 'length' attribute for cylinder geometry");
468 
469  if (_.vertex_count == 0) _.vertex_count = 10; // default
470 
471  auto glCyl = mrpt::opengl::CCylinder::Create();
472  glCyl->setHeight(_.length);
473  glCyl->setRadius(_.radius);
474  glCyl->setSlicesCount(_.vertex_count);
475  glCyl->setColor_u8(block_color_);
476  addCustomVisualization(glCyl);
477  }
478  break;
479 
481  {
482  ASSERTMSG_(_.radius > 0, "Missing 'radius' attribute for cylinder geometry");
483 
484  if (_.vertex_count == 0) _.vertex_count = 10; // default
485 
486  auto glSph = mrpt::opengl::CSphere::Create(_.radius, _.vertex_count);
487  glSph->setColor_u8(block_color_);
488  addCustomVisualization(glSph);
489  }
490  break;
491 
492  case GeometryType::Box:
493  {
494  ASSERTMSG_(_.lx > 0, "Missing 'lx' attribute for box geometry");
495  ASSERTMSG_(_.ly > 0, "Missing 'ly' attribute for box geometry");
496  ASSERTMSG_(_.lz > 0, "Missing 'lz' attribute for box geometry");
497 
498  auto glBox = mrpt::opengl::CBox::Create();
499  glBox->setBoxCorners({0, 0, 0}, {_.lx, _.ly, _.lz});
500  glBox->setColor_u8(block_color_);
501  addCustomVisualization(glBox);
502  }
503  break;
504 
506  {
507  ASSERTMSG_(_.lx > 0, "Missing 'lx' attribute for semi_cylinder_bump geometry");
508  ASSERTMSG_(_.ly > 0, "Missing 'ly' attribute for semi_cylinder_bump geometry");
509  ASSERTMSG_(_.lz > 0, "Missing 'lz' attribute for semi_cylinder_bump geometry");
510 
511  if (_.vertex_count == 0) _.vertex_count = 10; // default
512 
513  auto glCyl = mrpt::opengl::CCylinder::Create();
514  glCyl->setHeight(_.lx);
515  glCyl->setRadius(_.ly * 0.5);
516  glCyl->setScale(2 * _.lz / _.ly, 1.0, 1.0);
517 
518  glCyl->setSlicesCount(_.vertex_count);
519  glCyl->setColor_u8(block_color_);
520 
522  glCyl, mrpt::poses::CPose3D::FromXYZYawPitchRoll(
523  -0.5 * _.lx, .0, .0, .0_deg, 90.0_deg, .0_deg));
524  }
525  break;
526 
528  {
529  ASSERTMSG_(_.lx > 0, "Missing 'lx' attribute for ramp geometry");
530  ASSERTMSG_(_.ly > 0, "Missing 'ly' attribute for ramp geometry");
531  ASSERTMSG_(_.lz > 0, "Missing 'lz' attribute for ramp geometry");
532 
533  auto glRamp = mrpt::opengl::CSetOfTriangles::Create();
534 
535  const auto p0 = mrpt::math::TPoint3Df(0, -_.ly * 0.5, 0);
536  const auto p1 = mrpt::math::TPoint3Df(_.lx, -_.ly * 0.5, _.lz);
537  const auto p2 = mrpt::math::TPoint3Df(0, _.ly * 0.5, 0);
538  const auto p3 = mrpt::math::TPoint3Df(_.lx, _.ly * 0.5, _.lz);
539  const auto p4 = mrpt::math::TPoint3Df(_.lx, -_.ly * 0.5, 0);
540  const auto p5 = mrpt::math::TPoint3Df(_.lx, _.ly * 0.5, 0);
541 
542  mrpt::opengl::TTriangle t;
543  t.setColor(block_color_);
544  // T0
545  t.vertex(0) = p0;
546  t.vertex(1) = p1;
547  t.vertex(2) = p2;
548  t.computeNormals();
549  glRamp->insertTriangle(t);
550  // T1
551  t.vertex(0) = p2;
552  t.vertex(1) = p1;
553  t.vertex(2) = p3;
554  t.computeNormals();
555  glRamp->insertTriangle(t);
556  // T2
557  t.vertex(0) = p0;
558  t.vertex(1) = p4;
559  t.vertex(2) = p1;
560  t.computeNormals();
561  glRamp->insertTriangle(t);
562  // T3
563  t.vertex(0) = p5;
564  t.vertex(1) = p3;
565  t.vertex(2) = p2;
566  t.computeNormals();
567  glRamp->insertTriangle(t);
568  // T4
569  t.vertex(0) = p4;
570  t.vertex(1) = p5;
571  t.vertex(2) = p1;
572  t.computeNormals();
573  glRamp->insertTriangle(t);
574  // T5
575  t.vertex(0) = p3;
576  t.vertex(1) = p1;
577  t.vertex(2) = p5;
578  t.computeNormals();
579  glRamp->insertTriangle(t);
580 
581  // done:
582  addCustomVisualization(glRamp);
583  }
584  break;
585 
586  default:
587  THROW_EXCEPTION_FMT("Unknown type in <geometry type='%s'...>", _.typeStr.c_str());
588  };
589 }
590 
592 {
593  // true if any of the limits is a nan:
595 }
596 
597 std::optional<float> mvsim::Block::getElevationAt(const mrpt::math::TPoint2D& worldXY) const
598 {
599  // Is the point within the block?
600  const auto& myPose = getCPose3D();
601 
602  const auto localPt = myPose.inverseComposePoint(mrpt::math::TPoint3D(worldXY.x, worldXY.y, .0));
603 
604  // Quick discard? (saves much time):
605  if (std::abs(localPt.x) > maxRadius_ && std::abs(localPt.y) > maxRadius_) return {};
606 
607  // If we are close, then check the exact polygon:
608  if (!blockShape().contains({localPt.x, localPt.y})) return {};
609 
610  // Yes, the query point is within my 2D shape. We need to evaluate the block height at that
611  // point:
612 
613  const auto& _ = geomParams_;
614  switch (_.type)
615  {
617  case GeometryType::Box:
619  default:
620  return myPose.z() + block_z_max_;
621 
622  case GeometryType::Ramp:
623  return myPose.z() + _.lz * localPt.x / _.lx;
624 
626  {
627  const auto f =
628  std::sqrt(std::max<double>(.0, 1.0 - mrpt::square(2.0 * localPt.y / _.ly)));
629  return myPose.z() + _.lz * f;
630  }
631  };
632 }
mvsim::Block::block_color_
mrpt::img::TColor block_color_
Definition: Block.h:165
mvsim::World::TGUI_Options::show_forces
bool show_forces
Definition: World.h:505
mvsim::VisualObject::parent
World * parent()
Definition: VisualObject.h:51
Block.h
mvsim::World::getBox2DGroundBody
b2Body * getBox2DGroundBody()
Definition: World.h:309
XMLClassesRegistry.h
mvsim
Definition: Client.h:21
mvsim::Block::restitution_
double restitution_
Default: 0.01.
Definition: Block.h:170
b2Vec2::y
float y
Definition: b2_math.h:128
mvsim::VisualObject::world_
World * world_
Definition: VisualObject.h:73
mvsim::Block::gl_block_
mrpt::opengl::CSetOfObjects::Ptr gl_block_
Definition: Block.h:224
mvsim::Block::force_segments_for_rendering_cs_
std::mutex force_segments_for_rendering_cs_
Definition: Block.h:226
mvsim::Block::factory
static Ptr factory(World *parent, const rapidxml::xml_node< char > *xml_node)
Definition: Block.cpp:64
mvsim::Block::isStatic_
bool isStatic_
Definition: Block.h:155
mvsim::JointXMLnode
Definition: basic_types.h:53
b2FrictionJointDef
Friction joint definition.
Definition: b2_friction_joint.h:30
mvsim::Block::mass
double mass() const
Definition: Block.h:108
mvsim::Block::Block
Block(World *parent)
Definition: Block.cpp:38
mvsim::Shape2p5::setShapeManual
void setShapeManual(const mrpt::math::TPolygon2D &contour, const float zMin, const float zMax)
Definition: Shape2p5.cpp:217
mvsim::GeometryType::Ramp
@ Ramp
mvsim::Block::maxRadius_
double maxRadius_
Definition: Block.h:160
JointXMLnode.h
s
XmlRpcServer s
mvsim::GeometryType::Invalid
@ Invalid
mvsim::parse_xmlnode_children_as_param
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions &params, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="", mrpt::system::COutputLogger *logger=nullptr)
Definition: xml_utils.cpp:215
mvsim::Block::internal_parseGeometry
void internal_parseGeometry(const rapidxml::xml_node< char > &xml_geom_node)
Definition: Block.cpp:443
mvsim::World::guiOptions_
TGUI_Options guiOptions_
Definition: World.h:544
mvsim::xml_to_str_solving_includes
std::string xml_to_str_solving_includes(const World &parent, const rapidxml::xml_node< char > *xml_node, const std::set< std::string > &varsRetain={})
Definition: xml_utils.cpp:498
b2FrictionJointDef::maxForce
float maxForce
The maximum friction force in N.
Definition: b2_friction_joint.h:52
b2FrictionJoint
Definition: b2_friction_joint.h:60
mvsim::World::applyWorldRenderOffset
mrpt::math::TPose3D applyWorldRenderOffset(mrpt::math::TPose3D p) const
Definition: World.h:631
World.h
mvsim::Simulable::getCPose3D
mrpt::poses::CPose3D getCPose3D() const
Alternative to getPose()
Definition: Simulable.cpp:157
b2_staticBody
@ b2_staticBody
Definition: b2_body.h:45
mvsim::Block::mass_
double mass_
Definition: Block.h:154
b2PolygonShape::ComputeMass
void ComputeMass(b2MassData *massData, float density) const override
Definition: b2_polygon_shape.cpp:357
mvsim::Block::gl_forces_
mrpt::opengl::CSetOfLines::Ptr gl_forces_
Definition: Block.h:225
mvsim::World::get_gravity
double get_gravity() const
Definition: World.h:154
mvsim::Block::friction_joints_
std::vector< b2FrictionJoint * > friction_joints_
Definition: Block.h:151
b2FixtureDef
Definition: b2_fixture.h:61
mvsim::Block::create_multibody_system
virtual void create_multibody_system(b2World &world)
Definition: Block.cpp:316
mvsim::Block::apply_force
virtual void apply_force(const mrpt::math::TVector2D &force, const mrpt::math::TPoint2D &applyPoint=mrpt::math::TPoint2D(0, 0)) override
Definition: Block.cpp:407
mvsim::VisualObject::addCustomVisualization
void addCustomVisualization(const mrpt::opengl::CRenderizable::Ptr &glModel, const mrpt::poses::CPose3D &modelPose={}, const float modelScale=1.0f, const std::string &modelName="group", const std::optional< std::string > &modelURI=std::nullopt, const bool initialShowBoundingBox=false)
Definition: VisualObject.cpp:262
b2Vec2
A 2D column vector.
Definition: b2_math.h:41
xml_utils.h
b2PolygonShape::Set
void Set(const b2Vec2 *points, int32 count)
Definition: b2_polygon_shape.cpp:118
f
f
mvsim::VisualObject::setCollisionShape
void setCollisionShape(const Shape2p5 &cs)
Definition: VisualObject.h:95
rapidxml::xml_attribute
Definition: rapidxml.hpp:138
b2BodyDef::type
b2BodyType type
Definition: b2_body.h:74
b2Fixture::GetMassData
void GetMassData(b2MassData *massData) const
Definition: b2_fixture.h:354
mvsim::XmlClassesRegistry::get
const rapidxml::xml_node< char > * get(const std::string &xml_node_class) const
Definition: XMLClassesRegistry.cpp:20
b2FixtureDef::restitution
float restitution
The restitution (elasticity) usually in the range [0,1].
Definition: b2_fixture.h:85
mvsim::Block::blockShape
const mrpt::math::TPolygon2D & blockShape() const
Definition: Block.h:89
b2FixtureDef::friction
float friction
The friction coefficient, usually in the range [0,1].
Definition: b2_fixture.h:82
mvsim::Shape2p5
Definition: Shape2p5.h:31
b2MassData::center
b2Vec2 center
The position of the shape's centroid relative to the shape's origin.
Definition: b2_shape.h:39
mvsim::Block::internal_internalGuiUpdate_forces
void internal_internalGuiUpdate_forces(mrpt::opengl::COpenGLScene &scene)
Definition: Block.cpp:287
mvsim::Block::geomParams_
GeometryParams geomParams_
Definition: Block.h:222
b2_dynamicBody
@ b2_dynamicBody
Definition: b2_body.h:47
mvsim::DummyInvisibleBlock::internalGuiUpdate
void internalGuiUpdate(const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &viz, const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &physical, [[maybe_unused]] bool childrenOnly) override
Definition: Block.cpp:433
rapidxml
Definition: rapidxml.hpp:57
mvsim::TSimulContext
Definition: basic_types.h:58
mvsim::JointXMLnode::first_node
const rapidxml::xml_node< Ch > * first_node(const char *name) const
Definition: JointXMLnode.h:30
b2Shape::m_radius
float m_radius
Definition: b2_shape.h:102
mvsim::Block::default_block_z_min_max
bool default_block_z_min_max() const
Definition: Block.cpp:591
mvsim::Block::block_z_min_
double block_z_min_
Definition: Block.h:162
mvsim::Block::block_poly_
mrpt::math::TPolygon2D block_poly_
Definition: Block.h:156
mvsim::Simulable::simul_post_timestep
virtual void simul_post_timestep(const TSimulContext &context)
Definition: Simulable.cpp:64
mvsim::World::getBox2DWorld
std::unique_ptr< b2World > & getBox2DWorld()
Definition: World.h:307
mvsim::Block::register_block_class
static void register_block_class(const World &parent, const rapidxml::xml_node< char > *xml_node)
Definition: Block.cpp:50
b2FixtureDef::density
float density
The density, usually in kg/m^2.
Definition: b2_fixture.h:92
mvsim::Simulable::name_
std::string name_
Definition: Simulable.h:145
b2FrictionJointDef::localAnchorB
b2Vec2 localAnchorB
The local anchor point relative to bodyB's origin.
Definition: b2_friction_joint.h:49
mvsim::XmlClassesRegistry
Definition: XMLClassesRegistry.h:19
b2Vec2::x
float x
Definition: b2_math.h:128
mvsim::GeometryType::Cylinder
@ Cylinder
mvsim::Block::simul_pre_timestep
virtual void simul_pre_timestep(const TSimulContext &context) override
Definition: Block.cpp:220
mvsim::Block::updateMaxRadiusFromPoly
void updateMaxRadiusFromPoly()
Definition: Block.cpp:303
b2BodyDef
Definition: b2_body.h:52
mvsim::DummyInvisibleBlock::sensors_
TListSensors sensors_
Sensors aboard.
Definition: Block.h:289
mvsim::GeometryType::SemiCylinderBump
@ SemiCylinderBump
mvsim::Block::groundFriction_
double groundFriction_
Default: 0.5.
Definition: Block.h:169
mvsim::Block::block_z_max_
double block_z_max_
Definition: Block.h:163
rapidxml::parse_error::where
Ch * where() const
Definition: rapidxml.hpp:94
mvsim::Block::isStatic
bool isStatic() const
Definition: Block.cpp:416
b2FixtureDef::shape
const b2Shape * shape
Definition: b2_fixture.h:76
mvsim::Block::setIsStatic
void setIsStatic(bool b)
Definition: Block.cpp:423
rapidxml::xml_document
Definition: rapidxml.hpp:139
mvsim::World
Definition: World.h:82
rapidxml::xml_node< char >
b2World::CreateBody
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
mvsim::World::user_defined_variables
const std::map< std::string, std::string > & user_defined_variables() const
Definition: World.h:390
b2PolygonShape
Definition: b2_polygon_shape.h:32
mvsim::Simulable
Definition: Simulable.h:39
mvsim::Block::getElevationAt
std::optional< float > getElevationAt(const mrpt::math::TPoint2D &worldXY) const override
Definition: Block.cpp:597
std
mvsim::GeometryType::Sphere
@ Sphere
mvsim::Block::Ptr
std::shared_ptr< Block > Ptr
Definition: Block.h:53
block_classes_registry
static XmlClassesRegistry block_classes_registry("block:class")
b2FrictionJointDef::maxTorque
float maxTorque
The maximum friction torque in N-m.
Definition: b2_friction_joint.h:55
mvsim::Block::intangible_
bool intangible_
Definition: Block.h:174
mvsim::parse_xmlnode_shape
void parse_xmlnode_shape(const rapidxml::xml_node< char > &xml_node, mrpt::math::TPolygon2D &out_poly, const char *functionNameContext="")
Definition: xml_utils.cpp:258
mvsim::Block::force_segments_for_rendering_
std::vector< mrpt::math::TSegment3D > force_segments_for_rendering_
Definition: Block.h:227
mvsim::Simulable::simul_pre_timestep
virtual void simul_pre_timestep(const TSimulContext &context)
Definition: Simulable.cpp:35
mvsim::Block::simul_post_timestep
virtual void simul_post_timestep(const TSimulContext &context) override
Definition: Block.cpp:227
mvsim::Block::fixture_block_
b2Fixture * fixture_block_
Definition: Block.h:192
mrpt::math
Definition: xml_utils.h:22
b2World
Definition: b2_world.h:46
mvsim::Simulable::getPose
mrpt::math::TPose3D getPose() const
Definition: Simulable.cpp:490
b2MassData
This holds the mass data computed for a shape.
Definition: b2_shape.h:33
mvsim::XmlClassesRegistry::add
void add(const std::string &input_xml_node_class)
Definition: XMLClassesRegistry.cpp:29
root
root
rapidxml::parse_error::what
virtual const char * what() const
Definition: rapidxml.hpp:85
mvsim::Block::lateral_friction_
double lateral_friction_
Default: 0.5.
Definition: Block.h:168
mvsim::Block::block_com_
mrpt::math::TPoint2D block_com_
In local coordinates.
Definition: Block.h:166
rapidxml.hpp
mvsim::parse_xmlnode_attribs
void parse_xmlnode_attribs(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions &params, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
Definition: xml_utils.cpp:182
b2FrictionJointDef::localAnchorA
b2Vec2 localAnchorA
The local anchor point relative to bodyA's origin.
Definition: b2_friction_joint.h:46
rapidxml::parse_error
Definition: rapidxml.hpp:71
mvsim::GeometryType::Box
@ Box
mvsim::VisualObject
Definition: VisualObject.h:35
t
geometry_msgs::TransformStamped t
mvsim::DummyInvisibleBlock::DummyInvisibleBlock
DummyInvisibleBlock(World *parent)
Definition: Block.cpp:431
b2JointDef::bodyA
b2Body * bodyA
The first attached body.
Definition: b2_joint.h:89
mvsim::Simulable::getPoseNoLock
mrpt::math::TPose3D getPoseNoLock() const
No thread-safe version. Used internally only.
Definition: Simulable.cpp:496
mvsim::Block::internalGuiUpdate
virtual void internalGuiUpdate(const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &viz, const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &physical, bool childrenOnly) override
Definition: Block.cpp:232
b2_maxPolygonVertices
#define b2_maxPolygonVertices
Definition: b2_settings.h:53
rapidxml::xml_document::parse
void parse(Ch *text)
Definition: rapidxml.hpp:1381
mvsim::JointXMLnode::add
void add(const rapidxml::xml_node< Ch > *node)
Definition: JointXMLnode.h:28
b2JointDef::bodyB
b2Body * bodyB
The second attached body.
Definition: b2_joint.h:92


mvsim
Author(s):
autogenerated on Wed May 28 2025 02:13:07