Qontrol
TaskSet.hpp
1 // This file is part of Qontrol, a quadratic optimization library to
2 // control robot.
3 //
4 // Copyright (C) 2023 Lucas Joseph <lucas.joseph@inria.fr>
5 //
6 // Qontrol is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 3 of
14 // the License, or (at your option) any later version.
15 //
16 // Qontrol is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Qontrol. If not, see <http://www.gnu.org/licenses/>.
24 
25 #pragma once
26 
27 #include <Qontrol/Model/GenericModel.hpp>
28 #include <Qontrol/Tasks/GenericTask.hpp>
29 #include <Qontrol/Problem/ControlOutput.hpp>
30 
31 #include <algorithm>
32 #include <memory>
33 #include <vector>
34 
35 namespace Qontrol {
36 namespace Task {
42 template <Qontrol::ControlOutput output> class TaskSet {
43 public:
44  TaskSet(std::shared_ptr<Model::GenericModel> model_library)
45  : model_ptr_{model_library} {
46  }
47 
56  std::shared_ptr<Task::GenericTask> add(std::string task_name, int task_dimension,
57  double task_weight = 1.0) {
58  if (!exist(task_name)) {
59  auto base_task_ptr = std::make_shared<Task::GenericTask>(
60  task_name, task_dimension, model_ptr_->getNrOfDegreesOfFreedom());
61  tasks_ptrs_.push_back(base_task_ptr);
62  tasks_names_.push_back(task_name);
63  tasks_weight_.push_back(task_weight);
64  return base_task_ptr;
65  } else {
66  throw std::logic_error("Task with name " + task_name + " already exist.");
67  }
68  }
69 
78  template <template <Qontrol::ControlOutput output2> class ControlInput>
79  std::shared_ptr<ControlInput<output>> add(std::string task_name,
80  double task_weight = 1.0) {
81  if (!exist(task_name)) {
82  auto task_ptr = std::shared_ptr<ControlInput<output>>(
83  new ControlInput<output>(task_name, model_ptr_));
84  // Implicit conversion to GenericTask when pushing
85  tasks_ptrs_.push_back(task_ptr);
86  tasks_names_.push_back(task_name);
87  tasks_weight_.push_back(task_weight);
88  return task_ptr;
89  } else {
90  throw std::logic_error("Task with name " + task_name + " already exist.");
91  }
92  }
93 
99  bool exist(std::string task_name) {
100  return (findTaskIterator(task_name) != tasks_names_.end());
101  }
102 
107  void getNames() {
108  for (auto task : tasks_ptrs_)
109  PLOGD << "Task name " << task->getName();
110  }
111 
116  void update(double dt) {
117  for (auto task : tasks_ptrs_) {
118  task->update(dt);
119  }
120  }
121 
127  std::vector<std::shared_ptr<Task::GenericTask>> getTasks() {
128  return tasks_ptrs_;
129  }
130 
136  std::vector<double> getTasksWeight() { return tasks_weight_; }
137 
138 
139 
146  int getTaskIndex(std::string task_name) {
147  if (exist(task_name)) {
148  auto itr = findTaskIterator(task_name);
149  return std::distance(tasks_names_.begin(), itr);
150  } else {
151  PLOGI << "Task " << task_name << " doesn't exist. Cannot get it's index.";
152  return -1;
153  }
154  }
155 
161  void remove(std::shared_ptr<Task::GenericTask> task_ptr) {
162  remove(task_ptr->getName());
163  }
164 
170  void remove(std::string task_name) {
171  if (exist(task_name)) {
172  auto index = getTaskIndex(task_name);
173  tasks_ptrs_.erase(tasks_ptrs_.begin() + index);
174  tasks_names_.erase(tasks_names_.begin() + index);
175  tasks_weight_.erase(tasks_weight_.begin() + index);
176  }
177  }
178 
185  bool setTaskWeight(std::shared_ptr<Task::GenericTask> task, double task_weight) {
186  return setTaskWeight(task->getName(), task_weight);
187  }
188 
195  bool setTaskWeight(std::string task_name, double task_weight) {
196  if (exist(task_name)) {
197  tasks_weight_.at(getTaskIndex(task_name)) = task_weight;
198  return true;
199  } else {
200  PLOGW << "Task " << task_name << " doesn't exist. Cannot set its weight";
201  return false;
202  }
203  }
204 
205 protected:
206  std::shared_ptr<Model::GenericModel> model_ptr_;
207  std::vector<std::string> tasks_names_;
208 
209 private:
216  std::vector<std::string>::iterator findTaskIterator(std::string task_name) {
217  return std::find(tasks_names_.begin(), tasks_names_.end(), task_name);
218  }
219 
220  std::vector<std::shared_ptr<Task::GenericTask>> tasks_ptrs_;
221  std::vector<double> tasks_weight_;
222 };
223 } // namespace Task
224 } // namespace Qontrol
Qontrol::Task::TaskSet::exist
bool exist(std::string task_name)
Check if a task exists in the task set.
Definition: TaskSet.hpp:99
Qontrol::Task::TaskSet::setTaskWeight
bool setTaskWeight(std::shared_ptr< Task::GenericTask > task, double task_weight)
Set a task weight relatively to all the tasks in the task set.
Definition: TaskSet.hpp:185
Qontrol::Task::TaskSet::setTaskWeight
bool setTaskWeight(std::string task_name, double task_weight)
Set a task weight relatively to all the tasks in the task set.
Definition: TaskSet.hpp:195
Qontrol::Task::TaskSet::getTaskIndex
int getTaskIndex(std::string task_name)
Get the index of a task in the task set.
Definition: TaskSet.hpp:146
Qontrol::Task::TaskSet::getTasksWeight
std::vector< double > getTasksWeight()
Get the relative weight of all the tasks in the task set ordered in their declaration order.
Definition: TaskSet.hpp:136
Qontrol::Task::TaskSet::getTasks
std::vector< std::shared_ptr< Task::GenericTask > > getTasks()
Get all the tasks.
Definition: TaskSet.hpp:127
Qontrol::Task::TaskSet::remove
void remove(std::string task_name)
Remove a task from the task set.
Definition: TaskSet.hpp:170
Qontrol::Task::TaskSet::add
std::shared_ptr< Task::GenericTask > add(std::string task_name, int task_dimension, double task_weight=1.0)
Add a custom task to the task set.
Definition: TaskSet.hpp:56
Qontrol::Task::TaskSet
Handle all the tasks added to the problem.
Definition: TaskSet.hpp:42
Qontrol::Task::TaskSet::update
void update(double dt)
Call the update function of all the tasks in the task set.
Definition: TaskSet.hpp:116
Qontrol::Task::TaskSet::getNames
void getNames()
Get the names of all the tasks ordered in their declaration order.
Definition: TaskSet.hpp:107
Qontrol::Task::TaskSet::remove
void remove(std::shared_ptr< Task::GenericTask > task_ptr)
Remove a task from the task set.
Definition: TaskSet.hpp:161
Qontrol::Task::TaskSet::add
std::shared_ptr< ControlInput< output > > add(std::string task_name, double task_weight=1.0)
Add an implemented task in the task set.
Definition: TaskSet.hpp:79