High Resolution Timer

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
cmenge
Posts: 11
Joined: Thu May 18, 2006 4:18 pm

High Resolution Timer

Post by cmenge » Fri May 19, 2006 3:14 am

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!

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Fri May 19, 2006 8:55 am

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
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

cmenge
Posts: 11
Joined: Thu May 18, 2006 4:18 pm

Post by cmenge » Fri May 19, 2006 10:02 am

Mark,

I appreciate the feedback; can you detail what you mean by the following?
If you can include the entire procedure in an external, I'd recommend doing so.
By using the word "external" are you recomending the Revolution SDK and incorporate into a Revolution script?

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!

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Fri May 19, 2006 11:10 am

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
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

cmenge
Posts: 11
Joined: Thu May 18, 2006 4:18 pm

Post by cmenge » Fri May 19, 2006 12:26 pm

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?

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Fri May 19, 2006 1:35 pm

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 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

cmenge
Posts: 11
Joined: Thu May 18, 2006 4:18 pm

Post by cmenge » Fri May 19, 2006 4:40 pm

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?

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Fri May 19, 2006 5:19 pm

cmenge,

Read from socket with message doesn't block anything in Revolution.

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

Garrett
Posts: 386
Joined: Sat Apr 08, 2006 8:15 am
Contact:

Post by Garrett » Fri May 19, 2006 5:47 pm

By the way,

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 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:

Code: Select all

100
203
307
410
513
616
720
823
926
1029
And the results of setting the results into the field after the loop is done:

Code: Select all

100
200
301
401
501
601
701
801
901
1001
-Garrett

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Fri May 19, 2006 5:59 pm

Hi Garett,

That was exactly my point.

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

Garrett
Posts: 386
Joined: Sat Apr 08, 2006 8:15 am
Contact:

Post by Garrett » Fri May 19, 2006 7:24 pm

Mark wrote:Hi Garett,

That was exactly my point.

Best,

Mark
Ehhh, sorry if I doubled up on your point.

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

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Fri May 19, 2006 8:26 pm

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
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

Garrett
Posts: 386
Joined: Sat Apr 08, 2006 8:15 am
Contact:

Post by Garrett » Fri May 19, 2006 9:15 pm

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
Other languages that offer as much, but not as great as Rev are:

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

Post Reply

Return to “Talking LiveCode”