diff_drive_pose_controller.cpp
Go to the documentation of this file.
2 
3 #include <cmath>
4 #include <ros/console.h>
6 
7 namespace yocs
8 {
9 
10 DiffDrivePoseController::DiffDrivePoseController(std::string name, double v_max, double w_max, double dist_thres,
11  double orient_thres, double dist_eps, double orient_eps,
12  double orientation_gain, double k_1, double k_2, double beta,
13  double lambda, double v_min, double v_min_movement,
14  double w_min_movement)
15 {
16  name_ = name;
17 
18  r_ = 0.0;
19  v_ = 0.0;
20  w_ = 0.0;
21  delta_ = 0.0;
22  theta_ = 0.0;
23  cur_ = 0.0;
24  pose_reached_ = false;
25 
26  v_min_movement_ = v_min_movement;
27  w_min_movement_ = w_min_movement;
28  setCurrentLimits(v_min, -w_max, v_max, w_max); //set the limits so they include everything for now
29 
30  dist_thres_ = dist_thres;
31  orient_thres_ = orient_thres;
32  dist_eps_ = dist_eps;
33  orient_eps_ = orient_eps;
34 
35  orientation_gain_ = orientation_gain;
36  k_1_ = k_1;
37  k_2_ = k_2;
38  beta_ = beta;
39  lambda_ = lambda;
40 }
41 
42 void DiffDrivePoseController::setInput(double distance_to_goal, double delta, double theta)
43 {
44  r_ = distance_to_goal;
45  delta_ = mtk::wrapAngle(delta);
46  theta_ = mtk::wrapAngle(theta);
47 }
48 
49 void DiffDrivePoseController::setCurrentLimits(double v_min, double w_min, double v_max, double w_max)
50 {
51  v_min_ = v_min;
52  w_min_ = w_min;
53  v_max_ = v_max;
54  w_max_ = w_max;
55 }
56 
58 {
60  return pose_reached_;
61 }
62 
64 {
65  double angle_diff = mtk::wrapAngle(theta_ - delta_);
66 
67  if (r_ > dist_thres_)
68  {
69  controlPose();
70  }
71  else
72  {
73  //reached goal position, so just adjust orientation
74  v_ = 0.0;
75  controlOrientation(angle_diff);
76  }
77 
78  // check, if pose has been reached
79  if ((r_ <= dist_thres_) && (std::abs(angle_diff) <= orient_thres_))
80  {
81  if (!pose_reached_)
82  {
83  pose_reached_ = true;
84  if ( verbose_ ) {
85  ROS_INFO_STREAM("Pose reached. [" << name_ <<"]");
86  }
87  onGoalReached();
88  }
89  }
90  else if ((r_ > (dist_thres_ + dist_eps_)) || (std::abs(angle_diff) > (orient_thres_ + orient_eps_)))
91  {
92  if (pose_reached_)
93  {
94  pose_reached_ = false;
95  if ( verbose_ ) {
96  ROS_INFO_STREAM("Tracking new goal pose. [" << name_ <<"]");
97  }
98  }
99  }
100 }
101 
103 {
104  double atan2_k1_theta = std::atan2(-k_1_*theta_, 1.0);
105  cur_ = (-1 / r_)
106  * (k_2_ * (delta_ - atan2_k1_theta) + (1 + (k_1_ / (1 + std::pow((k_1_ * theta_), 2)))) * sin(delta_));
107 
108  v_ = v_max_ / (1 + beta_ * std::pow(std::abs(cur_), lambda_));
111 
112  //calculate needed angular velocity for given curvature
113  w_ = cur_ * v_;
114  //enforce limits on angular velocity
117 
118  //adjust linear velocity to bounded angular velocity
119  v_ = w_ / cur_;
120  //enforce limits on linear velocity
122  v_ = enforceMinMax(v_, v_min_, v_max_);
123 
124 // ROS_WARN_STREAM("r_: " << r_ << " dist_thres_: " << dist_thres_ << ", delta_-theta_: " << delta_ - theta_ << ", orient_thres_" << orient_thres_);
125 }
126 
127 void DiffDrivePoseController::controlOrientation(double angle_difference)
128 {
129 
130  w_ = orientation_gain_ * (angle_difference);
131 
132  //enforce limits on angular velocity
134  w_ = enforceMinMax(w_, w_min_, w_max_);
135 }
136 
137 double DiffDrivePoseController::enforceMinMax(double& value, double min, double max)
138 {
139  return std::min(std::max(value, min), max);
140 }
141 
142 double DiffDrivePoseController::enforceMinVelocity(double value, double min)
143 {
144  if (value < 0.0)
145  {
146  if (value > -min)
147  {
148  value = -min;
149  }
150  }
151  else
152  {
153  if (value < min)
154  {
155  value = min;
156  }
157  }
158 
159  return value;
160 }
161 
163 {
164  v = v_;
165  w = w_;
166 }
167 
168 } /* end namespace */
double v_min_movement_
minimum linear base velocity at which we still move [m/s]
virtual void getControlOutput(double &v, double &w)
Get controller result / output after spinning.
double wrapAngle(double a)
double delta_
current heading of the base [rad]
double r_
distance to pose goal [m]
double dist_eps_
Error in distance above which pose is considered different.
bool verbose_
Enable or disable ros messages.
double k_2_
constant factor applied to the heading error feedback
virtual double enforceMinMax(double &value, double min, double max)
Enforce value to be between min and max.
virtual void controlOrientation(double angle_difference)
double orient_eps_
Error in orientation above which pose is considered different.
double w_
angular base velocity [rad/s]
double w_min_
(current) minimum angular base velocity [rad/s]
double cur_
path to goal curvature
double orientation_gain_
p gain for angle controller
bool pose_reached_
True, if pose has been reached (v == 0, w == 0)
virtual void onGoalReached()
Gets executed when goal is reached, use in child class.
double theta_
direction of the pose goal [rad]
double v_max_
maximum linear base velocity [m/s]
virtual void setInput(double distance_to_goal, double delta, double theta)
Set input of controller. Should be called before each spinOnce.
double w_min_movement_
minimum angular base velocity at which we still move [rad/s]
double v_min_
(current) minimum linear base velocity [m/s]
virtual void calculateControls()
Calculates the controls with the set variables (speed, goal etc.)
void setCurrentLimits(double v_min, double w_min, double v_max, double w_max)
DiffDrivePoseController(std::string name, double v_max, double w_max, double dist_thres=0.01, double orient_thres=0.02, double dist_eps=0.01 *0.2, double orient_eps=0.02 *0.2, double orientation_gain=0.3, double k_1=1.0, double k_2=3.0, double beta=0.4, double lambda=2.0, double v_min=0.01, double v_min_movement=0.01, double w_min_movement=0.01)
#define ROS_INFO_STREAM(args)
double orient_thres_
lower bound for the orientation (w = 0)
double v_
linear base velocity [m/s]
double w_max_
maximum angular base velocity [rad/s]
double dist_thres_
lower bound for the distance (v = 0)
double k_1_
constant factor determining the ratio of the rate of change in theta to the rate of change in r ...
virtual double enforceMinVelocity(double value, double min)
Enforce the minimum velocity.
virtual bool step()
Execute one controller step.


yocs_diff_drive_pose_controller
Author(s): Marcus Liebhardt
autogenerated on Mon Jun 10 2019 15:53:50