Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPS location on Linux #1569

Closed
gardners opened this issue Apr 5, 2020 · 23 comments · Fixed by #1577
Closed

GPS location on Linux #1569

gardners opened this issue Apr 5, 2020 · 23 comments · Fixed by #1577
Assignees
Milestone

Comments

@gardners
Copy link

gardners commented Apr 5, 2020

Steps to reproduce

  1. Use Mapper on desktop computers

Actual behaviour

There is no support for GPS in the desktop application.

Expected behaviour

It would be great if there were a way to show current GPS location on the map, so that I can use my ruggedised laptop for mapping outdoors.
Similarly being able to capture traces, or use GPS position as a waypoint when drawing paths would be great.

Configuration

Mapper Version: 0.9.2
Operating System: Ubuntu 18.04

@dg0yt
Copy link
Member

dg0yt commented Apr 5, 2020

There is no support for GPS in the desktop application.

In "touch mode", there is GPS support also on the desktop, since v0.9.0. The feature depends on the platform:

  • Cross-platform: NMEA via serial port. Requires an environment variable to name the port.
  • Windows: "Location"
  • macOS: "Core Location"
  • Linux: "GeoClue"

Documentation and improvements will come with actual use and feedback.

Related: GH-422

@gardners
Copy link
Author

gardners commented Apr 5, 2020

Ok. That seems a reasonable work-around to me.

So in that case, if I do something like:

$ MAPPER_MOBILE_GUI=1 QT_NMEA_SERIAL_PORT=/dev/ttyACM0 Mapper
With a GPS available on /dev/ttyACM0 like this one:

$ head /dev/ttyACM0 
$GNRMC,065901.00,A,3018.94658,S,13920.03591,E,0.341,,050420,,,A*76
$GNVTG,,T,,M,0.341,N,0.631,K,A*3F
$GNGGA,065901.00,3018.94658,S,13920.03591,E,1,11,0.79,362.4,M,10.3,M,,*50
$GNGSA,A,3,03,01,04,11,09,14,,,,,,,1.64,0.79,1.44*1A
$GNGSA,A,3,69,84,68,85,70,,,,,,,,1.64,0.79,1.44*17
$GPGSV,4,1,14,01,43,333,29,03,70,189,14,04,50,236,23,06,00,212,*76
$GPGSV,4,2,14,07,00,322,,09,22,262,21,11,11,347,25,14,08,114,11*7C
$GPGSV,4,3,14,16,22,054,18,22,74,081,,23,,,33,26,29,086,*4E
$GPGSV,4,4,14,31,31,137,,41,20,289,*7D
$GLGSV,3,1,09,68,20,095,08,69,48,150,17,70,24,222,24,78,15,149,*65

Then it should work, or have I missed something?
It seems to not be working, and there is no sign that it is opening the GPS serial port, as nothing has the file open when I check with lsof:

$ sudo lsof | grep -i ttyACM0
$

This is with Sensors -> Location -> Source set to "default". Or should I be using GeoClue? I tried that briefly as well, but had no luck there.

@dg0yt
Copy link
Member

dg0yt commented Apr 5, 2020

MAPPER_MOBILE_GUI=1 is no longer needed at the command line: You can toggle "Touch mode" on the Welcome screen.

In my CI builds of Qt, there is a file libqtposition_serialnmea.so, However, on my Ubuntu 18.04, this Qt plugin is not installed:

$ ls /usr/lib/x86_64-linux-gnu/qt5/plugins/position/
libqtposition_geoclue.so  libqtposition_positionpoll.so

I don't know why the serial NMEA plugin is not available in Debian or Ubuntu. Maybe it is a packaging bug.

So from this point of view, you will have to use GeoClue on Ubuntu 18.04 for now.

@dg0yt
Copy link
Member

dg0yt commented Apr 5, 2020

So from this point of view, you will have to use GeoClue on Ubuntu 18.04 for now.

But I don't find much information on how to connect GeoClue to the serial port. The best starting point I have is: https://gitlab.freedesktop.org/geoclue/geoclue/-/issues/85

  • They "didn't want the normal GPS devices (whether builtin or Bluetooth) in Geoclue".
  • You could connect via another tool, https://github.com/zeenix/gps-share/
    You could also connect an Android phone's GPS, via an app which has been updated in a while.

... In the end, it may be easier to just build the missing plugin :-(

@dg0yt
Copy link
Member

dg0yt commented Apr 5, 2020

There is another Qt positioning plugin which is not packaged on Debian/Ubuntu: gypsy.

@gardners
Copy link
Author

gardners commented Apr 6, 2020

Yes, I had tried GeoClue without luck, which is why I instead tried to use the NMEA serial interface ;)
I'll have another look when I get a moment.

@dg0yt dg0yt changed the title Show GPS location / allow use of GPS location as waypoint on paths GPS location on Linux Apr 6, 2020
@dg0yt
Copy link
Member

dg0yt commented Apr 6, 2020

I created a package "qtlocation-opensource-serialnmea" with just the serial NMEA plugin on https://build.opensuse.org/package/show/home:dg0yt

Download / installation:
https://software.opensuse.org//download.html?project=home%3Adg0yt&package=qtlocation-opensource-serialnmea

With the plugin installed, you may choose "Serial port (NMEA)" and the actual port in the settings.

@gardners
Copy link
Author

gardners commented Apr 6, 2020

Thanks -- Confirming that this gives the option in Mapper to select it. Now I just have to get outside or wait for the atmospherics to improve for me to get a fix through the window. One or the other will happen in the next few hours, and I'll give feedback then.

@gardners
Copy link
Author

gardners commented Apr 7, 2020

I have confirmed that my GPS is running on /dev/ttyACM0 (gpsmon shows the current fix when run), but I still see no location in Mapper. Does it assume 9600bps or anything like that? (My GPS is at 57600, and I'm not sure that I can actually change it).

@dg0yt
Copy link
Member

dg0yt commented Apr 7, 2020

The plugin sets the port to 4800 baud.

Unfortunately, there is not much documentation available from Qt (https://doc.qt.io/qt-5.12/qtpositioning-index.html). Most of time I will have to look at the source code at https://code.woboq.org/qt5/qtlocation/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp.html. But I will test if one of my devices can be made work on Linux.

@gardners
Copy link
Author

gardners commented Apr 7, 2020

Hmm.. That's a bit annoying that they have it hardwired like that. Let me know how you go with any of your devices, and if that works, then I'll see if I can figure out how to set my internal GPS to 4800 baud.

@dg0yt
Copy link
Member

dg0yt commented Apr 7, 2020

gpsmon shows the current fix when run

Well, gpsmon is part of gpsd, and gpsd claims to work with geoclue - I assume over a local network port provided by gpsd.

@gardners
Copy link
Author

gardners commented Apr 7, 2020

Not sure. I just settled on gpsmon as a convenient way to actually probe a serially-connected GPS, to make sure that it is working. I can take another look at trying to get GeoClue to use the GPS.

@lpechacek
Copy link
Member

Well, gpsmon is part of gpsd, and gpsd claims to work with geoclue - I assume over a local network port provided by gpsd.

But not vice versa. One of the geoclue maintainers stated that gpsd support was dropped from geoclue in 2013.

@lpechacek
Copy link
Member

gps-share, created by the same person who wrote the above-referenced comment, seems to be the way to go. However, it fails to build for me both on openSUSE Tumbleweed and Debian Buster.

@lpechacek
Copy link
Member

lpechacek commented Apr 9, 2020

I haven't suffered such horrible pain for a long time but I've just made my external receiver work with Geoclue2. Key points are:

  • Geoclue2 does parse NMEA but it refuses to accept source configuration, effectively making the source configuration some else's problem. The "someone else" is Avahi.
  • Avahi accepts service registration on two fronts. It can either be configured via the D-Bus interface or statically in /etc/avahi/services/. gps-share does the service registration on D-Bus and then forwards data from the serial port to a TCP socket. That is, however, unnecessary as a different combination of Linux tools does the same. Do one thing and do it well.
  • So the final chain is: external receiver -> OS kernel -> something that takes NMEA data from /dev/ttyACM0 and passes it to a TCP socket + something else what tells Avahi that NMEA data is at at that port (the configuration part which is Geoclue refusing) -> Geoclue2 daemon interpreting NMEA data -> Mapper reading position data via D-Bus interface

For the record, the configuration steps. Don't try this at home!

  1. Connect the receiver and check that it provides data.
lpechacek@fmn:~> head -3 /dev/ttyACM0
$GNRMC,084830.00,A,4900.00000,N,01400.00000,E,0.090,,090420,,,D,V*19
$GNVTG,,T,,M,0.090,N,0.166,K,D*30
$GNGGA,084830.00,4900.00000,N,01400.00000,E,2,12,1.03,353.2,M,44.2,M,,0000*4B
  1. Start something that moves the NMEA data onto network. gps-share is one option, I've suceeded with the below procedure.
lpechacek@fmn:~> avahi-publish-service -f NMEA_SOURCE _nmea-0183._tcp 10110 accuracy=exact &
[1] 12529
lpechacek@fmn:~> Established under name 'NMEA_SOURCE'

lpechacek@fmn:~> socat TCP4-LISTEN:10110,reuseaddr,fork /dev/ttyACM0,rawer

In another terminal window check that the service is known to Avahi.

lpechacek@fmn:~> avahi-browse -t _nmea-0183._tcp
+ wlp1s0 IPv6 NMEA_SOURCE                                   _nmea-0183._tcp      local
+ wlp1s0 IPv4 NMEA_SOURCE                                   _nmea-0183._tcp      local

If nothing appears, check that you have a broadcast network interface up and that mdns port is open in your firewall.
3) Make sure network-nmea is enabled in /etc/geoclue/geoclue.conf, restart geoclue and try reading the position data from it. If you are lucky, it goes like this.

lpechacek@fmn:~> fgrep -A3 network-nmea /etc/geoclue/geoclue.conf
[network-nmea]

# Fetch location from NMEA sources on local network?
enable=true
lpechacek@fmn:~> sudo systemctl restart geoclue
[sudo] password for root: 
lpechacek@fmn:~> /usr/lib/geoclue-2.0/demos/where-am-i
Client object: /org/freedesktop/GeoClue2/Client/1

New location:
Latitude:    49.000000°
Longitude:   14.000000°
Accuracy:    0.000000 meters
Altitude:    364.200000 meters
Heading:     23013856.000000°
Timestamp:   Thu 09 Apr 2020 11:04:11 AM CEST (1586423051 seconds since the Epoch)

If you are unlucky, you will see accuracy somewhere around 25 km and more debugging is necessary. Either Geoclue cannot find the Avahi service (not registered, communication blocked by firewall) and the symptoms are - no results from Avahi browser and the message "Not starting GClueNMEASource". Should not happen if you checked the service registration in step 2 and I'm including this output only for illustration.

lpechacek@fmn:~> sudo systemctl stop geoclue
lpechacek@fmn:~> sudo G_MESSAGES_DEBUG=Geoclue /usr/lib/geoclue
(geoclue:24032): Geoclue-DEBUG: 11:13:21.753: Available accuracy level from GClueWifi: 4
(geoclue:24032): Geoclue-DEBUG: 11:13:21.756: Avahi Service Browser's CACHE_EXHAUSTED event occurred
(geoclue:24032): Geoclue-DEBUG: 11:13:21.756: Avahi Service Browser's ALL_FOR_NOW event occurred
(geoclue:24032): Geoclue-DEBUG: 11:13:21.758: WiFi device 'wlp1s0' added.
...
(geoclue:24032): Geoclue-DEBUG: 11:13:28.570: Not starting GClueNMEASource (accuracy level: 0). Requested accuracy level: 8.

More likely the hostname advertised by Avahi won't resolve to an IP address.

lpechacek@fmn:~> sudo G_MESSAGES_DEBUG=Geoclue /usr/lib/geoclue
(geoclue:24210): Geoclue-DEBUG: 11:18:42.414: Available accuracy level from GClueWifi: 4
(geoclue:24210): Geoclue-DEBUG: 11:18:42.417: Service 'NMEA_SOURCE' of type '_nmea-0183._tcp' found in domain 'local'
(geoclue:24210): Geoclue-DEBUG: 11:18:42.419: Service 'NMEA_SOURCE' of type '_nmea-0183._tcp' found in domain 'local'
(geoclue:24210): Geoclue-DEBUG: 11:18:42.419: Avahi Service Browser's CACHE_EXHAUSTED event occurred
(geoclue:24210): Geoclue-DEBUG: 11:18:42.419: Service fmn.local:10110 resolved
(geoclue:24210): Geoclue-DEBUG: 11:18:42.419: Available accuracy level from GClueNMEASource: 8
(geoclue:24210): Geoclue-DEBUG: 11:18:42.420: No. of _nmea-0183._tcp services 1
(geoclue:24210): Geoclue-DEBUG: 11:18:42.420: Service fmn.local:10110 resolved
(geoclue:24210): Geoclue-DEBUG: 11:18:42.420: No. of _nmea-0183._tcp services 2
(geoclue:24210): Geoclue-DEBUG: 11:18:42.421: WiFi device 'wlp1s0' added.
...
(geoclue:24210): Geoclue-DEBUG: 11:18:50.991: GClueNMEASource now active
...
(geoclue:24210): Geoclue-DEBUG: 11:18:51.011: 'geoclue-where-am-i' started.
...
(geoclue:24210): Geoclue-WARNING **: 11:18:51.501: Failed to connect to NMEA service: Error resolving “fmn.local”: Name or service not known

The where-am-i demo program may show noticeable delay upon startup and then it reports accuracy in the range of kilometers. The remedy is to add the failing hostname to /etc/hosts as a synonym for localhost.

lpechacek@fmn:~> sudo vi /etc/hosts
lpechacek@fmn:~> fgrep fmn.local /etc/hosts
127.0.0.1	fmn.local

These are all the issues I've faced so far.
4) At this point, where-am-i should show reasonable data. So, start Mapper in touch mode and enable GPS display:
ezgif-4-74524ce0de25

@lpechacek
Copy link
Member

However, it fails to build for me both on openSUSE Tumbleweed and Debian Buster.

Solved by installing libdbus-devel. It is just a cryptic message from the Rust build system which prevented me from seeing the missing dependency.

@dg0yt
Copy link
Member

dg0yt commented Apr 11, 2020

If head /dev/ttyACM0 works, we may implement an easy way to just read from the device, without taking Qt serialport into the code path. I could add another static plugin if you are willing to test this @lpechacek.

@lpechacek
Copy link
Member

@dg0yt, sure, I can test the new code.

@gardners
Copy link
Author

@dg0yt I was actually going to suggest exactly this :) Also very happy to test, as not being able to do outdoor checking and mapping is the current hold-up for me to continue mapping the area here, as the contour and other data here in the middle of the mountainous desert here is, shall we say, a touch on the sparse side.

@dg0yt dg0yt linked a pull request Apr 12, 2020 that will close this issue
@dg0yt dg0yt added this to the v0.9.3 milestone Apr 13, 2020
@dg0yt dg0yt self-assigned this Apr 13, 2020
@lpechacek
Copy link
Member

If head /dev/ttyACM0 works...

Took me some time to understand the meaning of the sentence. Of course, the user needs to have access to the communication port. On openSUSE and Debian it means being a member of dialout user group. I hope that most Linux users will be able to make the necessary configuration steps.

@dg0yt
Copy link
Member

dg0yt commented Apr 16, 2020

If head /dev/ttyACM0 works...

What I meant was: If it can be treated as a regular file...

@dg0yt
Copy link
Member

dg0yt commented Apr 26, 2020

Got my G-Rays 2 bluetooth receiver playing with "NMEA (OpenOrienteering)" on Linux.

  1. Enable Bluetooth on PC. (Can be verified by hciconfig returning some device being "UP".)
  2. Use hcitool scan to find HW adress of GPS receiver.
  3. Use sudo rfcomm bind 0 [HW address] to create /dev/rfcomm0 bound to the the device's first channel.
  4. Set Mapper to use rfcomm0 or /dev/rfcomm0.

Cleanup: sudo rfcomm release 0

Remarks:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants