|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
||||
|
||||
|
Re: Velocity PID Programming: Terms dependent on time
Quote:
There's a much more accurate system timer that is available: Timer::GetPPCTimestamp() has low overhead and returns time in seconds in double precision with 1/3 microsecond resolution. According to the WPILibC++Source20120204rev3111 source code date February 4 2012, it uses a 64-bit counter incrementing at 33MHz, which if true wouldn't overflow in your lifetime. Warning: I'm told that earlier versions of GetPPCTimestamp() used a 32-bit counter instead of 64, and would rollover every 130 seconds. Check the source code on your machine to make sure. Last edited by Ether : 30-01-2013 at 20:42. |
|
#2
|
|||
|
|||
|
Re: Velocity PID Programming: Terms dependent on time
There are 3 ways to get a timestamp in the 2013 WPILib C++ code. All of them are black box calls into lower level code, so the information here comes from the comments. If I have time tomorrow I will test timing on the cRIO and cRIO-II.
Timer::GetFPGATimestamp() and ::GetClock() -- double precision seconds since FPGA was reset. Uses FPGA clock so is synchronized with other FPGA timers. FPGA clock counts time in microseconds with an unsigned 32-bit integer. Rolls over every 71.6 minutes. (Timer::Reset does NOT reset the rollover.) Timer::GetPPCTimestamp() -- double precision seconds since cRIO was powered on. Uses PPC system clock so is not synchronized with FPGA timers. Hardcoded assumption of 33MHz in WPILib. The counter is fetched with niTimestamp64() so it's probably 64-bit and rolls over every 9 billion minutes. ::GetTime() -- double precision seconds since January 1, 1970. This uses the vxWorks real-time clock which I can't find documentation on. The API allows nanosecond precision which seems optimistic. |
|
#3
|
||||
|
||||
|
Re: Velocity PID Programming: Terms dependent on time
Anyone know if there is a common high-resolution timer that can be called from LabVIEW? I'm only familiar with the millisecond resolution timer that's available from the timing palette.
|
|
#4
|
||||
|
||||
|
Re: Velocity PID Programming: Terms dependent on time
Quote:
|
|
#5
|
||||
|
||||
|
Re: Velocity PID Programming: Terms dependent on time
While I do not claim the role of LabVIEW guru here, I remember once using LabVIEW's Code Interface Node (CIN) capability to write C code at a low level. I imagine this capability still exists within LabVIEW. I think it does but it has been years since I used it.
|
|
#6
|
|||||
|
|||||
|
Re: Velocity PID Programming: Terms dependent on time
Quote:
Look under Real Time -> RT Timing They use a 32-bit internal counter. Last edited by Mark McLeod : 31-01-2013 at 11:18. |
|
#7
|
||||
|
||||
|
Re: Velocity PID Programming: Terms dependent on time
I could be wrong, but in the context of this thread I think he wants to read a high resolution timer, not wait.
|
|
#8
|
|||||
|
|||||
|
Re: Velocity PID Programming: Terms dependent on time
I added the Tick Counter.
|
|
#9
|
||||
|
||||
|
Re: Velocity PID Programming: Terms dependent on time
Quote:
1) how many layers of code are wrapped around each of these timers, and 2) can each one be used in a critical section, and 3) how long does each take to execute, and 4) is there anybody who has authoritative answers to these questions |
|
#10
|
|||
|
|||
|
Re: Velocity PID Programming: Terms dependent on time
Quote:
WPILib uses these routines outside of critical regions, so I assume they are either lock-free or have their own independent locks. Testing may be the best way to answer these questions, but I'm also curious about the recommended/official way to handle time. It looks like the FPGA clock is preferred since the other ways of grabbing a timestamp aren't used by WPILib except in Vision. I'll collect some data on our cRIOs tomorrow. |
|
#11
|
||||
|
||||
|
Re: Velocity PID Programming: Terms dependent on time
Quote:
Code:
INCORRECT!! cli // disable interrupts /* do something uninterruptable here */ sti // enable interrupts Code:
CORRECT: pushf // save interrupt state cli // disable interrupts /* do something uninterruptable here */ popf // restore saved interrupt state Quote:
Quote:
|
|
#12
|
|||
|
|||
|
Re: Velocity PID Programming: Terms dependent on time
Quote:
Quote:
Over 100,000 calls, mean clock access times were: FPGA = 0.02320 msec PPC = 0.00048 msec vxWorks = 0.00172 msec The max elapsed time between subsequent calls was around 0.002 msec for all of them so my test was getting time sliced and the reported numbers are a bit high. The FPGA and PPC clocks have similar accuracy. I was wondering if the PPC clock wouldn't accurately track the FPGA clock, but elapsed times over short periods are within the error of my measurement. We also experimented measuring system performance with an external clock by generating a digital signal and capturing it with a logic analyzer sampling at 8MHz. We captured good data watching our periodic teleop code, but ran out of daylight before digging into system clock stuff. |
|
#13
|
|||
|
|||
|
Re: Velocity PID Programming: Terms dependent on time
I won't claim to be an authority on the LV-RT side of this, but I can help out a bit.
The ms timestamp in LV is very portable and has been in LV since the mac days. It is often used for simplicity when doing slower I/O and timing. Often, NI would have a card on the bus with a better time source that was synched to the I/O, but it would generally need to keep that timer operation controlled by the driver or the board. Bringing out out to user code in the loop would generally not make sense. RT OSes change that. You'll find there are numerous clocks and ways to access them. The simplest step is to use the RT Tick Count. In the attached image, it is configured for microseconds and I did a quick jitter test at time critical priority. It is zoomed in, but this is how it looked for the 100,000 iterations I took. Again, I'm not the authority, but this looks like it is based on the OS timer and clearly has some overhead. But it is a simple drop in replacement of the ms ticks and works for the OP question. For the PPC timer, I think you would use RT Get Timestamp.vi. I say think because I now realize that I don't have all of RT installed. I have much of it synched from a source server and not all of it is functional. If you read the help on the node, there is an example at the bottom for measuring an operation using this node. But I can't run it to give data. I'm curious to see if typical FRC install can. For the FPGA timer, access from RT code is via the serial bus and while available, the better use of this timer is within the FPGA circuit itself. This gives you implicit access to the 25ns clock that is driving your circuit. Greg McKaskle |
|
#14
|
|||
|
|||
|
Re: Velocity PID Programming: Terms dependent on time
Here's far more than anyone probably wanted to know about the clocks available with WPILib C++. I used 10 runs of 1000 clock accesses for each of the 3 clocks. I did this with the default task (thread) priority, high task priority, and high priority locked (which prevents the task from being scheduled off the cpu unless it explicitly blocks).
The clock of choice is definitely the PPC clock: Timer::GetPPCTimestamp. I experimented more with external timing with a signal analyzer and the external timing matched the PPC clock to +/- 4 microseconds. I only measured durations between 0.5 msec and 1.5 sec. It's kind of fun to see code profiled on a signal analyzer. Here's the inner loop of the test: Code:
#define RUN_TIMER_TEST(F) \
elapsed = last = Timer::GetPPCTimestamp(); \
for (j = 0; j < NumInnerIters; ++j) { \
now = F(); \
dt = now - last; \
if (j > 0) { \
if (dt > max_dt) max_dt = dt; \
if (dt < min_dt) min_dt = dt; \
} \
else { \
max_dt = 0.0; \
min_dt = 1.0; \
} \
last = now; \
} \
elapsed = Timer::GetPPCTimestamp() - elapsed; \
avg_dt = elapsed / NumInnerIters;
Code:
Clock name, Avg time per call (measured by PPC clock), Min delta time, Max delta time (as returned by clock under test) TIMING TEST - Normal FRC priority, task unlocked FPGA,0.00002835,0.00002300,0.00088700 FPGA,0.00002785,0.00002300,0.00080900 FPGA,0.00002644,0.00002300,0.00065500 FPGA,0.00002736,0.00002300,0.00087600 FPGA,0.00002860,0.00002300,0.00213800 FPGA,0.00002668,0.00002300,0.00062900 FPGA,0.00002698,0.00002300,0.00109000 FPGA,0.00002833,0.00002300,0.00179700 FPGA,0.00002706,0.00002300,0.00065600 FPGA,0.00002622,0.00002300,0.00064400 GetTime,0.00000171,0.00000143,0.00013781 GetTime,0.00000154,0.00000143,0.00002217 GetTime,0.00000186,0.00000143,0.00031662 GetTime,0.00000300,0.00000143,0.00085568 GetTime,0.00000155,0.00000143,0.00002766 GetTime,0.00000171,0.00000143,0.00014114 GetTime,0.00000154,0.00000143,0.00001907 GetTime,0.00000347,0.00000143,0.00190639 GetTime,0.00000153,0.00000143,0.00001216 GetTime,0.00000154,0.00000143,0.00001144 PPC,0.00000043,0.00000042,0.00000076 PPC,0.00000094,0.00000039,0.00051412 PPC,0.00000049,0.00000042,0.00006042 PPC,0.00000043,0.00000042,0.00000052 PPC,0.00000044,0.00000039,0.00001458 PPC,0.00000043,0.00000042,0.00000055 PPC,0.00000044,0.00000042,0.00000924 PPC,0.00000043,0.00000042,0.00000052 PPC,0.00000043,0.00000039,0.00000045 PPC,0.00000043,0.00000039,0.00000736 TIMING TEST - Highest priority, task unlocked FPGA,0.00002249,0.00002100,0.00005700 FPGA,0.00002248,0.00002100,0.00005100 FPGA,0.00002251,0.00002100,0.00006300 FPGA,0.00002252,0.00002100,0.00005500 FPGA,0.00002249,0.00002100,0.00005100 FPGA,0.00002248,0.00002100,0.00004900 FPGA,0.00002249,0.00002100,0.00005000 FPGA,0.00002248,0.00002100,0.00005100 FPGA,0.00002250,0.00002100,0.00004600 FPGA,0.00002248,0.00002100,0.00006000 GetTime,0.00000156,0.00000143,0.00002623 GetTime,0.00000155,0.00000143,0.00002289 GetTime,0.00000157,0.00000143,0.00002337 GetTime,0.00000155,0.00000143,0.00001884 GetTime,0.00000159,0.00000143,0.00002933 GetTime,0.00000156,0.00000143,0.00002670 GetTime,0.00000157,0.00000143,0.00002551 GetTime,0.00000157,0.00000143,0.00002885 GetTime,0.00000155,0.00000143,0.00002384 GetTime,0.00000155,0.00000143,0.00001431 PPC,0.00000043,0.00000042,0.00000094 PPC,0.00000045,0.00000039,0.00002179 PPC,0.00000046,0.00000042,0.00002609 PPC,0.00000043,0.00000042,0.00000094 PPC,0.00000045,0.00000039,0.00002306 PPC,0.00000043,0.00000039,0.00000045 PPC,0.00000043,0.00000042,0.00000045 PPC,0.00000044,0.00000039,0.00001088 PPC,0.00000043,0.00000042,0.00000045 PPC,0.00000044,0.00000042,0.00000988 TIMING TEST - Highest priority, task locked FPGA,0.00002047,0.00001900,0.00005600 FPGA,0.00002048,0.00001900,0.00006400 FPGA,0.00002048,0.00001900,0.00006900 FPGA,0.00002047,0.00001900,0.00006300 FPGA,0.00002046,0.00001900,0.00006900 FPGA,0.00002047,0.00001900,0.00005000 FPGA,0.00002048,0.00001900,0.00004700 FPGA,0.00002046,0.00001900,0.00006400 FPGA,0.00002049,0.00001900,0.00006800 FPGA,0.00002046,0.00001900,0.00005100 GetTime,0.00000155,0.00000143,0.00002122 GetTime,0.00000156,0.00000143,0.00002432 GetTime,0.00000158,0.00000143,0.00002551 GetTime,0.00000160,0.00000143,0.00002837 GetTime,0.00000157,0.00000143,0.00002694 GetTime,0.00000156,0.00000143,0.00002766 GetTime,0.00000155,0.00000143,0.00002146 GetTime,0.00000155,0.00000143,0.00002623 GetTime,0.00000157,0.00000143,0.00002432 GetTime,0.00000156,0.00000143,0.00002766 PPC,0.00000043,0.00000042,0.00000085 PPC,0.00000046,0.00000039,0.00002967 PPC,0.00000043,0.00000042,0.00000064 PPC,0.00000045,0.00000042,0.00001970 PPC,0.00000043,0.00000042,0.00000058 PPC,0.00000044,0.00000039,0.00000985 PPC,0.00000043,0.00000042,0.00000055 PPC,0.00000044,0.00000042,0.00001009 PPC,0.00000043,0.00000042,0.00000055 PPC,0.00000043,0.00000039,0.00000045 |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|