有没有办法获得 5-10 米的恒定精度?
Is there a way to get a constant accuracy of 5-10 mts?
我正在尝试构建一些定位应用程序,主要问题是准确性数据(不确定 getAccuracy() 是否可靠地测量误差)。我在论坛上看到一些 post 的准确度大约是 5-10,但对我来说总是在 30 米左右。
目前,我正在使用 fusedlocationproviderclient,我不需要 API 密钥,对吗? Wifi 搜索已启用,否则它会跳到 300~ 另外,我来自南美洲,可能是我所在地区的错误更多。
public class MainActivity extends AppCompatActivity {
private FusedLocationProviderClient cliente;
private LocationRequest locationRequest;
private LocationCallback locationCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
locationRequest = new LocationRequest();
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(3000);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
gps_bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (gps_bt.isChecked()) {
sensor.setText("GPS");
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
} else {
sensor.setText("Torre celular y wifi");
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
}
});
upd_bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (upd_bt.isChecked()) {
actualizacion.setText("Encendidas");
actualizar = true;
empezarActualizacion();
} else {
actualizacion.setText("Apagadas");
actualizar = false;
detenerActualizacion();
}
}
});
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
for (Location location : locationResult.getLocations()) {
latitud.setText(String.valueOf(location.getLatitude()));
longitud.setText(String.valueOf(location.getLongitude()));
precision.setText(String.valueOf(location.getAccuracy()));
if (location.hasAltitude()) {
altitud.setText(String.valueOf(location.getAltitude()));
} else {
altitud.setText("No se pudo colectar la altitud");
}
if (location.hasSpeed()) {
velocidad.setText(String.valueOf(location.getSpeed()) + "m/s");
} else {
velocidad.setText("No se puede recuperar la velocidad");
}
}
}
};
cliente = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
cliente.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
latitud.setText(String.valueOf(location.getLatitude()));
longitud.setText(String.valueOf(location.getLongitude()));
precision.setText(String.valueOf(location.getAccuracy()));
if (location.hasAltitude()) {
altitud.setText(String.valueOf(location.getAltitude()));
} else {
altitud.setText("No se pudo colectar la altitud");
}
if (location.hasSpeed()) {
velocidad.setText(String.valueOf(location.getSpeed()) + "m/s");
} else {
velocidad.setText("No se puede recuperar la velocidad");
}
}
}
});
} else {
//pedir permisos
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISO_FINE_LOCATION);
}
}
}
它总是抛出 30 米或更多,正如我之前提到的,如果可能的话,我希望达到 10 米左右。清单文件带有 FINE_LOCATION。对于将来的使用,这也将适用于 phone 数据 (LTE/4g/3g) 我是否也必须授予 COARSE_LOCATION 的许可?它 fusedlocationproviderclient 是为此目的的最佳选择吗?使用kalman可以改善lat/long数据?我在三星 S8 上做了测试,但我想从棒棒糖上覆盖。谢谢大家
在智能手机上保持 5 到 10 米不变,仍然不可能。因为?
在某些情况下,您可以获得最佳精度,但在大多数情况下则不能。
嵌入在设备中的 GNSS 芯片外部的元素会影响误差幅度。例如:
- 来自不同来源的电磁干扰,包括自然的和人为的;
- GNSS 芯片内部时钟延迟(导致计算设备与卫星之间的距离时出现错误);
- 当时可用的卫星数(当setPriority ==
locationRequest.PRIORITY_HIGH_ACCURACY);
- 没有 wifi 和/或 GSM 信号 (RBS) 或质量信号(当
setPriority == locationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
- L1信号架构deficiencies(gnss信号最流行
在当前的智能手机中);
不过有好处news。承诺更精确的设备,因为它们将提供支持 L5 信号的芯片。
L5 signal 的工作方式完全不同,并且在设计方面比旧的 L1 更稳健。
高精度主要impact消耗能量,所以在绝大多数情况下你应该很高兴得到20、10米的精度。
我正在尝试构建一些定位应用程序,主要问题是准确性数据(不确定 getAccuracy() 是否可靠地测量误差)。我在论坛上看到一些 post 的准确度大约是 5-10,但对我来说总是在 30 米左右。
目前,我正在使用 fusedlocationproviderclient,我不需要 API 密钥,对吗? Wifi 搜索已启用,否则它会跳到 300~ 另外,我来自南美洲,可能是我所在地区的错误更多。
public class MainActivity extends AppCompatActivity {
private FusedLocationProviderClient cliente;
private LocationRequest locationRequest;
private LocationCallback locationCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
locationRequest = new LocationRequest();
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(3000);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
gps_bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (gps_bt.isChecked()) {
sensor.setText("GPS");
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
} else {
sensor.setText("Torre celular y wifi");
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
}
});
upd_bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (upd_bt.isChecked()) {
actualizacion.setText("Encendidas");
actualizar = true;
empezarActualizacion();
} else {
actualizacion.setText("Apagadas");
actualizar = false;
detenerActualizacion();
}
}
});
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
for (Location location : locationResult.getLocations()) {
latitud.setText(String.valueOf(location.getLatitude()));
longitud.setText(String.valueOf(location.getLongitude()));
precision.setText(String.valueOf(location.getAccuracy()));
if (location.hasAltitude()) {
altitud.setText(String.valueOf(location.getAltitude()));
} else {
altitud.setText("No se pudo colectar la altitud");
}
if (location.hasSpeed()) {
velocidad.setText(String.valueOf(location.getSpeed()) + "m/s");
} else {
velocidad.setText("No se puede recuperar la velocidad");
}
}
}
};
cliente = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
cliente.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
latitud.setText(String.valueOf(location.getLatitude()));
longitud.setText(String.valueOf(location.getLongitude()));
precision.setText(String.valueOf(location.getAccuracy()));
if (location.hasAltitude()) {
altitud.setText(String.valueOf(location.getAltitude()));
} else {
altitud.setText("No se pudo colectar la altitud");
}
if (location.hasSpeed()) {
velocidad.setText(String.valueOf(location.getSpeed()) + "m/s");
} else {
velocidad.setText("No se puede recuperar la velocidad");
}
}
}
});
} else {
//pedir permisos
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISO_FINE_LOCATION);
}
}
}
它总是抛出 30 米或更多,正如我之前提到的,如果可能的话,我希望达到 10 米左右。清单文件带有 FINE_LOCATION。对于将来的使用,这也将适用于 phone 数据 (LTE/4g/3g) 我是否也必须授予 COARSE_LOCATION 的许可?它 fusedlocationproviderclient 是为此目的的最佳选择吗?使用kalman可以改善lat/long数据?我在三星 S8 上做了测试,但我想从棒棒糖上覆盖。谢谢大家
在智能手机上保持 5 到 10 米不变,仍然不可能。因为? 在某些情况下,您可以获得最佳精度,但在大多数情况下则不能。 嵌入在设备中的 GNSS 芯片外部的元素会影响误差幅度。例如:
- 来自不同来源的电磁干扰,包括自然的和人为的;
- GNSS 芯片内部时钟延迟(导致计算设备与卫星之间的距离时出现错误);
- 当时可用的卫星数(当setPriority == locationRequest.PRIORITY_HIGH_ACCURACY);
- 没有 wifi 和/或 GSM 信号 (RBS) 或质量信号(当 setPriority == locationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
- L1信号架构deficiencies(gnss信号最流行 在当前的智能手机中);
不过有好处news。承诺更精确的设备,因为它们将提供支持 L5 信号的芯片。 L5 signal 的工作方式完全不同,并且在设计方面比旧的 L1 更稳健。
高精度主要impact消耗能量,所以在绝大多数情况下你应该很高兴得到20、10米的精度。