diff --git a/scenes/настройки/настройки.tscn b/scenes/настройки/настройки.tscn index c21899b6..87b1403e 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\\\"'], @@ -68,6 +69,7 @@ const SUPPRESS = 17 ## Строка - Подавление const KEYBOARD = 18 ## Строка - Виртуальная клавиатура const HIDE_EMS2 = 19 ## Строка - Скрыть вкладку ЭМС 2 const COMMIT = 20 ## Строка - Версия УАРЭП +const TRASSA = 21 var name_to_line_index: = {} ## Для преобразования названия параметра в номер строки @@ -91,6 +93,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) @@ -207,6 +214,9 @@ 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/signaller.gd b/scripts/signaller.gd index 82d8cf19..561ed7de 100644 --- a/scripts/signaller.gd +++ b/scripts/signaller.gd @@ -110,7 +110,7 @@ signal interfer_new(ecm: interfer.Interfer) ## [param ecm] - Новая помеха.[br] ## [param ecms] - словарь помех.[br] ## [param thrs] - словарь id помех и связанных с ними целей.[br] -signal interfer_off(ecm: interfer.Interfer, ecms: Dictionary, thrs: Dictionary) +signal interfer_off(ecm: interfer.Interfer) ## Вызывается при нажатии отключить. diff --git a/scripts/trassa.gd b/scripts/trassa.gd index b203716e..3cb5b526 100644 --- a/scripts/trassa.gd +++ b/scripts/trassa.gd @@ -1,6 +1,9 @@ class_name trassa_unit extends Node -const ONLINE_TIMEOUT: = 5000 +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: = [] @@ -11,11 +14,158 @@ class Trassa extends unit.Unit: emit_signal('line_changed', self) return Error.ERR_BUSY - func _init(unit_name: StringName): - self.name = unit_name + 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(data: PackedByteArray, tick: int): + + # Обработка полученного пакета + func parse(rx_data: PackedByteArray, tick: int): rx_tick = tick if not online: online = true - emit_signal('line_changed', self) + 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 + + + # 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)