【问题标题】:Calculating distance using Linear acceleration android [duplicate]使用线性加速度计算距离android [重复]
【发布时间】:2012-10-07 05:55:49
【问题描述】:

可能重复:
Android accelerometer accuracy (Inertial navigation)

我正在使用以下代码来计算距离。 tnewanewarraylists,分别包含 timestampsaccelerations

 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;
   }


代码中是否有任何逻辑错误?因为我得到的值比实际长度小得多。

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


如果您观察 logcat,首先它会迭代 49 个加速度值及其各自的时间戳(以毫秒为单位)。然后是平均值、总和、最大值、最小值等。
然后,如果您看到有startpos=3endpos=8。这是迭代次数范围,我用来计算距离。即,我只使用从迭代 3 到 8 的加速度和时间戳的值。
这是因为,我从 加速度上升到相反方向的突然变化。您可以看到 3-8 中的值符合逻辑。从 3 开始,加速度明显上升,在 8 之后突然下降。

【问题讨论】:

  • 看看我的answer here为什么。
  • @Ali :但是这个链接说他正在使用加速度计获得准确的结果 - stackoverflow.com/questions/7858759/…
  • 我看不到它写在哪里他在双重积分后得到了准确的结果(你想要做什么)。
  • @Ali :他说他在使用加速度计(第 4-5 行)时得到了很好的结果(接近真实值)。我同意他没有计算距离(我是这样),但他正在获得准确的加速度读数。我认为从这些读数中您也可以得到速度和距离。误差不应超过 80%。
  • 我不认为它会起作用,请参阅我第一条评论中链接上的推理。

标签: android accelerometer android-sensors


【解决方案1】:

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

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

查看实际内部代码:
frameworks/base/services/sensorservice/LinearAccelerationSensor.cpp
函数LinearAccelerationSensor::process() 对上述文件很感兴趣。

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

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

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

【讨论】:

  • 感谢您发布 cmets 作为答案。但是你说 Galaxy ACE 上没有启用传感器融合。但是 LINEAR_ACCELERATION 在我的手机(ACE)中有效。 LINEAR_ACCELERATION 是传感器融合的结果。它使用两个或更多传感器来提供线性加速度。
  • LINEAR_ACCELERATION 只不过是ACCELEROMETER - 重力分量。在没有陀螺仪的设备上,融合是不可能的,因为根据定义它需要加速度+陀螺仪。
  • 如果我错了,请纠正我。要找出重力分量,您需要一个陀螺仪。它给出了手机的方向,因此重力分量被移除
  • 不,陀螺仪不是绝对必要的。更新了描述LINEAR_ACCELERATION 传感器内部结构的答案。即在将加速度计数据报告为线性加速度之前对其进行了哪些操作。
  • 假设您在短时间内非常快速地加速到 +3g 的数量级。但是加速度计的范围是-/+2g,他的意思是它会报告+2g(而你实际上是+3g)。所以你的实际位置和计算的位置会有所不同,并且没有真正的方法来纠正这个问题。只是有可能检测到它;因为如果你在 MAX 限制下获得很多值,那么你超过它的机会就更大。再一次,当设备在手且用户步行时,这种“大”加速度并不常见。但是,尽管如此,您还是需要注意这个陷阱。
【解决方案2】:

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

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 米)

total_Accel = 0.5

total_Accel = 1.0

total_Accel = 1.5(约 0.25 米)

total_Accel = 1.0

total_Accel = 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 米)

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

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

【讨论】:

  • 我还没有完全阅读完这篇文章。但是关于时间戳,我使用了 System.currentMillis()。我得到了 60 毫秒的时间间隔,如 delay_sensor_ui 的 android 文档中所指定的那样。
  • 我不明白为什么我需要跟踪我之前的加速度。 onSensorChanged(MotionEvent event){} 在加速度发生变化时调用。它提供了新的加速度,而不是加速度的变化。所以我所需要的只是 x ms 和 x + 60ms 之间的加速度以及 x 处的速度(每 60 ms 后的 i.t 初始速度)
  • 对不起时间戳信息。上个月左右我一直在努力研究这些东西,我想我认为所有传感器都在同一个单位报告时间。在给出错误答案之前,我应该仔细检查我的事实。我确实仔细检查了 SensorEvent event.timestamp 文档,它说它以纳秒为单位,但这是针对 API Level 3 的,所以也许这就是混乱的来源。抱歉,我不能更确定,但希望其他人可以参与进来。
  • 我必须注销,但明天我会就您的第二个问题回复您。基本上它与传感器的工作方式有关。这就是为什么 RC 飞机飞行员说你不能单独使用加速度计来跟踪位置的原因,因为加速度只有在你知道从静止状态开始移动后发生了什么的情况下才有用。如果你还没有,也许你想在谷歌上搜索一个线性加速教程。除非您真正将注意力集中在加速上,否则这一切都是没有意义的。
  • 嘿,伙计们,在这里插话.. 但有人可以解释他说“在没有加速度计数据的情况下冲洗并重复”的最后一部分吗?
【解决方案3】:

这是对您问题的回答:

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

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

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

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

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


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

10 毫秒............ 0.5............ 0.5............ ............0.005 m/s..

20 毫秒............ 0.5............ 1.0............ ............0.015 m/s..

30ms............ 0.5............1.5............ ............0.030 m/s..

40ms............ -0.5............1.0............ ............0.040 m/s..

50ms............ -0.5............0.5............ .......0.045 m/s..

60ms............ -0.5............0.0............ .......0.045 m/s..

70ms............ -0.5............-0.5............ ............0.040 m/s..

80ms............ -0.5............ -1.0............ .......0.030 m/s..

90ms............ -0.5............ -1.5............ ............0.015 m/s..

100ms............ 0.5............-1.0............ ............0.005 m/s..

110ms............ 0.5............-0.5............ ............0.000 m/s..

120 毫秒............ 0.5......................0.0............ ............0.000 m/s..

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

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

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

【讨论】:

  • 可以给我一些代码实现吗?
猜你喜欢
  • 2013-07-08
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多