Average Ticker

AverageBot Devblog 7 – Nearing Completion!

AverageBot Devblog 7Line sensors finally sorted this week!

As we get closer to the Pi Wars competition on 5th December, I’ve been putting in the hours to get AverageBot ready for action. To recap on my progress so far, check out my other Pi Wars devblogs here.

With the physical build mostly complete, key progress this week has been completion and submission of my initial code (a competition challenge itself), including those pesky line followers. I’ve also written and tested some code for the three point turn challenge.

Let’s show you what I’ve been up to, and what’s left to do…

Line Followers

I finally got round to wiring and coding the line followers on my robot, after months of putting it off. It was pretty much as I expected – a pain to set up the hardware, and a bit of a pain to code – but totally necessary for the Line Follower course.

First I tackled the hardware. Wiring seemed straight forward – three pins to connect – Power, Ground and Signal (GPIO).

Using all three line following sensors created a new problem – a lack of 3.3V connections. The PiRoCon motor controller does have a few of these dotted around the board, but just for the fun of it I decided to make a little pin extender out of an old ProtoCam protoype I had in my drawer:

ProtoCam board recycling

Look…a cheeky plug of my ProtoCam board range!

Custom GPIO duplicator

Yes the pins are bent. Yes it doesn’t look pretty. Yes it works…and that’s all that matters!

Next problem: the sensors are meant to work at 5V but at that voltage I couldn’t get the high/low signal to change on a simple test script. After an hour of swearing at these components, I decided to try them at 3.3V and they worked instantly (hence my need for more 3.3V pins mentioned above).

Line sensors

All three line sensors working, gotta love that red glow!

With the sensors functioning, I then had to work out how to code them. Getting the high/low to register is one thing – but making a robot follow a track is a considerably larger beast!

Fellow Twitterer @sweenig suggested I try the Raspberry Pi Guy’s tutorial over on YouTube which gave me the fundamental understanding I needed to kick off my code. Here’s the video:

It’s a lot simpler than you’d think, but it gets a lot more complicated when you attempt tracks with tighter turns and sharp angles. So far I have the following code (below), which works on a basic oval but seems to freak out with anything complicated.

You’ll notice that I have a variable called ‘LastDir’. This is to track the last left or right sensor that my robot detected, to say “If the left or right sensor saw the line last, and then suddenly no line is seen by any sensor, it’s probably best to try that last direction again”.

It’s an attempt at pulling the robot back to the track on tight turns where it might lose itself. It doesn’t work all that well…but the theory is bang on the money!

    def linefollow(): ### PROGRAM 4 ###
    
    ## Line sensor: http://4tronix.co.uk/store/index.php?rt=product/product&product_id=144
    ## Logic:
    ##     When seeing white (off of the line) = Low logic
    ##     When seeing black (on the line) = High logic
    
        print "LineFollow script started"
        LLeft = ""
        LRight = ""
        LMiddle = ""
        LastDir = 0
        sleepspeed = 0
        while True:
            print "while started"
            #time.sleep(0.1)
            
            # 0-0
            if GPIO.input(lineLeft) == 0 and GPIO.input(lineMiddle) == 0 and GPIO.input(lineRight) == 0: 
                print "0-0"
                
                if LastDir == 1:
                    print "lastDir is Left"
                    print "turning left"
                    Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                    time.sleep(0.1)
                    Left(60) # SPIN LEFT AT LOW SPEED SETTING
                    time.sleep(0.4)
                    
                if LastDir == 3:
                    print "lastDir is Right"
                    print "turning right"
                    Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                    time.sleep(0.1)
                    Right(60) # SPIN RIGHT AT LOW SPEED SETTING
                    time.sleep(0.4)
                    
                if LastDir == 2:
                    print "lastDir is Middle"
                    print "going straight"
                    Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                    time.sleep(0.1)
                   
                    
            # X-X
            elif GPIO.input(lineLeft) == 1 and GPIO.input(lineMiddle) == 1 and GPIO.input(lineRight) == 1: 
                print "1-1"
                
                if LastDir == 1:
                    print "lastDir is Left"
                    print "turning left"
                    Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                    time.sleep(0.1)
                    Left(60) # SPIN LEFT AT LOW SPEED SETTING
                    time.sleep(0.4)
                    
                if LastDir == 3:
                    print "lastDir is Right"
                    print "turning right"
                    Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                    time.sleep(0.1)
                    Right(60) # SPIN RIGHT AT LOW SPEED SETTING
                    time.sleep(0.4)
                    
                if LastDir == 2:
                    print "lastDir is Middle"
                    print "going straight"
                    Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                    time.sleep(0.1)
                
            # X-0 or X-X-0
            elif (GPIO.input(lineLeft) == 1 and GPIO.input(lineRight) == 0) or (GPIO.input(lineLeft) == 1 and GPIO.input(lineMiddle) == 1 and GPIO.input(lineRight) == 0) :
                print "X-0-0"
                LastDir = 1
                Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                time.sleep(0.1)
                Left(60) # SPIN LEFT AT LOW SPEED SETTING
                time.sleep(0.1)
                
            # 0-X or 0-X-X
            elif (GPIO.input(lineLeft) == 0 and GPIO.input(lineRight) == 1) or (GPIO.input(lineLeft) == 0 and GPIO.input(lineMiddle) == 1 and GPIO.input(lineRight) == 1):
                print "0-0-X"
                LastDir = 3
                Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                time.sleep(0.1)
                Right(60) # SPIN RIGHT AT LOW SPEED SETTING
                time.sleep(0.1)
                
            # 0-X-0
            elif GPIO.input(lineLeft) == 0 and GPIO.input(lineMiddle) == 1 and GPIO.input(lineRight) == 0:
                print "0-X-0"
                Forward (ForwardMediumL,ForwardMediumR) # FORWARD AT LOW SPEED SETTING
                LastDir = 2

I’ll be working on this between now and the competition, and may add a fourth sensor, but either way I have a feeling I may score low on the day with this one.

Three Point Turn

Another challenge I’ve left until now is the Three Point Turn – an autonomous challenge that requires clever use of sensors…or just good timing which is what I’m relying on!

I cracked this one in a day, simply setting up a script with some simple commands to make my robot go forward, left, forward, back, forward, left and then forwards again. I couldn’t include this in my code submission as I didn’t have it ready by then.

Here’s a video of it in action:

And here’s my code:

    def threepoint(): ### PROGRAM 3 ###
    
        Forward(ForwardHighL, ForwardHighR) # MOVE FORWARD FOR THE TIME IN TIME.SLEEP BELOW
        time.sleep(3.5)
        
        Left(SpeedMedium) # SPIN LEFT AT SET SPEED
        time.sleep(0.7)
        
        Forward(ForwardHighL, ForwardHighR) # MOVE FORWARD FOR THE TIME IN TIME.SLEEP BELOW
        time.sleep(0.5)
        
        Reverse(ReverseHighL, ReverseHighR) # REVERSE FOR THE TIME IN TIME.SLEEP BELOW
        time.sleep(1.1)
        
        Forward(ForwardHighL, ForwardHighR) # MOVE FORWARD FOR THE TIME IN TIME.SLEEP BELOW
        time.sleep(0.6)
        
        Left(SpeedMedium) # SPIN LEFT AT SET SPEED
        time.sleep(0.75)
        
        Forward(ForwardHighL, ForwardHighR) # MOVE FORWARD FOR THE TIME IN TIME.SLEEP BELOW
        time.sleep(3.6)
        
        # STOP THE ROBOT
        stop()
        
        # SET SEGMENT BACK TO UNDERSCORE FOR THE MAIN MENU
        bus.write_byte_data(addr, 0x13, 7)
        bus.write_byte_data(addr, 0x12, underscore)
        time.sleep(0.5)
        
        print "Returning to main menu"
        time.sleep(0.5)
        
        # RETURN TO MAIN MENU
        menu()

It really was that simple, and just a case of changing the timings over and over until I got it right. It’s a bit of a rough approach and likely to cause me problems on the day due to AverageBot’s constantly changing left/right bias, meaning it’ll probably veer off track and set a school on fire!

Three point turn test track

My test track for the three point turn competition

I’ll be looking to find a bit of hardboard from now until the competition, to test it out on the same surface that will be used on the day.

Robot manual

From microwaves to hand-held hoovers, all good electronic devices should come with a manual – and AverageBot wants a piece of that written action!

Now whilst I’m not making formal documentation for my robot, I decided it would be useful to have a page for each function and attachment to help me during the competition. I can imagine it’s pretty hectic on the day running between challenges and the ‘pit’, so a bit of help remembering keyboard commands and wire positions is a good thing.

Robot manual

A ‘Dummies Guide’ to help me on the day

Skittles Attachment

Last week I talked about how I had made an attachment to house a couple of servos, which would eventually have a panel to push the ball in the skittles challenge.

I planned to pop back to MakersCafe to get the main pushing panel laser cut this week, but with a very ill and snotty family I didn’t go to London at all. I did however manage to cut and fit the servo bars that this panel will be attached to – simply 2x 7mm wooden rods from eBay, cut to size and screwed to the servo horns:

Servo bars

My servo bars are ready for the pushing panel, as soon as it’s cut

So for now here’s the design of the panel, and hopefully I’ll be able to share the finished attachment next week.

Servo panel design

I’m looking forward to seeing how my hazard sign turns out with raster engraving

Next Week

Not a lot to do now as we get very close to the competition. Next week I’ll be refining code – getting the speed settings right, commenting and cleaning up my python and generally testing and re-testing each function.

I also have the ‘Big Pusha’ attachment to cut and finish (and test). Lastly there’s my manual/documentation, as well as general preparing and packing for the day – tools, spares, batteries, chargers, controllers and so on.

Until next time…

Be the first to comment on "AverageBot Devblog 7 – Nearing Completion!"

Leave a comment

Your email address will not be published.


*


This website uses cookies. Please visit our privacy policy page for more information. Privacy policy

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close