10 #include <mrpt/opengl/COpenGLScene.h>
19 using namespace mvsim;
87 *xml_chassis, attribs, {},
88 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
95 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
102 const char* w_names[4] = {
109 for (
size_t i = 0; i < 4; i++)
111 if (
auto xml_wheel = xml_node->
first_node(w_names[i]); xml_wheel)
118 mrpt::system::LVL_WARN,
"No XML entry '%s' found: using defaults for wheel #%u",
119 w_names[i],
static_cast<unsigned int>(i));
127 double front_x = 1.3;
128 double front_d = 2.0;
131 ack_ps[
"f_wheels_x"] =
TParamEntry(
"%lf", &front_x);
132 ack_ps[
"f_wheels_d"] =
TParamEntry(
"%lf", &front_d);
137 *xml_node, ack_ps, {},
"[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
149 const char* drive_names[6] = {
"open_front",
"open_rear",
"open_4wd",
150 "torsen_front",
"torsen_rear",
"torsen_4wd"};
156 std::string diff_type;
160 *xml_drive, attribs, {},
161 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
163 for (
size_t i = 0; i < DifferentialType::DIFF_MAX; ++i)
165 if (diff_type == drive_names[i])
181 *xml_drive, drive_params, {},
182 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
192 if (!control_class || !control_class->value())
194 "[DynamicsAckermannDrivetrain] Missing 'class' attribute "
195 "in <controller> XML node");
197 const std::string sCtrlClass = std::string(control_class->value());
198 if (sCtrlClass == ControllerRawForces::class_name())
199 controller_ = std::make_shared<ControllerRawForces>(*
this);
200 else if (sCtrlClass == ControllerTwistFrontSteerPID::class_name())
201 controller_ = std::make_shared<ControllerTwistFrontSteerPID>(*
this);
202 else if (sCtrlClass == ControllerFrontSteerPID::class_name())
203 controller_ = std::make_shared<ControllerFrontSteerPID>(*
this);
206 "[DynamicsAckermannDrivetrain] Unknown 'class'='%s' in "
207 "<controller> XML node",
223 std::vector<double> out_torque_per_wheel;
224 out_torque_per_wheel.assign(4, 0.0);
225 double torque_split_per_wheel[4] = {0.0};
242 torque_split_per_wheel[
WHEEL_RL] = 0.0;
243 torque_split_per_wheel[
WHEEL_RR] = 0.0;
248 torque_split_per_wheel[
WHEEL_FL] = 0.0;
249 torque_split_per_wheel[
WHEEL_FR] = 0.0;
268 torque_split_per_wheel[
WHEEL_RL] = 0.0;
269 torque_split_per_wheel[
WHEEL_RR] = 0.0;
280 torque_split_per_wheel[
WHEEL_FL] = 0.0;
281 torque_split_per_wheel[
WHEEL_FR] = 0.0;
296 const double w_F = w_FL + w_FR;
297 const double w_R = w_RL + w_RR;
314 torque_split_per_wheel[
WHEEL_FL] = t_F * t_FL;
315 torque_split_per_wheel[
WHEEL_FR] = t_F * t_FR;
316 torque_split_per_wheel[
WHEEL_RL] = t_R * t_RL;
317 torque_split_per_wheel[
WHEEL_RR] = t_R * t_RR;
325 "DynamicsAckermannDrivetrain::invoke_motor_controllers: \
326 Unknown differential type!");
331 ASSERT_(out_torque_per_wheel.size() == 4);
332 for (
int i = 0; i < 4; i++)
334 out_torque_per_wheel[i] = co.
drive_torque * torque_split_per_wheel[i];
343 return out_torque_per_wheel;
347 const double desired_equiv_steer_ang,
double& out_fl_ang,
double& out_fr_ang)
const
354 const double w_l = w / l;
357 const bool delta_neg = (desired_equiv_steer_ang < 0);
358 ASSERT_LT_(delta, 0.5 * M_PI - 0.01);
359 const double cot_do = 1.0 / tan(delta) + 0.5 * w_l;
360 const double cot_di = cot_do - w_l;
363 (delta_neg ? out_fr_ang : out_fl_ang) = atan(1.0 / cot_di) * (delta_neg ? -1.0 : 1.0);
364 (delta_neg ? out_fl_ang : out_fr_ang) = atan(1.0 / cot_do) * (delta_neg ? -1.0 : 1.0);
368 const double w1,
const double w2,
const double diffBias,
const double splitRatio,
double& t1,
371 if (mrpt::signWithZero(w1) == 0.0 || mrpt::signWithZero(w2) == 0.0)
374 t2 = 1.0 - splitRatio;
378 const double w1Abs = std::abs(w1);
379 const double w2Abs = std::abs(w2);
380 const double omegaMax = std::max(w1Abs, w2Abs);
381 const double omegaMin = std::min(w1Abs, w2Abs);
383 const double delta = omegaMax - diffBias * omegaMin;
385 const double deltaTorque = (delta > 0) ? delta / omegaMax : 0.0
f;
387 (w1Abs - w2Abs > 0) ? splitRatio * (1.0
f - deltaTorque) : splitRatio * (1.0f + deltaTorque);
388 const double f2 = (w1Abs - w2Abs > 0) ? (1.0
f - splitRatio) * (1.0f + deltaTorque)
389 : (1.0
f - splitRatio) * (1.0f - deltaTorque);
390 const double denom = 1.0f / (f1 + f2);
399 mrpt::math::TTwist2D odo_vel;
413 "The two wheels of a differential vehicle cannot be at the same Y "
416 const double w_veh = (w1 * R1 - w0 * R0) / Ay;
421 odo_vel.omega = w_veh;