class_name Iterfer extends Node ## Представление помехи. ## Режимы помехи. const ITERFER_MODE = { 'off': ['Откл', ['freq', 'width'], 0], 'srni1': ['СРН-И1', ['freq', 'width'], 1], 'srnm2': ['СРН-М2', ['freq', 'width'], 2], 'srngps': ['СРН-GPS', ['freq', 'width'], 3], 'lchm1': ['ЛЧМ-1', ['freq', 'width'], 10], 'lchm2': ['ЛЧМ-2', ['freq', 'width'], 16], 'mchm1': ['МЧМ-1', ['freq', 'width'], 11], 'pdm2': ['ПД-М2', ['freq', 'width'], 12], 'pdm4': ['ПД-М4', ['freq', 'width'], 13], 'pdm4s': ['ПД-М4С', ['freq', 'width'], 14], 'pdchm': ['ПД-ЧМ', ['freq', 'width'], 15], 'svi1': ['СВ-И1', ['freq', 'width'], 20], 'svm2': ['СВ-М2', ['freq', 'width'], 21], 'k1': ['K1', ['freq', 'width', 'dur', 'period'], 50], 'ozp1': ['ОЗП-1', ['freq', 'width'], 51] } const SOURCE_INTERFER = ['th','fs','cu'] const ID_INTERFERS_LEN = 63 ## Размер пула номеров целей. const INTERFER_OFF = 'off' 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 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 ## Угол места для помехи. 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'] = krp if krp != INTERFER_OFF: data_to_json['kni'] = kni data_to_json['powp'] = powp # TODO: Необходимо добавить управление мощностью data_to_json['params'] = params 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)) func on_nav_data_received(coords: Dictionary, unit_caps): 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) } 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, 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) ecm.tick_tx = tick func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit) -> 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) 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(unit0: capsrpb.CapsRpb, ecms: Dictionary) -> void: if not unit0.json_dic.has('ts'): return if not (unit0.json_dic['ts'] is float): return if unit0.json_dic['ts'] != 5: return if not unit0.json_dic.has('msvk'): return if not (unit0.json_dic['msvk'] is Array): return var msvk = unit0.json_dic['msvk'] var sz: = ecms.size() for dic_msvk in msvk: if not (dic_msvk is Dictionary): continue if dic_msvk.has('ispp'): var ispp = int(dic_msvk['ispp']) 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, unit0) if sz != ecms.size(): call_deferred('emit_signal', 'interfer_resized', ecms) ## Вызыватся, когда пользователь выбрал помеху и выбраны цели. 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] 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, 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 ispp: int = 0 if interfer_name == 'k1': 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) # Значение по умолчанию 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) 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