Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpTime.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Time management and measurement.
32 */
33
38
39#include <ctime>
40
41#include <visp3/core/vpTime.h>
42
43// https://devblogs.microsoft.com/cppblog/c14-stl-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
44#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) && \
45 (defined(_MSC_VER) && _MSC_VER >= 1900 /* VS2015 */ || !defined(_MSC_VER))
46#define USE_CXX11_CHRONO 1
47#else
48#define USE_CXX11_CHRONO 0
49#endif
50
51// Unix depend version
52
53#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
54#include <sys/time.h>
55#include <unistd.h>
56#elif defined(_WIN32)
57//#include <winbase.h>// Mute warning with clang-cl
58// warning : non-portable path to file '<Windows.h>'; specified path differs in case from file name on disk [-Wnonportable-system-include-path]
59#if defined(__clang__)
60# pragma clang diagnostic push
61# pragma clang diagnostic ignored "-Wnonportable-system-include-path"
62#endif
63
64#include <windows.h>
65
66#if defined(__clang__)
67# pragma clang diagnostic pop
68#endif
69
70#endif
71
73#ifndef DOXYGEN_SHOULD_SKIP_THIS
74namespace vpTime
75{
76#endif
77
85static const double minTimeForUsleepCall = 4;
86
92double getMinTimeForUsleepCall() { return minTimeForUsleepCall; }
93
99double measureTimeMicros()
100{
101#if USE_CXX11_CHRONO
102 std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
103 return std::chrono::duration<double, std::micro>(now.time_since_epoch()).count();
104#else
105#if defined(_WIN32)
106#if !defined(WINRT)
107 LARGE_INTEGER time, frequency;
108 QueryPerformanceFrequency(&frequency);
109 if (frequency.QuadPart == 0) {
110 return (timeGetTime());
111 }
112 else {
113 QueryPerformanceCounter(&time);
114 return static_cast<double>(1000000.0 * time.QuadPart / frequency.QuadPart);
115 }
116#else
117 throw(vpException(vpException::fatalError, "Cannot get time: not implemented on Universal Windows Platform"));
118#endif
119#elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
120 struct timeval tp;
121 gettimeofday(&tp, 0);
122 return (1000000.0 * tp.tv_sec + tp.tv_usec);
123#endif
124#endif
125}
126
133double measureTimeMs()
134{
135#if USE_CXX11_CHRONO
136 std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
137 return std::chrono::duration<double, std::milli>(now.time_since_epoch()).count();
138#else
139#if defined(_WIN32)
140#if !defined(WINRT)
141 LARGE_INTEGER time, frequency;
142 QueryPerformanceFrequency(&frequency);
143 if (frequency.QuadPart == 0) {
144 return (timeGetTime());
145 }
146 else {
147 QueryPerformanceCounter(&time);
148 return static_cast<double>(1000.0 * time.QuadPart / frequency.QuadPart);
149 }
150#else
151 throw(vpException(vpException::fatalError, "Cannot get time: not implemented on Universal Windows Platform"));
152#endif
153#elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
154 struct timeval tp;
155 gettimeofday(&tp, 0);
156 return (1000.0 * tp.tv_sec + tp.tv_usec / 1000.0);
157#endif
158#endif
159}
160
166double measureTimeSecond() { return vpTime::measureTimeMs() * 1e-3; }
167
181int wait(double t0, double t)
182{
183 double timeCurrent, timeToWait;
184 timeCurrent = measureTimeMs();
185
186 timeToWait = t0 + (t - timeCurrent);
187
188 if (timeToWait <= 0.) { // no need to wait
189 return 1;
190 }
191 else {
192#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
193 if (timeToWait > vpTime::minTimeForUsleepCall) {
194 usleep(static_cast<useconds_t>((timeToWait - vpTime::minTimeForUsleepCall) * 1000));
195 }
196 // Blocking loop to have an accurate waiting
197 do {
198 timeCurrent = measureTimeMs();
199 timeToWait = t0 + (t - timeCurrent);
200
201 } while (timeToWait > 0.);
202
203 return 0;
204#elif defined(_WIN32)
205#if !defined(WINRT_8_0)
206 if (timeToWait > vpTime::minTimeForUsleepCall) {
207 Sleep(static_cast<DWORD>(timeToWait - vpTime::minTimeForUsleepCall));
208 }
209 // Blocking loop to have an accurate waiting
210 do {
211 timeCurrent = measureTimeMs();
212 timeToWait = t0 + t - timeCurrent;
213
214 } while (timeToWait > 0.);
215
216 return 0;
217#else
219 "vpTime::wait() is not implemented on Windows Phone 8.0"));
220#endif
221#endif
222 }
223}
224
233void wait(double t)
234{
235 double timeToWait = t;
236
237 if (timeToWait <= 0.) { // no need to wait
238 return;
239 }
240 else {
241#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
242 double t0 = measureTimeMs();
243 if (timeToWait > vpTime::minTimeForUsleepCall) {
244 usleep(static_cast<useconds_t>((timeToWait - vpTime::minTimeForUsleepCall) * 1000));
245 }
246 // Blocking loop to have an accurate waiting
247 do {
248 double timeCurrent = measureTimeMs();
249 timeToWait = t0 + (t - timeCurrent);
250
251 } while (timeToWait > 0.);
252
253 return;
254#elif defined(_WIN32)
255#if !defined(WINRT_8_0)
256 double t0 = measureTimeMs();
257 if (timeToWait > vpTime::minTimeForUsleepCall) {
258 Sleep(static_cast<DWORD>(timeToWait - vpTime::minTimeForUsleepCall));
259 }
260 // Blocking loop to have an accurate waiting
261 do {
262 double timeCurrent = measureTimeMs();
263 timeToWait = t0 + t - timeCurrent;
264
265 } while (timeToWait > 0.);
266
267 return;
268#else
270 "vpTime::wait() is not implemented on Windows Phone 8.0"));
271#endif
272#endif
273 }
274}
275
281void sleepMs(double t)
282{
283#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
284 usleep(static_cast<useconds_t>(t * 1000));
285#elif defined(_WIN32)
286#if !defined(WINRT_8_0)
287 Sleep(static_cast<DWORD>(t));
288#else
290 "vpTime::sleepMs() is not implemented on Windows Phone 8.0"));
291#endif
292#endif
293}
294
371std::string getDateTime(const std::string &format)
372{
373 time_t rawtime;
374 struct tm *timeinfo;
375 char buffer[80];
376
377 time(&rawtime);
378 timeinfo = localtime(&rawtime);
379
380 strftime(buffer, 80, format.c_str(), timeinfo);
381 std::string str(buffer);
382
383 return str;
384}
385
386#ifndef DOXYGEN_SHOULD_SKIP_THIS
387}
388#endif
389
390vpChrono::vpChrono() : m_durationMs(), m_lastTimePoint() { }
391
395double vpChrono::getDurationMicros() { return m_durationMs * 1e3; }
396
400double vpChrono::getDurationMs() { return m_durationMs; }
401
405double vpChrono::getDurationSeconds() { return m_durationMs * 1e-3; }
406
411void vpChrono::start(bool reset)
412{
413#if USE_CXX11_CHRONO
414 m_lastTimePoint = std::chrono::steady_clock::now();
415#else
416 m_lastTimePoint = vpTime::measureTimeMs();
417#endif
418 if (reset) {
419 m_durationMs = 0.0;
420 }
421}
422
427{
428#if USE_CXX11_CHRONO
429 m_durationMs += std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - m_lastTimePoint).count();
430#else
431 m_durationMs += vpTime::measureTimeMs() - m_lastTimePoint;
432#endif
433}
434END_VISP_NAMESPACE
void start(bool reset=true)
Definition vpTime.cpp:411
void stop()
Definition vpTime.cpp:426
double getDurationSeconds()
Definition vpTime.cpp:405
double getDurationMs()
Definition vpTime.cpp:400
double getDurationMicros()
Definition vpTime.cpp:395
@ functionNotImplementedError
Function not implemented.
Definition vpException.h:66
@ fatalError
Fatal error.
Definition vpException.h:72
Time management and measurement.
Definition vpTime.h:78
VISP_EXPORT double measureTimeMs()
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")