I am trying to sync time between two android devices. The precision has to be upto 5 ms. The gps and network time werent this precise so i thought about sharing time between the devices over the local network and syncing the time using PTP(Precision time protocol).
Now as i can't change the time on non-rooted devices so i thought about saving the time difference shared by device and kept on showing the time to user in a textview.
Now the textview needed to be updated every one ms so the user can see the time in ms too.
I am updating the textview in a thread which is updated every ms.
class CountDownRunner implements Runnable {
// #Override
public void run() {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
while (!Thread.currentThread().isInterrupted()) {
try {
setCurrentTime();
Thread.sleep(1); // Pause of 1/100 Second
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e) {
}
}
}
}
This is where the problem comes that after syncing the time , the time diff is less then 5 ms but after some time of syncing the time starts to drift a part and after 10-15 mins the time diff is more then 1 sec.
So any ideas on how to rectify this issue?
seems like making thread.sleep(1000) works more like thread.sleep(1003 or 1004) and these changes keep on adding up to make a bigger drift
As I noted, Android is not a RTOS.
Moreover, you should not care whether sleep() returns in 1003 or 1004 milliseconds. You seem to be combining two things:
Determining how much time has elapsed since you synchronized the time
Displaying the current synchronized time
These have nothing to do with each other.
Use your sleep() loop -- or, better yet, postDelayed() for greater efficiency -- only to get control roughly every second to know that you need to update the TextView.
To determine what value to show in the TextView, do not add some assumed amount of time based on the sleep(). Instead:
When you get the synchronized time value from the other device, also save the current value of SystemClock.elapsedRealtime()
To determine how much time in milliseconds has elapsed since the synchronization, subtract the saved value of elapsedRealtime() from the current value of calling elapsedRealtime()
Related
I'm trying to measure and increase the execution time of a test case. What I'm doing is the following:
Let's assume I'm testing the method abc() using testAbc().
I'm using android studio and junit for my software development.
At the very beginning I'm recording the timestamp in nano seconds in
start variable, and then when the method finishes, it returns the
difference between the current nano seconds and the start.
testAbc() is divided into 3 parts: initialization, testing abc() and
assertion (checking the test results).
I keep track the test time inside testAbc() same way as I do in
abc() method.
after executing the test I found that abc() method takes about
45-50% of the test time.
I modified the testAbc() as follows:
void testAbc(){
startTime = System.nanoTime();
//no modification to the initialization part
//testing abc part is modified by placing it in a for loop to increase its
//execution time.
for(int i=0 ; i < 100; i++)
{
//test abc code goes here ...
abcTime += abc();
}
//assertion part wasn't modified
testEndTime = System.nanoTime - startTime;
}
By repeating the test part I thought the ratio between abcTime and testEndTime will increase (by dramatically increasing abcTime), however, it didn't at all I mean it's 45-50%.
My questions:
Why the ratio didn't increase? I mean in principle the execution time for the initialization and assertion parts should not be affected by the for loop and therefore the time for abc should get closer to the test time after 100 repetitions.
How can I increase the ratio between abc() and testAbc()?
thank you for your time.
I have been reading up on game loops and am having a hard time understanding the concept of interpolation. From what I seen so far, a high level game loop design should look something like the sample below.
ASSUME WE WANT OUR LOOP TO TAKE 50 TICKS
while(true){
beginTime = System.currentTimeMillis();
update();
render();
cycleTime = System.currentTimeMillis() - beginTime;
//if processing is quicker than we need, let the thread take a nap
if(cycleTime < 50)
Thread.sleep(cycleTime);
)
//if processing time is taking too long, update until we are caught up
if(cycleTime > 50){
update();
//handle max update loops here...
}
}
Lets assume that update() and render() both take only 1 tick to complete, leaving us with 49 ticks to sleep. While this is great for our target tick rate, it still results in a 'twitchy' animation due to so much sleep time. To adjust for this, instead of sleeping, I would assume that some kind of rendering should be going on within the first if condition. Most code samples I have found simply pass an interpolated value into the render method like this...
while(true){
beginTime = System.currentTimeMillis();
update();
render(interpolationValue);
cycleTime = System.currentTimeMillis() - beginTime;
//if processing is quicker than we need, let the thread take a nap
if(cycleTime < 50)
Thread.sleep(cycleTime);
)
//if processing time is taking too long, update until we are caught up
if(cycleTime > 50){
update();
//handle max update loops here...
}
interpolationValue = calculateSomeRenderValue();
}
I just don't see how this can work due to the 49 tick sleep time? If anyone knows of an article or sample I can check out please let me know as I am not really sure what the best approach to interpolation is...
I know its a bit late, but hopefully this article will help
http://gameprogrammingpatterns.com/game-loop.html
It explains game time scheduling very well. I think the main reason you are a bit confused is because of passing the render function the current elapsed time. Oh course this depending on which system you are using but conventionally the render doesn't modify the Scene in any way, it only draws it, therefore it doesn't need to know how much time has passed.
However the update call modifies the objects in the scene, and in order to keep them in time (e.g. playing animations, Lerps ect...) then the update function needs to know how much time has passed either globally, or since the last update.
Anyway no point me going to fair into it.... that article is very useful.
Hope this helps
The app is a sports timer for cycling, skiing etc, where racers start at regular intervals. e.g. 1 minute.
In my implementation of OnChronometerTickListener I notice that the calls occur at intervals significantly longer than 1000 mS. I use the elapsed time (between the Tick and the Chronometer's base) to count down the last 5 seconds for each interval. Due to the late callback, I can get ticks at, say,
55,500
56,600
57,750
58,870
59,980
61,110
I can therefor skip a whole second when I use m_Elapsed % 1000.
I have even seen the text in the Chronometer get behind and have to skip a second.
I have no problem with accuracy when I do calculations based on the Chronometer's base time and current system time.
Do I have to write my own Chronometer using finer callbacks?
Or is there some other fix?
Ive got an app with a class that implements Runnable. Where a thread is started and the run() methid overridden. This runs my graphics.
1.st question : how often is the run() called upon? i havent set a time for this so it must be a default value?
2.nd question : i want stuff to be done after a certain amount of time (2min,5min,10min) etc. What would be the best way to go about doing this, i was thinking about using an int as an counter and once it hits a specific value does what i want.
1.st question : how often is the run() called upon? i havent set a time for this so it must be a default value?
The run() method in your Thread is called when you call it eg. yourThread.start();
2.nd question : i want stuff to be done after a certain amount of time (2min,5min,10min) etc. What would be the best way to go about doing this, i was thinking about using an int as an counter and once it hits a specific value does what i want.
There are to options. Either you could call Thread.sleep() method (NB: Never do this in your UI thread).
Or you can do it the way you described above. So in your run() method you would have a while() loop and check on every iteration if the difference of the lastUpdate and the current time in milli seconds is bigger than the wanted period eg. 2 min, 5 min or 10 min.
I hope this helps.
Regarding question 2 - use ScheduledExecutor
1.st question : how often is the run() called upon?
You can find out for yourself, put this at the start of your Runnable:
Log.v("Running Runnable", System.currentTimeMillis() + "");
2.nd question : i want stuff to be done after a certain amount of time (2min,5min,10min) etc.
Extend a HandlerThread (it initializes the Looper for you!), add a Handler as a class variable, and use the Handler's postDelayed() or postAtTime() methods.
The exact amount of time in between calls to run() depends on the processor. The time between each call is the sort of thing that's really visible by the nanosecond. If you're trying to create a timer, I'd recommend using System.currentTimeMillis(), calling it in the run() method, and once the difference is greater than or equal to 1000 milliseconds, the actual timer decrements by one. This will keep track of seconds, and you can use it as a base for minutes and generating other events at specific times.
I'm writing some tracking app for android at the moment and would like to use the onLocationChanged() method to receive updates.
Now i want to receive updates every once in a while, even if the location itself did not change, so i know the tracking device is still alive etc.
It seems like onLocationChanged will only be triggered if the actual coordinates change, the timestamp alone does not suffice.
I've worked my way around this by polling LocationManager.getLastKnownLocation( LocationManager.GPS_PROVIDER ) every x-seconds and not using onLocationChanged.
I'm afraid though, that this is not the most effective method.
I could imagine some mechanism that would send updates every 30secs while the vehicle is moving and every 10minutes if it's not (to get some heartbeat).
Any ideas?
Thanks!
Simply have a Thread that sleeps for 10 minutes but is interrupted when the location change is fired by the locationListener. When the thread wakes up it does it's stuff.
So have a thread that contains a method like this
void myUpdateMethod() {
while (!shutdown) {
try {
Thread.sleep(1000 * 60 * 10);
} catch (InterruptedException e) { }
.. do update stuff here
}
}
and your listener would look like this
onLocationChanged(Location location) {
otherThread.interrupt();
}
And now you're guaranteed to get an update at least every 10 minutes, or sooner if an update is received. Although the caveat here is you can't use interrupt alone to shutdown the other thread.
You can set time interval and minimun update distance in registration of Location listener method. So just put 0 to distance changes.