diff --git a/scenes/настройки/настройки.tscn b/scenes/настройки/настройки.tscn index b69067fc..64267b01 100644 --- a/scenes/настройки/настройки.tscn +++ b/scenes/настройки/настройки.tscn @@ -31,6 +31,7 @@ const SETTING_TABLE = [ ['Кнопка «JTIDS»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], ['Кнопка «КУПД»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], ['Внешнее управление', TableEdit, TableToggle, 'Передать управление в 5П28'], + ['Внешнее указание Трасса', TableEdit, TableToggle, 'Разрешить постановку помех от Трасса'], ['Кнопка «Подавление»', TableEdit, TableToggle, 'Разрешить отображение кнопки'], ['Виртуальная клавиатура', TableEdit, TableToggle, 'Включить отображение экранной клавиатуры'], ['Скрыть вкладку ЭМС 2', TableEdit, TableToggle, 'Отображать вкладку \\\"ЭМС-2\\\"'], @@ -63,10 +64,11 @@ const SETTING_TABLE = [ ['Адрес БПО правого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора БПО'] ] const EXTERNAL_CU = 16 ## Внешнее целеуказание -const SUPPRESS = 17 ## Строка - Подавление -const KEYBOARD = 18 ## Строка - Виртуальная клавиатура -const HIDE_EMS2 = 19 ## Строка - Скрыть вкладку ЭМС 2 -const COMMIT = 20 ## Строка - Версия УАРЭП +const TRASSA = 17 +const SUPPRESS = 18 ## Строка - Подавление +const KEYBOARD = 19 ## Строка - Виртуальная клавиатура +const HIDE_EMS2 = 20 ## Строка - Скрыть вкладку ЭМС 2 +const COMMIT = 21 ## Строка - Версия УАРЭП var name_to_line_index: = {} ## Для преобразования названия параметра в номер строки @@ -90,6 +92,11 @@ func on_external_cu_btn_pressed(btn) -> void: signaller.emit_signal('interfer_off_all') +func on_trassa_btn_pressed(btn) -> void: + var state = btn.button_pressed + ProjectSettings.set_setting('application/config/Внешнее указание Трасса', state) + + func on_vk_pressed(btn) -> void: var state = btn.button_pressed signaller.emit_signal('kb_pressed', state) @@ -206,6 +213,11 @@ func button_settings(): var extern_cu_node = $scroll_set/table.get_node2(1, EXTERNAL_CU).get_children()[0] extern_cu_node.connect('pressed', on_external_cu_btn_pressed.bind(extern_cu_node)) on_external_cu_btn_pressed(extern_cu_node) + + var trassa_node = $scroll_set/table.get_node2(1, TRASSA).get_children()[0] + trassa_node.connect('pressed', on_trassa_btn_pressed.bind(trassa_node)) + on_trassa_btn_pressed(trassa_node) + var vk_node = $scroll_set/table.get_node2(1, KEYBOARD).get_children()[0] vk_node.connect('pressed', on_vk_pressed.bind(vk_node)) var ems2_hide_node = $scroll_set/table.get_node2(1, HIDE_EMS2).get_children()[0] diff --git a/scripts/settings.gd b/scripts/settings.gd index 2ac22b72..8d716db2 100644 --- a/scripts/settings.gd +++ b/scripts/settings.gd @@ -10,7 +10,7 @@ var UnitProfiles: Dictionary[StringName, Array] = { \ 'уарэп-яу07-частный': ['yau07rx', ['10.1.1.2', 50002, false, true], 'IP-адрес для приёма частных сообщений от ЯУ-07'], 'уарэп-яу07-общий': ['yau07rx', ['*', 50000, true, true], 'IP-адрес для приёма широковещательных сообщений от ЯУ-07'], 'уарэп-капсрпб': ['capsrpb', ['127.0.0.1', 42023, 42022, false, true], 'IP-адрес для обмена сообщениями со службой \"МП550\" (СТЦ)'], - 'уарэп-трасса': ['trassa', ['127.0.0.1', 50200, 50200, false, true], 'IP-адрес для обмена сообщениями с \"Трассой\"'], + 'уарэп-трасса': ['trassa', ['127.0.0.1', 50200, 10004, false, true], 'IP-адрес для обмена сообщениями с \"Трассой\"'], 'уарэп-эмс': ['yau07tx', ['10.1.1.52', 50052, false, false], 'IP-адрес прибора УФ'], 'уарэп-яу07-2в': ['yau07tx', ['10.1.1.22', 50022, false, false], 'IP-адрес прибора ПРД-В2'], 'уарэп-яу07-2н': ['yau07tx', ['10.1.1.21', 50021, false, false], 'IP-адрес прибора ПРД-Н2'], diff --git a/scripts/trassa.gd b/scripts/trassa.gd index faee6834..b207aa69 100644 --- a/scripts/trassa.gd +++ b/scripts/trassa.gd @@ -1,13 +1,165 @@ -class_name trassa_unit extends Node +class_name trassa_unit +extends Node +const ONLINE_TIMEOUT: int = 5000 # Время ожидания данных +const REQUEST_PERIOD: int = 3000 # Период отправки, мс +const WORDS_TOTAL: int = 75 +const NOINFO: int = 0x80000000 class Trassa extends unit.Unit: - var source_addr: = [] - func process(tick: int): + + var unit_caps = network.get_unit_instance('уарэп-капсрпб') + var source_addr: Array + var tx_stack: Array[int] = [] + var msg_counter: int = 0 + var ecms: Dictionary = {} # Словарь всех активных помех + var srn = 0 + var jtids = 0 + var prinud_but: Array = [] + var forced_buttons: Array = [] # Храним ссылки на кнопки + + # Инициализация + func _init(nm: StringName, buttons: Array = []) -> void: + self.name = nm + self.forced_buttons = buttons + tx_stack.resize(WORDS_TOTAL) + tx_stack.fill(NOINFO) + interfer.connect("interfer_resized", Callable(self, "on_interfer_resized")) + + + # Обработка полученного пакета + func parse(rx_data: PackedByteArray, tick: int): + rx_tick = tick + if not online: + online = true + emit_signal("line_changed", self) + var words: Array[int] = [] + var offset: int = 0 + while offset < rx_data.size(): + if offset + 4 <= rx_data.size(): + var word = rx_data.decode_u32(offset) + words.append(word) + offset += 4 + else: + break + if words.size() < 10: + emit_signal('parse_failed', self) + tx_stack.fill(NOINFO) + tx_stack[0] = words[0] # ID + tx_stack[1] = msg_counter # Nc + tx_stack[2] = 0x01 # Nб + tx_stack[3] = 0x00 # Ск + tx_stack[4] = 0x0194 # НТС + tx_stack[5] = (0x0001 << 16) | 0x0080 # Ии + tx_stack[6] = 0x01 # РКС + srn = words[7] # SRN + jtids = words[8] # JTIDS + btn_trassa_pressed() + interfer_data() + tx_stack[74] = _calc_crc(tx_stack) + emit_signal("data_received", self) + + + func interfer_data() -> void: + for i in range(67, 74): + tx_stack[i] = 0 + for ecm in ecms.values(): + if ecm.svk == 1: + var nmfs_value = ecm.nmfs + var fs_key = get_fs_key(nmfs_value) + if fs_key != NOINFO: + var string_index = fs_key / 4 + var bit_position = fs_key % 4 + if string_index >= 0 and string_index < 7: + var target_string = 67 + string_index + tx_stack[target_string] |= (1 << bit_position) + + + func get_fs_key(nmfs_value: int) -> int: + if prd.fs_caps_id.has(nmfs_value): + return prd.fs_caps_id[nmfs_value] + return NOINFO + + + # Отправка пакета от uarep-ctl + func process(now_tick: int) -> int: + if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT): + online = false + emit_signal("line_changed", self) + if (now_tick - tx_tick) > REQUEST_PERIOD: + tx_tick = now_tick + msg_counter += 1 + interfer_uarep() + interfer_data() + var data = PackedByteArray() + data.resize(WORDS_TOTAL * 4) + for i in range(WORDS_TOTAL): + data.encode_u32(i * 4, tx_stack[i]) + tx_data = data + tx_len = WORDS_TOTAL * 4 + return Error.OK return Error.ERR_BUSY - func _init(unit_name: StringName): - self.name = unit_name - func parse(data: PackedByteArray, now_tick: int): - pass + # CRC вычисление + func _calc_crc(data: Array) -> int: + var acc: int = 0 + for i in range(data.size() - 1): # кроме CRC + if i in [0, 1]: + continue + acc = (acc + (data[i] & 0xFFFFFFFF)) & 0xFFFFFFFF + return acc + + + # Обновление всех активных помех + func on_interfer_resized(ecms_dic: Dictionary) -> void: ecms = ecms_dic + + + func interfer_uarep() -> void: + tx_stack[65] = 0 + tx_stack[66] = 0 + for ecm in ecms.values(): + if ecm.krp == "srni1" and ecm.svk == 1: + tx_stack[65] = 1 + if ecm.krp == "svi1" and ecm.svk == 1: + tx_stack[66] = 1 + tx_stack[1] = msg_counter + + + # Обработка указаний от Трассы по кнопке + func btn_trassa_pressed() -> void: + var state = ProjectSettings.get_setting('application/config/Внешнее указание Трасса', false) + if state == true: + var tree: SceneTree = Engine.get_main_loop() + if tree is SceneTree: + var nodes: Array = tree.get_nodes_in_group('группа-принудительно') + for btn in nodes: + if btn.name == 'btn_srn': + btn.pressed = (srn == 1) + elif btn.name == 'btn_jtids': + btn.pressed = (jtids == 1) + if srn == 1: + tx_stack[65] = 1 + signaller.emit_signal('interfer_prinuditelno', frm_ecm_list.srn_sectors) + else: + tx_stack[65] = 0 + for ecm in ecms.values(): + if ecm.krp == "srni1" and ecm.svk == 1: + ecm.krp = interfer.INTERFER_OFF + interfer.send_ecm(ecm, unit_caps) + signaller.emit_signal('interfer_off', ecm) + if jtids == 1: + tx_stack[66] = 1 + signaller.emit_signal('interfer_prinuditelno', frm_ecm_list.jtids_sectors) + else: + tx_stack[66] = 0 + for ecm in ecms.values(): + if ecm.krp == "svi1" and ecm.svk == 1: + ecm.krp = interfer.INTERFER_OFF + interfer.send_ecm(ecm, unit_caps) + signaller.emit_signal('interfer_off', ecm) + for ecm in ecms.values(): + if ecm.krp == "svi1" and ecm.svk == 1: + ecm.krp = interfer.INTERFER_OFF + interfer.send_ecm(ecm, unit_caps) + signaller.emit_signal('interfer_off', ecm)