/* SPDX-License-Identifier: LGPL-2.1-or-later * Copyright 2009 Ruben Smits. */ /** \file * \ingroup intern_itasc */ #include "WSDLSSolver.hpp" #include "kdl/utilities/svd_eigen_HH.hpp" #include namespace iTaSC { WSDLSSolver::WSDLSSolver() : m_ns(0), m_nc(0), m_nq(0) { // default maximum speed: 50 rad/s m_qmax = 50.0; } WSDLSSolver::~WSDLSSolver() { } bool WSDLSSolver::init(unsigned int _nq, unsigned int _nc, const std::vector& gc) { if (_nc == 0 || _nq == 0 || gc.size() != _nc) return false; m_nc = _nc; m_nq = _nq; m_ns = std::min(m_nc,m_nq); m_AWq = e_zero_matrix(m_nc,m_nq); m_WyAWq = e_zero_matrix(m_nc,m_nq); m_WyAWqt = e_zero_matrix(m_nq,m_nc); m_S = e_zero_vector(std::max(m_nc,m_nq)); m_Wy_ydot = e_zero_vector(m_nc); m_ytask = gc; if (m_nq > m_nc) { m_transpose = true; m_temp = e_zero_vector(m_nc); m_U = e_zero_matrix(m_nc,m_nc); m_V = e_zero_matrix(m_nq,m_nc); m_WqV = e_zero_matrix(m_nq,m_nc); } else { m_transpose = false; m_temp = e_zero_vector(m_nq); m_U = e_zero_matrix(m_nc,m_nq); m_V = e_zero_matrix(m_nq,m_nq); m_WqV = e_zero_matrix(m_nq,m_nq); } return true; } bool WSDLSSolver::solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef) { unsigned int i, j, l; e_scalar N, M; // Create the Weighted jacobian m_AWq.noalias() = A*Wq; for (i=0; i 0) { if ((prevS-S) > maxDeltaS) { maxDeltaS = (prevS-S); maxS = prevS; } } N = M = e_scalar(0.); for (l=0, prev=m_ytask[0], norm=e_scalar(0.); l _qmax) { damp = Sinv*alpha*_qmax/norm; } else { damp = Sinv*alpha; } qdot += m_WqV.col(i)*damp; prevS = S; } if (maxDeltaS == e_scalar(0.0)) nlcoef = e_scalar(KDL::epsilon); else nlcoef = (maxS-maxDeltaS)/maxS; return true; } }