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.
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’)
elif position < 3450:
print(‘more power to left motor’)
print(‘power to both motors’)
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
For more information see this article about PED control
Also I would suggest looking at the Cannybots source code
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,
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 OR set
read current step value from Ardunio
Left Motor speed = step
Right Motor speed = step
And in Python the code looks like this
for instruction in course:
motorSpeed1 = instruction
motorSpeed2 = instruction
motorCount1 = instruction
motorCount2 = instruction
print(‘motor1 speed: ‘ + str(motorSpeed1))
flag = True
#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
print(‘Exit Button Pressed’)
# Start the motors
# read the serial port
rcv = readlineCR(port)
# and then spilt the result into 2 int’s if possable
numbers = rcv.split()
left = int(numbers)
right = int(numbers)
if left>(old_left+motorCount1) or right>(old_right+motorCount2):
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.