gear shifting test

This commit is contained in:
DJ2LS 2024-02-22 15:05:54 +01:00
parent 836f4b99d8
commit 22f0226600
8 changed files with 102 additions and 44 deletions

View file

@ -127,4 +127,13 @@ class ARQSession():
'total_bytes': total_bytes,
'duration': duration,
'bytes_per_minute': bytes_per_minute
}
}
def get_appropriate_speed_level(self, snr):
# Start with the lowest speed level as default
# In case of a not fitting SNR, we return the lowest speed level
appropriate_speed_level = min(self.SPEED_LEVEL_DICT.keys())
for level, details in self.SPEED_LEVEL_DICT.items():
if snr >= details['min_snr'] and level > appropriate_speed_level:
appropriate_speed_level = level
return appropriate_speed_level

View file

@ -76,13 +76,10 @@ class ARQSessionIRS(arq_session.ARQSession):
self.received_bytes = 0
self.received_crc = None
self.transmitted_acks = 0
self.speed_level = 0
self.abort = False
def set_decode_mode(self):
self.modem.demodulator.set_decode_mode(self.get_mode_by_speed_level(self.speed_level))
def all_data_received(self):
return self.total_length == self.received_bytes
@ -127,9 +124,6 @@ class ARQSessionIRS(arq_session.ARQSession):
self.log(f"New transfer of {self.total_length} bytes")
self.event_manager.send_arq_session_new(False, self.id, self.dxcall, self.total_length, self.state.name)
self.calibrate_speed_settings()
self.set_decode_mode()
info_ack = self.frame_factory.build_arq_session_info_ack(
self.id, self.total_crc, self.snr[0],
self.speed_level, self.frames_per_burst, flag_abort=self.abort)
@ -163,17 +157,20 @@ class ARQSessionIRS(arq_session.ARQSession):
def receive_data(self, burst_frame):
self.process_incoming_data(burst_frame)
self.calibrate_speed_settings()
if not self.all_data_received():
downshift, upshift = self.calibrate_speed_settings()
ack = self.frame_factory.build_arq_burst_ack(
self.id, self.received_bytes,
self.speed_level, self.frames_per_burst, self.snr[0], flag_abort=self.abort)
self.id,
self.received_bytes,
self.speed_level,
self.frames_per_burst,
self.snr[0],
flag_abort=self.abort,
flag_upshift=upshift,
flag_downshift=downshift
)
self.set_decode_mode()
# increase ack counter
# self.transmitted_acks += 1
self.set_state(IRS_State.BURST_REPLY_SENT)
self.launch_transmit_and_wait(ack, self.TIMEOUT_DATA, mode=FREEDV_MODE.signalling)
return None, None
@ -209,16 +206,46 @@ class ARQSessionIRS(arq_session.ARQSession):
self.transmission_failed()
def calibrate_speed_settings(self):
self.speed_level = 0 # for now stay at lowest speed level
return
# if we have two ACKS, then consider increasing speed level
if self.transmitted_acks >= 2:
self.transmitted_acks = 0
new_speed_level = min(self.speed_level + 1, len(self.SPEED_LEVEL_DICT) - 1)
latest_snr = self.snr[-1] if self.snr else -10
appropriate_speed_level = self.get_appropriate_speed_level(latest_snr)
modes_to_decode = {}
# check first if the next mode supports the actual snr
if self.snr[0] >= self.SPEED_LEVEL_DICT[new_speed_level]["min_snr"]:
self.speed_level = new_speed_level
# Log the latest SNR, current, and appropriate speed levels for clarity
self.log(
f"Latest SNR: {latest_snr}, Current Speed Level: {self.speed_level}, Appropriate Speed Level: {appropriate_speed_level}",
isWarning=True)
# Always decode the current mode
current_mode = self.get_mode_by_speed_level(self.speed_level).value
modes_to_decode[current_mode] = True
# Initialize shift flags
upshift = False
downshift = False
# Check if a shift is needed
if appropriate_speed_level != self.speed_level:
# Determine the direction of the shift
upshift = appropriate_speed_level > self.speed_level
downshift = appropriate_speed_level < self.speed_level
# Update the speed level
self.speed_level = appropriate_speed_level
self.log(f"Updated Speed Level: {self.speed_level}", isWarning=True)
# Determine additional modes based on the direction of the shift
if upshift and self.speed_level < len(self.SPEED_LEVEL_DICT) - 1:
next_mode = self.get_mode_by_speed_level(self.speed_level).value
modes_to_decode[next_mode] = True
elif downshift and self.speed_level > 0:
prev_mode = self.get_mode_by_speed_level(self.speed_level).value
modes_to_decode[prev_mode] = True
self.log(f"Modes to Decode: {modes_to_decode}", isWarning=True)
# Apply the new decode mode based on the updated speed level
self.modem.demodulator.set_decode_mode(modes_to_decode)
return downshift, upshift
def abort_transmission(self):
self.log(f"Aborting transmission... setting abort flag")

View file

@ -105,11 +105,25 @@ class ARQSessionISS(arq_session.ARQSession):
self.launch_twr(session_open_frame, self.TIMEOUT_CONNECT_ACK, self.RETRIES_CONNECT, mode=FREEDV_MODE.signalling)
self.set_state(ISS_State.OPEN_SENT)
def set_speed_and_frames_per_burst(self, frame):
self.speed_level = frame['speed_level']
self.log(f"Speed level set to {self.speed_level}")
self.frames_per_burst = frame['frames_per_burst']
self.log(f"Frames per burst set to {self.frames_per_burst}")
def update_speed_level(self, frame):
self.log("---------------------------------------------------------", isWarning=True)
# Log the received frame for debugging
self.log(f"Received frame: {frame}", isWarning=True)
# Safely extract upshift and downshift flags with default to False if not present
upshift = frame['flag'].get('UPSHIFT', False)
downshift = frame['flag'].get('DOWNSHIFT', False)
# Check for UPSHIFT frame and ensure speed level does not exceed max limit
if upshift and not downshift and self.speed_level < len(self.SPEED_LEVEL_DICT) - 1:
self.speed_level += 1
self.log(f"Upshifting. New speed level: {self.speed_level}")
# Check for DOWNSHIFT frame and ensure speed level does not go below 0
elif downshift and not upshift and self.speed_level > 0:
self.speed_level -= 1
self.log(f"Downshifting. New speed level: {self.speed_level}")
def send_info(self, irs_frame):
# check if we received an abort flag
@ -128,7 +142,7 @@ class ARQSessionISS(arq_session.ARQSession):
def send_data(self, irs_frame):
self.set_speed_and_frames_per_burst(irs_frame)
self.update_speed_level(irs_frame)
if 'offset' in irs_frame:
self.confirmed_bytes = irs_frame['offset']

View file

@ -15,6 +15,8 @@ class DataFrameFactory:
'FINAL': 0, # Bit-position for indicating the FINAL state
'ABORT': 1, # Bit-position for indicating the ABORT request
'CHECKSUM': 2, # Bit-position for indicating the CHECKSUM is correct or not
'DOWNSHIFT': 3, # Bit-position for indicating a requested ARQ DOWNSHIFT
'UPSHIFT': 4, # Bit-position for indicating a requested ARQ UPSHIFT
}
def __init__(self, config):
@ -404,7 +406,7 @@ class DataFrameFactory:
return frame
def build_arq_burst_ack(self, session_id: bytes, offset, speed_level: int,
frames_per_burst: int, snr: int, flag_final=False, flag_checksum=False, flag_abort=False):
frames_per_burst: int, snr: int, flag_final=False, flag_checksum=False, flag_abort=False, flag_downshift=False, flag_upshift=False):
flag = 0b00000000
if flag_final:
flag = helpers.set_flag(flag, 'FINAL', True, self.ARQ_FLAGS)
@ -415,6 +417,13 @@ class DataFrameFactory:
if flag_abort:
flag = helpers.set_flag(flag, 'ABORT', True, self.ARQ_FLAGS)
if flag_downshift:
flag = helpers.set_flag(flag, 'DOWNSHIFT', True, self.ARQ_FLAGS)
flag = helpers.set_flag(flag, 'UPSHIFT', False, self.ARQ_FLAGS)
if flag_upshift:
flag = helpers.set_flag(flag, 'DOWNSHIFT', False, self.ARQ_FLAGS)
flag = helpers.set_flag(flag, 'UPSHIFT', True, self.ARQ_FLAGS)
payload = {
"session_id": session_id.to_bytes(1, 'big'),

View file

@ -382,15 +382,15 @@ class Demodulator():
for mode in self.MODE_DICT:
codec2.api.freedv_set_sync(self.MODE_DICT[mode]["instance"], 0)
def set_decode_mode(self, mode):
def set_decode_mode(self, modes_to_decode):
# Reset all modes to not decode
for m in self.MODE_DICT:
self.MODE_DICT[m]["decode"] = False
for m in self.MODE_DICT: self.MODE_DICT[m]["decode"] = False
# Enable specified modes
for mode, decode in modes_to_decode.items():
if mode in self.MODE_DICT:
self.MODE_DICT[mode]["decode"] = decode
# signalling is always true
self.MODE_DICT[codec2.FREEDV_MODE.signalling.value]["decode"] = True
# Enable mode based on speed_level
self.MODE_DICT[mode.value]["decode"] = True
self.log.info(f"[MDM] [demod_audio] set data mode: {mode.name}")
return
enabled_modes = [mode.name for mode, details in self.MODE_DICT.items() if details["decode"]]
self.log.info(f"[MDM] [demod_audio] Enabled decode modes: {', '.join(enabled_modes)}")

View file

@ -91,7 +91,6 @@ class FrameHandler():
def add_to_heard_stations(self):
frame = self.details['frame']
print(frame)
if 'origin' not in frame:
return

View file

@ -29,7 +29,7 @@ app = Flask(__name__)
CORS(app)
CORS(app, resources={r"/*": {"origins": "*"}})
sock = Sock(app)
MODEM_VERSION = "0.13.7-alpha"
MODEM_VERSION = "0.14.0-alpha-exp"
# set config file to use
def set_config():

View file

@ -144,7 +144,7 @@ class TestARQSession(unittest.TestCase):
self.waitAndCloseChannels()
del cmd
def DisabledtestARQSessionLargePayload(self):
def testARQSessionLargePayload(self):
# set Packet Error Rate (PER) / frame loss probability
self.loss_probability = 0