TypeError : object 'line' is not a tuple or list

Discussion related to "under the hood" OpenMV topics.
Allen1234
Posts: 8
Joined: Mon Oct 30, 2017 2:45 am

TypeError : object 'line' is not a tuple or list

Postby Allen1234 » Sun Dec 10, 2017 10:26 pm

I tried to run this code on OpenMV IDE, but the system suddenly says TypeError and I don't know how to fix this.

This is the code. The TypeError box appears on the code line ( img.draw_line(l, color=(127)) # Draw lines)

Code: Select all

# Autonomous rover code by Chris Anderson, 3DR, DIY Robocars
# Copyrigbt 2017
# Released under a BSD 2.0 Open Source Licence

import sensor, image, pyb, math, time
from pyb import Servo
from pyb import LED

s1 = Servo(1) # P7 Motor
s2 = Servo(2) # P8 Steering
print (s1.calibration()) # show throttle servo calibration
cruise_speed = 0 # how fast should the car drive, range from 1000 to 2000
steering_gain = 500
kp = 0.8   # P term of the PID
ki = 0     # I term of the PID
kd = 0     # D term of the PID

red_led   = LED(1)
green_led = LED(2)
blue_led  = LED(3)
ir_led    = LED(4)

old_error = 0
measured_angle = 0
set_angle = 90 # this is the desired steering angle (straight ahead)
p_term = 0
i_term = 0
d_term = 0
old_time = pyb.millis()

def led_control(x):
    if   (x&1)==0: red_led.off()
    elif (x&1)==1: red_led.on()
    if   (x&2)==0: green_led.off()
    elif (x&2)==2: green_led.on()
    if   (x&4)==0: blue_led.off()
    elif (x&4)==4: blue_led.on()
    if   (x&8)==0: ir_led.off()
    elif (x&8)==8: ir_led.on()

def constrain(value, min, max):
    if value < min :
        return min
    if value > max :
        return max
    else:
        return value

def steer(angle):
    global steering_gain
    s1.angle(angle) # steer
    pyb.delay(10)

def update_pid():
    global old_time, old_error, measured_angle, set_angle
    global p_term, i_term, d_term
    now = pyb.millis()
    dt = now - old_time
    error = set_angle - measured_angle
    de = error - old_error

    p_term = kp * error
    i_term += ki * error
    i_term = constrain(i_term, 0, 100)
    d_term = (de / dt) * kd

    old_error = error
    output = p_term + i_term + d_term
    output = constrain(output, -50, 50)
    return output

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.RGB565
sensor.set_framesize(sensor.QQVGA) # or sensor.QVGA (or others)
clock = time.clock() # Tracks FPS.
#s1.pulse_width(2000)  # initialize the motor controller with a high signal for a second
#pyb.delay(1000)
#s1.pulse_width(1000) # return motor controller to low/off throttle
while(True):
    led_control(2)
#    s1.speed(120)   Start motor; currently disabled while I use RC for throttle
#    pyb.delay(10)
    clock.tick() # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot() # Take a picture and return the image.
    img.find_edges(image.EDGE_CANNY, threshold=(60, 150))  # Find edges
    lines = img.find_lines(threshold=35) # Find lines.
    counter = 0
    totalangle = 0
    for l in lines:
        img.draw_line(l, color=(127)) # Draw lines
    if lines:
        if (l[2]-l[0]) != 0: # don't allow vertical lines (undefined arctan)
            angle = -math.atan2(-(l[3]-l[1]),(l[2]-l[0])) # arctan (deltaY/deltaX); we use atan2 so we can tell what quadrant it's in
            angle = math.degrees(angle) # convert from radians to degrees
        if angle < 140 and angle > 40: # ignore lines that are mostly horizontal
                totalangle = totalangle + angle  # add up all the line angles so we can average them
                counter = counter + 1
        if counter != 0:
            now = pyb.millis()
            if  now > old_time + 1.0 :  # time has passed since last measurement
                measured_angle = totalangle/counter  # average of angles
                steer_angle = update_pid()
                old_time = now
                steer (steer_angle)
                print(str(measured_angle) + ', ' + str(set_angle) + ', ' + str(steer_angle))
#           s1.pulse_width(cruise_speed) # move forward at cruise speed; currently disabled while I run throttle with RC
User avatar
aakoch
Posts: 24
Joined: Wed Dec 06, 2017 11:07 pm

Re: TypeError : object 'line' is not a tuple or list

Postby aakoch » Sun Dec 10, 2017 10:46 pm

You need to call .line() on "l".

Code: Select all

img.draw_line(l.line(), color=(127)) # Draw lines
find_lines returns a "Line" object http://docs.openmv.io/library/omv.image ... ine-object
but draw_line needs a tuple.
User avatar
kwagyeman
Posts: 1745
Joined: Sun May 24, 2015 2:10 pm

Re: TypeError : object 'line' is not a tuple or list

Postby kwagyeman » Sun Dec 10, 2017 10:53 pm

Once I get around to updating the draw methods I can make this less error prone.
Nyamekye,
Allen1234
Posts: 8
Joined: Mon Oct 30, 2017 2:45 am

Re: TypeError : object 'line' is not a tuple or list

Postby Allen1234 » Sun Dec 10, 2017 11:06 pm

Thank you aakoch for the information. :P But it still does not work. Thanks for the help btw

Can't wait to hear from you kwagyeman :D
User avatar
kwagyeman
Posts: 1745
Joined: Sun May 24, 2015 2:10 pm

Re: TypeError : object 'line' is not a tuple or list

Postby kwagyeman » Sun Dec 10, 2017 11:15 pm

What's the error you are getting now?
Nyamekye,
Allen1234
Posts: 8
Joined: Mon Oct 30, 2017 2:45 am

Re: TypeError : object 'line' is not a tuple or list

Postby Allen1234 » Mon Dec 11, 2017 11:37 am

Oh, its functional. It was my mistake.
img.draw_line(l.line(), color=(127)) # Draw lines, i mistakenly typed img.draw_line(l.lines(), color=(127)) # Draw lines. Sorry for that. Thank you aakoch.

Although, the camera detects, my rover did not move. I have already adjusted the cruising speed to 1500. The motor still did not run.
User avatar
kwagyeman
Posts: 1745
Joined: Sun May 24, 2015 2:10 pm

Re: TypeError : object 'line' is not a tuple or list

Postby kwagyeman » Mon Dec 11, 2017 12:13 pm

Hi, find where the code drive power to the motor and print out what you are telling the motor to do. See what's going on. I can help more with a specific question.
Nyamekye,
Allen1234
Posts: 8
Joined: Mon Oct 30, 2017 2:45 am

Re: TypeError : object 'line' is not a tuple or list

Postby Allen1234 » Mon Dec 11, 2017 12:49 pm

Thank you kwagyeman :D . I'll post it here once I've found the code
Allen1234
Posts: 8
Joined: Mon Oct 30, 2017 2:45 am

Re: TypeError : object 'line' is not a tuple or list

Postby Allen1234 » Mon Dec 11, 2017 12:53 pm

Code: Select all

s1 = Servo(1) # P7 Motor
s2 = Servo(2) # P8 Steering
print (s1.calibration()) # show throttle servo calibration
cruise_speed = 1500 # how fast should the car drive, range from 1000 to 2000
steering_gain = 500
kp = 0.8   # P term of the PID
ki = 0     # I term of the PID
kd = 0     # D term of the PID

Code: Select all

def steer(angle):
    global steering_gain
    s1.angle(angle) # steer
    pyb.delay(10)

def update_pid():
    global old_time, old_error, measured_angle, set_angle
    global p_term, i_term, d_term
    now = pyb.millis()
    dt = now - old_time
    error = set_angle - measured_angle
    de = error - old_error

    p_term = kp * error
    i_term += ki * error
    i_term = constrain(i_term, 0, 100)
    d_term = (de / dt) * kd

    old_error = error
    output = p_term + i_term + d_term
    output = constrain(output, -50, 50)
    return output

Code: Select all

 now = pyb.millis()
            if  now > old_time + 1.0 :  # time has passed since last measurement
                measured_angle = totalangle/counter  # average of angles
                steer_angle = update_pid()
                old_time = now
                steer (steer_angle)
                print(str(measured_angle) + ', ' + str(set_angle) + ', ' + str(steer_angle))
#           s1.pulse_width(cruise_speed) # move forward at cruise speed; currently disabled while I run throttle with RC
I use a small rc smart kit, so the voltage produces may not be high, about 6v.
User avatar
kwagyeman
Posts: 1745
Joined: Sun May 24, 2015 2:10 pm

Re: TypeError : object 'line' is not a tuple or list

Postby kwagyeman » Mon Dec 11, 2017 1:49 pm

Hi, this looks likes Chris's code. Have you tried asking him what's going on? I'm not sure where to start to help you. Since that's a PID loop you kinda need to remove everything but the P part and see if that provides enough drive strength. If so not, increase the P gains until the robot starts to move.
Nyamekye,

Return to “Technical Discussion”

Who is online

Users browsing this forum: Google [Bot] and 2 guests