I am trying to build an android application for sphero where I need to stop sphero in certain zones of the room and I am trying to do so with the locatorData using a DeviceMessenger.AsyncDataListener.
I have noticed, however that it is impossible to tell where he is while he is still rolling and stop it when it is in a certain set of coordinates, because the data arrives with great delay. He basically stops much farther and I can see the coordinates increasing with delay on screen. I know the communication is asynchronous and i could somehow be losing some data during communication but I thought that by giving him a window around the coordinates I want him to be I would be able to stop him more or less in that zone, but it doesn't look like it works decently.
For now, the only solution I've come up with is to send a roll command, calculate the amount of time it needs to roll to get to those coordinates based on velocity and send a delayed stop command, but I don't like this solution and I don't think it's going to work correctly in the long run, when I implement all the features I need. Does anyone have any suggestions about the locatorData and how to use it in this case?
I have used the 'locatorData' before and what you are trying to do is very possible. There are a couple ways you can go about accomplishing it.
The great delay you are experiencing is not communication delay, but the fact that the Locator sensor only updates 10 times a second (10Hz). However, this should still be more than enough time to work within your constraints of stopping the ball within a boundary. Another factor is, have you thought about that the ball needs about 1-2 feet to come to a stop? This depends on the speed the ball is traveling when you send a stop rolling command.
One way you cab accomplish your goal is by driving the ball at a slower speed. If you were to drive at 50% power instead of 100% your results should be more accurate. Since, the time delay and stop delay have less impact on the accuracy.
Another way you could accomplish this is by doing a predictive algorithm. Using the 'locatorData', you know where the ball is (x, y), and you know the velocity in which it is traveling (vx, vy) you can predict where it is going to be in the future. Therefore, you can send a stop command in advance when your algorithm determines the ball will be at your destination in 1-2 seconds.
You might want to look into the ConfigureLocator command as well, since this can make the starting point of your ball be (x=0, y=0).
I hope this information helps!
Related
I am biggener in android. I am trying to implement a fitness app that can keep track of the running speed and running distance in Android. How can i calculate the above mentioned things ?
In theory you could analyse windows of accelerometer data and count the number of peaks and the forces of those to determine running. Then, if the user has entered an average step distance, that could give an equation of distance.
Would be a lot easier using GPS as it provides the speed directly.
You might be interested in this library: https://github.com/mcharmas/Android-ReactiveLocation I recently added Activity Recognition, which can tell you whenever a user starts running. Might take a little while from one begins to run before the phone 'knows' that as being the activity, though.
I am trying to make a very simple Android pedometer, but so far it's failing pretty badly. I got some advice here and there on the internet, but nothing seems to be working.
I basically set an acceleration sensor and get the values of the x, y and z axis. After that I calculate their distance from the origin, which is basically:
d = sqrt(x²+y²+z²) followed by the calculation of their moving average. My idea was whenever I find a local peak I should count as a step. The issue is, I have no idea how to find the local peak right away in order to count the step. I am sorry if this seems like a simple problem, but I really have no idea how to go on from here.
Thank you very much.
I tried to implement this and the approach you take is subject to substantial measurement errors. You should just accept it. The reasons are:
a phone can be in any location, not only the trousers' pocket
phone accelerators are not medically precise, and they can deviate and "flow" given exactly the same position in space
moving average is not the best known technique to do this, a better one would use some sort of waves and wavelet analysis
One step has two local maximums and two local minimums (if I remember correctly)
There is no strict definition of a "step" globally accepted, this is due to physiology, measurements and various techniques used in the research field
Now to your question:
Plot the signal from the three axis you have, this will dramatically help you (signal vs time)
Define a window of a fixed (or slightly moving) size, moving window is required to detect people who walk slower, run or have disability
Every time you have a new measurement (usual frequency is about 20-30 Hz), put one to the tail of the window (your signal measurement's queue) and pop one from the head. In this way you will always have a queue with the last N measurements
Again for every mesurements recalculate your stuff and decide if the window contains one (or two!) minimums and count it as a step
good luck!
I am trying to create an application that will track movement of the device in 2D space. After doing research online, all I could find that one way to do it is integrate linear acceleration twice but the error is horrible.
Are there any solutions to this problem? I would like to be able to move my phone up, which would cause a vertical line to be drawn on the screen, to scale of how far the phone was moved. Then if I move the phone to the left, horizontal line would be drawn - effectively allowing me to draw on the screen using movements of the phone.
Can this be done at all? If so, what direction should I take in the development? I don't know where to start...
EDIT: More about the project:
I am trying to make an exercise app that will track the movement of the leg/arm: for example, when you are doing stomach crunches and the phone is attached with an armstrap to your ankle.
The app would track repeated movements of the leg.
Unfortunately the accelerometers in these phones are nowhere near what you need to implement an inertial measurement unit. The big problem is since you are integrating twice an integration always comes with a constant integral(x,dx) = x^2/2 +c this constant is what makes this difficult. To make things worse you get it twice, once when integrating to get velocity and once to get position.
One method of fixing this that I have seen in commercial innertial measurement units is called a zero velocity null, this is where you use some other source of data to tell it when you have stopped the motion of the device so you can zero out the velocity. For example I saw a project put an inertial measurement unit on a shoe and it would zero the velocity whenever it detected the shoe being put on the ground which vastly improved the accuracy. Its possible that you could use a camera or something to determine this, however I have not seen it done. If you would like to start messing with this then you are an awesome person and I would love to hear how it turns out.
Edit: I should clarify that the constant I mention above is where the error accumulates. If you can zero velocity null it then you periodically drop the accumulated error from your stored current velocity. The error in position will still accumulate, however this would make it not drift when they are holding it relatively still which may make it passable for drawing.
I know no other way other than integrating the acceleration twice.
Moreover I think that it's not possible if you don't have knowledge about other sensors that might be in your device (for example on one of my devices I have 7 (seven) sensors related to various physical signals the device might be receiving).
Other than that remember that the sensor data is noisy and almost always must be pre-filtered. For example you can use geometric mean of last 10 samples. That should lower your error by providing a smoother input data to the integrating function.
I am writing an android program that is a speedometer. the way it works wright now is it takes 2 GPS locations over time, and divides the distance by time to get speed. the problem with this is that it only refreshes when the gps moves, so when I stop moving it would stay at the last speed that I had. is there a better way of doing this?
You could keep track of how long it is since you've had the last update, and adjust the speed after a certain amount of time has past. (You could use a Handler to schedule the check).
In general gps is only going to give you a rough estimation of the speed though.
You can also use the Location object's speed estimate directly (check that it has one by calling hasSpeed(), then get it by calling getSpeed()).
let's say i want to build a smartphone app that tells a user when/where to get off a subway station. i can think of two ways of doing this:
1) using GPS and map of the subway routes, track the location of the user and notifies him when the destination is reached
2) have him press start when he gets on a train as the train starts (which may not be realistic because the user could simply forget to do this), use the known travel time from starting station to end station, and simply notifies him when the time is up.
can someone tell me if there are any other good approaches? thanks.
You may have to go with 'dead reckoning'. Basically, dead reckoning is a navigation technique that uses a confirmed starting location plus accurate velocity and time to calculate a new location. Keep in mind that velocity is itself a combination of heading and speed and that the heading must be a true heading. In an airplane, compass heading would have to be combined with wind speed and direction to get a true heading. I don't think you have to account for drift on a subway, but you will have to account for varying device orientation as the user moves around or uses the device itself. Also, just because heading is normally a compass bearing doesn't mean that it has to be. You may be able to get the job done using only the accelerometers and a timer.
Proper use of dead-reckoning also requires frequent 'resets' to known locations as you reach them so that errors can't add up too badly. For this application, I would argue that curve- and stop-detection can be used as resets. You may get false positives for 'service' stops that are too close to real stops, but those may be rare enough to ignore. In fact, if it wasn't the exit stop, it might not matter because you might still be accurate enough for the next-stop warning and if was the exit stop, it won't matter because the ride is over.
To summarize: you need to be sure that you have a good initial starting point; you need to compensate for device reorientation to get true heading; you need to know your average speed between heading changes and the time-on-heading to calculate distance-on-heading. You can improve overall accuracy by resetting at known landmarks.
Edit: I don't know if this gets you any closer to the answer, but Chris Stratton raised an interesting point about summing the accelerometer vectors. Is it possible to track the orientation of the device accurately enough to have a reliable orientation-independent gravity vector? Can you keep that out of your vector sum? Can that provide a useful acceleration along a useful orientation-independent vector? If so, then tracking the duration of the acceleration will get you an average speed for that duration and a final speed for the end of acceleration. Absent acceleration, the speed will remain constant. Putting that all together might pile inaccuracy on top of inaccuracy to the point of uselessness.
If the subway line has cellular service (some that were going to had it turned off on security concerns) you might be able to do something with network location.
You could use the accelerometer to try to detect and count station stops - but trains stop in between stations from time to time due to delays ahead. Also battery life would be reduced. EDIT: realized you won't be able to tell acceleration from deceleration as you have no idea of orientation (unless you find the compass sensor workable in that environment) - you could only see that the vector sum of the three accelerometers was greater than gravity for a period of seconds.
You could try to use the microphone to detect the sounds of train motors and brakes (some are extremely characteristic) but that has the same problem with battery life and unscheduled stops between stations. Not to mention scheduled stations bypassed for repair work.
Perhaps you should give the user a scrollable list of stations marking the journey and let them keep track.
Both of those sound like poor solutions. You almost certainly won't get a GPS trace in a subway. And the 2nd way sounds like it will be inaccurate enough to make the app useless.
Read carefully Falmarri's answer. He's completely right, although he didn't give you an answer. Let me try then...
If the routes have no many curves, it will be easier: you just have to hardcode the latitude and longitude of each station, and then, calculating the position of the user will be straightforward (just a little of math and that's it). If the routes have curves, then you have more work to do but it's basically the same.
You will probably want to use a way to know the distance between the current location and the station location. You could use some of the existing algorithms, for instance the Haversine formula.