Libbarrett
1.2.4
|
00001 /* 00002 * utils-inl.h 00003 * 00004 * Created on: Nov 11, 2009 00005 * Author: dc 00006 */ 00007 00008 /* Copyright 2009 Barrett Technology <support@barrett.com> */ 00009 00010 /* This file is part of libbarrett. 00011 * 00012 * This version of libbarrett is free software: you can redistribute it 00013 * and/or modify it under the terms of the GNU General Public License as 00014 * published by the Free Software Foundation, either version 3 of the 00015 * License, or (at your option) any later version. 00016 * 00017 * This version of libbarrett is distributed in the hope that it will be 00018 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU General Public License along 00023 * with this version of libbarrett. If not, see 00024 * <http://www.gnu.org/licenses/>. 00025 * 00026 * Further, non-binding information about licensing is available at: 00027 * <http://wiki.barrett.com/libbarrett/wiki/LicenseNotes> 00028 */ 00029 00030 00031 #include <algorithm> 00032 #include <cmath> 00033 #include <cassert> 00034 00035 namespace barrett { 00036 namespace math { 00037 00038 00039 namespace detail { 00040 template<typename Scalar> struct CwiseSignOp { 00041 inline const Scalar operator() (const Scalar& x) const { 00042 return sign(x); 00043 } 00044 }; 00045 } 00046 00047 template<typename Derived> 00048 inline const Eigen::CwiseUnaryOp< 00049 detail::CwiseSignOp<typename Eigen::ei_traits<Derived>::Scalar>, 00050 Derived 00051 > sign(const Eigen::MatrixBase<Derived>& x) 00052 { 00053 return x.unaryExpr(detail::CwiseSignOp<typename Eigen::ei_traits<Derived>::Scalar>()); 00054 } 00055 00056 inline double sign(double x) 00057 { 00058 if (x > 0.0) { 00059 return 1.0; 00060 } else if (x == 0.0) { 00061 return 0.0; 00062 } else { 00063 return -1.0; 00064 } 00065 } 00066 00067 00068 using std::abs; 00069 00070 template<typename Derived> 00071 inline const Eigen::CwiseUnaryOp< 00072 Eigen::ei_scalar_abs_op<typename Eigen::ei_traits<Derived>::Scalar>, 00073 Derived 00074 > abs(const Eigen::MatrixBase<Derived>& x) 00075 { 00076 return x.cwise().abs(); 00077 } 00078 00079 00080 template<typename Derived1, typename Derived2> 00081 inline const Eigen::CwiseBinaryOp< 00082 Eigen::ei_scalar_min_op<typename Eigen::ei_traits<Derived1>::Scalar>, 00083 Derived1, 00084 Derived2 00085 > min(const Eigen::MatrixBase<Derived1>& a, const Eigen::MatrixBase<Derived2>& b) 00086 { 00087 return a.cwise().min(b); 00088 } 00089 00090 inline double min(double a, double b) 00091 { 00092 return std::min(a, b); 00093 } 00094 00095 00096 template<typename Derived1, typename Derived2> 00097 inline const Eigen::CwiseBinaryOp< 00098 Eigen::ei_scalar_max_op<typename Eigen::ei_traits<Derived1>::Scalar>, 00099 Derived1, 00100 Derived2 00101 > max(const Eigen::MatrixBase<Derived1>& a, const Eigen::MatrixBase<Derived2>& b) 00102 { 00103 return a.cwise().max(b); 00104 } 00105 00106 inline double max(double a, double b) 00107 { 00108 return std::max(a, b); 00109 } 00110 00111 00112 namespace detail { 00113 template<typename Scalar> struct CwiseUnarySaturateOp { 00114 CwiseUnarySaturateOp(Scalar lowerLimit, Scalar upperLimit) : lowerLimit(lowerLimit), upperLimit(upperLimit) {} 00115 00116 inline const Scalar operator() (const Scalar& x) const { 00117 return saturate(x, lowerLimit, upperLimit); 00118 } 00119 00120 Scalar lowerLimit, upperLimit; 00121 }; 00122 00123 template<typename Scalar> struct CwiseBinarySaturateOp { 00124 inline const Scalar operator() (const Scalar& x, const Scalar& limit) const { 00125 return saturate(x, limit); 00126 } 00127 }; 00128 } 00129 00130 template<typename Derived> 00131 inline const Eigen::CwiseUnaryOp< 00132 detail::CwiseUnarySaturateOp<typename Eigen::ei_traits<Derived>::Scalar>, 00133 Derived 00134 > saturate(const Eigen::MatrixBase<Derived>& x, double limit) 00135 { 00136 return x.unaryExpr(detail::CwiseUnarySaturateOp<typename Eigen::ei_traits<Derived>::Scalar>(-limit, limit)); 00137 } 00138 00139 template<typename Derived1, typename Derived2> 00140 inline const Eigen::CwiseBinaryOp< 00141 detail::CwiseBinarySaturateOp<typename Eigen::ei_traits<Derived1>::Scalar>, 00142 Derived1, 00143 Derived2 00144 > saturate(const Eigen::MatrixBase<Derived1>& x, const Eigen::MatrixBase<Derived2>& limit) 00145 { 00146 return x.binaryExpr(limit, detail::CwiseBinarySaturateOp<typename Eigen::ei_traits<Derived1>::Scalar>()); 00147 } 00148 00149 inline double saturate(double x, double limit) 00150 { 00151 return saturate(x, -limit, limit); 00152 } 00153 00154 00155 template<typename Derived> 00156 inline const Eigen::CwiseUnaryOp< 00157 detail::CwiseUnarySaturateOp<typename Eigen::ei_traits<Derived>::Scalar>, 00158 Derived 00159 > saturate(const Eigen::MatrixBase<Derived>& x, double lowerLimit, double upperLimit) 00160 { 00161 return x.unaryExpr(detail::CwiseUnarySaturateOp<typename Eigen::ei_traits<Derived>::Scalar>(lowerLimit, upperLimit)); 00162 } 00163 00164 inline double saturate(double x, double lowerLimit, double upperLimit) 00165 { 00166 assert(lowerLimit < upperLimit); 00167 00168 if (x > upperLimit) { 00169 return upperLimit; 00170 } else if (x < lowerLimit) { 00171 return lowerLimit; 00172 } else { 00173 return x; 00174 } 00175 } 00176 00177 00178 namespace detail { 00179 template<typename Scalar> struct CwiseUnaryDeadbandOp { 00180 CwiseUnaryDeadbandOp(Scalar cutoff) : cutoff(cutoff) {} 00181 00182 inline const Scalar operator() (const Scalar& x) const { 00183 return deadband(x, cutoff); 00184 } 00185 00186 Scalar cutoff; 00187 }; 00188 00189 template<typename Scalar> struct CwiseBinaryDeadbandOp { 00190 inline const Scalar operator() (const Scalar& x, const Scalar& cutoff) const { 00191 return deadband(x, cutoff); 00192 } 00193 }; 00194 } 00195 00196 template<typename Derived> 00197 inline const Eigen::CwiseUnaryOp< 00198 detail::CwiseUnaryDeadbandOp<typename Eigen::ei_traits<Derived>::Scalar>, 00199 Derived 00200 > deadband(const Eigen::MatrixBase<Derived>& x, double cutoff) 00201 { 00202 return x.unaryExpr(detail::CwiseUnaryDeadbandOp<typename Eigen::ei_traits<Derived>::Scalar>(cutoff)); 00203 } 00204 00205 template<typename Derived1, typename Derived2> 00206 inline const Eigen::CwiseBinaryOp< 00207 detail::CwiseBinaryDeadbandOp<typename Eigen::ei_traits<Derived1>::Scalar>, 00208 Derived1, 00209 Derived2 00210 > deadband(const Eigen::MatrixBase<Derived1>& x, const Eigen::MatrixBase<Derived2>& cutoff) 00211 { 00212 return x.binaryExpr(cutoff, detail::CwiseBinaryDeadbandOp<typename Eigen::ei_traits<Derived1>::Scalar>()); 00213 } 00214 00215 inline double deadband(double x, double cutoff) 00216 { 00217 if (x > cutoff) { 00218 return x - cutoff; 00219 } else if (x < -cutoff) { 00220 return x + cutoff; 00221 } else { 00222 return 0.0; 00223 } 00224 } 00225 00226 00227 } 00228 }