Merge remote-tracking branch 'sasha/master'
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
# Ссылки на составные части
|
||||
|
||||
- [Собранные исполняемые файлы для шаблонов экспорта и редактора](https://gitea.srez.local:3000/sasha80/godot-bin)
|
||||
- [Исполняемые файлы для шаблонов экспорта и редактора](https://gitea.srez.local:3000/sasha80/godot-bin)
|
||||
- [Проброс последовательных портов через Ethernet](http://gitea.srez.local:3000/sasha80/uart-forwarder)
|
||||
- [Сборка Godot из исходников](http://gitea.srez.local:3000/sasha80/godot-build)
|
||||
- [Сервер карт](http://gitea.srez.local:3000/sasha80/map-tiles)
|
||||
|
||||
# Ссылки на имитаторы
|
||||
|
||||
@@ -24,7 +25,7 @@
|
||||
приходящих на соответствующий порт. Скрипт `ip-tables-navigation.sh` выполняет
|
||||
необходимые для этого настройки.
|
||||
- Для доступа к последовательным портам расположенным на другом вычислительном модуле,
|
||||
следует использовать [проброс портов](http://gitea.srez.local:3000/sasha80/uart-forwarder).
|
||||
следует использовать [проброс портов](http://gitea.srez.local:3000/sasha80/uart-forwarder).
|
||||
|
||||
# Разработка
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ config/map_bcs=Vector3(0.5, 1.5, 0.3)
|
||||
config/map_tile_size=256
|
||||
config/map_minimum_zoom=5
|
||||
config/map_maximum_zoom=19
|
||||
config/map_server_addr="https://b.tile.openstreetmap.org"
|
||||
interfer/center_offset=Vector2(200, 225)
|
||||
interfer/default_color0=Vector3(0.38, 0.47, 0.51)
|
||||
interfer/default_color1=Vector3(0.39, 0.44, 0.5)
|
||||
|
||||
@@ -17,9 +17,10 @@ class_name MercatorTileMap
|
||||
@export var tile_width: float = 256.0
|
||||
@export var tile_height: float = 256.0
|
||||
@export_range(1, 1000, 1) var max_concurrent_requests:int = 5
|
||||
@export_range(100, 100000, 1) var max_cached_tiles: int = 200
|
||||
@export_range(0, 25, 1) var max_zoom_level: int = 19
|
||||
@export_range(0, 25, 1) var min_zoom_level: int = 0
|
||||
@export_range(100, 100000, 1) var max_cached_tiles: int = 1024
|
||||
@export_range(0, 20, 1) var max_zoom_level: int = 20
|
||||
@export_range(0, 20, 1) var min_zoom_level: int = 0
|
||||
@export_range(0, 20, 1) var max_zoom_level_server: int = 20
|
||||
@export_color_no_alpha() var back_color: = Color.BLACK
|
||||
const default_size: = 400.0
|
||||
var is_centered: = false
|
||||
@@ -104,7 +105,13 @@ const image_load_proc_names = {
|
||||
set(v): image_load_proc = Callable(image, image_load_proc_names[v])
|
||||
|
||||
|
||||
func _ready():
|
||||
func on_map_centered(toggle_centered: bool): is_centered = toggle_centered
|
||||
|
||||
|
||||
func get_marks_count(): return _marks.size()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
image_type = 'png'
|
||||
$canvas.connect('mouse_entered', func(): _rollover = true)
|
||||
$canvas.connect('mouse_exited', func(): _rollover = false)
|
||||
@@ -116,11 +123,7 @@ func _ready():
|
||||
unit_nav.connect('data_received', on_data_received)
|
||||
|
||||
|
||||
func on_map_centered(toggle_centered: bool):
|
||||
is_centered = toggle_centered
|
||||
|
||||
|
||||
func on_data_received(coords: Dictionary):
|
||||
func on_data_received(coords: Dictionary) -> void:
|
||||
if not is_centered:
|
||||
return
|
||||
if coords.has_all(['latitude', 'longitude']):
|
||||
@@ -134,7 +137,7 @@ func _on_resize() -> void:
|
||||
|
||||
|
||||
## Создаёт новую отметку из координат экрана
|
||||
func add_mark_from_screen_pos(id: int, x: float, y: float, mark: Node):
|
||||
func add_mark_from_screen_pos(id: int, x: float, y: float, mark: Node) -> bool:
|
||||
if _marks.has(id):
|
||||
return false
|
||||
var wrld_pos = screen_to_world(_xyz, x, y)
|
||||
@@ -147,19 +150,17 @@ func add_mark_from_screen_pos(id: int, x: float, y: float, mark: Node):
|
||||
return true
|
||||
|
||||
|
||||
func get_marks_count(): return _marks.size()
|
||||
|
||||
|
||||
func delete_mark(id: int):
|
||||
func delete_mark(id: int) -> bool:
|
||||
if not _marks.has(id):
|
||||
return false
|
||||
_marks[id].mark.queue_free()
|
||||
_marks.erase(id)
|
||||
queue_redraw()
|
||||
return true
|
||||
|
||||
|
||||
## Создаёт новую отметку из долготы и широты
|
||||
func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size: float = 32):
|
||||
func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size: float = 32) -> bool:
|
||||
if _marks.has(id):
|
||||
return false
|
||||
var wrld_pos = lonlat_to_world(lon, lat)
|
||||
@@ -172,7 +173,7 @@ func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size
|
||||
|
||||
|
||||
## Возвращает новую позицию для точки, если она выходит из поля видимости
|
||||
func fix_mark_position(dot):
|
||||
func fix_mark_position(dot) -> void:
|
||||
if is_mark_visible(dot):
|
||||
return
|
||||
var v = 2 * tile_width * pow(2, _xyz.z)
|
||||
@@ -182,12 +183,12 @@ func fix_mark_position(dot):
|
||||
dot.position.x = _xyz.x + $canvas.size.x / v
|
||||
|
||||
|
||||
func is_mark_visible(dot):
|
||||
func is_mark_visible(dot) -> bool:
|
||||
var screen_pos = world_to_screen(dot.position.x, dot.position.y)
|
||||
return screen_pos.x > 0 and screen_pos.x < $canvas.size.x
|
||||
|
||||
|
||||
func _input(e):
|
||||
func _input(e) -> void:
|
||||
var lmp = get_local_mouse_position()
|
||||
if not _rollover:
|
||||
return
|
||||
@@ -222,7 +223,7 @@ func is_border_visible():
|
||||
return screen_to_tile(0, 0, z).y != 0
|
||||
|
||||
|
||||
func multiply_zoom(multiplier: float, pivot: Vector2):
|
||||
func multiply_zoom(multiplier: float, pivot: Vector2) -> void:
|
||||
var p1: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
_xyz.z = clampf(_xyz.z * multiplier, min_zoom_level, max_zoom_level)
|
||||
var p2: = screen_to_world(_xyz, pivot.x, pivot.y)
|
||||
@@ -230,7 +231,7 @@ func multiply_zoom(multiplier: float, pivot: Vector2):
|
||||
_xyz.y -= p2.y - p1.y
|
||||
|
||||
|
||||
func set_zoom(zoom: float, pivot=null):
|
||||
func set_zoom(zoom: float, pivot=null) -> void:
|
||||
if pivot == null:
|
||||
pivot = $canvas.size / 2.0
|
||||
|
||||
@@ -241,7 +242,7 @@ func set_zoom(zoom: float, pivot=null):
|
||||
_xyz.y -= p2.y - p1.y
|
||||
|
||||
|
||||
func _draw():
|
||||
func _draw() -> void:
|
||||
|
||||
var lmp = get_local_mouse_position()
|
||||
if mouse_wheel_count > 0:
|
||||
@@ -275,7 +276,7 @@ func _draw():
|
||||
visible_marks_count += int(dot.mark.visible)
|
||||
|
||||
|
||||
func _clean_all():
|
||||
func _clean_all() -> void:
|
||||
_queue.clear()
|
||||
_cache.clear()
|
||||
_marks.clear()
|
||||
@@ -286,7 +287,7 @@ func _clean_all():
|
||||
|
||||
|
||||
# get the tile from queue with the newest timestamp
|
||||
func get_next_in_queue():
|
||||
func get_next_in_queue() -> Tile:
|
||||
var tile = null
|
||||
for idx in _queue:
|
||||
var t = _queue.get(idx)
|
||||
@@ -296,7 +297,7 @@ func get_next_in_queue():
|
||||
|
||||
|
||||
# delete oldest tiles from cache
|
||||
func _clean_cache():
|
||||
func _clean_cache() -> void:
|
||||
var overflow = _cache.size() - max_cached_tiles
|
||||
if overflow <= 0:
|
||||
return
|
||||
@@ -307,7 +308,7 @@ func _clean_cache():
|
||||
_cache.erase(vals[i].i)
|
||||
|
||||
|
||||
func _process(delta):
|
||||
func _process(delta) -> void:
|
||||
now += delta
|
||||
|
||||
# if cache is overflowing - clean it
|
||||
@@ -340,8 +341,7 @@ func _process(delta):
|
||||
emit_signal('load_completed')
|
||||
|
||||
|
||||
# result, response_code, headers, body
|
||||
func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile):
|
||||
func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile) -> void:
|
||||
|
||||
_req_count -= 1
|
||||
remove_child(req)
|
||||
@@ -401,7 +401,7 @@ func _draw_subtile(tx: int, ty: int, tz: int, origx: int, origy: int, origz: flo
|
||||
return false
|
||||
|
||||
|
||||
func _draw_tile(tx: int, ty: int, z: float):
|
||||
func _draw_tile(tx: int, ty: int, z: float) -> void:
|
||||
var tz = floor(z)
|
||||
var p1 = tile_to_screen(tx, ty, z)
|
||||
var p2 = tile_to_screen(tx + 1, ty + 1, z)
|
||||
@@ -556,10 +556,12 @@ func get_tile(x: int, y: int, z: int, create: bool = true) -> Tile:
|
||||
|
||||
var queue_size: = _queue.size()
|
||||
if create and (not $canvas/player.is_playing()):
|
||||
tile = Tile.new(idx, x, y, z)
|
||||
tile.url = base_url.replace('{x}', str(x)).replace('{y}', str(y)).replace('{z}', str(z))
|
||||
tile.t = now
|
||||
_queue[idx] = tile
|
||||
if not tile:
|
||||
tile = Tile.new(idx, x, y, z)
|
||||
tile.url = base_url.replace('{x}', str(x)).replace('{y}', str(y)).replace('{z}', str(z))
|
||||
tile.t = now
|
||||
if z <= max_zoom_level_server:
|
||||
_queue[idx] = tile
|
||||
|
||||
if queue_size == 0 and _queue.size():
|
||||
emit_signal('load_started')
|
||||
@@ -600,8 +602,8 @@ class Tile:
|
||||
self.y = y0
|
||||
self.z = z0
|
||||
|
||||
|
||||
func haversine_m(lat1, lon1, lat2, lon2):
|
||||
# Возвращает расстояние в метрах между двумя точками на карте
|
||||
func haversine_m(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
|
||||
# Радиус Земли в метрах
|
||||
const R: = 6372795.0
|
||||
# Преобразование градусов в радианы
|
||||
@@ -624,16 +626,17 @@ func haversine_m(lat1, lon1, lat2, lon2):
|
||||
return dist
|
||||
|
||||
|
||||
func remove_closest_dot(screen_pos):
|
||||
func remove_closest_dot(screen_pos: Vector2) -> bool:
|
||||
var closest_dot = find_at_screen_position(screen_pos)
|
||||
if not closest_dot:
|
||||
return
|
||||
return false
|
||||
remove_child(closest_dot.mark)
|
||||
closest_dot.mark.queue_free()
|
||||
_marks.erase(closest_dot)
|
||||
return true
|
||||
|
||||
|
||||
func find_at_screen_position(screen_pos: Vector2):
|
||||
func find_at_screen_position(screen_pos: Vector2) -> Node:
|
||||
var closest_dot = null
|
||||
var closest_distance = INF
|
||||
for mark in _marks.values():
|
||||
@@ -650,7 +653,7 @@ func clear() -> void:
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func set_coordinates(lon: float, lat: float):
|
||||
func set_coordinates(lon: float, lat: float) -> void:
|
||||
var anim: Animation = $player.get_animation('goto')
|
||||
var new_pos = lonlat_to_world(lon, lat)
|
||||
anim.track_insert_key(0, 0, _xyz.x)
|
||||
|
||||
@@ -28,7 +28,9 @@ size = Vector2(400, 400)
|
||||
|
||||
[node name="tilemap" type="CanvasGroup" groups=["gui_items"]]
|
||||
script = ExtResource("1_l64tp")
|
||||
max_zoom_level = 21
|
||||
base_url = "http://192.168.11.105:8001/osm_tiles/{z}/{x}/{y}.png"
|
||||
max_zoom_level = 15
|
||||
max_zoom_level_server = 10
|
||||
az = 2.0
|
||||
|
||||
[node name="canvas" type="TextureRect" parent="." groups=["gui_items"]]
|
||||
|
||||
@@ -8,56 +8,57 @@ const ALIGNMENT = [HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER]
|
||||
const HEADER_ROW = [TableHeader, TableHeader]
|
||||
const HEADER_ROW_TEXT = ['Параметр', 'Значение']
|
||||
const SETTING_TABLE = [
|
||||
['Ограниченный режим', TableEdit, TableToggle],
|
||||
['Управление элементами в ограниченном режиме', TableEdit, TableToggle],
|
||||
['Кнопка «ПД-М4»', TableEdit, TableToggle],
|
||||
['Кнопка «ПД-М2»', TableEdit, TableToggle],
|
||||
['Кнопка «ОЗП-1»', TableEdit, TableToggle],
|
||||
['Кнопка «МЧМ-1»', TableEdit, TableToggle],
|
||||
['Кнопка «ОРН-И1»', TableEdit, TableToggle],
|
||||
['Кнопка «ОРН-М2»', TableEdit, TableToggle],
|
||||
['Кнопка «ЛЧМ-1»', TableEdit, TableToggle],
|
||||
['Кнопка «ПД-М4С»', TableEdit, TableToggle],
|
||||
['Кнопка «ПД-ЧМ»', TableEdit, TableToggle],
|
||||
['Кнопка «СВ-И1»', TableEdit, TableToggle],
|
||||
['Кнопка «К1»', TableEdit, TableToggle],
|
||||
['Кнопка «СВ-М2»', TableEdit, TableToggle],
|
||||
['Кнопка «ОРН»', TableEdit, TableToggle],
|
||||
['Кнопка «JTIDS»', TableEdit, TableToggle],
|
||||
['Кнопка «КУПД»', TableEdit, TableToggle],
|
||||
['Внешнее целеуказание', TableEdit, TableToggle],
|
||||
['Кнопка «Подавление»', TableEdit, TableToggle],
|
||||
['Виртуальная клавиатура', TableEdit, TableToggle],
|
||||
['Скрыть вкладку ЭМС 2', TableEdit, TableToggle],
|
||||
['Текущая версия ПО УАРЭП', TableEdit, TableEdit ],
|
||||
['Адрес сервера карт', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-частный', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-общий', TableEdit, TableEdit ],
|
||||
['уарэп-капсрпб', TableEdit, TableEdit ],
|
||||
['уарэп-эмс', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-2в', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-2н', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-2к', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-4в', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-4н', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-4к', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-1в', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-1н', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-1к', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-3в', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-3н', TableEdit, TableEdit ],
|
||||
['уарэп-яу07-3к', TableEdit, TableEdit ],
|
||||
['уарэп-5п28', TableEdit, TableEdit ],
|
||||
['уарэп-щ3', TableEdit, TableEdit ],
|
||||
['уарэп-спт25-1', TableEdit, TableEdit ],
|
||||
['уарэп-спт25-2', TableEdit, TableEdit ]
|
||||
]
|
||||
const EXTERNAL_CU = 17 # Внешнее целееуказание
|
||||
const SUPPRESS = 18 # Строка - Подавление
|
||||
const KEYBOARD = 19 # Строка - Виртуальная клавиатура
|
||||
const HIDE_EMS2 = 20 # Строка - Скрыть вкладку ЭМС 2
|
||||
const COMMIT = 21 # Строка - Версия УАРЭП
|
||||
const SERVER = 22 # Строка - Сервер карт
|
||||
['Ограниченный режим', TableEdit, TableToggle, 'Ограничть возможности по постановке помех'],
|
||||
['Кнопка «ПД-М4»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «ПД-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «ОЗП-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «МЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «ОРН-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «ОРН-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «ЛЧМ-1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «ПД-М4С»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «ПД-ЧМ»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «СВ-И1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «К1»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «СВ-М2»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «ОРН»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «JTIDS»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «КУПД»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Внешнее целеуказание', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Кнопка «Подавление»', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Виртуальная клавиатура', TableEdit, TableToggle, 'Разрешить отображение экранной клавиатуры'],
|
||||
['Скрыть вкладку ЭМС 2', TableEdit, TableToggle, 'Разрешить отображение кнопки'],
|
||||
['Текущая версия ПО УАРЭП', TableEdit, TableEdit, 'Время сборки, версия и номер фиксации'],
|
||||
['уарэп-яу07-частный', TableEdit, TableEdit, 'IP-адрес для получения частных сообщений от ЯУ-07'],
|
||||
['уарэп-яу07-общий', TableEdit, TableEdit, 'IP-адрес для получения широковещательных сообщений от ЯУ-07'],
|
||||
['уарэп-капсрпб', TableEdit, TableEdit, 'IP-адрес для связи с КАПС-РПБ'],
|
||||
['уарэп-эмс', TableEdit, TableEdit, 'IP-адрес для связи с ЭМС'],
|
||||
['уарэп-яу07-2в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 2'],
|
||||
['уарэп-яу07-2н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 2'],
|
||||
['уарэп-яу07-2к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 2'],
|
||||
['уарэп-яу07-4в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 4'],
|
||||
['уарэп-яу07-4н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 4'],
|
||||
['уарэп-яу07-4к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 4'],
|
||||
['уарэп-яу07-1в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 1'],
|
||||
['уарэп-яу07-1н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 1'],
|
||||
['уарэп-яу07-1к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 1'],
|
||||
['уарэп-яу07-3в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 3'],
|
||||
['уарэп-яу07-3н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 3'],
|
||||
['уарэп-яу07-3к', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-К 3'],
|
||||
['уарэп-5п28', TableEdit, TableEdit, 'IP-адрес для связи с 5П28'],
|
||||
['навигация', TableEdit, TableEdit, 'Порт назначения для получения данных от АКНГ'],
|
||||
['уарэп-щ3', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором Щ3'],
|
||||
['уарэп-спт25-1', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором СПТ-25 1'],
|
||||
['уарэп-спт25-2', TableEdit, TableEdit, 'Путь к UART-устройству для связи с прибором СПТ-25 2'],
|
||||
['Шаблон адреса сервера карт', TableEdit, TableEdit, 'URL-адрес сервера карт, содержащий поля \"{x}\", \"{y}\", \"{z}\" для подстановки индекса плитки'] ]
|
||||
const EXTERNAL_CU = 16 ## Внешнее целееуказание
|
||||
const SUPPRESS = 17 ## Строка - Подавление
|
||||
const KEYBOARD = 18 ## Строка - Виртуальная клавиатура
|
||||
const HIDE_EMS2 = 19 ## Строка - Скрыть вкладку ЭМС 2
|
||||
const COMMIT = 20 ## Строка - Версия УАРЭП
|
||||
|
||||
|
||||
func on_checkbutton_pressed(i_row: int): on_row_pressed(i_row)
|
||||
|
||||
|
||||
## Вызывается, когда узел впервые попадает в дерево сцены.
|
||||
@@ -92,8 +93,57 @@ func on_row_pressed(i_row: int):
|
||||
$scroll_set/table.set_row_selected(i_row, true)
|
||||
|
||||
|
||||
func on_checkbutton_pressed(i_row: int):
|
||||
on_row_pressed(i_row)
|
||||
func parse_cmd_line_args(settings_data: Dictionary):
|
||||
var args = OS.get_cmdline_args()
|
||||
for i in range(0, args.size(), 2):
|
||||
var key: String = args[i]
|
||||
key = key.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes()
|
||||
if not settings_data.has(key):
|
||||
continue
|
||||
if not ((i + 1) < args.size()):
|
||||
push_error('для аргумента \"%s\" не указано значение.' % key)
|
||||
break
|
||||
var val0 = args[i + 1]
|
||||
var val1 = settings_data[key]
|
||||
val0 = val0.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes()
|
||||
if typeof(val1) == TYPE_BOOL:
|
||||
if val0 not in ['yes', 'true', 'да', 'no', 'false', 'нет']:
|
||||
push_error('для аргумента \"%s\" указано неверное значение \"%s\".' % [key, val0])
|
||||
break
|
||||
settings_data[key] = true if val0 in ['yes', 'true', 'да'] else false
|
||||
elif typeof(val1) == TYPE_ARRAY:
|
||||
var val0s = val0.split(',')
|
||||
if val0s.size() != val1.size():
|
||||
push_error('для аргумента \"%s\" указано неверное значение \"%s\" (исходное: \"%s\").' % [key, val0, val1])
|
||||
break
|
||||
for j in val0s.size():
|
||||
var val: String = val0s[j]
|
||||
val = val.lstrip('\'\" ').rstrip('\'\" ').strip_edges().strip_escapes()
|
||||
if tools.type_is_num(val):
|
||||
val0s[j] = int(val)
|
||||
elif val in ['true', 'false']:
|
||||
val0s[j] = true if val == 'true' else false
|
||||
else:
|
||||
val0s[j] = val
|
||||
elif typeof(val1) == TYPE_STRING:
|
||||
settings_data[key] = val0
|
||||
|
||||
|
||||
## Загружает настройки из файла
|
||||
func load_settings(settings_data: Dictionary):
|
||||
var settings_file = settings.get_settings_file_path()
|
||||
var file = FileAccess.open(settings_file, FileAccess.READ)
|
||||
var abs_path = ProjectSettings.globalize_path(settings_file)
|
||||
if file:
|
||||
var read = file.get_as_text()
|
||||
file.close()
|
||||
var json_conv = JSON.new()
|
||||
if json_conv.parse(read) == OK:
|
||||
settings_data.merge(json_conv.get_data())
|
||||
else:
|
||||
log.warning('Не удалось разобрать \"%s\", будут использованы настройки по умолчанию' % abs_path)
|
||||
else:
|
||||
log.warning('Файл \"%s\" не найден, будут использованы настройки по умолчанию' % abs_path)
|
||||
|
||||
|
||||
func setting_tab():
|
||||
@@ -101,57 +151,54 @@ func setting_tab():
|
||||
$heard_table.set_header_text(HEADER_ROW_TEXT)
|
||||
$heard_table.set_columns_min_size([600, 950])
|
||||
$heard_table.set_columns_alignments(ALIGNMENT)
|
||||
var settings_data = {} # Загружаем настройки из файла
|
||||
var file = FileAccess.open(settings.settings_file, FileAccess.READ)
|
||||
var abs_path = ProjectSettings.globalize_path(settings.settings_file)
|
||||
if file:
|
||||
var read = file.get_as_text()
|
||||
file.close()
|
||||
var json_conv = JSON.new()
|
||||
if json_conv.parse(read) == OK:
|
||||
settings_data = json_conv.get_data()
|
||||
else:
|
||||
log.warning('Не удалось разобрать \"%s\", будут использованы настройки по умолчанию' % abs_path)
|
||||
else:
|
||||
log.warning('Файл \"%s\" не найден, будут использованы настройки по умолчанию' % abs_path)
|
||||
var settings_data = {}
|
||||
load_settings(settings_data)
|
||||
parse_cmd_line_args(settings_data)
|
||||
|
||||
for i in SETTING_TABLE.size():
|
||||
var setting_str = SETTING_TABLE[i]
|
||||
var parameter = setting_str[0]
|
||||
var node_label = setting_str[1]
|
||||
var node_value = setting_str[2]
|
||||
var tbl_row = SETTING_TABLE[i]
|
||||
var param_name = tbl_row[0]
|
||||
var node_label = tbl_row[1]
|
||||
var node_value = tbl_row[2]
|
||||
var tootip_text = tbl_row[3]
|
||||
$scroll_set/table.add_row([node_label, node_value])
|
||||
var label_instance = $scroll_set/table.get_node2(0, i)
|
||||
label_instance.text = parameter
|
||||
label_instance.text = param_name
|
||||
label_instance.tooltip_text = tootip_text
|
||||
$scroll_set/table.set_node_editable(0, i, false)
|
||||
var node_values = $scroll_set/table.get_node2(1, i).get_children()
|
||||
if node_values.size():
|
||||
var child = node_values[0]
|
||||
if child is CheckButton:
|
||||
child.connect('pressed', Callable(self, 'on_checkbutton_pressed').bind(i))
|
||||
if parameter in settings_data:
|
||||
child.set_pressed(settings_data[parameter])
|
||||
else:
|
||||
child.set_pressed(false)
|
||||
var commit_instance = $scroll_set/table.get_node2(1, COMMIT)
|
||||
var server_instance = $scroll_set/table.get_node2(1, SERVER)
|
||||
commit_instance.text = '%s' % commit.VCS_HEAD
|
||||
server_instance.text = ProjectSettings.get('application/config/map_server_addr')
|
||||
var val = settings_data[param_name] if settings_data.has(param_name) else false
|
||||
child.set_pressed(val)
|
||||
else:
|
||||
if settings_data.has(param_name):
|
||||
var val = settings_data[param_name]
|
||||
if typeof(val) == TYPE_STRING:
|
||||
$scroll_set/table.get_node2(1, i).text = settings_data[param_name]
|
||||
|
||||
$scroll_set/table.set_node_editable(1, COMMIT, false)
|
||||
$scroll_set/table.set_columns_min_size([600, 950])
|
||||
$scroll_set/table.set_columns_alignments(ALIGNMENT)
|
||||
for i in SETTING_TABLE.size():
|
||||
var setting_str = SETTING_TABLE[i]
|
||||
var parameter = setting_str[0]
|
||||
if parameter in settings.UnitProfiles:
|
||||
var unit_data = settings.UnitProfiles[parameter]
|
||||
var profiles = $scroll_set/table.get_node2(1, i)
|
||||
var joined_data = ''
|
||||
for j in range(unit_data[2].size()):
|
||||
joined_data += str(unit_data[2][j])
|
||||
if j < unit_data[2].size() - 1:
|
||||
joined_data += ','
|
||||
profiles.text = str(unit_data[1]) + ' : ' + joined_data
|
||||
$scroll_set/table.connect('row_pressed', Callable(self, 'on_row_pressed'))
|
||||
|
||||
var commit_instance = $scroll_set/table.get_node2(1, COMMIT)
|
||||
commit_instance.text = '%s' % commit.VCS_HEAD
|
||||
|
||||
for i in SETTING_TABLE.size():
|
||||
var param_name = SETTING_TABLE[i][0]
|
||||
if not settings.UnitProfiles.has(param_name):
|
||||
continue
|
||||
var unit_data = settings.UnitProfiles[param_name]
|
||||
var profile = $scroll_set/table.get_node2(1, i)
|
||||
var joined_data = ''
|
||||
for j in unit_data[2].size():
|
||||
joined_data += str(unit_data[2][j])
|
||||
if j < unit_data[2].size() - 1:
|
||||
joined_data += ','
|
||||
profile.text = '%s : %s' % [str(unit_data[1]), joined_data]
|
||||
button_settings()
|
||||
|
||||
|
||||
@@ -171,7 +218,7 @@ func button_settings():
|
||||
|
||||
func _on_btn_save_settings_pressed():
|
||||
var json_data = {}
|
||||
for i in range(SETTING_TABLE.size()):
|
||||
for i in SETTING_TABLE.size():
|
||||
var parameter = SETTING_TABLE[i][0]
|
||||
if parameter in settings.UnitProfiles:
|
||||
var profiles = $scroll_set/table.get_node2(1, i)
|
||||
@@ -191,16 +238,19 @@ func _on_btn_save_settings_pressed():
|
||||
else:
|
||||
port = port.strip_edges()
|
||||
if port.is_valid_int():
|
||||
json_data[parameter].append(int(port))
|
||||
else:
|
||||
json_data[parameter].append(port)
|
||||
port = int(port)
|
||||
json_data[parameter].append(port)
|
||||
else:
|
||||
var children = $scroll_set/table.get_node2(1, i).get_children()
|
||||
if len(children):
|
||||
var child = children[0]
|
||||
json_data[parameter] = child.is_pressed()
|
||||
var file = FileAccess.open(settings.settings_file, FileAccess.WRITE)
|
||||
var abs_path = ProjectSettings.globalize_path(settings.settings_file)
|
||||
else:
|
||||
var row = $scroll_set/table.get_row(i)
|
||||
json_data[parameter] = row[1].text
|
||||
var settings_file = settings.get_settings_file_path()
|
||||
var file = FileAccess.open(settings_file, FileAccess.WRITE)
|
||||
var abs_path = ProjectSettings.globalize_path(settings_file)
|
||||
if not file:
|
||||
log.error('Не удалось открыть файл для записи \"%s\"' % abs_path)
|
||||
return
|
||||
|
||||
@@ -164,7 +164,7 @@ func map_threat_to_bip(th: threats.Threat, bip: Control):
|
||||
var sector_width = 50.0
|
||||
for key in prd.FS_FREQ:
|
||||
var freq_range = prd.FS_FREQ[key]
|
||||
var _num_values = (freq_range[1]- freq_range[0]) / sector_width
|
||||
var _num_values = (freq_range[1] - freq_range[0]) / sector_width
|
||||
if freq_range[0] <= freq and freq <= freq_range[1]:
|
||||
sector_key = key
|
||||
break
|
||||
@@ -195,7 +195,7 @@ func on_interfer_new(ecm):
|
||||
if interfer.thrs.has(ecm.ispp):
|
||||
var th_id = interfer.thrs[ecm.ispp]
|
||||
var bip = get_node('%d' % th_id)
|
||||
if bip!= null:
|
||||
if bip != null:
|
||||
if ecm.krp!= interfer.INTERFER_OFF:
|
||||
bip.set_track_visible(true)
|
||||
if ecm.svk == 1:
|
||||
|
||||
@@ -2,7 +2,7 @@ class_name navigation extends Node
|
||||
|
||||
## "Протокол №120-11435-09.PDF"
|
||||
|
||||
const ONLINE_TIMEOUT: = 5000 ## Время ожидания пакета, милисекунды
|
||||
const ONLINE_TIMEOUT: = 5000 ## Время ожидания пакета, миллисекунды
|
||||
const pow_2_30: = pow(2.0, 30.0)
|
||||
|
||||
## Источник данных навигации
|
||||
|
||||
@@ -153,10 +153,7 @@ func _ready() -> void:
|
||||
var unit_key = settings.get_unit_key(unit_name)
|
||||
units[unit_key] = new_unit
|
||||
units_udp[unit_key] = new_unit
|
||||
if len(st[2]) > 1:
|
||||
dst_ports[unit_key] = st[2][1]
|
||||
else:
|
||||
dst_ports[unit_key] = st[2][0]
|
||||
dst_ports[unit_key] = st[2][1] if len(st[2]) > 1 else st[2][0]
|
||||
|
||||
if proto in TCP_PROTO:
|
||||
var unit_tcp = TCP_PROTO[proto].new(unit_name)
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
@tool
|
||||
class_name rep_settings extends Node
|
||||
class_name uarep_settings extends Node
|
||||
|
||||
## Параметры.
|
||||
|
||||
var settings_file = ProjectSettings.get_setting('application/config/settings_path', 'user://settings.json') # Путь к файлу с настройками
|
||||
## Настройки программы
|
||||
|
||||
var settings_program: Dictionary
|
||||
|
||||
@@ -57,6 +55,7 @@ const UM_MAX: = 55.0
|
||||
func _ready() -> void:
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
var settings_file = settings.get_settings_file_path()
|
||||
var abs_path = ProjectSettings.globalize_path(settings_file)
|
||||
log.info('Путь к файлу настроек: \"%s\"' % abs_path)
|
||||
var file = FileAccess.open(settings_file, FileAccess.READ)
|
||||
@@ -103,6 +102,13 @@ func _ready() -> void:
|
||||
log.info('Не удалось прочитать значение \"%s\" из файла настроек, будет использовано значение по умолчанию' % key)
|
||||
|
||||
|
||||
## Возвращает полный путь к файлу с настройками
|
||||
func get_settings_file_path():
|
||||
return ProjectSettings.get_setting(
|
||||
'application/config/settings_path',
|
||||
'user://settings.json')
|
||||
|
||||
|
||||
## Возвращает ключ устройства.
|
||||
func get_unit_key(unit_name: String) -> Array:
|
||||
var item = UnitProfiles[unit_name]
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
class_name tcp5_p28 extends Node
|
||||
|
||||
## Реализация "Протокол информационного сопряжения.
|
||||
## СПО АСУ изделия «МП‑550» с СПО 5П-28".
|
||||
|
||||
## СПО АСУ изделия МП-550 с СПО 5П-28
|
||||
|
||||
const ONLINE_TIMEOUT = 5000 ## Время ожидания пакета от 5П-28, мс.
|
||||
const BUFFER_SIZE = 2048 ## Размер приёмного буфера для датаграмм.
|
||||
|
||||
## Тип модуляции для запаковки в пакет для 5П-28.
|
||||
const MOD_TYPES: Array = ['',
|
||||
'am',
|
||||
'ook',
|
||||
'ask',
|
||||
'fm',
|
||||
'qpsk',
|
||||
'oqpsk',
|
||||
'pi4qpsk',
|
||||
'qam16',
|
||||
'qam32',
|
||||
'qam64',
|
||||
'qam128',
|
||||
'qam256',
|
||||
'qam512',
|
||||
'cpfsk',
|
||||
'psk',
|
||||
'ofdm',]
|
||||
const MOD_TYPES: Array = [
|
||||
'',
|
||||
'am',
|
||||
'ook',
|
||||
'ask',
|
||||
'fm',
|
||||
'qpsk',
|
||||
'oqpsk',
|
||||
'pi4qpsk',
|
||||
'qam16',
|
||||
'qam32',
|
||||
'qam64',
|
||||
'qam128',
|
||||
'qam256',
|
||||
'qam512',
|
||||
'cpfsk',
|
||||
'psk',
|
||||
'ofdm' ]
|
||||
|
||||
const CU_STATE: Dictionary = {
|
||||
0: 2, # Подготовка к выполнению
|
||||
@@ -42,19 +42,19 @@ class TCP5P28 extends unit.Unit:
|
||||
const CMD_TYPE_IN: int = 3
|
||||
|
||||
const PR_STATE: Dictionary = {
|
||||
'уарэп-эмс': [1, 1],
|
||||
'уарэп-яу07-1н': [9, 8],
|
||||
'уарэп-яу07-1в': [5, 4],
|
||||
'уарэп-яу07-1к': [13, 12],
|
||||
'уарэп-яу07-2н': [10, 9],
|
||||
'уарэп-яу07-2в': [6, 5],
|
||||
'уарэп-яу07-2к': [14, 13],
|
||||
'уарэп-яу07-3н': [11, 10],
|
||||
'уарэп-яу07-3в': [7, 6],
|
||||
'уарэп-яу07-3к': [15, 14],
|
||||
'уарэп-яу07-4н': [12, 11],
|
||||
'уарэп-яу07-4в': [8, 7],
|
||||
'уарэп-яу07-4к': [16, 15], }
|
||||
'уарэп-эмс': [1, 1],
|
||||
'уарэп-яу07-1н': [9, 8],
|
||||
'уарэп-яу07-1в': [5, 4],
|
||||
'уарэп-яу07-1к': [13, 12],
|
||||
'уарэп-яу07-2н': [10, 9],
|
||||
'уарэп-яу07-2в': [6, 5],
|
||||
'уарэп-яу07-2к': [14, 13],
|
||||
'уарэп-яу07-3н': [11, 10],
|
||||
'уарэп-яу07-3в': [7, 6],
|
||||
'уарэп-яу07-3к': [15, 14],
|
||||
'уарэп-яу07-4н': [12, 11],
|
||||
'уарэп-яу07-4в': [8, 7],
|
||||
'уарэп-яу07-4к': [16, 15] }
|
||||
|
||||
signal get_threats(unit: TCP5P28) ## Сигнал запрос целей.
|
||||
signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания.
|
||||
@@ -125,7 +125,7 @@ class TCP5P28 extends unit.Unit:
|
||||
var data_len = 12 # длинна блока данных в байтах
|
||||
data.resize(data_len)
|
||||
data.encode_u16(0, 0) # Код ошибки
|
||||
data.encode_u16(2, len(interfers)) # Количество целей
|
||||
data.encode_u16(2, interfers.size()) # Количество целей
|
||||
data.encode_u32(4, uarep_state) # Состояние УА-РЕП
|
||||
data.encode_u32(8, uarep_line) # Состояние линий связи
|
||||
var cu_data: PackedByteArray = []
|
||||
@@ -136,15 +136,11 @@ class TCP5P28 extends unit.Unit:
|
||||
continue
|
||||
var cu = ecms[id]
|
||||
cu_data.encode_u16(0, cu.ispp)
|
||||
var state: int
|
||||
if CU_STATE.has(cu.svk):
|
||||
state = CU_STATE[cu.svk]
|
||||
else:
|
||||
state = 9
|
||||
var state: int = CU_STATE[cu.svk] if CU_STATE.has(cu.svk) else 9
|
||||
cu_data.encode_u8(2, state) # Состояние выполнения команды
|
||||
cu_data.encode_u8(3, 0xFF) # Эффективность работы помехи
|
||||
data.append_array(cu_data)
|
||||
var data_to_send: PackedByteArray = create_header(data_len + 4 * len(interfers))
|
||||
var data_to_send: PackedByteArray = create_header(data_len + 4 * interfers.size())
|
||||
data_to_send.append_array(data)
|
||||
tx_stack.append(data_to_send)
|
||||
|
||||
@@ -195,7 +191,7 @@ class TCP5P28 extends unit.Unit:
|
||||
func to_cp866(proto: String, th_data: PackedByteArray):
|
||||
var cp866_proto: PackedByteArray = proto.to_ascii_buffer()
|
||||
cp866_proto.resize(36)
|
||||
for i in len(cp866_proto):
|
||||
for i in cp866_proto.size():
|
||||
th_data[28 + i] = cp866_proto[i]
|
||||
|
||||
func set_interfer(data: PackedByteArray):
|
||||
|
||||
@@ -35,7 +35,7 @@ func allways(val: bool, msg: String = '<не указано>'):
|
||||
get_tree().quit(Error.FAILED)
|
||||
|
||||
|
||||
func _check_index(obj, index) -> bool:
|
||||
func check_index(obj, index) -> bool:
|
||||
if obj is Dictionary:
|
||||
if obj.has(index):
|
||||
return true
|
||||
@@ -59,11 +59,11 @@ func get_value_by_path(obj, paths: Array, ret_val: Array):
|
||||
var index = paths.pop_at(0)
|
||||
ret_val[1] = false
|
||||
if paths.size():
|
||||
if _check_index(obj, index):
|
||||
if check_index(obj, index):
|
||||
ret_val[2] += 1
|
||||
get_value_by_path(obj[index], paths, ret_val)
|
||||
else:
|
||||
if _check_index(obj, index):
|
||||
if check_index(obj, index):
|
||||
ret_val[0] = obj[index]
|
||||
ret_val[1] = true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user