00001 /* **-*-c++-*-************************************************************** 00002 Copyright (C)2002 David Jung <opensim@pobox.com> 00003 00004 This program/file is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or 00007 (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. (http://www.gnu.org) 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 00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 $Id: SVDFullSpaceSolver 1080 2004-07-28 19:51:26Z jungd $ 00019 $Revision: 1.2 $ 00020 $Date: 2004-07-28 15:51:26 -0400 (Wed, 28 Jul 2004) $ 00021 $Author: jungd $ 00022 00023 ****************************************************************************/ 00024 00025 #ifndef _ROBOT_CONTROL_KINEMATICS_SVDFULLSPACESOLVER_ 00026 #define _ROBOT_CONTROL_KINEMATICS_SVDFULLSPACESOLVER_ 00027 00028 #include <robot/control/kinematics/kinematics> 00029 00030 #include <robot/control/kinematics/FullSpaceSolver> 00031 00032 00033 namespace robot { 00034 namespace control { 00035 namespace kinematics { 00036 00037 00038 00039 /// Solver that finds the set of vectors gi, such that dq = sum ti.gi s.t. sum tk=1 00040 /// is a solution to Jdq=dx, and dq = sum ti.gi s.t. sum tk=0 is a solution to 00041 /// Jdq=0 (null-space) using Singular Value Decomposition (SVD) 00042 class SVDFullSpaceSolver : public FullSpaceSolver 00043 { 00044 public: 00045 SVDFullSpaceSolver(); 00046 00047 virtual String className() const { return String("SVDFullSpaceSolver"); } 00048 virtual Object& clone() const { return *NewObj SVDFullSpaceSolver(*this); } 00049 00050 /// Computes a set of vectors gi that can be used to find solutions to Ax=b for x 00051 /** 00052 * @param A_in NxM Matrix 00053 * @param b_in N-dim Vector 00054 * @param dependentRowsEliminated is filled out with the indices of rows of A_in 00055 * that are eliminated from the computation because they 00056 * are dependent (actually if Ai|bi is dependent. If only 00057 * Ai is dependent but bi conflicts an exception is throw 00058 * because solution is impossible) 00059 * @return returns the set of vector gis as columns of a Matrix 00060 * @exception std::invalid_argument if gis can't be found for the provided A & b 00061 */ 00062 virtual Matrix solve(const Matrix& A_in, const Vector& b_in, 00063 array<Int>& dependentRowsEliminated); 00064 00065 00066 /// if true, if A is ill-conditioned (SVD gives large condition number), an exception is thrown in solve() 00067 /// otherwise, all 0 singular values are considered infinite (the corresponding elements of Sinv are set to 0) 00068 /// and a solution is returned (which should have least-norm error from requested b) 00069 void setStopOnIllCondition(bool stopOnIllCondition) { this->stopOnIllCondition = stopOnIllCondition; } 00070 00071 protected: 00072 SVDFullSpaceSolver(const SVDFullSpaceSolver& fsp) : FullSpaceSolver(fsp) {} 00073 00074 /// if true, if A is ill-conditioned (SVD gives large condition number), an exception is thrown 00075 bool stopOnIllCondition; 00076 00077 inline static bool isSmall(Real a) { return Math::abs(a) < 5.0e-05; /*(=def. SMALL)*/ } 00078 00079 }; 00080 00081 00082 } // namespace kinematics 00083 } // namespace control 00084 } // namespace robot 00085 00086 #endif