8

Possible Duplicate:
Android accelerometer accuracy (Inertial navigation)

I am using the following code to calculate the distance. tnew and anew are arraylists containing timestamps and accelerations respectively.

 double distance=0;
 double init_vel=0;
long time_prev=tnew.next();
   while(anew.hasNext())
   {
    float temp_acc=anew.next();
    long temp_time=tnew.next();

    interval=(temp_time-time_prev)/1000f;   //milliseconds to seconds
    double fin_vel=init_vel+(temp_acc*interval);
    distance+=(init_vel*interval)+0.5f*temp_acc*interval*interval;

    init_vel=fin_vel;
    time_prev=temp_time;
   }


Is there any logical mistake in the code? Because I am getting values much smaller than the actual length.

Output of LogCat :

--------- beginning of /dev/log/system

--------- beginning of /dev/log/main

V/PhonetapeActivity( 8842): Sensor Listener Registered

V/PhonetapeActivity( 8842): Sensor Unregistered

V/PhonetapeActivity( 8842): No. of Iterations : 49

V/PhonetapeActivity( 8842): Value of acceleration : 3.5762787E-7

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665585965

V/PhonetapeActivity( 8842): Value of acceleration : -0.15275347

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586017

V/PhonetapeActivity( 8842): Value of acceleration : 0.15585232

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586077

V/PhonetapeActivity( 8842): Value of acceleration : 1.075269

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586138

V/PhonetapeActivity( 8842): Value of acceleration : 3.6529458

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586199

V/PhonetapeActivity( 8842): Value of acceleration : 9.645137

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586257

V/PhonetapeActivity( 8842): Value of acceleration : 17.022213

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586316

V/PhonetapeActivity( 8842): Value of acceleration : 9.721476

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586376

V/PhonetapeActivity( 8842): Value of acceleration : -18.729362

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586437

V/PhonetapeActivity( 8842): Value of acceleration : -22.868385

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586497

V/PhonetapeActivity( 8842): Value of acceleration : -16.777517

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586557

V/PhonetapeActivity( 8842): Value of acceleration : -7.0492268

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586617

V/PhonetapeActivity( 8842): Value of acceleration : -3.860828

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586677

V/PhonetapeActivity( 8842): Value of acceleration : 1.7244682

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586737

V/PhonetapeActivity( 8842): Value of acceleration : 5.0734243

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586797

V/PhonetapeActivity( 8842): Value of acceleration : 6.4193974

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586857

V/PhonetapeActivity( 8842): Value of acceleration : 2.739545

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586917

V/PhonetapeActivity( 8842): Value of acceleration : 5.559997

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586977

V/PhonetapeActivity( 8842): Value of acceleration : 4.2290807

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587037

V/PhonetapeActivity( 8842): Value of acceleration : 5.0012918

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587097

V/PhonetapeActivity( 8842): Value of acceleration : 5.9317436

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587157

V/PhonetapeActivity( 8842): Value of acceleration : 5.20226

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587217

V/PhonetapeActivity( 8842): Value of acceleration : 7.1381693

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587276

V/PhonetapeActivity( 8842): Value of acceleration : 7.6460614

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587337

V/PhonetapeActivity( 8842): Value of acceleration : 5.566694

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587396

V/PhonetapeActivity( 8842): Value of acceleration : 3.355657

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587457

V/PhonetapeActivity( 8842): Value of acceleration : 1.8876343

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587517

V/PhonetapeActivity( 8842): Value of acceleration : -0.8815446

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587577

V/PhonetapeActivity( 8842): Value of acceleration : -0.9595623

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587646

V/PhonetapeActivity( 8842): Value of acceleration : -4.233544

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587697

V/PhonetapeActivity( 8842): Value of acceleration : -1.9580669

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587765

V/PhonetapeActivity( 8842): Value of acceleration : -1.4569702

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587822

V/PhonetapeActivity( 8842): Value of acceleration : -0.6058636

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587876

V/PhonetapeActivity( 8842): Value of acceleration : -0.21207428

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587937

V/PhonetapeActivity( 8842): Value of acceleration : 0.5068469

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587997

V/PhonetapeActivity( 8842): Value of acceleration : 5.614555

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588057

V/PhonetapeActivity( 8842): Value of acceleration : -4.5297813

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588122

V/PhonetapeActivity( 8842): Value of acceleration : -0.29250193

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588178

V/PhonetapeActivity( 8842): Value of acceleration : -2.4922757

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588237

V/PhonetapeActivity( 8842): Value of acceleration : -1.7652755

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588297

V/PhonetapeActivity( 8842): Value of acceleration : -2.3279366

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588357

V/PhonetapeActivity( 8842): Value of acceleration : -1.8127642

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588419

V/PhonetapeActivity( 8842): Value of acceleration : -1.956768

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588477

V/PhonetapeActivity( 8842): Value of acceleration : -0.8337221

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588537

V/PhonetapeActivity( 8842): Value of acceleration : -0.24841261

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588601

V/PhonetapeActivity( 8842): Value of acceleration : 0.23997736

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588657

V/PhonetapeActivity( 8842): Value of acceleration : 0.14441395

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588723

V/PhonetapeActivity( 8842): Value of acceleration : 0.23150349

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588777

V/PhonetapeActivity( 8842):  1st while loop ended

V/PhonetapeActivity( 8842): 2nd while loop ended

V/PhonetapeActivity( 8842): Avg value : 0.4006781578063965

V/PhonetapeActivity( 8842): Max Value : 17.022213

V/PhonetapeActivity( 8842): Min Value : -22.868385

V/PhonetapeActivity( 8842): Standard Deviation : -0.0031174493

V/PhonetapeActivity( 8842): 3rd while loop started

V/PhonetapeActivity( 8842): startpos=3 endpos=8

V/PhonetapeActivity( 8842): acceleration=0.1558523178100586 interval=0.061000000685453415

V/PhonetapeActivity( 8842): distance=5.799264876044276E-4

V/PhonetapeActivity( 8842): next init velocity=0.009506991493243078

V/PhonetapeActivity( 8842): acceleration=1.0752689838409424 interval=0.061000000685453415

V/PhonetapeActivity( 8842): distance=0.005160928954000712

V/PhonetapeActivity( 8842): next init velocity=0.07509840024458736

V/PhonetapeActivity( 8842): acceleration=3.6529457569122314 interval=0.057999998331069946

V/PhonetapeActivity( 8842): distance=0.021805144861910285

V/PhonetapeActivity( 8842): next init velocity=0.2869692480489858

V/PhonetapeActivity( 8842): acceleration=9.645136833190918 interval=0.05900000035762787

V/PhonetapeActivity( 8842): distance=0.07231105232279186

V/PhonetapeActivity( 8842): next init velocity=0.8560323246566197

V/PhonetapeActivity( 8842): acceleration=17.022212982177734 interval=0.05999999865889549

V/PhonetapeActivity( 8842): distance=0.18495295465057213

V/PhonetapeActivity( 8842): next init velocity=1.8773650807587172

V/PhonetapeActivity( 8842): 3rd while loop ended

V/PhonetapeActivity( 8842): final distance=0.18495295465057213

V/PhonetapeActivity( 8842): values of acceleration, timestamp, distance, start_time and calibrating reset


If you observe the logcat, first it iterates through 49 values of acceleration and their respective time stamps in milliseconds. Then there is a avg, sum, max, min etc.
Then if you see there is a startpos=3 and endpos=8. This is the iteration number range, I am using to calculate the distance .i.e I am using the values of acceleration and timestamp only from iteration 3 to 8.
This is because, I detect the start of distance calculation from a rise in acceleration to a sudden change in the opposite direction. You can see that the values from 3-8 fit into the logic. From 3 there is a considerable rise in acceleration and after 8 there is a sudden decrease.

4

3 回答 3

6

加速度计非常精确,但不擅长航位推算。陀螺仪擅长于此,但随着时间的推移它们会“漂移”。“传感器融合”是串联使用加速度/陀螺仪数据来纠正对方不足的过程。AFAIR,Galaxy Ace 上未启用“传感器融合”。LINEAR_ACCELERATION只不过是ACCELEROMETER-重力分量。在没有陀螺仪的设备上,根据定义,融合是不可能的,它需要加速度+陀螺仪。

加速度计数据包含 9.8 的重力分量。这可以通过简单地确定加速度计数据的 2 个连续样本之间的差异来过滤掉。这给了我们LINEAR_ACCELERATION数据。

检查一下实际的内部代码:
frameworks/base/services/sensorservice/LinearAccelerationSensor.cpp上述文件中感兴趣
的函数。LinearAccelerationSensor::process()

此外,上述链接和视频所讨论的过滤/平均等基本操作也需要在您的应用程序中获得的加速度数据上执行。以这种方式获得的处理值将比原始值更好(尽管不如您的设备上存在传感器融合所获得的值)。然后可以使用这些来更准确地计算速度和位置。

也就是说,每秒 16 个样本(@poll-rate=60ms)本身就相对不准确。您可能想尝试注册sensorEventListnerusingSENSOR_DELAY_FASTEST以查看您可以在设备上获得的最大样本数。

另请注意,手机上的加速度计被限制在某个 MAX 灵敏度(通常为 -/​​+ 2/4/8 G 范围)。虽然正常的步行/跑步可能会在这些范围内运行,但突然的加速冲动(例如在自行车上)肯定会被限制在 MAX 上,并且您将在航位推算中失去同步。这可以通过注意非常接近 -/+MAX 的样本数来检查。-/+MAX 处的大量样本意味着您肯定会失去与实际位置的同步。

于 2012-10-19T03:04:15.283 回答
4

我要检查的第一件事是您的时间间隔。我不确定它是否被正确转换。时间戳如下所示:

public long timestamp 事件发生的时间,以纳秒为单位

所以在文档中,我们看到转换是通过除以 10 亿而不是 1000 来完成的。

float dT = (event.timestamp - timestamp) / 1000000000.0f;
timestamp = event.timestamp;

也就是说,我认为更改只会缩小值,但要计算真实世界的距离,您需要注意您的单位。

接下来,在阅读这些内容时,人们总是在讨论您需要如何知道每次读数的初始位置,以便对现实世界的线性测量有意义。我没有看到您跟踪您之前的加速度,这将使每个后续测量的积分基于瞬时加速度或加速度的变化,而不是完全加速度。

尝试这样的事情:

final int X = 0;
double distance[];
double init_vel[];
double total_Accel[];

void dblIntegrate(SensorEvent event){
    double data[] = new double[3];
    for(int i = 0; i < event.lenght; i++){
        data[i] = (double)event[i];
        total_Accel[i] += data[i];
        vel[i] = init_vel[i] + (total_Accel[i] * dt);
        init_vel[i] = vel[i];

        ....rinse and repeate to get distance
        (not using the accel data of course)
    }
}

我意识到您理解这一点,但对于其他正在阅读此内容的人 => 请记住,您不能在每次调用 dblIntegrate() 时重新实例化计数变量 total_Accel 或 init_vel。

如果你做得对,你应该看到 total_Accel 从零到某个最大值,然后在每次移动设备时回到零。这意味着每次设备向任何方向移动时,您都在添加等量的正加速度和负加速度。

我相信这是最难正确理解的加速度属性,因为要让设备从静止状态变为静止状态,您的 total_acceleration 将从零到最大 pos/neg 值回到零到相反的最大值,然后回到零。

例如,如果我将手机背面放在桌子上,底部朝向我的胸部,向右移动一米,你会得到这样的结果:

total_Accel = 0.0(0 米)

总加速度 = 0.5

total_Accel = 1.0

total_Accel = 1.5(约 0.25 米)

total_Accel = 1.0

总加速度 = 0.5

total_Accel = 0.0(如果加速度完全分布,0.5 米)

total_Accel = -0.5

total_Accel = -1.0

total_Accel = -1.5(约 0.75 米)

total_Accel = -1.0

total_Accel = -0.5

total_Accel = 0.0(1 米)

在示例中,您可以开始了解为什么简单地对加速度变化进行双重积分不会给您带来速度/位移的真正变化。

无论如何我希望如此,因为写这篇文章比我想象的要长得多!:)

于 2012-10-17T20:24:18.623 回答
2

这是对您问题的回答:

为什么我需要跟踪我之前的加速度。onSensorChanged(MotionEvent event){} 在加速度发生变化时调用。它提供了新的加速度,而不是加速度的变化。

简短的回答是,在不包括初始条件(您之前的总加速度)的情况下整合读数,您最终将得到一个不包括所有信息的值。另外,你走得越久,你的价值就越远离真实价值,因为你失去了越来越多的信息。

我不认为你想要解释加速度、速度和位移(这不是那个地方)所以也许我可以通过扩展我上面包含的例子来展示它。

一部手机靠在桌子上,底部朝向我的胸部,它向右移动任意距离并停止。如果你查看你的数据,你会得到类似的东西。当然,实际数字会有很大差异,但它们的符号会是相同的,比例会是一样的,但会像你预期的那样开始小于它们的峰值(除非你用枪射在墙上或其他什么地方) .:

时间…………加速度读数…………总加速度…………总速度


00 毫秒............. 0.0............0.0............ …………0.000……

10 毫秒............ 0.5............ 0.5............ ............0.005 米/秒..

20 毫秒............ 0.5............ 1.0............ ............0.015 米/秒..

30ms............ 0.5............1.5............ ............0.030 米/秒..

40ms............ -0.5............1.0............ ............0.040 米/秒..

50ms............ -0.5............0.5............ ............0.045 米/秒..

60ms............ -0.5............0.0............ ............0.045 米/秒..

70ms............ -0.5............-0.5............ ............0.040 米/秒..

80ms............ -0.5............ -1.0............ ............0.030 米/秒..

90ms............ -0.5............ -1.5............ ............0.015 米/秒..

100ms............ 0.5............-1.0............ ............0.005 米/秒..

110ms............ 0.5............-0.5............ ............0.000 米/秒..

120 毫秒............ 0.5......................0.0............ ............0.000 米/秒..

您可以看到,如果您不跟踪总加速度,您的总速度将是上面标记为 Total Accel 的列。这意味着您的手机将始终沿 x 轴的正方向移动,但您的速度将在运动的后半部分为负(向后移动)。

我希望这能证明我的情况,即使它不能解释加速度或加速度计背后的机制。

如果您想了解加速度计的工作原理,它们是 MEMS 类型的传感器,我认为它们使用带有加重端的悬挂悬臂梁来测量加速度的力。

于 2012-10-18T15:54:24.547 回答