Skip to content

timestamp inaccuracy on Windows #934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
danielhrisca opened this issue Nov 14, 2020 · 9 comments
Closed

timestamp inaccuracy on Windows #934

danielhrisca opened this issue Nov 14, 2020 · 9 comments

Comments

@danielhrisca
Copy link
Contributor

The function time.time is not reliable for setting the time stamps on Windows.

Even if the resolution is good enough, the value returned by time.time is updated according to the interval Windows timer (see https://stackoverflow.com/questions/1938048/high-precision-clock-in-python)

On my PC this defaults to 10ms steps which in my opinion is a very high inaccuracy.

@christiansandberg
Copy link
Collaborator

Which context are you referring to? Message timestamps are derived by hardware when possible, but some interfaces simply don't provide this in which case we use time.time() as a fallback.

@danielhrisca
Copy link
Contributor Author

danielhrisca commented Nov 14, 2020

I was looking for example at the Vector implementation were an offset is computed based on time.time

@christiansandberg
Copy link
Collaborator

That's just to convert from relative to absolute timestamps. There will obviously be an absolute error due the fact that we don't read the hardware time and PC time simultaneously but relative accuracy between messages will still be very accurate.

@danielhrisca
Copy link
Contributor Author

I my use case I need to synchronize the CAN messages with some other device data, using the PC time as reference. How could I do this as accurately as possible?

@christiansandberg
Copy link
Collaborator

I don't know a better way unfortunately. Maybe you could measure the error somehow and compensate with an offset. Feel free to improve it!

@hardbyte
Copy link
Owner

The resolution of time.time using a recent Python on a recent windows is <1ms - see https://www.python.org/dev/peps/pep-0564/#windows but if you want to suggest an improvement feel free.

@danielhrisca
Copy link
Contributor Author

@hardbyte the resolution is good but the value is refreshed at best every ~0.5ms if you change the Windows timer interval. By default it is set at ~10ms. Running the test code from the linked SO thread will show this clearly

@hardbyte
Copy link
Owner

Hmm I got ~1ms (not ~10ms) on a windows laptop without changing anything. I'm not convinced we can do much better from python-can?

I ran this:

import time

# measure the smallest time delta by spinning until the time changes
def measure():
    t0 = time.time()
    t1 = t0
    while t1 == t0:
        t1 = time.time()
    return t1-t0

samples = [measure() for i in range(30)]

for s in samples:
    print(f'time delta: {s:.12f} seconds') 

I see time delta: 0.000000238419 seconds on Linux and time delta: 0.001001238419 seconds on Windows.

danielhrisca added a commit to danielhrisca/python-can that referenced this issue Nov 15, 2020
… buses on the Windows platform. (see hardbyte#934)

On Windows the value returned by time.time is refreshed at best every 0.5ms, and on some PCs the default refresh rate is every 10ms.

The idea is to get the value of time.perf_counter at the moment when time.time is refreshed and use this as a reference point.
@danielhrisca
Copy link
Contributor Author

@hardbyte @christiansandberg
I've send PR #936 to improve the accuracy for Vector and Kvaser buses

hardbyte pushed a commit that referenced this issue Jan 18, 2021
* fixes #732: add support for VN8900 xlGetChannelTime function
* improve time stamp accuracy of the CAN messages for Kvaser and Vector buses on the Windows platform. (see #934)
On Windows the value returned by time.time is refreshed at best every 0.5ms, and on some PCs the default refresh rate is every 10ms. The idea is to get the value of time.perf_counter at the moment when time.time is refreshed and use this as a reference point.
* check the time.time resolution before using the new time correlation function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants