556 lines
23 KiB
GDScript
556 lines
23 KiB
GDScript
class_name Iterfer extends Node
|
||
|
||
## Представление помехи.
|
||
|
||
## Режимы помехи.
|
||
const ITERFER_MODE = {
|
||
INTERFER_OFF: [INTERFER_OFF, {}, 0],
|
||
'srni1': ['ПСП + ФМ-2', 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] }
|
||
|
||
const SRNI1_PARAMS = {'par_names' : ['freq', 'width']}
|
||
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 = {'par_names' : ['freq', 'filename'],
|
||
'files': 'PDM2_20.pcm',
|
||
'call_proc': 'call_all_diap'}
|
||
const PDM4_PARAMS = {'par_names' : ['freq', 'filename'],
|
||
'files': 'PDM4_20.pcm',
|
||
'call_proc': 'call_all_diap'}
|
||
const PDM4S_PARAMS = {'par_names' : ['freq', 'filename'],
|
||
'files': 'PDM4S_5.pcm',
|
||
'call_proc': 'call_all_diap'}
|
||
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 PDCHM_PARAMS = {'files': {
|
||
5 : 'pdchm_5.pcm',
|
||
10: 'pdchm__0.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 = 100.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 ## Разрешить излучение
|
||
|
||
## Сеанс помехи.
|
||
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 ## Номер модуля ФС в нумерации СТЦ
|
||
|
||
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) ## Вызывается при изменении количества сеансов помех.
|
||
|
||
|
||
## Отправляет словарь помех в юнит, для запаковки и отправки в 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:
|
||
var ecms: Dictionary = {} ## Словарь помех.
|
||
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)
|
||
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))
|
||
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, ecms))
|
||
signaller.connect('interfer_new', Callable(self, 'send_ecm').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'))
|
||
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))
|
||
threats.connect('threat_lost', Callable(self, 'on_threats_lost').bind(ecms, unit_caps))
|
||
var unit_nav = network.get_unit_instance('навигация')
|
||
unit_nav.connect('data_received', on_nav_data_received.bind(unit_caps))
|
||
threats.connect('threats_resized', Callable(self, 'on_threats_resized'))
|
||
threats.connect('threat_update', Callable(self, 'on_threats_update').bind(ecms, unit_caps))
|
||
|
||
|
||
func on_nav_data_received(coords: Dictionary, unit_caps):
|
||
var ship_time = Time.get_datetime_dict_from_system()
|
||
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:
|
||
for thr in threats.values():
|
||
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 = thr.aoa
|
||
send_ecm(ecm, unit_instance)
|
||
signaller.emit_signal('fs_update_color', ecms)
|
||
prd.update_fs_state(ecms)
|
||
|
||
if not auto_enabled:
|
||
return
|
||
|
||
if auto_enabled:
|
||
for thr in threats.values():
|
||
thr.auto_selected = true
|
||
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) -> void:
|
||
if not unit_instance.json_dic.has('ts'): return
|
||
if not (unit_instance.json_dic['ts'] is float): return
|
||
if unit_instance.json_dic['ts'] != 5: return
|
||
map_msvk_to_ecms(unit_instance, ecms)
|
||
map_mpchf_to_view(unit_instance)
|
||
|
||
|
||
## Извлекает массив состояний выполнения команды
|
||
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['msvk']
|
||
if msvk is not Array: return
|
||
for dic_msvk in msvk:
|
||
if not (dic_msvk is 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_view(unit_instance: unit.Unit):
|
||
var json_dic = unit_instance.json_dic
|
||
if not json_dic.has('mpchf'): return
|
||
var mpchf = json_dic['mpchf']
|
||
if mpchf is not Array: return
|
||
|
||
|
||
## Вызыватся, когда пользователь выбрал помеху и выбраны цели.
|
||
func on_interfer_create(interfer_name, sel_threats, fs_arr, power, u, ecms) -> void:
|
||
for item in sel_threats:
|
||
var param: Dictionary = {}
|
||
var kni: float = item.aoa
|
||
var id = item.id
|
||
param['freq'] = item.freq
|
||
param['width'] = item.width
|
||
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]
|
||
var th = null
|
||
if not interfer_name in EXCLUDE_INTERFER:
|
||
th = find_threat(item[1], kni)
|
||
if th != null:
|
||
param['freq'] = th.freq
|
||
param['width'] = th.width
|
||
else:
|
||
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
|
||
if th == null:
|
||
interfer_create(u, interfer_name, ecms, param, kni, id, fs, SOURCE_INTERFER[1], power)
|
||
else:
|
||
id = th.id
|
||
interfer_create(u, interfer_name, ecms, param, kni, id, thrs, SOURCE_INTERFER[0], power)
|
||
|
||
func on_interfer_rcv(interfer_params: Array, unit0, ecms) -> void:
|
||
var err: bool = false
|
||
var mode = interfer_params[0]
|
||
var id = interfer_params[1]
|
||
var aoa = interfer_params[2]
|
||
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(unit0, 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.kni = kni
|
||
ecm.krp = interfer_name
|
||
ecm.params = param
|
||
ecm.powp = power
|
||
ecm.source_interfer = source_interfer
|
||
ecm.modulation = emit_enable
|
||
ecm.um = param.get('um', 15.0) # Значение по умолчанию
|
||
var ecm_params = ITERFER_MODE[interfer_name][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()
|
||
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, ecms, thrs)
|
||
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 emit_enable:
|
||
return
|
||
elif not ecm.modulation:
|
||
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():
|
||
ecm.krp = INTERFER_OFF
|
||
send_ecm(ecm, unit0)
|
||
signaller.emit_signal('interfer_off', ecm, ecms, thrs)
|
||
|
||
|
||
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]
|
||
ecm.krp = INTERFER_OFF
|
||
send_ecm(ecm, unit0)
|
||
signaller.emit_signal('interfer_off', ecm, ecms, thrs)
|
||
|
||
|
||
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
|
||
|
||
|
||
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.params['freq'] = threat.freq
|
||
ecm.kni = threat.aoa
|
||
set_nmfs(ecm)
|
||
if threat.tmod != 'fm':
|
||
if ecm != null:
|
||
send_ecm(ecm, unit_caps)
|
||
return
|
||
var th_fm_dict: Dictionary
|
||
var fs_index_arr: Array
|
||
prd.find_fs_index(threat.aoa, threat.freq, fs_index_arr)
|
||
if fs_index_arr.size() == 0:
|
||
if ecm != null:
|
||
send_ecm(ecm, unit_caps)
|
||
return
|
||
var fs_index = fs_index_arr[0]
|
||
var nmfs = prd.FS_PRD[fs_index][1]
|
||
if ecm == null:
|
||
for ecm_i in ecms.values():
|
||
if nmfs != ecm_i.nmfs: continue
|
||
if ecm_i.svk != 1: continue
|
||
ecm = ecm_i
|
||
if ecm == null: return
|
||
|
||
for th_index in thrs_dict:
|
||
if thrs_dict[th_index].tmod != 'fm': continue
|
||
fs_index_arr = []
|
||
prd.find_fs_index(thrs_dict[th_index].aoa, thrs_dict[th_index].freq, fs_index_arr)
|
||
if fs_index_arr.size() == 0: continue
|
||
if fs_index_arr[0] != fs_index: continue
|
||
th_fm_dict[th_index] = thrs_dict[th_index]
|
||
if len(th_fm_dict) > 1:
|
||
pass
|
||
send_ecm(ecm, unit_caps)
|
||
|
||
|
||
func get_freq_range(freq_range_dict: Dictionary, th_dict: Dictionary):
|
||
for key_i in th_dict:
|
||
var min_range: int = 6000
|
||
var key_min = null
|
||
for key_j in th_dict:
|
||
if key_i == key_j: continue
|
||
var width = (th_dict[key_i].width / 2) + (th_dict[key_j].width / 2)
|
||
var freq_range = abs(th_dict[key_i].freq - th_dict[key_j].freq) + width
|
||
if freq_range < min_range:
|
||
key_min = key_j
|
||
min_range = freq_range
|
||
var max_width = 0
|
||
for key in PDCHM_PARAMS['files'].keys():
|
||
if max_width < key: max_width = key
|
||
if min_range > max_width:
|
||
th_dict.erase(key_i)
|
||
continue
|
||
else:
|
||
if key_min == null: continue
|
||
freq_range_dict[key_i] = [th_dict[key_i], th_dict[key_min], min_range]
|
||
|
||
|
||
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
|