Vexcode VR Python coroutine issue

On this particular line of code:

if i>=28: # pick up 14 and drop 14

I came across this error message:

Traceback (most recent call last):
File “/lib/python3.8/asyncio/tasks.py”, line 280, in __step
result = coro.send(None)
line 62, in main
TypeError: ‘<’ not supported between instances of ‘coroutine’ and ‘coroutine’

If it helps, I am using the Vexcode VR Over Under Playground.

Has anyone encountered this before? Any assists would be appreciated!

The rest of the code would definitely help.

3 Likes
#region VEXcode Generated Robot Configuration
import math
import random
from vexcode_vrc import *
from vexcode_vrc.events import get_Task_func

# Brain should be defined by default
brain=Brain()

drivetrain = Drivetrain("drivetrain", 0)
arm_motor = Motor("ArmMotor", 3)
rotation = Rotation("Rotation", 7)
intake_motor = Motor("IntakeMotor", 8)
optical = Optical("Optical", 11)
gps = GPS("GPS", 20)

# Add project code in "main"
def main():
    def priority_key_length(nums):
        return math.isqrt((nums[0]-gps.x_position(MM))**2+(nums[1]-gps.y_position(MM)**2))

    def priority_key_angle(nums):
        return int(math.degrees(math.atan(nums[1]/nums[0])))
    
    def pick_up_triball():
        intake_motor.spin_for(FORWARD, 360, DEGREES)

    def release_triball():
        intake_motor.spin_for(REVERSE, 360, DEGREES)

    def rotate_to_target_triball():
        #rotate until the following returns True
        #assume unidirectional and points in the same direction as intake, but might need changing later
        while optical.is_near_object == False: 
            drivetrain.turn(RIGHT) 
            #can change between left and right, shouldn't matter but we can verify in testing which gives more points
    drivetrain.set_rotation(0, DEGREES) 
    

    triball_locations=[[-1600,1600], [1600,1600],[0,1500],[-125,1075],[-125,600],[-300,300],[-600,0],[-100,0],[-100,-600],[-100,-1100],[-1600,-1600],[1600,-1600]]
    i=0

    pickup_toggle_times=i

    # goal_front==(1200,600) - (1200, -600)
    ## goal front is anywhere between

    while True:
        length_order=triball_locations.sort(reverse=True, key=priority_key_length)
        priority_length=list(map(priority_key_length,length_order))
        priority_angle=list(map(priority_key_angle, priority_length)) 
        if i>=28: # pick up 14 and drop 14
            break

        #incomplete - adjust based off current angle and position

        #somehow broken code that i may not need now but might need int he future:

        #length_to_origin=math.isqrt((gps.x_position(MM)**2+gps.y_position(MM)**2)
        #angle_to_origin=int(math.atan(gps.y_position(MM)/gps.x_position(MM)))
        
        
        #incomplete - adjust based off current angle and position
        elif pick_toggle_times % 2 == 0: #dont have a ball yet
        
            curr_ball_len=priority_length.pop()
            curr_ball_ang=priority_angle.pop()
            drivetrain.turn_to_rotation(curr_ball_ang, DEGREES)
            drivetrain.drive_for(FORWARD, curr_ball_len, MM)
            
            #second check to make sure that triball is close by

            if optical.is_near_object()==True:
                pick_up_triball()
                #update counter
                i=i+1
            else:
                #just in case something went wrong, we'll go back to the start of the function
                continue
        elif pick_toggle_times % 2 == 1: # already have a ball
            #rotate up/down
            while gps.y_position(MM)!=0: 
                if gps.y_position(MM) >0:
                    drivetrain.turn_to_rotation(-90, DEGREES)
                elif gps.y_position(MM) >0:
                    drivetrain.turn_to_rotation(90, DEGREES) 
                #go up/down until you hit y=0
                drivetrain.drive(FORWARD)
            drivetrain.turn_to_rotation(0, DEGREES)
            while gps.x_position(MM)!=1200:
                drivetrain.drive(FORWARD)
            # rotate dropper until its in front of goal
            # deposit
                release_triball()
            # update counter
            i=i+1
    total==i//2
vr_thread(main)

edit: code tags added by moderators

I think this line should instead be

length_order=sorted(triball_locations, key=priority_key_length, reverse=True)

Also, this line is sort of sketchy:

I’m not really sure what that’s doing.

Hey, can you rerun the code and make sure the error message is exactly what you’ve written here?

Your error message is indicating that ‘<’ is not working between … …, but the code you’ve shown has a ‘>=’. In addition, when I pasted the code into my own editor, line 62 is blank. I have seen some other parts of your code that could potentially give a similar error message, which I’ll point out below, but I would appreciate you insuring that you have given the correct error message.

  • pick_toggle_times and pickup_toggle_times are not the same, at lines 43, 64, and 80.
  • optical.is_near_object and optical.is_near_object() have both been compared to true and false. I am unsure which is correct as I don’t have an optical sensor, but both are not correct. Also, comparing to True and False is not needed, as (var == True) is the same as (var), and (var == False) is the same as (not var).

Also… if I had to guess, there is likely problems within the length_order=triball_locations.sort(reverse=True, key=priority_key_length) priority_length=list(map(priority_key_length,length_order)) priority_angle=list(map(priority_key_angle, priority_length))
section. From my understanding, priorty_length will be a list of direct distances from the robot to the triball, calculated by the pythagorean theorem. However, if you then try to feed that, rather than the original 2d distances into the priorty_key_angle function, the function will not be able to work. It should actually cause an error, as nums[1] wouldn’t exist. If there was a section that would cause an error with coroutines, I would assume this section would be causing it. You might be able to fix it by changing the third line from using (priority_length) to (length_order).

Lastly, I haven’t seen any reason as to why the i>= 28 line would be causing problems. I also can’t run the code bc I don’t have the vexcode vr python version.

My bad, I removed some comments at the start of the code: Here is the full thing:

#region VEXcode Generated Robot Configuration
import math
import random
from vexcode_vrc import *
from vexcode_vrc.events import get_Task_func

# Brain should be defined by default
brain=Brain()

drivetrain = Drivetrain("drivetrain", 0)
arm_motor = Motor("ArmMotor", 3)
rotation = Rotation("Rotation", 7)
intake_motor = Motor("IntakeMotor", 8)
optical = Optical("Optical", 11)
gps = GPS("GPS", 20)
#endregion VEXcode Generated Robot Configuration
# ------------------------------------------
# 
# 	Project:      VEXcode Inital Draft 1
#	Author:       Lucian and Epsilon
#	Created:
#	Description:  VEXcode Python Project
# 
# ------------------------------------------

# Add project code in "main"
def main():
    def priority_key_length(nums):
        return math.isqrt((nums[0]-gps.x_position(MM))**2+(nums[1]-gps.y_position(MM)**2))

    def priority_key_angle(nums):
        return int(math.degrees(math.atan(nums[1]/nums[0])))
    
    def pick_up_triball():
        intake_motor.spin_for(FORWARD, 360, DEGREES)

    def release_triball():
        intake_motor.spin_for(REVERSE, 360, DEGREES)

    def rotate_to_target_triball():
        #rotate until the following returns True
        #assume unidirectional and points in the same direction as intake, but might need changing later
        while optical.is_near_object == False: 
            drivetrain.turn(RIGHT) 
            #can change between left and right, shouldn't matter but we can verify in testing which gives more points
    drivetrain.set_rotation(0, DEGREES) 
    

    triball_locations=[[-1600,1600], [1600,1600],[0,1500],[-125,1075],[-125,600],[-300,300],[-600,0],[-100,0],[-100,-600],[-100,-1100],[-1600,-1600],[1600,-1600]]
    i=0

    pickup_toggle_times=i

    # goal_front==(1200,600) - (1200, -600)
    ## goal front is anywhere between

    while True:
        length_order=triball_locations.sort(reverse=True, key=priority_key_length)
        priority_length=list(map(priority_key_length,length_order))
        priority_angle=list(map(priority_key_angle, priority_length)) 
        if i>=28: # pick up 14 and drop 14
            break

        #incomplete - adjust based off current angle and position

        #somehow broken code that i may not need now but might need int he future:

        #length_to_origin=math.isqrt((gps.x_position(MM)**2+gps.y_position(MM)**2)
        #angle_to_origin=int(math.atan(gps.y_position(MM)/gps.x_position(MM)))
        
        
        #incomplete - adjust based off current angle and position
        elif pick_toggle_times % 2 == 0: #dont have a ball yet
        
            curr_ball_len=priority_length.pop()
            curr_ball_ang=priority_angle.pop()
            drivetrain.turn_to_rotation(curr_ball_ang, DEGREES)
            drivetrain.drive_for(FORWARD, curr_ball_len, MM)
            
            #second check to make sure that triball is close by

            if optical.is_near_object()==True:
                pick_up_triball()
                #update counter
                i=i+1
            else:
                #just in case something went wrong, we'll go back to the start of the function
                continue
        elif pick_toggle_times % 2 == 1: # already have a ball
            #rotate up/down
            while gps.y_position(MM)!=0: 
                if gps.y_position(MM) >0:
                    drivetrain.turn_to_rotation(-90, DEGREES)
                elif gps.y_position(MM) >0:
                    drivetrain.turn_to_rotation(90, DEGREES) 
                #go up/down until you hit y=0
                drivetrain.drive(FORWARD)
            drivetrain.turn_to_rotation(0, DEGREES)
            while gps.x_position(MM)!=1200:
                drivetrain.drive(FORWARD)
            # rotate dropper until its in front of goal
            # deposit
                release_triball()
            # update counter
            i=i+1
    total==i//2
vr_thread(main)

edit: code tags added by mods, please remember to use them.

Moreover, here is the error code I got once more:

Traceback (most recent call last):
File “/lib/python3.8/asyncio/tasks.py”, line 280, in __step
result = coro.send(None)
line 61, in main
TypeError: ‘<’ not supported between instances of ‘coroutine’ and ‘coroutine’

Hm, it’s beyond me as to why the error message indicates a ‘<’ as opposed to a ‘>=’, or why it believes the variable i or the simple int 28 is a coroutine. I suppose I would still recommend fixing the things I mentioned above, especially the map() section, as that seems most likely to be generating similar errors.

However, are you able to run the code? Or, more importantly, if you placed a print(“H w”) statement at the top, would it run? If so, you could try placing print(i) statements around your code, especially to see what type (i) is right before the error occurs. If print(type(i)) still indicates it is an int, and you add some filler code between the map section and the i<= 28 section to make sure the error isn’t just occuring after the list(map()) code, then I really can’t help you any more.

VEXcode VR has a simple system in place to help mask the fact that all the robot commands that seem to be synchronous are actually all asynchronous functions. To make this work for subroutine functions in the code, the preprocessor converts all the normal functions and function calls found in the code to async functions. This process works fine for most use cases, but we never consider that it would impact code where you want to pass a function definition as a reference.

For right now, it is possible to work around this limitation by using lambda functions. In the code you provided I think you just need to change priority_key_length and priority_key_angle to something like

priority_key_length = lambda nums : math.isqrt((nums[0]-gps.x_position(MM))**2+(nums[1]-gps.y_position(MM)**2))
priority_key_angle = lambda nums : int(math.degrees(math.atan(nums[1]/nums[0])))

Unfortunately, after making that change it looks like there are still be a few math issues with your code, but that should be easy enough to fix.

2 Likes

Ok i’ve tried all of your suggestions, which includes:

  1. i’ve tried replacing length_order=triball_locations.sort(reverse=True, key=priority_key_length) with length_order=sorted(triball_locations, key=priority_key_length, reverse=True)

  2. [17:49]

i’ve changed priority_key_length and priority_key_angle to

priority_key_length = lambda nums : math.isqrt((nums[0]-gps.x_position(MM))**2+(nums[1]-gps.y_position(MM)**2))
priority_key_angle = lambda nums : int(math.degrees(math.atan(nums[1]/nums[0])))

and i still get the same coroutine error. At this point i just want sth to run lmao

#region VEXcode Generated Robot Configuration
import math
import random
from vexcode_vrc import *
from vexcode_vrc.events import get_Task_func

# Brain should be defined by default
brain=Brain()

drivetrain = Drivetrain("drivetrain", 0)
arm_motor = Motor("ArmMotor", 3)
rotation = Rotation("Rotation", 7)
intake_motor = Motor("IntakeMotor", 8)
optical = Optical("Optical", 11)
gps = GPS("GPS", 20)
#endregion VEXcode Generated Robot Configuration
# ------------------------------------------
# 
# 	Project:      VEXcode Inital Draft 1
#	Author:       Lucian and Epsilon
#	Created:
#	Description:  VEXcode Python Project
# 
# ------------------------------------------

# Add project code in "main"
def main():
    priority_key_length = lambda nums : math.isqrt(abs((nums[0]-gps.x_position(MM))**2+(nums[1]-gps.y_position(MM)**2)))
    priority_key_angle = lambda nums : (math.degrees(math.atan(nums[1]/nums[0])))
    #def priority_key_length(nums):
        #return math.isqrt((nums[0]-gps.x_position(MM))**2+(nums[1]-gps.y_position(MM)**2))
    #def priority_key_angle(nums):
        #return int(math.degrees(math.atan(nums[1]/nums[0])))
    
    def pick_up_triball():
        intake_motor.spin_for(FORWARD, 360, DEGREES)

    def release_triball():
        intake_motor.spin_for(REVERSE, 360, DEGREES)

    def rotate_to_target_triball():
        #rotate until the following returns True
        #assume unidirectional and points in the same direction as intake, but might need changing later
        while optical.is_near_object() == False: 
            drivetrain.turn(RIGHT) 
            #can change between left and right, shouldn't matter but we can verify in testing which gives more points
    drivetrain.set_rotation(0, DEGREES) 
    

    triball_locations=[[-1600,1600], [1600,1600],[0,1500],[-125,1075],[-125,600],[-300,300],[-600,0],[-100,0],[-100,-600],[-100,-1100],[-1600,-1600],[1600,-1600]]
    i=0



    # goal_front==(1200,600) - (1200, -600)
    ## goal front is anywhere between

    while True:
        length_order=sorted(triball_locations, key=priority_key_length, reverse=True)
        priority_length=list(map(priority_key_length,length_order))
        priority_angle=list(map(priority_key_angle, priority_length)) 
        #if i>=28: # pick up 14 and drop 14
           # break

        #incomplete - adjust based off current angle and position

        #somehow broken code that i may not need now but might need int he future:

        #length_to_origin=math.isqrt((gps.x_position(MM)**2+gps.y_position(MM)**2)
        #angle_to_origin=int(math.atan(gps.y_position(MM)/gps.x_position(MM)))
        
        
        #incomplete - adjust based off current angle and position
        if i % 2 == 0: #dont have a ball yet
        
            curr_ball_len=priority_length.pop()
            curr_ball_ang=priority_angle.pop()
            drivetrain.turn_to_rotation(curr_ball_ang, DEGREES)
            drivetrain.drive_for(FORWARD, curr_ball_len, MM)
            
            #second check to make sure that triball is close by

           # if optical.is_near_object()==True:
            intake_motor.spin_for(FORWARD, 360, DEGREES)
            #update counter
            i=i+1
            wait(10, MSEC)
           
           
                #just in case something went wrong, we'll go back to the start of the function
                
        elif i % 2 == 1: # already have a ball
            #rotate up/down
            while gps.y_position(MM)!=0: 
                if gps.y_position(MM) > 0:
                    drivetrain.turn_to_rotation(-90, DEGREES)
                elif gps.y_position(MM) >0:
                    drivetrain.turn_to_rotation(90, DEGREES) 
                #go up/down until you hit y=0
                drivetrain.drive(FORWARD)
            drivetrain.turn_to_rotation(0, DEGREES)
            while gps.x_position(MM)!=1200:
                drivetrain.drive(FORWARD)
            # rotate dropper until its in front of goal
            # deposit
                intake_motor.spin_for(REVERSE, 360, DEGREES)
            # update counter
            i=i+1
            wait(10, MSEC)
vr_thread(main)

Here’s the new code

Here’s the error i got:

Traceback (most recent call last):
File “/lib/python3.8/asyncio/tasks.py”, line 280, in __step
result = coro.send(None)
line 65, in main
line 32, in
TypeError: ‘int’ object is not subscriptable

Traceback (most recent call last):
File “/lib/python3.8/asyncio/tasks.py”, line 280, in __step
result = coro.send(None)
line 65, in main
line 32, in
TypeError: ‘int’ object is not subscriptable

Hi,

priority_key_length = lambda nums : math.isqrt(abs((nums[0]-gps.x_position(MM))**2+(nums[1]-gps.y_position(MM)**2)))
priority_key_angle = lambda nums : (math.degrees(math.atan(nums[1]/nums[0])))

length_order=sorted(triball_locations, key=priority_key_length, reverse=True)
priority_length=list(map(priority_key_length,length_order))
priority_angle=list(map(priority_key_angle, priority_length)) 

curr_ball_len=priority_length.pop()
curr_ball_ang=priority_angle.pop()

Above is a few snippets of your code that I believe are causing the problem. The first line is setting priority_key_length to be a function that takes in a list of two numbers and returns a single number, representing the distance. The second line is setting priority_key_angle to be a function that also takes in a list of 2 numbers and returns a single number, representing the angle. Importantly, the two input numbers for this function need to be the x and y distances the object is from the robot for this code to work.

Now, looking at the second section: The first line takes a list of coordinates, which is a list of (lists of 2 numbers), and sorts it according to priority_key_length. This should work. (reverse might need to be flipped, I don’t know). The second creates the list priority_length, which is a list of lengths, ordered by closest to farthest. However, priority_length is now the direct length, not the x and y distances, because you applied priority_key_length to it in the map function. Therefore, it is a single number. Thus, in the third line, when you try to apply priority_key_angle to priority_length, the function errs because each unit in priority_length is a single number, not a coordinate, and priority_key_angle requires a list of 2 numbers. Thus the err, int is not subscriptable, because you call nums[0] and nums[1] when nums is just a random number, not a coordinate. Therefore, you need to replace priority_length to length_order, as length_order is a set of coordinates. Of course, this will still not work as you need to adjust those coordinates with the GPS coordinates. I recommend changing the definition of priority_key_angle to subtract the GPS coords.
This hopefully explains the error you are currently getting.

A few other notes: priority_key_angle could technically divide by 0, although it is unlikely if you subtract gps coords. Also, there is one more problem that might cause you to always go to the first triball because you are redefining length_order, priority_length, and priority_angle every loop iteration using triball_locations, which is not pop()'d. However, I would try fixing the current error and getting the code to run first, and then see if you can fix the other problem.