Blender  V2.59
IK_QJacobian.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: IK_QJacobian.cpp 38232 2011-07-08 12:18:54Z blendix $
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Original Author: Laurence
00025  * Contributor(s): Brecht
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00035 #include "IK_QJacobian.h"
00036 #include "TNT/svd.h"
00037 
00038 IK_QJacobian::IK_QJacobian()
00039 : m_sdls(true), m_min_damp(1.0)
00040 {
00041 }
00042 
00043 IK_QJacobian::~IK_QJacobian()
00044 {
00045 }
00046 
00047 void IK_QJacobian::ArmMatrices(int dof, int task_size)
00048 {
00049         m_dof = dof;
00050         m_task_size = task_size;
00051 
00052         m_jacobian.newsize(task_size, dof);
00053         m_jacobian = 0;
00054 
00055         m_alpha.newsize(dof);
00056         m_alpha = 0;
00057 
00058         m_null.newsize(dof, dof);
00059 
00060         m_d_theta.newsize(dof);
00061         m_d_theta_tmp.newsize(dof);
00062         m_d_norm_weight.newsize(dof);
00063 
00064         m_norm.newsize(dof);
00065         m_norm = 0.0;
00066 
00067         m_beta.newsize(task_size);
00068 
00069         m_weight.newsize(dof);
00070         m_weight_sqrt.newsize(dof);
00071         m_weight = 1.0;
00072         m_weight_sqrt = 1.0;
00073 
00074         if (task_size >= dof) {
00075                 m_transpose = false;
00076 
00077                 m_jacobian_tmp.newsize(task_size, dof);
00078 
00079                 m_svd_u.newsize(task_size, dof);
00080                 m_svd_v.newsize(dof, dof);
00081                 m_svd_w.newsize(dof);
00082 
00083                 m_work1.newsize(task_size);
00084                 m_work2.newsize(dof);
00085 
00086                 m_svd_u_t.newsize(dof, task_size);
00087                 m_svd_u_beta.newsize(dof);
00088         }
00089         else {
00090                 // use the SVD of the transpose jacobian, it works just as well
00091                 // as the original, and often allows using smaller matrices.
00092                 m_transpose = true;
00093 
00094                 m_jacobian_tmp.newsize(dof, task_size);
00095 
00096                 m_svd_u.newsize(task_size, task_size);
00097                 m_svd_v.newsize(dof, task_size);
00098                 m_svd_w.newsize(task_size);
00099 
00100                 m_work1.newsize(dof);
00101                 m_work2.newsize(task_size);
00102 
00103                 m_svd_u_t.newsize(task_size, task_size);
00104                 m_svd_u_beta.newsize(task_size);
00105         }
00106 }
00107 
00108 void IK_QJacobian::SetBetas(int id, int, const MT_Vector3& v)
00109 {
00110         m_beta[id] = v.x();
00111         m_beta[id+1] = v.y();
00112         m_beta[id+2] = v.z();
00113 }
00114 
00115 void IK_QJacobian::SetDerivatives(int id, int dof_id, const MT_Vector3& v, MT_Scalar norm_weight)
00116 {
00117         m_jacobian[id][dof_id] = v.x()*m_weight_sqrt[dof_id];
00118         m_jacobian[id+1][dof_id] = v.y()*m_weight_sqrt[dof_id];
00119         m_jacobian[id+2][dof_id] = v.z()*m_weight_sqrt[dof_id];
00120 
00121         m_d_norm_weight[dof_id] = norm_weight;
00122 }
00123 
00124 void IK_QJacobian::Invert()
00125 {
00126         if (m_transpose) {
00127                 // SVD will decompose Jt into V*W*Ut with U,V orthogonal and W diagonal,
00128                 // so J = U*W*Vt and Jinv = V*Winv*Ut
00129                 TNT::transpose(m_jacobian, m_jacobian_tmp);
00130                 TNT::SVD(m_jacobian_tmp, m_svd_v, m_svd_w, m_svd_u, m_work1, m_work2);
00131         }
00132         else {
00133                 // SVD will decompose J into U*W*Vt with U,V orthogonal and W diagonal,
00134                 // so Jinv = V*Winv*Ut
00135                 m_jacobian_tmp = m_jacobian;
00136                 TNT::SVD(m_jacobian_tmp, m_svd_u, m_svd_w, m_svd_v, m_work1, m_work2);
00137         }
00138 
00139         if (m_sdls)
00140                 InvertSDLS();
00141         else
00142                 InvertDLS();
00143 }
00144 
00145 bool IK_QJacobian::ComputeNullProjection()
00146 {
00147         MT_Scalar epsilon = 1e-10;
00148         
00149         // compute null space projection based on V
00150         int i, j, rank = 0;
00151         for (i = 0; i < m_svd_w.size(); i++)
00152                 if (m_svd_w[i] > epsilon)
00153                         rank++;
00154 
00155         if (rank < m_task_size)
00156                 return false;
00157 
00158         TMatrix basis(m_svd_v.num_rows(), rank);
00159         TMatrix basis_t(rank, m_svd_v.num_rows());
00160         int b = 0;
00161 
00162         for (i = 0; i < m_svd_w.size(); i++)
00163                 if (m_svd_w[i] > epsilon) {
00164                         for (j = 0; j < m_svd_v.num_rows(); j++)
00165                                 basis[j][b] = m_svd_v[j][i];
00166                         b++;
00167                 }
00168         
00169         TNT::transpose(basis, basis_t);
00170         TNT::matmult(m_null, basis, basis_t);
00171 
00172         for (i = 0; i < m_null.num_rows(); i++)
00173                 for (j = 0; j < m_null.num_cols(); j++)
00174                         if (i == j)
00175                                 m_null[i][j] = 1.0 - m_null[i][j];
00176                         else
00177                                 m_null[i][j] = -m_null[i][j];
00178         
00179         return true;
00180 }
00181 
00182 void IK_QJacobian::SubTask(IK_QJacobian& jacobian)
00183 {
00184         if (!ComputeNullProjection())
00185                 return;
00186 
00187         // restrict lower priority jacobian
00188         jacobian.Restrict(m_d_theta, m_null);
00189 
00190         // add angle update from lower priority
00191         jacobian.Invert();
00192 
00193         // note: now damps secondary angles with minimum damping value from
00194         // SDLS, to avoid shaking when the primary task is near singularities,
00195         // doesn't work well at all
00196         int i;
00197         for (i = 0; i < m_d_theta.size(); i++)
00198                 m_d_theta[i] = m_d_theta[i] + /*m_min_damp**/jacobian.AngleUpdate(i);
00199 }
00200 
00201 void IK_QJacobian::Restrict(TVector& d_theta, TMatrix& null)
00202 {
00203         // subtract part already moved by higher task from beta
00204         TVector beta_sub(m_beta.size());
00205 
00206         TNT::matmult(beta_sub, m_jacobian, d_theta);
00207         m_beta = m_beta - beta_sub;
00208 
00209         // note: should we be using the norm of the unrestricted jacobian for SDLS?
00210         
00211         // project jacobian on to null space of higher priority task
00212         TMatrix jacobian_copy(m_jacobian);
00213         TNT::matmult(m_jacobian, jacobian_copy, null);
00214 }
00215 
00216 void IK_QJacobian::InvertSDLS()
00217 {
00218         // Compute the dampeds least squeares pseudo inverse of J.
00219         //
00220         // Since J is usually not invertible (most of the times it's not even
00221         // square), the psuedo inverse is used. This gives us a least squares
00222         // solution.
00223         //
00224         // This is fine when the J*Jt is of full rank. When J*Jt is near to
00225         // singular the least squares inverse tries to minimize |J(dtheta) - dX)|
00226         // and doesn't try to minimize  dTheta. This results in eratic changes in
00227         // angle. The damped least squares minimizes |dtheta| to try and reduce this
00228         // erratic behaviour.
00229         //
00230         // The selectively damped least squares (SDLS) is used here instead of the
00231         // DLS. The SDLS damps individual singular values, instead of using a single
00232         // damping term.
00233 
00234         MT_Scalar max_angle_change = MT_PI/4.0;
00235         MT_Scalar epsilon = 1e-10;
00236         int i, j;
00237 
00238         m_d_theta = 0;
00239         m_min_damp = 1.0;
00240 
00241         for (i = 0; i < m_dof; i++) {
00242                 m_norm[i] = 0.0;
00243                 for (j = 0; j < m_task_size; j+=3) {
00244                         MT_Scalar n = 0.0;
00245                         n += m_jacobian[j][i]*m_jacobian[j][i];
00246                         n += m_jacobian[j+1][i]*m_jacobian[j+1][i];
00247                         n += m_jacobian[j+2][i]*m_jacobian[j+2][i];
00248                         m_norm[i] += sqrt(n);
00249                 }
00250         }
00251 
00252         for (i = 0; i<m_svd_w.size(); i++) {
00253                 if (m_svd_w[i] <= epsilon)
00254                         continue;
00255 
00256                 MT_Scalar wInv = 1.0/m_svd_w[i];
00257                 MT_Scalar alpha = 0.0;
00258                 MT_Scalar N = 0.0;
00259 
00260                 // compute alpha and N
00261                 for (j=0; j<m_svd_u.num_rows(); j+=3) {
00262                         alpha += m_svd_u[j][i]*m_beta[j];
00263                         alpha += m_svd_u[j+1][i]*m_beta[j+1];
00264                         alpha += m_svd_u[j+2][i]*m_beta[j+2];
00265 
00266                         // note: for 1 end effector, N will always be 1, since U is
00267                         // orthogonal, .. so could be optimized
00268                         MT_Scalar tmp;
00269                         tmp = m_svd_u[j][i]*m_svd_u[j][i];
00270                         tmp += m_svd_u[j+1][i]*m_svd_u[j+1][i];
00271                         tmp += m_svd_u[j+2][i]*m_svd_u[j+2][i];
00272                         N += sqrt(tmp);
00273                 }
00274                 alpha *= wInv;
00275 
00276                 // compute M, dTheta and max_dtheta
00277                 MT_Scalar M = 0.0;
00278                 MT_Scalar max_dtheta = 0.0, abs_dtheta;
00279 
00280                 for (j = 0; j < m_d_theta.size(); j++) {
00281                         MT_Scalar v = m_svd_v[j][i];
00282                         M += MT_abs(v)*m_norm[j];
00283 
00284                         // compute tmporary dTheta's
00285                         m_d_theta_tmp[j] = v*alpha;
00286 
00287                         // find largest absolute dTheta
00288                         // multiply with weight to prevent unnecessary damping
00289                         abs_dtheta = MT_abs(m_d_theta_tmp[j])*m_weight_sqrt[j];
00290                         if (abs_dtheta > max_dtheta)
00291                                 max_dtheta = abs_dtheta;
00292                 }
00293 
00294                 M *= wInv;
00295 
00296                 // compute damping term and damp the dTheta's
00297                 MT_Scalar gamma = max_angle_change;
00298                 if (N < M)
00299                         gamma *= N/M;
00300 
00301                 MT_Scalar damp = (gamma < max_dtheta)? gamma/max_dtheta: 1.0;
00302 
00303                 for (j = 0; j < m_d_theta.size(); j++) {
00304                         // slight hack: we do 0.80*, so that if there is some oscillation,
00305                         // the system can still converge (for joint limits). also, it's
00306                         // better to go a little to slow than to far
00307                         
00308                         MT_Scalar dofdamp = damp/m_weight[j];
00309                         if (dofdamp > 1.0) dofdamp = 1.0;
00310                         
00311                         m_d_theta[j] += 0.80*dofdamp*m_d_theta_tmp[j];
00312                 }
00313 
00314                 if (damp < m_min_damp)
00315                         m_min_damp = damp;
00316         }
00317 
00318         // weight + prevent from doing angle updates with angles > max_angle_change
00319         MT_Scalar max_angle = 0.0, abs_angle;
00320 
00321         for (j = 0; j<m_dof; j++) {
00322                 m_d_theta[j] *= m_weight[j];
00323 
00324                 abs_angle = MT_abs(m_d_theta[j]);
00325 
00326                 if (abs_angle > max_angle)
00327                         max_angle = abs_angle;
00328         }
00329         
00330         if (max_angle > max_angle_change) {
00331                 MT_Scalar damp = (max_angle_change)/(max_angle_change + max_angle);
00332 
00333                 for (j = 0; j<m_dof; j++)
00334                         m_d_theta[j] *= damp;
00335         }
00336 }
00337 
00338 void IK_QJacobian::InvertDLS()
00339 {
00340         // Compute damped least squares inverse of pseudo inverse
00341         // Compute damping term lambda
00342 
00343         // Note when lambda is zero this is equivalent to the
00344         // least squares solution. This is fine when the m_jjt is
00345         // of full rank. When m_jjt is near to singular the least squares
00346         // inverse tries to minimize |J(dtheta) - dX)| and doesn't 
00347         // try to minimize  dTheta. This results in eratic changes in angle.
00348         // Damped least squares minimizes |dtheta| to try and reduce this
00349         // erratic behaviour.
00350 
00351         // We don't want to use the damped solution everywhere so we
00352         // only increase lamda from zero as we approach a singularity.
00353 
00354         // find the smallest non-zero W value, anything below epsilon is
00355         // treated as zero
00356 
00357         MT_Scalar epsilon = 1e-10;
00358         MT_Scalar max_angle_change = 0.1;
00359         MT_Scalar x_length = sqrt(TNT::dot_prod(m_beta, m_beta));
00360 
00361         int i, j;
00362         MT_Scalar w_min = MT_INFINITY;
00363 
00364         for (i = 0; i <m_svd_w.size() ; i++) {
00365                 if (m_svd_w[i] > epsilon && m_svd_w[i] < w_min)
00366                         w_min = m_svd_w[i];
00367         }
00368         
00369         // compute lambda damping term
00370 
00371         MT_Scalar d = x_length/max_angle_change;
00372         MT_Scalar lambda;
00373 
00374         if (w_min <= d/2)
00375                 lambda = d/2;
00376         else if (w_min < d)
00377                 lambda = sqrt(w_min*(d - w_min));
00378         else
00379                 lambda = 0.0;
00380 
00381         lambda *= lambda;
00382 
00383         if (lambda > 10)
00384                 lambda = 10;
00385 
00386         // immediately multiply with Beta, so we can do matrix*vector products
00387         // rather than matrix*matrix products
00388 
00389         // compute Ut*Beta
00390         TNT::transpose(m_svd_u, m_svd_u_t);
00391         TNT::matmult(m_svd_u_beta, m_svd_u_t, m_beta);
00392 
00393         m_d_theta = 0.0;
00394 
00395         for (i = 0; i < m_svd_w.size(); i++) {
00396                 if (m_svd_w[i] > epsilon) {
00397                         MT_Scalar wInv = m_svd_w[i]/(m_svd_w[i]*m_svd_w[i] + lambda);
00398 
00399                         // compute V*Winv*Ut*Beta
00400                         m_svd_u_beta[i] *= wInv;
00401 
00402                         for (j = 0; j<m_d_theta.size(); j++)
00403                                 m_d_theta[j] += m_svd_v[j][i]*m_svd_u_beta[i];
00404                 }
00405         }
00406 
00407         for (j = 0; j<m_d_theta.size(); j++)
00408                 m_d_theta[j] *= m_weight[j];
00409 }
00410 
00411 void IK_QJacobian::Lock(int dof_id, MT_Scalar delta)
00412 {
00413         int i;
00414 
00415         for (i = 0; i < m_task_size; i++) {
00416                 m_beta[i] -= m_jacobian[i][dof_id]*delta;
00417                 m_jacobian[i][dof_id] = 0.0;
00418         }
00419 
00420         m_norm[dof_id] = 0.0; // unneeded
00421         m_d_theta[dof_id] = 0.0;
00422 }
00423 
00424 MT_Scalar IK_QJacobian::AngleUpdate(int dof_id) const
00425 {
00426         return m_d_theta[dof_id];
00427 }
00428 
00429 MT_Scalar IK_QJacobian::AngleUpdateNorm() const
00430 {
00431         int i;
00432         MT_Scalar mx = 0.0, dtheta_abs;
00433 
00434         for (i = 0; i < m_d_theta.size(); i++) {
00435                 dtheta_abs = MT_abs(m_d_theta[i]*m_d_norm_weight[i]);
00436                 if (dtheta_abs > mx)
00437                         mx = dtheta_abs;
00438         }
00439         
00440         return mx;
00441 }
00442 
00443 void IK_QJacobian::SetDoFWeight(int dof, MT_Scalar weight)
00444 {
00445         m_weight[dof] = weight;
00446         m_weight_sqrt[dof] = sqrt(weight);
00447 }
00448