Files
uarep-ctl/scripts/prd.gd

528 lines
22 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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