1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-06-24 13:05:21 -04:00

Compare commits

...

222 Commits

Author SHA1 Message Date
Edouard Griffiths
7c738b161c
Merge pull request #2475 from srcejon/fix_2435
Radio Astronomy: Add option to auto save data to .csv.
2025-06-24 16:38:46 +02:00
Jon Beniston
4afde2a399 Radio Astronomy: Add option to auto save data to .csv. For #2435 2025-06-24 12:32:42 +01:00
Edouard Griffiths
7f5f59e510
Merge pull request #2474 from srcejon/freq_scanner
FreqScanner: Fix crash if row is selected when remove is pressed.
2025-06-24 08:10:07 +02:00
Edouard Griffiths
61608067f4
Merge pull request #2473 from srcejon/fix_2470
RemoteTCP: Add support for SDR_RX_SAMPLE_24BIT=OFF
2025-06-24 00:53:30 +02:00
srcejon
deac6017e3 FreqScanner: Fix crash if row is selected when remove is pressed. For #2391 2025-06-23 22:52:32 +01:00
Jon Beniston
d67798da56 RemoteTCP: Add support for SDR_RX_SAMPLE_24BIT=OFF 2025-06-23 22:36:09 +01:00
Edouard Griffiths
ca5898bc57
Merge pull request #2472 from srcejon/fix_2470
Fix --remote-tcp.
2025-06-23 18:18:05 +02:00
Edouard Griffiths
694c3a334d
Merge pull request #2467 from srcejon/android_fixes
A few small fixes
2025-06-23 18:17:50 +02:00
Jon Beniston
99fca7c09e Fix --remote-tcp. For #2470 2025-06-20 15:43:01 +01:00
Jon Beniston
d2470a5379 Remove obsolete GOES TLE. Remove NOAA18 as no longer active. For #2372 2025-06-17 12:20:29 +01:00
Jon Beniston
638898d3a4 Fix crash if route database not downloaded 2025-06-17 11:53:56 +01:00
Jon Beniston
e16772c154 Hide 3D only buttons if no 3D map 2025-06-17 11:53:36 +01:00
Jon Beniston
914a3af96f Fix Android compilation 2025-06-17 11:53:00 +01:00
Edouard Griffiths
e5fc6fbd81
Merge pull request #2465 from srcejon/freq_scanner
Map and ADS-B updates
2025-06-13 14:38:33 +02:00
srcejon
83bff3e847 FramelessWindowResizer: Enable child tracking for QWebEngineView. 2025-06-12 15:11:33 +01:00
srcejon
b340b92a04 Fix 2D map tracks. 2025-06-12 09:46:00 +01:00
srcejon
89a25c8a7f Fix QML warning 2025-06-12 09:21:33 +01:00
srcejon
0e93251349 Fix update of current position after filtering. 2025-06-11 10:37:45 +01:00
srcejon
65e6f89214 Restore position of 2D map after changing settings. #2458 2025-06-10 18:03:57 +01:00
srcejon
e287ac60d5 Remove debug 2025-06-10 18:03:00 +01:00
srcejon
5985a0d2e0 Fix gcc warning. 2025-06-10 15:52:30 +01:00
srcejon
9864650d9a Fix parameter injection warning. #2203 2025-06-10 15:52:09 +01:00
srcejon
0a3a455937 Fix reg exp for lat,long string. 2025-06-10 15:31:36 +01:00
srcejon
e564ac2f39 Update Kiki public URL. Add proxy support. 2025-06-10 15:30:52 +01:00
srcejon
7948561cdc Update docs. 2025-06-10 14:37:14 +01:00
srcejon
43e1e9c095 Update map docmentation. 2025-06-10 13:13:41 +01:00
srcejon
811f320536 Fix typos. 2025-06-10 11:46:58 +01:00
srcejon
290ba12c93
Merge branch 'f4exb:master' into freq_scanner 2025-06-10 11:37:54 +01:00
srcejon
6dba1f6813 Update ADS-B documentation. 2025-06-10 11:30:48 +01:00
Edouard Griffiths
05f88acf02
Merge pull request #2461 from srcejon/fix_2456
Add 384000 and maximum supported audio sample rates for Qt 6
2025-06-10 11:23:41 +02:00
srcejon
3e0375f6d5 Update docs 2025-06-09 20:07:35 +01:00
srcejon
d441dad344 Add debug 2025-06-09 20:07:22 +01:00
srcejon
55de2c724f Wait until connected before sending initial CZML 2025-06-09 20:06:58 +01:00
srcejon
cca47bbb50 Use Ellipsoid as default terrain, to minimize quota usage. 2025-06-09 16:12:13 +01:00
srcejon
8a3a246888 Add maptiler API key setting for satellite maps. Rotate default key.
Use OSM map tiles, as wikimedia tiles are no longer available.
Fix gcc warnings.
2025-06-09 15:36:01 +01:00
srcejon
b7619e1c57 Add missing return values. 2025-06-09 12:46:01 +01:00
Jon Beniston
9b714aed45 Add 384000 and maximum supported sample rates for Qt 6 AudioDeviceInfo. For #2456. 2025-06-09 11:29:16 +01:00
srcejon
c791067ea8 Fix gcc error. 2025-06-09 11:12:46 +01:00
srcejon
bc235856a8 Add Whittaker Eilers smoothing. 2025-06-09 11:01:25 +01:00
srcejon
ff3b3f4ef5 Map: Add PFD, first person view and path smoothing. Only send changes via CZML. 2025-06-09 10:44:17 +01:00
srcejon
29f7d534e5 Support wasm files in web server. 2025-06-09 10:38:53 +01:00
srcejon
395e9e0821 Use settings keys 2025-06-09 10:36:46 +01:00
srcejon
1e5257b851 Update Cesium resources 2025-06-09 10:34:57 +01:00
srcejon
d26aa35969 Map: Add support for latest Cesium graphics settings: MSAA, Terrain Lighting, Water effects, Fog and HDR, display FPS.
Add setting to select default imagery. Use Sentinel 2 as default to avoid hitting Bing Maps quota.
Add directional light strength setting.
Add ArcGIS API Key setting.
2025-06-09 10:34:41 +01:00
srcejon
24b1807a07 Map: Rotate default API keys. 2025-06-09 10:25:50 +01:00
srcejon
6c9dd36f8b Map: Add Aurora prediction and Maidenhead grid 2025-06-09 10:23:12 +01:00
srcejon
1aeac6e268 Map: Add World Magnetic Model data and show magnetic declination on map. 2025-06-09 10:18:05 +01:00
srcejon
d834c363b3 Add Cesium workaround for #1640 2025-06-09 10:14:12 +01:00
srcejon
d988aab950 Use Mode S roll data rather than estimated for map. 2025-06-09 10:13:15 +01:00
srcejon
c50097e420 Fix for Qt 5 2025-06-05 13:54:12 +01:00
srcejon
1baca797f6 Use aircraftPath 2025-06-05 13:53:34 +01:00
srcejon
6a9bba0656 Add CORS proxy for Emscripten. 2025-06-04 20:24:58 +01:00
srcejon
aa28bc700d Fix init order. 2025-06-04 20:22:43 +01:00
srcejon
96cc7a550f Remove unused variables. 2025-06-04 20:22:32 +01:00
srcejon
4678abf091 Use combined aircraft database.
Use png rather than bmp.
Add sideview images.
2025-06-04 20:22:09 +01:00
srcejon
276083d3e8 Fix for Qt5. 2025-06-04 19:28:47 +01:00
srcejon
13ecf0124e Add checklist widget 2025-06-04 18:23:53 +01:00
srcejon
db9ccd9ca8 Azel: Mark methods as const. 2025-06-04 18:15:59 +01:00
srcejon
1304926162 Add colour tracks to map. 2025-06-04 18:11:52 +01:00
srcejon
2aa2ad27da Add addtional map aircraft icons. 2025-06-04 18:11:20 +01:00
srcejon
1975c1748c Add additional demod stats.
Add analysis of Mode S frames in order to help filter out false positives.
Remove Boost. Use Profiler instead.
Fix crash if interrrupted before run.
Decode full preamble for Mode S frames.
Add support for additional Mode S downlink formats.
Allow demod stats to be reset.
Add timestamps for buffers, to ensure ordering of frames.
Add additional data columns (Aircraft Type, Sideview, Track,  Interrogator Code, TCAS, ACAS, RA, Max speed, Version, Length, Width, ADS-B/Mode S frame counts, radius, NACp, NACv, GVA, NIC, SIL, Stops).
Add PCE (Preamble Chip Errors) settings for Mode S demod.
Remove correlate full preamable setting.
Send aircraft state to Map feature for display on PFD.
Add support for airline route database.
Use combined aircraft database from sdrangel.org rather than OSN database.
Add stats table, with demod stats and breakdown of frame types received..
Add button to delete all aircraft from table.
Add display of interrogator code coverage.
Remove airport elevation setting as now calculated dynamically.
Add QNH setting.
Add coverage map.
Add chart of frame rate and aircraft count.
Add table/map orientation setting.
Add display of aircraft position uncertainty.
Add coloured flight paths with several palettes.
Add setting to favour airline livery over aircraft type in 3D model matching.
Only use 4 engine map icon for aircraft with 4 engines.
Add specialised aircraft map icons (Eurofighter, Spitfire, F35, A400M, Apache, Chinook, Glider)
Display aircraft route in labels.
Better validate local/global aircraft positions.
Add support for tc==31, aircraft operational status frames.
Add decoding of Mode S df 0, 11, 16 frames.
Add decoding of BDS 0,5 0,8, 0,9.
2025-06-04 18:05:10 +01:00
srcejon
f882747e97 Remove boost dependency and add charts and sideviews. 2025-06-04 17:01:41 +01:00
srcejon
f1aab5c97e Add additional ADS-B toolbar icons 2025-06-04 17:00:46 +01:00
srcejon
d453e164fa Add additional ADS-B map aircraft icons to better reflect aircraft categories. 2025-06-04 17:00:04 +01:00
srcejon
3b22d436ee Update flags 2025-06-04 16:59:06 +01:00
srcejon
4c1f99a7d2 Add aircraft sideviews. 2025-06-04 16:58:22 +01:00
srcejon
cd38c0d6a3 Convert airline logos from BMP to PNG to reduce size. 2025-06-04 16:56:58 +01:00
srcejon
91b83cff3b
Merge branch 'f4exb:master' into freq_scanner 2025-06-03 16:16:38 +01:00
f4exb
c333fb505c SSB Demod: clamp audio to 16 bit samples boundaries for better audio overdrive robustness. Fixes #2452 2025-06-02 22:01:21 +02:00
srcejon
b897b2176d Merge master 2025-06-02 12:10:21 +01:00
Edouard Griffiths
f7b9727ef9
Merge pull request #2450 from f4exb/fix-swagger
Fix swagger
2025-05-29 18:50:53 +02:00
f4exb
76b4623375 Upgrade Swagger UI to 5.22.0 and added WDSPRx.yaml to resources 2025-05-29 15:10:16 +02:00
f4exb
28077752a9 Swagger schema fixes 2025-05-29 12:48:11 +02:00
f4exb
3d3195489a Added Swagger schema validation container in the compose stack 2025-05-29 12:47:57 +02:00
f4exb
89d7fe736f Updated versions and changelogs 2025-05-04 20:01:51 +02:00
f4exb
2f47258605 Added Python script to control PlutoDVB2 2025-05-04 19:57:24 +02:00
f4exb
de4147b853 DATV demod: pass symbol rate in report 2025-05-04 01:44:51 +02:00
f4exb
002f5e8af3 Demod DATV: improve UDP TS output detection 2025-05-03 17:16:19 +02:00
f4exb
ce007419e8 DATV demod server plugin 2025-05-03 04:29:19 +02:00
f4exb
fc82606e6e DATV demod: completely remove LDPC external command references 2025-05-03 02:38:48 +02:00
f4exb
ab54ac7a63 DATV demod: prepare for server version 2025-05-03 01:43:35 +02:00
f4exb
379c802d39 Move datvideorender.h outside datvdemodsink.h 2025-05-02 23:57:25 +02:00
Edouard Griffiths
e6eb23d8a0
Merge pull request #2442 from srcejon/fix_2441
Try to fix Windows CI build
2025-04-23 11:43:39 +02:00
Jon Beniston
0111ce247b Try Python 3.12 for CI build as well. 2025-04-23 09:20:55 +01:00
Jon Beniston
c108f5be40 Try using Python 3.12 instead 2025-04-23 09:10:24 +01:00
Jon Beniston
1074bd0105 Try earlier versions to work around #2441 2025-04-23 08:40:40 +01:00
Jon Beniston
a5d1f48580 Try setup-python: true to fix #2441 2025-04-23 08:25:47 +01:00
f4exb
1c8d7bdaf1 AudioCATSISO: accept ttyS* serial ports for CAT. Fixes #2420 2025-04-21 14:34:53 +02:00
f4exb
77b2b815b8 Replace sprintf by snprintf wherever possible 2025-04-21 14:34:53 +02:00
Edouard Griffiths
2e1411311b
Merge pull request #2439 from srcejon/fix_qt_6_9
Fix build with Qt 6.9.0.
2025-04-21 14:34:01 +02:00
Edouard Griffiths
c8fed979d4
Merge pull request #2438 from mattsoftware/gs232_fixes
Also accept +0179+0001 as an acceptable gs232 format for reporting po…
2025-04-21 13:28:57 +02:00
Jon Beniston
60869b74f9 Fix build with Qt 6.9.0. 2025-04-21 10:59:54 +01:00
Matt Paine
88b2f29894 Comment out the debug statements 2025-04-21 19:22:21 +10:00
Matt Paine
fa6a801411 Also accept +0179+0001 as an acceptable gs232 format for reporting position 2025-04-21 10:59:09 +10:00
Edouard Griffiths
1c6b167527
Merge pull request #2433 from srcejon/fix_sat_tracker_doppler_crash
Fix sat tracker doppler crash
2025-04-17 17:38:28 +02:00
Jon Beniston
bafcb75313 Fix doppler correction. 2025-04-16 14:43:47 +01:00
Jon Beniston
e33d6e9b64 Satellite Tracker: Fix crash when doppler enabled. 2025-04-16 11:23:38 +01:00
Edouard Griffiths
7e6342624c
Merge pull request #2432 from srcejon/fix_2428
ChannelWebAPIUtils: Add double version of patchDeviceSetting.
2025-04-14 16:56:53 +02:00
Jon Beniston
90ddb54371 ChannelWebAPIUtils: Add double version of patchDeviceSetting. Fix #2428 2025-04-14 09:13:44 +01:00
f4exb
356e5e42be Use -DCMAKE_POLICY_VERSION_MINIMUM=3.5 for external packages Windows build 2025-04-05 21:59:21 +02:00
f4exb
c7e2a78903 Use SerialDV 1.1.5 2025-04-05 09:39:09 +02:00
Edouard Griffiths
8ff41d60fd
Merge pull request #2425 from lukolszewski/feature/adding-split-button
Split button added, swagger changed manually, but should be the same …
2025-04-05 01:03:37 +02:00
Łukasz Olszewski
5f74620406 Split button added, swagger changed manually, but should be the same when regenerated 2025-03-27 01:20:53 +01:00
srcejon
7a97bbfea0
Merge branch 'f4exb:master' into freq_scanner 2025-03-10 09:33:04 +00:00
Edouard Griffiths
81bae39a22
Merge pull request #2417 from srcejon/fix_2002
Update HackRF to v2024.02.1.
2025-03-09 11:41:36 +01:00
Jon Beniston
596544ade7 Update HackRF to v2024.02.1. For #2002 2025-03-08 09:33:18 +00:00
Edouard Griffiths
fed8856e1e
Merge pull request #2416 from srcejon/fix_2415
Update LimeSuite to latest version to fix Windows build
2025-03-08 00:51:48 +01:00
Jon Beniston
825c1d0759 Update LimeSuite to latest version, to fix #2415 2025-03-07 16:37:31 +00:00
srcejon
190b8c6aeb
Merge branch 'f4exb:master' into freq_scanner 2025-03-07 16:25:34 +00:00
Edouard Griffiths
0c502c59f8
Merge pull request #2414 from srcejon/fix_2283
Fix HackRF support
2025-03-07 09:33:44 +01:00
Jon Beniston
ad46defda9 Merge branch 'fix_2283' of https://github.com/srcejon/sdrangel into fix_2283 2025-03-06 17:12:01 +00:00
Jon Beniston
42a674037f HackRfInput: Call applySettings before starting thread, otherwise HackRF will not start correctly. Handle not all settingsKeys being set, when adjusting centre frequency. 2025-03-06 17:11:35 +00:00
Jon Beniston
3c9931bc59 LoadConfigurationFSM::loadDeviceSets: Wait 250ms to allow devices to initialise, as DeviceGUI::sendSettings has 100ms delay. 2025-03-06 17:09:16 +00:00
srcejon
cb5d921e68 Add altitudeDateTime to MapItem 2025-03-06 13:55:38 +00:00
srcejon
5ae5641f99
Merge branch 'f4exb:master' into freq_scanner 2025-03-06 13:46:24 +00:00
Edouard Griffiths
b3f83c33fa
Merge pull request #2410 from srcejon/fix_2324
wdsp: Remove redundant code that causes stack overflow on Mac.
2025-03-05 07:21:32 +01:00
Jon Beniston
c40da37faf wdsp: Remove redundant code that causes stack overflow on Mac. For #2324. 2025-02-27 13:20:44 +00:00
Edouard Griffiths
ba673bf3a2
Merge pull request #2402 from srcejon/fix_2401
Fix -DBUILD_SHARED_LIBS=ON for FLAC
2025-02-16 21:05:19 +01:00
Jon Beniston
082a07d39b Fix -DBUILD_SHARED_LIBS=ON for FLAC 2025-02-16 18:11:37 +00:00
Edouard Griffiths
d24c552d24
Merge pull request #2397 from srcejon/mac_ci
Mac x64 build for Mac OS 12
2025-02-10 03:29:44 +01:00
Edouard Griffiths
31ab1480d0
Merge pull request #2394 from srcejon/fix_2242
Radiosonde: Fix pressure calculation.
2025-02-09 10:14:27 +01:00
srcejon
08537b5a5a Add callsign to aircraft state 2025-02-04 16:00:04 +00:00
srcejon
4627be2e50 Add labelDateTime to MapItem 2025-02-04 13:51:52 +00:00
Jon Beniston
7f20ca0a6d Fix indent 2025-02-04 12:04:51 +00:00
Jon Beniston
310df0046c Try setting MACOSX_DEPLOYMENT_TARGET to see if it can run on older MacOSes. 2025-02-04 12:03:13 +00:00
srcejon
3c5ce69846
Merge branch 'f4exb:master' into freq_scanner 2025-02-04 11:02:29 +00:00
Jon Beniston
b653117360 Fix lint warnings. 2025-02-03 14:04:43 +00:00
Jon Beniston
a2f8428352 Radiosonde: Fix pressure calculation. #2242 2025-02-03 13:58:46 +00:00
f4exb
e6b3e50fd2 Updated version and changelog 2025-02-02 19:09:22 +01:00
Edouard Griffiths
504684c609
Merge pull request #2389 from srcejon/fix_2364
Update snap to use UHD 4.7.
2025-01-26 09:56:52 +01:00
Jon Beniston
fc64424377 Update snap to use UHD 4.7. 2025-01-25 15:57:43 +00:00
Edouard Griffiths
89e392e91f
Merge pull request #2386 from srcejon/fix_2384
Fix gcc warnings about warning options
2025-01-25 10:21:50 +01:00
srcejon
23279d2f46 Fix gcc warnings about warning options 2025-01-23 22:57:16 +00:00
Edouard Griffiths
d7863b25c6
Merge pull request #2385 from srcejon/mac_ci
Update Mac Github actions
2025-01-23 21:53:11 +01:00
Edouard Griffiths
6ded8f079b
Merge pull request #2383 from srcejon/fix_file_sink_ui
FileSink: Add minimum width constraint so widgets don't move around a…
2025-01-23 20:47:12 +01:00
srcejon
d524bf2057
Merge branch 'f4exb:master' into mac_ci 2025-01-23 14:31:04 +00:00
Jon Beniston
6df8b94637 Try to fix arm build as well. 2025-01-23 11:02:37 +00:00
Edouard Griffiths
19d8a1da0f
Merge pull request #2382 from srcejon/fix_2378
Radiosonde: Add option to display predicted paths.
2025-01-23 10:26:24 +01:00
Jon Beniston
2ea5ef220b Add set +e to allow script to continue on error 2025-01-23 08:53:01 +00:00
Jon Beniston
9ea7ade57f Try continue-on-error: true to allow make to be retried 2025-01-22 21:38:22 +00:00
Jon Beniston
c9c9febe41 Use version 4.1 of x265 as master is broken on Mac. 2025-01-22 21:38:00 +00:00
Jon Beniston
4519e512c6 Retry make package in case hdituil fails 2025-01-22 20:45:22 +00:00
srcejon
2248b42a06
Merge branch 'f4exb:master' into mac_ci 2025-01-22 20:35:49 +00:00
Jon Beniston
7af58538b6 FileSink: Add minimum width constraint so widgets don't move around as dials are changed. 2025-01-21 13:47:47 +00:00
Jon Beniston
9f61152d37 Merge branch 'fix_2378' of https://github.com/srcejon/sdrangel into fix_2378 2025-01-21 13:33:17 +00:00
Jon Beniston
52d59b8609 Radiosonde: Add option to display predicted paths. 2025-01-21 13:33:11 +00:00
Edouard Griffiths
6b30f17361
Merge pull request #2381 from srcejon/fix_2359
Add --start command line option to start all devices and features.
2025-01-21 14:33:07 +01:00
Jon Beniston
2f280ec06a Radiosonde: Fix radio type sent to SondeHub 2025-01-21 10:41:01 +00:00
Edouard Griffiths
3c7fd19f59
Merge pull request #2380 from srcejon/fix_2375
Fix SSB Mod Morse keyer
2025-01-20 22:28:59 +01:00
Edouard Griffiths
e38e2e773f
Merge pull request #2379 from srcejon/fix_2378
Radiosonde: Rate limit position updates to SondeHub.
2025-01-20 21:06:42 +01:00
Jon Beniston
f841eecab9 Add --start option to start all devices and features. For #2359. 2025-01-20 10:54:21 +00:00
Jon Beniston
b2a1dc3569 Fix SSB Mod Morse keyer 2025-01-20 09:25:33 +00:00
Jon Beniston
9c64424cec Display errors from SondeHub as warnings rather than debug. 2025-01-19 13:09:55 +00:00
Jon Beniston
a3692309c0 Radiosonde: Rate limit position updates to SondeHub. Fixes #2378. 2025-01-19 13:09:16 +00:00
Edouard Griffiths
83b36c6aab
Merge pull request #2377 from srcejon/sid_fix_read_csv
SID: Fix crash when loading data from .csv.
2025-01-19 10:43:18 +01:00
Jon Beniston
c62a25f40a Undo auto-format. 2025-01-17 13:33:53 +00:00
Jon Beniston
86ac92e63e SID: Fix crash when loading data from .csv. 2025-01-17 13:31:19 +00:00
Edouard Griffiths
aa65bd5b39
Merge pull request #2371 from das-Iro/colormap-acab
Added "All Colors Are Beautiful" colormap
2025-01-11 00:18:46 +01:00
Arne Jünemann
4203e72e12 Added All Colors Are Beautiful colormap 2025-01-10 15:53:30 +01:00
srcejon
73f345792d Add date and time for interpolatable properties 2025-01-05 20:47:19 +00:00
srcejon
5eeae7c231 Add type and onSurface fields 2025-01-05 10:24:33 +00:00
srcejon
67dec1dd83 Fix spelling 2025-01-03 11:43:18 +00:00
srcejon
4e3545cf0e Add aircraft state to MapItem 2025-01-03 11:30:35 +00:00
Edouard Griffiths
3f7e1193fa
Merge pull request #2369 from tyrylu/right_click_using_keyboard
right-click-enabler: Allow activation of the right click action by keyboard
2025-01-02 18:10:47 +01:00
Lukáš Tyrychtr
c2652d3ee5 right-click-enabler: Allow activation of the right click action by keyboard
This allows for example, selecting the audio output device for visually
impaired.
2024-12-28 18:19:54 +01:00
Edouard Griffiths
51b540cf72
Merge pull request #2365 from srcejon/usrp_gpio
Add GPIO support for USRP devices
2024-12-25 21:02:23 +01:00
Edouard Griffiths
70d090101a
Merge pull request #2363 from srcejon/freq_scanner
ADS-B: Fix OpenSky authentication to enable 4000 API calls per day.
2024-12-25 20:11:19 +01:00
Jon Beniston
d3584f6af2 RemoteTCPSink: Handle client disconnecting immediately. 2024-12-24 13:25:14 +00:00
Jon Beniston
c5efd73f6b Document GPIOs. 2024-12-24 12:56:36 +00:00
Jon Beniston
4510f40729 ChannelWebAPIUtils::patchDeviceSetting: Add support for sinks and MIMO. 2024-12-24 12:49:10 +00:00
Jon Beniston
56bd20d59b USRP: Implement GPIO settings. 2024-12-24 12:48:43 +00:00
srcejon
a4269dcd78 Add GPIO pins to USRP and regen swagger 2024-12-24 10:59:35 +00:00
srcejon
9f661aee30 ADS-B: Fix OpenSky authentication to enable 4000 API calls per day. 2024-12-20 16:34:11 +00:00
Edouard Griffiths
35088962fe
Merge pull request #2362 from srcejon/freq_scanner
Fix Win32 plugin directory for Qt6 build
2024-12-18 15:50:07 +01:00
srcejon
930e4d7e50 Fix Win32 plugin directory for Qt6 build 2024-12-18 09:33:15 +00:00
Edouard Griffiths
f4e2d10055
Merge pull request #2357 from srcejon/fix_2336
Fix audio modulators when channel sample rate is greater than audio sample rate
2024-12-10 21:46:39 +01:00
Jon Beniston
68126592ad Fix naming of Kazakhstan flag 2024-12-10 14:05:19 +00:00
Jon Beniston
5ea872fe30 Add additional DSC coast stations. 2024-12-10 14:04:47 +00:00
Jon Beniston
7dec953ade DSC: Use coast stations of rmessage source as well. 2024-12-10 10:46:12 +00:00
Jon Beniston
1462890a77 Fix modulators when channel sample rate is greater than audio sample rate. 2024-12-10 10:45:48 +00:00
Edouard Griffiths
d696dd66a0
Merge pull request #2355 from srcejon/dsc_coast_station_names
DSC Demod: Add coast station names.
2024-12-09 21:03:04 +01:00
Jon Beniston
107d1ee6c8 Fix lint warnings. 2024-12-09 12:03:34 +00:00
Jon Beniston
4a8adc4a42 DSC: Add coast station names. 2024-12-09 11:58:17 +00:00
Jon Beniston
a9385cb91c macos-14 is arm only 2024-12-05 14:40:08 +00:00
Jon Beniston
ec0ffa005a Try macos-14, as 13 fails due to https://github.com/actions/runner-images/issues/7522 2024-12-05 13:11:08 +00:00
Jon Beniston
405073d198 Install svn needed to build lame 2024-12-05 10:15:18 +00:00
Jon Beniston
88c5554970 Update mac_x64 build to macos-13, as github no longer supports 12. 2024-12-05 09:08:02 +00:00
f4exb
c4e57a1696 Updated versions and changelogs 2024-12-05 02:10:24 +01:00
Edouard Griffiths
99011d8bbc
Merge pull request #2347 from srcejon/win_code_sign
Upload signed releases rather than unsigned releases to Github
2024-12-03 15:11:01 +01:00
Jon Beniston
d86dbbade9 Upload signed releases rather than unsigned releases to Github releases page.
Only sign releases, not all pull requests.
2024-12-02 22:41:18 +00:00
Edouard Griffiths
87a3d9dea7
Merge pull request #2344 from srcejon/win_code_sign
Windows code signing update
2024-12-02 20:11:39 +01:00
Jon Beniston
c0b8620baa Increase timeout to 1 hour 2024-12-02 13:50:24 +00:00
Jon Beniston
4b714dfaa5 Remove unzip step, as it appears we get a .exe 2024-12-02 13:46:56 +00:00
f4exb
ec4d14be3f FT8 Demod: limit upper bandwidth to 5.8 kHz 2024-12-02 13:01:22 +01:00
Edouard Griffiths
1f0a8e3690
Merge pull request #2342 from srcejon/fix_2332
Stop device while loading device set.
2024-11-26 23:09:14 +01:00
Edouard Griffiths
5ba42f1866
Merge pull request #2341 from srcejon/fix_aircraft_db
ADSB: Update URL of OpenSkyNetwork Aircraft database.
2024-11-26 17:57:57 +01:00
Jon Beniston
3c3e5cf3df Stop device while changing channel set. Fixes #2332 2024-11-26 11:52:30 +00:00
Jon Beniston
943a1fb56c ADSB: Update URL of OpenSkyNetwork Aircraft database. 2024-11-26 10:41:48 +00:00
Edouard Griffiths
460ebfbeb2
Merge pull request #2340 from srcejon/fix_2315
Fix crash and audio mod
2024-11-26 09:47:11 +01:00
srcejon
a91fa3b760 Don't stop source if being deleted. For #2315. Send DSPSignalNotification in audio mods for #2336. 2024-11-25 17:16:08 +00:00
Edouard Griffiths
d0cae88ba8
Merge pull request #2338 from srcejon/fix_2337
RadioSonde: Limit precision of floating point numbers sent to SondeHub.
2024-11-19 16:27:50 +01:00
Edouard Griffiths
30a0198862
Merge pull request #2335 from srcejon/win_code_sign
Code Signing: Use relative path. Increase approval timeout to 30 minutes.
2024-11-19 10:11:14 +01:00
Jon Beniston
7b7f9e2c06 Limit precision of floating point numbers sent to SondeHub. 2024-11-18 09:48:50 +00:00
Jon Beniston
a12d664055 Use relative path. Increase timeout to 30 minutes. 2024-11-16 10:48:26 +00:00
Edouard Griffiths
5cc7b3ac33
Merge pull request #2334 from srcejon/fix_2333
ADSB: Include adsbdemodsettings.h
2024-11-16 10:38:53 +01:00
Jon Beniston
4465e1e8b8 ADSB: Include adsbdemodsettings.h 2024-11-15 13:00:39 +00:00
Edouard Griffiths
4da9a34c87
Merge pull request #2331 from srcejon/win_code_sign
Use release signing certificate for Windows installer.
2024-11-14 15:18:19 +01:00
Edouard Griffiths
7bc6210b64
Merge pull request #2330 from srcejon/fix_2315
Fix a few memory leaks and race conditions
2024-11-14 14:31:09 +01:00
Jon Beniston
f8a991e4a3 Use release signing certificate for Windows installer. 2024-11-14 12:40:01 +00:00
srcejon
6dcc342c10 Fix memory leak and race condition relating to DSP*Engines. Part of #2159 2024-11-14 11:42:53 +00:00
srcejon
7c7a7d7c1e FreeDV: Fix memory allocation/free issues. Part of #2315. 2024-11-14 11:40:46 +00:00
Edouard Griffiths
0a94970a70
Merge pull request #2328 from srcejon/freq_scanner
DemodAnalyzer: Ensure sample rate is set in worker.
2024-11-12 23:16:04 +01:00
srcejon
875f16f12a Wav Files: Add support for meta-data. 2024-11-12 20:36:33 +00:00
srcejon
c4733a3645 DemodAnalyzer: Ensure sample rate is set in worker. Fixes #2309. 2024-11-12 20:36:10 +00:00
Edouard Griffiths
585841e787
Merge pull request #2327 from srcejon/fix_2322
SDRplayv3: Patch path to libsdrplay_api.so.3
2024-11-12 21:16:46 +01:00
Edouard Griffiths
bba9d0b421
Merge pull request #2326 from srcejon/fix_1734
ADS-B: Fix memory use after delete.
2024-11-12 20:23:35 +01:00
Jon Beniston
600e338bab SDRplayv3: Mac now appears to link with libsdrplay_api.so.3 rather than libsdrplay_api.so.3.15. 2024-11-12 15:38:34 +00:00
srcejon
f03499a9a3 ADS-B: Fix memory use after delete. For #1734 and part of #2315 2024-11-12 12:39:14 +00:00
f4exb
73533231a5 Fixed Appveyor Docker image build 2024-11-12 11:01:48 +01:00
Edouard Griffiths
d52179dbe2
Merge pull request #2323 from srcejon/win_code_sign
Windows Signing: Fix output-artifact-directory and unzip file.
2024-11-12 10:58:44 +01:00
Jon Beniston
a7c67a8540 Fix output-artifact-directory and unzip file. 2024-11-11 16:53:52 +00:00
f4exb
cb4651af0b Fixed Appveyor Docker image build 2024-11-11 17:15:20 +01:00
13067 changed files with 69707 additions and 7074 deletions

View File

@ -35,7 +35,7 @@ environment:
APPVEYOR_BUILD_WORKER_IMAGE: Linux
APPVEYOR_CONSOLE_DISABLE_PTY: true
# for:
for:
# # - matrix:
# # only:
# # - TARGET: 'vs2019gui'
@ -132,13 +132,13 @@ environment:
# deploy:
# provider: Environment
# name: f4exb
# - matrix:
# only:
# - TARGET: ubuntu2204docker
# before_build:
# - git clone https://github.com/f4exb/sdrangel-docker.git
# - cd sdrangel-docker
# build_script:
# - cd sdrangel
# - ./build_vanilla.sh -T ${APPVEYOR_PULL_REQUEST_HEAD_COMMIT:-${APPVEYOR_REPO_COMMIT}}
# - ./build_server.sh -T ${APPVEYOR_PULL_REQUEST_HEAD_COMMIT:-${APPVEYOR_REPO_COMMIT}}
- matrix:
only:
- TARGET: ubuntu2204docker
before_build:
- git clone https://github.com/f4exb/sdrangel-docker.git
- cd sdrangel-docker
build_script:
- cd sdrangel
- ./build_vanilla.sh -T ${APPVEYOR_PULL_REQUEST_HEAD_COMMIT:-${APPVEYOR_REPO_COMMIT}}
- ./build_server.sh -T ${APPVEYOR_PULL_REQUEST_HEAD_COMMIT:-${APPVEYOR_REPO_COMMIT}}

View File

@ -9,12 +9,18 @@ on:
jobs:
build_mac_x64:
runs-on: macos-12
runs-on: macos-13
env:
MACOSX_DEPLOYMENT_TARGET: 12.0
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Update brew
run: brew update
- name: Install brew packages
run: brew install nasm subversion
- name: Install SDRplay API
run: |
wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.15.0.pkg
@ -40,7 +46,23 @@ jobs:
- name: Build SDRangel on Mac
run: |
cd build
make -j4 package
make -j4
- name: Create dmg
run: |
cd build
RETRIES=5
COUNT=1
set +e
while [ $COUNT -lt $RETRIES ]; do
make package
if [ $? -eq 0 ]; then
RETRIES=0
break
fi
let COUNT=$COUNT+1
done
shell: bash
continue-on-error: true
- name: Get version
id: get_version
run: |
@ -99,7 +121,23 @@ jobs:
- name: Build SDRangel on Mac
run: |
cd build
make -j3 package
make -j3
- name: Create dmg
run: |
cd build
RETRIES=5
COUNT=1
set +e
while [ $COUNT -lt $RETRIES ]; do
make package
if [ $? -eq 0 ]; then
RETRIES=0
break
fi
let COUNT=$COUNT+1
done
shell: bash
continue-on-error: true
- name: Get version
id: get_version
run: |

View File

@ -41,6 +41,9 @@ jobs:
echo github.event_name: ${{ github.event_name }}
echo github.ref: ${{ github.ref }}
echo github.workspace: ${{ github.workspace }}
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install basic dependencies on Windows
if: startsWith(matrix.config.os, 'windows')
run: |
@ -94,11 +97,6 @@ jobs:
with:
name: sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
path: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
- name: Upload release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v0.1.13
with:
files: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
build_mac:
runs-on: macos-14

View File

@ -6,7 +6,6 @@ on:
- master
tags:
- 'v*'
pull_request:
jobs:
build:
@ -38,6 +37,9 @@ jobs:
echo github.event_name: ${{ github.event_name }}
echo github.ref: ${{ github.ref }}
echo github.workspace: ${{ github.workspace }}
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install basic dependencies on Windows
if: startsWith(matrix.config.os, 'windows')
run: |
@ -71,7 +73,7 @@ jobs:
version: '6.7.3'
dir: ${{matrix.config.QT_INST_DIR}}
arch: ${{matrix.config.QT_ARCH}}
setup-python: false
setup-python: 'false'
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
- name: build sdrangel on Windows
if: startsWith(matrix.config.os, 'windows')
@ -99,13 +101,19 @@ jobs:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '553b8f53-adf0-4fe5-be3d-283504a21a51'
project-slug: 'sdrangel'
signing-policy-slug: 'test-signing'
signing-policy-slug: 'release-signing'
github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: '${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64-signed.exe'
output-artifact-directory: 'build\signed'
wait-for-completion-timeout-in-seconds: 3600
- name: Upload signed artifact
id: upload-signed-artifact
uses: actions/upload-artifact@v4
with:
name: sdrangel-${{ steps.get_version.outputs.version }}-win64-signed.exe
path: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64-signed.exe
path: ${{ github.workspace }}/build/signed/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
- name: Upload release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: ${{ github.workspace }}/build/signed/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe

View File

@ -1,3 +1,39 @@
sdrangel (7.22.7-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 04 May 2025 17:58:14 +0200
sdrangel (7.22.6-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 02 Feb 2025 18:08:11 +0100
sdrangel (7.22.5-1) unstable; urgency=medium
* Windows: upload signed releases rather than unsigned releases to Github releases page. PR #2347
* Windows: fixed signed releases. PR #2344
* FT8 Demod: limit upper bandwidth to 5.8 kHz. Fixes #2339
* Stop device while changing channel set. Fixes #2332. PR #2342
* ADSB: Update URL of OpenSkyNetwork Aircraft database. PR #2341
* Don't stop source if being deleted. For #2315. PR #2340
* Send DSPSignalNotification in audio mods for #2336. PR #2340
* Radiosonde: limit precision of floating point numbers sent to SondeHub. PR #2338
* Windows signed releases: use relative path. Increase timeout to 30 minutes. PR #2335
* ADSB: Include adsbdemodsettings.h PR #2334
* Use release signing certificate for Windows installer. PR #2331
* Fix memory leak and race condition relating to DSP*Engines. Part of #2159 PR #2330
* FreeDV: Fix memory allocation/free issues. Part of #2315. PR #2330
* Wav Files: Add support for meta-data. PR #2328
* DemodAnalyzer: Ensure sample rate is set in worker. Fixes #2309. PR #2328
^ SDRplayv3: Mac: link with libsdrplay_api.so.3 rather than libsdrplay_api.so.3.15. PR #2327
* ADS-B: Fix memory use after delete. For #1734 and part of #2315 PR #2326
* Fixed Appveyor Docker image build
* Fix output-artifact-directory and unzip file. PR #2323
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Thu, 05 Dec 2024 01:07:27 +0100
sdrangel (7.22.4-1) unstable; urgency=medium
* Use macos-12 for Mac x86 build. PR #2321

View File

@ -20,7 +20,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# configure version
set(sdrangel_VERSION_MAJOR "7")
set(sdrangel_VERSION_MINOR "22")
set(sdrangel_VERSION_PATCH "4")
set(sdrangel_VERSION_PATCH "7")
set(sdrangel_VERSION_SUFFIX "")
# SDRAngel cmake options

View File

@ -188,7 +188,9 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
logger = nullptr;
}
MainWindow w(logger, parser);
MainWindow w(logger, parser);
w.show();
if (parser.getListDevices())
{
@ -197,12 +199,6 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
return EXIT_SUCCESS;
}
if (parser.getRemoteTCPSink()) {
RemoteTCPSinkStarter::start(parser);
}
w.show();
return a.exec();
}

View File

@ -19,7 +19,11 @@ if(WIN32)
endif()
if(NOT MSVC)
add_compile_options(-Wall -Wextra -Wvla -Woverloaded-virtual -Wno-inconsistent-missing-override -ffast-math -fno-finite-math-only -ftree-vectorize)
add_compile_options(-Wall -Wextra -Wvla -ffast-math -fno-finite-math-only -ftree-vectorize)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Woverloaded-virtual>)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Wno-inconsistent-missing-override)
endif()
else()
# Disable some warnings, so more useful warnings aren't hidden in the noise
# 4996 'fopen': This function or variable may be unsafe. Consider using fopen_s instead.

36
debian/changelog vendored
View File

@ -1,3 +1,39 @@
sdrangel (7.22.7-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 04 May 2025 17:58:14 +0200
sdrangel (7.22.6-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 02 Feb 2025 18:08:11 +0100
sdrangel (7.22.5-1) unstable; urgency=medium
* Windows: upload signed releases rather than unsigned releases to Github releases page. PR #2347
* Windows: fixed signed releases. PR #2344
* FT8 Demod: limit upper bandwidth to 5.8 kHz. Fixes #2339
* Stop device while changing channel set. Fixes #2332. PR #2342
* ADSB: Update URL of OpenSkyNetwork Aircraft database. PR #2341
* Don't stop source if being deleted. For #2315. PR #2340
* Send DSPSignalNotification in audio mods for #2336. PR #2340
* Radiosonde: limit precision of floating point numbers sent to SondeHub. PR #2338
* Windows signed releases: use relative path. Increase timeout to 30 minutes. PR #2335
* ADSB: Include adsbdemodsettings.h PR #2334
* Use release signing certificate for Windows installer. PR #2331
* Fix memory leak and race condition relating to DSP*Engines. Part of #2159 PR #2330
* FreeDV: Fix memory allocation/free issues. Part of #2315. PR #2330
* Wav Files: Add support for meta-data. PR #2328
* DemodAnalyzer: Ensure sample rate is set in worker. Fixes #2309. PR #2328
^ SDRplayv3: Mac: link with libsdrplay_api.so.3 rather than libsdrplay_api.so.3.15. PR #2327
* ADS-B: Fix memory use after delete. For #1734 and part of #2315 PR #2326
* Fixed Appveyor Docker image build
* Fix output-artifact-directory and unzip file. PR #2323
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Thu, 05 Dec 2024 01:07:27 +0100
sdrangel (7.22.4-1) unstable; urgency=medium
* Use macos-12 for Mac x86 build. PR #2321

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 KiB

After

Width:  |  Height:  |  Size: 844 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 KiB

After

Width:  |  Height:  |  Size: 819 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 KiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

BIN
doc/img/Map_plugin_pfd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

View File

@ -11,9 +11,9 @@
set(CODEC2_TAG "v1.0.3")
set(CM256CC_TAG c0e92b92aca3d1d36c990b642b937c64d363c559)
set(MBELIB_TAG fe83b32c6a60cdd7bce8cecf3c7a0b9ec87a7667)
set(SERIALDV_TAG "v1.1.4")
set(SERIALDV_TAG "v1.1.5")
set(DSDCC_TAG "v1.9.5")
set(LIMESUITE_TAG "v23.11.0")
set(LIMESUITE_TAG b39cb61ed03d74c35a2de757d495e901acbb6404)
set(BLADERF_TAG "2021.02")
set(LIBIIO_TAG 826563e41b5ce9890b75506f672017de8d76d52d)
set(AIRSPYHF_TAG "1af81c0ca18944b8c9897c3c98dc0a991815b686")
@ -29,7 +29,7 @@ set(SOAPYSDR_SDRPLAY_TAG "soapy-sdrplay-0.2.0")
set(SOAPYSDR_AUDIO_TAG "soapy-audio-0.1.1")
set(SOAPYSDR_REMOTE_TAG "soapy-remote-0.5.1")
set(AIRSPY_TAG "37c768ce9997b32e7328eb48972a7fda0a1f8554")
set(HACKRF_TAG "v2022.09.1")
set(HACKRF_TAG "v2024.02.1")
set(LIBXML2_TAG "v2.10.4")
set(UHD_TAG "v4.7.0.0")
set(BOOST_TAG "1.86.0")
@ -54,6 +54,7 @@ if (WIN32)
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG=${SDRANGEL_BINARY_LIB_DIR}
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=${SDRANGEL_BINARY_LIB_DIR}
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO=${SDRANGEL_BINARY_LIB_DIR}
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
)
elseif (LINUX)
set(COMMON_CMAKE_ARGS
@ -420,6 +421,7 @@ if (NOT FFMPEG_FOUND AND NOT USE_PRECOMPILED_LIBS)
if (NOT X265_FOUND OR X265_EXTERNAL)
ExternalProject_Add(x265
GIT_REPOSITORY https://bitbucket.org/multicoreware/x265_git.git
GIT_TAG 4.1
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/x265"
SOURCE_SUBDIR "source"
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
@ -858,7 +860,7 @@ if(ENABLE_CHANNELRX_REMOTETCPSINK)
ExternalProject_Add(flac
GIT_REPOSITORY https://github.com/xiph/flac.git
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/flac"
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DINSTALL_MANPAGES=OFF -D=BUILD_SHARED_LIBS=ON -DWITH_FORTIFY_SOURCE=OFF -DWITH_STACK_PROTECTOR=PFF -DBUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DWITH_OGG=OFF -DBUILD_DOCS=OFF
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DINSTALL_MANPAGES=OFF -DBUILD_SHARED_LIBS=ON -DWITH_FORTIFY_SOURCE=OFF -DWITH_STACK_PROTECTOR=PFF -DBUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DWITH_OGG=OFF -DBUILD_DOCS=OFF
BUILD_BYPRODUCTS "${FLAC_LIBRARIES}"
INSTALL_COMMAND ""
TEST_COMMAND ""

View File

@ -82,7 +82,7 @@ std::string Packing::unpackcall(int x)
if (x <= 1002)
{
sprintf(tmp, "CQ %d", x - 3);
snprintf(tmp, sizeof(tmp), "CQ %d", x - 3);
return std::string(tmp);
}
@ -96,7 +96,7 @@ std::string Packing::unpackcall(int x)
int ci3 = x / 27;
x %= 27;
int ci4 = x;
sprintf(tmp, "CQ %c%c%c%c", c4[ci1], c4[ci2], c4[ci3], c4[ci4]);
snprintf(tmp, sizeof(tmp), "CQ %c%c%c%c", c4[ci1], c4[ci2], c4[ci3], c4[ci4]);
return std::string(tmp);
}
@ -193,9 +193,9 @@ std::string Packing::unpackgrid15(int ng, int ir)
char tmp[16];
if (db >= 0) {
sprintf(tmp, "%s+%02d", ir ? "R" : "", db);
snprintf(tmp, sizeof(tmp), "%s+%02d", ir ? "R" : "", db);
} else {
sprintf(tmp, "%s-%02d", ir ? "R" : "", 0 - db);
snprintf(tmp, sizeof(tmp), "%s-%02d", ir ? "R" : "", 0 - db);
}
return std::string(tmp);
@ -396,7 +396,7 @@ std::string Packing::unpack_5(int a77[], std::string& call1str, std::string& cal
i += 3;
int qsonb = un64(a77, i, 11);
char report[16];
sprintf(report, "%d%04d", rst, qsonb);
snprintf(report, sizeof(report), "%d%04d", rst, qsonb);
i += 11;
// g25
int ng = un64(a77, i, 25);
@ -467,9 +467,9 @@ std::string Packing::unpack_0_1(int a77[], std::string& call1str, std::string& c
char tmp[32];
if (r >= 0) {
sprintf(tmp, "+%02d", r);
snprintf(tmp, sizeof(tmp), "+%02d", r);
} else {
sprintf(tmp, "-%02d", -r);
snprintf(tmp, sizeof(tmp), "-%02d", -r);
}
locstr = std::string(tmp);
@ -553,7 +553,7 @@ std::string Packing::unpack_3(int a77[], std::string& call1str, std::string& cal
else
{
char tmp[32];
sprintf(tmp, "%04d", serial);
snprintf(tmp, sizeof(tmp), "%04d", serial);
serialstr = std::string(tmp);
}
@ -571,7 +571,7 @@ std::string Packing::unpack_3(int a77[], std::string& call1str, std::string& cal
}
{
char tmp[16];
sprintf(tmp, "%d ", rst);
snprintf(tmp, sizeof(tmp), "%d ", rst);
msg += std::string(tmp);
}
@ -634,7 +634,7 @@ std::string Packing::unpack_0_3(int a77[], int n3, std::string& call1str, std::s
{
char tmp[16];
sprintf(tmp, "%d%c ", n_transmitters + 1, clss + 'A');
snprintf(tmp, sizeof(tmp), "%d%c ", n_transmitters + 1, clss + 'A');
msg += std::string(tmp);
}
@ -658,9 +658,9 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
char tmp[64];
if (i3 == 0) {
sprintf(tmp, "%d.%d", i3, n3);
snprintf(tmp, sizeof(tmp), "%d.%d", i3, n3);
} else {
sprintf(tmp, "%d", i3);
snprintf(tmp, sizeof(tmp), "%d", i3);
}
type = std::string(tmp);
@ -714,7 +714,7 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
}
call1 = "UNK";
sprintf(tmp, "UNK i3=%d n3=%d", i3, n3);
snprintf(tmp, sizeof(tmp), "UNK i3=%d n3=%d", i3, n3);
return std::string(tmp);
}

View File

@ -4,6 +4,6 @@ PLUGINS=$(git diff --name-only ${1}..${2} | grep plugins/ | cut -d'/' -f2,3 | so
for plugin in $PLUGINS
do
FILE=$(find $BASEDIR/plugins/$plugin -name "*plugin.cpp")
sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.4\"\)/" $FILE
echo $FILE
sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.7\"\)/" $FILE
done

View File

@ -17,10 +17,18 @@ if (NOT SERVER_MODE)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
if(WIN32 AND Qt6_FOUND)
# https://bugreports.qt.io/browse/QTBUG-124589
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_RUNTIME_DIR}")
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
endif()
else()
if(WIN32)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
@ -32,10 +40,17 @@ else()
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
if(WIN32 AND Qt6_FOUND)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
endif()
endif()
if (ENABLE_CHANNELMIMO)

View File

@ -211,6 +211,26 @@ else()
message(STATUS "Not building wdsprx (ENABLE_CHANNELRX_WDSPRX=${ENABLE_CHANNELRX_WDSPRX} WDSP_SUPPORT=${WDSP_SUPPORT})")
endif()
# need ffmpeg 3.1 that correstonds to
# libavutil 55.27.100
# libavcodec 57.48.101
# libavformat 57.40.101
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
if (ENABLE_CHANNELRX_DEMODDATV AND FFMPEG_FOUND)
if(WIN32)
add_subdirectory(demoddatv)
else()
if(((AVUTIL_VERSION VERSION_GREATER "55.27.99") AND (AVCODEC_VERSION VERSION_GREATER "57.48.101")) OR FFMPEG_EXTERNAL OR FFMPEG_SKIP_CHECK)
message(STATUS "Include demoddatv")
add_subdirectory(demoddatv)
else()
message(STATUS "FFmpeg too old to compile demoddatv; needs at least avutil: 55.27.100, avcodec/avformat: 57.48.101")
endif()
endif()
else()
message(STATUS "Not building demoddatv (ENABLE_CHANNELRX_DEMODDATV=${ENABLE_CHANNELRX_DEMODDATV} FFMPEG_FOUND=${FFMPEG_FOUND})")
endif()
if(NOT SERVER_MODE)
if (ENABLE_CHANNELRX_HEATMAP)
@ -230,25 +250,4 @@ if(NOT SERVER_MODE)
else()
message(STATUS "Not building demodatv (ENABLE_CHANNELRX_DEMODATV=${ENABLE_CHANNELRX_DEMODATV})")
endif()
# need ffmpeg 3.1 that correstonds to
# libavutil 55.27.100
# libavcodec 57.48.101
# libavformat 57.40.101
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
if (ENABLE_CHANNELRX_DEMODDATV AND FFMPEG_FOUND)
if(WIN32)
add_subdirectory(demoddatv)
else()
if(((AVUTIL_VERSION VERSION_GREATER "55.27.99") AND (AVCODEC_VERSION VERSION_GREATER "57.48.101")) OR FFMPEG_EXTERNAL OR FFMPEG_SKIP_CHECK)
message(STATUS "Include demoddatv")
add_subdirectory(demoddatv)
else()
message(STATUS "FFmpeg too old to compile demoddatv; needs at least avutil: 55.27.100, avcodec/avformat: 57.48.101")
endif()
endif()
else()
message(STATUS "Not building demoddatv (ENABLE_CHANNELRX_DEMODDATV=${ENABLE_CHANNELRX_DEMODDATV} FFMPEG_FOUND=${FFMPEG_FOUND})")
endif()
endif()

View File

@ -88,7 +88,7 @@ ChannelAnalyzer::~ChannelAnalyzer()
delete m_networkManager;
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, true);
if (m_basebandSink->isRunning()) {
stop();
@ -103,7 +103,7 @@ void ChannelAnalyzer::setDeviceAPI(DeviceAPI *deviceAPI)
if (deviceAPI != m_deviceAPI)
{
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, false);
m_deviceAPI = deviceAPI;
m_deviceAPI->addChannelSink(this);
m_deviceAPI->addChannelSinkAPI(this);

View File

@ -27,7 +27,7 @@
const PluginDescriptor ChannelAnalyzerPlugin::m_pluginDescriptor = {
ChannelAnalyzer::m_channelId,
QStringLiteral("Channel Analyzer"),
QStringLiteral("7.22.1"),
QStringLiteral("7.22.5"),
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,

View File

@ -84,7 +84,7 @@ ChannelPower::~ChannelPower()
);
delete m_networkManager;
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, true);
if (m_basebandSink->isRunning()) {
stop();
@ -98,7 +98,7 @@ void ChannelPower::setDeviceAPI(DeviceAPI *deviceAPI)
if (deviceAPI != m_deviceAPI)
{
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, false);
m_deviceAPI = deviceAPI;
m_deviceAPI->addChannelSink(this);
m_deviceAPI->addChannelSinkAPI(this);

View File

@ -29,7 +29,7 @@
const PluginDescriptor ChannelPowerPlugin::m_pluginDescriptor = {
ChannelPower::m_channelId,
QStringLiteral("Channel Power"),
QStringLiteral("7.22.1"),
QStringLiteral("7.22.5"),
QStringLiteral("(c) Jon Beniston, M7RCE"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,

View File

@ -28,7 +28,6 @@ set(adsb_HEADERS
include_directories(
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${Boost_INCLUDE_DIRS}
)
if(NOT SERVER_MODE)
@ -47,6 +46,7 @@ if(NOT SERVER_MODE)
adsbdemodicons.qrc
airlinelogos.qrc
flags.qrc
sideviews.qrc
)
set(adsb_HEADERS
${adsb_HEADERS}
@ -60,7 +60,7 @@ if(NOT SERVER_MODE)
)
set(TARGET_NAME ${PLUGINS_PREFIX}demodadsb)
set(TARGET_LIB Qt::Widgets Qt::Quick Qt::QuickWidgets Qt::Positioning)
set(TARGET_LIB Qt::Widgets Qt::Quick Qt::QuickWidgets Qt::Positioning Qt::Charts)
if(Qt${QT_DEFAULT_MAJOR_VERSION}Location_FOUND)
list(APPEND TARGET_LIB Qt::Location)
endif()
@ -86,12 +86,7 @@ if(NOT BUILD_SHARED_LIBS)
set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME})
endif()
if (NOT WIN32)
link_directories(${Boost_LIBRARY_DIRS})
endif()
target_link_libraries(${TARGET_NAME} PRIVATE
Boost::disable_autolinking
Qt::Core
${TARGET_LIB}
sdrbase

View File

@ -17,10 +17,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono/chrono.hpp>
#include <stdio.h>
#include <complex.h>
#include <QTime>
@ -49,6 +45,7 @@
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgConfigureADSBDemod, Message)
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgAircraftReport, Message)
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgResetStats, Message)
const char* const ADSBDemod::m_channelIdURI = "sdrangel.channel.adsbdemod";
const char* const ADSBDemod::m_channelId = "ADSBDemod";
@ -104,9 +101,9 @@ ADSBDemod::~ADSBDemod()
);
delete m_networkManager;
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, true);
delete m_basebandSink; // This results in a call to ADSBDemod::stop(), so need to delete before worker and thread
delete m_worker;
delete m_basebandSink;
delete m_thread;
}
@ -115,7 +112,7 @@ void ADSBDemod::setDeviceAPI(DeviceAPI *deviceAPI)
if (deviceAPI != m_deviceAPI)
{
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, false);
m_deviceAPI = deviceAPI;
m_deviceAPI->addChannelSink(this);
m_deviceAPI->addChannelSinkAPI(this);
@ -194,6 +191,13 @@ bool ADSBDemod::handleMessage(const Message& cmd)
m_aircraftReport = msg.getReport();
return true;
}
else if (MsgResetStats::match(cmd))
{
MsgResetStats& msg = (MsgResetStats&) cmd;
MsgResetStats* rep = new MsgResetStats(msg);
m_basebandSink->getInputMessageQueue()->push(rep);
return true;
}
else
{
return false;
@ -337,9 +341,6 @@ void ADSBDemod::webapiUpdateChannelSettings(
if (channelSettingsKeys.contains("samplesPerBit")) {
settings.m_samplesPerBit = response.getAdsbDemodSettings()->getSamplesPerBit();
}
if (channelSettingsKeys.contains("correlateFullPreamble")) {
settings.m_correlateFullPreamble = response.getAdsbDemodSettings()->getCorrelateFullPreamble() != 0;
}
if (channelSettingsKeys.contains("demodModeS")) {
settings.m_demodModeS = response.getAdsbDemodSettings()->getDemodModeS() != 0;
}
@ -458,7 +459,6 @@ void ADSBDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& res
response.getAdsbDemodSettings()->setRfBandwidth(settings.m_rfBandwidth);
response.getAdsbDemodSettings()->setCorrelationThreshold(settings.m_correlationThreshold);
response.getAdsbDemodSettings()->setSamplesPerBit(settings.m_samplesPerBit);
response.getAdsbDemodSettings()->setCorrelateFullPreamble(settings.m_correlateFullPreamble ? 1 : 0);
response.getAdsbDemodSettings()->setDemodModeS(settings.m_demodModeS ? 1 : 0);
response.getAdsbDemodSettings()->setInterpolatorPhaseSteps(settings.m_interpolatorPhaseSteps);
response.getAdsbDemodSettings()->setInterpolatorTapsPerPhase(settings.m_interpolatorTapsPerPhase);
@ -587,9 +587,6 @@ void ADSBDemod::webapiReverseSendSettings(const QList<QString>& channelSettingsK
if (channelSettingsKeys.contains("samplesPerBit") || force) {
swgADSBDemodSettings->setSamplesPerBit(settings.m_samplesPerBit);
}
if (channelSettingsKeys.contains("correlateFullPreamble") || force) {
swgADSBDemodSettings->setCorrelateFullPreamble(settings.m_correlateFullPreamble ? 1 : 0);
}
if (channelSettingsKeys.contains("demodModeS") || force) {
swgADSBDemodSettings->setDemodModeS(settings.m_demodModeS ? 1 : 0);
}

View File

@ -92,6 +92,21 @@ public:
{ }
};
class MsgResetStats : public Message {
MESSAGE_CLASS_DECLARATION
public:
static MsgResetStats* create()
{
return new MsgResetStats();
}
private:
MsgResetStats() :
Message()
{ }
};
ADSBDemod(DeviceAPI *deviceAPI);
virtual ~ADSBDemod();
virtual void destroy() { delete this; }

View File

@ -23,6 +23,7 @@
#include "dsp/downchannelizer.h"
#include "adsbdemodbaseband.h"
#include "adsbdemod.h"
#include "adsb.h"
MESSAGE_CLASS_DEFINITION(ADSBDemodBaseband::MsgConfigureADSBDemodBaseband, Message)
@ -132,6 +133,11 @@ bool ADSBDemodBaseband::handleMessage(const Message& cmd)
return true;
}
else if (ADSBDemod::MsgResetStats::match(cmd))
{
m_sink.resetStats();
return true;
}
else
{
return false;

View File

@ -50,7 +50,6 @@ ADSBDemodDisplayDialog::ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWid
ui->airportSize->setCurrentIndex((int)settings->m_airportMinimumSize);
ui->heliports->setChecked(settings->m_displayHeliports);
ui->units->setCurrentIndex((int)settings->m_siUnits);
ui->displayStats->setChecked(settings->m_displayDemodStats);
ui->autoResizeTableColumns->setChecked(settings->m_autoResizeTableColumns);
ui->aviationstackAPIKey->setText(settings->m_aviationstackAPIKey);
ui->checkWXAPIKey->setText(settings->m_checkWXAPIKey);
@ -67,12 +66,17 @@ ADSBDemodDisplayDialog::ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWid
ui->mapProvider->setCurrentText(settings->m_mapProvider);
}
ui->mapType->setCurrentIndex((int)settings->m_mapType);
ui->maptilerAPIKey->setText(m_settings->m_maptilerAPIKey);
ui->navAids->setChecked(settings->m_displayNavAids);
ui->atcCallsigns->setChecked(settings->m_atcCallsigns);
ui->photos->setChecked(settings->m_displayPhotos);
ui->verboseModelMatching->setChecked(settings->m_verboseModelMatching);
ui->airfieldElevation->setValue(settings->m_airfieldElevation);
ui->favourLivery->setChecked(settings->m_favourLivery);
ui->transitionAltitude->setValue(settings->m_transitionAlt);
for (auto i = ADSBDemodSettings::m_palettes.cbegin(), end = ADSBDemodSettings::m_palettes.cend(); i != end; ++i) {
ui->flightPathPalette->addItem(i.key());
}
ui->flightPathPalette->setCurrentText(settings->m_flightPathPaletteName);
}
ADSBDemodDisplayDialog::~ADSBDemodDisplayDialog()
@ -107,16 +111,11 @@ void ADSBDemodDisplayDialog::accept()
m_settings->m_displayHeliports = ui->heliports->isChecked();
m_settingsKeys.append("displayHeliports");
}
if (m_settings->m_siUnits != ui->units->currentIndex() == 0 ? false : true)
if (m_settings->m_siUnits != (ui->units->currentIndex() == 0 ? false : true))
{
m_settings->m_siUnits = ui->units->currentIndex() == 0 ? false : true;
m_settingsKeys.append("siUnits");
}
if (m_settings->m_displayDemodStats != ui->displayStats->isChecked())
{
m_settings->m_displayDemodStats = ui->displayStats->isChecked();
m_settingsKeys.append("displayDemodStats");
}
if (m_settings->m_autoResizeTableColumns != ui->autoResizeTableColumns->isChecked())
{
m_settings->m_autoResizeTableColumns = ui->autoResizeTableColumns->isChecked();
@ -160,6 +159,11 @@ void ADSBDemodDisplayDialog::accept()
m_settings->m_mapType = (ADSBDemodSettings::MapType)ui->mapType->currentIndex();
m_settingsKeys.append("mapType");
}
if (m_settings->m_maptilerAPIKey != ui->maptilerAPIKey->text())
{
m_settings->m_maptilerAPIKey = ui->maptilerAPIKey->text();
m_settingsKeys.append("maptilerAPIKey");
}
if (m_settings->m_displayNavAids != ui->navAids->isChecked())
{
m_settings->m_displayNavAids = ui->navAids->isChecked();
@ -180,10 +184,10 @@ void ADSBDemodDisplayDialog::accept()
m_settings->m_verboseModelMatching = ui->verboseModelMatching->isChecked();
m_settingsKeys.append("verboseModelMatching");
}
if (m_settings->m_airfieldElevation != ui->airfieldElevation->value())
if (m_settings->m_favourLivery != ui->favourLivery->isChecked())
{
m_settings->m_airfieldElevation = ui->airfieldElevation->value();
m_settingsKeys.append("airfieldElevation");
m_settings->m_favourLivery = ui->favourLivery->isChecked();
m_settingsKeys.append("favourLivery");
}
if (m_settings->m_transitionAlt != ui->transitionAltitude->value())
{
@ -200,6 +204,12 @@ void ADSBDemodDisplayDialog::accept()
m_settings->m_tableFontSize = m_fontSize;
m_settingsKeys.append("tableFontSize");
}
if (m_settings->m_flightPathPaletteName != ui->flightPathPalette->currentText())
{
m_settings->m_flightPathPaletteName = ui->flightPathPalette->currentText();
m_settingsKeys.append("flightPathPaletteName");
m_settings->applyPalette();
}
QDialog::accept();
}

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>417</width>
<height>467</height>
<height>505</height>
</rect>
</property>
<property name="font">
@ -124,22 +124,16 @@
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="displayStatsLabel">
<widget class="QLabel" name="verboseModelMatchingLabel">
<property name="text">
<string>Display demodulator statistics</string>
<string>Log 3D model matching information</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="displayStats">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QCheckBox" name="verboseModelMatching">
<property name="toolTip">
<string>Display demodulator statistics</string>
<string>Log information about how aircraft are matched to 3D models</string>
</property>
<property name="text">
<string/>
@ -147,16 +141,16 @@
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="verboseModelMatchingLabel">
<widget class="QLabel" name="favourLiveryLabel">
<property name="text">
<string>Log 3D model matching information</string>
<string>Favour airline livery over aircraft type</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="verboseModelMatching">
<widget class="QCheckBox" name="favourLivery">
<property name="toolTip">
<string>Log information about how aircraft are matched to 3D models</string>
<string>Favour airline livery over aircraft type for 3D models</string>
</property>
<property name="text">
<string/>
@ -192,36 +186,13 @@
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="airfieldElevationLabel">
<property name="text">
<string>Airfield barometric altitude (ft)</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QSpinBox" name="airfieldElevation">
<property name="toolTip">
<string>Barometric altitude reported by aircraft when on airfield surface</string>
</property>
<property name="minimum">
<number>-10000</number>
</property>
<property name="maximum">
<number>30000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="transitionAltitudeLabel">
<property name="text">
<string>Transition altitude (ft)</string>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="9" column="1">
<widget class="QSpinBox" name="transitionAltitude">
<property name="toolTip">
<string>Transition altitude in feet</string>
@ -232,6 +203,9 @@
<property name="maximum">
<number>20000</number>
</property>
<property name="value">
<number>6000</number>
</property>
</widget>
</item>
</layout>
@ -303,14 +277,14 @@
</item>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="aircraftMinZoomLabel">
<property name="text">
<string>Zoom level for aircraft scaling</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QSpinBox" name="aircraftMinZoom">
<property name="toolTip">
<string>When map zoom (0 min zoom - 15 max zoom) is higher than this value, aircraft icon size will be scaled</string>
@ -320,14 +294,14 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="airportSizeLabel">
<property name="text">
<string>Display airports with size</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="QComboBox" name="airportSize">
<property name="toolTip">
<string>Sets the minimum airport size that will be displayed on the map</string>
@ -349,14 +323,14 @@
</item>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="heliportsLabel">
<property name="text">
<string>Display heliports</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QCheckBox" name="heliports">
<property name="toolTip">
<string>When checked, heliports are displayed on the map</string>
@ -366,14 +340,14 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="airportRangeLabel">
<property name="text">
<string>Airport display distance (km)</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QSpinBox" name="airportRange">
<property name="toolTip">
<string>Displays airports within the specified distance in kilometres from My Position</string>
@ -383,14 +357,14 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="airspacesLabel">
<property name="text">
<string>Airspaces to display</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QListWidget" name="airspaces">
<property name="toolTip">
<string>Airspace categories to display</string>
@ -547,14 +521,14 @@
</item>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="airspaceRangeLabel">
<property name="text">
<string>Airspace display distance (km)</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QSpinBox" name="airspaceRange">
<property name="toolTip">
<string>Displays airspace within the specified distance in kilometres from My Position</string>
@ -564,14 +538,14 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="displayNavAids">
<property name="text">
<string>Display NAVAIDs</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QCheckBox" name="navAids">
<property name="toolTip">
<string>Display NAVAIDs such as VORs and NDBs</string>
@ -581,7 +555,7 @@
</property>
</widget>
</item>
<item row="9" column="1">
<item row="10" column="1">
<widget class="QCheckBox" name="atcCallsigns">
<property name="toolTip">
<string>Use ATC callsigns (SPEEDBIRD) rather than ICAO (BAW) for aircraft labels on map</string>
@ -591,13 +565,44 @@
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="atcCallsignsLabel">
<property name="text">
<string>Use ATC callsigns on map</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="flightPathPalette">
<property name="toolTip">
<string>Colour palette to use for aircraft flight paths</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="flightPathPaletteLabel">
<property name="text">
<string>Flight path palette</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Maptiler API key</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="maptilerAPIKey">
<property name="toolTip">
<string>API key for Maptiler (https://maptiler.com) for satellite map</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -607,10 +612,10 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@
#include <QTextToSpeech>
#include <QRandomGenerator>
#include <QNetworkAccessManager>
#include <QtCharts>
#include "channel/channelgui.h"
#include "dsp/dsptypes.h"
@ -56,11 +57,17 @@ class WebAPIAdapterInterface;
class HttpDownloadManager;
class ADSBDemodGUI;
class ADSBOSMTemplateServer;
class CheckList;
class AircraftModel;
namespace Ui {
class ADSBDemodGUI;
}
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
using namespace QtCharts;
#endif
// Custom widget to allow formatted decimal numbers to be sorted numerically
class CustomDoubleTableWidgetItem : public QTableWidgetItem
{
@ -89,12 +96,16 @@ struct Aircraft {
QString m_icaoHex;
QString m_callsign; // Flight callsign
QString m_flight; // Guess at flight number
bool m_globalPosition; // Position has been determined from global decode
Real m_latitude; // Latitude in decimal degrees
Real m_longitude; // Longitude in decimal degrees
int m_altitude; // Altitude in feet
float m_radius; // Horizontal containment radius limit (Rc) in metres
int m_altitude; // Altitude in feet (will be 0 if on surface)
int m_pressureAltitude; // Pressure altitude in feet for Map PFD altimeter (can be negative on surface)
bool m_onSurface; // Indicates if on surface or airborne
bool m_altitudeGNSS; // Altitude is GNSS HAE (Height above WGS-84 ellipsoid) rather than barometric alitute (relative to 29.92 Hg)
float m_heading; // Heading or track in degrees
float m_heading; // Heading in degrees magnetic
float m_track; // Track in degrees true?
int m_verticalRate; // Vertical climb rate in ft/min
QString m_emitterCategory; // Aircraft type
QString m_status; // Aircraft status
@ -102,23 +113,37 @@ struct Aircraft {
Real m_range; // Distance from station to aircraft
Real m_azimuth; // Azimuth from station to aircraft
Real m_elevation; // Elevation from station to aircraft
QDateTime m_time; // When last updated
QDateTime m_rxTime; // When last frame received (can be long ago if reading from log file)
QDateTime m_updateTime; // Last time we updated data for this aircraft (used for determining when to remove an aircraft)
int m_selAltitude; // Selected altitude in MCP/FCU or FMS in feet
int m_selHeading; // Selected heading in MCP/FCU in degrees
int m_baro; // Aircraft baro setting in mb (Mode-S)
float m_baro; // Aircraft baro setting in mb (Mode-S)
float m_roll; // In degrees
int m_groundspeed; // In knots
float m_turnRate; // In degrees per second
int m_trueAirspeed; // In knots
int m_indicatedAirspeed; // In knots
float m_mach; // Mach number
bool m_autopilot;
bool m_vnavMode;
bool m_altHoldMode;
bool m_approachMode;
bool m_lnavMode;
bool m_tcasOperational; // Appears only to be true if TA/RA, false if TA ONLY
bool m_bdsCapabilities[16][16]; // BDS capabilities are indicaited by BDS 1.7
int m_adsbVersion;
bool m_nicSupplementA;
bool m_nicSupplementB;
bool m_nicSupplementC;
bool m_positionValid; // Indicates if we have valid data for the above fields
bool m_altitudeValid;
bool m_pressureAltitudeValid;
bool m_onSurfaceValid;
bool m_headingValid;
bool m_trackValid;
bool m_verticalRateValid;
bool m_selAltitudeValid;
bool m_selHeadingValid;
@ -129,16 +154,30 @@ struct Aircraft {
bool m_trueAirspeedValid;
bool m_indicatedAirspeedValid;
bool m_machValid;
bool m_autopilotValid;
bool m_vnavModeValid;
bool m_altHoldModeValid;
bool m_approachModeValid;
bool m_lnavModeValid;
bool m_tcasOperationalValid;
bool m_bdsCapabilitiesValid;
bool m_adsbVersionValid;
bool m_nicSupplementAValid;
bool m_nicSupplementBValid;
bool m_nicSupplementCValid;
// State for calculating position using two CPR frames
bool m_cprValid[2];
Real m_cprLat[2];
Real m_cprLong[2];
double m_cprLat[2];
double m_cprLong[2];
QDateTime m_cprTime[2];
int m_adsbFrameCount; // Number of ADS-B frames for this aircraft
int m_modesFrameCount; // Number of Mode-S frames for this aircraft
int m_nonTransponderFrameCount;
int m_tisBFrameCount;
int m_adsrFrameCount;
float m_minCorrelation;
float m_maxCorrelation;
float m_correlation;
@ -148,8 +187,12 @@ struct Aircraft {
bool m_isHighlighted; // Are we highlighting this aircraft in the table and map
bool m_showAll;
QVariantList m_coordinates; // Coordinates we've recorded the aircraft at
QList<QVariantList> m_coordinates; // Coordinates we've recorded the aircraft at, split up in to altitude ranges
QList<QVariantList> m_recentCoordinates; // Last 20 seconds of coordinates for ATC mode
QList<QDateTime> m_coordinateDateTimes;
QList<int> m_coordinateColors; // 0-7 index to 8 color palette according to altitude
QList<int> m_recentCoordinateColors;
int m_lastColor;
AircraftInformation *m_aircraftInfo; // Info about the aircraft from the database
QString m_aircraft3DModel; // 3D model for map based on aircraft type
@ -159,6 +202,7 @@ struct Aircraft {
ADSBDemodGUI *m_gui;
QString m_flagIconURL;
QString m_airlineIconURL;
QString m_sideviewIconURL;
// For animation on 3D map
float m_runwayAltitude;
@ -168,10 +212,14 @@ struct Aircraft {
bool m_rotorStarted; // Rotors started on 'Rotorcraft'
bool m_engineStarted; // Engines started (typically propellors)
QDateTime m_positionDateTime;
QDateTime m_orientationDateTime;
QDateTime m_orientationDateTime; // FIXME
QDateTime m_headingDateTime;
QDateTime m_prevHeadingDateTime;
int m_prevHeading;
QDateTime m_trackDateTime;
QDateTime m_altitudeDateTime;
QDateTime m_indicatedAirspeedDateTime;
QDateTime m_prevTrackDateTime;
int m_prevTrack;
float m_trackWhenHeadingSet;
float m_pitchEst; // Estimated pitch based on vertical rate
float m_rollEst; // Estimated roll based on rate of change in heading
@ -182,30 +230,48 @@ struct Aircraft {
QTableWidgetItem *m_callsignItem;
QTableWidgetItem* m_atcCallsignItem;
QTableWidgetItem *m_modelItem;
QTableWidgetItem *m_typeItem;
QTableWidgetItem *m_sideviewItem;
QTableWidgetItem *m_airlineItem;
QTableWidgetItem *m_latitudeItem;
QTableWidgetItem *m_longitudeItem;
QTableWidgetItem *m_altitudeItem;
QTableWidgetItem *m_headingItem;
QTableWidgetItem *m_trackItem;
QTableWidgetItem *m_verticalRateItem;
CustomDoubleTableWidgetItem *m_rangeItem;
QTableWidgetItem *m_azElItem;
QTableWidgetItem *m_emitterCategoryItem;
QTableWidgetItem *m_statusItem;
QTableWidgetItem *m_squawkItem;
QTableWidgetItem *m_identItem;
QTableWidgetItem *m_registrationItem;
QTableWidgetItem *m_countryItem;
QTableWidgetItem *m_registeredItem;
QTableWidgetItem *m_manufacturerNameItem;
QTableWidgetItem *m_ownerItem;
QTableWidgetItem *m_operatorICAOItem;
QTableWidgetItem *m_interogatorCodeItem;
QTableWidgetItem *m_timeItem;
QTableWidgetItem *m_totalFrameCountItem;
QTableWidgetItem *m_adsbFrameCountItem;
QTableWidgetItem *m_modesFrameCountItem;
QTableWidgetItem *m_nonTransponderItem;
QTableWidgetItem *m_tisBFrameCountItem;
QTableWidgetItem *m_adsrFrameCountItem;
QTableWidgetItem *m_radiusItem;
QTableWidgetItem *m_nacpItem;
QTableWidgetItem *m_nacvItem;
QTableWidgetItem *m_gvaItem;
QTableWidgetItem *m_nicItem;
QTableWidgetItem *m_nicBaroItem;
QTableWidgetItem *m_silItem;
QTableWidgetItem *m_correlationItem;
QTableWidgetItem *m_rssiItem;
QTableWidgetItem *m_flightStatusItem;
QTableWidgetItem *m_depItem;
QTableWidgetItem *m_arrItem;
QTableWidgetItem *m_stopsItem;
QTableWidgetItem *m_stdItem;
QTableWidgetItem *m_etdItem;
QTableWidgetItem *m_atdItem;
@ -218,6 +284,13 @@ struct Aircraft {
QTableWidgetItem *m_apItem;
QTableWidgetItem *m_vModeItem;
QTableWidgetItem *m_lModeItem;
QTableWidgetItem *m_tcasItem;
QTableWidgetItem *m_acasItem;
QTableWidgetItem *m_raItem;
QTableWidgetItem *m_maxSpeedItem;
QTableWidgetItem *m_versionItem;
QTableWidgetItem *m_lengthItem;
QTableWidgetItem *m_widthItem;
QTableWidgetItem *m_rollItem;
QTableWidgetItem *m_groundspeedItem;
QTableWidgetItem *m_turnRateItem;
@ -231,16 +304,18 @@ struct Aircraft {
QTableWidgetItem *m_staticPressureItem;
QTableWidgetItem *m_staticAirTempItem;
QTableWidgetItem *m_humidityItem;
QTableWidgetItem *m_tisBItem;
Aircraft(ADSBDemodGUI *gui) :
m_icao(0),
m_globalPosition(false),
m_latitude(0),
m_longitude(0),
m_radius(0.0f),
m_altitude(0),
m_onSurface(false),
m_altitudeGNSS(false),
m_heading(0),
m_track(0),
m_verticalRate(0),
m_azimuth(0),
m_elevation(0),
@ -253,9 +328,22 @@ struct Aircraft {
m_trueAirspeed(0),
m_indicatedAirspeed(0),
m_mach(0.0f),
m_autopilot(false),
m_vnavMode(false),
m_altHoldMode(false),
m_approachMode(false),
m_lnavMode(false),
m_tcasOperational(false),
m_adsbVersion(0),
m_nicSupplementA(false),
m_nicSupplementB(false),
m_nicSupplementC(false),
m_positionValid(false),
m_altitudeValid(false),
m_pressureAltitudeValid(false),
m_onSurfaceValid(false),
m_headingValid(false),
m_trackValid(false),
m_verticalRateValid(false),
m_selAltitudeValid(false),
m_selHeadingValid(false),
@ -266,9 +354,22 @@ struct Aircraft {
m_trueAirspeedValid(false),
m_indicatedAirspeedValid(false),
m_machValid(false),
m_autopilotValid(false),
m_vnavModeValid(false),
m_altHoldModeValid(false),
m_approachModeValid(false),
m_lnavModeValid(false),
m_tcasOperationalValid(false),
m_bdsCapabilitiesValid(false),
m_adsbVersionValid(false),
m_nicSupplementAValid(false),
m_nicSupplementBValid(false),
m_nicSupplementCValid(false),
m_adsbFrameCount(0),
m_modesFrameCount(0),
m_nonTransponderFrameCount(0),
m_tisBFrameCount(0),
m_adsrFrameCount(0),
m_minCorrelation(INFINITY),
m_maxCorrelation(-INFINITY),
m_correlation(0.0f),
@ -302,9 +403,12 @@ struct Aircraft {
m_callsignItem = new QTableWidgetItem();
m_atcCallsignItem = new QTableWidgetItem();
m_modelItem = new QTableWidgetItem();
m_typeItem = new QTableWidgetItem();
m_sideviewItem = new QTableWidgetItem();
m_airlineItem = new QTableWidgetItem();
m_altitudeItem = new QTableWidgetItem();
m_headingItem = new QTableWidgetItem();
m_trackItem = new QTableWidgetItem();
m_verticalRateItem = new QTableWidgetItem();
m_rangeItem = new CustomDoubleTableWidgetItem();
m_azElItem = new QTableWidgetItem();
@ -313,19 +417,34 @@ struct Aircraft {
m_emitterCategoryItem = new QTableWidgetItem();
m_statusItem = new QTableWidgetItem();
m_squawkItem = new QTableWidgetItem();
m_identItem = new QTableWidgetItem();
m_registrationItem = new QTableWidgetItem();
m_countryItem = new QTableWidgetItem();
m_registeredItem = new QTableWidgetItem();
m_manufacturerNameItem = new QTableWidgetItem();
m_ownerItem = new QTableWidgetItem();
m_operatorICAOItem = new QTableWidgetItem();
m_interogatorCodeItem = new QTableWidgetItem();
m_timeItem = new QTableWidgetItem();
m_totalFrameCountItem = new QTableWidgetItem();
m_adsbFrameCountItem = new QTableWidgetItem();
m_modesFrameCountItem = new QTableWidgetItem();
m_nonTransponderItem = new QTableWidgetItem();
m_tisBFrameCountItem = new QTableWidgetItem();
m_adsrFrameCountItem = new QTableWidgetItem();
m_radiusItem = new QTableWidgetItem();
m_nacpItem = new QTableWidgetItem();
m_nacvItem = new QTableWidgetItem();
m_gvaItem = new QTableWidgetItem();
m_nicItem = new QTableWidgetItem();
m_nicBaroItem = new QTableWidgetItem();
m_silItem = new QTableWidgetItem();
m_correlationItem = new QTableWidgetItem();
m_rssiItem = new QTableWidgetItem();
m_flightStatusItem = new QTableWidgetItem();
m_depItem = new QTableWidgetItem();
m_arrItem = new QTableWidgetItem();
m_stopsItem = new QTableWidgetItem();
m_stdItem = new QTableWidgetItem();
m_etdItem = new QTableWidgetItem();
m_atdItem = new QTableWidgetItem();
@ -338,6 +457,13 @@ struct Aircraft {
m_apItem = new QTableWidgetItem();
m_vModeItem = new QTableWidgetItem();
m_lModeItem = new QTableWidgetItem();
m_tcasItem = new QTableWidgetItem();
m_acasItem = new QTableWidgetItem();
m_raItem = new QTableWidgetItem();
m_maxSpeedItem = new QTableWidgetItem();
m_versionItem = new QTableWidgetItem();
m_lengthItem = new QTableWidgetItem();
m_widthItem = new QTableWidgetItem();
m_rollItem = new QTableWidgetItem();
m_groundspeedItem = new QTableWidgetItem();
m_turnRateItem = new QTableWidgetItem();
@ -351,16 +477,15 @@ struct Aircraft {
m_staticPressureItem = new QTableWidgetItem();
m_staticAirTempItem = new QTableWidgetItem();
m_humidityItem = new QTableWidgetItem();
m_tisBItem = new QTableWidgetItem();
}
QString getImage() const;
QString getText(const ADSBDemodSettings *settings, bool all=false) const;
// Label to use for aircraft on map
QString getLabel(const ADSBDemodSettings *settings) const;
QString getLabel(const ADSBDemodSettings *settings, QDateTime& dateTime) const;
// Name to use when selected as a target (E.g. for use as target name in Rotator Controller)
QString targetName()
QString targetName() const
{
if (!m_callsign.isEmpty())
return QString("Callsign: %1").arg(m_callsign);
@ -368,6 +493,71 @@ struct Aircraft {
return QString("ICAO: %1").arg(m_icao, 0, 16);
}
void setOnSurface(const QDateTime& dateTime);
void setAltitude(int altitudeFt, bool gnss, const QDateTime& dateTime, const ADSBDemodSettings& settings);
void setVerticalRate(int verticalRate, const ADSBDemodSettings& settings);
void setGroundspeed(float groundspeed, const ADSBDemodSettings& settings);
void setTrueAirspeed(int airspeed, const ADSBDemodSettings& settings);
void setIndicatedAirspeed(int airspeed, const QDateTime& dateTime, const ADSBDemodSettings& settings);
void setTrack(float track, const QDateTime& dateTime);
void setHeading(float heading, const QDateTime& dateTime);
void addCoordinate(const QDateTime& dateTime, AircraftModel *model);
void clearCoordinates(AircraftModel *model);
};
class AircraftPathModel : public QAbstractListModel {
Q_OBJECT
public:
using QAbstractListModel::QAbstractListModel;
enum MarkerRoles{
coordinatesRole = Qt::UserRole + 1,
colorRole = Qt::UserRole + 2,
};
AircraftPathModel(AircraftModel *aircraftModel, Aircraft *aircraft) :
m_aircraftModel(aircraftModel),
m_aircraft(aircraft),
m_paths(0),
m_showFullPath(false),
m_showATCPath(false)
{
settingsUpdated();
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
(void) parent;
return m_paths;
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void add();
void updateLast();
void removed();
void clear();
void settingsUpdated();
Qt::ItemFlags flags(const QModelIndex &index) const override
{
(void) index;
return Qt::ItemIsEnabled;
}
QHash<int, QByteArray> roleNames() const {
QHash<int, QByteArray> roles;
roles[coordinatesRole] = "coordinates";
roles[colorRole] = "color";
return roles;
}
private:
AircraftModel *m_aircraftModel;
Aircraft *m_aircraft;
int m_paths; // Should match m_aircraft->m_coordinates.count()
bool m_showFullPath;
bool m_showATCPath;
};
// Aircraft data model used by QML map item
@ -385,12 +575,16 @@ public:
aircraftPathRole = Qt::UserRole + 6,
showAllRole = Qt::UserRole + 7,
highlightedRole = Qt::UserRole + 8,
targetRole = Qt::UserRole + 9
targetRole = Qt::UserRole + 9,
radiusRole = Qt::UserRole + 10,
showRadiusRole = Qt::UserRole + 11,
aircraftPathModelRole = Qt::UserRole + 12,
};
Q_INVOKABLE void addAircraft(Aircraft *aircraft) {
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_aircrafts.append(aircraft);
m_pathModels.append(new AircraftPathModel(this, aircraft));
endInsertRows();
}
@ -409,7 +603,8 @@ public:
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}
void aircraftUpdated(Aircraft *aircraft) {
void aircraftUpdated(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0)
{
@ -418,30 +613,72 @@ public:
}
}
void allAircraftUpdated() {
/*
// Not sure why this doesn't work - it should be more efficient
// than the following code
emit dataChanged(index(0), index(rowCount()));
*/
for (int i = 0; i < m_aircrafts.count(); i++)
void highlightChanged(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0)
{
QModelIndex idx = index(i);
m_pathModels[row]->settingsUpdated();
QModelIndex idx = index(row);
emit dataChanged(idx, idx);
}
}
void removeAircraft(Aircraft *aircraft) {
void clearCoords(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0) {
m_pathModels[row]->clear();
}
}
void aircraftCoordsUpdated(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0) {
m_pathModels[row]->updateLast();
}
}
void aircraftCoordsAdded(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0) {
m_pathModels[row]->add();
}
}
void aircraftCoordsRemoved(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0) {
m_pathModels[row]->removed();
}
}
void allAircraftUpdated()
{
emit dataChanged(index(0), index(rowCount()-1));
for (int i = 0; i < m_aircrafts.count(); i++) {
m_pathModels[i]->settingsUpdated();
}
}
void removeAircraft(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0)
{
beginRemoveRows(QModelIndex(), row, row);
m_aircrafts.removeAt(row);
delete m_pathModels.takeAt(row);
endRemoveRows();
}
}
QHash<int, QByteArray> roleNames() const {
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
roles[positionRole] = "position";
roles[headingRole] = "heading";
@ -452,22 +689,12 @@ public:
roles[showAllRole] = "showAll";
roles[highlightedRole] = "highlighted";
roles[targetRole] = "target";
roles[radiusRole] = "containmentRadius";
roles[aircraftPathModelRole] = "aircraftPathModel";
return roles;
}
void setFlightPaths(bool flightPaths)
{
m_flightPaths = flightPaths;
allAircraftUpdated();
}
void setAllFlightPaths(bool allFlightPaths)
{
m_allFlightPaths = allFlightPaths;
allAircraftUpdated();
}
void setSettings(const ADSBDemodSettings *settings)
void setSettings(const ADSBDemodSettings *settings)
{
m_settings = settings;
allAircraftUpdated();
@ -487,11 +714,11 @@ public:
}
}
const ADSBDemodSettings *m_settings;
private:
QList<Aircraft *> m_aircrafts;
bool m_flightPaths;
bool m_allFlightPaths;
const ADSBDemodSettings *m_settings;
QList<AircraftPathModel *> m_pathModels;
};
// Airport data model used by QML map item
@ -667,26 +894,34 @@ public:
airspacePolygonRole = Qt::UserRole + 6
};
Q_INVOKABLE void addAirspace(Airspace *airspace) {
Q_INVOKABLE void addAirspace(Airspace *airspace)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_airspaces.append(airspace);
// Convert QPointF to QVariantList of QGeoCoordinates
QVariantList polygon;
for (const auto p : airspace->m_polygon)
{
QGeoCoordinate coord(p.y(), p.x(), airspace->topHeightInMetres());
polygon.push_back(QVariant::fromValue(coord));
}
m_polygons.append(polygon);
updatePolygon(airspace, -1);
endInsertRows();
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
Q_UNUSED(parent)
return m_airspaces.count();
}
void removeAllAirspaces() {
void removeAirspace(Airspace *airspace)
{
int idx = m_airspaces.indexOf(airspace);
if (idx >= 0)
{
beginRemoveRows(QModelIndex(), idx, idx);
m_airspaces.removeAt(idx);
m_polygons.removeAt(idx);
endRemoveRows();
}
}
void removeAllAirspaces()
{
if (m_airspaces.count() > 0)
{
beginRemoveRows(QModelIndex(), 0, m_airspaces.count() - 1);
@ -696,6 +931,23 @@ public:
}
}
void airspaceUpdated(const Airspace *airspace)
{
int row = m_airspaces.indexOf(airspace);
if (row >= 0)
{
updatePolygon(airspace, row);
QModelIndex idx = index(row);
emit dataChanged(idx, idx);
}
}
bool contains(const Airspace *airspace)
{
return m_airspaces.contains(airspace);
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant& value, int role = Qt::EditRole) override;
@ -706,7 +958,8 @@ public:
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}
QHash<int, QByteArray> roleNames() const {
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
roles[nameRole] = "name";
roles[detailsRole] = "details";
@ -718,8 +971,25 @@ public:
}
private:
QList<Airspace *> m_airspaces;
QList<const Airspace *> m_airspaces;
QList<QVariantList> m_polygons;
void updatePolygon(const Airspace *airspace, int row)
{
// Convert QPointF to QVariantList of QGeoCoordinates
QVariantList polygon;
for (const auto p : airspace->m_polygon)
{
QGeoCoordinate coord(p.y(), p.x(), airspace->topHeightInMetres());
polygon.push_back(QVariant::fromValue(coord));
}
if (row == -1) {
m_polygons.append(polygon);
} else {
m_polygons.replace(row, polygon);
}
}
};
// NavAid model used for each NavAid on the map
@ -867,6 +1137,23 @@ protected:
class ADSBDemodGUI : public ChannelGUI {
Q_OBJECT
struct Interogator {
Real m_minLatitude;
Real m_maxLatitude;
Real m_minLongitude;
Real m_maxLongitude;
bool m_valid;
Airspace m_airspace;
Interogator() :
m_valid(false)
{
}
void update(int ic, Aircraft *aircraft, AirspaceModel *airspaceModel, CheckList *checkList, bool display);
void calcPoly();
};
public:
static ADSBDemodGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
virtual void destroy();
@ -923,6 +1210,7 @@ private:
QHash<int, Aircraft *> m_aircraft; // Hashed on ICAO
QSharedPointer<const QHash<int, AircraftInformation *>> m_aircraftInfo;
QSharedPointer<const QHash<QString, AircraftRouteInformation *>> m_routeInfo; // Hashed on callsign
QSharedPointer<const QHash<int, AirportInformation *>> m_airportInfo; // Hashed on id
AircraftModel m_aircraftModel;
AirportModel m_airportModel;
@ -936,12 +1224,85 @@ private:
Aircraft *m_trackAircraft; // Aircraft we want to track in Channel Report
MovingAverageUtil<float, double, 10> m_correlationAvg;
MovingAverageUtil<float, double, 10> m_correlationOnesAvg;
MovingAverageUtil<float, double, 100> m_qnhAvg;
Aircraft *m_highlightAircraft; // Aircraft we want to highlight, when selected in table
float m_currentAirportRange; // Current settings, so we only update if changed
ADSBDemodSettings::AirportType m_currentAirportMinimumSize;
bool m_currentDisplayHeliports;
static const int m_maxRangeDeg = 5;
QList<float> m_maxRange[2];
Airspace m_coverageAirspace[2];
Interogator m_interogators[ADSB_IC_MAX];
enum StatsRow {
ADSB_FRAMES,
MODE_S_FRAMES,
TOTAL_FRAMES,
ADSB_RATE,
MODE_S_RATE,
TOTAL_RATE,
DATA_RATE,
CORRELATOR_MATCHES,
PERCENT_VALID,
PREAMBLE_FAILS,
CRC_FAILS,
TYPE_FAILS,
INVALID_FAILS,
ICAO_FAILS,
RANGE_FAILS,
ALT_FAILS,
AVERAGE_CORRELATION,
TC_0,
TC_1_4,
TC_5_8,
TC_9_18,
TC_19,
TC_20_22,
TC_24,
TC_28,
TC_29,
TC_31,
TC_UNUSED,
DF0,
DF4,
DF5,
DF11,
DF16,
DF17,
DF18,
DF19,
DF20_21,
DF22,
DF24,
MAX_RANGE,
MAX_ALTITUDE,
MAX_RATE
};
qint64 m_rangeFails;
qint64 m_altFails;
QDateTime m_frameRateTime;
qint64 m_adsbFrameRateCount;
qint64 m_modesFrameRateCount;
qint64 m_totalBytes;
float m_maxRangeStat;
float m_maxAltitudeStat;
float m_maxRateState;
qint64 m_dfStats[32];
qint64 m_tcStats[32];
QChart *m_chart;
QLineSeries *m_adsbFrameRateSeries;
QLineSeries *m_modesFrameRateSeries;
QLineSeries *m_aircraftSeries;
QDateTimeAxis *m_xAxis;
QValueAxis *m_fpsYAxis;
QValueAxis *m_aircraftYAxis;
QDateTime m_averageTime;
#ifdef QT_TEXTTOSPEECH_FOUND
QTextToSpeech *m_speech;
#endif
@ -977,10 +1338,13 @@ private:
static const QString m_flightStatuses[];
static const QString m_hazardSeverity[];
static const QString m_fomSources[];
static const QString m_nacvStrings[];
explicit ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
virtual ~ADSBDemodGUI();
QString maptilerAPIKey() const;
void blockApplySettings(bool block);
void applySetting(const QString& settingsKey);
void applySettings(const QStringList& settingsKeys, bool force = false);
@ -990,8 +1354,6 @@ private:
void makeUIConnections();
void updateAbsoluteCenterFrequency();
void updatePosition(Aircraft *aircraft);
bool updateLocalPosition(Aircraft *aircraft, double latitude, double longitude, bool surfacePosition);
void clearFromMap(const QString& name);
void sendToMap(Aircraft *aircraft, QList<SWGSDRangel::SWGMapAnimation *> *animations);
Aircraft *getAircraft(int icao, bool &newAircraft);
@ -1006,10 +1368,24 @@ private:
float correlationOnes,
unsigned crc,
bool updateModel);
void decodeModeS(const QByteArray data, int df, Aircraft *aircraft);
void decodeID(const QByteArray& data, QString& emitterCategory, QString& callsign);
void decodeGroundspeed(const QByteArray& data, float& v, float& h);
void decodeAirspeed(const QByteArray& data, bool& tas, int& as, bool& hdgValid, float& hdg);
void decodeVerticalRate(const QByteArray& data, int& verticalRate);
void updateAircraftPosition(Aircraft *aircraft, double latitude, double longitude, const QDateTime& dateTime);
bool validateGlobalPosition(double latitude, double longitude, bool countFailure);
bool validateLocalPosition(double latitude, double longitude, bool surfacePosition, bool countFailure);
bool decodeGlobalPosition(int f, const double cprLat[2], const double cprLong[2], const QDateTime cprTime[2], double& latitude, double& longitude, bool countFailure);
bool decodeLocalPosition(int f, double cprLat, double cprLong, bool onSurface, const Aircraft *aircraft, double& latitude, double& longitude, bool countFailure);
void decodeCpr(const QByteArray& data, int& f, double& latCpr, double& lonCpr) const;
bool decodeAltitude(const QByteArray& data, int& altFt) const;
void decodeModeSAltitude(const QByteArray& data, const QDateTime dateTime, Aircraft *aircraft);
void decodeModeS(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft);
void decodeCommB(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft, bool &updatedCallsign);
QList<SWGSDRangel::SWGMapAnimation *> *animate(QDateTime dateTime, Aircraft *aircraft);
SWGSDRangel::SWGMapAnimation *gearAnimation(QDateTime startDateTime, bool up);
SWGSDRangel::SWGMapAnimation *gearAngle(QDateTime startDateTime, bool flat);
SWGSDRangel::SWGMapAnimation *flapsAnimation(QDateTime startDateTime, float currentFlaps, float flaps);
SWGSDRangel::SWGMapAnimation *slatsAnimation(QDateTime startDateTime, bool retract);
SWGSDRangel::SWGMapAnimation *rotorAnimation(QDateTime startDateTime, bool stop);
@ -1022,18 +1398,18 @@ private:
QString subAircraftString(Aircraft *aircraft, const QString &string);
void resizeTable();
QString getDataDir();
void readAirportDB(const QString& filename);
void readAirportFrequenciesDB(const QString& filename);
void update3DModels();
void updateAirports();
void updateAirspaces();
void updateNavAids();
void updateChannelList();
void removeAircraft(QHash<int, Aircraft *>::iterator& i, Aircraft *aircraft);
QAction *createCheckableItem(QString& text, int idx, bool checked);
Aircraft* findAircraftByFlight(const QString& flight);
QString dataTimeToShortString(QDateTime dt);
void initFlightInformation();
void initAviationWeather();
void setShowContainmentRadius(bool show);
void applyMapSettings();
void updatePhotoText(Aircraft *aircraft);
void updatePhotoFlightInformation(Aircraft *aircraft);
@ -1045,16 +1421,33 @@ private:
void applyImportSettings();
void sendAircraftReport();
void updatePosition(float latitude, float longitude, float altitude);
void clearOldHeading(Aircraft *aircraft, const QDateTime& dateTime, float newTrack);
void updateQNH(const Aircraft *aircraft, float qnh);
void setCallsign(Aircraft *aircraft, const QString& callsign);
void initCoverageMap();
void clearCoverageMap();
void updateCoverageMap(float azimuth, float elevation, float distance, float altitude);
void leaveEvent(QEvent*);
void enterEvent(EnterEventType*);
void updateDFStats(int df);
bool updateTCStats(int tc, int row, int low, int high);
void resetStats();
void plotChart();
int countActiveAircraft();
void averageSeries(QLineSeries *series, const QDateTime& startTime, const QDateTime& endTime);
void legendMarkerClicked();
private slots:
void on_deltaFrequency_changed(qint64 value);
void on_rfBW_valueChanged(int value);
void on_threshold_valueChanged(int value);
void on_chipsThreshold_valueChanged(int value);
void on_phaseSteps_valueChanged(int value);
void on_tapsPerPhase_valueChanged(int value);
void statsTable_customContextMenuRequested(QPoint pos);
void adsbData_customContextMenuRequested(QPoint point);
void on_adsbData_cellClicked(int row, int column);
void on_adsbData_cellDoubleClicked(int row, int column);
@ -1063,18 +1456,24 @@ private slots:
void columnSelectMenu(QPoint pos);
void columnSelectMenuChecked(bool checked = false);
void on_spb_currentIndexChanged(int value);
void on_correlateFullPreamble_clicked(bool checked);
void on_demodModeS_clicked(bool checked);
void on_feed_clicked(bool checked);
void on_notifications_clicked();
void on_flightInfo_clicked();
void on_findOnMapFeature_clicked();
void on_getOSNDB_clicked();
void on_deleteAircraft_clicked();
void on_getAircraftDB_clicked();
void on_getAirportDB_clicked();
void on_getAirspacesDB_clicked();
void on_coverage_clicked(bool checked);
void on_displayChart_clicked(bool checked);
void on_stats_clicked(bool checked);
void on_flightPaths_clicked(bool checked);
void on_allFlightPaths_clicked(bool checked);
void on_atcLabels_clicked(bool checked);
void on_displayOrientation_clicked(bool checked);
void on_displayRadius_clicked(bool checked);
void on_ic_globalCheckStateChanged(int state);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void handleInputMessages();
@ -1101,6 +1500,12 @@ private slots:
void devicePositionChanged(float latitude, float longitude, float altitude);
void requestMetar(const QString& icao);
void weatherUpdated(const AviationWeather::METAR &metar);
void on_manualQNH_clicked(bool checked);
void on_qnh_valueChanged(int value);
void clearCoverage(const QPoint& p);
void clearStats(const QPoint& p);
void clearChart(const QPoint& p);
void resetChartAxes();
signals:
void homePositionChanged();

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,13 @@
<file>icons/aircraft.png</file>
<file>icons/airport.png</file>
<file>icons/controltower.png</file>
<file>icons/coverage.png</file>
<file>icons/allflightpaths.png</file>
<file>icons/vor.png</file>
<file>icons/stats.png</file>
<file>icons/chart.png</file>
<file>icons/horizontal.png</file>
<file>icons/vertical.png</file>
<file>icons/radius.png</file>
</qresource>
</RCC>

View File

@ -5,14 +5,22 @@
<file>map/map_6_strict.qml</file>
<file>map/ModifiedMapView.qml</file>
<file>map/MapStation.qml</file>
<file>map/aircraft_2engine.png</file>
<file>map/aircraft_2enginesmall.png</file>
<file>map/aircraft_4engine.png</file>
<file>map/aircraft_small.png</file>
<file>map/aircraft_large.png</file>
<file>map/aircraft_heavy_2engine.png</file>
<file>map/aircraft_heavy_4engine.png</file>
<file>map/aircraft_helicopter.png</file>
<file>map/aircraft_light.png</file>
<file>map/aircraft_space.png</file>
<file>map/aircraft_drone.png</file>
<file>map/aircraft_fighter.png</file>
<file>map/aircraft_glider.png</file>
<file>map/spitfire.png</file>
<file>map/a400m.png</file>
<file>map/f35.png</file>
<file>map/apache.png</file>
<file>map/chinook.png</file>
<file>map/eurofighter.png</file>
<file>map/airport_large.png</file>
<file>map/airport_medium.png</file>
<file>map/airport_small.png</file>

View File

@ -25,7 +25,7 @@
// Map main ADS-B table column numbers to combo box indices
std::vector<int> ADSBDemodNotificationDialog::m_columnMap = {
ADSB_COL_ICAO, ADSB_COL_CALLSIGN, ADSB_COL_MODEL,
ADSB_COL_ICAO, ADSB_COL_CALLSIGN, ADSB_COL_MODEL, ADSB_COL_TYPE,
ADSB_COL_ALTITUDE, ADSB_COL_GROUND_SPEED, ADSB_COL_RANGE,
ADSB_COL_CATEGORY, ADSB_COL_STATUS, ADSB_COL_SQUAWK,
ADSB_COL_REGISTRATION, ADSB_COL_MANUFACTURER, ADSB_COL_OWNER, ADSB_COL_OPERATOR_ICAO
@ -117,6 +117,7 @@ void ADSBDemodNotificationDialog::addRow(ADSBDemodSettings::NotificationSettings
match->addItem("ICAO ID");
match->addItem("Callsign");
match->addItem("Aircraft");
match->addItem("Type");
match->addItem("Alt (ft)");
match->addItem("GS (kn)");
match->addItem("D (km)");

View File

@ -36,7 +36,8 @@ void ADSBDemodSettings::resetToDefaults()
{
m_inputFrequencyOffset = 0;
m_rfBandwidth = 2*1300000;
m_correlationThreshold = 10.0f; //<! ones/zero powers correlation threshold in dB
m_correlationThreshold = 7.0f; //<! ones/zero powers correlation threshold in dB
m_chipsThreshold = 0;
m_samplesPerBit = 4;
m_removeTimeout = 60;
m_feedEnabled = false;
@ -73,13 +74,13 @@ void ADSBDemodSettings::resetToDefaults()
m_tableFontName = "Liberation Sans";
m_tableFontSize = 9;
m_displayDemodStats = false;
m_correlateFullPreamble = true;
m_demodModeS = true;
m_autoResizeTableColumns = false;
m_interpolatorPhaseSteps = 4; // Higher than these two values will struggle to run in real-time
m_interpolatorTapsPerPhase = 3.5f; // without gaining much improvement in PER
m_aviationstackAPIKey = "";
m_checkWXAPIKey = "";
m_maptilerAPIKey = "";
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++)
{
m_columnIndexes[i] = i;
@ -98,13 +99,24 @@ void ADSBDemodSettings::resetToDefaults()
m_displayNavAids = true;
m_displayPhotos = true;
m_verboseModelMatching = false;
m_airfieldElevation = 0;
m_aircraftMinZoom = 11;
m_workspaceIndex = 0;
m_hidden = false;
m_atcLabels = true;
m_atcCallsigns = true;
m_transitionAlt = 6000; // Depends on airport. 18,000 in USA
m_qnh = 1013.25;
m_manualQNH = false;
m_displayCoverage = false;
m_displayChart = false;
m_displayOrientation = false;
m_displayRadius = false;
for (int i = 0; i < ADSB_IC_MAX; i++) {
m_displayIC[i] = false;
}
m_flightPathPaletteName = "Spectral";
applyPalette();
m_favourLivery = true;
}
QByteArray ADSBDemodSettings::serialize() const
@ -141,7 +153,6 @@ QByteArray ADSBDemodSettings::serialize() const
s.writeString(25, m_tableFontName);
s.writeS32(26, m_tableFontSize);
s.writeBool(27, m_displayDemodStats);
s.writeBool(28, m_correlateFullPreamble);
s.writeBool(29, m_demodModeS);
s.writeBool(30, m_autoResizeTableColumns);
s.writeS32(31, m_interpolatorPhaseSteps);
@ -165,7 +176,6 @@ QByteArray ADSBDemodSettings::serialize() const
}
s.writeBool(44, m_verboseModelMatching);
s.writeS32(45, m_airfieldElevation);
s.writeBool(46, m_exportClientEnabled);
s.writeBool(47, m_exportServerEnabled);
@ -192,6 +202,19 @@ QByteArray ADSBDemodSettings::serialize() const
s.writeS32(67, m_transitionAlt);
s.writeString(68, m_amDemod);
s.writeFloat(69, m_qnh);
s.writeBool(70, m_manualQNH);
s.writeBool(71, m_displayCoverage);
s.writeBool(72, m_displayChart);
s.writeBool(73, m_displayOrientation);
s.writeBool(74, m_displayRadius);
s.writeString(75, m_flightPathPaletteName);
s.writeS32(76, m_chipsThreshold);
s.writeBool(77, m_favourLivery);
s.writeString(78, m_maptilerAPIKey);
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++) {
s.writeS32(100 + i, m_columnIndexes[i]);
}
@ -229,7 +252,7 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
d.readS32(1, &tmp, 0);
m_inputFrequencyOffset = tmp;
d.readReal(2, &m_rfBandwidth, 2*1300000);
d.readReal(3, &m_correlationThreshold, 0.0f);
d.readReal(3, &m_correlationThreshold, 7.0f);
d.readS32(4, &m_samplesPerBit, 4);
d.readS32(5, &m_removeTimeout, 60);
d.readBool(6, &m_feedEnabled, false);
@ -268,7 +291,6 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
d.readString(25, &m_tableFontName, "Liberation Sans");
d.readS32(26, &m_tableFontSize, 9);
d.readBool(27, &m_displayDemodStats, false);
d.readBool(28, &m_correlateFullPreamble, true);
d.readBool(29, &m_demodModeS, true);
d.readBool(30, &m_autoResizeTableColumns, false);
d.readS32(31, &m_interpolatorPhaseSteps, 4);
@ -296,7 +318,6 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
}
d.readBool(44, &m_verboseModelMatching, false);
d.readS32(45, &m_airfieldElevation, 0);
d.readBool(46, &m_exportClientEnabled, true);
d.readBool(47, &m_exportServerEnabled, true);
@ -328,6 +349,21 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
d.readS32(67, &m_transitionAlt, 6000);
d.readString(68, &m_amDemod);
d.readFloat(69, &m_qnh, 1013.25);
d.readBool(70, &m_manualQNH, false);
d.readBool(71, &m_displayCoverage, false);
d.readBool(72, &m_displayChart, false);
d.readBool(73, &m_displayOrientation, false);
d.readBool(74, &m_displayRadius, false);
d.readString(75, &m_flightPathPaletteName, "Spectral");
d.readS32(76, &m_chipsThreshold, 0);
d.readBool(77, &m_favourLivery, true);
d.readString(78, &m_maptilerAPIKey, "");
applyPalette();
#ifdef LINUX
if (m_mapProvider == "osm") {
m_mapProvider = "mapboxgl";
@ -413,6 +449,9 @@ void ADSBDemodSettings::applySettings(const QStringList& settingsKeys, const ADS
if (settingsKeys.contains("correlationThreshold")) {
m_correlationThreshold = settings.m_correlationThreshold;
}
if (settingsKeys.contains("chipsThreshold")) {
m_chipsThreshold = settings.m_chipsThreshold;
}
if (settingsKeys.contains("samplesPerBit")) {
m_samplesPerBit = settings.m_samplesPerBit;
}
@ -521,9 +560,6 @@ void ADSBDemodSettings::applySettings(const QStringList& settingsKeys, const ADS
if (settingsKeys.contains("displayDemodStats")) {
m_displayDemodStats = settings.m_displayDemodStats;
}
if (settingsKeys.contains("correlateFullPreamble")) {
m_correlateFullPreamble = settings.m_correlateFullPreamble;
}
if (settingsKeys.contains("demodModeS")) {
m_demodModeS = settings.m_demodModeS;
}
@ -548,6 +584,9 @@ void ADSBDemodSettings::applySettings(const QStringList& settingsKeys, const ADS
if (settingsKeys.contains("checkWXAPIKey")) {
m_checkWXAPIKey = settings.m_checkWXAPIKey;
}
if (settingsKeys.contains("maptilerAPIKey")) {
m_maptilerAPIKey = settings.m_maptilerAPIKey;
}
if (settingsKeys.contains("logFilename")) {
m_logFilename = settings.m_logFilename;
}
@ -575,9 +614,6 @@ void ADSBDemodSettings::applySettings(const QStringList& settingsKeys, const ADS
if (settingsKeys.contains("verboseModelMatching")) {
m_verboseModelMatching = settings.m_verboseModelMatching;
}
if (settingsKeys.contains("airfieldElevation")) {
m_airfieldElevation = settings.m_airfieldElevation;
}
if (settingsKeys.contains("aircraftMinZoom")) {
m_aircraftMinZoom = settings.m_aircraftMinZoom;
}
@ -590,6 +626,32 @@ void ADSBDemodSettings::applySettings(const QStringList& settingsKeys, const ADS
if (settingsKeys.contains("transitionAlt")) {
m_transitionAlt = settings.m_transitionAlt;
}
if (settingsKeys.contains("qnh")) {
m_qnh = settings.m_qnh;
}
if (settingsKeys.contains("manualQNH")) {
m_manualQNH = settings.m_manualQNH;
}
if (settingsKeys.contains("displayCoverage")) {
m_displayCoverage = settings.m_displayCoverage;
}
if (settingsKeys.contains("displayChart")) {
m_displayChart = settings.m_displayChart;
}
if (settingsKeys.contains("displayOrientation")) {
m_displayOrientation = settings.m_displayOrientation;
}
if (settingsKeys.contains("displayRadius")) {
m_displayRadius = settings.m_displayRadius;
}
if (settingsKeys.contains("flightPathPaletteName"))
{
m_flightPathPaletteName = settings.m_flightPathPaletteName;
applyPalette();
}
if (settingsKeys.contains("favourLivery")) {
m_favourLivery = settings.m_favourLivery;
}
}
QString ADSBDemodSettings::getDebugString(const QStringList& settingsKeys, bool force) const
@ -605,6 +667,9 @@ QString ADSBDemodSettings::getDebugString(const QStringList& settingsKeys, bool
if (settingsKeys.contains("correlationThreshold") || force) {
ostr << " m_correlationThreshold: " << m_correlationThreshold;
}
if (settingsKeys.contains("chipsThreshold") || force) {
ostr << " m_chipsThreshold: " << m_chipsThreshold;
}
if (settingsKeys.contains("samplesPerBit") || force) {
ostr << " m_samplesPerBit: " << m_samplesPerBit;
}
@ -704,9 +769,6 @@ QString ADSBDemodSettings::getDebugString(const QStringList& settingsKeys, bool
if (settingsKeys.contains("displayDemodStats") || force) {
ostr << " m_displayDemodStats: " << m_displayDemodStats;
}
if (settingsKeys.contains("correlateFullPreamble") || force) {
ostr << " m_correlateFullPreamble: " << m_correlateFullPreamble;
}
if (settingsKeys.contains("demodModeS") || force) {
ostr << " m_demodModeS: " << m_demodModeS;
}
@ -728,6 +790,9 @@ QString ADSBDemodSettings::getDebugString(const QStringList& settingsKeys, bool
if (settingsKeys.contains("checkWXAPIKey") || force) {
ostr << " m_checkWXAPIKey: " << m_checkWXAPIKey.toStdString();
}
if (settingsKeys.contains("maptilerAPIKey") || force) {
ostr << " m_maptilerAPIKey: " << m_maptilerAPIKey.toStdString();
}
if (settingsKeys.contains("logFilename") || force) {
ostr << " m_logFilename: " << m_logFilename.toStdString();
}
@ -755,9 +820,6 @@ QString ADSBDemodSettings::getDebugString(const QStringList& settingsKeys, bool
if (settingsKeys.contains("verboseModelMatching") || force) {
ostr << " m_verboseModelMatching: " << m_verboseModelMatching;
}
if (settingsKeys.contains("airfieldElevation") || force) {
ostr << " m_airfieldElevation: " << m_airfieldElevation;
}
if (settingsKeys.contains("aircraftMinZoom") || force) {
ostr << " m_aircraftMinZoom: " << m_aircraftMinZoom;
}
@ -770,6 +832,114 @@ QString ADSBDemodSettings::getDebugString(const QStringList& settingsKeys, bool
if (settingsKeys.contains("transitionAlt") || force) {
ostr << " m_transitionAlt: " << m_transitionAlt;
}
if (settingsKeys.contains("qnh") || force) {
ostr << " m_qnh: " << m_qnh;
}
if (settingsKeys.contains("manualQNH") || force) {
ostr << " m_manualQNH: " << m_manualQNH;
}
if (settingsKeys.contains("displayCoverage") || force) {
ostr << " m_displayCoverage: " << m_displayCoverage;
}
if (settingsKeys.contains("displayChart") || force) {
ostr << " m_displayChart: " << m_displayChart;
}
if (settingsKeys.contains("displayOrientation") || force) {
ostr << " m_displayOrientation: " << m_displayOrientation;
}
if (settingsKeys.contains("displayRadius") || force) {
ostr << " m_displayRadius: " << m_displayRadius;
}
if (settingsKeys.contains("flightPathPaletteName") || force) {
ostr << " m_flightPathPaletteName: " << m_flightPathPaletteName.toStdString();
}
if (settingsKeys.contains("favourLivery") || force) {
ostr << " m_favourLivery: " << m_favourLivery;
}
return QString(ostr.str().c_str());
}
void ADSBDemodSettings::applyPalette()
{
if (m_palettes.contains(m_flightPathPaletteName)) {
m_flightPathPalette = m_palettes.value(m_flightPathPaletteName);
} else {
m_flightPathPalette = m_rainbowPalette;
}
}
const QVariant ADSBDemodSettings::m_rainbowPalette[8] = {
QVariant(QColor(0xff, 0x00, 0x00)),
QVariant(QColor(0xff, 0x7f, 0x00)),
QVariant(QColor(0xff, 0xff, 0x00)),
QVariant(QColor(0xf7, 0xff, 0x00)),
QVariant(QColor(0x00, 0xff, 0x00)),
QVariant(QColor(0x00, 0xff, 0x7f)),
QVariant(QColor(0x00, 0xff, 0xff)),
QVariant(QColor(0x00, 0x7f, 0xff)),
};
const QVariant ADSBDemodSettings::m_pastelPalette[8] = {
QVariant(QColor(0xff, 0xad, 0xad)),
QVariant(QColor(0xff, 0xd6, 0xa5)),
QVariant(QColor(0xfd, 0xff, 0xb6)),
QVariant(QColor(0xca, 0xff, 0xbf)),
QVariant(QColor(0x9b, 0xf6, 0xff)),
QVariant(QColor(0xa0, 0xc4, 0xff)),
QVariant(QColor(0xbd, 0xb2, 0xff)),
QVariant(QColor(0xff, 0xc6, 0xff)),
};
const QVariant ADSBDemodSettings::m_spectralPalette[8] = {
QVariant(QColor(0xd5, 0x3e, 0x4f)),
QVariant(QColor(0xf4, 0x6d, 0x43)),
QVariant(QColor(0xfd, 0xae, 0x61)),
QVariant(QColor(0xfe, 0xe0, 0x8b)),
QVariant(QColor(0xe6, 0xf5, 0x98)),
QVariant(QColor(0xab, 0xdd, 0xa4)),
QVariant(QColor(0x66, 0xc2, 0xa5)),
QVariant(QColor(0x32, 0x88, 0xbd)),
};
const QVariant ADSBDemodSettings::m_bluePalette[8] = {
QVariant(QColor(0xde, 0xeb, 0xf7)),
QVariant(QColor(0xc6, 0xdb, 0xef)),
QVariant(QColor(0x9e, 0xca, 0xe1)),
QVariant(QColor(0x6b, 0xae, 0xd6)),
QVariant(QColor(0x42, 0x92, 0xc6)),
QVariant(QColor(0x21, 0x71, 0xb5)),
QVariant(QColor(0x08, 0x51, 0x9c)),
QVariant(QColor(0x08, 0x30, 0x6b)),
};
const QVariant ADSBDemodSettings::m_purplePalette[8] = {
QVariant(QColor(0xcc, 0xaf, 0xf2)),
QVariant(QColor(0xb6, 0x99, 0xe0)),
QVariant(QColor(0xa0, 0x84, 0xcf)),
QVariant(QColor(0x8a, 0x6f, 0xbd)),
QVariant(QColor(0x76, 0x5a, 0xac)),
QVariant(QColor(0x62, 0x45, 0x9a)),
QVariant(QColor(0x4f, 0x30, 0x89)),
QVariant(QColor(0x3e, 0x18, 0x78)),
};
const QVariant ADSBDemodSettings::m_greyPalette[8] = {
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
};
const QHash<QString, const QVariant *> ADSBDemodSettings::m_palettes = {
{"Rainbow", &ADSBDemodSettings::m_rainbowPalette[0]},
{"Pastel", &ADSBDemodSettings::m_pastelPalette[0]},
{"Spectral", &ADSBDemodSettings::m_spectralPalette[0]},
{"Blues", &ADSBDemodSettings::m_bluePalette[0]},
{"Purples", &ADSBDemodSettings::m_purplePalette[0]},
{"Grey", &ADSBDemodSettings::m_greyPalette[0]},
};

View File

@ -29,63 +29,89 @@
class Serializable;
// Number of columns in the table
#define ADSBDEMOD_COLUMNS 54
#define ADSBDEMOD_COLUMNS 78
// ADS-B table columns
#define ADSB_COL_ICAO 0
#define ADSB_COL_CALLSIGN 1
#define ADSB_COL_ATC_CALLSIGN 2
#define ADSB_COL_MODEL 3
#define ADSB_COL_AIRLINE 4
#define ADSB_COL_COUNTRY 5
#define ADSB_COL_GROUND_SPEED 6
#define ADSB_COL_TRUE_AIRSPEED 7
#define ADSB_COL_INDICATED_AIRSPEED 8
#define ADSB_COL_MACH 9
#define ADSB_COL_SEL_ALTITUDE 10
#define ADSB_COL_ALTITUDE 11
#define ADSB_COL_VERTICALRATE 12
#define ADSB_COL_SEL_HEADING 13
#define ADSB_COL_HEADING 14
#define ADSB_COL_TURNRATE 15
#define ADSB_COL_ROLL 16
#define ADSB_COL_RANGE 17
#define ADSB_COL_AZEL 18
#define ADSB_COL_CATEGORY 19
#define ADSB_COL_STATUS 20
#define ADSB_COL_SQUAWK 21
#define ADSB_COL_REGISTRATION 22
#define ADSB_COL_REGISTERED 23
#define ADSB_COL_MANUFACTURER 24
#define ADSB_COL_OWNER 25
#define ADSB_COL_OPERATOR_ICAO 26
#define ADSB_COL_AP 27
#define ADSB_COL_V_MODE 28
#define ADSB_COL_L_MODE 29
#define ADSB_COL_BARO 30
#define ADSB_COL_HEADWIND 31
#define ADSB_COL_EST_AIR_TEMP 32
#define ADSB_COL_WIND_SPEED 33
#define ADSB_COL_WIND_DIR 34
#define ADSB_COL_STATIC_PRESSURE 35
#define ADSB_COL_STATIC_AIR_TEMP 36
#define ADSB_COL_HUMIDITY 37
#define ADSB_COL_LATITUDE 38
#define ADSB_COL_LONGITUDE 39
#define ADSB_COL_TIME 40
#define ADSB_COL_FRAMECOUNT 41
#define ADSB_COL_TIS_B 42
#define ADSB_COL_CORRELATION 43
#define ADSB_COL_RSSI 44
#define ADSB_COL_FLIGHT_STATUS 45
#define ADSB_COL_DEP 46
#define ADSB_COL_ARR 47
#define ADSB_COL_STD 48
#define ADSB_COL_ETD 49
#define ADSB_COL_ATD 50
#define ADSB_COL_STA 51
#define ADSB_COL_ETA 52
#define ADSB_COL_ATA 53
#define ADSB_COL_TYPE 4
#define ADSB_COL_SIDEVIEW 5
#define ADSB_COL_AIRLINE 6
#define ADSB_COL_COUNTRY 7
#define ADSB_COL_GROUND_SPEED 8
#define ADSB_COL_TRUE_AIRSPEED 9
#define ADSB_COL_INDICATED_AIRSPEED 10
#define ADSB_COL_MACH 11
#define ADSB_COL_SEL_ALTITUDE 12
#define ADSB_COL_ALTITUDE 13
#define ADSB_COL_VERTICALRATE 14
#define ADSB_COL_SEL_HEADING 15
#define ADSB_COL_HEADING 16
#define ADSB_COL_TRACK 17
#define ADSB_COL_TURNRATE 18
#define ADSB_COL_ROLL 19
#define ADSB_COL_RANGE 20
#define ADSB_COL_AZEL 21
#define ADSB_COL_CATEGORY 22
#define ADSB_COL_STATUS 23
#define ADSB_COL_SQUAWK 24
#define ADSB_COL_IDENT 25
#define ADSB_COL_REGISTRATION 26
#define ADSB_COL_REGISTERED 27
#define ADSB_COL_MANUFACTURER 28
#define ADSB_COL_OWNER 29
#define ADSB_COL_OPERATOR_ICAO 30
#define ADSB_COL_AP 31
#define ADSB_COL_V_MODE 32
#define ADSB_COL_L_MODE 33
#define ADSB_COL_TCAS 34
#define ADSB_COL_ACAS 35
#define ADSB_COL_RA 36
#define ADSB_COL_MAX_SPEED 37
#define ADSB_COL_VERSION 38
#define ADSB_COL_LENGTH 39
#define ADSB_COL_WIDTH 40
#define ADSB_COL_BARO 41
#define ADSB_COL_HEADWIND 42
#define ADSB_COL_EST_AIR_TEMP 43
#define ADSB_COL_WIND_SPEED 44
#define ADSB_COL_WIND_DIR 45
#define ADSB_COL_STATIC_PRESSURE 46
#define ADSB_COL_STATIC_AIR_TEMP 47
#define ADSB_COL_HUMIDITY 48
#define ADSB_COL_LATITUDE 49
#define ADSB_COL_LONGITUDE 50
#define ADSB_COL_IC 51
#define ADSB_COL_TIME 52
#define ADSB_COL_FRAMECOUNT 53
#define ADSB_COL_ADSB_FRAMECOUNT 54
#define ADSB_COL_MODES_FRAMECOUNT 55
#define ADSB_COL_NON_TRANSPONDER 56
#define ADSB_COL_TIS_B_FRAMECOUNT 57
#define ADSB_COL_ADSR_FRAMECOUNT 58
#define ADSB_COL_RADIUS 59
#define ADSB_COL_NACP 60
#define ADSB_COL_NACV 61
#define ADSB_COL_GVA 62
#define ADSB_COL_NIC 63
#define ADSB_COL_NIC_BARO 64
#define ADSB_COL_SIL 65
#define ADSB_COL_CORRELATION 66
#define ADSB_COL_RSSI 67
#define ADSB_COL_FLIGHT_STATUS 68
#define ADSB_COL_DEP 69
#define ADSB_COL_ARR 70
#define ADSB_COL_STOPS 71
#define ADSB_COL_STD 72
#define ADSB_COL_ETD 73
#define ADSB_COL_ATD 74
#define ADSB_COL_STA 75
#define ADSB_COL_ETA 76
#define ADSB_COL_ATA 77
#define ADSB_IC_MAX 63
struct ADSBDemodSettings
{
@ -104,6 +130,7 @@ struct ADSBDemodSettings
int32_t m_inputFrequencyOffset;
Real m_rfBandwidth;
Real m_correlationThreshold; //!< Correlation power threshold in dB
int m_chipsThreshold; //!< How many chips in preamble can be incorrect for Mode S
int m_samplesPerBit;
int m_removeTimeout; //!< Time in seconds before removing an aircraft, unless a new frame is received
@ -159,7 +186,6 @@ struct ADSBDemodSettings
QString m_tableFontName; //!< Font to use for table
int m_tableFontSize;
bool m_displayDemodStats;
bool m_correlateFullPreamble;
bool m_demodModeS; //!< Demodulate all Mode-S frames, not just ADS-B
QString m_amDemod; //!< AM Demod to tune to selected ATC frequency
bool m_autoResizeTableColumns;
@ -169,6 +195,7 @@ struct ADSBDemodSettings
QList<NotificationSettings *> m_notificationSettings;
QString m_aviationstackAPIKey; //!< aviationstack.com API key
QString m_checkWXAPIKey; //!< checkwxapi.com API key
QString m_maptilerAPIKey; //!< maptiler.com API key (for osm/satellite map)
QString m_logFilename;
bool m_logEnabled;
@ -186,13 +213,24 @@ struct ADSBDemodSettings
bool m_displayPhotos;
Serializable *m_rollupState;
bool m_verboseModelMatching;
int m_airfieldElevation; //!< QFE in ft so aircraft takeoff/land from correct position
int m_aircraftMinZoom;
bool m_atcLabels;
bool m_atcCallsigns;
int m_transitionAlt;
float m_qnh;
bool m_manualQNH;
bool m_displayCoverage;
bool m_displayChart;
bool m_displayOrientation;
bool m_displayRadius;
bool m_displayIC[ADSB_IC_MAX];
QString m_flightPathPaletteName;
bool m_favourLivery; //!< Favour airline livery over aircraft type when exact 3D model isn't available
const QVariant *m_flightPathPalette;
ADSBDemodSettings();
void resetToDefaults();
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
@ -203,6 +241,16 @@ struct ADSBDemodSettings
void deserializeNotificationSettings(const QByteArray& data, QList<NotificationSettings *>& notificationSettings);
void applySettings(const QStringList& settingsKeys, const ADSBDemodSettings& settings);
QString getDebugString(const QStringList& settingsKeys, bool force = false) const;
void applyPalette();
static const QVariant m_rainbowPalette[8];
static const QVariant m_pastelPalette[8];
static const QVariant m_spectralPalette[8];
static const QVariant m_bluePalette[8];
static const QVariant m_purplePalette[8];
static const QVariant m_greyPalette[8];
static const QHash<QString, const QVariant *> m_palettes;
};
#endif /* PLUGINS_CHANNELRX_DEMODADSB_ADSBDEMODSETTINGS_H_ */

View File

@ -19,14 +19,16 @@
#include <QTime>
#include <QDebug>
#include "util/profiler.h"
#include "adsbdemodsink.h"
#include "adsbdemodsinkworker.h"
#include "adsbdemod.h"
#include "adsb.h"
ADSBDemodSink::ADSBDemodSink() :
m_channelSampleRate(6000000),
m_channelFrequencyOffset(0),
m_feedTime(0.0),
m_sampleBuffer{nullptr, nullptr, nullptr},
m_worker(this),
m_writeBuffer(0),
@ -53,7 +55,7 @@ ADSBDemodSink::~ADSBDemodSink()
void ADSBDemodSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
{
// Start timing how long we are in this function
m_startPoint = boost::chrono::steady_clock::now();
PROFILER_START();
// Optimise for common case, where no resampling or frequency offset
if ((m_interpolatorDistance == 1.0f) && (m_channelFrequencyOffset == 0))
@ -113,8 +115,7 @@ void ADSBDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
}
// Calculate number of seconds in this function
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - m_startPoint;
m_feedTime += sec.count();
PROFILER_STOP("ADSB feed");
}
void ADSBDemodSink::processOneSample(Real magsq)
@ -127,8 +128,17 @@ void ADSBDemodSink::processOneSample(Real magsq)
m_writeIdx++;
if (!m_bufferDateTimeValid[m_writeBuffer])
{
m_bufferFirstSampleDateTime[m_writeBuffer] = QDateTime::currentDateTime();
QDateTime dateTime = QDateTime::currentDateTime();
if (m_minFirstSampleDateTime.isValid() && (dateTime < m_minFirstSampleDateTime)) {
dateTime = m_minFirstSampleDateTime;
}
m_bufferFirstSampleDateTime[m_writeBuffer] = dateTime;
m_bufferDateTimeValid[m_writeBuffer] = true;
// Make sure timestamps from different buffers are in order, even if we receive samples faster than real time
const qint64 samplesPerSecondMSec = ADS_B_BITS_PER_SECOND * m_settings.m_samplesPerBit / 1000;
const qint64 offsetMSec = m_bufferSize / samplesPerSecondMSec;
m_minFirstSampleDateTime = dateTime.addMSecs(offsetMSec);
}
if (m_writeIdx >= m_bufferSize)
{
@ -138,15 +148,9 @@ void ADSBDemodSink::processOneSample(Real magsq)
if (m_writeBuffer >= m_buffers)
m_writeBuffer = 0;
// Don't include time spent waiting for a buffer
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - m_startPoint;
m_feedTime += sec.count();
if (m_worker.isRunning())
m_bufferWrite[m_writeBuffer].acquire();
m_startPoint = boost::chrono::steady_clock::now();
m_writeIdx = m_samplesPerFrame - 1; // Leave space for copying samples from previous buffer
m_bufferDateTimeValid[m_writeBuffer] = false;
@ -253,7 +257,6 @@ void ADSBDemodSink::applySettings(const ADSBDemodSettings& settings, const QStri
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
<< " m_rfBandwidth: " << settings.m_rfBandwidth
<< " m_correlationThreshold: " << settings.m_correlationThreshold
<< " m_correlateFullPreamble: " << settings.m_correlateFullPreamble
<< " m_demodModeS: " << settings.m_demodModeS
<< " m_samplesPerBit: " << settings.m_samplesPerBit
<< " force: " << force;
@ -285,3 +288,9 @@ void ADSBDemodSink::applySettings(const ADSBDemodSettings& settings, const QStri
m_settings.applySettings(settingsKeys, settings);
}
}
void ADSBDemodSink::resetStats()
{
ADSBDemod::MsgResetStats* msg = ADSBDemod::MsgResetStats::create();
m_worker.getInputMessageQueue()->push(msg);
}

View File

@ -19,9 +19,6 @@
#ifndef INCLUDE_ADSBDEMODSINK_H
#define INCLUDE_ADSBDEMODSINK_H
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono/chrono.hpp>
#include "dsp/channelsamplesink.h"
#include "dsp/nco.h"
#include "dsp/interpolator.h"
@ -60,6 +57,7 @@ public:
void setMessageQueueToWorker(MessageQueue *messageQueue) { m_messageQueueToWorker = messageQueue; }
void startWorker();
void stopWorker();
void resetStats();
private:
friend ADSBDemodSinkWorker;
@ -83,9 +81,6 @@ private:
Real m_interpolatorDistance;
Real m_interpolatorDistanceRemain;
boost::chrono::steady_clock::time_point m_startPoint;
double m_feedTime; //!< Time spent in feed()
// Triple buffering for sharing sample data between two threads
// Top area of each buffer is not used by writer, as it's used by the reader
// for copying the last few samples of the previous buffer, so it can
@ -96,6 +91,7 @@ private:
QSemaphore m_bufferWrite[3]; //!< Semaphore to control write access to the buffers
QSemaphore m_bufferRead[3]; //!< Semaphore to control read access from the buffers
QDateTime m_bufferFirstSampleDateTime[3]; //!< Time for first sample in the buffer
QDateTime m_minFirstSampleDateTime;
bool m_bufferDateTimeValid[3];
ADSBDemodSinkWorker m_worker; //!< Worker thread that does the actual demodulation
int m_writeBuffer; //!< Which of the 3 buffers we're writing in to

View File

@ -15,30 +15,288 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono/chrono.hpp>
#include <QDebug>
#include "util/db.h"
#include "util/profiler.h"
#include "util/units.h"
#include "util/osndb.h"
#include "util/popcount.h"
#include "adsbdemodreport.h"
#include "adsbdemodsink.h"
#include "adsbdemodsinkworker.h"
#include "adsbdemodsettings.h"
#include "adsbdemod.h"
#include "adsb.h"
MESSAGE_CLASS_DEFINITION(ADSBDemodSinkWorker::MsgConfigureADSBDemodSinkWorker, Message)
const Real ADSBDemodSinkWorker::m_correlationScale = 3.0f;
static int grayToBinary(int gray, int bits)
{
int binary = 0;
for (int i = bits - 1; i >= 0; i--) {
binary = binary | ((((1 << (i+1)) & binary) >> 1) ^ ((1 << i) & gray));
}
return binary;
}
static int gillhamToFeet(int n)
{
int c1 = (n >> 10) & 1;
int a1 = (n >> 9) & 1;
int c2 = (n >> 8) & 1;
int a2 = (n >> 7) & 1;
int c4 = (n >> 6) & 1;
int a4 = (n >> 5) & 1;
int b1 = (n >> 4) & 1;
int b2 = (n >> 3) & 1;
int d2 = (n >> 2) & 1;
int b4 = (n >> 1) & 1;
int d4 = n & 1;
int n500 = grayToBinary((d2 << 7) | (d4 << 6) | (a1 << 5) | (a2 << 4) | (a4 << 3) | (b1 << 2) | (b2 << 1) | b4, 4);
int n100 = grayToBinary((c1 << 2) | (c2 << 1) | c4, 3) - 1;
if (n100 == 6) {
n100 = 4;
}
if (n500 %2 != 0) {
n100 = 4 - n100;
}
return -1200 + n500*500 + n100*100;
}
static int decodeModeSAltitude(const QByteArray& data)
{
int altitude = 0; // Altitude in feet
int altitudeCode = ((data[2] & 0x1f) << 8) | (data[3] & 0xff);
if (altitudeCode & 0x40) // M bit indicates metres
{
int altitudeMetres = ((altitudeCode & 0x1f80) >> 1) | (altitudeCode & 0x3f);
altitude = Units::metresToFeet(altitudeMetres);
}
else
{
// Remove M and Q bits
int altitudeFix = ((altitudeCode & 0x1f80) >> 2) | ((altitudeCode & 0x20) >> 1) | (altitudeCode & 0xf);
// Convert to feet
if (altitudeCode & 0x10) {
altitude = altitudeFix * 25 - 1000;
} else {
altitude = gillhamToFeet(altitudeFix);
}
}
return altitude;
}
void ADSBDemodSinkWorker::handleModeS(unsigned char *data, int bytes, unsigned icao, int df, int firstIndex, unsigned short preamble, Real preambleCorrelation, Real correlationOnes, const QDateTime& dateTime, unsigned crc)
{
// Ignore downlink formats we can't decode / unlikely
if ((df != 19) && (df != 22) && (df < 24))
{
QList<RXRecord> l;
if (m_modeSOnlyIcaos.contains(icao))
{
l = m_modeSOnlyIcaos.value(icao);
if (abs(l.last().m_firstIndex - firstIndex) < 4) {
return; // Duplicate
}
}
else
{
// Stop hash table from getting too big - clear every 10 seconds or so
QDateTime currentDateTime = QDateTime::currentDateTime();
if (m_lastClear.secsTo(currentDateTime) >= 10)
{
//qDebug() << "Clearing ModeS only hash. size=" << m_modeSOnlyIcaos.size();
m_modeSOnlyIcaos.clear();
m_lastClear = currentDateTime;
}
}
RXRecord rx;
rx.m_data = QByteArray((char*)data, bytes);
rx.m_firstIndex = firstIndex;
rx.m_preamble = preamble;
rx.m_preambleCorrelation = preambleCorrelation;
rx.m_correlationOnes = correlationOnes;
rx.m_dateTime = dateTime;
rx.m_crc = crc;
l.append(rx);
m_modeSOnlyIcaos.insert(icao, l);
// Have we heard from the same address several times in the last 10 seconds?
if (l.size() >= 5)
{
// Check all frames have consistent altitudes and identifiers
bool idConsistent = true;
bool altitudeConsistent = true;
int altitude = -1;
int id = -1;
for (int i = 0; i < l.size(); i++)
{
int df2 = ((l[i].m_data[0] >> 3) & ADS_B_DF_MASK);
if ((df2 == 0) || (df2 == 4) || (df2 == 16) || (df2 == 20))
{
int curAltitude = decodeModeSAltitude(l[i].m_data);
if (altitude == -1)
{
altitude = curAltitude;
}
else
{
if (abs(curAltitude - altitude) > 1000) {
altitudeConsistent = false;
}
}
}
else if ((df2 == 5) || (df2 == 21))
{
int curId = ((data[2] & 0x1f) << 8) | (data[3] & 0xff); // No decode - we just want to know if it changes
if (id == -1)
{
id = curId;
}
else
{
if (id != curId) {
idConsistent = false;
}
}
}
}
// FIXME: We could optionally check to see if aircraft ICAO is in db, but the db isn't complete
if (altitudeConsistent && idConsistent)
{
// Forward all frames
for (int i = 0; i < l.size(); i++) {
forwardFrame((const unsigned char *) l[i].m_data.data(), l[i].m_data.size(), l[i].m_preambleCorrelation, l[i].m_correlationOnes, l[i].m_dateTime, l[i].m_crc);
}
m_icaos.insert(icao, l.back().m_dateTime.toMSecsSinceEpoch());
}
else
{
m_modeSOnlyIcaos.remove(icao);
}
}
}
}
// Check if a Mode S frame has reserved bits set or reserved field values
// Refer: Annex 10 Volume IV
bool ADSBDemodSinkWorker::modeSValid(unsigned char *data, unsigned df)
{
bool invalid = false;
if (df == 0)
{
invalid = ((data[0] & 0x1) | (data[1] & 0x18) | (data[2] & 0x60)) != 0;
}
else if ((df == 4) || (df == 20))
{
unsigned fs = data[0] & 0x3;
unsigned dr = (data[1] >> 3) & 0x1f;
invalid = (fs == 6) || (fs == 7) || ((dr >= 8) && (dr <= 15));
}
else if ((df == 5) || (df == 21))
{
unsigned fs = data[0] & 0x3;
unsigned dr = (data[1] >> 3) & 0x1f;
invalid = (fs == 6) || (fs == 7) || ((dr >= 8) && (dr <= 15)) || ((data[3] & 0x40) != 0);
}
else if (df == 11)
{
unsigned ca = data[0] & 0x7;
invalid = ((ca >= 1) && (ca <= 3));
}
else if (df == 16)
{
invalid = ((data[0] & 0x3) | (data[1] & 0x18) | (data[2] & 0x60)) != 0;
}
return invalid;
}
// Check if valid ICAO address - i.e. not a reserved address - see Table 9-1 in Annex X Volume III
bool ADSBDemodSinkWorker::icaoValid(unsigned icao)
{
unsigned msn = (icao >> 20) & 0xf;
return (icao != 0) && (msn != 0xf) && (msn != 0xb) && (msn != 0xd);
}
// Is it less than a minute since the last received frame for this ICAO
bool ADSBDemodSinkWorker::icaoHeardRecently(unsigned icao, const QDateTime &dateTime)
{
const int timeLimitMSec = 60*1000;
if (m_icaos.contains(icao))
{
if ((dateTime.toMSecsSinceEpoch() - m_icaos.value(icao)) < timeLimitMSec) {
return true;
} else {
m_icaos.remove(icao);
}
}
return false;
}
void ADSBDemodSinkWorker::forwardFrame(const unsigned char *data, int size, float preambleCorrelation, float correlationOnes, const QDateTime& dateTime, unsigned crc)
{
// Pass to GUI
if (m_sink->getMessageQueueToGUI())
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, size),
preambleCorrelation,
correlationOnes,
dateTime,
crc);
m_sink->getMessageQueueToGUI()->push(msg);
}
// Pass to worker to feed to other servers
if (m_sink->getMessageQueueToWorker())
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, size),
preambleCorrelation,
correlationOnes,
dateTime,
crc);
m_sink->getMessageQueueToWorker()->push(msg);
}
}
void ADSBDemodSinkWorker::run()
{
int readBuffer = 0;
m_lastClear = QDateTime::currentDateTime();
// Acquire first buffer
m_sink->m_bufferRead[readBuffer].acquire();
if (isInterruptionRequested()) {
return;
}
// Start recording how much time is spent processing in this method
boost::chrono::steady_clock::time_point startPoint = boost::chrono::steady_clock::now();
PROFILER_START();
// Check for updated settings
handleInputMessages();
@ -52,8 +310,6 @@ void ADSBDemodSinkWorker::run()
<< " samplesPerFrame: " << samplesPerFrame
<< " samplesPerChip: " << samplesPerChip
<< " samplesPerBit: " << samplesPerBit
<< " correlateFullPreamble: " << m_settings.m_correlateFullPreamble
<< " correlationScale: " << m_correlationScale
<< " correlationThreshold: " << m_settings.m_correlationThreshold;
int readIdx = m_sink->m_samplesPerFrame - 1;
@ -64,61 +320,33 @@ void ADSBDemodSinkWorker::run()
// Correlate received signal with expected preamble
// chip+ indexes are 0, 2, 7, 9
// correlating over first 6 bits gives a reduction in per-sample
// processing, but more than doubles the number of false matches
Real preambleCorrelationOnes = 0.0;
Real preambleCorrelationZeros = 0.0;
if (m_settings.m_correlateFullPreamble)
for (int i = 0; i < samplesPerChip; i++)
{
for (int i = 0; i < samplesPerChip; i++)
{
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 12*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 13*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 12*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 13*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 14*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 15*samplesPerChip + i];
}
}
else
{
for (int i = 0; i < samplesPerChip; i++)
{
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
}
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 14*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 15*samplesPerChip + i];
}
// Use the ratio of ones power over zeros power, as we don't care how powerful the signal
@ -139,6 +367,7 @@ void ADSBDemodSinkWorker::run()
int firstIdx = startIdx;
m_demodStats.m_correlatorMatches++;
// Skip over preamble
startIdx += samplesPerBit*ADS_B_PREAMBLE_BITS;
@ -148,6 +377,7 @@ void ADSBDemodSinkWorker::run()
int currentBit;
unsigned char currentByte = 0;
int df;
int firstIndex = 0;
for (int bit = 0; bit < ADS_B_ES_BITS; bit++)
{
@ -166,6 +396,9 @@ void ADSBDemodSinkWorker::run()
currentByte |= currentBit << (7-(bit & 0x7));
if ((bit & 0x7) == 0x7)
{
if (byteIdx == 0) {
firstIndex = startIdx;
}
data[byteIdx++] = currentByte;
currentByte = 0;
// Don't try to demodulate any further, if this isn't an ADS-B frame
@ -179,6 +412,10 @@ void ADSBDemodSinkWorker::run()
}
}
Real preambleCorrelationScaled = preambleCorrelation * m_correlationScale;
Real correlationOnes = preambleCorrelationOnes / samplesPerChip;
QDateTime dateTime = rxDateTime(firstIdx, readBuffer);
// Is ADS-B?
df = ((data[0] >> 3) & ADS_B_DF_MASK);
if ((df == 17) || (df == 18))
@ -189,109 +426,177 @@ void ADSBDemodSinkWorker::run()
m_crc.calculate(data, ADS_B_ES_BYTES-3);
if (parity == m_crc.get())
{
// Got a valid frame
m_demodStats.m_adsbFrames++;
// Get 24-bit ICAO and save in hash of ICAOs that have been seen
// Get 24-bit ICAO
unsigned icao = ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff);
m_icaos.insert(icao, true);
// Don't try to re-demodulate the same frame
// We could possibly allow a partial overlap here
readIdx += (ADS_B_ES_BITS+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
// Pass to GUI
if (m_sink->getMessageQueueToGUI())
if (icaoValid(icao))
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, sizeof(data)),
preambleCorrelation * m_correlationScale,
preambleCorrelationOnes / samplesPerChip,
rxDateTime(firstIdx, readBuffer),
m_crc.get());
m_sink->getMessageQueueToGUI()->push(msg);
// Got a valid frame
m_demodStats.m_adsbFrames++;
// Save in hash of ICAOs that have been seen
m_icaos.insert(icao, dateTime.toMSecsSinceEpoch());
// Don't try to re-demodulate the same frame
// We could possibly allow a partial overlap here
readIdx += (ADS_B_ES_BITS+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
forwardFrame(data, sizeof(data), preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
}
// Pass to worker to feed to other servers
if (m_sink->getMessageQueueToWorker())
else
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, sizeof(data)),
preambleCorrelation * m_correlationScale,
preambleCorrelationOnes / samplesPerChip,
rxDateTime(firstIdx, readBuffer),
m_crc.get());
m_sink->getMessageQueueToWorker()->push(msg);
m_demodStats.m_icaoFails++;
}
}
else
{
m_demodStats.m_crcFails++;
}
}
else if (m_settings.m_demodModeS)
{
int bytes;
// Decode premable, as correlation alone results in too many false positives for Mode S frames
startIdx = readIdx;
unsigned short preamble = 0;
QVector<float> preambleChips(16);
// Determine number of bytes in frame depending on downlink format
if ((df == 0) || (df == 4) || (df == 5) || (df == 11)) {
bytes = 56/8;
} else if ((df == 16) || (df == 20) || (df == 21) || (df >= 24)) {
bytes = 112/8;
} else {
bytes = 0;
}
if (bytes > 0)
for (int bit = 0; bit < ADS_B_PREAMBLE_BITS; bit++)
{
// Extract received parity
int parity = (data[bytes-3] << 16) | (data[bytes-2] << 8) | data[bytes-1];
// Calculate CRC on received frame
m_crc.init();
m_crc.calculate(data, bytes-3);
int crc = m_crc.get();
// DF4 / DF5 / DF20 / DF21 have ICAO address XORed in to parity.
// Extract ICAO from parity and see if it matches an aircraft we've already
// received an ADS-B frame from
if ((df == 4) || (df == 5) || (df == 20) || (df == 21))
preambleChips[bit*2] = 0.0f;
preambleChips[bit*2+1] = 0.0f;
for (int i = 0; i < samplesPerChip; i++)
{
unsigned icao = (parity ^ crc) & 0xffffff;
if (m_icaos.contains(icao)) {
crc ^= icao;
}
preambleChips[bit*2] += m_sink->m_sampleBuffer[readBuffer][startIdx+i];
preambleChips[bit*2+1] += m_sink->m_sampleBuffer[readBuffer][startIdx+samplesPerChip+i];
}
// For DF11, the last 7 bits may have an address/interogration identifier (II)
// XORed in, so we ignore those bits
if ((parity == crc) || ((df == 11) && ((parity & 0xffff80) == (crc & 0xffff80))))
startIdx += samplesPerBit;
}
startIdx = firstIdx;
float onesAvg = (preambleChips[0] + preambleChips[2] + preambleChips[7] + preambleChips[9]) / 4.0f;
float zerosAvg = (preambleChips[1] + preambleChips[3] + preambleChips[4] + preambleChips[5] + preambleChips[6] + preambleChips[8]
+ preambleChips[10] + + preambleChips[11] + preambleChips[12] + preambleChips[13] + preambleChips[14] + preambleChips[15]) / 12.0f;
float midPoint = zerosAvg + (onesAvg - zerosAvg) / 2.0f;
for (int i = 0; i < 16; i++)
{
unsigned chip = preambleChips[i] > midPoint;
preamble |= chip << (15-i);
}
// qDebug() << "Preamble" << preambleChips << "zerosAvg" << zerosAvg << "onesAvg" << onesAvg << "midPoint" << midPoint << "chips" << Qt::hex << preamble;
const unsigned short expectedPreamble = 0xa140;
int preambleDifferences = popcount(expectedPreamble ^ preamble);
if (preambleDifferences <= m_settings.m_chipsThreshold)
{
int bytes;
// Determine number of bytes in frame depending on downlink format
if ((df == 0) || (df == 4) || (df == 5) || (df == 11)) {
bytes = 56/8;
} else if ((df == 16) || (df == 19) || (df == 20) || (df == 21) || (df == 22) || ((df >= 24) && (df <= 27))) {
bytes = 112/8;
} else {
bytes = 0;
}
if (bytes > 0)
{
m_demodStats.m_modesFrames++;
// Pass to GUI (only pass formats it can decode)
if (m_sink->getMessageQueueToGUI() && ((df == 4) || (df == 5) || (df == 20) || (df == 21)))
bool invalid = modeSValid(data, df);
if (!invalid)
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, bytes),
preambleCorrelation * m_correlationScale,
preambleCorrelationOnes / samplesPerChip,
rxDateTime(firstIdx, readBuffer),
m_crc.get());
m_sink->getMessageQueueToGUI()->push(msg);
// Extract received parity
int parity = (data[bytes-3] << 16) | (data[bytes-2] << 8) | data[bytes-1];
// Calculate CRC on received frame
m_crc.init();
m_crc.calculate(data, bytes-3);
int crc = m_crc.get();
bool forward = false;
// ICAO address XORed in to parity, apart from DF11
// Extract ICAO from parity and see if it matches an aircraft we've already
// received an ADS-B or Mode S frame from
// For DF11, the last 7 bits may have an iterogration code (II/SI)
// XORed in, so we ignore those bits. This does sometimes lead to false-positives
if (df != 11)
{
unsigned icao = (parity ^ crc) & 0xffffff;
if (icaoValid(icao))
{
if (icaoHeardRecently(icao, dateTime)) {
forward = true;
} else {
handleModeS(data, bytes, icao, df, firstIndex, preamble, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
}
}
else
{
m_demodStats.m_icaoFails++;
}
}
else
{
// Ignore IC bits
parity &= 0xffff80;
crc &= 0xffff80;
if (parity == crc)
{
// Get 24-bit ICAO
unsigned icao = ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff);
if (icaoValid(icao))
{
if (icaoHeardRecently(icao, dateTime)) {
forward = true;
} else {
handleModeS(data, bytes, icao, df, firstIndex, preamble, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
}
}
else
{
m_demodStats.m_icaoFails++;
}
}
else
{
m_demodStats.m_crcFails++;
}
}
if (forward)
{
m_demodStats.m_modesFrames++;
// Don't try to re-demodulate the same frame
// We could possibly allow a partial overlap here
readIdx += ((bytes*8)+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
forwardFrame(data, bytes, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
}
else
{
m_demodStats.m_crcFails++;
}
}
// Pass to worker to feed to other servers
if (m_sink->getMessageQueueToWorker())
else
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, bytes),
preambleCorrelation * m_correlationScale,
preambleCorrelationOnes / samplesPerChip,
rxDateTime(firstIdx, readBuffer),
m_crc.get());
m_sink->getMessageQueueToWorker()->push(msg);
m_demodStats.m_invalidFails++;
}
}
else
{
m_demodStats.m_crcFails++;
m_demodStats.m_typeFails++;
}
}
else
m_demodStats.m_typeFails++;
{
m_demodStats.m_preambleFails++;
}
}
else
{
m_demodStats.m_typeFails++;
}
}
readIdx++;
if (readIdx > m_sink->m_bufferSize - samplesPerFrame)
{
@ -300,9 +605,7 @@ void ADSBDemodSinkWorker::run()
nextBuffer = 0;
// Update amount of time spent processing (don't include time spend in acquire)
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - startPoint;
m_demodStats.m_demodTime += sec.count();
m_demodStats.m_feedTime = m_sink->m_feedTime;
PROFILER_STOP("ADS-B demod");
// Send stats to GUI
if (m_sink->getMessageQueueToGUI())
@ -320,7 +623,7 @@ void ADSBDemodSinkWorker::run()
handleInputMessages();
// Resume timing how long we are processing
startPoint = boost::chrono::steady_clock::now();
PROFILER_RESTART();
int samplesRemaining = m_sink->m_bufferSize - readIdx;
if (samplesRemaining > 0)
@ -360,15 +663,6 @@ void ADSBDemodSinkWorker::handleInputMessages()
QStringList settingsKeys = cfg->getSettingsKeys();
bool force = cfg->getForce();
if (settingsKeys.contains("correlateFullPreamble") || force)
{
if (settings.m_correlateFullPreamble) {
m_correlationScale = 3.0;
} else {
m_correlationScale = 2.0;
}
}
if ((settingsKeys.contains("correlationThreshold") && (m_settings.m_correlationThreshold != settings.m_correlationThreshold)) || force)
{
m_correlationThresholdLinear = CalcDb::powerFromdB(settings.m_correlationThreshold);
@ -383,6 +677,10 @@ void ADSBDemodSinkWorker::handleInputMessages()
}
delete message;
}
else if (ADSBDemod::MsgResetStats::match(*message))
{
m_demodStats.reset();
}
}
}

View File

@ -26,10 +26,9 @@
#include "util/message.h"
#include "util/messagequeue.h"
#include "adsbdemodstats.h"
#include "adsbdemodsettings.h"
class ADSBDemodSink;
struct ADSBDemodSettings;
struct ADSBDemodStats;
class ADSBDemodSinkWorker : public QThread {
Q_OBJECT
@ -78,11 +77,29 @@ private:
ADSBDemodSink *m_sink;
ADSBDemodStats m_demodStats;
Real m_correlationThresholdLinear;
Real m_correlationScale;
static const Real m_correlationScale;
crcadsb m_crc; //!< Have as member to avoid recomputing LUT
QHash<int, bool> m_icaos; //!< ICAO addresses that have been received
QHash<unsigned, qint64> m_icaos; //!< ICAO addresses that have been received and msecsSinceEpoch last heard
QDateTime m_lastClear;
struct RXRecord {
QByteArray m_data;
int m_firstIndex;
unsigned short m_preamble;
Real m_preambleCorrelation;
Real m_correlationOnes;
QDateTime m_dateTime;
unsigned m_crc;
};
QHash<int, QList<RXRecord>> m_modeSOnlyIcaos;
QDateTime rxDateTime(int firstIdx, int readBuffer) const;
void handleModeS(unsigned char *data, int bytes, unsigned icao, int df, int firstIndex, unsigned short preamble, Real preambleCorrelation, Real correlationOnes, const QDateTime& dateTime, unsigned crc);
void forwardFrame(const unsigned char *data, int size, float preambleCorrelation, float correlationOnes, const QDateTime& dateTime, unsigned crc);
bool icaoHeardRecently(unsigned icao, const QDateTime &dateTime);
static bool icaoValid(unsigned icao);
static bool modeSValid(unsigned char *data, unsigned df);
};

View File

@ -25,20 +25,27 @@ struct ADSBDemodStats {
qint64 m_correlatorMatches; //!< Total number of correlator matches
qint64 m_adsbFrames; //!< How many ADS-B frames with correct CRCs
qint64 m_modesFrames; //!< How many non-ADS-B Mode-S frames with correct CRCs
qint64 m_preambleFails; //!< How many non-ADS-B Mode S frames with errors in preamble
qint64 m_crcFails; //!< How many frames we've demoded with incorrect CRCs
qint64 m_typeFails; //!< How many frames we've demoded with unknown type (DF) so we can't check CRC
double m_demodTime; //!< How long we've spent in run()
double m_feedTime; //!< How long we've spent in feed()
qint64 m_invalidFails; //!< How many frames we've demoded with reserved bits set
qint64 m_icaoFails; //!< How many frames we've demoded with reserved ICAO
ADSBDemodStats() :
m_correlatorMatches(0),
m_adsbFrames(0),
m_modesFrames(0),
m_crcFails(0),
m_typeFails(0),
m_demodTime(0.0),
m_feedTime(0.0)
ADSBDemodStats()
{
reset();
}
void reset()
{
m_correlatorMatches = 0;
m_adsbFrames = 0;
m_modesFrames = 0;
m_preambleFails = 0;
m_crcFails = 0;
m_typeFails = 0;
m_invalidFails = 0;
m_icaoFails = 0;
}
};

View File

@ -67,14 +67,14 @@ private slots:
{
xml = QString("\
{\
\"UrlTemplate\" : \"https://maps.wikimedia.org/osm-intl/%z/%x/%y%1.png\",\
\"UrlTemplate\" : \"https://tile.openstreetmap.org/%z/%x/%y.png\",\
\"ImageFormat\" : \"png\",\
\"QImageFormat\" : \"Indexed8\",\
\"ID\" : \"wmf-intl-%2x\",\
\"ID\" : \"osm-%1x\",\
\"MaximumZoomLevel\" : 18,\
\"MapCopyRight\" : \"<a href='https://wikimediafoundation.org/wiki/Terms_of_Use'>WikiMedia Foundation</a>\",\
\"DataCopyRight\" : \"<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors\"\
}").arg(hiresURL).arg(hires ? 1 : 2);
}").arg(hires ? 1 : 2);
}
else if (tokens[1] == "/satellite")
{

View File

@ -30,7 +30,7 @@
const PluginDescriptor ADSBPlugin::m_pluginDescriptor = {
ADSBDemod::m_channelId,
QStringLiteral("ADS-B Demodulator"),
QStringLiteral("7.22.3"),
QStringLiteral("7.22.6"),
QStringLiteral("(c) Jon Beniston, M7RCE"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Some files were not shown because too many files have changed in this diff Show More