0% found this document useful (0 votes)
8 views25 pages

FCS Assignment

The document is an assignment by Adhithya Vishwa A, detailing various control system analyses and designs using Python scripts. It covers first and second order system step responses, pole-zero maps, root locus plots, Bode plots, state feedback design, and state observer design. Each section includes code snippets and results demonstrating the respective control system concepts.

Uploaded by

dravidabishek22
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views25 pages

FCS Assignment

The document is an assignment by Adhithya Vishwa A, detailing various control system analyses and designs using Python scripts. It covers first and second order system step responses, pole-zero maps, root locus plots, Bode plots, state feedback design, and state observer design. Each section includes code snippets and results demonstrating the respective control system concepts.

Uploaded by

dravidabishek22
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

FCS Assignment

Name: Adhithya Vishwa A

Reg. No.: 127179004

Date: 04.05.2025

Contents:

First Order Sysytem Step Response ---------------------------------- 2

Second Sysytem Order Step Response ------------------------------ 5

Pole-Zero Map ------------------------------------------------------------ 8

Root Locus Plot ----------------------------------------------------------- 11

Bode Plot ------------------------------------------------------------------- 14

Design of State Feedback ----------------------------------------------- 18

Design of State Observer ------------------------------------------------ 22


| First Order System Step
Ex. 1

Response - Python Script

Code:
import matplotlib.pyplot as plt

from control import tf, step_response

import numpy as np

# Define the transfer functions

sys1 = tf([1], [1, 1])

sys2 = tf([1], [5, 1])

sys3 = tf([1], [0.5, 1])

# Generate a time vector

T = np.linspace(0, 10, 1000)

# Get step responses

T1, y1 = step_response(sys1, T)

T2, y2 = step_response(sys2, T)

T3, y3 = step_response(sys3, T)

# Plot the step responses


plt.figure()

plt.plot(T1, y1, label='sys1: 1/(s+1)')

plt.plot(T2, y2, label='sys2: 1/(5s+1)')

plt.plot(T3, y3, label='sys3: 1/(0.5s+1)')

plt.title('Step Response of sys1, sys2, and sys3')

plt.xlabel('Time (seconds)')

plt.ylabel('Amplitude')

plt.grid(True)

plt.legend()

plt.show()
Output:

Result:
Hence the Output was obtained.
| Second Order System Step
Ex. 2

Response - Python Script

Code:
import numpy as np

import matplotlib.pyplot as plt

from control.matlab import tf, step

# Time vector

t = np.arange(0, 20.0001, 0.01)

# Define transfer functions

systems = [

tf([5], [1, 0, 5]),

tf([5], [1, 2, 5]),

tf([5], [1, 5, 5]),

tf([5], [1, 7, 5])

labels = [

'sys1: [1, 0, 5]',

'sys2: [1, 2, 5]',


'sys3: [1, 5, 5]',

'sys4: [1, 7, 5]'

plt.figure(figsize=(10, 6))

# Compute and plot each step response with axes swapped

for sys, label in zip(systems, labels):

t_out, y_out = step(sys, T=t)

plt.plot(y_out, t_out, label=label) # Swapped x and y

plt.title('Step Response of Systems (Axes Swapped)')

plt.xlabel('Amplitude')

plt.ylabel('Time (seconds)')

plt.legend()

plt.grid(True)

plt.show()
Output:

Result:
Hence the Output was obtained.
Ex. 3 | Pole-Zero Map - Python Script

Code:
import matplotlib.pyplot as plt

from control import tf, pzmap

wn = 1

K=1

T1 = 0

T2 = 0.5

T3 = 1

T4 = 5

# Define transfer functions

sys1 = tf([K], [1, 2*T1*wn, wn**2])

sys2 = tf([K], [1, 2*T2*wn, wn**2])

sys3 = tf([K], [1, 2*T3*wn, wn**2])

sys4 = tf([K], [1, 2*T4*wn, wn**2])

# Plot pole-zero maps in subplots

plt.figure(figsize=(8, 12))

plt.subplot(4, 1, 1)
pzmap(sys1, title='Pole-Zero Map: T1=0')

plt.subplot(4, 1, 2)

pzmap(sys2, title='Pole-Zero Map: T2=0.5')

plt.subplot(4, 1, 3)

pzmap(sys3, title='Pole-Zero Map: T3=1')

plt.subplot(4, 1, 4)

pzmap(sys4, title='Pole-Zero Map: T4=5')

plt.tight_layout()

plt.show()
Output:

Result:
Hence the Output was obtained.
| Root Locus Plot - Python
Ex. 4

Script

Code:
import matplotlib.pyplot as plt

from control import tf, rlocus

# Define the transfer functions

sys1 = tf([1], [1, 4]) # 1/(s + 4)

sys2 = tf([1], [1, 4, 0]) # 1/(s^2 + 4s)

sys3 = tf([1], [1, 4, 0, 0]) # 1/(s^3 + 4s^2)

sys4 = tf([1, 9], [1, 4, 0, 0]) # (s + 9)/(s^3 + 4s^2)

# Create subplots with constrained layout for better spacing

fig, axs = plt.subplots(2, 2, figsize=(12, 8), constrained_layout=True)

# Plot root locus for each transfer function

rlocus(sys1, ax=axs[0, 0])

axs[0, 0].set_title('Root Locus of sys1: 1/(s + 4)')

rlocus(sys2, ax=axs[0, 1])

axs[0, 1].set_title('Root Locus of sys2: 1/(s² + 4s)')


rlocus(sys3, ax=axs[1, 0])

axs[1, 0].set_title('Root Locus of sys3: 1/(s³ + 4s²)')

rlocus(sys4, ax=axs[1, 1])

axs[1, 1].set_title('Root Locus of sys4: (s + 9)/(s³ + 4s²)')

# Show the plots

plt.show()
Output:

Result:
Hence the Output was obtained.
Ex. 5 | Bode Plot - Python Script

Code:
import numpy as np

import matplotlib.pyplot as plt

import matplotlib.gridspec as gridspec

from control import tf, margin, bode_plot

from numpy.polynomial import polynomial as P

# Define transfer functions

sys1 = tf([1], [1, 4])

sys2 = tf([1], P.polyfromroots([0, -4]))

sys3 = tf([1], P.polyfromroots([0, 0, -4]))

sys4 = tf([1, 9], P.polyfromroots([0, 0, -4]))

systems = [sys1, sys2, sys3, sys4]

titles = [

'First Order System',

'Second Order System',

'Third Order System',

'Third Order System with Zero'

]
# Create figure with gridspec for nested subplots

fig = plt.figure(figsize=(14, 10))

gs = gridspec.GridSpec(2, 2, figure=fig, hspace=0.5, wspace=0.3)

for idx, (sys, title) in enumerate(zip(systems, titles)):

# Get row/col position in main grid

row = idx // 2

col = idx % 2

# Create a 2x1 subgrid for magnitude/phase in this cell

subgs = gs[row, col].subgridspec(2, 1)

mag_ax = fig.add_subplot(subgs[0])

phase_ax = fig.add_subplot(subgs[1])

# Calculate margins

gm, pm, _, _ = margin(sys)

# Generate Bode plot on the two axes

bode_plot(

sys,

dB=True,

plot_magnitude=True,

plot_phase=True,
omega_limits=(1e-2, 1e3),

display_margins=True,

margins_method='best',

title=title,

ax=[mag_ax, phas""" """e_ax] # Pass BOTH axes as a list

# Annotate margins

if not np.isinf(gm):

gm_db = 20 * np.log10(gm)

mag_ax.axhline(gm_db, color='r', linestyle='--', alpha=0.7)

mag_ax.text(0.5, gm_db + 2, f'GM: {gm_db:.1f} dB',

color='r', ha='center')

if not np.isnan(pm):

phase_ax.axhline(-180 + pm, color='b', linestyle='--', alpha=0.7)

phase_ax.text(0.5, -180 + pm + 5, f'PM: {pm:.1f}°',

color='b', ha='center')

plt.tight_layout()

plt.show()
Output:

Result:
Hence the Output was obtained.
| Design of State Feedback -
Ex. 6

Python Script
Code:
import numpy as np

import matplotlib.pyplot as plt

from control import ss, place, ctrb, step_response

# System matrices

A = np.array([[0, 1, 0],

[0, 0, 1],

[-1, -5, -6]])

B = np.array([[0], [0], [1]]) # Corrected as column vector

C = np.array([[1, 0, 0]]) # Corrected as row vector

D = np.array([[0]]) # Corrected as 2D array

# Check controllability

U = ctrb(A, B)

if np.linalg.matrix_rank(U) != A.shape[0]:

raise ValueError("System is not controllable")

# Desired closed-loop poles

desired_poles = [-2+4j, -2-4j, -10 ]# Complex conjugate poles


# Compute state feedback gain

K = place(A, B, desired_poles)

# Closed-loop system

A_cl = A - B @ K

sys_cl = ss(A_cl, B, C, D)

# Simulate step response

t = np.linspace(0, 10, 1000)

t_step, y_step = step_response(sys_cl, t, X0=[1, 0, 0])

# Plot results

plt.figure(figsize=(10, 6))

plt.plot(t_step, y_step, label='Output', linewidth=2)

plt.xlabel('Time (s)', fontsize=12)

plt.ylabel('System Response', fontsize=12)

plt.title('Closed-Loop Response with Pole Placement', fontsize=14)

plt.grid(True)

plt.legend()

plt.show()

# Display gain matrix


print("\nState feedback gain matrix K:")

print(K)
Output:

Result:
Hence the Output was obtained.
| Design of State Observer -
Ex. 7

Python Script

Code:
import numpy as np

import control as ctrl

import matplotlib.pyplot as plt

Rs = 0.47

Lq = 1.23e-3

B = 0.0002

Kb = 0.42

Kt = 0.73

J = 6.5e-4

A = np.array([[-B/J, Kt/J],

[-Kb/Lq, -Rs/Lq]])

B = np.array([[0],

[1/Lq]])

C = np.array([[1, 0]])

D = np.array([[0]])

open_sys = ctrl.ss(A, B, C, D)

wr = 3 # reference omega, ω

zr = 0.7 # reference zeta, ζ


nr = wr**2

dr = [1, 2*zr*wr, wr**2] # x" + 2·ζ·ω·x' + ω^2·x

Gr = ctrl.tf([nr], dr)

cp = ctrl.poles(Gr)

K = ctrl.acker(A, B, cp)

sys = ctrl.ss(A - B @ K, B, C, D)

Nbar = 1 / ctrl.dcgain(sys)

cls = ctrl.ss(A - B @ K, B * Nbar, C, D)

or_val = 10 * np.real(cp[0])

op = [or_val + 1, or_val - 1]

L = ctrl.place(A.T, C.T, op).T

Aco = np.block([[A - B @ K, B @ K],

[np.zeros_like(A), A - L @ C]])

Bco = np.vstack([B * Nbar, np.zeros_like(B)])

Cco = np.hstack([C, np.zeros_like(C)])

Dco = 0

clco = ctrl.ss(Aco, Bco, Cco, Dco)

plt.figure()

plt.grid(True)

plt.title('Step Response Comparison')

t = np.linspace(0, 2, 500)

t1, y_clco = ctrl.step_response(clco, t)

t2, y_cls = ctrl.step_response(cls, t)


t3, y_open = ctrl.step_response(open_sys, t)

plt.plot(t1, y_clco.T, '-*b', label='Closed-loop observer-based control')

plt.plot(t2, y_cls.T, '-r', label='Closed-loop state feedback')

plt.plot(t3, y_open.T, '--g', label='Open loop')

plt.xlabel('Time (s)')

plt.ylabel('Output')

plt.legend()

plt.show()
Output:

Result:
Hence the Output is obtained.

You might also like