如何解决PI 控制器线程和奇怪的问题
我将旋转编码器连接到直流电机轴上,希望在 PI4 上创建一个 python 脚本,在其中可以设置所需的角度,电机将以 10 的占空比顺时针移动,电机将停止并将位置保持在所需的角度,一旦设置的角度从旋转编码器读回代码(@每转 800 个脉冲 - 读出 0.45 度增量)。
理想情况下,PI 控制器将保持设定的角度(在代码中设置,但在以后的 GUI 中设置)并且无论轴上的外力如何都不会移动。
最后,我在我的 PI 控制信号“PI”进入占空比输出后使用 if 语句,从而控制电机在达到设定点时的速度(减速或加速 tp 到达设定点)与控制方向输出的错误 PI 极性......如果可以做得更好,我会很感激任何建议
我只遇到了 1 个我无法弄清楚的错误,也无法在线找到解决方案...但我觉得我已经接近正确地获取此代码了。欢迎任何批评。错误与 Pi 方程的“PI”输出有关:
“int 类型的值不可索引”
from RPi import GPIO
import time
import threading
#Encoder GPIO Pins
clk = 15 # GRN/YLW Z+
dt = 11 # BLU/GRN Z-
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(clk,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(dt,pull_up_down=GPIO.PUD_DOWN)
#Motor GPIO Pins
PWMPin = 18 # PWM Pin connected to ENA.
Motor1 = 16 # Connected to Input 1.
Motor2 = 18 # Connected to Input 2.
GPIO.setup(PWMPin,GPIO.OUT) # We have set our pin mode to output
GPIO.setup(Motor1,GPIO.OUT)
GPIO.setup(Motor2,GPIO.OUT)
GPIO.output(Motor1,GPIO.LOW)# When program start then all Pins will be LOW.
GPIO.output(Motor2,GPIO.LOW)
def MotorClockwise():
GPIO.output(Motor1,GPIO.LOW) # Motor will move in clockwise direction.
GPIO.output(Motor2,GPIO.HIGH)
def MotorAntiClockwise():
GPIO.output(Motor1,GPIO.HIGH) # Motor will move in anti-clockwise direction.
GPIO.output(Motor2,GPIO.LOW)
#Sim Values
duty_c = 10 #duty Cycle
PwmValue = GPIO.PWM(PWMPin,10000) # We have set our PWM frequency to 5000.
PwmValue.start(duty_c) # That's the maximum value 100 %.
error = 0
Set_point = 1.8
encoder_counter = 0
encoder_angle = 0
Kp = 2
Ki = 1
PI = 0
#Sim Parameters
Ts = .1 #sampling time
Tstop = 200 #end simulation time
N = int(Tstop/Ts)#simulation length
def ReadEncoder():
global encoder_counter
global encoder_angle
clkLastState = GPIO.input(clk)
while True:
clkState = GPIO.input(clk)
dtState = GPIO.input(dt)
encoder_angle = float(encoder_counter/800)*360
if clkState != clkLastState:
if dtState != clkState:
encoder_counter += 1
else:
encoder_counter -= 1
#print("encoder_counter",encoder_counter )
print("encoder_angle",encoder_angle )
time.sleep(1)
clkState = clkLastState
# some delay needed in order to prevent too much cpu load,# however this will limit the max rotation speed detected
time.sleep(.001)
def PI_function():
global PI
global duty_c
global error
global Kp
global Ki
global encoder_angle
for k in range(N+1):
error = int(Set_point) - encoder_angle
print (f"{error} Error Detected")
PI = PI[k-1] + KP*(error[k] - error[k-1]) + (Kp/Ki)*error[k] #PI equation
print (f"{PI} PI value")
if (PI > 0):
MotorClockwise()
else:
MotorAntiClockwise()
if ((PI > duty_c) & (duty_c <100)):
duty_c += 1
if ((PI < duty_c) & (duty_c > 10)):
duty_c -= 1
return()
def main_function():
if (N != 0):
encoder_thread = threading.Thread( target=ReadEncoder)
encoder_thread.start()
encoder_thread.join()
PI_thread = threading.Thread( target=PI_function)
PI_thread.start()
PI_thread.join()
PwmValue.ChangeDutyCycle(duty_c)
else:
PwmValue.ChangeDutyCycle(0)
print(f"Motor Stopped & Holding at {encoder_angle} degrees")
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。