Skip to Content
Основные понятияВождение и безопасность

Вождение и безопасность

Tracelet может превратить необработанный поток данных о местоположении и акселерометре в значимый поток события о том, как движется устройство — полностью на устройстве, без облака звонки. В 3.3.0 добавлены три независимые функции:

ОсобенностьЧто это вам говоритВы включаете его с помощьюВы слушаете
Автомобильные мероприятия«Водитель резко затормозил/сильно ускорился/резко повернул/превысил скорость»НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕ
Транспортный режим«Пользователь сейчас ходит/бегает/ездит на велосипеде/в транспортном средстве»НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕ
Авария и падение«Возможно, только что произошло столкновение (или падение)»НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕ

Все здесь включено и отключено по умолчанию. Если вы не включите функцию, его механизм даже не создается — существующее отслеживание ведет себя точно так же, как до. Включайте только то, что вам нужно.


Для кого это? (реальные примеры)

  • Страхование по факту использования/безопасность автопаркасобытия по вождению дают вам стоимость каждой поездки картинка рискованного вождения (резкое торможение, превышение скорости) без какой-либо серверной части обработка.
  • Приложения для доставки/обслуживания на местахрежим транспорта позволяют помечать каждую поездку как вождение вместо ходьбы (например, «вышел из фургона и пошел к двери»).
  • Приложения для одиноких работников, совместных поездок и личной безопасностиобнаружение столкновений и падений дает вам надежный триггер (с окном отмены пользователя «Я в порядке»), чтобы запустить поток SOS.

Вы можете включить любую комбинацию — они независимы.


1. Дорожные события (телематика)

30-секундная версия

// 1. Turn it on (e.g. with a 50 km/h limit for speeding) await Tracelet.ready(Config( telematics: TelematicsConfig( enableDrivingEvents: true, speedLimitKmh: 50, ), )); // 2. Listen Tracelet.onDrivingEvent((event) { print('${event.kind} — severity ${event.severity}'); }); // 3. Start tracking as usual await Tracelet.start();

Вот и все. По мере движения устройства вы будете получать такие события, как:

harsh_braking — severity 0.82 speeding — severity 0.40

Что означает каждое поле

Каждый DrivingEvent имеет:

ПолеЗначение
НОТРАНС0ЛАТЕharsh_braking, harsh_acceleration, harsh_cornering или speeding
НОТРАНС0ЛАТЕ0.01.0 — насколько далеко прошло пороговое значение (удобно для оценки)
НОТРАНС0ЛАТЕИзмеряемое число: сила перегрузки для суровых условий, км/ч сверх допустимого для превышения скорости
НОТРАНС0ЛАТЕСкорость на данный момент, м/с
latitude / longitude / timestampГде и когда

Настройка порогов

Все пороговые значения указаны в g (1 g ≈ 9,81 м/с², сила тяжести). По умолчанию следуйте общепринятой практике страхования/парка — вам редко придется ее менять:

ВариантПо умолчаниюЧто он делает
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕТормозите сильнее → harsh_braking
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕУскорьтесь сильнее → harsh_acceleration
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕПоворот сильнее этого → harsh_cornering
НОТРАНС0ЛАТЕ0 (выкл.)Ограничение скорости; 0 отключает обнаружение превышения скорости
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕБлагодать превыше предела, прежде чем она засчитается
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕДолжно быть, слишком долго (избегайте коротких всплесков)
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕИгнорировать события со скоростью ниже этой скорости (шум парковки)

Почему иногда нет событий? События вождения определяются на основе данных о скорости GPS, которые обновляется примерно раз в секунду и немного шумно. Tracelet сознательно отдает предпочтение точность важнее чувствительности — скорее пропустят пограничное событие, чем плачь волк. Для достижения наилучших результатов используйте его во время вождения (не во время ходьбы).


2. Вид транспорта

Сообщает, является ли пользователь still, walking, running, cycling или находится в vehicle, сочетая движение акселерометра со скоростью GPS.

await Tracelet.ready(Config( classifier: ClassifierConfig(enableFusedClassifier: true), )); Tracelet.onModeChange((event) { print('Now: ${event.mode} (confidence ${event.confidence})'); });
ВариантПо умолчаниюЧто он делает
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕГлавный выключатель
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕЕсли true, объединенный режим отменяет действия ОС при принятии решений об использовании батареи. Если false (по умолчанию), он просто аннотирует — значение ОС остается основным
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕНовый режим должен действовать так долго, прежде чем о нем будет сообщено (перестанет мерцать)
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕНиже этот режим отображается как unknown
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕЕсли true, режим фиксации также перенастраивает фильтры местоположения. См. ниже

Аннотация или переопределение: по умолчанию классификатором является второе мнение. сообщает о режиме, но не меняет способ выборки данных GPS Tracelet. Большинству приложений этого нужно. Устанавливайте fusedClassifierAuthoritative: true только в том случае, если вы специально хотите, чтобы результат для управления поведением батареи/выборки.

Автоматическая настройка фильтров местоположений

Новое в версии 3.8.0.

Отслеживание с точностью до расстояния требует разных порогов фильтра для разных деятельность. Ходьба – это трудный случай: при ~1,4 м/с минимальный уровень шума GPS является большим. часть того, как далеко вы на самом деле продвинулись, поэтому свободный фильтр записывает дрожание как расстояние. В машине все наоборот — тесные пороги выбрасывают реальное движение.

Вы не можете выбрать один набор заранее. Ваши пользователи не заявляют: «Я сейчас бегаю», и одна сессия обычно включает прогулку до начала тропы, пробежку и идти назад. Итак, пусть классификатор решает:

await Tracelet.ready(Config( classifier: ClassifierConfig( enableFusedClassifier: true, // required autoTuneFromTransportMode: true, ), ));

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

МодаНОТРАНС0ЛАТЕНОТРАНС1ЛАТЕНОТРАНС2ЛАТЕНОТРАНС3ЛАТЕ
НОТРАНС0ЛАТЕ25 м15 м10 м3 м/с
НОТРАНС0ЛАТЕ8 м15 м10 м4 м/с
НОТРАНС0ЛАТЕ12 м25 м15 м9 м/с
НОТРАНС0ЛАТЕ20 м30 м20 м20 м/с
НОТРАНС0ЛАТЕ30 м50 м30 м60 м/с
НОТРАНС0ЛАТЕваши настроенные значения восстановлены

Бег трусцой специально не имеет гребка — он попадает в диапазон running (6–20 км/ч), именно поэтому «предустановка для бега», ориентированная на пользователя, была бы фикцией.

Как это остается предсказуемым:

  • Перенастройка происходит только при фиксированном изменении режима – уже с доверительным контролем. и устраняется modeSwitchDwellMs — никогда по показаниям датчика, поэтому пороговые значения не могу болтать.
  • Пороги меняются на месте. Ваш одометр остается постоянным на протяжении всего изменение режима, а не потеря сегмента.
  • Примененные значения поступают в событии onModeChange и в журнале отладки, поэтому автонастройка никогда не молчит.
  • unknown восстанавливает все, что вы настроили. Tracelet не угадывает, когда это произойдет. не знает.
  • Выключение autoTuneFromTransportMode (или enableFusedClassifier) выключение в среда выполнения немедленно восстанавливает настроенные пороговые значения — эта функция никогда не оставляет свои эффекты позади, как только вы его выключаете.

Смотрим, что было применено

ModeChangeEvent.appliedTuning содержит четыре пороговых значения, которые были введены в сила. Это null, когда автонастройка выключена и когда установлен режим unknown. (который восстанавливает ваши собственные ценности):

Tracelet.onModeChange((event) { final tuning = event.appliedTuning; if (tuning == null) { print('${event.mode} — your configured thresholds are in force'); } else { print('${event.mode} → distanceFilter ${tuning.distanceFilter} m, ' 'odometerAccuracyThreshold ${tuning.odometerAccuracyThreshold} m'); } });

Те же значения появляются в журнале с debug: true и logLevel: verbose:

auto-tune: 'walking' → distanceFilter=8.0m trackingAccuracy=15m odometerAccuracy=10m maxImpliedSpeed=4m/s

Читаем, что сейчас действует

onModeChange сообщает вам о моменте фиксации режима. Спросить, что фильтры используются в любой момент, включая случаи, когда не произошло смены режима часы — используйте Tracelet.getCurrentLocationTuning():

final tuning = await Tracelet.getCurrentLocationTuning(); print('in force: distanceFilter ${tuning?.distanceFilter} m, ' 'trackingAccuracyThreshold ${tuning?.trackingAccuracyThreshold} m');

Это считывается из собственного процессора местоположения, а не из конфигурации, которую вы используете. набор. Это различие имеет значение: Tracelet.activeConfig — это зеркало Дартса последний переданный вами Config, поэтому он сообщает то, что вы запросили, а не то, что фильтр на самом деле используется — и он вообще не может показать вам автонастройку, потому что автонастройка изменяет пороговые значения без какого-либо вызова конфигурации.

Возвращает null до того, как сеанс отслеживания создаст процессор, и всегда null в Интернете, который не имеет эквивалентного состояния фильтра.

Это переопределяет установленные вами значения geo.distanceFilter и geo.filter.*. до тех пор, пока зафиксирован режим. В этом суть функции, но это так. означает, что настроенные вами пороговые значения не соответствуют тем, которые действуют во время выполнения — вызовите getCurrentLocationTuning(), чтобы увидеть, что есть на самом деле. Оставьте false ( default), если вам нужны точные значения.


3. Обнаружение столкновений и падений

Готовность к производству. Обнаружение сбоев поставляется со стабильным конвейером на устройстве: обработчик правил по умолчанию, а также дополнительно обученная лицензированная модель сбоев AI. на наборе данных о сбоях CC0 / public-domain, поэтому он разрешен для коммерческого использования. в производственных приложениях. Обнаружение падения по-прежнему остается добровольным и оптимальным. Отслеживать текущие исследование точности в Проблеме № 183 .

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

await Tracelet.ready(Config( impact: ImpactConfig( enableCrashDetection: true, confirmWindowMs: 15000, // 15s for the user to say "I'm fine" ), )); Tracelet.onImpact((event) async { if (event.isPotential) { // Show a big "Are you OK?" countdown screen. // If the user taps "I'm fine": await Tracelet.cancelImpact(event.id); // If they tap "Get help now": // await Tracelet.confirmImpact(event.id); } else { // event.kind == 'crash' (or 'fall') — confirmed. // The user didn't cancel in time → start your SOS flow. } });

Как работает поток

  1. Сильный удар при быстром движении → вы получаете событие potential_crash с confirmDeadline.
  2. Показать интерфейс обратного отсчета. Пользователь может отменить (cancelImpact) или подтвердить сейчас (НЕ ПЕРЕВОДИЛОСЬ).
  3. Если они ничего не сделают до истечения крайнего срока → сработает подтвержденное событие crash.
ВариантПо умолчаниюЧто он делает
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕОбнаружение аварий транспортных средств
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕЛичное падение (максимальное усилие — больше ложных тревог)
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕСила удара (g) считается столкновением. Снижен с 3,0 на основе большого исследования полевых данных (3,0 g пропускает ~ половину реальных аварий); способствует отзыву, поскольку обратный отсчет отмены обнаруживает ложные тревоги. Настройтесь, если видите слишком много подсказок.
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕДолжно быть, двигались так быстро (подтверждение)
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕОтменить продолжительность обратного отсчета
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕПодавить кандидатов с низким уровнем доверия

Tracelet предоставляет вам окно запуска и отмены — он никогда не выключает телефон. звонит или связывается со службами экстренной помощи. Создание фактического потока SOS/экстренной помощи ответственность вашего приложения (и позволяет вам контролировать UX и легальную копию).

Подтверждение сохраняется после закрытия приложения

Жестокое воздействие часто заканчивается тем, что ОС убивает приложение — телефон выбрасывается, транспортное средство останавливается, устройство переходит в режим сна. Если обратный отсчет отмены живет только в памяти, подтвержденный crash/fall никогда не сработает. Tracelet делает обратный отсчет безопасным: в тот момент, когда potential_crash/potential_fall поднимается, он сохраняется на диске и пробуждение запланировано сразу после истечения крайнего срока. Если приложение все еще живо, оно подтверждает нормально и снимает пробуждение с охраны; если его убили, то пробуждение повторно генерирует подтвержденное событие из нового процесса, поэтому поток SOS продолжает работать.

ПлатформаМеханизм
АндроидТочный сигнал тревоги AlarmManager (setExactAndAllowWhileIdle, срабатывает даже в режиме Doze) пробуждает получателя, который повторно доставляет подтвержденное событие.
iOSЛокальное уведомление, запланированное к крайнему сроку, предупреждает пользователя, даже если приложение не работает; подтвержденное событие повторно доставляется при следующем запуске SDK (фоновый перезапуск или приоритетный режим). Предоставьте разрешение на уведомление для оповещения пользователя — повторная доставка работает в любом случае.

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

Дополнительные подсказки, подтверждающие реальную аварию или падение

Самого по себе сильного толчка недостаточно — это вызовет слишком много ложных тревог. Поэтому Tracelet ищет дополнительные подсказки из реального мира, которые обычно случаются во время реальных событий. разбиться или упасть. Чем больше подсказок он видит, тем больше он уверен. Эти подсказки могут только Сделайте Tracelet более уверенным в себе — они никогда не отменяют настоящее мероприятие.

  • Телефон падал — как раз перед тем, как кто-то уронил телефон или взял трубку. падение, телефон ненадолго становится невесомым. Пятнистость, которая делает падение сильнее правдоподобно.
  • После этого всё замерло — после настоящего падения человек и телефон обычно перестают двигаться. Эта внезапная тишина — сильный знак.
  • Автомобиль внезапно остановился — при реальной аварии автомобиль переходит от скорости к почти остановился через секунду или две. Резкое падение скорости приводит к аварии.
  • Взрыв давления — серьезная авария (или срабатывание подушки безопасности) вызывает быстрое изменение давления воздуха внутри автомобиля. Телефоны с датчиком давления могут обратите на это внимание; телефоны без него просто пропускают эту проверку, без каких-либо недостатков.

Дополнительно: лицензированная модель сбоя AI.

По умолчанию при обнаружении сбоев используется механизм правил (порог g + скорость). подтверждение выше) — никаких дополнительных настроек, работает «из коробки». Для более высокой точности вы можете включить модель сбоя AI: обученную модель, которая предотвращает сбой при изученная вероятность вместо фиксированного порога.

Он по желанию и загружается по требованию (никогда не внедряется), поэтому базовый размер SDK неизменен. Чтобы включить его, получите лицензионный ключ и укажите на него свой конфиг:

await Tracelet.ready(Config( impact: ImpactConfig( enableCrashDetection: true, crashModelUnlockUrl: 'https://unlock.ikolvi.com/unlock', crashModelLicenseKey: '<your license key>', crashModelThreshold: 0.5074, // rf_probability_threshold from training ), ));
ВариантПо умолчаниюЧто он делает
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕКонечная точка лицензирования, которая активирует модель. null ⇒ чистый механизм правил
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕВаш лицензионный ключ (со страницы «Получить лицензию»)
НОТРАНС0ЛАТЕНОТРАНС1ЛАТЕВероятность, при которой модель зафиксирует сбой

Если модель не может быть активирована по какой-либо причине (офлайн, неверный ключ), SDK автоматически возвращается к обработчику правил — ваше приложение продолжает работать.

Получить лицензию

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

  • лицензия разработчика — для отладочных сборок и эмуляторов. Просто идентификатор вашего приложения, ничего лишнего настраивать.
  • лицензия на продукт — для вашего поставляемого приложения; также нужен сертификат подписи вашего приложения SHA-256 (Play Console → Целостность приложения → Подписание приложения или ./gradlew signingReport).

На портале также перечислены выданные вами ключи, и вы можете мгновенно отозвать их.


Пробуем без вождения (симуляция) и доступа к базе данных.

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

Получение телематических данных из базы данных

Каждое событие вождения и удара автоматически сохраняется в локальной базе данных SQLite. Вы можете получить эти структурированные записи, чтобы отобразить историю рискованного поведения при вождении:

// Fetch the 50 most recent telematics events from the database final events = await Tracelet.getTelematicsEvents(50); for (final event in events) { print('Event Type: \${event.eventType}'); // e.g. harsh_braking, crash print('Severity: \${event.severity}'); print('Location: \${event.latitude}, \${event.longitude}'); }

События возвращаются сначала самые новые, и синхронизация не удаляет их из этого списка. просмотр — включение syncTelematics загружает события, но оставляет вашу локальную историю нетронутый.

Отправка их на ваш бэкэнд

Установите HttpConfig.syncTelematics: true, и несинхронизированные события будут работать как обычно. синхронизация местоположения — массив telematics корневого уровня в том же POST или собственный запрос, когда вы устанавливаете HttpConfig.telematicsUrl. Неудачные загрузки сохраняют события поставлены в очередь, а не отбрасывать их. Для проводной схемы границы пакетной обработки и компромисс с отдельной конечной точкой, см. Телематическая синхронизация 📖.

Моделирование событий

Вы можете внедрить имитацию телематических событий непосредственно в собственные механизмы отслеживания. Это идеально подходит для тестирования реакции вашего приложения (например, отображения экрана SOS при сбое) или тестирования компонентов пользовательского интерфейса. Страница примера приложения Вождение и безопасность и наложение Tracelet Doctor используют этот API, чтобы позволить разработчикам запускать события с помощью кнопок.

// Simulate a harsh braking event (named arguments) await Tracelet.simulateTelematicsEvent( eventType: 'harsh_braking', severity: 0.85, // 0.0 to 1.0 latitude: 37.422, longitude: -122.084, );

Очистка базы данных

Если вам необходимо сбросить состояние диагностики или очистить историю телематических событий из локальной базы данных, вы можете очистить очередь:

await Tracelet.destroyTelematicsEvents();

В автоматических тестах вы также можете управлять двигателями непосредственно из Dart (они предоставляются через flutter_rust_bridge) — см. example/integration_test/behavior_simulation_test.dart.


Разрешения

  • Для участия в автомобильных мероприятиях требуется только разрешение на определение местоположения, которое вы уже используете для отслеживание — ничего лишнего.
  • Транспортный режим и авария/падение используют акселерометр. На Андроиде это уже работает для обнаружения движения (нет нового разрешения). В iOS добавление Описание использования Движение и фитнес повышает точность. См. iOS и Страницы настройки Android.

Приятно знать

  • На устройстве и детерминированный — все обнаружение выполняется в общем ядре Rust. Нет сеть, без облачной модели, одинаковые результаты на Android и iOS.
  • События вождения также доступны в Интернете (они получаются с помощью GPS).
  • Побочный канал — эти события проводятся наряду с вашими обычными onLocation поток; они никогда не меняют ваше местоположение или одометр, и они присоединяйтесь к полезной нагрузке синхронизации только в том случае, если вы согласитесь с syncTelematics.