Qontrol
TaskSet.hpp
1 
2 // This file is part of Qontrol, a quadratic optimization library to
3 // control robot.
4 //
5 // Copyright (C) 2023 Lucas Joseph <lucas.joseph@inria.fr>
6 //
7 // Qontrol is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 3 of
15 // the License, or (at your option) any later version.
16 //
17 // Qontrol is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Qontrol. If not, see <http://www.gnu.org/licenses/>.
25 
26 #pragma once
27 
28 #include <Qontrol/Model/GenericModel.hpp>
29 #include <Qontrol/Tasks/GenericTask.hpp>
30 #include <Qontrol/Problem/ControlOutput.hpp>
31 
32 #include <algorithm>
33 #include <memory>
34 #include <vector>
35 
36 namespace Qontrol {
37 namespace Task {
43 template <Qontrol::ControlOutput output> class TaskSet {
44 public:
45  TaskSet(std::shared_ptr<Model::GenericModel> model_library)
46  : model_ptr_{model_library} {
47  }
48 
57  std::shared_ptr<Task::GenericTask> add(std::string task_name, int task_dimension,
58  double task_weight = 1.0) {
59  if (!exist(task_name)) {
60  auto base_task_ptr = std::make_shared<Task::GenericTask>(
61  task_name, task_dimension, model_ptr_->getNrOfDegreesOfFreedom());
62  tasks_ptrs_.push_back(base_task_ptr);
63  tasks_names_.push_back(task_name);
64  tasks_weight_.push_back(task_weight);
65  return base_task_ptr;
66  } else {
67  throw std::logic_error("Task with name " + task_name + " already exist.");
68  }
69  }
70 
71  std::shared_ptr<Task::GenericTask> add(std::string task_name, int task_dimension,
72  int optim_vector_dimension,double task_weight = 1.0) {
73  if (!exist(task_name)) {
74  auto base_task_ptr = std::make_shared<Task::GenericTask>(
75  task_name, task_dimension, optim_vector_dimension);
76  tasks_ptrs_.push_back(base_task_ptr);
77  tasks_names_.push_back(task_name);
78  tasks_weight_.push_back(task_weight);
79  return base_task_ptr;
80  } else {
81  throw std::logic_error("Task with name " + task_name + " already exist.");
82  }
83  }
84 
93  template <template <Qontrol::ControlOutput output2> class ControlInput>
94  std::shared_ptr<ControlInput<output>> add(std::string task_name,
95  double task_weight = 1.0) {
96  if (!exist(task_name)) {
97  auto task_ptr = std::shared_ptr<ControlInput<output>>(
98  new ControlInput<output>(task_name, model_ptr_));
99  // Implicit conversion to GenericTask when pushing
100  tasks_ptrs_.push_back(task_ptr);
101  tasks_names_.push_back(task_name);
102  tasks_weight_.push_back(task_weight);
103  return task_ptr;
104  } else {
105  throw std::logic_error("Task with name " + task_name + " already exist.");
106  }
107  }
108 
114  bool exist(std::string task_name) {
115  return (findTaskIterator(task_name) != tasks_names_.end());
116  }
117 
122  void getNames() {
123  for (auto task : tasks_ptrs_)
124  PLOGD << "Task name " << task->getName();
125  }
126 
131  void update(double dt) {
132  for (auto task : tasks_ptrs_) {
133  task->update(dt);
134  }
135  }
136 
142  std::vector<std::shared_ptr<Task::GenericTask>> getTasks() {
143  return tasks_ptrs_;
144  }
145 
151  std::vector<double> getTasksWeight() { return tasks_weight_; }
152 
153 
154 
161  int getTaskIndex(std::string task_name) {
162  if (exist(task_name)) {
163  auto itr = findTaskIterator(task_name);
164  return std::distance(tasks_names_.begin(), itr);
165  } else {
166  PLOGI << "Task " << task_name << " doesn't exist. Cannot get it's index.";
167  return -1;
168  }
169  }
170 
176  void remove(std::shared_ptr<Task::GenericTask> task_ptr) {
177  remove(task_ptr->getName());
178  }
179 
185  void remove(std::string task_name) {
186  if (exist(task_name)) {
187  auto index = getTaskIndex(task_name);
188  tasks_ptrs_.erase(tasks_ptrs_.begin() + index);
189  tasks_names_.erase(tasks_names_.begin() + index);
190  tasks_weight_.erase(tasks_weight_.begin() + index);
191  }
192  }
193 
200  bool setTaskWeight(std::shared_ptr<Task::GenericTask> task, double task_weight) {
201  return setTaskWeight(task->getName(), task_weight);
202  }
203 
210  bool setTaskWeight(std::string task_name, double task_weight) {
211  if (exist(task_name)) {
212  tasks_weight_.at(getTaskIndex(task_name)) = task_weight;
213  return true;
214  } else {
215  PLOGW << "Task " << task_name << " doesn't exist. Cannot set its weight";
216  return false;
217  }
218  }
219 
220 protected:
221  std::shared_ptr<Model::GenericModel> model_ptr_;
222  std::vector<std::string> tasks_names_;
223 
224 private:
231  std::vector<std::string>::iterator findTaskIterator(std::string task_name) {
232  return std::find(tasks_names_.begin(), tasks_names_.end(), task_name);
233  }
234 
235  std::vector<std::shared_ptr<Task::GenericTask>> tasks_ptrs_;
236  std::vector<double> tasks_weight_;
237 };
238 } // namespace Task
239 } // namespace Qontrol
Qontrol::Task::TaskSet::exist
bool exist(std::string task_name)
Check if a task exists in the task set.
Definition: TaskSet.hpp:114
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:200
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:210
Qontrol::Task::TaskSet::getTaskIndex
int getTaskIndex(std::string task_name)
Get the index of a task in the task set.
Definition: TaskSet.hpp:161
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:151
Qontrol::Task::TaskSet::getTasks
std::vector< std::shared_ptr< Task::GenericTask > > getTasks()
Get all the tasks.
Definition: TaskSet.hpp:142
Qontrol::Task::TaskSet::remove
void remove(std::string task_name)
Remove a task from the task set.
Definition: TaskSet.hpp:185
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:57
Qontrol::Task::TaskSet
Handle all the tasks added to the problem.
Definition: TaskSet.hpp:43
Qontrol::Task::TaskSet::update
void update(double dt)
Call the update function of all the tasks in the task set.
Definition: TaskSet.hpp:131
Qontrol::Task::TaskSet::getNames
void getNames()
Get the names of all the tasks ordered in their declaration order.
Definition: TaskSet.hpp:122
Qontrol::Task::TaskSet::remove
void remove(std::shared_ptr< Task::GenericTask > task_ptr)
Remove a task from the task set.
Definition: TaskSet.hpp:176
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:94