Skip to content

Commit

Permalink
Merge pull request #170 from semuconsulting/RC-1.5.1
Browse files Browse the repository at this point in the history
RC 1.5.1
  • Loading branch information
semuadmin authored Dec 6, 2024
2 parents 620c430 + 0fd7f2a commit 3b7c3f6
Show file tree
Hide file tree
Showing 42 changed files with 1,784 additions and 613 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"editor.formatOnSave": true,
"modulename": "pygpsclient",
"distname": "pygpsclient",
"moduleversion": "1.5.0",
"moduleversion": "1.5.1",
"python.defaultInterpreterPath": "python3",
}
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ You will need to logout and login for the launcher to take effect.
| User-selectable 'widgets' | To show or hide the various widgets, go to Menu..View and click on the relevant hide/show option. |
|---------------------------|---------------------------------------------------------------------------------------------------|
|![banner widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/banner_widget.png?raw=true)| Expandable banner showing key navigation status information based on messages received from receiver. To expand or collapse the banner or serial port configuration widgets, click the ![expand icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-arrow-80-16.png?raw=true)/![expand icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-triangle-1-16.png?raw=true) buttons. **NB**: some fields (e.g. hdop/vdop, hacc/vacc) are only available from proprietary NMEA or UBX messages and may not be output by default. The minimum messages required to populate all available fields are: NMEA: GGA, GSA, GSV, RMC, UBX00 (proprietary); UBX: NAV-DOP, NAV-PVT, NAV_SAT |
|![console widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/console_widget.png?raw=true)| Configurable serial console widget showing all incoming data streams (both GNSS and RTK) in either parsed, binary or tabular hexadecimal formats. Double-click to copy contents of console to clipboard. The scroll behaviour and number of lines retained in the console can be configured via the settings panel. Supports user-configurable color tagging of selected strings for easy identification. Color tags are loaded from the `"colortag_b":` value (`0` = disable, `1` = enable) and `"colortags_l":` list (`[string, color]` pairs) in your json configuration file (see example provided). If color is set to "HALT", streaming will halt on any match and a warning displayed. NB: color tagging does impose a small performance overhead - turning it off will improve console response times at very high transaction rates.|
|![console widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/console_widget.png?raw=true)| Configurable serial console widget showing all incoming data streams (both GNSS and RTK) in either parsed, binary or tabular hexadecimal formats. Double-right-click to copy contents of console to clipboard. The scroll behaviour and number of lines retained in the console can be configured via the settings panel. Supports user-configurable color tagging of selected strings for easy identification. Color tags are loaded from the `"colortag_b":` value (`0` = disable, `1` = enable) and `"colortags_l":` list (`[string, color]` pairs) in your json configuration file (see example provided). If color is set to "HALT", streaming will halt on any match and a warning displayed. NB: color tagging does impose a small performance overhead - turning it off will improve console response times at very high transaction rates.|
|![skyview widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/skyview_widget.png?raw=true)| Skyview widget showing current satellite visibility and position (elevation / azimuth). Satellite icon borders are colour-coded to distinguish between different GNSS constellations. For consistency between NMEA and UBX data sources, will display GLONASS NMEA SVID (65-96) rather than slot (1-24). |
|![graphview widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/graphview_widget.png?raw=true)| Graphview widget showing current satellite reception (carrier-to-noise ratio or cnr). Double-click to toggle legend. |
|![static map](https://github.com/semuconsulting/PyGPSClient/blob/master/images/staticmap.png?raw=true)| Map widget with various modes of display. Map Type = 'world': a static offline Mercator world map showing current global location.
Expand All @@ -268,8 +268,9 @@ You will need to logout and login for the launcher to take effect.
|![import custom map](https://github.com/semuconsulting/PyGPSClient/blob/master/images/importcustommap.png?raw=true)| <a name="custommap">Import Custom Map dialog</a>. Click ![load icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-folder-18-24.png?raw=true) to open the custom map image location (*the default file suffix is `*.tif` - select Show Options to select any file suffix `*.*`*). If the `rasterio` library is installed and the image is georeferenced (e.g. using [QGIS](https://qgis.org/)), the map extent will be automatically extracted - otherwise it must be entered manually. Import the custom map path anad extent settings by clicking ![play icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-arrow-12-24.png?raw=true). See [Creating Custom Maps for PyGPSClient](https://www.semuconsulting.com/gnsswiki/custommapwiki/) for tips on how to create a suitable georeferenced map image.|
|![spectrum widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/spectrum_widget.png?raw=true)| Spectrum widget showing a spectrum analysis chart (*GNSS receiver must be capable of outputting UBX MON-SPAN messages*). Clicking anywhere in the spectrum chart will display the frequency and decibel reading at that point. Double-clicking anywhere in the chart will toggle the GNSS frequency band markers (L1, G2, etc.) on or off. Right-click anywhere in the chart to capture a snapshot of the spectrum data, which will then be superimposed on the live data. Double-right-click to clear snapshot. **NB:** Some receivers (e.g. NEO-F10N) will not output the requisite MON-SPAN messages unless the port baud rate is at least 57,600. |
|![sysmon widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/sysmon_widget.png?raw=true)| System Monitor widget showing device cpu, memory and I/O utilisation (*GNSS receiver must be capable of outputting UBX MON-SYS and/or MON-COMMS messages*). Tick checkbox to toggle between actual (cumulative) I/O stats and pending I/O. |
|![scatterplot widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/scatterplot_widget.png?raw=true)| Scatterplot widget showing variability in position reporting over time. (Optional) Enter fixed reference position. Select Average to center plot on dynamic average position (*displayed at top left*), or Fixed to center on fixed reference position (*if entered*). Check Autorange to set plot range automatically. Set the update interval (e.g. 4 = every 4th navigation solution). Use the range slider or mouse wheel to adjust plot range. Right-click to set fixed reference point to the current mouse cursor position. Double-click clear existing plot. The default center mode, autorange, update increment, scale index and fixed reference position settings can be stored in the json configuration file as `scattercenter_s`/`scatterautorange_b`/`scatterinterval_n`/`scatterscale_n`/`scatterlat_f`/`scatterlon_f`. |
|![scatterplot widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/scatterplot_widget.png?raw=true)| Scatterplot widget showing variability in position reporting over time. (Optional) Enter fixed reference position. Select Average to center plot on dynamic average position (*displayed at top left*), or Fixed to center on fixed reference position (*if entered*). Check Autorange to set plot range automatically. Set the update interval (e.g. 4 = every 4th navigation solution). Use the range slider or mouse wheel to adjust plot range. Right-click to set fixed reference point to the current mouse cursor position. Double-click to clear the existing data. Settings may be saved to a json configuration file. |
|![rover widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/rover_widget.png?raw=true) | Rover widget plots the relative 2D position, track and status information for the roving receiver in a fixed or moving base / rover RTK configuration. Can also display relative position of NTRIP mountpoint and receiver in a static RTK configuration. Double-click to clear existing plot. (*GNSS rover receiver must be capable of outputting UBX NAV-RELPOSNED messages.*) |
|![chart view](/images/chart_widget.png?raw=true) | Chart widget acts as a multi-channel "oscilloscope", allowing the user to plot a series of named numeric data attributes from any NMEA, UBX, RTCM or SPARTN data source, with configurable y (value) and x (time) axes. By default, the number of channels is set to 4, but this can be manually edited by the user via the json configuration file setting `chartsettings_d["numchn_n"]`. For each channel, user can select: (*optional*) identity of message source e.g. `NAV-PVT`; attribute name e.g. `hAcc`; scaling factor (divisor) e.g. 1000; y axis range e.g. 0 - 5. Wildcards are available for attribute groups - "\*" (average of group values), "+" (maximum of group values), "-" (minimum of group values) e.g. `cno*` will plot the average `cno` value for a group of satellites. Double-click to clear the existing data. Double-right-click to save the current chart data to the clipboard in CSV format. Settings may be saved to a json configuration file. |
---
## <a name="ubxconfig">UBX Configuration Facilities</a>

Expand Down
15 changes: 15 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# PyGPSClient Release Notes

### RELEASE 1.5.1

1. Add new user-selectable and configurable "Chart" widget:
- The Chart widget broadly emulates a multi-channel "oscilloscope", allowing the user to plot designated numeric data attribute values over time. By default, the number of channels is set to 4, but this can be manually edited by the user via the json configuration file setting `chartsettings_d["numchn_n"]`.
- Any numeric attribute from any incoming NMEA, UBX, RTCM or SPARTN message can be plotted.
- For each channel, user must specify the parsed data attribute name e.g. "hAcc" or "numSV".
- User can optionally specify a message identity e.g. "GNGGA" or "NAV-PVT", in which case only the attribute from that message identity will be plotted.
- Nested group attributes must include the full group index e.g. "cno_04". Alternatively, one of three wildcard characters '*', '+' or '-' can be appended, representing the average, minimum or maximum of the nested group values e.g. "cno\*" = (cno_01 + cno_02 + ... + cno_0n) / n ; "cno+" = max(cno_01, cno_02, ..., cno_0n).
- X (time) and Y (value) axes are fully configurable.
- Double-right-click will save the current chart data to the clipboard in CSV format.
- The maximum number of datapoints per channel is configurable, though **NB** the practical maximum will be dependent on available platform memory and performance. 100,000 datapoints per channel is roughly equivalent to 3 MB in-memory data.
- Chart settings will be saved to the json configuration file when "Save Configuration" is invoked.
- Principally intended to provide a real-time view of incoming data trends over relatively short periods (minutes or hours). *Analyses of much long time-series data (days or weeks) can probably be done more efficiently by saving a binary log of the incoming data and processing the data offline through a standard Python graphing tool like `matplotlib`*.
1. Add Check (for updates) on startup option to About dialog (NB: check requires internet connectivity)

### RELEASE 1.5.0

FIXES:
Expand Down
16 changes: 16 additions & 0 deletions docs/pygpsclient.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ pygpsclient.banner\_frame module
:undoc-members:
:show-inheritance:

pygpsclient.chart\_frame module
-------------------------------

.. automodule:: pygpsclient.chart_frame
:members:
:undoc-members:
:show-inheritance:

pygpsclient.confirm\_box module
-------------------------------

.. automodule:: pygpsclient.confirm_box
:members:
:undoc-members:
:show-inheritance:

pygpsclient.console\_frame module
---------------------------------

Expand Down
Binary file added images/chart_widget.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/good_sats.png
Binary file not shown.
Binary file removed images/high_precision.png
Binary file not shown.
Binary file removed images/low_precision.png
Binary file not shown.
Binary file removed images/poor_sats.png
Binary file not shown.
49 changes: 43 additions & 6 deletions pygpsclient.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"Spectrum": false,
"System Monitor": false,
"Scatter Plot": false,
"checkforupdate_b": 0,
"mapupdateinterval_n": 60,
"defaultport_s": "USB",
"mqapikey_s": "<======= YOUR MQ API KEY ======>",
Expand Down Expand Up @@ -110,12 +111,48 @@
"spartndecode_b": 0,
"spartnkey_s": "abcd1234abcd1234abcd1234abcd1234",
"spartnbasedate_n": -1,
"scatterautorange_b": 0,
"scattercenter_s": "Average",
"scatterinterval_n": 1,
"scatterscale_n": 6,
"scatterlat_f": 37.23345133,
"scatterlon_f": -115.81513477,
"scattersettings_d": {
"maxpoints_n": 2000,
"scatterautorange_b": 1,
"scattercenter_s": "Average",
"scatterinterval_n": 1,
"scatterscale_n": 12,
"scatterlat_f": 37.23345,
"scatterlon_f": -115.81513
},
"chartsettings_d": {
"numchn_n": 4,
"timrng_n": "240",
"maxpoints_n": "2000",
"0": {
"id_s": "NAV-PVT",
"name_s": "hAcc",
"scale_f": "100",
"miny_f": "0",
"maxy_f": "1"
},
"1": {
"id_s": "NAV-PVT",
"name_s": "pDOP",
"scale_f": "1",
"miny_f": "0",
"maxy_f": "10"
},
"2": {
"id_s": "NAV-PVT",
"name_s": "numSV",
"scale_f": "1",
"miny_f": "0",
"maxy_f": "50"
},
"3": {
"id_s": "NAV-PVT",
"name_s": "carrSoln",
"scale_f": "1",
"miny_f": "0",
"maxy_f": "5"
}
},
"ubxpresets_l": [
"Force HOT Reset (!!! Will require reconnection !!!), CFG, CFG-RST, 00000000, 1",
"Force WARM Reset (!!! Will require reconnection !!!), CFG, CFG-RST, 00010000, 1",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name = "pygpsclient"
authors = [{ name = "semuadmin", email = "semuadmin@semuconsulting.com" }]
maintainers = [{ name = "semuadmin", email = "semuadmin@semuconsulting.com" }]
description = "GNSS Diagnostic and UBX Configuration GUI Application"
version = "1.5.0"
version = "1.5.1"
license = { file = "LICENSE" }
keywords = [
"PyGPSClient",
Expand Down
2 changes: 1 addition & 1 deletion src/pygpsclient/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
:license: BSD 3-Clause
"""

__version__ = "1.5.0"
__version__ = "1.5.1"
23 changes: 21 additions & 2 deletions src/pygpsclient/about_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from platform import python_version
from subprocess import CalledProcessError, run
from sys import platform
from tkinter import Button, E, Frame, Label, Tcl, Toplevel, W
from tkinter import Button, Checkbutton, E, Frame, IntVar, Label, Tcl, Toplevel, W
from webbrowser import open_new_tab

from PIL import Image, ImageTk
Expand Down Expand Up @@ -69,6 +69,9 @@ def __init__(self, app, **kwargs):
self._img_github = ImageTk.PhotoImage(Image.open(ICON_GITHUB).resize((32, 32)))
self._img_exit = ImageTk.PhotoImage(Image.open(ICON_EXIT))
self._img_sponsor = ImageTk.PhotoImage(Image.open(ICON_SPONSOR))
self._checkonstartup = IntVar()
cfu = self.__app.saved_config.get("checkforupdate_b", False)
self._checkonstartup.set(cfu)
self._updates = []

self._body()
Expand Down Expand Up @@ -112,6 +115,11 @@ def _body(self):
font=self.__app.font_sm,
cursor="hand2",
)
self._chk_checkupdate = Checkbutton(
self._frm_container,
text="Check on startup",
variable=self._checkonstartup,
)
self._lbl_giticon = Label(
self._frm_container,
image=self._img_github,
Expand Down Expand Up @@ -159,7 +167,10 @@ def _do_layout(self):
column=0, row=4 + i, columnspan=2, padx=2, pady=2
)
self._btn_checkupdate.grid(
column=0, row=5 + i, ipadx=3, ipady=3, columnspan=2, padx=3, pady=3
column=0, row=5 + i, ipadx=3, ipady=3, padx=3, pady=3
)
self._chk_checkupdate.grid(
column=1, row=5 + i, ipadx=3, ipady=3, padx=3, pady=3
)
self._lbl_giticon.grid(column=0, row=6 + i, padx=(3, 1), pady=3, sticky=E)
self._lbl_sponsoricon.grid(column=1, row=6 + i, padx=(3, 1), pady=3, sticky=W)
Expand All @@ -181,6 +192,7 @@ def _attach_events(self):
self._lbl_copyright.bind("<Button>", self._on_license)
self._btn_ok.bind("<Return>", self._ok_press)
self._btn_ok.focus_set()
self._checkonstartup.trace_add("write", self._on_save_settings)

def _on_github(self, *args, **kwargs): # pylint: disable=unused-argument
"""
Expand Down Expand Up @@ -272,3 +284,10 @@ def _do_update(self, *args, **kwargs): # pylint: disable=unused-argument

self._btn_checkupdate.config(text="RESTART APP", fg="green")
self._btn_checkupdate.bind("<Button>", self.__app.on_exit)

def _on_save_settings(self, var, index, mode): # pylint: disable=unused-argument
"""
Save current settings to saved app config dict.
"""

self.__app.saved_config["checkforupdate_b"] = self._checkonstartup.get()
Loading

0 comments on commit 3b7c3f6

Please sign in to comment.