Pi Wars – Line Following and 3 Point Turn

The deadline for the Pi Wars code quality challenge has passed, glad to say that I beat the deadline and uploaded my code to my Github account. I decided to share my code to everyone, and you can find it here.

https://github.com/Corteil/PiWars2015.git

 

Line Following

I would suggest that you watch the above video, while listening to Grove Amanda’s “I see you baby”

 

I had a good couple of weeks since my last post, I wrote the code for line following challenge. For the challenge, I selected a line following sensor made by Pololu, the QTR. The QTR as an array of 8 IR LEDs and receivers, the Arduino library provided by Pololu outputs a number between 0 and 7000. This makes it possible to adjust the speed of motors, to keep Revenge on the line. The library also remembers the position of the line when it was lost. This allows the code to decide which way to turn Revenge when the line is lost. I used an Arduino to read the position of the line, the Raspberry Pi is connected to the Arduino via a serial connection. My code is very crude and basically just switches the motors on/off depending where the line is/was. I used the following rules to decide which way to turn Revenge.

If the line position is less than 3450 turn right
if the line position is more than 3550 turn left
if the line position is between 3450 and 3550 power both motors

This translates to the following code in Python

if position > 3550:

      print(‘more power to right motor’)

     DIABLO.SetMotor1(0)

      DIABLO.SetMotor2(-0.5)

elif position < 3450:

      print(‘more power to left motor’)

      DIABLO.SetMotor1(-0.5)

      DIABLO.SetMotor2(0)

else:

      print(‘power to both motors’)

       DIABLO.SetMotor1(-0.4)

       DIABLO.SetMotor2(-0.4)

Improvements to code would be to adjust the speed to the motors and not just kill the power to one motor when needing to turn, and to use a PID control method for error control, and make the run much smother. A good example of a line following robot using the PID control method are Cannybots.

for more information about PID control visit see this article

https://www.robotix.in/tutorial/avr/pid/

For more information see this article about PED control

Also I would suggest looking at the Cannybots source code

https://github.com/Cannybots

 

3-point turn

 

For the 3 point turn, I’m using rotary encoders, on the middle wheels of Revenge, the rotary encoders count the number of steps each wheel turns by. I’m using a IR LED and receiver module,

connected to an Arduino, the Arduino is connected to the Raspberry Pi by the serial port.IMG_20151129_112759

Picture of encoder rings and IR LED and Receiver

The black triangle in the image is the IR module, you can also see the encode ring. The IR module outputs deferent values depending if the white or black section is in front of the sensor. The Arduino counts the changes in values.

Now that I can count the number of steps Revenges wheels turn, I can use this information to stop the motors turning at a pre-set value. This allows Revenge to turn and move in a repeatable way. My code is uses the follow rule

If motor count >= stop motor

The motor settings and number of steps to move are stored in a python list.

[left motor speed, right motor speed, left number of steps, right number of steps]

and each move is store in another list.

[move 1, move 2, move3]

 

A FOR loop is reads each move and passes the motor speed settings to the motor controller and a WHILE loop keeps checking the count from the Arduino, this ends the WHILE loop when one of the step values is reached and kills the power to the motors.

FOR step in routine

     WHILE motor count left OR motor count right is less than set[2] OR set[3]
read current step value from Ardunio

       Left Motor speed = step[0]
Right Motor speed = step[1]

     Stop motors

And in Python the code looks like this

for instruction in course:

        motorSpeed1 = instruction[0]

        motorSpeed2 = instruction[1]

        motorCount1 = instruction[2]

        motorCount2 = instruction[3]

        print(‘motor1 speed: ‘ + str(motorSpeed1))

        flag = True

 

        while flag:

            #print ‘Press CTRL+C or “SELECT” on joypad to quit’

            # Get the latest events from the system

            hadEvent = False

            events = pygame.event.get()

            # Handle each event individually

            for event in events:

                if event.type == pygame.QUIT:

                    # User exit

                    running = False

                elif event.type == pygame.JOYBUTTONDOWN:

                    # A button on the joystick just got pushed down

                    hadEvent = True

 

                if joystick.get_button(buttonQuit):

                    DIABLO.MotorsOff()

                    print(‘Exit Button Pressed’)

                    sys.exit()

                 # Start the motors

 

            DIABLO.SetMotor1(motorSpeed1)

            DIABLO.SetMotor2(motorSpeed2)

 

            # read the serial port

 

            rcv = readlineCR(port)

 

            # and then spilt the result into 2 int’s if possable

            numbers = rcv.split()

            left = int(numbers[0])

            right = int(numbers[1])

            print numbers

            if left>(old_left+motorCount1) or right>(old_right+motorCount2):

                DIABLO.MotorsOff()

                print(‘Motors stopped’)

                flag = False

                old_left = left

                old_right = right

That’s it for now, with less than 6 days to go, it’s time to add some bling to Revenge and let PyroBot get into the action.