检测 iPhone 何时被碰撞

发布于 2024-11-27 14:39:18 字数 1649 浏览 4 评论 0原文

我希望能够检测 iPhone 是否撞到了什么东西......最好听陀螺仪/加速计并判断其移动速度或是否突然移动和停止。

事实上,我如何判断设备是否移动然后突然停止?

这个答案很好,但相反iOS :根据加速度计输出准确确定碰撞的能量 - 它可以平滑运动,如果我想检测急剧的运动的话。

陀螺仪和加速度计也可用于 3GS 吗?

更新代码

来自Apple文档http://developer.apple.com/library/iOS/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html#//apple_ref/doc/uid/TP40009541-CH4-SW26

从加速度数据中分离瞬时运动 如果您使用加速度计数据仅检测设备的即时运动,则需要能够将运动的突然变化与重力的恒定影响隔离开来。您可以使用高通滤波器来做到这一点。

清单 4-6 显示了简化的高通滤波器计算。前一个事件的加速度值存储在该类的 accelX、accelY 和 accelZ 成员变量中。此示例计算低通滤波器值,然后从当前值中减去该值以获得运动的瞬时分量。

清单 4-6 从加速度计数据中获取运动的瞬时部分

define kFilteringFactor 0.1

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    // Subtract the low-pass value from the current value to get a simplified high-pass filter
    accelX = acceleration.x - ( (acceleration.x * kFilteringFactor) + (accelX * (1.0 - kFilteringFactor)) );
    accelY = acceleration.y - ( (acceleration.y * kFilteringFactor) + (accelY * (1.0 - kFilteringFactor)) );
    accelZ = acceleration.z - ( (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor)) );

   // Use the acceleration data.
}

那么我将如何“使用加速度数据”来计算是否检测到瞬时运动?

I want to be able to detect if an iphone has been bumped into something...would it be best to listen to the gyroscope / accelerometer and judge how fast its moved or if its moved and stopped suddenly.

In fact how would I judge if the device has moved then stopped suddenly?

This answer is great but in reverse iOS: Accurately determining energy of a bump from accelerometer output - it smooths out the movement, if anything I want to detect a sharp movement.

Also are both the Gyroscope and Accelerometer available for 3GS ?

UPDATED WITH CODE

From the Apple doc http://developer.apple.com/library/iOS/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html#//apple_ref/doc/uid/TP40009541-CH4-SW26

Isolating Instantaneous Motion from Acceleration Data
If you are using accelerometer data to detect just the instant motion of a device, you need to be able to isolate sudden changes in movement from the constant effect of gravity. You can do that with a high-pass filter.

Listing 4-6 shows a simplified high-pass filter computation. The acceleration values from the previous event are stored in the accelX, accelY, and accelZ member variables of the class. This example computes the low-pass filter value and then subtracts it from the current value to obtain just the instantaneous component of motion.

Listing 4-6 Getting the instantaneous portion of movement from accelerometer data

define kFilteringFactor 0.1

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    // Subtract the low-pass value from the current value to get a simplified high-pass filter
    accelX = acceleration.x - ( (acceleration.x * kFilteringFactor) + (accelX * (1.0 - kFilteringFactor)) );
    accelY = acceleration.y - ( (acceleration.y * kFilteringFactor) + (accelY * (1.0 - kFilteringFactor)) );
    accelZ = acceleration.z - ( (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor)) );

   // Use the acceleration data.
}

How would I then 'Use the acceleration data' to work out if an instantaneous motion is detected?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ま昔日黯然 2024-12-04 14:39:18

正确的方法是在传感器融合后使用高通滤波器和线性加速度。检查 Sensor.TYPE_LINEAR_ACCELERATION 此处,它适用于 Android。 据我所知,iPhone 没有传感器融合功能。 正如 Kay 指出的,Core Motion 提供了传感器融合功能,请参阅下面的评论。

如果您感兴趣,这里有一个精彩的有关传感器融合的视频,从 32:10 开始。

一个有点混乱的解决方法是使用高通滤波器并使用加速度计数据而不进行传感器融合。如果你的手机撞到什么东西,你可能也会在陀螺仪数据中得到峰值,但根据我的经验,加速度计更好,因为它们可以检测突然的速度变化。

这很混乱,因为你可以通过快速旋转手机来愚弄它。

The proper way would be to use a high-pass filter and linear acceleration after sensor fusion. Check Sensor.TYPE_LINEAR_ACCELERATION here, it is for Android. As far as I know iPhone does not have sensor fusion. As Kay pointed it out, Core Motion provides sensor fusion, see the comment below.

If you are interested, here is an excellent video on sensor fusion, start at 32:10.

A somewhat messy workaround is to use a high-pass filter and to use the accelerometer data without sensor fusion. If you bump to phone into something you might get spikes in the gyro data too but in my experience the accelerometers are better as they detect sudden velocity changes.

It is messy because you can fool this by quickly rotating the phone.

深海不蓝 2024-12-04 14:39:18

我使用了这段代码:

#define kUpdateFrequency    100.0
#define kFilteringFactor    0.1
float accelZ;
int spikeZCount = 0; 

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0 / kUpdateFrequency];
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];

- (void) accelerometer: (UIAccelerometer *) accelerometer didAccelerate: (UIAcceleration *) acceleration 
{
    accelZ = acceleration.z - ( (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor)) );

    if (accelZ > 0.0f)
    {
        if (spikeZCount > 9)
        {
            //  NSLog(@"SPIKE!");
            [[UIAccelerometer sharedAccelerometer] setDelegate:nil];

            [self isBumped];
        }
        else
        {
            spikeZCount++;
            //  NSLog(@"spikeZCount %i",spikeZCount);
        }
    }
    else
    {
        // NSLog(@"spikeZCount Reset");
        spikeZCount = 0;
    }
}

I used this code:

#define kUpdateFrequency    100.0
#define kFilteringFactor    0.1
float accelZ;
int spikeZCount = 0; 

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0 / kUpdateFrequency];
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];

- (void) accelerometer: (UIAccelerometer *) accelerometer didAccelerate: (UIAcceleration *) acceleration 
{
    accelZ = acceleration.z - ( (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor)) );

    if (accelZ > 0.0f)
    {
        if (spikeZCount > 9)
        {
            //  NSLog(@"SPIKE!");
            [[UIAccelerometer sharedAccelerometer] setDelegate:nil];

            [self isBumped];
        }
        else
        {
            spikeZCount++;
            //  NSLog(@"spikeZCount %i",spikeZCount);
        }
    }
    else
    {
        // NSLog(@"spikeZCount Reset");
        spikeZCount = 0;
    }
}

根据之前的答案,我进行了一些概括,得出以下效果非常好的结果:

// Isolate Instantaneous Motion from Acceleration Data
// (using a simplified high-pass filter)
CMAcceleration acceleration = accelerometerData.acceleration;
float prevAccelX = w_self.accelX;
float prevAccelY = w_self.accelY;
float prevAccelZ = w_self.accelZ;
w_self.accelX = acceleration.x - ( (acceleration.x * kFilteringFactor) +
                                   (w_self.accelX * (1.0 - kFilteringFactor)) );
w_self.accelY = acceleration.y - ( (acceleration.y * kFilteringFactor) +
                                   (w_self.accelY * (1.0 - kFilteringFactor)) );
w_self.accelZ = acceleration.z - ( (acceleration.z * kFilteringFactor) +  
                                   (w_self.accelZ * (1.0 - kFilteringFactor)) );

// Compute the derivative (which represents change in acceleration).
float deltaX = ABS((w_self.accelX - prevAccelX));
float deltaY = ABS((w_self.accelY - prevAccelY));
float deltaZ = ABS((w_self.accelZ - prevAccelZ));

// Check if the derivative exceeds some sensitivity threshold
// (Bigger value indicates stronger bump)
float sensitivityThreshold = 1.0;
float bumpVectorLength = sqrtf(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ);
if ( bumpVectorLength > sensitivityThreshold ) {
    NSLog( @"BUMP:  |%.3f, %.3f, %.3f| = %.3f", deltaX, deltaY, deltaZ, bumpVectorLength);
}

From the previous answers, I generalized a bit to get the following which works pretty well:

// Isolate Instantaneous Motion from Acceleration Data
// (using a simplified high-pass filter)
CMAcceleration acceleration = accelerometerData.acceleration;
float prevAccelX = w_self.accelX;
float prevAccelY = w_self.accelY;
float prevAccelZ = w_self.accelZ;
w_self.accelX = acceleration.x - ( (acceleration.x * kFilteringFactor) +
                                   (w_self.accelX * (1.0 - kFilteringFactor)) );
w_self.accelY = acceleration.y - ( (acceleration.y * kFilteringFactor) +
                                   (w_self.accelY * (1.0 - kFilteringFactor)) );
w_self.accelZ = acceleration.z - ( (acceleration.z * kFilteringFactor) +  
                                   (w_self.accelZ * (1.0 - kFilteringFactor)) );

// Compute the derivative (which represents change in acceleration).
float deltaX = ABS((w_self.accelX - prevAccelX));
float deltaY = ABS((w_self.accelY - prevAccelY));
float deltaZ = ABS((w_self.accelZ - prevAccelZ));

// Check if the derivative exceeds some sensitivity threshold
// (Bigger value indicates stronger bump)
float sensitivityThreshold = 1.0;
float bumpVectorLength = sqrtf(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ);
if ( bumpVectorLength > sensitivityThreshold ) {
    NSLog( @"BUMP:  |%.3f, %.3f, %.3f| = %.3f", deltaX, deltaY, deltaZ, bumpVectorLength);
}
温暖的光 2024-12-04 14:39:18

iPhone 3GS 有加速计,但没有陀螺仪。但是,根据 http://techcrunch.com,支持陀螺仪/2010/06/18/iphone-4-陀螺仪-perspectiverse/

iPhone 3GS has Accelerometer but not Gyroscope. However, there is support for Gyroscope according to http://techcrunch.com/2010/06/18/iphone-4-gyroscope-perspectiverse/.

情话已封尘 2024-12-04 14:39:18

这取决于不同的情况:

  1. 手机是否在空中自由落体(或被抛出),即您不再将其握在手中。
  2. 如果自由落体,我的猜测是这取决于手机当时的入射角
    正在撞击障碍物。如果手机正好落在其中之一上
    其表面,陀螺仪不会报告旋转。但这很难确定。
  3. 你碰撞的材料的弹性。

我同意阿里关于加速度的回答,但不同意投掷时的答案。但无论如何请记住,一款让用户扔掉 iPhone 的应用程序不太可能获得应用程序商店的批准,-)

It depends on different circumstances:

  1. Whether the phone is falling free in the air (or was thrown) i.e. you don't hold it in your hand anymore.
  2. If falling free my guess is it depends on the incident angle at the moment the phone
    is striking the obstacle. If the phone is falling exactly on one of
    its faces, the gyro won't report a rotation. But this will be hard to determine.
  3. The elasticity of the material you are bumping in.

I agree with Ali's answer regarding acceleration but not when throwing. But anyway bear in mind that an app that puts the users up to throw their iPhone won't have good chances to get app store approval ,-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文