ZacharyIgielman
Posts: 101
Joined: Sun Dec 08, 2013 11:27 am
Location: London

Raspberry Pi Line Follower randomly stops working

Fri Jan 17, 2014 4:16 pm

I have built a robot. It follows a black line on a white piece of paper. It sends a live stream of what a pi camera on the robot is seeing to the local network. It sill also stop should an object come within 30cm of it's path.

After writing a tutorial/blog post about it (which is below), I came to taking a video to show it working, when I discovered after a random period of time, it stops working. Sometimes the python program exits, sometimes it continues printing the direction the car should be going (meaning the python program is still running). Sometimes the car stops, sometimes it continues doing whatever it was doing when the program quitted (eg if the program quitted round a bend, it would continues turning, if it quitted on a straight, it would continue straight). I was hoping to show this at the Cambridge Raspberry Jam on 8th Feb but this issue needs to be overcome.

Here is a video of it not working (it stops working at 1:05, this time it continued printing the direction to the command line): http://www.youtube.com/watch?v=22DHk18ivx0

I have noticed it tends to stop working when it is printing right to the command line, just an observation. Could this be the cause?

PLEASE HELP ME FIX THIS PROBLEM!

Below is the blog post that I wrote on how to build it (this should give you all the information you need to help me fix it, if you need any more, just ask!):

Parts:

Raspberry Pi
Polulu robot chassis
2x Micro metal gear-motors
4x AA batteries
5v USB battery pack mobile phone charger
330ohm resistor
470ohm resistor
HR-SC04 sonar module
2x Digital line detectors
Ryanteck's MCB
Varied jumper wires
SD card
Keyboard
USB wifi dongle
Micro USB cable

Estimated bill of materials: £60 incl. Raspberry Pi excl. Screen, internet connection, local wireless network and laptop to program pi and watch video stream

Wiring and circuit:

http://t.co/pEyHpc0E0x

Code:

Code: Select all

#run these commands before this file to start stream:
#mkdir /tmp/stream 2>/dev/null
#nohup raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 500 -th 0:0:0 -t 9999999 &
#LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -w /usr/local/www" &

#import necessary modules
import RPi.GPIO as GPIO, sys, threading, time

#use physical pin numbering
GPIO.setmode(GPIO.BOARD)

#set up digital line detectors as inputs
GPIO.setup(3, GPIO.IN)
GPIO.setup(22, GPIO.IN)

#set up motor control pins for RTK-000-001
#use pwm on inputs so motors don't go too fast
GPIO.setup(11, GPIO.OUT)
p=GPIO.PWM(11, 20)
GPIO.setup(15, GPIO.OUT)
q=GPIO.PWM(15, 20)
GPIO.setup(12, GPIO.OUT)
a=GPIO.PWM(12,20)
GPIO.setup(16, GPIO.OUT)
b=GPIO.PWM(16,20)
#turn off motors
GPIO.output(11, 0)
GPIO.output(15, 0)
GPIO.output(16, 0)
GPIO.output(12, 0)

# Allow module to settle
time.sleep(0.5)

# Define GPIO to use on Pi for sonar
GPIO_TRIGGER = 7
GPIO_ECHO = 8
# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)  	# Echo
# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Allow module to settle
time.sleep(0.5)

#make a global variable to communcate between sonar functiona and main loop
globalstop=0

def sonar():
    	while True:
            		global globalstop
            		global GPIO_TRIGGER
            		global GPIO_ECHO
            		# Send 10us pulse to trigger
            		GPIO.output(GPIO_TRIGGER, True)
            		time.sleep(0.00001)
            		GPIO.output(GPIO_TRIGGER, False)
            		start = time.time()
            		count=time.time()
            		while GPIO.input(GPIO_ECHO)==0 and time.time()-count<0.1:
                    		start = time.time()
            		stop=time.time()
            		while GPIO.input(GPIO_ECHO)==1:
                    		stop = time.time()
            		# Calculate pulse length
            		elapsed = stop-start
            		# Distance pulse travelled in that time is time
            		# multiplied by the speed of sound (cm/s)
            		distance = elapsed * 34000
            		# That was the distance there and back so halve the value
            		distance = distance / 2
            		if distance<20:
                    		globalstop=1
                    		print("Too close")
            		else:
                    		globalstop=0
                    		print("Far")
            		time.sleep(1)

threading.Timer(1, sonar).start()

try:
    	while True:
            		if GPIO.input(3)==1 and GPIO.input(22)==1 or globalstop==1:
                    		b.stop()
                    		GPIO.output(16,0)
                    		a.stop()
                    		GPIO.output(12,0)
                    		p.stop()
                    		q.stop()
                    		GPIO.output(11,0)
                    		GPIO.output(15,0)
                    		print('stop')
            		elif GPIO.input(3)==0 and GPIO.input(22)==0:
                    		p.start(60)
                    		a.stop()
                    		GPIO.output(12, 0)
                    		q.start(60)
                    		b.stop()
                    		GPIO.output(16, 0)
                    		print('straight')
            		elif GPIO.input(3)==1:
                    		q.start(100)
                    		p.stop()
                    		GPIO.output(11,0)
                    		b.stop()
                    		GPIO.output(16,0)
                    		a.start(100)
                    		print('right')
            		elif GPIO.input(22)==1:
                    		q.stop()
                    		GPIO.output(15,0)
                    		p.start(100)
                    		a.stop()
                    		GPIO.output(12,0)
                    		b.start(100)
                    		print('left')
except KeyboardInterrupt:
    	GPIO.cleanup()
    	sys.exit()
How to do a live stream:

I used the instructions on recantha’s and Miguel Grinberg’s blogs to do a live stream.
It uses mjpg_streamer to stream stills from the camera. You basically set up your camera to write single pictures to /tmp in timelapse mode and then mjpg_streamer pseudo-streams from the single image file.

Firstly, set up mjpg_streamer: http://blog.miguelgrinberg.com/post/how ... spberry-pi

Commands to start the stream:

Code: Select all

mkdir /tmp/stream 2>/dev/null
nohup raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 500 -th 0:0:0 -t 9999999 &
LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -w /usr/local/www" &
The first one creates a folder in your temporary storage to store the photo for the stream.
The second one uses raspistill’s time-lapse command to take photos 500 milliseconds apart for 9999999 milliseconds and writes them to the same file (/tmp/stream/pic.jpg) which means every photo overwrites the last. So the photo at /tmp/stream/pic.jpg will always be a photo taken less than half a second ago. The ‘&’ symbol means it runs in the background so we can run the next commands and do other things while it’s running.
The third one starts the mjpeg-streamer streaming the /tmp/stream/pic.jpg file.
After you run these commands (you must’ve installed it before you run them: http://blog.miguelgrinberg.com/post/how ... spberry-pi), you can connect with your web browser and watch the stream live. If you want to watch from within the same Raspberry Pi you can enter http://localhost:8080 in the browser's address bar. If you want to watch from another computer in your network use http://<IP-address>:8080.

Photos:

http://t.co/b8scMKsgqV
http://t.co/Q66n8u9kiE
Don't be mean, I'm only fifteen :D

bantammenace2012
Posts: 122
Joined: Mon May 28, 2012 12:18 pm

Re: Raspberry Pi Line Follower randomly stops working

Fri Jan 17, 2014 4:45 pm

Irrespective of your age what you have already achieved here is fantastic so don't be afraid of showing it at the Cambridge Raspberry Jam. Not only that you have shown that you are grown-up enough to ask for help.
You know it works so start with the simple things first:
1. Does the jiggling of the robot cause any physical connections to become loose ?
2. Does it start to work again when you reboot ? Can you reboot it without touching it? Just the act of physically picking it up to reboot it might get a dodgy connection working again.
2. Does it always stop after the same amount of time ? If so then you might need to look at how the software is running or whether something is overheating/tripping. I can't help you on this I'm afraid.

Keep us all posted as to what you discover.

ZacharyIgielman
Posts: 101
Joined: Sun Dec 08, 2013 11:27 am
Location: London

Re: Raspberry Pi Line Follower randomly stops working

Fri Jan 17, 2014 4:52 pm

bantammenace2012 wrote:Irrespective of your age what you have already achieved here is fantastic so don't be afraid of showing it at the Cambridge Raspberry Jam. Not only that you have shown that you are grown-up enough to ask for help.
You know it works so start with the simple things first:
1. Does the jiggling of the robot cause any physical connections to become loose ?
2. Does it start to work again when you reboot ? Can you reboot it without touching it? Just the act of physically picking it up to reboot it might get a dodgy connection working again.
2. Does it always stop after the same amount of time ? If so then you might need to look at how the software is running or whether something is overheating/tripping. I can't help you on this I'm afraid.

Keep us all posted as to what you discover.
Nothing comes loose. I simply press Control C, run the script again and it works. I don't have to touch it. I have noticed something interesting, the last five times, although the length of time it was working has varied, it has always stopped working when it is printing right (although when I moved the robot after is has stopped, it changes what it is printing appropriately). Should I check that motor/connection for what? Is there something wrong with that code?
Don't be mean, I'm only fifteen :D

bantammenace2012
Posts: 122
Joined: Mon May 28, 2012 12:18 pm

Re: Raspberry Pi Line Follower randomly stops working

Fri Jan 17, 2014 4:57 pm

Apologies I have seen thta you state that it stops after a random time interval.
Perhaps try a bigger/more powerful battery.

ZacharyIgielman
Posts: 101
Joined: Sun Dec 08, 2013 11:27 am
Location: London

Re: Raspberry Pi Line Follower randomly stops working

Fri Jan 17, 2014 5:06 pm

Now it has changed the way it stops working. It doesn't matter whether it's going left or right, the python program simply exits after a random but small number of seconds. The car continues going in whatever direction it was when it quit. Here is a video of that happening a couple of times over: http://www.youtube.com/watch?v=NDDxDVFddIQ

This may be something to do with the fact that I had a live camera stream running this time. It seems like whenever I have a live camera stream running, this happens (script crashes), when I don't (less strain on processor), the other happens (python script continues, car stops moving when right).

Both are solvable by Ctrl+C then the script again, but why is that necessary?
Don't be mean, I'm only fifteen :D

Ravenous
Posts: 1956
Joined: Fri Feb 24, 2012 1:01 pm
Location: UK

Re: Raspberry Pi Line Follower randomly stops working

Fri Jan 17, 2014 5:20 pm

In your "try: ... while True:" loop in the main part of the program, there are IF/ ELIF to do several things. Should there be an ELSE (I don't know the proper Python syntax) to specify something else, safe, that should be done at that point? I am making a wild there should be..

The reason I say this is your robot going straight ahead is the "elif GPIO.input(3)==0 and GPIO.input(22)==0:" line I think.

At the least, you could do an ELSE there at the end and say PRINT('oops') to see how often the code goes that way...

Ravenous
Posts: 1956
Joined: Fri Feb 24, 2012 1:01 pm
Location: UK

Re: Raspberry Pi Line Follower randomly stops working

Fri Jan 17, 2014 5:25 pm

To clarify, the bit I'm talking about above, I think it might be useful to put an ELSE after the last ELIF, just for something to do if none of the other conditions are met. Just to see how often execution goes that way.

Tzarls
Authorised Reseller
Authorised Reseller
Posts: 225
Joined: Tue Feb 26, 2013 6:59 am

Re: Raspberry Pi Line Follower randomly stops working

Fri Jan 17, 2014 6:27 pm

Can you check the status of the globalstop variable when your robot stops? Maybe the sonar is falsely detecting a collision. That doesn´t explain why the program exits, but might provide some clues about what´s going on...

EDIT: Just checked you code more carefully - there shouldn´t be a problem with the sonar thing, but hey, you never now....

patw
Posts: 2
Joined: Sat Mar 02, 2013 4:36 am

Re: Raspberry Pi Line Follower randomly stops working

Sat Jan 18, 2014 1:02 am

Hello,
I think the suggestion to add an else block is a good one for troubleshooting. The biggest hint you have is that you have to hit ctrl-c and restart the program to make it work. That means that the program is still running, which means that it's almost surely stuck in the "while True" loop, or else it would exit. For troubleshooting, I would add a logging statement at the beginning of each of your if/elif blocks to be sure you know which block you are entering. Then, add the else block with a similar log statement to show whether or not you are stuck on getting input. If it turns out that you are hitting the "else", then you can figure out why you are not hitting the other conditions as you would expect, perhaps by logging the values of your inputs.

Disclaimer: I'm pretty new to the PI myself and the suggestions above are general troubleshooting suggestions that may or may not help =)

Good luck!

keithellis
Posts: 142
Joined: Thu Dec 12, 2013 10:39 pm
Location: Suffolk, UK
Contact: Website

Re: Raspberry Pi Line Follower randomly stops working

Tue Jan 21, 2014 5:54 pm

Have you got this working yet. With my limited knowledge I would have controlled the motors slightly differently .

You have setup PWM so to change the speed of the motor you can use

Code: Select all

a.ChangeDutyCycle(dc)
where a is your variable for a, b, q or p
and dc is the duty cycle, 0 for off up to 100 for full speed, you seem to be using a duty cycle of 60.

So to turn a pin off use

Code: Select all

a.ChangeDutyCycle(0)
and to turn a pin on use

Code: Select all

a.ChangeDutyCycle(60)
you can change the 60 to set the speed up to a value of 100.

you also seem to be using p.start(dc) with a mixture of GPIO.output(pin,high/low)

Once you have PWM setup you do not need to use any other command other than a.changeDutyCycle(dc)

Also, try commenting out the sonar part to make sure it follows the line without sonar, if it does then the problem may be in the sonar code.

One final comment, your PWM frequency is very low, to get smooth motor control I would use at least a frequency of 150.

keithellis
Posts: 142
Joined: Thu Dec 12, 2013 10:39 pm
Location: Suffolk, UK
Contact: Website

Re: Raspberry Pi Line Follower randomly stops working

Tue Jan 21, 2014 6:30 pm

Another thought, might cause an issue.

You don't always do

Code: Select all

a.stop()
before you do

Code: Select all

a.start(60)
i.e in your "straight" command you do

Code: Select all

p.start(60)
and then in your "left" command you do

Code: Select all

p.start(100)
It might be causing a problem by starting PWM twice, or many multiple times. I would suggest you define a function stop() and do

Code: Select all

a.ChangeDutyCycle(0)
on all four pins and then call this function before you set any pins to high using changeDutyCycle(60) or (100).

I've got a robot which was working fine until I fried my Pi, it's not following a line, but turns on key commands. You can see my code here:
https://github.com/keithellis74/pi-car/ ... t_LED02.py The only thing I do is bring in the duty cycle over a period of time, this does not work particularly well and will probably get rid of this. So the for loop in my drive_motors() function can be removed.

Return to “Automation, sensing and robotics”