limiter.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <vector>
19 #include <ros/ros.h>
20 
22 
23 /* BEGIN LimiterContainer ***************************************************************************************/
28 {
29  // If nothing to do just return v_in.
30  KDL::Twist v_out(v_in);
31  for (input_LimIter_t it = this->input_limiters_.begin(); it != this->input_limiters_.end(); it++)
32  {
33  v_out = (*it)->enforceLimits(v_out);
34  }
35 
36  return v_out;
37 }
39 {
40  // If nothing to do just return q_dot.
41  KDL::JntArray q_dot_norm(q_dot_ik);
42  for (output_LimIter_t it = this->output_limiters_.begin(); it != this->output_limiters_.end(); it++)
43  {
44  q_dot_norm = (*it)->enforceLimits(q_dot_norm, q);
45  }
46 
47  return q_dot_norm;
48 }
49 
54 {
55  this->eraseAll();
56 
58  {
60  {
62  }
63 
65  {
67  }
68 
70  {
72  }
73 
75  {
77  }
78  }
79  else
80  {
82  {
84  }
85 
87  {
89  }
90 
92  {
94  }
95 
97  {
99  }
100  }
101 }
102 
107 {
108  for (uint32_t cnt = 0; cnt < this->input_limiters_.size(); ++cnt)
109  {
110  delete(this->input_limiters_[cnt]);
111  }
112  for (uint32_t cnt = 0; cnt < this->output_limiters_.size(); ++cnt)
113  {
114  delete(this->output_limiters_[cnt]);
115  }
116 
117  this->input_limiters_.clear();
118  this->output_limiters_.clear();
119 }
120 
125 {
126  this->input_limiters_.push_back(lb);
127 }
129 {
130  this->output_limiters_.push_back(lb);
131 }
132 
137 {
138  this->eraseAll();
139 }
140 /* END LimiterContainer *****************************************************************************************/
141 
142 /* BEGIN LimiterAllJointPositions *******************************************************************************/
151 {
152  KDL::JntArray q_dot_norm(q_dot_ik);
153  double tolerance = limiter_params_.limits_tolerance / 180.0 * M_PI;
154  double max_factor = 1.0;
155  int joint_index = -1;
156 
157  for (unsigned int i = 0; i < q_dot_ik.rows(); i++)
158  {
159  if ((limiter_params_.limits_max[i] - LIMIT_SAFETY_THRESHOLD <= q(i) && q_dot_ik(i) > 0) ||
160  (limiter_params_.limits_min[i] + LIMIT_SAFETY_THRESHOLD >= q(i) && q_dot_ik(i) < 0))
161  {
162  ROS_ERROR_STREAM("Joint " << i << " violates its limits. Setting to Zero!");
163  KDL::SetToZero(q_dot_norm);
164  return q_dot_norm;
165  }
166 
167  if (fabs(limiter_params_.limits_max[i] - q(i)) <= tolerance) // Joint is close to the MAXIMUM limit
168  {
169  if (q_dot_ik(i) > 0) // Joint moves towards the MAX limit
170  {
171  double temp = 1.0 / pow((0.5 + 0.5 * cos(M_PI * (q(i) + tolerance - limiter_params_.limits_max[i]) / tolerance)), 5.0);
172  // double temp = tolerance / fabs(limiter_params_.limits_max[i] - q(i));
173  if (temp > max_factor)
174  {
175  max_factor = temp;
176  joint_index = i;
177  }
178  }
179  }
180 
181  if (fabs(q(i) - limiter_params_.limits_min[i]) <= tolerance) // Joint is close to the MINIMUM limit
182  {
183  if (q_dot_ik(i) < 0) // Joint moves towards the MIN limit
184  {
185  double temp = 1.0 / pow(0.5 + 0.5 * cos(M_PI * (q(i) - tolerance - limiter_params_.limits_min[i]) / tolerance), 5.0);
186  // double temp = tolerance / fabs(q(i) - limiter_params_.limits_min[i]);
187  if (temp > max_factor)
188  {
189  max_factor = temp;
190  joint_index = i;
191  }
192  }
193  }
194  }
195 
196  if (max_factor > 1.0)
197  {
198  ROS_ERROR_STREAM_THROTTLE(1, "Position tolerance surpassed (by Joint " << joint_index << "): Scaling ALL VELOCITIES with factor = " << max_factor);
199  for (unsigned int i = 0; i < q_dot_ik.rows(); i++)
200  {
201  q_dot_norm(i) = q_dot_ik(i) / max_factor;
202  }
203  }
204 
205  return q_dot_norm;
206 }
207 /* END LimiterAllJointPositions *********************************************************************************/
208 
209 /* BEGIN LimiterAllJointVelocities ******************************************************************************/
215 {
216  KDL::JntArray q_dot_norm(q_dot_ik);
217  double max_factor = 1.0;
218  int joint_index = -1;
219 
220  for (unsigned int i = 0; i < q_dot_ik.rows(); i++)
221  {
222  if (max_factor < std::fabs(q_dot_ik(i) / limiter_params_.limits_vel[i]))
223  {
224  max_factor = std::fabs(q_dot_ik(i) / limiter_params_.limits_vel[i]);
225  joint_index = i;
226  }
227  }
228 
229  if (max_factor > 1.0)
230  {
231  ROS_WARN_STREAM_THROTTLE(1, "Velocity limit surpassed (by Joint " << joint_index << "): Scaling ALL VELOCITIES with factor = " << max_factor);
232  for (unsigned int i = 0; i < q_dot_ik.rows(); i++)
233  {
234  q_dot_norm(i) = q_dot_ik(i) / max_factor;
235  }
236  }
237 
238  return q_dot_norm;
239 }
240 /* END LimiterAllJointVelocities ********************************************************************************/
241 
242 /* BEGIN LimiterAllJointAccelerations ******************************************************************************/
248 {
249  KDL::JntArray q_dot_norm(q_dot_ik);
250 
251  ROS_WARN("LimiterAllJointAccelerations not yet implemented");
252 
253  return q_dot_norm;
254 }
255 /* END LimiterAllJointAccelerations *****************************************************************************/
256 
257 /* BEGIN LimiterAllCartesianVelocities ********************************************************************/
263 {
264  KDL::Twist v_out(v_in);
265 
266  double max_factor = 1.0;
267  max_factor = std::max( max_factor, std::fabs(v_in.rot.x()/limiter_params_.max_rot_twist) );
268  max_factor = std::max( max_factor, std::fabs(v_in.rot.y()/limiter_params_.max_rot_twist) );
269  max_factor = std::max( max_factor, std::fabs(v_in.rot.z()/limiter_params_.max_rot_twist) );
270  max_factor = std::max( max_factor, std::fabs(v_in.vel.x()/limiter_params_.max_lin_twist) );
271  max_factor = std::max( max_factor, std::fabs(v_in.vel.y()/limiter_params_.max_lin_twist) );
272  max_factor = std::max( max_factor, std::fabs(v_in.vel.z()/limiter_params_.max_lin_twist) );
273 
274  if (max_factor > 1.0)
275  {
276  ROS_WARN_STREAM_THROTTLE(1, "Cartesian velocity limit surpassed: Scaling ALL VELOCITIES with factor = " << max_factor);
277  v_out.rot.x(v_in.rot.x()/max_factor);
278  v_out.rot.y(v_in.rot.y()/max_factor);
279  v_out.rot.z(v_in.rot.z()/max_factor);
280  v_out.vel.x(v_in.vel.x()/max_factor);
281  v_out.vel.y(v_in.vel.y()/max_factor);
282  v_out.vel.z(v_in.vel.z()/max_factor);
283 
284  }
285 
286  return v_out;
287 }
288 /* END LimiterAllCartesianVelocities **********************************************************************/
289 
290 /* BEGIN LimiterIndividualJointPositions ************************************************************************/
296 {
297  KDL::JntArray q_dot_norm(q_dot_ik);
298  double tolerance = limiter_params_.limits_tolerance / 180.0 * M_PI;
299 
300  for (unsigned int i = 0; i < q_dot_ik.rows(); i++)
301  {
302  if ((limiter_params_.limits_max[i] - LIMIT_SAFETY_THRESHOLD <= q(i) && q_dot_ik(i) > 0) ||
303  (limiter_params_.limits_min[i] + LIMIT_SAFETY_THRESHOLD >= q(i) && q_dot_ik(i) < 0))
304  {
305  ROS_ERROR_STREAM("Joint " << i << " violates its limits. Setting to Zero!");
306  q_dot_norm(i) = 0.0;
307  }
308 
309  double factor = 1.0;
310  if (fabs(limiter_params_.limits_max[i] - q(i)) <= tolerance) // Joint is close to the MAXIMUM limit
311  {
312  if (q_dot_ik(i) > 0.0) // Joint moves towards the MAX limit
313  {
314  double temp = 1.0 / pow((0.5 + 0.5 * cos(M_PI * (q(i) + tolerance - limiter_params_.limits_max[i]) / tolerance)), 5.0);
315  // double temp = tolerance / fabs(limiter_params_.limits_max[i] - q(i));
316  factor = (temp > factor) ? temp : factor;
317  }
318  }
319 
320  if (fabs(q(i) - limiter_params_.limits_min[i]) <= tolerance) // Joint is close to the MINIMUM limit
321  {
322  if (q_dot_ik(i) < 0.0) // Joint moves towards the MIN limit
323  {
324  double temp = 1.0 / pow(0.5 + 0.5 * cos(M_PI * (q(i) - tolerance - limiter_params_.limits_min[i]) / tolerance), 5.0);
325  // double temp = tolerance / fabs(q(i) - limiter_params_.limits_min[i]);
326  factor = (temp > factor) ? temp : factor;
327  }
328  }
329  q_dot_norm(i) = q_dot_norm(i) / factor;
330  }
331 
332  return q_dot_norm;
333 }
334 /* END LimiterIndividualJointPositions **************************************************************************/
335 
336 /* BEGIN LimiterIndividualJointVelocities ***********************************************************************/
342 {
343  KDL::JntArray q_dot_norm(q_dot_ik);
344 
345  for (unsigned int i = 0; i < q_dot_ik.rows(); i++)
346  {
347  double factor = 1.0;
348  if (factor < std::fabs(q_dot_ik(i) / limiter_params_.limits_vel[i]))
349  {
350  factor = std::fabs(q_dot_ik(i) / limiter_params_.limits_vel[i]);
351  q_dot_norm(i) = q_dot_ik(i) / factor;
352  }
353  }
354 
355  return q_dot_norm;
356 }
357 /* END LimiterIndividualJointVelocities *************************************************************************/
358 
359 /* BEGIN LimiterIndividualJointAccelerations ********************************************************************/
365 {
366  KDL::JntArray q_dot_norm(q_dot_ik);
367 
368  ROS_WARN("LimiterIndividualJointAccelerations not yet implemented");
369 
370  return q_dot_norm;
371 }
372 /* END LimiterIndividualJointAccelerations **********************************************************************/
373 
374 /* BEGIN LimiterIndividualCartesianVelocities ********************************************************************/
380 {
381  KDL::Twist v_out(v_in);
382 
383  // limiting rotational velocities
384  if (v_in.rot.x() >limiter_params_.max_rot_twist)
386  if (v_in.rot.x() <-limiter_params_.max_rot_twist)
388 
389  if (v_in.rot.y() >limiter_params_.max_rot_twist)
391  if (v_in.rot.y() <-limiter_params_.max_rot_twist)
393 
394  if (v_in.rot.z() >limiter_params_.max_rot_twist)
396  if (v_in.rot.z() <-limiter_params_.max_rot_twist)
398 
399  // limiting linear velocities
400  if (v_in.vel.x() >limiter_params_.max_lin_twist)
402  if (v_in.vel.x() <-limiter_params_.max_lin_twist)
404 
405  if (v_in.vel.y() >limiter_params_.max_lin_twist)
407  if (v_in.vel.y() <-limiter_params_.max_lin_twist)
409 
410  if (v_in.vel.z() >limiter_params_.max_lin_twist)
412  if (v_in.vel.z() <-limiter_params_.max_lin_twist)
414 
415  return v_out;
416 }
417 /* END LimiterIndividualCartesianVelocities **********************************************************************/
Class for joint velocity limiter (all scaled to keep direction), implementing interface methods...
Definition: limiter.h:91
std::vector< double > limits_min
unsigned int rows() const
virtual KDL::JntArray enforceLimits(const KDL::JntArray &q_dot_ik, const KDL::JntArray &q) const
Definition: limiter.cpp:214
virtual ~LimiterContainer()
Definition: limiter.cpp:136
const LimiterParams & limiter_params_
Definition: limiter.h:51
Vector vel
virtual KDL::JntArray enforceLimits(const KDL::JntArray &q_dot_ik, const KDL::JntArray &q) const
Definition: limiter.cpp:364
std::vector< const LimiterJointBase * >::const_iterator output_LimIter_t
Definition: limiter.h:56
std::vector< const LimiterCartesianBase * > input_limiters_
Definition: limiter.h:53
Class for a limiter, declaring a method to limit joint positions individually.
Definition: limiter.h:142
Base class for joint/output limiters, defining interface methods.
Definition: limiter_base.h:24
#define ROS_WARN(...)
virtual KDL::JntArray enforceLimits(const KDL::JntArray &q_dot_ik, const KDL::JntArray &q) const
Definition: limiter.cpp:247
double z() const
virtual KDL::Twist enforceLimits(const KDL::Twist &v_in) const
Definition: limiter.cpp:27
virtual KDL::JntArray enforceLimits(const KDL::JntArray &q_dot_ik, const KDL::JntArray &q) const
Definition: limiter.cpp:150
Class for limiting the cartesian velocities commands in order to guarantee a BIBO system (all scaled ...
Definition: limiter.h:125
Vector rot
double y() const
double x() const
std::vector< const LimiterCartesianBase * >::const_iterator input_LimIter_t
Definition: limiter.h:55
Class for joint acceleration limiter (individually scaled -> changes direction), implementing interfa...
Definition: limiter.h:176
std::vector< const LimiterJointBase * > output_limiters_
Definition: limiter.h:54
Class for joint velocity limiter (individually scaled -> changes direction), implementing interface m...
Definition: limiter.h:159
#define LIMIT_SAFETY_THRESHOLD
Definition: limiter.h:25
#define ROS_WARN_STREAM_THROTTLE(rate, args)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
std::vector< double > limits_max
void SetToZero(Jacobian &jac)
virtual KDL::Twist enforceLimits(const KDL::Twist &v_in) const
Definition: limiter.cpp:262
virtual KDL::Twist enforceLimits(const KDL::Twist &v_in) const
Definition: limiter.cpp:379
Class for limiting the cartesian velocities commands in order to guarantee a BIBO system (individuall...
Definition: limiter.h:193
void add(const LimiterCartesianBase *lb)
Definition: limiter.cpp:124
virtual KDL::JntArray enforceLimits(const KDL::JntArray &q_dot_ik, const KDL::JntArray &q) const
Definition: limiter.cpp:341
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Class for joint acceleration limiter (all scaled to keep direction), implementing interface methods...
Definition: limiter.h:108
#define ROS_ERROR_STREAM(args)
#define ROS_ERROR_STREAM_THROTTLE(rate, args)
Class for limiters, declaring the method to limit all joint positions.
Definition: limiter.h:74
Base class for cartesian/input limiters, defining interface methods.
Definition: limiter_base.h:48
virtual KDL::JntArray enforceLimits(const KDL::JntArray &q_dot_ik, const KDL::JntArray &q) const
Definition: limiter.cpp:295
std::vector< double > limits_vel


cob_twist_controller
Author(s): Felix Messmer , Marco Bezzon , Christoph Mark , Francisco Moreno
autogenerated on Thu Apr 8 2021 02:40:00