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