Стек GPS
Общий принцип работы GPS
Host
Технологии
Для получения данных от GPS используется ряд технологий:
- Общение между железом и софтом осуществляется через драйвер gps_drv_stp.ko (поднимается ряд чар-девайсов: /dev/ccci_c2k_agps, /dev/fw_log_gps, /dev/gps2scp, /dev/gps_emi, /dev/gps_pwr, /dev/stpgps, /dev/stpgps2);
- Общением между драйвером и /vendor/bin/mnld осуществляется через закрытую библиотеку libmnl.so;
- /vendor/bin/mnld имеет ряд интерфейсов для связи с прочими программами, один из интерфейсов - HAL
О GeoClue2
На текущий момент данные от gps-manager в GeoClue2 передаются через стандартный Unix-сокет. К сожалению, механизм определения положения по WiFi сетям не работает, поэтому позиция будет доступна только от GPS.
Как получить локацию в QT
Добавить пакет location в pro-файл. Пример файла для сборки:
TEMPLATE = app
TARGET = sample_qtlocation
CONFIG += console c++11
QT = core location
SOURCES += main.cpp
В cpp-файле:
- Подключить заголовки для функций работы с позицией;
- Проверить, что источник данных по умолчанию является geoclue2;
- Подключить получение позиции через connect;
- Задать метод получения позиции в SatellitePositioningMethods;
- Начать отправлять обновления через регулярные промежутки времени, по дефолту 1 секунда, задать другой промежуток с помощью функции setUpdateInterval().
#include <QCoreApplication>
#include <ostream>
#include <iostream>
#include <QGeoServiceProvider>
#include <QGeoPositionInfo>
#include <QGeoPositionInfoSource>
static bool isHighAccuracySource(const QGeoPositionInfoSource *source)
{
return source->supportedPositioningMethods().testFlag(
QGeoPositionInfoSource::SatellitePositioningMethods);
}
int main(int argc, char * argv[]) {
QCoreApplication app(argc, argv);
QVariantMap params;
params["desktopId"] = "SomeIdentifierString";
auto m_positionInfoSource = QGeoPositionInfoSource::createDefaultSource(NULL);
std::cout << "default source: " << m_positionInfoSource->sourceName().toStdString() << " with " << (!isHighAccuracySource(m_positionInfoSource) ? "low":"high") << " accuracy" << std::endl;
QObject::connect(m_positionInfoSource, &QGeoPositionInfoSource::positionUpdated, [=](const QGeoPositionInfo &info) {
if(info.coordinate().isValid()) {
std::cout << "****** Update ****** " << std::endl << info.coordinate().toString().toStdString() << std::endl;
std::cout << "Latitude: " << info.coordinate().latitude() << std::endl;
std::cout << "Longitude: " << info.coordinate().longitude() << std::endl;
std::cout << "TS: " << info.timestamp().toString().toStdString() << std::endl;
std::cout << "Accuracy: " << info.attribute(QGeoPositionInfo::HorizontalAccuracy) << std::endl;
} else {
std::cout << "The coordinates are invalid!" << std::endl;
}
});
m_positionInfoSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
m_positionInfoSource->setUpdateInterval(5000);
m_positionInfoSource->startUpdates();
return app.exec();
}
Для компиляции используйте команды:
qmake-qt5 ./test.pro
make
На телефоне может потребовать библиотека lib64qt5location5, для её установки используйте команду:
sudo dnf install lib64qt5location5
Или включите пакет в spec-файл.