$search
00001 00002 /****************************************************************************** 00003 * 00004 * Copyright (c) 2012 00005 * 00006 * SCHUNK GmbH & Co. KG 00007 * 00008 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00009 * 00010 * Project name: Drivers for "Amtec M5 Protocol" Electronics V4 00011 * 00012 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00013 * 00014 * Email:robotics@schunk.com 00015 * 00016 * ToDo: 00017 * 00018 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00019 * 00020 * Redistribution and use in source and binary forms, with or without 00021 * modification, are permitted provided that the following conditions are met: 00022 * 00023 * * Redistributions of source code must retain the above copyright 00024 * notice, this list of conditions and the following disclaimer. 00025 * * Redistributions in binary form must reproduce the above copyright 00026 * notice, this list of conditions and the following disclaimer in the 00027 * documentation and/or other materials provided with the distribution. 00028 * * Neither the name of SCHUNK GmbH & Co. KG nor the names of its 00029 * contributors may be used to endorse or promote products derived from 00030 * this software without specific prior written permission. 00031 * 00032 * This program is free software: you can redistribute it and/or modify 00033 * it under the terms of the GNU Lesser General Public License LGPL as 00034 * published by the Free Software Foundation, either version 3 of the 00035 * License, or (at your option) any later version. 00036 * 00037 * This program is distributed in the hope that it will be useful, 00038 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00039 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00040 * GNU Lesser General Public License LGPL for more details. 00041 * 00042 * You should have received a copy of the GNU Lesser General Public 00043 * License LGPL along with this program. 00044 * If not, see <http://www.gnu.org/licenses/>. 00045 * 00046 ******************************************************************************/ 00047 00048 00049 #ifndef UTIL_INLINEFUNCTIONS_H 00050 #define UTIL_INLINEFUNCTIONS_H 00051 00052 #include "../Util/GlobalDefines.h" 00053 00054 #ifndef _WIN32 00055 #include <unistd.h> 00056 #endif 00057 00058 #include <time.h> 00059 #include <limits.h> 00060 00061 #if defined (_WIN32) 00062 #include <sys/timeb.h> 00063 #include <windows.h> 00064 #include <process.h> 00065 #endif 00066 #ifdef __QNX__ 00067 #include <sys/time.h> 00068 #include <time.h> 00069 #include <sys/timeb.h> 00070 #include <unistd.h> 00071 #include <semaphore.h> 00072 #include <signal.h> 00073 #include <i86.h> 00074 #include <process.h> 00075 #define TRACE printf 00076 #define CRITICAL_SECTION int 00077 #endif 00078 00079 #ifdef __LINUX__ 00080 #include <sys/time.h> 00081 //#include <linux/delay.h> 00082 #include <pthread.h> 00083 #define TRACE printf 00084 #define CRITICAL_SECTION pthread_mutex_t 00085 #endif 00086 #include "../Util/Math.h" 00087 00088 // returns the squared fValue 00089 template <class T> inline T sqr(T fValue) 00090 { 00091 return fValue*fValue; 00092 }; 00093 00094 // returns the rounded integer fValue 00095 template <class T> inline int iRound(T v) 00096 { 00097 return (v>=0) ? (int)(v+.5) : (int)(v-.5); 00098 }; 00099 00100 // returns the minimum of fValue a and fValue b 00101 template <class T> inline T util_min(T a, T b) 00102 { 00103 return (a<b) ? a : b; 00104 }; 00105 00106 // returns the maximum of fValue a and fValue b 00107 template <class T> inline T util_max(T a, T b) 00108 { 00109 return (a>b) ? a : b; 00110 }; 00111 00112 #ifndef NO_ABS_FCT 00113 00114 // returns the absolute fValue 00115 inline long abs(long iValue) 00116 { 00117 #if defined(NO_CAST_FUNCTION_TEMPLATES) 00118 return long(abs(iValue)); 00119 #else 00120 return static_cast<long>(abs(iValue)); 00121 #endif 00122 }; 00123 00124 // returns the absolute uiValue 00125 inline unsigned long abs(unsigned long uiValue) 00126 { 00127 #if defined(NO_CAST_FUNCTION_TEMPLATES) 00128 return unsigned long(abs(uiValue)); 00129 #else 00130 return static_cast<unsigned long>(abs(uiValue)); 00131 #endif 00132 }; 00133 00134 // returns the absolute fValue 00135 inline float abs(float fValue) 00136 { 00137 #if defined(NO_CAST_FUNCTION_TEMPLATES) 00138 return float(fabs(fValue)); 00139 #else 00140 return static_cast<float>(fabs(fValue)); 00141 #endif 00142 }; 00143 00144 // returns the absolute fValue 00145 inline double abs(double fValue) 00146 { 00147 return fabs(fValue); 00148 }; 00149 00150 #endif 00151 00152 // returns fValue a with the sign of fValue b 00153 inline float util_sign(float a, float b) 00154 { 00155 return ((b) >= 0.0) ? fabs(a) : -fabs(a); 00156 }; 00157 00158 // returns fValue a with the sign of fValue b 00159 inline double util_sign(double a, double b) 00160 { 00161 return ((b) >= 0.0) ? fabs(a) : -fabs(a); 00162 }; 00163 00164 template <class T> inline void util_shift(T a, T b, T c, T d) 00165 { 00166 (a)=(b); 00167 (b)=(c); 00168 (c)=(d); 00169 } 00170 00171 // converts degrees to radians 00172 inline double util_degToRad(double fAngle) 00173 { 00174 return fAngle * M_PI / 180.0; 00175 }; 00176 00177 // converts radians to degrees 00178 inline double util_radToDeg(double fAngle) 00179 { 00180 return fAngle * 180.0 / M_PI; 00181 }; 00182 00183 // fits fPhase into the interval [0,2 \pi[ 00184 inline double util_adjustedPhase(double fPhase) 00185 { 00186 return fPhase - (2*M_PI)*floor(fPhase*M_1_2PI); 00187 } 00188 00189 // computes fPhase1 - fPhase2 as a fValue of [-pi,pi[ 00190 inline double util_phaseDifference(double fPhase1, double fPhase2) 00191 { 00192 return util_adjustedPhase(fPhase1 - fPhase2 + M_PI) - M_PI; 00193 } 00194 00195 // computes the average of fPhase1 and fPhase2 as a fValue of [0, 2pi[ 00196 inline double util_averagedPhase(double fPhase1, double fPhase2) 00197 { 00198 return util_adjustedPhase(fPhase1 + (util_phaseDifference(fPhase2,fPhase1)*0.5)); 00199 } 00200 00201 // exhanges the contents of two variables 00202 template <class Type> 00203 inline void util_swap(Type& a, Type& b) 00204 { 00205 Type swappy = a; 00206 a = b; b = swappy; 00207 } 00208 00209 #if defined _WIN32 00210 00211 #ifndef __HAS_SLEEP__ 00212 #define __HAS_SLEEP__ 00213 00214 // encapsulates the Win32 version of sleep called Sleep 00215 inline void sleep(unsigned int uiSec) 00216 { 00217 #if defined(NO_CAST_FUNCTION_TEMPLATES) 00218 Sleep(DWORD(uiSec*1000)); 00219 #else 00220 Sleep(static_cast<DWORD> (uiSec*1000)); 00221 #endif 00222 } 00223 #endif 00224 #endif 00225 00226 #if defined (__LINUX__) 00227 inline int EnterCriticalSection(CRITICAL_SECTION *cs) 00228 { 00229 pthread_mutex_lock(cs); 00230 return 0; 00231 } 00232 00233 inline int LeaveCriticalSection(CRITICAL_SECTION *cs) 00234 { 00235 pthread_mutex_unlock(cs); 00236 return 0; 00237 } 00238 00239 inline int InitializeCriticalSection(CRITICAL_SECTION *cs) 00240 { 00241 pthread_mutex_init(cs,NULL); 00242 pthread_mutex_unlock(cs); 00243 return 0; 00244 } 00245 00246 inline int DeleteCriticalSection(CRITICAL_SECTION *cs) 00247 { 00248 // pthread_mutex_exit(cs); 00249 return 0; 00250 } 00251 00252 inline int Sleep(long iMilliSec) 00253 { 00254 timespec tm, tm2; 00255 00256 tm.tv_sec=iMilliSec/1000; 00257 tm.tv_nsec=(iMilliSec%1000)*1000000; 00258 00259 nanosleep(&tm,&tm2); 00260 return 0; 00261 } 00262 #endif 00263 00264 #if defined (__QNX__) 00265 inline int EnterCriticalSection(CRITICAL_SECTION *cs) 00266 { 00267 sem_wait( (sem_t *)cs ); 00268 return 0; 00269 } 00270 inline int LeaveCriticalSection(CRITICAL_SECTION *cs) 00271 { 00272 sem_post( (sem_t *)cs ); 00273 return 0; 00274 } 00275 inline int InitializeCriticalSection(CRITICAL_SECTION *cs) 00276 { 00277 sem_init( (sem_t*)cs, 1, 1 ); 00278 return 0; 00279 } 00280 00281 inline int DeleteCriticalSection(CRITICAL_SECTION *cs) 00282 { 00283 // sem_exit((sem_t*) cs); 00284 sem_destroy( (sem_t*)cs ); 00285 return 0; 00286 } 00287 00288 inline int Sleep(long iMilliSec) 00289 { 00290 delay(iMilliSec); 00291 return 0; 00292 } 00293 #endif 00294 00295 // -------------------------------------------------------------------------- ; 00296 00297 // sets the alarm clock to the specified number of uiSec. 00298 /* 00299 sets the alarm clock to the specified number of uiSec. 00300 NOTE for UNIX-systems: see the manual pages for alarm(2) 00301 NOTE for WIN32-systems: does nothing! (just returns 0). 00302 uiSec: number of uiSec 00303 the amount of time previously remaining in the alarm clock. 00304 */ 00305 inline unsigned int util_setAlarm(unsigned int uiSec) 00306 { 00307 #ifdef _WIN32 00308 // there does not exist any alarm function for WIN32! 00309 return 0; 00310 #else 00311 return alarm(uiSec); 00312 #endif 00313 }; 00314 00315 // -------------------------------------------------------------------------- ; 00316 00317 // cancels any previously made alarm request. 00318 /* 00319 cancels any previously made alarm request. 00320 NOTE for UNIX-systems: see the manual pages for alarm(2) 00321 NOTE for WIN32-systems: does nothing! (just returns 0). 00322 the amount of time previously remaining in the alarm clock. 00323 */ 00324 inline unsigned int util_deactivateAlarm() 00325 { 00326 #ifdef _WIN32 00327 // there does not exist any alarm function for WIN32! 00328 return 0; 00329 #else 00330 return alarm(0); // if number of uiSec is equal 0, any previously 00331 // made alarm request is canceled 00332 #endif 00333 }; 00334 00335 #endif // UTIL_INLINEFUNCTIONS_H