Files
uarep-ctl/scripts/threats.gd

227 lines
11 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.

extends Node
## Работа с целями.
const MSG9_RESEND_TIMEOUT = 3.0 ## Время повторной отправки пакета 9
## Режимы работы АФСП и БПО (Протокол ТНИИС-СТЦ, пункт 2.5.10)
enum AFSP_BPO_MODE {
run = 1,
test = 2 }
var msg9_num: int = 0 ## Счётчик сообщений "тип 9"
var gos_flag = true ## Флаг работать по своим целям
var gos_protocols: PackedStringArray ## Список протоколов своих целей
var bpo_mode: = AFSP_BPO_MODE.run ## Режим работы АФСП и БПО
var bpo_mode_rx: = AFSP_BPO_MODE.run ## Режим работы БПО полученный от
## Цель
class Threat:
var alt: float ## Текущая высота, метры.
var aoa: float ## Курсовой угол на источник сигнала, градусы.
var atick: float ## Тик обнаружения.
var baud: float ## Модуляционная скорость.
var fflags: Dictionary ## Флаги достоверности полей.
var freq: float ## Частота несущей или центральная частота, МГц.
var freqm: String ## Режим смены частоты.
var id: int ## Идентификатор цели.
var lat: float ## Текущие координаты, широта в градусах.
var lon: float ## Текущие координаты, долгота в градусах.
var pow: float ## Уровень принимаемого сигнала, дБм.
var proto: String ## Тип протокола источника сигнала.
var rkrp: String ## Рекомендуемый режим помехи.
var rparams: Dictionary ## Рекомендуемые параметры помехи.
var salt: float ## Координаты старта, высота от уровня моря, м.
var slat: float ## Координаты старта, широта в градусах.
var slon: float ## Координаты старта, долгота в градусах.
var tick: int ## Тик время приёма сигнала, мс.
var tick_rx: int ## Тик время обновления цели, мс.
var tmod: String ## Тип модуляции.
var width: float ## Ширина занимаемого диапазона частот, МГц.
var selected: bool ## Флаг, что цель выбрана.
var auto_selected: bool = false ## Флаг автомата для целей
var emit_state: int = 0 ## 0 - подавление не назначено, 1 - назначено, 2 - выполняется
var nmfs: int ## Индекс модуля ФС, в зону действия которого попала цель
var priority: int ## Приоритет опасности цели
var gos: bool = false ## Своя или чужая цель
func _init(): clear_fflags()
func _to_string() -> String: return 'номер: %d пеленг: %0.1f частота: %0.1f МГц' % [id, aoa, freq]
func clear_fflags(): tools.get_members_names(self).any(func(vn): fflags[vn] = false)
func set_from_dic(dic: Dictionary):
var items: = fflags.keys().filter(func(vn): return dic.has(vn))
items.any(func(vn): set(vn, dic[vn]); fflags[vn] = true; return false)
signal threat_new(th: Threat)
signal threat_lost(th: Threat)
signal threat_update(th: Threat)
signal threats_resized(th: Dictionary)
func _ready() -> void:
var unit_caps = network.get_unit_instance('уарэп-капсрпб')
var unit_5p28 = network.get_unit_instance('уарэп-5п28')
var timer_check_lost: = Timer.new()
var timer_msg9: = Timer.new()
var timer_aoa_update: = Timer.new()
add_child(timer_check_lost)
add_child(timer_aoa_update)
add_child(timer_msg9)
var threats = {} ## Список целей. Индекс - <номер цели>
unit_caps.connect('data_received', Callable(self, 'on_data_capsrpb_received').bind(threats))
unit_caps.connect('line_changed', Callable(self, 'on_caps_line_changed').bind(timer_msg9))
unit_5p28.connect('get_threats', Callable(self, 'on_get_threats').bind(unit_5p28, threats))
timer_check_lost.connect('timeout', Callable(self, 'on_timer_check_lost').bind(settings.ThreatParams.time_lost, threats))
timer_check_lost.start(settings.ThreatParams.time_lost / 1000.0)
timer_aoa_update.connect('timeout', Callable(self, 'on_timer_aoa_update').bind(threats, timer_aoa_update))
timer_aoa_update.start(3.0)
timer_aoa_update.one_shot = true
timer_msg9.connect('timeout', Callable(self, 'on_timer_msg9').bind(unit_caps, timer_msg9))
signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(threats))
signaller.connect('rto_threat_unsel', Callable(self, 'on_rto_threat_unsel').bind(threats))
signaller.connect('rto_threat_unsel_all', Callable(self, 'on_rto_threat_unsel_all').bind(threats))
signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(threats))
signaller.connect('interfer_init', Callable(self, 'on_interfer_init').bind(threats))
signaller.connect('connect_work_signal', Callable(self, 'on_connect_work_signal').bind(threats))
signaller.connect('режим_контроль', Callable(self, 'on_mode_change').bind(unit_caps, timer_msg9, AFSP_BPO_MODE.test))
signaller.connect('режим_работа', Callable(self, 'on_mode_change').bind(unit_caps, timer_msg9, AFSP_BPO_MODE.run))
ProjectSettings.connect('settings_changed', on_settings_changed.bind(threats))
## Периодически удаляет устаревшие цели.
func on_timer_check_lost(time_lost: int, threats: Dictionary):
var tick: = Time.get_ticks_msec()
var sz: = threats.size()
for th in threats.values():
if (tick - th.tick_rx) >= time_lost:
threats.erase(th.id)
call_deferred('emit_signal', 'threat_lost', th)
if sz != threats.size():
call_deferred('emit_signal', 'threats_resized', threats)
func on_timer_aoa_update(threats:Dictionary, tmr):
signaller.emit_signal('th_aoa_update', threats)
tmr.start(1.0)
## отправляет словарь целей в юнит, для запаковки и отправки в 5П28.
func on_get_threats(unit_instance, threats): unit_instance.pack_threats(threats)
## Снимает выделение с цели, если нажать по отметке цели.
func on_rto_threat_unsel(th_id, threats): threats[th_id].selected = false
## Снимает выделение со всех целей.
func on_rto_threat_unsel_all(threats):
for th in threats.values():
signaller.emit_signal('rto_threat_unsel', th.id)
## Выбирает цель, если нажать по отметке цели.
func on_rto_threat_sel(th_id, threats): on_threat_selected(threats[th_id], threats)
## Выбирает цель, если выбрать в таблице.
func on_threat_selected(th, threats):
for threat in threats.values():
threat.selected = false
th.selected = true
## Формирует список выбранных целей для включения помехи.
func on_interfer_init(interfer_name, fs_arr, power, threats):
var sel_threats: Array = []
for threat in threats.values():
if interfer.auto_enabled:
if threat.auto_selected:
sel_threats.append(threat)
else:
if threat.selected:
sel_threats.append(threat)
if len(sel_threats) or len(fs_arr):
signaller.emit_signal('interfer_create', interfer_name, sel_threats, fs_arr, power)
## Производит приём целей.
func on_data_capsrpb_received(unit: capsrpb.CapsRpb, threats: Dictionary):
if not unit.json_dic.has('ts'): return
if unit.json_dic['ts'] != 5: return
if not unit.json_dic.has('mis'): return
if not unit.json_dic.has('sa'): return
var mis = unit.json_dic['mis']
bpo_mode_rx = int(unit.json_dic['sa']) as AFSP_BPO_MODE
var sz: = threats.size()
for dic_th in mis:
if dic_th is not Dictionary:
continue
if not dic_th.has('id'):
continue
var id = int(dic_th['id'])
if threats.has(id):
var th = threats[id]
th.clear_fflags()
th.set_from_dic(dic_th)
th.tick_rx = unit.tick
if th.fflags.proto and th.proto != '':
th.priority = 1
else:
th.priority = 0
set_gos(th)
call_deferred('emit_signal', 'threat_update', th)
else:
var th: = Threat.new()
th.set_from_dic(dic_th)
threats[id] = th
th.tick_rx = unit.tick
set_gos(th)
call_deferred('emit_signal', 'threat_new', th)
if sz != threats.size():
call_deferred('emit_signal', 'threats_resized', threats)
func on_settings_changed(ths: Dictionary):
gos_flag = ProjectSettings.get_setting('application/config/Включить работу по своим целям', true)
var protocols: String = ProjectSettings.get_setting('application/config/Список своих протоколов', '')
gos_protocols = protocols.split(",", true)
for th in ths.values():
set_gos(th)
func set_gos(th: Threat):
if gos_flag: th.gos = false
elif (th.proto in gos_protocols) and th.fflags.proto: th.gos = true
func on_connect_work_signal(ths: Dictionary):
emit_signal('threats_resized', ths)
func on_mode_change(unit_caps, timer_msg9, state):
bpo_mode = state
send_msg9(unit_caps)
timer_msg9.start(MSG9_RESEND_TIMEOUT)
func send_msg9(unit_caps):
msg9_num += 1
var json_data : Dictionary = {}
json_data['ts'] = 9
json_data['ss'] = msg9_num
json_data['sa'] = bpo_mode
var pac = JSON.stringify(json_data).to_utf8_buffer()
unit_caps.tx_stack.append(pac)
func on_timer_msg9(unit_caps, timer_msg9):
send_msg9(unit_caps)
func on_caps_line_changed(unit_caps, timer_msg9):
if unit_caps.online:
send_msg9(unit_caps)
timer_msg9.start(MSG9_RESEND_TIMEOUT)