- C 97.4%
- QML 1.6%
- JavaScript 0.3%
- Rust 0.2%
- Tree-sitter Query 0.2%
- Other 0.1%
|
|
||
|---|---|---|
| .github/workflows | ||
| assets | ||
| bridge | ||
| docs | ||
| extras/mimic | ||
| lib | ||
| po | ||
| qml | ||
| src | ||
| tui | ||
| vendor | ||
| www | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| clickable.yaml | ||
| compilar_solo_mimic.sh | ||
| LICENSE | ||
| manifest.json | ||
| navius | ||
| navius.apparmor | ||
| navius.content-hub | ||
| navius.desktop | ||
| navius.url-dispatcher | ||
| README.es.md | ||
| README.md | ||
| snapcraft.yaml | ||
Navius GPS
GPS navigator for Ubuntu Touch. Rust + QML, packaged as Click.
Community · Telegram — GUI & Design · Telegram — Bugs & Issues
User manual · Developer docs User manual Spanish · Developer docs Spanish
Navius account and privacy
Navius works fully offline without an account. Creating an account is optional and enables community features (alerts, traffic prediction, nearby ads).
When you are logged in:
- The app sends your route position to the server for traffic prediction using the Valhalla routing engine.
- Ads may appear along the road based on your location.
If you do not want to send any data, simply do not create or use a Navius account.
You can use any public Valhalla server or run your own with OSM Scout Server.
Features
- Turn-by-turn navigation with voice instructions (TTS)
- Routing via Valhalla (own or public server), alternatives, avoid tolls/ferries/motorways
- Vector map with MapLibre (own tiles or Maptiler)
- Satellite view with GPS signal overlay
- Speed limits per segment (OSM Legal Default Speeds)
- Synthetic predicted traffic by road hierarchy (Valhalla predicted traffic)
- Route planning with scheduled departure time and saved plans
- Per-destination TODOs (tasks to complete at each stop)
- Nearby POI search (fuel, parking, restaurants, hotels…)
- GPS track recording (SQLite + GPX export)
- Driving simulator with manual speed/direction control
- Google Maps integration (external launch)
- Satellite and 3D mode (buildings)
- Dead-reckoning and GPS interpolation at 10 Hz
- Concurrent Waydroid support without GPS loss
Architecture
┌─────────────────────────────────────────────────────────┐
│ QML (UI) │
│ Main.qml · SearchPanel · NavBar · PreferencesPanel … │
├─────────────────────────────────────────────────────────┤
│ Rust (backend) │
│ SatelliteModel · NavHttp · NavTts · NavTracker │
├───────────────────┬─────────────────────────────────────┤
│ C++ (glue) │ JavaScript (route logic) │
│ satellite_source │ NavSearch.js · SimRoute.js │
│ location_props │ TodoDB.js │
├───────────────────┴─────────────────────────────────────┤
│ lomiri-location-service (D-Bus) · GPS HAL │
└─────────────────────────────────────────────────────────┘
Rust modules
| Module | Description |
|---|---|
main.rs |
Qt initialization, QML type registration, engine loading |
satellite_model.rs |
QObject exposed to QML: proxy between SatelliteSource (C++) and the UI; 1 Hz tick |
nav_http.rs |
QObject for async HTTP POST via QNetworkAccessManager; done(req_id, body, err) signal |
nav_tts.rs |
Multi-engine TTS: Piper (neural), Mimic HTS (Spanish), PicoTTS (fallback); FIFO queue, WAV pre-generation |
nav_tracker.rs |
GPS track recording in SQLite; haversine, GPX export |
qrc.rs |
Loads QRC resources generated by build.rs |
C++ modules
| File | Description |
|---|---|
satellite_source.h |
SatelliteSource: GPS data source. Reads from LLS via Qt Positioning + satellite bridge. Manages automatic LLS reconnection |
location_props.h/.cpp |
LocationPropsWatcher: polls VisibleSpaceVehicles from LLS; detects LLS restart via D-Bus NameOwnerChanged and emits llsRestarted signal |
Main QML
| File | Description |
|---|---|
Main.qml |
Root window; app states (idle, navigating, parking); global configuration |
GpsSource.qml |
GPS abstraction: unifies real fix, simulation, dead-reckoning and 10 Hz interpolation |
NavSearch.js |
Geocoding logic (Photon/Komoot) and route calculation (Valhalla API); speed limit enrichment via trace_attributes |
SearchPanel.qml |
Planning panel: destinations, per-stop TODOs, departure time, saved plans, favourites, history, POI search |
NavBar.qml |
Active navigation bar: current instruction, distance, ETA, speed, speed limit |
SpeedView.qml |
Circular speedometer |
SatelliteView.qml |
Polar satellite view with SNR signal |
PreferencesPanel.qml |
Settings: Valhalla server, vehicle type, TTS, simulator, map styles |
TodoDB.js |
SQLite API (LocalStorage) for per-destination TODOs |
SimRoute.js |
Simulation route generator with realistic speed |
Build and deploy
Requires Clickable ≥ 8.7.0.
# Build for aarch64 device
clickable build
# Deploy to device (USB)
clickable install
# Launch
clickable launch
To build only the Mimic TTS library:
bash compilar_solo_mimic.sh
Build dependencies
The postbuild hook in clickable.yaml automatically bundles:
- espeak-ng + data (phonemes for Piper)
- Piper (downloaded from GitHub if not in
vendor/piper_aarch64/) - PicoTTS (
vendor/picotts/, compiled during build) - Mimic HTS Spanish (
vendor/mimic_hts/+extras/mimic/) - libpcaudio stub (
src/libpcaudio_stub.c) — PCM audio without PulseAudio dependency - libpiper_limit (
src/libpiper_limit.c) — limits Piper CPU usage viasetrlimit - libQMapLibre + MapboxMap plugin (
lib/)
GPS and lomiri-location-service
Navius uses lomiri-location-service (LLS) as the GPS backend via D-Bus. A patched package (3.4.1+navius5) is distributed that fixes multiple stability issues with the GPS HAL on HALIUM_10, especially when Waydroid runs concurrently.
LLS patches (navius1–navius5)
navius1 — Waydroid SIGSEGV + EDEADLK
Waydroid overwrites LLS GPS callbacks while LLS is dispatching them → SIGSEGV. Fixed with std::shared_mutex (callbacks under shared lock; register_callbacks() under exclusive lock). Split into three phases of register_callbacks() to avoid EDEADLK from HAL re-entry during u_hardware_gps_new().
navius2 — Non-blocking start_positioning() + satellite API
start_positioning() and register_callbacks() run in a detached thread so the D-Bus thread doesn't block on binder IPC (can block indefinitely when Waydroid holds the HAL). Added D-Bus method GetVisibleSpaceVehicles and Restart=always in the systemd unit.
navius3 — Fast path + concurrent recovery guard
Fast path in start_positioning(): if the GPS handle is valid (normal case), calls u_hardware_gps_start() directly without spawning a thread. Atomic flag positioning_active prevents two concurrent recovery threads.
navius4 — Watchdog + dispatch modes in fast path
Thread watchdog (5 s tick, 10 s threshold): detects frozen GPS, re-registers callbacks and restarts GPS automatically. dispatch_updated_modes_to_driver() added to fast path before u_hardware_gps_start().
navius5 — Centralised lls_trace.h
LLS_DEBUG constant and LLS_TRACE() macro moved to a single shared header (include/location_service/com/lomiri/location/lls_trace.h).
Fixes in navius (this repo)
- Automatic reconnection (
location_props.cpp):NameOwnerChangedon D-Bus; when LLS restarts, navius recreates the position source and LLS session automatically. - Lambda leak (
satellite_source.h):init_pos_and_session()reconnectedllsRestartedon every call, accumulatingStartPositionUpdatescalls exponentially. Connections are now registered once ininit_sources(). startUpdates()on main thread (satellite_source.h): the Qt LLS plugin usesQEventLoopinternally instartUpdates(). Calling it from a thread without an event loop blocked forever. Fixed withQMetaObject::invokeMethodon the main thread.
Enabling debug traces
// src/location_props.h
static constexpr bool NAVIUS_DEBUG = true; // navius traces on stderr
// lomiri-location-service/include/.../lls_trace.h
static constexpr bool LLS_DEBUG = true; // LLS internal traces on stderr
View traces on device:
ssh phablet@<ip> "journalctl --user -f -u navius.woodyst_navius.desktop"
# or
adb shell "sudo -u phablet NAVIUS_DEBUG=1 /opt/click.ubuntu.com/navius.woodyst/current/navius 2>&1"
Valhalla server
Navius can use any Valhalla server. The custom server is configured in Preferences → Valhalla Server.
Default server: https://valhalla.egpsistemas.com
Map build
Tiles are built with the standard Valhalla pipeline in 13 phases:
| Phase | Description |
|---|---|
| 01 | PBF download |
| 02–06 | Parse, enhance, build tiles |
| … | … |
| 13 | Predicted traffic (generate_traffic.py + valhalla_add_predicted_traffic) |
Predicted traffic uses synthetic profiles by tile level:
| Level | Road type | Free-flow | Peak | Night |
|---|---|---|---|---|
| 0 | Motorways | 115 km/h | 85 | 110 |
| 1 | Primary/secondary | 85 km/h | 55 | 80 |
| 2 | Local/residential | 45 km/h | 25 | 40 |
Peak hours: Mon–Fri 7–9h and 17–19h (parabolic fade).
Route requests always include date_time so Valhalla applies the speed profile for the current time or the scheduled departure time.
TTS (Text-to-Speech)
Three engines available, selectable in Preferences:
| Engine | Quality | Latency | Languages |
|---|---|---|---|
| Piper | Neural (high) | ~300 ms | Many (.onnx voices) |
| Mimic HTS | HTS (medium) | ~100 ms | Spanish (built-in) |
| PicoTTS | Concatenative (low) | ~50 ms | ES, EN, DE, FR, IT |
Piper pre-generates WAVs for upcoming instructions in the background to minimise playback latency. libpiper_limit.so limits Piper CPU usage via LD_PRELOAD + setrlimit.
Satellite bridge
When the GPS hardware is not directly accessible (Waydroid, emulators), the bridge navius-sat-bridge.py reads NMEA data from the HAL and writes it to /run/user/32011/navius.woodyst/navius-sat.txt. SatelliteSource reads this file as a secondary source if LLS provides no data.
# Install the bridge (on device)
bash bridge/install.sh
File structure
navius/
├── src/
│ ├── main.rs # Rust entrypoint
│ ├── satellite_model.rs # GPS proxy QObject
│ ├── satellite_source.h # C++: LLS + GPS bridge
│ ├── location_props.h/.cpp # C++: SV polling, LLS reconnection
│ ├── nav_http.rs # Async HTTP
│ ├── nav_tts.rs # TTS (Piper/Mimic/Pico)
│ ├── nav_tracker.rs # GPS tracks SQLite/GPX
│ ├── build.rs # QRC + C++ compilation
│ ├── libpcaudio_stub.c # PCM audio stub
│ └── libpiper_limit.c # Piper CPU limiter
├── qml/
│ ├── Main.qml # Main window
│ ├── GpsSource.qml # GPS abstraction
│ ├── NavSearch.js # Geocoding + Valhalla routing
│ ├── SearchPanel.qml # Route planning
│ ├── NavBar.qml # Active navigation bar
│ ├── SpeedView.qml # Speedometer
│ ├── SatelliteView.qml # Satellite view
│ ├── PreferencesPanel.qml # Settings
│ ├── RouteSelectPanel.qml # Vehicle/route type selection
│ ├── RouteViewPanel.qml # Instruction list
│ ├── StopTodoPanel.qml # Per-stop TODOs
│ ├── TodoDB.js # SQLite LocalStorage TODOs
│ ├── SimRoute.js # Simulation route
│ ├── SimTestRoutes.js # Test routes for simulator
│ └── [other panels and dialogs]
├── vendor/
│ ├── piper_aarch64/ # Piper binary + libs
│ ├── picotts/ # PicoTTS source
│ ├── mimic_hts/ # Mimic HTS Spanish source
│ └── mimic_hts_voice/ # Spanish HTS voice
├── extras/
│ └── mimic/ # Compiled Mimic (generated)
├── bridge/
│ ├── navius-sat-bridge.py # NMEA satellite bridge
│ ├── navius-sat-bridge-hal.c # Direct HAL access
│ └── navius-sat-bridge.service # systemd unit
├── lib/
│ ├── libQMapLibre.so.3.0.0 # MapLibre GL
│ └── MapboxMap/ # MapboxMap QML plugin
├── assets/
│ ├── logo.svg
│ └── gps_search.png
├── clickable.yaml # Clickable build config
├── manifest.json # Click metadata
├── navius.apparmor # AppArmor permissions
└── Cargo.toml # Rust dependencies
Data persistence
All user data is stored in:
~/.local/share/navius.woodyst/
├── gps_tracks.db # SQLite: recorded tracks
├── gps_tracks/ # Exported GPX files
└── QtProject/ # Qt Settings (favourites, history, plans, waypoints, preferences)
QML Settings categories
| Category | Contents |
|---|---|
nav |
current waypoints, route options (tolls, ferry, unpaved, motorway) |
dest_history |
recent destination history (max 50) |
favorites |
favourites with name and address |
saved_plans |
saved plans (destinations + TODOs + departure time + options) |
search_ui |
expanded state of sections in the panel |
Per-destination TODOs are stored in SQLite via TodoDB.js (LocalStorage) with key dest_key = "${lat}_${lon}".
Environment variables and debug
| Variable | Effect |
|---|---|
NAVIUS_DEBUG=true (in location_props.h) |
Enables GPS/LLS traces on stderr |
LLS_DEBUG=true (in lls_trace.h) |
Enables LLS internal traces on stderr |
QML_XHR_ALLOW_FILE_READ/WRITE=1 |
Allows XMLHttpRequest to file:// (enabled by default in the binary) |
QML_DISABLE_DISK_CACHE=1 |
Disables compiled QML cache |
The instruction and network request log can be viewed inside the app by enabling the log panel (tap the log area in SearchPanel).
License
Copyright (C) 2026 Edi
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.