如何在EV3 Micropython环境中使用PID控制器?

问题描述

我在VS Code中安装了Mindstorm EV3扩展程序。我们尝试将此PID控制器导入VS Code Mindstorm Extension。我们该怎么做?我们尝试了“导入PID”,它不起作用...我们试图将PID.py代码粘贴到我们的文件中,它也不起作用。这是Github链接

https://github.com/ivmech/ivPID

    #!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import (Motor,TouchSensor,ColorSensor,InfraredSensor,UltrasonicSensor,GyroSensor)
from pybricks.parameters import Port,Stop,Direction,Button,Color
from pybricks.tools import wait,StopWatch,DataLog
from pybricks.robotics import DriveBase
from pybricks.media.ev3dev import SoundFile,ImageFile
# This program requires LEGO EV3 MicroPython v2.0 or higher.
# Click "Open user guide" on the EV3 extension tab for more information.
# Variables and constants
ev3 = EV3Brick()
leftMotor = Motor(Port.B,Direction.Clockwise)
rightMotor = Motor(Port.C,Direction.Clockwise)
#left medium motor
mediumMotor = Motor(Port.D,Direction.COUNTERClockwise)
#right medium motor
mediumMotor2 = Motor(Port.A,Direction.COUNTERClockwise)
robot = DriveBase(leftMotor,rightMotor,55.85,108)
robot.settings(300,100,200,100)
rightcolor = ColorSensor(Port.S1)
leftcolor = ColorSensor(Port.S2)
gyroSensor = GyroSensor(Port.S3)
black = 3
white = 30
import time
def linesquare():
    leftblack = leftcolor.reflection() > black - 2 and leftcolor.reflection() < black + 2
    rightblack = rightcolor.reflection() > black - 2 and rightcolor.reflection() < black + 2
    leftMotor.run(200)
    rightMotor.run(200)
    while not leftblack or not rightblack:
        leftblack = leftcolor.reflection() > black - 2 and leftcolor.reflection() < black + 2
        rightblack = rightcolor.reflection() > black - 2 and rightcolor.reflection() < black + 2
        if leftblack:
            leftMotor.brake()
        if rightblack:
            rightMotor.brake()
    leftrange = leftcolor.reflection() > threshold - 2 and leftcolor.reflection() < threshold + 2
    rightrange = rightcolor.reflection() > threshold - 2 and rightcolor.reflection() < threshold + 2
    while not leftrange or not rightrange:
        leftrange = leftcolor.reflection() > threshold - 2 and leftcolor.reflection() < threshold + 2
        rightrange = rightcolor.reflection() > threshold - 2 and rightcolor.reflection() < threshold + 2
        if leftrange:
            leftMotor.brake()
        else:
            if leftcolor.reflection() > threshold + 2:
                leftMotor.run(50)
            else:
                leftMotor.run(-50)
        if rightrange:
            rightMotor.brake()
        else:
            if rightcolor.reflection() > threshold + 2:
                rightMotor.run(50)
            else:
               rightMotor.run(-50)
class PID:
    """PID Controller
    """
    def _init_(self,P=0.2,I=0.0,D=0.0,current_time=None):
        self.Kp = P
        self.Ki = I
        self.Kd = D
        self.sample_time = 0.00
        self.current_time = current_time if current_time is not None else time.time()
        self.last_time = self.current_time
        self.clear()
    def clear(self):
        """Clears PID computations and coefficients"""
        self.SetPoint = 0.0
        self.PTerm = 0.0
        self.ITerm = 0.0
        self.DTerm = 0.0
        self.last_error = 0.0
        # Windup Guard
        self.int_error = 0.0
        self.windup_guard = 20.0
        self.output = 0.0
    def update(self,Feedback_value,current_time=None):
        """Calculates PID value for given reference Feedback
        .. math::
            u(t) = K_p e(t) + K_i \int_{0}^{t} e(t)dt + K_d {de}/{dt}
        .. figure:: images/pid_1.png
           :align:   center
           Test PID with Kp=1.2,Ki=1,Kd=0.001 (test_pid.py)
        """
        error = self.SetPoint - Feedback_value
        self.current_time = current_time if current_time is not None else time.time()
        delta_time = self.current_time - self.last_time
        delta_error = error - self.last_error
        if (delta_time >= self.sample_time):
            self.PTerm = self.Kp * error
            self.ITerm += error * delta_time
            if (self.ITerm < -self.windup_guard):
                self.ITerm = -self.windup_guard
            elif (self.ITerm > self.windup_guard):
                self.ITerm = self.windup_guard
            self.DTerm = 0.0
            if delta_time > 0:
                self.DTerm = delta_error / delta_time
            # Remember last time and last error for next calculation
            self.last_time = self.current_time
            self.last_error = error
            self.output = self.PTerm + (self.Ki * self.ITerm) + (self.Kd * self.DTerm)
    def setSampleTime(self,sample_time):
        """PID that should be updated at a regular interval.
        Based on a pre-determined sample time,the PID decides if it should compute or return immediately.
        """
        self.sample_time = sample_time
#run 1
#robot.straight(610)
#robot.turn(-45)
pid = PID(0.9,1,0.001)
pid.setSampleTime(0.01)
pid.SetPoint=(black + white) / 2
Feedback = rightcolor.reflection()
#robot.reset()
print(pid.last_time)
print(pid.current_time)
print(time.time())
while robot.distance() < 960:
    print(pid.last_time)
    print(pid.current_time)
    print(time.time())
    pid.update(Feedback)
    robot.drive(200,pid.output)
    Feedback = rightcolor.reflection()
robot.turn(90)
robot.straight(-500)
linesquare()
robot.straight(1200)
mediumMotor.run_time(300,3000)

我们得到的错误是上次没有属性。但是它在test.py

时有效

任何想法都有帮助!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)