В процессе. Отображение целей. Приём данных. Разбор пакетов КАПС РПБ.

This commit is contained in:
sasha80
2023-07-28 16:38:00 +03:00
parent fc8183c36e
commit 054b98ab1d
10 changed files with 255 additions and 95 deletions

View File

@@ -30,7 +30,7 @@ class CapsRpb:
emit_signal('line_changed', self)
var utf8_data = data.get_string_from_utf8()
if Error.OK == json_conv.parse(utf8_data):
json_dic.merge(json_conv.get_data())
json_dic.merge(json_conv.get_data(), true)
emit_signal('data_received', self)
else:
var msg = json_conv.get_error_message()

View File

@@ -7,7 +7,7 @@ class Socket extends PacketPeerUDP:
self.put_packet(data)
const PROTO_TYPE: = {'yau07tx': yau07.YaU07, 'jsontx': capsrpb.CapsRpb}
const PROTOCOL_TYPES: = {'yau07tx': yau07.YaU07, 'jsontx': capsrpb.CapsRpb}
var poll_sockets: Array[Socket]
var units: Dictionary
var sock_unicast: Socket
@@ -15,10 +15,10 @@ var logger_page: Node
func create_socket(nm) -> Socket:
var addr = REPSettings.addr[nm][1]
var port = REPSettings.addr[nm][2]
var broad = REPSettings.addr[nm][3]
var bind = REPSettings.addr[nm][4]
var addr = REPSettings.UnitProfiles[nm][1]
var port = REPSettings.UnitProfiles[nm][2]
var broad = REPSettings.UnitProfiles[nm][3]
var bind = REPSettings.UnitProfiles[nm][4]
var sock: = Socket.new()
sock.set_broadcast_enabled(broad)
var rc = Error.OK if not bind else sock.bind(port, addr)
@@ -28,32 +28,34 @@ func create_socket(nm) -> Socket:
func _ready() -> void:
var addr = REPSettings.addr['уарэп-яу07-частный'][1]
var port = REPSettings.addr['уарэп-яу07-частный'][2]
sock_unicast = Socket.new()
sock_unicast.bind(port, addr)
for key in REPSettings.addr:
var setting = REPSettings.addr[key]
Log.info('Сетевой модуль готов')
poll_sockets.append(create_socket('уарэп-яу07-частный'))
poll_sockets.append(create_socket('уарэп-яу07-общий'))
poll_sockets.append(create_socket('уарэп-капсрпб-пол'))
sock_unicast = poll_sockets[0]
for unit_name in REPSettings.UnitProfiles:
var setting = REPSettings.UnitProfiles[unit_name]
var proto = setting[0]
if proto in PROTO_TYPE:
var unit = PROTO_TYPE[proto].new(key)
var k = REPSettings.get_unit_key(setting)
units[k] = unit
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(k))
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(k))
if proto in PROTOCOL_TYPES:
var unit = PROTOCOL_TYPES[proto].new(unit_name)
var unit_key = REPSettings.get_unit_key(unit_name)
units[unit_key] = unit
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
for key in units:
var unit = units[key]
Log.info('%s %s:%d' % [unit.name, key[0], key[1]])
for key in units: Log.info('%s %s:%d' % [units[key].name, key[0], key[1]])
func poll_receive(sock: Socket):
func poll_receive(sock: Socket) -> bool:
while sock.get_available_packet_count() > 0:
var data: = sock.get_packet()
var addr: = sock.get_packet_ip()
var port: = sock.get_packet_port()
var addr_port: = [addr, port]
if addr_port in units: units[addr_port].parse(data)
return false
func _process(delta: float) -> void:
@@ -62,4 +64,4 @@ func _process(delta: float) -> void:
match unit.process(delta):
Error.OK: sock_unicast.send_to(addr, unit.data_tx)
Error.FAILED: emit_signal('socket_error', 'ошибка: %s %s:%d' % [unit, addr[0], addr[1]])
for sock in poll_sockets: poll_receive(sock)
poll_sockets.any(func(sock): poll_receive(sock))

View File

@@ -1,7 +1,7 @@
extends Node
@export var addr: = { \
@export var UnitProfiles: = { \
# Название Протокол Адрес Порт Широков. Привяз. Комментарий
'уарэп-яу07-частный': ['yau07rx', '127.0.0.1', 50079, false, true, 'IP-адрес на котором принимают частные сообщения от ЯУ-07'],
'уарэп-яу07-общий': ['yau07rx', '127.0.0.255', 50000, true, true, 'IP-адрес на котором принимают широковещательные сообщения от ЯУ-07'],
@@ -23,5 +23,15 @@ extends Node
'уарэп-щ3': ['uart', '/dev/stty0', 115200, 1, 1, false, 1000, 'Прибор Щ3'] } # скорость, стартовых, стоповых, чётность, таймаут в мкс
func get_unit_key(item: Array) -> Array: return [item[1], item[2]]
@export var ThreatParams = {
'time_lost': [5000, 'Время после последнего обновления в мс, через которое цель считается потерянной'],
'freq_min': [200.0, 'Нижняя рабочая частота, МГЦ'],
'freq_max': [6000.0, 'Нижняя рабочая частота, МГЦ'] }
func _ready() -> void: Log.info('Модуль настроек готов')
func get_unit_key(unit_name: String) -> Array:
assert(unit_name in UnitProfiles, 'ошибка: нет такого устройства "%s"' % unit_name)
var item = UnitProfiles[unit_name]
return [item[1], item[2]]

View File

@@ -1,75 +1,85 @@
extends Node
enum ThreatSrc {
MP405,
RLKS,
RPB,
SIGMA }
@onready var timer_check_lost: = Timer.new()
class Threat:
var alt: float # Текущая высота, метры.
var aoa: float # Курсовой угол на источник сигнала, градусы.
var atick: float # Тик обнаружения.
var baud: float # Модуляционная скорость.
var fflags: Dictionary # Флаги достоверности полей.
var freq: float # Частота несущей или центральная частота, МГц.
var freqm: String # Режим смены частоты.
var lat: float # Текущие координаты, долгота в градусах.
var lon: float # Текущие координаты, широта в градусах.
var power: float # Уровень принимаемого сигнала, дБм.
var proto: String # Тип протокола источника сигнала.
var rkrp: String # Рекомендуемый режим помехи.
var rparams: String # Рекомендуемые параметры помехи.
var salt: float # Координаты старта, высота от уровня моря, м.
var slat: float # Координаты старта, широта в градусах.
var slon: float # Координаты старта, долгота в градусах.
var tick: int # Время приёма сигнала, мс.
var tmod: String # Тип модуляции.
var utime: Dictionary # Время крайнего обновления.
var width: float # Ширина занимаемого диапазона частот, МГц.
var id: int # Идентификатор цели
enum FFlags { # Допустимые значения для Threat.fflags
ALT = 1 << 1,
AOA = 1 << 2,
ATIME = 1 << 3,
BAUD = 1 << 4,
FFLAGS = 1 << 5,
FREQ = 1 << 6,
FREQM = 1 << 7,
LAT = 1 << 8,
LON = 1 << 9,
POW_RX = 1 << 10,
PROTO = 1 << 11,
RKRP = 1 << 12,
RPARAMS = 1 << 13,
SALT = 1 << 14,
SLAT = 1 << 15,
SLON = 1 << 16,
TICK = 1 << 17,
TMOD = 1 << 18,
UTIME = 1 << 19,
WIDTH = 1 << 20 }
func _init(): Tools.get_members_names(self).any(func(vn): fflags[vn] = false)
var alt: float # Текущая высота, метры.
var aoa: float # Курсовой угол на источник сигнала, градусы.
var atime: Dictionary # Время обнаружения.
var baud: float # Модуляционная скорость.
var fflags: FFlags # Флаги достоверности полей.
var freq: float # Частота несущей или центральная частота, МГц.
var freqm: String # Режим смены частоты.
var lat: float # Текущие координаты, долгота в градусах.
var lon: float # Текущие координаты, широта в градусах.
var pow_rx: float # Уровень принимаемого сигнала, дБм.
var proto: String # Тип протокола источника сигнала.
var rkrp: String # Рекомендуемый режим помехи.
var rparams: String # Рекомендуемые параметры помехи.
var salt: float # Координаты старта, высота от уровня моря, м.
var slat: float # Координаты старта, широта в градусах.
var slon: float # Координаты старта, долгота в градусах.
var tick: int # Время приёма сигнала, мс.
var tmod: String # Тип модуляции.
var utime: Dictionary # Время крайнего обновления.
var width: float # Ширина занимаемого диапазона частот, МГц.
func _to_string() -> String: return 'номер:%d пеленг:%0.1f частота:%0.1f МГц' % [id, aoa, freq]
func set_from_dic(dic_vals: Dictionary):
var items: = fflags.keys().filter(func(vn): return vn in dic_vals)
items.any(func(vn): set(vn, dic_vals[vn]); fflags[vn] = true; return false)
var _threats = {}
signal threat_new(threats: Dictionary, th: Threat)
signal threat_lost(threats: Dictionary, th: Threat)
signal threat_update(threats: Dictionary, th: Threat)
var threats = {}
"""
Список целей. Индекс - <источник цели>:<номер цели>
Источник цели может быть: 'RPB', 'SIGMA', 'RLKS', 'MP405'
"""
func on_parse_threads(unit: capsrpb.CapsRpb):
print_debug(unit)
func _ready() -> void:
Log.info('Модуль обработки целей готов')
var unit = REPSettings.addrs[]
var unit_key = REPSettings.get_unit_key('уарэп-капсрпб-отп')
var unit = REPNetwork.units[unit_key]
unit.connect('data_received', Callable(self, 'on_data_capsrpb_received'))
add_child(timer_check_lost)
timer_check_lost.connect('timeout', Callable(self, 'on_timer_check_lost'))
timer_check_lost.start(REPSettings.ThreatParams.time_lost[0] / 2000.0)
func on_timer_check_lost():
var tick = Time.get_ticks_msec()
for id in threats.keys():
var th = threats[id]
if (tick - th.atick) >= REPSettings.ThreatParams.time_lost[0]:
threats.erase(th.id)
call_deferred('emit_signal', 'threat_lost', threats, th)
func on_data_capsrpb_received(unit: capsrpb.CapsRpb):
pass
if 'mis' not in unit.json_dic:
return
var mis = unit.json_dic['mis']
for dic_th in mis:
if 'id' in dic_th:
var id = int(dic_th['id'])
if id in threats:
var th = threats[id]
th.set_from_dic(dic_th)
th.atick = Time.get_ticks_msec()
call_deferred('emit_signal', 'threat_update', threats, th)
else:
var th = Threat.new()
th.set_from_dic(dic_th)
th.atick = Time.get_ticks_msec()
th.fflags['atick'] = true
threats[id] = th
call_deferred('emit_signal', 'threat_new', threats, th)

View File

@@ -1,6 +1,16 @@
extends Node
func radians(val: float): return (val * PI) / 180.0
func get_members_names(obj: Object) -> Array:
var pl = obj.get_property_list()
var names: = Array()
for item in pl: names.append(item.name)
return names
func assert_array_ipaddr(val: Array):
""" Выкидывает исключение, если массив не содержит ip-адрес """
assert(val.size() == 2)