So, 2 days without an update. That’s not to say I haven’t been working on it, but I’ve been mostly just trying out various different methods of displaying the overlays on the camera view.
Today’s Results
Last time I posted, I had the locations overlaid, but only moving from the left of the screen to the right. After day 7 I had it moving both left and right and up and down. I spent most of day 8 trying to get them to move slightly differently, but in the end decided that what I had in the first place was probably the best I would get. Today I played with the distance values, and now have the pointers resized and moving at varying speeds depending on how close you are.
Again it’s hard to show it working properly without any locations visible, but the example here is showing various cinemas in a 10km area. The large one is my town’s cinema, the smallest ones are in other towns further away.
Then, if I rotate the phone to the right a bit:
The nearby one has moved much further to the right than the distant ones. This is similar to the perspective of objects that you can see. For example, right now, I’m sitting in front of my computer, which is in front of a window. If I move to the left, I can’t see the monitor in front of me any more, but I can still see the next house out of the window.
The slider doesn’t do a lot at the moment. It’s supposed to affect the display area, but at the moment it only uses these values for the google search. While this does prioritise nearby locations, if there aren’t many locations that match in that area, it’ll still return some faraway things. I think rather than making this a fully adjustable scale, I’ll probably make 3-4 ‘levels’ of search area. Right now the perspective/sizes change over quite a large distance, with the smallest size being at over 10km away. Obviously if you’re in a city and actually looking at buildings, you don’t care about things 10km away, and all of the things you’re looking at would be within 100m of you. Right now, those would all be shown at the same size. I’ve had to do this for testing because there aren’t any locations near me which I can search. I’m also not applying any specific calculations to work out the size. I’m using log on the distances and going from there, but then I’m just using a bunch of if statements to categorise each point into a specific size.
If I can work out a better way of calculating it I might make a full sliding scale. I also need to find a better way to filter the search results though, as right now it would still display faraway items if you set the area to the minimum, and these results were producing huge/inverse images because it was scaling them by a negative number from the calculations I tried. There are various ways around this, but for now the method I’ve got is working well.Currently I’m aiming to have, say a”city” view, where you just want things that you can see very close by, a “wide range” view, where you can see all of the results in the region, and 1 or 2 in between that. That should be sufficient for now.
The Code/Maths
I won’t go into all the details because it hurts my head now, but I’ll explain a few of the basics.
I said a few days ago that I didn’t think I’d have to worry about the Accelerometer values, but it turns out that I do. The orientation values basically show how far they are rotated away from a specific point, but not in positives and negatives. For example, if you’re holding it flat, it will say 0 degrees. You rotate it upwards slighly, it will say 10 degrees. But if you rotate it downwards slightly from flat, it will also show 10 degrees. The values also jump between 0, 180, and -180 at certain points, so it can be quite confusing. Enter the accelerometer. This sensor -does- know if it’s tilted upwards or downwards. The specific numbers it’s giving don’t mean much, but the key piece of information here is whether it’s positive or negative. As with the previous example, you have 10 degrees in both cases, but in one case the accelerometer value will be negative, and in the other, it will be positive. You can use this in a simple if statement to perform a different calculation depending on the accelerometer value.
After implementing the movement in two dimensions, I ran into another problem. It worked fine if I was holding it perfectly horizontal, but if it was rotated sideways, moving it up or down would result in the points jumping across the screen at certain points. The solution to this was using the third orientation value, and another accelerometer value. So basically, I have 4 sets of calculations for each combination of positive or negative on each of the accelerometer values. This then allows me to rotate the points to match the users view too, and overcomes the jumps across the screen.
As I’ve said, I’m not going to go into detail here, but I’ll give 3 suggestions:
Read this tutorial. I don’t think the maths is entirely correct, but it should give you an idea of how it works:
http://www.devx.com/wireless/Article/42482/1954
Download “SensorList” on your Android phone. This gives you the outputs for each of the sensors, and a graph of them. From this, you should be able to work out what you need to do with the numbers. Pay close attention to what happens to the numbers as you tilt it past horizontal or vertical on each axis.
Contact me via comments or email and I’ll try and explain it a bit better. I also plan on writing an in-depth tutorial once this is all finished.
The distance calculations again took some trial and error. Many attempts resulted in markers which were either far too big, far too small, or not enough differentiation between the distances. I overcame this by first finding the logarithm of the distances. Currently, I do want to see faraway points, but I don’t care about much beyond 10km away. In log base 10, 10000 is 4. Using a sort of semilogarithmic scale, I took these values, and as the log10 of the distance went up by 0.25, I increased the scale by 0.2, ranging from 2 to 4, which is between 100m and 10km. There are no results closer than 100m to me right now, and only a few within 500m or so, so this worked well for now. But when you’re in a city and just want to see what’s within 100m of you, this will have to be changed. The log10 of anything below 1 is a negative number, which would cause issues with the scale, but this isn’t a problem in this case because the GPS isn’t accurate enough to say that something is less than a meter away from you. But I’ll have to change the scale of this for using a smaller search area, such as between 1 (10 meters) and 2 (100 meters), possibly up to 3 (1km) for very small outliers.
Another issue I encountered was that the app was getting increasingly slow, to the point that it was very difficult to even type in search queries, and the points were not moving across the screen very smoothly. This was solved (partially) by looking into the garbage collector. If you look at LogCat in DDMS when you have an app running, you’ll see something along the lines of “GC cleared 1000 objects in 100ms”. What this means is that it’s periodically stopping for a short period to clear stuff out of the temporary memory. 100ms doesn’t seem like a lot, but it makes quite a difference with a real time application of this nature. Especially when it has to do this for every draw cycle. The reason that this happens is when you create objects in some way like Paint paint = new Paint(); it’s creating a whole new object which you’re not getting rid of. Java deals with this stuff on it’s own quite well, compared to languages like C where you have to do all of this yourself.
In my case, I was creating new Location objects for every search result (up to 8 at a time) on every draw cycle (which occur multiple times per second). The solution to this is to declare your objects as private at the start of the program, and set them up in your onCreate method. You can then simply edit and refer to them in your draw cycles, rather than creating endless objects multiple times per second. Mostly these sorts of problems can be solved by looking for any lines that are creating objects by using the new operator, particularly within your onDraw methods, and also sensor listener methods. The background APIs are going to do a fair bit of object creation on their own too, so you won’t be able to get rid of everything, but you’ll be able to avoid significant issues. There’s also the issue that declaring the object for the entire program will take up more memory in the long run, rather than only for a short time. Depending on the nature of your app you might not want to do something like this, but for graphics-heavy apps, it helps a lot.
The Next Steps
I have the foundations augmented reality working now. There are a few more steps to perfect it, though I’d like to move on to the bigger parts and come back to the minor details when there’s time.
- Showing details of the location on camera view. Currently there’s no way to see -what- locations you’re looking at, unlike on the map where you can click to see the name of it. I had trouble implementing any sort of click listener for the images, but there’s probably a way. Alternatively, an overlay could just display the details of the nearest point to the center.
- Set up the different search areas to work correctly.
- Sort the Google search results so that irrelevant results are discarded, and closest items are prioritised. Also need to search through multiple results beyond 8.
- Test to make sure the results are accurate in a city area.
That’s about it for the app itself. Beyond that, I need to create a database for adding my own points, so that it can be demonstrated at the University, and extended further in the future. This is fairly simple, and I’ll probably just do it by setting up a MySQL server on my website and a PHP script to create the JSON output. It would be easier to encode the JSON output in Java using the Jackson libraries, but then it’ll take more work to it up to receive HTTP requests. Javascript is another option but I’m not familar with it.
Tomorrow’s Goal
One more day working on the minor points described above. Location details are very important and I still need to decide on how to display it. Search areas are quite important but I’m pretty confident of how to do this. Google results are less important as I won’t need to be showing many Google results in my University demonstration, but it would be good to improve this.
Links
As I said, most of this was all trial and error til I got it right. I’ll point you to this tutorial again which helps with getting started in Augmented Reality, though the maths doesn’t appear to be entirely correct.
http://www.devx.com/wireless/Article/42482/1954
This page explains how to make your app more efficient by dealing with the Garbage Collector.
http://blog.javia.org/android-allocation-free-code-avoids-the-gc-freeze/
This app is very useful for working out what you need to do with your sensor outputs. It gives you every number your sensors are outputting, and plots them on a graph.
http://www.androlib.com/android.application.com-miian-android-sensors-xmiE.aspx
Alternatively, here’s the QR code link which you can scan on your Android phone, to take you directly to the market download.

















