Compare commits

8 Commits

14 changed files with 533 additions and 1 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
# Godot 4+ specific ignores
.godot/
/android/
/dist/

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://b8yyluxikhlr0"
path="res://.godot/imported/PID_Spinning_Stuff.glb-977aece4b561e834c064e6c1c7e53471.scn"
[deps]
source_file="res://Assets/PID_Spinning_Stuff.glb"
dest_files=["res://.godot/imported/PID_Spinning_Stuff.glb-977aece4b561e834c064e6c1c7e53471.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://cin3pgpeydkpe"
path="res://.godot/imported/PID_Spinning_Target.glb-739e3becae2412e2332407d1fc9f1fc7.scn"
[deps]
source_file="res://Assets/PID_Spinning_Target.glb"
dest_files=["res://.godot/imported/PID_Spinning_Target.glb-739e3becae2412e2332407d1fc9f1fc7.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

BIN
Assets/PID_Test_Obj.blend Normal file

Binary file not shown.

View File

@@ -0,0 +1,59 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c8ywajojvb7pw"
path="res://.godot/imported/PID_Test_Obj.blend-06d5e64216d0d8667c2f9c3cb6d12c34.scn"
[deps]
source_file="res://Assets/PID_Test_Obj.blend"
dest_files=["res://.godot/imported/PID_Test_Obj.blend-06d5e64216d0d8667c2f9c3cb6d12c34.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
blender/nodes/visible=0
blender/nodes/active_collection_only=false
blender/nodes/punctual_lights=true
blender/nodes/cameras=true
blender/nodes/custom_properties=true
blender/nodes/modifiers=1
blender/meshes/colors=false
blender/meshes/uvs=true
blender/meshes/normals=true
blender/meshes/export_geometry_nodes_instances=false
blender/meshes/tangents=true
blender/meshes/skins=2
blender/meshes/export_bones_deforming_mesh_only=false
blender/materials/unpack_enabled=true
blender/materials/export_materials=1
blender/animation/limit_playback=true
blender/animation/always_sample=true
blender/animation/group_tracks=true
gltf/naming_version=2

108
Levels/pid_test.gd Normal file
View File

@@ -0,0 +1,108 @@
extends Node3D
var p:float = 0.4
var i:float = 0.0
var d:float = 1
var force:float = 200.0
var error:float = 0.0
var last_error = 0.0
var error_derivative:float = 0.0
var integral:float = 0.0
var target:float = 0.0 #0.0 -> 359.99
var p_input:SpinBox
var i_input:SpinBox
var d_input:SpinBox
var force_input:SpinBox
var target_input:SpinBox
var spinner_node:Node3D
var target_node:Node3D
var error_lable:Label
var speed_lable:Label
var acceleration_label:Label
var error_derivative_lable:Label
var integral_lable:Label
var spinner_speed:float = 0.0
var max_speed:float = 120 # deg/m -> 1/360/60s = 1rpm
var acceleration:float
func _ready() -> void:
spinner_node = get_node("Spinner")
target_node = get_node("Target")
p_input = get_node("PID Menue/PanelContainer/VBoxContainer/Proportinal Term (P)/Input")
p_input.value_changed.connect(_update_p_value)
i_input = get_node("PID Menue/PanelContainer/VBoxContainer/Integral (I)/Input")
i_input.value_changed.connect(_update_i_value)
d_input = get_node("PID Menue/PanelContainer/VBoxContainer/Derivative (D)/Input")
d_input.value_changed.connect(_update_d_value)
force_input = get_node("PID Menue/PanelContainer/VBoxContainer/Force/Input")
force_input.value_changed.connect(_update_force_value)
target_input =get_node("PID Menue/PanelContainer/VBoxContainer/Target Rotation/Input")
target_input.value_changed.connect(_update_target_rot)
error_lable = get_node("PID Menue/PanelContainer/VBoxContainer/Error/Output")
speed_lable = get_node("PID Menue/PanelContainer/VBoxContainer/Speed/Output")
error_derivative_lable = get_node("PID Menue/PanelContainer/VBoxContainer/Error Derivative/Output")
acceleration_label = get_node("PID Menue/PanelContainer/VBoxContainer/Acceleration/Output")
integral_lable = get_node("PID Menue/PanelContainer/VBoxContainer/Integral/Output")
# Set default values
p_input.value = p
i_input.value = i
d_input.value = d
force_input.value = force
func _update_target_rot(value:float) -> void:
target_node.rotation.x = deg_to_rad(value)
func _update_p_value(value:float) -> void:
p = value
func _update_i_value(value:float) -> void:
i = value
func _update_d_value(value:float) -> void:
d = value
func _update_force_value(value:float) -> void:
force = value
func _process(delta: float) -> void:
# PID Stuff
target = rad_to_deg(target_node.rotation.x)
error = target - rad_to_deg(spinner_node.rotation.x)
error_derivative = (error - last_error) /delta
integral += error * delta
# Clamp acceleration between min and max force
var pid_output := (p * error) + (i * integral) + (d * error_derivative)
acceleration = clampf(pid_output, -force, force)
# Set speed
var next_speed = spinner_speed + acceleration * delta
# Block acceleration that would exceed max speed
if abs(spinner_speed) >= max_speed and sign(acceleration) == sign(spinner_speed):
acceleration = 0.0
next_speed = spinner_speed
spinner_speed = clamp(next_speed, -max_speed, max_speed)
spinner_node.rotation_degrees.x += spinner_speed * delta
last_error = error
func _physics_process(delta: float) -> void:
#UI Updats
error_lable.text = str(error).pad_decimals(2).pad_zeros(3) + " deg"
error_derivative_lable.text = str(error_derivative).pad_decimals(2).pad_zeros(3)
integral_lable.text = str(integral).pad_decimals(2).pad_zeros(3)
speed_lable.text = str(spinner_speed).pad_decimals(2).pad_zeros(3) + " deg/m"
acceleration_label.text = str(acceleration/force*100).pad_decimals(2).pad_zeros(3) + " %"

1
Levels/pid_test.gd.uid Normal file
View File

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

View File

@@ -1,3 +1,221 @@
[gd_scene format=3 uid="uid://caj5t8q1fii5m"]
[gd_scene load_steps=8 format=3 uid="uid://caj5t8q1fii5m"]
[ext_resource type="PackedScene" uid="uid://cin3pgpeydkpe" path="res://Assets/PID_Spinning_Target.glb" id="1_0c8sw"]
[ext_resource type="Script" uid="uid://b63aqs33qyp0g" path="res://Levels/pid_test.gd" id="1_sxbsa"]
[ext_resource type="PackedScene" uid="uid://b8yyluxikhlr0" path="res://Assets/PID_Spinning_Stuff.glb" id="2_sxbsa"]
[sub_resource type="Environment" id="Environment_d03hh"]
background_mode = 2
background_color = Color(0.14478481, 0.14478481, 0.14478481, 1)
ambient_light_source = 2
[sub_resource type="Theme" id="Theme_sxbsa"]
[sub_resource type="Theme" id="Theme_d03hh"]
[sub_resource type="LabelSettings" id="LabelSettings_sxbsa"]
font_size = 24
[node name="PidTest" type="Node3D"]
script = ExtResource("1_sxbsa")
[node name="Target" type="Node3D" parent="."]
[node name="PID_Spinning_Target" parent="Target" instance=ExtResource("1_0c8sw")]
[node name="Spinner" type="Node3D" parent="."]
[node name="PID_Spinning_Stuff" parent="Spinner" instance=ExtResource("2_sxbsa")]
[node name="OmniLight3D" type="OmniLight3D" parent="Spinner/PID_Spinning_Stuff"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.40560818, 0.6382216, 0)
light_color = Color(0.99999994, 0.20727095, 0.32746297, 1)
light_energy = 0.2
shadow_enabled = true
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(-4.3597606e-08, -0.072106734, 0.99739695, -3.1518854e-09, 0.99739695, 0.072106734, -1, 0, -4.371139e-08, 4.3431935, 0.43207824, 0)
environment = SubResource("Environment_d03hh")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.25000006, 0.9659258, 0.06698735, -0.2588191, -1.9081726e-08, 0.9659258, 0.93301266, -0.25881913, 0.25000003, 0, 3.3288543, 0)
[node name="PID Menue" type="Control" parent="."]
layout_mode = 3
anchors_preset = 0
offset_left = 20.0
offset_top = 20.0
offset_right = 20.0
offset_bottom = 20.0
theme = SubResource("Theme_sxbsa")
[node name="PanelContainer" type="PanelContainer" parent="PID Menue"]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="VBoxContainer" type="VBoxContainer" parent="PID Menue/PanelContainer"]
layout_mode = 2
theme = SubResource("Theme_d03hh")
[node name="Spinner Header" type="Label" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
text = "Spinner Controll"
label_settings = SubResource("LabelSettings_sxbsa")
[node name="Proportinal Term (P)" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Proportinal Term (P)"]
layout_mode = 2
size_flags_horizontal = 3
text = "Proportinal Term (P)"
[node name="MarginContainer" type="MarginContainer" parent="PID Menue/PanelContainer/VBoxContainer/Proportinal Term (P)"]
custom_minimum_size = Vector2(20, 0)
layout_mode = 2
[node name="Input" type="SpinBox" parent="PID Menue/PanelContainer/VBoxContainer/Proportinal Term (P)"]
layout_mode = 2
max_value = 1.0
step = 0.01
value = 0.5
[node name="Integral (I)" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Integral (I)"]
layout_mode = 2
size_flags_horizontal = 3
text = "Integral (I)"
[node name="Input" type="SpinBox" parent="PID Menue/PanelContainer/VBoxContainer/Integral (I)"]
layout_mode = 2
max_value = 1.0
step = 0.01
[node name="Derivative (D)" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Derivative (D)"]
layout_mode = 2
size_flags_horizontal = 3
text = "Derivative (D)"
[node name="Input" type="SpinBox" parent="PID Menue/PanelContainer/VBoxContainer/Derivative (D)"]
layout_mode = 2
max_value = 1.0
step = 0.01
[node name="Force" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Force"]
layout_mode = 2
size_flags_horizontal = 3
text = "Force"
[node name="Input" type="SpinBox" parent="PID Menue/PanelContainer/VBoxContainer/Force"]
layout_mode = 2
[node name="MarginContainer" type="MarginContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
custom_minimum_size = Vector2(0, 20)
layout_mode = 2
[node name="Target Header" type="Label" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
text = "Target"
label_settings = SubResource("LabelSettings_sxbsa")
[node name="Target Rotation" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Target Rotation"]
layout_mode = 2
size_flags_horizontal = 3
text = "Target Rotation"
[node name="Input" type="SpinBox" parent="PID Menue/PanelContainer/VBoxContainer/Target Rotation"]
layout_mode = 2
max_value = 1439.96
step = 0.01
custom_arrow_step = 10.0
[node name="MarginContainer2" type="MarginContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
custom_minimum_size = Vector2(0, 20)
layout_mode = 2
[node name="Solution" type="Label" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
text = "Solution"
label_settings = SubResource("LabelSettings_sxbsa")
[node name="Error" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Error"]
layout_mode = 2
size_flags_horizontal = 3
text = "Error"
[node name="Output" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Error"]
layout_mode = 2
text = "000.00"
horizontal_alignment = 1
uppercase = true
[node name="Error Derivative" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Error Derivative"]
layout_mode = 2
size_flags_horizontal = 3
text = "Error Derivative"
[node name="Output" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Error Derivative"]
layout_mode = 2
text = "000.00"
horizontal_alignment = 1
uppercase = true
[node name="Integral" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Integral"]
layout_mode = 2
size_flags_horizontal = 3
text = "Integral"
[node name="Output" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Integral"]
layout_mode = 2
text = "000.00"
horizontal_alignment = 1
uppercase = true
[node name="Speed" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Speed"]
layout_mode = 2
size_flags_horizontal = 3
text = "Speed"
[node name="Output" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Speed"]
layout_mode = 2
text = "000.00"
horizontal_alignment = 1
uppercase = true
[node name="Acceleration" type="HBoxContainer" parent="PID Menue/PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Acceleration"]
layout_mode = 2
size_flags_horizontal = 3
text = "Acceleration"
[node name="Output" type="Label" parent="PID Menue/PanelContainer/VBoxContainer/Acceleration"]
layout_mode = 2
text = "000.00"
horizontal_alignment = 1
uppercase = true

6
back_to_main.gd Normal file
View File

@@ -0,0 +1,6 @@
extends Node
var main_menue: PackedScene = preload("res://main.tscn")
func _input(event: InputEvent) -> void:
if event.is_action_pressed("main_menue"):
get_tree().change_scene_to_packed(main_menue)

1
back_to_main.gd.uid Normal file
View File

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

45
export_presets.cfg Normal file
View File

@@ -0,0 +1,45 @@
[preset.0]
name="Godot Experiments"
platform="Web"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="dist/Experements.html"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=true
encrypt_directory=false
script_export_mode=2
[preset.0.options]
custom_template/debug=""
custom_template/release=""
variant/extensions_support=false
variant/thread_support=false
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/export_icon=true
html/custom_html_shell=""
html/head_include=""
html/canvas_resize_policy=2
html/focus_canvas_on_start=true
html/experimental_virtual_keyboard=false
progressive_web_app/enabled=false
progressive_web_app/ensure_cross_origin_isolation_headers=true
progressive_web_app/offline_page=""
progressive_web_app/display=1
progressive_web_app/orientation=0
progressive_web_app/icon_144x144=""
progressive_web_app/icon_180x180=""
progressive_web_app/icon_512x512=""
progressive_web_app/background_color=Color(0, 0, 0, 1)
threads/emscripten_pool_size=8
threads/godot_pool_size=4

View File

@@ -16,6 +16,10 @@ config/features=PackedStringArray("4.5", "Forward Plus")
boot_splash/bg_color=Color(0, 0, 0, 1)
config/icon="res://icon.svg"
[autoload]
BackToMain="*res://back_to_main.gd"
[input]
w={
@@ -48,6 +52,11 @@ e={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
]
}
main_menue={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
[physics]