Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpTime.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See https://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * Time management and measurement.
33 *
34*****************************************************************************/
35
36#include <ctime>
37
38#include <visp3/core/vpDebug.h>
39#include <visp3/core/vpTime.h>
40
41// https://devblogs.microsoft.com/cppblog/c14-stl-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
42#if VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11 && \
43 (defined(_MSC_VER) && _MSC_VER >= 1900 /* VS2015 */ || !defined(_MSC_VER))
44#define USE_CXX11_CHRONO 1
45#else
46#define USE_CXX11_CHRONO 0
47#endif
48
54// Unix depend version
55
56#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
57#include <sys/time.h>
58#include <unistd.h>
59#elif defined(_WIN32)
60//#include <winbase.h>
61#include <windows.h>
62#endif
63
64#ifndef DOXYGEN_SHOULD_SKIP_THIS
65namespace vpTime
66{
67#endif
68
76static const double minTimeForUsleepCall = 4;
77
83double getMinTimeForUsleepCall() { return minTimeForUsleepCall; }
84
90double measureTimeMicros()
91{
92#if USE_CXX11_CHRONO
93 std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
94 return std::chrono::duration<double, std::micro>(now.time_since_epoch()).count();
95#else
96#if defined(_WIN32)
97#if !defined(WINRT)
98 LARGE_INTEGER time, frequency;
99 QueryPerformanceFrequency(&frequency);
100 if (frequency.QuadPart == 0) {
101 return (timeGetTime());
102 }
103 else {
104 QueryPerformanceCounter(&time);
105 return (double)(1000000.0 * time.QuadPart / frequency.QuadPart);
106 }
107#else
108 throw(vpException(vpException::fatalError, "Cannot get time: not implemented on Universal Windows Platform"));
109#endif
110#elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
111 struct timeval tp;
112 gettimeofday(&tp, 0);
113 return (1000000.0 * tp.tv_sec + tp.tv_usec);
114#endif
115#endif
116}
117
124double measureTimeMs()
125{
126#if USE_CXX11_CHRONO
127 std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
128 return std::chrono::duration<double, std::milli>(now.time_since_epoch()).count();
129#else
130#if defined(_WIN32)
131#if !defined(WINRT)
132 LARGE_INTEGER time, frequency;
133 QueryPerformanceFrequency(&frequency);
134 if (frequency.QuadPart == 0) {
135 return (timeGetTime());
136 }
137 else {
138 QueryPerformanceCounter(&time);
139 return (double)(1000.0 * time.QuadPart / frequency.QuadPart);
140 }
141#else
142 throw(vpException(vpException::fatalError, "Cannot get time: not implemented on Universal Windows Platform"));
143#endif
144#elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
145 struct timeval tp;
146 gettimeofday(&tp, 0);
147 return (1000.0 * tp.tv_sec + tp.tv_usec / 1000.0);
148#endif
149#endif
150}
151
157double measureTimeSecond() { return vpTime::measureTimeMs() * 1e-3; }
158
172int wait(double t0, double t)
173{
174 double timeCurrent, timeToWait;
175 timeCurrent = measureTimeMs();
176
177 timeToWait = t0 + t - timeCurrent;
178
179 if (timeToWait <= 0.) // no need to wait
180 return (1);
181 else {
182#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
183 if (timeToWait > vpTime::minTimeForUsleepCall) {
184 usleep((useconds_t)((timeToWait - vpTime::minTimeForUsleepCall) * 1000));
185 }
186 // Blocking loop to have an accurate waiting
187 do {
188 timeCurrent = measureTimeMs();
189 timeToWait = t0 + t - timeCurrent;
190
191 } while (timeToWait > 0.);
192
193 return 0;
194#elif defined(_WIN32)
195#if !defined(WINRT_8_0)
196 if (timeToWait > vpTime::minTimeForUsleepCall) {
197 Sleep((DWORD)(timeToWait - vpTime::minTimeForUsleepCall));
198 }
199 // Blocking loop to have an accurate waiting
200 do {
201 timeCurrent = measureTimeMs();
202 timeToWait = t0 + t - timeCurrent;
203
204 } while (timeToWait > 0.);
205
206 return 0;
207#else
209 "vpTime::wait() is not implemented on Windows Phone 8.0"));
210#endif
211#endif
212 }
213}
214
223void wait(double t)
224{
225 double timeToWait = t;
226
227 if (timeToWait <= 0.) // no need to wait
228 return;
229 else {
230#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
231 double t0 = measureTimeMs();
232 if (timeToWait > vpTime::minTimeForUsleepCall) {
233 usleep((useconds_t)((timeToWait - vpTime::minTimeForUsleepCall) * 1000));
234 }
235 // Blocking loop to have an accurate waiting
236 do {
237 double timeCurrent = measureTimeMs();
238 timeToWait = t0 + t - timeCurrent;
239
240 } while (timeToWait > 0.);
241
242 return;
243#elif defined(_WIN32)
244#if !defined(WINRT_8_0)
245 double t0 = measureTimeMs();
246 if (timeToWait > vpTime::minTimeForUsleepCall) {
247 Sleep((DWORD)(timeToWait - vpTime::minTimeForUsleepCall));
248 }
249 // Blocking loop to have an accurate waiting
250 do {
251 double timeCurrent = measureTimeMs();
252 timeToWait = t0 + t - timeCurrent;
253
254 } while (timeToWait > 0.);
255
256 return;
257#else
259 "vpTime::wait() is not implemented on Windows Phone 8.0"));
260#endif
261#endif
262 }
263}
264
270void sleepMs(double t)
271{
272#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
273 usleep((useconds_t)(t * 1000));
274#elif defined(_WIN32)
275#if !defined(WINRT_8_0)
276 Sleep((DWORD)(t));
277#else
279 "vpTime::sleepMs() is not implemented on Windows Phone 8.0"));
280#endif
281#endif
282}
283
357std::string getDateTime(const std::string &format)
358{
359 time_t rawtime;
360 struct tm *timeinfo;
361 char buffer[80];
362
363 time(&rawtime);
364 timeinfo = localtime(&rawtime);
365
366 strftime(buffer, 80, format.c_str(), timeinfo);
367 std::string str(buffer);
368
369 return str;
370}
371
372#ifndef DOXYGEN_SHOULD_SKIP_THIS
373};
374#endif
375
376vpChrono::vpChrono() : m_durationMs(), m_lastTimePoint() { }
377
381double vpChrono::getDurationMicros() { return m_durationMs * 1e3; }
382
386double vpChrono::getDurationMs() { return m_durationMs; }
387
391double vpChrono::getDurationSeconds() { return m_durationMs * 1e-3; }
392
397void vpChrono::start(bool reset)
398{
399#if USE_CXX11_CHRONO
400 m_lastTimePoint = std::chrono::steady_clock::now();
401#else
402 m_lastTimePoint = vpTime::measureTimeMs();
403#endif
404 if (reset) {
405 m_durationMs = 0.0;
406 }
407}
408
413{
414#if USE_CXX11_CHRONO
415 m_durationMs += std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - m_lastTimePoint).count();
416#else
417 m_durationMs += vpTime::measureTimeMs() - m_lastTimePoint;
418#endif
419}
void start(bool reset=true)
Definition vpTime.cpp:397
void stop()
Definition vpTime.cpp:412
double getDurationSeconds()
Definition vpTime.cpp:391
double getDurationMs()
Definition vpTime.cpp:386
double getDurationMicros()
Definition vpTime.cpp:381
error that can be emitted by ViSP classes.
Definition vpException.h:59
@ functionNotImplementedError
Function not implemented.
Definition vpException.h:78
@ fatalError
Fatal error.
Definition vpException.h:84
Time management and measurement.
Definition vpTime.h:73
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMicros()
VISP_EXPORT double getMinTimeForUsleepCall()
VISP_EXPORT double measureTimeSecond()
VISP_EXPORT void sleepMs(double t)
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")
VISP_EXPORT double measureTimeMs()