Task ==== In OpenSoT, **tasks** are utilized to construct a cost function. Considering a specific *task*, denoted as :math:`\mathcal{T}_1`, it is defined by its corresponding matrices and vectors: .. math:: \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: .. math:: \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 :math:`\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 :math:`\mathbf{A}` as ``Eigen::MatrixXd _A``, along with the vectors :math:`\mathbf{b}` as ``Eigen::VectorXd _b`` and :math:`\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: .. math:: \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 :math:`\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 :math:`\mathbf{A}` matrix of the *Task* and set the desired columns to :math:`\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 :math:`\mathbf{A}` matrix is set to :math:`\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 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 `__: .. code-block:: cpp //Creates a task Eigen::MatrixXd A(2,2); A.Random(); Eigen::VectorXd b(2); b.Random(); auto t1 = std::make_shared("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 `__.