High Resolution Timer
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
High Resolution Timer
Hey Guys,
I'm developing a real time application that needs accuracy to 1 millisecond or less.
Does your software provide accurate timing?
If the accuracy is not there I was considering using the Revolution SDK and incorporating the high resolution timers supplied by the Win32 API?
Thanks!
I'm developing a real time application that needs accuracy to 1 millisecond or less.
Does your software provide accurate timing?
If the accuracy is not there I was considering using the Revolution SDK and incorporating the high resolution timers supplied by the Win32 API?
Thanks!
Hi cmenge,
Revolution provides a milliseconds function. Check out the built-in docs.
Note, however, that Revolution's performance is highly influanced by other system tasks. I don't know what you want to measure, but I would be a little careful. Revolution is very likely to measure with an inaccuracy of at least 2 or 3 milliseconds. If you can include the entire procedure in an external, I'd recommend doing so.
Best,
Mark
Revolution provides a milliseconds function. Check out the built-in docs.
Note, however, that Revolution's performance is highly influanced by other system tasks. I don't know what you want to measure, but I would be a little careful. Revolution is very likely to measure with an inaccuracy of at least 2 or 3 milliseconds. If you can include the entire procedure in an external, I'd recommend doing so.
Best,
Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode
Mark,
I appreciate the feedback; can you detail what you mean by the following?
In our current application we are using Win32 threads set to a hi priority, this is the only way to keep timing accurate and solid.
Cheers!
I appreciate the feedback; can you detail what you mean by the following?
By using the word "external" are you recomending the Revolution SDK and incorporate into a Revolution script?If you can include the entire procedure in an external, I'd recommend doing so.
In our current application we are using Win32 threads set to a hi priority, this is the only way to keep timing accurate and solid.
Cheers!
hi cmenge,
I have little details for you, as I never needed accurate timing. If I use the millisecs, it is just to have some indication of the time, not because of scientific measurements.
When you compile and run a script, Revolution will eat up something between 0 and 2 millisecs, possibly more, before actually running the script. So, the measured value will always be slightly inaccurate. Usually, this is not a problem for me, but for scientific research it is.
Now, everything depends on what you try to accomplish and how. A script such as
on mouseUp
put the millisecs into myMills
repeat 10
wait 100 millisecs
put the millisecs - myMills & return after fld 1
end repeat
end mouseUp
will return very inaccurate results. Here is a similar example that shows Rev's inaccuracy:
on mouseUp
put the millisecs into myMills
repeat 100
wait 10 millisecs
put the millisecs - myMills & return after fld 1
put the millisecs into myMills
end repeat
end mouseUp
(For both scripts, you need a button that contains the script and a field to put the data into).
On my rather slow machine, the second script is off by more than 100% during some of its cycles, even though one would expect the first line after the wait to execute rather quickly.
Of course, all this is explainable, since there are statements being executed between the moments of measurement. It does demonstrate, though, that by consequence of the need to read and display the values, Revolution will never display a fully accurate result. Revolution is just too slow for that. I don't think that setting Rev's threads to a high priority will help.
If you can make an external that creates a list of measurement points and gives back control to Revolution after doing the last measurement, that might give you better results (Yes, it is the external SDK that should give you some insight into creating externals). My advice, though, is to use an external device to do the measurements. Then have Revolution read the data from this device.
Best,
Mark
I have little details for you, as I never needed accurate timing. If I use the millisecs, it is just to have some indication of the time, not because of scientific measurements.
When you compile and run a script, Revolution will eat up something between 0 and 2 millisecs, possibly more, before actually running the script. So, the measured value will always be slightly inaccurate. Usually, this is not a problem for me, but for scientific research it is.
Now, everything depends on what you try to accomplish and how. A script such as
on mouseUp
put the millisecs into myMills
repeat 10
wait 100 millisecs
put the millisecs - myMills & return after fld 1
end repeat
end mouseUp
will return very inaccurate results. Here is a similar example that shows Rev's inaccuracy:
on mouseUp
put the millisecs into myMills
repeat 100
wait 10 millisecs
put the millisecs - myMills & return after fld 1
put the millisecs into myMills
end repeat
end mouseUp
(For both scripts, you need a button that contains the script and a field to put the data into).
On my rather slow machine, the second script is off by more than 100% during some of its cycles, even though one would expect the first line after the wait to execute rather quickly.
Of course, all this is explainable, since there are statements being executed between the moments of measurement. It does demonstrate, though, that by consequence of the need to read and display the values, Revolution will never display a fully accurate result. Revolution is just too slow for that. I don't think that setting Rev's threads to a high priority will help.
If you can make an external that creates a list of measurement points and gives back control to Revolution after doing the last measurement, that might give you better results (Yes, it is the external SDK that should give you some insight into creating externals). My advice, though, is to use an external device to do the measurements. Then have Revolution read the data from this device.
Best,
Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode
Hi Mark,
I appreciate the detailed response; it really does help give us a better understanding of Revolution.
We sell electric motion bases, the kind of stuff you might see at a theme park. These bases are usually controlled by some type of 3D interactive computer simulation, could be a driving game, fling, boating, space ship, etc.
We would like to uses Revolution to develop an application that will communicate via sockets with the 3D simulation. The 3D game application will generate telemetry (Yaw, Pitch, Roll) via its physics engine. The Revolution software will then receive this telemetry from the 3D simulation via UDP sockets and move the motion base.
This is where the timing comes in; we need a solid steady loop in the motion control application. On average this thread will need to run at approximately 90 Hz +/- 5 Hz.
What we really need is stability; I need to be able to modify the priority of a script so it will always run at a solid frame rate. In Windows you can increase a process or specific threads priority and most times this will give a solid frame rate.
My thought is to have a ReadData( ) function. This function would read all of the data coming from the 3D simulation and store the data in a global structure for processing. This ReadData() function will need to run at a solid frame rate; the user will drag a slider to increase or decrease this frame rate compensating for a faster or slower machine. 90Hz is just over 11.1 milliseconds per frame. If I can get a solid 11.1 milliseconds this just might work.
Is it possible to generate a solid frame rate with a specific function call/scrip in Revolution?
I appreciate the detailed response; it really does help give us a better understanding of Revolution.
We sell electric motion bases, the kind of stuff you might see at a theme park. These bases are usually controlled by some type of 3D interactive computer simulation, could be a driving game, fling, boating, space ship, etc.
We would like to uses Revolution to develop an application that will communicate via sockets with the 3D simulation. The 3D game application will generate telemetry (Yaw, Pitch, Roll) via its physics engine. The Revolution software will then receive this telemetry from the 3D simulation via UDP sockets and move the motion base.
This is where the timing comes in; we need a solid steady loop in the motion control application. On average this thread will need to run at approximately 90 Hz +/- 5 Hz.
What we really need is stability; I need to be able to modify the priority of a script so it will always run at a solid frame rate. In Windows you can increase a process or specific threads priority and most times this will give a solid frame rate.
My thought is to have a ReadData( ) function. This function would read all of the data coming from the 3D simulation and store the data in a global structure for processing. This ReadData() function will need to run at a solid frame rate; the user will drag a slider to increase or decrease this frame rate compensating for a faster or slower machine. 90Hz is just over 11.1 milliseconds per frame. If I can get a solid 11.1 milliseconds this just might work.
Is it possible to generate a solid frame rate with a specific function call/scrip in Revolution?
hi cmegne,
The following non-functional demo script might indeed "just" work. I assume that the simulating software is on one socket and your motion base on another.
on startReading
put "Localhost:1010" into mySocket --or any other socket
open datagram socket mySocket
open datagram socket "192.168.0.99:1234" -- socket of your hardware
-- give the similating software a value
write someVarWithValue to socket mySocket
read from socket mySocket until return with message "rcvData"
end startReading
on rcvData theSock,theMsg
-- I guess you want a list of values in a field
put theMsg & return after fld "keep an eye in this"
-- send theMsg to your motion base
write theMsg to socket "192.168.0.99:1234"
read from socket theSock with msg rcvData
end rcvData
You may need a three-tier script or something more complex even. This script would just read the data from the socket whenever it comes available. If you leave the sockets open, you might have the speed you need, although I consider it impossible to send data to your motion base exactly every 11.1 milliseconds.
Best,
Mark
The following non-functional demo script might indeed "just" work. I assume that the simulating software is on one socket and your motion base on another.
on startReading
put "Localhost:1010" into mySocket --or any other socket
open datagram socket mySocket
open datagram socket "192.168.0.99:1234" -- socket of your hardware
-- give the similating software a value
write someVarWithValue to socket mySocket
read from socket mySocket until return with message "rcvData"
end startReading
on rcvData theSock,theMsg
-- I guess you want a list of values in a field
put theMsg & return after fld "keep an eye in this"
-- send theMsg to your motion base
write theMsg to socket "192.168.0.99:1234"
read from socket theSock with msg rcvData
end rcvData
You may need a three-tier script or something more complex even. This script would just read the data from the socket whenever it comes available. If you leave the sockets open, you might have the speed you need, although I consider it impossible to send data to your motion base exactly every 11.1 milliseconds.
Best,
Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode
Hi Mark,
I'll give your code a try thank you very much. Yes the timing can be very tricky. When I first developed the motion control application four, five years ago setting up the Windows thread and high resolution timer was very difficult. It took several months of trial and error but we finally got something that was almost perfect +/- 3 milliseconds for each frame.
My initial thought would be to try what you have posted but my guess is that we will take our C++ ReadData() function and create a DLL with the Revolution SDK. This will allow us to combine the benefits of Revolution script and previous C++ development.
I'll post an update once we have completed testing.
Cheers!
P.S. One more quick thought, I noticed with your sample code you are waiting for data, essentially in Windows terms a blocked socket. This would be a problem in real time programming, potentially causing long delays in processing code. I'm not sure this will be a problem with Revolution? If I'm getting things right each script is message based and does not necessarily hold up the main processing loop.
I'm I correct?
I'll give your code a try thank you very much. Yes the timing can be very tricky. When I first developed the motion control application four, five years ago setting up the Windows thread and high resolution timer was very difficult. It took several months of trial and error but we finally got something that was almost perfect +/- 3 milliseconds for each frame.
My initial thought would be to try what you have posted but my guess is that we will take our C++ ReadData() function and create a DLL with the Revolution SDK. This will allow us to combine the benefits of Revolution script and previous C++ development.
I'll post an update once we have completed testing.
Cheers!
P.S. One more quick thought, I noticed with your sample code you are waiting for data, essentially in Windows terms a blocked socket. This would be a problem in real time programming, potentially causing long delays in processing code. I'm not sure this will be a problem with Revolution? If I'm getting things right each script is message based and does not necessarily hold up the main processing loop.
I'm I correct?
By the way,
If you use the same code from above like this:
You will find that there may be only an offset of 1 millisecond. Anytime
you set text of a GUI element it is going to take time. So when doing
timing for more critical needs, you don't want to be setting the text of
anything until after the timing is done.
Here are the results of setting the text of the field while in the loop:
And the results of setting the results into the field after the loop is done:
-Garrett
If you use the same code from above like this:
Code: Select all
on mouseUp
put empty into field "fMilliseconds"
put the millisecs into varMilliseconds
repeat 10
wait 100 millisecs
put the millisecs - varMilliseconds & return after varResults
end repeat
put varResults into field "fMilliseconds"
end mouseUp
you set text of a GUI element it is going to take time. So when doing
timing for more critical needs, you don't want to be setting the text of
anything until after the timing is done.
Here are the results of setting the text of the field while in the loop:
Code: Select all
100
203
307
410
513
616
720
823
926
1029
Code: Select all
100
200
301
401
501
601
701
801
901
1001
Ehhh, sorry if I doubled up on your point.Mark wrote:Hi Garett,
That was exactly my point.
Best,
Mark
I must add though that I'm rather happy with the fact that only a mere
single millisecond might be lost. Try this in other languages that offer as
much as Rev does and I bet you lose more than a single millisecond.
-Garrett
Hi Garrett,
What other languages offer as much as Rev does? ;-)
I completely agree that 1 millisec off is a great performance, but if human lives are involved, I wouldn't count on it.
Best,
Mark
What other languages offer as much as Rev does? ;-)
I completely agree that 1 millisec off is a great performance, but if human lives are involved, I wouldn't count on it.
Best,
Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode
Other languages that offer as much, but not as great as Rev are:Mark wrote:Hi Garrett,
What other languages offer as much as Rev does?
I completely agree that 1 millisec off is a great performance, but if human lives are involved, I wouldn't count on it.
Best,
Mark
VB
RB
Delphi
Gambas
Mono
You get the idea. What I meant was, a language as large, or as feature
rich as Rev.
My point was that when a language becomes large, it has a tendancy to
become bloated and slow and one would have to turn to a smaller more
optimized language in order to gain the speed. But Rev really kind of
defies this and though is a very large language, still offers speed that is
comprable to a smaller more optimized language.
I've even dabbled in smaller languages that couldn't handle many of the
things Rev does and blaze through with awsome speeds.
I recently made a program that allows you type in a word that you want
to find rhyming words for. The dictionary file I use contains over
185,000 words, each on it's own line. Each word on each line has some
pronounciation codes which are usually 3 letters each and typically in sets
of 6 codes for each word.
In some of the other languages I've used, most could not even freaking
load the dictionary file at all. Those that could, were so slow that making
this program in them would be insane.
But Rev loads the file like a champ, and within a second or two, or less.
Then comes the searching for rhyming words. In other languages this
would have taken minutes even.
But with Rev, it's damn near instantaneous! It was so fast I actually had
to put some "wait 1 sec" lines in there so the user could see the status
messages.
AND! These speed results are damn near the same on a 500 Mhz box
with only 256 Mg of memory! I almost bet I could drop that program on
a 200 Mhz box with 64 Mg of memory and see little to no difference at all
in the speed.
I'd like to see RB, VB or any of the others accomplish that!
Well, I'm going off topic here. Sorry about that.
-Garrett