Procházet zdrojové kódy

add qth_locator.py and fix things

Pierre Bourdin před 1 týdnem
rodič
revize
9ccb6f0a4b
8 změnil soubory, kde provedl 324 přidání a 79 odebrání
  1. 206 0
      qth_locator.py
  2. binární
      tx_process/.3_transmit.swp
  3. 32 16
      tx_process/3_transmit
  4. 24 11
      tx_process/easter1
  5. 17 12
      tx_process/easter2
  6. 11 11
      tx_process/easter3
  7. 18 12
      tx_process/easter4
  8. 16 17
      tx_process/easter5

+ 206 - 0
qth_locator.py

@@ -0,0 +1,206 @@
+#!/usr/bin/python3
+
+
+"""
+Created on Mar 3, 2017
+
+@author: 4X5DM
+@other: F4IYQ
+"""
+
+from math import floor
+import argparse
+
+# Constants
+ASCII_0 = 48
+ASCII_A = 65
+ASCII_a = 97
+
+# argparse
+parser = argparse.ArgumentParser(description='Convert QTH locator to latitude and longitude.')
+
+subparsers = parser.add_subparsers()
+p_square_to_location = subparsers.add_parser('square_to_location', help='Convert QTH locator to latitude and longitude')
+p_square_to_location.set_defaults(func='square_to_location')
+p_square_to_location.add_argument('qth_locator', type=str, help='QTH locator in format AA00 or AA00aa00')
+
+p_location_to_square = subparsers.add_parser('location_to_square', help='Convert latitude and longitude to QTH locator')
+p_location_to_square.set_defaults(func='location_to_square')
+p_location_to_square.add_argument('--lat', type=float, help='Latitude in decimal format')
+p_location_to_square.add_argument('--lon', type=float, help='Longitude in decimal format')
+
+p_test = subparsers.add_parser('test', help='Test QTH locator conversion')
+p_test.set_defaults(func='test')
+
+args = parser.parse_args()
+
+def square_to_location(qth_locator):
+    """
+    Converts QTH locator to latitude and longitude in decimal format.
+    Gets QTH locator as string.
+    Returns Tuple containing latitude and longitude as floats.
+    """
+
+    # Validate input
+    assert isinstance(qth_locator, str)
+    assert 4 <= len(qth_locator) <= 8
+    assert len(qth_locator) % 2 == 0
+
+    qth_locator = qth_locator.upper()
+
+    # Separate fields, squares and subsquares
+    # Fields
+    lon_field = ord(qth_locator[0]) - ASCII_A
+    lat_field = ord(qth_locator[1]) - ASCII_A
+
+    # Squares
+    lon_sq = ord(qth_locator[2]) - ASCII_0
+    lat_sq = ord(qth_locator[3]) - ASCII_0
+
+    # Subsquares
+    if len(qth_locator) >= 6:
+        lon_sub_sq = ord(qth_locator[4]) - ASCII_A
+        lat_sub_sq = ord(qth_locator[5]) - ASCII_A
+    else:
+        lon_sub_sq = 0
+        lat_sub_sq = 0
+
+    # Extended squares
+    if len(qth_locator) == 8:
+        lon_ext_sq = ord(qth_locator[6]) - ASCII_0
+        lat_ext_sq = ord(qth_locator[7]) - ASCII_0
+    else:
+        lon_ext_sq = 0
+        lat_ext_sq = 0
+
+    # Calculate latitude and longitude
+    lon = -180.0
+    lat = -90.0
+
+    lon += 20.0 * lon_field
+    lat += 10.0 * lat_field
+
+    lon += 2.0 * lon_sq
+    lat += 1.0 * lat_sq
+
+    lon += 5.0 / 60 * lon_sub_sq
+    lat += 2.5 / 60 * lat_sub_sq
+
+    lon += 0.5 / 60 * lon_ext_sq
+    lat += 0.25 / 60 * lat_ext_sq
+
+    return lat, lon
+
+
+def location_to_square(lat, lon):
+    """
+    Converts latitude and longitude in decimal format to QTH locator.
+    Gets latitude and longitude as floats.
+    Returns QTH locator as string.
+    """
+
+    # Validate input
+    assert isinstance(lat, (int, float))
+    assert isinstance(lon, (int, float))
+    assert -90.0 <= lat <= 90.0
+    assert -180.0 <= lon <= 180.0
+
+    # Separate fields, squares and subsquares
+    lon += 180
+    lat += 90
+
+    # Fields
+    lon_field = int(floor(lon / 20))
+    lat_field = int(floor(lat / 10))
+
+    lon -= lon_field * 20
+    lat -= lat_field * 10
+
+    # Squares
+    lon_sq = int(floor(lon / 2))
+    lat_sq = int(floor(lat / 1))
+
+    lon -= lon_sq * 2
+    lat -= lat_sq * 1
+
+    # Subsquares
+    lon_sub_sq = int(floor(lon / (5.0 / 60)))
+    lat_sub_sq = int(floor(lat / (2.5 / 60)))
+
+    lon -= lon_sub_sq * (5.0 / 60)
+    lat -= lat_sub_sq * (2.5 / 60)
+
+    # Extended squares
+    lon_ext_sq = int(round(lon / (0.5 / 60)))
+    lat_ext_sq = int(round(lat / (0.25 / 60)))
+
+    qth_locator = f'{chr(lon_field + ASCII_A)}'
+    qth_locator += chr(lat_field + ASCII_A)
+
+    qth_locator += chr(lon_sq + ASCII_0)
+    qth_locator += chr(lat_sq + ASCII_0)
+
+    if lon_sub_sq > 0 or lat_sub_sq > 0 or lon_ext_sq > 0 or lat_ext_sq > 0:
+        qth_locator += chr(lon_sub_sq + ASCII_a)
+        qth_locator += chr(lat_sub_sq + ASCII_a)
+
+    if lon_ext_sq > 0 or lat_ext_sq > 0:
+        qth_locator += chr(lon_ext_sq + ASCII_0)
+        qth_locator += chr(lat_ext_sq + ASCII_0)
+
+    return qth_locator
+
+
+if __name__ == '__main__':
+
+    if args.func == 'test':
+        print('Testing QTH Locator conversion...')
+        squares = [
+        ('JJ00', (0, 0)),
+        ('KM32', (32, 26)),
+        ('KM32jn07', (32.570831, 26.750003)),
+        ('KM72kk55', (32.437487, 34.875015)),
+        ('JN45fo', (45.603333, 8.456667)),
+        ('KO92so', (52.601484, 39.565160)),
+        ('KM72jb', (32.071209, 34.780089)),
+        # ('', (0, 0)),
+        # ('', (0, 0)),
+        ]
+
+        print('\nQTH locator to coordinates:')
+        for sq, res in squares:
+            loc = square_to_location(sq)
+            print(f'{sq}: {res}, calculated: {loc}')
+
+        print('\nCoordinates to QTH locator:')
+        for sq, loc in squares:
+            qth = location_to_square(loc[0], loc[1])
+            print(f'{loc}: {sq}, calculated: {qth}')
+
+    if args.func == 'square_to_location':
+        qth = args.qth_locator
+        lat, lon = square_to_location(qth)
+        print(f'QTH locator: {qth}, calculated coordinates: {lat}, {lon}')
+        exit(0)
+
+    if args.func == 'location_to_square':
+        lat = args.lat
+        lon = args.lon
+        if lat is None or lon is None:
+            parser.print_help()
+            exit(1)
+        if lat == 0 and lon == 0:
+            print('Error: latitude and longitude cannot be both zero.')
+            exit(1)
+        if lat < -90 or lat > 90:
+            print('Error: latitude must be between -90 and 90.')
+            exit(1)
+        if lon < -180 or lon > 180:
+            print('Error: longitude must be between -180 and 180.')
+            exit(1)
+        qth = location_to_square(lat, lon).upper()
+        print(qth)
+        exit(0)
+
+
+    print('\nDone.')

binární
tx_process/.3_transmit.swp


+ 32 - 16
tx_process/3_transmit

@@ -27,31 +27,47 @@ echo " => Playing WAV file"
 cd ~/trxamadrmv3_7/linux
 ./txwfal 0
 sleep 1
-aplay ~/BallonSonde/sound/2025_stpourcain/1_prez.wav
-ionice -c 2 -n 0 aplay /ramfs/out.wav
+
+
+############################
+# Partie prez + SSTV
+#aplay ~/BallonSonde/sound/2025_stpourcain/1_prez.wav
+#ionice -c 2 -n 0 aplay /ramfs/out.wav
 
 sleep 1
 
-aplay ~/BallonSonde/sound/2025_stpourcain/2_qpsq31.wav
-# Generate the wav file to Tx
-/home/pi/BallonSonde/tx_process/qpsk31
-# Tx the wav file !
-aplay /ramfs/psk.wav
+
+###########################
+# Partie QPSK31
+
+#aplay ~/BallonSonde/sound/2025_stpourcain/2_qpsq31.wav
+#/home/pi/BallonSonde/tx_process/qpsk31
+#aplay /ramfs/psk.wav
+
+###########################
+# Partie CW super crade
+ARGS=$(/home/pi/BallonSonde/read_nmea.py | awk '{print $3 $5}' | awk -F'[=,]' '{print "--lat " $2 " --lon " $4}')
+QTH=$(~/BallonSonde/qth_locator.py location_to_square $ARGS)
+
+MESSAGE="F4KOA-AM F4KOA-AM from France 
+QTH : $QTH 
+PEACE FOR ALL 
+"
 
 aplay ~/BallonSonde/sound/2025_stpourcain/3_cw.wav
-echo "F4KOA-AM F4KOA-AM from France" | /usr/local/bin/cwwav -f 700 -w 20 -o /ramfs/cw.wav
-aplay /ramfs/cw.wav; rm /ramfs/cw.wav
-# On se passe 
-#/home/pi/BallonSonde/read_nmea.py | awk '{print $10$3$4$5$6}' | sed -e "s/,/ /g" | sed -e "s/ NS=//g" | sed -e "s/ EW=//g" | sed -e "s/=/ /g" | /usr/local/bin/cwwav -f 700 -w 20 -o /ramfs/cw.wav
-# alt 311.7 lat 46.0154466667N lon 1.0988666667E for example...
-#aplay /ramfs/cw.wav; rm /ramfs/cw.wav
-
-aplay ~/BallonSonde/sound/2025_stpourcain/4_stop.wav
+echo $MESSAGE | /usr/local/bin/cwwav -f 700 -w 22 -o /ramfs/cw.wav; aplay /ramfs/cw.wav; rm /ramfs/cw.wav
+
+##########################
+# Stop Message
+
+#aplay ~/BallonSonde/sound/2025_stpourcain/4_stop.wav
+# On coupe le TX# 
 raspi-gpio set 4 dh
 
+##########################
 # un peu de repos pour le transceiver :)
 # et ça aide au GPS pour retrouver ses petits.
-sleep 30
+#sleep 30
 
 if [[ -f /ramfs/out.wav ]]; then
 	echo " => All done, cleaning ramfs"

+ 24 - 11
tx_process/easter1

@@ -1,11 +1,24 @@
-          _     _
-         /\`\ /`/\
-         \/\ V /\/
-           /6 6\
-          (= Y =)
-          /`"^"`\
-         / /   \ \
-        (_/     \_)
-         /       \o
-      ___\       /___
-     (((____/^\____)))
+              _-o#&&*''''?d:>b\_
+          _o/"`''  '',, dMF9MMMMMHo_
+       .o&#'        `"MbHMMMMMMMMMMMHo.
+     .o"" '         vodM*$&&HMMMMMMMMMM?.
+    ,'              $M&ood,~'`(&##MMMMMMH\
+   /               ,MMMMMMM#b?#bobMMMMHMMML
+  &              ?MMMMMMMMMMMMMMMMM7MMM$R*Hk
+ ?$.            :MMMMMMMMMMMMMMMMMMM/HMMM|`*L
+|               |MMMMMMMMMMMMMMMMMMMMbMH'   T,
+$H#:            `*MMMMMMMMMMMMMMMMMMMMb#}'  `?
+]MMH#             ""*""""*#MMMMMMMMMMMMM'    -
+MMMMMb_                   |MMMMMMMMMMMP'     :
+HMMMMMMMHo                 `MMMMMMMMMT       .
+?MMMMMMMMP                  9MMMMMMMM}       -
+-?MMMMMMM                  |MMMMMMMMM?,d-    '
+ :|MMMMMM-                 `MMMMMMMT .M|.   :
+  .9MMM[                    &MMMMM*' `'    .
+   :9MMk                    `MMM#"        -
+     &M}                     `          .-
+      `&.                             .
+        `~,   .                     ./
+            . _                  .-
+              '`--._,dd###pp=""'
+

+ 17 - 12
tx_process/easter2

@@ -1,12 +1,17 @@
-
-          .=""=.
-         / _  _ \
-        |  d  b  |
-        \   /\   /             ,
-       ,/'-=\/=-'\,    |\   /\/ \/|   ,_
-      / /        \ \   ; \/`     '; , \_',
-     | /          \ |   \        /
-     \/ \        / \/    '.    .'    /`.
-         '.    .'          `~~` , /\ `"`
-         _|`~~`|_              .  `"
-         /|\  /|\
+      ,-.
+     / \  `.  __..-,O
+    :   \ --''_..-'.'
+    |    . .-' `. '.
+    :     .     .`.'
+     \     `.  /  ..
+      \      `.   ' .
+       `,       `.   \
+      ,|,`.        `-.\
+     '.||  ``-...__..-`
+      |  |
+      |__|
+      /||\
+     //||\\
+    // || \\
+ __//__||__\\__
+'--------------' I Love SSTV

+ 11 - 11
tx_process/easter3

@@ -1,12 +1,12 @@
+  .             *        .     .       .
+       .     _     .     .            .       .
+.    .   _  / |      .        .  *         _  .     .
+        | \_| |                           | | __
+      _ |     |                   _       | |/  |
+     | \      |      ____        | |     /  |    \
+     |  |     \    +/_\/_\+      | |    /   |     \
+jro_/____\--...\___ \_||_/ ___...|__\-..|____\____/__
+      .     .      |_|__|_|         .       .
+   .    . .       _/ /__\ \_ .          .
+      .       .    .           .         .
 
-      /`\   /`\
-     (/\ \-/ /\)
-        )6 6(
-      >{= Y =}<
-       /'-^-'\
-      (_)""-(_).
-     /*  ((*   *'.
-    |   *))  *   *\
-    | *  ((*   *  /
-     \  *))  *  .'
-      '-.((*_.-'

+ 18 - 12
tx_process/easter4

@@ -1,12 +1,18 @@
-           ___     ___
-          /::_\._./_::\
-       _={::(_>[_]<_)::}=_
-     _~   ^--~/:i:\~--^   ~_
-   .d^       /:/ \:\       ^b.
-  .d^       (;/   \;)       ^b.
-  i|  ,___                   |i
-  ii /  /^\  ,___    q&&&p   ii
-  ii \__), ^^ _, \  *+*+*+*  ii
-  |i    / @ @ \\_/ x=X=X=X=x i|
-  ||   { -.x.- }   pXoXoXoXq ||
- /=============================\
+ .              +   .                .   . .     .  .
+                   .                    .       .     *
+  .       *                        . . . .  .   .  + .
+            "You Are Here"            .   .  +  . . .
+.                 |             .  .   .    .    . .
+                  |           .     .     . +.    +  .
+                 \|/            .       .   . .
+        . .       V          .    * . . .  .  +   .
+           +      .           .   .      +
+                            .       . +  .+. .
+  .                      .     . + .  . .     .      .
+           .      .    .     . .   . . .        ! /
+      *             .    . .  +    .  .       - O -
+          .     .    .  +   . .  *  .       . / |
+               . + .  .  .  .. +  .
+.      .  .  .  *   .  *  . +..  .            *
+ .      .   . .   .   .   . .  +   .    .            +
+

+ 16 - 17
tx_process/easter5

@@ -1,18 +1,17 @@
-                ,@@SSSSs,     ,sSSSSSs,
-                @S;;;;sSs@SSS@sSs;;;;Ss
-                @SSSSSSSs@SSS@sSSSSsSSS        |_|  /| |~> |~> \ /
-             ,|||S@SSSSS'SsssS'SSSSSSS||,      | | /~| |~  |~   |
-          ,||||'' @@SS'.SSS^SSS.`SSSS``||||,
-        ,|||'      "" .SSSs sSSS. ""     `|||,    |_~  /| (~ ~|~ |_~ |~>
-      ,|||'          sSSSS' `SSSSs         `|||,  |__ /~| _)  |  |__ |~\
-     ,||'                                    `||,
-    |||',____                 ,____      ,____`|||   |_~ \ | |_~ |~> \ /
-   |||'/   /~\               /   /~\    /   /~\ |||  |__  \| |__ |~\  |
-   |||/   /   \  |\_/|___   /   /   \  /   /   \|||
-   |||\   )\,."~~|/~\|   \  \   )\,."~~~ ,/ \   )||   |_) | | |\| |\| \ / |
-   ||| ~~~ /  ^   ^ __,"  \  ~~~ /  ^   ^ \  ~~~|||   |_) |_| | | | |  |  .
-   |||    /   @   @  \ \   )    /   @   @  \    |||
-   |||   (      *     ) \__/   ( ^v^  *     )   |||
-   |||    \    ^v^   /."";      \   ^\|/^  /    |||
-   ============================."".=======."".=====
+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+⠀⠀⠀⠀⠀⠀⢀⡠⠔⠚⠉⠉⠀⠀⠀⠀⠈⠉⠙⠲⢤⣀⠀⠀⠀⠀⠀⠀
+⠀⠀⠀⠀⣠⠔⠋⠀⢀⣠⠤⠒⢢⠀⠀⣴⠒⠦⢤⣀⠀⠈⠳⣄⠀⠀⠀⠀
+⠀⠀⢀⡴⠁⠀⣠⠖⠋⠀⠀⠀⢸⠀⠀⣿⠀⠀⠀⠈⠓⢤⡀⠈⠳⡄⠀⠀
+⠀⢀⡞⠀⢀⡼⠁⠀⠀⠀⠀⠀⢸⠀⠀⣿⠀⠀⠀⠀⠀⠀⠳⡄⠀⠙⣆⠀
+⠀⡞⠀⠀⡞⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠘⡄⠀⠸⡄
+⢰⠃⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⠀⣧
+⢸⠀⠀⡏⠀⠀⠀⠀⠀⠀⠀⣠⠞⠀⠀⠙⢦⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸
+⢸⠀⠀⣧⠀⠀⠀⠀⠀⣠⠞⠁⠀⠀⠀⡀⠀⠓⣄⠀⠀⠀⠀⠀⢸⠀⠀⣸
+⠘⡆⠀⠸⡀⠀⠀⣠⠞⠁⠀⣠⢾⠀⠀⢷⣄⠀⠈⠳⣄⠀⠀⠀⡞⠀⠀⡇
+⠀⢳⡀⠀⠳⣄⠔⠁⠀⢀⠔⠁⢸⠀⠀⢺⠈⠳⣄⠀⠈⠳⣤⡼⠁⠀⡼⠀
+⠀⠀⢳⡀⠀⠀⠀⢀⡴⠋⠀⠀⢸⠀⠀⢸⠀⠀⠈⠳⣄⠀⠀⠀⢀⡼⠁⠀
+⠀⠀⠀⠙⢦⡀⠀⠘⠦⣄⡀⠀⢸⠀⠀⢼⠀⠀⣀⡤⠚⠀⠀⣠⠞⠀⠀⠀
+⠀⠀⠀⠀⠀⠙⠦⣀⠀⠀⠉⠑⠊⠀⠀⠘⠚⠉⠁⠀⣀⡤⠚⠁⠀⠀⠀⠀
+⠀⠀⠀⠀⠀⠀⠀⠈⠙⠒⠦⠤⢄⣀⣀⡠⠤⠤⠖⠊⠁⠀⠀⠀⠀
 
+   NO WAR, PEACE FOR ALL.