18 #ifndef COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_JLA_IMPL_H 19 #define COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_JLA_IMPL_H 27 #include <boost/shared_ptr.hpp> 28 #include <boost/pointer_cast.hpp> 30 #include <kdl/chainjnttojacsolver.hpp> 31 #include <kdl/jntarray.hpp> 42 template <
typename T_PARAMS,
typename PRIO>
45 std::ostringstream oss;
46 oss << this->member_inst_cnt_;
48 oss << this->constraint_params_.joint_idx_;
50 oss << this->priority_;
51 std::string taskid =
"JointLimitAvoidance_" + oss.str();
55 template <
typename T_PARAMS,
typename PRIO>
58 return this->partial_values_.transpose();
61 template <
typename T_PARAMS,
typename PRIO>
64 return Eigen::VectorXd::Identity(1, 1) * this->derivative_value_;
67 template <
typename T_PARAMS,
typename PRIO>
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);
77 this->abs_delta_max_ = std::abs(limit_max - joint_pos);
78 this->rel_max_ = std::abs(this->abs_delta_max_ / limit_max);
80 this->abs_delta_min_ = std::abs(joint_pos - limit_min);
81 this->rel_min_ = std::abs(this->abs_delta_min_ / limit_min);
83 const double rel_val = this->rel_max_ < this->rel_min_ ? this->rel_max_ : this->rel_min_;
86 this->calcPartialValues();
87 this->calcDerivativeValue();
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;
99 if (this->state_.getCurrent() ==
CRITICAL && pred_rel_val < rel_val)
101 ROS_WARN_STREAM(this->getTaskId() <<
": Current state is CRITICAL but prediction is smaller than current rel_val -> Stay in CRIT.");
103 else if (rel_val < critical || pred_rel_val < critical)
109 this->state_.setState(
DANGER);
113 template <
typename T_PARAMS,
typename PRIO>
120 double activation_gain;
121 const double rel_delta = this->rel_min_ < this->rel_max_ ? this->rel_min_ : this->rel_max_;
123 if (rel_delta < activation_threshold)
125 activation_gain = 1.0;
127 else if (rel_delta < activation_buffer_region)
129 activation_gain = 0.5 * (1.0 +
cos(M_PI * (rel_delta - activation_threshold) / (activation_buffer_region - activation_threshold)));
133 activation_gain = 0.0;
136 if (activation_gain < 0.0)
138 activation_gain = 0.0;
141 return activation_gain;
145 template <
typename T_PARAMS,
typename PRIO>
148 return this->constraint_params_.params_.k_H;
152 template <
typename T_PARAMS,
typename PRIO>
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);
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]);
164 this->last_value_ = this->value_;
169 template <
typename T_PARAMS,
typename PRIO>
172 this->derivative_value_ = -0.1 * this->value_;
176 template <
typename T_PARAMS,
typename PRIO>
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());
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;
191 partial_values(this->constraint_params_.joint_idx_) = std::abs(denom) >
ZERO_THRESHOLD ? nominator / denom : nominator /
DIV0_SAFE;
192 this->partial_values_ = partial_values;
197 template <
typename T_PARAMS,
typename PRIO>
200 std::ostringstream oss;
201 oss << this->member_inst_cnt_;
203 oss << this->priority_;
204 std::string taskid =
"JointLimitAvoidanceMid_" + oss.str();
208 template <
typename T_PARAMS,
typename PRIO>
212 this->calcDerivativeValue();
213 this->calcPartialValues();
216 template <
typename T_PARAMS,
typename PRIO>
223 template <
typename T_PARAMS,
typename PRIO>
226 return this->constraint_params_.params_.k_H;
230 template <
typename T_PARAMS,
typename PRIO>
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_;
238 for (uint8_t i = 0; i < joint_pos.
rows() ; ++i)
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]);
246 this->value_ = H_q / 4.0;
250 template <
typename T_PARAMS,
typename PRIO>
254 double cycle = (now - this->last_time_).toSec();
255 this->last_time_ = now;
259 this->derivative_value_ = (this->value_ - this->last_value_) / cycle;
263 this->derivative_value_ = (this->value_ - this->last_value_) /
DEFAULT_CYCLE;
268 template <
typename T_PARAMS,
typename PRIO>
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;
276 uint8_t vec_rows =
static_cast<uint8_t
>(joint_pos.
rows());
277 Eigen::VectorXd partial_values = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
279 for (uint8_t i = 0; i < vec_rows; ++i)
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)
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]);
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;
296 this->partial_values_ = partial_values;
301 template <
typename T_PARAMS,
typename PRIO>
304 std::ostringstream oss;
305 oss << this->member_inst_cnt_;
307 oss << this->priority_;
308 std::string taskid =
"JointLimitAvoidanceIneq_" + oss.str();
312 template <
typename T_PARAMS,
typename PRIO>
315 return this->partial_values_.transpose();
318 template <
typename T_PARAMS,
typename PRIO>
321 return Eigen::VectorXd::Identity(1, 1) * this->derivative_value_;
324 template <
typename T_PARAMS,
typename PRIO>
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);
334 this->abs_delta_max_ = std::abs(limit_max - joint_pos);
335 this->rel_max_ = std::abs(this->abs_delta_max_ / limit_max);
337 this->abs_delta_min_ = std::abs(joint_pos - limit_min);
338 this->rel_min_ = std::abs(this->abs_delta_min_ / limit_min);
340 const double rel_val = this->rel_max_ < this->rel_min_ ? this->rel_max_ : this->rel_min_;
343 this->calcPartialValues();
344 this->calcDerivativeValue();
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);
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);
353 this->prediction_value_ = pred_rel_max < pred_rel_min ? pred_rel_max : pred_rel_min;
358 if (this->state_.getCurrent() ==
CRITICAL && this->prediction_value_ < rel_val)
360 ROS_WARN_STREAM(this->getTaskId() <<
": Current state is CRITICAL but prediction is smaller than current rel_val -> Stay in CRIT.");
362 else if (rel_val < critical || this->prediction_value_ < critical)
364 if (this->prediction_value_ < critical)
373 this->state_.setState(
DANGER);
377 template <
typename T_PARAMS,
typename PRIO>
383 double activation_gain;
386 if (this->abs_delta_max_ > this->abs_delta_min_)
388 rel_delta = this->rel_min_;
393 rel_delta = this->rel_max_;
396 if (rel_delta < activation_threshold)
398 activation_gain = 1.0;
400 else if (rel_delta < activation_buffer_region)
402 activation_gain = 0.5 * (1.0 +
cos(M_PI * (rel_delta - activation_threshold) / (activation_buffer_region - activation_threshold)));
406 activation_gain = 0.0;
409 if (activation_gain < 0.0)
411 activation_gain = 0.0;
414 return activation_gain;
418 template <
typename T_PARAMS,
typename PRIO>
423 if (this->abs_delta_max_ > this->abs_delta_min_ && this->rel_min_ > 0.0)
429 if (this->rel_max_ > 0.0)
439 double k_H = factor * params.
k_H;
444 template <
typename T_PARAMS,
typename PRIO>
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];
452 double joint_pos = this->joint_states_.current_q_(joint_idx);
454 this->last_value_ = this->value_;
455 this->value_ = (limit_max - joint_pos) * (joint_pos - limit_min);
459 template <
typename T_PARAMS,
typename PRIO>
462 this->derivative_value_ = 0.1 * this->value_;
466 template <
typename T_PARAMS,
typename PRIO>
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());
476 partial_values(this->constraint_params_.joint_idx_) = -2.0 * joint_pos + limit_max + limit_min;
477 this->partial_values_ = partial_values;
481 #endif // COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_JLA_IMPL_H void calcDerivativeValue()
Calculate derivative of values.
virtual Eigen::MatrixXd getTaskJacobian() const
std::vector< double > limits_min
virtual std::string getTaskId() const
void calcPartialValues()
Calculates values of the gradient of the cost function.
virtual Eigen::VectorXd getTaskDerivatives() 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.
virtual Eigen::MatrixXd getTaskJacobian() const
void calcValue()
Calculate values of the JLA cost function.
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 calcValue()
Calculate values of the JLA cost function.
virtual Eigen::VectorXd getTaskDerivatives() const
ConstraintThresholds thresholds
void calcValue()
Calculate values of the JLA cost function.
void calcDerivativeValue()
Simple first order differential equation for exponential increase (move away from limit!) ...
#define ROS_WARN_STREAM(args)
virtual double getActivationGain() const
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
std::vector< double > limits_max
void calcPartialValues()
Calculates values of the gradient of the cost function.
virtual std::string getTaskId() const
virtual std::string getTaskId() const
virtual double getActivationGain() const
void calcDerivativeValue()
Calculate derivative of values.
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.
virtual double getActivationGain() const
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
double activation_with_buffer
void calcPartialValues()
Calculates values of the gradient of the cost function.