stack_of_tasks_solver.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
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     // predict next joint states!
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     // First iteration: update constraint state and calculate the according GPM weighting (DANGER state)
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     // Second iteration: Process constraints with sum of prios for active GPM constraints!
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;  // "global" weighting for all constraints.
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     // ROS_INFO_STREAM("============== Task output ============= with main task damping: " << this->in_cart_vel_damping_);
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);  //ToDo: Do we need damping here?
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     // only necessary for GPM sum because task stack is already sorted according to PRIOs.
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             // "global" weighting k_H for all constraint tasks.
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;  // smm adapted q_dot_0 vector
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);  // task must be decided whether negative or not!
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;  // smm adapted q_dot_0 vector
00155         }
00156         else
00157         {
00158             // just compute the particular solution
00159         }
00160     }
00161 
00162     if (cstate.getCurrent() > this->global_constraint_state_ )
00163     {
00164         this->global_constraint_state_ = cstate.getCurrent();
00165     }
00166 }


cob_twist_controller
Author(s): Felix Messmer , Marco Bezzon , Christoph Mark , Francisco Moreno
autogenerated on Thu Jun 6 2019 21:19:26