Merge remote-tracking branch 'sasha/master'

# Conflicts:
#	scenes/button-flat/nine-patch-button.gd
#	scenes/frame-ecm-list/scroll-ecm-list.gd
#	scenes/grid-buttons-ecm/grid-buttons-ecm.tscn
#	scenes/настройки/настройки.tscn
#	scenes/работа/работа.gd
#	scripts/interfer.gd
#	scripts/settings.gd
#	scripts/trassa.gd
This commit is contained in:
MaD_CaT
2025-10-20 13:32:23 +03:00
60 changed files with 1427 additions and 706 deletions

2
.gitignore vendored
View File

@@ -30,6 +30,8 @@ override.cfg
# контроль версий
scripts/commit.gd
*.bak
# python специфичное
modbus/pymodbus/__pycache__
modbus/serial/__pycache__

View File

@@ -17,11 +17,14 @@ signal handled()
Logger.ERROR: Color.RED,
Logger.FATAL: Color.RED,
}
@export var max_lines_count: int = 512
var _logger : Logger
func _on_check_box_scroll_toggled(toggled_on: bool) -> void: scroll_following = toggled_on
func _enter_tree() -> void:
var logger := get_node_or_null("/root/log") as Logger
if is_instance_valid(logger):
@@ -38,7 +41,7 @@ func get_color(level: int) -> Color:
## Установить журнал событий.
func set_logger(logger: Logger) -> void:
assert(is_instance_valid(logger), "Invalid Logger.")
tools.allways(is_instance_valid(logger), 'Invalid Logger.')
if not is_instance_valid(logger) or is_same(_logger, logger):
return
@@ -58,20 +61,25 @@ func get_logger() -> Logger:
func format(message: Dictionary) -> String:
return format_text.format(
{
"year": "%02d" % message["year"],
"month": "%02d" % message["month"],
"day": "%02d" % message["day"],
"hour": "%02d" % message["hour"],
"minute": "%02d" % message["minute"],
"second": "%02d" % message["second"],
"level": message["level_name"],
"text": message["text"],
'year': '%04d' % message['year'],
'month': '%02d' % message['month'],
'day': '%02d' % message['day'],
'hour': '%02d' % message['hour'],
'minute': '%02d' % message['minute'],
'second': '%02d' % message['second'],
'level': message['level_name'],
'text': message['text'],
}
)
## Обработать сообщение.
func handle_message(message: Dictionary) -> void:
push_color(get_color(message["level"]))
append_text(format(message) + "\n")
push_color(get_color(message['level']))
append_text(format(message) + '\n')
pop()
handled.emit()
var pc: = get_paragraph_count()
if pc < max_lines_count:
return
for i in pc - max_lines_count:
remove_paragraph(i)

View File

@@ -25,23 +25,26 @@ config/map_tile_size=256
config/map_minimum_zoom=5
config/map_maximum_zoom=19
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)
interfer/select_color=Vector3(1, 1, 1)
interfer/interfer_color=Vector3(0.58, 0.47, 0.51)
interfer/default_color0=Color(0.38, 0.47, 0.51, 1)
interfer/default_color1=Color(0.39, 0.44, 0.5, 1)
interfer/select_color=Color(1, 1, 1, 1)
interfer/interfer_color=Color(0.58, 0.47, 0.51, 1)
interfer/resend_timeout=1000.0
config/external_cu=false
config/unit_rr_request_period=5.0
config/unit_rr_request_period=20.0
config/kems_files_path="user://kems/"
config/emsg_files_path="user://emsg/"
config/settings_path="user://settings.json"
config/unit_bpo_request_period=20.0
interfer/emit_color=Color(0.58, 0.471, 0.51, 0.2)
interfer/emit_sel_color=Color(1, 1, 1, 1)
[autoload]
commit="*res://scripts/commit.gd"
tools="*res://scripts/tools.gd"
log="*res://addons/godot-logger/scripts/logger.gd"
unit="*res://scripts/unit.gd"
tools="*res://scripts/tools.gd"
signaller="*res://scripts/signaller.gd"
settings="*res://scripts/settings.gd"
network="*res://scripts/network.gd"
@@ -84,6 +87,7 @@ window/size/viewport_height=1200
window/size/window_width_override=1024
window/size/window_height_override=768
window/subwindows/embed_subwindows=false
window/frame_pacing/android/enable_frame_pacing=false
window/stretch/mode="canvas_items"
window/dpi/allow_hidpi=false
@@ -142,6 +146,7 @@ folder_colors={
map_server_addr=false
center_offset=Vector2(0, 0)
external_cu=false
unit_bpo_request_period=0.0
[global_group]

View File

@@ -2,11 +2,11 @@ class_name bip_ extends Control
var selected: bool
## Присваивает заданое значение видимости селектору.
## Присваивает заданное значение видимости селектору.
func set_track_visible(value: bool): $track.visible = value
## Присваивает заданое значение видимости индикатору выполнения.
## Присваивает заданное значение видимости индикатору выполнения.
func set_ecm_visible(value: bool): $ecm_done.visible = value
@@ -14,7 +14,7 @@ func update(tick_rx: int):
$bip.set_instance_shader_parameter('tick_update', tick_rx)
## Функция присваивает заданое значение видимости селектору.
## Присваивает заданое значение видимости селектору.
func set_sel_visible(value: bool):
selected = value
$selector.visible = value

View File

@@ -15,17 +15,19 @@ code = "shader_type canvas_item;
uniform vec4 color: source_color = vec4(1, 1, 1, 1);
uniform vec4 color_up: source_color = vec4(1, 1, 1, 1); /* Цвет вспышки при обновлении */
const float ds = 0.00725; /* Относительное расстояние на котором выполняется сглаживание краёв */
const float dsr = 6.125;
const float ds = 0.01; /* Относительное расстояние на котором выполняется сглаживание краёв */
const float dsr = 10.0;
const vec2 center = vec2(0.5, 0.5); /* Центр должен быть в (0.5, 0.5), но это не так */
const float radius = 0.075 - ds * 2.0; /* Радиус должен быть 0.5, но это не так */
uniform float speed: hint_range(-1024.0, 1024.0) = 0.0; /* Время вспышки при обновлении, c */
uniform int ant_band_count_0 = 3;
const float ant_band_r0_0 = 0.3;
const float ant_band_r0_0 = 0.27
const float ant_band_r1_0 = 0.4;
;
const float ant_band_r1_0 = 0.47;
float smooth_px(float r, float R, float dss)
{
@@ -97,7 +99,7 @@ void fragment()
shader = SubResource("Shader_60ho7")
shader_parameter/color = Color(1, 1, 1, 0.968627)
shader_parameter/color_up = Color(1, 1, 1, 0)
shader_parameter/speed = 73.0
shader_parameter/speed = -118.48
shader_parameter/ant_band_count_0 = 3
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hqs6j"]
@@ -185,23 +187,14 @@ void fragment()
}
"
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lpmq6"]
shader = SubResource("Shader_81bae")
shader_parameter/color = Color(0.0862745, 0.560784, 0.72549, 0.886275)
shader_parameter/color_up = Color(1, 1, 1, 0)
shader_parameter/speed = -73.0
shader_parameter/ant_band_count_0 = 9
shader_parameter/ant_band_r0_0 = 0.45
shader_parameter/ant_band_r1_0 = 0.5
[sub_resource type="ShaderMaterial" id="ShaderMaterial_h3oo7"]
shader = SubResource("Shader_81bae")
shader_parameter/color = Color(1, 0, 0, 1)
shader_parameter/color_up = Color(1, 1, 1, 0)
shader_parameter/speed = 66.064
shader_parameter/ant_band_count_0 = 3
shader_parameter/ant_band_r0_0 = 0.47
shader_parameter/ant_band_r1_0 = 0.5
shader_parameter/speed = 85.808
shader_parameter/ant_band_count_0 = 4
shader_parameter/ant_band_r0_0 = 0.3
shader_parameter/ant_band_r1_0 = 0.45
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lkrha"]
shader = ExtResource("3_2a1qb")
@@ -213,51 +206,63 @@ shader_parameter/point_5 = Vector2(0.214, 0.125)
shader_parameter/point_6 = Vector2(0.25, 0.125)
shader_parameter/point_7 = Vector2(0.125, 0.214)
shader_parameter/point_8 = Vector2(0.125, 0.25)
shader_parameter/len = 0.264
shader_parameter/speed = 71.0
shader_parameter/len = 0.179
shader_parameter/speed = 63.0
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_svd33"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lpmq6"]
shader = SubResource("Shader_81bae")
shader_parameter/color = Color(0.0784314, 0.501961, 0.701961, 0.917647)
shader_parameter/color_up = Color(1, 1, 1, 0)
shader_parameter/speed = 158.179
shader_parameter/ant_band_count_0 = 9
shader_parameter/ant_band_r0_0 = 0.27
shader_parameter/ant_band_r1_0 = 0.45
[node name="threat" type="Control"]
layout_mode = 3
anchors_preset = 0
offset_right = 20.0
offset_bottom = 20.0
offset_left = -12.0
offset_top = -12.0
offset_right = 12.0
offset_bottom = 12.0
script = ExtResource("1_h7l70")
[node name="bip" type="Sprite2D" parent="."]
material = SubResource("ShaderMaterial_qq6yq")
position = Vector2(10, 10)
scale = Vector2(20, 20)
position = Vector2(12, 12)
scale = Vector2(14, 14)
texture = SubResource("PlaceholderTexture2D_xbpqf")
[node name="selector" type="Sprite2D" parent="."]
visible = false
material = SubResource("ShaderMaterial_fkqwb")
scale = Vector2(20, 20)
position = Vector2(-1, -1)
scale = Vector2(26, 26)
texture = SubResource("PlaceholderTexture2D_hqs6j")
centered = false
[node name="recomendation" type="Sprite2D" parent="."]
visible = false
material = SubResource("ShaderMaterial_lpmq6")
scale = Vector2(20, 20)
texture = SubResource("PlaceholderTexture2D_hqs6j")
centered = false
offset = Vector2(0.5, 0.5)
[node name="ecm_done" type="Sprite2D" parent="."]
visible = false
material = SubResource("ShaderMaterial_h3oo7")
position = Vector2(-5, -5)
scale = Vector2(30, 30)
position = Vector2(-2, -2)
scale = Vector2(28, 28)
texture = SubResource("PlaceholderTexture2D_hqs6j")
centered = false
offset = Vector2(0.5, 0.5)
[node name="track" type="Sprite2D" parent="."]
visible = false
material = SubResource("ShaderMaterial_lkrha")
position = Vector2(10, 10)
scale = Vector2(26, 26)
position = Vector2(12, 12)
scale = Vector2(34, 34)
texture = SubResource("PlaceholderTexture2D_svd33")
[node name="recomendation" type="Sprite2D" parent="."]
visible = false
material = SubResource("ShaderMaterial_lpmq6")
scale = Vector2(24, 24)
texture = SubResource("PlaceholderTexture2D_hqs6j")
offset = Vector2(0.5, 0.5)
[connection signal="gui_input" from="." to="." method="_on_bip_gui_input"]

View File

@@ -59,7 +59,7 @@ var _pressed: = false
$button.set_toggle_mode(val)
@export var font_size: int = true:
@export var font_size: int = 15:
set(val):
$button.add_theme_font_size_override('theme_override_font_sizes/font_size', val)

View File

@@ -2,7 +2,9 @@ class_name Diagram extends Sprite2D
const NUM_OF_RANGE = 7
const NUM_OF_DIRECTIONS = 4
var fs_default_colors: Array ## Цвета по умолчанию для блоков ФС.
var fs_default_colors: Array[Color] ## Цвета по умолчанию для блоков ФС.
@export var SecZap: PackedScene
func _ready() -> void:
signaller.connect('map_mode_changed', Callable(self, 'set_view_mode'))
@@ -11,20 +13,24 @@ func _ready() -> void:
func sv(val: float) -> float: return val / ($строб.scale.x / 2.0) * 0.125
func set_canvas_rotation(val: float) -> void: material.set('shader_parameter/rotation', val)
func set_strob_visible(val: bool): $строб.visible = val
func set_strob_center(val: Vector2): $строб.position = val
func set_strob_dir(val: float): $строб.material.set('shader_parameter/dir', val)
func set_strob_color(val: Color): $строб.material.set('shader_parameter/color', val)
func set_strob_width(val: float): $строб.material.set('shader_parameter/width', val)
func set_strob_band(val: float): $строб.material.set('shader_parameter/band', val / 125.0)
func set_strob_radius(val: float): $строб.material.set('shader_parameter/radius', sv(val))
func set_strob_dir(val: float): $строб.set_instance_shader_parameter('dir', val)
func set_strob_width(val: float): $строб.set_instance_shader_parameter('width', val)
func set_strob_band(val: float): $строб.set_instance_shader_parameter('band', val / 125.0)
func set_strob_radius(val: float): $строб.set_instance_shader_parameter('radius', sv(val))
func set_strob_color(val: Color): $строб.set_instance_shader_parameter('color', val)
func get_strob_center() -> Vector2: return $строб.position
func get_strob_visible() -> bool: return $строб.visible
func get_strob_width() -> float: return $строб.material.get('shader_parameter/width')
func get_strob_band() -> float: return $строб.material.get('shader_parameter/band') * 125.0
func get_strob_radius() -> float: return $строб.material.get('shader_parameter/radius') * 125.0
func get_strob_center() -> Vector2: return $строб.position
func get_strob_visible() -> bool: return $строб.visible
func get_strob_dir() -> float: return $строб.get_instance_shader_parameter('dir')
func get_strob_width() -> float: return $строб.get_instance_shader_parameter('width')
func get_strob_band() -> float: return $строб.get_instance_shader_parameter('band') * 125.0
func get_strob_radius() -> float: return $строб.get_instance_shader_parameter('radius') * 125.0
func get_strob_color() -> float: return $строб.get_instance_shader_parameter('color')
func get_canvas_rotation() -> float: return material.get('shader_parameter/rotation')
func get_radius_outter() -> float: return material.get('shader_parameter/radius_outter')
func get_radius_inner_0() -> float: return material.get('shader_parameter/radius_inner_0')
func get_radius_inner_1() -> float: return material.get('shader_parameter/radius_inner_1')
@@ -32,6 +38,51 @@ func get_radius_inner_1() -> float: return material.get('shader_parameter/radius
func set_band_colors(val: Array): material.set('shader_parameter/ant_band_c', val)
## Добавляет сектор запрета[br]
## [param id] - Индекс сектора запрета.[br]
## [param szv.x] - Центральная частота (198...546).[br]
## [param szv.w] - Ширина диапазона (198...546).[br]
## [param szv.y] - Угол центра (0...360).[br]
## [param szv.z] - Ширина по углу (0...360).[br]
func add_seczap(id: int, szv: Vector4):
var seczap: = SecZap.instantiate()
seczap.name = StringName('SECZAP%d' % id)
seczap.position = $строб.position
seczap.set_instance_shader_parameter('dir', szv.y - 90.0)
seczap.set_instance_shader_parameter('width', szv.z)
seczap.set_instance_shader_parameter('band', sv(szv.w))
seczap.set_instance_shader_parameter('radius', sv(szv.x))
add_child(seczap)
## Удаляет сектор запрета[br]
## [param id] - Индекс сектора запрета[br]
func remove_seczap(id: int):
var seczap: = get_node_or_null('SECZAP%d' % id)
if not seczap: return
remove_child(seczap)
seczap.queue_free()
## Изменяет сектор запрета[br]
## [param id] - Индекс сектора запрета[br]
## [param szv.x] - Центральная частота[br]
## [param szv.w] - Ширина диапазона[br]
## [param szv.y] - Угол центра[br]
## [param szv.z] - Ширина по углу[br]
func set_seczap(id: int, szv: Vector4):
var seczap: = get_node('SECZAP%d' % id)
seczap.set_instance_shader_parameter('dir', szv.y)
seczap.set_instance_shader_parameter('width', szv.z)
seczap.set_instance_shader_parameter('band', sv(szv.w))
seczap.set_instance_shader_parameter('radius', sv(szv.x))
func set_seczap_color(id: int, color: Color):
var seczap: = get_node('SECZAP%d' % id)
seczap.set_instance_shader_parameter('color', color)
func set_view_mode(val: int):
if val == 1:
$строб.hide()
@@ -42,8 +93,10 @@ func set_view_mode(val: int):
## Закрашивание по умолчанию блоков ФС цветами из настроек.
func set_def_colors():
var color0: Vector3 = ProjectSettings.get_setting('application/interfer/default_color0', Vector3(0.38, 0.47, 0.51))
var color1: Vector3 = ProjectSettings.get_setting('application/interfer/default_color1', Vector3(0.39, 0.44, 0.50))
var color0: Color = ProjectSettings.get_setting('application/interfer/default_color0', Color(0.38, 0.47, 0.51, 1.0))
var color1: Color = ProjectSettings.get_setting('application/interfer/default_color1', Color(0.39, 0.44, 0.50, 1.0))
color0 *= Color(1.0, 1.0, 1.0, 0.0)
color1 *= Color(1.0, 1.0, 1.0, 0.0)
var col_arr: Array = [color0, color1]
var col = false
for i in NUM_OF_RANGE:

View File

@@ -11,19 +11,13 @@ size = Vector2(1600, 1200)
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lniyv"]
resource_local_to_scene = true
shader = ExtResource("4_obn6s")
shader_parameter/color = Color(1, 1, 1, 0.168627)
shader_parameter/clip_color = Color(1, 0.5, 0.5, 1)
shader_parameter/width = 45.0
shader_parameter/band = 0.02
shader_parameter/radius = 0.08
shader_parameter/dir = 0.0
shader_parameter/inner_clip = 0.045
[node name="canvas" type="Sprite2D"]
material = ExtResource("1_newdt")
texture = SubResource("PlaceholderTexture2D_2bft1")
centered = false
script = ExtResource("2_8xjuy")
SecZap = ExtResource("3_tgnog")
[node name="строб" parent="." instance=ExtResource("3_tgnog")]
material = SubResource("ShaderMaterial_lniyv")

View File

@@ -5,18 +5,16 @@
[sub_resource type="ShaderMaterial" id="ShaderMaterial_xo5or"]
resource_local_to_scene = true
shader = ExtResource("1_e0gfn")
shader_parameter/color = Color(1, 1, 1, 0.168627)
shader_parameter/clip_color = Color(1, 0.5, 0.5, 1)
shader_parameter/width = 45.0
shader_parameter/band = 0.02
shader_parameter/radius = 0.08
shader_parameter/dir = 0.0
shader_parameter/inner_clip = 0.045
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_2lkm8"]
[node name="sector" type="Sprite2D"]
material = SubResource("ShaderMaterial_xo5or")
instance_shader_parameters/band = 0.02
instance_shader_parameters/color = Color(1, 1, 1, 0.188235)
instance_shader_parameters/inner_clip = 0.045
instance_shader_parameters/radius = 0.08
instance_shader_parameters/width = 45.0
position = Vector2(610, 600)
scale = Vector2(1108, 1108)
texture = SubResource("PlaceholderTexture2D_2lkm8")

View File

@@ -20,7 +20,7 @@ const INTERFER_STATE = {
5: '' }
## Состояние выполнения сеанса помехи
## Названия помех
const INTERFER_NAMES = {
'off': 'Откл',
'mchm1': 'МЧМ-1',
@@ -46,6 +46,7 @@ const COLUMN_NAME = 1
const COLUMN_AOA = 2
const COLUMN_STATE = 3
var course = 0.0 ## Курс корабля
func on_rto_threat_unsel(_th_id): $table.clear_rows_selected()
@@ -88,6 +89,8 @@ func _ready():
interfer.connect('interfer_recommendate', Callable(self, 'on_interfer_recommendate'))
$table.connect('row_pressed', Callable(self, 'on_row_pressed'))
call_deferred('init_table')
var unit_nav = network.get_unit_instance('навигация')
unit_nav.connect('data_received', on_navi_data_received)
func init_table():
@@ -148,7 +151,10 @@ func map_th_to_row(ecm) -> Array:
row[COLUMN_NAME] = ''
if INTERFER_NAMES.has(ecm.krp):
row[COLUMN_NAME] = '%s' % INTERFER_NAMES[ecm.krp]
row[COLUMN_AOA] = '%s' % ecm.kni
var aoa = ecm.kni + course
if aoa > 360.0:
aoa -= 360.0
row[COLUMN_AOA] = '%5.1f' % aoa
row[COLUMN_STATE] = ''
if INTERFER_STATE.has(ecm.svk):
row[COLUMN_STATE] = '%s' % INTERFER_STATE[ecm.svk]
@@ -159,7 +165,10 @@ func on_interfer_recommendate(ecm):
var sel_rows: Array
$table.get_selected_rows(sel_rows)
if not len(sel_rows): return
var row = sel_rows[0]
var sel_ecm = $table.get_node_user_data(0, sel_rows[0])
if ecm == sel_ecm:
signaller.emit_signal('interfer_selected', ecm)
func on_navi_data_received(data: Dictionary):
course = data.get('k', 0.0)

View File

@@ -89,7 +89,8 @@ func map_th_to_row(th) -> Array:
row.resize(TABLE_COLUMN_PARAM.size())
var i_col: int = 0
for param_name in TABLE_COLUMN_PARAM:
row[i_col] = '%s' % th.get(param_name)
var val = th.get(param_name)
row[i_col] = '%0.1f' % val if val is float else '%s' % val
i_col += 1
return row

View File

@@ -5,7 +5,7 @@
[node name="grd_btns" type="GridContainer"]
offset_right = 1096.0
offset_bottom = 54.0
columns = 16
columns = 15
[node name="btn_off" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
layout_mode = 2
@@ -14,7 +14,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "Откл."
disabled = true
font_size = 1
metadata/rfi_name = "off"
[node name="btn_p12" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -24,7 +23,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "МЧМ-1"
disabled = true
font_size = 1
metadata/rfi_name = "mchm1"
[node name="btn_p16" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -34,7 +32,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "СРН-И1"
disabled = true
font_size = 1
metadata/rfi_name = "srni1"
[node name="btn_p15" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -44,7 +41,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "СРН-М2"
disabled = true
font_size = 1
metadata/rfi_name = "srnm2"
[node name="btn_p18" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -54,7 +50,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "СРН-GPS"
disabled = true
font_size = 1
metadata/rfi_name = "srngps"
[node name="btn_p14" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -64,7 +59,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "ПД-М4"
disabled = true
font_size = 1
metadata/rfi_name = "pdm4"
[node name="btn_p13" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -74,7 +68,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "ПД-М2"
disabled = true
font_size = 1
metadata/rfi_name = "pdm2"
[node name="btn_p11" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -84,7 +77,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "ЛЧМ-1"
disabled = true
font_size = 1
metadata/rfi_name = "lchm1"
[node name="btn_p17" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -94,7 +86,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "ЛЧМ-2"
disabled = true
font_size = 1
metadata/rfi_name = "lchm2"
[node name="btn_p10" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -104,7 +95,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "ПД-М4С"
disabled = true
font_size = 1
metadata/rfi_name = "pdm4s"
[node name="btn_p9" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -114,7 +104,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "ПД-ЧМ"
disabled = true
font_size = 1
metadata/rfi_name = "pdchm"
[node name="btn_p8" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -124,7 +113,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "СВ-И1"
disabled = true
font_size = 1
metadata/rfi_name = "svi1"
[node name="btn_p7" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -134,7 +122,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "K1"
disabled = true
font_size = 1
metadata/rfi_name = "k1"
[node name="btn_p6" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -144,7 +131,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "СВ-М2"
disabled = true
font_size = 1
metadata/rfi_name = "svm2"
[node name="btn_p5" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -154,7 +140,6 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "ОЗП-1"
disabled = true
font_size = 1
metadata/rfi_name = "ozp1"
[node name="btn_p19" parent="." groups=["группа-режим-помехи"] instance=ExtResource("1_oy80h")]
@@ -164,5 +149,4 @@ size_flags_vertical = 3
strips_rotation = 30.0
text = "ЕПРЛС"
disabled = true
font_size = 1
metadata/rfi_name = "eprls"

View File

@@ -1,14 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://8ll27id5ajq1"]
[gd_scene load_steps=4 format=3 uid="uid://8ll27id5ajq1"]
[ext_resource type="Script" uid="uid://d0jwv5opi3mrl" path="res://scenes/pribor-afsp/pribor-afsp.gd" id="1_151rh"]
[ext_resource type="Script" uid="uid://bux47vkw71w1t" path="res://scenes/контроль/request.gd" id="2_4vyhj"]
[ext_resource type="PackedScene" uid="uid://dnxq870xf6pkh" path="res://scenes/контроль/bort-afsp.tscn" id="3_d7iti"]
[sub_resource type="GDScript" id="GDScript_yhnwg"]
script/source = "extends Timer
func _ready(): wait_time = ProjectSettings.get_setting('application/config/unit_rr_request_period')
"
[ext_resource type="PackedScene" uid="uid://dnxq870xf6pkh" path="res://scenes/pribor-afsp/bort-afsp.tscn" id="3_d7iti"]
[node name="pribor_afsp" type="Control"]
layout_mode = 3
@@ -19,17 +13,20 @@ offset_right = 70.0
offset_bottom = 30.0
scale = Vector2(1, 0.9)
script = ExtResource("1_151rh")
prefix_path = "DeviceDescription[DeviceName]"
this_afsp_name = "Устройство РР левого борта"
unit_name = &"уарэп-афсп-левый"
settings_path_to_url = "Адрес АФСП левого борта"
settings_path_to_wait_time = "Период опроса состояния АФСП, секунды"
metadata/DeviceName = &"Устройство РР левого борта"
[node name="request" type="HTTPRequest" parent="."]
use_threads = true
script = ExtResource("2_4vyhj")
projsettings_path_left = "application/config/Адрес АФСП левого борта"
projsettings_path_right = "application/config/Адрес АФСП правого борта"
request_url = null
[node name="timer" type="Timer" parent="request"]
autostart = true
script = SubResource("GDScript_yhnwg")
[node name="bort" parent="." instance=ExtResource("3_d7iti")]
layout_mode = 0

View File

@@ -1,14 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://5uv1idl3lqet"]
[gd_scene load_steps=4 format=3 uid="uid://5uv1idl3lqet"]
[ext_resource type="Script" uid="uid://d0jwv5opi3mrl" path="res://scenes/pribor-afsp/pribor-afsp.gd" id="1_tfses"]
[ext_resource type="Script" uid="uid://bux47vkw71w1t" path="res://scenes/контроль/request.gd" id="2_miwrd"]
[ext_resource type="PackedScene" uid="uid://dnxq870xf6pkh" path="res://scenes/контроль/bort-afsp.tscn" id="3_xpxb5"]
[sub_resource type="GDScript" id="GDScript_yhnwg"]
script/source = "extends Timer
func _ready(): wait_time = ProjectSettings.get_setting('application/config/unit_rr_request_period')
"
[ext_resource type="PackedScene" uid="uid://dnxq870xf6pkh" path="res://scenes/pribor-afsp/bort-afsp.tscn" id="3_xpxb5"]
[node name="pribor_afsp" type="Control"]
layout_mode = 3
@@ -19,17 +13,20 @@ offset_right = 81.0
offset_bottom = 108.0
scale = Vector2(1, 0.9)
script = ExtResource("1_tfses")
prefix_path = "DeviceDescription[DeviceName]"
this_afsp_name = "Устройство РР правого борта"
unit_name = &"уарэп-афсп-правый"
settings_path_to_url = "Адрес АФСП правого борта"
settings_path_to_wait_time = "Период опроса состояния АФСП, секунды"
metadata/DeviceName = &"Устройство РР правого борта"
[node name="request" type="HTTPRequest" parent="."]
use_threads = true
script = ExtResource("2_miwrd")
projsettings_path_left = "application/config/Адрес АФСП левого борта"
projsettings_path_right = "application/config/Адрес АФСП правого борта"
request_url = null
[node name="timer" type="Timer" parent="request"]
autostart = true
script = SubResource("GDScript_yhnwg")
[node name="bort" parent="." instance=ExtResource("3_xpxb5")]
layout_mode = 0

View File

@@ -1,26 +1,57 @@
@tool
class_name pribor_afsp extends 'res://scenes/контроль/прибор.gd'
@export var prefix_path: String = 'DeviceDescripton[DeviceName]'
@export var prefix_path: String = '' ## Должно быть в JSON
@export var this_afsp_name: String = '' ## Должно быть в JSON
@export var unit_name: StringName= '' ## Должно быть в settings.gd
@export var settings_path_to_url: String = '' ## Должно быть в ProjectSettings
@export var settings_path_to_wait_time: String = '' ## Должно быть в ProjectSettings
static var json_conv: JSON = JSON.new()
static var node_maper = load('res://scenes/контроль/node-maper.gd')
var ctrl_pos = 0
# SystemName: "gen" DevList - там состояние связи с генератором по кан шине
func _ready() -> void:
ProjectSettings.connect('settings_changed', on_settings_chaged)
on_settings_chaged()
func on_settings_chaged():
$request.request_url = ProjectSettings.get_setting('application/config/%s' % settings_path_to_url)
$request/timer.wait_time = float(ProjectSettings.get_setting('application/config/%s' % settings_path_to_wait_time))
tools.allways($request.request_url != null)
func _on_request_completed(result, _response_code, headers, body: PackedByteArray):
var unit_instance: = network.get_unit_instance(unit_name)
if result != 0:
var rs = $request.get_result_string(result)
log.error('\"%s\"' % rs)
if unit_instance.online:
unit_instance.online = false
unit_instance.emit_signal('line_changed', unit_instance)
return
var json_str: String = body.get_string_from_utf8()
if not json_str:
push_error('не удаётся получить строку utf8 из данных (%s)' % headers)
if unit_instance.online:
unit_instance.online = false
unit_instance.emit_signal('line_changed', unit_instance)
return
var rc = json_conv.parse(json_str)
var rc: = json_conv.parse(json_str)
if rc != Error.OK:
var err = json_conv.get_error_message()
var err: = json_conv.get_error_message()
push_error('разбор json прерван - \"%s\" (%s)' % [err, headers])
if unit_instance.online:
unit_instance.online = false
unit_instance.emit_signal('line_changed', unit_instance)
return
var pp = []
@@ -32,12 +63,18 @@ func _on_request_completed(result, _response_code, headers, body: PackedByteArra
push_error('путь %s не найден (%s)' % [pp_copy, ret_val[2]])
return
var this_afsp_name: StringName = $bort.get_meta('DeviceName', '')
var received_afsp_name: StringName = ret_val[0]
if this_afsp_name != received_afsp_name:
# TODO: Сюда попадаем, когда приходит от другого борта
#push_error('не известное устройство: \"%s\", ожидадось: \"%s\"' % [received_afsp_name, this_afsp_name])
return
unit_instance.rx_tick = Time.get_ticks_msec()
if not unit_instance.online:
unit_instance.online = true
unit_instance.emit_signal('line_changed', unit_instance)
for child in $bort.get_node('konverter/grid').get_children():
node_maper.map_value_to_item(json_conv.data, child, 'value0')
node_maper.map_value_to_item(json_conv.data, child, 'value1')
@@ -63,4 +100,3 @@ func _on_item_pressed(block_a: Control):
var metas = block_a.get_meta_list()
for n in metas:
var v = block_a.get_meta(n)
print_debug('%s:%s' % [n, v])

View File

@@ -1,29 +1,55 @@
@tool
class_name pribor_rtr extends 'res://scenes/контроль/прибор.gd'
@export var prefix_path: String = 'DeviceDescripton[DeviceName]'
@export var prefix_path: String = '' ## Должно быть в JSON
@export var this_bpo1_name: String = '' ## Должно быть в JSON
@export var this_bpo2_name: String = '' ## Должно быть в JSON
@export var unit_name1: StringName= '' ## Должно быть в settings.gd
@export var unit_name2: StringName= '' ## Должно быть в settings.gd
@export var settings_path1_to_url: String = '' ## Должно быть в ProjectSettings
@export var settings_path2_to_url: String = '' ## Должно быть в ProjectSettings
@export var settings_path_to_wait_time: String = '' ## Должно быть в ProjectSettings
static var json_conv: JSON = JSON.new()
static var node_maper = load('res://scenes/контроль/node-maper.gd')
var ctrl_pos = 110
const bort_to_node_name = {
'Устройство РР левого борта': 'grid_bpo_a1',
'Устройство РР правого борта': 'grid_bpo_a2'}
var bort_to_node_name = {}
var bort_to_unit_name = {}
func _ready() -> void:
ProjectSettings.connect('settings_changed', on_settings_changed)
on_settings_changed()
find_labels(self)
func on_settings_changed():
bort_to_node_name.merge({this_bpo1_name: 'grid_bpo_a1', this_bpo2_name: 'grid_bpo_a2'}, true)
bort_to_unit_name.merge({this_bpo1_name: unit_name1, this_bpo2_name: unit_name2})
$request1.request_url = ProjectSettings.get_setting('application/config/%s' % settings_path1_to_url)
$request1/timer.wait_time = float(ProjectSettings.get_setting('application/config/%s' % settings_path_to_wait_time))
$request2.request_url = ProjectSettings.get_setting('application/config/%s' % settings_path2_to_url)
$request2/timer.wait_time = float(ProjectSettings.get_setting('application/config/%s' % settings_path_to_wait_time))
assert($request1.request_url != null)
assert($request2.request_url != null)
func _on_request_completed(result, _response_code, headers, body: PackedByteArray):
if result != 0:
var rs = $request.get_result_string(result)
log.error('\"%s\"' % rs)
var rs = $request1.get_result_string(result)
push_error('\"%s\"' % rs)
return
var json_str: String = body.get_string_from_utf8()
var json_str: = body.get_string_from_utf8()
if not json_str:
push_error('не удаётся получить строку из utf8-данных (%s)' % headers)
return
var rc = json_conv.parse(json_str)
var rc: = json_conv.parse(json_str)
if rc != Error.OK:
var err = json_conv.get_error_message()
push_error('разбор json прерван - \"%s\" (%s)' % [err, headers])
@@ -39,10 +65,50 @@ func _on_request_completed(result, _response_code, headers, body: PackedByteArra
return
if not bort_to_node_name.has(ret_val[0]):
push_error('не известное устройство: \"%s\"' % ret_val[0])
return
var node_name = bort_to_node_name[ret_val[0]]
var bort_node = get_node(node_name)
var unit_name = bort_to_unit_name[ret_val[0]]
var unit_instance = network.get_unit_instance(unit_name)
unit_instance.rx_tick = Time.get_ticks_msec()
if not unit_instance.online:
unit_instance.online = true
unit_instance.emit_signal('line_changed', unit_instance)
for item in bort_node.get_children():
node_maper.map_value_to_item(json_conv.data, item, 'state')
var items = get_tree().get_nodes_in_group('управляется-по-шине-1')
for node in items:
if node.state == 1:
$yas_bpo_a1.state = 1
break
items = get_tree().get_nodes_in_group('управляется-по-шине-2')
for node in items:
if node.state == 1:
$yas_bpo_a2.state = 1
break
items = get_tree().get_nodes_in_group('потребитель-питания')
for node in items:
if node.state == 1:
$mod_pit_g1.state = 1
break
func find_labels(node1: Node):
if node1 is Label:
if node1.name in ["lbl_rname", "rname"]:
if not node1.has_meta("tooltip_set"):
ctrl_pos += 1
var box_number = ceili(float(ctrl_pos) / 10.0)
var position_number = ctrl_pos % 10
if position_number == 0:
position_number = 10
node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number]
node1.mouse_filter = Control.MOUSE_FILTER_STOP
node1.set_meta("tooltip_set", true)
for child in node1.get_children():
find_labels(child)

View File

@@ -13,6 +13,14 @@ offset_top = 150.0
offset_right = 115.0
offset_bottom = 150.0
script = ExtResource("1_bhc4e")
prefix_path = "DeviceDescription[DeviceName]"
this_bpo1_name = "Устройство БПО левого борта"
this_bpo2_name = "Устройство БПО правого борта"
unit_name1 = &"уарэп-бпо-1"
unit_name2 = &"уарэп-бпо-2"
settings_path1_to_url = "Адрес БПО левого борта"
settings_path2_to_url = "Адрес БПО правого борта"
settings_path_to_wait_time = "Период опроса состояния БПО, секунды"
[node name="mod_pit_g1" parent="." instance=ExtResource("2_jp6m0")]
layout_mode = 2
@@ -43,63 +51,63 @@ offset_right = 498.0
offset_bottom = 320.0
columns = 4
[node name="kanal1" parent="grid_bpo_a1" instance=ExtResource("2_jp6m0")]
[node name="kanal1" parent="grid_bpo_a1" groups=["потребитель-питания"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 1"
metadata/state = "SelfTest[0].SystemList[0].DevList[0]['TestPassed']"
[node name="kanal2" parent="grid_bpo_a1" instance=ExtResource("2_jp6m0")]
[node name="kanal2" parent="grid_bpo_a1" groups=["потребитель-питания", "управляется-по-шине-1"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 2"
metadata/state = "SelfTest[0].SystemList[0].DevList[1]['TestPassed']"
[node name="kanal3" parent="grid_bpo_a1" instance=ExtResource("2_jp6m0")]
[node name="kanal3" parent="grid_bpo_a1" groups=["потребитель-питания", "управляется-по-шине-1"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 3"
metadata/state = "SelfTest[0].SystemList[0].DevList[2]['TestPassed']"
[node name="kanal4" parent="grid_bpo_a1" instance=ExtResource("2_jp6m0")]
[node name="kanal4" parent="grid_bpo_a1" groups=["потребитель-питания", "управляется-по-шине-1"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 4"
metadata/state = "SelfTest[0].SystemList[0].DevList[3]['TestPassed']"
[node name="kanal5" parent="grid_bpo_a1" instance=ExtResource("2_jp6m0")]
[node name="kanal5" parent="grid_bpo_a1" groups=["потребитель-питания", "управляется-по-шине-1"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 5"
metadata/state = "SelfTest[0].SystemList[0].DevList[4]['TestPassed']"
[node name="kanal6" parent="grid_bpo_a1" instance=ExtResource("2_jp6m0")]
[node name="kanal6" parent="grid_bpo_a1" groups=["потребитель-питания", "управляется-по-шине-1"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 6"
metadata/state = "SelfTest[0].SystemList[0].DevList[5]['TestPassed']"
[node name="kanal7" parent="grid_bpo_a1" instance=ExtResource("2_jp6m0")]
[node name="kanal7" parent="grid_bpo_a1" groups=["потребитель-питания", "управляется-по-шине-1"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 7"
metadata/state = "SelfTest[0].SystemList[0].DevList[6]['TestPassed']"
[node name="kanal8" parent="grid_bpo_a1" instance=ExtResource("2_jp6m0")]
[node name="kanal8" parent="grid_bpo_a1" groups=["потребитель-питания", "управляется-по-шине-1"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 8"
metadata/state = "SelfTest[0].SystemList[0].DevList[7]['TestPassed']"
[node name="yas_bpo_a1" parent="." instance=ExtResource("3_jcpjs")]
[node name="yas_bpo_a1" parent="." groups=["потребитель-питания"] instance=ExtResource("3_jcpjs")]
offset_left = 500.0
offset_top = 175.0
offset_right = 550.0
@@ -126,63 +134,63 @@ offset_right = 498.0
offset_bottom = 520.0
columns = 4
[node name="kanal1" parent="grid_bpo_a2" instance=ExtResource("2_jp6m0")]
[node name="kanal1" parent="grid_bpo_a2" groups=["потребитель-питания", "управляется-по-шине-2"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 1"
metadata/state = "SelfTest[0].SystemList[0].DevList[0]['TestPassed']"
[node name="kanal2" parent="grid_bpo_a2" instance=ExtResource("2_jp6m0")]
[node name="kanal2" parent="grid_bpo_a2" groups=["потребитель-питания", "управляется-по-шине-2"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 2"
metadata/state = "SelfTest[0].SystemList[0].DevList[1]['TestPassed']"
[node name="kanal3" parent="grid_bpo_a2" instance=ExtResource("2_jp6m0")]
[node name="kanal3" parent="grid_bpo_a2" groups=["потребитель-питания", "управляется-по-шине-2"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 3"
metadata/state = "SelfTest[0].SystemList[0].DevList[2]['TestPassed']"
[node name="kanal4" parent="grid_bpo_a2" instance=ExtResource("2_jp6m0")]
[node name="kanal4" parent="grid_bpo_a2" groups=["потребитель-питания", "управляется-по-шине-2"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 4"
metadata/state = "SelfTest[0].SystemList[0].DevList[3]['TestPassed']"
[node name="kanal5" parent="grid_bpo_a2" instance=ExtResource("2_jp6m0")]
[node name="kanal5" parent="grid_bpo_a2" groups=["потребитель-питания", "управляется-по-шине-2"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 5"
metadata/state = "SelfTest[0].SystemList[0].DevList[4]['TestPassed']"
[node name="kanal6" parent="grid_bpo_a2" instance=ExtResource("2_jp6m0")]
[node name="kanal6" parent="grid_bpo_a2" groups=["потребитель-питания", "управляется-по-шине-2"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 6"
metadata/state = "SelfTest[0].SystemList[0].DevList[5]['TestPassed']"
[node name="kanal7" parent="grid_bpo_a2" instance=ExtResource("2_jp6m0")]
[node name="kanal7" parent="grid_bpo_a2" groups=["потребитель-питания", "управляется-по-шине-2"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 7"
metadata/state = "SelfTest[0].SystemList[0].DevList[6]['TestPassed']"
[node name="kanal8" parent="grid_bpo_a2" instance=ExtResource("2_jp6m0")]
[node name="kanal8" parent="grid_bpo_a2" groups=["потребитель-питания", "управляется-по-шине-2"] instance=ExtResource("2_jp6m0")]
layout_mode = 2
size_flags_horizontal = 7
size_flags_vertical = 7
fname = "Канал 8"
metadata/state = "SelfTest[0].SystemList[0].DevList[7]['TestPassed']"
[node name="yas_bpo_a2" parent="." instance=ExtResource("3_jcpjs")]
[node name="yas_bpo_a2" parent="." groups=["потребитель-питания"] instance=ExtResource("3_jcpjs")]
offset_left = 500.0
offset_top = 375.0
offset_right = 550.0
@@ -191,14 +199,22 @@ show_rname = false
self_size = Vector2i(50, 145)
fname = "Яч. связи"
[node name="request" type="HTTPRequest" parent="."]
[node name="request1" type="HTTPRequest" parent="."]
use_threads = true
script = ExtResource("4_crej3")
projsettings_path_left = "application/config/Адрес БПО левого борта"
projsettings_path_right = "application/config/Адрес БПО правого борта"
request_url = null
[node name="timer" type="Timer" parent="request"]
[node name="timer" type="Timer" parent="request1"]
autostart = true
[connection signal="request_completed" from="request" to="." method="_on_request_completed"]
[connection signal="timeout" from="request/timer" to="request" method="_on_request_timer"]
[node name="request2" type="HTTPRequest" parent="."]
use_threads = true
script = ExtResource("4_crej3")
[node name="timer" type="Timer" parent="request2"]
autostart = true
[connection signal="request_completed" from="request1" to="." method="_on_request_completed"]
[connection signal="timeout" from="request1/timer" to="request1" method="_on_request_timer"]
[connection signal="request_completed" from="request2" to="." method="_on_request_completed"]
[connection signal="timeout" from="request2/timer" to="request2" method="_on_request_timer"]

View File

@@ -15,10 +15,10 @@ const constants_k: Dictionary = {
'POWER_THRESHOLD': 40,
'RAY_DOU_NUM': 0x3,
'ATT_UM_1': 0x0,
'ATT_UM_6': 0x7,
'ATT_UM_7': 0x7,
'POWER_UM': 85,
'TIMER_DELAY': 5.0,
'ATT_UM_6': 0x3,
'ATT_UM_7': 0x2,
'POWER_UM': 100,
'TIMER_DELAY': 10.0,
'STATE_MASHINE_TIMER': 0.3,
}
# Конфигурация параметров для каждого прибора
@@ -55,9 +55,9 @@ var block_kasseta_y5_prd_config_k: = {
}
# Основные переменные
var start_litera: int = 1
var ug_work_1: int = 0
var ug_work_2: int = 0
var ug_work_3: int = 0
var ug_work_1: int = 3 ## Аттенюация усилителей мощности
var ug_work_2: int = 2 ## Аттенюация усилителей мощности
var ug_work_3: int = 0 ## Аттенюация усилителей мощности
var mashine_timer: Timer = Timer.new()
var prd_k_module: Object
var unit_prd_k: Object
@@ -77,6 +77,7 @@ var control_results_k: Dictionary = {
}
var test_control_k = preload('res://scripts/pribor-prd.gd')
var ctrl_pos = 30
func _ready() -> void:
@@ -86,6 +87,7 @@ func _ready() -> void:
initialize_connections()
setup_timer()
set_default_state()
find_labels(self)
func on_state_mashine() -> void:
@@ -166,7 +168,7 @@ func on_mode_changed(in_tree: bool) -> void:
mashine_timer.start()
func power_fill(pow_dic: Dictionary) -> void:
func power_fill(pow_dic: Dictionary, fs_result: Dictionary) -> void:
#if not control_prd_k.block_kasseta_y5_config.yau07 or not control_prd_k.block_kasseta_y5_config.ukp1 or not control_prd_k.block_kasseta_y5_config.ukp2:
#return
var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
@@ -179,6 +181,9 @@ func power_fill(pow_dic: Dictionary) -> void:
if pow_dic[powamp_meta].size() < 6:
status = STATE_VAL.ERROR
else:
if powamp_meta == 'um_7' and not fs_result.fs_1: return
if powamp_meta in ['um_1', 'um_2', 'um_3', 'um_4', 'um_5', 'um_6'] and not fs_result.fs_6: return
if powamp_meta in ['um_8', 'um_9', 'um_10', 'um_11', 'um_12', 'um_13'] and not fs_result.fs_7: return
i_powapm.value0 = pow_dic[powamp_meta]
for i_p in pow_dic[powamp_meta]:
if i_p < constants_k.POWER_THRESHOLD:
@@ -228,7 +233,7 @@ func on_control_result(result_dic: Dictionary, power_dic: Dictionary) -> void:
else:
result_dic.fs_7 = false
power_fill(power_dic)
power_fill(power_dic, result_dic)
var result = true
for device in result_dic.values():
@@ -242,3 +247,19 @@ func on_control_result(result_dic: Dictionary, power_dic: Dictionary) -> void:
else:
$control_result.text = 'Прибор ПРД-%s неисправен' % name_prd
$control_result.add_theme_color_override('font_color', Color.RED)
func find_labels(node1: Node):
if node1 is Label:
if node1.name in ["lbl_rname", "rname"]:
if not node1.has_meta("tooltip_set"):
ctrl_pos += 1
var box_number = ceili(float(ctrl_pos) / 10.0)
var position_number = ctrl_pos % 10
if position_number == 0:
position_number = 10
node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number]
node1.mouse_filter = Control.MOUSE_FILTER_STOP
node1.set_meta("tooltip_set", true)
for child in node1.get_children():
find_labels(child)

View File

@@ -13,10 +13,10 @@ const constants_n = {
'TEMP_THRESHOLD': 70,
'POWER_THRESHOLD': 40,
'RAY_DOU_NUM': 0x3,
'ATT_UM_2': 0x7,
'ATT_UM_3': 0x7,
'POWER_UM': 70,
'TIMER_DELAY': 5.0,
'ATT_UM_2': 0x2,
'ATT_UM_3': 0x3,
'POWER_UM': 100,
'TIMER_DELAY': 10.0,
'STATE_MASHINE_TIMER': 0.3,
}
# Конфигурация параметров для каждого прибора
@@ -50,8 +50,8 @@ var block_kasseta_y5_prd_config_n: = {
# Основные переменные
var start_litera: int = 2
var ug_work_1: int = 0
var ug_work_2: int = 0
var ug_work_1: int = 2 ## Аттенюация усилителей мощности
var ug_work_2: int = 3 ## Аттенюация усилителей мощности
# Флаги и таймеры
var mashine_timer: Timer = Timer.new()
var prd_n_module: Object
@@ -69,8 +69,7 @@ var control_results_n: Dictionary = {
'fs_3': 2,
}
var test_control_n = preload('res://scripts/pribor-prd.gd')
var ctrl_pos = 0
################################
func on_state_mashine() -> void:
control_prd_n.state_control_machine()
@@ -83,6 +82,7 @@ func _ready() -> void:
initialize_connections()
setup_timer()
set_default_state()
find_labels(self)
func initialize_connections() -> void:
@@ -159,7 +159,7 @@ func on_mode_changed(in_tree: bool) -> void:
mashine_timer.start()
func power_fill(pow_dic: Dictionary) -> void:
func power_fill(pow_dic: Dictionary, fs_result: Dictionary) -> void:
#if not control_prd_n.block_kasseta_y5_config.yau07 or not control_prd_n.block_kasseta_y5_config.ukp1 or not control_prd_n.block_kasseta_y5_config.ukp2:
#return
var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
@@ -169,6 +169,8 @@ func power_fill(pow_dic: Dictionary) -> void:
if pow_dic[powamp_meta].size() < 6:
status = STATE_VAL.ERROR
else:
if powamp_meta in ['um_1', 'um_2', 'um_3', 'um_4', 'um_5', 'um_6'] and not fs_result.fs_2: return
if powamp_meta in ['um_7', 'um_8', 'um_9', 'um_10', 'um_11', 'um_12'] and not fs_result.fs_3: return
i_powapm.value0 = pow_dic[powamp_meta]
for i_p in pow_dic[powamp_meta]:
if i_p < constants_n.POWER_THRESHOLD:
@@ -207,14 +209,14 @@ func on_control_result(result_dic: Dictionary, power_dic: Dictionary) -> void:
$kasseta_FS_ND/ref_A4.state = STATE_VAL.GOOD if result_dic.dkm_2 else STATE_VAL.ERROR
$dou2_A5.state = STATE_VAL.GOOD if result_dic.dou_2 else STATE_VAL.ERROR
else:
result_dic.fs_2 = false
result_dic.fs_2 = 0
if result_dic.fs_3 == 1:
$kasseta_FS_ND/ref_A3.state = STATE_VAL.GOOD if result_dic.dkm_3 else STATE_VAL.ERROR
$dou3_A6.state = STATE_VAL.GOOD if result_dic.dou_3 else STATE_VAL.ERROR
else:
result_dic.fs_3 = false
result_dic.fs_3 = 0
power_fill(power_dic)
power_fill(power_dic, result_dic)
var result = true
for device in result_dic.values():
@@ -228,3 +230,19 @@ func on_control_result(result_dic: Dictionary, power_dic: Dictionary) -> void:
else:
$control_result.text = 'Прибор ПРД-%s неисправен' % name_prd
$control_result.add_theme_color_override('font_color', Color.RED)
func find_labels(node1: Node):
if node1 is Label:
if node1.name in ["lbl_rname", "rname"]:
if not node1.has_meta("tooltip_set"):
ctrl_pos += 1
var box_number = ceili(float(ctrl_pos) / 10.0)
var position_number = ctrl_pos % 10
if position_number == 0:
position_number = 10
node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number]
node1.mouse_filter = Control.MOUSE_FILTER_STOP
node1.set_meta("tooltip_set", true)
for child in node1.get_children():
find_labels(child)

View File

@@ -13,10 +13,10 @@ const constants_v = {
'TEMP_THRESHOLD': 70,
'POWER_THRESHOLD': 40,
'RAY_DOU_NUM': 0x3,
'ATT_UM_4': 0x7,
'ATT_UM_5': 0x7,
'POWER_UM': 75,
'TIMER_DELAY': 5.0,
'ATT_UM_4': 0x2,
'ATT_UM_5': 0x3,
'POWER_UM': 100,
'TIMER_DELAY': 10.0,
'STATE_MASHINE_TIMER': 0.3,
}
# Конфигурация параметров для каждого прибора
@@ -50,8 +50,8 @@ var block_kasseta_y5_prd_config_v: = {
# Основные переменные
var start_litera: int = 4
var ug_work_1: int = 0
var ug_work_2: int = 0
var ug_work_1: int = 2 ## Аттенюация усилителей мощности
var ug_work_2: int = 3 ## Аттенюация усилителей мощности
# Флаги и таймеры
var mashine_timer: Timer = Timer.new()
var prd_v_module: Object
@@ -69,6 +69,7 @@ var control_results_v: Dictionary = {
'fs_5': 2,
}
var test_control_v = preload('res://scripts/pribor-prd.gd')
var ctrl_pos = 70
func on_state_mashine() -> void:
@@ -82,6 +83,7 @@ func _ready() -> void:
initialize_connections()
setup_timer()
set_default_state()
find_labels(self)
func initialize_connections() -> void:
@@ -159,9 +161,7 @@ func on_mode_changed(in_tree: bool) -> void:
mashine_timer.start()
func power_fill(pow_dic: Dictionary) -> void:
#if not control_prd_v.block_kasseta_y5_config.yau07 or not control_prd_v.block_kasseta_y5_config.ukp1 or not control_prd_v.block_kasseta_y5_config.ukp2:
#return
func power_fill(pow_dic: Dictionary, fs_result: Dictionary) -> void:
var power_amplifier: Array = get_tree().get_nodes_in_group('power_amplifier')
for i_powapm in power_amplifier:
var powamp_meta: String = i_powapm.get_meta('um')
@@ -169,6 +169,8 @@ func power_fill(pow_dic: Dictionary) -> void:
if pow_dic[powamp_meta].size() < 6:
status = STATE_VAL.ERROR
else:
if powamp_meta in ['um_1', 'um_2', 'um_3', 'um_4', 'um_5', 'um_6'] and not fs_result.fs_4: return
if powamp_meta in ['um_7', 'um_8', 'um_9', 'um_10', 'um_11', 'um_12'] and not fs_result.fs_5: return
i_powapm.value0 = pow_dic[powamp_meta]
for i_p in pow_dic[powamp_meta]:
if i_p < constants_v.POWER_THRESHOLD:
@@ -207,13 +209,13 @@ func on_control_result(result_dic: Dictionary, power_dic: Dictionary) -> void:
$kasseta_FS_VD/ref_A2.state = STATE_VAL.GOOD if result_dic.dkm_5 else STATE_VAL.ERROR
$dou5_A6.state = STATE_VAL.GOOD if result_dic.dou_5 else STATE_VAL.ERROR
else:
result_dic.fs_5 = false
result_dic.fs_5 = 0
if result_dic.fs_4 == 1:
$kasseta_FS_VD/ref_A6.state = STATE_VAL.GOOD if result_dic.dkm_4 else STATE_VAL.ERROR
$dou4_A5.state = STATE_VAL.GOOD if result_dic.dou_4 else STATE_VAL.ERROR
else:
result_dic.fs_4 = false
power_fill(power_dic)
result_dic.fs_4 = 0
power_fill(power_dic, result_dic)
var result = true
for device in result_dic.values():
@@ -227,3 +229,19 @@ func on_control_result(result_dic: Dictionary, power_dic: Dictionary) -> void:
else:
$control_result.text = 'Прибор ПРД-%s неисправен' % name_prd
$control_result.add_theme_color_override('font_color', Color.RED)
func find_labels(node1: Node):
if node1 is Label:
if node1.name in ["lbl_rname", "rname"]:
if not node1.has_meta("tooltip_set"):
ctrl_pos += 1
var box_number = ceili(float(ctrl_pos) / 10.0)
var position_number = ctrl_pos % 10
if position_number == 0:
position_number = 10
node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number]
node1.mouse_filter = Control.MOUSE_FILTER_STOP
node1.set_meta("tooltip_set", true)
for child in node1.get_children():
find_labels(child)

View File

@@ -5,18 +5,21 @@ enum STATE_VAL {NONE = 0, GOOD = 1, ERROR = 2}
const DEV_LIST = ['00:1f.6', '07:00.0', '08:00.0', '0b:00.0']
const USB_TRACKERBALL = '13ba:0018'
const REVFF = '(rev ff)'
var ctrl_pos = 100
func _ready() -> void:
if Engine.is_editor_hint():
return
var unit_uf = network.get_unit_instance('уарэп-эмс')
var unit_uf: = network.get_unit_instance('уарэп-эмс')
unit_uf.connect('line_changed', on_line_changed)
on_timer.bind(unit_uf)
control_vk()
on_line_changed(unit_uf)
find_labels(self)
func on_timer(unit_uf: unit.Unit):
func on_timer(unit_name: StringName):
var unit_uf = network.get_unit_instance(unit_name)
status_uf() # отслеживание состояния прибора
if unit_uf.online: # проверка ЯУ, внутреннего коммутатора и ИП-5Б
control_ems(unit_uf.status) # проверка ЭМС ячеек
@@ -73,6 +76,8 @@ func control_vk() -> void:
else:
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.ERROR
$ref_uf/ref_bu1/ref_A8_BU.state = STATE_VAL.GOOD ## заглушка для зеленения ВК-110
func control_ems(status: Array) -> void:
$ref_uf/ref_kassetav13/ref_A4_KEMS.state = STATE_VAL.GOOD if ((status[0] >> 0) & 1) and ((status[0] >> 3) & 1) else STATE_VAL.ERROR
@@ -98,3 +103,19 @@ func status_uf() -> void:
$lbl_header2.text = 'Прибор не исправен'
$lbl_header2.modulate = Color.RED
$lbl_header2.visible = true
func find_labels(node1: Node):
if node1 is Label:
if node1.name in ["lbl_rname", "rname"]:
if not node1.has_meta("tooltip_set"):
ctrl_pos += 1
var box_number = ceili(float(ctrl_pos) / 10.0)
var position_number = ctrl_pos % 10
if position_number == 0:
position_number = 10
node1.tooltip_text = "Ящик - %d, Позиция - %d" % [box_number, position_number]
node1.mouse_filter = Control.MOUSE_FILTER_STOP
node1.set_meta("tooltip_set", true)
for child in node1.get_children():
find_labels(child)

View File

@@ -155,3 +155,6 @@ horizontal_alignment = 1
vertical_alignment = 1
[node name="timer" type="Timer" parent="."]
autostart = true
[connection signal="timeout" from="timer" to="." method="on_timer" binds= [&"уарэп-эмс"]]

View File

@@ -33,6 +33,7 @@ offset_left = 88.0
offset_top = 319.0
offset_right = 343.0
offset_bottom = 749.0
tooltip_text = "Ящик - 11, Позиция - 3"
script = ExtResource("4_v0lil")
unit_name = "уарэп-спт25-1"
fname = "СПТ-25-230-400-3"
@@ -67,6 +68,7 @@ offset_left = 392.0
offset_top = 320.0
offset_right = 642.0
offset_bottom = 750.0
tooltip_text = "Ящик - 11, Позиция - 2"
script = ExtResource("4_v0lil")
unit_name = "уарэп-спт25-2"
fname = "СПТ-25-230-400-3"

View File

@@ -106,7 +106,7 @@ vertical_alignment = 1
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 6
tooltip_text = "Позиционное обозначение"
tooltip_text = "Ящик - 11, Позиция - 1"
mouse_filter = 0
theme_override_font_sizes/font_size = 22
horizontal_alignment = 2

View File

@@ -3,8 +3,8 @@
extends 'res://scenes/контроль/элемент-я.gd'
func on_line_changed(unit0):
if not unit0.online:
func on_line_changed(unit_instance):
if not unit_instance.online:
disable_all()

View File

@@ -0,0 +1,48 @@
extends Label
# Используем более понятные имена переменных
const STATUS_GOOD := {"text": "Исправно", "color": Color.GREEN, "font_color": Color.BLACK}
const STATUS_BAD := {"text": "Отказ", "color": Color.RED, "font_color": Color.WHITE}
var _is_uf_status_initialized: bool = false
var is_prd_operational: bool = true
var is_uf_operational: bool = false
func _ready() -> void:
tooltip_text = 'Нет связи с приборами комплекса'
for prd_module in prd.prd_dict.values():
prd_module.connect('update_serviceability', Callable(self, 'on_serviceability_changed').bind(prd_module))
var unit_uf: = network.get_unit_instance('уарэп-эмс')
unit_uf.connect('data_received', Callable(self, 'on_uf_status_receive'))
add_theme_color_override("font_color", Color.BLACK)
func on_serviceability_changed(unit_prd_module: Object) -> void:
var check_service: bool = true
for prd_module in prd.prd_dict.values():
if prd_module.unit_yau07.online:
if not unit_prd_module.serviceability:
check_service = false
if check_service != is_prd_operational:
is_prd_operational = check_service
_update_serviceability_display()
func _update_serviceability_display() -> void:
var status := STATUS_GOOD if (is_uf_operational and is_prd_operational) else STATUS_BAD
text = status.text
modulate = status.color
tooltip_text = 'Результаты обобщенного признака работоспособности изделия'
add_theme_color_override("font_color", status.font_color)
func on_uf_status_receive(unit_uf: Object) -> void:
var KEMS_B = ((unit_uf.status[0] >> 0) & 1) and ((unit_uf.status[0] >> 3) & 1)
var EMS_B_1 = ((unit_uf.status[0] >> 1) & 1) and ((unit_uf.status[0] >> 4) & 1)
var EMS_B_2 = ((unit_uf.status[0] >> 2) & 1) and ((unit_uf.status[0] >> 5) & 1)
var IP27B = ((unit_uf.status[2] >> 6) & 1)
var check_service: bool = KEMS_B and EMS_B_1 and EMS_B_2 and IP27B
if not _is_uf_status_initialized or check_service != is_uf_operational:
is_uf_operational = check_service
_update_serviceability_display()
signaller.emit_signal('update_uf_serviceability', check_service)
_is_uf_status_initialized = true

View File

@@ -0,0 +1 @@
uid://b5ykwyk5vpi6

View File

@@ -9,21 +9,17 @@ const TAB_TOSIGNAL_NAME = {
5: 'режим_настройки' }
func on_ems2_hide_pressed(state): set_tab_hidden(4, state)
func _on_tab_changed(tab) -> void: signaller.emit_signal(TAB_TOSIGNAL_NAME[tab])
func _on_button_trenazh_toggled(toggled_mode: bool) -> void: signaller.emit_signal('режим_тренаж', toggled_mode)
func _enter_tree() -> void:
network.logger_page = $Журнал
signaller.connect('ems2_hide_pressed', on_ems2_hide_pressed)
ProjectSettings.connect('settings_changed', on_setting_changed)
func on_ems2_hide_pressed(state):
set_tab_hidden(4, state)
func _on_tab_changed(tab) -> void:
if TAB_TOSIGNAL_NAME.has(tab):
signaller.emit_signal(TAB_TOSIGNAL_NAME[tab])
func on_setting_changed():
var ext_cu = ProjectSettings.get_setting('application/config/Внешнее управление', false)
get_parent().get_node('remote_control').visible = ext_cu

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=14 format=3 uid="uid://3slb0i3pvowc"]
[gd_scene load_steps=20 format=3 uid="uid://3slb0i3pvowc"]
[ext_resource type="Script" uid="uid://bvo6tcreqyuex" path="res://scenes/tabs-switch/tab-switch.gd" id="1_fg0vd"]
[ext_resource type="PackedScene" uid="uid://b276iygic5itk" path="res://scenes/работа/работа.tscn" id="2_u7p16"]
@@ -7,6 +7,8 @@
[ext_resource type="PackedScene" uid="uid://dab6loryocc73" path="res://scenes/эмс/эмс.tscn" id="5_u71bh"]
[ext_resource type="PackedScene" uid="uid://bnptm4rlp60dq" path="res://scenes/настройки/настройки.tscn" id="6_i8iv3"]
[ext_resource type="PackedScene" uid="uid://musb21x2u0xs" path="res://scenes/эмс2/эмс2.tscn" id="6_rsg03"]
[ext_resource type="Script" uid="uid://b5ykwyk5vpi6" path="res://scenes/tabs-switch/lbl_ready.gd" id="8_tidwt"]
[ext_resource type="Script" uid="uid://roajn6c6wvc1" path="res://scenes/tabs-switch/тренаж_режим.gd" id="9_41d34"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_tidwt"]
@@ -20,6 +22,17 @@
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o1r22"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nmdfd"]
bg_color = Color(0.061, 100, 0.051, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cw2ss"]
bg_color = Color(0.473976, 0.473976, 0.473976, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_41d34"]
bg_color = Color(0.39, 100, 0.327, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_imu1q"]
[node name="panel" type="Panel"]
offset_right = 1600.0
offset_bottom = 1200.0
@@ -56,7 +69,7 @@ visible = false
layout_mode = 2
metadata/_tab_index = 3
[node name="ЭМС2" parent="tab_switch" instance=ExtResource("6_rsg03")]
[node name="ЭМС ТГ" parent="tab_switch" instance=ExtResource("6_rsg03")]
visible = false
layout_mode = 2
metadata/_tab_index = 4
@@ -73,12 +86,13 @@ offset_right = 1600.0
offset_bottom = 27.0
tooltip_text = "Готовность аппаратуры к работе"
mouse_filter = 0
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_font_sizes/font_size = 14
theme_override_styles/normal = SubResource("StyleBoxFlat_o1r22")
text = "Исправно"
text = "Нет связи"
horizontal_alignment = 1
vertical_alignment = 1
script = ExtResource("8_tidwt")
metadata/_edit_lock_ = true
[node name="remote_control" type="Label" parent="."]
visible = false
@@ -95,4 +109,23 @@ text = "Внешнее управление"
horizontal_alignment = 1
vertical_alignment = 1
[node name="тренаж_режим" type="Button" parent="."]
layout_mode = 0
offset_left = 1404.0
offset_right = 1501.0
offset_bottom = 27.0
tooltip_text = "Задействовать режим Тренаж"
focus_mode = 0
theme_override_colors/font_hover_pressed_color = Color(0, 0, 0, 1)
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_colors/font_pressed_color = Color(0, 0, 0, 1)
theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_nmdfd")
theme_override_styles/hover = SubResource("StyleBoxFlat_cw2ss")
theme_override_styles/pressed = SubResource("StyleBoxFlat_41d34")
theme_override_styles/normal = SubResource("StyleBoxFlat_imu1q")
toggle_mode = true
text = "Тренаж"
script = ExtResource("9_41d34")
[connection signal="tab_changed" from="tab_switch" to="tab_switch" method="_on_tab_changed"]
[connection signal="toggled" from="тренаж_режим" to="tab_switch" method="_on_button_trenaj_toggled"]

View File

@@ -0,0 +1,11 @@
extends Button
func _ready():
connect("toggled", Callable(self, "_on_button_toggled"))
func _on_button_toggled(mode: bool):
if mode:
tooltip_text = "Режим \"Тренаж\" задействован\nТекущее состояние: включено"
else:
tooltip_text = "Задейстовать режим \"Тренаж\"\nТекущее состояние: отключено"

View File

@@ -0,0 +1 @@
uid://roajn6c6wvc1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -23,6 +23,8 @@ const TILE_REQUEST_NAME: = 'tile_request_%d'
@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
@export var show_ship_radius: bool = true
@export var ship_radius_km: float = 8.0
@onready var scale_label: String
@onready var coordinates_label: String
@onready var threat_mark: PackedScene = load("res://scenes/tilemap/threat.tscn")
@@ -34,6 +36,8 @@ var is_centered: = false
var is_out_border1: = true
var is_out_border2: = true
var threat_markers := {}
var zoom_timer: Timer
var zoom_action: String
@export var animation_time: float = 0.1:
set(val):
@@ -86,7 +90,6 @@ var image: = Image.new()
var image_load_proc: Callable
var now: = 0
var visible_marks_count: = 0
var map_server_available: = false
var border1: ImageTexture
var border2: ImageTexture
@@ -129,6 +132,12 @@ func _ready() -> void:
img.set_pixel(0, 1, Color.CORAL)
border2 = ImageTexture.create_from_image(img)
zoom_timer = Timer.new()
add_child(zoom_timer)
zoom_timer.one_shot = false
zoom_timer.wait_time = 0.1
zoom_timer.timeout.connect(_on_zoom_timeout)
_xyz.z = min_zoom_level
image_type = 'png'
$canvas.connect('mouse_entered', func(): _rollover = true)
@@ -152,7 +161,7 @@ func on_data_received(coords: Dictionary) -> void:
if not is_centered:
return
if coords.has_all(['latitude', 'longitude']):
set_coordinates(coords['longitude'], coords['latitude'])
set_coordinates(coords['longitude'], coords['latitude'], coords['k'])
func _on_resize() -> void:
@@ -252,6 +261,7 @@ func multiply_zoom(multiplier: float, pivot: Vector2) -> void:
var p2: = screen_to_world(_xyz, pivot)
_xyz.x -= p2.x - p1.x
_xyz.y -= p2.y - p1.y
update_scale_label()
func increment_zoom(increment: float, pivot: Vector2) -> void:
@@ -260,6 +270,7 @@ func increment_zoom(increment: float, pivot: Vector2) -> void:
var p2: = screen_to_world(_xyz, pivot)
_xyz.x -= p2.x - p1.x
_xyz.y -= p2.y - p1.y
update_scale_label()
func set_zoom(zoom: float, pivot: Vector2) -> void:
@@ -268,6 +279,7 @@ func set_zoom(zoom: float, pivot: Vector2) -> void:
var p2: = screen_to_world(_xyz, pivot)
_xyz.x -= p2.x - p1.x
_xyz.y -= p2.y - p1.y
update_scale_label()
func _draw() -> void:
@@ -302,6 +314,9 @@ func _draw() -> void:
if is_out_border2 and _dragging:
draw_texture_rect(border2, Rect2(p1, p2), false, Color.WHITE, false)
if should_draw_ship_radius():
draw_ship_radius()
func _clean_all() -> void:
_queue.clear()
@@ -366,21 +381,21 @@ func _process(delta) -> void:
func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile) -> void:
var unit_instance = network.get_unit_instance('уарэп-карта')
_req_count -= 1
remove_child(req)
req.queue_free()
if result != HTTPRequest.RESULT_SUCCESS:
if map_server_available:
map_server_available = false
emit_signal('map_server_offline')
if unit_instance.online:
unit_instance.online = false
unit_instance.emit_signal('line_changed', unit_instance)
_queue[tile.i] = tile
return
if not map_server_available:
map_server_available = true
emit_signal('map_server_online')
if not unit_instance.online:
unit_instance.online = true
unit_instance.emit_signal('line_changed', unit_instance)
if code == 404:
push_error('на сервере нет \"%s\"' % tile.url)
@@ -390,6 +405,11 @@ func _response(result, code, _headers: Array, body: PackedByteArray, req, tile:
push_error('не удалось получить изображение (неверный формат?) из \"%s\"' % tile.url)
return
unit_instance.rx_tick = Time.get_ticks_msec()
if not unit_instance.online:
unit_instance.online = true
unit_instance.emit_signal('line_changed', unit_instance)
tile.texture = ImageTexture.create_from_image(image)
_cache[tile.i] = tile
@@ -677,7 +697,7 @@ func clear() -> void:
queue_redraw()
func set_coordinates(lon: float, lat: float) -> void:
func set_coordinates(lon: float, lat: float, course: float) -> void:
var anim: Animation = $player.get_animation('goto')
var new_pos: Vector2 = lonlat_to_world(lon, lat)
anim.track_insert_key(0, 0, _xyz.x)
@@ -690,7 +710,8 @@ func set_coordinates(lon: float, lat: float) -> void:
ship_instance = ship_mark.instantiate()
add_mark_from_lon_lat(ship_id, lon, lat, ship_instance, 0.0)
else:
_marks[ship_id].position = lonlat_to_world(lon, lat)
ship_instance.position = lonlat_to_world(lon, lat)
ship_instance.rotation_degrees = course - 90
func blend_mask(val: bool) -> void:
@@ -699,7 +720,7 @@ func blend_mask(val: bool) -> void:
func update_coordinates_label(lon: float, lat: float) -> void:
coordinates_label = 'Координаты:\nNS:%f\nEW: %f' % [lat, lon]
coordinates_label = 'Координаты:\nNS:%f\nEW:%f' % [lat, lon]
signaller.emit_signal('update_coordinates_map', coordinates_label)
@@ -731,3 +752,80 @@ func _on_threat_lost(th) -> void:
var target = get_parent().get_node(str(th.id))
if target:
target.queue_free()
func zoom_in() -> void:
if _xyz.z >= max_zoom_level:
return
var center: Vector2 = $canvas.size / 2.0
increment_zoom(zoom_step, center)
queue_redraw()
func zoom_out() -> void:
if _xyz.z <= min_zoom_level:
return
var center: Vector2 = $canvas.size / 2.0
increment_zoom(-zoom_step, center)
queue_redraw()
func _on_zoom_plus_button_down() -> void:
zoom_action = "in"
perform_zoom()
zoom_timer.start(0.3)
func _on_zoom_minus_button_down() -> void:
zoom_action = "out"
perform_zoom()
zoom_timer.start(0.3)
func _on_zoom_button_up() -> void:
zoom_action = ""
zoom_timer.stop()
func _on_zoom_timeout():
perform_zoom()
zoom_timer.wait_time = 0.1
func perform_zoom():
if zoom_action != "":
if zoom_action == "in":
zoom_in()
else:
zoom_out()
update_scale_label()
# Вычисление для радиуса в мировых координатах
func get_ship_radius_world() -> float:
if not _marks.has(ship_id):
return 0.0
var ship_world_pos = _marks[ship_id].position
var ship_lonlat = world_to_lonlat(ship_world_pos.x, ship_world_pos.y)
var earth_radius_km = 6371.0
var distance_deg = (ship_radius_km / earth_radius_km) * (180.0 / PI) / cos(deg_to_rad(ship_lonlat.y))
var east_lon = ship_lonlat.x + distance_deg
var east_point_world = lonlat_to_world(east_lon, ship_lonlat.y)
return abs(east_point_world.x - ship_world_pos.x)
func should_draw_ship_radius() -> bool:
if not show_ship_radius or not _marks.has(ship_id):
return false
return _xyz.z >= 11
func draw_ship_radius() -> void:
var ship_world_pos = _marks[ship_id].position
var ship_screen_pos = world_to_screen(ship_world_pos)
var radius_world = get_ship_radius_world()
var radius_point_world = Vector2(ship_world_pos.x + radius_world, ship_world_pos.y)
var radius_point_screen = world_to_screen(radius_point_world)
var radius_screen = ship_screen_pos.distance_to(radius_point_screen)
#draw_arc(ship_screen_pos, radius_screen, 0, TAU, 64, Color.ORANGE, 2.0) # отрисовка контура
draw_circle(ship_screen_pos, radius_screen, Color.ORANGE_RED * Color(1, 1, 1, 0.1)) # отрисовка заливки

View File

@@ -7,6 +7,7 @@ func on_threats_changed(th: Object, msg: String): log.message(Logger.INFO, '%s:
func on_parse_error(unit_inst, msg: String): log.message(Logger.ERROR, '%s: %s' % [unit_inst.name, msg])
func on_interfer_off(ecm, msg: String): log.message(Logger.INFO, '%s: %s' % [msg, ecm.to_string()])
func on_set_program_mode(msg: String): log.message(Logger.INFO, msg)
func on_mode_trenazh(val: bool): log.message(Logger.INFO, 'Режим \"Тренаж\" %s' % ['отменён', 'задейсвован'][int(val)])
func on_interfer_new(ecm, msg: String):
if ecm.krp != interfer.INTERFER_OFF:
@@ -33,6 +34,7 @@ func _ready() -> void:
signaller.conn(signaller.режим_эмс, Callable(log, 'info').bind('Программа в режиме \"ЭМС\"'))
signaller.conn(signaller.режимурнал, Callable(log, 'info').bind('Программа в режиме \"Журнал\"'))
signaller.conn(signaller.режимонтроль, Callable(log, 'info').bind('Программа в режиме \"Контроль\"'))
signaller.conn(signaller.режимренаж, Callable(self, 'on_mode_trenazh'))
func _on_clear_button_down() -> void:

View File

@@ -36,6 +36,7 @@ colors = {
8: Color(0.91, 0, 0, 1),
16: Color(0.868077, 0.247988, 0.62812, 1)
}
max_lines_count = 256
[node name="btn_save" type="Button" parent="."]
layout_mode = 0
@@ -112,6 +113,12 @@ button_pressed = true
text = "Контроль"
metadata/filter = "Контроль"
[node name="CheckBox_SCROLL" type="CheckBox" parent="filtrs"]
layout_mode = 2
button_pressed = true
text = "Прокручивать до конца"
metadata/filter = "Контроль"
[connection signal="button_down" from="btn_save" to="." method="_on_btn_save_button_down"]
[connection signal="button_down" from="btn_clear" to="." method="_on_clear_button_down" flags=3]
[connection signal="canceled" from="dlg_file" to="." method="_on_dlg_file_confirmed"]
@@ -124,3 +131,4 @@ metadata/filter = "Контроль"
[connection signal="pressed" from="filtrs/CheckBox_FATAL" to="." method="_on_check_box_pressed"]
[connection signal="pressed" from="filtrs/CheckBox_THREAT" to="." method="_on_check_box_pressed"]
[connection signal="pressed" from="filtrs/CheckBox_CONTROL" to="." method="_on_check_box_pressed"]
[connection signal="toggled" from="filtrs/CheckBox_SCROLL" to="content" method="_on_check_box_scroll_toggled"]

View File

@@ -19,32 +19,16 @@ const RESULT_STRINGS = {
RESULT_TIMEOUT: 'Время истекло' }
@export var projsettings_path_left: String = ''
@export var projsettings_path_right: String = ''
var i_bort: int = 0
var addr_left: String
var addr_right: String
func on_settings_changed():
addr_left = ProjectSettings.get_setting(projsettings_path_left)
addr_right = ProjectSettings.get_setting(projsettings_path_right)
@export var request_url: String = ''
func get_result_string(result: Result):
return RESULT_STRINGS[result] if RESULT_STRINGS.has(result) else '<неизвестный код результата HTTPRequest - %d>' % result
func _ready():
ProjectSettings.connect('settings_changed', on_settings_changed)
on_settings_changed()
func _on_request_timer():
var addr = [addr_left, addr_right][i_bort]
var rc = request(addr)
if HTTPClient.Status.STATUS_DISCONNECTED != get_http_client_status():
return
var rc: = request(request_url)
if rc != Error.OK:
var s: String = '%s: %s' % [error_string(rc), addr]
log.error('ошибка: %s' % s)
i_bort = (i_bort + 1) % 2
push_error('%s: \"%s\"' % [error_string(rc), request_url])

View File

@@ -36,7 +36,6 @@ signal pressed(control: PanelContainer)
return
$margin/vbox/grid1/level7.value = v
$margin/vbox/grid1/level7.tint_progress = Color.RED if v > 70 else Color.WHITE
@export var min_value0: float:
@@ -141,16 +140,16 @@ signal pressed(control: PanelContainer)
func _on_button_pressed(): emit_signal('pressed', self)
func _enter_tree() -> void: call_deferred('_enter_tree_defered')
func set_value0(value: Array): value0.assign(value)
func _enter_tree() -> void: call_deferred('_enter_tree_defered')
func _ready():
var items: Array= get_level_nodes()
var items: Array = get_level_nodes()
for item in items:
item.connect('value_changed', on_level_changed.bind(item, value1_info))
item.connect('value_changed', on_level_changed.bind(item, value0_info))
on_level_changed(item.value, item, value0_info)
var level7 = $margin/vbox/grid1/level7
var level7: = $margin/vbox/grid1/level7
level7.connect('value_changed', on_level_changed.bind(level7, value1_info))
on_level_changed(level7.value, level7, value1_info)
@@ -225,11 +224,10 @@ func get_name_nodes() -> Array:
func set_value0_animated(target_node, target_value: float) -> void:
var tween = create_tween()
var tween: Tween = create_tween()
tween.set_ease(Tween.EASE_OUT)
tween.set_trans(Tween.TRANS_QUINT)
tween.tween_property(target_node, \"value\", target_value, animation_duration)
tween.tween_property(target_node, 'value', target_value, animation_duration)
"
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_rceim"]

View File

@@ -1,6 +1,6 @@
@tool
extends Node
extends TextureButton
@export var state_colors: Array

View File

@@ -25,63 +25,99 @@ script/source = "extends Panel
#TODO: рефактор: заменить подчёркивание на тире
const PRIBORS_RES = \\
{
'pribor_prd_k_1': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 1'],
'pribor_prd_k_2': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 2'],
'pribor_prd_k_3': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 3'],
'pribor_prd_k_4': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 4'],
'pribor_prd_n_1': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 1'],
'pribor_prd_n_2': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 2'],
'pribor_prd_n_3': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 3'],
'pribor_prd_n_4': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 4'],
'pribor_prd_v_1': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 1'],
'pribor_prd_v_2': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 2'],
'pribor_prd_v_3': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 3'],
'pribor_prd_v_4': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 4'],
'pribor_rtr': ['res://scenes/pribor-afsp/pribor-bpo.tscn', 'Контроль исправности прибора РТР'],
'pribor_afsp_1': ['res://scenes/pribor-afsp/pribor-afsp-1.tscn', 'Контроль исправности прибора АФСП 1'],
'pribor_afsp_2': ['res://scenes/pribor-afsp/pribor-afsp-2.tscn', 'Контроль исправности прибора АФСП 2'],
'pribor_uf': ['res://scenes/pribor-uf/pribor-uf.tscn', 'Контроль исправности прибора УФ'],
'pribor_uyep': ['res://scenes/pribor-uyep/pribor-uyep.tscn', 'Контроль исправности устройства У-ЭП'],
'pribor_prd_k_1': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 1'],
'pribor_prd_k_2': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 2'],
'pribor_prd_k_3': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 3'],
'pribor_prd_k_4': ['res://scenes/pribor-prd-k/pribor-prd-k.tscn', 'Контроль исправности прибора ПРД-К 4'],
'pribor_prd_n_1': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 1'],
'pribor_prd_n_2': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 2'],
'pribor_prd_n_3': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 3'],
'pribor_prd_n_4': ['res://scenes/pribor-prd-n/pribor-prd-n.tscn', 'Контроль исправности прибора ПРД-Н 4'],
'pribor_prd_v_1': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 1'],
'pribor_prd_v_2': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 2'],
'pribor_prd_v_3': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 3'],
'pribor_prd_v_4': ['res://scenes/pribor-prd-v/pribor-prd-v.tscn', 'Контроль исправности прибора ПРД-В 4'],
'pribor_rtr': ['res://scenes/pribor-afsp/pribor-bpo.tscn', 'Контроль исправности прибора РТР'],
'pribor_afsp_1': ['res://scenes/pribor-afsp/pribor-afsp-1.tscn', 'Контроль исправности прибора АФСП 1'],
'pribor_afsp_2': ['res://scenes/pribor-afsp/pribor-afsp-2.tscn', 'Контроль исправности прибора АФСП 2'],
'pribor_uf': ['res://scenes/pribor-uf/pribor-uf.tscn', 'Контроль исправности прибора УФ'],
'pribor_uyep': ['res://scenes/pribor-uyep/pribor-uyep.tscn', 'Контроль исправности устройства У-ЭП'],
}
func on_line_changed(u, conn_node, _pribor_meta): conn_node.set_val(u.online)
func on_serv_changed(u, pribor_node, _pribor_meta): pribor_node.state = int(u.serviceability)
func on_mode_changed():
clean_pribor_items()
reset_pribor_buttons()
func reset_pribor_buttons():
var pribor_buttons: = get_tree().get_nodes_in_group('pribor_buttons')
for node in pribor_buttons:
node.button_pressed = false
func _ready():
var group = ButtonGroup.new()
# Кнопки приборов, по нажатию на которые отображаеся мнемосхема
for k in PRIBORS_RES:
var pribor_node = get_node(k)
var pribor_node: Node = get_node(k)
var pribor_path = PRIBORS_RES[k][0]
var header_text = PRIBORS_RES[k][1]
pribor_node.set_button_group(group)
pribor_node.connect('button_down', Callable(self, 'on_pribor_press').bind(pribor_path, header_text, pribor_node))
var conn_node = pribor_node.get_node('connect_pribor')
var pribor_meta = pribor_node.get_meta('unit_name', [])
var unit_names = pribor_node.get_meta('unit_name', [])
var pribor_proc = pribor_node.get_meta('online_proc', '')
if pribor_proc == '':
continue
if pribor_meta.size():
for i in pribor_meta.size():
var unit_pribor = network.get_unit_instance(pribor_meta[i])
unit_pribor.connect('line_changed', Callable(self, pribor_proc).bind(conn_node, pribor_meta))
if not unit_names.size():
continue
for i in unit_names.size():
var unit_instance: = network.get_unit_instance(unit_names[i])
unit_instance.connect('line_changed', Callable(self, pribor_proc).bind(conn_node, unit_names))
for item in unit_names:
if prd.prd_dict.has(item):
var prd_module = prd.prd_dict[item]
prd_module.connect('update_serviceability', Callable(self, 'on_serviceability_changed').bind(prd_module, pribor_node))
if item == 'уарэп-эмс':
signaller.connect('update_uf_serviceability', Callable(self, 'on_update_uf_serviceability').bind(pribor_node))
# Пиктограммы приборов, которые отображают состояние подключения только
for pribor_node in get_tree().get_nodes_in_group('pribor_pics'):
var unit_name = pribor_node.get_meta('unit_name')
var unit_instance: = network.get_unit_instance(unit_name)
var conn_node: = pribor_node.get_node('connect_pribor')
unit_instance.connect('line_changed', on_line_changed.bind(conn_node, unit_name))
signaller.conn(signaller.режим_работа, on_mode_changed)
signaller.conn(signaller.режим_журнал, on_mode_changed)
signaller.conn(signaller.режим_настройки, on_mode_changed)
signaller.conn(signaller.режим_эмс, on_mode_changed)
func online_change_arr(_u, conn_node, pribor_meta):
var state_online = true
for i in pribor_meta.size():
var unit_pribor = network.get_unit_instance(pribor_meta[i])
if not unit_pribor.online:
state_online = false
var state_online: = false
for meta in pribor_meta:
var unit_pribor = network.get_unit_instance(meta)
if unit_pribor.online:
state_online = true
break
conn_node.set_val(state_online)
func on_pribor_press(pribor_path, header_text, pribor_node):
func clean_pribor_items():
var items = get_tree().get_nodes_in_group('pribor_items')
for item in items:
remove_child(item)
item.queue_free()
func on_pribor_press(pribor_path, header_text, pribor_node):
clean_pribor_items()
var pribor_obj = load(pribor_path)
if not pribor_obj:
push_error('не загружено: \\\"%s\\\" (%s)' % [pribor_path, header_text])
@@ -97,6 +133,18 @@ func on_pribor_press(pribor_path, header_text, pribor_node):
pribor.set_meta('unit_name', unit_name)
pribor.add_to_group('pribor_items')
add_child(pribor)
func on_serviceability_changed(prd_module: Object, prd_pribor:Node)-> void:
if not prd_module.unit_yau07.online:
prd_pribor.state = 0
return
prd_pribor.state = 1 if prd_module.serviceability else 2
func on_update_uf_serviceability(uf_serviceaability: bool, uf_pribor: Node)-> void:
uf_pribor.state = 1 if uf_serviceaability else 2
"
[sub_resource type="SpriteFrames" id="SpriteFrames_foasq"]
@@ -122,7 +170,7 @@ grow_vertical = 2
script = SubResource("GDScript_iqgf5")
metadata/_edit_lock_ = true
[node name="capsrpb" type="TextureRect" parent="."]
[node name="capsrpb" type="TextureRect" parent="." groups=["pribor_pics"]]
editor_description = "Кнопка для отображения внешних соединений."
self_modulate = Color(0.788235, 0.788235, 0.788235, 1)
layout_mode = 0
@@ -136,6 +184,7 @@ size_flags_vertical = 15
texture = ExtResource("2_oysma")
script = ExtResource("2_8r80x")
unit_name = &"уарэп-капсрпб"
metadata/unit_name = &"уарэп-капсрпб"
[node name="label" type="Label" parent="capsrpb"]
layout_mode = 0
@@ -155,7 +204,7 @@ scale = Vector2(2.6, 2.6)
sprite_frames = SubResource("SpriteFrames_foasq")
script = ExtResource("11_u7tym")
[node name="5p28" type="TextureRect" parent="."]
[node name="5p28" type="TextureRect" parent="." groups=["pribor_pics"]]
editor_description = "Кнопка для отображения внешних соединений."
self_modulate = Color(0.788235, 0.788235, 0.788235, 1)
layout_mode = 0
@@ -169,6 +218,7 @@ size_flags_vertical = 15
texture = ExtResource("2_oysma")
script = ExtResource("2_8r80x")
unit_name = &"уарэп-5п28"
metadata/unit_name = &"уарэп-5п28"
[node name="label" type="Label" parent="5p28"]
layout_mode = 0
@@ -189,7 +239,7 @@ sprite_frames = SubResource("SpriteFrames_foasq")
frame_progress = 0.72355
script = ExtResource("11_u7tym")
[node name="akng" type="TextureRect" parent="."]
[node name="akng" type="TextureRect" parent="." groups=["pribor_pics"]]
editor_description = "Кнопка для отображения внешних соединений."
self_modulate = Color(0.788235, 0.788235, 0.788235, 1)
layout_mode = 0
@@ -203,6 +253,7 @@ size_flags_vertical = 15
texture = ExtResource("2_oysma")
script = ExtResource("2_8r80x")
unit_name = &"навигация"
metadata/unit_name = &"навигация"
[node name="label" type="Label" parent="akng"]
layout_mode = 0
@@ -223,7 +274,7 @@ sprite_frames = SubResource("SpriteFrames_foasq")
frame_progress = 0.72355
script = ExtResource("11_u7tym")
[node name="maps" type="TextureRect" parent="."]
[node name="maps" type="TextureRect" parent="." groups=["pribor_pics"]]
editor_description = "Кнопка для отображения внешних соединений."
self_modulate = Color(0.788235, 0.788235, 0.788235, 1)
layout_mode = 0
@@ -236,7 +287,8 @@ size_flags_horizontal = 15
size_flags_vertical = 15
texture = ExtResource("2_oysma")
script = ExtResource("2_8r80x")
unit_name = &"навигация"
unit_name = &"уарэп-карта"
metadata/unit_name = &"уарэп-карта"
[node name="label" type="Label" parent="maps"]
layout_mode = 0
@@ -257,7 +309,7 @@ sprite_frames = SubResource("SpriteFrames_foasq")
frame_progress = 0.72355
script = ExtResource("11_u7tym")
[node name="trassa" type="TextureRect" parent="."]
[node name="trassa" type="TextureRect" parent="." groups=["pribor_pics"]]
editor_description = "Кнопка для отображения внешних соединений."
self_modulate = Color(0.788235, 0.788235, 0.788235, 1)
layout_mode = 0
@@ -271,6 +323,7 @@ size_flags_vertical = 15
texture = ExtResource("2_oysma")
script = ExtResource("2_8r80x")
unit_name = &"уарэп-трасса"
metadata/unit_name = &"уарэп-трасса"
[node name="label" type="Label" parent="trassa"]
layout_mode = 0
@@ -291,6 +344,58 @@ sprite_frames = SubResource("SpriteFrames_foasq")
frame_progress = 0.72355
script = ExtResource("11_u7tym")
[node name="pribor_prd_n_1" type="TextureButton" parent="." groups=["pribor_buttons"]]
editor_description = "Кнопка для выбора прибора."
layout_mode = 0
offset_left = 1048.0
offset_top = 193.0
offset_right = 1125.0
offset_bottom = 309.0
size_flags_horizontal = 15
size_flags_vertical = 15
toggle_mode = true
action_mode = 0
texture_normal = ExtResource("6_i1yfn")
stretch_mode = 4
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
metadata/online_proc = "on_line_changed"
metadata/unit_name = ["уарэп-яу07-1н"]
[node name="label" type="Label" parent="pribor_prd_n_1"]
layout_mode = 0
offset_left = 8.0
offset_top = -38.0
offset_right = 60.0
offset_bottom = -19.0
text = "ПРД Н1"
horizontal_alignment = 1
vertical_alignment = 1
[node name="frame" type="NinePatchRect" parent="pribor_prd_n_1"]
visible = false
self_modulate = Color(0.890196, 0.486275, 0.196078, 1)
layout_mode = 0
offset_left = -10.0
offset_top = -24.0
offset_right = 95.0
offset_bottom = 126.0
texture = ExtResource("4_rasbe")
region_rect = Rect2(-3, -3, 89, 89)
patch_margin_left = 16
patch_margin_top = 16
patch_margin_right = 16
patch_margin_bottom = 16
[node name="connect_pribor" type="AnimatedSprite2D" parent="pribor_prd_n_1"]
light_mask = 3
position = Vector2(35, -10)
scale = Vector2(0.625, 0.625)
sprite_frames = SubResource("SpriteFrames_foasq")
frame_progress = 0.72355
script = ExtResource("11_u7tym")
[node name="pribor_uf" type="TextureButton" parent="." groups=["pribor_buttons"]]
editor_description = "Кнопка для выбора прибора."
layout_mode = 0
@@ -305,7 +410,8 @@ action_mode = 0
texture_normal = ExtResource("2_0nvm1")
stretch_mode = 0
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.74, 0.37, 1), Color(0.854902, 0.0705882, 0.0705882, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
state = 1
metadata/unit_name = ["уарэп-эмс"]
metadata/online_proc = "on_line_changed"
@@ -321,6 +427,7 @@ vertical_alignment = 1
[node name="frame" type="NinePatchRect" parent="pribor_uf"]
visible = false
self_modulate = Color(0.890196, 0.486275, 0.196078, 1)
layout_mode = 0
offset_left = -14.0
offset_top = -30.0
@@ -356,7 +463,9 @@ action_mode = 0
texture_normal = ExtResource("3_hhadv")
stretch_mode = 0
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = [&"уарэп-бпо-1", &"уарэп-бпо-2"]
metadata/online_proc = "online_change_arr"
[node name="label" type="Label" parent="pribor_rtr"]
layout_mode = 0
@@ -417,7 +526,9 @@ action_mode = 0
texture_normal = ExtResource("9_iqgf5")
stretch_mode = 0
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = [&"уарэп-афсп-левый"]
metadata/online_proc = "on_line_changed"
[node name="label" type="Label" parent="pribor_afsp_1"]
layout_mode = 0
@@ -482,7 +593,9 @@ texture_normal = ExtResource("9_iqgf5")
stretch_mode = 0
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = [&"уарэп-афсп-правый"]
metadata/online_proc = "on_line_changed"
[node name="label" type="Label" parent="pribor_afsp_2"]
layout_mode = 0
@@ -544,7 +657,7 @@ action_mode = 0
texture_normal = ExtResource("5_kvnex")
stretch_mode = 0
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = ["уарэп-щ3", "уарэп-спт25-1", "уарэп-спт25-2"]
metadata/online_proc = "online_change_arr"
@@ -596,7 +709,7 @@ texture_normal = ExtResource("6_i1yfn")
stretch_mode = 4
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = ["уарэп-яу07-2в"]
metadata/online_proc = "on_line_changed"
@@ -648,7 +761,7 @@ texture_normal = ExtResource("6_i1yfn")
stretch_mode = 4
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = ["уарэп-яу07-2н"]
metadata/online_proc = "on_line_changed"
@@ -702,7 +815,7 @@ texture_normal = ExtResource("6_i1yfn")
stretch_mode = 4
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = ["уарэп-яу07-2к"]
metadata/online_proc = "on_line_changed"
@@ -754,7 +867,7 @@ texture_normal = ExtResource("6_i1yfn")
stretch_mode = 4
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = ["уарэп-яу07-3в"]
metadata/online_proc = "on_line_changed"
@@ -806,7 +919,7 @@ texture_normal = ExtResource("6_i1yfn")
stretch_mode = 4
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = ["уарэп-яу07-3н"]
metadata/online_proc = "on_line_changed"
@@ -858,7 +971,7 @@ texture_normal = ExtResource("6_i1yfn")
stretch_mode = 4
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
state_colors = [Color(1, 1, 1, 1), Color(0, 1, 0, 1), Color(1, 0, 0, 1)]
metadata/unit_name = ["уарэп-яу07-3к"]
metadata/online_proc = "on_line_changed"
@@ -947,58 +1060,6 @@ sprite_frames = SubResource("SpriteFrames_foasq")
frame_progress = 0.72355
script = ExtResource("11_u7tym")
[node name="pribor_prd_n_1" type="TextureButton" parent="." groups=["pribor_buttons"]]
editor_description = "Кнопка для выбора прибора."
layout_mode = 0
offset_left = 1048.0
offset_top = 193.0
offset_right = 1125.0
offset_bottom = 309.0
size_flags_horizontal = 15
size_flags_vertical = 15
toggle_mode = true
action_mode = 0
texture_normal = ExtResource("6_i1yfn")
stretch_mode = 4
flip_h = true
script = ExtResource("3_4pt7j")
state_colors = [Color(1, 1, 1, 1), Color(0, 0.87, 0, 1), Color(0.65, 0.0715, 0.0715, 1)]
metadata/online_proc = "on_line_changed"
metadata/unit_name = ["уарэп-яу07-1н"]
[node name="label" type="Label" parent="pribor_prd_n_1"]
layout_mode = 0
offset_left = 8.0
offset_top = -38.0
offset_right = 60.0
offset_bottom = -19.0
text = "ПРД Н1"
horizontal_alignment = 1
vertical_alignment = 1
[node name="frame" type="NinePatchRect" parent="pribor_prd_n_1"]
visible = false
self_modulate = Color(0.890196, 0.486275, 0.196078, 1)
layout_mode = 0
offset_left = -10.0
offset_top = -24.0
offset_right = 95.0
offset_bottom = 126.0
texture = ExtResource("4_rasbe")
region_rect = Rect2(-3, -3, 89, 89)
patch_margin_left = 16
patch_margin_top = 16
patch_margin_right = 16
patch_margin_bottom = 16
[node name="connect_pribor" type="AnimatedSprite2D" parent="pribor_prd_n_1"]
light_mask = 3
position = Vector2(35, -10)
scale = Vector2(0.625, 0.625)
sprite_frames = SubResource("SpriteFrames_foasq")
frame_progress = 0.72355
script = ExtResource("11_u7tym")
[node name="pribor_prd_k_1" type="TextureButton" parent="." groups=["pribor_buttons"]]
editor_description = "Кнопка для выбора прибора."
layout_mode = 0
@@ -1325,6 +1386,7 @@ points = PackedVector2Array(-8, 0, 608, 0)
width = 2.0
default_color = Color(1, 1, 1, 0.352941)
[connection signal="toggled" from="pribor_prd_n_1" to="pribor_prd_n_1" method="_on_toggled"]
[connection signal="toggled" from="pribor_uf" to="pribor_uf" method="_on_toggled"]
[connection signal="toggled" from="pribor_rtr" to="pribor_rtr" method="_on_toggled"]
[connection signal="toggled" from="pribor_afsp_1" to="pribor_afsp_1" method="_on_toggled"]
@@ -1337,7 +1399,6 @@ default_color = Color(1, 1, 1, 0.352941)
[connection signal="toggled" from="pribor_prd_n_3" to="pribor_prd_n_3" method="_on_toggled"]
[connection signal="toggled" from="pribor_prd_k_3" to="pribor_prd_k_3" method="_on_toggled"]
[connection signal="toggled" from="pribor_prd_v_1" to="pribor_prd_v_1" method="_on_toggled"]
[connection signal="toggled" from="pribor_prd_n_1" to="pribor_prd_n_1" method="_on_toggled"]
[connection signal="toggled" from="pribor_prd_k_1" to="pribor_prd_k_1" method="_on_toggled"]
[connection signal="toggled" from="pribor_prd_v_4" to="pribor_prd_v_4" method="_on_toggled"]
[connection signal="toggled" from="pribor_prd_n_4" to="pribor_prd_n_4" method="_on_toggled"]

View File

@@ -38,7 +38,7 @@ const SETTING_TABLE = [
['Текущая версия ПО УАРЭП', TableEdit, TableEdit, 'Время сборки, версия и номер фиксации'],
['уарэп-яу07-частный', TableEdit, TableEdit, 'IP-адрес для получения частных сообщений от ЯУ-07'],
['уарэп-яу07-общий', TableEdit, TableEdit, 'IP-адрес для получения широковещательных сообщений от ЯУ-07'],
['уарэп-капсрпб', TableEdit, TableEdit, 'IP-адрес для связи с КАПС-РПБ'],
['уарэп-капсрпб', TableEdit, TableEdit, 'IP-адрес для связи с КАПС-РПБ [<адрес этого узла>, <адрес удалённого узла>, <порт этого узла>, <порт удалённого узла>]'],
['уарэп-эмс', TableEdit, TableEdit, 'IP-адрес для связи с ЭМС'],
['уарэп-яу07-2в', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-В 2'],
['уарэп-яу07-2н', TableEdit, TableEdit, 'IP-адрес для связи с прибором ПРД-Н 2'],
@@ -61,7 +61,10 @@ const SETTING_TABLE = [
['Адрес АФСП левого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора АФСП'],
['Адрес АФСП правого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора АФСП'],
['Адрес БПО левого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора БПО'],
['Адрес БПО правого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора БПО'] ]
['Адрес БПО правого борта', TableEdit, TableEdit, 'http-адрес для запроса состояния прибора БПО'],
['Период опроса состояния БПО, секунды', TableEdit, TableEdit, 'Время в секундах' ],
['Период опроса состояния АФСП, секунды', TableEdit, TableEdit, 'Время в секундах' ],
['уареп-трасса', TableEdit, TableEdit, 'IP-адрес для связи с Трассой [<адрес этого узла>, <адрес удалённого узла>, <порт этого узла>, <порт удалённого узла>]'] ]
const EXTERNAL_CU = 16 ## Внешнее целеуказание
const TRASSA = 17
@@ -86,20 +89,17 @@ func _ready() -> void:
func on_external_cu_btn_pressed(btn) -> void:
var state = btn.button_pressed
ProjectSettings.set_setting('application/config/Внешнее управление', state)
if state:
ProjectSettings.set_setting('application/config/Внешнее управление', btn.button_pressed)
if btn.button_pressed:
signaller.emit_signal('interfer_off_all')
func on_trassa_btn_pressed(btn) -> void:
var state = btn.button_pressed
ProjectSettings.set_setting('application/config/Внешнее указание Трасса', state)
ProjectSettings.set_setting('application/config/Внешнее указание Трасса', btn.button_pressed)
func on_vk_pressed(btn) -> void:
var state = btn.button_pressed
signaller.emit_signal('kb_pressed', state)
signaller.emit_signal('kb_pressed', btn.button_pressed)
func on_ems2_pressed(btn) -> void:
@@ -175,7 +175,7 @@ func setting_tab():
var child = node_values[0]
if child is CheckButton:
child.connect('pressed', Callable(self, 'on_checkbutton_pressed').bind(i))
var val = settings_data[param_name] if settings_data.has(param_name) else false
var val = ProjectSettings.get_setting('application/config/%s' % param_name)
child.set_pressed(val)
else:
if settings_data.has(param_name):
@@ -213,11 +213,9 @@ func button_settings():
var extern_cu_node = $scroll_set/table.get_node2(1, EXTERNAL_CU).get_children()[0]
extern_cu_node.connect('pressed', on_external_cu_btn_pressed.bind(extern_cu_node))
on_external_cu_btn_pressed(extern_cu_node)
var trassa_node = $scroll_set/table.get_node2(1, TRASSA).get_children()[0]
var trassa_node = $scroll_set/table.get_node2(1, TRASSA).get_children()
trassa_node = trassa_node[0]
trassa_node.connect('pressed', on_trassa_btn_pressed.bind(trassa_node))
on_trassa_btn_pressed(trassa_node)
var vk_node = $scroll_set/table.get_node2(1, KEYBOARD).get_children()[0]
vk_node.connect('pressed', on_vk_pressed.bind(vk_node))
var ems2_hide_node = $scroll_set/table.get_node2(1, HIDE_EMS2).get_children()[0]

View File

@@ -18,6 +18,7 @@ class_name work extends Panel
@export var strob_min_width: float ## Минимальная ширина строба по углу.
@export var window_0_id: int ## Идетификатор окна. Присваивается godot от 0 до количества созданных окон.
const SVK_EMIT = 1 ## Код состояния выполнения помехи - выполняется
var drag_button: MouseButton ## Кнопка мыши нажатая при перетаскивании.
var drag_fsm: DragFSM = DragFSM.IDLE ## Текущее состояние перетаскивания.
@@ -30,7 +31,13 @@ var strob_band_begin: float ## Ширина строба в моме
var strob_dir_begin: float ## Направление антенны в момент начала перетаскивания.
var strob_width_begin: float ## Ширина строба по углу в момент начала перетаскивания.
var view_mode: MapViewMode ## Режим отображения карты
var thrs_dict: Dictionary ## Ссылка на словарь целей
var color_ecm: Color
var color_select: Color
var color_emit: Color
var color_emit_sel: Color
var course = 0.0 ## Курс корабля
signal drag_begin ## Вызывается в момент начала перетаскивания.
signal drag_continue ## Вызывается во время продолжения перетаскивания.
@@ -44,6 +51,7 @@ const map_sizes = [
var fs_band = prd.FS_BAND_RTO ## Текущий режим блоков ФС по частоте
var fs_selected: Dictionary ## Словарь выбранных секторов
var fs_active: Dictionary ## Словарь секторов назначенных на подавление
var fs_emit: Dictionary ## Словарь секторов назначенных на подавление
## Состояние перетаскивания.
enum DragFSM {
@@ -72,10 +80,6 @@ const VAL_TO_EVENT = {
true: 'full_auto' } ## Выбор целей и установка помех автоматически.
## Обработчик сигнала изменения списка целей.
func on_threats_resized(threats: Dictionary): $count_all_pad/count_all.text = '%02d' % threats.size()
## Обработчик выбора цели.
func on_threat_selected(th, ecm_btns): on_rto_threat_sel(th.id, ecm_btns)
@@ -84,6 +88,25 @@ func on_threat_selected(th, ecm_btns): on_rto_threat_sel(th.id, ecm_btns)
func on_enter_tree() -> void: call_deferred('on_button_strobe_pressed')
func on_settings_changed():
color_emit_sel = ProjectSettings.get_setting('application/interfer/emit_sel_color', Color(1.0, 1.0, 1.0, 1.0))
color_emit = ProjectSettings.get_setting('application/interfer/emit_color', Color(0.58, 0.47, 0.51, 1.0))
color_ecm = ProjectSettings.get_setting('application/interfer/interfer_color', Color(0.58, 0.47, 0.51, 1.0))
color_select = ProjectSettings.get_setting('application/interfer/select_color', Color(1.0, 1.0, 1.0, 1.0))
color_select *= Color(1.0, 1.0, 1.0, 0.0)
color_ecm *= Color(1.0, 1.0, 1.0, 0.0)
color_emit_sel *= Color(1.0, 1.0, 1.0, 0.2)
## Обработчик сигнала изменения списка целей.
func on_threats_resized(ths: Dictionary):
$count_all_pad/count_all.text = '%02d' % ths.size()
var c: int = ths.values().filter(func(th: threats.Threat): return th.proto != '').size()
$count_danger_pad/count_danger.text = '%02d' % c
thrs_dict = ths
## Обработчик нажатия на кнопку вид.
func on_button_view_toggled(toggled: bool):
signaller.emit_signal('map_mode_changed', int(toggled))
@@ -113,6 +136,8 @@ func _exit_tree() -> void:
## Производит инициализацию.
func _ready():
ProjectSettings.connect('settings_changed', on_settings_changed)
on_settings_changed()
min_zoom = ProjectSettings.get_setting('application/config/map_minimum_zoom', 5)
max_zoom = ProjectSettings.get_setting('application/config/map_maximum_zoom', 19)
drag_fsm = DragFSM.OFF
@@ -120,28 +145,42 @@ func _ready():
btns_select.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_select').bind(btn, btns_select)))
var nodes: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
nodes.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_pressed').bind(btn, nodes)))
threats.connect('threat_new', Callable(self, 'on_threat_new'))
threats.connect('threat_lost', Callable(self, 'on_threat_lost'))
threats.connect('threats_resized', Callable(self, 'on_threats_resized'))
threats.connect('threat_update', Callable(self, 'on_threat_update'))
signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(nodes))
signaller.connect('bip_pressed', Callable(self, 'on_bip_pressed').bind(nodes))
signaller.connect('rto_threat_unsel', Callable(self, 'on_rto_threat_unsel').bind(nodes))
signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(nodes))
signaller.connect('interfer_selected', Callable(self, 'on_interfer_selected').bind(nodes))
signaller.connect('interfer_new', Callable(self, 'on_interfer_new'))
signaller.connect('interfer_off_all', Callable(self, 'on_interfer_off_all'))
signaller.connect('interfer_prinuditelno', Callable(self, 'on_interfer_prinuditelno').bind(nodes))
signaller.connect('fs_selected', Callable(self, 'on_fs_selected'))
signaller.connect('fs_update_color', Callable(self, 'on_fs_update_color'))
interfer.connect('interfer_update', Callable(self, 'on_interfer_new'))
signaller.connect('interfer_prinuditelno', Callable(self, 'on_chk_interfer_prinuditelno'))
signaller.connect('fs_update_state', Callable(self, 'on_fs_update_state'))
signaller.connect('map_user_panning', Callable(self, 'on_user_panning'))
threats.connect('threat_new', Callable(self, 'on_threat_new'))
threats.connect('threat_lost', Callable(self, 'on_threat_lost'))
threats.connect('threats_resized', Callable(self, 'on_threats_resized'))
threats.connect('threat_update', Callable(self, 'on_threat_update'))
signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(nodes))
signaller.connect('bip_pressed', Callable(self, 'on_bip_pressed').bind(nodes))
signaller.connect('rto_threat_unsel', Callable(self, 'on_rto_threat_unsel').bind(nodes))
signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(nodes))
signaller.connect('interfer_selected', Callable(self, 'on_interfer_selected').bind(nodes))
signaller.connect('interfer_new', Callable(self, 'on_interfer_new'))
signaller.connect('interfer_off_all', Callable(self, 'on_interfer_off_all'))
signaller.connect('interfer_prinuditelno', Callable(self, 'on_interfer_prinuditelno').bind(nodes))
signaller.connect('fs_selected', Callable(self, 'on_fs_selected'))
signaller.connect('fs_update_color', Callable(self, 'on_fs_update_color'))
interfer.connect('interfer_update', Callable(self, 'on_interfer_new'))
signaller.connect('interfer_prinuditelno', Callable(self, 'on_chk_interfer_prinuditelno'))
signaller.connect('fs_update_state', Callable(self, 'on_fs_update_state'))
signaller.connect('map_user_panning', Callable(self, 'on_user_panning'))
signaller.connect('update_coordinates_map', Callable(self, 'on_update_coordinates_label'))
signaller.connect('update_scale_map', Callable(self, 'on_update_scale_label'))
signaller.connect('update_scale_map', Callable(self, 'on_update_scale_label'))
var unit_nav = network.get_unit_instance('навигация')
unit_nav.connect('data_received', on_navi_data_received)
on_btn_center_toggled(true)
on_btn_activate_toggled(true)
#$canvas.add_seczap(0, Vector4(372, 0, 30, 348))
#$canvas.add_seczap(1, Vector4(372, 90, 30, 348))
#$canvas.add_seczap(2, Vector4(198 + 348, 180, 30, 5))
#$canvas.add_seczap(3, Vector4(203, 270, 30, 5))
#$canvas.set_seczap_color(2, Color.MAGENTA)
#$canvas.set_seczap_color(3, Color.CHARTREUSE)
func on_navi_data_received(data: Dictionary):
$canvas.set_canvas_rotation(data.get('k', 0.0))
course = data.get('k', 0.0)
func on_user_panning():
@@ -166,7 +205,7 @@ func get_all_nodes(root):
## Производит отображение цели на диаграмму.
func map_threat_to_bip(th: threats.Threat, bip: Control):
func map_threat_to_bip(th: threats.Threat, bip: Control) -> bool:
var freq = th.freq
var sector_key = null
var sector_width = 50.0
@@ -176,7 +215,7 @@ func map_threat_to_bip(th: threats.Threat, bip: Control):
if freq_range[0] <= freq and freq <= freq_range[1]:
sector_key = key
break
if sector_key!= null:
if sector_key != null:
radius_internal = fs_band[sector_key][0]
radius_outter = fs_band[sector_key][1]
freq_low = prd.FS_FREQ[sector_key][0]
@@ -189,33 +228,34 @@ func map_threat_to_bip(th: threats.Threat, bip: Control):
radius_outter,
freq_low,
freq_high) - bip.size / 2
return sector_key != null
## Обработчик сигнала обновления цели.
func on_threat_update(th):
var bip = get_node('%d' % th.id)
bip.update(th.tick_rx)
map_threat_to_bip(th, bip)
bip.visible = map_threat_to_bip(th, bip)
## Обработчик выбора помехи для цели.
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 ecm.krp!= interfer.INTERFER_OFF:
bip.set_track_visible(true)
if ecm.svk == 1:
bip.set_ecm_visible(true)
else: bip.set_ecm_visible(false)
else:
bip.set_ecm_visible(false)
bip.set_track_visible(false)
if not interfer.thrs.has(ecm.ispp): return
var th_id = interfer.thrs[ecm.ispp]
var bip = get_node('%d' % th_id)
if bip != null:
if ecm.krp!= interfer.INTERFER_OFF:
bip.set_track_visible(true)
if ecm.svk == 1:
bip.set_ecm_visible(true)
else: bip.set_ecm_visible(false)
else:
interfer.thrs.erase(ecm.ispp)
set_fs_color(ecm)
update_fs_colors()
bip.set_ecm_visible(false)
bip.set_track_visible(false)
else:
interfer.thrs.erase(ecm.ispp)
set_fs_color(ecm)
update_fs_colors()
set_fs_color(ecm)
@@ -226,6 +266,7 @@ func on_interfer_off_all():
bip.set_ecm_visible(false)
bip.set_track_visible(false)
fs_active.clear()
fs_emit.clear()
update_fs_colors()
@@ -259,24 +300,33 @@ func on_rto_threat_sel(th_id, ecm_btns):
unsel_fs_all(false)
else:
item.set_sel_visible(false)
var th = thrs_dict[th_id]
var krp = interfer.get_krp(th)
for btn in ecm_btns:
set_btns_disabled(false, btn)
var btn_meta = btn.get_meta('rfi_name')
if krp == btn_meta:
btn.modulate = Color.DEEP_SKY_BLUE
else:
btn.modulate = Color(1.0, 1.0, 1.0, 1.0)
## Обработчик снятия выбора РТО цели.
func on_rto_threat_unsel(th_id, _ecm_btns):
func on_rto_threat_unsel(th_id, ecm_btns):
var bips: Array = get_children().filter(func(item): return item.name.is_valid_int())
for item in bips:
if th_id == item.name.to_int():
item.set_sel_visible(false)
break
set_ecm_btns_state(true)
for btn in ecm_btns:
btn.modulate = Color(1.0, 1.0, 1.0, 1.0)
## Обработчик нажатия кнопки "Строб". Управляет отображением строба.
func on_button_strobe_pressed() -> void:
drag_fsm = DragFSM.IDLE if $btns_select/btn_strob.is_pressed() else DragFSM.OFF
$canvas.set_strob_visible(drag_fsm == DragFSM.IDLE)
$canvas.set_strob_visible((drag_fsm == DragFSM.IDLE) and (view_mode == MapViewMode.RTO))
## Поведение радиокнопок в группе. Управляет состоянием кнопок выбора целей.
@@ -341,6 +391,7 @@ func set_strob(pos: Vector2) -> void:
## Обработка движения мыши для управления стробом. Вызывается во время движения мыши.
func _on_drag_continue(event) -> void:
if not $canvas.get_strob_visible(): return
if drag_button == MOUSE_BUTTON_RIGHT:
if shift_pressed:
var strob_width: float = get_strob_width(event.position, strob_width_begin)
@@ -354,6 +405,7 @@ func _on_drag_continue(event) -> void:
## Обработка движения мыши для управления стробом. Вызывается при нажатии мыши.
func _on_drag_begin(event) -> void:
if not $canvas.get_strob_visible(): return
drag_pos_begin = event.position
if drag_button == MOUSE_BUTTON_LEFT:
set_strob(event.position)
@@ -390,7 +442,7 @@ func sel_fs_sector(event):
if (event.button_index == MOUSE_BUTTON_LEFT) or (event.button_index == MOUSE_BUTTON_RIGHT):
var center: Vector2 = $tilemap.position
var center_offset: Vector2 = ProjectSettings.get_setting('application/interfer/center_offset', Vector2i(0, 25))
var angle: float = event.position.angle_to_point(center + center_offset) * 180/PI - 45.0
var angle: float = event.position.angle_to_point(center + center_offset) * 180/PI - 45.0 - course
if angle < 0:
angle += 360
var distance: float = event.position.distance_to(center + center_offset)
@@ -418,21 +470,31 @@ func sel_fs_sector(event):
func set_fs_color(ecm):
if not prd.fs_caps_id.has(ecm.nmfs):
push_warning('нет такого модуля ФС: %d, но имеется: %s' % [ecm.nmfs, prd.fs_caps_id.keys()])
return
if ecm.krp != interfer.INTERFER_OFF:
fs_active[prd.fs_caps_id[ecm.nmfs]] = null
else:
fs_active.erase(prd.fs_caps_id[ecm.nmfs])
if ecm.svk == SVK_EMIT:
fs_emit[prd.fs_caps_id[ecm.nmfs]] = null
else:
fs_emit.erase(prd.fs_caps_id[ecm.nmfs])
update_fs_colors()
func update_fs_colors():
var fs_colors = $canvas.fs_default_colors.duplicate()
var color_ecm: Vector3 = ProjectSettings.get_setting('application/interfer/interfer_color', Vector3(0.58, 0.47, 0.51))
var color_select: Vector3 = ProjectSettings.get_setting('application/interfer/select_color', Vector3(1.0, 1.0, 1.0))
for key in fs_active.keys():
fs_colors[key] = color_ecm
for key in fs_emit.keys():
fs_colors[key] = color_emit
for key in fs_selected.keys():
fs_colors[key] = color_select
if key in fs_emit:
fs_colors[key] = color_emit_sel
else:
fs_colors[key] = color_select
$canvas.set_band_colors(fs_colors)
@@ -470,6 +532,7 @@ func set_btns_disabled(value: bool, btn):
func on_fs_update_color(ecms):
fs_active.clear()
fs_emit.clear()
for ecm in ecms.values():
set_fs_color(ecm)
update_fs_colors()

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=17 format=3 uid="uid://b276iygic5itk"]
[gd_scene load_steps=18 format=3 uid="uid://b276iygic5itk"]
[ext_resource type="Script" uid="uid://daudc0s3oox3i" path="res://scenes/работа/работа.gd" id="1_niok4"]
[ext_resource type="PackedScene" uid="uid://nl1vklubr5kr" path="res://scenes/bip/bip.tscn" id="2_br3s6"]
@@ -51,6 +51,10 @@ _data = {
offsets = PackedFloat32Array(0.181818, 0.751623)
colors = PackedColorArray(1, 1, 1, 0.352941, 1, 1, 1, 0)
[sub_resource type="SystemFont" id="SystemFont_5ffal"]
generate_mipmaps = true
subpixel_positioning = 0
[node name="Работа" type="Panel"]
script = ExtResource("1_niok4")
Bip = ExtResource("2_br3s6")
@@ -86,6 +90,7 @@ self_modulate = Color(1, 1, 1, 0.415686)
position = Vector2(360, 360)
min_zoom_level = 3
max_zoom_level_server = 11
ship_radius_km = 3.0
az = 3.0
[node name="player" type="AnimationPlayer" parent="tilemap"]
@@ -95,11 +100,10 @@ libraries = {
[node name="grd_side" parent="." instance=ExtResource("3_s2j0e")]
layout_mode = 0
offset_left = 1114.0
offset_left = 1116.0
offset_top = 7.0
offset_right = 1594.0
offset_bottom = 1170.0
metadata/_edit_lock_ = true
[node name="grd_btns" parent="." instance=ExtResource("5_2jnbs")]
layout_mode = 0
@@ -203,6 +207,7 @@ offset_left = 115.0
offset_top = 1085.0
offset_right = 257.0
offset_bottom = 1112.0
tooltip_text = "Автоматический выбор цели и помехи"
action_mode = 0
text = "Автоматически"
@@ -259,6 +264,7 @@ offset_top = 995.0
offset_right = 1136.0
offset_bottom = 1127.0
scale = Vector2(0.5, 0.5)
tooltip_text = "Применение выбранного режима помехи"
toggle_mode = true
button_pressed = true
action_mode = 0
@@ -283,27 +289,58 @@ offset_top = 1005.0
offset_right = 1030.0
offset_bottom = 1121.0
scale = Vector2(0.5, 0.5)
tooltip_text = "Устанавливает центр карты на текущие координаты"
toggle_mode = true
button_pressed = true
texture_normal = ExtResource("12_5ffal")
texture_pressed = ExtResource("13_ggrwd")
[node name="label" type="Label" parent="btn_center"]
layout_mode = 0
offset_left = -32.0
offset_top = 100.0
offset_right = 65.0
offset_bottom = 119.0
scale = Vector2(2, 2)
text = "Центрировать"
horizontal_alignment = 1
vertical_alignment = 1
[node name="coordinates_map" type="Label" parent="."]
layout_mode = 0
offset_left = 1000.0
offset_left = 999.0
offset_top = 128.0
offset_right = 1112.0
offset_right = 1111.0
offset_bottom = 147.0
text = "Координаты:"
[node name="scale_map" type="Label" parent="."]
layout_mode = 0
offset_left = 1000.0
offset_top = 192.0
offset_right = 1110.0
offset_bottom = 213.0
offset_left = 999.0
offset_top = 202.0
offset_right = 1109.0
offset_bottom = 223.0
text = "Масштаб:"
[node name="zoom_plus" type="Button" parent="."]
layout_mode = 0
offset_left = 1056.0
offset_top = 230.0
offset_right = 1088.0
offset_bottom = 262.0
theme_override_fonts/font = SubResource("SystemFont_5ffal")
theme_override_font_sizes/font_size = 20
text = "+"
[node name="zoom_minus" type="Button" parent="."]
layout_mode = 0
offset_left = 1056.0
offset_top = 270.0
offset_right = 1088.0
offset_bottom = 302.0
theme_override_font_sizes/font_size = 20
text = ""
[connection signal="drag_begin" from="." to="." method="_on_drag_begin"]
[connection signal="drag_continue" from="." to="." method="_on_drag_continue"]
[connection signal="toggled" from="btn_view" to="." method="on_button_view_toggled"]
@@ -311,3 +348,8 @@ text = "Масштаб:"
[connection signal="toggled" from="btn_activate" to="." method="on_btn_activate_toggled"]
[connection signal="toggled" from="btn_activate" to="." method="on_btn_activate"]
[connection signal="toggled" from="btn_center" to="." method="on_btn_center_toggled"]
[connection signal="button_down" from="zoom_plus" to="tilemap" method="_on_zoom_plus_button_down"]
[connection signal="button_up" from="zoom_plus" to="tilemap" method="_on_zoom_plus_button_up"]
[connection signal="button_up" from="zoom_plus" to="tilemap" method="_on_zoom_button_up"]
[connection signal="button_down" from="zoom_minus" to="tilemap" method="_on_zoom_minus_button_down"]
[connection signal="button_up" from="zoom_minus" to="tilemap" method="_on_zoom_button_up"]

View File

@@ -17,7 +17,7 @@ class CapsRpb extends unit.Unit:
var source_addr: Array ## Адрес отправителя данных
func _to_string() -> String: return String('CapsRpb(\"%s\")' % self.name)
func _init(nm): self.name = nm
func _init(unit_name): self.name = unit_name
func parse(data: PackedByteArray, now_tick: int):
tick = now_tick

View File

@@ -5,7 +5,7 @@ class_name Iterfer extends Node
## Режимы помехи.
const ITERFER_MODE = {
INTERFER_OFF: [INTERFER_OFF, {}, 0],
'srni1': ['ПСП + ФМ-2', SRNI1_PARAMS, 1],
'srni1': [INTERFER_IQFILE, SRNI1_PARAMS, 1],
'srnm2': ['Линейная ЧМ', SRNM2_PARAMS, 2],
'srngps': [INTERFER_IQFILE, SRNGPS_PARAMS, 3],
'lchm1': ['Линейная ЧМ', LCHM1_PARAMS, 10],
@@ -19,14 +19,17 @@ const ITERFER_MODE = {
'svm2': [INTERFER_IQFILE, SVM2_PARAMS, 21],
'k1': [INTERFER_IQFILE, K1_PARAMS, 50],
'ozp1': [INTERFER_IQFILE, OZP1_PARAMS, 51],
'eprls': [INTERFER_IQFILE, EPRLS_PARAMS, 52], }
'eprls': [INTERFER_IQFILE, EPRLS_PARAMS, 52] }
const RECOMMEND_INTERFER = {
'ПСП + ФМ-2': 'srni1',
'Линейная ЧМ': 'lchm1'
}
const SRNI1_PARAMS = {'par_names' : ['freq', 'width']}
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',
@@ -36,15 +39,27 @@ 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 = {'par_names' : ['freq', 'filename'],
'files': 'PDM2_20.pcm',
'call_proc': 'call_all_diap'}
const PDM4_PARAMS = {'par_names' : ['freq', 'filename'],
'files': 'PDM4_20.pcm',
'call_proc': 'call_all_diap'}
const PDM4S_PARAMS = {'par_names' : ['freq', 'filename'],
'files': 'PDM4S_5.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']}
@@ -65,10 +80,10 @@ const EPRLS_PARAMS = {'files' : 'ERLS.pcm',
'par_names' : ['freq', 'filename']}
# Файл : Ключ (ширина): ['имя файла']
const PDCHM_PARAMS = {'files': {
5 : 'pdchm_5.pcm',
10: 'pdchm__0.pcm',
20: 'pdchm_20.pcm',
40: 'pdchm_40.pcm' },
5 : 'PDCHM_5.pcm',
10: 'PDCHM_10.pcm',
20: 'PDCHM_20.pcm',
40: 'PDCHM_40.pcm' },
'call_proc': 'call_pdchm',
'par_names' : ['freq', 'filename'],}
@@ -77,7 +92,7 @@ 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 = 100.0
const POW_DEFAULT: float = 50.0
var msg6_num: int = 0 ## Счётчик сообщений "тип 6"
var msg8_num: int = 0 ## Счётчик сообщений "тип 8"
var id_array: Array ## Массив id воздействий.
@@ -87,6 +102,8 @@ var cu: Dictionary ## Словарь воздействий для 5
var thrs_dict: Dictionary ## Ссылка на словарь целей
var auto_enabled: bool = false ## Режим автомата
var emit_enable: bool = true ## Разрешить излучение
var trenazh_mode: bool = false ## Переключение режима Тренаж
var course = 0.0 ## Курс корабля
## Сеанс помехи.
class Interfer:
@@ -163,7 +180,6 @@ 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('уарэп-капсрпб')
@@ -171,13 +187,15 @@ func _ready() -> void:
var timer_check_state: = Timer.new()
add_child(timer_check_state)
var resend_timeout = ProjectSettings.get_setting('application/interfer/resend_timeout', 1000.0)
var ecms: Dictionary = {} ## Словарь помех.
var seczaps: Dictionary = {} ## Словарь секторов запрета
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_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, ecms))
signaller.connect('interfer_new', Callable(self, 'send_ecm').bind(unit_caps))
signaller.connect('interfer_new', Callable(self, 'on_interfer_new').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').bind(ecms))
@@ -185,15 +203,20 @@ func _ready() -> void:
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)
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))
threats.connect('threats_resized', Callable(self, 'on_threats_resized'))
threats.connect('threat_update', Callable(self, 'on_threats_update').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_trenazh_mode(val: bool): trenazh_mode = val
func on_nav_data_received(coords: Dictionary, unit_caps):
var ship_time = Time.get_datetime_dict_from_system()
course = coords.get('k', 0.0)
var data_to_json = {
'ts': 8,
'ss': msg8_num,
@@ -216,25 +239,27 @@ func on_nav_data_received(coords: Dictionary, unit_caps):
## Проверяет состояние отправки пакета и если не доставлен, повторяет отправку.
func on_timer_check_state(unit, ecms, resend_timeout) -> void:
func on_timer_check_state(unit_instance, 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)
send_ecm(ecm, unit_instance)
ecm.tick_tx = tick
func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit) -> void:
func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit_instance) -> 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)
ecm.kni = thr.aoa - course
if ecm.kni < 0:
ecm.kni += 360
send_ecm(ecm, unit_instance)
signaller.emit_signal('fs_update_color', ecms)
prd.update_fs_state(ecms)
prd.update_fs_state(ecms, trenazh_mode)
if not auto_enabled:
return
@@ -247,84 +272,91 @@ func on_th_aoa_update(threats: Dictionary, ecms: Dictionary, unit) -> void:
## Производит приём состояния помех. [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']
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', [])
for dic_msvk in msvk:
if not (dic_msvk is Dictionary): continue
if dic_msvk.has('ispp'):
var ispp = int(dic_msvk['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)
else:
var ecm = Interfer.new()
ecm.set_from_dic(dic_msvk)
ecm.krp = INTERFER_OFF
send_ecm(ecm, unit0)
if dic_msvk is not Dictionary: continue
if not dic_msvk.has('ispp'): continue
var ispp = int(dic_msvk['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)
else:
var ecm = Interfer.new()
ecm.set_from_dic(dic_msvk)
ecm.krp = INTERFER_OFF
send_ecm(ecm, unit_instance)
## Извлекает массив пространственно-частотных фильтров
func map_mpchf_to_seczaps(unit_instance: unit.Unit, seczaps: Dictionary):
var json_dic: = unit_instance.json_dic as Dictionary
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:
var ecm_name = interfer_name
for item in sel_threats:
var param: Dictionary = {}
var kni: float = item.aoa
var kni: float = item.aoa - course
if kni < 0:
kni += 360.0
var id = item.id
param['freq'] = item.freq
param['width'] = item.width
if (item.rkrp != '') and item.fflags.rkrp:
if (item.rkrp != '') and item.fflags.rkrp and auto_enabled:
var krp = get_krp(item)
if krp != '':
ecm_name = krp
interfer_name = krp
set_rparams(item, param)
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, ecm_name, ecms, param, kni, id, thrs, SOURCE_INTERFER[0], power)
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]
var th = null
if not interfer_name in EXCLUDE_INTERFER:
th = find_threat(item[1], kni)
if th != null:
param['freq'] = th.freq
param['width'] = th.width
if (th.rkrp != '') and th.fflags.rkrp:
var krp = get_krp(th)
if krp != '':
ecm_name = krp
set_rparams(th, param)
else:
param['freq'] = item[1]
param['width'] = item[2]
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
if th == null:
interfer_create(u, ecm_name, ecms, param, kni, id, fs, SOURCE_INTERFER[1], power)
else:
id = th.id
interfer_create(u, ecm_name, ecms, param, kni, id, thrs, SOURCE_INTERFER[0], power)
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 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
@@ -491,13 +523,15 @@ func on_threats_update(threat, ecms, unit_caps):
ecm = ecms[ecm_i]
ecm.params['freq'] = threat.freq
ecm.params['width'] = threat.width
if (threat.rkrp != '') and threat.fflags.rkrp:
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)
emit_signal('interfer_recommendate', ecm)
ecm.kni = threat.aoa
ecm.kni = threat.aoa - course
if ecm.kni < 0:
ecm.kni += 360
set_nmfs(ecm)
if threat.tmod != 'fm':
if ecm != null:
@@ -607,3 +641,11 @@ func on_interfer_off(ecm: Interfer, ecms):
interfer.push_id(ecm.ispp)
if sz != ecms.size():
interfer.call_deferred('emit_signal', 'interfer_resized', ecms)
func on_interfer_new(ecm, unit_caps):
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()
send_ecm(ecm, unit_caps)

View File

@@ -29,7 +29,7 @@ class NaviSource extends unit.Unit:
if rx_data.size() < 28:
emit_signal('parse_failed', self)
return false
var flags: = rx_data.decode_u16(26) # Флаги достоверности полей структуры
var flags: = rx_data.decode_u16(28) # Флаги достоверности полей структуры
data.clear()
data['mode'] = akng_mode[(flags >> 4) & 3] # Режим работы АКНГ
if flags & (1 << 0):

View File

@@ -1,3 +1,4 @@
@tool
class_name Network extends Node
const YAU07_PROTO: = {'yau07tx': yau07.YaU07}
@@ -6,7 +7,7 @@ const TCP_PROTO: = {'5p28': tcp5p28.TCP5P28}
const SERIAL_PROTO: = {'spt25': spt25.SPT25}
const MODBUS_PROTO: = {'mbcs': sch3.Sch3}
const NAVI_PROTO: = {'navi': navi.NaviSource}
const NULL_PROTO: = {null: unit.Unit}
var tick: int = 0
@@ -19,32 +20,46 @@ class SocketSerial extends SerialPort:
'N': SerialPort.PARITY_NONE,
'E': SerialPort.PARITY_EVEN,
'O': SerialPort.PARITY_ODD }
static var tick: int
var unit_instance: unit.Unit
var tx_buffer: PackedByteArray
func on_serial_data(data: PackedByteArray):
unit_instance.parse(data, tick)
func _init() -> void:
tx_buffer.resize(256)
func on_settings_changed():
try_close()
var rc = try_open()
if rc != Error.OK:
log.message(log.ERROR, 'невозможно открыть %s для \"%s\"' % [self, unit_instance.name])
else:
log.message(log.INFO, '%s для \"%s\"' % [self, unit_instance.name])
func send_to(data: PackedByteArray):
tx_buffer[0] = 0x7e
func format_buffer(data: PackedByteArray):
var buffer: PackedByteArray
buffer.resize(64)
var i: = 1
for v in data:
if v != 0x7e:
tx_buffer[i] = v
i += 1
buffer[i] = v; i += 1
else:
tx_buffer[i] = FLAG
i += 1
tx_buffer[i] = FLAG ^ FLAG_MASK
i += 1
buffer[i] = FLAG; i += 1
buffer[i] = FLAG ^ FLAG_MASK; i += 1
var v_sum: = get_check_sum(data)
tx_buffer.encode_u16(i, v_sum)
i += 2
tx_buffer[i] = FLAG
i += 1
buffer.encode_u16(i, v_sum); i += 2
buffer[i] = FLAG; i += 1
buffer.resize(i)
return buffer
func send_to(data: PackedByteArray):
if not is_open():
try_open()
return
# var buffer = format_buffer(data) # Не проверено, но должно работать
# Эта последовательность для запроса состояния, получена от разработчиков СПТ-25
const tx_tula = [0x7e, 0x01, 0x04, 0xbb, 0x50, 0x7e]
write_raw(tx_tula)
const tx_tula: = [0x7e, 0x01, 0x04, 0xbb, 0x50, 0x7e]
var sz = write_raw(tx_tula)
if sz != tx_tula.size():
try_open()
func _to_string() -> String: return 'последовательный порт \"%s\" @ %d (%s)' % [self.port, self.baudrate, 'открыт' if is_open() else 'закрыт']
@@ -65,12 +80,12 @@ class SocketSerial extends SerialPort:
fcs = (fcs >> 1) ^ P_DIV if fcs & 1 else fcs >> 1
return (~fcs) & 0xffff
func try_open(parsing_proc: Callable):
func try_open() -> Error:
if is_open():
return Error.OK
var rc: = open(port)
if rc == Error.OK:
data_received.connect(parsing_proc)
data_received.connect(on_serial_data)
start_monitoring(timeout)
return rc
@@ -79,7 +94,7 @@ class SocketSerial extends SerialPort:
return Error.FAILED
stop_monitoring()
close()
var connections = data_received.get_connections()
var connections: = data_received.get_connections()
for conn in connections:
data_received.disconnect(conn.callable)
return Error.OK
@@ -119,6 +134,7 @@ var units_udprx: Dictionary[StringName, unit.Unit] ## Экземпляры
var units_tcp: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с tcp-соединением
var units_serial: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с uart-соединением
var units_modbus: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с modbusserial-соединением
var units_nullp: Dictionary[StringName, unit.Unit] ## Экземпляры устройств без протокола
var serials: Dictionary[StringName, SocketSerial] ## Последовательные порты (uart)
var dst_ports: Dictionary[StringName, int] ## Преобразование имя устройства в порт назначения
var dst_addrs: Dictionary[StringName, StringName] ## Преобразование имя устройства в адрес назначения
@@ -128,9 +144,6 @@ var send_sockets: Dictionary[StringName, SocketUDP] ## Таблица <имя
var addr_port_to_unit_name: Dictionary[StringName, StringName] ## Преобразование адрес:порт в имя устройства
func on_serial_data(data, unit): unit.parse(data, tick)
## [param unit_name] - Уникальное имя устройства[br]
func create_socket_udp(unit_name: StringName) -> SocketUDP:
var st = settings.UnitProfiles[unit_name][1]
@@ -151,8 +164,8 @@ func create_socket_udp(unit_name: StringName) -> SocketUDP:
func create_socket_caps(unit_name: StringName) -> SocketUDP:
var st = settings.UnitProfiles[unit_name][1]
var addr = st[0]
var port = st[1]
var addr = st[1]
var port = st[2]
var sock: = SocketUDP.new()
var rc: = sock.bind(port, addr)
if rc == Error.OK:
@@ -179,8 +192,8 @@ func create_socket_tcp(unit_name: StringName) -> SocketTCP:
## [param unit_name] - Уникальное имя устройства[br]
func create_serial(unit_name: StringName) -> SocketSerial:
var st = settings.UnitProfiles[unit_name][1]
func create_serial(unit_instance: unit.Unit) -> SocketSerial:
var st = settings.UnitProfiles[unit_instance.name][1]
var serial: = SocketSerial.new()
serial.port = st[0]
serial.baudrate = st[2]
@@ -188,9 +201,14 @@ func create_serial(unit_name: StringName) -> SocketSerial:
serial.timeout = 20000
serial.bytesize = st[4]
serial.stopbits = st[5]
serial.unit_instance = unit_instance
return serial
func on_serial_got_error(where: String, what: String, serial: SocketSerial, unit_instance: unit.Unit):
push_error([where, what, serial])
## [param unit_name] - Уникальное имя устройства[br]
func create_modbus(unit_name: StringName) -> sch_3.Sch3:
var unit_modbus: = sch_3.Sch3.new(unit_name)
@@ -198,6 +216,7 @@ func create_modbus(unit_name: StringName) -> sch_3.Sch3:
func _ready() -> void:
if Engine.is_editor_hint(): return
var sock_unicast: = create_socket_udp('уарэп-яу07-частный')
var sock_broadcast: = create_socket_udp('уарэп-яу07-общий')
var sock_navi: = create_socket_udp('навигация')
@@ -249,7 +268,7 @@ func _ready() -> void:
units[unit_name] = new_unit
units_udptx[unit_name] = new_unit
dst_addrs[unit_name] = unit_profile[0]
dst_ports[unit_name] = unit_profile[2]
dst_ports[unit_name] = unit_profile[3]
if proto in TCP_PROTO:
var unit_tcp = TCP_PROTO[proto].new(unit_name)
@@ -265,14 +284,20 @@ func _ready() -> void:
bind_modbuses.append([unit_modbus, unit_name])
if proto in SERIAL_PROTO:
var unit_serial = SERIAL_PROTO[proto].new(unit_name)
var serial: = create_serial(unit_name)
units_serial[unit_name] = unit_serial
units[unit_name] = unit_serial
var unit_instance = SERIAL_PROTO[proto].new(unit_name)
var serial: = create_serial(unit_instance)
serial.connect('got_error', on_serial_got_error.bind(serial, unit_instance))
ProjectSettings.connect('settings_changed', serial.on_settings_changed)
units_serial[unit_name] = unit_instance
units[unit_name] = unit_instance
serials[unit_name] = serial
bind_serials.append([serial, unit_serial, unit_name])
bind_serials.append([serial, unit_instance, unit_name])
if proto in NULL_PROTO:
var unit_null = NULL_PROTO[proto].new(unit_name)
units[unit_name] = unit_null
units_nullp[unit_name] = unit_null
ProjectSettings.connect('settings_changed', Callable(self, '_on_settings_changed_serial').bind(bind_serials))
tcp_sockets.append([create_socket_tcp('уарэп-5п28'), units_tcp['уарэп-5п28']])
for key: StringName in dst_ports:
@@ -291,21 +316,6 @@ func _on_settings_changed_modbus(bind_modbuses: Array):
var _unit_name = bm[1]
func _on_settings_changed_serial(bind_serials: Array):
var external_ctl = ProjectSettings.get_setting('application/config/Внешнее управление', false)
for bs in bind_serials:
var serial = bs[0]
var unit_serial = bs[1]
var unit_name = bs[2]
serial.try_close()
if not external_ctl:
var rc = serial.try_open(on_serial_data.bind(unit_serial))
if rc != Error.OK:
log.message(log.ERROR, 'невозможно открыть %s для \"%s\"' % [serial, unit_name])
else:
log.message(log.INFO, '%s для \"%s\"' % [serial, unit_name])
func poll_receive_udp(sock: SocketUDP) -> bool:
while sock.get_available_packet_count() > 0:
var data: = sock.get_packet()
@@ -397,6 +407,7 @@ func _process(_delta: float) -> void:
for unit_name: StringName in units_serial:
var unit_serial: = units_serial[unit_name]
var serial: = serials[unit_name]
serial.tick = tick
if Error.OK == unit_serial.process(tick):
serial.send_to(unit_serial.tx_data)
for unit_name: StringName in units_modbus:

View File

@@ -33,8 +33,8 @@ const FS_FREQ: Dictionary = {
0: [390.0, 510.0, 450.0],
1: [800.0, 1065.0, 932.0],
2: [1065.0, 1210.0, 1137.0],
3: [1150.0, 1280.0, 1215.0],
4: [1490.0, 2000.0, 1575.0],
3: [1150.0, 1380.0, 1215.0],
4: [1380.0, 2000.0, 1575.0],
5: [2000.0, 3500.0, 2750.0],
6: [3500.0, 6000.0, 4750.0] }
@@ -86,7 +86,7 @@ const FS_PRD: Dictionary = {
var fs_dict: Dictionary ## Словарь с модулями ФС
var prd_dict: Dictionary ## Словарь с приборами ПРД
var course = 0.0 ## Курс корабля
var fs_caps_id: Dictionary ## Словарь соответствия номеров ФС от КАПС РПБ внутрипрограммной нумерации
@@ -158,7 +158,9 @@ class PRD:
var state = PrdState.WORK
var cmd_array: Array ## Очередь команд
var ug_online: bool = false ## Состояние ячейки УГ
var serviceability: bool = false
var set_ug_state: bool = true ## Необходимо ли записать в УГ настройки
signal update_serviceability()
func _init(u_name, u_yau07):
prd_name = u_name
@@ -185,6 +187,7 @@ class PRD:
unit_yau07.connect('command_done', Callable(self, 'on_command_done'))
unit_yau07.connect('line_changed', Callable(self, 'on_line_changed'))
func on_command_done(u):
if yemsg_board.state_board != yemsg_board.WAIT or yemsg_board.state_cmd != yemsg_board.WAIT:
yemsg_board.on_command_done(u)
@@ -196,6 +199,7 @@ class PRD:
func on_line_changed(unit_ems):
emit_signal('update_serviceability')
if not unit_ems.online:
yemsg_board.ems_load = yemsg_board.LoadState.NOT_DEFINED
yemsg_board.set_wait()
@@ -222,6 +226,14 @@ class PRD:
ug_online = (unit_yau07.status[0] >> 1) & 1
if not ug_online:
set_ug_state = true
var ukp_1_online = (unit_yau07.status[0] >> 2) & 1
var ukp_2_online = (unit_yau07.status[0] >> 3) & 1
var ems_g_online = (unit_yau07.status[0] & 1) & 1
var check_serviceability = ug_online and ukp_1_online and ukp_2_online and ems_g_online
if serviceability != check_serviceability:
serviceability = check_serviceability
emit_signal('update_serviceability')
func execute_cmd():
if not len(cmd_array): return
@@ -284,6 +296,8 @@ func _ready() -> void:
unit_caps.connect('data_received', Callable(self, 'on_data_capsrpb_received'))
signaller.connect('режим_контроль', Callable(self, 'on_mode_changed').bind(PrdState.CONTROL))
signaller.connect('режим_работа', Callable(self, 'on_mode_changed').bind(PrdState.WORK))
var unit_nav = network.get_unit_instance('навигация')
unit_nav.connect('data_received', on_navi_data_received)
func get_fs_param(index: int) -> Array:
@@ -319,7 +333,7 @@ func find_fs_index(aoa: float, freq: int, fs_index_arr: Array):
## Обновление состояния модулей формирователя сигналов
func update_fs_state(ecms):
func update_fs_state(ecms, trenaz_mode: bool):
for fs in fs_dict.values(): ## Запрет модуляции для всех ФС
fs.set_modulation(false)
for ecm in ecms.values(): ## Выставление состояния помехи в ФС
@@ -331,7 +345,8 @@ func update_fs_state(ecms):
for prd_module in prd_dict.values(): ## Отправка команды на исполнение в ПРД
if prd_module.state != PrdState.WORK: continue
if not prd_module.unit_yau07.online: continue
prd_module.cmd_array.append([prd_module.unit_yau07.CmdCode.WRITE_ISA, [prd_module.yemsg_board.base_addr_isa, 6666]])
if not trenaz_mode:
prd_module.cmd_array.append([prd_module.unit_yau07.CmdCode.WRITE_ISA, [prd_module.yemsg_board.base_addr_isa, 6666]])
var um_data_array: Array = []
for fs in prd_module.fs_dic.values():
if not prd_module.ug_online: continue
@@ -387,3 +402,7 @@ func on_data_capsrpb_received(unit0: capsrpb.CapsRpb):
func on_mode_changed(changed_mode: int) -> void:
for pdr in prd.prd_dict.values():
pdr.state = changed_mode
func on_navi_data_received(data: Dictionary):
course = data.get('k', 0.0)

View File

@@ -5,6 +5,20 @@ class TestPRD extends Node:
const RAY_25:= 'RAY_25'
const RAY_35:= 'RAY_35'
const RAY_45:= 'RAY_45'
enum DataIndices {
STATUS_BOARD = 0,
IN_BLANK_PRD = 1,
IN_IMPULS_PRD = 7,
OUT_BLANK_PRD = 13,
OUT_IMPULS_PRD = 19,
DRY_CONTACT = 27,
DKM = 28,
POWER_UKP_1 = 31,
TEMPERATURE_UKP_1 = 47,
POWER_UKP_2 = 63,
TEMPERATURE_UKP_2 = 79,
}
enum STATE_MASHINE {
INIT,
FS_TURN_ON,
@@ -60,7 +74,10 @@ class TestPRD extends Node:
var self_name: String
var state: int = STATE_MASHINE.INIT
var current_litera: int
var flag_timer_started: bool = false
var flag_write_isa: bool = false
var flag_fs_status_ok: bool = false
var flag_si_fs_input: bool = false
var flag_si_fs_output: bool = false
var unit_prd: Object
var module_prd: Object
var power_amplify: Array
@@ -105,6 +122,7 @@ class TestPRD extends Node:
block_kasseta_y5_config = check_block_kasseta_y5(status, block_kasseta_y5_config)
block_ip_config = check_block_ip(status, block_ip_config)
control_results.temperature = check_temperature_um(status, power_amplify)
socket_status_ems_g(status)
_process_dkm_status(status)
if current_litera != 0:
var tek_litera: Dictionary = power_result[current_litera]
@@ -114,6 +132,21 @@ class TestPRD extends Node:
power_result[current_litera] = tek_litera
func socket_status_ems_g(packet_form_yau_07: PackedByteArray) -> void:
var number_socket_input: int
if current_litera >= 1 and current_litera <= 7:
number_socket_input = current_litera + 7
var in_blank: int = packet_form_yau_07.decode_u16(DataIndices.IN_BLANK_PRD)
flag_si_fs_input = (in_blank & (1 << number_socket_input)) != 0 ## Флаг СИ от ФС входа в ЭМС-Г для текущей литеры
var number_socket_output: int
number_socket_output = 4 if current_litera in [2, 4, 6] else 3 if current_litera == 1 else 5
var out_blank: int = packet_form_yau_07.decode_u16(DataIndices.OUT_BLANK_PRD)
flag_si_fs_output = (out_blank & (1 << number_socket_output)) != 0 ## Флаг Модуляции УМ ЭМС-Г для текущей литеры
## Пакеты от MP550Service
func on_fs_update_state(packet_type_7: Dictionary, fs_mapping: Dictionary) -> void:
var fs_key: String = FS_KEYS.get(current_litera, '')
@@ -123,6 +156,7 @@ class TestPRD extends Node:
var fs_result := {fs_key: 0}
fs_result = on_fs_state(packet_type_7, fs_mapping, fs_result)
control_results[fs_key] = fs_result[fs_key]
flag_fs_status_ok = control_results[fs_key] == 1
##
@@ -134,24 +168,26 @@ class TestPRD extends Node:
_handle_fs_turn_on_state()
state = STATE_MASHINE.FS_WORK
STATE_MASHINE.FS_WORK:
if ecms.size():
if ecms.size() and flag_fs_status_ok:
ems_6666_timer.start()
_handle_fs_work_state()
STATE_MASHINE.CHEK_KASSETA_Y5:
if block_kasseta_y5_config['yau07']:
state = STATE_MASHINE.WRITE_ISA
STATE_MASHINE.WRITE_ISA:
_handle_ug_set_state(0x6)
state = STATE_MASHINE.READ_ISA
if not flag_write_isa:
_handle_ug_set_state(0x6)
state = STATE_MASHINE.READ_ISA
STATE_MASHINE.READ_ISA:
if (unit_prd.cmd_state == unit_prd.CmdState.DONE) or (unit_prd.cmd_state == unit_prd.CmdState.FAIL):
_handle_read_isa(module_prd, unit_prd, [constants.ADDR_UG_LITERA_1, constants.ADDR_UG_LITERA_2, constants.ADDR_UG_LITERA_3])
flag_write_isa = false
state = STATE_MASHINE.UG_SET_RAY
STATE_MASHINE.UG_SET_RAY:
var addr: int = constants.ADDR_UG_LITERA_1
if current_litera == 3 or current_litera == 5 or current_litera == 7:
addr = constants.ADDR_UG_LITERA_2
if unit_prd.isa_ports.has(addr) and (unit_prd.cmd_state == unit_prd.CmdState.DONE):
control_timer.stop()
if unit_prd.isa_ports[addr] & 0x07 == 0:
state = STATE_MASHINE.UG_SET_RAY_1
elif unit_prd.isa_ports[addr] & 0x07 == 1:
@@ -170,28 +206,36 @@ class TestPRD extends Node:
state = STATE_MASHINE.UG_SET_RAY_0
STATE_MASHINE.UG_SET_RAY_0:
_handle_ug_set_state(0x0)
await get_tree().create_timer(1.0).timeout
state = STATE_MASHINE.READ_ISA
if flag_si_fs_input and not flag_write_isa:
control_timer.stop()
_handle_ug_set_state(0x0)
await get_tree().create_timer(0.5).timeout
state = STATE_MASHINE.READ_ISA
STATE_MASHINE.UG_SET_RAY_1:
_handle_ug_set_state(0x1)
state = STATE_MASHINE.READ_ISA
if not flag_write_isa:
_handle_ug_set_state(0x1)
state = STATE_MASHINE.READ_ISA
STATE_MASHINE.UG_SET_RAY_2:
_handle_ug_set_state(0x2)
state = STATE_MASHINE.READ_ISA
if not flag_write_isa:
_handle_ug_set_state(0x2)
state = STATE_MASHINE.READ_ISA
STATE_MASHINE.UG_SET_RAY_3:
_handle_ug_set_state(0x3)
state = STATE_MASHINE.READ_ISA
if not flag_write_isa:
_handle_ug_set_state(0x3)
state = STATE_MASHINE.READ_ISA
STATE_MASHINE.UG_SET_RAY_4:
_handle_ug_set_state(0x4)
state = STATE_MASHINE.READ_ISA
if not flag_write_isa:
_handle_ug_set_state(0x4)
state = STATE_MASHINE.READ_ISA
STATE_MASHINE.UG_SET_RAY_5:
_handle_ug_set_state(0x5)
state = STATE_MASHINE.READ_ISA
if not flag_write_isa:
_handle_ug_set_state(0x5)
state = STATE_MASHINE.READ_ISA
STATE_MASHINE.IN_EMS_STOP:
ems_6666_timer.stop()
state = STATE_MASHINE.FS_TURN_OFF
STATE_MASHINE.FS_TURN_OFF:
ems_6666_timer.stop()
_handle_fs_turn_off_state()
state = STATE_MASHINE.STOP_CONTROL
STATE_MASHINE.STOP_CONTROL:
@@ -248,28 +292,27 @@ class TestPRD extends Node:
elif self_name == '' or self_name == '' or self_name == '' or self_name == '':
dic_att['ATT_UM_1'] = constants.ATT_UM_2
dic_att['ATT_UM_2'] = constants.ATT_UM_3
control_label.text = 'Выполняется настройка угла (%s) и атт (%s, %s, %s)' % [
var log_text = dic_att.ATT_UM_3 if current_litera == 1 else dic_att.ATT_UM_1 if current_litera in [2, 4, 6] else dic_att.ATT_UM_2
control_label.text = 'Выполняется настройка угла (%s) и атт (0x0%s)' % [
dic_att.RAY_DOU_NUM,
dic_att.ATT_UM_1,
dic_att.ATT_UM_2,
dic_att.ATT_UM_3,
log_text
]
on_ug_setting(module_prd, unit_prd, dic_att)
flag_write_isa = on_ug_setting(module_prd, unit_prd, dic_att)
func _on_ems_6666_timer() -> void:
print_debug('Write 6666')
module_prd.cmd_array.append([unit_prd.CmdCode.WRITE_ISA, [constants.BASE_ADDR_EMS_G, 6666]])
func _handle_fs_turn_off_state() -> void:
control_label.text = 'Выполняется отключение ФС-%s' % current_litera
flag_fs_status_ok = false
manage_fs(false, self_name, pribor_config, fs_parameters, current_litera, constants.POWER_UM)
func _handle_stop_control_state() -> void:
control_label.text = 'Выполняется завершение проверки ФС-%s' % current_litera
flag_timer_started = false
_advance_to_next_fs()
state = STATE_MASHINE.INIT
@@ -313,7 +356,7 @@ class TestPRD extends Node:
add_child(ems_6666_timer)
ems_6666_timer.timeout.connect(_on_ems_6666_timer)
ems_6666_timer.wait_time = 1.5
ems_6666_timer.wait_time = 1.0
func _process_dkm_status(status: PackedByteArray) -> void:
@@ -322,7 +365,15 @@ class TestPRD extends Node:
var dkm_bit = _get_dkm_bit_for_current_fs(current_litera, constants)
if dkm_bit == 0:
control_results['dkm_1'] = check_dkm(status, dkm_bit)
elif dkm_bit == 1:
var addr: int = constants.ADDR_UG_LITERA_1
if current_litera == 3 or current_litera == 5 or current_litera == 7:
addr = constants.ADDR_UG_LITERA_2
if not unit_prd.isa_ports.has(addr) or not (unit_prd.cmd_state == unit_prd.CmdState.DONE):
return
if not unit_prd.isa_ports[addr] & 0x07 == 6: return
if dkm_bit == 1:
control_results['dkm_2'] = check_dkm(status, dkm_bit)
elif dkm_bit == 2:
control_results['dkm_3'] = check_dkm(status, dkm_bit)
@@ -379,16 +430,15 @@ class TestPRD extends Node:
## Установка угла и аттенюации для УМ
static func on_ug_setting(prd_module: Object, prd_unit: Object, settings_ug: Dictionary) -> void:
static func on_ug_setting(prd_module: Object, prd_unit: Object, settings_ug: Dictionary) -> bool:
var result_1 = ((settings_ug.ATT_UM_1 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07)
var result_2 = ((settings_ug.ATT_UM_2 & 0x07) << 3) | (settings_ug.RAY_DOU_NUM & 0x07)
prd_module.cmd_array.append([prd_unit.CmdCode.WRITE_ISA, [ settings_ug.BASE_EMS_G, 6666,
settings_ug.ADDR_UG_LITERA_1, result_1,
prd_module.cmd_array.append([prd_unit.CmdCode.WRITE_ISA, [ settings_ug.ADDR_UG_LITERA_1, result_1,
settings_ug.ADDR_UG_LITERA_2, result_2,
settings_ug.ADDR_UG_LITERA_3, settings_ug.ATT_UM_3,
]
])
return true
static func _handle_read_isa(prd_module: Object, prd_unit: Object, read_isa_ports: Array) -> void:
@@ -414,6 +464,7 @@ class TestPRD extends Node:
params.width,
sectors[litera - 1] if litera == 1 else sectors[litera - 5] if litera > 5 else sectors[litera - 4] if litera > 3 else sectors[litera - 2]
])
signaller.emit_signal('emit_changed', mode)
signaller.emit_signal('interfer_init', interfer_name, fs_arr, power_um)
@@ -635,7 +686,6 @@ class TestPRD extends Node:
for i_pow_arr in ray_dic.values():
for i_pow in i_pow_arr.size():
if i_pow_arr[i_pow] < cnst.POWER_THRESHOLD:
#print_debug('dou_%s: false' % litera)
all_dou_ok = false
control_dic[dou] = all_dou_ok

View File

@@ -9,8 +9,8 @@ var UnitProfiles: Dictionary[StringName, Array] = { \
# < Название: Протокол, Адрес, <Порт>|[, Порт], Широковещательное, Привязывать, Комментарий >
'уарэп-яу07-частный': ['yau07rx', ['10.1.1.2', 50002, false, true], 'IP-адрес для приёма частных сообщений от ЯУ-07'],
'уарэп-яу07-общий': ['yau07rx', ['*', 50000, true, true], 'IP-адрес для приёма широковещательных сообщений от ЯУ-07'],
'уарэп-капсрпб': ['capsrpb', ['127.0.0.1', 42023, 42022, false, true], 'IP-адрес для обмена сообщениями со службой \"МП550\" (СТЦ)'],
'уарэп-трасса': ['trassa', ['127.0.0.1', 50200, 10004, false, true], 'IP-адрес для обмена сообщениями с \"Трассой\"'],
'уарэп-капсрпб': ['capsrpb', ['127.0.0.1', '127.0.0.1', 42023, 42022, false, true], 'IP-адрес для обмена сообщениями со службой \"МП550\" (СТЦ)'],
'уарэп-трасса': ['trassa', ['192.168.1.23', '192.168.1.34', 50200, 10004, false, true], 'IP-адрес для обмена сообщениями с \"Трассой\"'],
'уарэп-эмс': ['yau07tx', ['10.1.1.52', 50052, false, false], 'IP-адрес прибора УФ'],
'уарэп-яу07-2в': ['yau07tx', ['10.1.1.22', 50022, false, false], 'IP-адрес прибора ПРД-В2'],
'уарэп-яу07-2н': ['yau07tx', ['10.1.1.21', 50021, false, false], 'IP-адрес прибора ПРД-Н2'],
@@ -35,6 +35,11 @@ var UnitProfiles: Dictionary[StringName, Array] = { \
# < Название: Протокол, < Имя порта, Адрес СПТ-25, Скорость, Чётность, Бит на символ, Стоп битов >, Комментарий >
'уарэп-спт25-1': ['spt25', ['/dev/ttyUSB1', 0, 19200, 'N', 8, 1], 'Прибор СПТ-25 (G1)'],
'уарэп-спт25-2': ['spt25', ['/dev/ttyUSB2', 0, 19200, 'N', 8, 1], 'Прибор СПТ-25 (G2)'],
'уарэп-афсп-левый': [null, [], 'Прибор АФСП левого борта'],
'уарэп-афсп-правый': [null, [], 'Прибор АФСП правого борта'],
'уарэп-бпо-1': [null, [], 'Прибор БПО 1'],
'уарэп-бпо-2': [null, [], 'Прибор БПО 2'],
'уарэп-карта': [null, [], 'Сервер карты'],
}
## Параметры цели.
@@ -45,7 +50,7 @@ var UnitProfiles: Dictionary[StringName, Array] = { \
const FREQ_MAX: = 6000.0
const FREQ_MIN: = 400.0
const WIDTH_MAX: = 100.0
const WIDTH_MAX: = 120.0
const WIDTH_MIN: = 0.0
const DUR_MAX: = 1000000.0
const PERIOD_MAX: = 1000000.0
@@ -74,7 +79,7 @@ func _ready() -> void:
log.warning('Будут использованы настройики по умолчанию.')
return
var json_data = json_conv.get_data()
settings_program.merge(json_data)
settings_program.merge(json_data, true)
for key in settings_program:
ProjectSettings.set_setting('application/config/%s' % key, settings_program[key])
for key: StringName in UnitProfiles.keys():

View File

@@ -34,6 +34,10 @@ signal режим_эмс()
## Вызывается при переходе в режим [b]Настройка[/b].
signal режимастройки()
## Вызывается при включении/отключении режима [b]Тренаж[/b].[br]
## [param val] - [b]true[/b] тренаж включён.
signal режимренаж(val: bool)
## Вызывается, когда оператор переводит программу в режим [b]Автомат выбора цели и помехи[/b].
signal full_auto()
@@ -189,3 +193,11 @@ signal update_scale_map(new_scale)
## Вызывается при изменении текущих координат.[br]
## [param new_coordinates] - обновленное значение координат ([b]true[/b]
signal update_coordinates_map(new_coordinates)
## Вызывается при изменении исправности прибора УФ.[br]
## [param uf_serviceaability] - обновленное значение состояния исправности ([b]true[/b]
signal update_uf_serviceability(uf_serviceaability: bool)
signal tool_tip(new_ctrl_pos)

View File

@@ -13,40 +13,11 @@ class SPT25 extends unit.Unit:
func _to_string() -> String: return String('СПТ-25 %s %s' % [self.name, ['отключен', 'на связи'][int(online)]])
##Вычисление контрольной суммы
func sciCalcFCS(src: PackedByteArray) -> int:
var P_DIV = 0
var ln = src[0]
var FCS = ~((src[2]<<8) + src[1])
for i in range(3, ln):
var C = src[i]
for j in 8:
if C & 1:
if FCS & 1:
FCS = ((FCS >> 1) | 0x8000)^P_DIV
else:
FCS = ((FCS >> 1) | 0x8000)
else:
if FCS & 1:
FCS = (FCS >> 1) ^ P_DIV
else:
FCS = FCS >> 1
C >>= 1
for j in 16:
if FCS & 1:
FCS = (FCS >> 1) ^ P_DIV
else:
FCS = FCS >> 1
return ~FCS
func _init(nm) -> void:
self.name = nm
tx_data.resize(5)
tx_data[0] = 0 # Адрес абонента, которому предназначен пакет
tx_data[1] = CmdCode.INFO # Тип пакета, КОД КОМАНДЫ - Получить информацию о состоянии преобразователя
tx_data[2] = 0 # Данные
tx_data[3] = 0 # Данные
tx_data[4] = 0 # Данные
func _init(unit_name) -> void:
self.name = unit_name
tx_data.resize(2)
tx_data[0] = 0 # Адрес абонента, которому предназначен пакет
tx_data[1] = CmdCode.INFO # Тип пакета, КОД КОМАНДЫ - Получить информацию о состоянии преобразователя
func parse(rx_data: PackedByteArray, tick: int):

View File

@@ -45,13 +45,13 @@ signal threats_resized(th: Dictionary)
func _ready() -> void:
var threats = {} ## Список целей. Индекс - <номер цели>
var unit_caps = network.get_unit_instance('уарэп-капсрпб')
var unit_5p28 = network.get_unit_instance('уарэп-5п28')
var timer_check_lost: = Timer.new()
var timer_aoa_update: = Timer.new()
add_child(timer_check_lost)
add_child(timer_aoa_update)
var threats = {} ## Список целей. Индекс - <номер цели>
unit_caps.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(settings.ThreatParams.time_lost, threats))
@@ -69,7 +69,7 @@ func _ready() -> void:
## Периодически удаляет устаревшие цели.
func on_timer_check_lost(time_lost: int, threats: Dictionary):
var tick = Time.get_ticks_msec()
var tick: = Time.get_ticks_msec()
var sz: = threats.size()
for th in threats.values():
if (tick - th.tick_rx) >= time_lost:
@@ -84,7 +84,7 @@ func on_timer_aoa_update(threats:Dictionary, tmr):
tmr.start(1.0)
## отправляет словарь целей в юнит, для запаковки и отправки в 5П28.
func on_get_threats(unit, threats): unit.pack_threats(threats)
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
@@ -115,7 +115,7 @@ func on_interfer_init(interfer_name, fs_arr, power, threats):
sel_threats.append(threat)
if threat.auto_selected:
sel_threats.append(threat)
if len(sel_threats) or (len(fs_arr)):
if len(sel_threats) or len(fs_arr):
signaller.emit_signal('interfer_create', interfer_name, sel_threats, fs_arr, power)
@@ -128,20 +128,22 @@ func on_data_capsrpb_received(unit: capsrpb.CapsRpb, threats: Dictionary):
var mis = unit.json_dic['mis']
var sz: = threats.size()
for dic_th in mis:
if dic_th is Dictionary:
if dic_th.has('id'):
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
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
call_deferred('emit_signal', 'threat_new', th)
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
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
call_deferred('emit_signal', 'threat_new', th)
if sz != threats.size():
call_deferred('emit_signal', 'threats_resized', threats)

View File

@@ -9,7 +9,7 @@ func round_to(v: float, a: float) -> float: return snappedf(v, -a if v < 0 else
## Возвращает [b]true[/b], если [param val] число, [b]false[/b] - если иначе.
func type_is_num(val) -> bool: return (typeof(val) == TYPE_INT) or (typeof(val) == TYPE_FLOAT)
func type_is_num(val) -> bool: return (val is int) or (val is float)
## Возвращает значение в радианах для угла в градусах [param val].
@@ -33,7 +33,7 @@ func is_overlap(x1, x2, y1, y2) -> bool: return max(x1, y1) <= min(x2, y2)
## [param msg] - сообщение об ошибке
func allways(val: bool, msg: String = '<не указано>'):
if val: return
push_error('ошибка: %s\n' % msg)
push_error('%s\n' % msg)
get_tree().quit(Error.FAILED)

View File

@@ -1,5 +1,4 @@
class_name trassa_unit
extends Node
class_name trassa_unit extends Node
const ONLINE_TIMEOUT: int = 5000 # Время ожидания данных
const REQUEST_PERIOD: int = 3000 # Период отправки, мс
@@ -7,24 +6,23 @@ const WORDS_TOTAL: int = 75
const NOINFO: int = 0x80000000
class Trassa extends unit.Unit:
var source_addr: = []
var unit_caps = network.get_unit_instance('уарэп-капсрпб')
var source_addr: Array
var tx_stack: Array[int] = []
var msg_counter: int = 0
var ecms: Dictionary = {} # Словарь всех активных помех
var srn = 0
var srn = 0
var jtids = 0
var prinud_but: Array = []
var forced_buttons: Array = [] # Храним ссылки на кнопки
# Инициализация
func _init(nm: StringName, buttons: Array = []) -> void:
self.name = nm
self.forced_buttons = buttons
self.forced_buttons = buttons
tx_stack.resize(WORDS_TOTAL)
tx_stack.fill(NOINFO)
interfer.connect("interfer_resized", Callable(self, "on_interfer_resized"))
interfer.connect('interfer_resized', Callable(self, 'on_interfer_resized'))
# Обработка полученного пакета
@@ -32,7 +30,7 @@ class Trassa extends unit.Unit:
rx_tick = tick
if not online:
online = true
emit_signal("line_changed", self)
emit_signal('line_changed', self)
var words: Array[int] = []
var offset: int = 0
while offset < rx_data.size():
@@ -85,7 +83,7 @@ class Trassa extends unit.Unit:
func process(now_tick: int) -> int:
if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT):
online = false
emit_signal("line_changed", self)
emit_signal('line_changed', self)
if (now_tick - tx_tick) > REQUEST_PERIOD:
tx_tick = now_tick
msg_counter += 1
@@ -119,15 +117,15 @@ class Trassa extends unit.Unit:
tx_stack[65] = 0
tx_stack[66] = 0
for ecm in ecms.values():
if ecm.krp == "srni1" and ecm.svk == 1:
if ecm.krp == 'srni' and ecm.svk == 1:
tx_stack[65] = 1
if ecm.krp == "svi1" and ecm.svk == 1:
if ecm.krp == 'svi1' and ecm.svk == 1:
tx_stack[66] = 1
tx_stack[1] = msg_counter
# Обработка указаний от Трассы по кнопке
func btn_trassa_pressed() -> void:
func btn_trassa_pressed() -> void:
var state = ProjectSettings.get_setting('application/config/Внешнее указание Трасса', false)
if state == true:
var tree: SceneTree = Engine.get_main_loop()
@@ -154,12 +152,12 @@ class Trassa extends unit.Unit:
else:
tx_stack[66] = 0
for ecm in ecms.values():
if ecm.krp == "svi1" and ecm.svk == 1:
if ecm.krp == 'svi1' and ecm.svk == 1:
ecm.krp = interfer.INTERFER_OFF
interfer.send_ecm(ecm, unit_caps)
signaller.emit_signal('interfer_off', ecm)
for ecm in ecms.values():
if ecm.krp == "svi1" and ecm.svk == 1:
if ecm.krp == 'svi1' and ecm.svk == 1:
ecm.krp = interfer.INTERFER_OFF
interfer.send_ecm(ecm, unit_caps)
signaller.emit_signal('interfer_off', ecm)

View File

@@ -1,9 +1,10 @@
{
"Адрес АФСП левого борта": "http://172.22.246.13:8081/selftest",
"Адрес АФСП правого борта": "http://172.22.246.11:8082/selftest",
"Адрес БПО левого борта": "http://172.22.246.13:8081/selftest",
"Адрес БПО правого борта": "http://172.22.246.11:8082/selftest",
"Адрес БПО левого борта": "http://172.22.246.13:8081/selftest?presetType=bpo&400000000",
"Адрес БПО правого борта": "http://172.22.246.11:8082/selftest?presetType=bpo&400000000",
"Виртуальная клавиатура": false,
"Внешнее указание Трасса": false,
"Внешнее управление": false,
"Кнопка «JTIDS»": false,
"Кнопка «К1»": false,
@@ -22,28 +23,32 @@
"Кнопка «СВ-И1»": false,
"Кнопка «СВ-М2»": false,
"Ограниченный режим": false,
"Период опроса состояния АФСП, секунды": "30",
"Период опроса состояния БПО, секунды": "30",
"Скрыть вкладку ЭМС 2": true,
"Текущая версия ПО УАРЭП": "HEAD 48353cc Fri Sep 5 14:44:15 2025 +0300",
"Шаблон адреса сервера карт": "http://169.254.27.71:8001/osm_tiles/{z}/{x}/{y}.png",
"Текущая версия ПО УАРЭП": "master b2633d8 Thu Sep 11 16:26:39 2025 +0300",
"Шаблон адреса сервера карт": "http://10.1.1.2:8001/osm_tiles/{z}/{x}/{y}.png",
"навигация": [
"*",
60000,
true,
true
],
"уареп-трасса": "127.0.0.1,127.0.0.1,50200,10004",
"уарэп-5п28": [
"127.0.0.1",
50000
50777
],
"уарэп-капсрпб": [
"127.0.0.1",
"192.168.11.102",
"192.168.11.105",
42023,
42022,
false,
true
],
"уарэп-спт25-1": [
"/dev/ttyUSB1",
"/home/user/tty0",
0,
19200,
"N",
@@ -51,7 +56,7 @@
1
],
"уарэп-спт25-2": [
"/dev/ttyUSB2",
"/home/user/tty1",
0,
19200,
"N",
@@ -59,7 +64,7 @@
1
],
"уарэп-щ3": [
"/dev/ttyUSB0",
"/home/user/tty3",
7,
19200,
"N",
@@ -152,8 +157,8 @@
true
],
"уарэп-яу07-частный": [
"10.1.1.2",
50002,
"10.1.1.253",
50253,
false,
true
]

View File

@@ -1,4 +1,4 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://s6xe8igevnv2"]
[gd_resource type="ShaderMaterial" load_steps=2 format=4 uid="uid://s6xe8igevnv2"]
[sub_resource type="Shader" id="1"]
code = "shader_type canvas_item;
@@ -15,6 +15,7 @@ uniform vec4 color1: source_color = vec4(0.39, 0.44, 0.50, 0.4);
uniform float radius_inner_0 = RADIUS_INNER_0;
uniform float radius_inner_1 = RADIUS_INNER_1;
uniform float radius_outter = 550.0; /* Радиус внешний. Должно быть равно ant_band_r1_6 */
uniform float alpha: hint_range(0.0, 1.0) = 0.5;
uniform int mode = 0; /* Режим отображения. Приоритет РТО - 0, приоритет РЛС - 1 */
const int ant_band_count_0 = 2;
@@ -41,8 +42,7 @@ const float ant_band_r1_4[] = {450.0, 530.0};
const float ant_band_r1_5[] = {500.0, 540.0};
const float ant_band_r1_6[] = {550.0, 550.0};
uniform vec3 ant_band_c[28];
uniform vec4 ant_band_c[28];
const float d4 = 90.0;
const float ds = 1.0;
@@ -76,21 +76,19 @@ void antenas(inout vec4 c, vec2 uv, vec2 p0, int cnt, float r0, float r1, inout
index--;
j = index - 3;
}
col.x = ant_band_c[j].x;
col.y = ant_band_c[j].y;
col.z = ant_band_c[j].z;
col.rgb = ant_band_c[j].rgb;
index++;
col.a = 0.5;
float v = float(i & 1);
vec4 color = v * col + (1.0f - v) * col;
sector(c, uv, p0, float(i) * da, da, r0, r1, color);
}
col.a = alpha + (random_timed(uv) - 0.5f) * ant_band_c[j].a;
float v = float(i & 1);
vec4 color = v * col + (1.0f - v) * col;
sector(c, uv, p0, float(i) * da, da, r0, r1, color);
}
}
void vertex()
{
rotate_vec2(VERTEX, radians(rotation), pc0);
rotate_vec2(VERTEX, radians(360.0 - rotation), pc0);
}
@@ -98,7 +96,7 @@ void fragment()
{
ivec2 isz = textureSize(TEXTURE, 0);
vec2 uv = UV * vec2(float(isz.x), float(isz.y)); // координаты текущей точки в пикселях
COLOR = vec4(0, 0, 0, 0); //texture(TEXTURE, UV); // Цвет текущей точки
COLOR = vec4(0, 0, 0, 0);
int index = 0;
// Сетка антенн
antenas(COLOR, uv, pc0, ant_band_count_0, ant_band_r0_0[mode], ant_band_r1_0[mode], index);
@@ -120,5 +118,6 @@ shader_parameter/color1 = Color(0.3315, 0.45645, 0.51, 0.537255)
shader_parameter/radius_inner_0 = 200.0
shader_parameter/radius_inner_1 = 480.0
shader_parameter/radius_outter = 550.0
shader_parameter/alpha = 0.5
shader_parameter/mode = 0
shader_parameter/ant_band_c = PackedVector3Array(0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5, 0.38, 0.47, 0.51, 0.39, 0.44, 0.5)
shader_parameter/ant_band_c = PackedVector4Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

View File

@@ -4,18 +4,18 @@ shader_type canvas_item;
/* Закрашенный сектор окружности ограниченный угловым сектором и радиусами */
uniform vec4 color: source_color = vec4(1, 1, 1, 1);
uniform vec4 clip_color: source_color = vec4(1.0, 0.5, 0.5, 1.0);
uniform float width: hint_range(0.0, 360.0, 0.1) = 45.0;
uniform float band: hint_range(0.0, 0.125) = 0.02;
uniform float radius: hint_range(0.0, 0.125) = 0.08;
uniform float dir: hint_range(0.0, 360.0) = 0.0;
uniform float inner_clip: hint_range(0.0, 0.125) = 0.045;
instance uniform vec4 color: source_color = vec4(1, 1, 1, 1);
instance uniform vec4 clip_color: source_color = vec4(1.0, 0.5, 0.5, 1.0);
instance uniform float width: hint_range(0.0, 360.0, 0.1) = 45.0;
instance uniform float band: hint_range(0.0, 0.125) = 0.02;
instance uniform float radius: hint_range(0.0, 0.125) = 0.08;
instance uniform float dir: hint_range(0.0, 360.0) = 0.0;
instance uniform float inner_clip: hint_range(0.0, 0.125) = 0.045;
const vec2 center = vec2(0.125, 0.125); /* Центр. Должен быть в (0.5, 0.5), но это не так */
const float dsa = 0.0025; /* Относительное расстояние на котором выполняется сглаживание краёв по радиальным линиям */
const float dsr = 0.00025; /* Относительное расстояние на котором выполняется сглаживание краёв по круговым линиям */
const float dsa = 0.003; /* Относительное расстояние на котором выполняется сглаживание краёв по радиальным линиям */
const float dsr = 0.0003; /* Относительное расстояние на котором выполняется сглаживание краёв по круговым линиям */
vec4 sector(vec4 c, vec2 uv_pos, float r0, float r1, float w)

View File

@@ -1,6 +1,12 @@
const float DS = 0.004; /* Относительное расстояние на котором выполняется сглаживание краёв */
float random_timed(vec2 uv)
{
return fract(sin(TIME * dot(uv.xy, vec2(12.9898, 78.233))) * 43758.5453123);
}
float smooth_px(float r, float R, float ds)
{
return 1.0 - smoothstep(R - ds, R + ds, r);

View File

@@ -324,9 +324,12 @@ func _set_row_selected(i_row: int, selected: bool = true) -> void:
if nodes.has(selector_key) and (not selected):
var node = nodes[node_key]
var selector = nodes[selector_key]
node.remove_child(selector)
selector.queue_free()
nodes.erase(selector_key)
if is_instance_valid(selector):
node.remove_child(selector)
selector.queue_free()
else:
push_warning('обращение к удалённому элементу \"%s\"' % selector_key)
elif (not nodes.has(selector_key)) and selected:
var selector = ScnSelector.instantiate()
var rect: = [0, 0, 0, 0]