我有一个关于Android设备中加速度计的快速问题.它始终开启/活动吗?鉴于加速度计用于检测设备的方向,无论是横向还是纵向.
在官方文档(SensorManager)中,它指出应该关闭传感器以节省电力.但我想知道这是否仅适用于其他传感器,如磁场传感器,陀螺仪,光传感器等.
我需要提出一个节能的案例,我不想错误地说加速度计有时会被禁用,而是用它来禁用其他传感器(在应用程序的罗盘功能中).
或者加速度计的电池消耗仅与注册接收数据的应用相关,而只是"开启"或启用是不相关的,因为它始终是?
谢谢你的任何澄清!
android accelerometer power-management android-sensors compass-geolocation
关于从加速度计数据中去除噪声,其他传感器数据,计算时空状态以及在Android和其他设备中使用卡尔曼滤波器存在很多问题.
显然,最简单的方法是在Android上实现JKalman过滤器,以便为汽车提供稳定的移动设备.
但是看看JKalman代码包中的示例实现,它并没有说太多,它实际上与其他Kalman实现非常不同.
他们像这样实例化一个卡尔曼类:
JKalman kalman = new JKalman(4, 2);
Run Code Online (Sandbox Code Playgroud)
根据定义在哪里
public JKalman(int dynam_params, int measure_params) throws Exception {
this(dynam_params, measure_params, 0);
}
Run Code Online (Sandbox Code Playgroud)
dynam_params是"测量向量维数"和measure_params是"状态向量维数".
如何将Android中读取的传感器数据映射到这些?
下面是加速度计的数据,每500ms采样一次.在其他听众中,有来自陀螺仪和指南针的数据.我该如何将这些数据转换为输入到卡尔曼?
@Override
public void onSensorChanged(SensorEvent event) {
actualTime = System.currentTimeMillis();
if(actualTime - lastUpdateAcc < 500)
return;
else{
lastUpdateAcc = actualTime;
//update myPosition
TextView tv = (TextView)findViewById(R.id.textView3);
tv.setText(String.format("X: %8.4f -- Y: %8.4f -- Z: %8.4f",
event.values[0], event.values[1], event.values[2]));
//draw on the screen
//draw new path, if one exists
} …Run Code Online (Sandbox Code Playgroud) 可能重复:
Android加速计精度(惯性导航)
我使用以下代码来计算距离.tnew并anew分别arraylists包含时间戳和加速度.
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;
}
Run Code Online (Sandbox Code Playgroud)
代码中是否有任何逻辑错误?因为我得到的值远小于实际长度.
产量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 …Run Code Online (Sandbox Code Playgroud) 我正在编写一个应用程序,通过安全操作帮助锁定史密斯,主要是通过创建动态需要的图表.当试图通过操纵进入安全装置时,需要对"轮组"进行详细分析,并通过绘制"栅栏"在"门"上的相对深度来完成.如果所有门都排列在包装上,则栅栏杆将落入凸轮门,锁将打开.如果有人对更详细的解释感兴趣,你可以在这里找到Matt Blaze的一个很棒的治疗方法(从3.3左右开始):www.crypto.com/papers/safelocks.pdf
制作图表非常重要,而且它真正需要的是精确测量表盘上的两个位置,一遍又一遍,并记录两个声音之间的拨号距离.因此,假设"下降"点在10到15之间,声音事件可能发生在11.5和14.5,或者下一次可能发生在12和15.锁定史密斯制作这些之间的距离图表数字和查找,数字缩小,在图表上,或者可能只是图表中的最低位置.
我正在通过我的Androids耳机插孔使用老式收音机电话拾音器(吸盘式麦克风)来收听声音事件.为了精确测量发生事件的表盘,我简单地将手机安装到带魔术贴的表盘上,并使用SensorManager根据手机从音频尖峰事件旋转到尖峰的距离来计算声音之间的距离-事件.这很好,但我想在不将手机安装到表盘的情况下这样做.一些公司过去通过使用网络摄像头看表盘本身来完成它,但这似乎不如仅仅安装手机准确,因为我可以使用分数旋转来获得更高的精度.
一旦你进入插入位置,你总是会听到一个声音,然后将表盘备份到下一个声音,所以我想我可以简单地听一下声音事件,然后一旦表盘将方向测量反转到下一个声音事件,但这需要表盘不变,这在现实生活中不会发生.而且我想我可以通过使用动态像素或伺服来移动锁匠的表盘,但同样,这不是一个好的解决方案.所以我的问题是,如果你们中的任何一个聪明的人都能想到这些相关费率(声音事件之间的距离和拨号位置的变化)可以量化而无需将手机安装到表盘上吗?
我使用本教程从设备的陀螺仪获得俯仰和滚动数据:http://www.thousand-thoughts.com/2012/03/android-sensor-fusion-tutorial/
所有读数都非常准确(有一个滤波器应用于教程中的代码以消除陀螺漂移).不幸的是,只有当我的设备平放在与地面平行的表面上时,代码才有效.我的应用程序工作的最理想位置是设备的顶部指向正面(即,设备垂直于地面,屏幕面向用户).每当我将设备定位在此位置时,音高值将达到+90度(如预期的那样).我想要做的是将此位置设置为我的设备的0度点(或初始位置),以便当我的设备直立(纵向模式)且屏幕朝向用户时,音高读数为0度.
我在这个问题的帮助下问了教程的作者,他回答说:
"如果你想将直立位置作为初始位置,你必须相应地旋转你的参考框架.最简单的方法是将产生的旋转矩阵绕x轴旋转-90度.但你必须请注意算法中的哪一点应用这个旋转.永远记住旋转不是可交换操作.为了更具体这一点,我将不得不再次检查代码,因为我还没有使用它一段时间现在."
我真的很困惑,并且难以理解如何旋转我的参考框架.我想底线是我不知道如何围绕x轴旋转矩阵-90度.如果有人可以帮我解决这个问题,那就太棒了.这是我的代码,以防任何人想要引用它:
public class AttitudeDisplayIndicator extends SherlockActivity implements SensorEventListener {
private SensorManager mSensorManager = null;
// angular speeds from gyro
private float[] gyro = new float[3];
// rotation matrix from gyro data
private float[] gyroMatrix = new float[9];
// orientation angles from gyro matrix
private float[] gyroOrientation = new float[3];
// magnetic field vector
private float[] magnet = new float[3];
// accelerometer vector
private float[] accel = new float[3];
// orientation angles from accel …Run Code Online (Sandbox Code Playgroud) 我已经实现了旋转矢量和方向矢量的监听器,虽然我知道它已经折旧我想测试两者.
我知道旋转矢量是一个融合传感器并推荐但是根据它,NORTH(getOrientation返回的值[0](rotationMatrix,value)geaving bearing 0)与Orientation传感器的NORTH不匹配.我还从playstore的不同应用程序中得出结论,方向传感器值似乎更接近它们.
此外很多次我从Rotation_Vector的方位角值[0]然后getOrientation刚刚射击并保持在-180到180之间振荡
PS"getRotationMatrix(float [] R,float [] I,float [] gravity,float [] geomagnetic)"也给出与旋转向量相同的结果.
public final void onSensorChanged(SensorEvent event)
{
float rotationMatrix[];
switch(event.sensor.getType())
{
.
.
.
case Sensor.TYPE_ROTATION_VECTOR:
rotationMatrix=new float[16];
mSensorManager.getRotationMatrixFromVector(rotationMatrix,event.values);
determineOrientation(rotationMatrix);
break;
case Sensor.TYPE_ORIENTATION:
sensorZValue.setText(""+event.values[0]); //rotation about geographical z axis
sensorXValue.setText(""+event.values[1]); //rotation about geographical x axis
sensorYValue.setText(""+event.values[2]); //rotation about geographical y axis
}//switch case ends
}
private void determineOrientation(float[] rotationMatrix)
{
float[] orientationValues = new float[3];
SensorManager.getOrientation(rotationMatrix, orientationValues);
double azimuth = Math.toDegrees(orientationValues[0]);
double pitch = Math.toDegrees(orientationValues[1]); …Run Code Online (Sandbox Code Playgroud) android magnetometer digital-compass rotational-matrices android-sensors
我开发了一个应用程序,有些人抱怨它需要太多的电池,这是屏幕后第二大消耗的过程.但是,在某些设备中,它不会消耗那么多电池.
我的应用程序所做的所有工作都在服务中.该服务是粘性的并且一直在运行(android系统可能在资源较少时将其杀死或在设备进入休眠状态时暂停),只要屏幕打开就有监听加速度计,它不是前台服务并没有举行唤醒锁.
有人能告诉我为什么需要大量电池吗?为什么这只发生在一些设备上?
这是相关代码:
public class aListenerService extends Service implements SensorEventListener
{
private BroadcastReceiver mScreenReceiver = new BroadcastReceiver()
{
// if screen was turned on then register to accelerometer
// if screen was turned off then unregister from accelerometer
}
private BroadcastReceiver mPhoneStateReceiver = new BroadcastReceiver()
{
// do something...
}
@Override
public void onCreate()
{
super.onCreate();
// get sensor manager and accelerometer sensor
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// register accelerometer sensor and receiver
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); …Run Code Online (Sandbox Code Playgroud) 我试图仅在垂直方向上跟踪设备的移动,即向上和向下移动.这应该与设备的方向无关.我已经知道或尝试过的事情就是这些
线性加速度由传感器TYPE_LINEAR_ACCELERATION给出,轴是电话轴,因此跟踪任何特定轴都没有区别.
我尝试应用转置或旋转矢量的倒数(旋转矢量的反转或转置是相同的)然后尝试跟踪线性加速度矢量的z方向.似乎没有帮助.
我正在尝试使用重力值(TYPE_GRAVITY)来制作点积,以获得加速度的方向,但它似乎容易出错.即使我快速移动我的设备,它也会说下降.
我将在这里概述这种方法
dotProduct = vectorA[0]*vectorB[0]+vectorA[1]*vectorB[1] + vectorA[2]*vectorB[2];
cosineVal = dotProduct/(|vectorA|*|vectorB|)
if(cosineVal > 0 ) down else Up.
Run Code Online (Sandbox Code Playgroud)
这种方法有什么缺陷?请帮忙,我已经坚持了一段时间了.
我目前正在开发一个应用程序来跟踪步骤。
为了跟踪步骤,我使用手机的以下传感器:Sensor.TYPE_STEP_COUNTER
这适用于我测试过的所有设备。最近我有机会在三星 S10 设备上测试该应用程序,但它不再跟踪步骤,而它可以在三星 S9 的 Android 9 上运行。它也适用于运行 Android 6 的 Google Nexus。
我在运行应用程序时发现以下警告:
一些额外的调试信息:
调试信息有些混杂,因为我测试了计步器传感器和计步器传感器都产生了相同的结果。
我注册传感器的代码:
private SensorEventListener sensorEventListener = new SensorEventListener() {
/**
* This Method gets called on each Sensor Trigger event
*
* @param sensorEvent Event created by Sensor
*/
@Override …Run Code Online (Sandbox Code Playgroud) 我能做的事情:
sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
val accelerometerSensor =
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
accSensor,
accelerometerSensor,
SensorManager.SENSOR_DELAY_NORMAL
)
Run Code Online (Sandbox Code Playgroud)
serviceIntent = Intent(context, SensorService::class.java)
context.startForegroundService(serviceIntent)
Run Code Online (Sandbox Code Playgroud)
但我无法:
从系统接收运动开始和运动结束通知/回调的方式可能是什么,以便我们可以决定启动/结束前台服务。
android ×10
android-sensors ×10
java ×2
algorithm ×1
gyroscope ×1
kotlin ×1
magnetometer ×1
sensor ×1
vector ×1