PD Looping Help in Python

So I recently tried porting a PD loop from Vex Code to Python in RMS because I couldn’t seem to find any example code teaching how to do it. With the help of Connor from the former 1814D, I seem to have written what seems like what I think the loop would look like. Due to everyone being on break, I can’t actually test what it does on the robot and I wanted to see if I am in the right direction and what I did wrong. If anybody can either confirm that I am in the right path or help me fix any issues, please help a fellow coder in desperation.

global Auton, DriveStraightTarget, DriveStraightVelocity, DriveStraightPreviousError, ArmPIDTarget, ArmPIDVelocity, ArmPIDPreviousError, TrayPIDTarget, TrayPIDVelocity, TrayPIDPreviousError
def DriveStraight():
    while True:
        kP = .5  #SUBJECT TO CHANGE ONCE TESTED
        kD = .4  #SUBJECT TO CHANGE ONCE TESTED
        Error = BLMotor.rotation(RotationUnits.DEG) - DriveStraightTarget
        derivative = Error - DriveStraightPreviousError
        FRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        FLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        DriveStraightPreviousError = Error
        sys.sleep(.02)
def ArmPID():
    while True:
        kP = .5 #SUBJECT TO CHANGE ONCE TESTED
        kD = .4 #SUBJECT TO CHANGE ONCE TESTER
        Error = ArmPot.value(RotationUnits.DEG) - ArmPIDTarget
        derivative = Error - ArmPIDPreviousError
        ArmMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (ArmPIDVelocity/100)), VoltageUnits.VOLT)
        ArmPIDPreviousError = Error
        sys.sleep(.02)
def TrayPID():
    while True:
        kP = .5 #SUBJECT TO CHANGE ONCE TESTED
        kD = .4 #SUBJECT TO CHANGE ONCE TESTED
        Error = TrayPot.value(RotationUnits.DEG) - TrayPIDTarget
        derivative = Error - TrayPIDPreviousError
        TrayMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (TrayPIDVelocity/100)), VoltageUnits.VOLT)
        TrayPIDPreviousError = Error
        sys.sleep(.02)

def StartAuton():
    TrayMotor.set_stopping(BrakeType.HOLD)
    IntakeLeft.set_stopping(BrakeType.HOLD)
    IntakeRight.set_stopping(BrakeType.HOLD)
    ArmMotor.set_stopping(BrakeType.HOLD)
    BLMotor.set_stopping(BrakeType.HOLD)
    FLMotor.set_stopping(BrakeType.HOLD)
    FRMotor.set_stopping(BrakeType.HOLD)
    TrayMotor.reset_rotation()
    IntakeLeft.reset_rotation()
    IntakeRight.reset_rotation()
    ArmMotor.reset_rotation()
    BLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FRMotor.reset_rotation()

def pre_auton():
    DriveStraightPreviousError = 0
    ArmPIDPreviousError = 0
    TrayPIDPreviousError = 0
    Inertial.start_calibration()
    con.screen.clear_screen()
    brain.screen.clear_screen()
    brain.screen.draw_image_from_file("MenuPage.png",0,0)
    brain.screen.render()
    Auton = 'MenuPage'
    
    pass

def autonomous():
    DriveStraightProcess = multiprocessing.Process(target=DriveStraight, args=DriveStraightTarget)
    ArmPIDProcess = multiprocessing.Process(target=ArmPID, args=ArmPIDTarget)
    TrayPIDProcess = multiprocessing.Process(target=TrayPID, args=TrayPIDTarget)
    DriveStraightProcess.start()
    ArmPIDProcess.start()
    TrayPIDProcess.start()
    DriveStraightProcess.join()
    ArmPIDProcess.join()
    TrayPIDProcess.join()
    StartAuton()
    ArmPIDVelocity = 100   #PUTTING RANDOM NUMBERS FOR ALL OF THIS
    ArmPIDTarget = 50
    sys.sleep(.02)
    TrayPIDVelocity = 100
    TrayPIDTarget = 50
    sys.sleep(.02)
    DriveStraightVelocity = 100
    DriveStraightTarget = 1000
    sys.sleep(.02)
    
    pass
1 Like

small nitpick, variable for your drive pd on power, its hard to look at when you have it in your actual power, that being said, I’m no rms master, so I can’t give you many tips. looks okay to me.

1 Like

Yeah it doesn’t look very clean, probably will have to clean it up so that underclassmen can learn from it. Thanks for the response!

These commands don’t exist in RMS Python. If you want threading, you want sys.run_in_thread.

But you also don’t want threading, or at least not like you’ve done here. Threads started by your auton or drivercontrol threads don’t terminate when they do, and you have included no way to terminate these functions.

The global keyword doesn’t work the way you’re using it here. In global scope, where you have this, it does nothing. Global is used in a function to show that the variable being assigned to references the global version instead of the implied local version:

x = 20
def change_x():
  x = 5
change_x()
print x #prints 20

versus:

x = 20
def change_x():
  global x
  x = 5
change_x()
print x #prints 5

When only reading from a global variable, there’s no need to declare it global:

x = 5
def display_x():
  print x
display_x() #prints 5

It’s not much, but you also don’t need to set kP and kD every loop:

could become

kP = .5 #SUBJECT TO CHANGE ONCE TESTED
kD = .4 #SUBJECT TO CHANGE ONCE TESTER
while True:

And last bit, it looked like you were trying to use your functions with arguments of some kind, when you have not written them to accept arguments.

2 Likes

Firstly I want to thank you for getting back to me with some guidance as I have never actually done multiple threads in any code before. I am going to think ahead and try to solve this in steps so that maybe one day somebody who is confused like me can figure it out by me going through this pain.
First issue you stated:
The commands that you said didn’t exist, I had imported multiprocessing because I saw a post on how you could run the multiple things at once, I am just gonna take your advice and use that command. Here is my code after my attempt to use your recommendation:

def DriveStraight():
    while True:
        kP = .5  #SUBJECT TO CHANGE ONCE TESTED
        kD = .4  #SUBJECT TO CHANGE ONCE TESTED
        Error = BLMotor.rotation(RotationUnits.DEG) - DriveStraightTarget
        derivative = Error - DriveStraightPreviousError
        FRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        FLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        DriveStraightPreviousError = Error
        sys.sleep(.02)
def ArmPID():
    while True:
        kP = .5 #SUBJECT TO CHANGE ONCE TESTED
        kD = .4 #SUBJECT TO CHANGE ONCE TESTER
        Error = ArmPot.value(RotationUnits.DEG) - ArmPIDTarget
        derivative = Error - ArmPIDPreviousError
        ArmMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (ArmPIDVelocity/100)), VoltageUnits.VOLT)
        ArmPIDPreviousError = Error
        sys.sleep(.02)
def TrayPID():
    while True:
        kP = .5 #SUBJECT TO CHANGE ONCE TESTED
        kD = .4 #SUBJECT TO CHANGE ONCE TESTED
        Error = TrayPot.value(RotationUnits.DEG) - TrayPIDTarget
        derivative = Error - TrayPIDPreviousError
        TrayMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (TrayPIDVelocity/100)), VoltageUnits.VOLT)
        TrayPIDPreviousError = Error
        sys.sleep(.02)

def StartAuton():
    TrayMotor.set_stopping(BrakeType.HOLD)
    IntakeLeft.set_stopping(BrakeType.HOLD)
    IntakeRight.set_stopping(BrakeType.HOLD)
    ArmMotor.set_stopping(BrakeType.HOLD)
    BLMotor.set_stopping(BrakeType.HOLD)
    FLMotor.set_stopping(BrakeType.HOLD)
    FRMotor.set_stopping(BrakeType.HOLD)
    TrayMotor.reset_rotation()
    IntakeLeft.reset_rotation()
    IntakeRight.reset_rotation()
    ArmMotor.reset_rotation()
    BLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FRMotor.reset_rotation()

def pre_auton():
    DriveStraightPreviousError = 0
    ArmPIDPreviousError = 0
    TrayPIDPreviousError = 0
    Inertial.start_calibration()
    con.screen.clear_screen()
    brain.screen.clear_screen()
    brain.screen.draw_image_from_file("MenuPage.png",0,0)
    brain.screen.render()
    Auton = 'MenuPage'
    
    pass

def autonomous():
    sys.run_in_thread(DriveStraight)
    sys.run_in_thread(ArmPID)
    sys.run_in_thread(TrayPID)
    #START CODE
    StartAuton()
    ArmPIDVelocity = 100   #PUTTING RANDOM NUMBERS FOR ALL OF THIS
    ArmPIDTarget = 50
    sys.sleep(.02)
    TrayPIDVelocity = 100
    TrayPIDTarget = 50
    sys.sleep(.02)
    DriveStraightVelocity = 100
    DriveStraightTarget = 1000
    sys.sleep(.02)
    #END CODE
    sys.exit(DriveStraight)
    sys.exit(ArmPID)
    sys.exit(TrayPID)
    pass

I hope I did this correctly, two questions, can all three processes run in autonomous or would I have to start and stop every process when I need it? Secondly, In drivercontrol, where exactly would I run the threads? Im guessing anywhere in the while loop but I want to make sure.
Second suggestion:
I feel like I understood the global command better with your examples, Here’s me using what I learned to get the areas right:

DriveStraightPreviousError = 0
ArmPIDPreviousError = 0
TrayPIDPreviousError = 0
kP = .5 #SUBJECT TO CHANGE ONCE TESTED
kD = .4 #SUBJECT TO CHANGE ONCE TESTED
def DriveStraight():
    while True:
        global DriveStraightTarget, DriveStraightVelocity, DriveStraightPreviousError, kP, kD
        Error = BLMotor.rotation(RotationUnits.DEG) - DriveStraightTarget
        derivative = Error - DriveStraightPreviousError
        FRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        FLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        DriveStraightPreviousError = Error
        sys.sleep(.02)
def ArmPID():
    while True:
        global ArmPIDTarget, ArmPIDVelocity, ArmPIDPreviousError, kP, kD
        Error = ArmPot.value(RotationUnits.DEG) - ArmPIDTarget
        derivative = Error - ArmPIDPreviousError
        ArmMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (ArmPIDVelocity/100)), VoltageUnits.VOLT)
        ArmPIDPreviousError = Error
        sys.sleep(.02)
def TrayPID():
    while True:
        global TrayPIDTarget, TrayPIDVelocity, TrayPIDPreviousError, kP, kD
        Error = TrayPot.value(RotationUnits.DEG) - TrayPIDTarget
        derivative = Error - TrayPIDPreviousError
        TrayMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (TrayPIDVelocity/100)), VoltageUnits.VOLT)
        TrayPIDPreviousError = Error
        sys.sleep(.02)

def StartAuton():
    TrayMotor.set_stopping(BrakeType.HOLD)
    IntakeLeft.set_stopping(BrakeType.HOLD)
    IntakeRight.set_stopping(BrakeType.HOLD)
    ArmMotor.set_stopping(BrakeType.HOLD)
    BLMotor.set_stopping(BrakeType.HOLD)
    FLMotor.set_stopping(BrakeType.HOLD)
    FRMotor.set_stopping(BrakeType.HOLD)
    TrayMotor.reset_rotation()
    IntakeLeft.reset_rotation()
    IntakeRight.reset_rotation()
    ArmMotor.reset_rotation()
    BLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FRMotor.reset_rotation()

def pre_auton():
    Inertial.start_calibration()
    con.screen.clear_screen()
    brain.screen.clear_screen()
    brain.screen.draw_image_from_file("MenuPage.png",0,0)
    brain.screen.render()
    Auton = 'MenuPage'
    
    pass

def autonomous():
    global TrayPIDTarget, TrayPIDVelocity, ArmPIDTarget, ArmPIDVelocity, DriveStraightTarget, DriveStraightVelocity
    sys.run_in_thread(DriveStraight)
    sys.run_in_thread(ArmPID)
    sys.run_in_thread(TrayPID)
    #START CODE
    StartAuton()
    ArmPIDVelocity = 100   #PUTTING RANDOM NUMBERS FOR ALL OF THIS
    ArmPIDTarget = 50
    sys.sleep(.02)
    TrayPIDVelocity = 100
    TrayPIDTarget = 50
    sys.sleep(.02)
    DriveStraightVelocity = 100
    DriveStraightTarget = 1000
    sys.sleep(.02)
    #END CODE
    sys.exit(DriveStraight)
    sys.exit(ArmPID)
    sys.exit(TrayPID)
    pass

I hope I am on the right track so far, as far as this goes:
And last bit, it looked like you were trying to use your functions with arguments of some kind, when you have not written them to accept arguments.
I dont have a single clue what you’re talking about. If you could give an example or explain it I would appreciate it greatly!
Once again thank you @John_TYler for helping me out!
BRANDON | 1429B

Part of the reason I included advice against using threads for these tasks is that threads do not stop when autonomous or driver control are ended. That is, if you start these three threads in autonomous, they will run forever, including during driver control, where you really don’t want them running. You need to either do without threads or include a way for them to end when the competition mode changes.

I think this will work. I’d have put the global after the function definition and before the loops, but it should work inside the loops as well.

Your original attempt at multithreading included arguments. That was what the args= part was about. Arguments are the things you pass to functions inside the brackets.

1 Like

In the end of the autonomous period, I included:

sys.exit(DriveStraight)
sys.exit(ArmPID)
sys.exit(TrayPID)

Wouldn’t that work in ending the threads?
If you recommend doing something else, could you help me out in what that would be?
Also, why wouldn’t I want threads running during DriveControl? I wanted to use the threads for my Arm Functions like this:

if con.buttonR1.pressing():
            ArmPIDTarget = 100 #ARM AT THE TOP
elif con.buttonR2.pressing():
            ArmPIDTarget = 50 #ARM AT THE BOTTOM
else:
            ArmPIDTarget = ArmPot.value(RotationUnits.DEG)

No. Read the docs on sys.exit:

def sys.exit ( val )
Terminate the program, returning an error code.

If you call sys.exit anywhere, it ends the whole program.

If a thread has no more instructions to run, it ends. In other words, you need to include some way for execution to reach the end of your threads instead of having them run forever with while True.

The arm and tray threads might be fine, but you definitely don’t want drive position PID running during drivercontrol. And if you’re going to have a thread that runs all the time, you’ll want to start it from some place that only runs once, like pre_auton.

1 Like

So I could have a global variable that is set to 1. Then do while variable == 1, loop the PID control. Then in the end of the autonomous period, I can set the variable to any other integer? Also, I see what you mean by having the wheel PID in drivercontrol, it would contradict the controller input.

This is my attempt in doing what you said to do.

ArmPIDPreviousError = 0
TrayPIDPreviousError = 0
PIDON = 1
kP = .5 #SUBJECT TO CHANGE ONCE TESTED
kD = .4 #SUBJECT TO CHANGE ONCE TESTED
def DriveStraight():
    global DriveStraightTarget, DriveStraightVelocity, DriveStraightPreviousError, kP, kD, PIDON
    while PIDON == 1:
        Error = BLMotor.rotation(RotationUnits.DEG) - DriveStraightTarget
        derivative = Error - DriveStraightPreviousError
        FRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        FLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        DriveStraightPreviousError = Error
        sys.sleep(.02)
def ArmPID():
    global ArmPIDTarget, ArmPIDVelocity, ArmPIDPreviousError, kP, kD, PIDON
    while PIDON == 1:
        Error = ArmPot.value(RotationUnits.DEG) - ArmPIDTarget
        derivative = Error - ArmPIDPreviousError
        ArmMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (ArmPIDVelocity/100)), VoltageUnits.VOLT)
        ArmPIDPreviousError = Error
        sys.sleep(.02)
def TrayPID():
    global TrayPIDTarget, TrayPIDVelocity, TrayPIDPreviousError, kP, kD, PIDON
    while PIDON == 1:
        Error = TrayPot.value(RotationUnits.DEG) - TrayPIDTarget
        derivative = Error - TrayPIDPreviousError
        TrayMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (TrayPIDVelocity/100)), VoltageUnits.VOLT)
        TrayPIDPreviousError = Error
        sys.sleep(.02)

def StartAuton():
    TrayMotor.set_stopping(BrakeType.HOLD)
    IntakeLeft.set_stopping(BrakeType.HOLD)
    IntakeRight.set_stopping(BrakeType.HOLD)
    ArmMotor.set_stopping(BrakeType.HOLD)
    BLMotor.set_stopping(BrakeType.HOLD)
    FLMotor.set_stopping(BrakeType.HOLD)
    FRMotor.set_stopping(BrakeType.HOLD)
    TrayMotor.reset_rotation()
    IntakeLeft.reset_rotation()
    IntakeRight.reset_rotation()
    ArmMotor.reset_rotation()
    BLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FRMotor.reset_rotation()

def pre_auton():
    Inertial.start_calibration()
    con.screen.clear_screen()
    brain.screen.clear_screen()
    brain.screen.draw_image_from_file("MenuPage.png",0,0)
    brain.screen.render()
    Auton = 'MenuPage'
    pass

def autonomous():
    global TrayPIDTarget, TrayPIDVelocity, ArmPIDTarget, ArmPIDVelocity, DriveStraightTarget, DriveStraightVelocity, PIDON
    sys.run_in_thread(DriveStraight)
    sys.run_in_thread(ArmPID)
    sys.run_in_thread(TrayPID)
    #START CODE
    StartAuton()
    ArmPIDVelocity = 100   #PUTTING RANDOM NUMBERS FOR ALL OF THIS
    ArmPIDTarget = 50
    sys.sleep(.02)
    TrayPIDVelocity = 100
    TrayPIDTarget = 50
    sys.sleep(.02)
    DriveStraightVelocity = 100
    DriveStraightTarget = 1000
    sys.sleep(.02)
    #END CODE
    PIDON = 0
    pass

More direct would be just polling the is_autonomous method on your competition object. The way you’ve done it would enter autonomous, start the various threads, set the targets, then turn them off.

ArmPIDPreviousError = 0
TrayPIDPreviousError = 0
kP = .5 #SUBJECT TO CHANGE ONCE TESTED
kD = .4 #SUBJECT TO CHANGE ONCE TESTED
def DriveStraight():
    global DriveStraightTarget, DriveStraightVelocity, DriveStraightPreviousError, kP, kD, PIDON
    while Competition.is_autonomous:
        Error = BLMotor.rotation(RotationUnits.DEG) - DriveStraightTarget
        derivative = Error - DriveStraightPreviousError
        FRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        FLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        DriveStraightPreviousError = Error
        sys.sleep(.02)
def ArmPID():
    global ArmPIDTarget, ArmPIDVelocity, ArmPIDPreviousError, kP, kD, PIDON
    while Competition.is_autonomous or Competition.is_driver_control:
        Error = ArmPot.value(RotationUnits.DEG) - ArmPIDTarget
        derivative = Error - ArmPIDPreviousError
        ArmMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (ArmPIDVelocity/100)), VoltageUnits.VOLT)
        ArmPIDPreviousError = Error
        sys.sleep(.02)
def TrayPID():
    global TrayPIDTarget, TrayPIDVelocity, TrayPIDPreviousError, kP, kD, PIDON
    while Competition.is_autonomous or Competition.is_driver_control:
        Error = TrayPot.value(RotationUnits.DEG) - TrayPIDTarget
        derivative = Error - TrayPIDPreviousError
        TrayMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (TrayPIDVelocity/100)), VoltageUnits.VOLT)
        TrayPIDPreviousError = Error
        sys.sleep(.02)

def StartAuton():
    TrayMotor.set_stopping(BrakeType.HOLD)
    IntakeLeft.set_stopping(BrakeType.HOLD)
    IntakeRight.set_stopping(BrakeType.HOLD)
    ArmMotor.set_stopping(BrakeType.HOLD)
    BLMotor.set_stopping(BrakeType.HOLD)
    FLMotor.set_stopping(BrakeType.HOLD)
    FRMotor.set_stopping(BrakeType.HOLD)
    TrayMotor.reset_rotation()
    IntakeLeft.reset_rotation()
    IntakeRight.reset_rotation()
    ArmMotor.reset_rotation()
    BLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FRMotor.reset_rotation()

def pre_auton():
    Inertial.start_calibration()
    con.screen.clear_screen()
    brain.screen.clear_screen()
    brain.screen.draw_image_from_file("MenuPage.png",0,0)
    brain.screen.render()
    Auton = 'MenuPage'
    pass

def autonomous():
    global TrayPIDTarget, TrayPIDVelocity, ArmPIDTarget, ArmPIDVelocity, DriveStraightTarget, DriveStraightVelocity, PIDON
    sys.run_in_thread(DriveStraight)
    sys.run_in_thread(ArmPID)
    sys.run_in_thread(TrayPID)
    #START CODE
    StartAuton()
    ArmPIDVelocity = 100   #PUTTING RANDOM NUMBERS FOR ALL OF THIS
    ArmPIDTarget = 50
    sys.sleep(.02)
    TrayPIDVelocity = 100
    TrayPIDTarget = 50
    sys.sleep(.02)
    DriveStraightVelocity = 100
    DriveStraightTarget = 1000
    sys.sleep(.02)
    #END CODE
    pass

Getting warmer. Do you know what I meant by “method” and “object”?

1 Like

Nope, care to explain? I am not giving up until I figure this thing out xD.

Methods are functions attached to objects. An object is an instance of a class. Competition is a class, and is_autonomous is a method that can be called on objects that are created from the Competition class. That being said, take a look at this snippet of yours:

while Competition.is_autonomous:

First, let’s take a look at Competition. Is it an object created from the Competition class?

Next, take a look at how is_autonomous is being used. Does it look like any other method or function call that you’ve seen? What’s missing?

2 Likes
DriveStraightPreviousError = 0
ArmPIDPreviousError = 0
TrayPIDPreviousError = 0
kP = .5 #SUBJECT TO CHANGE ONCE TESTED
kD = .4 #SUBJECT TO CHANGE ONCE TESTED
def DriveStraight():
    global DriveStraightTarget, DriveStraightVelocity, DriveStraightPreviousError, kP, kD, PIDON
    while Competition.is_autonomous():
        Error = BLMotor.rotation(RotationUnits.DEG) - DriveStraightTarget
        derivative = Error - DriveStraightPreviousError
        FRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        FLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        DriveStraightPreviousError = Error
        sys.sleep(.02)
def ArmPID():
    global ArmPIDTarget, ArmPIDVelocity, ArmPIDPreviousError, kP, kD, PIDON
    while Competition.is_autonomous() or Competition.is_driver_control():
        Error = ArmPot.value(RotationUnits.DEG) - ArmPIDTarget
        derivative = Error - ArmPIDPreviousError
        ArmMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (ArmPIDVelocity/100)), VoltageUnits.VOLT)
        ArmPIDPreviousError = Error
        sys.sleep(.02)
def TrayPID():
    global TrayPIDTarget, TrayPIDVelocity, TrayPIDPreviousError, kP, kD, PIDON
    while Competition.is_autonomous() or Competition.is_driver_control():
        Error = TrayPot.value(RotationUnits.DEG) - TrayPIDTarget
        derivative = Error - TrayPIDPreviousError
        TrayMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (TrayPIDVelocity/100)), VoltageUnits.VOLT)
        TrayPIDPreviousError = Error
        sys.sleep(.02)

def StartAuton():
    TrayMotor.set_stopping(BrakeType.HOLD)
    IntakeLeft.set_stopping(BrakeType.HOLD)
    IntakeRight.set_stopping(BrakeType.HOLD)
    ArmMotor.set_stopping(BrakeType.HOLD)
    BLMotor.set_stopping(BrakeType.HOLD)
    FLMotor.set_stopping(BrakeType.HOLD)
    FRMotor.set_stopping(BrakeType.HOLD)
    TrayMotor.reset_rotation()
    IntakeLeft.reset_rotation()
    IntakeRight.reset_rotation()
    ArmMotor.reset_rotation()
    BLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FRMotor.reset_rotation()

def pre_auton():
    Inertial.start_calibration()
    con.screen.clear_screen()
    brain.screen.clear_screen()
    brain.screen.draw_image_from_file("MenuPage.png",0,0)
    brain.screen.render()
    Auton = 'MenuPage'
    pass

def autonomous():
    global TrayPIDTarget, TrayPIDVelocity, ArmPIDTarget, ArmPIDVelocity, DriveStraightTarget, DriveStraightVelocity, PIDON
    sys.run_in_thread(DriveStraight)
    sys.run_in_thread(ArmPID)
    sys.run_in_thread(TrayPID)
    #START CODE
    StartAuton()
    ArmPIDVelocity = 100   #PUTTING RANDOM NUMBERS FOR ALL OF THIS
    ArmPIDTarget = 50
    sys.sleep(.02)
    TrayPIDVelocity = 100
    TrayPIDTarget = 50
    sys.sleep(.02)
    DriveStraightVelocity = 100
    DriveStraightTarget = 1000
    sys.sleep(.02)
    #END CODE
    pass

?

1 Like

You got the answer to the second question. How about the first?

1 Like

Is it vex.Competition.is_autonomous()?

Competition is the name of the class. You need to make an object from it:

competition = new Competition()
competition.is_autonomous()
2 Likes
brain.screen.render(True,False) 
DriveStraightPreviousError = 0
ArmPIDPreviousError = 0
TrayPIDPreviousError = 0
competition = new Competition()
kP = .5 #SUBJECT TO CHANGE ONCE TESTED
kD = .4 #SUBJECT TO CHANGE ONCE TESTED
def DriveStraight():
    global DriveStraightTarget, DriveStraightVelocity, DriveStraightPreviousError, kP, kD, PIDON
    while competition.is_autonomous()
        Error = BLMotor.rotation(RotationUnits.DEG) - DriveStraightTarget
        derivative = Error - DriveStraightPreviousError
        FRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        FLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BRMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        BLMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (DriveStraightVelocity/100)), VoltageUnits.VOLT)
        DriveStraightPreviousError = Error
        sys.sleep(.02)
def ArmPID():
    global ArmPIDTarget, ArmPIDVelocity, ArmPIDPreviousError, kP, kD, PIDON
    while competition.is_autonomous() or competition.is_driver_control():
        Error = ArmPot.value(RotationUnits.DEG) - ArmPIDTarget
        derivative = Error - ArmPIDPreviousError
        ArmMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (ArmPIDVelocity/100)), VoltageUnits.VOLT)
        ArmPIDPreviousError = Error
        sys.sleep(.02)
def TrayPID():
    global TrayPIDTarget, TrayPIDVelocity, TrayPIDPreviousError, kP, kD, PIDON
    while competition.is_autonomous() or competition.is_driver_control():
        Error = TrayPot.value(RotationUnits.DEG) - TrayPIDTarget
        derivative = Error - TrayPIDPreviousError
        TrayMotor.spin_with_voltage(DirectionType.FWD,(((Error * kP + derivative * kD) * .12) * (TrayPIDVelocity/100)), VoltageUnits.VOLT)
        TrayPIDPreviousError = Error
        sys.sleep(.02)

def StartAuton():
    TrayMotor.set_stopping(BrakeType.HOLD)
    IntakeLeft.set_stopping(BrakeType.HOLD)
    IntakeRight.set_stopping(BrakeType.HOLD)
    ArmMotor.set_stopping(BrakeType.HOLD)
    BLMotor.set_stopping(BrakeType.HOLD)
    FLMotor.set_stopping(BrakeType.HOLD)
    FRMotor.set_stopping(BrakeType.HOLD)
    TrayMotor.reset_rotation()
    IntakeLeft.reset_rotation()
    IntakeRight.reset_rotation()
    ArmMotor.reset_rotation()
    BLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FLMotor.reset_rotation()
    FRMotor.reset_rotation()

def pre_auton():
    Inertial.start_calibration()
    con.screen.clear_screen()
    brain.screen.clear_screen()
    brain.screen.draw_image_from_file("MenuPage.png",0,0)
    brain.screen.render()
    Auton = 'MenuPage'
    pass

def autonomous():
    global TrayPIDTarget, TrayPIDVelocity, ArmPIDTarget, ArmPIDVelocity, DriveStraightTarget, DriveStraightVelocity
    sys.run_in_thread(DriveStraight)
    sys.run_in_thread(ArmPID)
    sys.run_in_thread(TrayPID)
    #START CODE
    StartAuton()
    ArmPIDVelocity = 100   #PUTTING RANDOM NUMBERS FOR ALL OF THIS
    ArmPIDTarget = 50
    sys.sleep(.02)
    TrayPIDVelocity = 100
    TrayPIDTarget = 50
    sys.sleep(.02)
    DriveStraightVelocity = 100
    DriveStraightTarget = 1000
    sys.sleep(.02)
    #END CODE
    pass

Sorry for the wait. Got distracted in school work. Imagine paying attention to school HAHAHA. mild sarcasm.

2 Likes