Is it possible to clear the values from a STEP_COUNTER listener? I thought that you might be able to do it by unregistering the listener, but apparently the values are preserved. I'm registering a listener on the step_counter sensor, checking for changes, but then I want to flush or clear these values after a certain period of time. Any ideas?
Apparently not but I did mine with a bit of math. I store the value of the count when the step_counter is initiated and then do some math.
mFinalCount = mCurrentCount;
mUpdatedCount = mCurrentCount - mFinalCount*2;
mNewCount = count - mUpdatedCount;
// count is the Float.valueOf(event.values[0]
Basically lets say the step counter is 300, the mUpdatedCount becomes -300 so now count(300) - mUpdatedCount(-300) = 0
I'm really new to android by the way but this worked for me.
Related
I working on an app that I need to calculate distance travelled from point A to point B (by car).
I asked Elm Electronics (chipset manufacturer) and they said there is no standard OBD-II PID to return mileage from odometer, although car manufacturers might provide a PID. Since this way is not standard then I found another way.
PID 0131 (Distance traveled since codes cleared), is returning something that I think might be helpful. IF i'm able to clear it at point A and read its value at point B then I'm done :)
I thought a lot to guess what does "codes cleared" mean but I couldn't realize what does it mean? and my another important question, how to clear code or reset this PID?
Any suggestion would be appreciated. Thanks.
Update
I just tested on two Cars.
On Benz car no OBD-II command works. I couldn't get any data :(
I got correct reply on Persona car (Local Malaysia) but 0x0131 PID was always returned 7F01 which is 16608KM even after passing few Kms. I tried to reset it by sending 04 command (as Eric suggested on his answer), However, nothing got clear :) and I still got 7F01 as response.
My Library can be used for anyone who is looking for OBD-II lib from here.
So, What I plan to do is, since I'm able to get speed (v) then I'm able to calculate distance based on d = v * t formula.
Elm Electronics are right. The resetting trouble codes solution is a possible, but maybe unwanted workaround though.
Mode 04 is for resetting the codes. Sending 04 will reset the MIL (Malfunction Indicator Light) and reset the codes you want to reset.
In the comments, Chris suggested to use the value, and than keep track of this value yourself. That way you don't need to misuse the Mode 04.
Th 0131 value overflows at 65535 km. But when you bring you car in for maintenance, they could reset this value, depending on who is maintaining your car ofcourse.
Source: Mode 04 - Wikipedia
There are two PIds: 0x0121 Distance travelled with malfunction indicator lamp (MIL) on which keeps the distance with MIL on and 0x0131 Distance travelled since codes cleared which keeps the distance after clearing the MIL by using mode 0x04. By saying code, it meant the Diagnostics Trouble Code (DTC). When one of them keeps counting the distance the other one is fixed and activation is done for them only based on MIL on or off.
For having the milage, afaik, you need to have current mileage from the odometer as the reference, in addition to those two PIDs. For example, if the current mileage on the odometer* is X and the first time readings for those two PIDs are Y and Z respectively, and x and y are real-time readings from those two PIDs, these two formulas can give you the mileage and trip distance:
Real-Time mileage** = X + (y - Y) + (z - Z)
Trip distance (MIL Off) = x(end) - x(start)
Trip distance (MIL On) = y(end) - y(start)
*The odometer is supposed to be available by PID 0x01A6 Odometer, but in almost all the vehicles, it's not supported.
**The overflow in readings from those two PIDs should be considered as well.
I think You can use the PID 0x011F (Run time since engine start) and PID 0x010D (Vehicle speed). If you save these values in an sd card then you can multiply these two values.
Ok so delta-time is 1/fps right? Say the fps was 50, then delta time would equal 1/50= 0.02. My question is that frame rate varies(one second it might be 50, another it might be 52). So say for one second the fps is 50, that means that delta time will be equal to 0.02, but the NEXT second the fps will be 52, but we don't know that yet. So our animations are being done with delta time of 1/50 but the fps is actually 52. Until the next second is finished we won't know that the fps has changed. This may not seem like a big deal if the changes are small, but if they become very big then we have a problem. So the thing is we are always doing calculations based on the previous second's fps. I want to know how to solve this. Thanks!
You're right that 1/fps = delta-time. However, fps isn't known at the present, and as you pointed out going about it this way would cause a problem! In practice, the formula is re-arranged such that 1/dt = fps.
So, we determine delta-time by determining how much time has passed since the last update( deltaTime = (CurrentTime - LastTime) ). If we were to have a variable that we add delta time to every every update (say, deltaCounter += deltaTime), and another variable which is a counter we add one to each update (Counter++), we would see that when deltaCounter is becomes equal to 1, the Counter variable is our fps for that second.
Further Reading on Delta Time and its Implementation
private static int SENSOR_DELAY_SLOW = 5000000;
sensMngr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensMngr.registerListener(this, sensMngr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SENSOR_DELAY_SLOW);
I want to capture the sensor's data every 5 seconds but it ignores my desired rate. The listener captures values even over 400 times per second.
Of course I can filter incoming data manually in the onSensorChanged(SensorEvent event) method, but my primary aim is to reduce the battery drain.
Documentation
What am I doing wrong?
Thank you.
You want SensorManager.SENSOR_DELAY_UI and you're going to have to filter down from there. There are only 4 selectable speeds and you can't define your own. SENSOR_DELAY_UI tends to go a max of around 3 samples per second and since you are getting results when the sensor values change it can be a few seconds between samples. This will all vary from device to device.
There is no way to define a fixed rate for sensor value delivery in Android.
I'm developing an android application using GPS. I'd like to implement a feature that displays the users average speed over the 1/5/15 minute. Something like the CPU load on unix. I can calculate average easily by cumulating the distance traveled second by second and divide it by the elapsed time, but I can't think of a smart way of calculating the moving average.
Obviously I can get id done by putting the distance between the last and the current position in an array every second while deleting the oldest value.
I'm looking for a neat way of doing this.
Heres one way to go about it that is pretty straight forward:
If you are sampling position every second keep 901 samples in a queue, thats 15 mins worth (and 1 extra).
Position 0 is the most recent measurement, effectively your current position.
For an average speed over the last X minutes:
s = X * 60;
point1 = postion_queue[0]; // this is your current position
point2 = postion_queue[s]; // this is your position s seconds ago
d = distance_between_points(point1, point2);
speed = d / s;
speed is now distance units per second, convert to mph, or kph or whatever units you need. Different values of X can be used for any average between 1 and 15 minutes.
You will need to store all the values for the whole time span, as you already suggested. The reason is that you somehow need to "forget" the contributions of the old values to the moving average. You can't do that exactly if you don't know what these values where (i.e. if you do not store them).
In your case, 1 value each second for 15 minutes amounts to 15 * 60 = 900 data points, that should be OK.
Note that you do not need to perform a sum over the whole array each time you update: You can calculate the new moving average from the number of data points, the new value and the value you are "forgetting" at that moment:
new_average = (n * old_average - x_forget + x_new) / n
Here, n is the number of data points (900 in your case), x_forget is the value you are "forgetting" and x_new is the latest value. You then drop x_forget from the front of your array and store x_new at the end. Instead of an array you might want to use a queue implemented via a linked list.
i am creating an augmented reality app that simply visualices a textview when the phone is facing a Point of Interest (wich gps position is stored on the phone). The textview is painted on the point of interest location in the screen.
It works ok, the problem is that compass and accelerometer are very "variant", and the textview is constantly moving up and down left and right because the innacuracy of the sensors.
there is a way to solve it?
Our problem is same. I also had same problem when I create simple augmented reality project. The solution is to use exponential smoothing or moving average function. I recommend exponential smoothing because it only need to store one previous values. Sample implementation is available below :
private float[] exponentialSmoothing( float[] input, float[] output, float alpha ) {
if ( output == null )
return input;
for ( int i=0; i<input.length; i++ ) {
output[i] = output[i] + alpha * (input[i] - output[i]);
}
return output;
}
Alpha is smoothing factor (0<= alpha <=1). If you set alpha = 1, the output will be same as the input (no smoothing at all). If you set alpha = 0, the output will never change. To remove noise, you can simply smoothening accelerometer and magnetometer values.
In my case, I use accelerometer alpha value = 0.2 and magnetometer alpha value = 0.5. The object will be more stable and the movement is quite nice.
You should take a look at low-pass filters for you orientation data or sensor fusion if you want to a step further.
Good Luck with your app.
JQCorreia
I solved it with a simple trick. This will delay your results a bit but they surly avoid the inaccuracy of the compass and accelerometer.
Create a history of the last N values (so save the value to an array, increment index, when you reach N start with zero again). Then you simply use the arithmetic average of the stored values.
Integration of gyroscope sensor readings can give a huge improvement in the stability of the final estimation of the orientation.
Have a look at the steady compass application if your device has a gyroscope, or just have a look at the video if you do not have a gyroscope.
The integration of gyroscope can be done in a rather simple way using a complementary filter.