Мой алгоритм расчета положения смартфона - GPS и датчики

Я разрабатываю приложение для Android для расчета положения на основе данных датчика.

  1. Акселерометр -> Рассчитать линейное ускорение

  2. Магнитометр + Акселерометр -> Направление движения

Исходное положение будет взято из GPS (широта + долгота).

Теперь, основываясь на показаниях датчика, мне нужно рассчитать новое положение смартфона:

Мой алгоритм следующий - (но не вычисляет точное положение): пожалуйста, помогите мне улучшить его.

Примечание. Мой код алгоритма находится на 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 Значит, при вычислении скорости что-то не так, но я не знаю, что именно

введите описание изображения здесь

ОТВЕТ:

Я нашел решение для расчета положения на основе датчика: я опубликовал ответ ниже.

Если вам нужна помощь, оставьте, пожалуйста, комментарий

это результаты по сравнению с GPS (Примечание: GPS выделен красным)

введите описание изображения здесь


person Dawood Awan    schedule 01.11.2013    source источник
comment
Вы уверены, что направление движения и ускорение не меняется во время движения? Приведенное вами уравнение предполагает, что ускорение остается постоянным во время движения.   -  person Abhishek Bansal    schedule 04.11.2013
comment
Разгон меняется.   -  person Dawood Awan    schedule 04.11.2013
comment
Такие тождества, как s = ut + (1/2) at ^ 2 (от точки A до точки B), могут применяться только в том случае, если ускорение остается постоянным на уровне «a» на протяжении всего времени между и A и B.   -  person Abhishek Bansal    schedule 04.11.2013
comment
Так что же делать, если меняется ускорение?   -  person Dawood Awan    schedule 04.11.2013
comment
Как меняется ускорение? Вам придется применять эту идентификацию в течение коротких промежутков времени, когда ускорение остается постоянным на определенном уровне. Если ускорение постоянно увеличивается / уменьшается со скоростью, то вы входите в область исчисления.   -  person Abhishek Bansal    schedule 04.11.2013
comment
Я использую датчик акселерометра в смартфонах, чтобы получить линейное ускорение. Он может меняться 2 раза за одну секунду, но после фильтрации у меня примерно одно значение в секунду. Вы предлагаете мне использовать интеграцию?   -  person Dawood Awan    schedule 04.11.2013
comment
Попробуйте это: stackoverflow.com/questions/6530271/   -  person user2940520    schedule 04.11.2013
comment
Попробуйте это: stackoverflow.com/questions/6530271/, это должно быть хорошо.   -  person user2940520    schedule 04.11.2013


Ответы (6)


Как некоторые из вас упомянули, вы ошиблись в уравнениях, но это лишь часть ошибки.

  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;
    
  2. датчик может вращаться, поэтому необходимо применять направление:

    // 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 is the global gravity vector (~9.81 m/s^2 on Earth)
    • в коде моя глобальная ось Y указывает вверх, поэтому gy=-9.81, а остальные 0.0
  3. время измерения имеет решающее значение

    Акселерометр нужно проверять как можно чаще (секунда - это очень долго). Я рекомендую не использовать период таймера больше 10 мс, чтобы сохранить точность, а также время от времени вы должны переопределять рассчитанное положение с помощью значения GPS. Направление по компасу можно проверять реже, но при правильной фильтрации

  4. компас не всегда правильный

    Значения компаса должны быть отфильтрованы для некоторых пиковых значений. Иногда он считывает неверные значения, а также может быть отключен из-за электромагнитного загрязнения или металлической окружающей среды. В этом случае направление можно проверить с помощью GPS во время движения и внести некоторые корректировки. Например, проверяйте GPS каждую минуту и ​​сравнивайте направление GPS с компасом, и если он постоянно отклоняется на некоторый угол, добавьте его или вычтите.

  5. зачем делать простые вычисления на сервере ???

    Ненавижу трату трафика в Интернете. Да, вы можете регистрировать данные на сервере (но все же я думаю, что файл на устройстве будет лучше), но зачем проверять функциональность ограничения положения при подключении к Интернету ??? не говоря уже о задержках ...

[Edit 1] дополнительные примечания

Немного отредактировал код выше. Ориентация должна быть максимально точной, чтобы минимизировать совокупные ошибки.

Гироскопы лучше компаса (а еще лучше использовать их оба). Ускорение следует фильтровать. Некоторая фильтрация нижних частот должна быть в порядке. После удаления гравитации я бы ограничил ax, ay, az до используемых значений и выбросил слишком маленькие значения. Если скорость близка к низкой, также сделайте полную остановку (если это не поезд или движение в вакууме). Это должно снизить дрейф, но увеличить количество других ошибок, поэтому между ними необходимо найти компромисс.

Добавляйте калибровку на лету. Когда фильтруется acceleration = 9.81 или очень близко к нему, устройство, вероятно, стоит на месте (если это не летательный аппарат). Ориентацию / направление можно скорректировать по фактическому направлению силы тяжести.

person Spektre    schedule 04.11.2013
comment
Прекрасное объяснение. Предлагаете ли вы провести эти расчеты на самом смартфоне? И для ясности dt = t2 - t1, где t1 - начальное время, а t2 = время чтения? - person Dawood Awan; 04.11.2013
comment
да и dt - это время между двумя итерациями = фактическое время - последнее фактическое время. не имеет значения, измерено ли оно до или после итерации (веток нет, но я предпочитаю измерять его в начале итерации) - person Spektre; 05.11.2013
comment
Спасибо за помощь. Просто хочу спросить, зачем мне добавлять предыдущую скорость к новой? vx + = ax * dt; - person Dawood Awan; 06.11.2013
comment
потому что вы измеряете только ускорение ... так что скорость интегрируется (через это дополнение) ... это просто правило прямоугольника для интегрального вычисления - person Spektre; 06.11.2013
comment
@AlexWien Я пытался сделать это на смартфоне, но поскольку поток SensorListener работает в основном потоке пользовательского интерфейса, пользовательский интерфейс зависает. Я новичок в Android, и вопросы, которые я прочитал в Stackoverflow, предполагают, что я не могу запустить Sensor Listener в отдельном потоке. Вы знаете какой-либо способ вычисления этого положения на смартфоне в отдельном потоке? - person Dawood Awan; 07.11.2013
comment
Если вы можете измерить время хотя бы с разрешением 1 мс, тогда вам вообще не нужны потоки, и вы можете собрать все вместе в один цикл. Эти вычисления не требуют постоянного dt. Также некоторые хорошо размещенные блокировки Sleep + для общих переменных могут сильно разморозиться (иногда планировщики сходят с ума, когда обращаются к визуальным материалам в потоке в неправильное время, даже на Windows и многоядерных процессорах). На одноядерном устройстве вы не можете предполагать 100% асинхронный запуск отдельных потоков. Также иногда причиной зависания является блокировка API ОС / ожидание объекта, особенно в сочетании с кодом режима ядра (вместо этого используйте собственные блокировки). - person Spektre; 07.11.2013
comment
Сначала прочтите мой ответ, тогда вы, вероятно, можете пропустить свой проект. Но чтобы ответить: даже если Sensor Listenrer работает в основном потоке, просто сохраните данные датчика в (круговом) массиве. Если ваши вычисления настолько дороги (в чем я сомневаюсь), тогда создайте отдельный поток, который выполняет вычисления в этом массиве; Или посмотрите демонстрационный код. Для iphone есть некоторые демонстрации, поэтому я ожидаю, что для Android должен быть демонстрационный код для простых вычислений данных датчика. - person AlexWien; 07.11.2013
comment
да, вы правы ... гравитацию нужно убрать перед интеграцией без гироскопов, это можно сделать, но ее ужасная фильтрация и очень медленная - person Spektre; 08.11.2013
comment
Интересный. Спасибо за помощь - person Dawood Awan; 08.11.2013

Датчики ускорения и гироскопы не подходят для расчета положения.
Через несколько секунд ошибки становятся невероятно высокими. (Я почти не помню, что проблема заключается в двойной интеграции).
Посмотрите это видео с технической беседой Google о слиянии датчиков он очень подробно объясняет, почему это невозможно.

person AlexWien    schedule 06.11.2013

После решения позиции, которую я рассчитал с помощью датчиков, я хотел бы опубликовать здесь свой код на случай, если кому-то понадобится в будущем:

Примечание. Это проверялось только на телефоне Samsung Galaxy S2, и только когда человек шел с телефоном, это не проверялось при движении в машине или на велосипеде

Это результат, который я получил при сравнении с GPS (красная линия GPS, синяя - положение, рассчитанное с помощью датчика)

Это результат, который я получил при сравнении с GPS (красная линия GPS, синий - положение, рассчитанное с помощью датчика)

Код не очень эффективен, но я надеюсь, что то, что я поделился этим кодом, кому-то поможет и укажет в правильном направлении.

У меня было два отдельных класса:

  1. CalculatePosition
  2. CustomSensorService

    public class CalculatePosition {

            static Double earthRadius = 6378D;
            static Double oldLatitude,oldLongitude;
            static Boolean IsFirst = true;
    
            static Double sensorLatitude, sensorLongitude;
    
            static Date CollaborationWithGPSTime;
            public static float[] results;
    
    
    
            public static void calculateNewPosition(Context applicationContext,
                    Float currentAcceleration, Float currentSpeed,
                    Float currentDistanceTravelled, Float currentDirection, Float TotalDistance) {
    
    
                results = new float[3];
                if(IsFirst){
                    CollaborationWithGPSTime = new Date();
                    Toast.makeText(applicationContext, "First", Toast.LENGTH_LONG).show();
                    oldLatitude = CustomLocationListener.mLatitude;
                    oldLongitude = CustomLocationListener.mLongitude;
                    sensorLatitude = oldLatitude;
                    sensorLongitude = oldLongitude;
                    LivePositionActivity.PlotNewPosition(oldLongitude,oldLatitude,currentDistanceTravelled * 1000, currentAcceleration, currentSpeed, currentDirection, "GPSSensor",0.0F,TotalDistance);
                    IsFirst  = false;
                    return;
                } 
    
                Date CurrentDateTime = new Date();
    
                if(CurrentDateTime.getTime() - CollaborationWithGPSTime.getTime() > 900000){
                    //This IF Statement is to Collaborate with GPS position --> For accuracy --> 900,000 == 15 minutes
                    oldLatitude = CustomLocationListener.mLatitude;
                    oldLongitude = CustomLocationListener.mLongitude;
                    LivePositionActivity.PlotNewPosition(oldLongitude,oldLatitude,currentDistanceTravelled * 1000, currentAcceleration, currentSpeed, currentDirection, "GPSSensor", 0.0F, 0.0F);
                    return;
                }
    
                //Convert Variables to Radian for the Formula
                oldLatitude = Math.PI * oldLatitude / 180;
                oldLongitude = Math.PI * oldLongitude / 180;
                currentDirection = (float) (Math.PI * currentDirection / 180.0);
    
                //Formulae to Calculate the NewLAtitude and NewLongtiude
                Double newLatitude = Math.asin(Math.sin(oldLatitude) * Math.cos(currentDistanceTravelled / earthRadius) + 
                        Math.cos(oldLatitude) * Math.sin(currentDistanceTravelled / earthRadius) * Math.cos(currentDirection));
                Double newLongitude = oldLongitude + Math.atan2(Math.sin(currentDirection) * Math.sin(currentDistanceTravelled / earthRadius)
                        * Math.cos(oldLatitude), Math.cos(currentDistanceTravelled / earthRadius)
                        - Math.sin(oldLatitude) * Math.sin(newLatitude));
    
                //Convert Back from radians
                newLatitude = 180 * newLatitude / Math.PI;
                newLongitude = 180 * newLongitude / Math.PI;
                currentDirection = (float) (180 * currentDirection / Math.PI);
    
                //Update old Latitude and Longitude
                oldLatitude = newLatitude;
                oldLongitude = newLongitude;
    
                sensorLatitude = oldLatitude;
                sensorLongitude = oldLongitude;
    
                IsFirst = false;
                //Plot Position on Map
                LivePositionActivity.PlotNewPosition(newLongitude,newLatitude,currentDistanceTravelled * 1000, currentAcceleration, currentSpeed, currentDirection, "Sensor", results[0],TotalDistance);
    
    
    
    
    
        }
    }
    

    открытый класс CustomSensorService extends Service реализует SensorEventListener {

    static SensorManager sensorManager;
    static Sensor mAccelerometer;
    private Sensor mMagnetometer;
    private Sensor mLinearAccelertion;
    
    static Context mContext;
    
    private static float[] AccelerometerValue;
    private static float[] MagnetometerValue;
    
    public static  Float currentAcceleration = 0.0F;
    public static  Float  currentDirection = 0.0F;
    public static Float CurrentSpeed = 0.0F;
    public static Float CurrentDistanceTravelled = 0.0F;
    /*---------------------------------------------*/
    float[] prevValues,speed;
    float[] currentValues;
    float prevTime, currentTime, changeTime,distanceY,distanceX,distanceZ;
    float[] currentVelocity;
    public static CalculatePosition CalcPosition;
    /*-----FILTER VARIABLES-------------------------*-/
     * 
     * 
     */
    
    public static Float prevAcceleration = 0.0F;
    public static Float prevSpeed = 0.0F;
    public static Float prevDistance = 0.0F;
    
    public static Float totalDistance;
    
    TextView tv;
    Boolean First,FirstSensor = true;
    
    @Override
    public void onCreate(){
    
        super.onCreate();
        mContext = getApplicationContext();
        CalcPosition =  new CalculatePosition();
        First = FirstSensor = true;
        currentValues = new float[3];
        prevValues = new float[3];
        currentVelocity = new float[3];
        speed = new float[3];
        totalDistance = 0.0F;
        Toast.makeText(getApplicationContext(),"Service Created",Toast.LENGTH_SHORT).show();
    
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    
        mAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        //mGyro = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
        mLinearAccelertion = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
    
        sensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
        //sensorManager.registerListener(this, mGyro, SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, mLinearAccelertion, SensorManager.SENSOR_DELAY_NORMAL);
    
    }
    
    @Override
    public void onDestroy(){
        Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
        sensorManager.unregisterListener(this);
        //sensorManager = null;
        super.onDestroy();
    }
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void onSensorChanged(SensorEvent event) {
    
        float[] values = event.values;
        Sensor mSensor = event.sensor;
    
        if(mSensor.getType() == Sensor.TYPE_ACCELEROMETER){
            AccelerometerValue = values;
        }
    
        if(mSensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION){           
            if(First){
                prevValues = values;
                prevTime = event.timestamp / 1000000000;
                First = false;
                currentVelocity[0] = currentVelocity[1] = currentVelocity[2] = 0;
                distanceX = distanceY= distanceZ = 0;
            }
            else{
                currentTime = event.timestamp / 1000000000.0f;
    
                changeTime = currentTime - prevTime;
    
                prevTime = currentTime;
    
    
    
                calculateDistance(event.values, changeTime);
    
                currentAcceleration =  (float) Math.sqrt(event.values[0] * event.values[0] + event.values[1] * event.values[1] + event.values[2] * event.values[2]);
    
                CurrentSpeed = (float) Math.sqrt(speed[0] * speed[0] + speed[1] * speed[1] + speed[2] * speed[2]);
                CurrentDistanceTravelled = (float) Math.sqrt(distanceX *  distanceX + distanceY * distanceY +  distanceZ * distanceZ);
                CurrentDistanceTravelled = CurrentDistanceTravelled / 1000;
    
                if(FirstSensor){
                    prevAcceleration = currentAcceleration;
                    prevDistance = CurrentDistanceTravelled;
                    prevSpeed = CurrentSpeed;
                    FirstSensor = false;
                }
                prevValues = values;
    
            }
        }
    
        if(mSensor.getType() == Sensor.TYPE_MAGNETIC_FIELD){
            MagnetometerValue = values;
        }
    
        if(currentAcceleration != prevAcceleration || CurrentSpeed != prevSpeed || prevDistance != CurrentDistanceTravelled){
    
            if(!FirstSensor)
                totalDistance = totalDistance + CurrentDistanceTravelled * 1000;
            if (AccelerometerValue != null && MagnetometerValue != null && currentAcceleration != null) {
                //Direction
                float RT[] = new float[9];
                float I[] = new float[9];
                boolean success = SensorManager.getRotationMatrix(RT, I, AccelerometerValue,
                        MagnetometerValue);
                if (success) {
                    float orientation[] = new float[3];
                    SensorManager.getOrientation(RT, orientation);
                    float azimut = (float) Math.round(Math.toDegrees(orientation[0]));
                    currentDirection =(azimut+ 360) % 360;
                    if( CurrentSpeed > 0.2){
                        CalculatePosition.calculateNewPosition(getApplicationContext(),currentAcceleration,CurrentSpeed,CurrentDistanceTravelled,currentDirection,totalDistance);
                    }
                }
                prevAcceleration = currentAcceleration;
                prevSpeed = CurrentSpeed;
                prevDistance = CurrentDistanceTravelled;
            }
        }
    
    }
    
    
    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }
    public void calculateDistance (float[] acceleration, float deltaTime) {
        float[] distance = new float[acceleration.length];
    
        for (int i = 0; i < acceleration.length; i++) {
            speed[i] = acceleration[i] * deltaTime;
            distance[i] = speed[i] * deltaTime + acceleration[i] * deltaTime * deltaTime / 2;
        }
        distanceX = distance[0];
        distanceY = distance[1];
        distanceZ = distance[2];
    }
    

    }

РЕДАКТИРОВАТЬ:

public static void PlotNewPosition(Double newLatitude, Double newLongitude, Float currentDistance, 
        Float currentAcceleration, Float currentSpeed, Float currentDirection, String dataType) {

    LatLng newPosition = new LatLng(newLongitude,newLatitude);

    if(dataType == "Sensor"){
        tvAcceleration.setText("Speed: " + currentSpeed + " Acceleration: " + currentAcceleration + " Distance: " + currentDistance +" Direction: " + currentDirection + " \n"); 
        map.addMarker(new MarkerOptions()
        .position(newPosition)
        .title("Position")
        .snippet("Sensor Position")
        .icon(BitmapDescriptorFactory
                .fromResource(R.drawable.line)));
    }else if(dataType == "GPSSensor"){
        map.addMarker(new MarkerOptions()
        .position(newPosition)
        .title("PositionCollaborated")
        .snippet("GPS Position"));
    }
    else{
        map.addMarker(new MarkerOptions()
        .position(newPosition)
        .title("Position")
        .snippet("New Position")
        .icon(BitmapDescriptorFactory
                .fromResource(R.drawable.linered)));
    }
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(newPosition, 18));
}
person Dawood Awan    schedule 19.05.2014
comment
Привет, я сейчас работаю над похожим приложением. Можете ли вы поделиться целым кодом вашего приложения? - person Bresiu; 21.06.2014
comment
Невозможно получить такой же результат. Можете ли вы также добавить код прослушивателя местоположения? - person Pandiri Deepak; 24.10.2017
comment
Я пытаюсь сделать то же самое со встроенной системой с 9-осевым акселерометром. Здесь я получаю показания акселерометра, магнитомера и гироскопа для всех трех осей. Я пытаюсь повторно использовать ваш расчет или алгоритм. Однако я не понимаю разницы между sensor.TYPE_ACCELEROMETER и TYPE_LINEAR_ACCELERATION. В чем разница между ними? как мне действительно получить linear_acceleration от 3-х осевого акселерометра - person 230490; 03.02.2020
comment
@ 230490 LINEAR_ACCELERATION - это вычисленное значение, то же самое, что TYPE_ACCELEROMETER за вычетом силы тяжести. Ссылка: stackoverflow.com/a/27461970/1910735, также я думаю, что это объясняется по этой ссылке (developer.android.com/reference/android/hardware/) - person Dawood Awan; 03.02.2020

Согласно нашему обсуждению, поскольку ваше ускорение постоянно меняется, уравнения движения, которые вы применили, не дадут вам точного ответа.

Возможно, вам придется постоянно обновлять свое положение и скорость по мере получения нового значения ускорения.

Поскольку это было бы крайне неэффективно, я предлагаю вызывать функцию обновления каждые несколько секунд и использовать среднее значение ускорения в течение этого периода для получения новой скорости и положения.

person Abhishek Bansal    schedule 04.11.2013

Я не совсем уверен, но я думаю, что примерно в этой части:

Double initialVelocity = prevLocation.Speed;
var t = secondsTravelling.TotalSeconds;
var finalvelocity = initialVelocity + Double.Parse(currentAcceleration) * t;

если, скажем, на prevLocation скорость была: 27,326 ... и t == 0 и currentAcceleration == 0 (как вы сказали, вы были в режиме ожидания), окончательная скорость снизится до

var finalvelocity = 27.326 + 0*0;
var finalvelocity == 27.326

Если конечная скорость становится скоростью текущего местоположения, так что предыдущее местоположение = текущее местоположение. Это означало бы, что ваша конечная скорость может не снизиться. Но опять же, здесь довольно много предположений.

person CuccoChaser    schedule 01.11.2013
comment
Хорошая точка зрения. Похоже, сейчас мне придется его отфильтровать. если условие возможно. - person Dawood Awan; 01.11.2013
comment
Я добавил несколько сенсорных фильтров на Android End. Отправлю ответ, когда найду его. Я принял во внимание вашу точку зрения о начальной скорости - person Dawood Awan; 02.11.2013

Похоже, ты усложняешь себе жизнь. Вы должны иметь возможность просто и легко использовать Google Play Service Location API. доступ к местоположению, направлению, скорости и т. д. точно.

Я бы посмотрел на это, вместо того, чтобы делать для него работу на стороне сервера.

person David    schedule 01.11.2013
comment
Приложение предназначено для использования датчиков, а не службы определения местоположения .. Приложение Fusion датчиков :-( - person Dawood Awan; 01.11.2013