mirror of
https://github.com/svpcom/wfb-ng.git
synced 2025-03-13 18:14:27 -03:00
Update TX card selection logic
1. Now only cards with near-maximum RX packet counter will be used in RSSI filtering. 2. Python code cleanup
This commit is contained in:
parent
614f1f84db
commit
671ec3680c
4
Makefile
4
Makefile
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -27,12 +27,10 @@ import time
|
||||
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
|
||||
|
||||
@ -114,7 +112,9 @@ class StatsAndSelectorFactory(Factory):
|
||||
|
||||
# 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 = []
|
||||
@ -212,34 +212,53 @@ class StatsAndSelectorFactory(Factory):
|
||||
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
|
||||
|
||||
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())
|
||||
# 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 max_rssi <= cur_ant_rssi + self.tx_sel_delta:
|
||||
if not ants_with_max_pkts:
|
||||
return
|
||||
|
||||
log.msg('Switch TX antenna from %d to %d' % (self.tx_sel, max_rssi_ant))
|
||||
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 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 #%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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user