我知道我正在尝试使用加速度计来获取设备的线性运动,但我只是在幽默我。
我正在试图找出正确的公式来取Sensor.TYPE_LINEAR_ACCELEROMETER
(我认为这是正常的加速度计数据减去重力)并且基本上说“这已经过了很多时间并且我自上次以来加速了x量,所以我已经旅行了数量。
应该是distanceTraveledOnX = linearAccerationOfX * TimePassed;
在现实世界中足够容易吗?如果我每分钟跑1英里,持续10分钟,那么我已经走了10英里..速度*时间=距离
问题是我不确定linearAcceleration用于度量单位。我知道我的timePassed是在NanoSeconds中,就像我说的那样(在onSensorChanged
中)
currentTime = System.nanoTime(); // var of type(double) timePassed = currentTime - lastTime; lastTime = currentTime;
有人可以帮我找出将linearAcceleration值转换为纳秒测量值的公式。
感谢
修改
这是我目前使用的代码,但我总是得到0:
public void onSensorChanged(SensorEvent evt) {
if (type == Sensor.TYPE_LINEAR_ACCELERATION) {
newTime = System.currentTimeMillis()/1000;
float oldVelocity = lastTime1-lastTime0;
float newVelocity = newTime- lastTime1;
if(oldVelocity<1)oldVelocity =1;
newX = lastX1 + ((lastX1 - lastX0)/oldVelocity)*newVelocity +(evt.values[0]/2)*(newVelocity*newVelocity);
lastX0 = lastX1;
lastX1 = newX;
lastTime0 = lastTime1;
lastTime1 = newTime;
Log.v("SENSOR MAN LINEAR", "new X:"+newX);
}
}
答案 0 :(得分:1)
这个东西是高中物理,如果你不知道加速度和速度之间的区别,你需要在你有任何希望之前复习它。
我可以告诉你这么多:手机或平板电脑的线性加速度读数远远不够精确或准确无法做到你想要的,无需经常校正(通过gps或其他方法)。有一整个研究领域试图解决这个问题。我参加了会议。
也就是说,您还需要考虑设备的方向也会发生变化,除非这是某种特殊应用,例如:该设备被困在只能朝一个方向移动的雪橇上。
让我们假设这种情况,并假设设备绑在雪橇上,设备右侧(+ X轴)沿行进方向对齐。让我们假设在程序启动时已知雪橇的初始位置(称之为X0),并且初始速度为零。
您的代码看起来大致如下:
double x0; // previous position, meters
double x; // current position
double v0; // previous velocity, meters/second
double v; // current velocity
long t0; // previous time, nanoseconds
long t; // current time
public void onStart() {
x0 = getInitialPosition();
x = x0;
v0 = 0;
v = v;
t0 = System.getCurrentTime() * 1000000;
// Enable sensors; left as an exercise for the reader
}
public void onSensorChanged(SensorEvent event) {
// Assume linear acceleration is the only active sensor
double accel = event.values[0]; // X axis is our axis of acceleration
t = event.timestamp;
double dt = (t - t0) * .000001;
v = v0 + accel * dt;
x = x0 + v * dt;
t0 = t;
v0 = v;
x0 = x;
}
这绝不是一个完整的解决方案。这样做的权利涉及微分方程式,我没有在这里解释(翻译:我忘记了我在大学里学到的一切)。但是,如果您的加速度值足够准确,并且您的时间片足够短,那么这是可行的。
如果您需要在多个方向上解决这个问题,只要设备永远不会改变方向,它就会稍微复杂一些。如果是,那么您还需要捕获旋转传感器并了解四元数和旋转矩阵。
即使你做的一切都是正确的,错误仍会累积,所以现在你需要某种基于GPS的校正因子,已知的环境几何形状(例如,如果你在室内,软件有一个建筑物的地图,它可以在转弯时进行修正),以及其他环境线索,例如已知位置的WiFi热点。
此时您可能想要阅读卡尔曼滤波器。
执行摘要:在一般情况下,这是一个很难解决的问题,如果你解决了这个问题,可能会有名气和财富等着你。
答案 1 :(得分:0)
嗯,从学校知道的正确形式是 finalXPosition =(linearAcceleration * timePassed ^ 2)/ 2 + initialVelocity * timePassed + initialXPosition
finalVelocity = initialVelocity * timePassed
链接这些块你将获得理论价值。
在实践中,通过GPS定期校准initialXPosition和initialVelocity可以获得最佳效果。
在onSensorChanged中接收校准水平加速度的简单示例:
class Integrator {
private float position = 0f;
private float velocity = 0f;
public void setGpsPosition (float gpsPosition) {
position = gpsPosition;
}
public void setGpsVelocity (float gpsVelocity) {
velocity = gpsVelocity;
}
public void onAccelerationChangeHandler(float acceleration, float timePassed) {
position += acceleration*timePassed*timePassed/2f + velocity*timePassed;
velocity += acceleration*timePassed;
}
public float getCurrentPosition() {
return position;
}
}
x-acceleration的用法:
long lastTime = 0;
public void onSensorChanged(SensorEvent evt) {
if (evt.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
long newTime = System.currentTimeMillis();
OnAccelerationChangeHandler(evt.values[0], (newTime-lastTime)/1000);
lastTime = newTime;
}
请注意,在一分钟范围之外,错误会使这一切毫无意义,无需gps校正。明白,如果你以恒定速度行走,传感器根本不会给你任何东西。