15 #include <mrpt/opengl/COpenGLScene.h> 19 using namespace mvsim;
25 m_max_steer_ang(DEG2RAD(30))
29 m_chassis_mass = 500.0;
30 m_chassis_z_min = 0.20;
31 m_chassis_z_max = 1.40;
32 m_chassis_color = TColor(0xe8, 0x30, 0x00);
35 m_chassis_poly.clear();
36 m_chassis_poly.push_back(TPoint2D(-0.8, -1.0));
37 m_chassis_poly.push_back(TPoint2D(-0.8, 1.0));
38 m_chassis_poly.push_back(TPoint2D(1.5, 0.9));
39 m_chassis_poly.push_back(TPoint2D(1.8, 0.8));
40 m_chassis_poly.push_back(TPoint2D(1.8, -0.8));
41 m_chassis_poly.push_back(TPoint2D(1.5, -0.9));
42 updateMaxRadiusFromPoly();
44 m_fixture_chassis = NULL;
45 for (
int i = 0; i < 4; i++) m_fixture_wheels[i] = NULL;
82 std::map<std::string, TParamEntry> attribs;
83 attribs[
"mass"] =
TParamEntry(
"%lf", &this->m_chassis_mass);
84 attribs[
"zmin"] =
TParamEntry(
"%lf", &this->m_chassis_z_min);
85 attribs[
"zmax"] =
TParamEntry(
"%lf", &this->m_chassis_z_max);
86 attribs[
"color"] =
TParamEntry(
"%color", &this->m_chassis_color);
89 *xml_chassis, attribs,
90 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
97 *xml_shape, m_chassis_poly,
98 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
105 const char* w_names[4] = {
112 for (
size_t i = 0; i < 4; i++)
116 if (xml_wheel) m_wheels_info[i].loadFromXML(xml_wheel);
123 double front_x = 1.3;
124 double front_d = 2.0;
125 std::map<std::string, TParamEntry> ack_ps;
127 ack_ps[
"f_wheels_x"] =
TParamEntry(
"%lf", &front_x);
128 ack_ps[
"f_wheels_d"] =
TParamEntry(
"%lf", &front_d);
134 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
137 m_wheels_info[
WHEEL_FL].x = front_x;
138 m_wheels_info[
WHEEL_FL].y = 0.5 * front_d;
140 m_wheels_info[
WHEEL_FR].x = front_x;
141 m_wheels_info[
WHEEL_FR].y = -0.5 * front_d;
146 const char* drive_names[6] = {
"open_front",
"open_rear",
"open_4wd",
147 "torsen_front",
"torsen_rear",
"torsen_4wd"};
153 std::map<std::string, TParamEntry> attribs;
154 std::string diff_type;
159 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
161 for (
size_t i = 0; i < DifferentialType::DIFF_MAX; ++i)
163 if (diff_type == drive_names[i])
170 std::map<std::string, TParamEntry> drive_params;
171 drive_params[
"front_rear_split"] =
174 drive_params[
"front_left_right_split"] =
176 drive_params[
"front_left_right_bias"] =
178 drive_params[
"rear_left_right_split"] =
180 drive_params[
"rear_left_right_bias"] =
184 *xml_drive, drive_params,
185 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
197 if (!control_class || !control_class->
value())
199 "[DynamicsAckermannDrivetrain] Missing 'class' attribute " 200 "in <controller> XML node");
202 const std::string sCtrlClass = std::string(control_class->
value());
215 "[DynamicsAckermannDrivetrain] Unknown 'class'='%s' in " 216 "<controller> XML node",
217 sCtrlClass.c_str()));
229 const TSimulContext& context, std::vector<double>& out_torque_per_wheel)
232 out_torque_per_wheel.assign(4, 0.0);
233 double torque_split_per_wheel[4] = {0.0};
250 torque_split_per_wheel[
WHEEL_RL] = 0.0;
251 torque_split_per_wheel[
WHEEL_RR] = 0.0;
256 torque_split_per_wheel[
WHEEL_FL] = 0.0;
257 torque_split_per_wheel[
WHEEL_FR] = 0.0;
277 torque_split_per_wheel[
WHEEL_RL] = 0.0;
278 torque_split_per_wheel[
WHEEL_RR] = 0.0;
290 torque_split_per_wheel[
WHEEL_FL] = 0.0;
291 torque_split_per_wheel[
WHEEL_FR] = 0.0;
303 const double w_FL = m_wheels_info[
WHEEL_FL].getW();
304 const double w_FR = m_wheels_info[
WHEEL_FR].getW();
305 const double w_RL = m_wheels_info[
WHEEL_RL].getW();
306 const double w_RR = m_wheels_info[
WHEEL_RR].getW();
307 const double w_F = w_FL + w_FR;
308 const double w_R = w_RL + w_RR;
328 torque_split_per_wheel[
WHEEL_FL] = t_F * t_FL;
329 torque_split_per_wheel[
WHEEL_FR] = t_F * t_FR;
330 torque_split_per_wheel[
WHEEL_RL] = t_R * t_RL;
331 torque_split_per_wheel[
WHEEL_RR] = t_R * t_RR;
339 "DynamicsAckermannDrivetrain::invoke_motor_controllers: \ 340 Unknown differential type!");
345 ASSERT_(out_torque_per_wheel.size() == 4);
346 for (
int i = 0; i < 4; i++)
348 out_torque_per_wheel[i] =
362 const double desired_equiv_steer_ang,
double& out_fl_ang,
363 double& out_fr_ang)
const 370 const double w_l = w / l;
374 const bool delta_neg = (desired_equiv_steer_ang < 0);
375 ASSERT_BELOW_(delta, 0.5 * M_PI - 0.01);
376 const double cot_do = 1.0 / tan(delta) + 0.5 * w_l;
377 const double cot_di = cot_do - w_l;
380 (delta_neg ? out_fr_ang : out_fl_ang) =
381 atan(1.0 / cot_di) * (delta_neg ? -1.0 : 1.0);
382 (delta_neg ? out_fl_ang : out_fr_ang) =
383 atan(1.0 / cot_do) * (delta_neg ? -1.0 : 1.0);
387 const double w1,
const double w2,
const double diffBias,
388 const double splitRatio,
double& t1,
double& t2)
390 if (signWithZero(w1) == 0.0 ||
391 signWithZero(w2) == 0.0)
394 t2 = 1.0 - splitRatio;
398 const double w1Abs = std::abs(w1);
399 const double w2Abs = std::abs(w2);
400 const double omegaMax = std::max(w1Abs, w2Abs);
401 const double omegaMin = std::min(w1Abs, w2Abs);
403 const double delta = omegaMax - diffBias * omegaMin;
405 const double deltaTorque = (delta > 0) ? delta / omegaMax : 0.0
f;
406 const double f1 = (w1Abs - w2Abs > 0) ? splitRatio * (1.0
f - deltaTorque)
407 : splitRatio * (1.0f + deltaTorque);
408 const double f2 = (w1Abs - w2Abs > 0)
409 ? (1.0
f - splitRatio) * (1.0f + deltaTorque)
410 : (1.0
f - splitRatio) * (1.0f - deltaTorque);
411 const double denom = 1.0f / (f1 + f2);
426 const double w0 = m_wheels_info[
WHEEL_RL].getW();
427 const double w1 = m_wheels_info[
WHEEL_RR].getW();
428 const double R0 = m_wheels_info[
WHEEL_RL].diameter * 0.5;
429 const double R1 = m_wheels_info[
WHEEL_RR].diameter * 0.5;
434 "The two wheels of a differential vehicle CAN'T by at the same Y " 437 const double w_veh = (w1 * R1 - w0 * R0) / Ay;
438 const double vx_veh = w0 * R0 + w_veh * m_wheels_info[
WHEEL_RL].y;
440 odo_vel.
vals[0] = vx_veh;
441 odo_vel.
vals[2] = w_veh;
444 odo_vel.
vals[1] = 0.0;
449 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]));
450 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]));
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="")
DifferentialType m_diff_type
min turning radius
static const char * class_name()
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
DynamicsAckermannDrivetrain(World *parent)
void parse_xmlnode_attribs(const rapidxml::xml_node< char > &xml_node, const std::map< std::string, TParamEntry > ¶ms, const char *function_name_context="")
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="")
void computeDiffTorqueSplit(const double w1, const double w2, const double diffBias, const double defaultSplitRatio, double &t1, double &t2)
static const char * class_name()
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
static const char * class_name()
virtual void invoke_motor_controllers(const TSimulContext &context, std::vector< double > &out_force_per_wheel)
std::shared_ptr< ControllerBase > ControllerBasePtr
double steer_ang
Equivalent ackerman steering angle.
TFSIMD_FORCE_INLINE const tfScalar & w() const
T b2Clamp(T a, T low, T high)
ControllerBasePtr m_controller
The installed controller.
virtual void dynamics_load_params_from_xml(const rapidxml::xml_node< char > *xml_node)
vec3 getVelocityLocal() const
virtual vec3 getVelocityLocalOdoEstimate() const
void computeFrontWheelAngles(const double desired_equiv_steer_ang, double &out_fl_ang, double &out_fr_ang) const