iOS:通过加速计输出精确确定碰撞能量
我正在创建一个音叉应用程序,你可以将iPhone轻拍到另一只手的手掌上,或者轻拍一个柔软的表面,以设置音叉镀锌 所以我想检测每个“凹凸”中包含的能量 编辑:删除了一吨树胶iOS:通过加速计输出精确确定碰撞能量,ios,math,accelerometer,detect,bump,Ios,Math,Accelerometer,Detect,Bump,我正在创建一个音叉应用程序,你可以将iPhone轻拍到另一只手的手掌上,或者轻拍一个柔软的表面,以设置音叉镀锌 所以我想检测每个“凹凸”中包含的能量 编辑:删除了一吨树胶 有人能帮我破解这个吗?首先,你问的问题: A只是校准一下。站立的加速度是重力的稳定拉力,任何突然的偏离都是由于撞击物体而增加的加速度。您还必须跟踪陀螺仪报告的方向变化,这样您就可以忽略重力突然向新方向的移动 B积分加速度,得到速度的变化。这个平方乘以手机的质量,除以2,就是静止帧中的能量 这个问题基本上无法解决。理论上,如果情
有人能帮我破解这个吗?首先,你问的问题: A只是校准一下。站立的加速度是重力的稳定拉力,任何突然的偏离都是由于撞击物体而增加的加速度。您还必须跟踪陀螺仪报告的方向变化,这样您就可以忽略重力突然向新方向的移动 B积分加速度,得到速度的变化。这个平方乘以手机的质量,除以2,就是静止帧中的能量 这个问题基本上无法解决。理论上,如果情况灵活,撞击产生的加速度将倾向于显示为具有特征形状的尖峰状曲线,因此,如果有几个点不在峰值上,则可以估计整个形状。但我怀疑这个装置太僵硬,采样太稀疏。对此你无能为力,除非硬件能为你集成加速功能,我怀疑我不了解iPhone 但无论如何,能源可能不是最好的使用方法;你可以用枕头敲击它和用锤子敲击它一样多的能量,但你不会期望音叉响得那么响。峰值加速度可能更好,但这仍然依赖于来自加速度计的良好数据
你能用一下麦克风吗?试着记录它在你膝盖上敲击时听到的声音,寻找普通声音中不存在的特征,比如,我不知道,大低频振幅,宽频谱,甚至可能是这种情况下的特征共振。它可能仍然会对环境中的嘈杂声做出一点反应,但这是非常现实的。首先,您提出的问题: A只是校准一下。站立的加速度是重力的稳定拉力,任何突然的偏离都是由于撞击物体而增加的加速度。您还必须跟踪陀螺仪报告的方向变化,这样您就可以忽略重力突然向新方向的移动 B积分加速度,得到速度的变化。这个平方乘以手机的质量,除以2,就是静止帧中的能量 这个问题基本上无法解决。理论上,如果情况灵活,撞击产生的加速度将倾向于显示为具有特征形状的尖峰状曲线,因此,如果有几个点不在峰值上,则可以估计整个形状。但我怀疑这个装置太僵硬,采样太稀疏。对此你无能为力,除非硬件能为你集成加速功能,我怀疑我不了解iPhone 但无论如何,能源可能不是最好的使用方法;你可以用枕头敲击它和用锤子敲击它一样多的能量,但你不会期望音叉响得那么响。峰值加速度可能更好,但这仍然依赖于来自加速度计的良好数据
你能用一下麦克风吗?试着记录它在你膝盖上敲击时听到的声音,寻找普通声音中不存在的特征,比如,我不知道,大低频振幅,宽频谱,甚至可能是这种情况下的特征共振。它可能仍然会对环境中的大噪音有一点反应,但这是非常现实的。您需要的是一个卡尔曼滤波器。谷歌搜索这个短语;写一篇文章超出了像这样的互联网论坛的范围。有很多关于卡尔曼滤波器的书 一个问题是:iphone界面并不是真正为你所需要的东西而设计的。正是因为这个问题,我的雇主不得不与苹果合作,访问和咀嚼内部设备。不,我不能说太多关于他们做了什么或者这个项目是什么
关于平放时的加速计读数:它应该向上记录1G,而不是向下记录。没有办法感知地心引力。牛顿的观点:没有重力盾这样的东西。相对论性POV:引力是一种虚构的力。加速度计没有感应重力。它正在感应地球或工作台,将加速计向上推。您需要的是一个卡尔曼滤波器。谷歌搜索这个短语;写一篇文章超出了像这样的互联网论坛的范围。有很多关于卡尔曼滤波器的书 一个问题是:iphone界面并不是真正为你所需要的东西而设计的。正是因为这个问题,我的雇主不得不与苹果合作,访问和咀嚼内部设备。不,我不能说太多关于他们做了什么或者这个项目是什么 关于h时的加速计读数
eld flat:它应该向上注册1G,而不是向下注册。没有办法感知地心引力。牛顿的观点:没有重力盾这样的东西。相对论性POV:引力是一种虚构的力。加速度计没有感应重力。它正在感应地球或桌子,将加速度计向上推。多亏了freenode数学频道上的一个向导,多亏了Igor,我有了一个非常好的工作解决方案 使用标准方法以可能的最大频率100Hz触发回调,该频率将包含瞬时加速度x、y、z值 我会让代码为自己说话,好的代码应该永远为自己说话
typedef
struct {
double x,y,z;
}
vec_d3;
#define RECENT_COUNT 10
#define SMOOTH_IP( x, x_new, fac ) x = fac * x + ( 1. - fac ) * x_new
- (void) accelerometer: (UIAccelerometer *) accelerometer
didAccelerate: (UIAcceleration *) acceleration
{
// smooth incoming acceleration values
static vec_d3 smooth = { DOUBLE_EMPTY, 0, 0 };
{
if ( smooth.x == DOUBLE_EMPTY )
{
smooth.x = acceleration.x;
smooth.y = acceleration.y;
smooth.z = acceleration.z;
return;
}
SMOOTH_IP( smooth.x, acceleration.x, 0.9 );
SMOOTH_IP( smooth.y, acceleration.y, 0.9 );
SMOOTH_IP( smooth.z, acceleration.z, 0.9 );
}
// keep track of last k smoothed acceleration values
static vec_d3 recent[ RECENT_COUNT ];
{
static int ptr = 0;
static BOOL gotEnoughData = NO;
recent[ ptr ] = smooth;
ptr++;
if ( ptr == RECENT_COUNT )
{
ptr = 0;
gotEnoughData = YES;
}
// return if array not filled yet
if ( ! gotEnoughData )
return;
}
// get the resultant variation in acceleration over the whole array
double variation;
{
vec_d3 min = smooth, max = smooth;
for ( int i=0; i < RECENT_COUNT; i++ )
{
min.x = MIN( min.x, recent[ i ].x );
min.y = MIN( min.y, recent[ i ].y );
min.z = MIN( min.z, recent[ i ].z );
max.x = MAX( max.x, recent[ i ].x );
max.y = MAX( max.y, recent[ i ].y );
max.z = MAX( max.z, recent[ i ].z );
}
vec_d3 V = (vec_d3)
{
.x = max.x - min.x,
.y = max.y - min.y,
.z = max.z - min.z
};
variation = sqrt(
V.x * V.x +
V.y * V.y +
V.z * V.z
);
}
// smooth it
static double var_smoothed = DOUBLE_EMPTY;
{
if ( var_smoothed == DOUBLE_EMPTY )
{
var_smoothed = variation;
return;
}
SMOOTH_IP( var_smoothed, variation, 0.9 );
}
// see if it's just passed a peak
{
static double varSmoothed_last = DOUBLE_EMPTY;
if ( varSmoothed_last == DOUBLE_EMPTY )
{
varSmoothed_last = var_smoothed;
return;
}
static double varSmoothed_preLast = DOUBLE_EMPTY;
if ( varSmoothed_preLast == DOUBLE_EMPTY )
{
varSmoothed_preLast = varSmoothed_last;
varSmoothed_last = var_smoothed;
return;
}
#define THRESHOLD_IMPULSE .15
if ( varSmoothed_last > varSmoothed_preLast
&& varSmoothed_last > var_smoothed
&& varSmoothed_last > THRESHOLD_IMPULSE )
{
LOG ( @"PotPeak @ %f", varSmoothed_last );
// hit a peak at imp_last
[self peakedWithImpulse: varSmoothed_last ];
}
varSmoothed_preLast = varSmoothed_last;
varSmoothed_last = var_smoothed;
}
}
多亏了freenode数学频道上的一个向导,多亏了Igor,我有了一个非常好的工作解决方案 使用标准方法以可能的最大频率100Hz触发回调,该频率将包含瞬时加速度x、y、z值 我会让代码为自己说话,好的代码应该永远为自己说话
typedef
struct {
double x,y,z;
}
vec_d3;
#define RECENT_COUNT 10
#define SMOOTH_IP( x, x_new, fac ) x = fac * x + ( 1. - fac ) * x_new
- (void) accelerometer: (UIAccelerometer *) accelerometer
didAccelerate: (UIAcceleration *) acceleration
{
// smooth incoming acceleration values
static vec_d3 smooth = { DOUBLE_EMPTY, 0, 0 };
{
if ( smooth.x == DOUBLE_EMPTY )
{
smooth.x = acceleration.x;
smooth.y = acceleration.y;
smooth.z = acceleration.z;
return;
}
SMOOTH_IP( smooth.x, acceleration.x, 0.9 );
SMOOTH_IP( smooth.y, acceleration.y, 0.9 );
SMOOTH_IP( smooth.z, acceleration.z, 0.9 );
}
// keep track of last k smoothed acceleration values
static vec_d3 recent[ RECENT_COUNT ];
{
static int ptr = 0;
static BOOL gotEnoughData = NO;
recent[ ptr ] = smooth;
ptr++;
if ( ptr == RECENT_COUNT )
{
ptr = 0;
gotEnoughData = YES;
}
// return if array not filled yet
if ( ! gotEnoughData )
return;
}
// get the resultant variation in acceleration over the whole array
double variation;
{
vec_d3 min = smooth, max = smooth;
for ( int i=0; i < RECENT_COUNT; i++ )
{
min.x = MIN( min.x, recent[ i ].x );
min.y = MIN( min.y, recent[ i ].y );
min.z = MIN( min.z, recent[ i ].z );
max.x = MAX( max.x, recent[ i ].x );
max.y = MAX( max.y, recent[ i ].y );
max.z = MAX( max.z, recent[ i ].z );
}
vec_d3 V = (vec_d3)
{
.x = max.x - min.x,
.y = max.y - min.y,
.z = max.z - min.z
};
variation = sqrt(
V.x * V.x +
V.y * V.y +
V.z * V.z
);
}
// smooth it
static double var_smoothed = DOUBLE_EMPTY;
{
if ( var_smoothed == DOUBLE_EMPTY )
{
var_smoothed = variation;
return;
}
SMOOTH_IP( var_smoothed, variation, 0.9 );
}
// see if it's just passed a peak
{
static double varSmoothed_last = DOUBLE_EMPTY;
if ( varSmoothed_last == DOUBLE_EMPTY )
{
varSmoothed_last = var_smoothed;
return;
}
static double varSmoothed_preLast = DOUBLE_EMPTY;
if ( varSmoothed_preLast == DOUBLE_EMPTY )
{
varSmoothed_preLast = varSmoothed_last;
varSmoothed_last = var_smoothed;
return;
}
#define THRESHOLD_IMPULSE .15
if ( varSmoothed_last > varSmoothed_preLast
&& varSmoothed_last > var_smoothed
&& varSmoothed_last > THRESHOLD_IMPULSE )
{
LOG ( @"PotPeak @ %f", varSmoothed_last );
// hit a peak at imp_last
[self peakedWithImpulse: varSmoothed_last ];
}
varSmoothed_preLast = varSmoothed_last;
varSmoothed_last = var_smoothed;
}
}
注意:这通常会输出一个介于0和0.9之间的值,用于敲击我的手掌。然而,在空中挥舞它会达到1.5。我试图尝试一下这段代码,但是我得到了DOUBLE_EMPTY的错误。你能解释一下什么是双_空吗?ThanksDOUBLE_EMPTY是一个表示变量为空的值。使用类似于DBL_MAX的内容,即:定义双_空DBL_MAX@Pi你能解释一下你的代码在做什么吗?我正在试着用你的代码检测路面颠簸,但我面临一些困难。你能帮我在我的应用程序中编码这个算法吗。注意:这通常会输出一个介于0和0.9之间的值,用于敲击我的手掌。然而,在空中挥舞它会达到1.5。我试图尝试一下这段代码,但是我得到了DOUBLE_EMPTY的错误。你能解释一下什么是双_空吗?ThanksDOUBLE_EMPTY是一个表示变量为空的值。使用类似于DBL_MAX的内容,即:定义双_空DBL_MAX@Pi你能解释一下你的代码在做什么吗?我正在试着用你的代码检测路面颠簸,但我面临一些困难。你能帮我在我的应用程序中编码这个算法吗。很抱歉重新设计了我的问题,让我回答一些已经不存在的问题。我这样做是为了创造一个更好的资源,让将来搜索这个的人更简洁。谢谢你的回答!很抱歉重新设计了我的问题,让我回答一些已经不存在的问题。我这样做是为了创造一个更好的资源,让将来搜索这个的人更简洁。谢谢你的回答!