How do I start a Stopped Thread (Python)

Hello, I am trying to incorperate a function that automatically charges and launches my catapult (for Rapid Relay) into my auton and I can’t figure out how to start the thread after I have stopped it.

Also, whenever I try to launch the atapult usinng the

motor.spin_for()

command, the thread stops. Does anyone know why it stopped?

post all the code (at least the relevant code if it’s really large)

2 Likes

Sorry, I remembered just after posting and I can’t edit my topic

Full code
# As of 10/28/2024 12:57 P.M.

#region VEXcode Generated and Custom Robot Configuration

from vex import *
import random
# Brain should be defined by default
brain=Brain()

# Robot configuration code
brain_inertial = Inertial()
# Drivetrain configuration
left_drive_smart = Motor(Ports.PORT1, 2, False)
right_drive_smart = Motor(Ports.PORT11, 2, True)
drivetrain = SmartDrive(left_drive_smart, right_drive_smart, brain_inertial, 200)

# Motor configuration
intake = Motor(Ports.PORT12, True)
H_Wheel = Motor(Ports.PORT4, True)
controller = Controller()
cata_motor_a = Motor(Ports.PORT10, True)
cata_motor_b = Motor(Ports.PORT8, False)
cata = MotorGroup(cata_motor_a, cata_motor_b)
chargingBumper = Bumper(Ports.PORT6)
launchingBumper = Bumper(Ports.PORT5)
touchLED = Touchled(Ports.PORT7)

# Make random actually random
def setRandomSeedUsingAccel():
    wait(100, MSEC)
    xaxis = brain_inertial.acceleration(XAXIS) * 1000
    yaxis = brain_inertial.acceleration(YAXIS) * 1000
    zaxis = brain_inertial.acceleration(ZAXIS) * 1000
    random.seed(int(xaxis + yaxis + zaxis))
    
# Set random seed 
setRandomSeedUsingAccel()

vexcode_initial_drivetrain_calibration_completed = False
def calibrate_drivetrain():
    # Calibrate the Drivetrain Inertial
    global vexcode_initial_drivetrain_calibration_completed
    sleep(200, MSEC)
    brain.screen.print("Calibrating")
    brain.screen.next_row()
    brain.screen.print("Inertial")
    brain_inertial.calibrate()
    while brain_inertial.is_calibrating():
        sleep(25, MSEC)
    vexcode_initial_drivetrain_calibration_completed = True
    brain_inertial.reset_heading()
    brain.screen.clear_screen()
    brain.screen.set_cursor(1, 1)
calibrate_drivetrain()

# turns on or off the autoCata function
global autoCataOn, launch, autoStop
autoCataOn = True
autoStop = False
launch = False
lCall = Event()

# define a task that will handle monitoring inputs from controller
def catapult_thread():
    while True:
        # automatic catapult charging function
        if (autoCataOn):
            try:
                if launchingBumper.pressing() and chargingBumper.pressing():
                    # Launching code
                    cata.stop()
                    cata.spin(REVERSE)
                    wait(100, MSEC)
                    cata.stop()
                elif chargingBumper.pressing() or launch:
                    # Stop charging code
                    wait(10, MSEC)
                    cata.stop()
                else:
                    # Charging code
                    cata.spin(FORWARD)                      
            except:
                pass   

            if chargingBumper.pressing() and launchingBumper.pressing():
                touchLED.set_color(Color.GREEN)
            elif chargingBumper.pressing() and not launchingBumper.pressing():
                touchLED.set_color(Color.YELLOW)
            elif not chargingBumper.pressing() and  launchingBumper.pressing():
                touchLED.set_color(Color.BLUE)
            else:
                touchLED.set_color(Color.RED)
       
        # wait before repeating the process
        wait(10, MSEC)

# define variable for remote controller enable/disable
remote_control_code_enabled = True

catapult_thread_auto = Thread(catapult_thread)

    

#endregion VEXcode Generated and Custom Robot Configuration

#region Set velocities and stoppings:
# Brain
brain_inertial.calibrate()
brain_inertial.set_heading(0, DEGREES)
brain_inertial.set_rotation(0, DEGREES)
# Drivetrain
drivetrain.set_drive_velocity(70, PERCENT)
drivetrain.set_turn_velocity(20, PERCENT)
drivetrain.set_stopping(HOLD)
drivetrain.set_timeout(3000, MSEC)
drivetrain.set_turn_threshold(.5)
# Motors
H_Wheel.set_velocity(100, PERCENT)
H_Wheel.set_stopping(HOLD)
H_Wheel.set_timeout(1000, MSEC)
intake.set_velocity(100, PERCENT)
intake.set_stopping(COAST)
cata.set_velocity(100, PERCENT)
cata.set_stopping(COAST)
cata.set_timeout(2, SECONDS)
# Sensors
touchLED.set_fade(FadeType.OFF)
touchLED.set_brightness(100)
touchLED.set_color(Color.RED)

#endregion Set velocities and stoppings

#region Define Auton Skills functions:

################################################################################

def turnPD(endAngle, clockwise):
    kP = 1.00
    kD = 0.00
    startingAngle = brain_inertial.heading()
    prevError = 0
    error = 0
    derivative = 0
    difference = 0
    while True:
        currentAngle = brain_inertial.heading() 
        if (currentAngle <= endAngle + 1) and (currentAngle >= endAngle - 1):
            left_drive_smart.stop()
            right_drive_smart.stop()
            touchLED.set_color(Color.GREEN)
            break
        error = endAngle - currentAngle
        derivative = error - prevError
        power = error*kP + derivative*kD
        if clockwise:
            right_drive_smart.spin(REVERSE, power, PERCENT)
            left_drive_smart.spin(FORWARD, power, PERCENT)
        else:
            right_drive_smart.spin(FORWARD, power)
            left_drive_smart.spin(REVERSE, power)
        wait(10, MSEC)

################################################################################

def drivePD(dist, dir):
    kP = 0.70
    kD = 1.00
    error = 0
    prevError = 0
    traveled = 0
    left_drive_smart.reset_position()
    right_drive_smart.reset_position()
    touchLED.set_color(Color.RED)
    while True:
        if (traveled + 5 >= dist) and (traveled - 5 <= dist):
            left_drive_smart.stop()
            right_drive_smart.stop()
            touchLED.set_color(Color.GREEN)
            break
        traveled = abs((left_drive_smart.position() + right_drive_smart.position()) / 2) / 360 * 200 # distance traveled in milimeters 
        error = dist - traveled # calculate the distance to the target (error)
        deriv = error - prevError # calculate derivative (deriv)
        prevError = error # sets the previous error (prevError) to the current error (error)
        power = error * kP + deriv * kD # calculates the power based on errer, kP, derivative, and kD  
        if dir == FORWARD:
            drivetrain.drive(FORWARD, power, PERCENT) # drives the robot forward at power's speed
        else:
            drivetrain.drive(REVERSE, power, PERCENT) # drives the robot reverse at power's speed
        wait(15, MSEC) # waits 15 seconds

################################################################################

def drive_turn(dist, h_lock, direction, angle):
   
    # locks the H_Wheel to drive straight
    if h_lock:
        H_Wheel.stop(HOLD)
    else:
        H_Wheel.stop(COAST)
    # note to self: insert drive pid later
    if direction:
        drivePD(dist, FORWARD)
    elif not direction:
        drivePD(dist, REVERSE)
    else:
        print("Direction type is incorrect")
     # note to self: insert turn pid later
    H_Wheel.stop(COAST)
    drivetrain.turn_to_heading(angle, DEGREES)

################################################################################

def strafe(straight, direction, dist):
    if straight and direction == "R":
        H_Wheel.spin(FORWARD, 100, PERCENT)
        left_drive_smart.spin(FORWARD, 10, PERCENT)
        right_drive_smart.spin(REVERSE, 9, PERCENT)
    elif straight and direction == "L":
        H_Wheel.spin(REVERSE, 100, PERCENT)
        left_drive_smart.spin(REVERSE, 10, PERCENT)
        right_drive_smart.spin(FORWARD, 10, PERCENT)
    elif not straight and direction == "R":
        H_Wheel.spin(FORWARD, 100, PERCENT)
    else:
        H_Wheel.spin(REVERSE, 100, PERCENT)
    
################################################################################

def firstGoal():
    intake.spin(FORWARD, 100, PERCENT)
    drive_turn(200, True, True, 40)
    # intakes a ball and gives room to score
    drive_turn(300, True, True, 280)
    # Intakes ball and aligns with goal wall
    H_Wheel.stop(HOLD)
    drivetrain.drive(REVERSE, 70, PERCENT)
    wait(500, MSEC)
    intake.stop()
    wait(2200, MSEC)
    # Drives backward to goal wall and score (hopefully)
    catapult(False)
    wait(1000, MSEC)
    catapult(True)
    drivetrain.stop()
    intake.stop()
    
################################################################################

def otherGoal():
    drive_turn(500, True, True, 340)
    intake.spin(FORWARD)
    drive_turn(530, True, True, 270)
    # Intakes the first RL (Rapid Load) ball and aligns with the goal
    wait(2000, MSEC)
    # Gives time for the RLer to load second ball into the robot
    H_Wheel.stop(HOLD)
    drivetrain.drive(REVERSE, 70, PERCENT)
    wait(3000, MSEC)
    H_Wheel.spin(REVERSE)
    wait(100, MSEC)
    H_Wheel.stop()
    # Drives backward to goal wall and score (hopefully)
    catapult(False)
    wait(1000, MSEC)
    drivetrain.stop()
    intake.stop()
    catapult(True)
     
    pass

################################################################################

def repeatScoringL():
    drive_turn(150, True, True, 275)
    H_Wheel.set_stopping(HOLD)
    H_Wheel.stop()
    intake.spin(FORWARD, 100, PERCENT)
    drive_turn(550, True, True, 270)
    wait(833, MSEC)
    drive_turn(500, True, False, 270) 
    drive_turn(200, True, False, 270)
    catapult(False)
    wait(166, MSEC)
    catapult(True)

################################################################################

def repeatScoringR():
    drivetrain.set_timeout(2, SECONDS)
    H_Wheel.set_stopping(HOLD)
    H_Wheel.stop()
    drivetrain.set_stopping(COAST)
    intake.spin(FORWARD, 100, PERCENT)
    drive_turn(700, True, True, 270)
    wait(833, MSEC)
    drive_turn(750, True, False, 270)
    catapult(False)
    wait(326, MSEC)
    catapult(True)
    drivetrain.set_stopping(HOLD)
    drivetrain.set_timeout(3, SECONDS)

################################################################################

def start():
    firstGoal()
    repeatScoringR()
    otherGoal()
    while True:
        repeatScoringR()

#endregion Define Auton Skills functions

def test():
    Start = Thread(start)
    
################################################################################

def catapult(charge):
    if charge:
        cata.spin(FORWARD)
    else:
        cata.spin(REVERSE, 100, PERCENT)
        wait(300, MSEC)
        cata.stop()
        touchLED.set_color(Color.RED)
     
brain.screen.set_font(FontType.MONO60)
brain.screen.print("1417R")

catapult(True)

touchLED.pressed(start)
Issues
def catapult_thread():
    while True:
        # automatic catapult charging function
        if (autoCataOn):
            try:
                if launchingBumper.pressing() and chargingBumper.pressing():
                    # Launching code
                    cata.stop()
                    cata.spin(REVERSE)
                    wait(100, MSEC)
                    cata.stop()
                elif chargingBumper.pressing() or launch:
                    # Stop charging code
                    wait(10, MSEC)
                    cata.stop()
                else:
                    # Charging code
                    cata.spin(FORWARD)                      
            except:
                pass   

            if chargingBumper.pressing() and launchingBumper.pressing():
                touchLED.set_color(Color.GREEN)
            elif chargingBumper.pressing() and not launchingBumper.pressing():
                touchLED.set_color(Color.YELLOW)
            elif not chargingBumper.pressing() and  launchingBumper.pressing():
                touchLED.set_color(Color.BLUE)
            else:
                touchLED.set_color(Color.RED)
       
        # wait before repeating the process
        wait(10, MSEC)

and

def catapult(charge):
    if charge:
        cata.spin(FORWARD)
    else:
        cata.spin(REVERSE, 100, PERCENT)
        wait(300, MSEC)
        cata.stop()
        touchLED.set_color(Color.RED)

Whenever I call the function “catapult”, my thread stops. I was trying to put all of my autonomous code into a seperate thread but that didn’t work. “catapult” didn’t work at all. If you need any more information, just tell me.

2 Likes

First thing to figure out is if the thread is really stopped. I think it’s more likely that, because you are controlling the “cata” motor group from multiple places, the motors get into some state you are not expecting (perhaps you constantly send stop to them from somewhere and override any other spin commands).

Okay, I’ll check in a second. But is there a way to start a thead if it is stopped using the thread.stop() command?

In the while loop, I have an if statement that checks the bool “autoCataOn” that is a global varible, so I should be able to change its value. However, everytime I try to change it, it says the varible is not accessed. Could you help me?