Is it possible to get a PID template for Vex V5 code Python?

Please help me figure this out, and if any of you guys have a VEX PID template that I can use please share it in this thread. My team and I are desperate.
We are a rookie team trying to try our best; please help support us:)

OP wants Python not C++.

4 Likes

Hey @jpearman do you think you could remove or polish it up if there is any useless codes. You can also improve it if you want. @Raj_Patel you would have to change the Kp, Ki and Kd, and the distance and the functions and etc.

import time

import time

# PID Constants
Kp = 1.0
Ki = 0.1
Kd = 0.02

# Motor and encoder setup 
def reset_motor_encoders():
    LeftMotor.reset_encoder()
    RightMotor.reset_encoder()

def get_motor_encoder(motor):
    return motor.get_encoder_value()

def set_motor_velocity(left_velocity, right_velocity):
    LeftMotor.set_velocity(left_velocity)
    RightMotor.set_velocity(right_velocity)

def stop_motors():
    LeftMotor.stop()
    RightMotor.stop()

# PID Control Function
def pid_drive(target_degrees, tolerance=5):
    error = 0
    previous_error = 0
    integral = 0
    derivative = 0
    output = 0

    reset_motor_encoders()

    while abs(error) > tolerance:
        current_degrees = get_motor_encoder(LeftMotor)  # Assuming both motors have similar encoder readings
        error = target_degrees - current_degrees
        integral += error
        derivative = error - previous_error

        output = Kp * error + Ki * integral + Kd * derivative

        set_motor_velocity(output, output)

        previous_error = error

    stop_motors()

# Move Forward 40.6 inches
target_degrees = 1164  # Calculated for 40.6 inches
pid_drive(target_degrees)
1 Like

I have no template, but this video by Connor is beneficial. VEXCode PID Tutorial

It is in C++ but if you understand Python, it should be able to help your understanding of how to set up a PID. All code is the same in its base function, so you could potentially write a pseudo code from this video, and then translate your pseudo code into Python afterwords.

Is there anyway possible to use this code without the encoders?
Is there anyway we can change this code, so it does not have to use encoders?
Thank y`all so much for this by the way!!! I really appreciate it!!!

One more question, would this work in auto too?

you can use the inbuild encoders that is in the motors, they are quite reliable, but not as accurate as the encoder.

Hi yes, it does.

Additionally you would have to change the target degrees accordingly, here is the formula for it to calculating it. Firstly you have to calculate the wheel circumference. Then you have to use the wheel circumference to calculate the degrees per inch, which is wheel circumference/360 degrees. Then you have to use the degrees per inch plus the desired inch length, which gives you the target_degrees.

I want to add a relevant: I am unsure if this is a new update or not, but it appears that the VEXCode API got updated from the last time I saw it and it looks genuinely impressive. @jpearman or whoever was in charge of updating the API, I am genuinely impressed by the API improvements and it is really amazing to see how far it has become. I would highly recommend individuals who are trying to understand VEXcode to go to the following for additional assistance with commands and tutorials:

C++: C++ — VEXcode Documentation

Python: Python — VEXcode Documentation

As for OP, I would highly consider getting more familiar with C++ as it is more standard to what the majority of individuals in VEX are using and therefore you will receive help a lot quicker from the community. After communicating with professionals and english professors about referencing and other matters, I am planning on releasing a C++ from zero website that audits learncpp and fixes a lot of the website’s syntax errors, slow search, removes un-needed fluff, and addresses shortfalls and things to look for when using either VEXCode or PROS.

1 Like

Credit should go to @tfriez’s staff for this work.

10 Likes

@Raj_Patel , hi sorry but it seems like the the robot won’t even move as the error is already zero, which the robot thinks it has reached its desired location. Which in fact it didn’t. So here is the updated code, reworked some of the things and added a few blocks so you can easily just write the blocks, without copy pasting the whole code.

Kp = 0
Kd = 0
Ki = 0
CorrectionKp = 0
Error = 0
PreviousError = 0
Integral = 0
Derivative = 0
Output = 0
LeftError = 0
RightError = 0
Correction = 0
TargetDegrees = 0
LeftDegrees = 0
RightDegrees = 0
CurrentDegrees = 0
TargetTurnDegrees = 0
CurrentTurn = 0
NegativeOutput = 0

def Recalculate_error_within_the_loop():
    global Kp, Kd, Ki, CorrectionKp, Error, PreviousError, Integral, Derivative, Output, LeftError, RightError, Correction, TargetDegrees, LeftDegrees, RightDegrees, CurrentDegrees, TargetTurnDegrees, CurrentTurn, NegativeOutput
    LeftDegrees = Left.position(DEGREES)
    RightDegrees = Right.position(DEGREES)
    CurrentDegrees = (LeftDegrees + RightDegrees) / 2
    Error = TargetDegrees - CurrentDegrees
    Integral = Integral + Error
    Derivative = Error - PreviousError

def Standard_PID_output_calculation___Moving__():
    global Kp, Kd, Ki, CorrectionKp, Error, PreviousError, Integral, Derivative, Output, LeftError, RightError, Correction, TargetDegrees, LeftDegrees, RightDegrees, CurrentDegrees, TargetTurnDegrees, CurrentTurn, NegativeOutput
    Output = (Kp * Error + Ki * Integral) + Kd * Derivative
    LeftError = LeftDegrees - RightDegrees
    Correction = CorrectionKp * LeftError

def Recalculate_error_for_turning():
    global Kp, Kd, Ki, CorrectionKp, Error, PreviousError, Integral, Derivative, Output, LeftError, RightError, Correction, TargetDegrees, LeftDegrees, RightDegrees, CurrentDegrees, TargetTurnDegrees, CurrentTurn, NegativeOutput
    LeftDegrees = Left.position(DEGREES)
    RightDegrees = Right.position(DEGREES)
    Integral = Integral + Error
    Derivative = Error - PreviousError

def Standard_PID_output_calculation___Turning__():
    global Kp, Kd, Ki, CorrectionKp, Error, PreviousError, Integral, Derivative, Output, LeftError, RightError, Correction, TargetDegrees, LeftDegrees, RightDegrees, CurrentDegrees, TargetTurnDegrees, CurrentTurn, NegativeOutput
    Output = (Kp * Error + Ki * Integral) + Kd * Derivative
    NegativeOutput = 0 - Output

def when_started1():
    global Kp, Kd, Ki, CorrectionKp, Error, PreviousError, Integral, Derivative, Output, LeftError, RightError, Correction, TargetDegrees, LeftDegrees, RightDegrees, CurrentDegrees, TargetTurnDegrees, CurrentTurn, NegativeOutput
    TargetDegrees = 1164
    Kp = 1
    Ki = 0.1
    Ki = 0.02
    CorrectionKp = 0.1
    Error = 0
    PreviousError = 0
    Integral = 0
    Derivative = 0
    Output = 0
    LeftError = 0
    RightError = 0
    Correction = 0
    Left.set_position(0, DEGREES)
    Right.set_position(0, DEGREES)
    Error = TargetDegrees

def when_started2():
    global Kp, Kd, Ki, CorrectionKp, Error, PreviousError, Integral, Derivative, Output, LeftError, RightError, Correction, TargetDegrees, LeftDegrees, RightDegrees, CurrentDegrees, TargetTurnDegrees, CurrentTurn, NegativeOutput
    while not Error < 5:
        Recalculate_error_within_the_loop()
        Standard_PID_output_calculation___Moving__()
        Left.set_velocity((Output - Correction), PERCENT)
        Right.set_velocity((Output + Correction), PERCENT)
        PreviousError = Error
        wait(5, MSEC)
    Left.stop()
    Right.stop()
    TargetTurnDegrees = 270
    Error = TargetTurnDegrees
    Left.set_position(0, DEGREES)
    Right.set_position(0, DEGREES)
    while not CurrentTurn < TargetTurnDegrees:
        Recalculate_error_for_turning()
        Standard_PID_output_calculation___Turning__()
        Left.set_velocity(Output, PERCENT)
        Right.set_velocity(NegativeOutput, PERCENT)
        wait(5, MSEC)
    Left.stop()
    Right.stop()
    TargetDegrees = 630
    Left.set_position(0, DEGREES)
    Right.set_position(0, DEGREES)
    while not Error < 5:
        Recalculate_error_within_the_loop()
        Standard_PID_output_calculation___Moving__()
        Left.set_velocity((Output - Correction), PERCENT)
        Right.set_velocity((Output + Correction), PERCENT)
        PreviousError = Error
        wait(5, MSEC)
    Left.stop()
    Right.stop()

ws2 = Thread( when_start

Do let me know if any issues arise. Once again sorry on my end.

1 Like

Would this work without using any encoders?

Hey, I am Robert from a rookie VEX team! This is our first time coding a robot, and we are hoping that someone can help deliver us a template that we can use for our robot. We understand that we are a rookie team, but we are trying to give it our all to win 1 tournament.
THANK YOU!

@Raj_Patel and @Robert2024 are you both on the same team ?

You need to try writing some code, then post and ask for help if specific things in the code don’t seem to work. It’s no use asking the forum members to write code for you as code needs to reflect your skill level, not that of others.

6 Likes

Hi yes, you would have to use the inbuilt encoders that is in the motor.

Sorry about that, I will help and not post the entire code. Next time.

No we are on different team. Thank you, know I understand what to do beforehand.
Sorry about this, but thank you with sharing this with me.

One question, we have 2 motor groups for the base, consist of 3 motors each, if we set those motor groups for this set of code, will we have to copy the same code for the 2 other motors. Since they are not grouped together will we have to copy the same PID code, that we will use for our drive base, twice?

No, you can stack them together, and the single motor on each side that is not part of the motor group can be used as a encoder. You js have to declare them in the code. So if your left side has 3, and you are able to group 2 motors if I believe and then js have to copy the output-correcton for that motor.

same I’m a rookie thx pookies

Those 2 motors though are apart of another subsystem, meaning they are not apart of the base.
Sorry for not clarifying that