Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <set>
00019
00020 #include "cob_twist_controller/constraint_solvers/solvers/stack_of_tasks_solver.h"
00021 #include "cob_twist_controller/task_stack/task_stack_controller.h"
00022
00023 Eigen::MatrixXd StackOfTasksSolver::solve(const Vector6d_t& in_cart_velocities,
00024 const JointStates& joint_states)
00025 {
00026 this->global_constraint_state_ = NORMAL;
00027 ros::Time now = ros::Time::now();
00028 double cycle = (now - this->last_time_).toSec();
00029 this->last_time_ = now;
00030
00031 Eigen::MatrixXd damped_pinv = pinv_calc_.calculate(this->params_, this->damping_, this->jacobian_data_);
00032 Eigen::MatrixXd pinv = pinv_calc_.calculate(this->jacobian_data_);
00033
00034 Eigen::MatrixXd particular_solution = damped_pinv * in_cart_velocities;
00035
00036 Eigen::MatrixXd ident = Eigen::MatrixXd::Identity(pinv.rows(), this->jacobian_data_.cols());
00037 Eigen::MatrixXd projector = ident - pinv * this->jacobian_data_;
00038
00039 Eigen::MatrixXd projector_i = Eigen::MatrixXd::Identity(this->jacobian_data_.cols(), this->jacobian_data_.cols());
00040 Eigen::VectorXd q_i = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
00041 Eigen::MatrixXd qdots_out = Eigen::MatrixXd::Zero(this->jacobian_data_.cols(), 1);
00042
00043 Eigen::VectorXd sum_of_gradient = Eigen::VectorXd::Zero(this->jacobian_data_.cols());
00044
00045 KDL::JntArrayVel predict_jnts_vel(joint_states.current_q_.rows());
00046
00047
00048 for (int i = 0; i < joint_states.current_q_.rows(); ++i)
00049 {
00050 predict_jnts_vel.q(i) = particular_solution(i, 0) * cycle + joint_states.current_q_(i);
00051 predict_jnts_vel.qdot(i) = particular_solution(i, 0);
00052 }
00053
00054
00055 double inv_sum_of_prionums = 0.0;
00056 for (std::set<ConstraintBase_t>::iterator it = this->constraints_.begin(); it != this->constraints_.end(); ++it)
00057 {
00058 (*it)->update(joint_states, predict_jnts_vel, this->jacobian_data_);
00059 const double constr_prio = (*it)->getPriorityAsNum();
00060 if ((*it)->getState().getCurrent() == DANGER)
00061 {
00062 inv_sum_of_prionums += constr_prio > ZERO_THRESHOLD ? 1.0 / constr_prio : 1.0 / DIV0_SAFE;
00063 }
00064 }
00065
00066
00067 for (std::set<ConstraintBase_t>::iterator it = this->constraints_.begin(); it != this->constraints_.end(); ++it)
00068 {
00069 this->processState(it, projector, particular_solution, inv_sum_of_prionums, sum_of_gradient);
00070 }
00071
00072 sum_of_gradient = this->params_.k_H * sum_of_gradient;
00073
00074 if (CRITICAL == this->global_constraint_state_)
00075 {
00076 this->in_cart_vel_damping_ = START_CNT;
00077 }
00078 else
00079 {
00080 this->in_cart_vel_damping_ = this->in_cart_vel_damping_ > 1.0 ? (this->in_cart_vel_damping_ - 1.0) : 1.0;
00081 }
00082
00083 const Vector6d_t scaled_in_cart_velocities = (1.0 / pow(this->in_cart_vel_damping_, 2.0)) * in_cart_velocities;
00084 Task_t t(this->params_.priority_main, "Main task", this->jacobian_data_, scaled_in_cart_velocities);
00085 t.tcp_ = this->params_;
00086 this->task_stack_controller_.addTask(t);
00087
00088
00089 TaskSetIter_t it = this->task_stack_controller_.beginTaskIter();
00090 while ((it = this->task_stack_controller_.nextActiveTask()) != this->task_stack_controller_.getTasksEnd())
00091 {
00092 Eigen::MatrixXd J_task = it->task_jacobian_;
00093 Eigen::MatrixXd J_temp = J_task * projector_i;
00094 Eigen::VectorXd v_task = it->task_;
00095 Eigen::MatrixXd J_temp_inv = pinv_calc_.calculate(J_temp);
00096 q_i = q_i + J_temp_inv * (v_task - J_task * q_i);
00097 projector_i = projector_i - J_temp_inv * J_temp;
00098 }
00099
00100 qdots_out.col(0) = q_i + projector_i * sum_of_gradient;
00101 return qdots_out;
00102 }
00103
00104
00105 void StackOfTasksSolver::processState(std::set<ConstraintBase_t>::iterator& it,
00106 const Eigen::MatrixXd& projector,
00107 const Eigen::MatrixXd& particular_solution,
00108 double inv_sum_of_prios,
00109 Eigen::VectorXd& sum_of_gradient)
00110 {
00111 Eigen::VectorXd q_dot_0 = (*it)->getPartialValues();
00112 const double activation_gain = (*it)->getActivationGain();
00113 Eigen::MatrixXd tmp_projection = projector * q_dot_0;
00114 const double magnitude = (*it)->getSelfMotionMagnitude(particular_solution, tmp_projection);
00115 ConstraintState cstate = (*it)->getState();
00116
00117 const double constr_prio = (*it)->getPriorityAsNum();
00118 const double inv_constr_prio = constr_prio > ZERO_THRESHOLD ? 1.0 / constr_prio : 1.0 / DIV0_SAFE;
00119
00120 const double gpm_weighting = inv_constr_prio / inv_sum_of_prios;
00121
00122 if (cstate.isTransition())
00123 {
00124 if (cstate.getCurrent() == CRITICAL)
00125 {
00126
00127 Task_t t = (*it)->createTask();
00128 double factor = activation_gain * std::abs(magnitude);
00129 t.task_ = factor * t.task_;
00130 this->task_stack_controller_.addTask(t);
00131 this->task_stack_controller_.activateTask((*it)->getTaskId());
00132 }
00133 else if (cstate.getCurrent() == DANGER)
00134 {
00135 this->task_stack_controller_.deactivateTask((*it)->getTaskId());
00136 sum_of_gradient += gpm_weighting * activation_gain * magnitude * q_dot_0;
00137 }
00138 else
00139 {
00140 this->task_stack_controller_.deactivateTask((*it)->getTaskId());
00141 }
00142 }
00143 else
00144 {
00145 if (cstate.getCurrent() == CRITICAL)
00146 {
00147 Task_t t = (*it)->createTask();
00148 double factor = activation_gain * std::abs(magnitude);
00149 t.task_ = factor * t.task_;
00150 this->task_stack_controller_.addTask(t);
00151 }
00152 else if (cstate.getCurrent() == DANGER)
00153 {
00154 sum_of_gradient += gpm_weighting * activation_gain * magnitude * q_dot_0;
00155 }
00156 else
00157 {
00158
00159 }
00160 }
00161
00162 if (cstate.getCurrent() > this->global_constraint_state_ )
00163 {
00164 this->global_constraint_state_ = cstate.getCurrent();
00165 }
00166 }