$search
00001 /*************************************************************************** 00002 Jacobian.h - description 00003 ------------------------- 00004 begin : June 2006 00005 copyright : (C) 2006 Erwin Aertbelien 00006 email : firstname.lastname@mech.kuleuven.ac.be 00007 00008 History (only major changes)( AUTHOR-Description ) : 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU Lesser General Public * 00013 * License as published by the Free Software Foundation; either * 00014 * version 2.1 of the License, or (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00019 * Lesser General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation, Inc., 59 Temple Place, * 00024 * Suite 330, Boston, MA 02111-1307 USA * 00025 * * 00026 ***************************************************************************/ 00027 #ifndef KDL_Jacobian_H 00028 #define KDL_Jacobian_H 00029 00030 #include <kdl/traits.h> 00031 #include <assert.h> 00032 #include <bitset> 00033 #include <vector> 00034 00035 #define MAXNROFDERIV 31 00036 00037 typedef std::bitset<MAXNROFDERIV> JacobianBitset; 00038 00064 template <typename T> 00065 class Expr { 00066 public: 00067 typedef typename T::exprType exprType; 00071 typedef typename T::derivType derivType; 00072 00076 typedef typename T::valueType valueType; 00077 00081 T elem; 00082 public: 00086 Expr(const T& _elem):elem(_elem) {} 00087 }; 00088 00089 00090 00104 template <typename T> 00105 class Jacobian { 00106 public: 00107 00108 typedef T exprType; 00109 typedef typename Traits<T>::valueType valueType; 00110 00114 typedef typename Traits<T>::derivType derivType; 00115 private: 00116 valueType val; 00117 std::vector<derivType> der; 00118 int size; 00119 JacobianBitset hasderiv; 00120 public: 00127 explicit Jacobian(int _size=0): 00128 val(), 00129 der(_size), 00130 size(_size), 00131 hasderiv() { 00132 assert(_size < MAXNROFDERIV); 00133 } 00134 00135 void resize(int _size) { 00136 size=_size; 00137 hasderiv = JacobianBitset(); 00138 der.resize(_size); 00139 assert(_size < MAXNROFDERIV); 00140 } 00141 00142 00143 00149 Jacobian(const Jacobian<T>& arg): 00150 val(arg.val), 00151 der(arg.size), 00152 size(arg.size), 00153 hasderiv(arg.hasderiv) 00154 { 00155 for (int i=0;i<size;++i) der[i]=arg.der[i]; 00156 } 00157 00164 Jacobian(const valueType& arg):val(arg),der(0),size(0),hasderiv() { 00165 } 00166 00170 ~Jacobian() { 00171 } 00172 00180 derivType deriv(int i) const{ 00181 assert((0<=i)&&(i<size)); 00182 assert(hasderiv[i]); 00183 return der[i]; 00184 } 00185 00199 derivType& deriv(int i) { 00200 assert((0<=i)&&(i<size)); 00201 hasderiv[i]=true; 00202 return der[i]; 00203 } 00204 00211 valueType& value(){ 00212 return val; 00213 } 00214 00221 valueType value() const { 00222 return val; 00223 } 00224 00225 00229 int nrOfDeriv() const { 00230 return size; 00231 } 00232 00237 bool hasDeriv(int i) const { 00238 return hasderiv[i]; 00239 } 00240 00244 bool hasDerivs() const { 00245 return hasderiv.any(); 00246 } 00247 00248 00254 JacobianBitset getDerivs() const { 00255 return hasderiv; 00256 } 00257 00264 void setDeriv(int i,bool s=true) { 00265 assert(!( (!s) && (size==0) )); 00266 hasderiv[i] = s; 00267 } 00268 00279 template <class A> 00280 Jacobian<T>& operator=(const Expr<A>& e) { 00281 const A& expr = e.elem; 00282 hasderiv = expr.getDerivs(); 00283 if (hasderiv.any()) { 00284 assert(expr.nrOfDeriv()==nrOfDeriv()); 00285 for (int i=0;i<size;++i) 00286 if (hasderiv[i]) { 00287 der[i] = expr.deriv(i); 00288 } 00289 } 00290 // it is important that the following is located after the 00291 // der[i] assignments. In this way, A = A*B is a correct use of 00292 // this routine. i.e. expr.deriv(i) could refer to expr.value() 00293 val = expr.value(); 00294 return *this; 00295 } 00296 00297 00304 Jacobian<T>& operator=(const Jacobian<T>& expr) { 00305 hasderiv = expr.hasderiv; 00306 if (hasderiv.any()) { 00307 assert(expr.nrOfDeriv()==nrOfDeriv()); 00308 for (int i=0;i<size;++i) 00309 if (hasderiv[i]) { 00310 der[i] = expr.deriv(i); 00311 } 00312 } 00313 val = expr.value(); 00314 return *this; 00315 } 00316 00323 Jacobian<T>& operator=(const T& expr) { 00324 val = expr; 00325 hasderiv.reset(); 00326 return *this; 00327 } 00328 }; 00329 00330 00331 00337 template <typename T> 00338 class Cnst { 00339 public: 00340 typedef T exprType; 00341 typedef typename Traits<T>::valueType valueType; 00342 00346 typedef typename Traits<T>::derivType derivType; 00347 private: 00348 valueType val; 00349 public: 00350 // 00351 // -Default constructor 00352 // -Default copy constructor 00353 // -Default destructor 00354 // are sufficient. 00355 00356 00361 derivType deriv(int i) const{ 00362 assert(false); // should never be called, this is a CONSTANT object. 00363 return derivType(); 00364 } 00365 00370 derivType& deriv(int i) { 00371 assert(false); // should never be called, this is a CONSTANT object. 00372 return derivType(); 00373 } 00374 00381 valueType& value(){ 00382 return val; 00383 } 00384 00391 valueType value() const { 00392 return val; 00393 } 00394 00395 00399 int nrOfDeriv() const { 00400 return 0; 00401 } 00402 00407 bool hasDeriv(int i) const { 00408 return false; 00409 } 00410 00414 bool hasDerivs() const { 00415 return false; 00416 } 00417 00418 00424 JacobianBitset getDerivs() const { 00425 return JacobianBitset(0); 00426 } 00427 00433 void setDeriv(int i,bool s=true) { 00434 assert(false); 00435 } 00436 00437 00444 Cnst<T>& operator=(const T& expr) { 00445 val = expr; 00446 return *this; 00447 } 00448 }; 00449 00450 00451 00452 00453 00454 00455 00456 00457 00458 #endif //KDL_Jacobian 00459