Asked
— Edited
Im struggling with using time in ezscript. I want to check how long it has been since a given face was recognized. But all the time functions seem to give strings and I cant really figure out how to convert those to number and compare. Using the script help I came up this this:
Quote:
$lastfacedetection= now() ....if ( FmtTimeSpan(CDateTime(now()) - CDateTime($lastfacedetection) ), "mm") >5)) do something endif
but that doesnt work, it tells me: Operator '-' invalid for strings.
Help?
In the past, people would calculate the hours, minutes, seconds manually and it would be a lengthy equation. I always assumed the FmtTimeSpan() would do the trick, since the EZ-Script datetime format and functions derive directly from their .Net counterparts. I looked and to my surprise, there is no way to retrieve total minutes or total seconds, etc from a timespan format! That really surprised me.
So the new release includes TotalHours(), TotalMinutes() and TotalSeconds() functions from timespan: https://synthiam.com/Community/Questions/11811
You can use them like this...
PS, if you ever want to add your own methods that extend the EZ-Script capability, that can be done via a custom plugin. Here's how: https://synthiam.com/Community/Tutorials/146/23
So on a Sunday, 3 hours after I posted a question, I get not only a response, but a new release that fixes a problem I ran in to? Thats impressive
.
I''ll give it a try next week, thanks a lot.
Btw another issue Im running in to frequently and that is slightly annoying, is that I cant keep a script open in one window and do something in another window. The ezscript editor insists on staying in focus. I imagine window management could get slightly messy/confusing if you allow multiple script windows to stay open within the same ARC window,, but it is often useful, like when I need to look up some servo position or test something in another script or copy paste between scripts.
To keep it manageable for people who dont often need this, maybe you could add an option to detach a script editor so it becomes its own windows... , well, window? Similarly, I would love to make better use of my display screen estate. I have 4 monitors, not counting my laptop, I know, you may laugh, but I can only use one, and it feels really cramped with ARC GUI and I keep having to scroll and/or switch "workspaces". Anything you can think off to make that more efficient would be appreciated.
Im still having some issues, this time with precision. Consider this code:
Since this code does nothing except save current time and then compare it to the current time, you would expect to get zero, or at least really close to zero since the script executes in milliseconds.
Instead I get a random number between 0 and 1 (seconds). Probably because CDateTime rounds to a second even though the internal clock and now() work at a higher precision.
Is there a way to store decimal seconds or milliseconds from the clock?
You are not getting random numbers. You are getting the difference between Now() and Now() on two different command executions.
Think about how code works... it reads line by line and executes one line in front of another.
So, this puts the current time into the variable $tmp $tmp = now()
a few clock cycles go by and you compare the current time with the time that was assigned to the variable
$delay = TotalSeconds(now() - CDateTime($tmp))
Computers execute commands in a consecutive linear fashion, that means one after another.
To give you an example that is testable - try this modified version of your code example..
Explain what you'd like to do and I'll help provide direction on the code.
*Edit: I re-read what you typed and maybe you're looking for no decimal level precision? Computers will provide absolute highest precision based on variable type used. If you wish to lower precision to whole numbers (integer), then do this... (note: rounding will occur)
Hey DJ,
With all due respect, I think you're wrong here. The time you get from my test code has (almost) nothing to do with the execution time. It will print values up to nearly 1 second, but the entire script executes from start to finish in 00:00:00.0080011. Likewise your code with the 2 second sleep will return anything between 2 and 3 seconds, but will execute in 2 seconds plus only a few milliseconds. The sleep command has some inherent variability (which is why I didnt use it in my test code), but it will be in the micro second range, at worst maybe a millisecond or so, but not 100s of milliseconds.
As an example, running your code:
Start 2: $tmp = now() 5: Sleep(2000) 8: $delta = TotalSeconds(now()-CDateTime($tmp)) 11: print($delta) > 2.9029819 Done (00:00:02.0145256)
As you see, on that run it reported a delta of over 2.9s but executed in 2.01s. If you think about it, even if the sleep command where widely inaccurate and the computer would be super slow, then its still not possible that it measures a time difference that is longer than the time it took to execute the script.
What I am trying to do is rewriting the servo tracking functionality, controlling both eyes and neck, and "intelligently" looking for a face when it loses track. I need to know how long it has been since the last loop, and I need that to be more accurate than 1 second.
BTW, I wonder if this "time rounding" may also be causing the "talk servo" plugin to be widely variable in its accuracy. Sometimes it seems good, sometimes it lags by like a full second, even when saying the same words. Could this be caused by the same underlying problem?
To further prove my point, this little script reports $delta every ~100ms:
Given that the sleep() command is outside the time measurement code, you would expect $delta to be very close to zero, basically just the time it takes to execute the time conversion and comparison lines. And since every loop iteration is identical, you would expect $delta to be almost identical on each iteration, with at most some slight random variation in execution time.
Thats not what you get.
The output shows $delta increasing with each iteration of the loop by ~0.1s ( exactly 100ms sleep+ the small time it takes to execute the time comparison code, which is what delta SHOULD be measuring), until it approaches 1, then it rolls over again to ~0:
This is not random or coincidence, the increase of $delta at a rate of 0.1s per iteration, or 0.1s per 0.1s, correlates exactly with the progression of the system clock,not with the time it takes to actually execute the code. So $delta is essentially reporting how far the system clock is from the next full second, which is not what I want it to do
edit: im probably making this more complicated than need be. It seems in ezscript now() returns a string representing date/time with integer seconds:
1: $tmp = now() 2: print($tmp) > 11/27/2018 12:57:55 PM
So any measurement can only be accurate to a second? If so, can we have a millis() function? I dont need nanosecond accuracy, but a full second is just too much for many things.
Moreover, CDateTime, at least in C++, appears to only accept integers for seconds.
That said, I still dont understand why my code doesnt return zero or one for $delta though, if indeed now() always returns an integer number of seconds .
So i tried this:
That will give exactly zero or exactly one second, so either storing now() in a variable reduces it to an integer-second precision, or CDateTime does, or both.
But given my previous results, Im guessing the now() function within Totalseconds() somehow does get processed with decimals?
Last test:
Gives me this:
So it would appear CDateTime() is causing rounding of seconds, resulting in $delta2 being either zero or one, depending on the clock switching seconds before or after the sleep. Storing the result of now() in a variable may cause rounding too, Im not 100% sure there. But passing now() to TotalSeconds() appears not to cause any rounding, as $delta shows a non integer difference between now() and the rounded/integer $tmp confused
Now you’re getting into conversation of the operating system. Microsoft Windows is not a real-time OS and the datetime function precision is not in millisecond accuracy. It’s barely in second accuracy, as you can see from the results of your tests.
Google how the datetime works with windows and the accuracy of system ticks. It’s beyond the control of ARC.
If you can explain what you’re goal is, maybe I can help. A time span can provide more accuracy - but I’ll need to know what you’re goal is.