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 #ifndef COB_TWIST_CONTROLLER_TASK_STACK_TASK_STACK_CONTROLLER_H
00019 #define COB_TWIST_CONTROLLER_TASK_STACK_TASK_STACK_CONTROLLER_H
00020
00021 #include <vector>
00022 #include <string>
00023 #include <stdint.h>
00024 #include <ros/ros.h>
00025
00026 #include <boost/shared_ptr.hpp>
00027 #include <Eigen/Dense>
00028
00029 #include "cob_twist_controller/cob_twist_controller_data_types.h"
00030 #include "cob_twist_controller/damping_methods/damping_base.h"
00031
00032 template
00033 <typename PRIO>
00034 struct Task
00035 {
00036 PRIO prio_;
00037 Eigen::MatrixXd task_jacobian_;
00038 Eigen::VectorXd task_;
00039 std::string id_;
00040 bool is_active_;
00041 TwistControllerParams tcp_;
00042
00043 Task(PRIO prio, std::string id) : prio_(prio), id_(id), is_active_(true)
00044 {}
00045
00046 Task(PRIO prio, std::string id, Eigen::MatrixXd task_jacobian, Eigen::VectorXd task)
00047 : prio_(prio), id_(id), task_jacobian_(task_jacobian), task_(task), is_active_(true)
00048 {}
00049
00050 Task(const Task& task)
00051 : prio_(task.prio_),
00052 id_(task.id_),
00053 task_jacobian_(task.task_jacobian_),
00054 task_(task.task_),
00055 is_active_(task.is_active_),
00056 tcp_(task.tcp_)
00057 {}
00058
00059 ~Task()
00060 {}
00061
00062 inline void setPriority(PRIO prio)
00063 {
00064 this->prio_ = prio;
00065 }
00066
00067 inline bool operator<(const Task& other) const
00068 {
00069 return ( this->prio_ < other.prio_ );
00070 }
00071
00072 inline bool operator>(const Task& other) const
00073 {
00074 return ( this->prio_ > other.prio_ );
00075 }
00076
00077 inline bool operator==(const Task& other) const
00078 {
00079 return ( this->prio_ == other.prio_ );
00080 }
00081 };
00082
00083 template
00084 <typename PRIO>
00085 class TaskStackController
00086 {
00087 public:
00088 typedef typename std::vector<Task<PRIO> >::iterator TypedIter_t;
00089 typedef typename std::vector<Task<PRIO> >::const_iterator TypedConstIter_t;
00090
00091 ~TaskStackController()
00092 {
00093 this->tasks_.clear();
00094 }
00095
00096 TaskStackController()
00097 {
00098 this->active_task_iter_ = this->tasks_.begin();
00099 this->modification_time_ = ros::Time(0);
00100 }
00101
00102 void clearAllTasks();
00103
00104 void addTask(Task<PRIO> t);
00105
00106 void deactivateTask(typename std::vector<Task<PRIO> >::iterator it);
00107 void deactivateTask(std::string task_id);
00108 void activateTask(std::string task_id);
00109 void deactivateAllTasks();
00110
00111 void activateAllTasks();
00112 void activateHighestPrioTask();
00113
00114 typename std::vector<Task<PRIO> >::iterator getTasksBegin();
00115 typename std::vector<Task<PRIO> >::iterator getTasksEnd();
00116 typename std::vector<Task<PRIO> >::iterator nextActiveTask();
00117 typename std::vector<Task<PRIO> >::iterator beginTaskIter();
00118
00119 int countActiveTasks() const;
00120 ros::Time getLastModificationTime() const;
00121
00122 private:
00123 void updateModificationTime(bool change);
00124
00125 std::vector<Task<PRIO> > tasks_;
00126 TypedIter_t active_task_iter_;
00127 ros::Time modification_time_;
00128 };
00129
00130 template <typename PRIO>
00131 int TaskStackController<PRIO>::countActiveTasks() const
00132 {
00133 int i = 0;
00134 for (TypedConstIter_t it = this->tasks_.begin(); it != this->tasks_.end(); it++)
00135 {
00136 if (it->is_active_)
00137 {
00138 ++i;
00139 }
00140 }
00141
00142 return i;
00143 }
00144
00148 template <typename PRIO>
00149 void TaskStackController<PRIO>::addTask(Task<PRIO> t)
00150 {
00151 TypedIter_t begin_it = this->tasks_.begin();
00152 TypedIter_t mem_it = this->tasks_.end();
00153 for (TypedIter_t it = this->tasks_.begin(); it != this->tasks_.end(); it++)
00154 {
00155 if (it->id_ == t.id_)
00156 {
00157 mem_it = it;
00158 it->task_jacobian_ = t.task_jacobian_;
00159 it->task_ = t.task_;
00160 it->tcp_ = t.tcp_;
00161 break;
00162 }
00163 }
00164
00165 if (this->tasks_.end() == mem_it)
00166 {
00167 for (TypedIter_t it = this->tasks_.begin(); it != this->tasks_.end(); it++)
00168 {
00169 if (t.prio_ < it->prio_)
00170 {
00171 mem_it = it;
00172 break;
00173 }
00174 }
00175
00176 if (this->tasks_.end() == mem_it)
00177 {
00178 this->tasks_.push_back(t);
00179 }
00180 else
00181 {
00182 this->tasks_.insert(mem_it, t);
00183 }
00184
00185 this->updateModificationTime(true);
00186 }
00187 }
00188
00189 template <typename PRIO>
00190 void TaskStackController<PRIO>::activateAllTasks()
00191 {
00192 bool change = false;
00193 for (TypedIter_t it = this->tasks_.begin(); it != this->tasks_.end(); it++)
00194 {
00195 if (!it->is_active_)
00196 {
00197 change = true;
00198 }
00199
00200 it->is_active_ = true;
00201 }
00202
00203 this->updateModificationTime(change);
00204 }
00205
00206 template <typename PRIO>
00207 void TaskStackController<PRIO>::activateHighestPrioTask()
00208 {
00209 TypedIter_t it = this->tasks_.begin();
00210 if (this->tasks_.end() != it)
00211 {
00212 this->updateModificationTime(!it->is_active_);
00213
00214 ROS_WARN_STREAM("Activation of highest prio task in stack: " << it->id_);
00215 it->is_active_ = true;
00216 }
00217 }
00218
00219 template <typename PRIO>
00220 typename std::vector<Task<PRIO> >::iterator TaskStackController<PRIO>::getTasksBegin()
00221 {
00222 return this->tasks_.begin();
00223 }
00224
00225 template <typename PRIO>
00226 typename std::vector<Task<PRIO> >::iterator TaskStackController<PRIO>::getTasksEnd()
00227 {
00228 return this->tasks_.end();
00229 }
00230
00231 template <typename PRIO>
00232 void TaskStackController<PRIO>::activateTask(std::string task_id)
00233 {
00234 for (TypedIter_t it = this->tasks_.begin(); it != this->tasks_.end(); it++)
00235 {
00236 if (it->id_ == task_id)
00237 {
00238 this->updateModificationTime(!it->is_active_);
00239 it->is_active_ = true;
00240 break;
00241 }
00242 }
00243 }
00244
00245 template <typename PRIO>
00246 void TaskStackController<PRIO>::deactivateTask(typename std::vector<Task<PRIO> >::iterator it)
00247 {
00248 if (std::find(this->tasks_.begin(), this->tasks_.end(), it) != this->tasks_.end())
00249 {
00250 this->updateModificationTime(it->is_active_);
00251 it->is_active_ = false;
00252 }
00253 }
00254
00255 template <typename PRIO>
00256 void TaskStackController<PRIO>::deactivateTask(std::string task_id)
00257 {
00258 for (TypedIter_t it = this->tasks_.begin(); it != this->tasks_.end(); it++)
00259 {
00260 if (it->id_ == task_id)
00261 {
00262 this->updateModificationTime(it->is_active_);
00263 it->is_active_ = false;
00264 break;
00265 }
00266 }
00267 }
00268
00269 template <typename PRIO>
00270 void TaskStackController<PRIO>::deactivateAllTasks()
00271 {
00272 bool change = false;
00273 for (TypedIter_t it = this->tasks_.begin(); it != this->tasks_.end(); it++)
00274 {
00275 if (it->is_active_)
00276 {
00277 change = true;
00278 }
00279
00280 it->is_active_ = false;
00281 }
00282
00283 this->updateModificationTime(change);
00284 }
00285
00286 template <typename PRIO>
00287 typename std::vector<Task<PRIO> >::iterator TaskStackController<PRIO>::nextActiveTask()
00288 {
00289 TypedIter_t ret = this->tasks_.end();
00290
00291 while (this->tasks_.end() != this->active_task_iter_)
00292 {
00293 if (this->active_task_iter_->is_active_)
00294 {
00295 ret = this->active_task_iter_++;
00296 break;
00297 }
00298
00299 this->active_task_iter_++;
00300 }
00301
00302 return ret;
00303 }
00304
00305 template <typename PRIO>
00306 typename std::vector<Task<PRIO> >::iterator TaskStackController<PRIO>::beginTaskIter()
00307 {
00308 this->active_task_iter_ = this->tasks_.begin();
00309 return this->active_task_iter_;
00310 }
00311
00312 template <typename PRIO>
00313 void TaskStackController<PRIO>::clearAllTasks()
00314 {
00315 this->tasks_.clear();
00316 this->active_task_iter_ = this->tasks_.end();
00317 this->updateModificationTime(true);
00318 }
00319
00320 template <typename PRIO>
00321 ros::Time TaskStackController<PRIO>::getLastModificationTime() const
00322 {
00323 return this->modification_time_;
00324 }
00325
00326 template <typename PRIO>
00327 void TaskStackController<PRIO>::updateModificationTime(bool change)
00328 {
00329 if (change)
00330 {
00331 this->modification_time_ = ros::Time::now();
00332 }
00333 }
00334
00335
00336 typedef TaskStackController<uint32_t> TaskStackController_t;
00337 typedef Task<uint32_t> Task_t;
00338 typedef std::vector<Task_t >::iterator TaskSetIter_t;
00339
00340 #endif // COB_TWIST_CONTROLLER_TASK_STACK_TASK_STACK_CONTROLLER_H