VehicleDifferential_ControllerTwistPID.cpp
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2023 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 
11 
12 #include "xml_utils.h"
13 
14 using namespace mvsim;
15 using namespace std;
16 
19  : ControllerBase(veh)
20 {
21  // Get distance between wheels:
22  // Warning: the controller *assumes* that both wheels are parallel (as it's
23  // a rule in differential robots!!)
24  distWheels_ = veh_.wheels_info_[0].y - veh_.wheels_info_[1].y;
25  ASSERT_(distWheels_ > 0);
26 }
27 
28 // See base class docs
32 {
33  const auto sp = setpoint();
34 
35  // For each wheel:
36  // 1) Compute desired velocity set-point (in m/s)
37  // 2) Run the PI/PID for that wheel independently (in newtons)
38  const double spVelL = sp.vx - 0.5 * sp.omega * distWheels_;
39  const double spVelR = sp.vx + 0.5 * sp.omega * distWheels_;
40 
41  // Compute each wheel actual velocity (from an "odometry" estimation of
42  // velocity, not ground-truth!):
43  const mrpt::math::TTwist2D vehVelOdo = veh_.getVelocityLocalOdoEstimate();
44  const double actVelL = vehVelOdo.vx - 0.5 * vehVelOdo.omega * distWheels_;
45  const double actVelR = vehVelOdo.vx + 0.5 * vehVelOdo.omega * distWheels_;
46 
47  // Apply controller:
48  for (auto& pid : PIDs_)
49  {
50  pid.KP = KP;
51  pid.KI = KI;
52  pid.KD = KD;
53  pid.max_out = max_torque;
54  }
55 
56  // "-" because \tau<0 makes robot moves forwards.
57  const double followErrorL = spVelL - actVelL;
58  const double followErrorR = spVelR - actVelR;
59 
60  const double zeroThres = 0.001; // m/s
61 
62  if (std::abs(spVelL) < zeroThres && //
63  std::abs(spVelR) < zeroThres && //
64  std::abs(spVelR) < zeroThres && //
65  std::abs(spVelR) < zeroThres)
66  {
67  co.wheel_torque_l = 0;
68  co.wheel_torque_r = 0;
69  for (auto& pid : PIDs_) pid.reset();
70  }
71  else
72  {
73  co.wheel_torque_l = -PIDs_[0].compute(followErrorL, ci.context.dt);
74  co.wheel_torque_r = -PIDs_[1].compute(followErrorR, ci.context.dt);
75  }
76 }
77 
79  const rapidxml::xml_node<char>& node)
80 {
81  TParameterDefinitions params;
82  params["KP"] = TParamEntry("%lf", &KP);
83  params["KI"] = TParamEntry("%lf", &KI);
84  params["KD"] = TParamEntry("%lf", &KD);
85  params["max_torque"] = TParamEntry("%lf", &max_torque);
86 
87  // Initial speed.
88  params["V"] = TParamEntry("%lf", &setpoint_.vx);
89  params["W"] = TParamEntry("%lf_deg", &setpoint_.omega);
90 
91  parse_xmlnode_children_as_param(node, params);
92 }
93 
95  const TeleopInput& in, TeleopOutput& out)
96 {
98 
99  auto lck = mrpt::lockHelper(setpointMtx_);
100 
101  switch (in.keycode)
102  {
103  case 'W':
104  case 'w':
105  setpoint_.vx += 0.1;
106  break;
107 
108  case 'S':
109  case 's':
110  setpoint_.vx -= 0.1;
111  break;
112 
113  case 'A':
114  case 'a':
115  setpoint_.omega += 2.0 * M_PI / 180;
116  break;
117 
118  case 'D':
119  case 'd':
120  setpoint_.omega -= 2.0 * M_PI / 180;
121  break;
122 
123  case ' ':
124  {
125  setpoint_ = {0, 0, 0};
126  for (auto& pid : PIDs_) pid.reset();
127  }
128  break;
129  };
130  out.append_gui_lines += "[Controller=" + string(class_name()) +
131  "] Teleop keys:\n"
132  "w/s=forward/backward.\n"
133  "a/d=left/right.\n"
134  "spacebar=stop.\n";
135  out.append_gui_lines += mrpt::format(
136  "setpoint: lin=%.03f ang=%.03f deg/s\n", setpoint_.vx,
137  180.0 / M_PI * setpoint_.omega);
138 }
virtual void teleop_interface(const TeleopInput &in, TeleopOutput &out) override
std::map< std::string, TParamEntry > TParameterDefinitions
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions &params, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="", mrpt::system::COutputLogger *logger=nullptr)
Definition: xml_utils.cpp:224
mrpt::math::TTwist2D setpoint_
"vx" and "omega" only
#define M_PI
double dt
timestep
Definition: basic_types.h:60
virtual void teleop_interface(const TeleopInput &in, TeleopOutput &out) override
virtual void load_config(const rapidxml::xml_node< char > &node) override
double max_torque
Maximum abs. value torque (for clamp) [Nm].
virtual void control_step(const DynamicsDifferential::TControllerInput &ci, DynamicsDifferential::TControllerOutput &co) override


mvsim
Author(s):
autogenerated on Tue Jul 4 2023 03:08:21