699 lines
29 KiB
GDScript
699 lines
29 KiB
GDScript
class_name Iterfer extends Node
|
||
|
||
## Представление помехи.
|
||
|
||
## Режимы помехи.
|
||
const ITERFER_MODE = {
|
||
INTERFER_OFF: [INTERFER_OFF, {}, 0],
|
||
'srni1': [INTERFER_IQFILE, SRNI1_PARAMS, 1],
|
||
'srnm2': ['Линейная ЧМ', SRNM2_PARAMS, 2],
|
||
'srngps': [INTERFER_IQFILE, SRNGPS_PARAMS, 3],
|
||
'lchm1': ['Линейная ЧМ', LCHM1_PARAMS, 10],
|
||
'lchm2': ['Линейная ЧМ', LCHM2_PARAMS, 16],
|
||
'mchm1': [INTERFER_IQFILE, MCHM1_PARAMS, 11],
|
||
'pdm2': [INTERFER_IQFILE, PDM2_PARAMS, 12],
|
||
'pdm4': [INTERFER_IQFILE, PDM4_PARAMS, 13],
|
||
'pdm4s': [INTERFER_IQFILE, PDM4S_PARAMS, 14],
|
||
'pdchm': [INTERFER_IQFILE, PDCHM_PARAMS, 15],
|
||
'svi1': [INTERFER_IQFILE, SVI1_PARAMS, 20],
|
||
'svm2': [INTERFER_IQFILE, SVM2_PARAMS, 21],
|
||
'k1': [INTERFER_IQFILE, K1_PARAMS, 50],
|
||
'ozp1': [INTERFER_IQFILE, OZP1_PARAMS, 51],
|
||
'eprls': [INTERFER_IQFILE, EPRLS_PARAMS, 52] }
|
||
|
||
const RECOMMEND_INTERFER = {
|
||
'ПСП + ФМ-2': 'srni1',
|
||
'Линейная ЧМ': 'lchm1'
|
||
}
|
||
|
||
const SRNI1_PARAMS = {'files': {3: ['SRNI1_LIT4.pcm', 1220],
|
||
4: ['SRNI1_LIT5.pcm', 1555]},
|
||
'call_proc': 'call_diap',
|
||
'par_names' : ['freq', 'filename']}
|
||
const SRNM2_PARAMS = {'par_names' : ['freq', 'width', 'period']}
|
||
const SRNGPS_PARAMS = {'par_names' : ['freq', 'filename'],
|
||
'files': 'SRNGPS.pcm',
|
||
'call_proc': 'call_all_diap'}
|
||
const LCHM1_PARAMS = {'par_names' : ['freq', 'width', 'period']}
|
||
const LCHM2_PARAMS = {'par_names' : ['freq', 'width', 'period']}
|
||
const MCHM1_PARAMS = {'par_names' : ['freq', 'filename'],
|
||
'files': 'MCHM1.pcm',
|
||
'call_proc': 'call_all_diap'}
|
||
const PDM2_PARAMS = {'files': {
|
||
20 : 'PDM2_20.pcm',
|
||
40: 'PDM2_40.pcm',
|
||
88: 'PDM2_88.pcm',
|
||
112: 'PDM2_112.pcm' },
|
||
'call_proc': 'call_pdchm',
|
||
'par_names' : ['freq', 'filename'],}
|
||
const PDM4_PARAMS = {'files': {
|
||
20 : 'PDM4_20.pcm',
|
||
40: 'PDM4_40.pcm',
|
||
84: 'PDM4_84.pcm',
|
||
108: 'PDM4_108.pcm' },
|
||
'call_proc': 'call_pdchm',
|
||
'par_names' : ['freq', 'filename'],}
|
||
const PDM4S_PARAMS = {'files': {
|
||
5 : 'PDM4S_5.pcm',
|
||
7 : 'PDM4S_10.pcm',
|
||
10: 'PDM4S_2_5.pcm',
|
||
20: 'PDM4S_10.pcm' },
|
||
'call_proc': 'call_pdchm',
|
||
'par_names' : ['freq', 'filename'],}
|
||
const K1_PARAMS = {'files' : 'K1.pcm',
|
||
'call_proc' : 'call_all_diap',
|
||
'par_names' : ['freq', 'filename']}
|
||
const OZP1_PARAMS = {'files': 'OZP1.pcm',
|
||
'call_proc': 'call_all_diap',
|
||
'par_names' : ['freq', 'filename']}
|
||
# Файл : Диапазон: ['имя файла', частота]
|
||
const SVI1_PARAMS = {'files': {1: ['SVI1_LIT2.pcm', 1017],
|
||
2: ['SVI1_LIT3.pcm', 1156]},
|
||
'call_proc': 'call_diap',
|
||
'par_names' : ['freq', 'filename']}
|
||
const SVM2_PARAMS = {'files': {1: ['SVM2_LIT2.pcm', 1017],
|
||
2: ['SVM2_LIT3.pcm', 1156]},
|
||
'call_proc': 'call_diap',
|
||
'par_names' : ['freq', 'filename']}
|
||
const EPRLS_PARAMS = {'files' : 'ERLS.pcm',
|
||
'call_proc' : 'call_all_diap',
|
||
'par_names' : ['freq', 'filename']}
|
||
# Файл : Ключ (ширина): ['имя файла']
|
||
const PDCHM_PARAMS = {'files': {
|
||
5 : 'PDCHM_5.pcm',
|
||
10: 'PDCHM_10.pcm',
|
||
20: 'PDCHM_20.pcm',
|
||
40: 'PDCHM_40.pcm' },
|
||
'call_proc': 'call_pdchm',
|
||
'par_names' : ['freq', 'filename'],}
|
||
|
||
const SOURCE_INTERFER = ['th','fs','cu']
|
||
const EXCLUDE_INTERFER = ['srni1', 'srnm2', 'srngps', 'svi1', 'svm2']
|
||
const ID_INTERFERS_LEN = 63 ## Размер пула номеров целей.
|
||
const INTERFER_OFF = 'off'
|
||
const INTERFER_IQFILE = 'IQ-файл'
|
||
const POW_DEFAULT: float = 50.0
|
||
var msg6_num: int = 0 ## Счётчик сообщений "тип 6"
|
||
var msg8_num: int = 0 ## Счётчик сообщений "тип 8"
|
||
var id_array: Array ## Массив id воздействий.
|
||
var thrs: Dictionary ## Словарь воздействия для целей, ключ - id воздействия.
|
||
var fs: Dictionary ## Словарь воздействий для секторов, ключ - id воздействия.
|
||
var cu: Dictionary ## Словарь воздействий для 5П-28, ключ - id воздействия.
|
||
var thrs_dict: Dictionary ## Ссылка на словарь целей
|
||
var auto_enabled: bool = false ## Режим автомата
|
||
var emit_enable: bool = true ## Разрешить излучение
|
||
var trenazh_mode: bool = false ## Переключение режима Тренаж
|
||
var course = 0.0 ## Курс корабля
|
||
var gos_flag = true ## Флаг работать по своим целям
|
||
var gos_protocols: PackedStringArray ## Список протоколов своих целей
|
||
var gos_nmfs: Array ## Список номеров блоков ФС для которых запрещена работа
|
||
var fs_closed: Dictionary ## Словарь секторов запрета
|
||
|
||
|
||
## Сеанс помехи.
|
||
class Interfer:
|
||
var ispp: int = 0 ## Индекс сеанса.
|
||
var svk: = 0 ## Состояние сеанса. Ответ КАПСРПБ. Возможные значения в [param ITERFER_STATE].
|
||
var krp: String = '' ## Тип помехи. Возможные значения в [param INTERFER_MODE].
|
||
var powp: float = 100.0 ## Мощность излучения выраженная в процентах.
|
||
var kni: = 0.0 ## Курсовой угол направления излучения.
|
||
var params: = {} ## Параметры помехи.
|
||
var get_params: Array[String] ## Запрос массива параметров (список запрошенных параметров).
|
||
var retss: int ## Значение счётчика сообщения в котором был произведён запрос массива параметров.
|
||
var tick_tx: int ## Тик время обновления цели, мс.
|
||
var source_interfer: String = '' ## Тип объекта по которой поставлена помеха.
|
||
var modulation: bool ## Модуляция для включения усилителей
|
||
var um: float ## Угол места для помехи.
|
||
var nmfs: int = 0 ## Номер модуля ФС в нумерации СТЦ
|
||
var priority: int = 0 ## Приоритет помехи
|
||
|
||
func _to_string() -> String:
|
||
return 'номер: %d название: %s частота: %0.1f МГц пеленг: %0.1f гр.' % [ispp, ITERFER_MODE[krp][0], params['freq'], kni]
|
||
|
||
func get_msg6_data(msg_num: int) -> PackedByteArray:
|
||
var data_to_json : Dictionary = {}
|
||
data_to_json['ts'] = 6
|
||
data_to_json['ss'] = msg_num
|
||
data_to_json['ispp'] = ispp
|
||
data_to_json['krp'] = ITERFER_MODE[krp][0]
|
||
data_to_json['nmfs'] = nmfs
|
||
if krp != INTERFER_OFF:
|
||
data_to_json['kni'] = kni
|
||
data_to_json['powp'] = powp
|
||
data_to_json['params'] = {}
|
||
for key in ITERFER_MODE[krp][1]['par_names']:
|
||
if params.has(key):
|
||
data_to_json['params'][key] = params[key]
|
||
data_to_json['get'] = get_params
|
||
var pac = JSON.stringify(data_to_json).to_utf8_buffer()
|
||
return pac
|
||
|
||
func set_from_dic(dic: Dictionary):
|
||
var names: = tools.get_members_names(self)
|
||
names.any(func(vn): if dic.has(vn): set(vn, dic[vn]); return false)
|
||
|
||
func get_value(value_key):
|
||
var param = self.get(value_key)
|
||
if param == null:
|
||
if params.has(value_key): param = params[value_key]
|
||
return param
|
||
|
||
func set_value(value, value_key):
|
||
var param = self.get(value_key)
|
||
if param == null:
|
||
params[value_key] = value
|
||
else:
|
||
self.set(value_key, value)
|
||
|
||
signal interfer_preparing(ecm: Interfer) ## Вызывается в момент запуска помехи.
|
||
signal interfer_run(ecm: Interfer) ## Вызывается в момент начала работы помехи.
|
||
signal interfer_error(ecm: Interfer, msg: String) ## Вызывается при ошибке.
|
||
signal interfer_update(ecm: Interfer) ## Вызывается при обновлении помехи.
|
||
signal interfer_resized(ecms: Dictionary) ## Вызывается при изменении количества сеансов помех.
|
||
signal interfer_recommendate(ecm: Interfer) ## Вызывается когда назначается рекомендуемая для цели помеха
|
||
|
||
|
||
## Отправляет словарь помех в юнит, для запаковки и отправки в 5П28.
|
||
func on_get_interfers(unit, ecms) -> void: unit.pack_interfers(cu, ecms)
|
||
|
||
|
||
## Автомат выключен
|
||
func on_manual_control() -> void: auto_enabled = false
|
||
|
||
|
||
## Автомат отключен
|
||
func on_full_auto() -> void: auto_enabled = true
|
||
|
||
|
||
func _ready() -> void:
|
||
for i in ID_INTERFERS_LEN: # Заполняет массив ID целей
|
||
id_array.append(i + 1)
|
||
var unit_caps = network.get_unit_instance('уарэп-капсрпб')
|
||
var unit_5p28 = network.get_unit_instance('уарэп-5п28')
|
||
var timer_check_state: = Timer.new()
|
||
add_child(timer_check_state)
|
||
var resend_timeout = ProjectSettings.get_setting('application/interfer/resend_timeout', 1000.0)
|
||
var ecms: Dictionary = {} ## Словарь помех.
|
||
var seczaps: Dictionary = {} ## Словарь секторов запрета
|
||
timer_check_state.connect('timeout', Callable(self, 'on_timer_check_state').bind(unit_caps, ecms, resend_timeout))
|
||
timer_check_state.start(resend_timeout / 1000.0)
|
||
unit_caps.connect('data_received', Callable(self, 'on_data_capsrpb_received').bind(ecms, seczaps))
|
||
unit_5p28.connect('get_interfers', Callable(self, 'on_get_interfers').bind(unit_5p28, ecms))
|
||
signaller.connect('interfer_create', Callable(self, 'on_interfer_create').bind(unit_caps, ecms))
|
||
signaller.connect('interfer_rcv', Callable(self, 'on_interfer_rcv').bind(unit_5p28, unit_caps, ecms))
|
||
signaller.connect('interfer_new', Callable(self, 'on_interfer_new').bind(unit_caps))
|
||
signaller.connect('interfer_off_all', Callable(self, 'on_interfer_off_all').bind(unit_caps, ecms))
|
||
signaller.connect('th_aoa_update', Callable(self, 'on_th_aoa_update').bind(ecms, unit_caps))
|
||
signaller.connect('interfer_off', Callable(self, 'on_interfer_off').bind(ecms))
|
||
signaller.connect('manual_control', Callable(self, 'on_manual_control'))
|
||
signaller.connect('full_auto', Callable(self, 'on_full_auto'))
|
||
signaller.connect('interfer_prinuditelno', Callable(self, 'on_interfer_prinuditelno'))
|
||
signaller.connect('emit_changed', Callable(self, 'on_emit_changed').bind(ecms))
|
||
signaller.connect('режим_тренаж', on_trenazh_mode)
|
||
signaller.connect('update_fs_closed', Callable(self, 'on_update_fs_closed'))
|
||
threats.connect('threat_lost', Callable(self, 'on_threats_lost').bind(ecms, unit_caps))
|
||
threats.connect('threats_resized', Callable(self, 'on_threats_resized'))
|
||
threats.connect('threat_update', Callable(self, 'on_threats_update').bind(ecms, unit_caps))
|
||
ProjectSettings.connect('settings_changed', on_settings_changed)
|
||
var unit_nav = network.get_unit_instance('навигация')
|
||
unit_nav.connect('data_received', on_nav_data_received.bind(unit_caps))
|
||
|
||
|
||
func on_trenazh_mode(val: bool): trenazh_mode = val
|
||
|
||
|
||
func on_nav_data_received(coords: Dictionary, unit_caps):
|
||
var ship_time = Time.get_datetime_dict_from_system()
|
||
course = coords.get('k', 0.0)
|
||
var data_to_json = {
|
||
'ts': 8,
|
||
'ss': msg8_num,
|
||
'roll': coords.get('bk', 0),
|
||
'trim': coords.get('kk', 0),
|
||
'long': coords.get('longitude', 0),
|
||
'lat': coords.get('latitude', 0),
|
||
'course': coords.get('k', 0),
|
||
'speed': coords.get('speed', 0),
|
||
'year': ship_time['year'],
|
||
'month': ship_time['month'],
|
||
'day': ship_time['day'],
|
||
'hour': ship_time['hour'],
|
||
'minute': ship_time['minute'],
|
||
'second': ship_time['second'],}
|
||
var json_data = JSON.stringify(data_to_json).to_utf8_buffer()
|
||
unit_caps.tx_stack.append(json_data)
|
||
msg8_num += 1
|
||
msg8_num %= 0xffffffff
|
||
|
||
|
||
## Проверяет состояние отправки пакета и если не доставлен, повторяет отправку.
|
||
func on_timer_check_state(unit_instance, ecms, resend_timeout) -> void:
|
||
var tick = Time.get_ticks_msec()
|
||
for ecm in ecms.values():
|
||
if (tick - ecm.tick_tx) >= resend_timeout:
|
||
send_ecm(ecm, unit_instance)
|
||
ecm.tick_tx = tick
|
||
|
||
|
||
func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit_instance) -> void:
|
||
gos_nmfs.clear()
|
||
for thr in threats.values():
|
||
var fs_arr: Array = []
|
||
var th_aoa = fposmod(thr.aoa - course, 360)
|
||
prd.find_fs_index(th_aoa, thr.freq, fs_arr)
|
||
if fs_arr.size():
|
||
for item in fs_arr:
|
||
var nmfs = prd.FS_PRD[item][1]
|
||
thr.nmfs = nmfs
|
||
if (thr.proto in gos_protocols) and thr.fflags.proto and (not gos_flag):
|
||
gos_nmfs.append(nmfs)
|
||
|
||
thr.emit_state = 0
|
||
for ecm in ecms.values():
|
||
if thr.nmfs == ecm.nmfs:
|
||
set_th_emit(thr, ecm)
|
||
var ecm_active = true
|
||
if not gos_flag:
|
||
if ecm.nmfs in gos_nmfs:
|
||
interfer_off(ecm, unit_instance)
|
||
ecm_active = false
|
||
if ecm_active and (prd.fs_caps_id[ecm.nmfs] in fs_closed):
|
||
interfer_off(ecm, unit_instance)
|
||
|
||
var th_id = thr.id
|
||
for ecm_i in thrs.keys():
|
||
if thrs[ecm_i] == th_id:
|
||
var ecm = ecms[ecm_i]
|
||
ecm.params['freq'] = thr.freq
|
||
ecm.kni = fposmod(thr.aoa - course, 360)
|
||
call_ecm_proc(ecm)
|
||
if ecm.nmfs in gos_nmfs:
|
||
interfer_off(ecm, unit_instance)
|
||
elif prd.fs_caps_id[ecm.nmfs] in fs_closed:
|
||
interfer_off(ecm, unit_instance)
|
||
else:
|
||
send_ecm(ecm, unit_instance)
|
||
signaller.emit_signal('fs_update_color', ecms)
|
||
prd.update_fs_state(ecms, trenazh_mode)
|
||
|
||
if auto_enabled:
|
||
for thr in threats.values():
|
||
var fs_arr: Array = []
|
||
var th_aoa = fposmod(thr.aoa - course, 360)
|
||
prd.find_fs_index(th_aoa, thr.freq, fs_arr)
|
||
if fs_arr.size():
|
||
var need_continue = false
|
||
for item in fs_arr:
|
||
var nmfs = prd.FS_PRD[item][1]
|
||
if (nmfs in gos_nmfs) and (not gos_flag): need_continue = true
|
||
if prd.fs_caps_id[nmfs] in fs_closed: need_continue = true
|
||
if need_continue: continue
|
||
thr.auto_selected = true
|
||
if (thr.rkrp != '') and thr.fflags.rkrp and auto_enabled:
|
||
var krp = get_krp(thr)
|
||
if krp != '':
|
||
signaller.emit_signal('interfer_init', krp, [], interfer.POW_DEFAULT)
|
||
thr.auto_selected = false
|
||
continue
|
||
signaller.emit_signal('interfer_init', 'lchm1', [], interfer.POW_DEFAULT)
|
||
thr.auto_selected = false
|
||
|
||
|
||
## Производит приём состояния помех. [param unit] -> [param ecms].
|
||
func on_data_capsrpb_received(unit_instance: capsrpb.CapsRpb, ecms: Dictionary, seczaps: Dictionary) -> void:
|
||
if not unit_instance.json_dic.has('ts'): return
|
||
if not tools.type_is_num(unit_instance.json_dic['ts']): return
|
||
if unit_instance.json_dic['ts'] != 5: return
|
||
map_msvk_to_ecms(unit_instance, ecms)
|
||
map_mpchf_to_seczaps(unit_instance, seczaps)
|
||
|
||
|
||
## Извлекает массив состояний выполнения команды
|
||
func map_msvk_to_ecms(unit_instance: unit.Unit, ecms: Dictionary):
|
||
var json_dic = unit_instance.json_dic
|
||
if not json_dic.has('msvk'): return
|
||
var msvk = unit_instance.json_dic.get('msvk', [])
|
||
for dic_msvk in msvk:
|
||
if dic_msvk is not Dictionary: continue
|
||
if not dic_msvk.has('ispp'): continue
|
||
var ispp = int(dic_msvk['ispp'])
|
||
var errmsg = dic_msvk.get('errmsg', '')
|
||
if errmsg:
|
||
log.error('сеанс %d: \"%s\"' % [ispp, errmsg])
|
||
if ecms.has(ispp):
|
||
var ecm = ecms[ispp]
|
||
ecm.set_from_dic(dic_msvk)
|
||
call_deferred('emit_signal', 'interfer_update', ecm)
|
||
else:
|
||
var ecm = Interfer.new()
|
||
ecm.set_from_dic(dic_msvk)
|
||
ecm.krp = INTERFER_OFF
|
||
send_ecm(ecm, unit_instance)
|
||
|
||
|
||
## Извлекает массив пространственно-частотных фильтров
|
||
func map_mpchf_to_seczaps(unit_instance: unit.Unit, _seczaps: Dictionary):
|
||
var json_dic = unit_instance.json_dic
|
||
var mpchf = json_dic.get('mpchf', [])
|
||
if mpchf is not Array: return
|
||
for item in mpchf:
|
||
if item is not Dictionary: continue
|
||
var id = item.get('index', -1)
|
||
if id < 0: continue
|
||
var freq = item.get('freq', 0)
|
||
if freq == 0: continue
|
||
|
||
|
||
## Вызыватся, когда пользователь выбрал помеху и выбраны цели.
|
||
func on_interfer_create(interfer_name, sel_threats, fs_arr, power, u, ecms) -> void:
|
||
for item in sel_threats:
|
||
if auto_enabled:
|
||
var need_continue = false
|
||
for ecm in ecms.values():
|
||
if ecm.nmfs == item.nmfs:
|
||
if item.priority > ecm.priority:
|
||
interfer_off(ecm, u)
|
||
elif item.priority < ecm.priority:
|
||
need_continue = true
|
||
break
|
||
if need_continue: continue
|
||
var param: Dictionary = {}
|
||
var kni: float = item.aoa - course
|
||
if kni < 0:
|
||
kni += 360.0
|
||
var id = item.id
|
||
param['freq'] = item.freq
|
||
param['width'] = item.width * 1.5
|
||
if (item.rkrp != '') and item.fflags.rkrp and auto_enabled:
|
||
var krp = get_krp(item)
|
||
if krp != '':
|
||
interfer_name = krp
|
||
set_rparams(item, param)
|
||
if (param['width'] < settings.WIDTH_MIN):
|
||
param['width'] = settings.WIDTH_MIN
|
||
elif (param['width'] > settings.WIDTH_MAX):
|
||
param['width'] = settings.WIDTH_MAX
|
||
interfer_create(u, interfer_name, ecms, param, kni, id, thrs, SOURCE_INTERFER[0], power)
|
||
|
||
for item in fs_arr:
|
||
var param: Dictionary = {}
|
||
var kni: float = item[0]
|
||
var id = item[3]
|
||
param['freq'] = item[1]
|
||
param['width'] = item[2]
|
||
if (param['width'] < settings.WIDTH_MIN):
|
||
param['width'] = settings.WIDTH_MIN
|
||
elif (param['width'] > settings.WIDTH_MAX):
|
||
param['width'] = settings.WIDTH_MAX
|
||
interfer_create(u, interfer_name, ecms, param, kni, id, fs, SOURCE_INTERFER[1], power)
|
||
|
||
|
||
func on_interfer_rcv(interfer_params: Array, unit0, unit_caps, ecms) -> void:
|
||
var err: bool = false
|
||
var mode = interfer_params[0]
|
||
var id = interfer_params[1]
|
||
var aoa = interfer_params[2] - course
|
||
if aoa < 0:
|
||
aoa += 360
|
||
var um = interfer_params[3]
|
||
if (aoa < 0.0) and (aoa > 360.0):
|
||
err = true
|
||
var param: Dictionary = {}
|
||
if (um < -settings.UM_MIN) and (um > settings.UM_MAX):
|
||
err = true
|
||
param['um'] = um
|
||
param['freq'] = interfer_params[4]
|
||
if (param['freq'] < settings.FREQ_MIN) and (param['freq'] > settings.FREQ_MAX):
|
||
err = true
|
||
param['width'] = interfer_params[5]
|
||
if (param['width'] < settings.WIDTH_MIN) and (param['width'] > settings.WIDTH_MAX):
|
||
err = true
|
||
var interfer_name: = ''
|
||
for key in ITERFER_MODE:
|
||
if ITERFER_MODE[key][2] == mode:
|
||
interfer_name = key
|
||
break
|
||
if interfer_name == '':
|
||
err = true
|
||
if not err:
|
||
interfer_create(unit_caps, interfer_name, ecms, param, aoa, id, cu, SOURCE_INTERFER[2], POW_DEFAULT)
|
||
unit0.on_interfer_accept(err)
|
||
|
||
|
||
func interfer_create(u, interfer_name, ecms, param, kni, id, dict, source_interfer, power) -> void:
|
||
var sz = ecms.size()
|
||
var ispp: int = 0
|
||
param['dur'] = 1.0 # Необходимо добавить параметры управления
|
||
param['period'] = 1.0 # Необходимо добавить параметры управления
|
||
var key = dict.find_key(id)
|
||
if source_interfer != SOURCE_INTERFER[2]:
|
||
if key != null:
|
||
ispp = key
|
||
else:
|
||
if interfer_name == 'off':
|
||
return
|
||
ispp = pop_id()
|
||
if ispp == 0:
|
||
return
|
||
else:
|
||
ispp = id
|
||
dict[ispp] = id
|
||
var ecm: Interfer
|
||
if ecms.has(ispp):
|
||
ecm = ecms[ispp]
|
||
else:
|
||
ecm = Interfer.new()
|
||
ecm.ispp = ispp
|
||
ecms[ispp] = ecm
|
||
ecm.modulation = emit_enable
|
||
ecm.kni = kni
|
||
ecm.krp = interfer_name
|
||
ecm.params = param
|
||
ecm.powp = power
|
||
ecm.source_interfer = source_interfer
|
||
ecm.um = param.get('um', 15.0) # Значение по умолчанию
|
||
if source_interfer == SOURCE_INTERFER[0]:
|
||
if thrs_dict.has(dict[ispp]):
|
||
ecm.priority = thrs_dict[dict[ispp]].priority
|
||
call_ecm_proc(ecm)
|
||
var set_nmfs_ok = set_nmfs(ecm)
|
||
if set_nmfs_ok != Error.OK:
|
||
log.error('Ошибка выбора модуля ФС для помехи: %s' %[ecm.ispp])
|
||
signaller.emit_signal('interfer_new', ecm)
|
||
if interfer_name == 'off':
|
||
signaller.emit_signal('interfer_off', ecm)
|
||
thrs.erase(ispp)
|
||
ecm.tick_tx = Time.get_ticks_msec()
|
||
send_ecm(ecm, u)
|
||
if sz != ecms.size():
|
||
call_deferred('emit_signal', 'interfer_resized', ecms)
|
||
|
||
|
||
func send_ecm(ecm, unit0) -> void:
|
||
if ecm.krp != INTERFER_OFF:
|
||
if not ecm.modulation:
|
||
ecm.svk = 0
|
||
call_deferred('emit_signal', 'interfer_update', ecm)
|
||
return
|
||
msg6_num += 1
|
||
var json_data = ecm.get_msg6_data(msg6_num)
|
||
unit0.tx_stack.append(json_data)
|
||
|
||
|
||
func on_interfer_off_all(unit0, ecms: Dictionary) -> void:
|
||
for ecm in ecms.values():
|
||
interfer_off(ecm, unit0)
|
||
|
||
|
||
func on_threats_lost(th, ecms, unit0) -> void:
|
||
for key in interfer.thrs:
|
||
if interfer.thrs[key] == th.id:
|
||
var ecm_id = key
|
||
var ecm = ecms[ecm_id]
|
||
interfer_off(ecm, unit0)
|
||
|
||
|
||
func pop_id() -> int:
|
||
var id = 0
|
||
if len(id_array):
|
||
id = id_array[0]
|
||
id_array.remove_at(0)
|
||
return id
|
||
|
||
|
||
func push_id(id: int) -> void:
|
||
id_array.append(id)
|
||
id_array.sort()
|
||
|
||
|
||
func on_emit_changed(state, ecms) -> void:
|
||
emit_enable = state
|
||
for ecm in ecms.values():
|
||
ecm.modulation = state
|
||
|
||
|
||
func call_all_diap(ecm, ecm_params: Dictionary):
|
||
ecm.params['filename'] = ecm_params['files']
|
||
|
||
|
||
func call_diap(ecm, ecm_params: Dictionary):
|
||
var fs_index_arr: Array
|
||
prd.get_fs_index(ecm, fs_index_arr)
|
||
if len(fs_index_arr):
|
||
var band = fs_index_arr[0] / 4
|
||
if ecm_params['files'].has(band):
|
||
ecm.params['filename'] = ecm_params['files'][band][0]
|
||
ecm.params['freq'] = ecm_params['files'][band][1]
|
||
|
||
|
||
func call_pdchm(ecm, ecm_params: Dictionary):
|
||
var temp_key: float = settings.WIDTH_MIN
|
||
for key in ecm_params['files'].keys():
|
||
if key > temp_key: temp_key = key
|
||
for key in ecm_params['files'].keys():
|
||
if key < ecm.params['width']: continue
|
||
if key < temp_key:
|
||
temp_key = key
|
||
ecm.params['filename'] = ecm_params['files'][int(temp_key)]
|
||
|
||
|
||
func set_nmfs(ecm):
|
||
var fs_index_arr: Array
|
||
prd.get_fs_index(ecm, fs_index_arr)
|
||
if len(fs_index_arr):
|
||
ecm.nmfs = prd.FS_PRD[fs_index_arr[0]][1]
|
||
return Error.OK
|
||
else:
|
||
return Error.FAILED
|
||
|
||
|
||
func on_threats_resized(th_dic):
|
||
thrs_dict = th_dic
|
||
|
||
|
||
func on_threats_update(threat, ecms, unit_caps):
|
||
var th_id = threat.id
|
||
var ecm = null
|
||
for ecm_i in thrs.keys():
|
||
if thrs[ecm_i] == th_id:
|
||
ecm = ecms[ecm_i]
|
||
ecm.priority = threat.priority
|
||
ecm.params['freq'] = threat.freq
|
||
var width = threat.width * 1.5
|
||
if width < settings.WIDTH_MIN:
|
||
width = settings.WIDTH_MIN
|
||
ecm.params['width'] = width
|
||
if (threat.rkrp != '') and threat.fflags.rkrp and auto_enabled:
|
||
var krp = get_krp(threat)
|
||
if krp != '':
|
||
ecm.krp = krp
|
||
set_rparams(threat, ecm.params)
|
||
call_ecm_proc(ecm)
|
||
emit_signal('interfer_recommendate', ecm)
|
||
else:
|
||
call_ecm_proc(ecm)
|
||
ecm.kni = threat.aoa - course
|
||
if ecm.kni < 0:
|
||
ecm.kni += 360
|
||
set_nmfs(ecm)
|
||
if ecm != null:
|
||
send_ecm(ecm, unit_caps)
|
||
|
||
|
||
func find_threat(freq: int, aoa: float):
|
||
var fs_index_arr = []
|
||
prd.find_fs_index(aoa, freq, fs_index_arr)
|
||
if not fs_index_arr.size(): return null
|
||
var fs_index = fs_index_arr[0]
|
||
for th in thrs_dict.values():
|
||
fs_index_arr = []
|
||
prd.find_fs_index(th.aoa, th.freq, fs_index_arr)
|
||
if not fs_index_arr.size(): continue
|
||
if fs_index_arr[0] == fs_index:
|
||
return th
|
||
return null
|
||
|
||
|
||
func set_rparams(threat: threats.Threat, params: Dictionary):
|
||
if threat.rparams.has('freq'):
|
||
params['freq'] = threat.rparams['freq']
|
||
else:
|
||
params['freq'] = threat.freq
|
||
if threat.rparams.has('period'):
|
||
params['period'] = threat.rparams['period']
|
||
if threat.rparams.has('width'):
|
||
params['width'] = threat.rparams['width']
|
||
else:
|
||
params['width'] = threat.width * 1.5
|
||
if threat.rparams.has('filename'):
|
||
params['filename'] = threat.rparams['filename']
|
||
|
||
|
||
func get_krp(threat: threats.Threat):
|
||
var krp = ''
|
||
if RECOMMEND_INTERFER.has(threat.rkrp):
|
||
krp = RECOMMEND_INTERFER[threat.rkrp]
|
||
return krp
|
||
elif threat.rkrp == INTERFER_IQFILE:
|
||
if not threat.rparams.has('filename'): return krp
|
||
for key in ITERFER_MODE.keys():
|
||
var ecm_params = ITERFER_MODE[key][1]
|
||
if not ecm_params.has('files'): continue
|
||
if ecm_params['files'] == threat.rparams['filename']:
|
||
krp = key
|
||
return krp
|
||
return krp
|
||
|
||
|
||
func on_interfer_off(ecm: Interfer, ecms):
|
||
var sz = ecms.size()
|
||
signaller.emit_signal('on_prog_ecm_off', ecm)
|
||
ecms.erase(ecm.ispp)
|
||
thrs.erase(ecm.ispp)
|
||
interfer.cu.erase(ecm.ispp)
|
||
interfer.fs.erase(ecm.ispp)
|
||
interfer.push_id(ecm.ispp)
|
||
if sz != ecms.size():
|
||
interfer.call_deferred('emit_signal', 'interfer_resized', ecms)
|
||
|
||
|
||
func interfer_off(ecm, unit_caps):
|
||
ecm.krp = INTERFER_OFF
|
||
send_ecm(ecm, unit_caps)
|
||
signaller.emit_signal('interfer_off', ecm)
|
||
|
||
|
||
func on_interfer_new(ecm, unit_caps):
|
||
call_ecm_proc(ecm)
|
||
send_ecm(ecm, unit_caps)
|
||
|
||
|
||
func on_settings_changed():
|
||
gos_flag = ProjectSettings.get_setting('application/config/Включить работу по своим целям', true)
|
||
var protocols: String = ProjectSettings.get_setting('application/config/Список своих протоколов', '')
|
||
gos_protocols = protocols.split(",", true)
|
||
|
||
|
||
func call_ecm_proc(ecm):
|
||
var ecm_params = ITERFER_MODE[ecm.krp][1]
|
||
if ecm_params.has('call_proc'):
|
||
var call_set_params = Callable(self, ecm_params['call_proc']).bind(ecm, ecm_params)
|
||
call_set_params.call()
|
||
|
||
|
||
func on_update_fs_closed(fs_dict):
|
||
fs_closed = fs_dict
|
||
|
||
|
||
func set_th_emit(th: threats.Threat, ecm: Interfer):
|
||
var freq_min = ecm.params['freq'] - ecm.params.get('width', settings.WIDTH_MAX)/2
|
||
var freq_max = ecm.params['freq'] + ecm.params.get('width', settings.WIDTH_MAX)/2
|
||
if (th.freq >= freq_min) and (th.freq <= freq_max):
|
||
if ecm.svk == 1:
|
||
th.emit_state = 2
|
||
elif th.emit_state == 2:
|
||
return
|
||
else:
|
||
th.emit_state = 1
|
||
|