mirror of
https://github.com/svpcom/wfb-ng.git
synced 2025-02-20 23:43:49 -04:00
Add ARM/DISARM handler
This commit is contained in:
parent
5ca7dbdad0
commit
e7b49f07ce
@ -45,6 +45,9 @@ stbc = 1 # stbc streams: 1, 2, 3 or 0 if unused
|
|||||||
ldpc = 0 # use LDPC FEC. Currently available only for 8812au and must be supported both on TX and RX.
|
ldpc = 0 # use LDPC FEC. Currently available only for 8812au and must be supported both on TX and RX.
|
||||||
mcs_index = 1 # mcs index
|
mcs_index = 1 # mcs index
|
||||||
|
|
||||||
|
call_on_arm = None # call program on arm
|
||||||
|
call_on_disarm = None # call program on disarm
|
||||||
|
|
||||||
|
|
||||||
[gs_video]
|
[gs_video]
|
||||||
keypair = 'gs.key' # keypair generated by wfb-keygen
|
keypair = 'gs.key' # keypair generated by wfb-keygen
|
||||||
@ -84,6 +87,9 @@ stbc = 1 # stbc streams: 1, 2, 3 or 0 if unused
|
|||||||
ldpc = 0 # use LDPC FEC. Currently available only for 8812au and must be supported both on TX and RX.
|
ldpc = 0 # use LDPC FEC. Currently available only for 8812au and must be supported both on TX and RX.
|
||||||
mcs_index = 1 # mcs index
|
mcs_index = 1 # mcs index
|
||||||
|
|
||||||
|
call_on_arm = None # call program on arm
|
||||||
|
call_on_disarm = None # call program on disarm
|
||||||
|
|
||||||
|
|
||||||
[drone_video]
|
[drone_video]
|
||||||
keypair = 'drone.key'
|
keypair = 'drone.key'
|
||||||
|
@ -29,20 +29,54 @@ standard_library.install_aliases()
|
|||||||
from builtins import *
|
from builtins import *
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
from . import mavlink
|
import os
|
||||||
|
|
||||||
from twisted.python import log
|
from twisted.python import log
|
||||||
from twisted.internet import reactor, defer
|
from twisted.internet import reactor, defer, utils
|
||||||
from twisted.internet.protocol import DatagramProtocol, Protocol
|
from twisted.internet.protocol import DatagramProtocol, Protocol
|
||||||
from telemetry.conf import settings
|
|
||||||
|
from . import mavlink
|
||||||
|
from .conf import settings
|
||||||
|
from .mavlink_protocol import MAVLinkProtocol
|
||||||
|
|
||||||
|
|
||||||
|
class ExecError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def call_and_check_rc(cmd, *args):
|
||||||
|
def _check_rc(_args):
|
||||||
|
(stdout, stderr, rc) = _args
|
||||||
|
if rc != 0:
|
||||||
|
err = ExecError('RC %d: %s %s' % (rc, cmd, ' '.join(args)))
|
||||||
|
err.stdout = stdout.strip()
|
||||||
|
err.stderr = stderr.strip()
|
||||||
|
raise err
|
||||||
|
|
||||||
|
log.msg('# %s' % (' '.join((cmd,) + args),))
|
||||||
|
if stdout:
|
||||||
|
log.msg(stdout)
|
||||||
|
|
||||||
|
def _got_signal(f):
|
||||||
|
f.trap(tuple)
|
||||||
|
stdout, stderr, signum = f.value
|
||||||
|
err = ExecError('Got signal %d: %s %s' % (signum, cmd, ' '.join(args)))
|
||||||
|
err.stdout = stdout.strip()
|
||||||
|
err.stderr = stderr.strip()
|
||||||
|
raise err
|
||||||
|
|
||||||
|
return utils.getProcessOutputAndValue(cmd, args, env=os.environ).addCallbacks(_check_rc, _got_signal)
|
||||||
|
|
||||||
|
|
||||||
class ProxyProtocol:
|
class ProxyProtocol:
|
||||||
def __init__(self, agg_max_size=None, agg_timeout=None, inject_rssi=False):
|
def __init__(self, agg_max_size=None, agg_timeout=None, inject_rssi=False, arm_proto=None):
|
||||||
# use self.write to send mavlink message
|
# use self.write to send mavlink message
|
||||||
if inject_rssi:
|
if inject_rssi:
|
||||||
self.radio_mav = mavlink.MAVLink(self, srcSystem=3, srcComponent=242) # WFB
|
self.radio_mav = mavlink.MAVLink(self, srcSystem=3, srcComponent=242) # WFB
|
||||||
else:
|
else:
|
||||||
self.radio_mav = None
|
self.radio_mav = None
|
||||||
|
|
||||||
|
self.arm_proto = arm_proto
|
||||||
self.peer = None
|
self.peer = None
|
||||||
self.agg_max_size = agg_max_size
|
self.agg_max_size = agg_max_size
|
||||||
self.agg_timeout = agg_timeout
|
self.agg_timeout = agg_timeout
|
||||||
@ -73,6 +107,9 @@ class ProxyProtocol:
|
|||||||
self.peer.write(data)
|
self.peer.write(data)
|
||||||
|
|
||||||
def messageReceived(self, data):
|
def messageReceived(self, data):
|
||||||
|
if self.arm_proto:
|
||||||
|
self.arm_proto.dataReceived(data)
|
||||||
|
|
||||||
# send message to local transport
|
# send message to local transport
|
||||||
if self.agg_max_size is None or self.agg_timeout is None:
|
if self.agg_max_size is None or self.agg_timeout is None:
|
||||||
return self._send_to_peer(data)
|
return self._send_to_peer(data)
|
||||||
@ -108,8 +145,8 @@ class ProxyProtocol:
|
|||||||
class UDPProxyProtocol(DatagramProtocol, ProxyProtocol):
|
class UDPProxyProtocol(DatagramProtocol, ProxyProtocol):
|
||||||
noisy = False
|
noisy = False
|
||||||
|
|
||||||
def __init__(self, addr=None, agg_max_size=None, agg_timeout=None, inject_rssi=False, mirror=None):
|
def __init__(self, addr=None, agg_max_size=None, agg_timeout=None, inject_rssi=False, mirror=None, arm_proto=None):
|
||||||
ProxyProtocol.__init__(self, agg_max_size, agg_timeout, inject_rssi)
|
ProxyProtocol.__init__(self, agg_max_size, agg_timeout, inject_rssi, arm_proto=arm_proto)
|
||||||
self.reply_addr = addr
|
self.reply_addr = addr
|
||||||
self.fixed_addr = bool(addr)
|
self.fixed_addr = bool(addr)
|
||||||
self.mirror = mirror
|
self.mirror = mirror
|
||||||
@ -175,8 +212,8 @@ class UDPProxyProtocol(DatagramProtocol, ProxyProtocol):
|
|||||||
class SerialProxyProtocol(Protocol, ProxyProtocol):
|
class SerialProxyProtocol(Protocol, ProxyProtocol):
|
||||||
noisy = False
|
noisy = False
|
||||||
|
|
||||||
def __init__(self, agg_max_size=None, agg_timeout=None, inject_rssi=False):
|
def __init__(self, agg_max_size=None, agg_timeout=None, inject_rssi=False, arm_proto=None):
|
||||||
ProxyProtocol.__init__(self, agg_max_size, agg_timeout, inject_rssi)
|
ProxyProtocol.__init__(self, agg_max_size, agg_timeout, inject_rssi, arm_proto=arm_proto)
|
||||||
self.mavlink_fsm = self.mavlink_parser()
|
self.mavlink_fsm = self.mavlink_parser()
|
||||||
self.mavlink_fsm.send(None)
|
self.mavlink_fsm.send(None)
|
||||||
|
|
||||||
@ -240,3 +277,53 @@ class SerialProxyProtocol(Protocol, ProxyProtocol):
|
|||||||
for m in m_list:
|
for m in m_list:
|
||||||
self.messageReceived(m)
|
self.messageReceived(m)
|
||||||
|
|
||||||
|
|
||||||
|
class ARMProtocol(MAVLinkProtocol):
|
||||||
|
def __init__(self, call_on_arm, call_on_disarm):
|
||||||
|
MAVLinkProtocol.__init__(self, None, None)
|
||||||
|
self.call_on_arm = call_on_arm
|
||||||
|
self.call_on_disarm = call_on_disarm
|
||||||
|
self.armed = None
|
||||||
|
self.locked = False
|
||||||
|
|
||||||
|
def messageReceived(self, message):
|
||||||
|
if (message._header.msgId, message._header.srcSystem, message._header.srcComponent) != (mavlink.MAVLINK_MSG_ID_HEARTBEAT, 1, 1):
|
||||||
|
return
|
||||||
|
|
||||||
|
armed = bool(message.base_mode & mavlink.MAV_MODE_FLAG_SAFETY_ARMED)
|
||||||
|
|
||||||
|
if not self.locked:
|
||||||
|
self.locked = True
|
||||||
|
|
||||||
|
def _unlock(x):
|
||||||
|
self.locked = False
|
||||||
|
return x
|
||||||
|
|
||||||
|
return defer.maybeDeferred(self.change_state, armed).addBoth(_unlock)
|
||||||
|
|
||||||
|
def change_state(self, armed):
|
||||||
|
if armed == self.armed:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.armed = armed
|
||||||
|
cmd = None
|
||||||
|
|
||||||
|
if armed:
|
||||||
|
print('State change: ARMED')
|
||||||
|
cmd = self.call_on_arm
|
||||||
|
else:
|
||||||
|
print('State change: DISARMED')
|
||||||
|
cmd = self.call_on_disarm
|
||||||
|
|
||||||
|
def on_err(f):
|
||||||
|
log.msg('Command exec failed: %s' % (f.value,), isError=1)
|
||||||
|
|
||||||
|
if f.value.stdout:
|
||||||
|
log.msg(f.value.stdout, isError=1)
|
||||||
|
|
||||||
|
if f.value.stderr:
|
||||||
|
log.msg(f.value.stderr, isError=1)
|
||||||
|
|
||||||
|
if cmd is not None:
|
||||||
|
return call_and_check_rc(cmd).addErrback(on_err)
|
||||||
|
|
||||||
|
@ -36,48 +36,21 @@ import re
|
|||||||
|
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
from twisted.python import log, failure
|
from twisted.python import log, failure
|
||||||
from twisted.internet import reactor, defer, utils, main as ti_main
|
from twisted.internet import reactor, defer, main as ti_main
|
||||||
from twisted.internet.protocol import ProcessProtocol, DatagramProtocol, Protocol, Factory
|
from twisted.internet.protocol import ProcessProtocol, DatagramProtocol, Protocol, Factory
|
||||||
from twisted.protocols.basic import LineReceiver
|
from twisted.protocols.basic import LineReceiver
|
||||||
from twisted.internet.error import ReactorNotRunning
|
from twisted.internet.error import ReactorNotRunning
|
||||||
from twisted.internet.serialport import SerialPort
|
from twisted.internet.serialport import SerialPort
|
||||||
|
|
||||||
from telemetry.common import abort_on_crash, exit_status
|
from .common import abort_on_crash, exit_status
|
||||||
from telemetry.proxy import UDPProxyProtocol, SerialProxyProtocol
|
from .proxy import UDPProxyProtocol, SerialProxyProtocol, ARMProtocol, call_and_check_rc, ExecError
|
||||||
from telemetry.tuntap import TUNTAPProtocol, TUNTAPTransport
|
from .tuntap import TUNTAPProtocol, TUNTAPTransport
|
||||||
from telemetry.conf import settings
|
from .conf import settings
|
||||||
|
|
||||||
connect_re = re.compile(r'^connect://(?P<addr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):(?P<port>[0-9]+)$', re.IGNORECASE)
|
connect_re = re.compile(r'^connect://(?P<addr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):(?P<port>[0-9]+)$', re.IGNORECASE)
|
||||||
listen_re = re.compile(r'^listen://(?P<addr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):(?P<port>[0-9]+)$', re.IGNORECASE)
|
listen_re = re.compile(r'^listen://(?P<addr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):(?P<port>[0-9]+)$', re.IGNORECASE)
|
||||||
serial_re = re.compile(r'^serial:(?P<dev>[a-z0-9\-\_/]+):(?P<baud>[0-9]+)$', re.IGNORECASE)
|
serial_re = re.compile(r'^serial:(?P<dev>[a-z0-9\-\_/]+):(?P<baud>[0-9]+)$', re.IGNORECASE)
|
||||||
|
|
||||||
class ExecError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def call_and_check_rc(cmd, *args):
|
|
||||||
def _check_rc(_args):
|
|
||||||
(stdout, stderr, rc) = _args
|
|
||||||
if rc != 0:
|
|
||||||
err = ExecError('RC %d: %s %s' % (rc, cmd, ' '.join(args)))
|
|
||||||
err.stdout = stdout.strip()
|
|
||||||
err.stderr = stderr.strip()
|
|
||||||
raise err
|
|
||||||
|
|
||||||
log.msg('# %s' % (' '.join((cmd,) + args),))
|
|
||||||
if stdout:
|
|
||||||
log.msg(stdout)
|
|
||||||
|
|
||||||
def _got_signal(f):
|
|
||||||
f.trap(tuple)
|
|
||||||
stdout, stderr, signum = f.value
|
|
||||||
err = ExecError('Got signal %d: %s %s' % (signum, cmd, ' '.join(args)))
|
|
||||||
err.stdout = stdout.strip()
|
|
||||||
err.stderr = stderr.strip()
|
|
||||||
raise err
|
|
||||||
|
|
||||||
return utils.getProcessOutputAndValue(cmd, args, env=os.environ).addCallbacks(_check_rc, _got_signal)
|
|
||||||
|
|
||||||
|
|
||||||
class BadTelemetry(Exception):
|
class BadTelemetry(Exception):
|
||||||
pass
|
pass
|
||||||
@ -365,19 +338,26 @@ def init_mavlink(profile, wlans):
|
|||||||
mirror = m.group('addr'), int(m.group('port'))
|
mirror = m.group('addr'), int(m.group('port'))
|
||||||
log.msg('Mirror telem stream to %s:%d' % (mirror[0], mirror[1]))
|
log.msg('Mirror telem stream to %s:%d' % (mirror[0], mirror[1]))
|
||||||
|
|
||||||
|
if cfg.call_on_arm or cfg.call_on_disarm:
|
||||||
|
arm_proto = ARMProtocol(cfg.call_on_arm, cfg.call_on_disarm)
|
||||||
|
else:
|
||||||
|
arm_proto = None
|
||||||
|
|
||||||
if serial:
|
if serial:
|
||||||
p_in = SerialProxyProtocol(agg_max_size=settings.common.radio_mtu,
|
p_in = SerialProxyProtocol(agg_max_size=settings.common.radio_mtu,
|
||||||
agg_timeout=settings.common.mavlink_agg_timeout,
|
agg_timeout=settings.common.mavlink_agg_timeout,
|
||||||
inject_rssi=cfg.inject_rssi)
|
inject_rssi=cfg.inject_rssi,
|
||||||
|
arm_proto=arm_proto)
|
||||||
else:
|
else:
|
||||||
# The first argument is not None only if we initiate mavlink connection
|
# The first argument is not None only if we initiate mavlink connection
|
||||||
p_in = UDPProxyProtocol(connect, agg_max_size=settings.common.radio_mtu,
|
p_in = UDPProxyProtocol(connect, agg_max_size=settings.common.radio_mtu,
|
||||||
agg_timeout=settings.common.mavlink_agg_timeout,
|
agg_timeout=settings.common.mavlink_agg_timeout,
|
||||||
inject_rssi=cfg.inject_rssi,
|
inject_rssi=cfg.inject_rssi,
|
||||||
mirror=mirror)
|
mirror=mirror,
|
||||||
|
arm_proto=arm_proto)
|
||||||
|
|
||||||
p_tx_l = [UDPProxyProtocol(('127.0.0.1', cfg.port_tx + i)) for i, _ in enumerate(wlans)]
|
p_tx_l = [UDPProxyProtocol(('127.0.0.1', cfg.port_tx + i)) for i, _ in enumerate(wlans)]
|
||||||
p_rx = UDPProxyProtocol()
|
p_rx = UDPProxyProtocol(arm_proto=arm_proto)
|
||||||
p_rx.peer = p_in
|
p_rx.peer = p_in
|
||||||
|
|
||||||
if serial:
|
if serial:
|
||||||
|
Loading…
Reference in New Issue
Block a user