IoT: Написать алгоритм сглаживания числовых данных для топлива в баках
У нас имеется много данных по уровню топлива в баках у грузовых и легковых транспортных средств. Установленные датчики имеют точность 99% когда т/с стоит на месте. Во время движения (ускорение/торможение) топливо в баке движется и погрешность значительно растет (скриншот 1)
Задача такая:
Нужно написать алгоритм с сглаживанием числовых данных, а затем произвести расчеты для статистики по израсходованному топливу (пример того что должно быть на выходе в архиве result.js + массив с сглаженными значениями fuel_level)
На входе имеется массив с данными. Выглядит это приблизительно так:
type Point struct {
Timestamp int32 `json:"timestamp"`
FuelLevel float64 `json:"fuel_level"`
Speed int32 `json:"speed"`
}
type Points []Point
points := Points{
{ Timestamp: 1596749449000, FuelLevel : 172.5, Speed : 0 },
{ Timestamp: 1596751619000, FuelLevel : 171.03, Speed : 0 },
{ Timestamp: 1596751648000, FuelLevel : 174.14, Speed : 5 },
{ Timestamp: 1596751654000, FuelLevel : 172.76, Speed : 5 },
{ Timestamp: 1596751659000, FuelLevel : 172.76, Speed : 4 },
{ Timestamp: 1596751660000, FuelLevel : 172.76, Speed : 4 },
{ Timestamp: 1596751662000, FuelLevel : 172.76, Speed : 4 },
{ Timestamp: 1596751664000, FuelLevel : 172.76, Speed : 4 },
}
Что должен уметь делать алгоритм и какие решает он задачи:
1) Сглаживает все данные (уберет все отскоки, которые появляются из-за того, что топливо в баках движется при ускорениях, торможениях и поворотах т/с)
2) Вычислит сколько топлива было заправлено (привязка к timestamp)
3) Вычислит сколько топлива было израсходовано за всё время вместе с сливаниями.
4) Вычислит сколько топлива было слито (привязка к timestamp)
5) Минимальный уровень топлива (привязка к timestamp)
6) Максимальный уровень топлива (привязка к timestamp)
Везде погрешность не более 0.5%!!!!!!
Все заправки и сливы должны быть привязаны к timestamp. Если использовать moving median или moving mean нужно учитывать, что timestamp съедет и время слива или заправки не будет соответствовать действительности.
По поводу gps координат: они у нас имеются не во всех случаях, а в случаях, когда они есть - координаты могут тоже быть не точными. Поэтому обходимся без них.
На первом скриншоте это то, что приходит с датчиков. (y - уровень топлива, x - timestamp)
Данные реальные и за этот промежуток времени было 2 заправки по 200 литров
Второй скриншот - это результат, который мы имеем на данный момент с использованием решения написанного на Python. Его главный недостаток - невозможно определить точный timestamp слива и заправки, ну и второй недостаток - неудовлетворительное сглаживание (оно нужно, потому что на треке мы хотим видеть адекватное значение уровня топлива). В нашем случае проблема не в Python, а в том, что алгоритм написан на коленках в сжатые сроки
Во вложении также есть архив, где можно посмотреть 2 примера с тестовыми данными.
На первом примере как раз те данные, которые отражены не скриншотах.
На втором примере слив топлива в объеме 20 литров. Наш код показывается 21.39 литра и то, что сливали 3 раза. Это тоже неправильно.
result.json
{
fuel_consumption: 221.99, // общий расход топлива за весь промежуток времени
fuel_level_first: 171.77, // уровень топлива в самом начале
fuel_level_end: 147.93, // уровень топлива в конце
fuel_level_max: { timestamp: 12341234, value: 21.39 }, // максимальный уровень топлива
fuel_level_min: { timestamp: 12341234, value: 21.39 }, // минимальный уровень топлива
fuel_drain: [
{ timestamp: 12341234, value: 21.39 },
{ timestamp: 12341234, value: 21.39 },
], // сливания топлива
tucked_in: [
{ timestamp: 12341234, value: 21.39 },
{ timestamp: 12341234, value: 21.39 },
], // заправки
};
Весь код пишем на GO 1.15+
Большое спасибо!
Если есть вопросы по задаче или бюджету - пишите, не стесняемся, обсудим.