LINUX.ORG.RU

Разный результат исполнения из-под отладчика и с использованием systemctl

 , ,


1

1

Добрый день

Имеется Малинка RPi3b. Написано приложение на Qt, которое читает данные от GPS модуля и выводит их на экран. Если запускать апп при старте Малинки с помощью systemctl, то выводятся одни координаты. Если запускать апп из-под отладчика, то другие, отличаются на сотые доли градуса. Помогите, пожалуйста, разобраться.

Спасибо.



Последнее исправление: AlexVM2020 (всего исправлений: 2)

Ответ на: комментарий от aiqu6Ait

Под отладчиком прыгают десятитысячные доли координаты, это нормально. После включения координата неправильная, и стоит колом, ничего не меняется, хотя в посылке NMEA тысячные прыгают. Такое впечатление, что-то с округлением. В либе, которая парсит посылку от модуля в координаты, используется тип double. Может разные либы цепляются?

AlexVM2020
() автор топика
Ответ на: комментарий от AlexVM2020

Между 59.87426 и 59.86666 27 секунд, то есть ошибка примерно 700 метров, что много. Интересно, что 59.86666 - это 59°52’00", то есть секунды просто отброшены

AlexVM2020
() автор топика
Ответ на: комментарий от AlexVM2020

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

AlexVM2020
() автор топика
Ответ на: комментарий от AlexVM2020

Проблема в том, что в разных локалях применяются разные разделители для целой и дробной части. А в nmea строках запятая разделяет значения, а точка отделяет дробь в самом значении.
Так что либо пускать программу с локалью, где разделитель точка, либо переопределять переменную LC_NUMERIC, либо получать системный разделитель из localeconv, а потом менять точку в строках на этот символ перед преобразованием в дабл. В qt возможно вместо localeconv какие-то свои механизмы для указания символа разделителя при преобразовании строки в число, не знаток я qt.

imul ★★★★★
()
double toDouble(QString const& s, bool* ok)
{
	bool success = false;
	double ret = QLocale::system().toDouble(s, &success);
	if (!success)
		ret = QLocale::c().toDouble(s, &success);
	if (ok)
		*ok = success;
	return ret;
}
Beewek ★★
()
Ответ на: комментарий от AlexVM2020

https://doc.qt.io/qt-5/qcoreapplication.html#locale-settings

Locale Settings
On Unix/Linux Qt is configured to use the system locale settings by default. This can cause a conflict when using POSIX functions, for instance, when converting between data types such as floats and strings, since the notation may differ between locales. To get around this problem, call the POSIX function setlocale(LC_NUMERIC,"C") right after initializing QApplication, QGuiApplication or QCoreApplication to reset the locale that is used for number formatting to "C"-locale.
rumgot ★★★★★
()

Когда работаешь с NMEA, скорее всего ты пользуешься сишными функциями преобразования строки в число. В них есть проблема парсинга десятичной точки в виде символов "." и "," в зависимости от локали. От этого могут быть проблемы точности, в зависимости от того как представляются координаты (тройками градусы-минуты-секунды float, или одним числом double, или градусы-минуты целые, а секунды с плавающей точкой и т.д.).

Если у тебя уродская библиотека NMEA, которая это не учитывает, а ты ее не имеешь права менять, то перед вызовом ее функций можешь ставить C-локаль, после вызова переключать обратно на системную. Тогда твоя прога будет работать правильно независимо от того, в какой локали ты ее запустил.

А если можешь влиять на NMEA либу, и она предназначена для Qt, используй QString::toFloat(), там, насколько я помню, таких проблем нет.

Xintrea ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.