Files
uarep-ctl/scripts/pribor-prd.gd
2025-08-15 05:04:46 +03:00

609 lines
24 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.

class TestPRD extends Node:
const RAY_25_1:= 'ray_25_1'
const RAY_25_2:= 'ray_25_2'
const RAY_25_3:= 'ray_25_3'
const RAY_25_4:= 'ray_25_4'
const RAY_25_5:= 'ray_25_5'
const RAY_25_6:= 'ray_25_6'
const RAY_25_7:= 'ray_25_7'
enum STATE_VAL { NONE = 0, GOOD = 1, ERROR = 2 }
enum STATE_MASHINE {
INIT,
FS_TURN_ON,
FS_WORK,
CHEK_KASSETA_Y5,
UG_SET_RAY_0,
UG_SET_RAY_1,
UG_SET_RAY_2,
UG_SET_RAY_3,
UG_SET_RAY_4,
UG_SET_RAY_5,
UG_SET_RAY_6,
UM_RUN,
FS_TURN_OFF,
STOP_CONTROL,
AWAIT
}
const FS_KEYS := {
1: 'fs_1',
2: 'fs_2',
3: 'fs_3',
4: 'fs_4',
5: 'fs_5',
6: 'fs_6',
7: 'fs_7'
}
const TEMPERATURE_CONSTANTS := {
'CONST_MIN_TEMP': -25,
'MAXIMUM_CODE_ADC': 3796,
'MINIMUM_CODE_AD': 2660,
'TEMPERATURE_UKP_1': 47,
'TEMPERATURE_UKP_2': 79,
}
var power_result: Dictionary = {
RAY_25_1: [],
RAY_25_2: [],
RAY_25_3: [],
RAY_25_4: [],
RAY_25_5: [],
RAY_25_6: [],
RAY_25_7: [],
}
var constants: Dictionary
var pribor_config: Dictionary
var fs_parameters: Dictionary
var block_ip_config: Dictionary
var block_dkm_config: Dictionary
var block_fs_config: Dictionary
var block_kasseta_y5_config: Dictionary
var control_results: Dictionary
var self_name: String
var state: int = STATE_MASHINE.INIT
var current_fs: int
var flag_check_dkm: bool
var flag_timer_started: bool
#var ug_online: bool
var unit_prd: Object
var module_prd: Object
var power_amplify: Array
var fs_array_node: Array
var control_label: Label
var control_timer: Timer = Timer.new()
## Инициализация аргуметнов
func _init(init_data: Dictionary) -> void:
control_label = init_data['control_label']
power_amplify = init_data['power_amplifiers']
fs_array_node = init_data['fs_nodes']
unit_prd = init_data['unit_prd']
module_prd = init_data['module_prd']
constants = init_data['constants']
pribor_config = init_data['prd_config']
fs_parameters = init_data['fs_params']
block_ip_config = init_data['block_ip_prd_config']
block_dkm_config = init_data['block_dkm_prd_config']
block_fs_config = init_data['block_fs_prd_config']
control_results = init_data['control_results']
current_fs = init_data['current_fs']
block_kasseta_y5_config = init_data['block_kasseta_y5_prd_config']
func _ready() -> void:
initialize_connections()
setup_timer()
func _process(_delta: float) -> void:
pass
## Пакеты от ЯУ-07
func on_data_received(unit_pribor: Object) -> void:
if not is_inside_tree():
return
var status: PackedByteArray = unit_pribor.status
block_kasseta_y5_config = check_block_kasseta_y5(status, block_kasseta_y5_config)
block_ip_config = check_block_ip(status, block_ip_config)
check_temperature_um(status, power_amplify)
_process_dkm_status(status)
## Пакеты от MP550Service
func on_fs_update_state(packet_type_7: Dictionary, fs_mapping: Dictionary, fs_array: Array) -> void:
var fs_key: String = FS_KEYS.get(current_fs, '')
if fs_key.is_empty():
return
var fs_result := {fs_key: STATE_VAL.NONE}
fs_result = on_fs_state(packet_type_7, fs_mapping, fs_result)
_update_fs_states(fs_result, fs_array)
##
func state_control_machine() -> void:
match state:
STATE_MASHINE.INIT:
_handle_init_state()
STATE_MASHINE.FS_TURN_ON:
_handle_fs_turn_on_state()
STATE_MASHINE.CHEK_KASSETA_Y5:
pass
STATE_MASHINE.FS_WORK:
_handle_fs_work_state()
STATE_MASHINE.UG_SET_RAY_0:
_handle_ug_set_state(0x0)
STATE_MASHINE.UG_SET_RAY_1:
_handle_ug_set_state(0x1)
STATE_MASHINE.UG_SET_RAY_2:
_handle_ug_set_state(0x2)
STATE_MASHINE.UG_SET_RAY_3:
_handle_ug_set_state(0x3)
STATE_MASHINE.UG_SET_RAY_4:
_handle_ug_set_state(0x4)
STATE_MASHINE.UG_SET_RAY_5:
_handle_ug_set_state(0x5)
STATE_MASHINE.UG_SET_RAY_6:
_handle_ug_set_state(0x6)
STATE_MASHINE.UM_RUN:
flag_timer_started = _handle_um_run_state()
STATE_MASHINE.FS_TURN_OFF:
_handle_fs_turn_off_state()
STATE_MASHINE.STOP_CONTROL:
_handle_stop_control_state()
func _handle_init_state() -> void:
control_label.text = 'Выполняется инициализация ФС-%s' % current_fs
if current_fs in [1, 2, 3, 4, 5, 6, 7]:
state = STATE_MASHINE.FS_TURN_ON
else:
control_results = on_control_result(block_ip_config, block_dkm_config, block_fs_config, control_results)
state = STATE_MASHINE.AWAIT
func _handle_fs_turn_on_state() -> void:
control_label.text = 'Выполняется включение ФС-%s' % current_fs
manage_fs(true, self_name, pribor_config, fs_parameters, current_fs, constants.POWER_UM)
#control_timer.wait_time = constants.TIMER_DELAY
#control_timer.start()
state = STATE_MASHINE.FS_WORK
func _handle_fs_work_state() -> void:
control_label.text = 'Выполняется проверка ФС-%s' % current_fs
if not module_prd.unit_yau07.online:
return
if (current_fs == 2 and block_fs_config.fs_2 and not flag_timer_started) or \
(current_fs == 3 and block_fs_config.fs_3 and not flag_timer_started) or \
(current_fs == 4 and block_fs_config.fs_4 and not flag_timer_started) or \
(current_fs == 5 and block_fs_config.fs_5 and not flag_timer_started) or \
(current_fs == 6 and block_fs_config.fs_6 and not flag_timer_started) or \
(current_fs == 7 and block_fs_config.fs_7 and not flag_timer_started) or \
(current_fs == 1 and block_fs_config.fs_1 and not flag_timer_started):
state = STATE_MASHINE.UG_SET_RAY_6
func _handle_ug_set_state(RAY_DOU_NUM: int) -> void:
var dic_att := {
'RAY_DOU_NUM': RAY_DOU_NUM,
'ADDR_UG_LITERA_1': constants.ADDR_UG_LITERA_1,
'ADDR_UG_LITERA_2': constants.ADDR_UG_LITERA_2,
'ADDR_UG_LITERA_3': constants.ADDR_UG_LITERA_3,
'ATT_UM_3': 0x00,
}
if self_name == '' or self_name == '' or self_name == '' or self_name == '':
dic_att['ATT_UM_1'] = constants.ATT_UM_6
dic_att['ATT_UM_2'] = constants.ATT_UM_7
dic_att['ATT_UM_3'] = constants.ATT_UM_1
elif self_name == '' or self_name == '' or self_name == '' or self_name == '':
dic_att['ATT_UM_1'] = constants.ATT_UM_4
dic_att['ATT_UM_2'] = constants.ATT_UM_5
elif self_name == '' or self_name == '' or self_name == '' or self_name == '':
dic_att['ATT_UM_1'] = constants.ATT_UM_2
dic_att['ATT_UM_2'] = constants.ATT_UM_3
control_label.text = 'Выполняется настройка угла (%s) и атт (%s, %s, %s)' % [
dic_att.RAY_DOU_NUM,
dic_att.ATT_UM_1,
dic_att.ATT_UM_2,
dic_att.ATT_UM_3,
]
on_ug_setting(module_prd, unit_prd, dic_att)
state = STATE_MASHINE.UM_RUN
func _handle_um_run_state() -> bool:
control_label.text = 'Выполняется настройка ЭМС'
module_prd.cmd_array.append([unit_prd.CmdCode.WRITE_ISA, [constants.BASE_ADDR_EMS_G, 6666]])
state = STATE_MASHINE.FS_WORK
return true
func _handle_fs_turn_off_state() -> void:
control_label.text = 'Выполняется отключение ФС-%s' % current_fs
manage_fs(false, self_name, pribor_config, fs_parameters, current_fs, constants.POWER_UM)
state = STATE_MASHINE.STOP_CONTROL
func _handle_stop_control_state() -> void:
control_label.text = 'Выполняется завершение проверки ФС-%s' % current_fs
control_results = power_um_control_result(control_results, constants, power_result)
flag_timer_started = false
flag_check_dkm = false
_advance_to_next_fs()
state = STATE_MASHINE.INIT
func _advance_to_next_fs() -> void:
match current_fs:
1: current_fs = 6
2: current_fs = 3
3: current_fs = 0
4: current_fs = 5
5: current_fs = 0
6: current_fs = 7
7: current_fs = 0
######################################
func initialize_connections() -> void:
_determine_self_name()
var fs_mapping = _create_fs_mapping(self_name)
signaller.conn(signaller.fs_update_state, Callable(self, 'on_fs_update_state').bind(fs_mapping, fs_array_node))
unit_prd.connect('data_received', Callable(self, 'on_data_received'))
func _determine_self_name() -> void:
var current_unit = unit_prd.name
var parts = current_unit.split('-')
self_name = parts[-1]
func setup_timer() -> void:
add_child(control_timer)
control_timer.timeout.connect(on_stop_control)
control_timer.one_shot = true
control_timer.wait_time = 10.0
control_timer.start()
func _process_dkm_status(status: PackedByteArray) -> void:
if not block_fs_config.has(_get_current_fs_key()):
return
var dkm_bit = _get_dkm_bit_for_current_fs()
block_dkm_config = check_dkm(status, dkm_bit, block_dkm_config)
flag_check_dkm = block_dkm_config[_get_dkm_key_for_current_fs()]
if flag_check_dkm:
power_result[_get_ray_key_for_current_fs()] = power_um_ukp(status, current_fs, power_result[_get_ray_key_for_current_fs()])
func _get_current_fs_key() -> String:
return FS_KEYS.get(current_fs, '')
func _get_dkm_bit_for_current_fs() -> int:
match current_fs:
1: return constants.DKM_BIT_1
2: return constants.DKM_BIT_2
3: return constants.DKM_BIT_3
4: return constants.DKM_BIT_4
5: return constants.DKM_BIT_5
6: return constants.DKM_BIT_6
7: return constants.DKM_BIT_7
_: return -1
func _get_dkm_key_for_current_fs() -> String:
match current_fs:
1: return 'dkm_1'
2: return 'dkm_2'
3: return 'dkm_3'
4: return 'dkm_4'
5: return 'dkm_5'
6: return 'dkm_6'
7: return 'dkm_7'
_: return ''
func _get_ray_key_for_current_fs() -> String:
match current_fs:
1: return RAY_25_1
2: return RAY_25_2
3: return RAY_25_3
4: return RAY_25_4
5: return RAY_25_5
6: return RAY_25_6
7: return RAY_25_7
_: return ''
func _update_fs_states(fs_result: Dictionary, fs_array: Array) -> void:
for fs in fs_array:
var fs_meta: String = fs.get_meta('fs')
if fs_result.has(fs_meta):
var new_state = fs_result[fs_meta]
fs.state = new_state
block_fs_config[fs_meta] = new_state
func on_stop_control() -> void:
state = STATE_MASHINE.FS_TURN_OFF
static func on_control_result(ip_config: Dictionary, dkm_config: Dictionary, fs_config: Dictionary, ctrl_results: Dictionary) -> Dictionary:
var all_blocks_ip_ok = true
var all_blocks_dkm_ok = true
var all_blocks_fs_ok = true
for block in ip_config:
if not ip_config[block][1]:
all_blocks_ip_ok = false
ctrl_results['block_ip'] = all_blocks_ip_ok
for block in dkm_config:
if not dkm_config[block]:
all_blocks_dkm_ok = false
ctrl_results['dkm'] = all_blocks_dkm_ok
for block in fs_config:
if not fs_config[block]:
all_blocks_fs_ok = false
ctrl_results['fs'] = all_blocks_fs_ok
return ctrl_results
## Установка угла и аттенюации для УМ
static func on_ug_setting(prd_module: Object, prd_unit: Object, settings_ug: Dictionary) -> void:
var result_1 = ((settings_ug.ATT_UM_1 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07)
var result_2 = ((settings_ug.ATT_UM_2 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07)
prd_module.cmd_array.append([prd_unit.CmdCode.WRITE_ISA, [settings_ug.ADDR_UG_LITERA_1, result_1,
settings_ug.ADDR_UG_LITERA_2, result_2,
settings_ug.ADDR_UG_LITERA_3, settings_ug.ATT_UM_3]])
prd_module.cmd_array.append([prd_unit.CmdCode.READ_ISA, [settings_ug.ADDR_UG_LITERA_1, settings_ug.ADDR_UG_LITERA_2, settings_ug.ADDR_UG_LITERA_3]])
static func power_um_control_result(ctrl_results: Dictionary, constan: Dictionary, pwr_result: Dictionary) -> Dictionary:
ctrl_results['power_um'] = true
for amp_array in pwr_result.values():
if amp_array.size() == 0:
ctrl_results['power_um'] = false
return ctrl_results
for amp_array in pwr_result.values():
for value in amp_array:
if value < constan.TEMP_THRESHOLD:
ctrl_results['power_um'] = false
break
return ctrl_results
## Управаление модулем фс (включить/отключить излучение)
static func manage_fs(mode: bool, pribor: String, p_conf: Dictionary, fs_params: Dictionary, cur_fs: int, power_um: int) -> void:
# Получаем конфигурацию для текущего прибора
var config: Dictionary = p_conf[pribor]
var angle: float = config.angle
var sectors: Array = config.sectors
# Формируем выходные данные
var interfer_name: String = 'k1' if mode else 'off'
var fs_arr: Array = []
if cur_fs in fs_params:
var params = fs_params[cur_fs]
fs_arr.append([
angle,
params.freq,
params.width,
sectors[cur_fs - 1] if cur_fs == 1 else sectors[cur_fs - 5] if cur_fs > 5 else sectors[cur_fs - 4] if cur_fs > 3 else sectors[cur_fs - 2]
])
signaller.emit_signal('interfer_init', interfer_name, fs_arr, power_um)
## Проверка касет П1 и ИП МА2000
static func check_block_ip(status_prd: PackedByteArray, ip_config: Dictionary) -> Dictionary:
# Конфигурация проверяемых блоков
var byte_dry: int = 27
var ug_valid: bool = (status_prd[0] >> 1) & 1
for block in ip_config:
var bit: int = ip_config[block][0]
if ug_valid:
var status = status_prd[byte_dry] >> bit & 1
ip_config[block][1] = false if status else true
return ip_config
## Проверка кассеты у-5 (ЯУ-07Б, ЭМС-Г, УГ, УКП-1, УКП-2)
static func check_block_kasseta_y5(status_prd: PackedByteArray, y5_config: Dictionary) -> Dictionary:
y5_config.yau07 = true
y5_config.ems = (status_prd[0] & 1) and ((status_prd[0] >> 4) & 1)
y5_config.ug = (status_prd[0] >> 1) & 1
y5_config.ukp1 = (status_prd[0] >> 2) & 1
y5_config.ukp2 = (status_prd[0] >> 3) & 1
return y5_config
## Проверка температур УМ от УКП
static func check_temperature_um(status_prd: PackedByteArray, power_amplifier: Array) -> void:
const Constants: Dictionary = {
'CONST_MIN_TEMP': -25,
'MAXIMUM_CODE_ADC': 3796,
'MINIMUM_CODE_AD': 2660,
'TEMPERATURE_UKP_1': 47,
'TEMPERATURE_UKP_2': 79,
}
const TEMP: float = 115.0 / (Constants.MAXIMUM_CODE_ADC - Constants.MINIMUM_CODE_AD)
var ukp1_online: int = (status_prd[0] >> 2) & 1
var ukp2_online = (status_prd[0] >> 3) & 1
if ukp1_online:
var tmp_1: int
var temperature_ukp_1: int
for i_temp in 6:
temperature_ukp_1 = status_prd.decode_u16(Constants.TEMPERATURE_UKP_1 + 2 * i_temp)
tmp_1 = round(Constants.CONST_MIN_TEMP + (Constants.MAXIMUM_CODE_ADC - temperature_ukp_1) * TEMP + 3)
power_amplifier[i_temp].value0 = tmp_1
if power_amplifier.size() > 12: # Темпуратура от УМ литеры 1
temperature_ukp_1 = status_prd.decode_u16(Constants.TEMPERATURE_UKP_1 + 2 * 7)
tmp_1 = round(Constants.CONST_MIN_TEMP + (Constants.MAXIMUM_CODE_ADC - temperature_ukp_1) * TEMP + 3)
power_amplifier[6].value0 = tmp_1
if ukp2_online:
for i_temp in 6:
var temperature_ukp_2: int = status_prd.decode_u16(Constants.TEMPERATURE_UKP_2 + 2 * i_temp)
var tmp_2: int = round(Constants.CONST_MIN_TEMP + (Constants.MAXIMUM_CODE_ADC - temperature_ukp_2) * TEMP + 3)
if power_amplifier.size() > 12:
power_amplifier[i_temp+7].value0 = tmp_2
else:
power_amplifier[i_temp+6].value0 = tmp_2
## Проверка ДКМ
static func check_dkm(status_prd: PackedByteArray, bit_dkm: int, dkm_result: Dictionary) -> Dictionary:
var dkm: int = 28
var status_dkm = status_prd[dkm] >> bit_dkm & 1
if bit_dkm == 0:
dkm_result['dkm_1'] = status_dkm
elif bit_dkm == 1:
dkm_result['dkm_2'] = status_dkm
elif bit_dkm == 2:
dkm_result['dkm_3'] = status_dkm
elif bit_dkm == 3:
dkm_result['dkm_4'] = status_dkm
elif bit_dkm == 4:
dkm_result['dkm_5'] = status_dkm
elif bit_dkm == 5:
dkm_result['dkm_6'] = status_dkm
elif bit_dkm == 6:
dkm_result['dkm_7'] = status_dkm
return dkm_result
##
static func _create_fs_mapping(s_name: String) -> Dictionary:
var suffixes: Dictionary = {
0: '', 1: '', 2: '', 3: '',
4: '', 5: '', 6: '', 7: '',
8: '', 9: '', 10: '', 11: '',
12: '', 13: '', 14: '', 15: '',
16: '', 17: '', 18: '', 19: '',
20: '', 21: '', 22: '', 23: '',
24: '', 25: '', 26: '', 27: '',
}
var mapping: Dictionary = {}
for fs_num in suffixes:
mapping[fs_num] = {'condition': s_name == suffixes[fs_num]}
return mapping
##
static func on_fs_state(packet_type_7: Dictionary, fs_mapping: Dictionary, fs_results: Dictionary) -> Dictionary:
var FS_RULES = [
{'key': 'fs_1', 'min': 0, 'max': 4},
{'key': 'fs_2', 'min': 4, 'max': 8},
{'key': 'fs_3', 'min': 8, 'max': 12},
{'key': 'fs_4', 'min': 12, 'max': 16},
{'key': 'fs_5', 'min': 16, 'max': 20},
{'key': 'fs_6', 'min': 20, 'max': 24},
{'key': 'fs_7', 'min': 24, 'max': 27}
]
var updated_results := fs_results.duplicate()
for fs_num in packet_type_7:
if not (fs_num in fs_mapping and fs_mapping[fs_num]['condition']):
continue
var fs_data = packet_type_7[fs_num]
for rule_key in FS_RULES.size():
var rule: Dictionary = FS_RULES[rule_key]
if _should_apply_rule(fs_num, rule, updated_results):
updated_results[rule.key] = fs_data.isg
break
return updated_results
## Вспомогательная функция для проверки применения правила
static func _should_apply_rule(fs_num: int, rule: Dictionary, results: Dictionary) -> bool:
return bool(fs_num >= rule.min and fs_num < rule.max) and results.has(rule.key)
##
static func power_um_ukp(status: PackedByteArray, crnt_fs: int, pwr_result: Array) -> Array:
const Constants: Dictionary = {'POWER_UKP_1' : 31, 'POWER_UKP_2': 63}
var power_values: Array = []
var base_offset = 0
var iteration: int = 6
var ug_valid: bool = (status[0] >> 2) & 1
match crnt_fs:
1:
# Обработка для current_fs = 1 (одно значение)
var value = status.decode_u16(Constants.POWER_UKP_1 + 2 * 7)
if ug_valid:
power_values = [value]
2:
# Обработка для current_fs = 2 (6 значений из УКП1)
base_offset = Constants.POWER_UKP_1
if ug_valid:
for i in iteration:
power_values.append(status.decode_u16(base_offset + 2 * i))
3:
# Обработка для current_fs = 3 (6 значений из УКП2)
base_offset = Constants.POWER_UKP_2
if ug_valid:
for i in iteration:
power_values.append(status.decode_u16(base_offset + 2 * i))
4:
# Обработка для current_fs = 4 (6 значений из УКП1)
base_offset = Constants.POWER_UKP_1
if ug_valid:
for i in iteration:
power_values.append(status.decode_u16(base_offset + 2 * i))
5:
# Обработка для current_fs = 5 (6 значений из УКП2)
base_offset = Constants.POWER_UKP_2
if ug_valid:
for i in iteration:
power_values.append(status.decode_u16(base_offset + 2 * i))
6:
# Обработка для current_fs = 6 (6 значений из УКП1)
base_offset = Constants.POWER_UKP_1
if ug_valid:
for i in iteration:
power_values.append(status.decode_u16(base_offset + 2 * i))
7:
# Обработка для current_fs = 7 (6 значений из УКП2)
base_offset = Constants.POWER_UKP_2
if ug_valid:
for i in iteration:
power_values.append(status.decode_u16(base_offset + 2 * i))
power_values = update_max_power_values(power_values, pwr_result)
return power_values
## Обновление максимальных значений
static func update_max_power_values(power_data: Array, max_power_values: Array) -> Array:
if power_data.size() != 6:
if max_power_values.is_empty():
max_power_values = power_data.duplicate()
elif power_data[0] > max_power_values[0]:
max_power_values = power_data.duplicate()
return max_power_values
if max_power_values.is_empty():
max_power_values = power_data.duplicate()
else:
for i in 6:
if power_data[i] > max_power_values[i]:
max_power_values[i] = power_data[i]
return max_power_values.duplicate()