Blender V2.61 - r43446

IK_QJacobian.cpp

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