constraint_jla_impl.h
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 #ifndef COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_JLA_IMPL_H
19 #define COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_JLA_IMPL_H
20 
21 #include <sstream>
22 #include <string>
23 #include <vector>
24 #include <limits>
25 #include <ros/ros.h>
26 
27 #include <boost/shared_ptr.hpp>
28 #include <boost/pointer_cast.hpp>
29 
30 #include <kdl/chainjnttojacsolver.hpp>
31 #include <kdl/jntarray.hpp>
32 
35 
38 
40 
41 /* BEGIN JointLimitAvoidance ************************************************************************************/
42 template <typename T_PARAMS, typename PRIO>
44 {
45  std::ostringstream oss;
46  oss << this->member_inst_cnt_;
47  oss << "_Joint#";
48  oss << this->constraint_params_.joint_idx_;
49  oss << "_";
50  oss << this->priority_;
51  std::string taskid = "JointLimitAvoidance_" + oss.str();
52  return taskid;
53 }
54 
55 template <typename T_PARAMS, typename PRIO>
57 {
58  return this->partial_values_.transpose();
59 }
60 
61 template <typename T_PARAMS, typename PRIO>
63 {
64  return Eigen::VectorXd::Identity(1, 1) * this->derivative_value_;
65 }
66 
67 template <typename T_PARAMS, typename PRIO>
69 {
70  const ConstraintParams& params = this->constraint_params_.params_;
71  const LimiterParams& limiter_params = this->constraint_params_.limiter_params_;
72  const int32_t joint_idx = this->constraint_params_.joint_idx_;
73  const double limit_min = limiter_params.limits_min[joint_idx];
74  const double limit_max = limiter_params.limits_max[joint_idx];
75  const double joint_pos = this->joint_states_.current_q_(joint_idx);
76 
77  this->abs_delta_max_ = std::abs(limit_max - joint_pos);
78  this->rel_max_ = std::abs(this->abs_delta_max_ / limit_max);
79 
80  this->abs_delta_min_ = std::abs(joint_pos - limit_min);
81  this->rel_min_ = std::abs(this->abs_delta_min_ / limit_min);
82 
83  const double rel_val = this->rel_max_ < this->rel_min_ ? this->rel_max_ : this->rel_min_;
84 
85  this->calcValue();
86  this->calcPartialValues();
87  this->calcDerivativeValue();
88 
89  // Compute prediction
90  const double pred_delta_max = std::abs(limit_max - this->jnts_prediction_.q(joint_idx));
91  const double pred_rel_max = std::abs(pred_delta_max / limit_max);
92  const double pred_delta_min = std::abs(this->jnts_prediction_.q(joint_idx) - limit_min);
93  const double pred_rel_min = std::abs(pred_delta_min / limit_min);
94  const double pred_rel_val = pred_rel_max < pred_rel_min ? pred_rel_max : pred_rel_min;
95 
96  const double activation = params.thresholds.activation;
97  const double critical = params.thresholds.critical;
98 
99  if (this->state_.getCurrent() == CRITICAL && pred_rel_val < rel_val)
100  {
101  ROS_WARN_STREAM(this->getTaskId() << ": Current state is CRITICAL but prediction is smaller than current rel_val -> Stay in CRIT.");
102  }
103  else if (rel_val < critical || pred_rel_val < critical)
104  {
105  this->state_.setState(CRITICAL); // always highest task -> avoid HW destruction.
106  }
107  else
108  {
109  this->state_.setState(DANGER); // always active task -> avoid HW destruction.
110  }
111 }
112 
113 template <typename T_PARAMS, typename PRIO>
115 {
116  const ConstraintParams& params = this->constraint_params_.params_;
117  const double activation_threshold = params.thresholds.activation;
118  const double activation_buffer_region = params.thresholds.activation_with_buffer; // [%]
119 
120  double activation_gain;
121  const double rel_delta = this->rel_min_ < this->rel_max_ ? this->rel_min_ : this->rel_max_;
122 
123  if (rel_delta < activation_threshold)
124  {
125  activation_gain = 1.0;
126  }
127  else if (rel_delta < activation_buffer_region)
128  {
129  activation_gain = 0.5 * (1.0 + cos(M_PI * (rel_delta - activation_threshold) / (activation_buffer_region - activation_threshold)));
130  }
131  else
132  {
133  activation_gain = 0.0;
134  }
135 
136  if (activation_gain < 0.0)
137  {
138  activation_gain = 0.0;
139  }
140 
141  return activation_gain;
142 }
143 
145 template <typename T_PARAMS, typename PRIO>
146 double JointLimitAvoidance<T_PARAMS, PRIO>::getSelfMotionMagnitude(const Eigen::MatrixXd& particular_solution, const Eigen::MatrixXd& homogeneous_solution) const
147 {
148  return this->constraint_params_.params_.k_H;
149 }
150 
152 template <typename T_PARAMS, typename PRIO>
154 {
155  const LimiterParams& limiter_params = this->constraint_params_.limiter_params_;
156  const int32_t joint_idx = this->constraint_params_.joint_idx_;
157  std::vector<double> limits_min = limiter_params.limits_min;
158  std::vector<double> limits_max = limiter_params.limits_max;
159  const double joint_pos = this->joint_states_.current_q_(joint_idx);
160 
161  double nom = pow(limits_max[joint_idx] - limits_min[joint_idx], 2.0);
162  double denom = (limits_max[joint_idx] - joint_pos) * (joint_pos - limits_min[joint_idx]);
163 
164  this->last_value_ = this->value_;
165  this->value_ = std::abs(denom) > ZERO_THRESHOLD ? nom / denom : nom / DIV0_SAFE;
166 }
167 
169 template <typename T_PARAMS, typename PRIO>
171 {
172  this->derivative_value_ = -0.1 * this->value_;
173 }
174 
176 template <typename T_PARAMS, typename PRIO>
178 {
179  const LimiterParams& limiter_params = this->constraint_params_.limiter_params_;
180  const double joint_pos = this->joint_states_.current_q_(this->constraint_params_.joint_idx_);
181  const double joint_vel = this->joint_states_.current_q_dot_(this->constraint_params_.joint_idx_);
182  const double limits_min = limiter_params.limits_min[this->constraint_params_.joint_idx_];
183  const double limits_max = limiter_params.limits_max[this->constraint_params_.joint_idx_];
184  Eigen::VectorXd partial_values = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
185 
186  const double min_delta = (joint_pos - limits_min);
187  const double max_delta = (limits_max - joint_pos);
188  const double nominator = (2.0 * joint_pos - limits_min - limits_max) * (limits_max - limits_min) * (limits_max - limits_min);
189  const double denom = 4.0 * min_delta * min_delta * max_delta * max_delta;
190 
191  partial_values(this->constraint_params_.joint_idx_) = std::abs(denom) > ZERO_THRESHOLD ? nominator / denom : nominator / DIV0_SAFE;
192  this->partial_values_ = partial_values;
193 }
194 /* END JointLimitAvoidance **************************************************************************************/
195 
196 /* BEGIN JointLimitAvoidanceMid ************************************************************************************/
197 template <typename T_PARAMS, typename PRIO>
199 {
200  std::ostringstream oss;
201  oss << this->member_inst_cnt_;
202  oss << "_";
203  oss << this->priority_;
204  std::string taskid = "JointLimitAvoidanceMid_" + oss.str();
205  return taskid;
206 }
207 
208 template <typename T_PARAMS, typename PRIO>
210 {
211  this->calcValue();
212  this->calcDerivativeValue();
213  this->calcPartialValues();
214 }
215 
216 template <typename T_PARAMS, typename PRIO>
218 {
219  return 1.0;
220 }
221 
223 template <typename T_PARAMS, typename PRIO>
224 double JointLimitAvoidanceMid<T_PARAMS, PRIO>::getSelfMotionMagnitude(const Eigen::MatrixXd& particular_solution, const Eigen::MatrixXd& homogeneous_solution) const
225 {
226  return this->constraint_params_.params_.k_H;
227 }
228 
230 template <typename T_PARAMS, typename PRIO>
232 {
233  const LimiterParams& limiter_params = this->constraint_params_.limiter_params_;
234  std::vector<double> limits_min = limiter_params.limits_min;
235  std::vector<double> limits_max = limiter_params.limits_max;
236  const KDL::JntArray joint_pos = this->joint_states_.current_q_;
237  double H_q = 0.0;
238  for (uint8_t i = 0; i < joint_pos.rows() ; ++i)
239  {
240  double jnt_pos_with_step = joint_pos(i);
241  double nom = pow(limits_max[i] - limits_min[i], 2.0);
242  double denom = (limits_max[i] - jnt_pos_with_step) * (jnt_pos_with_step - limits_min[i]);
243  H_q += nom / denom;
244  }
245 
246  this->value_ = H_q / 4.0;
247 }
248 
250 template <typename T_PARAMS, typename PRIO>
252 {
254  double cycle = (now - this->last_time_).toSec();
255  this->last_time_ = now;
256 
257  if (cycle > 0.0)
258  {
259  this->derivative_value_ = (this->value_ - this->last_value_) / cycle;
260  }
261  else
262  {
263  this->derivative_value_ = (this->value_ - this->last_value_) / DEFAULT_CYCLE;
264  }
265 }
266 
268 template <typename T_PARAMS, typename PRIO>
270 {
271  const LimiterParams& limiter_params = this->constraint_params_.limiter_params_;
272  const KDL::JntArray joint_pos = this->joint_states_.current_q_;
273  std::vector<double> limits_min = limiter_params.limits_min;
274  std::vector<double> limits_max = limiter_params.limits_max;
275 
276  uint8_t vec_rows = static_cast<uint8_t>(joint_pos.rows());
277  Eigen::VectorXd partial_values = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
278 
279  for (uint8_t i = 0; i < vec_rows; ++i) // max limiting the arm joints but not the extensions.
280  {
281  double min_delta = joint_pos(i) - limits_min[i];
282  double max_delta = limits_max[i] - joint_pos(i);
283  if (min_delta * max_delta < 0.0)
284  {
285  ROS_WARN_STREAM("Limit of joint " << int(i) << " reached: " << std::endl
286  << "pos=" << joint_pos(i) << ";lim_min=" << limits_min[i] << ";lim_max=" << limits_max[i]);
287  }
288 
289  // Liegeois method can also be found in Chan paper ISSN 1042-296X [Page 288]
290  double limits_mid = 1.0 / 2.0 * (limits_max[i] + limits_min[i]);
291  double nominator = joint_pos(i) - limits_mid;
292  double denom = pow(limits_max[i] - limits_min[i], 2.0);
293  partial_values(i) = nominator / denom;
294  }
295 
296  this->partial_values_ = partial_values;
297 }
298 /* END JointLimitAvoidanceMid ************************************************************************************/
299 
300 /* BEGIN JointLimitAvoidanceIneq ************************************************************************************/
301 template <typename T_PARAMS, typename PRIO>
303 {
304  std::ostringstream oss;
305  oss << this->member_inst_cnt_;
306  oss << "_";
307  oss << this->priority_;
308  std::string taskid = "JointLimitAvoidanceIneq_" + oss.str();
309  return taskid;
310 }
311 
312 template <typename T_PARAMS, typename PRIO>
314 {
315  return this->partial_values_.transpose();
316 }
317 
318 template <typename T_PARAMS, typename PRIO>
320 {
321  return Eigen::VectorXd::Identity(1, 1) * this->derivative_value_;
322 }
323 
324 template <typename T_PARAMS, typename PRIO>
326 {
327  const ConstraintParams& params = this->constraint_params_.params_;
328  const LimiterParams& limiter_params = this->constraint_params_.limiter_params_;
329  const int32_t joint_idx = this->constraint_params_.joint_idx_;
330  const double limit_min = limiter_params.limits_min[joint_idx];
331  const double limit_max = limiter_params.limits_max[joint_idx];
332  const double joint_pos = this->joint_states_.current_q_(joint_idx);
333 
334  this->abs_delta_max_ = std::abs(limit_max - joint_pos);
335  this->rel_max_ = std::abs(this->abs_delta_max_ / limit_max);
336 
337  this->abs_delta_min_ = std::abs(joint_pos - limit_min);
338  this->rel_min_ = std::abs(this->abs_delta_min_ / limit_min);
339 
340  const double rel_val = this->rel_max_ < this->rel_min_ ? this->rel_max_ : this->rel_min_;
341 
342  this->calcValue();
343  this->calcPartialValues();
344  this->calcDerivativeValue();
345 
346  // Compute prediction
347  const double pred_delta_max = std::abs(limit_max - this->jnts_prediction_.q(joint_idx));
348  const double pred_rel_max = std::abs(pred_delta_max / limit_max);
349 
350  const double pred_delta_min = std::abs(this->jnts_prediction_.q(joint_idx) - limit_min);
351  const double pred_rel_min = std::abs(pred_delta_min / limit_min);
352 
353  this->prediction_value_ = pred_rel_max < pred_rel_min ? pred_rel_max : pred_rel_min;
354 
355  double activation = params.thresholds.activation;
356  double critical = params.thresholds.critical;
357 
358  if (this->state_.getCurrent() == CRITICAL && this->prediction_value_ < rel_val)
359  {
360  ROS_WARN_STREAM(this->getTaskId() << ": Current state is CRITICAL but prediction is smaller than current rel_val -> Stay in CRIT.");
361  }
362  else if (rel_val < critical || this->prediction_value_ < critical)
363  {
364  if (this->prediction_value_ < critical)
365  {
366  ROS_WARN_STREAM(this->getTaskId() << ": pred_val < critical!!!");
367  }
368 
369  this->state_.setState(CRITICAL);
370  }
371  else
372  {
373  this->state_.setState(DANGER); // GPM always active!
374  }
375 }
376 
377 template <typename T_PARAMS, typename PRIO>
379 {
380  const ConstraintParams& params = this->constraint_params_.params_;
381  const double activation_threshold = params.thresholds.activation; // [%]
382  const double activation_buffer_region = params.thresholds.activation_with_buffer; // [%]
383  double activation_gain;
384  double rel_delta;
385 
386  if (this->abs_delta_max_ > this->abs_delta_min_)
387  {
388  rel_delta = this->rel_min_;
389  }
390  else
391  {
392  // nearer to max limit
393  rel_delta = this->rel_max_;
394  }
395 
396  if (rel_delta < activation_threshold)
397  {
398  activation_gain = 1.0;
399  }
400  else if (rel_delta < activation_buffer_region)
401  {
402  activation_gain = 0.5 * (1.0 + cos(M_PI * (rel_delta - activation_threshold) / (activation_buffer_region - activation_threshold)));
403  }
404  else
405  {
406  activation_gain = 0.0;
407  }
408 
409  if (activation_gain < 0.0)
410  {
411  activation_gain = 0.0;
412  }
413 
414  return activation_gain;
415 }
416 
418 template <typename T_PARAMS, typename PRIO>
419 double JointLimitAvoidanceIneq<T_PARAMS, PRIO>::getSelfMotionMagnitude(const Eigen::MatrixXd& particular_solution, const Eigen::MatrixXd& homogeneous_solution) const
420 {
421  double factor;
422  const ConstraintParams& params = this->constraint_params_.params_;
423  if (this->abs_delta_max_ > this->abs_delta_min_ && this->rel_min_ > 0.0)
424  {
425  factor = (params.thresholds.activation * 1.1 / this->rel_min_) - 1.0;
426  }
427  else
428  {
429  if (this->rel_max_ > 0.0)
430  {
431  factor = (params.thresholds.activation * 1.1 / this->rel_max_) - 1.0;
432  }
433  else
434  {
435  factor = 1.0;
436  }
437  }
438 
439  double k_H = factor * params.k_H;
440  return k_H;
441 }
442 
444 template <typename T_PARAMS, typename PRIO>
446 {
447  const LimiterParams& limiter_params = this->constraint_params_.limiter_params_;
448  int32_t joint_idx = this->constraint_params_.joint_idx_;
449  double limit_min = limiter_params.limits_min[joint_idx];
450  double limit_max = limiter_params.limits_max[joint_idx];
451 
452  double joint_pos = this->joint_states_.current_q_(joint_idx);
453 
454  this->last_value_ = this->value_;
455  this->value_ = (limit_max - joint_pos) * (joint_pos - limit_min);
456 }
457 
459 template <typename T_PARAMS, typename PRIO>
461 {
462  this->derivative_value_ = 0.1 * this->value_;
463 }
464 
466 template <typename T_PARAMS, typename PRIO>
468 {
469  const LimiterParams& limiter_params = this->constraint_params_.limiter_params_;
470  int32_t joint_idx = this->constraint_params_.joint_idx_;
471  double limit_min = limiter_params.limits_min[joint_idx];
472  double limit_max = limiter_params.limits_max[joint_idx];
473  double joint_pos = this->joint_states_.current_q_(joint_idx);
474  Eigen::VectorXd partial_values = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
475 
476  partial_values(this->constraint_params_.joint_idx_) = -2.0 * joint_pos + limit_max + limit_min;
477  this->partial_values_ = partial_values;
478 }
479 /* END JointLimitAvoidanceIneq **************************************************************************************/
480 
481 #endif // COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_JLA_IMPL_H
void calcDerivativeValue()
Calculate derivative of values.
std::vector< double > limits_min
double now()
virtual std::string getTaskId() const
virtual std::string getTaskId() const
virtual Eigen::MatrixXd getTaskJacobian() const
virtual double getActivationGain() const
unsigned int rows() const
virtual double getSelfMotionMagnitude(const Eigen::MatrixXd &particular_solution, const Eigen::MatrixXd &homogeneous_solution) const
Returns a value for k_H to weight the partial values for e.g. GPM.
void calcPartialValues()
Calculates values of the gradient of the cost function.
virtual Eigen::VectorXd getTaskDerivatives() const
virtual std::string getTaskId() const
virtual double getSelfMotionMagnitude(const Eigen::MatrixXd &particular_solution, const Eigen::MatrixXd &homogeneous_solution) const
Returns a value for k_H to weight the partial values for e.g. GPM.
void calcValue()
Calculate values of the JLA cost function.
virtual Eigen::VectorXd getTaskDerivatives() const
virtual double getActivationGain() const
virtual void calculate()
virtual double getSelfMotionMagnitude(const Eigen::MatrixXd &particular_solution, const Eigen::MatrixXd &homogeneous_solution) const
Returns a value for k_H to weight the partial values for e.g. GPM.
void calcValue()
Calculate values of the JLA cost function.
void calcValue()
Calculate values of the JLA cost function.
virtual double getActivationGain() const
void calcDerivativeValue()
Simple first order differential equation for exponential increase (move away from limit!) ...
#define ROS_WARN_STREAM(args)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
#define DEFAULT_CYCLE
std::vector< double > limits_max
void calcPartialValues()
Calculates values of the gradient of the cost function.
static Time now()
#define ZERO_THRESHOLD
void calcDerivativeValue()
Calculate derivative of values.
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
virtual Eigen::MatrixXd getTaskJacobian() const
void calcPartialValues()
Calculates values of the gradient of the cost function.


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