VehicleDifferential.cpp
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2020 Jose Luis Blanco Claraco |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under 3-clause BSD License |
7  | See COPYING |
8  +-------------------------------------------------------------------------+ */
9 
12 #include <mvsim/World.h>
13 
14 #include <rapidxml.hpp>
15 
16 #include "xml_utils.h"
17 
18 using namespace mvsim;
19 using namespace std;
20 
21 // Ctor:
23  : VehicleBase(parent, 2 /*num wheels*/)
24 {
25  using namespace mrpt::math;
26 
27  m_chassis_mass = 15.0;
28  m_chassis_z_min = 0.05;
29  m_chassis_z_max = 0.6;
30  m_chassis_color = mrpt::img::TColor(0xff, 0x00, 0x00);
31 
32  // Default shape:
33  m_chassis_poly.clear();
34  m_chassis_poly.emplace_back(-0.4, -0.5);
35  m_chassis_poly.emplace_back(-0.4, 0.5);
36  m_chassis_poly.emplace_back(0.4, 0.5);
37  m_chassis_poly.emplace_back(0.6, 0.3);
38  m_chassis_poly.emplace_back(0.6, -0.3);
39  m_chassis_poly.emplace_back(0.4, -0.5);
41 
42  m_fixture_chassis = nullptr;
43  for (int i = 0; i < 2; i++) m_fixture_wheels[i] = nullptr;
44 }
45 
48  const rapidxml::xml_node<char>* xml_node)
49 {
50  const std::map<std::string, std::string> varValues = {{"NAME", m_name}};
51 
52  // <chassis ...> </chassis>
53  const rapidxml::xml_node<char>* xml_chassis =
54  xml_node->first_node("chassis");
55  if (xml_chassis)
56  {
57  // Attribs:
59  attribs["mass"] = TParamEntry("%lf", &this->m_chassis_mass);
60  attribs["zmin"] = TParamEntry("%lf", &this->m_chassis_z_min);
61  attribs["zmax"] = TParamEntry("%lf", &this->m_chassis_z_max);
62  attribs["color"] = TParamEntry("%color", &this->m_chassis_color);
63 
65  *xml_chassis, attribs, varValues,
66  "[DynamicsDifferential::dynamics_load_params_from_xml]");
67 
68  // Shape node (optional, fallback to default shape if none found)
69  const rapidxml::xml_node<char>* xml_shape =
70  xml_chassis->first_node("shape");
71  if (xml_shape)
73  *xml_shape, m_chassis_poly,
74  "[DynamicsDifferential::dynamics_load_params_from_xml]");
75  }
76 
77  // <l_wheel ...>, <r_wheel ...>
78  const char* w_names[2] = {"l_wheel", "r_wheel"};
79  const double w_default_y[2] = {0.5, -0.5};
80  m_wheels_info.clear();
81  m_wheels_info.resize(2); // reset default values
82 
83  // Load common params:
84  for (size_t i = 0; i < 2; i++)
85  {
86  const rapidxml::xml_node<char>* xml_wheel =
87  xml_node->first_node(w_names[i]);
88  if (xml_wheel)
89  m_wheels_info[i].loadFromXML(xml_wheel);
90  else
91  m_wheels_info[i].y = w_default_y[i];
92  }
93 
94  // Vehicle controller:
95  // -------------------------------------------------
96  {
97  const rapidxml::xml_node<char>* xml_control =
98  xml_node->first_node("controller");
99  if (xml_control)
100  {
101  rapidxml::xml_attribute<char>* control_class =
102  xml_control->first_attribute("class");
103  if (!control_class || !control_class->value())
104  throw runtime_error(
105  "[DynamicsDifferential] Missing 'class' attribute in "
106  "<controller> XML node");
107 
108  const std::string sCtrlClass = std::string(control_class->value());
109  if (sCtrlClass == ControllerRawForces::class_name())
110  m_controller =
112  else if (sCtrlClass == ControllerTwistPID::class_name())
114  else
115  throw runtime_error(mrpt::format(
116  "[DynamicsDifferential] Unknown 'class'='%s' in "
117  "<controller> XML node",
118  sCtrlClass.c_str()));
119 
120  m_controller->load_config(*xml_control);
121  }
122  }
123 
124  // Default controller:
125  if (!m_controller)
127 }
128 
129 // See docs in base class:
131  const TSimulContext& context, std::vector<double>& out_torque_per_wheel)
132 {
133  // Longitudinal forces at each wheel:
134  out_torque_per_wheel.assign(2, 0.0);
135 
136  if (m_controller)
137  {
138  // Invoke controller:
139  TControllerInput ci;
140  ci.context = context;
142  m_controller->control_step(ci, co);
143  // Take its output:
144  out_torque_per_wheel[WHEEL_L] = co.wheel_torque_l;
145  out_torque_per_wheel[WHEEL_R] = co.wheel_torque_r;
146  }
147 }
148 
149 // See docs in base class:
151 {
152  mrpt::math::TTwist2D odo_vel;
153  // Equations:
154 
155  // Velocities in local +X at each wheel i={0,1}:
156  // v_i = vx - w_veh * wheel_{i,y} = w_i * R_i
157  // Re-arranging:
158  const double w0 = m_wheels_info[WHEEL_L].getW();
159  const double w1 = m_wheels_info[WHEEL_R].getW();
160  const double R0 = m_wheels_info[WHEEL_L].diameter * 0.5;
161  const double R1 = m_wheels_info[WHEEL_R].diameter * 0.5;
162 
163  const double Ay = m_wheels_info[WHEEL_L].y - m_wheels_info[WHEEL_R].y;
164  ASSERTMSG_(
165  Ay != 0.0,
166  "The two wheels of a differential vehicle CAN'T by at the same Y "
167  "coordinate!");
168 
169  const double w_veh = (w1 * R1 - w0 * R0) / Ay;
170  const double vx_veh = w0 * R0 + w_veh * m_wheels_info[WHEEL_L].y;
171 
172  odo_vel.vx = vx_veh;
173  odo_vel.vy = 0.0;
174  odo_vel.omega = w_veh;
175 
176  return odo_vel;
177 }
mrpt::img::TColor m_chassis_color
Definition: VehicleBase.h:189
This file contains rapidxml parser and DOM implementation.
void updateMaxRadiusFromPoly()
excludes the mass of wheels)
std::map< std::string, TParamEntry > TParameterDefinitions
Ch * value() const
Definition: rapidxml.hpp:692
virtual void dynamics_load_params_from_xml(const rapidxml::xml_node< char > *xml_node) override
void parse_xmlnode_attribs(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions &params, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
Definition: xml_utils.cpp:140
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:936
virtual void invoke_motor_controllers(const TSimulContext &context, std::vector< double > &out_force_per_wheel) override
const GLint * attribs
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
std::shared_ptr< ControllerBase > ControllerBasePtr
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1025
std::vector< Wheel > m_wheels_info
Definition: VehicleBase.h:197
ControllerBasePtr m_controller
The installed controller.
virtual mrpt::math::TTwist2D getVelocityLocalOdoEstimate() const override
std::vector< b2Fixture * > m_fixture_wheels
Definition: VehicleBase.h:204
double m_chassis_z_min
each change via updateMaxRadiusFromPoly()
Definition: VehicleBase.h:188
void parse_xmlnode_shape(const rapidxml::xml_node< char > &xml_node, mrpt::math::TPolygon2D &out_poly, const char *functionNameContext="")
Definition: xml_utils.cpp:222
std::string m_name
Definition: Simulable.h:118
mrpt::math::TPolygon2D m_chassis_poly
Definition: VehicleBase.h:185
#define ASSERTMSG_(f, __ERROR_MSG)
b2Fixture * m_fixture_chassis
Created at.
Definition: VehicleBase.h:203
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1


mvsim
Author(s):
autogenerated on Fri May 7 2021 03:05:51