VehicleDifferential.cpp
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014 Jose Luis Blanco Claraco (University of Almeria) |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under GNU General Public License version 3 |
7  | See <http://www.gnu.org/licenses/> |
8  +-------------------------------------------------------------------------+ */
9 
11 #include <mvsim/World.h>
12 
13 #include "xml_utils.h"
14 
15 #include <mrpt/opengl/COpenGLScene.h>
16 #include <rapidxml.hpp>
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 = TColor(0xff, 0x00, 0x00);
31 
32  // Default shape:
33  m_chassis_poly.clear();
34  m_chassis_poly.push_back(TPoint2D(-0.4, -0.5));
35  m_chassis_poly.push_back(TPoint2D(-0.4, 0.5));
36  m_chassis_poly.push_back(TPoint2D(0.4, 0.5));
37  m_chassis_poly.push_back(TPoint2D(0.6, 0.3));
38  m_chassis_poly.push_back(TPoint2D(0.6, -0.3));
39  m_chassis_poly.push_back(TPoint2D(0.4, -0.5));
40  updateMaxRadiusFromPoly();
41 
42  m_fixture_chassis = NULL;
43  for (int i = 0; i < 2; i++) m_fixture_wheels[i] = NULL;
44 }
45 
48  const rapidxml::xml_node<char>* xml_node)
49 {
50  // <chassis ...> </chassis>
51  const rapidxml::xml_node<char>* xml_chassis =
52  xml_node->first_node("chassis");
53  if (xml_chassis)
54  {
55  // Attribs:
56  std::map<std::string, TParamEntry> attribs;
57  attribs["mass"] = TParamEntry("%lf", &this->m_chassis_mass);
58  attribs["zmin"] = TParamEntry("%lf", &this->m_chassis_z_min);
59  attribs["zmax"] = TParamEntry("%lf", &this->m_chassis_z_max);
60  attribs["color"] = TParamEntry("%color", &this->m_chassis_color);
61 
63  *xml_chassis, attribs,
64  "[DynamicsDifferential::dynamics_load_params_from_xml]");
65 
66  // Shape node (optional, fallback to default shape if none found)
67  const rapidxml::xml_node<char>* xml_shape =
68  xml_chassis->first_node("shape");
69  if (xml_shape)
71  *xml_shape, m_chassis_poly,
72  "[DynamicsDifferential::dynamics_load_params_from_xml]");
73  }
74 
75  // <l_wheel ...>, <r_wheel ...>
76  const char* w_names[2] = {"l_wheel", "r_wheel"};
77  const double w_default_y[2] = {0.5, -0.5};
78  // Load common params:
79  for (size_t i = 0; i < 2; i++)
80  {
81  const rapidxml::xml_node<char>* xml_wheel =
82  xml_node->first_node(w_names[i]);
83  if (xml_wheel)
84  m_wheels_info[i].loadFromXML(xml_wheel);
85  else
86  {
87  m_wheels_info[i] = Wheel();
88  m_wheels_info[i].y = w_default_y[i];
89  }
90  }
91 
92  // Vehicle controller:
93  // -------------------------------------------------
94  {
95  const rapidxml::xml_node<char>* xml_control =
96  xml_node->first_node("controller");
97  if (xml_control)
98  {
99  rapidxml::xml_attribute<char>* control_class =
100  xml_control->first_attribute("class");
101  if (!control_class || !control_class->value())
102  throw runtime_error(
103  "[DynamicsDifferential] Missing 'class' attribute in "
104  "<controller> XML node");
105 
106  const std::string sCtrlClass = std::string(control_class->value());
107  if (sCtrlClass == ControllerRawForces::class_name())
108  m_controller =
110  else if (sCtrlClass == ControllerTwistPID::class_name())
112  else
113  throw runtime_error(
114  mrpt::format(
115  "[DynamicsDifferential] Unknown 'class'='%s' in "
116  "<controller> XML node",
117  sCtrlClass.c_str()));
118 
119  m_controller->load_config(*xml_control);
120  }
121  }
122 
123  // Default controller:
124  if (!m_controller)
126 }
127 
128 // See docs in base class:
130  const TSimulContext& context, std::vector<double>& out_torque_per_wheel)
131 {
132  // Longitudinal forces at each wheel:
133  out_torque_per_wheel.assign(2, 0.0);
134 
135  if (m_controller)
136  {
137  // Invoke controller:
138  TControllerInput ci;
139  ci.context = context;
141  m_controller->control_step(ci, co);
142  // Take its output:
143  out_torque_per_wheel[WHEEL_L] = co.wheel_torque_l;
144  out_torque_per_wheel[WHEEL_R] = co.wheel_torque_r;
145  }
146 }
147 
148 // See docs in base class:
150 {
151  vec3 odo_vel;
152  // Equations:
153 
154  // Velocities in local +X at each wheel i={0,1}:
155  // v_i = vx - w_veh * wheel_{i,y} = w_i * R_i
156  // Re-arranging:
157  const double w0 = m_wheels_info[WHEEL_L].getW();
158  const double w1 = m_wheels_info[WHEEL_R].getW();
159  const double R0 = m_wheels_info[WHEEL_L].diameter * 0.5;
160  const double R1 = m_wheels_info[WHEEL_R].diameter * 0.5;
161 
162  const double Ay = m_wheels_info[WHEEL_L].y - m_wheels_info[WHEEL_R].y;
163  ASSERTMSG_(
164  Ay != 0.0,
165  "The two wheels of a differential vehicle CAN'T by at the same Y "
166  "coordinate!");
167 
168  const double w_veh = (w1 * R1 - w0 * R0) / Ay;
169  const double vx_veh = w0 * R0 + w_veh * m_wheels_info[WHEEL_L].y;
170 
171  odo_vel.vals[0] = vx_veh;
172  odo_vel.vals[2] = w_veh;
173 
174  // v_y = 0
175  odo_vel.vals[1] = 0.0;
176 
177 #if 0 // Debug
178  {
179  vec3 gt_vel = this->getVelocityLocal();
180  printf("\n gt: vx=%7.03f, vy=%7.03f, w= %7.03fdeg\n", gt_vel.vals[0], gt_vel.vals[1], mrpt::utils::RAD2DEG(gt_vel.vals[2]));
181  printf("odo: vx=%7.03f, vy=%7.03f, w= %7.03fdeg\n", odo_vel.vals[0], odo_vel.vals[1], mrpt::utils::RAD2DEG(odo_vel.vals[2]));
182  }
183 #endif
184  return odo_vel;
185 }
This file contains rapidxml parser and DOM implementation.
void parse_xmlnode_shape(const rapidxml::xml_node< char > &xml_node, mrpt::math::TPolygon2D &out_poly, const char *function_name_context="")
Definition: xml_utils.cpp:239
Ch * value() const
Definition: rapidxml.hpp:692
double vals[3]
Definition: basic_types.h:64
virtual void invoke_motor_controllers(const TSimulContext &context, std::vector< double > &out_force_per_wheel)
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:936
void parse_xmlnode_attribs(const rapidxml::xml_node< char > &xml_node, const std::map< std::string, TParamEntry > &params, const char *function_name_context="")
Definition: xml_utils.cpp:160
virtual vec3 getVelocityLocalOdoEstimate() const
std::shared_ptr< ControllerBase > ControllerBasePtr
virtual void dynamics_load_params_from_xml(const rapidxml::xml_node< char > *xml_node)
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1025
ControllerBasePtr m_controller
The installed controller.
vec3 getVelocityLocal() const


mvsim
Author(s):
autogenerated on Thu Jun 6 2019 19:36:40