• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

/home/hauberg/Dokumenter/Capture/humim-tracker-0.1/src/OpenTissue/OpenTissue/dynamics/mbd/limits/mbd_reach_cone.h

Go to the documentation of this file.
00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_LIMITS_MBD_REACH_CONE_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_LIMITS_MBD_REACH_CONE_H
00003 //
00004 // OpenTissue Template Library
00005 // - A generic toolbox for physics-based modeling and simulation.
00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen.
00007 //
00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php
00009 //
00010 #include <OpenTissue/configuration.h>
00011 
00012 #include <OpenTissue/dynamics/mbd/interfaces/mbd_sub_constraint_interface.h>
00013 #include <OpenTissue/core/math/math_constants.h>
00014 
00015 
00016 namespace OpenTissue
00017 {
00018   namespace mbd
00019   {
00020 
00081     template< typename mbd_types  >
00082     class ReachCone
00083       : public SubConstraintInterface<mbd_types>
00084     {
00085     public:
00086 
00087       typedef typename mbd_types::math_policy                       math_policy;
00088       typedef typename mbd_types::math_policy::real_type            real_type;
00089       typedef typename mbd_types::math_policy::size_type            size_type;
00090       typedef typename mbd_types::math_policy::value_traits         value_traits;
00091       typedef typename mbd_types::math_policy::vector3_type         vector3_type;
00092       typedef typename mbd_types::math_policy::vector_range         vector_range;
00093       typedef typename mbd_types::math_policy::idx_vector_range     idx_vector_range;
00094       typedef typename mbd_types::math_policy::matrix_range         matrix_range;
00095       typedef typename mbd_types::math_policy::vector_type          vector_type;
00096       typedef typename mbd_types::math_policy::quaternion_type      quaternion_type;
00097 
00098     protected:
00099 
00100       struct cone_constraint_type
00101       {
00102         real_type       m_theta_err;    
00103         vector3_type    m_u;            
00104       };
00105 
00106       typedef typename std::vector<cone_constraint_type>     constraint_container;
00107       typedef typename std::vector<vector3_type>             normal_container;
00108 
00109       constraint_container  m_contraints;       
00110 
00111 
00112       normal_container      m_cone_normals;     
00113 
00114 
00115 
00116 
00117 
00118 
00119       size_type          m_cone_sides;       
00120       size_type          m_rows;             
00121       vector_type        m_gamma;            
00122       vector_type        m_solution;         
00123 
00124     public:
00125 
00126       ReachCone()
00127         : m_cone_sides(0)
00128         , m_rows(0)
00129         , m_gamma(0)
00130         , m_solution(0)
00131       {}
00132 
00133       virtual ~ReachCone(){}
00134 
00135     public:
00136 
00142       void add_cone(vector3_type const & n_local)
00143       {
00144         vector3_type n_unit = normalize(n_local);
00145         //--- Test whether n_unit and the joint axis from the joint
00146         //--- frame on body A points in the same direction. I.e. whether
00147         //--- their dot product is non-negative.
00148         //--- If the dot product is negative then the user
00149         //--- is trying to setup and inconsistent reach cone.
00150         //---
00151         //--- But, in the local frame of the joint frame wrt. body A, the
00152         //--- joint axis is always (0,0,1) by convention. So this implies
00153         //--- that the z-coordinate of n_unit must be non-negative!
00154         if(n_unit(2)<value_traits::zero())
00155         {
00156           std::cout << "ReachCone::add_cone(): Inconsistent cone side, dropping it" << std::endl;
00157           return;
00158         }      
00159         m_cone_normals.push_back(n_unit);
00160         m_contraints.push_back(cone_constraint_type());
00161         ++m_cone_sides;
00162       }
00163 
00188       void evaluate(
00189         quaternion_type const & Q,
00190         vector3_type const & s_wcs,
00191         vector3_type const & s_local
00192         )
00193       {
00194         //std::cout << "ReachCone::evalute(): invoked " << std::endl;
00195         m_rows = 0;
00196         for( size_type i=0;i<m_cone_sides;++i)
00197         {
00198           //--- Compute the angle between the joint axis and the cone plane normal.
00199           vector3_type n_local = m_cone_normals[i];
00200 
00201           //---  Given two vectors n and s then the angle between them is given as
00202           //---
00203           //---      cos theta = n * s / |n| |s|
00204           //---  
00205           //--- If both vectors are unit vectors and we apply the small angle
00206           //--- approximation then we have
00207           //---
00208           //---      theta = n*s
00209           //---
00210           real_type theta_err = n_local * s_local;
00211           //--- If the angle violates the plane ``slope'' then create a angular joint limit.
00212 
00213           //--- The normal points to the inside region of the cone, thus we need to
00214           //--- test whether the s_local vector have tipped to the other side of the
00215           //--- cone plane. That is whether the cone face normal and the joint axis
00216           //--- wrt. body B points in opposite directions.
00217           if(theta_err<value_traits::zero()) 
00218           {
00219             // TODO KE 2006-08-06: If violation is greater than pi/2 radians
00220             // then we will not see the pi/2 error in the angle!
00221 
00222             m_contraints[m_rows].m_theta_err = theta_err;
00223             //std::cout << "\ttheta error = " << theta_err << std::endl;
00224 
00225             //--- Compute the current joint angle limit rotation axis. That is
00226             //--- the axis we need to rotate around to make the joint violation
00227             //--- disappear.
00228             vector3_type n_wcs = Q.rotate(n_local);
00229             m_contraints[m_rows].m_u = cross(n_wcs , s_wcs);
00230             ++m_rows;
00231           }
00232         }
00233       }
00234 
00235       size_type get_number_of_jacobian_rows() const {return m_rows;}
00236 
00237       void get_linear_jacobian_A(matrix_range & J,size_type const & offset)const
00238       {
00239         size_type row = offset;
00240         for(size_type i=0;i<m_rows;++i,++row)
00241         {
00242           J(row,0) = value_traits::zero();
00243           J(row,1) = value_traits::zero();
00244           J(row,2) = value_traits::zero();
00245         }
00246       }
00247 
00248       void get_linear_jacobian_B(matrix_range & J,size_type const & offset)const
00249       {
00250         size_type row = offset;
00251         for(size_type i=0;i<m_rows;++i,++row)
00252         {
00253           J(row,0) = value_traits::zero();
00254           J(row,1) = value_traits::zero();
00255           J(row,2) = value_traits::zero();
00256         }
00257       }
00258 
00259       void get_angular_jacobian_A(matrix_range & J,size_type const & offset)const
00260       {
00261         size_type row = offset;
00262         for(size_type i=0;i<m_rows;++i,++row)
00263         {
00264           J(row,0) = -m_contraints[i].m_u(0);
00265           J(row,1) = -m_contraints[i].m_u(1);
00266           J(row,2) = -m_contraints[i].m_u(2);
00267         }
00268       }
00269 
00270       void get_angular_jacobian_B(matrix_range & J,size_type const & offset)const
00271       {
00272         size_type row = offset;
00273         for(size_type i=0;i<m_rows;++i,++row)
00274         {
00275           J(row,0) = m_contraints[i].m_u(0);
00276           J(row,1) = m_contraints[i].m_u(1);
00277           J(row,2) = m_contraints[i].m_u(2);
00278         }
00279       }
00280 
00281       void get_stabilization_term(vector_range & b_error,size_type const & offset)const
00282       {
00283         real_type k_cor = this->get_frames_per_second()*this->get_error_reduction_parameter();
00284         size_type row = offset;
00285         for(size_type i=0;i<m_rows;++i,++row)
00286         {
00287           b_error(row) = - k_cor*m_contraints[i].m_theta_err;
00288         }
00289       }
00290 
00291       void get_low_limits(vector_range & lo,size_type const & offset)const
00292       {
00293         size_type row = offset;
00294         for(size_type i=0;i<m_rows;++i,++row)
00295         {
00296           lo(row) = value_traits::zero();
00297         }
00298       }
00299 
00300       void get_high_limits(vector_range & hi,size_type const & offset)const
00301       {
00302         size_type row = offset;
00303         for(size_type i=0;i<m_rows;++i,++row)
00304         {
00305           hi(row) = OpenTissue::math::detail::highest<real_type>();
00306         }
00307       }
00308 
00309       void get_dependency_indices(idx_vector_range & dep,size_type const & offset) const
00310       {
00311         size_type row = offset;
00312         for(size_type i=0;i<m_rows;++i,++row)
00313         {
00314           dep(row) = OpenTissue::math::detail::highest<size_type>();
00315         }
00316       }
00317 
00318       void get_dependency_factors(vector_range & factors,size_type const & offset) const
00319       {
00320         size_type row = offset;
00321         for(size_type i=0;i<m_rows;++i,++row)
00322         {
00323           factors(row) = value_traits::zero();
00324         }
00325       }
00326 
00327       void set_regularization(vector_range const & gamma,size_type const & offset)
00328       {
00329         math_policy::resize( m_gamma, m_rows);
00330         size_type row = offset;
00331         for(size_type i=0;i<m_rows;++i,++row)
00332         {
00333           assert(gamma(row)<=1 || !"ReachCone::set_regularization(): gamma value out of range");
00334           assert(gamma(row)>=0 || !"ReachCone::set_regularization(): gamma value out of range");
00335           m_gamma(i) = gamma(row);
00336         }
00337       }
00338 
00339       void get_regularization(vector_range & gamma,size_type const & offset)const
00340       {
00341         size_type row = offset;
00342         if(m_gamma.size()==0)
00343         {
00344           for(size_type i=0;i<m_rows;++i,++row)
00345             gamma(row) = value_traits::zero();
00346         }
00347         else
00348         {
00349           for(size_type i=0;i<m_rows;++i,++row)
00350             gamma(row) = m_gamma(i);
00351         }
00352       }
00353 
00354       void set_solution(vector_range const & solution,size_type const & offset)
00355       {
00356         assert(solution.size()==m_rows || !"ReachCone::set_solution(): solution array size did not match number of active cone constraints");
00357         math_policy::resize( m_solution, m_rows);
00358         size_type row = offset;
00359         for(size_type i=0;i<m_rows;++i,++row)
00360           m_solution(i) = solution(row);
00361       }
00362 
00363       void get_solution(vector_range & solution,size_type const & offset)const
00364       {
00365         size_type row = offset;
00366         if(m_solution.size()==0)
00367         {
00368           for(size_type i=0;i<m_rows;++i,++row)
00369             solution(row) = value_traits::zero();
00370         }
00371         else
00372         {
00373           for(size_type i=0;i<m_rows;++i,++row)
00374             solution(row) = m_solution(i);
00375         }
00376       }
00377 
00378     };
00379 
00380   } // namespace mbd
00381 } // namespace OpenTissue
00382 // OPENTISSUE_DYNAMICS_MBD_UTIL_LIMITS_MBD_REACH_CONE_H
00383 #endif

Generated on Thu Dec 1 2011 12:52:38 for HUMIM Tracker by  doxygen 1.7.1