Task

In OpenSoT, tasks are utilized to construct a cost function. Considering a specific task, denoted as \(\mathcal{T}_1\), it is defined by its corresponding matrices and vectors:

\[\mathcal{T}_1 = \left\{ \mathbf{A}_1 \in \mathbb{R}^{m \times n}, \mathbf{W}_1 \in \mathbb{R}^{m \times m}, \mathbf{b}_1 \in \mathbb{R}^{m}, \mathbf{c}_1 \in \mathbb{R}^{n} \right\},\]

which defines the scalar cost function:

\[\begin{align} \mathcal{F}_1 & = \lVert \mathbf{A}_1\mathbf{x} - \mathbf{b}_1 \rVert_{\mathbf{W}_1} + \mathbf{c}_1^T\mathbf{x} = \newline & = \left( \mathbf{A}_1\mathbf{x} - \mathbf{b}_1 \right)^T\mathbf{W}_1\left( \mathbf{A}_1\mathbf{x} - \mathbf{b}_1 \right) + \mathbf{c}_1^T\mathbf{x} = \newline & = \mathbf{x}^T\mathbf{A}_1^T\mathbf{W}_1\mathbf{A}_1\mathbf{x} -2\mathbf{b}_1^T\mathbf{W}_1\mathbf{A}_1\mathbf{x} + \mathbf{c}_1^T\mathbf{x}. \end{align}\]

Note

Most of the time, the \(\mathbf{c}\) term is used to implement the Lasso or an L-1 norm; thus, it is typically not utilized.

A Task object is inherited from the base class OpenSoT::Task in Task.h, where the method _update(const Vector_type &x) must be implemented to assign the matrix \(\mathbf{A}\) as Eigen::MatrixXd _A, along with the vectors \(\mathbf{b}\) as Eigen::VectorXd _b and \(\mathbf{c}\) as Eigen::VectorXd _c. This assignment will take place every time the update(const Vector_type &x) method is invoked.

The Hessian Type can be set according to the type of Hessian generated by the task as:

\[\mathbf{H} = \mathbf{A}^T\mathbf{W}\mathbf{A}.\]

Note

The information provided by the Hessian Type is used only by some back-end solvers, in particular qpOASES, therefore not mandatory.

If the weight matrix \(\mathbf{W}\) is diagonal, is possible to accelerate the computation of the Hessian, setting the _weight_is_diagonal flag to true by utilizing the setWeightIsDiagonalFlag(const bool flag) method.

You can use the applyActiveJointsMask(Matrix_type& A) function to apply a mask to the \(\mathbf{A}\) matrix of the Task and set the desired columns to \(\mathbf{0}\).

If a reset procedure for a Task is permitted, it must be implemented using the virtual reset() method.

You can activate or deactivate a Task using the setActive(const bool active_flag) method.

Note

When a Task is not active, its \(\mathbf{A}\) matrix is set to \(\mathbf{0}\).

Upon invoking the log(XBot::MatLogger2::Ptr logger) method, the internal matrices _A and _W, as well as the vectors _b and _c, are stored in the file specified within the log. To record additional data, you must implement the virtual method _log(XBot::MatLogger2::Ptr logger).

SubTask

A SubTask comprises a specific number of rows from a Task. The SubTask class facilitates the selection of adjacent and non-adjacent rows from a task by extracting sub-matrices from _A and _W, along with a sub-vector from _b.

Note

SubTasks do not make use of the _c vector!

A SubTask can be instantiated from a Task using the SubTask(TaskPtr taskPtr, const std::list<unsigned int> rowIndices) constructor found in SubTask.h.

Note

A SubTask holds a reference to the Task that was used to instantiate it. As a result, any modifications applied to the primary Task are reflected in the SubTask, and vice versa. When the update(const Vector_type &x) method is invoked on the SubTask, the referenced Task is also updated.

A common application of a SubTask is to focus on a specific portion of a task. For instance, in a Cartesian Task, a SubTask can be employed to isolate the positional component while disregarding the orientation.

GenericTask

A task can be created also from bare Eigen::MatrixXd and Eigen::VectorXd using the GenericTask class in GenericTask.h:

//Creates a task
Eigen::MatrixXd A(2,2); A.Random();
Eigen::VectorXd b(2); b.Random();
auto t1 = std::make_shared<OpenSoT::tasks::GenericTask>("task1", A, b);

Various set methods can be used to update the internal matrices and vectors. A linear task can be created through the GenericLPTask in GenericLPTask.h.