Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_LIMITS_MBD_LINEAR_JOINT_LIMIT_H
00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_LIMITS_MBD_LINEAR_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 LinearJointLimit
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::vector3_type vector3_type;
00030 typedef typename mbd_types::math_policy::vector_range vector_range;
00031 typedef typename mbd_types::math_policy::idx_vector_range idx_vector_range;
00032 typedef typename mbd_types::math_policy::matrix_range matrix_range;
00033 typedef typename mbd_types::math_policy::value_traits value_traits;
00034
00035 protected:
00036
00037 real_type m_d_min;
00038 real_type m_d_max;
00039 real_type m_d_cur;
00040 real_type m_d_error;
00041 vector3_type m_s_wcs;
00042 vector3_type m_c;
00043 vector3_type m_half_cXs;
00044 bool m_low_active;
00045 size_type m_rows;
00046 real_type m_gamma;
00047 real_type m_solution;
00048
00049 public:
00050
00056 void set_min_limit(real_type const & d_min)
00057 {
00058 assert(d_min<=0 || !"LinearJointLimit::set_min_limit(): out of bounds");
00059 assert(d_min!=m_d_max || !"LinearJointLimit::set_min_limit(): out of bounds");
00060 m_d_min = d_min;
00061 }
00062
00068 real_type get_min_limit() const { return m_d_min; }
00069
00075 void set_max_limit(real_type const & d_max)
00076 {
00077 assert(0<=d_max || !"LinearJointLimit::set_max_limit(): out of bounds");
00078 assert(d_max!=m_d_min || !"LinearJointLimit::set_max_limit(): out of bounds");
00079 m_d_max = d_max;
00080 }
00081
00087 real_type get_max_limit() const { return m_d_max; }
00088
00089 public:
00090
00091 LinearJointLimit()
00092 : m_d_min( OpenTissue::math::detail::lowest<real_type>() )
00093 , m_d_max( OpenTissue::math::detail::highest<real_type>() )
00094 , m_rows(0)
00095 , m_gamma(0)
00096 , m_solution(0)
00097 {}
00098
00099 virtual ~LinearJointLimit() {}
00100
00101 public:
00102
00111 void evaluate(real_type const & offset,vector3_type const & s_wcs,vector3_type const & r_A,vector3_type const & r_B )
00112 {
00113 m_rows = 0;
00114
00115 if(m_d_min == OpenTissue::math::detail::lowest<real_type>() && m_d_max == OpenTissue::math::detail::highest<real_type>() )
00116 return;
00117
00118 m_d_cur = offset;
00119 m_d_error = 0;
00120 m_low_active = false;
00121 if(m_d_min != OpenTissue::math::detail::lowest<real_type>() && m_d_cur <= m_d_min)
00122 {
00123
00124 m_d_error = m_d_min - m_d_cur;
00125 m_rows = 1;
00126 m_low_active = true;
00127 }
00128 if(m_d_max != OpenTissue::math::detail::highest<real_type>() && m_d_cur >= m_d_max)
00129 {
00130
00131 m_d_error = m_d_max - m_d_cur;
00132 m_rows = 1;
00133 }
00134
00135 m_s_wcs = s_wcs;
00136 m_c = r_B - r_A;
00137 m_half_cXs = cross(m_c , m_s_wcs)/value_traits::two();
00138 }
00139
00140 size_type get_number_of_jacobian_rows() const {return m_rows;}
00141
00142 void get_linear_jacobian_A(matrix_range & J,size_type const & offset)const
00143 {
00144 J(offset,0) = -m_s_wcs(0); J(offset,1) = -m_s_wcs(1); J(offset,2) = -m_s_wcs(2);
00145 }
00146
00147 void get_linear_jacobian_B(matrix_range & J,size_type const & offset)const
00148 {
00149 J(offset,0) = m_s_wcs(0); J(offset,1) = m_s_wcs(1); J(offset,2) = m_s_wcs(2);
00150 }
00151
00152 void get_angular_jacobian_A(matrix_range & J,size_type const & offset)const
00153 {
00154 J(offset,0) = m_half_cXs(0); J(offset,1) = m_half_cXs(1); J(offset,2) = m_half_cXs(2);
00155 }
00156
00157 void get_angular_jacobian_B(matrix_range & J,size_type const & offset)const
00158 {
00159 J(offset,0) = -m_half_cXs(0); J(offset,1) = -m_half_cXs(1); J(offset,2) = -m_half_cXs(2);
00160 }
00161
00162 void get_stabilization_term(vector_range & b_error,size_type const & offset)const
00163 {
00164 b_error(offset) = this->get_frames_per_second()*this->get_error_reduction_parameter()*m_d_error;
00165 }
00166
00167 void get_low_limits(vector_range & lo,size_type const & offset)const
00168 {
00169 if(m_low_active)
00170 lo(offset) = 0;
00171 else
00172 lo(offset) = OpenTissue::math::detail::lowest<real_type>();
00173 }
00174
00175 void get_high_limits(vector_range & hi,size_type const & offset)const
00176 {
00177 if(m_low_active)
00178 hi(offset) = OpenTissue::math::detail::highest<real_type>();
00179 else
00180 hi(offset) = 0;
00181 }
00182
00183 void get_dependency_indices(idx_vector_range & dep,size_type const & offset) const
00184 {
00185 dep(offset) = OpenTissue::math::detail::highest<size_type>();
00186 }
00187
00188 void get_dependency_factors(vector_range & factors,size_type const & offset) const
00189 {
00190 factors(offset) = 0;
00191 }
00192
00193 void set_regularization(vector_range const & gamma,size_type const & offset)
00194 {
00195 m_gamma = gamma(offset);
00196 }
00197
00198 void get_regularization(vector_range & gamma,size_type const & offset) const
00199 {
00200 gamma(offset) = m_gamma;
00201 }
00202
00203 void set_solution(vector_range const & solution,size_type const & offset)
00204 {
00205 m_solution = solution(offset);
00206 }
00207
00208 void get_solution(vector_range & solution,size_type const & offset) const
00209 {
00210 solution(offset) = m_solution;
00211 }
00212
00213 };
00214
00215 }
00216 }
00217
00218 #endif