From 7f01623237d0588b34cddf65a600936071f943f0 Mon Sep 17 00:00:00 2001 From: llinkz Date: Sun, 14 Jan 2024 16:22:30 +0100 Subject: [PATCH] v7.20 --- README.md | 88 ++++++++++++++++++++--------------------- directTDoA.py | 2 +- getmap.py | 2 +- kiwirecorder_patch.diff | 40 +++++++++++++------ 4 files changed, 73 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 3ad7ff1..710a9e1 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,9 @@ -# directTDoA v7.10 +# directTDoA v7.20 ->### Hmmm latest KiwiSDR software broke directTDoA (no GNSS/GPS detected), let's see if I can figure out what's the problem or simply wait. (03-Jan-2024) - Happy New Year ? ---- ->### RESTRICTION BECAUSE OF MAPBOX ABUSE (11-aug-2023) ->### directTDoA code is now running in degraded mode as the Mapbox token is no longer valid (solution below) - ->I knew it was a bad idea to share this in code but today I got a bill because some bad guys made **too many unrelated** requests using the Mapbox token. -> ->![mapbox abuse](http://linkz.ddns.net/mapbox-abuse.png) -![mapbox abuse](http://linkz.ddns.net/mapbox-abuse2.png) -#### -### Here's your solution to fix it (it seems not possible to restrict the token to Static Images API only) ->1/ Create your own [Mapbox.com](https://account.mapbox.com/auth/signup/) account -> ->2/ Go to account and get/create a default public token -> ->3/ Edit [getmap.py](https://github.com/llinkz/directTDoA/blob/master/getmap.py#L30) and modify `MAP_TOK` variable with your default public token -> ->### directTDoA use [Static Images API](https://docs.mapbox.com/api/maps/static-images/) and you'll get 50000 free monthly requests +>### 03 Jan 2024 - KiwiSDR software version > v1.647 broke directTDoA (no GNSS/GPS detected because of IQ wav incompatibility) +>### 12 Jan 2024 - Good news! Christoph, our TDoA master fixed the issue (was a bug in kiwirecorder.py) +>#### FIX : https://github.com/jks-prv/kiwiclient/commit/bc189087cf503820d56ddcc0f8781d7eed1b6337 +>#### The fix is simple and can be done by hand, just edit your kiwiclient/kiwirecorder.py file if you want a quick one ! --- ![directTDoA picture](http://linkz.ddns.net/directTDoA.png) @@ -25,69 +11,77 @@ This software is JUST a python 2/3 GUI designed to compute TDoA runs on shortwav > TDoA = Time Difference of Arrival .. (in this case: the Arrival of shortwave radio transmissions) -> # Linux users : GNU Octave version < 8 only ! -> because read_kiwi_iq_wav.cc will not compile - fix in progress... +>## Linux users : GNU Octave version < 8 only ! +> else, read_kiwi_iq_wav.cc will not compile - fix in progress... ## KNOWN ISSUES: #### 1/ If you plan to use the software on a machine without a sound card then you must comment out lines 15 & 16 in `/directTDoA/kiwiclient/kiwirecorder.py` -`#stream = sounddevice.OutputStream(12000, 2048, channels=1, dtype='int16')` +`#stream = sounddevice.OutputStream(48000, 2048, channels=1, dtype='int16')` `#stream.start()` #### 2/ On recent versions of Octave the handling of the font size has been changed (pixels Vs points) and you may find that they are too large in the final file, you can reduce the fontsize values on lines 41, 42 & 154 in `/directTDoA/TDoA/m/tdoa_plot_map.m` -## INSTALL AND RUN (on WINDOWS) +--- +## WINDOWS ##### The decision was made not to support installation from the repository. -Download [directTDoA-windows.zip](https://github.com/llinkz/directTDoA/releases), unzip and extract it +1/ Download the latest [directTDoA-windows.zip](https://github.com/llinkz/directTDoA/releases), unzip and extract it -Then double-click on `directTDoA.bat` +2/ Create your own [Mapbox.com](https://account.mapbox.com/auth/signup/) account, go to account and get/create a default public token then edit [getmap.py](https://github.com/llinkz/directTDoA/blob/master/getmap.py#L30) and modify `MAP_TOK` variable with your default public token +> NOTE: directTDoA use [Static Images API](https://docs.mapbox.com/api/maps/static-images/) and you'll get 50000 free monthly requests -#### IMPORTANT: You must use only this method to launch the program to avoid file path issues. +3/ double-click on `directTDoA.bat` -> Info: this archive contains all the necessary files already patched and compiled and also includes light versions of GNU Octave and python, so no need to install the full versions of the last two on your machine. The unzipped archive is 272 MB, compared to ~2 GB in the other installer way. +>#### IMPORTANT: You must use only this method to launch the program to avoid file path issues. +#### This .zip archive contains all the necessary files already patched and compiled and also includes light versions of GNU Octave and python, so no need to install the full versions of the last two on your machine. The unzipped archive is 272 MB, compared to ~2 GB in the other installer way. -## INSTALL AND RUN (on LINUX) +--- +## LINUX -Install python 3 and python3-pip using your package manager +1/ Install python 3 and python3-pip using your package manager -Install GNU octave (important: only versions < 8) +2/ Install GNU octave (important: only versions < 8) -Install git, patch, gcc, base-devel, ttf-dejavu, gcc-fortran, tk, portaudio, xdg-utils, epdfview, fltk +3/ Install git, patch, gcc, base-devel, ttf-dejavu, gcc-fortran, tk, portaudio, xdg-utils, epdfview, fltk, liboctave-dev -`git clone --recursive https://github.com/llinkz/directTDoA` +4/ `git clone --recursive https://github.com/llinkz/directTDoA && cd directTDoA` -`cd directTDoA` +5/ `./setup.sh` +> ####This setup script will install python modules, compile the necessary .oct file and apply some files patchs +> ####IMPORTANT: The octave files compilation process takes a lot of time, be patient, ignore warnings and don't stop the script -`./setup.sh` (this script will install python modules, compile the necessary .oct file and apply some files patchs) -#### IMPORTANT: The octave files compilation process takes a lot of time, be patient, ignore warnings and don't stop the script -`./directTDoA.py` +6/ Create your own [Mapbox.com](https://account.mapbox.com/auth/signup/) account, go to account and get/create a default public token then edit file named [getmap.py](https://github.com/llinkz/directTDoA/blob/master/getmap.py#L30) and modify `MAP_TOK` variable with your default public token (directTDoA use [Static Images API](https://docs.mapbox.com/api/maps/static-images/) and you'll get 50000 free monthly requests) -> NOTE: on some distros you may need to install liboctave-dev +7/ `./directTDoA.py` -## INSTALL AND RUN (on MAC OS X) +--- +## MAC OS X * REQUIREMENT Xcode + Homebrew (https://brew.sh/index_fr) -Install Homebrew, in terminal : `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` +1/ Install Homebrew, in terminal : `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` -Install Python, in terminal : `brew install python@2` or `brew install python@3` +2/ Install Python, in terminal : `brew install python@2` or `brew install python@3` -Install GNU Octave in Terminal : `brew install octave` +3/ Install GNU Octave in Terminal : `brew install octave` -`git clone --recursive https://github.com/llinkz/directTDoA` +4/ `git clone --recursive https://github.com/llinkz/directTDoA && cd directTDoA` -`cd directTDoA` +5/ `./setup.sh` +> ####This setup script will install python modules, compile the necessary .oct file and apply some files patchs +> ####IMPORTANT: The octave files compilation process takes a lot of time, be patient, ignore warnings and don't stop the script -`./setup.sh` (this script will install python modules, compile the necessary .oct file and apply patches to some files. Check errors but Ignore warnings) +6/ Create your own [Mapbox.com](https://account.mapbox.com/auth/signup/) account, go to account and get/create a default public token then edit file named [getmap.py](https://github.com/llinkz/directTDoA/blob/master/getmap.py#L30) and modify `MAP_TOK` variable with your default public token (directTDoA use [Static Images API](https://docs.mapbox.com/api/maps/static-images/) and you'll get 50000 free monthly requests) -`./directTDoA.py` +7/ `./directTDoA.py` +--- ## LICENSE * This python GUI code has been written and released under the "do what the f$ck you want with it" license - +--- ## CHANGE LOG * v1.00-1.50 : first working version, basic, static map, manual host adding, hardcoded coordinates, manual octave code run etc... * v2.00 : current work, update & dynamic maps full of GPS enabled nodes, auto octave code run, easier to use @@ -134,6 +128,8 @@ Install GNU Octave in Terminal : `brew install octave` * v7.01: Bug fix on map update because of a single KiwiSDR node using https (ofc it just happened after the v7.00 release - haha) * v7.02: Small but important fix * v7.10: Bug fix on Start/Stop Listen function + TKinter exception at start fixed + modified patches for wavreader.py & tdoa_plot_map.m + more map POIs + more recording mode choices + legend showing current TDoA algo + files directories shortcut menu + some ultimateTDoA interface improvements +* v7.20: TDoA broken because of early 2024 software mods, a bug was fixed in kiwirecorder.py (credit: Christoph Mayer, Thanks !) - only kiwirecorder_patch.diff has been modified (we will still use an old kiwiclient version) - apparently Listen mode is not working anymore - this version is only for bug correction. +--- ## Thanks * Christoph Mayer @ https://github.com/hcab14/TDoA for the main TDoA code, excellent work and thanks for the public release ! * John Seamons, KiwiSDR developper @ https://github.com/jks-prv diff --git a/directTDoA.py b/directTDoA.py index fab41f2..f9eea8c 100755 --- a/directTDoA.py +++ b/directTDoA.py @@ -47,7 +47,7 @@ from tkinter.simpledialog import askstring, askinteger from tkinter.font import Font -VERSION = "directTDoA v7.10" +VERSION = "directTDoA v7.20" class ReadKnownPointFile(object): diff --git a/getmap.py b/getmap.py index a7e240f..c6236dd 100644 --- a/getmap.py +++ b/getmap.py @@ -27,7 +27,7 @@ # navigation-preview-day-v4 / navigation-preview-night-v4 # navigation-guidance-day-v4 / navigation-guidance-night-v4 -MAP_TOK = "pk.eyJ1IjoibGxpbmt6IiwiYSI6ImNrM3JzMzE4ZTBlY3gzZXM1MnR5ODZrcnAifQ.fdqW8wmA7qhPYzFsGufZXg" +MAP_TOK = "Your_Mapbox_token_here" DATA_L = [] MAPBOX_ZOOM = {'2': [0, 0], '4': [900, 0], '6': [0, 600], '8': [900, 600]} NB_OF_NODES = len(glob.glob1(sys.argv[6].rsplit(os.sep, 1)[0], "*.wav")) diff --git a/kiwirecorder_patch.diff b/kiwirecorder_patch.diff index 3416155..2c3a8f3 100644 --- a/kiwirecorder_patch.diff +++ b/kiwirecorder_patch.diff @@ -1,17 +1,31 @@ ---- kiwirecorder.py 2020-04-19 22:07:10.613484893 +0000 -+++ kiwirecorder.py 2020-04-19 22:05:07.786030210 +0000 +--- kiwirecorder.py 2024-01-14 09:48:45.338711534 +0100 ++++ kiwirecorder.py 2024-01-14 09:36:05.647684241 +0100 @@ -10,6 +10,10 @@ from kiwi import KiwiSDRStream, KiwiWorker from optparse import OptionParser from optparse import OptionGroup +import sounddevice + -+stream = sounddevice.OutputStream(12000, 2048, channels=1, dtype='int16') ++stream = sounddevice.OutputStream(48000, 2048, channels=1, dtype='int16') +stream.start() HAS_RESAMPLER = True try: -@@ -151,8 +155,10 @@ +@@ -21,11 +25,12 @@ + + + def _write_wav_header(fp, filesize, samplerate, num_channels, is_kiwi_wav): ++ samplerate = int(samplerate+0.5); + fp.write(struct.pack('<4sI4s', b'RIFF', filesize - 8, b'WAVE')) + bits_per_sample = 16 + byte_rate = samplerate * num_channels * bits_per_sample // 8 + block_align = num_channels * bits_per_sample // 8 +- fp.write(struct.pack('<4sIHHIIHH', b'fmt ', 16, 1, num_channels, int(samplerate+0.5), byte_rate, block_align, bits_per_sample)) ++ fp.write(struct.pack('<4sIHHIIHH', b'fmt ', 16, 1, num_channels, samplerate, byte_rate, block_align, bits_per_sample)) + if not is_kiwi_wav: + fp.write(struct.pack('<4sI', b'data', filesize - 12 - 8 - 16 - 8)) + +@@ -151,8 +156,10 @@ # For AM, ignore the low pass filter cutoff lp_cut = -hp_cut if hp_cut is not None else hp_cut self.set_mod(mod, lp_cut, hp_cut, self._freq) @@ -24,8 +38,12 @@ else: self.set_agc(on=True) if self._options.compression is False: -@@ -270,31 +276,34 @@ - _write_wav_header(fp, filesize, int(self._output_sample_rate), self._num_channels, self._options.is_kiwi_wav) +@@ -267,34 +274,37 @@ + + # fp.tell() sometimes returns zero. _write_wav_header writes filesize - 8 + if filesize >= 8: +- _write_wav_header(fp, filesize, int(self._output_sample_rate), self._num_channels, self._options.is_kiwi_wav) ++ _write_wav_header(fp, filesize, self._output_sample_rate, self._num_channels, self._options.is_kiwi_wav) def _write_samples(self, samples, *args): - """Output to a file on the disk.""" @@ -65,7 +83,7 @@ + self._start_time = time.time() + # Write a static WAV header + with open(self._get_output_filename(), 'wb') as fp: -+ _write_wav_header(fp, 100, int(self._output_sample_rate), self._num_channels, self._options.is_kiwi_wav) ++ _write_wav_header(fp, 100, self._output_sample_rate, self._num_channels, self._options.is_kiwi_wav) + if self._options.is_kiwi_tdoa: + # NB: MUST be a print (i.e. not a logging.info) + print("file=%d %s" % (self._options.idx, self._get_output_filename())) @@ -84,7 +102,7 @@ def _on_gnss_position(self, pos): pos_record = False -@@ -371,9 +380,9 @@ +@@ -371,9 +381,9 @@ opt_single.server_host = s opt_single.status = 0 @@ -96,7 +114,7 @@ opt_single.__dict__[x] = _sel_entry(i, opt_single.__dict__[x]) l.append(opt_single) multiple_connections = i -@@ -567,6 +576,11 @@ +@@ -567,6 +577,11 @@ default=False, action='store_true', help='Also process sound data when in waterfall or S-meter mode (sound connection options above apply)') @@ -108,7 +126,7 @@ parser.add_option_group(group) group = OptionGroup(parser, "S-meter mode options", "") -@@ -635,7 +649,7 @@ +@@ -635,7 +650,7 @@ if opt.launch_delay != 0 and i != 0 and options[i-1].server_host == options[i].server_host: time.sleep(opt.launch_delay) r.start() @@ -117,7 +135,7 @@ logging.info("started sound recorder %d" % i) for i,r in enumerate(wf_recorders): -@@ -664,6 +678,7 @@ +@@ -664,6 +679,7 @@ logging.debug('gc %s' % gc.garbage)