18 #ifndef COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_CA_IMPL_H 19 #define COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_CA_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 const std::string frame_id = this->constraint_params_.id_;
46 std::ostringstream oss;
47 oss << this->member_inst_cnt_;
51 oss << this->priority_;
52 std::string taskid =
"CollisionAvoidance_" + oss.str();
61 template <
typename T_PARAMS,
typename PRIO>
64 return this->task_jacobian_;
72 template <
typename T_PARAMS,
typename PRIO>
75 return this->derivative_values_;
78 template <
typename T_PARAMS,
typename PRIO>
84 this->calcDerivativeValue();
85 this->calcPartialValues();
86 this->calcPredictionValue();
88 const double pred_min_dist = this->getPredictionValue();
92 const double crit_min_distance = this->getCriticalValue();
94 if (this->state_.getCurrent() ==
CRITICAL && pred_min_dist < crit_min_distance)
96 ROS_WARN_STREAM(this->getTaskId() <<
": Current state is CRITICAL but prediction " << pred_min_dist <<
" is smaller than current dist " << crit_min_distance <<
" -> Stay in CRIT.");
98 else if (crit_min_distance < critical || pred_min_dist < critical)
102 else if (crit_min_distance < activation_buffer)
104 this->state_.setState(
DANGER);
108 this->state_.setState(
NORMAL);
112 template <
typename T_PARAMS,
typename PRIO>
116 double activation_gain;
120 if (current_cost_func_value < activation)
122 activation_gain = 1.0;
124 else if (current_cost_func_value < activation_buffer_region)
126 activation_gain = 0.5 * (1.0 +
cos(M_PI * (current_cost_func_value - activation) / (activation_buffer_region - activation)));
130 activation_gain = 0.0;
133 return activation_gain;
136 template <
typename T_PARAMS,
typename PRIO>
143 template <
typename T_PARAMS,
typename PRIO>
148 double magnitude = 0.0;
150 if (current_distance_value < activation_with_buffer)
152 if (current_distance_value > 0.0)
154 magnitude =
pow(activation_with_buffer / current_distance_value, 2.0) - 1.0;
158 magnitude = activation_with_buffer / 0.000001;
162 double k_H = params.
k_H;
163 return k_H * magnitude;
167 template <
typename T_PARAMS,
typename PRIO>
173 template <
typename T_PARAMS,
typename PRIO>
176 double min_distance = std::numeric_limits<double>::max();
177 for (std::vector<ObstacleDistanceData>::const_iterator it = this->constraint_params_.current_distances_.begin();
178 it != this->constraint_params_.current_distances_.end();
181 if (it->min_distance < min_distance)
183 min_distance = it->min_distance;
190 template <
typename T_PARAMS,
typename PRIO>
194 std::vector<double> relevant_values;
195 for (std::vector<ObstacleDistanceData>::const_iterator it = this->constraint_params_.current_distances_.begin();
196 it != this->constraint_params_.current_distances_.end();
201 const double activation_gain = this->getActivationGain(it->min_distance);
202 const double magnitude = std::abs(this->getSelfMotionMagnitude(it->min_distance));
204 relevant_values.push_back(value);
208 if (relevant_values.size() > 0)
210 this->values_ = Eigen::VectorXd::Zero(relevant_values.size());
213 for (uint32_t idx = 0; idx < relevant_values.size(); ++idx)
215 this->values_(idx) = relevant_values.at(idx);
219 template <
typename T_PARAMS,
typename PRIO>
222 this->derivative_value_ = -0.1 * this->value_;
223 this->derivative_values_ = -0.1 * this->values_;
232 template <
typename T_PARAMS,
typename PRIO>
236 Eigen::VectorXd partial_values = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
237 Eigen::VectorXd sum_partial_values = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
238 this->partial_values_ = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
241 std::vector<Eigen::VectorXd> vec_partial_values;
246 std::vector<std::string>::const_iterator str_it = std::find(this->constraint_params_.frame_names_.begin(),
247 this->constraint_params_.frame_names_.end(),
248 this->constraint_params_.id_);
250 for (std::vector<ObstacleDistanceData>::const_iterator it = this->constraint_params_.current_distances_.begin();
251 it != this->constraint_params_.current_distances_.end();
254 if (params.thresholds.activation_with_buffer > it->min_distance)
256 if (this->constraint_params_.frame_names_.end() != str_it)
258 Eigen::Vector3d collision_pnt_vector = it->nearest_point_frame_vector - it->frame_vector;
259 Eigen::Vector3d distance_vec = it->nearest_point_frame_vector - it->nearest_point_obstacle_vector;
262 Eigen::Matrix3d skew_symm;
263 skew_symm << 0.0, collision_pnt_vector.z(), -collision_pnt_vector.y(),
264 -collision_pnt_vector.z(), 0.0, collision_pnt_vector.x(),
265 collision_pnt_vector.y(), -collision_pnt_vector.x(), 0.0;
267 Eigen::Matrix3d ident = Eigen::Matrix3d::Identity();
268 Eigen::Matrix<double, 6, 6> T;
269 T.block(0, 0, 3, 3) << ident;
270 T.block(0, 3, 3, 3) << skew_symm;
271 T.block(3, 0, 3, 3) << Eigen::Matrix3d::Zero();
272 T.block(3, 3, 3, 3) << ident;
275 uint32_t idx = str_it - this->constraint_params_.frame_names_.begin();
276 uint32_t frame_number = idx + 1;
279 KDL::Jacobian new_jac_chain(this->joint_states_.current_q_.rows());
285 if (0 != this->jnt_to_jac_.JntToJac(ja, new_jac_chain, frame_number))
287 ROS_ERROR_STREAM(
"Failed to calculate JntToJac. Error Code: " << this->jnt_to_jac_.getError() <<
" (" << this->jnt_to_jac_.strError(this->jnt_to_jac_.getError()) <<
")");
288 ROS_ERROR_STREAM(
"This is likely due to using a KinematicExtension! The ChainJntToJac-Solver is configured for the main chain only!");
294 jac_extension.block(0, 0, new_jac_chain.data.rows(), new_jac_chain.data.cols()) = new_jac_chain.data;
296 Eigen::Matrix3Xd m_transl = Eigen::Matrix3Xd::Zero(3, crit_pnt_jac.cols());
297 m_transl << crit_pnt_jac.row(0),
301 double vec_norm = distance_vec.norm();
302 vec_norm = (vec_norm > 0.0) ? vec_norm :
DIV0_SAFE;
303 Eigen::VectorXd term_2nd = (m_transl.transpose()) * (distance_vec / vec_norm);
307 const double denom = it->min_distance > 0.0 ? it->min_distance :
DIV0_SAFE;
308 const double activation_gain = this->getActivationGain(it->min_distance);
309 const double magnitude = this->getSelfMotionMagnitude(it->min_distance);
310 partial_values = (2.0 * ((it->min_distance - params.thresholds.activation_with_buffer) / denom) * term_2nd);
312 sum_partial_values += (activation_gain * magnitude * partial_values);
313 vec_partial_values.push_back(partial_values);
328 if (vec_partial_values.size() > 0)
330 this->task_jacobian_.resize(vec_partial_values.size(), this->jacobian_data_.cols());
333 for (uint32_t idx = 0; idx < vec_partial_values.size(); ++idx)
335 this->task_jacobian_.block(idx, 0, 1, this->jacobian_data_.cols()) = vec_partial_values.at(idx).transpose();
340 this->partial_values_ = sum_partial_values;
343 template <
typename T_PARAMS,
typename PRIO>
347 this->prediction_value_ = std::numeric_limits<double>::max();
350 double cycle = (now - this->last_pred_time_).toSec();
351 this->last_pred_time_ = now;
353 std::vector<std::string>::const_iterator str_it = std::find(this->constraint_params_.frame_names_.begin(),
354 this->constraint_params_.frame_names_.end(),
355 this->constraint_params_.id_);
358 if (this->constraint_params_.frame_names_.end() != str_it)
360 if (this->constraint_params_.current_distances_.size() > 0)
362 uint32_t frame_number = (str_it - this->constraint_params_.frame_names_.begin()) + 1;
366 int error = this->fk_solver_vel_.JntToCart(this->jnts_prediction_, frame_vel, frame_number);
369 ROS_ERROR_STREAM(
"Could not calculate twist for frame: " << frame_number <<
". Error Code: " << error <<
" (" << this->fk_solver_vel_.strError(error) <<
")");
370 ROS_ERROR_STREAM(
"This is likely due to using a KinematicExtension! The ChainFkSolverVel is configured for the main chain only!");
377 Eigen::Vector3d pred_twist_vel;
380 Eigen::Vector3d pred_twist_rot;
383 std::vector<ObstacleDistanceData>::const_iterator it = this->constraint_params_.current_distances_.begin();
385 for ( ; it != this->constraint_params_.current_distances_.end(); ++it)
405 #endif // COB_TWIST_CONTROLLER_CONSTRAINTS_CONSTRAINT_CA_IMPL_H
virtual Eigen::VectorXd getTaskDerivatives() const
IMETHOD Twist GetTwist() const
virtual double getCriticalValue() const
void calcPredictionValue()
Eigen::Vector3d nearest_point_obstacle_vector
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.
ConstraintThresholds thresholds
virtual Eigen::MatrixXd getTaskJacobian() const
#define ROS_WARN_STREAM(args)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
void calcDerivativeValue()
void vectorKDLToEigen(const KDL::Vector &k, Eigen::Matrix< double, 3, 1 > &e)
virtual double getActivationGain() const
Eigen::Matrix< double, 6, Eigen::Dynamic > Matrix6Xd_t
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
#define ROS_ERROR_STREAM(args)
double activation_with_buffer
virtual std::string getTaskId() const
Eigen::Vector3d nearest_point_frame_vector