Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

robot/control/kinematics/IKORFullSpaceSolver

Go to the documentation of this file.
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: IKORFullSpaceSolver 1080 2004-07-28 19:51:26Z jungd $
00019   $Revision: 1.8 $
00020   $Date: 2004-07-28 15:51:26 -0400 (Wed, 28 Jul 2004) $
00021   $Author: jungd $
00022 
00023 ****************************************************************************/
00024 
00025 #ifndef _ROBOT_CONTROL_KINEMATICS_IKORFULLSPACESOLVER_
00026 #define _ROBOT_CONTROL_KINEMATICS_IKORFULLSPACESOLVER_
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 Full-space using the IKOR project method
00040 ///  (refer to the OpenSim manual and references publications for detail)
00041 class IKORFullSpaceSolver : public FullSpaceSolver
00042 {
00043 public:
00044   IKORFullSpaceSolver();
00045 
00046   virtual String className() const { return String("IKORFullSpaceSolver"); }
00047   virtual Object& clone() const { return *NewObj IKORFullSpaceSolver(*this); }
00048 
00049   /// Computes a set of vectors gi that can be used to find solutions to Ax=b for x
00050   /**
00051    *   @param A_in                     NxM Matrix
00052    *   @param b_in                     N-dim Vector
00053    *   @param dependentRowsEliminated  is filled out with the indices of rows of A_in
00054    *                                   that are eliminated from the computation because they
00055    *                                   are dependent (actually if Ai|bi is dependent.  If only
00056    *                                   Ai is dependent but bi conflicts an exception is throw
00057    *                                   because solution is impossible)
00058    *   @return      returns the set of vector gis as columns of a Matrix
00059    *   @exception   std::invalid_argument if gis can't be found for the provided A & b
00060    */
00061    virtual Matrix solve(const Matrix& A_in, const Vector& b_in,
00062                         array<Int>& dependentRowsEliminated);
00063 
00064 protected:
00065   IKORFullSpaceSolver(const IKORFullSpaceSolver& c) : FullSpaceSolver(c) {}
00066 
00067   // Constants to indicate which rows/cols have been eliminated from A, any why.
00068   //  used in solve()'s rowElim/colElim vectors
00069   //  (NB: the actual values are the same as those used in IKORv2.0, for comparison)
00070   static const Int NotEleminated = 0;
00071   static const Int Eliminated_ZeroOrRestriction = 1;
00072   static const Int RowEliminated_Dependent = 2;
00073   static const Int RowEliminated_Special = 1;
00074   static const Int ColEliminated_SpecialCase1 = 2;
00075   static const Int ColEliminated_SpecialCase2 = 3;
00076 
00077   inline static bool isSmall(Real a) { return Math::abs(a) < 5.0e-05; /*(=def. SMALL)*/ }
00078 
00079 
00080   /// Reduces the A matrix
00081   /**
00082    * This is what IKORv2.0 had to say (below).
00083    * Again; why a general solution method for Matrices is talking
00084    * about work spaces, joint etc. is a little concerning!
00085    *
00086    * Restricted work space motions can be
00087    * identified by rows of the A which only
00088    * have one nonzero element.  Since the
00089    * corresponding column must be present in
00090    * all final joint space solutions, the
00091    * appropriate joint space motion will be
00092    * calculated before any redundancy
00093    * resolution is performed, and the
00094    * appropriate motions and joints will be
00095    * removed from the work space and A
00096    * respectively.  Also such cases as
00097    * dependent rows, and SpecialCase1 must be
00098    * identified and dealt with.
00099    */
00100   void reduceA(const Matrix& A, Matrix& Ared,
00101                const Vector& b, Vector& bred,
00102                const Int M, const Int N,
00103                Int& Mred, Int& Nred,
00104                base::IVector& colElim, base::IVector& rowElim,
00105                Matrix& specialg, Int& numSpecialgs);
00106 
00107 
00108   /// calculate a new g vector for a given square blocking pattern
00109   void blockColFindX(Vector& g,
00110                      const base::IVector& tackon, const Vector& block,
00111                      const Vector& b, const Matrix& A,
00112                      const Int Mred, const Int Nred);
00113 
00114 
00115   /// Finds the remaining solution vectors after the first has been selected.
00116   /** It is recursive and thus calls itself when a
00117    *  valid solution is found, if this solution
00118    *  leads to a dead end, it will pop back to
00119    *  last solution and build from there.  This
00120    *  insures that all possible combinations of
00121    *  blocking patterns are available, given
00122    *  first one, in pattern which follows the
00123    *  algoritm presented in the article.
00124    */
00125   void restOfSoln( const Int M, const Int N, const Int Mred, const Int Nred,
00126                   Int nextToFind,
00127                   Matrix& block, Matrix& g,
00128                   const Vector& bred, const Matrix& Ared,
00129                   const base::IVector& tackon, base::IVector& firstOK);
00130 
00131 
00132   /// returns true if the given two columns and dependent (used in special-case 1 detection)
00133   bool dependency(const Matrix& A, const base::IVector& slRow, Int Nred, Int first, Int second) const;
00134 
00135   /// returns true if the original b is in the range of A
00136   bool checkRange(const Matrix& A, const Vector& b, const Matrix& g, const base::IVector& rowElim);
00137 
00138 
00139   /// rebuilds the g Matrix
00140   /** adds zeros in eliminated cols and tacks on the g vectors created
00141    *  by special-case 1
00142    */
00143   void rebuildgs(Matrix& g,
00144                  const Int M, const Int N, const Int Mred, const Int Nred,
00145                  const base::IVector& colElim, const base::IVector& rowElim,
00146                  const Matrix& specialg, const Int numSpecialgs);
00147 
00148 
00149   bool systemComplete;
00150 
00151   enum Status { Unknown=0, Restricted, Complete, NotComplete };
00152   Status status;
00153 
00154 };
00155 
00156 
00157 } // namespace kinematics
00158 } // namespace control
00159 } // namespace robot
00160 
00161 #endif

Generated on Thu Jul 29 15:56:33 2004 for OpenSim by doxygen 1.3.6