import control
import numpy as np
import matplotlib.pyplot as plt
import kontrol
# Load the transfer function
plant = kontrol.load_transfer_function("../system_modeling/transfer_function_x1_without_guess.pkl")
# Get a controller. regulator_type="PID" for PID controller.
# The I component gives the system the ability to trace a setpoint with 0 error.
# The P component speeds up the control.
controller = kontrol.regulator.oscillator.pid(plant, regulator_type="PID")
# We don't need to damp the high frequency modes.
# Get some notch filters
# the notch_peaks_above=0.1 means we'll notch all peaks above 0.1 Hz.
notches = kontrol.regulator.post_filter.post_notch(plant, regulator=controller, notch_peaks_above=0.1)
# ^this returns a list of notch filters.
notches = np.prod(notches) # To get a transfer function, we take the product of the notches.
# Get a low-pass filter.
# This lower the cut-off frequency of the low-pass filter until
# a specified phase margin is attained (defaults to 45 degrees.)
# Use the phase_margin option to override this.
low_pass = kontrol.regulator.post_filter.post_low_pass(plant, regulator=controller, post_filter=notches, order=4)
# Final filter.
controller *= low_pass*notches
# Inspect the open-loop transfer function
oltf = controller*plant
f = np.logspace(-3, 2, 1024)
plt.subplot(211)
plt.loglog(f, abs((oltf)(1j*2*np.pi*f)), label="Open-loop transfer function")
plt.legend(loc=0)
plt.grid(which="both")
plt.ylabel("Magnitude")
plt.subplot(212)
plt.semilogx(f, 180/np.pi*np.angle(oltf(1j*2*np.pi*f)))
# plt.legend(loc=0)
plt.grid(which="both")
plt.xlabel("Frequency (Hz)")
plt.ylabel("Phase (degree)")