scatter plott support

This commit is contained in:
DJ2LS 2021-08-06 22:09:16 +02:00 committed by GitHub
parent e3cb2eb46a
commit c0ec0c1853
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 101 additions and 15 deletions

View file

@ -682,7 +682,7 @@ def received_ping_ack(data_in):
static.DXGRID = bytes(data_in[3:9]).rstrip(b'\x00')
helpers.add_to_heard_stations(static.DXCALLSIGN,static.DXGRID, 'PING-ACK')
helpers.add_to_heard_stations(static.DXCALLSIGN,static.DXGRID, 'PING-ACK', static.SNR)
logging.info("PING [" + str(static.MYCALLSIGN, 'utf-8') + "] >|< [" + str(static.DXCALLSIGN, 'utf-8') + "]["+ str(static.DXGRID, 'utf-8') +"] [SNR:" + str(static.SNR) + "]")
static.TNC_STATE = 'IDLE'
@ -723,7 +723,7 @@ def received_cq(data_in):
dxgrid = bytes(data_in[8:14]).rstrip(b'\x00')
logging.info("CQ RCVD [" + str(dxcallsign, 'utf-8') + "]["+ str(dxgrid, 'utf-8') +"] [SNR" + str(static.SNR) + "]")
helpers.add_to_heard_stations(dxcallsign,dxgrid, 'CQ CQ CQ')
helpers.add_to_heard_stations(dxcallsign,dxgrid, 'CQ CQ CQ', static.SNR)
@ -748,4 +748,4 @@ def received_beacon():
dxgrid = bytes(data_in[8:14]).rstrip(b'\x00')
logging.info("BEACON RCVD [" + str(dxcallsign, 'utf-8') + "]["+ str(dxgrid, 'utf-8') +"] [SNR" + str(static.SNR) + "]")
helpers.add_to_heard_stations(dxcallsign,dxgrid, 'BEACON')
helpers.add_to_heard_stations(dxcallsign,dxgrid, 'BEACON', static.SNR)

View file

@ -31,6 +31,32 @@ import numpy as np
from scipy.fft import fft, ifft
from scipy import signal
MODEM_STATS_NR_MAX = 320
MODEM_STATS_NC_MAX = 51
class MODEMSTATS(ctypes.Structure):
_fields_ = [
("Nc", ctypes.c_int),
("snr_est", ctypes.c_float),
("rx_symbols", (ctypes.c_float * MODEM_STATS_NR_MAX)*MODEM_STATS_NC_MAX),
("nr", ctypes.c_int),
("sync", ctypes.c_int),
("foff", ctypes.c_float),
("rx_timing", ctypes.c_float),
("clock_offset", ctypes.c_float),
("sync_metric", ctypes.c_float),
("pre", ctypes.c_int),
("post", ctypes.c_int),
("uw_fails", ctypes.c_int),
]
class RF():
def __init__(self):
@ -437,13 +463,18 @@ class RF():
#print("listening-" + str(mode) + " - " + "nin: " + str(nin) + " - " + str(self.c_lib.freedv_get_rx_status(freedv)))
self.calculate_snr(freedv)
self.get_scatter(freedv)
# forward data only if broadcast or we are the receiver
# bytes_out[1:2] == callsign check for signalling frames, bytes_out[6:7] == callsign check for data frames, bytes_out[1:2] == b'\x01' --> broadcasts like CQ
# we could also create an own function, which returns True. In this case we could add callsign blacklists and so on
if nbytes == bytes_per_frame and bytes(bytes_out[1:2]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[6:7]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[1:2]) == b'\x01':
self.calculate_snr(freedv)
static.SCATTER = []
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
@ -553,7 +584,40 @@ class RF():
# for debugging purposes to receive all data
pass
# print(bytes_out[:-2])
def get_scatter(self, freedv):
modemStats = MODEMSTATS()
self.c_lib.freedv_get_modem_extended_stats.restype = None
#c_lib.freedv_get_modem_extended_stats.argtypes = c_void_p, [MODEMSTATS]
#c_lib.freedv_get_modem_extended_stats(freedv, modemStats)
self.c_lib.freedv_get_modem_extended_stats(freedv, ctypes.byref(modemStats))
print("Nc: " + str(modemStats.Nc))
#print("snr_est: " + str(modemStats.snr_est))
print("nr: " + str(modemStats.nr))
#data = []
#MODEM_STATS_NR_MAX = 320
#MODEM_STATS_NC_MAX = 51
scatterdata = []
for i in range(MODEM_STATS_NC_MAX):
for j in range(MODEM_STATS_NR_MAX):
#xsymbols = modemStats.rx_symbols[i][j]
#xsymbols = modemStats.rx_symbols[i][::2]
#ysymbols = modemStats.rx_symbols[i][j+1]
#check if odd or not to get every 2nd item for x
if (j % 2) == 0:
xsymbols = modemStats.rx_symbols[i][j]
ysymbols = modemStats.rx_symbols[i][j+1]
if xsymbols != 0.0 and ysymbols != 0.0:
scatterdata.append({"x" : xsymbols, "y" : ysymbols })
# only append scatter data if new data arrived
if scatterdata != static.SCATTER:
static.SCATTER = scatterdata
def calculate_ber(self, freedv):
Tbits = self.c_lib.freedv_get_total_bits(freedv)
Terrs = self.c_lib.freedv_get_total_bit_errors(freedv)
@ -593,11 +657,11 @@ class RF():
#static.FFT = fft_raw.tolist()
#fft_raw = fft_raw.tobytes()
rate = 48000
M = 1024
freqs, times, Sx = signal.spectrogram(data_in_array, fs=rate, window='hanning', nperseg=1024, noverlap=M - 100, detrend=False, scaling='spectrum', return_onesided=True)
#rate = 48000
#M = 1024
#freqs, times, Sx = signal.spectrogram(data_in_array, fs=rate, window='hanning', nperseg=1024, noverlap=M - 100, detrend=False, scaling='spectrum', return_onesided=True)
freqs, times, Sx = signal.spectrogram(data_in_array, fs=rate, return_onesided=True, axis=-1)
#freqs, times, Sx = signal.spectrogram(data_in_array, fs=rate, return_onesided=True, axis=-1)
@ -608,8 +672,8 @@ class RF():
#print(fft_raw)
#static.FFT = fft_raw.hex()
#static.FFT = fft_raw
data_in = np.frombuffer(data_in, dtype=np.int16)
data = fft(data_in)
#data_in = np.frombuffer(data_in, dtype=np.int16)
#data = fft(data_in)
#print(data)
#data = getFFT(data_in, 48000, 2048)
#print(data)
@ -620,13 +684,13 @@ class RF():
#data = np.frombuffer(data_in, dtype=np.int16)
data.resize((1,2048))
#data.resize((1,2048))
#data = np.delete(data,0)
#data = data.tobytes()
#print(data)
static.FFT = data.tolist()
#static.FFT = data.tolist()
#static.FFT = data.hex()
def getFFT(data, rate, chunk_size, log_scale=False):

View file

@ -199,13 +199,15 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
"COMMAND": "STATION_INFO",
"MY_CALLSIGN": str(static.MYCALLSIGN, encoding),
"DX_CALLSIGN": str(static.DXCALLSIGN, encoding),
"DX_GRID": str(static.DXGRID, encoding)
"DX_GRID": str(static.DXGRID, encoding),
"EOF" : "EOF",
}
jsondata = json.dumps(output)
self.request.sendall(bytes(jsondata, encoding))
if received_json["type"] == 'GET' and received_json["command"] == 'TNC_STATE':
print(static.SCATTER)
output = {
"COMMAND": "TNC_STATE",
"PTT_STATE": str(static.PTT_STATE),
@ -219,6 +221,7 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
"MODE" : str(static.HAMLIB_MODE),
"BANDWITH" : str(static.HAMLIB_BANDWITH),
"FFT" : str(static.FFT),
"SCATTER" : static.SCATTER,
#"RX_BUFFER_LENGTH": str(len(static.RX_BUFFER)),
#"TX_N_MAX_RETRIES": str(static.TX_N_MAX_RETRIES),
#"ARQ_TX_N_FRAMES_PER_BURST": str(static.ARQ_TX_N_FRAMES_PER_BURST),
@ -228,7 +231,9 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
#"ARQ_RX_FRAME_N_BURSTS": str(static.ARQ_RX_FRAME_N_BURSTS),
#"ARQ_RX_N_CURRENT_ARQ_FRAME": str(static.ARQ_RX_N_CURRENT_ARQ_FRAME),
#"ARQ_N_ARQ_FRAMES_PER_DATA_FRAME": str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME)
}
"EOF" : "EOF",
}
jsondata = json.dumps(output)
#print(len(jsondata))
@ -242,6 +247,17 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
jsondata = json.dumps(output)
self.request.sendall(bytes(jsondata, encoding))
#if received_json["type"] == 'GET' and received_json["command"] == 'SCATTER':
#
# print(static.SCATTER)
# output = {
# "COMMAND" : "SCATTER",
# "DATA" : static.SCATTER
# }
# print(output)
# jsondata = json.dumps(output)
# self.request.sendall(bytes(jsondata, encoding))
if received_json["type"] == 'GET' and received_json["command"] == 'DATA_STATE':
output = {
"COMMAND": "DATA_STATE",
@ -253,7 +269,8 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
"ARQ_TX_N_TOTAL_ARQ_FRAMES": str(int.from_bytes(bytes(static.ARQ_TX_N_TOTAL_ARQ_FRAMES), "big")),
"ARQ_RX_FRAME_N_BURSTS": str(static.ARQ_RX_FRAME_N_BURSTS),
"ARQ_RX_N_CURRENT_ARQ_FRAME": str(static.ARQ_RX_N_CURRENT_ARQ_FRAME),
"ARQ_N_ARQ_FRAMES_PER_DATA_FRAME": str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME)
"ARQ_N_ARQ_FRAMES_PER_DATA_FRAME": str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME),
"EOF" : "EOF",
}
jsondata = json.dumps(output)
@ -267,6 +284,9 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
for i in range(0, len(static.HEARD_STATIONS)):
data["STATIONS"].append({"DXCALLSIGN": str(static.HEARD_STATIONS[i][0], 'utf-8'),"DXGRID": str(static.HEARD_STATIONS[i][1], 'utf-8'), "TIMESTAMP": static.HEARD_STATIONS[i][2], "DATATYPE": static.HEARD_STATIONS[i][3], "SNR": static.HEARD_STATIONS[i][4]})
# print(static.HEARD_STATIONS[i][1])
#data.append({"EOF" : "EOF"})
jsondata = json.dumps(data)
self.request.sendall(bytes(jsondata, encoding))

View file

@ -80,6 +80,7 @@ FREEDV_SIGNALLING_PAYLOAD_PER_FRAME = 0
BER = 0
SNR = 0
SCATTER = []
# ---------------------------------
# Audio Defaults
@ -95,6 +96,7 @@ AUDIO_FRAMES_PER_BUFFER = 8192 # 256 # 512 # 1024 #2048 --> nicht 880
AUDIO_CHANNELS = 1
AUDIO_RMS = 0
FFT = []
# ---------------------------------
# ARQ DEFAULTS