我的算法来计算智能手机的位置 - GPS 和传感器

My Algorithm to Calculate Position of Smartphone - GPS and Sensors(我的算法来计算智能手机的位置 - GPS 和传感器)
本文介绍了我的算法来计算智能手机的位置 - GPS 和传感器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个基于传感器数据计算位置的安卓应用程序

I am developing an android application to calculate position based on Sensor's Data

  1. 加速度计 --> 计算线性加速度

  1. Accelerometer --> Calculate Linear Acceleration

磁力计 + 加速度计 --> 运动方向

Magnetometer + Accelerometer --> Direction of movement

初始位置将从 GPS(纬度 + 经度)获取.

The initial position will be taken from GPS (Latitude + Longitude).

现在根据传感器的读数,我需要计算智能手机的新位置:

Now based on Sensor's Readings i need to calculate the new position of the Smartphone:

我的算法如下 - (但未计算准确位置):请帮助我改进它.

My Algorithm is following - (But is not calculating Accurate Position): Please help me improve it.

注意: 我的算法代码在 C# 中(我将传感器数据发送到服务器 - 数据存储在数据库中.我正在计算服务器上的位置)

所有 DateTime 对象均使用时间戳计算 - 从 01-01-1970

    var prevLocation = ServerHandler.getLatestPosition(IMEI);
    var newLocation = new ReceivedDataDTO()
                          {
                              LocationDataDto = new LocationDataDTO(),
                              UsersDto = new UsersDTO(),
                              DeviceDto = new DeviceDTO(),
                              SensorDataDto = new SensorDataDTO()
                          };

    //First Reading
    if (prevLocation.Latitude == null)
    {
        //Save GPS Readings
        newLocation.LocationDataDto.DeviceId = ServerHandler.GetDeviceIdByIMEI(IMEI);
        newLocation.LocationDataDto.Latitude = Latitude;
        newLocation.LocationDataDto.Longitude = Longitude;
        newLocation.LocationDataDto.Acceleration = float.Parse(currentAcceleration);
        newLocation.LocationDataDto.Direction = float.Parse(currentDirection);
        newLocation.LocationDataDto.Speed = (float) 0.0;
        newLocation.LocationDataDto.ReadingDateTime = date;
        newLocation.DeviceDto.IMEI = IMEI;
        // saving to database
        ServerHandler.SaveReceivedData(newLocation);
        return;
    }


    //If Previous Position not NULL --> Calculate New Position
   **//Algorithm Starts HERE**

    var oldLatitude = Double.Parse(prevLocation.Latitude);
    var oldLongitude = Double.Parse(prevLocation.Longitude);
    var direction = Double.Parse(currentDirection);
    Double initialVelocity = prevLocation.Speed;

    //Get Current Time to calculate time Travelling - In seconds
    var secondsTravelling = date - tripStartTime;
    var t = secondsTravelling.TotalSeconds;

    //Calculate Distance using physice formula, s= Vi * t + 0.5 *  a * t^2
    // distanceTravelled = initialVelocity * timeTravelling + 0.5 * currentAcceleration * timeTravelling * timeTravelling;
    var distanceTravelled = initialVelocity * t + 0.5 * Double.Parse(currentAcceleration) * t * t;

    //Calculate the Final Velocity/ Speed of the device.
    // this Final Velocity is the Initil Velocity of the next reading
    //Physics Formula: Vf = Vi + a * t
    var finalvelocity = initialVelocity + Double.Parse(currentAcceleration) * t;


    //Convert from Degree to Radians (For Formula)
    oldLatitude = Math.PI * oldLatitude / 180;
    oldLongitude = Math.PI * oldLongitude / 180;
    direction = Math.PI * direction / 180.0;

    //Calculate the New Longitude and Latitude
    var newLatitude = Math.Asin(Math.Sin(oldLatitude) * Math.Cos(distanceTravelled / earthRadius) + Math.Cos(oldLatitude) * Math.Sin(distanceTravelled / earthRadius) * Math.Cos(direction));
    var newLongitude = oldLongitude + Math.Atan2(Math.Sin(direction) * Math.Sin(distanceTravelled / earthRadius) * Math.Cos(oldLatitude), Math.Cos(distanceTravelled / earthRadius) - Math.Sin(oldLatitude) * Math.Sin(newLatitude));

    //Convert From Radian to degree/Decimal
    newLatitude = 180 * newLatitude / Math.PI;
    newLongitude = 180 * newLongitude / Math.PI;

这是我得到的结果 --> 手机没有移动.如您所见速度是 27.3263111114502 所以计算速度有问题,但我不知道是什么

This is the Result I get --> Phone was not moving. As you can see speed is 27.3263111114502 So there is something wrong in calculating Speed but I don't know what

回答:

我找到了一个基于传感器计算位置的解决方案:我在下面发布了一个答案.

I found a solution to calculate position based on Sensor: I have posted an Answer below.

如果您需要任何帮助,请发表评论

If you need any help, please leave a comment

这是与 GPS 相比的结果(注意: GPS 为红色)

this is The results compared to GPS (Note: GPS is in Red)

推荐答案

正如你们中的一些人提到的,你的方程式错误,但这只是错误的一部分.

As some of you mentioned you got the equations wrong but that is just a part of the error.

  1. 牛顿 - 非相对论速度的达朗贝尔物理学规定了这一点:

// init values
double ax=0.0,ay=0.0,az=0.0; // acceleration [m/s^2]
double vx=0.0,vy=0.0,vz=0.0; // velocity [m/s]
double  x=0.0, y=0.0, z=0.0; // position [m]

// iteration inside some timer (dt [seconds] period) ...
ax,ay,az = accelerometer values
vx+=ax*dt; // update speed via integration of acceleration
vy+=ay*dt;
vz+=az*dt;
 x+=vx*dt; // update position via integration of velocity
 y+=vy*dt;
 z+=vz*dt;

  • 传感器可以旋转,因此必须应用方向:

    // init values
    double gx=0.0,gy=-9.81,gz=0.0; // [edit1] background gravity in map coordinate system [m/s^2]
    double ax=0.0,ay=0.0,az=0.0; // acceleration [m/s^2]
    double vx=0.0,vy=0.0,vz=0.0; // velocity [m/s]
    double  x=0.0, y=0.0, z=0.0; // position [m]
    double dev[9]; // actual device transform matrix ... local coordinate system
    (x,y,z) <- GPS position;
    
    // iteration inside some timer (dt [seconds] period) ...
    dev <- compass direction
    ax,ay,az = accelerometer values (measured in device space)
    (ax,ay,az) = dev*(ax,ay,az);  // transform acceleration from device space to global map space without any translation to preserve vector magnitude
    ax-=gx;    // [edit1] remove background gravity (in map coordinate system)
    ay-=gy;
    az-=gz;
    vx+=ax*dt; // update speed (in map coordinate system)
    vy+=ay*dt;
    vz+=az*dt;
     x+=vx*dt; // update position (in map coordinate system)
     y+=vy*dt;
     z+=vz*dt;
    

    • gx,gy,gz 是全球重力矢量(~9.81 m/s^2 在地球上)
    • 在代码中,我的全局 Y 轴指向上方,因此 gy=-9.81 其余为 0.0
      • gx,gy,gz is the global gravity vector (~9.81 m/s^2 on Earth)
      • in code my global Y axis points up so the gy=-9.81 and the rest are 0.0
      • 测量时机很关键

        必须尽可能多地检查加速度计(第二个是很长的时间).我建议不要使用大于 10 毫秒的计时器周期来保持准确性,而且您应该不时使用 GPS 值覆盖计算的位置.指南针方向的检查频率可以降低,但需要适当的过滤

        Accelerometer must be checked as often as possible (second is a very long time). I recommend not to use timer period bigger than 10 ms to preserve accuracy also time to time you should override calculated position with GPS value. Compass direction can be checked less often but with proper filtration

        指南针始终不正确

        罗盘值应针对某些峰值进行过滤.有时它会读取错误的值,也可能会因电磁污染或金属环境而关闭.在这种情况下,可以通过 GPS 在移动过程中检查方向并进行一些修正.例如,每分钟检查一次 GPS 并将 GPS 方向与指南针进行比较,如果它一直在某个角度,则添加或减去它.

        Compass values should be filtered for some peak values. Sometimes it read bad values and also can be off by electro-magnetic polution or metal enviroment. In that case the direction can be checked by GPS during movement and some corrections can be made. For example chech GPS every minute and compare GPS direction with compass and if it is constantly of by some angle then add it or substract it.

        为什么要在服务器上进行简单的计算???

        讨厌在线浪费流量.是的,您可以在服务器上记录数据(但我仍然认为设备上的文件会更好)但是为什么要通过互联网连接来限制位置功能???更不用说延误了……

        Hate on-line waste of traffic. Yes you can log data on server (but still i think file on device will be better) but why to heck limit position functionality by internet connection ??? not to mention the delays ...

        附加说明

        稍微修改了上面的代码.方向必须尽可能精确,以尽量减少累积误差.

        Edited the code above a little. The orientation must be as precise as it can be to minimize cumulative errors.

        陀螺仪会比指南针更好(甚至更好地同时使用它们).应该过滤加速度.一些低通滤波应该没问题.去除重力后,我会将 ax,ay,az 限制为可用值并丢弃太小的值.如果接近低速也做完全停止(如果它不是火车或真空中的运动).这应该会降低漂移,但会增加其他错误,因此必须在它们之间找到折衷方案.

        Gyros would be better than compass (or even better use them both). Acceleration should be filtered. Some low pass filtering should be OK. After gravity removal I would limit ax,ay,az to usable values and throw away too small values. If near low speed also do full stop (if it is not a train or motion in vacuum). That should lower the drift but increase other errors so an compromise has to be found between them.

        即时添加校准.当过滤 acceleration = 9.81 或非常接近它时,设备可能静止不动(除非它是飞行机器).方向/方向可以通过实际重力方向进行校正.

        Add calibration on the fly. When filtered acceleration = 9.81 or very close to it then the device is probably stand still (unless its a flying machine). Orientation/direction can be corrected by actual gravity direction.

        这篇关于我的算法来计算智能手机的位置 - GPS 和传感器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

  • 本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

    相关文档推荐

    DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
    Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
    Programmatically show the desktop(以编程方式显示桌面)
    c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
    InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
    LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)