From c9509cd25b39f7500b700b2a2839122b79482664 Mon Sep 17 00:00:00 2001 From: Maxim Date: Fri, 15 Nov 2024 16:41:46 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=88=D0=B5=D0=B9=D0=B4=D0=B5=D1=80=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PRD.gd | 62 ++++++++++------ PRD_MP550.tscn | 61 +++++++++++++-- Shaders/ray.gdshader | 84 +++++++++++++++++++++ Shaders/shader_edu.tres | 159 ++++++++++++++++++++++++++++++++++++++++ Web.png | Bin 0 -> 23732 bytes Web.png.import | 34 +++++++++ constants.gd | 30 ++++---- project.godot | 2 +- yau07.gd | 2 + 9 files changed, 392 insertions(+), 42 deletions(-) create mode 100644 Shaders/ray.gdshader create mode 100644 Shaders/shader_edu.tres create mode 100644 Web.png create mode 100644 Web.png.import diff --git a/PRD.gd b/PRD.gd index cc4cacc..e6fead4 100644 --- a/PRD.gd +++ b/PRD.gd @@ -3,7 +3,7 @@ extends Node2D var unit = Yau07.YaU07.new('ЯУ07') var soc_unicast: Socket var soc_brodcast: Socket -var address: String = '0.0.0.0' +var address: String = '10.1.1.11' var ports_wr: Dictionary # Словарь с портами для записи var port: int var broadcast_packet: PackedByteArray @@ -12,6 +12,7 @@ var timeout: float = Yau07.ONLINE_TIMEOUT var last_update_time: float = 0.0 var flag_yau_control: bool + ## Класс для отправки данных в сокет class Socket extends PacketPeerUDP: func send_to(addr: String, port: int, data: PackedByteArray): @@ -31,8 +32,7 @@ func poll_receive(sock: Socket) -> bool: ## Приёмник $control_dev/control_dev.get_node2(0, 0).modulate = Constants.GREEN flag_yau_control = true last_update_time = 0.0 - - #unit.parse(broadcast_packet) + unit.parse(broadcast_packet) else: if sock.get_available_packet_count(): last_update_time = 0.0 @@ -44,14 +44,16 @@ func poll_receive(sock: Socket) -> bool: ## Приёмник func _ready() -> void: - # Таблица 1 + + # Таблица 1 (temp) node_select1 = $scroll1/table1 draw_tabl(node_select1, Constants.ROWS_REGS_DATA, Constants.ROWS_REGS_DATA.size()) # Выбор прибора для подключения var node_select_device = $select_dev/select_dev - draw_tabl(node_select_device, Constants.SELECT_DEVIСE, Constants.SELECT_DEVIСE.size()) + draw_tabl(node_select_device, Constants.SELECT_DEVICE, Constants.SELECT_DEVICE.size()) var get_select_device = node_select_device.get_node2(1, 0) + # Заполнение адресов for i_addr in Constants.ADDRESSES.size(): get_select_device.add_item(Constants.ADDRESSES[i_addr][0]) @@ -62,9 +64,10 @@ func _ready() -> void: # Контроль var node_control_device = $control_dev/control_dev - draw_tabl(node_control_device, Constants.CONTROL_DEVICE, Constants.CONTROL_DEVICE.size()) + draw_tabl(node_control_device, Constants.CONTROL_TABLE, Constants.CONTROL_TABLE.size()) + for i in Constants.CONTROL_DEVICE.size(): + node_control_device.get_node2(0, i).text = Constants.CONTROL_DEVICE[i] node_control_device.set_columns_min_size([300]) - # Привязка для принятия широковещательного канала soc_brodcast = Socket.new() @@ -80,7 +83,7 @@ func _ready() -> void: unit.connect('line_changed', Callable(self, 'on_line_changed')) unit.connect('command_fail', Callable(self, 'on_command_fail')) unit.connect('command_done', Callable(self, 'on_command_done')) - + unit.connect('data_received', Callable(self, 'data_received')) ## Рисует таблицу func draw_tabl(tbl, row: Array, count_row: int): @@ -91,7 +94,7 @@ func draw_tabl(tbl, row: Array, count_row: int): func _process(delta: float) -> void: last_update_time += delta poll_receive(soc_brodcast) - if broadcast_packet and flag_yau_control: + if broadcast_packet: parse_broadcast(broadcast_packet) match unit.process(delta): @@ -125,29 +128,29 @@ func parse_broadcast(packet): node_select1.set_node_text(2, 0, '%d' % dry_contact) for i in 9: if i == 0: - node_control_device.get_node2(0, i+6).text = 'ОШИБКА. КОНТРОЛЬ ИП МАА №1' if dry_contact & (1 << i) and flag_yau_control else 'ИП МАА №1' - node_control_device.get_node2(0, i+6).modulate = Constants.RED if dry_contact & (1 << i) and flag_yau_control else Constants.GREEN + node_control_device.get_node2(0, i+6).text = 'ИП МАА №1' if dry_contact & (1 << i) == 0 and flag_yau_control else 'ОШИБКА. КОНТРОЛЬ ИП МАА №1' + node_control_device.get_node2(0, i+6).modulate = Constants.GREEN if dry_contact & (1 << i) == 0 and flag_yau_control else Constants.RED elif i == 1: - node_control_device.get_node2(0, i+6).text = 'ОШИБКА. КОНТРОЛЬ ИП МАА №2' if dry_contact & (1 << i) and flag_yau_control else 'ИП МАА №2' - node_control_device.get_node2(0, i+6).modulate = Constants.RED if dry_contact & (1 << i) and flag_yau_control else Constants.GREEN + node_control_device.get_node2(0, i+6).text = 'ИП МАА №2' if dry_contact & (1 << i) == 0 and flag_yau_control else 'ОШИБКА. КОНТРОЛЬ ИП МАА №2' + node_control_device.get_node2(0, i+6).modulate = Constants.GREEN if dry_contact & (1 << i) == 0 and flag_yau_control else Constants.RED elif i == 2: - node_control_device.get_node2(0, i+6).text = 'ОШИБКА. КОНТРОЛЬ ИП9-50 №1' if dry_contact & (1 << i) and flag_yau_control else 'ИП9-50 №1' - node_control_device.get_node2(0, i+6).modulate = Constants.RED if dry_contact & (1 << i) and flag_yau_control else Constants.GREEN + node_control_device.get_node2(0, i+6).text = 'ИП9-50 №1' if dry_contact & (1 << i) == 0 and flag_yau_control else 'ОШИБКА. КОНТРОЛЬ ИП9-50 №1' + node_control_device.get_node2(0, i+6).modulate = Constants.GREEN if dry_contact & (1 << i) == 0 and flag_yau_control else Constants.RED elif i == 3: - node_control_device.get_node2(0, i+6).text = 'ОШИБКА. КОНТРОЛЬ ИП9-50 №2' if dry_contact & (1 << i) and flag_yau_control else 'ИП9-50 №2' - node_control_device.get_node2(0, i+6).modulate = Constants.RED if dry_contact & (1 << i) and flag_yau_control else Constants.GREEN + node_control_device.get_node2(0, i+6).text = 'ИП9-50 №2' if dry_contact & (1 << i) == 0 and flag_yau_control else 'ОШИБКА. КОНТРОЛЬ ИП9-50 №2' + node_control_device.get_node2(0, i+6).modulate = Constants.GREEN if dry_contact & (1 << i) == 0 and flag_yau_control else Constants.RED #elif i == 4: #node_control_device.get_node2(0, i+6).text = 'ОШИБКА. КОНТРОЛЬ ИП9-50 №3' if dry_contact & (1 << i) and flag_yau_control else 'ИП9-50 №3' #node_control_device.get_node2(0, i+6).modulate = Constants.RED if dry_contact & (1 << i) and flag_yau_control else Constants.GREEN elif i == 4: - node_control_device.get_node2(0, i+6).text = 'ОШИБКА. КОНТРОЛЬ ИП12-50 №1' if dry_contact & (1 << i) and flag_yau_control else 'ИП12-50 №1' - node_control_device.get_node2(0, i+6).modulate = Constants.RED if dry_contact & (1 << i) and flag_yau_control else Constants.GREEN + node_control_device.get_node2(0, i+6).text = 'ИП12-50 №1' if dry_contact & (1 << i) == 0 and flag_yau_control else 'ОШИБКА. КОНТРОЛЬ ИП12-50 №1' + node_control_device.get_node2(0, i+6).modulate = Constants.GREEN if dry_contact & (1 << i) == 0 and flag_yau_control else Constants.RED #elif i == 6: #node_control_device.get_node2(0, i+6).text = 'ОШИБКА. КОНТРОЛЬ ИП12-50 №2' if dry_contact & (1 << i) and flag_yau_control else 'ИП12-50 №2' #node_control_device.get_node2(0, i+6).modulate = Constants.RED if dry_contact & (1 << i) and flag_yau_control else Constants.GREEN elif i == 7: - node_control_device.get_node2(0, i+6).text = 'ОШИБКА. КОНТРОЛЬ ИП5-25' if dry_contact & (1 << i) and flag_yau_control else 'ИП5-25' - node_control_device.get_node2(0, i+6).modulate = Constants.RED if dry_contact & (1 << i) and flag_yau_control else Constants.GREEN + node_control_device.get_node2(0, i+6).text = 'ИП5-25' if dry_contact & (1 << i) == 0 and flag_yau_control else 'ОШИБКА. КОНТРОЛЬ ИП5-25' + node_control_device.get_node2(0, i+6).modulate = Constants.GREEN if dry_contact & (1 << i) == 0 and flag_yau_control else Constants.RED DKM = packet.decode_u16(37) node_select1.set_node_text(3, 0, '%d' % DKM) @@ -176,6 +179,23 @@ func parse_broadcast(packet): node_select1.set_node_text(3, i+1, '%d' % EMS_G) +func data_received(unit): + var status = unit.status + #var bit_online = 0 + id_board + #var bit_load = 3 + id_board + #online = (status[0] >> bit_online) & 1 + #ems_load = (status[0] >> bit_load) & 1 + var in_blank = int(status[1] | (status[2] << 8) | (status[3] << 16) | \ + (status[4] << 24) | (status[5] << 32)) + var in_imp = int(status[7] | (status[8] << 8) | (status[9] << 16) | \ + (status[10] << 24) | (status[11] << 32)) + var out_blank = int(status[13] | (status[14] << 8) | (status[15] << 16) | \ + (status[16] << 24) | (status[17] << 32)) + var out_imp = int(status[19] | (status[20] << 8) | (status[21] << 16)| \ + (status[22] << 24) | (status[23] << 32)) + var out_kz = int(status[25] | (status[26] << 8)) + + func on_line_changed(_unit) -> void: if unit.online: print('Off line') diff --git a/PRD_MP550.tscn b/PRD_MP550.tscn index b83b94a..37c84c3 100644 --- a/PRD_MP550.tscn +++ b/PRD_MP550.tscn @@ -1,7 +1,10 @@ -[gd_scene load_steps=7 format=3 uid="uid://cvor2jm4xk3ha"] +[gd_scene load_steps=16 format=3 uid="uid://cvor2jm4xk3ha"] [ext_resource type="Script" path="res://PRD.gd" id="1_v273n"] [ext_resource type="Script" path="res://table/table.gd" id="2_vmbyo"] +[ext_resource type="Material" uid="uid://s6xe8igevnv2" path="res://Shaders/shader_edu.tres" id="3_3syd3"] +[ext_resource type="Shader" path="res://Shaders/ray.gdshader" id="4_uy5o2"] +[ext_resource type="Texture2D" uid="uid://62v0xejejuwj" path="res://Web.png" id="5_i3nvb"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ovl8a"] bg_color = Color(0.388235, 0.227451, 0.290196, 1) @@ -14,6 +17,26 @@ anti_aliasing = false [sub_resource type="StyleBoxTexture" id="StyleBoxTexture_hdj8q"] +[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_723du"] +size = Vector2(1600, 1200) + +[sub_resource type="GDScript" id="GDScript_0sobq"] +script/source = "extends Sprite2D + +" + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_o7txs"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_dgiai"] +shader = ExtResource("4_uy5o2") +shader_parameter/color_signal = Color(0.690196, 0.776471, 0, 1) +shader_parameter/turn = 0.785 + +[sub_resource type="Gradient" id="Gradient_ki0n7"] + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_0pk2o"] +gradient = SubResource("Gradient_ki0n7") + [node name="Node2D" type="Node2D"] script = ExtResource("1_v273n") @@ -68,10 +91,10 @@ script = ExtResource("2_vmbyo") metadata/_edit_lock_ = true [node name="scroll1" type="ScrollContainer" parent="."] -offset_left = 586.0 -offset_top = 22.0 -offset_right = 949.0 -offset_bottom = 606.0 +offset_left = 478.0 +offset_top = 65.0 +offset_right = 841.0 +offset_bottom = 649.0 [node name="table1" type="GridContainer" parent="scroll1"] layout_mode = 2 @@ -91,4 +114,32 @@ text = "broadcast" editable = false wrap_mode = 1 +[node name="PSK" type="Sprite2D" parent="."] +material = ExtResource("3_3syd3") +position = Vector2(1243, 81) +scale = Vector2(0.340625, 0.321666) +texture = SubResource("PlaceholderTexture2D_723du") +offset = Vector2(800, 600) +script = SubResource("GDScript_0sobq") + +[node name="PSK grad" type="TextureRect" parent="PSK"] +modulate = Color(0, 0, 0, 1) +self_modulate = Color(0, 0, 0, 1) +show_behind_parent = true +material = SubResource("ShaderMaterial_o7txs") +offset_left = 554.954 +offset_top = -30.0 +offset_right = 1290.95 +offset_bottom = 1134.0 +texture = ExtResource("5_i3nvb") +expand_mode = 1 +metadata/_edit_lock_ = true + +[node name="ray" type="Sprite2D" parent="PSK"] +material = SubResource("ShaderMaterial_dgiai") +position = Vector2(549.221, 560.705) +scale = Vector2(21.8765, 21.6782) +texture = SubResource("GradientTexture2D_0pk2o") +metadata/_edit_lock_ = true + [connection signal="toggled" from="control_button" to="." method="_on_control_button"] diff --git a/Shaders/ray.gdshader b/Shaders/ray.gdshader new file mode 100644 index 0000000..c8ea8e0 --- /dev/null +++ b/Shaders/ray.gdshader @@ -0,0 +1,84 @@ +shader_type canvas_item; + +uniform vec4 color_signal: source_color; +uniform float turn = 0.785; + +const float outer_radius = 0.309; +const float inner_radius = 0.72; +const float zoom = 100.0; +const float speed = 2.1; +const float size = 6.0; +const float blur = 0.000001; +const float fill_ratio = 0.03; + + +float remap(float i_min, float i_max, float o_min, float o_max, float val) { + float t = (val - i_min) / (i_max - i_min); + return o_min + (o_max - o_min) * t; +} + + +float mask(vec2 uv, float value) +{ + float r = atan(uv.x, uv.y); + r = remap(-PI, PI, 0.0, 1.0, r); + r = step(r, value * 0.5); + + uv.x = uv.x + 1.0; + uv.x = uv.x * -1.0; + uv.x += 1.0; + float l = atan(uv.x, uv.y); + l = remap(-PI, PI, 0.0, 1.0, l); + l = step(l, value * 0.5); + + return r + l ; +} + + +vec2 rotate_uv(vec2 uv, vec2 pivot, float rotation) { + float cosa = cos(rotation); + float sina = sin(rotation); + uv -= pivot; + return vec2( + cosa * uv.x - sina * uv.y, + cosa * uv.y + sina * uv.x + ) + pivot; +} + + +float circle(vec2 uv, float value) +{ + float d = length(uv); + float t = smoothstep( + inner_radius + blur, + inner_radius - blur, + d + ) - smoothstep( + outer_radius + blur, + outer_radius - blur, + d + ); + + return t; +} + + +void fragment(){ + float d = length((UV-0.5)*2.0); + float t = pow(smoothstep(0.9,0.2,d),0.35); + vec2 uv = (UV * 2.0) - 1.0; + + vec3 rainbow = 0.5*cos(TIME+UV.xyx+vec3(0,2,4)); + vec4 color = vec4(rainbow.rgb,1.0); + vec2 origin = vec2(0.0, 0.0); + color = vec4(color_signal.rgb,1.0); + uv = rotate_uv(uv, origin, turn * TAU); + float c = circle(uv, 0.5); + float mask = mask(uv, fill_ratio); + d = sin(zoom*d - speed*TIME); + //d = abs(d); + d = size/d; + color *= d*t; + + COLOR = vec4(color * mask * c); +} \ No newline at end of file diff --git a/Shaders/shader_edu.tres b/Shaders/shader_edu.tres new file mode 100644 index 0000000..1fa072b --- /dev/null +++ b/Shaders/shader_edu.tres @@ -0,0 +1,159 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://s6xe8igevnv2"] + +[sub_resource type="Shader" id="1"] +code = "shader_type canvas_item; + +uniform vec4 colore: source_color; +uniform vec2 pc0; /* Центр сетки антенн */ +uniform vec4 color0: source_color = vec4(0.38, 0.47, 0.51, 0.4); +uniform vec4 color1: source_color = vec4(0.39, 0.44, 0.50, 0.4); + +const float mask_grad = 0.75; +const float rotation = 135.0; +const float radius_inner = 200.0; /* Радиус внутренний. Должно быть равно ant_band_r0_0 */ +const float radius_outter = 550.0; /* Радиус внешний. Должно быть равно ant_band_r1_6 */ + +const float ant_band_count_0 = 6.0; +const float ant_band_count_1 = 6.0; +const float ant_band_count_2 = 6.0; +const float ant_band_count_3 = 6.0; +const float ant_band_count_4 = 6.0; +const float ant_band_count_5 = 6.0; +const float ant_band_count_6 = 6.0; + +const float ant_band_r0_0 = 200.0; +const float ant_band_r0_1 = 250.0; +const float ant_band_r0_2 = 300.0; +const float ant_band_r0_3 = 350.0; +const float ant_band_r0_4 = 400.0; +const float ant_band_r0_5 = 450.0; +const float ant_band_r0_6 = 500.0; + +const float ant_band_r1_0 = 250.0; +const float ant_band_r1_1 = 300.0; +const float ant_band_r1_2 = 350.0; +const float ant_band_r1_3 = 400.0; +const float ant_band_r1_4 = 450.0; +const float ant_band_r1_5 = 500.0; +const float ant_band_r1_6 = 550.0; +const float d4 = 90.0; +const float ds = 1.0; + + +float SMOOTH(float r, float R, float d) +{ + return 1.0 - smoothstep(R - d, R + d, r); +} + + +float remap(float i_min, float i_max, float o_min, float o_max, float val) { + float t = (val - i_min) / (i_max - i_min); + return o_min + (o_max - o_min) * t; +} + + +float mask(vec2 uv, float value) +{ + float r = atan(uv.x, uv.y); + r = remap(-PI, PI, 0.0, 1.0, r); + r = step(r, value * 0.5); + + uv.x = uv.x + 1.0; + uv.x = uv.x * -1.0; + uv.x += 1.0; + float l = atan(uv.x, uv.y); + l = remap(-PI, PI, 0.0, 1.0, l); + l = step(l, value * 0.5); + + return r + l ; +} + + +void sector(inout vec4 c, vec2 uv, vec2 center, float a, float da, float r0, float r1, vec4 color) +{ + float l = distance(center, uv); + vec2 d = uv - center; + float sf = 500.0; + float theta = atan(d.x, d.y) * sf; + da /= 2.0; + float a0 = radians(a - da); + float a1 = radians(a + da); + float va = SMOOTH(a0 * sf, theta, ds) - SMOOTH(a1 * sf, theta, ds); + float vr = SMOOTH(r0, l, ds) - SMOOTH(r1, l, ds); + float rgb = sqrt(va * vr); + c.rgb += color.rgb * rgb * color.a; + c.a += rgb * color.a; +} + + +void antenas(inout vec4 c, vec2 uv, vec2 p0, float cnt, float r0, float r1, vec4 c0, vec4 c1) +{ + float da = 180.0f / float(cnt); + for (int i = int(-cnt); i <= int(cnt); i ++) + { + float v = float(i & 1); + vec4 col = v * c0 + (1.0f - v) * c1; + sector(c, uv, p0, float(i) * da, da, r0, r1, col); + } +} + + +void circle_thin(inout vec3 color, vec2 uv, vec2 p, float r, float w, vec3 c, float a) +{ + float d = distance(uv, p); + float v0 = r - w; + float v1 = r + w; + color += a * sqrt(smoothstep(v1, v0, d) * smoothstep(v0, v1, d) * c); +} + + +void line_r(inout vec4 color, vec2 uv, vec2 center, float theta0, float radius, vec4 c) +{ + vec2 d = uv - center; + vec2 p = radius * vec2(cos(theta0 * PI / 180.0), - sin(theta0 * PI / 180.0)); + float l = length(d - p * clamp(dot(d, p) / dot(p, p), 0.0, 1.0)); + color.rgb += c.rgb * SMOOTH(l, 1.0, ds) * c.a; +} + + +void rotate_vec2(inout vec2 vert, float a) +{ + float sin_a = sin(a); + float cos_a = cos(a); + vert *= mat2(vec2(cos_a, sin_a), vec2(-sin_a, cos_a)); +} + + +void vertex() +{ + VERTEX -= pc0; + rotate_vec2(VERTEX, radians(rotation)); + VERTEX += pc0; +} + + +void fragment() +{ + ivec2 isz = textureSize(TEXTURE, 0); + vec2 uv = UV * vec2(float(isz.x), float(isz.y)); // координаты текущей точки в пикселях + float mask = mask(uv, mask_grad); + COLOR = vec4(0.0, 0.0, 0.0, 0.0) - mask; //texture(TEXTURE, UV); // Цвет текущей точки + + // Сетка антенн + antenas(COLOR, uv, pc0, ant_band_count_0, ant_band_r0_0, ant_band_r1_0, color1, color0); + antenas(COLOR, uv, pc0, ant_band_count_1, ant_band_r0_1, ant_band_r1_1, color0, color1); + antenas(COLOR, uv, pc0, ant_band_count_2, ant_band_r0_2, ant_band_r1_2, color1, color0); + antenas(COLOR, uv, pc0, ant_band_count_3, ant_band_r0_3, ant_band_r1_3, color0, color1); + antenas(COLOR, uv, pc0, ant_band_count_4, ant_band_r0_4, ant_band_r1_4, color1, color0); + antenas(COLOR, uv, pc0, ant_band_count_5, ant_band_r0_5, ant_band_r1_5, color0, color1); + + +} +" + +[resource] +shader = SubResource("1") +shader_parameter/colore = Color(0, 0, 0, 1) +shader_parameter/pc0 = Vector2(560.03, 560) +shader_parameter/color0 = Color(0.203922, 0.203922, 0.203922, 0.478431) +shader_parameter/color1 = Color(0.945098, 0.964706, 0.972549, 0.117647) diff --git a/Web.png b/Web.png new file mode 100644 index 0000000000000000000000000000000000000000..96398f0f31576210bfed231af19b63d5f55fe0ca GIT binary patch literal 23732 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