Merge remote-tracking branch 'sasha/master'
# Conflicts: # modbus/server-serial-modbus.py # scripts/yems-boards.gd
This commit is contained in:
@@ -9,30 +9,30 @@ var FILES_ROWS_ALIGNMENT = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNM
|
||||
|
||||
|
||||
func fill_files_table(tbl: table, folder: String, rows_types: Array):
|
||||
var dir: = DirAccess.open(folder)
|
||||
if dir == null:
|
||||
return
|
||||
var files: = []
|
||||
var exclude_names: = ['.', '..']
|
||||
dir.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
|
||||
while true:
|
||||
var file: = dir.get_next()
|
||||
if file == '':
|
||||
break
|
||||
if file in exclude_names:
|
||||
continue
|
||||
var file_name = folder + '/' + file
|
||||
var fd = FileAccess.open(file_name, FileAccess.READ)
|
||||
if not fd:
|
||||
continue
|
||||
var glob_path = ProjectSettings.globalize_path(file_name)
|
||||
var sz = fd.get_length()
|
||||
var ut = fd.get_modified_time(file_name)
|
||||
fd.close()
|
||||
var mt = Time.get_datetime_dict_from_unix_time(ut)
|
||||
var file_row = [file, '%d' % sz, '%d-%02d-%02d %02d:%02d' % [mt.year, mt.month, mt.day, mt.hour, mt.minute]]
|
||||
tbl.add_row(rows_types)
|
||||
var i_row = tbl.get_rows_count() - 1
|
||||
tbl.set_row_text(i_row, file_row)
|
||||
tbl.set_node_meta(0, i_row, 'file_path', glob_path)
|
||||
dir.list_dir_end()
|
||||
var dir: = DirAccess.open(folder)
|
||||
if dir == null:
|
||||
return
|
||||
var files: = []
|
||||
var exclude_names: = ['.', '..']
|
||||
dir.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
|
||||
while true:
|
||||
var file: = dir.get_next()
|
||||
if file == '':
|
||||
break
|
||||
if file in exclude_names:
|
||||
continue
|
||||
var file_name = folder + '/' + file
|
||||
var fd = FileAccess.open(file_name, FileAccess.READ)
|
||||
if not fd:
|
||||
continue
|
||||
var glob_path = ProjectSettings.globalize_path(file_name)
|
||||
var sz = fd.get_length()
|
||||
var ut = fd.get_modified_time(file_name)
|
||||
fd.close()
|
||||
var mt = Time.get_datetime_dict_from_unix_time(ut)
|
||||
var file_row = [file, '%d' % sz, '%d-%02d-%02d %02d:%02d' % [mt.year, mt.month, mt.day, mt.hour, mt.minute]]
|
||||
tbl.add_row(rows_types)
|
||||
var i_row = tbl.get_rows_count() - 1
|
||||
tbl.set_row_text(i_row, file_row)
|
||||
tbl.set_node_meta(0, i_row, 'file_path', glob_path)
|
||||
dir.list_dir_end()
|
||||
|
||||
@@ -112,6 +112,9 @@ func _ready():
|
||||
signaller.connect('interfer_rcv', Callable(self, 'on_interfer_rcv').bind(unit_5p28, ecms))
|
||||
signaller.connect('interfer_new', Callable(self, 'send_ecm').bind(unit))
|
||||
signaller.connect('interfer_off_all', Callable(self, 'on_interfer_off_all').bind(unit, ecms))
|
||||
signaller.connect('th_aoa_update', Callable(self, 'on_th_aoa_update').bind(ecms, unit))
|
||||
signaller.connect('interfer_off', Callable(self, 'on_interfer_off'))
|
||||
threats.connect('threat_lost', Callable(self, 'on_threats_lost').bind(ecms, unit))
|
||||
|
||||
|
||||
## Проверяет состояние отправки пакета и если не доставлен, повторяет отправку.
|
||||
@@ -124,6 +127,18 @@ func on_timer_check_state(unit, ecms, resend_timeout):
|
||||
ecm.tick_tx = tick
|
||||
|
||||
|
||||
func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit):
|
||||
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)
|
||||
|
||||
|
||||
## Производит приём состояния помех. [param unit] -> [param ecms].
|
||||
func on_data_capsrpb_received(unit: capsrpb.CapsRpb, ecms: Dictionary):
|
||||
if not unit.json_dic.has('ts'): return
|
||||
@@ -248,6 +263,16 @@ func on_interfer_off_all(unit, ecms):
|
||||
send_ecm(ecm, unit)
|
||||
signaller.emit_signal('interfer_off',ecm, ecms, thrs)
|
||||
|
||||
func on_threats_lost(th, ecms, unit):
|
||||
for key in interfer.thrs:
|
||||
if interfer.thrs[key] == th.id:
|
||||
var ecm_id = key
|
||||
var ecm = ecms[ecm_id]
|
||||
ecm.krp = INTERFER_OFF
|
||||
push_id(ecm.ispp)
|
||||
send_ecm(ecm, unit)
|
||||
signaller.emit_signal('interfer_off',ecm, ecms, thrs)
|
||||
|
||||
|
||||
func pop_id():
|
||||
var id = 0
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
@tool
|
||||
class_name rep_network extends Node
|
||||
|
||||
|
||||
const PROTOCOL_TYPES: = {'yau07tx': yau07.YaU07, 'json-capsrpb': capsrpb.CapsRpb, 'udp-json-mbcs': modbus.ModbusClient}
|
||||
const TCP_PROTO: = {'5p28': tcp5p28.TCP5P28}
|
||||
const SERIAL_PROTO: = {'uart': spt25.SPT25 }
|
||||
|
||||
|
||||
class Serial extends SerialPort:
|
||||
func send_to(data: PackedByteArray):
|
||||
write_raw(data)
|
||||
func try_open(parsing_proc: Callable):
|
||||
if not is_open():
|
||||
open(port)
|
||||
if is_open():
|
||||
data_received.connect(parsing_proc)
|
||||
start_monitoring(timeout)
|
||||
|
||||
|
||||
class Socket extends PacketPeerUDP:
|
||||
func send_to(addr, data):
|
||||
@@ -14,7 +28,7 @@ class SocketTCP extends TCPServer:
|
||||
const RX_TIMEOUT: int = 1000 ## Время сброса счётчика принятия части пакета.
|
||||
var peerstream: = PacketPeerStream.new()
|
||||
var unit_key: Array ## Ключ юнита.
|
||||
var head_len: int = 8 ## Длинна заголовка команды.
|
||||
var head_len: int = 8 ## Длина заголовка команды.
|
||||
var len_place: int = 4 ## Номер начального байта с длинной блока данных.
|
||||
var type_len: int = 4 ## Количество байт в размере длинны.
|
||||
var rx_tick: int ## Время приёма последнего пакета.
|
||||
@@ -31,7 +45,10 @@ class SocketTCP extends TCPServer:
|
||||
var poll_sockets: Array[Socket]
|
||||
var tcp_sockets: Array
|
||||
var units: Dictionary
|
||||
var units_udp: Dictionary
|
||||
var units_tcp: Dictionary
|
||||
var units_serial: Dictionary
|
||||
var serials: Dictionary
|
||||
var dst_ports: Dictionary
|
||||
var unit_keys: Dictionary
|
||||
var sock_unicast: Socket
|
||||
@@ -62,6 +79,20 @@ func create_tcpsocket(nm) -> SocketTCP:
|
||||
return sock
|
||||
|
||||
|
||||
func create_serial(nm) -> Serial:
|
||||
var port = repsettings.UnitProfiles[nm][1]
|
||||
var baud = repsettings.UnitProfiles[nm][2][0]
|
||||
var sp: = Serial.new()
|
||||
sp.baudrate = baud
|
||||
sp.timeout = 20000
|
||||
var rc = sp.open(port)
|
||||
if rc != Error.OK:
|
||||
log.message(log.ERROR, 'Невозможно открыть порт \"%s\" для \"%s\"' % [port, nm])
|
||||
else:
|
||||
log.message(log.INFO, 'Последовательный порт \"%s\"@%d открыт для \"%s\"' % [port, baud, nm])
|
||||
return sp
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
log.info('Модуль работы с сетью готов')
|
||||
poll_sockets.append(create_socket('уарэп-яу07-частный'))
|
||||
@@ -78,6 +109,7 @@ func _ready() -> void:
|
||||
var unit = PROTOCOL_TYPES[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
units[unit_key] = unit
|
||||
units_udp[unit_key] = unit
|
||||
if logger_page:
|
||||
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
|
||||
@@ -85,7 +117,7 @@ func _ready() -> void:
|
||||
dst_ports[unit_key] = settings[2][1]
|
||||
else:
|
||||
dst_ports[unit_key] = settings[2][0]
|
||||
|
||||
|
||||
if proto in TCP_PROTO:
|
||||
var unit = TCP_PROTO[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
@@ -94,12 +126,24 @@ func _ready() -> void:
|
||||
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
|
||||
|
||||
if proto in SERIAL_PROTO:
|
||||
var unit = SERIAL_PROTO[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
if logger_page:
|
||||
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
|
||||
var serial = create_serial(unit_name)
|
||||
units_serial[unit_key] = unit
|
||||
units[unit_key] = unit
|
||||
serials[unit_key] = serial
|
||||
serial.try_open(unit.parse)
|
||||
|
||||
tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp[repsettings.get_unit_key('уарэп-5п28')]])
|
||||
|
||||
for key in units: log.info('%s %s:%d' % [units[key].name, key[0], key[1]])
|
||||
|
||||
for key in units: log.info('%s %s:%d' % [units[key].name, key[0], key[1]])
|
||||
for key in units_tcp: log.info('%s %s:%d' % [units_tcp[key].name, key[0], key[1]])
|
||||
for key in dst_ports:
|
||||
unit_keys[dst_ports[key]] = key
|
||||
for key in dst_ports: unit_keys[dst_ports[key]] = key
|
||||
|
||||
|
||||
func poll_receive(sock: Socket, tick: int) -> bool:
|
||||
while sock.get_available_packet_count() > 0:
|
||||
@@ -119,7 +163,6 @@ func poll_receive_tcp(sock: SocketTCP, tick: int) -> bool:
|
||||
if sock.is_connection_available(): # check if someone's trying to connect
|
||||
var client = sock.take_connection() # accept connection
|
||||
sock.peerstream.set_stream_peer(client) # bind peerstream to new client
|
||||
print_debug('client_is_connected')
|
||||
var peer = sock.peerstream.get_stream_peer()
|
||||
if peer:
|
||||
var peer_len_data = peer.get_available_bytes()
|
||||
@@ -163,16 +206,22 @@ func get_tcp_data(sock: SocketTCP, peer, len_rx):
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var tick = Time.get_ticks_msec()
|
||||
for addr in units:
|
||||
for addr in units_udp:
|
||||
var unit = units[addr]
|
||||
match unit.process(tick):
|
||||
Error.OK: sock_unicast.send_to([addr[0], dst_ports[addr]], unit.tx_data)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s %s:%d' % [unit, addr[0], addr[1]])
|
||||
for key in units_serial:
|
||||
var unit = units_serial[key]
|
||||
var serial = serials[key]
|
||||
match unit.process(tick):
|
||||
Error.OK: serial.send_to(unit.tx_data)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: \"%s\"' % unit.name)
|
||||
for sock_unit in tcp_sockets:
|
||||
var sock = sock_unit[0]
|
||||
var unit = sock_unit[1]
|
||||
match unit.process(tick):
|
||||
Error.OK: sock.send_to(unit.tx_data)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s' %unit)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s' % unit)
|
||||
poll_receive_tcp(sock, tick)
|
||||
poll_sockets.any(func(sock): poll_receive(sock, tick))
|
||||
@@ -1,3 +1,4 @@
|
||||
@tool
|
||||
class_name rep_settings extends Node
|
||||
|
||||
## Параметры.
|
||||
@@ -21,15 +22,15 @@ class_name rep_settings extends Node
|
||||
'уарэп-яу07-3н': ['yau07tx', '10.1.1.49', [50049], false, false, 'IP-адрес ЯУ-07 прибора ПРД-Н'],
|
||||
'уарэп-яу07-3к': ['yau07tx', '10.1.1.51', [50051], false, false, 'IP-адрес ЯУ-07 прибора ПРД-Н'],
|
||||
|
||||
# Название | Протокол | Адрес | Порт получения | Комментарий
|
||||
'уарэп-5п28': ['5p28', '127.0.0.1', [50000], 'IP-адрес комплекса 5П-28'],
|
||||
# Название: [ Протокол, Адрес, Порт получения, Комментарий ]
|
||||
'уарэп-5п28': [ '5p28', '127.0.0.1', [50000], 'IP-адрес комплекса 5П-28'],
|
||||
|
||||
# Название | Протокол | Адрес | Порт получения | Порт отправки | Комментарий
|
||||
'уарэп-щ3': ['udp-json-mbcs', '127.0.0.1', [48000, 44100], false, true, 'IP-адрес и порты через которые производят обмен сообщения с драйвером клиента Modbus Serial'],
|
||||
|
||||
# Название | Протокол | Имя порта | Скорость, бод | Чётность | Комментарий
|
||||
'уарэп-спт25-1': ['uart', '/dev/tty2', 115200, false, 'Адрес прибора СПТ-25 (G1)'],
|
||||
'уарэп-спт25-2': ['uart', '/dev/tty3', 115200, false, 'Адрес прибора СПТ-25 (G2)'],
|
||||
# Название: [ Протокол, Адрес, [ Порт получения, Порт отправки], ??, ??, Комментарий
|
||||
'уарэп-щ3': ['udp-json-mbcs', '127.0.0.1', [48000, 44100], false, true, 'IP-адрес и порты через которые производят обмен сообщения с драйвером клиента Modbus Serial'],
|
||||
|
||||
# Название: [ Протокол, Имя порта, Скорость, Чётность, ??, Комментарий
|
||||
'уарэп-спт25-1': ['uart', '/home/sasha/dev/tty0', [19200, false, false], 'Адрес прибора СПТ-25 (G1)'],
|
||||
'уарэп-спт25-2': ['uart', '/home/sasha/dev/tty4', [19200, false, false], 'Адрес прибора СПТ-25 (G2)'],
|
||||
}
|
||||
|
||||
## Параметры цели.
|
||||
@@ -1,10 +1,20 @@
|
||||
class_name Signaller extends Node
|
||||
|
||||
## Обмен сигналами между узлами. Здесь объявлены сигналы, которые используют.
|
||||
## Обмен сигналами между узлами. Здесь объявлены сигналы, которые используют
|
||||
## два и более узла, из разных файлов. Должен быть помещён в автозагрузку.
|
||||
|
||||
## Подключает обработчик к событию по его определению
|
||||
func conn(sgnl: Signal, clbl: Callable): connect(sgnl.get_name(), clbl)
|
||||
|
||||
|
||||
## Вызывает сигнал по его определению
|
||||
func emmit(sgnl: Signal): emit_signal(sgnl.get_name())
|
||||
|
||||
|
||||
## Вызывается при обнаружение ошибки последовательного порта
|
||||
signal serial_error()
|
||||
|
||||
|
||||
## Вызывается при переходе в режим [b]Работа[/b].
|
||||
signal режим_работа()
|
||||
|
||||
@@ -60,48 +70,48 @@ signal full_screen(id: int)
|
||||
|
||||
## Вызывается, когда пользователь выбирает цель.[br]
|
||||
## [param th_id] - Отметка цели на экране.
|
||||
signal rto_threat_sel (th_id: int)
|
||||
signal rto_threat_sel(th_id: int)
|
||||
|
||||
|
||||
## Вызывается, когда пользователь нажимает на значёк цели.[br]
|
||||
## [param th_id] - Отметка цели на экране.
|
||||
signal bip_pressed (th_id: int)
|
||||
signal bip_pressed(th_id: int)
|
||||
|
||||
|
||||
## Вызывается, когда пользователь снимает выделение с цели.[br]
|
||||
## [param th_id] - Отметка цели на экране.
|
||||
signal rto_threat_unsel (th_id: int)
|
||||
signal rto_threat_unsel(th_id: int)
|
||||
|
||||
|
||||
## Вызывается, когда пользователь снимает выделение со всех целей.
|
||||
signal rto_threat_unsel_all ()
|
||||
signal rto_threat_unsel_all()
|
||||
|
||||
|
||||
## Вызывается, когда пользователь выбирает помеху.[br]
|
||||
## [param btn] - Нажатая кнопка помехи.
|
||||
signal interfer_init (btn: PanelContainer, fs_arr: Array)
|
||||
signal interfer_init(btn: PanelContainer, fs_arr: Array)
|
||||
|
||||
|
||||
## Вызывается, когда выбраны цели для постановки помех.[br]
|
||||
## [param btn] - Нажатая кнопка помехи.[br]
|
||||
## [param sel_threats] - Cписок целей.
|
||||
signal interfer_create (btn: PanelContainer, sel_threats: Array, fs_arr: Array)
|
||||
signal interfer_create(btn: PanelContainer, sel_threats: Array, fs_arr: Array)
|
||||
|
||||
|
||||
## Вызывается, когда создалась новая помеха.[br]
|
||||
## [param ecm] - Новая помеха.[br]
|
||||
signal interfer_new (ecm: interfer.Interfer)
|
||||
signal interfer_new(ecm: interfer.Interfer)
|
||||
|
||||
|
||||
## Вызывается, когда отключается действующая помеха.[br]
|
||||
## [param ecm] - Новая помеха.[br]
|
||||
## [param ecms] - словарь помех.[br]
|
||||
## [param thrs] - словарь id помех и связанных с ними целей.[br]
|
||||
signal interfer_off (ecm: interfer.Interfer, ecms: Dictionary, thrs: Dictionary)
|
||||
signal interfer_off(ecm: interfer.Interfer, ecms: Dictionary, thrs: Dictionary)
|
||||
|
||||
|
||||
## Вызывается при нажатии отключить все помехи.
|
||||
signal interfer_off_all ()
|
||||
signal interfer_off_all()
|
||||
|
||||
|
||||
## Вызывается при получении внешнего целеуказания.
|
||||
@@ -111,7 +121,7 @@ signal interfer_rcv(interfer_params: Array)
|
||||
|
||||
## Вызывается, когда отключается действующая помеха.[br]
|
||||
## [param ecm] - Выбранная помеха.
|
||||
signal interfer_selected (ecm: interfer.Interfer)
|
||||
signal interfer_selected(ecm: interfer.Interfer)
|
||||
|
||||
|
||||
## Вызывается, когда отключается выбираем помеху по сектору в таблице.[br]
|
||||
@@ -127,3 +137,8 @@ signal map_coords_changed(lan: float, lat: float)
|
||||
## Вызывается при изменении размера изображения для отображения карты.[br]
|
||||
## [param mode] - Вновь установленный режим.
|
||||
signal map_mode_changed(mode: int)
|
||||
|
||||
## Вызывается при обновлении позиции(угла) цели.[br]
|
||||
signal th_aoa_update(threats: Dictionary)
|
||||
|
||||
signal fs_update_color(ecms:Dictionary)
|
||||
|
||||
32
scripts/spt25.gd
Normal file
32
scripts/spt25.gd
Normal file
@@ -0,0 +1,32 @@
|
||||
class_name spt25_unit extends Node
|
||||
|
||||
|
||||
class SPT25 extends unit.Unit:
|
||||
|
||||
var tx_tick: int = 0
|
||||
var req_period = 3000
|
||||
func _to_string() -> String: return String('СПТ-25: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
|
||||
func _init(nm) -> void:
|
||||
self.name = nm
|
||||
tx_data.resize(8)
|
||||
tx_data[0] = 0x7e # Флаги синхронизации пакета
|
||||
tx_data[1] = 0 # Адрес абонента, которому предназначен пакет
|
||||
tx_data[2] = 4 # Тип пакета, КОД КОМАНДЫ - Получить информацию о состоянии преобразователя
|
||||
tx_data[3] = 0 # Данные
|
||||
tx_data[4] = 0 # Данные
|
||||
tx_data[5] = 0 # Данные
|
||||
tx_data[6] = 0 # Контрольная сумма
|
||||
tx_data[7] = 0x7e # Флаги синхронизации пакета
|
||||
|
||||
func parse(rx_data: PackedByteArray):
|
||||
if not self.online:
|
||||
self.online = true
|
||||
emit_signal('line_changed', self)
|
||||
emit_signal('data_received', rx_data)
|
||||
|
||||
func process(delta: float):
|
||||
tick += delta
|
||||
if (tick - tx_tick) > req_period:
|
||||
return Error.OK
|
||||
return Error.ERR_BUSY
|
||||
@@ -34,28 +34,20 @@ const CU_STATE: Dictionary = {
|
||||
4:9, # Неисправность
|
||||
}
|
||||
|
||||
class TCP5P28:
|
||||
class TCP5P28 extends unit.Unit:
|
||||
const PACK_TYPE_CMD: int = 1
|
||||
const PACK_TYPE_RES: int = 2
|
||||
const CMD_TYPE_STATE: int = 1
|
||||
const CMD_TYPE_TH: int = 2
|
||||
const CMD_TYPE_IN: int = 3
|
||||
|
||||
signal line_changed(unit: TCP5P28) ## Сигнал состояние связи изменилось.
|
||||
signal data_received(unit: TCP5P28) ## Сигнал данные приняты.
|
||||
signal command_fail(unit: TCP5P28) ## Сигнал при не выполнении команды.
|
||||
signal parse_error(unit: TCP5P28, msg: String) ## Сигнал ошибки разбора сообщения.
|
||||
signal get_threats(unit: TCP5P28) ## Сигнал запрос целей.
|
||||
signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания.
|
||||
|
||||
var online: = false ## Состояние связи с источником сообщений.
|
||||
var name: String ## Имя экземпляра.
|
||||
var rx_tick: = 0 ## Тик время последнего приёма, мс.
|
||||
var tx_data: = PackedByteArray() ## Пакет для отправки.
|
||||
var tx_stack: Array ## Массив пакетов для отправки.
|
||||
|
||||
func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
func _init(nm): self.name = nm
|
||||
|
||||
func parse(data: PackedByteArray, now_tick: int):
|
||||
rx_tick = now_tick
|
||||
@@ -87,12 +79,12 @@ class TCP5P28:
|
||||
func pack_threats(ths):
|
||||
var data = PackedByteArray()
|
||||
var data_len = 4 + len(ths) * 80 # длинна блока данных в байтах
|
||||
var tick = Time.get_ticks_msec()
|
||||
var tick0 = Time.get_ticks_msec()
|
||||
data.resize(4)
|
||||
data.encode_u16(0, 0) # Код ошибки
|
||||
data.encode_u16(2, len(ths)) # Количество целей
|
||||
for th in ths.values():
|
||||
data.append_array(get_threats_data(th, int(tick)))
|
||||
data.append_array(get_threats_data(th, int(tick0)))
|
||||
var data_to_send: PackedByteArray = create_header(data_len)
|
||||
data_to_send.append_array(data)
|
||||
tx_stack.append(data_to_send)
|
||||
@@ -131,10 +123,10 @@ class TCP5P28:
|
||||
head_data.encode_u32(4, data_len) # Длинна пакета данных
|
||||
return head_data
|
||||
|
||||
func get_threats_data(th, tick):
|
||||
func get_threats_data(th, tick0):
|
||||
var th_data = PackedByteArray()
|
||||
th_data.resize(80) # Количество байт в массиве
|
||||
th_data.encode_u64(0, tick)
|
||||
th_data.encode_u64(0, tick0)
|
||||
var flags: int = 0 # с 0 по 7 бит рекомендованная помеха
|
||||
flags |= 0 << 8 # Флаг рекомендуемой помехи
|
||||
flags |= int(th.fflags['aoa']) << 9 # Флаг доставерности пеленга
|
||||
@@ -190,4 +182,3 @@ class TCP5P28:
|
||||
var data_to_send: PackedByteArray = create_header(data_len)
|
||||
data_to_send.append_array(data_tx)
|
||||
tx_stack.append(data_to_send)
|
||||
|
||||
|
||||
@@ -51,11 +51,15 @@ func _ready() -> void:
|
||||
var unit_5p28_key = repsettings.get_unit_key('уарэп-5п28')
|
||||
var unit_5p28 = repnetwork.units_tcp[unit_5p28_key]
|
||||
var timer_check_lost: = Timer.new()
|
||||
var timer_aoa_update: = Timer.new()
|
||||
add_child(timer_check_lost)
|
||||
add_child(timer_aoa_update)
|
||||
unit.connect('data_received', Callable(self, 'on_data_capsrpb_received').bind(threats))
|
||||
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(repsettings.ThreatParams.time_lost, threats))
|
||||
timer_check_lost.start(repsettings.ThreatParams.time_lost / 1000.0)
|
||||
timer_aoa_update.connect('timeout', Callable(self, 'on_timer_aoa_update').bind(threats))
|
||||
timer_aoa_update.start(0.25)
|
||||
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))
|
||||
@@ -74,10 +78,12 @@ func on_timer_check_lost(time_lost: int, threats: Dictionary):
|
||||
call_deferred('emit_signal', 'threats_resized', threats)
|
||||
|
||||
|
||||
func on_timer_aoa_update(threats:Dictionary):
|
||||
signaller.emit_signal('th_aoa_update', threats)
|
||||
|
||||
## отправляет словарь целей в юнит, для запаковки и отправки в 5П28.
|
||||
func on_get_threats(unit, threats): unit.pack_threats(threats)
|
||||
|
||||
|
||||
## Снимает выделение с цели, если нажать по отметке цели.
|
||||
func on_rto_threat_unsel(th_id, threats): threats[th_id].selected = false
|
||||
|
||||
|
||||
@@ -72,8 +72,9 @@ func get_string_slice(s_in: String, s_out: Array, i0: int, i1: int):
|
||||
|
||||
## Производит преобразование из декартовой в полярную систему координат.
|
||||
func pos_calc(freq: float, aoa: float, pos0: Vector2, r0: float, r1: float, f0: float, f1: float):
|
||||
var r = ((freq - f0) / (f1 - f0)) * r1 + r0
|
||||
var r = remap(freq, f0, f1, r0, r1)
|
||||
var aoa_rad = radians(aoa) - PI / 2.0
|
||||
|
||||
return Vector2(cos(aoa_rad), sin(aoa_rad)) * r + pos0
|
||||
|
||||
|
||||
|
||||
18
scripts/unit.gd
Normal file
18
scripts/unit.gd
Normal file
@@ -0,0 +1,18 @@
|
||||
class_name base_unit extends Node
|
||||
|
||||
## Базовый класс для управления подключаемыми устройствами
|
||||
|
||||
class Unit:
|
||||
signal line_changed(unit) ## Вызывается при изменение состояния связи
|
||||
signal command_done(unit) ## Вызывается после выполнения команды.
|
||||
signal command_fail(unit) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена.
|
||||
signal parse_failed(unit) ## Вызывается при обнаружении ошибки во входных данных
|
||||
signal data_received(unit) ## Вызывается по приёму данных
|
||||
|
||||
var tick = 0.0 ## Текущее тик-время в мс.
|
||||
var tx_data: = PackedByteArray() ## Буфер отправленный.
|
||||
var tx_len = 0 ## Длина последнего отправленного пакета.
|
||||
var online: bool
|
||||
var name: String
|
||||
func _init(nm) -> void: self.name = nm
|
||||
func _to_string() -> String: return String('устройство: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
@@ -9,13 +9,13 @@ const BUFFER_SIZE = 2048 ## Размер буфера для приёма д
|
||||
|
||||
|
||||
## Ячейка ЯУ-07.
|
||||
class YaU07:
|
||||
class YaU07 extends unit.Unit:
|
||||
|
||||
## Коды выполняемых команд.
|
||||
enum CmdCode {
|
||||
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07.
|
||||
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07.
|
||||
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07.
|
||||
READ_ISA = 0, ## Код команды "читать порт ISA" ячейки ЯУ-07.
|
||||
WRITE_ISA = 1, ## Код команды "записать порт ISA" ячейки ЯУ-07.
|
||||
WRITE_BLOCK = 60, ## Код команды "записать блок данных ISA" внешней шины ячейки ЯУ-07.
|
||||
READ_BLOCK = 61, ## Код команды "читать блок данных ISA" внешней шины ячейки ЯУ-07.
|
||||
}
|
||||
|
||||
@@ -28,27 +28,18 @@ class YaU07:
|
||||
FAIL ## Команда не выполнена.
|
||||
}
|
||||
|
||||
signal line_changed(unit: YaU07) ## Вызывается когда меняется состояние связи с ячейкой.
|
||||
signal command_done(unit: YaU07) ## Вызывается после выполнения команды.
|
||||
signal command_fail(unit: YaU07) ## Вызывается если возникла ошибка при выполнении команды и команда не выполнена.
|
||||
signal parse_failed(unit: YaU07)
|
||||
|
||||
var name: = String()
|
||||
var cmd_num_rx: = 0 ## Номер команды принятый.
|
||||
var cmd_num_tx: = 0 ## Номер команды переданный.
|
||||
var cmd_state = CmdState.UNCK ## Состояние выполнения команды.
|
||||
var cmd_result: = 1 ## Результат выполнения команды. Устанавливается в ЯУ-07.
|
||||
var cmd_data: = PackedByteArray() ## Данные команды. Устанавливается в ЯУ-07.
|
||||
var cmd_retry = 0 ## Счётчик оставшихся попыток выполнить команду.
|
||||
var tick = 0.0 ## Текущее тик-время в мс.
|
||||
var cmd_tick_tx = 0.0 ## Время последней отправки команды.
|
||||
var cmd_tick_rx = 0.0 ## Время последнего приёма команды.
|
||||
var status: = PackedByteArray() ## Поле "состояние прибора".
|
||||
var tx_data: = PackedByteArray() ## Буфер отправленный.
|
||||
var tx_len = 0 ## Длина последнего отправленного пакета.
|
||||
var isa_ports = {} ## Результат выполнения команды "читать порт".
|
||||
var isa_block = {} ## Результат выполнения команды "читать массив из порта".
|
||||
var online = false ## Состояние связи с ячейкой.
|
||||
|
||||
|
||||
func _to_string() -> String: return String('яу07: %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user