rvlab 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. rvlab-0.1.0/MANIFEST.in +1 -0
  2. rvlab-0.1.0/PKG-INFO +7 -0
  3. rvlab-0.1.0/pyproject.toml +19 -0
  4. rvlab-0.1.0/setup.cfg +4 -0
  5. rvlab-0.1.0/src/rvlab/__init__.py +0 -0
  6. rvlab-0.1.0/src/rvlab/ai_ml/Flocking_Bird.py +100 -0
  7. rvlab-0.1.0/src/rvlab/ai_ml/LR_Scalar_Method.py +29 -0
  8. rvlab-0.1.0/src/rvlab/ai_ml/LR_Vector_Method.py +26 -0
  9. rvlab-0.1.0/src/rvlab/ai_ml/Markov_Chain_Eigen_Vector.py +16 -0
  10. rvlab-0.1.0/src/rvlab/ai_ml/Markov_Chain_Linear_Chain.py +20 -0
  11. rvlab-0.1.0/src/rvlab/ai_ml/Markov_Chain_Power_Iteration.py +12 -0
  12. rvlab-0.1.0/src/rvlab/ai_ml/Simulated_annealing.py +62 -0
  13. rvlab-0.1.0/src/rvlab/ai_ml/__init__.py +0 -0
  14. rvlab-0.1.0/src/rvlab/control/__init__.py +0 -0
  15. rvlab-0.1.0/src/rvlab/control/lqr_matlab.py +100 -0
  16. rvlab-0.1.0/src/rvlab/control/p_pd_pi_pid_control_matlab.py +118 -0
  17. rvlab-0.1.0/src/rvlab/robotics/2_dof_circle_tracking_matlab.py +247 -0
  18. rvlab-0.1.0/src/rvlab/robotics/3_dof_circle_tracking_matlab.py +267 -0
  19. rvlab-0.1.0/src/rvlab/robotics/3_dof_helix_tracking_matlab.py +175 -0
  20. rvlab-0.1.0/src/rvlab/robotics/6_dof_matlab.py +691 -0
  21. rvlab-0.1.0/src/rvlab/robotics/__init__.py +0 -0
  22. rvlab-0.1.0/src/rvlab/robotics/astar_matlab.py +51 -0
  23. rvlab-0.1.0/src/rvlab/robotics/dijkistra_matlab.py +46 -0
  24. rvlab-0.1.0/src/rvlab/robotics/dtsar_matlab.py +71 -0
  25. rvlab-0.1.0/src/rvlab/robotics/rrt_matlab.py +67 -0
  26. rvlab-0.1.0/src/rvlab/robotics/sensor_fusion_kf_matlab.py +148 -0
  27. rvlab-0.1.0/src/rvlab/rpp/__init__.py +0 -0
  28. rvlab-0.1.0/src/rvlab/rpp/extended_kalman_filter_python.py +158 -0
  29. rvlab-0.1.0/src/rvlab/rpp/kalman_filter_python.py +83 -0
  30. rvlab-0.1.0/src/rvlab/rpp/particle_filter_matlab.py +86 -0
  31. rvlab-0.1.0/src/rvlab/vision/CV2_BGR_to_Plot_RGB.py +39 -0
  32. rvlab-0.1.0/src/rvlab/vision/Contrast_Streching.py +32 -0
  33. rvlab-0.1.0/src/rvlab/vision/Contrast_Streching_(automatic).py +22 -0
  34. rvlab-0.1.0/src/rvlab/vision/Edge_Detection_Laplacian.py +22 -0
  35. rvlab-0.1.0/src/rvlab/vision/Edge_Detection_Normal.py +20 -0
  36. rvlab-0.1.0/src/rvlab/vision/Edge_Detection_Sobel.py +30 -0
  37. rvlab-0.1.0/src/rvlab/vision/Histogram_Equalization.py +19 -0
  38. rvlab-0.1.0/src/rvlab/vision/Histogram_Equalization_Img.py +21 -0
  39. rvlab-0.1.0/src/rvlab/vision/Histogram_Equalization_manual.py +39 -0
  40. rvlab-0.1.0/src/rvlab/vision/Histogram_Plotting.py +38 -0
  41. rvlab-0.1.0/src/rvlab/vision/Image_Negative.py +23 -0
  42. rvlab-0.1.0/src/rvlab/vision/Lab_code_vision.pdf +0 -0
  43. rvlab-0.1.0/src/rvlab/vision/Logarithmic_Transformation.py +24 -0
  44. rvlab-0.1.0/src/rvlab/vision/Logical_Binary_Mask.py +39 -0
  45. rvlab-0.1.0/src/rvlab/vision/Meadian_filter.py +19 -0
  46. rvlab-0.1.0/src/rvlab/vision/Mean_Filter.py +17 -0
  47. rvlab-0.1.0/src/rvlab/vision/Mean_Median.py +26 -0
  48. rvlab-0.1.0/src/rvlab/vision/Power_Law_Transformation.py +23 -0
  49. rvlab-0.1.0/src/rvlab/vision/Sharpening_Image.py +25 -0
  50. rvlab-0.1.0/src/rvlab/vision/Unmask_Filterning.py +23 -0
  51. rvlab-0.1.0/src/rvlab/vision/__init__.py +0 -0
  52. rvlab-0.1.0/src/rvlab/vision/min_max_filter.py +26 -0
  53. rvlab-0.1.0/src/rvlab/vision/plotting_Histogram_of_an_image.py +30 -0
  54. rvlab-0.1.0/src/rvlab.egg-info/PKG-INFO +7 -0
  55. rvlab-0.1.0/src/rvlab.egg-info/SOURCES.txt +56 -0
  56. rvlab-0.1.0/src/rvlab.egg-info/dependency_links.txt +1 -0
  57. rvlab-0.1.0/src/rvlab.egg-info/requires.txt +3 -0
  58. rvlab-0.1.0/src/rvlab.egg-info/top_level.txt +1 -0
@@ -0,0 +1 @@
1
+ recursive-include src/rvlab *.pdf
rvlab-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.4
2
+ Name: rvlab
3
+ Version: 0.1.0
4
+ Summary: A clean, modern Python package for rvlab
5
+ Requires-Dist: numpy
6
+ Requires-Dist: opencv-python
7
+ Requires-Dist: matplotlib
@@ -0,0 +1,19 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "rvlab"
7
+ version = "0.1.0"
8
+ description = "A clean, modern Python package for rvlab"
9
+ dependencies = [
10
+ "numpy",
11
+ "opencv-python",
12
+ "matplotlib"
13
+ ]
14
+
15
+ [tool.setuptools]
16
+ include-package-data = true
17
+
18
+ [tool.setuptools.packages.find]
19
+ where = ["src"]
rvlab-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,100 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ from matplotlib.animation import FuncAnimation
4
+
5
+ #Initialization Parameters
6
+ N = 50 #no of boids
7
+ Width, Height = 800, 600 #Space Size
8
+
9
+ Max_Speed = 7
10
+ Max_Force = 0.05
11
+ Perception_Radius = 50
12
+
13
+ #Initialize Weights
14
+ W_Sep = 1.2
15
+ W_ALIGN = 1.0
16
+ W_COH = 1.0
17
+
18
+ #Initialize position and velocities
19
+ positions = np.random.rand(N,2)*[Width, Height]
20
+ velocities = (np.random.rand(N,2)-0.5)*10
21
+
22
+ #Limit Magnitude function to limit force, velocity and position
23
+ def limitMagnitude(vec, maxVal):
24
+ mag = np.linalg.norm(vec)
25
+ if mag>maxVal:
26
+ return (vec/mag)*maxVal
27
+ return vec
28
+
29
+ #Updating the velocity and position of each boid
30
+ def updateBoids():
31
+ global positions, velocities
32
+ newVelocities = np.copy(velocities)
33
+ for i in range(N):
34
+
35
+ posi = positions[i]
36
+ veli = velocities[i]
37
+ #initializing Separation, Alignment and cohesion
38
+ Separation = np.zeros(2)
39
+ Alignment = np.zeros(2)
40
+ Cohesion = np.zeros(2)
41
+
42
+ total = 0
43
+ for j in range(N):
44
+
45
+ if i==j:
46
+ continue
47
+
48
+ diff = positions[j]-posi
49
+ dist = np.linalg.norm(diff)
50
+
51
+ if dist<Perception_Radius and dist>0:
52
+ #update Separation
53
+ Separation += -diff/(dist**2)
54
+ #update Alighnment
55
+ Alignment += velocities[j]
56
+ #update Cohesion
57
+ Cohesion += positions[j]
58
+
59
+ total +=1
60
+
61
+ if total>0:
62
+
63
+ Alignment /= total
64
+ Alignment -=veli
65
+ Alignment = limitMagnitude(Alignment, Max_Force)
66
+
67
+ Cohesion /= total
68
+ Cohesion -=veli
69
+ Cohesion = limitMagnitude(Cohesion, Max_Force)
70
+
71
+ Separation = limitMagnitude(Separation, Max_Force)
72
+
73
+ #Calculate Acceleration
74
+ Acceleration = (W_Sep*Separation+W_ALIGN*Alignment+W_COH*Cohesion)
75
+
76
+ newVelocities[i] += Acceleration
77
+ newVelocities[i] = limitMagnitude(newVelocities[i], Max_Speed)
78
+
79
+ velocities = newVelocities
80
+ positions += velocities
81
+
82
+ #Wrap Around Edges
83
+ positions[:,0] = positions[:,0]%Width
84
+ positions[:,1] = positions[:,1]%Height
85
+
86
+ #Visualization
87
+ fig, ax = plt.subplots()
88
+ scat = ax.scatter(positions[:,0], positions[:,1])
89
+
90
+ #Wrapping the boids within the plot
91
+ ax.set_xlim(0, Width)
92
+ ax.set_ylim(0,Height)
93
+
94
+ def animate(frame):
95
+ updateBoids()
96
+ scat.set_offsets(positions)
97
+ return scat
98
+
99
+ ani = FuncAnimation(fig, animate, interval=10)
100
+ plt.show()
@@ -0,0 +1,29 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+
4
+ x = np.linspace(0,10,50)
5
+ y = 3*x+2+np.random.randn(50)*2
6
+
7
+ #Intializing Calculation terms
8
+ n = len(x)
9
+ sigmax = np.sum(x)
10
+ sigmay = np.sum(y)
11
+ sigmaxy = np.sum(x*y)
12
+ sigmaxsquare = np.sum(x**2)
13
+
14
+ #Calculating slome 'm' and intercept 'b'
15
+ m = ((n*sigmaxy) - (sigmax * sigmay))/(n*sigmaxsquare - sigmax**2)
16
+ b = (sigmay - m*sigmax)/n
17
+
18
+ y_pred = m*x+b
19
+
20
+ #plotting the data
21
+ plt.scatter(x,y, color='blue', label="Noisy Data")
22
+ plt.plot(x,y_pred, color="red", label= f"Predicted Line {m:.2f}x+{b:.2f}")
23
+ plt.xlabel("Independent (X)")
24
+ plt.title("Linear Regression using Least Squares Method")
25
+ plt.ylabel("Dependent Variable (Y)")
26
+ plt.gcf().text(0.5, 0.01, f"The Slope: {m:.2f} and Intercept: {b:.2f} of the predicted Line for noisy Data",
27
+ ha='center', fontsize=12)
28
+ plt.legend()
29
+ plt.show()
@@ -0,0 +1,26 @@
1
+ import numpy as np
2
+ import matplotlib.pyplot as plt
3
+ import random
4
+
5
+ x = np.linspace(0,10,50)
6
+ y = 3*x + 2 + np.random.randn(50)*2
7
+
8
+ const = np.ones(50)
9
+ x_final = np.column_stack((const,x))
10
+ x_final_Transpose = x_final.T
11
+
12
+ Beta = np.linalg.inv(x_final_Transpose@x_final)@x_final_Transpose@y
13
+
14
+ print("Co-efficients (Intercept, Slope):",Beta[0], Beta[1])
15
+ #Predicted Line
16
+ y_pred = Beta[1]*x+Beta[0]
17
+
18
+ plt.scatter(x,y, color='blue', label="Noisy Data")
19
+ plt.plot(x,y_pred, color="red", label= f"Predicted Line {Beta[1]:.2f}x+{Beta[0]:.2f}")
20
+ plt.xlabel("Independent (X)")
21
+ plt.title("Linear Regression using Least Squares Method")
22
+ plt.ylabel("Dependent Variable (Y)")
23
+ plt.gcf().text(0.5, 0.01, f"The Slope: {Beta[1]:.2f} and Intercept: {Beta[0]:.2f} of the predicted Line for noisy Data",
24
+ ha='center', fontsize=12)
25
+ plt.legend()
26
+ plt.show()
@@ -0,0 +1,16 @@
1
+ import numpy as np
2
+
3
+ def eigenDecomposition(P):
4
+ eigenvals, eigenvecs = np.linalg.eig(P)
5
+ index = np.argmin(np.abs(eigenvals-1))
6
+ vectorPI = np.real(eigenvecs[:,index])
7
+
8
+ #normalize
9
+ vectorPI = vectorPI/np.sum(vectorPI)
10
+
11
+ return vectorPI
12
+
13
+ P = np.array([[0.2,0.6,0.2],
14
+ [0.3,0.0,0.7],
15
+ [0.5,0.3,0.2]])
16
+ print("The Final steady-state (stationary distribution) of a Markov chain is: ", eigenDecomposition(P))
@@ -0,0 +1,20 @@
1
+ import numpy as np
2
+
3
+ def linearSystemModel(P):
4
+ n = P.shape[0]
5
+
6
+ A = P.T - np.eye(n)
7
+ b = np.zeros(n)
8
+
9
+ #Adding the sum equal to 1 constraing to filter the infinite solutions
10
+ A[-1] = np.ones(n)
11
+ b[-1] = 1
12
+
13
+ vectorPI = np.linalg.solve(A,b)
14
+
15
+ return vectorPI
16
+
17
+ P = np.array([[0.2,0.6,0.2],
18
+ [0.3,0.0,0.7],
19
+ [0.5,0.3,0.2]])
20
+ print("The Final steady-state (stationary distribution) of a Markov chain is: ", linearSystemModel(P))
@@ -0,0 +1,12 @@
1
+ import numpy as np
2
+
3
+ def multiply(A,B):
4
+ return A@B
5
+
6
+ P = np.array([[0.2,0.6,0.2],[0.3,0.0,0.7],[0.5,0.3,0.2]])
7
+ vectorPI = np.array([0.3,0.4,0.3])
8
+ n = int(input("No of Iterations you want to run: "))
9
+ for i in range(0,n):
10
+ vectorPI=multiply(vectorPI, P)
11
+
12
+ print("The Final steady-state (stationary distribution) of a Markov chain PI Vector after implementing power iteration is: ", vectorPI)
@@ -0,0 +1,62 @@
1
+ import math
2
+ import random
3
+ import matplotlib.pyplot as plt
4
+
5
+ #Solving a cubic equation using simulated annealing.
6
+ def simulated_Annealing(s0, T_max, T_min, alpha):
7
+ current_state= s0
8
+ T = T_max
9
+ E = []
10
+ states=[]
11
+ states.append(s0)
12
+ E.append(Energy(s0))
13
+
14
+ while T>T_min:
15
+
16
+ #Generate a random neighbour
17
+ next_state = getRandomNeighbour(current_state)
18
+
19
+ #Calculate the change in Energy
20
+ delta_E = Energy(next_state) - Energy(current_state)
21
+
22
+ #Decision rule
23
+ if delta_E < 0:
24
+ current_state = next_state
25
+ states.append(current_state)
26
+ E.append(Energy(current_state))
27
+
28
+ else:
29
+ r = random.random()
30
+
31
+ if r < pow(math.e, -delta_E/T):
32
+ current_state = next_state
33
+ states.append(current_state)
34
+ E.append(Energy(current_state))
35
+ T = T*alpha
36
+ plt.plot(states, E, label="Simulated Annealing Plot")
37
+ plt.plot(states[-1], E[-1], color='red', marker='o', label="Final Solution and Energy")
38
+ plt.text(states[-1], 0.5+E[-1], f"({states[-1]:.2f}, {E[-1]:.2f})")
39
+ plt.plot(states[E.index(min(E))], min(E), color='green', marker='o', label='Best Solution of the Run')
40
+ plt.text(states[E.index(min(E))], 0.5+min(E),f"({states[E.index(min(E))]:.2f},{min(E):.2f})")
41
+ plt.gcf().text(0.5, 0.01, f"The Final Solution state: {states[-1]:.2f} and Energy: {E[-1]:.2f}",
42
+ ha='center', fontsize=12)
43
+ plt.xlabel("States")
44
+ plt.ylabel("Energy")
45
+ plt.title("Simulated Annealing of x3-10x-2x2+10")
46
+ plt.legend()
47
+ plt.show()
48
+ return current_state
49
+
50
+ def getRandomNeighbour(currentState):
51
+ return random.uniform(-3,3)
52
+
53
+ def Energy(state):
54
+ return (state**3)-(10.0*state)-(2.0*(state**2))+10.0
55
+
56
+ print("******Welcome to simulated Annealing of x3-10x-2x2+10******")
57
+ Initial_State = float(input("What is the initial State:"))
58
+ Initial_Temparature = float(input("What is the initial Temparature:"))
59
+ Threshold_Temparature = float(input("What is the Threshold Temparature:"))
60
+ Cooling_Rate = float(input("What is the Cooling Rate:"))
61
+
62
+ Solution = simulated_Annealing(Initial_State, Initial_Temparature, Threshold_Temparature, Cooling_Rate)
File without changes
File without changes
@@ -0,0 +1,100 @@
1
+ %% LQR-Based Control of a Unicycle System
2
+ clear; clc; close all;
3
+ %% ===== PARAMETERS =====
4
+ v_d = 0.5; % desired forward velocity (m/s)
5
+ dt = 0.01; % time step (s)
6
+ T = 15; % total time (s)
7
+ t = 0:dt:T;
8
+ N = length(t);
9
+ init = [0, 0, 0]; % [x, y, theta]
10
+ goal = [3, 3, pi/4]; % [xd, yd, thetad]
11
+ %% ===== PART b: LINEARIZED SYSTEM =====
12
+ A = [0, 0, 0;
13
+ 0, 0, v_d;
14
+ 0, 0, 0];
15
+ B = [-1, 0;
16
+ 0, 0;
17
+ 0, -1];
18
+ %% ===== PART c: LQR DESIGN =====
19
+ Q = diag([10, 10, 5]); % penalize position & heading errors
20
+ R = diag([1, 0.5]); % penalize control effort
21
+ % Check controllability
22
+ Co = ctrb(A, B);
23
+ fprintf('Controllability rank: %d / %d\n', rank(Co), size(A,1));
24
+ % Compute LQR gain matrix
25
+ [K, ~, ~] = lqr(A, B, Q, R);
26
+ fprintf('LQR Gain K =\n'); disp(K);
27
+ %% ===== PART d: SIMULATE UNICYCLE WITH LQR =====
28
+ x = init(1); y = init(2); th = init(3);
29
+ xd = goal(1); yd = goal(2); thd = goal(3);
30
+ x_log = zeros(1,N);
31
+ y_log = zeros(1,N);
32
+ th_log = zeros(1,N);
33
+ v_log = zeros(1,N);
34
+ w_log = zeros(1,N);
35
+ e_log = zeros(1,N);
36
+ for i = 1:N
37
+ % Log current state
38
+ x_log(i) = x;
39
+ y_log(i) = y;
40
+ th_log(i) = th;
41
+ % Error in robot body frame
42
+ ex = cos(th)*(xd - x) + sin(th)*(yd - y);
43
+ ey = -sin(th)*(xd - x) + cos(th)*(yd - y);
44
+ et = atan2(sin(thd - th), cos(thd - th));
45
+ e = [ex; ey; et];
46
+ % LQR control law: u = K*e
47
+ u = K * e;
48
+ v = v_d + u(1); % linear velocity
49
+ w = u(2); % angular velocity
50
+ % Saturate inputs
51
+ v = max(-1.0, min(1.0, v));
52
+ w = max(-2.0, min(2.0, w));
53
+ v_log(i) = v;
54
+ w_log(i) = w;
55
+ e_log(i) = sqrt(ex^2 + ey^2);
56
+ end
57
+ % Unicycle kinematics update
58
+ x = x + dt * v * cos(th);
59
+ y = y + dt * v * sin(th);
60
+ th = th + dt * w;
61
+ th = atan2(sin(th), cos(th)); % wrap angle
62
+ fprintf('Final position error: %.4f m\n', e_log(end));
63
+ %% ===== PART e: PLOTS =====
64
+ % --- 1. Robot Path ---
65
+ figure('Color','w');
66
+ plot(x_log, y_log, 'b-', 'LineWidth', 2); hold on;
67
+ plot(init(1), init(2), 'go', 'MarkerSize', 10, 'MarkerFaceColor','g');
68
+ plot(goal(1), goal(2), 'r*', 'MarkerSize', 12, 'LineWidth', 2);
69
+ xlabel('X (m)'); ylabel('Y (m)');
70
+ title('LQR - Robot Path');
71
+ legend('Path', 'Start', 'Goal');
72
+ grid on; axis equal;
73
+ % --- 2. Position Error ---
74
+ figure('Color','w');
75
+ plot(t, e_log, 'r-', 'LineWidth', 2);
76
+ xlabel('Time (s)'); ylabel('Position Error (m)');
77
+ title('LQR - Position Error vs Time');
78
+ grid on;
79
+ % --- 3. Control Inputs ---
80
+ figure('Color','w');
81
+ subplot(2,1,1);
82
+ plot(t, v_log, 'b-', 'LineWidth', 2);
83
+ ylabel('v (m/s)'); title('LQR - Linear Velocity');
84
+ grid on;
85
+ subplot(2,1,2);
86
+ plot(t, w_log, 'r-', 'LineWidth', 2);
87
+ xlabel('Time (s)'); ylabel('\omega (rad/s)');
88
+ title('LQR - Angular Velocity');
89
+ grid on;
90
+ % --- 4. X, Y, Theta over time ---
91
+ figure('Color','w');
92
+ subplot(3,1,1);
93
+ plot(t, x_log, 'b', 'LineWidth', 1.5); yline(goal(1),'r--');
94
+ ylabel('X (m)'); title('LQR - State Trajectories'); grid on;
95
+ subplot(3,1,2);
96
+ plot(t, y_log, 'b', 'LineWidth', 1.5); yline(goal(2),'r--');
97
+ ylabel('Y (m)'); grid on;
98
+ subplot(3,1,3);
99
+ plot(t, th_log, 'b', 'LineWidth', 1.5); yline(goal(3),'r--');
100
+ ylabel('\theta (rad)'); xlabel('Time (s)'); grid on;
@@ -0,0 +1,118 @@
1
+ clc;
2
+ clear;
3
+ close all;
4
+ %% Simulation Parameters
5
+ dt = 0.1;
6
+ T = 25;
7
+ time = 0:dt:T;
8
+ %% Desired Goal Position
9
+ x_goal = 10;
10
+ y_goal = 10;
11
+ %% Controller Gains
12
+ % P
13
+ Kp_P = 0.8;
14
+ % PI
15
+ Kp_PI = 0.8;
16
+ Ki_PI = 0.02;
17
+ % PD
18
+ Kp_PD = 0.8;
19
+ Kd_PD = 0.3;
20
+ % PID
21
+ Kp_PID = 0.8;
22
+ Ki_PID = 0.02;
23
+ Kd_PID = 0.3;
24
+ controllers = {'P','PI','PD','PID'};
25
+ %% Create Figures
26
+ figure(1);
27
+ figure(2);
28
+ %% =========================================================
29
+ %% LOOP THROUGH CONTROLLERS
30
+ %% =========================================================
31
+ for c = 1:length(controllers)
32
+ %% Initial Conditions
33
+ x = 0;
34
+ y = 0;
35
+ theta = 0;
36
+ integral = 0;
37
+ prev_error = 0;
38
+ X = [];
39
+ Y = [];
40
+ E = [];
41
+ %% Simulation Loop
42
+ for k = 1:length(time)
43
+ %% Distance Error
44
+ error = sqrt((x_goal-x)^2 + (y_goal-y)^2);
45
+ %% Desired Heading
46
+ theta_d = atan2((y_goal-y),(x_goal-x));
47
+ %% Heading Error
48
+ omega = 2*(theta_d - theta);
49
+ %% Integral & Derivative Terms
50
+ integral = integral + error*dt;
51
+ derivative = (error - prev_error)/dt;
52
+ %% Controller Selection
53
+ switch controllers{c}
54
+ case 'P'
55
+ v = Kp_P*error;
56
+ case 'PI'
57
+ v = Kp_PI*error + ...
58
+ Ki_PI*integral;
59
+ case 'PD'
60
+ v = Kp_PD*error + ...
61
+ Kd_PD*derivative;
62
+ case 'PID'
63
+ v = Kp_PID*error + ...
64
+ Ki_PID*integral + ...
65
+ Kd_PID*derivative;
66
+ end
67
+ %% Velocity Saturation
68
+ v = min(v,2);
69
+ %% Unicycle Model
70
+ x = x + v*cos(theta)*dt;
71
+ y = y + v*sin(theta)*dt;
72
+ theta = theta + omega*dt;
73
+ %% Store Data
74
+ X = [X x];
75
+ Y = [Y y];
76
+ E = [E error];
77
+ prev_error = error;
78
+ end
79
+ %% =====================================================
80
+ %% FIGURE 1 : ROBOT TRAJECTORY
81
+ %% =====================================================
82
+ figure(1);
83
+ subplot(2,2,c);
84
+ plot(X,Y,'b','LineWidth',2);
85
+ hold on;
86
+ %% Start Position
87
+ plot(X(1),Y(1),...
88
+ 'go','MarkerSize',10,'LineWidth',2);
89
+ %% Goal Position
90
+ plot(x_goal,y_goal,...
91
+ 'kx','MarkerSize',12,'LineWidth',3);
92
+ %% Final Robot Position
93
+ plot(X(end),Y(end),...
94
+ 'ro','MarkerSize',10,'LineWidth',2);
95
+ %% Robot Direction Arrow
96
+ quiver(X(end),Y(end),...
97
+ cos(theta),sin(theta),...
98
+ 0.8,'r','LineWidth',2);
99
+ grid on;
100
+ axis equal;
101
+ xlabel('X Position');
102
+ ylabel('Y Position');
103
+ title([controllers{c} ' Controller']);
104
+ legend('Trajectory',...
105
+ 'Start Position',...
106
+ 'Goal Position',...
107
+ 'Robot Position');
108
+ %% =====================================================
109
+ %% FIGURE 2 : ERROR vs TIME
110
+ %% =====================================================
111
+ figure(2);
112
+ subplot(2,2,c);
113
+ plot(time,E,'LineWidth',2);
114
+ grid on;
115
+ xlabel('Time (s)');
116
+ ylabel('Distance Error');
117
+ title([controllers{c} ' Error vs Time']);
118
+ end