📜 ⬆️ ⬇️

Data from HTC Desire sensors

Introduction


Hi harassocial! I have long wanted to write an article, as I once had to work with the data received from HTC Desire sensors, which are running Android.
image
The goal was to: determine the movement of the object. That is, according to the data from the sensors, it was possible to obtain the values ​​of the accelerations and the moments of time of these measurements. Further processing the data already calculate the speed, and then move.

Work with data


For a start, I had to tinker with the development environment for the android. Previously, I had no programming experience in the middle of Eclipse in Java, I had to learn the basics. But in the end, an application was written that collected data into the SQLite database on a microSD card. Here are the first data that were obtained:

This is a graph of acceleration (Y axis) versus time (X axis), in this experience, the phone was simply pushed on the table so that it slid. Then we went to all sorts of tests, I wanted to check, for example, the saturation value of the sensors (the maximum measurable value of acceleration). The phone moved on a circular trajectory with gradual acceleration. Graph data below:

The saturation of the sensors occurred at a value of approximately 18.35 m / s ^ 2.
Then I wanted to try to process the received data:

An example is also shown of the phone sliding on the table: the blue line is acceleration, the red line is speed and the green line is displacement. This is not very good, one of the first examples. There was no way to determine the movement.
Here is a more perfect example of such an experience:

Here, after processing the data, a plausible value for moving the phone around the table was obtained.
Later I wanted to see how the data will look when walking with the phone:

And also when running with the phone:

On the example of walking and running, it is already clearly visible how various errors from the sensors accumulate; for their further exclusion, a detailed study of the processes of obtaining all these data is required. In particular, there is data only from one X axis, there is no consideration of the effect of gravitational acceleration on the sensors (rotation in the phone space is not taken into account). Here is an example in which this rotation, hence the effect of gravity was eliminated from one of the axes:

in this experience, the phone was lying on the table, and one of its sides was raised to the ghost of the perpendicular position of the phone to the table. Here, the red line is the angle (obtained from the compass), green is the value on the acceleration sensor (in fact, value = acceleration + gravity), violet is the value of acceleration (corrected for angle values). That is, in this example, it was possible to eliminate the influence of gravity.

Conclusion


This question is very interesting, and these examples are just a small manifestation of my curiosity. As it turned out, the frequency of measurements from these sensors is too small to get really high-quality data, but I think when there will be time to do more detailed study of this issue.

UPD: I dug up the source code of one of the program variants, please do not scold this only acquaintance with Java for android:
')
package com.dimond.acc;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.database.sqlite.SQLiteDatabase;

public class acc extends Activity implements SensorListener {

public class AXYZTdata
{
float ax;
float ay;
float az;
long time;
public AXYZTdata( float in_ax, float in_ay, float in_az, long in_time)
{
ax = in_ax;
ay = in_ay;
az = in_az;
time = in_time;
}
}
SensorManager sm = null ;
final String tag = "logging" ;
private EditText MassivN;
TextView DataText;
String TimeNowtmp;
int N, sec, stroka=0;
AXYZTdata[] mass = new AXYZTdata[10000];
float acc_x, acc_y, acc_z, acc_time = 0;
SQLiteDatabase mDatabase = SQLiteDatabase.openOrCreateDatabase( "/mnt/sdcard/DB/" +String.valueOf(System.currentTimeMillis())+ ".db" , null );
int onoff=0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
Button start = (Button) findViewById(R.id.Start);
Button stop = (Button) findViewById(R.id.Stop);
Button write = (Button) findViewById(R.id.Write);
DataText = (TextView) findViewById(R.id.data);
//
String DATABASE_CREATE =
"create table accdb" +
"(_id integer primary key autoincrement, " +
"acc_x text not null," +
"acc_y text not null," +
"acc_z text not null," +
"time_h_m_s text not null);" ;
mDatabase.execSQL(DATABASE_CREATE);
//
start.setOnClickListener( new OnClickListener() {
public void onClick(View arg0)
{
startwrite();
}
});
//
stop.setOnClickListener( new OnClickListener() {
public void onClick(View arg0)
{
stopwrite();
}
});
//
write.setOnClickListener( new OnClickListener() {
public void onClick(View arg0)
{
masstosql();
DataText.setText( "Writed!!!" );
}
});
}


public void startwrite()
{
onoff=1;
return ;
}
public void stopwrite()
{
onoff=0;
DataText.setText(String.valueOf(stroka));
return ;
}
public void masstosql()
{
long StartTime = mass[0].time;
for ( int i=0; i<stroka; i++)
{
mDatabase.execSQL(String.format( "INSERT INTO accdb (acc_x, acc_y, acc_z, time_h_m_s) VALUES ('%s','%s','%s','%s');" ,
mass[i].ax, mass[i].ay, mass[i].az, mass[i].time-StartTime));
}
return ;
}

public void onSensorChanged( int sensor, float [] values) {
synchronized ( this ) {
Log.d(tag, "onSensorChanged: " + sensor + ", x: " + values[0] + ", y: " + values[1] + ", z: " + values[2]);
if (sensor == SensorManager.SENSOR_ACCELEROMETER && onoff==1) {
AXYZTdata tmp;
tmp = new AXYZTdata(values[0], values[1],values[2], System.currentTimeMillis());
mass[stroka] = tmp;
stroka++;
}
}
}
public void onAccuracyChanged( int sensor, int accuracy) {
Log.d(tag, "onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);
}
@Override
protected void onResume() {
super.onResume();
sm.registerListener( this , SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_FASTEST);
}

@Override
protected void onStop() {
sm.unregisterListener( this );
super.onStop();
}


}


* This source code was highlighted with Source Code Highlighter .


Who cares here the draft application .

Source: https://habr.com/ru/post/119360/


All Articles