Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_LIMITS_MBD_ANGULAR_JOINT_LIMIT_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_LIMITS_MBD_ANGULAR_JOINT_LIMIT_H
00003
00004
00005
00006
00007
00008
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
00021 template< typename mbd_types >
00022 class AngularJointLimit
00023 : public SubConstraintInterface<mbd_types>
00024 {
00025 public:
00026
00027 typedef typename mbd_types::math_policy::real_type real_type;
00028 typedef typename mbd_types::math_policy::size_type size_type;
00029 typedef typename mbd_types::math_policy::value_traits value_traits;
00030 typedef typename mbd_types::math_policy::vector3_type vector3_type;
00031 typedef typename mbd_types::math_policy::vector_range vector_range;
00032 typedef typename mbd_types::math_policy::idx_vector_range idx_vector_range;
00033 typedef typename mbd_types::math_policy::matrix_range matrix_range;
00034
00035 protected:
00036
00037 real_type m_theta_min;
00038 real_type m_theta_max;
00039 real_type m_theta_cur;
00040 real_type m_theta_error;
00041 vector3_type m_s_wcs;
00042 bool m_low_active;
00043 size_type m_rows;
00044 real_type m_gamma;
00045 real_type m_solution;
00046
00047 public:
00048
00054 void set_min_limit(real_type const & theta_min)
00055 {
00056 assert(theta_min == OpenTissue::math::detail::lowest<real_type>() || (theta_min<=value_traits::zero() && theta_min>=-value_traits::pi()) || !"AngularJointLimit::set_min_limit(): min out of bounds");
00057 assert(m_theta_max>=theta_min || !"AngularJointLimit::set_min_limit(): min out of bounds");
00058 m_theta_min = theta_min;
00059 }
00060
00061 real_type get_min_limit() const { return m_theta_min; }
00062
00068 void set_max_limit(real_type const & theta_max)
00069 {
00070 assert(theta_max == OpenTissue::math::detail::highest<real_type>() || (theta_max>=value_traits::zero() && theta_max<=value_traits::pi()) || !"AngularJointLimit::set_max_limit(): max out of bounds");
00071 assert(theta_max>=m_theta_min || !"AngularJointLimit::set_max_limit(): max out of bounds");
00072 m_theta_max = theta_max;
00073 }
00074
00075 real_type get_max_limit() const { return m_theta_max; }
00076
00077 public:
00078
00079 AngularJointLimit()
00080 : m_theta_min( OpenTissue::math::detail::lowest<real_type>() )
00081 , m_theta_max( OpenTissue::math::detail::highest<real_type>() )
00082 , m_rows(0)
00083 , m_gamma(value_traits::zero())
00084 , m_solution(value_traits::zero())
00085 {}
00086
00087 virtual ~AngularJointLimit(){}
00088
00089 public:
00090
00091 void evaluate(vector3_type const & s_wcs,real_type const & angle)
00092 {
00093 m_rows = 0;
00094 m_theta_cur = angle;
00095 m_s_wcs = s_wcs;
00096 m_theta_error = value_traits::zero();
00097 m_low_active = false;
00098
00099 if(m_theta_min != OpenTissue::math::detail::lowest<real_type>() && m_theta_cur<m_theta_min)
00100 {
00101 m_theta_error = m_theta_min - m_theta_cur;
00102 m_low_active = true;
00103 m_rows = 1;
00104 }
00105 if(m_theta_max != OpenTissue::math::detail::highest<real_type>() && m_theta_cur>m_theta_max)
00106 {
00107 m_theta_error = m_theta_max - m_theta_cur;
00108 m_rows = 1;
00109 }
00110 }
00111
00112 size_type get_number_of_jacobian_rows() const {return m_rows;}
00113
00114 void get_linear_jacobian_A(matrix_range & J,size_type const & offset)const
00115 {
00116 J(offset,0) = value_traits::zero();
00117 J(offset,1) = value_traits::zero();
00118 J(offset,2) = value_traits::zero();
00119 }
00120
00121 void get_linear_jacobian_B(matrix_range & J,size_type const & offset)const
00122 {
00123 J(offset,0) = value_traits::zero();
00124 J(offset,1) = value_traits::zero();
00125 J(offset,2) = value_traits::zero();
00126 }
00127
00128 void get_angular_jacobian_A(matrix_range & J,size_type const & offset)const
00129 {
00130 J(offset,0) = -m_s_wcs(0); J(offset,1) = -m_s_wcs(1); J(offset,2) = -m_s_wcs(2);
00131 }
00132
00133 void get_angular_jacobian_B(matrix_range & J,size_type const & offset)const
00134 {
00135 J(offset,0) = m_s_wcs(0); J(offset,1) = m_s_wcs(1); J(offset,2) = m_s_wcs(2);
00136 }
00137
00138 void get_stabilization_term(vector_range & b_error,size_type const & offset)const
00139 {
00140 b_error(offset) = this->get_frames_per_second()*this->get_error_reduction_parameter()*m_theta_error;
00141 }
00142
00143 void get_low_limits(vector_range & lo,size_type const & offset)const
00144 {
00145 if(m_low_active)
00146 lo(offset) = value_traits::zero();
00147 else
00148 lo(offset) = OpenTissue::math::detail::lowest<real_type>();
00149 }
00150
00151 void get_high_limits(vector_range & hi,size_type const & offset)const
00152 {
00153 if(m_low_active)
00154 hi(offset) = OpenTissue::math::detail::highest<real_type>();
00155 else
00156 hi(offset) = value_traits::zero();
00157 }
00158
00159 void get_dependency_indices(idx_vector_range & dep,size_type const & offset) const
00160 {
00161 dep(offset) = OpenTissue::math::detail::highest<size_type>();
00162 }
00163
00164 void get_dependency_factors(vector_range & factors,size_type const & offset) const
00165 {
00166 factors(offset) = value_traits::zero();
00167 }
00168
00169 void set_regularization(vector_range const & gamma,size_type const & offset)
00170 {
00171 m_gamma = gamma(offset);
00172 }
00173
00174 void get_regularization(vector_range & gamma,size_type const & offset) const
00175 {
00176 gamma(offset) = m_gamma;
00177 }
00178
00179 void set_solution(vector_range const & solution,size_type const & offset)
00180 {
00181 m_solution = solution(offset);
00182 }
00183
00184 void get_solution(vector_range & solution,size_type const & offset) const
00185 {
00186 solution(offset) = m_solution;
00187 }
00188 };
00189
00190 }
00191 }
00192
00193 #endif