extends Node enum PrdState {WORK, CONTROL} const TIME_YAU07_SEND = 50 const MIN_UM_POWER = 200 ## минимальная мощность с усилителя, что бы отобразить значёк излучения ## Границы секторов блоков ФС по частоте в режиме РТО. const FS_BAND_RTO: Dictionary = { 0: [200.0, 250.0], 1: [250.0, 300.0], 2: [300.0, 350.0], 3: [350.0, 400.0], 4: [400.0, 450.0], 5: [450.0, 500.0], 6: [500.0, 550.0] } ## Границы секторов блоков ФС по частоте в режиме РЛС. const FS_BAND_RLS: Dictionary = { 0: [480.0, 490.0], 1: [490.0, 500.0], 2: [500.0, 510.0], 3: [510.0, 520.0], 4: [520.0, 530.0], 5: [530.0, 540.0], 6: [540.0, 550.0] } ## Границы секторов блоков ФС по пеленгу. const FS_SECTORS: Dictionary = { 0: [0.0, 90.0], 3: [90.0, 180.0], 2: [180.0, 270.0], 1: [270.0, 360.0] } const FS_FREQ: Dictionary = { 0: [390.0, 510.0, 450.0], 1: [800.0, 1065.0, 932.0], 2: [1065.0, 1210.0, 1137.0], 3: [1150.0, 1380.0, 1215.0], 4: [1380.0, 2000.0, 1575.0], 5: [2000.0, 3500.0, 2750.0], 6: [3500.0, 6000.0, 4750.0] } ## Названия приборов ПРД const PRD_NAMES: Array = [ 'уарэп-яу07-1н', 'уарэп-яу07-1в', 'уарэп-яу07-1к', 'уарэп-яу07-2н', 'уарэп-яу07-2в', 'уарэп-яу07-2к', 'уарэп-яу07-3н', 'уарэп-яу07-3в', 'уарэп-яу07-3к', 'уарэп-яу07-4н', 'уарэп-яу07-4в', 'уарэп-яу07-4к', ] ## Соответствие модулей ФС их нахождению в приборе ПРД и номеру от КАПС РПБ const FS_PRD: Dictionary = { 0: ['уарэп-яу07-1к', 11], 1: ['уарэп-яу07-4к', 41], 2: ['уарэп-яу07-3к', 31], 3: ['уарэп-яу07-2к', 21], 4: ['уарэп-яу07-1н', 12], 5: ['уарэп-яу07-4н', 42], 6: ['уарэп-яу07-3н', 32], 7: ['уарэп-яу07-2н', 22], 8: ['уарэп-яу07-1н', 13], 9: ['уарэп-яу07-4н', 43], 10: ['уарэп-яу07-3н', 33], 11: ['уарэп-яу07-2н', 23], 12: ['уарэп-яу07-1в', 14], 13: ['уарэп-яу07-4в', 44], 14: ['уарэп-яу07-3в', 34], 15: ['уарэп-яу07-2в', 24], 16: ['уарэп-яу07-1в', 15], 17: ['уарэп-яу07-4в', 45], 18: ['уарэп-яу07-3в', 35], 19: ['уарэп-яу07-2в', 25], 20: ['уарэп-яу07-1к', 16], 21: ['уарэп-яу07-4к', 46], 22: ['уарэп-яу07-3к', 36], 23: ['уарэп-яу07-2к', 26], 24: ['уарэп-яу07-1к', 17], 25: ['уарэп-яу07-4к', 47], 26: ['уарэп-яу07-3к', 37], 27: ['уарэп-яу07-2к', 27], } var fs_dict: Dictionary ## Словарь с модулями ФС var prd_dict: Dictionary ## Словарь с приборами ПРД var course = 0.0 ## Курс корабля var fs_caps_id: Dictionary ## Словарь соответствия номеров ФС от КАПС РПБ внутрипрограммной нумерации class Fs: const UM_PORTS: Dictionary = { 1 : 0x106, 2 : 0x108, 3 : 0x106, 4 : 0x108, 5 : 0x106, 6 : 0x108 } const CODE_UM: Array = [ [-5, 0], [0 , 10], [10, 20], [20, 30], [30, 40], [40, 90], [90, 100]] var index ## Индекс блока усилителей var modulation: bool ## Состояние модуляции var prd_name: String ## Ипя прибора ПРД в котором стоит модуль var um_port: int = 0 ## Порт для угла места var um_code_tx: int = 0 ## Код угла места для отправки в прибор var um_code_rx: int = 0 ## Текущий код угла места var isg: int = 2 ## Состояние модуля fs от КАПС РПБ var pow_caps_rx: float = 0.0 ## Мощность излучения принятая от КАПС РПБ var freq_caps_rx: float = 0.0 ## Частота принятая от КАПС РПБ var width_caps_rx: float = 0.0 ## Ширина полосы принятая от КАПС РПБ var msvk: Array var ready: bool = false ## Готовность сектора к излучению var caps_online: bool = false ## Состояние связи с КАПС РПБ var yau_07_online: bool = false ## Состояние связи ЯУ-07 var lit: int ## Литера ФС var power: bool = false ## Признак излучения усилителей signal update_modulation(index) func _init(i, p_name): prd_name = p_name index = i lit = index/4 if UM_PORTS.has(lit): um_port = UM_PORTS[lit] func set_modulation(val): modulation = val func set_um_code(um: float): if um < CODE_UM[0][0]: um_code_tx = 0 elif um > CODE_UM[len(CODE_UM) - 1][1]: um_code_tx = len(CODE_UM) - 1 else: for i in CODE_UM.size(): if (um >= CODE_UM[i][0]) and (um < CODE_UM[i][1]): um_code_tx = i func set_um_data(data_arr, u): if UM_PORTS.has(index/4): var val = um_code_tx if u.isa_ports.has(um_port): val = tools.set_bits(u.isa_ports[um_port], um_code_tx, 0x0007) data_arr.append(um_port) data_arr.append(val) # Установка готовности модуля ФС к излучению func set_ready(): ready = isg and caps_online and yau_07_online func set_power(power_arr: Array): power = false for val in power_arr: if val > MIN_UM_POWER: power = true break class PRD: enum STATE_DEVICE { NONE, GOOD, ERROR } var prd_name: String ## Имя прибора var unit_yau07: Object ## Юнит эмс var unit_control: Object ## Класс проверки прибора ПРД var fs_dic: Dictionary ## Массив блоков ФС var yemsg_board: yemsboards.EmsBoard ## Плата ЭМС-Г var state = PrdState.WORK var cmd_array: Array ## Очередь команд var ug_online: bool = false ## Состояние ячейки УГ var set_ug_state: bool = true ## Необходимо ли записать в УГ настройки signal update_serviceability(state: int) ## Сообщает изменение текущего состояния юнита ПРД var serviceability: int: set(v): if v != serviceability: serviceability = v emit_signal('update_serviceability', v) func _init(u_name, u_yau07): prd_name = u_name unit_yau07 = u_yau07 init_ems_g() func init_ems_g(): var in_tbl: Array = [] var out_tbl: Array = [] for j in yemsconsts.NUM_INPUT_G: in_tbl.append([j+1]) out_tbl.append([j+yemsconsts.STATUS_OUT_OFFSET]) yemsg_board = yemsboards.EmsBoard.new(yemsconsts.EMG_G_ID, 0x120, in_tbl, out_tbl, unit_yau07) yemsg_board.ems_g_fn = yemsconsts.EMS_G_BOARDS[prd_name] var params = ['','',0.0, 0,0] for item in yemsg_board.in_tbl: var in_dev: yemsdevs.InDev = yemsdevs.InDev.new(item[0], params, 0, 0x120) yemsg_board.in_devs[in_dev.id] = in_dev for item in yemsg_board.out_tbl: var out_dev = yemsdevs.OutDev.new(item[0], params, 0, 0x120) yemsg_board.out_devs[out_dev.id] = out_dev yemsg_board.need_write = true unit_yau07.connect('data_received', Callable(self, 'on_data_received')) unit_yau07.connect('command_done', Callable(self, 'on_command_done')) unit_yau07.connect('line_changed', Callable(self, 'on_line_changed')) func on_command_done(u): if yemsg_board.state_board != yemsg_board.WAIT or yemsg_board.state_cmd != yemsg_board.WAIT: yemsg_board.on_command_done(u) return for fs in fs_dic.values(): for port in u.isa_ports.keys(): if port == fs.um_port: fs.um_code_rx = u.isa_ports[port] & 0x7 func on_line_changed(unit_ems): if not unit_ems.online: yemsg_board.ems_load = yemsg_board.LoadState.NOT_DEFINED yemsg_board.set_wait() set_ug_state = true serviceability = STATE_DEVICE.NONE func on_data_received(_u): set_prd_status() if yemsg_board.state_board != yemsg_board.WAIT or yemsg_board.state_cmd != yemsg_board.WAIT: return if yemsg_board.online: if yemsg_board.ems_load == yemsg_board.LoadState.NOT_LOAD: start_load() elif yemsg_board.ems_load == yemsg_board.LoadState.IN_PROCESS: yemsg_board.set_load_done() elif (yemsg_board.ems_load == yemsg_board.LoadState.DONE) and len(yemsg_board.cmd_array): yemsg_board.execute_cmd() else: execute_cmd() return execute_cmd() ## Мониторинг состояния юнита прд func set_prd_status() -> void: # Обновление статуса платы ЯУ-07 yemsg_board.set_status(unit_yau07.status) # Проверка онлайн-статусов основных модулей ug_online = (unit_yau07.status[0] >> 1) & 1 var ukp_1_online = (unit_yau07.status[0] >> 2) & 1 var ukp_2_online = (unit_yau07.status[0] >> 3) & 1 var ems_g_online = (unit_yau07.status[0] & 1) & 1 # Установка флага состояния УГ if not ug_online: set_ug_state = true # Проверка источников питания var ip_online: bool = _check_dry_contact(unit_yau07.status, prd_name) var check_temperature_um: bool = unit_control.flags.temperature_ok var check_dic: Dictionary = { 'ukp_1_online': ukp_1_online, 'ukp_2_online': ukp_2_online, 'ems_g_online': ems_g_online, 'ip_online': ip_online, 'ug_online': ug_online, 'temperature_um': check_temperature_um } # Определение состояния обслуживания if unit_control: if unit_control.flags.control_is_over: serviceability = 0 # Перед результатом контроля необходимо сбросить значение serviceability = _set_serviceability_from_control_results(unit_control) else: serviceability = _set_serviceability_from_online_status(check_dic) ## Проверка онлайн-статуса сухих контактов static func _check_dry_contact(unit_yau07_status: PackedByteArray, self_name: String) -> bool: var bit_ip_config: Array = [0, 1, 2, 3, 4, 5, 6, 7] var is_k_type: bool = self_name in ['уарэп-яу07-1к', 'уарэп-яу07-2к', 'уарэп-яу07-3к', 'уарэп-яу07-4к'] for bit in bit_ip_config: if not is_k_type and bit in [5, 6]: # Игнорируем биты 5 и 6 для всех приборов, кроме типа "к" continue var status: bool = unit_yau07_status[27] >> bit & 1 if status: return false return true ## Установка состояния обслуживания на основе результатов контроля static func _set_serviceability_from_control_results(unit_ctrl: Object) -> int: var control_results = unit_ctrl.get_control_results() var result_dic = control_results.result_dic const CRITICAL_DEVICES: Array = [ 'fs_1', 'fs_2', 'fs_3', 'fs_4', 'fs_5', 'fs_6', 'fs_7', 'dkm_1', 'dkm_2', 'dkm_3', 'dkm_4', 'dkm_5', 'dkm_6', 'dkm_7', 'block_ip', 'dou_2', 'dou_3', 'dou_4', 'dou_5', 'dou_6', 'dou_7' ] var all_ok: bool = true for device_key in CRITICAL_DEVICES: if result_dic.has(device_key) and result_dic[device_key] is bool: if not result_dic[device_key]: all_ok = false break return STATE_DEVICE.GOOD if all_ok else STATE_DEVICE.ERROR ## Установка состояния обслуживания на основе онлайн-статусов static func _set_serviceability_from_online_status(check_dic: Dictionary) -> int: var all_online: bool = true for status in check_dic: if not check_dic[status]: all_online = false break return STATE_DEVICE.NONE if all_online else STATE_DEVICE.ERROR func execute_cmd(): if not len(cmd_array): return if unit_yau07.cmd_state != unit_yau07.CmdState.DONE: return var cmd: Array = cmd_array.pop_front() unit_yau07.send_isa(cmd[0], cmd[1]) func start_load(): var file = FileAccess.open(yemsconsts.emsg_files_folder + yemsg_board.ems_g_fn, FileAccess.READ) var abs_dir = ProjectSettings.globalize_path(yemsconsts.emsg_files_folder + yemsg_board.ems_g_fn) if file == null: yemsg_board.ems_load = yemsg_board.LoadState.FAIL yemsg_board.set_wait() log.error('Не удалось прочитать файл настроек ячейки ЭМС-Г %s' %abs_dir) return var read = file.get_as_text() file.close() var json_conv: = JSON.new() if Error.OK == json_conv.parse(read): var json_data = json_conv.get_data() yemsg_board.need_write = true yemsg_board.ems_load = yemsg_board.LoadState.IN_PROCESS var read_ok = yemsg_board.btn_load(json_data) if read_ok: yemsg_board.state_board = yemsg_board.WRITE yemsg_board.start_rw_kems(false) else: yemsg_board.ems_load = yemsg_board.LoadState.FAIL yemsg_board.set_wait() log.error('Не удалось прочитать файл настроек ячейки ЭМС-Г %s' %abs_dir) else: yemsg_board.ems_load = yemsg_board.LoadState.FAIL yemsg_board.set_wait() log.error('Не удалось прочитать файл настроек ячейки ЭМС-Г %s' %abs_dir) func on_update_modulation(index): yemsg_board.add_cmd(index/4, fs_dic[index].modulation) func set_um(data_arr): cmd_array.append([unit_yau07.CmdCode.WRITE_ISA, data_arr]) func set_fs_caps_online(caps_online: bool): for fs in fs_dic.values(): fs.caps_online = caps_online fs.set_ready() func _ready() -> void: check_dir() for prd_name in PRD_NAMES: var unit_prd = network.get_unit_instance(prd_name) var new_prd = PRD.new(prd_name, unit_prd) prd_dict[prd_name] = new_prd new_prd.unit_yau07.connect('line_changed', on_yau07_line_changed.bind(new_prd)) var unit_control = TestPRD.new({'unit_prd': unit_prd}, new_prd.cmd_array) add_child(unit_control) new_prd.unit_control = unit_control for key in FS_PRD.keys(): var fs = Fs.new(key, FS_PRD[key][0]) fs_dict[key] = fs if prd_dict.has(fs.prd_name): prd_dict[fs.prd_name].fs_dic[key] = fs fs.connect('update_modulation', prd_dict[fs.prd_name].on_update_modulation.bind(fs.index)) for key in FS_PRD.keys(): fs_caps_id[FS_PRD[key][1]] = key var unit_caps = network.get_unit_instance('уарэп-капсрпб') unit_caps.connect('data_received', Callable(self, 'on_data_capsrpb_received')) unit_caps.connect('line_changed', Callable(self, 'on_caps_line_changed')) signaller.connect('режим_контроль', Callable(self, 'on_mode_changed').bind(PrdState.CONTROL)) signaller.connect('режим_работа', Callable(self, 'on_mode_changed').bind(PrdState.WORK)) var unit_nav = network.get_unit_instance('навигация') unit_nav.connect('data_received', on_navi_data_received) func get_fs_param(index: int) -> Array: var freq = (FS_FREQ[index / 4][2]) var sector = (FS_SECTORS[index % 4][0] + FS_SECTORS[index % 4][1])/2 - 45.0 if sector < 0: sector += 360.0 var width = FS_FREQ[index / 4][1] - FS_FREQ[index / 4][0] return [sector, freq, width, index] ## Функция возвращает массив с индексами модулей ФС для выбранной помехи func get_fs_index(ecm, fs_index_arr): var angle: float = ecm.kni if ecm.params.has('freq'): find_fs_index(angle, ecm.params['freq'], fs_index_arr) func find_fs_index(aoa: float, freq: int, fs_index_arr: Array): var sector: int var band: Array var angle = aoa + 45.0 if angle > 360.0: angle -= 360.0 for sec in FS_SECTORS.values(): if float(angle) >= sec[0] and float(angle) <= sec[1]: sector = FS_SECTORS.find_key(sec) for diap in FS_FREQ.values(): if freq >= diap[0] and freq <= diap[1]: band.append(FS_FREQ.find_key(diap)) for item in band: fs_index_arr.append(item * 4 + sector) ## Обновление состояния модулей формирователя сигналов func update_fs_state(ecms, trenaz_mode: bool): for fs in fs_dict.values(): ## Запрет модуляции для всех ФС fs.set_modulation(false) for ecm in ecms.values(): ## Выставление состояния помехи в ФС var fs_ids: Array get_fs_index(ecm, fs_ids) for fs_index in fs_ids: var fs = fs_dict[fs_index] fs.set_um_code(ecm.um) for prd_module in prd_dict.values(): ## Отправка команды на исполнение в ПРД if prd_module.state != PrdState.WORK: continue if not prd_module.unit_yau07.online: continue if not trenaz_mode: prd_module.cmd_array.append([prd_module.unit_yau07.CmdCode.WRITE_ISA, [prd_module.yemsg_board.base_addr_isa, 6666]]) var um_data_array: Array = [] for fs in prd_module.fs_dic.values(): if not prd_module.ug_online: continue if prd_module.set_ug_state: fs.set_um_data(um_data_array, prd_module.unit_yau07) else: if fs.um_code_tx != fs.um_code_rx: fs.set_um_data(um_data_array, prd_module.unit_yau07) if um_data_array.size(): prd_module.set_ug_state = false prd_module.set_um(um_data_array) ## Проверяет ниличие директории, если их нет, создаёт func check_dir(): var dir = DirAccess.open(yemsconsts.emsg_files_folder) if dir: return else: DirAccess.make_dir_absolute(yemsconsts.emsg_files_folder) ## Производит приём состояния модулей ФС. func on_data_capsrpb_received(unit0: capsrpb.CapsRpb): if not unit0.json_dic.has('ts'): return if not unit0.json_dic['ts'] == 7: return if not unit0.json_dic.has('msfs'): return var msfs = unit0.json_dic['msfs'] for fs in msfs: if fs is Dictionary: if not fs.has('nmfs'): return var nmfs = int(fs['nmfs']) if not fs_caps_id.has(nmfs): continue var ii = fs_caps_id[nmfs] if not fs_dict.has(ii): continue var fs_module = fs_dict[ii] if fs.has('isg'): fs_module.isg = int(fs['isg']) fs_module.set_ready() if fs.has('pow'): fs_module.pow_caps_rx = int(fs['pow']) if fs.has('freq'): fs_module.freq_caps_rx = int(fs['freq']) if fs.has('width'): fs_module.width_caps_rx = int(fs['width']) signaller.emit_signal('fs_update_state', fs_dict) ## Вызывается при переходе в режим работа/контроль func on_mode_changed(changed_mode: int) -> void: for pdr in prd.prd_dict.values(): pdr.state = changed_mode func on_navi_data_received(data: Dictionary): course = data.get('k', 0.0) func on_caps_line_changed(unit_caps): for pribor_prd in prd_dict.values(): pribor_prd.set_fs_caps_online(unit_caps.online) signaller.emit_signal('fs_update_state', fs_dict) func on_yau07_line_changed(unit_yau07, prd_pribor): for fs in prd_pribor.fs_dic.values(): fs.yau_07_online = unit_yau07.online fs.set_ready() signaller.emit_signal('fs_update_state', fs_dict) func get_fs_power(nmfs: int): if not fs_caps_id.has(nmfs): return false var fs_index: int = fs_caps_id[nmfs] var prd_obj: PRD = prd_dict[FS_PRD[fs_index][0]] var fs: Fs = prd_obj.fs_dic[fs_index] var power_arr: Array = prd_obj.unit_control.power_um_ukp(prd_obj.unit_yau07.status, fs.lit + 1, [], true) fs.set_power(power_arr) return fs.power