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/CSphere.h> 18 #include <mrpt/poses/CPose2D.h> 19 #include <mrpt/version.h> 34 using namespace mvsim;
57 "[Block::register_vehicle_class] XML node is nullptr");
58 if (0 != strcmp(xml_node->
name(),
"block:class"))
59 throw runtime_error(mrpt::format(
60 "[Block::register_block_class] XML element is '%s' " 61 "('block:class' expected)",
77 if (!root)
throw runtime_error(
"[Block::factory] XML node is nullptr");
78 if (0 != strcmp(root->
name(),
"block"))
79 throw runtime_error(mrpt::format(
80 "[Block::factory] XML root element is '%s' ('block' expected)",
94 const string sClassName = block_class->value();
98 "[Block::factory] Block class '%s' undefined",
101 nodes.
add(class_root);
114 if (attrib_name && attrib_name->
value())
116 block->name_ = attrib_name->
value();
122 block->name_ = mrpt::format(
"block%03i", ++cnt);
128 block->parseSimulable(nodes);
142 block->parseVisual(nodes);
145 if (
const auto* xml_shape = nodes.
first_node(
"shape"); xml_shape)
148 *xml_shape, block->block_poly_,
"[Block::factory]");
149 block->updateMaxRadiusFromPoly();
151 else if (
const auto* xml_geom = nodes.
first_node(
"geometry"); xml_geom)
153 block->internal_parseGeometry(*xml_geom);
161 const auto& bbVis = block->collisionShape();
162 if (!bbVis.has_value())
165 "Error: Tag <shape_from_visual/> found but neither <visual> " 166 "nor <geometry> entries, while parsing <block>");
168 const auto& bb = bbVis.value();
170 if (bb.volume() == 0)
173 "Error: Tag <shape_from_visual/> found but bounding box of " 174 "visual object seems incorrect, while parsing <block>");
178 block->block_poly_ = bb.getContour();
179 block->block_z_min(bb.zMin());
180 block->block_z_max(bb.zMax());
186 if (block->default_block_z_min_max())
188 block->block_z_min(0.0);
189 block->block_z_max(1.0);
193 block->updateMaxRadiusFromPoly();
202 const auto q = block->getPose();
203 const auto dq = block->getTwist();
205 block->b2dBody_->SetTransform(
b2Vec2(q.x, q.y), q.yaw);
207 block->b2dBody_->SetLinearVelocity(
b2Vec2(dq.vx, dq.vy));
208 block->b2dBody_->SetAngularVelocity(dq.omega);
220 char* input_str =
const_cast<char*
>(xml_text.c_str());
224 xml.
parse<0>(input_str);
229 static_cast<long>(std::count(input_str, e.
where<
char>(),
'\n') + 1);
230 throw std::runtime_error(mrpt::format(
231 "[Block::factory] XML parse error (Line %u): %s",
232 static_cast<unsigned>(line), e.
what()));
250 const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& viz,
251 const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& physical,
260 gl_block_ = mrpt::opengl::CSetOfObjects::Create();
264 auto gl_poly = mrpt::opengl::CPolyhedron::CreateCustomPrism(
270 #if MRPT_VERSION >= 0x240 292 gl_forces_ = mrpt::opengl::CSetOfLines::Create();
304 [[maybe_unused]] mrpt::opengl::COpenGLScene& scene)
326 const float n = segment.norm();
357 std::vector<b2Vec2> pts(nPts);
358 for (
size_t i = 0; i < nPts; i++)
362 blockPoly.
Set(&pts[0], nPts);
369 fixtureDef.
shape = &blockPoly;
395 const size_t nContactPoints = 2;
396 const double weight_per_contact_point =
399 const double max_friction = mu * weight_per_contact_point;
402 const mrpt::math::TPoint2D pt_loc[nContactPoints] = {
409 fjd.
bodyB = b2dBody_;
411 for (
size_t i = 0; i < nContactPoints; i++)
413 const b2Vec2 local_pt =
b2Vec2(pt_loc[i].x, pt_loc[i].y);
427 const mrpt::math::TVector2D& force,
const mrpt::math::TPoint2D& applyPoint)
433 b2dBody_->GetWorldPoint(
b2Vec2(applyPoint.x, applyPoint.y));
434 b2dBody_->ApplyForce(
b2Vec2(force.x, force.y), wPt,
true );
458 const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& viz,
459 const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& physical,
460 [[maybe_unused]]
bool childrenOnly)
462 if (!viz || !physical)
return;
464 for (
auto&
s :
sensors_)
s->guiUpdate(viz, physical);
472 float length = 0, lx = 0, ly = 0, lz = 0;
473 int vertex_count = 0;
476 {
"type", {
"%s", &type}},
477 {
"radius", {
"%f", &radius}},
478 {
"length", {
"%f", &length}},
482 {
"vertex_count", {
"%i", &vertex_count}},
487 "[Block::internal_parseGeometry]");
492 "Geometry type attribute is missing, i.e. <geometry type='...' ... " 496 if (type ==
"cylinder")
499 radius > 0,
"Missing 'radius' attribute for cylinder geometry");
501 length > 0,
"Missing 'length' attribute for cylinder geometry");
503 if (vertex_count == 0) vertex_count = 10;
505 auto glCyl = mrpt::opengl::CCylinder::Create();
506 glCyl->setHeight(length);
507 glCyl->setRadius(radius);
508 glCyl->setSlicesCount(vertex_count);
509 glCyl->setColor_u8(block_color_);
512 else if (type ==
"sphere")
515 radius > 0,
"Missing 'radius' attribute for cylinder geometry");
517 if (vertex_count == 0) vertex_count = 10;
519 auto glSph = mrpt::opengl::CSphere::Create(radius, vertex_count);
520 glSph->setColor_u8(block_color_);
523 else if (type ==
"box")
525 ASSERTMSG_(lx > 0,
"Missing 'lx' attribute for box geometry");
526 ASSERTMSG_(ly > 0,
"Missing 'ly' attribute for box geometry");
527 ASSERTMSG_(lz > 0,
"Missing 'lz' attribute for box geometry");
529 auto glBox = mrpt::opengl::CBox::Create();
530 glBox->setBoxCorners({0, 0, 0}, {lx, ly, lz});
531 glBox->setColor_u8(block_color_);
537 "Unknown type in <geometry type='%s'...>", type.c_str());
544 return block_z_max_ != block_z_max_ || block_z_min_ != block_z_min_;
This file contains rapidxml parser and DOM implementation.
float mass
The mass of the shape, usually in kilograms.
float maxForce
The maximum friction force in N.
mrpt::math::TPoint2D block_com_
In local coordinates.
std::vector< b2FrictionJoint * > friction_joints_
mrpt::opengl::CSetOfLines::Ptr gl_forces_
b2Fixture * fixture_block_
b2Vec2 localAnchorA
The local anchor point relative to bodyA's origin.
float density
The density, usually in kg/m^2.
mrpt::opengl::CSetOfObjects::Ptr gl_block_
std::map< std::string, TParamEntry > TParameterDefinitions
virtual const char * what() const
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions ¶ms, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="", mrpt::system::COutputLogger *logger=nullptr)
mrpt::math::TPose3D getPose() const
void updateMaxRadiusFromPoly()
bool default_block_z_min_max() const
float maxTorque
The maximum friction torque in N-m.
mrpt::img::TColor block_color_
b2Vec2 localAnchorB
The local anchor point relative to bodyB's origin.
mrpt::math::TPose3D getPoseNoLock() const
No thread-safe version. Used internally only.
double restitution_
Default: 0.01.
std::vector< mrpt::math::TSegment3D > force_segments_for_rendering_
const rapidxml::xml_node< Ch > * first_node(const char *name) const
virtual void apply_force(const mrpt::math::TVector2D &force, const mrpt::math::TPoint2D &applyPoint=mrpt::math::TPoint2D(0, 0)) override
static Ptr factory(World *parent, const rapidxml::xml_node< char > *xml_node)
GLenum GLuint GLenum GLsizei length
static void register_block_class(const rapidxml::xml_node< char > *xml_node)
std::unique_ptr< b2World > & getBox2DWorld()
double lateral_friction_
Default: 0.5.
void parse_xmlnode_attribs(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions ¶ms, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
b2Vec2 center
The position of the shape's centroid relative to the shape's origin.
std::shared_ptr< Block > Ptr
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
void ComputeMass(b2MassData *massData, float density) const override
Friction joint definition.
void setShapeManual(const mrpt::math::TPolygon2D &contour, const float zMin, const float zMax)
mrpt::math::TPolygon2D block_poly_
void GetMassData(b2MassData *massData) const
virtual void create_multibody_system(b2World &world)
DummyInvisibleBlock(World *parent)
const std::map< std::string, std::string > & user_defined_variables() const
TListSensors sensors_
Sensors aboard.
void internal_parseGeometry(const rapidxml::xml_node< char > &xml_geom_node)
void setCollisionShape(const Shape2p5 &cs)
virtual void simul_post_timestep(const TSimulContext &context)
virtual void simul_pre_timestep(const TSimulContext &context) override
virtual void simul_pre_timestep(const TSimulContext &context)
void internal_internalGuiUpdate_forces(mrpt::opengl::COpenGLScene &scene)
void Set(const b2Vec2 *points, int32 count)
void internalGuiUpdate(const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &viz, const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &physical, [[maybe_unused]] bool childrenOnly) override
double groundFriction_
Default: 0.5.
b2Body * getBox2DGroundBody()
virtual void simul_post_timestep(const TSimulContext &context) override
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)
#define b2_maxPolygonVertices
void parse_xmlnode_shape(const rapidxml::xml_node< char > &xml_node, mrpt::math::TPolygon2D &out_poly, const char *functionNameContext="")
This file contains rapidxml printer implementation.
const rapidxml::xml_node< char > * get(const std::string &xml_node_class) const
void add(const std::string &input_xml_node_class)
b2Body * bodyA
The first attached body.
float restitution
The restitution (elasticity) usually in the range [0,1].
This holds the mass data computed for a shape.
virtual void internalGuiUpdate(const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &viz, const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &physical, bool childrenOnly) override
void add(const rapidxml::xml_node< Ch > *node)
static XmlClassesRegistry block_classes_registry("block:class")
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
b2Body * CreateBody(const b2BodyDef *def)
b2Body * bodyB
The second attached body.
float friction
The friction coefficient, usually in the range [0,1].
std::mutex force_segments_for_rendering_cs_
double get_gravity() const