Skip to content

Commit

Permalink
Update TX card selection logic
Browse files Browse the repository at this point in the history
1. Now only cards with near-maximum RX packet counter will be used in RSSI filtering.
2. Python code cleanup
  • Loading branch information
svpcom committed Aug 10, 2024
1 parent 614f1f8 commit 671ec36
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 27 deletions.
2 changes: 2 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[TYPECHECK]
ignored-classes=Section
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ bdist: all_bin

check:
cppcheck --std=c++11 --library=std --library=posix --library=gnu --inline-suppr --template=gcc --enable=all --suppress=cstyleCast --suppress=missingOverride --suppress=missingIncludeSystem src/

pylint:
pylint --disable=R,C wfb_ng/*.py

clean:
rm -rf env wfb_rx wfb_tx wfb_tx_cmd wfb_keygen dist deb_dist build wfb_ng.egg-info wfb-ng-*.tar.gz _trial_temp *~ src/*.o

Expand Down
6 changes: 5 additions & 1 deletion wfb_ng/conf/master.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ radio_mtu = 1445 # Used for mavlink aggregation and for tunnel packets
tunnel_agg_timeout= 0.005 # aggragate tuntap packets if less than radio_mtu but no longer than 5ms
mavlink_agg_timeout = 0.1 # aggragate mavlink packets if less than radio_mtu but no longer than 100ms
mavlink_err_rate = True # If true then inject RX error rate else absolute values
tx_sel_delta = 3 # hysteresis for antenna selection, [dB]

tx_sel_rssi_delta = 3 # hysteresis for antenna selection by RSSI, [dB]
tx_sel_counter_abs_delta = 3 # hysteresis for antenna selection by RX packet counter
tx_sel_counter_rel_delta = 0.1 # default is max(3 packets or 10% of packets from the best antenna)

tx_rcv_buf_size = 2097152 # UDP SO_RCVBUF. Set 0 to use net.core.rmem_default. Increase in case of non-cbr data stream
# This should not be greater than net.core.rmem_max

Expand Down
3 changes: 1 addition & 2 deletions wfb_ng/latency_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@
#

import sys
import time
import struct
import os
from twisted.python import log
from twisted.internet import reactor, defer, task
from twisted.internet.protocol import DatagramProtocol
from twisted.trial import unittest

from .common import df_sleep, abort_on_crash, exit_status


Expand Down
6 changes: 3 additions & 3 deletions wfb_ng/mavlink_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
import struct
import time

from . import call_and_check_rc, ExecError
from . import call_and_check_rc
from .mavlink import MAV_MODE_FLAG_SAFETY_ARMED, MAVLINK_MSG_ID_HEARTBEAT, mavlink_map

from zope.interface import implementer
from twisted.python import log
from twisted.internet import reactor, defer, utils, interfaces
from twisted.internet.protocol import Protocol, DatagramProtocol, Factory
from twisted.internet import defer, interfaces
from twisted.internet.protocol import Protocol, Factory


def unpack_mavlink(msg_id, mbuf):
Expand Down
3 changes: 0 additions & 3 deletions wfb_ng/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

import struct
import os

from contextlib import closing
from twisted.python import log
from twisted.internet import reactor, defer
Expand Down
49 changes: 34 additions & 15 deletions wfb_ng/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@
import struct
import gzip

from base64 import b85encode
from itertools import groupby
from twisted.python import log, failure
from twisted.python.logfile import LogFile
from twisted.internet import reactor, defer, main as ti_main, threads, task
from twisted.internet.protocol import ProcessProtocol, Protocol, Factory
from twisted.internet.protocol import ProcessProtocol, Factory
from twisted.protocols.basic import LineReceiver, Int32StringReceiver
from twisted.internet.serialport import SerialPort

Expand Down Expand Up @@ -114,7 +112,9 @@ def __init__(self, profile, wlans, link_domain, logger):

# Select antenna #0 by default
self.tx_sel = 0
self.tx_sel_delta = settings.common.tx_sel_delta
self.tx_sel_rssi_delta = settings.common.tx_sel_rssi_delta
self.tx_sel_counter_rel_delta = settings.common.tx_sel_counter_rel_delta
self.tx_sel_counter_abs_delta = settings.common.tx_sel_counter_abs_delta

# tcp sockets for UI
self.ui_sessions = []
Expand Down Expand Up @@ -212,34 +212,53 @@ def _stats_agg_by_freq(self, ant_stats):
snr_min, snr_avg, snr_max) in stats_agg.items())

def select_tx_antenna(self, stats_agg):
wlan_rssi = {}
wlan_rssi_and_pkts = {}
max_pkts = 0

for k, grp in groupby(sorted(((ant_id >> 8) & 0xff, rssi_avg) \
for k, grp in groupby(sorted(((ant_id >> 8) & 0xff, pkt_s, rssi_avg) \
for ant_id, (pkt_s,
rssi_min, rssi_avg, rssi_max,
snr_min, snr_avg, snr_max) in stats_agg.items()),
lambda x: x[0]):
# Select max average rssi [dBm] from all wlan's antennas
wlan_rssi[k] = max(rssi for _, rssi in grp)

if not wlan_rssi:
grp = list(grp)
# Use max average rssi [dBm] from all wlan's antennas
# Use max packet counter per antenna from all wlan's antennas
rssi = max(rssi for _, pkt_s, rssi in grp)
pkts = max(pkt_s for _, pkt_s, rssi in grp)
max_pkts = max(pkts, max_pkts)
wlan_rssi_and_pkts[k] = (rssi, pkts)

if not wlan_rssi_and_pkts:
return

# Select antennas with near-maximum RX packet counters only
tx_sel_counter_thr = max_pkts - max(self.tx_sel_counter_abs_delta, max_pkts * self.tx_sel_counter_rel_delta)
ants_with_max_pkts = set(idx for idx, (rssi, pkt_s) in wlan_rssi_and_pkts.items() if pkt_s >= tx_sel_counter_thr)

if not ants_with_max_pkts:
return

cur_ant_rssi = wlan_rssi.get(self.tx_sel, -1000)
max_rssi, max_rssi_ant = max((rssi, idx) for idx, rssi in wlan_rssi.items())
new_max_rssi, new_tx_ant = max((rssi, idx) for idx, (rssi, pkt_s) in wlan_rssi_and_pkts.items() if idx in ants_with_max_pkts)
cur_max_rssi = wlan_rssi_and_pkts.get(self.tx_sel, (-1000, 0))[0]

if new_tx_ant == self.tx_sel:
return

if max_rssi <= cur_ant_rssi + self.tx_sel_delta:
if self.tx_sel in ants_with_max_pkts and new_max_rssi - cur_max_rssi < self.tx_sel_rssi_delta:
# Already selected antenna with near-maximum RX packets counter
# and other antennas doesn't have significally large RSSI
return

log.msg('Switch TX antenna from %d to %d' % (self.tx_sel, max_rssi_ant))
log.msg('Switch TX antenna #%d -> #%d, RSSI %d -> %d[dB]' % (self.tx_sel, new_tx_ant, cur_max_rssi, new_max_rssi))

for ant_sel_cb in self.ant_sel_cb_list:
try:
ant_sel_cb(max_rssi_ant)
ant_sel_cb(new_tx_ant)
except Exception:
log.err()

self.tx_sel = max_rssi_ant
self.tx_sel = new_tx_ant

def process_new_session(self, rx_id, session):
if self.logger is not None:
Expand Down
6 changes: 3 additions & 3 deletions wfb_ng/tuntap.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@
#

import os
from . import mavlink
import fcntl
import struct

from collections import deque
from twisted.python import log, failure
from twisted.internet import reactor, defer, abstract, main, task
from twisted.internet import defer, abstract, main, task
from twisted.internet.protocol import Protocol, connectionDone
from pyroute2 import IPRoute
from contextlib import closing
from .conf import settings

from .proxy import ProxyProtocol


class TUNTAPTransport(abstract.FileDescriptor):
TUN = 0x0001
TAP = 0x0002
Expand Down

0 comments on commit 671ec36

Please sign in to comment.