Files
uarep-ctl/scripts/interfer.gd
TotMaxim 2e6be9b4f1
Some checks failed
Локальный тест / test (push) Has been cancelled
Исправление качки
2026-04-09 19:39:12 +03:00

790 lines
33 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_name Iterfer extends Node
const default_um: = 5.0 ## Угол места по умолчанию
## Представление помехи.
## Режимы помехи.
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],
'elrs': [INTERFER_IQFILE, ELRS_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 ELRS_PARAMS = {'files' : 'ELRS.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 = 80.0
const PERIOD_DEFAULT = 7.5
const MIN_WIDTH_COEF = 1.0
const MIN_RESEND_TIMEOUT = 0.05
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 ## Словарь секторов запрета
var width_coef: float = 1.5 ## Коэффициент расширения полосы
var now: = 0.0 ## Время с момента запуска
var resend_timeout: float = 1.0 ## Время повторной отправки команды
var trim = 0.0 ## Килевая качка
var roll = 0.0 ## Бортовая качка
signal send_ecms(time_now) ## Сигнал отправки помех, если настало время
var unit_nav: unit.Unit ## Навигация
## Сеанс помехи.
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: float ## Тик время обновления цели, мс.
var source_interfer: String = '' ## Тип объекта по которой поставлена помеха.
var modulation: bool ## Модуляция для включения усилителей
var um: float ## Угол места для помехи.
var nmfs: int = 0 ## Номер модуля ФС в нумерации СТЦ
var priority: int = 0 ## Приоритет помехи
var active: bool = false ## Флаг, что фиксируется мощность на выходном усилителе
var freq_change = false ## Флаг, что частота изменнена пользователем
var bort = false ## Признак бортовая или килевая качка
var trim_roll = 0.0 ## Качка для конкретной помехи
var trim_roll_manual = false ## Флаг что ум задан оператором
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
elif value_key == 'um':
trim_roll_manual = true
params[value_key] = value
set_um()
else:
self.set(value_key, value)
if value_key == 'freq':
freq_change = true
func set_um():
if not self.trim_roll_manual:
self.um = params.get('um', default_um) + self.trim_roll
else:
self.um = params.get('um', default_um)
if (self.um < settings.UM_MIN):
self.um = settings.UM_MIN
elif (self.um > settings.UM_MAX):
self.um = settings.UM_MAX
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 ecms: Dictionary = {} ## Словарь помех.
var seczaps: Dictionary = {} ## Словарь секторов запрета
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'))
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))
signaller.connect('interfer_off', Callable(self, 'on_interfer_off').bind(ecms, unit_caps))
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))
ProjectSettings.connect('settings_changed', on_settings_changed)
unit_nav = network.get_unit_instance('навигация')
unit_nav.connect('data_received', on_nav_data_received.bind(unit_caps, ecms))
connect('send_ecms', Callable(self, 'on_send_ecms').bind(ecms, unit_caps))
call_deferred('emit_signal', 'interfer_resized', ecms)
func on_trenazh_mode(val: bool): trenazh_mode = val
func on_nav_data_received(coords: Dictionary, unit_caps, ecms):
var ship_time = Time.get_datetime_dict_from_system()
var update_bk_kk = false
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()
if data_to_json['roll'] != roll:
roll = data_to_json['roll']
update_bk_kk = true
if data_to_json['trim'] != trim:
trim = data_to_json['trim']
update_bk_kk = true
unit_caps.tx_stack.append(json_data)
msg8_num += 1
msg8_num %= 0xffffffff
if update_bk_kk:
for ecm in ecms.values():
if ecm.bort:
ecm.trim_roll = roll
else:
ecm.trim_roll = trim
ecm.set_um()
signaller.emit_signal('interfer_new', ecm)
func on_th_aoa_update(threats: Dictionary, ecms: Dictionary) -> 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:
signaller.emit_signal('interfer_off', ecm)
ecm_active = false
if ecm_active and (prd.fs_caps_id[ecm.nmfs] in fs_closed):
signaller.emit_signal('interfer_off', ecm)
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.params['um'] = get_um(thr.lat, thr.lon, thr.alt)
ecm.kni = fposmod(thr.aoa - course, 360)
call_ecm_proc(ecm)
if ecm.nmfs in gos_nmfs or prd.fs_caps_id[ecm.nmfs] in fs_closed:
signaller.emit_signal('interfer_off', ecm)
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', [])
var ispp_arr: Array = []
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'])
ispp_arr.append(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)
for ecm in ecms.values():
if (ecm.ispp not in ispp_arr) and (ecm.krp == INTERFER_OFF):
var sz = ecms.size()
signaller.emit_signal('prog_ecm_off', ecm)
ecms.erase(ecm.ispp)
thrs.erase(ecm.ispp)
cu.erase(ecm.ispp)
fs.erase(ecm.ispp)
push_id(ecm.ispp)
if sz != ecms.size():
interfer.call_deferred('emit_signal', 'interfer_resized', ecms)
## Извлекает массив пространственно-частотных фильтров
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:
signaller.emit_signal('interfer_off', ecm)
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 * width_coef
param['um'] = get_um(item.lat, item.lon, item.alt)
if item.rparams.has('period'):
param['period'] = item.rparams['period']
if (item.rkrp != '') and item.fflags.rkrp and auto_enabled:
var krp = get_krp(item)
if krp != '':
interfer_name = krp
set_rparams(item, param)
check_width(param)
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]
check_width(param)
interfer_create(u, interfer_name, ecms, param, kni, id, fs, SOURCE_INTERFER[1], power)
## Возвращает угол места до заданной цели
## [param lat] -
## [param lon] -
## [param alt] - высота
func get_um(lat: float, lon: float, alt: float) -> float:
var dist = tools.haversine_m(lat, lon, unit_nav.latlon.x, unit_nav.latlon.y)
return rad_to_deg(atan(alt / dist)) if dist > 0.0 else default_um
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'] = param.get('period', PERIOD_DEFAULT)
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
if source_interfer == SOURCE_INTERFER[0]:
if thrs_dict.has(dict[ispp]):
ecm.priority = thrs_dict[dict[ispp]].priority
call_ecm_proc(ecm)
set_bort(ecm)
ecm.set_um()
var set_nmfs_ok = set_nmfs(ecm)
if set_nmfs_ok != Error.OK:
log.error('Ошибка выбора модуля ФС для помехи: %s' %[ecm.ispp])
ecms.erase(ispp)
dict.erase(ispp)
return
signaller.emit_signal('interfer_new', ecm)
if interfer_name == 'off':
signaller.emit_signal('interfer_off', ecm)
thrs.erase(ispp)
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:
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():
signaller.emit_signal('interfer_off', ecm)
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]
signaller.emit_signal('interfer_off', ecm)
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]
if not ecm.freq_change:
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):
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 * width_coef
ecm.params['width'] = width
check_width(ecm.params)
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)
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('width'):
params['width'] = threat.rparams['width'] * width_coef
else:
params['width'] = threat.width * width_coef
if threat.rparams.has('period'):
params['period'] = threat.rparams['period']
check_width(params)
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 typeof(ecm_params['files']) == TYPE_DICTIONARY:
for value in ecm_params['files'].values():
if typeof(value) == TYPE_STRING:
if value == threat.rparams['filename']:
krp = key
return krp
elif typeof(value) == TYPE_ARRAY:
if value[0] == threat.rparams['filename']:
krp = key
return krp
elif typeof(ecm_params['files']) == TYPE_STRING:
if ecm_params['files'] == threat.rparams['filename']:
krp = key
return krp
return krp
func on_interfer_off(ecm: Interfer, ecms, unit_caps):
ecm.krp = INTERFER_OFF
send_ecm(ecm, unit_caps)
if not unit_caps.online:
var sz = ecms.size()
signaller.emit_signal('prog_ecm_off', ecm)
ecms.erase(ecm.ispp)
thrs.erase(ecm.ispp)
cu.erase(ecm.ispp)
fs.erase(ecm.ispp)
push_id(ecm.ispp)
if sz != ecms.size():
interfer.call_deferred('emit_signal', 'interfer_resized', ecms)
func on_interfer_new(ecm):
call_ecm_proc(ecm)
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)
width_coef = float(ProjectSettings.get_setting('application/config/Коэффициент ширины полосы излучения', 1.5))
if width_coef < MIN_WIDTH_COEF: width_coef = MIN_WIDTH_COEF
resend_timeout = float(ProjectSettings.get_setting('application/config/Время повторной отправки помехи', 1.0))
if resend_timeout < MIN_RESEND_TIMEOUT: resend_timeout = MIN_RESEND_TIMEOUT
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
func check_width(param: Dictionary):
if (param['width'] < settings.WIDTH_MIN): param['width'] = settings.WIDTH_MIN
elif (param['width'] > settings.WIDTH_MAX): param['width'] = settings.WIDTH_MAX
func on_send_ecms(time_now, ecms, unit_caps):
for ecm in ecms.values():
if (time_now - ecm.tick_tx) >= resend_timeout:
send_ecm(ecm, unit_caps)
ecm.tick_tx = time_now
func _process(delta: float) -> void:
now += delta
emit_signal('send_ecms', now)
func set_bort(ecm: Interfer):
var sec = 0
for sect in prd.FS_SECTORS.keys():
if ecm.kni >= prd.FS_SECTORS[sect][0] and ecm.kni <= prd.FS_SECTORS[sect][1]:
sec = sect
if (sec == 0) or (sec == 2):
ecm.bort = false
else:
ecm.bort = true
if ecm.bort:
ecm.trim_roll = roll
else:
ecm.trim_roll = trim