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.