20 #include <mrpt/poses/CPose2D.h> 21 #include <mrpt/opengl/CPolyhedron.h> 23 #include <mrpt/version.h> 24 #if MRPT_VERSION < 0x199 25 #include <mrpt/utils/utils_defs.h> 28 #include <mrpt/math/TPose2D.h> 29 #include <mrpt/core/format.h> 30 #include <mrpt/core/bits_math.h> 31 using namespace mrpt::img;
39 using namespace mvsim;
48 m_b2d_block_body(NULL),
49 m_q(0, 0, 0, 0, 0, 0),
54 m_block_color(0x00, 0x00, 0xff),
56 m_lateral_friction(0.5),
57 m_ground_friction(0.5),
62 m_block_poly.push_back(TPoint2D(-0.5, -0.5));
63 m_block_poly.push_back(TPoint2D(-0.5, 0.5));
64 m_block_poly.push_back(TPoint2D(0.5, 0.5));
65 m_block_poly.push_back(TPoint2D(0.5, -0.5));
66 updateMaxRadiusFromPoly();
74 const b2Vec2& pos = m_b2d_block_body->GetPosition();
83 const b2Vec2& vel = m_b2d_block_body->GetLinearVelocity();
84 const float32 w = m_b2d_block_body->GetAngularVelocity();
85 m_dq.vals[0] = vel(0);
86 m_dq.vals[1] = vel(1);
97 throw runtime_error(
"[Block::register_vehicle_class] XML node is NULL");
98 if (0 != strcmp(xml_node->
name(),
"block:class"))
99 throw runtime_error(mrpt::format(
100 "[Block::register_block_class] XML element is '%s' " 101 "('block:class' expected)",
106 std::stringstream ss;
119 if (!root)
throw runtime_error(
"[Block::factory] XML node is NULL");
120 if (0 != strcmp(root->
name(),
"block"))
121 throw runtime_error(mrpt::format(
122 "[Block::factory] XML root element is '%s' ('block' expected)",
136 const string sClassName = block_class->
value();
139 throw runtime_error(mrpt::format(
140 "[Block::factory] Block class '%s' undefined",
141 sClassName.c_str()));
142 block_root_node.
add(class_root);
155 if (attrib_name && attrib_name->
value())
163 block->
m_name = mrpt::format(
"block%i", ++cnt);
169 const xml_node<>* node = block_root_node.
first_node(
"init_pose");
172 "[Block::factory] Missing XML node <init_pose>");
175 node->value(),
"%lf %lf %lf", &block->m_q.x, &block->m_q.y,
178 "[Block::factory] Error parsing <init_pose>...</init_pose>");
179 block->m_q.yaw *= M_PI / 180.0;
184 const xml_node<>* node = block_root_node.
first_node(
"init_vel");
188 node->value(),
"%lf %lf %lf", &block->m_dq.vals[0],
189 &block->m_dq.vals[1], &block->m_dq.vals[2]))
191 "[Block::factory] Error parsing <init_vel>...</init_vel>");
192 block->m_dq.vals[2] *= M_PI / 180.0;
195 const mrpt::poses::CPose2D pose(
196 0, 0, block->m_q.yaw);
198 block->m_dq.vals[0], block->m_dq.vals[1], block->m_dq.vals[0],
199 block->m_dq.vals[1]);
204 std::map<std::string, TParamEntry> params;
205 params[
"mass"] =
TParamEntry(
"%lf", &block->m_mass);
206 params[
"zmin"] =
TParamEntry(
"%lf", &block->m_block_z_min);
207 params[
"zmax"] =
TParamEntry(
"%lf", &block->m_block_z_max);
208 params[
"ground_friction"] =
TParamEntry(
"%lf", &block->m_ground_friction);
209 params[
"lateral_friction"] =
TParamEntry(
"%lf", &block->m_lateral_friction);
210 params[
"restitution"] =
TParamEntry(
"%lf", &block->m_restitution);
211 params[
"color"] =
TParamEntry(
"%color", &block->m_block_color);
216 *class_root, params,
"[Block::factory]");
224 *xml_shape, block->m_block_poly,
"[Block::factory]");
225 block->updateMaxRadiusFromPoly();
233 if (block->m_b2d_block_body)
236 block->m_b2d_block_body->SetTransform(
237 b2Vec2(block->m_q.x, block->m_q.y), block->m_q.yaw);
239 block->m_b2d_block_body->SetLinearVelocity(
240 b2Vec2(block->m_dq.vals[0], block->m_dq.vals[1]));
241 block->m_b2d_block_body->SetAngularVelocity(block->m_dq.vals[2]);
253 char* input_str =
const_cast<char*
>(xml_text.c_str());
257 xml.
parse<0>(input_str);
262 static_cast<long>(std::count(input_str, e.
where<
char>(),
'\n') + 1);
263 throw std::runtime_error(mrpt::format(
264 "[Block::factory] XML parse error (Line %u): %s",
265 static_cast<unsigned>(line), e.
what()));
278 local_vel.
vals[2] = m_dq.vals[2];
280 const mrpt::poses::CPose2D p(0, 0, -m_q.yaw);
282 m_dq.vals[0], m_dq.vals[1], local_vel.
vals[0], local_vel.
vals[1]);
288 return mrpt::poses::CPose2D(mrpt::math::TPose2D(m_q));
298 m_gl_block = mrpt::opengl::CSetOfObjects::Create();
301 auto gl_poly = mrpt::opengl::CPolyhedron::CreateCustomPrism(
302 m_block_poly, m_block_z_max - m_block_z_min);
303 gl_poly->setLocation(0, 0, m_block_z_min);
304 gl_poly->setColor(TColorf(m_block_color));
305 m_gl_block->insert(gl_poly);
310 m_gl_forces = mrpt::opengl::CSetOfLines::Create();
311 m_gl_forces->setLineWidth(3.0);
312 m_gl_forces->setColor_u8(TColor(0xff, 0xff, 0xff));
315 scene, 3, m_gl_forces);
319 m_gl_block->setPose(m_q);
322 internal_gui_update_forces(scene);
325 void Block::internal_gui_update_forces(mrpt::opengl::COpenGLScene& scene)
329 std::lock_guard<std::mutex> csl(m_force_segments_for_rendering_cs);
330 m_gl_forces->clear();
331 m_gl_forces->appendLines(m_force_segments_for_rendering);
332 m_gl_forces->setVisibility(
true);
336 m_gl_forces->setVisibility(
false);
340 void Block::updateMaxRadiusFromPoly()
344 m_max_radius = 0.001f;
345 for (TPolygon2D::const_iterator it = m_block_poly.begin();
346 it != m_block_poly.end(); ++it)
348 const float n = it->norm();
349 keep_max(m_max_radius, n);
360 m_b2d_block_body = world->
CreateBody(&bodyDef);
366 const size_t nPts = m_block_poly.size();
369 std::vector<b2Vec2> pts(nPts);
370 for (
size_t i = 0; i < nPts; i++)
371 pts[i] =
b2Vec2(m_block_poly[i].
x, m_block_poly[i].
y);
374 blockPoly.
Set(&pts[0], nPts);
379 fixtureDef.
shape = &blockPoly;
388 fixtureDef.
friction = m_lateral_friction;
391 m_fixture_block = m_b2d_block_body->CreateFixture(&fixtureDef);
395 m_fixture_block->GetMassData(&vehMass);
396 m_block_com.x = vehMass.
center.
x;
397 m_block_com.y = vehMass.
center.
y;
402 const size_t nContactPoints = 2;
403 const double weight_per_contact_point =
405 const double mu = m_ground_friction;
406 const double max_friction = mu * weight_per_contact_point;
409 const vec2 pt_loc[nContactPoints] = {
vec2(m_max_radius, 0),
410 vec2(-m_max_radius, 0)};
415 fjd.
bodyB = m_b2d_block_body;
417 for (
size_t i = 0; i < nContactPoints; i++)
419 const b2Vec2 local_pt =
b2Vec2(pt_loc[i].vals[0], pt_loc[i].vals[1]);
421 fjd.
localAnchorA = m_b2d_block_body->GetWorldPoint(local_pt);
428 m_friction_joints.push_back(b2_friction);
433 double fx,
double fy,
double local_ptx,
double local_pty)
435 ASSERT_(m_b2d_block_body);
436 const b2Vec2 wPt = m_b2d_block_body->GetWorldPoint(
437 b2Vec2(local_ptx, local_pty));
438 m_b2d_block_body->ApplyForce(
b2Vec2(fx, fy), wPt,
true );
vec3 getVelocityLocal() const
This file contains rapidxml parser and DOM implementation.
b2Vec2 localAnchorA
The local anchor point relative to bodyA's origin.
void parse_xmlnode_shape(const rapidxml::xml_node< char > &xml_node, mrpt::math::TPolygon2D &out_poly, const char *function_name_context="")
virtual void apply_force(double fx, double fy, double local_ptx=0.0, double local_pty=0.0)
std::string m_name
User-supplied name of the block (e.g. "r1", "veh1")
b2Vec2 localAnchorB
The local anchor point relative to bodyB's origin.
float32 maxForce
The maximum friction force in N.
virtual void simul_post_timestep(const TSimulContext &context)
static void register_block_class(const rapidxml::xml_node< char > *xml_node)
void simul_post_timestep_common(const TSimulContext &context)
b2Vec2 center
The position of the shape's centroid relative to the shape's origin.
TFSIMD_FORCE_INLINE const tfScalar & y() const
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
Friction joint definition.
double get_gravity() const
void ComputeMass(b2MassData *massData, float32 density) const
float32 mass
The mass of the shape, usually in kilograms.
virtual void create_multibody_system(b2World *world)
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const std::map< std::string, TParamEntry > ¶ms, const char *function_name_context="")
b2Joint * CreateJoint(const b2JointDef *def)
#define SCENE_INSERT_Z_ORDER(_SCENE, _ZORDER_INDEX, _OBJ_TO_INSERT)
float32 maxTorque
The maximum friction torque in N-m.
TGUI_Options m_gui_options
virtual void gui_update(mrpt::opengl::COpenGLScene &scene)
virtual const char * what() const
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
#define b2_maxPolygonVertices
TFSIMD_FORCE_INLINE const tfScalar & x() const
float32 density
The density, usually in kg/m^2.
const rapidxml::xml_node< Ch > * first_node(const char *name)
static Block * factory(World *parent, const rapidxml::xml_node< char > *xml_node)
TFSIMD_FORCE_INLINE const tfScalar & w() const
void Set(const b2Vec2 *points, int32 count)
b2Body * getBox2DGroundBody()
float32 restitution
The restitution (elasticity) usually in the range [0,1].
const rapidxml::xml_node< char > * get(const std::string &xml_node_class) const
b2World * getBox2DWorld()
This file contains rapidxml printer implementation.
void add(const std::string &input_xml_node_class)
b2Body * bodyA
The first attached body.
This holds the mass data computed for a shape.
void add(const rapidxml::xml_node< Ch > *node)
XmlClassesRegistry block_classes_registry("block:class")
float32 friction
The friction coefficient, usually in the range [0,1].
mrpt::poses::CPose2D getCPose2D() const
virtual void simul_pre_timestep(const TSimulContext &context)
b2Body * CreateBody(const b2BodyDef *def)
b2Body * bodyB
The second attached body.