10 #include <mrpt/core/lock_helper.h>    11 #include <mrpt/math/TPose2D.h>    33 using namespace mvsim;
    44         static bool done = 
false;
    82           m_chassis_z_min(0.05),
    84           m_chassis_color(0xff, 0x00, 0x00),
    85           m_chassis_com(.0, .0),
    86           m_wheels_info(nWheels),
    87           m_fixture_wheels(nWheels, nullptr)
   107                         "[VehicleBase::register_vehicle_class] XML node is nullptr");
   108         if (0 != strcmp(xml_node->
name(), 
"vehicle:class"))
   110                         "[VehicleBase::register_vehicle_class] XML element is '%s' "   111                         "('vehicle:class' expected)",
   116         std::stringstream 
ss;
   133                 throw runtime_error(
"[VehicleBase::factory] XML node is nullptr");
   134         if (0 != strcmp(root->
name(), 
"vehicle"))
   136                         "[VehicleBase::factory] XML root element is '%s' ('vehicle' "   152                         const string sClassName = veh_class->
value();
   157                                         "[VehicleBase::factory] Vehicle class '%s' undefined",
   158                                         sClassName.c_str()));
   160                         veh_root_node.
add(class_root);
   167         const xml_node<>* dyn_node = veh_root_node.
first_node(
"dynamics");
   170                         "[VehicleBase::factory] Missing XML node <dynamics>");
   173         if (!dyn_class || !dyn_class->
value())
   175                         "[VehicleBase::factory] Missing mandatory attribute 'class' in "   182                         "[VehicleBase::factory] Unknown vehicle dynamics class '%s'",
   183                         dyn_class->
value()));
   190                 if (attrib_name && attrib_name->
value())
   192                         veh->m_name = attrib_name->
value();
   204                 const xml_node<>* node = veh_root_node.
first_node(
"init_pose");
   207                                 "[VehicleBase::factory] Missing XML node <init_pose>");
   210                 if (3 != ::sscanf(node->value(), 
"%lf %lf %lf", &p.
x, &p.
y, &p.
yaw))
   212                                 "[VehicleBase::factory] Error parsing "   213                                 "<init_pose>...</init_pose>");
   221                 const xml_node<>* node = veh_root_node.
first_node(
"init_vel");
   227                                         node->value(), 
"%lf %lf %lf", &dq.
vx, &dq.
vy, &dq.
omega))
   229                                         "[VehicleBase::factory] Error parsing "   230                                         "<init_vel>...</init_vel>");
   234                         dq.
rotate(veh->getPose().yaw);
   241         veh->parseVisual(veh_root_node.
first_node(
"visual"));
   242         veh->parseSimulable(veh_root_node.
first_node(
"publish"));
   246         veh->dynamics_load_params_from_xml(dyn_node);
   258                         veh->getVisualModelBoundingBox(bbmin, bbmax);
   262                                         "Error: Tag <shape_from_visual/> found but bounding box of "   263                                         "visual object seems incorrect.");
   266                         auto& poly = veh->m_chassis_poly;
   268                         poly.emplace_back(bbmin.
x, bbmin.
y);
   269                         poly.emplace_back(bbmin.
x, bbmax.
y);
   270                         poly.emplace_back(bbmax.
x, bbmax.
y);
   271                         poly.emplace_back(bbmax.
x, bbmin.
y);
   274         veh->updateMaxRadiusFromPoly();
   279                 const xml_node<>* log_path_node = veh_root_node.
first_node(
"log_path");
   283                         veh->m_log_path = log_path_node->value();
   296                 const auto q = veh->getPose();
   297                 const auto dq = veh->getTwist();
   299                 veh->m_b2d_body->SetTransform(
b2Vec2(
q.x, 
q.y), 
q.yaw);
   301                 veh->m_b2d_body->SetLinearVelocity(
b2Vec2(dq.vx, dq.vy));
   302                 veh->m_b2d_body->SetAngularVelocity(dq.omega);
   309                 const xml_node<>* frict_node = veh_root_node.
first_node(
"friction");
   313                         veh->m_friction = std::shared_ptr<FrictionBase>(
   319                         veh->m_friction = std::shared_ptr<FrictionBase>(
   327         for (
const auto& xmlNode : veh_root_node)
   329                 if (!strcmp(xmlNode->name(), 
"sensor"))
   340         World* parent, 
const std::string& xml_text)
   346         char* input_str = 
const_cast<char*
>(xml_text.c_str());
   350                 xml.
parse<0>(input_str);
   355                         static_cast<long>(std::count(input_str, e.
where<
char>(), 
'\n') + 1);
   357                         "[VehicleBase::factory] XML parse error (Line %u): %s",
   358                         static_cast<unsigned>(line), e.
what()));
   366         for (
auto& 
s : 
m_sensors) 
s->simul_pre_timestep(context);
   388         const double massPerWheel =
   390         const double weightPerWheel = massPerWheel * gravity;
   392         std::vector<mrpt::math::TPoint2D> wheels_vels;
   397         std::vector<mrpt::math::TSegment3D>
   400         for (
size_t i = 0; i < nW; i++)
   408                 fi.
weight = weightPerWheel;
   415                 m_friction->evaluate_friction(fi, net_force_);
   418                 const b2Vec2 wForce = m_b2d_body->GetWorldVector(
b2Vec2(
   419                         net_force_.
x, net_force_.
y));  
   420                 const b2Vec2 wPt = m_b2d_body->GetWorldPoint(
   425                 m_b2d_body->ApplyForce(wForce, wPt, 
true );
   448                         const double forceScale =
   472         for (
auto& 
s : 
m_sensors) 
s->simul_post_timestep(context);
   477         for (
size_t i = 0; i < nW; i++)
   488                 const double cur_abs_phi = std::abs(w.
getPhi());
   489                 if (cur_abs_phi > 1e4)
   491                                 ::fmod(cur_abs_phi, 2 * 
M_PI) *
   492                                 (w.
getPhi() < 0.0 ? -1.0 : 1.0));
   516         std::vector<mrpt::math::TPoint2D>& vels,
   524         const double w = veh_vel_local.
omega;  
   528         for (
size_t i = 0; i < nW; i++)
   532                 vels[i].x = veh_vel_local.
vx - w * wheel.
y;
   533                 vels[i].y = veh_vel_local.
vy + w * wheel.
x;
   571                 const float n = pt.norm();
   592                 std::vector<b2Vec2> pts(nPts);
   593                 for (
size_t i = 0; i < nPts; i++)
   597                 chassisPoly.
Set(&pts[0], nPts);
   602                 fixtureDef.
shape = &chassisPoly;
   638                 fixtureDef.
shape = &wheelShape;
   670                         for (
size_t i = 0; i < nWs; i++)
   672                                 m_gl_wheels[i] = mrpt::opengl::CSetOfObjects::Create();
   677                         mrpt::opengl::CPolyhedron::Ptr gl_poly =
   691                 for (
size_t i = 0; i < nWs; i++)
   733                         std::make_shared<CSVLogger>();
   750                         std::to_string(i + 1) + 
".log");
   756         std::map<std::string, std::shared_ptr<CSVLogger>>
::iterator it;
   759                 it->second->writeRow();
   768                 applyPoint.
x, applyPoint.
y));  
   769         m_b2d_body->ApplyForce(
b2Vec2(force.x, force.y), wPt, 
true );
   776         for (
auto& sensor : 
m_sensors) sensor->registerOnServer(c);
 
#define ASSERT_EQUAL_(__A, __B)
void getWheelsVelocityLocal(std::vector< mrpt::math::TPoint2D > &vels, const mrpt::math::TTwist2D &veh_vel_local) const 
mrpt::img::TColor m_chassis_color
double force_scale
In meters/Newton. 
void internal_internalGuiUpdate_forces(mrpt::opengl::COpenGLScene &scene)
This file contains rapidxml parser and DOM implementation. 
GLint GLint GLint GLint GLint GLint y
mrpt::opengl::CSetOfObjects::Ptr m_gl_chassis
void updateMaxRadiusFromPoly()
excludes the mass of wheels) 
static SensorBase::Ptr factory(VehicleBase &parent, const rapidxml::xml_node< char > *xml_node)
static constexpr char PL_DQ_Y[]
static Ptr factory(World *parent, const rapidxml::xml_node< char > *xml_node)
static constexpr char PL_Q_ROLL[]
#define THROW_EXCEPTION(msg)
GLubyte GLubyte GLubyte GLubyte w
virtual void simul_post_timestep(const TSimulContext &context) override
double simul_time
Current time in the simulated world. 
#define REGISTER_VEHICLE_DYNAMICS(TEXTUAL_NAME, CLASS_NAME)
virtual void initLoggers()
static constexpr char LOGGER_WHEEL[]
std::vector< double > m_torque_per_wheel
static constexpr char WL_VEL_X[]
mrpt::math::TPose3D getPose() const 
static CSetOfLinesPtr Create(const std::vector< mrpt::math::TSegment3D > &sgms, const bool antiAliasing=true)
std::unique_ptr< b2World > & getBox2DWorld()
void getAs3DObject(mrpt::opengl::CSetOfObjects &obj)
std::shared_ptr< CSVLogger > getLoggerPtr(std::string logger_name)
static constexpr char PL_Q_X[]
static constexpr char WL_TORQUE[]
b2Vec2 center
The position of the shape's centroid relative to the shape's origin. 
virtual void internalGuiUpdate(mrpt::opengl::COpenGLScene &scene, bool childrenOnly) override
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const 
void insert(const CRenderizablePtr &newObject, const std::string &viewportName=std::string("main"))
static constexpr char PL_Q_Z[]
static constexpr char PL_Q_PITCH[]
std::vector< mrpt::math::TSegment3D > m_force_segments_for_rendering
double get_gravity() const 
TClassFactory_vehicleDynamics classFactory_vehicleDynamics
static constexpr char PL_Q_YAW[]
static constexpr char PL_DQ_Z[]
size_t getNumWheels() const 
void ComputeMass(b2MassData *massData, float32 density) const 
float32 mass
The mass of the shape, usually in kilograms. 
VehicleBase(World *parent, size_t nWheels)
static CPolyhedronPtr CreateCustomPrism(const std::vector< mrpt::math::TPoint2D > &baseVertices, double height)
mrpt::math::TTwist2D getVelocityLocal() const 
void setPhi(double val)
Orientation (rad) wrt vehicle local frame. 
double getW() const 
Spinning velocity (rad/s) wrt shaft. 
GLint GLint GLint GLint GLint x
std::shared_ptr< SensorBase > Ptr
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
void internal_internalGuiUpdate_sensors(mrpt::opengl::COpenGLScene &scene)
virtual void create_multibody_system(b2World &world)
std::shared_ptr< VehicleBase > Ptr
mrpt::opengl::CSetOfLines::Ptr m_gl_forces
std::mutex m_force_segments_for_rendering_cs
TGUI_Options m_gui_options
virtual const char * what() const 
static constexpr char PL_Q_Y[]
static constexpr char WL_FRIC_X[]
static constexpr char PL_DQ_X[]
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const 
#define b2_maxPolygonVertices
Ptr create(const std::string &class_name, ARG1 a1) const 
static void register_vehicle_class(const rapidxml::xml_node< char > *xml_node)
std::map< std::string, std::shared_ptr< CSVLogger > > m_loggers
void GetMassData(b2MassData *massData) const 
void rotate(const double ang)
virtual void registerOnServer(mvsim::Client &c)
void registerOnServer(mvsim::Client &c) override
TListSensors m_sensors
Sensors aboard. 
float32 density
The density, usually in kg/m^2. 
const Wheel & getWheelInfo(const size_t idx) const 
virtual void invoke_motor_controllers(const TSimulContext &context, std::vector< double > &out_force_per_wheel)=0
void SetAsBox(float32 hx, float32 hy)
virtual void simul_post_timestep(const TSimulContext &context)
double getPhi() const 
Orientation (rad) wrt vehicle local frame. 
const rapidxml::xml_node< Ch > * first_node(const char *name)
std::vector< Wheel > m_wheels_info
virtual void simul_pre_timestep(const TSimulContext &context)
std::vector< mrpt::opengl::CSetOfObjects::Ptr > m_gl_wheels
void Set(const b2Vec2 *points, int32 count)
virtual void writeLogStrings()
virtual mrpt::poses::CPose3D internalGuiGetVisualPose() override
float32 restitution
The restitution (elasticity) usually in the range [0,1]. 
const rapidxml::xml_node< char > * get(const std::string &xml_node_class) const 
static constexpr char WL_VEL_Y[]
std::vector< b2Fixture * > m_fixture_wheels
static constexpr char LOGGER_POSE[]
double m_chassis_z_min
each change via updateMaxRadiusFromPoly() 
static FrictionBase::Ptr factory(VehicleBase &parent, const rapidxml::xml_node< char > *xml_node)
This file contains rapidxml printer implementation. 
void add(const std::string &input_xml_node_class)
static constexpr char WL_WEIGHT[]
GLdouble GLdouble GLdouble GLdouble q
void register_all_veh_dynamics()
static XmlClassesRegistry veh_classes_registry("vehicle:class")
mrpt::math::TPoint2D m_chassis_com
GLint GLint GLint GLint GLint GLint GLsizei width
mrpt::math::TPolygon2D m_chassis_poly
static constexpr char WL_FRIC_Y[]
b2Fixture * m_fixture_chassis
Created at. 
This holds the mass data computed for a shape. 
virtual void apply_force(const mrpt::math::TVector2D &force, const mrpt::math::TPoint2D &applyPoint=mrpt::math::TPoint2D(0, 0)) override
void add(const rapidxml::xml_node< Ch > *node)
float32 friction
The friction coefficient, usually in the range [0,1]. 
virtual double getChassisMass() const 
b2Body * CreateBody(const b2BodyDef *def)
FrictionBasePtr m_friction
mrpt::math::TTwist2D getTwist() const 
static constexpr char DL_TIMESTAMP[]
virtual void simul_pre_timestep(const TSimulContext &context) override