I've been struggling with an app for fall detection for quite some time now. The app runs, but it will freeze up at times, and then resume 10-15 seconds after.
My approach is to do integral calculations (which means I had to import a third party library: Apache Commons). For these integral calculations I need norm values.
I'm calling a method for calculating the norm when the sensor updates:
public void onSensorChanged(SensorEvent event){
acceleration.setText("\n " + event.values[0] + " , " + event.values[1] + " , " + event.values[2] + " \n");
x = event.values[0];
y = event.values[1];
z = event.values[2];
if (!checkFall)
sample(x, y, z);
}
calling the sample function makes the app run slow (visible through setting text on UI).
Sample which is seemingly the root of my problems looks like this:
private void sample(double x, double y, double z)
{
if(xList.size() < 120 && yList.size() < 120 && zList.size() < 120)
{
xList.add(x);
yList.add(y);
zList.add(z);
}
if(xList.size() == 120)
{
for (int j = 0; j < norm.length; j++)
{
norm[j] = sqrt(pow(xList.get(j), 2) + pow(yList.get(j), 2) + pow(zList.get(j), 2));
for(int p = 0; p < norm.length-1; p++)
{
for(int q = 0; q < diff.length; q++)
{
diff[q] = norm[p] - norm[p+1];
}
}
if (norm[j]/9.81 < 0.5)
{
final counterClass timer = new counterClass(4000, 20, norm, diff);
checkFall = true;
timer.start();
// if exceeded three times, save the arrayList and register fall
}
}
(I've tried disabling the timer call when the if statement norm[j]/9.81 < 0.5 has been met, because I thought the error may be in a function that a countdown timer is calling) - but to no help, the app freezes whenever the norm approaches 0.
There are no obvious errors in the logcat, which is why I'm having a hard time narrowing down where the error is. Perhaps I'm accessing the arrays in a terrible way?
If there is any missing information you'd like me to provide or if my questions is too vague, please let me know.
EDIT:
Counter Class
public counterClass(long millisInFuture, long countDownInterval, double[] norm, double[] diff) {
super(millisInFuture, countDownInterval); // Duration & how often onTick should be called
nor = norm;
dif = diff;
}
public void onTick(long millisUntilFinished) {
listFall(); // Adding accelerometer data to fall list array List each time its called
new Thread(new Runnable() {
#Override
public void run() {
vCheck(nor,dif);
}
}).start();
}
Related
I want to create a start menue for a Pong clone where the ball in the background bounces off the edges. However the game loop updates to fast so the Coordinates of the ball are already out of the JFrame before you can see it and it moves to fast. I found that through sysouts.
I guess it has something to do with threads but I am not sure.
The main class calls this Class as a thread but the important part is in the class BackgroundBallMovement
package main;
public class BackgroundBallMovement implements Runnable{
private boolean running = true;
#Override
public void run() {
long lastTime = System.nanoTime();
final double ns = 1000000000.0 / 60;
double delta = 0;
while(running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
while(delta >= 1) {
update();
delta = 0;
System.out.println("X-Koordinate " + Var.ballX + " " + "Y-Koordinate " + Var.ballY);
}
render();
}
}
//Spiellogik updaten
private synchronized void update() {
Var.ballX += 1;
Var.ballY += 1;
}
//Objekte zeichnen
private synchronized void render() {
Var.drawStartMenue.repaint();
}
}
You're not using Thread.sleep(). Instead you are waiting until System.nanoTime() changed. This means that the CPU is running all the time (not good).
Also this loop:
while(delta >= 1) {
...
delta = 0;
...
}
doesn't make sense because it could be replaced by an if.
Then you are never updating the lastTime variable. So this line:
delta += (now - lastTime) / ns;
will result in a quadratic function because it will result in something like this (each loop execution):
delta += 0.1;
delta += 0.2;
delta += 0.3;
...
Then because you are never updating the lastTime variable after 1s the condition
while(delta >= 1)
will always be met and your ball will move incredibly fast.
Your first approach could be something like this:
#Override
public void run()
{
while(running)
{
update();
render()
System.out.println("X-Koordinate " + Var.ballX + " " + "Y-Koordinate " + Var.ballY);
Thread.sleep(1000L/60L);
}
}
That's because your math sucks ;-)
Yes, (now - lastTime) / ns is the amount of frames that should have been rendered since the engine started. Therefore your code simplifies to:
while (true) {
delta = framesSinceStart();
while (delta >= 1) {
renderFrame();
delta = 0;
}
}
which is equivalent to
while (true) {
if (framesSinceStart() >= 1) {
renderFrame();
}
}
That is, your code correctly waits to render the first frame, but doesn't record that it has rendered that frame, and therefore always thinks it is late, and never waits anymore.
Instead, you might try something like:
while (true) {
if (framesSinceStart() - framesRendered >= 1) {
renderFrame();
framesRendered++;
}
}
Btw, simply staying in an endless loop to spend time is not very power efficient. It would be better to use something like Thread.sleep() to wait - but calculating the time it should be waiting by hand is a little hairy. Fortunately, the Java API comes with nice helper classes to use:
ThreadPoolExecutor executor = Executors.newSingleThreadExecutor();
executor.scheduleAtFixedRate(() -> renderFrame(), 0, 1000 / 60, TimeUnit.ms);
Try Thread.sleep(long millis)
while(running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
while(delta >= 1) {
update();
delta = 0;
try{
Thread.sleep(1000);
} catch(Exception e) { }
System.out.println("X-Koordinate " + Var.ballX + " " + "Y-Koordinate " + Var.ballY);
}
render();
}
another thing you can try is reducing the ball speed.
private synchronized void update() {
Var.ballX += 0.01;
Var.ballY += 0.01;
}
Hello im working with an app that are counting how many jumps you are making, im using gyroscope for this app to calculate the jumpings you are making. But the problem i have atm is that when i move the device slightly it counts as an jump, and that's not how i want it. I want it when ever it reaches an altitue it shal count as an jump.
int count = 0;
public void onSensorChanged(SensorEvent event) {
double d = Math.round(Math.sqrt(Math.pow(2, event.values[0]) + Math.pow(2, event.values[1]) + Math.pow(2, event.values[2])) - 2);
String result ="";
if(d != 0){
count++;
result = String.valueOf(d/100.0);
}
text.setText("jump counts" + " " + count);
text.invalidate();
Log.i("Gyro", result);
}
You can introduce a threshold value for which a jump is counted if the gyro returns a distance greater than or equal to that threshold value.
int count = 0;
public void onSensorChanged(SensorEvent event) {
double d = Math.round(Math.sqrt(Math.pow(2, event.values[0]) + Math.pow(2, event.values[1]) + Math.pow(2, event.values[2])) - 2);
String result ="";
SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
float threshold=preferences.getFloat(KEY,defaulttValue)
if(d != 0 && d>=threshold){
count++;
result = String.valueOf(d/100.0);
}
text.setText("jump counts" + " " + count);
text.invalidate();
Log.i("Gyro", result);
}
this threshold value can be calibrated by the user, stored in shared preferences so that it can be modified later.
Although there might be similar questions (such as A), their answers do not solve my problem.
I am using Android Studio 1.5.1 targeting Android API 18 (before Android KitKat 4.4, so I’m dealing with Dalvik, not ART runtime).
I have a modified Android that adds memory space overhead (specifically designed by the author and it is outside the scope of this question) with any used variables. For example, if we declare an integer variable, the variable will be stored in 8 bytes (64-bit) instead of 4 bytes (32-bit). This modification is completely transparent to apps which can run on the modified Android without any problem.
I need to measure that overhead in execution time, for example, when I use variables.
Here is what I did so far but it does not seems to work because the overhead variable (at the end of //Method #1 in the code below) is inconsistent, sometime it is negative, positive, or zero. In the ideal solution, it should be always (or at least most of the time) positive.
long start, end, time1, time2, overhead;
//Baseline
start = System.nanoTime();
total=0; total+=1; total+=2; total+=3; total+=4; total+=5; total+=6;
total+=7; total+=8; total+=9;
end = System.nanoTime();
System.out.println("********************* The sum is " + total);
time1 = end - start;
System.out.println("********************* start=" + start + " end=" + end + " time=" + time1);
//Method #1
start = System.nanoTime();
total = (a0() + a1() + a2() + a3() + a4() + a5() + a6() + a7() + a8() + a9());
end = System.nanoTime();
System.out.println("********************* The sum is " + total);
time2 = end - start;
System.out.println("********************* start=" + start + " end=" + end + " time=" + time2);
overhead = time2 - time1;
System.out.println("********************* overhead=" + overhead );
}
private int a0()
{
return 0;
}
private int a1()
{
return 1;
}
private int a2()
{
return 2;
}
private int a3()
{
return 3;
}
private int a4()
{
return 4;
}
private int a5()
{
return 5;
}
private int a6()
{
return 6;
}
private int a7()
{
return 7;
}
private int a8()
{
return 8;
}
private int a9()
{
return 9;
}
My question is:
In Android, how to measure that execution time overhead programmatically?
What you are describing is simply experimental error.
the overhead variable is inconsistent, sometime it is negative,
positive, or zero. In the ideal solution, it should be always (or at
least most of the time) positive.
I don't have an exact solution for you problem on Android, but when I have done experimental testing in other contexts, I typically run multiple iterations and then divide by the number of iterations to get an average.
Here is some pseudocode:
int N = 10000;
startTimer();
for (int i = 0; i < N; i++) {
runExperiment();
}
stopTimer();
double averageRuntime = timer / N;
The problem is that the code that you are trying to time is executing faster than the resolution of System.nanotime(). Try doing your additions in a loop, for e.g.
for (int i = 0; i < 1000; i++) {
total += i;
}
Increase the loop count (1000) until you start getting reasonable elapsed times.
I have a program which is PrimeNumbers class. It displays if the x is a prime or not. The x is the number being analyzed in the program.
There is a time on how long will the program take to know the answer. x is so big it takes 9 seconds to know the answer. How could the program run faster using more threads? I am having a hard time on getting how to implement thread in this situation.
public class PrimeNumbers {
private static int x = 2147483647;
public static boolean prime= true;
public static void main(String[]args){
long start, end, elapsetime;
start= System.currentTimeMillis();
for(int y=2; y<x; y++){
if(x % y == 0){
prime=false;
System.out.println(y);
break;
}
}
end = System.currentTimeMillis();
elapsetime = end - start;
System.out.println("Prime: " + prime);
System.out.println(elapsetime+ " mill sec " + (elapsetime / 1000
+ " seconds."));
}
}
I'm going to ignore whether you've got the most efficient approach and focus on how your current code could be faster with more threads.
You currently iterate through all the numbers from 2 -> x and perform a simple test. A way to improve performance might be to split this task into Z chunks and start Z threads to perform the tests in parallel.
E.g. if you had two threads, you would have one thread examine 2 -> x/2 and the other examine x/2 + 1 -> x. Each thread should break from its testing if a global (and probably volatile) flag is set to true, which would indicate the other thread has disproved the prime.
Your primality test is very inefficient, you're looping over each number less than x. How can you improve it? This link should be helpful.
A good algorithm would be the AKS test, or Sieve of Eratosthenes. The code below implements one of the algorithms from the wiki article, which is much more efficient than the test you posted.
public static boolean isPrime(long n) {
// http://en.wikipedia.org/wiki/Primality test
if (n <= 3) return n > 1;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i*i <=n; i+=6) {
if (n % i == 0 || n % (i+2) == 0) return false;
}
return true;
}
}
If you intersted for a better algorithm Munyari has already suggested one.
Ignoring this following example can help you how you can make parallely execute an algorithm (even if it is a stupid algorithm)
We need a class which implements Callable interface (similar one to Runnable). It should get the part of the job and calculate it.
public class PrimeChecker implements Callable<Boolean> {
private final long numberToCheck;
private final long start;
private final long end;
public PrimeChecker(long numberToCheck, long start, long end) {
this.numberToCheck = numberToCheck;
this.start = start;
if (end >= numberToCheck) {
this.end = numberToCheck - 1;
}else{
this.end = end;
}
System.out.println("A PrimeChecker with start " + start + " and end " + end + " values to check number "
+ numberToCheck);
}
#Override
public Boolean call() throws Exception {
boolean prime = true;
long current = start;
if (current != 2 && (current % 2 == 0)) {
current = current + 1;
}
for (; current < end; current = current + 2) {
if (numberToCheck % current == 0) {
prime = false;
System.out.println("The number " + numberToCheck + " is divisable with " + current);
return prime;
}
}
return prime;
}
}
It simply start from a number and check if the given number numberToCheck is divisable and continues until it reaches the number end.
In the Main class we have to create multiple PrimeChecker jobs and execute them parallely. For this purpose we use Java's ExecutorService. It creates for us a thread pool. And then we can divide the job on multiple PrimeCheckers. Finally we execute them invokeAll method of ExecutorService. This gives us a Future list, which contains results of each jobs that we executed parallely.
public class Main {
public static boolean prime= true;
public static void main(String[] args) throws InterruptedException, ExecutionException {
long startTime = System.currentTimeMillis();
long numberToCheck = 5333334345L;
int numberOfThreads = 10;
System.out.println("Checking if the number " + numberToCheck + " ...");
ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
List<PrimeChecker> primeCheckers = new ArrayList<PrimeChecker>();
long partOfNumber = (long) Math.ceil((double)numberToCheck/ numberOfThreads);
long start = 2 ;
long end = 0;
for(int i = 0; i < numberOfThreads; i++){
end = end + partOfNumber;
primeCheckers.add(new PrimeChecker(numberToCheck, start, end));
start = end+1;
}
List<Future<Boolean>> futures = executor.invokeAll(primeCheckers);
for(Future<Boolean> future : futures){
prime = future.get();
if(prime == false){
break;
}
}
System.out.println("The number " + numberToCheck + " is " + (prime ? "a prime" :"NOT !!!!!!!!!!!!!!!!!!!! a prime") + " number");
long endTime = System.currentTimeMillis();
long elapsetime = endTime - startTime;
System.out.println(elapsetime + " milliseconds");
System.exit(0);
}
}
You can try it with different numbers of threads (see numberOfThreads variable) to see the difference.
I hope it is a useful example for you, to understand multi threading better. (Be careful: It is only a tiny tiny part part of the whole threading theme)
If you do not need to implement the prime check yourself, I would propose to use the API. You can control the certainty, depending on your needs. In the example it is: 1-(1/2)100
public static void main(String[] args) {
BigInteger mersenne = new BigInteger("2").pow(521).add(BigInteger.ONE.negate());
System.out.println("digits of the number: " + mersenne.toString().length());
long start = System.currentTimeMillis();
final int certainty = 100;
boolean isPrime = mersenne.isProbablePrime(certainty);
System.out.println("elapsed millis: " + (System.currentTimeMillis() - start));
System.out.println("isPrime : " + isPrime);
}
edit
Here is an optimised version of the proposed example.
public class PrimeNumbers {
private static int x = 2147483647;
public static boolean prime= true;
public static void main(String[]args){
long start, end, elapsetime;
int divisor = 1;
start= System.currentTimeMillis();
if (x % 2 == 0) {
prime = false;
divisor = 2;
} else {
// - you can use an increment of two
// because you don't need to check
// for a divisor which is a multiple
// of two
// - you don't need to check for any divisor
// which is greater than x/2
for(int y=3; y < x/2; y += 2){
if(x % y == 0){
prime=false;
divisor = y;
break;
}
}
}
end = System.currentTimeMillis();
System.out.println("Prime: " + prime);
if (!prime) {
System.out.println("divisible by: " + divisor);
}
elapsetime = end - start;
System.out.println(elapsetime+ " mill sec " + (elapsetime / 1000
+ " seconds."));
}
}
I'm creating a 2d zombie shooter game and I'm trying to think of a good way to gradually increase the rate of which zombies are created.
I create a zombie with the following code.
public void createZombies(){
int direction = new Random().nextInt(4);
if (direction == 0) {
// spawn from top
zombies.add(new Zombie(new Random().nextInt(1120), new Random()
.nextInt(1)));
}
if (direction == 1) {
// spawn from left
zombies.add(new Zombie(new Random().nextInt(1), new Random()
.nextInt(640)));
}
if (direction == 2) {
// spawn from bottom
zombies.add(new Zombie(new Random().nextInt(1120), 640));
}
if (direction == 3) {
// spawn from right
zombies.add(new Zombie(1120, new Random().nextInt(640)));
}
}
I basically want to call that method from my main method (which runs continuously). I thought of maybe using modular and do something like:
int x = 1;
if(x % 1000 == 0){
createZombies();
}
x++;
but that seems messy - and it doesnt change how frequently they are created.
I'm just a bit stumped at finding a good way to do this - and surprisingly I couldn't find anything useful on here either.
So if anybody can point out a good idea to do this it would be greatly appreciated!!
Guava has a RateLimiter which may be useful for your use case. In particular, you could do something like:
//initially, create one zombie every 10 seconds
final RateLimiter zombieRate = RateLimiter.create(0.1);
Runnable increaseRate = new Runnable() {
#Override public void run() {
//increase rate by 20%
zombieRate.setRate(zombieRate.getRate() * 1.2);
}
};
//then increase the rate every minute
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(increaseRate, 1, 1, TimeUnit.MINUTES);
Your Zombie creation then becomes:
while (true) {
zombieRate.acquire();
createZombie();
}
You can simply decrease each time the period between zombie creations:
int x = 1;
int tau = 1000;
if(x % tau == 0){
createZombies();
}
x++;
tau = tau > 0 ? --tau : 1;
You have to define the "velocity" of zomby creation in respect to time elapsed.
double velocity=0.5; //every 2ms 1 zomby
long latestCreation = System.currentTimeMillis();
double rest = 0;
public synchronized void createZombies() {
double number=velocity * (System.currentTimeMillis() - latestCreation) + rest;
latestCreation = System.currentTimeMillis()
int n = Math.round(number);
rest = number - n; //n° of partial zomby
for (int i=0; i<n; i++) createZomby();
}
from your thread or when you prefer call createZombies().
Unfortunatly you cannot know when the thread will be really executed then you have to define a function time dependent. The var "rest" is an optimization when the number will return some decimal.
Maybe you can do something like this:
float maxZombieRate = 0.8; //for example
float zombieRate = 0.05;
while(zombieRate<=maxZombieRate){ //you could have a timer too
if(Math.random <= zombieRate){ //Math.random returns values between 0 and 1
createZombies(); //
zombieRate+=0.05; //increase in 5% the probability of run createZombies()
}
}