00001 /**************************************************************** 00002 * 00003 * Copyright (c) 2010 00004 * 00005 * Fraunhofer Institute for Manufacturing Engineering 00006 * and Automation (IPA) 00007 * 00008 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00009 * 00010 * Project name: care-o-bot 00011 * ROS stack name: cob_driver 00012 * ROS package name: cob_powercube_chain 00013 * Description: 00014 * 00015 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00016 * 00017 * Author: Felix Geibel, email:Felix.Geibel@gmx.de 00018 * Supervised by: Alexander Bubeck, email:alexander.bubeck@ipa.fhg.de 00019 * 00020 * Date of creation: Aug 2007 00021 * ToDo: 00022 * 00023 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00024 * 00025 * Redistribution and use in source and binary forms, with or without 00026 * modification, are permitted provided that the following conditions are met: 00027 * 00028 * * Redistributions of source code must retain the above copyright 00029 * notice, this list of conditions and the following disclaimer. 00030 * * Redistributions in binary form must reproduce the above copyright 00031 * notice, this list of conditions and the following disclaimer in the 00032 * documentation and/or other materials provided with the distribution. 00033 * * Neither the name of the Fraunhofer Institute for Manufacturing 00034 * Engineering and Automation (IPA) nor the names of its 00035 * contributors may be used to endorse or promote products derived from 00036 * this software without specific prior written permission. 00037 * 00038 * This program is free software: you can redistribute it and/or modify 00039 * it under the terms of the GNU Lesser General Public License LGPL as 00040 * published by the Free Software Foundation, either version 3 of the 00041 * License, or (at your option) any later version. 00042 * 00043 * This program is distributed in the hope that it will be useful, 00044 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00045 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00046 * GNU Lesser General Public License LGPL for more details. 00047 * 00048 * You should have received a copy of the GNU Lesser General Public 00049 * License LGPL along with this program. 00050 * If not, see <http://www.gnu.org/licenses/>. 00051 * 00052 ****************************************************************/ 00053 00054 #ifdef __LINUX__ 00055 #include <cob_powercube_chain/TimeStamp.h> 00056 #else 00057 #include <windows.h> 00058 #include <cob_powercube_chain/TimeStamp.h> 00059 00060 namespace RTB { 00061 #endif 00062 00063 //----------------------------------------------------------------------------- 00064 #ifdef __LINUX__ 00065 TimeStamp::TimeStamp() 00066 { 00067 m_TimeStamp.tv_sec = 0; 00068 m_TimeStamp.tv_nsec = 0; 00069 } 00070 00071 void TimeStamp::SetNow() 00072 { 00073 ::clock_gettime(CLOCK_REALTIME, &m_TimeStamp); 00074 } 00075 00076 double TimeStamp::TimespecToDouble(const ::timespec& LargeInt) 00077 { 00078 return double(LargeInt.tv_sec) + double(LargeInt.tv_nsec) / 1e9; 00079 } 00080 00081 ::timespec TimeStamp::DoubleToTimespec(double TimeS) 00082 { 00083 ::timespec DeltaTime; 00084 if (! ( TimeS < 4e9 && TimeS > 0.0 )) 00085 { 00086 DeltaTime.tv_sec = 0; 00087 DeltaTime.tv_nsec = 0; 00088 return DeltaTime; 00089 } 00090 00091 DeltaTime.tv_sec = ::time_t(TimeS); 00092 DeltaTime.tv_nsec 00093 = static_cast<long int>((TimeS - double(DeltaTime.tv_sec)) * 1e9); 00094 00095 return DeltaTime; 00096 } 00097 00098 double TimeStamp::operator-(const TimeStamp& EarlierTime) const 00099 { 00100 ::timespec Res; 00101 00102 Res.tv_sec = m_TimeStamp.tv_sec - EarlierTime.m_TimeStamp.tv_sec; 00103 Res.tv_nsec = m_TimeStamp.tv_nsec - EarlierTime.m_TimeStamp.tv_nsec; 00104 00105 if (Res.tv_nsec < 0) { 00106 Res.tv_sec--; 00107 Res.tv_nsec += 1000000000; 00108 } 00109 00110 return TimespecToDouble(Res); 00111 } 00112 00113 void TimeStamp::operator+=(double TimeS) 00114 { 00115 ::timespec Dbl = DoubleToTimespec(TimeS); 00116 m_TimeStamp.tv_sec += Dbl.tv_sec; 00117 m_TimeStamp.tv_nsec += Dbl.tv_nsec; 00118 if (m_TimeStamp.tv_nsec > 1000000000) 00119 { 00120 m_TimeStamp.tv_sec++; 00121 m_TimeStamp.tv_nsec -= 1000000000; 00122 } 00123 } 00124 00125 void TimeStamp::operator-=(double TimeS) 00126 { 00127 ::timespec Dbl = DoubleToTimespec(TimeS); 00128 m_TimeStamp.tv_sec -= Dbl.tv_sec; 00129 m_TimeStamp.tv_nsec -= Dbl.tv_nsec; 00130 if (m_TimeStamp.tv_nsec < 0.0) 00131 { 00132 m_TimeStamp.tv_sec--; 00133 m_TimeStamp.tv_nsec += 1000000000; 00134 } 00135 } 00136 00137 bool TimeStamp::operator>(const TimeStamp& Time) 00138 { 00139 if (m_TimeStamp.tv_sec > Time.m_TimeStamp.tv_sec) return true; 00140 if ((m_TimeStamp.tv_sec == Time.m_TimeStamp.tv_sec) && 00141 (m_TimeStamp.tv_nsec > Time.m_TimeStamp.tv_nsec)) return true; 00142 return false; 00143 } 00144 00145 bool TimeStamp::operator<(const TimeStamp& Time) 00146 { 00147 if (m_TimeStamp.tv_sec < Time.m_TimeStamp.tv_sec) return true; 00148 if ((m_TimeStamp.tv_sec == Time.m_TimeStamp.tv_sec) && 00149 (m_TimeStamp.tv_nsec < Time.m_TimeStamp.tv_nsec)) return true; 00150 return false; 00151 } 00152 00153 void TimeStamp::getTimeStamp(long& lSeconds, long& lNanoSeconds) 00154 { 00155 lSeconds = m_TimeStamp.tv_sec; 00156 lNanoSeconds = m_TimeStamp.tv_nsec; 00157 }; 00158 00159 void TimeStamp::setTimeStamp(const long& lSeconds, const long& lNanoSeconds) 00160 { 00161 m_TimeStamp.tv_sec = lSeconds; 00162 m_TimeStamp.tv_nsec = lNanoSeconds; 00163 }; 00164 00165 #else 00166 //------------------------------------------------------------------- 00167 00168 LARGE_INTEGER ClockFrequency; 00169 BOOL CounterHW = QueryPerformanceFrequency( &ClockFrequency ); 00170 double TimeStamp::m_SecPerCount = 1.0 / TimeStamp::LargeIntToDouble(ClockFrequency); 00171 double TimeStamp::m_DwordSize = double(0xFFFFFFFF); 00172 00173 //----------------------------------------------------------------------------- 00174 00175 TimeStamp::TimeStamp() 00176 { 00177 m_TimeStamp.HighPart = 0; 00178 m_TimeStamp.LowPart = 0; 00179 } 00180 00181 void TimeStamp::SetNow() 00182 { 00183 QueryPerformanceCounter( &m_TimeStamp ); 00184 } 00185 00186 double TimeStamp::LargeIntToDouble(const LARGE_INTEGER& LargeInt) 00187 { 00188 return LargeInt.HighPart * m_DwordSize + LargeInt.LowPart; 00189 } 00190 00191 LARGE_INTEGER TimeStamp::DoubleToLargeInt(double TimeS) 00192 { 00193 LARGE_INTEGER DeltaTime; 00194 DeltaTime.LowPart = 0; 00195 DeltaTime.HighPart = 0; 00196 if (! ( TimeS < 4e9 && TimeS > 0.0 )) return DeltaTime; 00197 DeltaTime.LowPart = (unsigned long)(TimeS / m_SecPerCount); 00198 return DeltaTime; 00199 } 00200 00201 double TimeStamp::operator-(const TimeStamp& EarlierTime) const 00202 { 00203 LARGE_INTEGER Res; 00204 Res.HighPart = m_TimeStamp.HighPart - EarlierTime.m_TimeStamp.HighPart; 00205 Res.LowPart = m_TimeStamp.LowPart - EarlierTime.m_TimeStamp.LowPart; 00206 if (EarlierTime.m_TimeStamp.LowPart > m_TimeStamp.LowPart) 00207 Res.HighPart--; 00208 return LargeIntToDouble(Res) * m_SecPerCount; 00209 } 00210 00211 void TimeStamp::operator+=(double TimeS) 00212 { 00213 LARGE_INTEGER& Dbl = DoubleToLargeInt(TimeS); 00214 LARGE_INTEGER Res; 00215 Res.LowPart = m_TimeStamp.LowPart + Dbl.LowPart; 00216 if ((Res.LowPart < m_TimeStamp.LowPart) || (Res.LowPart < Dbl.LowPart)) 00217 m_TimeStamp.HighPart++; 00218 m_TimeStamp.LowPart = Res.LowPart; 00219 } 00220 00221 void TimeStamp::operator-=(double TimeS) 00222 { 00223 LARGE_INTEGER& Dbl = DoubleToLargeInt(TimeS); 00224 LARGE_INTEGER Res; 00225 Res.LowPart = m_TimeStamp.LowPart - Dbl.LowPart; 00226 Res.HighPart = m_TimeStamp.HighPart - Dbl.HighPart; 00227 if ((Res.LowPart > m_TimeStamp.LowPart)) 00228 Res.HighPart--; 00229 m_TimeStamp.LowPart = Res.LowPart; 00230 m_TimeStamp.HighPart = Res.HighPart; 00231 } 00232 00233 bool TimeStamp::operator>(const TimeStamp& Time) 00234 { 00235 if (m_TimeStamp.HighPart > Time.m_TimeStamp.HighPart) return true; 00236 if ((m_TimeStamp.HighPart == Time.m_TimeStamp.HighPart) && 00237 (m_TimeStamp.LowPart > Time.m_TimeStamp.LowPart)) return true; 00238 return false; 00239 } 00240 00241 bool TimeStamp::operator<(const TimeStamp& Time) 00242 { 00243 if (m_TimeStamp.HighPart < Time.m_TimeStamp.HighPart) return true; 00244 if ((m_TimeStamp.HighPart == Time.m_TimeStamp.HighPart) && 00245 (m_TimeStamp.LowPart < Time.m_TimeStamp.LowPart)) return true; 00246 return false; 00247 } 00248 } 00249 #endif 00250