10 #include <mrpt/opengl/COpenGLScene.h> 19 using namespace mvsim;
88 *xml_chassis, attribs, {},
89 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
97 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
104 const char* w_names[4] = {
111 for (
size_t i = 0; i < 4; i++)
113 if (
auto xml_wheel = xml_node->
first_node(w_names[i]); xml_wheel)
120 mrpt::system::LVL_WARN,
121 "No XML entry '%s' found: using defaults for wheel #%u",
122 w_names[i], static_cast<unsigned int>(i));
130 double front_x = 1.3;
131 double front_d = 2.0;
134 ack_ps[
"f_wheels_x"] =
TParamEntry(
"%lf", &front_x);
135 ack_ps[
"f_wheels_d"] =
TParamEntry(
"%lf", &front_d);
140 *xml_node, ack_ps, {},
141 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
153 const char* drive_names[6] = {
"open_front",
"open_rear",
"open_4wd",
154 "torsen_front",
"torsen_rear",
"torsen_4wd"};
161 std::string diff_type;
165 *xml_drive, attribs, {},
166 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
168 for (
size_t i = 0; i < DifferentialType::DIFF_MAX; ++i)
170 if (diff_type == drive_names[i])
180 drive_params[
"front_left_right_split"] =
182 drive_params[
"front_left_right_bias"] =
184 drive_params[
"rear_left_right_split"] =
189 *xml_drive, drive_params, {},
190 "[DynamicsAckermannDrivetrain::dynamics_load_params_from_xml]");
202 if (!control_class || !control_class->
value())
204 "[DynamicsAckermannDrivetrain] Missing 'class' attribute " 205 "in <controller> XML node");
207 const std::string sCtrlClass = std::string(control_class->
value());
209 controller_ = std::make_shared<ControllerRawForces>(*
this);
212 std::make_shared<ControllerTwistFrontSteerPID>(*
this);
214 controller_ = std::make_shared<ControllerFrontSteerPID>(*
this);
217 "[DynamicsAckermannDrivetrain] Unknown 'class'='%s' in " 218 "<controller> XML node",
227 controller_ = std::make_shared<ControllerRawForces>(*this);
235 std::vector<double> out_torque_per_wheel;
236 out_torque_per_wheel.assign(4, 0.0);
237 double torque_split_per_wheel[4] = {0.0};
254 torque_split_per_wheel[
WHEEL_RL] = 0.0;
255 torque_split_per_wheel[
WHEEL_RR] = 0.0;
260 torque_split_per_wheel[
WHEEL_FL] = 0.0;
261 torque_split_per_wheel[
WHEEL_FR] = 0.0;
280 torque_split_per_wheel[
WHEEL_RL] = 0.0;
281 torque_split_per_wheel[
WHEEL_RR] = 0.0;
293 torque_split_per_wheel[
WHEEL_FL] = 0.0;
294 torque_split_per_wheel[
WHEEL_FR] = 0.0;
310 const double w_F = w_FL + w_FR;
311 const double w_R = w_RL + w_RR;
331 torque_split_per_wheel[
WHEEL_FL] = t_F * t_FL;
332 torque_split_per_wheel[
WHEEL_FR] = t_F * t_FR;
333 torque_split_per_wheel[
WHEEL_RL] = t_R * t_RL;
334 torque_split_per_wheel[
WHEEL_RR] = t_R * t_RR;
342 "DynamicsAckermannDrivetrain::invoke_motor_controllers: \ 343 Unknown differential type!");
348 ASSERT_(out_torque_per_wheel.size() == 4);
349 for (
int i = 0; i < 4; i++)
351 out_torque_per_wheel[i] =
362 return out_torque_per_wheel;
366 const double desired_equiv_steer_ang,
double& out_fl_ang,
367 double& out_fr_ang)
const 374 const double w_l = w / l;
378 const bool delta_neg = (desired_equiv_steer_ang < 0);
379 ASSERT_LT_(delta, 0.5 *
M_PI - 0.01);
380 const double cot_do = 1.0 /
tan(delta) + 0.5 * w_l;
381 const double cot_di = cot_do - w_l;
384 (delta_neg ? out_fr_ang : out_fl_ang) =
385 atan(1.0 / cot_di) * (delta_neg ? -1.0 : 1.0);
386 (delta_neg ? out_fl_ang : out_fr_ang) =
387 atan(1.0 / cot_do) * (delta_neg ? -1.0 : 1.0);
391 const double w1,
const double w2,
const double diffBias,
392 const double splitRatio,
double& t1,
double& t2)
394 if (mrpt::signWithZero(w1) == 0.0 || mrpt::signWithZero(w2) == 0.0)
397 t2 = 1.0 - splitRatio;
401 const double w1Abs = std::abs(w1);
402 const double w2Abs = std::abs(w2);
403 const double omegaMax = std::max(w1Abs, w2Abs);
404 const double omegaMin =
std::min(w1Abs, w2Abs);
406 const double delta = omegaMax - diffBias * omegaMin;
408 const double deltaTorque = (delta > 0) ? delta / omegaMax : 0.0
f;
409 const double f1 = (w1Abs - w2Abs > 0) ? splitRatio * (1.0
f - deltaTorque)
410 : splitRatio * (1.0f + deltaTorque);
411 const double f2 = (w1Abs - w2Abs > 0)
412 ? (1.0
f - splitRatio) * (1.0f + deltaTorque)
413 : (1.0
f - splitRatio) * (1.0f - deltaTorque);
414 const double denom = 1.0f / (f1 + f2);
424 mrpt::math::TTwist2D odo_vel;
438 "The two wheels of a differential vehicle cannot be at the same Y " 441 const double w_veh = (w1 * R1 - w0 * R0) / Ay;
446 odo_vel.omega = w_veh;
This file contains rapidxml parser and DOM implementation.
void updateMaxRadiusFromPoly()
DifferentialType diff_type_
min turning radius
std::map< std::string, TParamEntry > TParameterDefinitions
ControllerBase::Ptr controller_
The installed controller.
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions ¶ms, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="", mrpt::system::COutputLogger *logger=nullptr)
virtual mrpt::math::TTwist2D getVelocityLocalOdoEstimate() const override
static const char * class_name()
void parse_xmlnode_attribs(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions ¶ms, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
virtual void dynamics_load_params_from_xml(const rapidxml::xml_node< char > *xml_node) override
std::deque< Wheel > wheels_info_
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
DynamicsAckermannDrivetrain(World *parent)
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
void computeDiffTorqueSplit(const double w1, const double w2, const double diffBias, const double defaultSplitRatio, double &t1, double &t2)
static const char * class_name()
mrpt::math::TPolygon2D chassis_poly_
b2Fixture * fixture_chassis_
Created at.
static const char * class_name()
T b2Clamp(T a, T low, T high)
double steer_ang
Equivalent Ackermann steering angle.
mrpt::img::TColor chassis_color_
static int min(int n1, int n2)
void parse_xmlnode_shape(const rapidxml::xml_node< char > &xml_node, mrpt::math::TPolygon2D &out_poly, const char *functionNameContext="")
virtual std::vector< double > invoke_motor_controllers(const TSimulContext &context) override
INLINE Rall1d< T, V, S > tan(const Rall1d< T, V, S > &arg)
void computeFrontWheelAngles(const double desired_equiv_steer_ang, double &out_fl_ang, double &out_fr_ang) const
xml_attribute< Ch > * first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
std::vector< b2Fixture * > fixture_wheels_