Доработка.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -38,3 +38,5 @@ modbus/serial/__pycache__
|
|||||||
/scenes/pribor-prd-k/kasseta-fs-kd.tscn.bak
|
/scenes/pribor-prd-k/kasseta-fs-kd.tscn.bak
|
||||||
/scenes/pribor-prd-k/pribor-prd-k.tscn.bak
|
/scenes/pribor-prd-k/pribor-prd-k.tscn.bak
|
||||||
/scenes/pribor-prd-n/kasseta-fs-nd.tscn.bak
|
/scenes/pribor-prd-n/kasseta-fs-nd.tscn.bak
|
||||||
|
|
||||||
|
*.patch
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
- [Проброс последовательных портов через Ethernet](http://gitea.srez.local:3000/sasha80/uart-forwarder)
|
- [Проброс последовательных портов через Ethernet](http://gitea.srez.local:3000/sasha80/uart-forwarder)
|
||||||
- [Сборка Godot из исходников](http://gitea.srez.local:3000/sasha80/godot-build)
|
- [Сборка Godot из исходников](http://gitea.srez.local:3000/sasha80/godot-build)
|
||||||
- [Сервер карт](http://gitea.srez.local:3000/sasha80/map-tiles)
|
- [Сервер карт](http://gitea.srez.local:3000/sasha80/map-tiles)
|
||||||
- [Генераторы PCM файлов для модулей ФС](http://gitea.srez.local:3000/danil_tim/Signals_to_the_MP-550)
|
|
||||||
|
|
||||||
# Ссылки на имитаторы
|
# Ссылки на имитаторы
|
||||||
|
|
||||||
@@ -36,4 +35,5 @@
|
|||||||
|
|
||||||
- После клонирования запустить скрипт `git-hooks-config.sh`
|
- После клонирования запустить скрипт `git-hooks-config.sh`
|
||||||
- В среде **Windows** запуск скрипта `git-hooks-config.sh` производить из оболочки `git bash`
|
- В среде **Windows** запуск скрипта `git-hooks-config.sh` производить из оболочки `git bash`
|
||||||
- При необходимости обновить `settings.json`
|
- Нужно обновить `settings.json`
|
||||||
|
- поиск циклических зависимостей
|
||||||
|
|||||||
164
check-graph.py
Normal file
164
check-graph.py
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import networkx as nx
|
||||||
|
|
||||||
|
# pip install networkx plotly numpy scipy
|
||||||
|
|
||||||
|
def build_class_graph(directory):
|
||||||
|
"""Builds a directed acyclic graph of class dependencies."""
|
||||||
|
# Create a graph to store the dependencies
|
||||||
|
graph = nx.DiGraph()
|
||||||
|
dependencies = {}
|
||||||
|
|
||||||
|
# Find all .gd files in the directory
|
||||||
|
for root, dirs, files in os.walk(directory):
|
||||||
|
for file in files:
|
||||||
|
if not file.endswith(".gd"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
file_path = os.path.join(root, file)
|
||||||
|
# Find the class name in the file
|
||||||
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
|
contents = f.read()
|
||||||
|
match = re.search(r"^class_name\s+(\w+)", contents, re.MULTILINE)
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
|
||||||
|
class_name = match.group(1)
|
||||||
|
graph.add_node(class_name)
|
||||||
|
|
||||||
|
# Find the dependencies of the class
|
||||||
|
for dep_match in re.finditer(
|
||||||
|
r"^\s*extends\s+(\w+)", contents, re.MULTILINE
|
||||||
|
):
|
||||||
|
dep_name = dep_match.group(1)
|
||||||
|
graph.add_edge(class_name, dep_name)
|
||||||
|
|
||||||
|
# Find all uses of the class name in other files
|
||||||
|
for root2, dirs2, files2 in os.walk(directory):
|
||||||
|
for file2 in files2:
|
||||||
|
if not file2.endswith(".gd"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if file_path == os.path.join(root2, file2):
|
||||||
|
continue
|
||||||
|
|
||||||
|
with open(os.path.join(root2, file2), "r", encoding="utf-8") as f2:
|
||||||
|
contents2 = f2.read()
|
||||||
|
if re.search(rf"\b{class_name}\b", contents2):
|
||||||
|
print(
|
||||||
|
file2.ljust(30, " "),
|
||||||
|
f"--> class_name {class_name}".ljust(50, " "),
|
||||||
|
f" from {file}",
|
||||||
|
)
|
||||||
|
graph.add_edge(class_name, file2)
|
||||||
|
dependencies[file2] = file
|
||||||
|
|
||||||
|
pos = nx.planar_layout(graph)
|
||||||
|
|
||||||
|
# Set the node positions in the graph
|
||||||
|
nx.set_node_attributes(graph, pos, "pos")
|
||||||
|
|
||||||
|
return graph, dependencies
|
||||||
|
|
||||||
|
|
||||||
|
def debug_graph(graph):
|
||||||
|
"""Builds and visualizes a graph of class dependencies in the directory."""
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
|
||||||
|
# Create the plotly figure
|
||||||
|
fig = go.Figure()
|
||||||
|
|
||||||
|
# Add the nodes to the figure
|
||||||
|
for node in graph.nodes():
|
||||||
|
x, y = graph.nodes[node]["pos"]
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scatter(
|
||||||
|
x=[x],
|
||||||
|
y=[y],
|
||||||
|
text=[node],
|
||||||
|
hovertext=[f"Class: {node}"],
|
||||||
|
mode="markers",
|
||||||
|
marker=dict(
|
||||||
|
symbol="circle", size=20, line=dict(width=1, color="black"),
|
||||||
|
),
|
||||||
|
name=node,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add the edges to the figure
|
||||||
|
for edge in graph.edges():
|
||||||
|
x0, y0 = graph.nodes[edge[0]]["pos"]
|
||||||
|
x1, y1 = graph.nodes[edge[1]]["pos"]
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scatter(
|
||||||
|
x=[x0, x1],
|
||||||
|
y=[y0, y1],
|
||||||
|
text=[f"{edge[0]} -> {edge[1]}", ""],
|
||||||
|
hovertext=[f"Depends on: {edge[1]}", ""],
|
||||||
|
mode="lines+markers+text",
|
||||||
|
line=dict(width=2, color="black"),
|
||||||
|
marker=dict(size=0),
|
||||||
|
textposition="middle right",
|
||||||
|
showlegend=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Customize the layout and style of the figure
|
||||||
|
fig.update_layout(
|
||||||
|
title="Class Dependency Graph",
|
||||||
|
title_font_size=24,
|
||||||
|
margin=dict(l=20, r=20, t=50, b=20),
|
||||||
|
hovermode="closest",
|
||||||
|
plot_bgcolor="white",
|
||||||
|
showlegend=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Show the figure
|
||||||
|
fig.show()
|
||||||
|
|
||||||
|
|
||||||
|
def find_circular_dependencies(dependencies):
|
||||||
|
"""Finds circular dependencies between classes in the directory."""
|
||||||
|
|
||||||
|
circular_dependencies = []
|
||||||
|
|
||||||
|
for file, dependency in dependencies.items():
|
||||||
|
visited = set()
|
||||||
|
path = [file]
|
||||||
|
|
||||||
|
while dependency and dependency not in visited:
|
||||||
|
visited.add(dependency)
|
||||||
|
path.append(dependency)
|
||||||
|
dependency = dependencies.get(dependency)
|
||||||
|
|
||||||
|
# Circular check
|
||||||
|
if dependency in path:
|
||||||
|
start_index = path.index(dependency)
|
||||||
|
circular_dependency = path[start_index:]
|
||||||
|
if circular_dependency not in circular_dependencies:
|
||||||
|
circular_dependencies.append(circular_dependency)
|
||||||
|
break
|
||||||
|
|
||||||
|
# Convert circular_dependencies to dependency paths
|
||||||
|
dependency_paths = []
|
||||||
|
for circular_dependency in circular_dependencies:
|
||||||
|
dependency_path = " -> ".join(circular_dependency)
|
||||||
|
dependency_paths.append(dependency_path)
|
||||||
|
|
||||||
|
return dependency_paths
|
||||||
|
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
graph, dependencies = build_class_graph("./")
|
||||||
|
debug_graph(graph)
|
||||||
|
circular_deps = find_circular_dependencies(dependencies)
|
||||||
|
print("----------------------------------")
|
||||||
|
if circular_deps:
|
||||||
|
print(" Circular dependencies found!")
|
||||||
|
for dep in circular_deps:
|
||||||
|
print("\t", dep)
|
||||||
|
else:
|
||||||
|
print(" No circular dependencies found.")
|
||||||
|
print("----------------------------------")
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
[ext_resource type="PackedScene" uid="uid://lwmw4egynmd1" path="res://scenes/контроль/контроль.tscn" id="3_txp0s"]
|
[ext_resource type="PackedScene" uid="uid://lwmw4egynmd1" path="res://scenes/контроль/контроль.tscn" id="3_txp0s"]
|
||||||
[ext_resource type="PackedScene" uid="uid://trt0q8th3bn2" path="res://scenes/журнал/журнал.tscn" id="4_cu5k8"]
|
[ext_resource type="PackedScene" uid="uid://trt0q8th3bn2" path="res://scenes/журнал/журнал.tscn" id="4_cu5k8"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dab6loryocc73" path="res://scenes/эмс/эмс.tscn" id="5_u71bh"]
|
[ext_resource type="PackedScene" uid="uid://dab6loryocc73" path="res://scenes/эмс/эмс.tscn" id="5_u71bh"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://musb21x2u0xs" path="res://scenes/эмс2/эмс2.tscn" id="6_41d34"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bnptm4rlp60dq" path="res://scenes/настройки/настройки.tscn" id="6_i8iv3"]
|
[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://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"]
|
[ext_resource type="Script" uid="uid://roajn6c6wvc1" path="res://scenes/tabs-switch/тренаж_режим.gd" id="9_41d34"]
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ visible = false
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
metadata/_tab_index = 3
|
metadata/_tab_index = 3
|
||||||
|
|
||||||
[node name="ЭМС ТГ" parent="tab_switch" instance=ExtResource("6_rsg03")]
|
[node name="ЭМС ТГ" parent="tab_switch" instance=ExtResource("6_41d34")]
|
||||||
visible = false
|
visible = false
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
metadata/_tab_index = 4
|
metadata/_tab_index = 4
|
||||||
|
|||||||
@@ -3,6 +3,5 @@
|
|||||||
[ext_resource type="Texture2D" uid="uid://cj1f2uy6qfvki" path="res://scenes/tilemap/23900.png" id="1_v0nwa"]
|
[ext_resource type="Texture2D" uid="uid://cj1f2uy6qfvki" path="res://scenes/tilemap/23900.png" id="1_v0nwa"]
|
||||||
|
|
||||||
[node name="23900" type="Sprite2D"]
|
[node name="23900" type="Sprite2D"]
|
||||||
rotation = -6.28319
|
|
||||||
scale = Vector2(0.496934, 0.496934)
|
scale = Vector2(0.496934, 0.496934)
|
||||||
texture = ExtResource("1_v0nwa")
|
texture = ExtResource("1_v0nwa")
|
||||||
|
|||||||
@@ -147,12 +147,11 @@ func _ready() -> void:
|
|||||||
signaller.connect('map_centered', on_map_centered)
|
signaller.connect('map_centered', on_map_centered)
|
||||||
if not Engine.is_editor_hint():
|
if not Engine.is_editor_hint():
|
||||||
var unit_nav = network.get_unit_instance('навигация')
|
var unit_nav = network.get_unit_instance('навигация')
|
||||||
unit_nav.connect('data_received', Callable(self, 'on_data_received'))
|
unit_nav.connect('data_received', on_data_received)
|
||||||
ProjectSettings.connect('settings_changed', _settings_changed)
|
ProjectSettings.connect('settings_changed', _settings_changed)
|
||||||
threats.connect('threat_new', Callable(self, '_on_threat_new'))
|
threats.connect('threat_new', Callable(self, '_on_threat_new'))
|
||||||
threats.connect('threat_lost', Callable(self, '_on_threat_lost'))
|
threats.connect('threat_lost', Callable(self, '_on_threat_lost'))
|
||||||
threats.connect('threat_update', Callable(self, '_on_threat_update'))
|
threats.connect('threat_update', Callable(self, '_on_threat_update'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _settings_changed():
|
func _settings_changed():
|
||||||
@@ -196,7 +195,7 @@ func add_mark_from_lon_lat(id: int, lon: float, lat: float, mark: Node, gap_size
|
|||||||
if _marks.has(id):
|
if _marks.has(id):
|
||||||
return false
|
return false
|
||||||
var wrld_pos: Vector2 = lonlat_to_world(lon, lat)
|
var wrld_pos: Vector2 = lonlat_to_world(lon, lat)
|
||||||
_marks[id] = {'id': id, 'position': wrld_pos, 'mark': mark, 'gap_size': gap_size} # Добавляем ID
|
_marks[id] = {'position': wrld_pos, 'mark': mark, 'gap_size': gap_size}
|
||||||
add_child(mark)
|
add_child(mark)
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
return true
|
return true
|
||||||
@@ -294,15 +293,20 @@ func _draw() -> void:
|
|||||||
for tx in range(t1.x, t2.x):
|
for tx in range(t1.x, t2.x):
|
||||||
for ty in range(t1.y, t2.y):
|
for ty in range(t1.y, t2.y):
|
||||||
_draw_tile(tx, ty, z)
|
_draw_tile(tx, ty, z)
|
||||||
|
# Рисование отметок
|
||||||
|
var n: = pow(2, z)
|
||||||
|
var dx: = n * tile_width
|
||||||
var c: Vector2 = $canvas.size / 2.0
|
var c: Vector2 = $canvas.size / 2.0
|
||||||
var r: float = c.length()
|
var r: float = c.length()
|
||||||
visible_marks_count = 0
|
visible_marks_count = 0
|
||||||
for dot in _marks.values():
|
for dot in _marks.values():
|
||||||
var screen_pos = world_to_screen(dot.position)
|
var scr_pos: Vector2 = world_to_screen(dot.position)
|
||||||
dot.mark.position = screen_pos
|
scr_pos.x = posmod(int(scr_pos.x), int(dx))
|
||||||
|
dot.mark.position = scr_pos
|
||||||
dot.mark.visible = is_mark_visible(dot)
|
dot.mark.visible = is_mark_visible(dot)
|
||||||
dot.mark.visible = c.distance_to(screen_pos) < (r - dot.gap_size)
|
dot.mark.visible = c.distance_to(scr_pos) < (r - dot.gap_size)
|
||||||
visible_marks_count += int(dot.mark.visible)
|
visible_marks_count += int(dot.mark.visible)
|
||||||
|
# Рисование границ
|
||||||
var p1: Vector2 = $canvas.position
|
var p1: Vector2 = $canvas.position
|
||||||
var p2: Vector2 = $canvas.size / Vector2(1, 20)
|
var p2: Vector2 = $canvas.size / Vector2(1, 20)
|
||||||
if is_out_border1 and _dragging:
|
if is_out_border1 and _dragging:
|
||||||
@@ -376,22 +380,33 @@ func _process(delta) -> void:
|
|||||||
update_scale_label()
|
update_scale_label()
|
||||||
|
|
||||||
|
|
||||||
func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile) -> void:
|
func process_online(result):
|
||||||
var unit_instance = network.get_unit_instance('уарэп-карта')
|
# ERROR: res://scenes/tilemap/tilemap.gd:396 - Invalid access to property or key 'online' on a base object of type 'Nil'.
|
||||||
_req_count -= 1
|
var unit_instance: = network.get_unit_instance('уарэп-карта')
|
||||||
remove_child(req)
|
if not unit_instance: return
|
||||||
req.queue_free()
|
|
||||||
|
|
||||||
if result != HTTPRequest.RESULT_SUCCESS:
|
if result != HTTPRequest.RESULT_SUCCESS:
|
||||||
if unit_instance.online:
|
if unit_instance.online:
|
||||||
unit_instance.online = false
|
unit_instance.online = false
|
||||||
unit_instance.emit_signal('line_changed', unit_instance)
|
unit_instance.emit_signal('line_changed', unit_instance)
|
||||||
_queue[tile.i] = tile
|
return false
|
||||||
return
|
|
||||||
|
|
||||||
|
unit_instance.rx_tick = Time.get_ticks_msec()
|
||||||
if not unit_instance.online:
|
if not unit_instance.online:
|
||||||
unit_instance.online = true
|
unit_instance.online = true
|
||||||
unit_instance.emit_signal('line_changed', unit_instance)
|
unit_instance.emit_signal('line_changed', unit_instance)
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func _response(result, code, _headers: Array, body: PackedByteArray, req, tile: Tile) -> void:
|
||||||
|
_req_count -= 1
|
||||||
|
remove_child(req)
|
||||||
|
req.queue_free()
|
||||||
|
|
||||||
|
if process_online(result):
|
||||||
|
_queue[tile.i] = tile
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
if code == 404:
|
if code == 404:
|
||||||
push_error('на сервере нет \"%s\"' % tile.url)
|
push_error('на сервере нет \"%s\"' % tile.url)
|
||||||
@@ -401,11 +416,6 @@ func _response(result, code, _headers: Array, body: PackedByteArray, req, tile:
|
|||||||
push_error('не удалось получить изображение (неверный формат?) из \"%s\"' % tile.url)
|
push_error('не удалось получить изображение (неверный формат?) из \"%s\"' % tile.url)
|
||||||
return
|
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)
|
tile.texture = ImageTexture.create_from_image(image)
|
||||||
_cache[tile.i] = tile
|
_cache[tile.i] = tile
|
||||||
|
|
||||||
@@ -707,7 +717,7 @@ func set_coordinates(lon: float, lat: float, course: float) -> void:
|
|||||||
add_mark_from_lon_lat(ship_id, lon, lat, ship_instance, 0.0)
|
add_mark_from_lon_lat(ship_id, lon, lat, ship_instance, 0.0)
|
||||||
else:
|
else:
|
||||||
_marks[ship_id].position = lonlat_to_world(lon, lat)
|
_marks[ship_id].position = lonlat_to_world(lon, lat)
|
||||||
ship_instance.rotation_degrees = course
|
ship_instance.rotation_degrees = fmod(course, 360.0)
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ func _ready():
|
|||||||
signaller.connect('map_user_panning', Callable(self, 'on_user_panning'))
|
signaller.connect('map_user_panning', Callable(self, 'on_user_panning'))
|
||||||
signaller.connect('update_coordinates_map', Callable(self, 'on_update_coordinates_label'))
|
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'))
|
||||||
signaller.connect('sector_klaster', Callable(self, 'sector_klaster'))
|
signaller.connect('sector_klaster', Callable(self, 'sector_klaster'))
|
||||||
signaller.connect('clear_klaster', Callable(self, 'clear_all_klaster'))
|
signaller.connect('clear_klaster', Callable(self, 'clear_all_klaster'))
|
||||||
var unit_nav = network.get_unit_instance('навигация')
|
var unit_nav = network.get_unit_instance('навигация')
|
||||||
unit_nav.connect('data_received', on_navi_data_received)
|
unit_nav.connect('data_received', on_navi_data_received)
|
||||||
|
|||||||
@@ -379,8 +379,8 @@ texture_normal = ExtResource("14_ggrwd")
|
|||||||
[connection signal="drag_continue" from="." to="." method="_on_drag_continue"]
|
[connection signal="drag_continue" from="." to="." method="_on_drag_continue"]
|
||||||
[connection signal="toggled" from="btn_view" to="." method="on_button_view_toggled"]
|
[connection signal="toggled" from="btn_view" to="." method="on_button_view_toggled"]
|
||||||
[connection signal="toggled" from="chk_auto" to="." method="on_value_changed"]
|
[connection signal="toggled" from="chk_auto" to="." method="on_value_changed"]
|
||||||
[connection signal="toggled" from="btn_activate" to="." method="on_btn_activate"]
|
|
||||||
[connection signal="toggled" from="btn_activate" to="." method="on_btn_activate_toggled"]
|
[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="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_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_plus_button_up"]
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ scale = Vector2(1.77945, 1.77945)
|
|||||||
texture = ExtResource("5_yqn2y")
|
texture = ExtResource("5_yqn2y")
|
||||||
|
|
||||||
[node name="СостояниеРэс2" type="Sprite2D" parent="Op-63"]
|
[node name="СостояниеРэс2" type="Sprite2D" parent="Op-63"]
|
||||||
|
visible = false
|
||||||
position = Vector2(281.865, 35.2331)
|
position = Vector2(281.865, 35.2331)
|
||||||
scale = Vector2(3.20301, 3.20301)
|
scale = Vector2(3.20301, 3.20301)
|
||||||
texture = ExtResource("6_m57px")
|
texture = ExtResource("6_m57px")
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ func _ready() -> void:
|
|||||||
unit_caps.connect('data_received', Callable(self, 'on_data_capsrpb_received').bind(ecms, seczaps))
|
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))
|
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_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_rcv', Callable(self, 'on_interfer_rcv').bind(unit_5p28, unit_caps, ecms))
|
||||||
signaller.connect('interfer_new', Callable(self, 'on_interfer_new').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('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('th_aoa_update', Callable(self, 'on_th_aoa_update').bind(ecms, unit_caps))
|
||||||
@@ -351,8 +351,8 @@ func map_msvk_to_ecms(unit_instance: unit.Unit, ecms: Dictionary):
|
|||||||
|
|
||||||
|
|
||||||
## Извлекает массив пространственно-частотных фильтров
|
## Извлекает массив пространственно-частотных фильтров
|
||||||
func map_mpchf_to_seczaps(unit_instance: unit.Unit, seczaps: Dictionary):
|
func map_mpchf_to_seczaps(unit_instance: unit.Unit, _seczaps: Dictionary):
|
||||||
var json_dic: = unit_instance.json_dic as Dictionary
|
var json_dic = unit_instance.json_dic
|
||||||
var mpchf = json_dic.get('mpchf', [])
|
var mpchf = json_dic.get('mpchf', [])
|
||||||
if mpchf is not Array: return
|
if mpchf is not Array: return
|
||||||
for item in mpchf:
|
for item in mpchf:
|
||||||
@@ -397,7 +397,7 @@ func on_interfer_create(interfer_name, sel_threats, fs_arr, power, u, ecms) -> v
|
|||||||
interfer_create(u, interfer_name, ecms, param, kni, id, fs, SOURCE_INTERFER[1], 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:
|
func on_interfer_rcv(interfer_params: Array, unit0, unit_caps, ecms) -> void:
|
||||||
var err: bool = false
|
var err: bool = false
|
||||||
var mode = interfer_params[0]
|
var mode = interfer_params[0]
|
||||||
var id = interfer_params[1]
|
var id = interfer_params[1]
|
||||||
@@ -425,7 +425,7 @@ func on_interfer_rcv(interfer_params: Array, unit0, ecms) -> void:
|
|||||||
if interfer_name == '':
|
if interfer_name == '':
|
||||||
err = true
|
err = true
|
||||||
if not err:
|
if not err:
|
||||||
interfer_create(unit0, interfer_name, ecms, param, aoa, id, cu, SOURCE_INTERFER[2], POW_DEFAULT)
|
interfer_create(unit_caps, interfer_name, ecms, param, aoa, id, cu, SOURCE_INTERFER[2], POW_DEFAULT)
|
||||||
unit0.on_interfer_accept(err)
|
unit0.on_interfer_accept(err)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ class_name navigation extends Node
|
|||||||
|
|
||||||
const ONLINE_TIMEOUT: = 5000 ## Время ожидания пакета, миллисекунды
|
const ONLINE_TIMEOUT: = 5000 ## Время ожидания пакета, миллисекунды
|
||||||
const pow_2_30: = pow(2.0, 30.0)
|
const pow_2_30: = pow(2.0, 30.0)
|
||||||
|
const FRACT_MAX: int = 3
|
||||||
|
|
||||||
## Источник данных навигации
|
## Источник данных навигации
|
||||||
class NaviSource extends unit.Unit:
|
class NaviSource extends unit.Unit:
|
||||||
var cmd_tick_rx: int = 0
|
var cmd_tick_rx: int = 0
|
||||||
|
var fract: int = 0
|
||||||
var data: = {} ## Принятые данные
|
var data: = {} ## Принятые данные
|
||||||
var source_addr: = [] ## Адрес отправителя
|
var source_addr: = [] ## Адрес отправителя
|
||||||
const akng_mode = {0:'тестовый', 1:'основной', 2:'резервный', 3:'аварийный'}
|
const akng_mode = {0:'тестовый', 1:'основной', 2:'резервный', 3:'аварийный'}
|
||||||
@@ -43,5 +45,8 @@ class NaviSource extends unit.Unit:
|
|||||||
if flags & (1 << 3):
|
if flags & (1 << 3):
|
||||||
data['speed'] = rx_data.decode_float(20) # Скорость, м/с
|
data['speed'] = rx_data.decode_float(20) # Скорость, м/с
|
||||||
data['err'] = rx_data.decode_u16(24) #
|
data['err'] = rx_data.decode_u16(24) #
|
||||||
emit_signal('data_received', data)
|
if fract == 0:
|
||||||
|
emit_signal('data_received', data)
|
||||||
|
fract += 1
|
||||||
|
fract %= FRACT_MAX
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#@tool
|
@tool
|
||||||
class_name Network extends Node
|
class_name Network extends Node
|
||||||
|
|
||||||
const YAU07_PROTO: = {'yau07tx': yau07.YaU07}
|
const YAU07_PROTO: = {'yau07tx': yau07.YaU07}
|
||||||
@@ -22,18 +22,20 @@ class SocketSerial extends SerialPort:
|
|||||||
'O': SerialPort.PARITY_ODD }
|
'O': SerialPort.PARITY_ODD }
|
||||||
static var tick: int
|
static var tick: int
|
||||||
var unit_instance: unit.Unit
|
var unit_instance: unit.Unit
|
||||||
|
var failed: = {}
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
connect('got_error', on_serial_got_error)
|
||||||
|
|
||||||
|
func on_serial_got_error(where: String, what: String):
|
||||||
|
if where not in failed:
|
||||||
|
push_error([where, what, unit_instance])
|
||||||
|
failed[where] = what
|
||||||
|
|
||||||
func on_serial_data(data: PackedByteArray):
|
func on_serial_data(data: PackedByteArray):
|
||||||
|
failed.clear()
|
||||||
unit_instance.parse(data, tick)
|
unit_instance.parse(data, tick)
|
||||||
|
|
||||||
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 format_buffer(data: PackedByteArray):
|
func format_buffer(data: PackedByteArray):
|
||||||
var buffer: PackedByteArray
|
var buffer: PackedByteArray
|
||||||
buffer.resize(64)
|
buffer.resize(64)
|
||||||
@@ -50,16 +52,16 @@ class SocketSerial extends SerialPort:
|
|||||||
buffer.resize(i)
|
buffer.resize(i)
|
||||||
return buffer
|
return buffer
|
||||||
|
|
||||||
func send_to(data: PackedByteArray):
|
func send_to(_data: PackedByteArray):
|
||||||
if not is_open():
|
if not is_open():
|
||||||
try_open()
|
call_deferred('try_open')
|
||||||
return
|
return
|
||||||
# var buffer = format_buffer(data) # Не проверено, но должно работать
|
# var buffer = format_buffer(data) # Не проверено, но должно работать
|
||||||
# Эта последовательность для запроса состояния, получена от разработчиков СПТ-25
|
# Эта последовательность для запроса состояния, получена от разработчиков СПТ-25
|
||||||
const tx_tula: = [0x7e, 0x01, 0x04, 0xbb, 0x50, 0x7e]
|
const tx_tula: = [0x7e, 0x01, 0x04, 0xbb, 0x50, 0x7e]
|
||||||
var sz = write_raw(tx_tula)
|
var sz = write_raw(tx_tula)
|
||||||
if sz != tx_tula.size():
|
if sz != tx_tula.size():
|
||||||
try_open()
|
call_deferred('try_close')
|
||||||
|
|
||||||
func _to_string() -> String: return 'последовательный порт \"%s\" @ %d (%s)' % [self.port, self.baudrate, 'открыт' if is_open() else 'закрыт']
|
func _to_string() -> String: return 'последовательный порт \"%s\" @ %d (%s)' % [self.port, self.baudrate, 'открыт' if is_open() else 'закрыт']
|
||||||
|
|
||||||
@@ -144,6 +146,15 @@ var send_sockets: Dictionary[StringName, SocketUDP] ## Таблица <имя
|
|||||||
var addr_port_to_unit_name: Dictionary[StringName, StringName] ## Преобразование адрес:порт в имя устройства
|
var addr_port_to_unit_name: Dictionary[StringName, StringName] ## Преобразование адрес:порт в имя устройства
|
||||||
|
|
||||||
|
|
||||||
|
func on_settings_changed(serial: SocketSerial):
|
||||||
|
serial.try_close()
|
||||||
|
var rc = serial.try_open()
|
||||||
|
if rc != Error.OK:
|
||||||
|
log.message(log.ERROR, 'невозможно открыть %s для \"%s\"' % [serial.port, serial.unit_instance.name])
|
||||||
|
else:
|
||||||
|
log.message(log.INFO, 'открыт %s для \"%s\"' % [serial.port, serial.unit_instance.name])
|
||||||
|
|
||||||
|
|
||||||
## [param unit_name] - Уникальное имя устройства[br]
|
## [param unit_name] - Уникальное имя устройства[br]
|
||||||
func create_socket_udp(unit_name: StringName) -> SocketUDP:
|
func create_socket_udp(unit_name: StringName) -> SocketUDP:
|
||||||
var st = settings.UnitProfiles[unit_name][1]
|
var st = settings.UnitProfiles[unit_name][1]
|
||||||
@@ -202,13 +213,10 @@ func create_serial(unit_instance: unit.Unit) -> SocketSerial:
|
|||||||
serial.bytesize = st[4]
|
serial.bytesize = st[4]
|
||||||
serial.stopbits = st[5]
|
serial.stopbits = st[5]
|
||||||
serial.unit_instance = unit_instance
|
serial.unit_instance = unit_instance
|
||||||
|
ProjectSettings.connect('settings_changed', func(): on_settings_changed(serial))
|
||||||
return serial
|
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]
|
## [param unit_name] - Уникальное имя устройства[br]
|
||||||
func create_modbus(unit_name: StringName) -> sch_3.Sch3:
|
func create_modbus(unit_name: StringName) -> sch_3.Sch3:
|
||||||
var unit_modbus: = sch_3.Sch3.new(unit_name)
|
var unit_modbus: = sch_3.Sch3.new(unit_name)
|
||||||
@@ -286,8 +294,6 @@ func _ready() -> void:
|
|||||||
if proto in SERIAL_PROTO:
|
if proto in SERIAL_PROTO:
|
||||||
var unit_instance = SERIAL_PROTO[proto].new(unit_name)
|
var unit_instance = SERIAL_PROTO[proto].new(unit_name)
|
||||||
var serial: = create_serial(unit_instance)
|
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_serial[unit_name] = unit_instance
|
||||||
units[unit_name] = unit_instance
|
units[unit_name] = unit_instance
|
||||||
serials[unit_name] = serial
|
serials[unit_name] = serial
|
||||||
@@ -391,6 +397,7 @@ func get_tcp_data(sock: SocketTCP, peer: StreamPeer, len_rx: int):
|
|||||||
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
|
if Engine.is_editor_hint(): return
|
||||||
tick = Time.get_ticks_msec()
|
tick = Time.get_ticks_msec()
|
||||||
RenderingServer.global_shader_parameter_set('tick_curent', tick)
|
RenderingServer.global_shader_parameter_set('tick_curent', tick)
|
||||||
for unit_name: StringName in units_udptx:
|
for unit_name: StringName in units_udptx:
|
||||||
@@ -424,5 +431,4 @@ func _process(_delta: float) -> void:
|
|||||||
|
|
||||||
## [param unit_name] - Уникальное имя устройства[br]
|
## [param unit_name] - Уникальное имя устройства[br]
|
||||||
func get_unit_instance(unit_name: StringName) -> unit.Unit:
|
func get_unit_instance(unit_name: StringName) -> unit.Unit:
|
||||||
tools.allways(unit_name in units, 'нет такого устройства: \"%s\"' % unit_name)
|
return units.get(unit_name, null)
|
||||||
return units[unit_name]
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class Sch3 extends unit.Unit:
|
|||||||
var unit_prof = ProjectSettings.get_setting('application/config/%s' % unit_sch3.name)
|
var unit_prof = ProjectSettings.get_setting('application/config/%s' % unit_sch3.name)
|
||||||
if unit_prof:
|
if unit_prof:
|
||||||
unit_sch3.port = unit_prof[0]
|
unit_sch3.port = unit_prof[0]
|
||||||
unit_sch3.params = unit_prof[1]
|
unit_sch3.params = unit_prof.slice(1, -1)
|
||||||
step_fsm = Sch3Fsm.CONNECT
|
step_fsm = Sch3Fsm.CONNECT
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ func is_overlap(x1, x2, y1, y2) -> bool: return max(x1, y1) <= min(x2, y2)
|
|||||||
func allways(val: bool, msg: String = '<не указано>'):
|
func allways(val: bool, msg: String = '<не указано>'):
|
||||||
if val: return
|
if val: return
|
||||||
push_error('%s\n' % msg)
|
push_error('%s\n' % msg)
|
||||||
get_tree().quit(Error.FAILED)
|
|
||||||
|
|
||||||
|
|
||||||
## Преобразует путь в виде целой строки в массив отдельных элементов пути.[br]
|
## Преобразует путь в виде целой строки в массив отдельных элементов пути.[br]
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ class Trassa extends unit.Unit:
|
|||||||
sector_draw(json_dic)
|
sector_draw(json_dic)
|
||||||
emit_signal('data_received', self)
|
emit_signal('data_received', self)
|
||||||
else:
|
else:
|
||||||
var msg = json_conv.get_error_message()
|
|
||||||
emit_signal('parse_failed', self)
|
emit_signal('parse_failed', self)
|
||||||
else:
|
else:
|
||||||
emit_signal('parse_failed', self)
|
emit_signal('parse_failed', self)
|
||||||
@@ -110,7 +109,6 @@ class Trassa extends unit.Unit:
|
|||||||
var hfb = int(data["hfb"])
|
var hfb = int(data["hfb"])
|
||||||
var dap = int(data["dap"])
|
var dap = int(data["dap"])
|
||||||
var daa = int(data["daa"])
|
var daa = int(data["daa"])
|
||||||
var key = str(lfb) + "_" + str(hfb)
|
|
||||||
for i in range(set_klaster.size()):
|
for i in range(set_klaster.size()):
|
||||||
var mapping = set_klaster[i]
|
var mapping = set_klaster[i]
|
||||||
if lfb == mapping[0] and hfb == mapping[1]:
|
if lfb == mapping[0] and hfb == mapping[1]:
|
||||||
@@ -203,6 +201,7 @@ class Trassa extends unit.Unit:
|
|||||||
return NOINFO
|
return NOINFO
|
||||||
|
|
||||||
|
|
||||||
|
# Отправка пакета от uarep-ctl
|
||||||
func process(now_tick: int) -> int:
|
func process(now_tick: int) -> int:
|
||||||
if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT):
|
if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT):
|
||||||
online = false
|
online = false
|
||||||
@@ -225,15 +224,15 @@ class Trassa extends unit.Unit:
|
|||||||
# Контрольная сумма
|
# Контрольная сумма
|
||||||
func _calc_crc(data: Array) -> int:
|
func _calc_crc(data: Array) -> int:
|
||||||
var acc: int = 0
|
var acc: int = 0
|
||||||
for i in range(data.size() - 1):
|
for i in range(data.size() - 1): # кроме CRC
|
||||||
if i in [0, 1]:
|
if i in [0, 1]:
|
||||||
continue
|
continue
|
||||||
acc = (acc + (data[i] & 0xFFFFFFFF)) & 0xFFFFFFFF
|
acc = (acc + (data[i] & 0xFFFFFFFF)) & 0xFFFFFFFF
|
||||||
return acc
|
return acc
|
||||||
|
|
||||||
|
|
||||||
func on_interfer_resized(ecms_dic: Dictionary) -> void:
|
# Обновление всех активных помех
|
||||||
ecms = ecms_dic
|
func on_interfer_resized(ecms_dic: Dictionary) -> void: ecms = ecms_dic
|
||||||
|
|
||||||
|
|
||||||
func interfer_uarep() -> void:
|
func interfer_uarep() -> void:
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ const float DS = 0.004; /* Относитель
|
|||||||
|
|
||||||
float random_timed(vec2 uv)
|
float random_timed(vec2 uv)
|
||||||
{
|
{
|
||||||
return fract(sin(TIME * dot(uv.xy, vec2(12.9898, 78.233))) * 43758.5453123);
|
return fract(sin(dot(uv + TIME, vec2(12.9898, 78.233))) * 43758.5453);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float smooth_px(float r, float R, float ds)
|
float smooth_px(float r, float R, float ds)
|
||||||
{
|
{
|
||||||
return 1.0 - smoothstep(R - ds, R + ds, r);
|
return 1.0 - smoothstep(R - ds, R + ds, r);
|
||||||
|
|||||||
Reference in New Issue
Block a user