13

我正在尝试制作一个应用程序,该应用程序可以使用加速度计检测您使用 iPhone 制作的形状。举个例子,如果你用手拿着 iPhone 画一个圆圈,应用程序就可以在屏幕上重新绘制它。这也适用于正方形,甚至更复杂的形状。我见过做这种事情的唯一应用程序示例是 AirPaint ( http://vimeo.com/2276713 ),但它似乎无法实时完成。

我的第一个尝试是对来自加速度计的 X 和 Y 参数应用低通滤波器,并使指针向这些值移动,与屏幕大小成比例。但这显然不够,我的精度很低,如果我摇动设备,它也会使指针移动......

有什么想法吗?你认为加速度计数据足以做到这一点吗?还是我应该考虑使用其他数据,例如指南针?

提前致谢 !

4

4 回答 4

10

好的,我发现了一些似乎可行的方法,但我仍然有一些问题。这是我如何进行的(承认设备是垂直的):

1 - 我有我的默认 x、y 和 z 值。
2 - 我使用低通滤波器从该数据中提取重力矢量。
3 - 我从每个 x、y 和 z 中减去归一化的重力矢量,得到运动加速度。
4 - 然后,我将这个加速度值与时间积分,得到速度。
5 - 我再次将此速度与时间积分,并找到一个位置。

以下所有代码都在我的控制器的加速计中:didAccelerate:委托。我试图让球根据我找到的位置移动。这是我的代码:

NSTimeInterval interval = 0;
NSDate *now = [NSDate date];
if (previousDate != nil)
{
    interval = [now timeIntervalSinceDate:previousDate];
}
previousDate = now;

//Isolating gravity vector
gravity.x = currentAcceleration.x * kFileringFactor + gravity.x * (1.0 - kFileringFactor);
gravity.y = currentAcceleration.y * kFileringFactor + gravity.y * (1.0 - kFileringFactor);
gravity.z = currentAcceleration.z * kFileringFactor + gravity.z * (1.0 - kFileringFactor);
float gravityNorm = sqrt(gravity.x * gravity.x + gravity.y * gravity.y + gravity.z * gravity.z);

//Removing gravity vector from initial acceleration
filteredAcceleration.x = acceleration.x - gravity.x / gravityNorm;
filteredAcceleration.y = acceleration.y - gravity.y / gravityNorm;
filteredAcceleration.z = acceleration.z - gravity.z / gravityNorm;

//Calculating velocity related to time interval
velocity.x = velocity.x + filteredAcceleration.x * interval;
velocity.y = velocity.y + filteredAcceleration.y * interval;
velocity.z = velocity.z + filteredAcceleration.z * interval;

//Finding position
position.x = position.x + velocity.x * interval * 160;
position.y = position.y + velocity.y * interval * 230;

如果我执行这个,我会得到很好的值,我的意思是我可以看到加速度根据我的动作进入正值或负值。但是当我尝试将该位置应用到我的球视图时,我可以看到它正在移动,但倾向于朝一个方向移动而不是另一个方向。这意味着,例如,如果我用我的设备画圆圈,我会看到描述曲线的球朝向屏幕的左上角。类似的东西:http: //img685.imageshack.us/i/capturdcran20100422133.png/

您对正在发生的事情有任何想法吗?提前致谢 !

于 2010-04-22T11:47:27.577 回答
7

问题是你不能两次积分加速度来获得位置。并非不知道初始位置和速度。还记得你在学校学习集成时添加的 +C 术语吗?好吧,当您定位时,它是一个 ct+k 术语。这很重要。那是在您考虑返回的加速度数据被量化和平均之前,因此您实际上并没有整合设备的实际加速度。当集成两次时,这些错误最终会变大。

仔细观看 AirPaint 演示,您会确切地看到这种情况,渲染的形状与移动的形状明显不同。

即使是具有一些位置和速度感应功能的设备(例如 Wiimote)也无法进行手势识别。这是一个棘手的问题,人们付了很多钱(例如,像 AILive 这样的公司)来为他们解决。

话虽如此,如果它们的大规模特征不同,您可能很容易区分某些类型的手势。如果设备在六个角度范围(例如)中的每一个范围内都接收到加速度,则可以检测到一个圆圈。您可以检测到在空中滑动 iPhone 和摇晃它。

要区分圆形和方形将变得更加困难。

于 2010-04-24T00:59:20.523 回答
2

似乎您在减去瞬时加速度之前正在对重力矢量进行归一化。这将保持相对方向但删除任何相对比例。我测试的最新设备(当然不是 Idevice)返回的重力大约为 -9.8,可能校准到 m/s。假设没有其他加速度,如果你要对其进行归一化然后从过滤后的通道中减去它,你最终会得到 -8.8 而不是 0.0f 的当前加速度;

2 个选项: - 您可以在过滤器通过后减去重力矢量 - 捕获初始加速度矢量长度,标准化加速度和重力矢量,通过加速度和重力法线的点缩放加速度矢量。

还值得记住要考虑设备的方向。

于 2010-07-06T21:05:22.263 回答
2

您需要查看加速度与速度和速度与位置的关系。此刻我的脑子里正在放屁,但我确信它是不可或缺的……你想对时间的加速度进行积分。维基百科应该可以帮助您解决数学问题,我相信某处有一个很好的图书馆可以帮助您。

请记住,加速度计并不完美,轮询速度也不够快。真正突然的动作可能不会那么好。但是为了轻轻地在空中画画,它应该可以正常工作。

于 2010-04-20T11:52:00.470 回答