Почему моя система пространства состояний с ПИД-управлением всегда нестабильна?Python

Программы на Python
Anonymous
Почему моя система пространства состояний с ПИД-управлением всегда нестабильна?

Сообщение Anonymous »

Я не могу найти правильное усиление для моего контроллера, который должен обеспечить стабильность балочно-шаровой системы. Цель задачи о мяче и балке — управлять напряжением (V), чтобы переместить шар в определенное положение (r) на балке. Но поскольку он всегда нестабилен, похоже, что мой контроллер недостаточно быстро реагирует на вызываемые им колебания. Если я отлаживаю свой код, кажется, что до того, как моя матрица A сможет передать изменения из первого цикла в «r», значение «qdot» уже слишком велико, чтобы противостоять ему с помощью усиления. Поэтому моя система всегда стремится к бесконечности. A — линеаризованная матрица 6x6, а B — матрица 6x1 вида [0,0,0,0,0,1]
Это код Python:

Код: Выделить всё

#Code to determine the A and B matrix

import numpy as np
import matplotlib.pyplot as plt

#Define constants, state space variables, and calculate_system_matrices function...

class PIDController:
def __init__(self, Kc, Ti, Td, setpoint, A, B, C, D):

#initializing, for example:

self.max_output = 24

def compute(self, current_value, current_time):
error = self.setpoint - current_value[0]

delta_time = current_time - self.prev_time
self.prev_time = current_time

# Proportional term
proportional = self.Kc * error
self.proportional_values.append(proportional)

# Integral term
if self.Ti != 0:
self.integral += error * delta_time
self.integral = np.clip(self.integral, -
self.max_output/self.Ti, self.max_output/self.Ti)
else:
self.integral = 0.0
self.integral_values.append(self.integral)  # Store integral term

# Derivative term
if delta_time != 0:
self.derivative = (error - self.prev_error) / delta_time
else:
# Handle division by zero error
self.derivative = 0.0
self.derivative_values.append(self.derivative)

self.prev_error = error

# PID control law with output limitation
if self.Ti != 0 and self.Td !=0:
pid_output = proportional + self.Kc/self.Ti * self.integral +
self.Kc * self.Td * self.derivative
elif self.Td !=0:
pid_output = proportional + self.Kc * self.Td * self.derivative

else:
pid_output = proportional

# Apply output saturation
pid_output = np.clip(pid_output, -self.max_output, self.max_output)

# State-space model simulation
x_next = np.dot(self.A, current_value) + self.B * pid_output
output = np.dot(self.C, current_value) + self.D * pid_output

self.r_values.append(current_value[0])
self.error_values.append(error)

return output, x_next

if __name__ == "__main__":
# Calculate system matrices A and B from the provided system dynamics
A, B = calculate_system_matrices()
C = np.array([[1., 0., 0., 0., 0., 0.]])

# Define output matrix C and feedforward matrix D based on your
requirements
C = np.array([[1., 0., 0., 0., 0., 0.]])
D = np.array([[0.]])

# Setpoint is the target value
setpoint = 0.2

# Define initial state
initial_state = np.array([[0.1], [0], [0], [0], [0], [0]])

Kc = 10
Ti = 0
Td = 1

# Initialize PID controller with tuned parameters
pid = PIDController(Kc, Ti, Td, setpoint, A, B, C, D)

# Simulation parameters
num_steps = 100
current_time = 0.0  # Initialize current time

# Lists to store results
outputs = []
r_values = []
error_values = []

current_value = initial_state
# Simulating the system
for _ in range(num_steps):
# Compute control signal and update state
output, current_value = pid.compute(current_value, current_time)

# Store results
outputs.append(output)
r_values.append(current_value[0])  # Assuming position is the first element of current_value
error_values.append(pid.setpoint - current_value[0])  # Calculate error

# Increment time
current_time += 0.1  # Increment current_time by 1 (assuming unit time steps)
print("current_time:",current_time)
#print("Output:", output, "State:", current_value)
Я попробовал добавить тюнер Циглера-Николса, но он не смог найти правильное усиление. Я пытался сократить приращение current_time, но и это не помогло. Я попытался установить ограничение на pid_output, но система все равно уходит в бесконечность. Чтобы было легче сосредоточиться на проблеме, я удалил часть кода, определяющую код A и B, а также класс Циглера Николса.

Подробнее здесь: https://stackoverflow.com/questions/783 ... s-unstable

Вернуться в «Python»