Syncing to work on interview with entrepreneur essay
This commit is contained in:
BIN
6th-Semester-Spring-2024/SysCon/Labs/Lab7/SysConLab7.mlx
Normal file
BIN
6th-Semester-Spring-2024/SysCon/Labs/Lab7/SysConLab7.mlx
Normal file
Binary file not shown.
Binary file not shown.
25
6th-Semester-Spring-2024/SysCon/routh_hurwitz.m/license.txt
Normal file
25
6th-Semester-Spring-2024/SysCon/routh_hurwitz.m/license.txt
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright (c) 2019, Varun Bhatia
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution
|
||||
* Neither the name of nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
341
6th-Semester-Spring-2024/SysCon/routh_hurwitz.m/routh_hurwitz.m
Normal file
341
6th-Semester-Spring-2024/SysCon/routh_hurwitz.m/routh_hurwitz.m
Normal file
@ -0,0 +1,341 @@
|
||||
%% Routh-Hurwitz Stability Criterion Table Generator V1.1
|
||||
|
||||
% Author: Varun Bhatia [bhatiav16@berkeley.edu]
|
||||
|
||||
% Date: July 28, 2019
|
||||
|
||||
% This function goes through the process of setting up a Routh-Hurwitz
|
||||
% table to determine information regarding the in/stability of a control
|
||||
% system given a closed/open-loop transfer function. More specifically, this
|
||||
% will solve for and output how many closed/open-loop poles are in the
|
||||
% right-half plane, the left-half plane, and on the jw-axis. Additionally,
|
||||
% this function will take into account and generate the Routh_Hurwitz table
|
||||
% given two special cases:
|
||||
% 1)First element of a row is 0.
|
||||
% 2)Entire Row is 0.
|
||||
|
||||
%Recall that this function operates under the assumption that you are
|
||||
%inputting a CLOSED LOOP TRANSFER FUNCTION. Later developments will
|
||||
%incorporate inputs of open loop forward transfer functions with unity
|
||||
%and/or nonunity feedback.
|
||||
|
||||
%Any usage of MATLAB functions is accredited to MathWorks.
|
||||
|
||||
%UPDATE 1.1: This program now takes into account UNITY feedback.
|
||||
|
||||
%%
|
||||
|
||||
function []= routh_hurwitz()
|
||||
|
||||
prompt_n = 'Enter highest power in numerator: ';
|
||||
num_hp = input(prompt_n);
|
||||
num_hp_added = num_hp + 1;
|
||||
num = zeros(1, num_hp_added);
|
||||
|
||||
for i = 1:num_hp+1
|
||||
num(i) = input('Enter coefficients, starting with the highest power: ');
|
||||
end
|
||||
|
||||
prompt_d = 'Enter highest power in denominator: ';
|
||||
den_hp = input(prompt_d);
|
||||
den_hp_added = den_hp + 1;
|
||||
den = zeros(1, den_hp_added);
|
||||
|
||||
for i = 1:den_hp+1
|
||||
den(i) = input('Enter coefficients, starting with the highest power: ');
|
||||
end
|
||||
|
||||
prompt_TF = 'Are you entering an open loop or closed loop TF? If closed loop type "C", if open loop type "O" with quotes around letter: ';
|
||||
TF_type = input(prompt_TF);
|
||||
|
||||
if TF_type == "O"
|
||||
|
||||
H = tf(num,den);
|
||||
K = 1;
|
||||
G = feedback(H,K)
|
||||
[~,d] = tfdata(G, 'v');
|
||||
den = d; %to acquire the new denominator coefficients from post-feedback
|
||||
|
||||
elseif TF_type == "C"
|
||||
|
||||
G = tf(num,den)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
if den_hp == 0
|
||||
cols = 1;
|
||||
elseif den_hp == 1 | den_hp == 2
|
||||
cols = 2;
|
||||
elseif den_hp == 3 | den_hp == 4
|
||||
cols = 3;
|
||||
elseif den_hp == 5 | den_hp == 6
|
||||
cols = 4;
|
||||
elseif den_hp == 7 | den_hp == 8
|
||||
cols = 5;
|
||||
elseif den_hp == 9 | den_hp == 10
|
||||
cols = 6;
|
||||
elseif den_hp == 11 | den_hp == 12
|
||||
cols = 7;
|
||||
elseif den_hp == 13 | den_hp == 14
|
||||
cols = 8;
|
||||
end
|
||||
|
||||
%the matrix with proper number of rows and columns
|
||||
RH_Table = zeros(den_hp+1, cols);
|
||||
|
||||
|
||||
%set up the first element in row 1 & row 2 since MATLAB doesn't do 0 indexing
|
||||
if cols == 1
|
||||
RH_Table(1,1) = den(1);
|
||||
|
||||
elseif cols > 1
|
||||
RH_Table(1,1) = den(1);
|
||||
RH_Table(2,1) = den(2);
|
||||
|
||||
end
|
||||
|
||||
if cols == 1
|
||||
fprintf('\n *Only one element in the RH Table, thus, you have a stable system.* \n');
|
||||
|
||||
elseif cols > 1
|
||||
first_count = 3; %since added first element (element 1) above so now skip one and start at 3rd element for first row
|
||||
second_count = 4; %since added second element (element 2) above so now skip one and start at 4th element for second row
|
||||
|
||||
%filling in the first row of the RH table
|
||||
for i = 2:cols %start at 2 because filled in first element above
|
||||
if first_count <= den_hp_added
|
||||
RH_Table(1,i) = den(first_count);
|
||||
first_count = first_count + 2;
|
||||
else
|
||||
RH_Table(1,i) = 0;
|
||||
end
|
||||
end
|
||||
|
||||
%filling in the second row of the RH table
|
||||
for i = 2:cols %start at 2 because filled in first element above
|
||||
if second_count <= den_hp_added
|
||||
RH_Table(2,i) = den(second_count);
|
||||
second_count = second_count + 2;
|
||||
else
|
||||
RH_Table(2,i) = 0;
|
||||
end
|
||||
end
|
||||
|
||||
%now fill in remaining elements of RH Table with determinants
|
||||
X = zeros(2,2);
|
||||
|
||||
for i = 1:(den_hp-1)
|
||||
for j = 1:(cols-1)
|
||||
X(1,1) = RH_Table(i,1);
|
||||
X(2,1) = RH_Table(i+1,1);
|
||||
X(1,2) = RH_Table(i,j+1);
|
||||
X(2,2) = RH_Table(i+1,j+1);
|
||||
|
||||
RH_Table(i+2,j) = -det(X)/RH_Table(i+1,1);
|
||||
end
|
||||
end
|
||||
|
||||
RH_Table % to show full RH table
|
||||
|
||||
%now analyze the first column of the table for sign changes to
|
||||
%determine how many poles in the right half-plane.
|
||||
sign_changes = 0;
|
||||
for i = 1:(den_hp)
|
||||
if (RH_Table(i,1) * RH_Table(i+1,1) < 0)
|
||||
sign_changes = sign_changes + 1;
|
||||
end
|
||||
end
|
||||
|
||||
if sign_changes > 0
|
||||
fprintf(['\n *You have %d right-half poles and %d left-half poles.',...
|
||||
' Thus, you have an unstable system.* \n'],sign_changes,den_hp-sign_changes)
|
||||
else
|
||||
fprintf(['\n *You have %d right-half poles and %d left-half poles.',...
|
||||
' Thus, you have a stable system.* \n'],sign_changes,den_hp-sign_changes)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
%Special Case #1: Check if there exists a full row of zeros. If so, the
|
||||
%following code will be utilized.
|
||||
|
||||
%first check if any array contains a row of zeros
|
||||
row_of_zeros = 0;
|
||||
tol = 1.e-6;
|
||||
for i = 1:(den_hp + 1)
|
||||
if abs(RH_Table(i,:) - 0) < tol
|
||||
row_of_zeros = 1;
|
||||
row = i;
|
||||
break; %break because you have identified a row of zeros
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%If the check shows that you do indeed have a row of zeros, the following
|
||||
%code will run
|
||||
|
||||
if (row_of_zeros == 1)
|
||||
row_above = RH_Table(row-1,:);
|
||||
aux_poly = poly2sym(row_above);
|
||||
diff_poly = diff(aux_poly);
|
||||
diff_poly_coeffs = flip(coeffs(diff_poly));
|
||||
|
||||
for j = 1:cols
|
||||
if numel(diff_poly_coeffs) < cols
|
||||
diff_poly_coeffs = [diff_poly_coeffs, 0]; %add zero to the end of coefficients to make sure dimensions match when adding back to table
|
||||
else
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
RH_Table(row,:) = diff_poly_coeffs; %replacing row in RH Table with the coefficients of row above, differentiated
|
||||
|
||||
X = zeros(2,2);
|
||||
|
||||
for i = row-1:(den_hp-1)
|
||||
for j = 1:(cols-1)
|
||||
X(1,1) = RH_Table(i,1);
|
||||
X(2,1) = RH_Table(i+1,1);
|
||||
X(1,2) = RH_Table(i,j+1);
|
||||
X(2,2) = RH_Table(i+1,j+1);
|
||||
|
||||
RH_Table(i+2,j) = -det(X)/RH_Table(i+1,1);
|
||||
end
|
||||
end
|
||||
|
||||
%Split up the sign changes process into two:
|
||||
%1) Check sign changes until two rows above row of zeros normally and
|
||||
%store these sign changes.
|
||||
%2) Check sign changes from one row above row of zeros down to bottom.
|
||||
%By symmetry, the right half poles must equal the left half poles, and
|
||||
%anything left over are jw-axis poles. Additionally, the row above the
|
||||
%row of zeros is required to be an even polynomial.
|
||||
|
||||
%1)
|
||||
first_sign_changes = 0;
|
||||
second_sign_changes = 0;
|
||||
for k = 1:(row-2)
|
||||
if (RH_Table(k,1) * RH_Table(k+1,1) < 0)
|
||||
first_sign_changes = first_sign_changes + 1;
|
||||
end
|
||||
end
|
||||
|
||||
%2)
|
||||
for k = row-1:den_hp
|
||||
if (RH_Table(k,1) * RH_Table(k+1,1) < 0)
|
||||
second_sign_changes = second_sign_changes + 1;
|
||||
end
|
||||
end
|
||||
|
||||
total_sign_changes = first_sign_changes + second_sign_changes;
|
||||
left_half_poles =((row-2)-first_sign_changes + second_sign_changes);
|
||||
jw_axis_poles = den_hp - (row-2) - (2*second_sign_changes);
|
||||
|
||||
RH_Table
|
||||
|
||||
if (total_sign_changes) > 0
|
||||
fprintf(['\n *Upon changes made to the RH Table, you now have %d right-half',...
|
||||
' poles and %d left-half poles. Additionally, you have %d jw-axis poles. Thus, you have an unstable',...
|
||||
' system.* \n'],total_sign_changes,left_half_poles,jw_axis_poles);
|
||||
elseif (total_sign_changes == 0)
|
||||
fprintf(['\n *Upon changes made to the RH Table, you now have %d',...
|
||||
' right-half poles and %d left-half poles. Additionally, you have %d jw-axis poles.',...
|
||||
' Thus, you have a marginally stable system.* \n'],total_sign_changes,left_half_poles, jw_axis_poles);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%Special Case #2: Check if zero exists in first column and if so, form reciprocal
|
||||
%polynomial and redo process above to get determinants. Have a separate
|
||||
%method for this portion, however, for the purposes of File Exchange, I've
|
||||
%attached that portion below.
|
||||
|
||||
for i = 1:(den_hp+1)
|
||||
if RH_Table(i,1) == 0
|
||||
den = flip(den);
|
||||
if cols == 1
|
||||
RH_Table(1,1) = den(1);
|
||||
elseif cols > 1
|
||||
RH_Table(1,1) = den(1);
|
||||
RH_Table(2,1) = den(2);
|
||||
end
|
||||
|
||||
if cols == 1
|
||||
fprintf('\n *Only one element in the RH Table, thus, you have a stable system.* \n');
|
||||
elseif cols > 1
|
||||
first_count = 3;
|
||||
second_count = 4;
|
||||
for k = 2:cols
|
||||
if first_count <= den_hp_added
|
||||
RH_Table(1,k) = den(first_count);
|
||||
first_count = first_count + 2;
|
||||
else
|
||||
RH_Table(1,k) = 0;
|
||||
end
|
||||
end
|
||||
|
||||
for l = 2:cols
|
||||
if second_count <= den_hp_added
|
||||
RH_Table(2,l) = den(second_count);
|
||||
second_count = second_count + 2;
|
||||
else
|
||||
RH_Table(2,l) = 0;
|
||||
end
|
||||
end
|
||||
|
||||
X = zeros(2,2);
|
||||
for m = 1:(den_hp-1)
|
||||
for j = 1:(cols-1)
|
||||
X(1,1) = RH_Table(m,1);
|
||||
X(2,1) = RH_Table(m+1,1);
|
||||
X(1,2) = RH_Table(m,j+1);
|
||||
X(2,2) = RH_Table(m+1,j+1);
|
||||
|
||||
RH_Table(m+2,j) = -det(X)/RH_Table(m+1,1);
|
||||
end
|
||||
end
|
||||
|
||||
sign_changes = 0;
|
||||
for k = 1:(den_hp)
|
||||
if (RH_Table(k,1) * RH_Table(k+1,1) < 0) %if the element * next element is negative, must be a sign change
|
||||
sign_changes = sign_changes + 1;
|
||||
end
|
||||
end
|
||||
|
||||
RH_Table
|
||||
if sign_changes > 0
|
||||
fprintf(['\n *Upon changes made to the RH Table, you now have %d right-half',...
|
||||
' poles and %d left-half poles. Thus, you have an unstable',...
|
||||
' system.* \n'],sign_changes,den_hp-sign_changes)
|
||||
else
|
||||
fprintf(['\n *Upon changes made to the RH Table, you now have %d',...
|
||||
' right-half poles and %d left-half poles.',...
|
||||
' Thus, you have a stable system.* \n'],sign_changes,den_hp-sign_changes)
|
||||
end
|
||||
end
|
||||
end
|
||||
end %end special case #2%
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user