You are on page 1of 7

Appendix A

>
Appendix B
The server-daemon software is Copyright © 2008 Ian Daniher
<itdaniher@gmail.com>, and may be used under the terms of the
MIT License <http://www.opensource.org/licenses/mit-license.php>.
Source code for the daemon is unavailable at this time.

All of the control client code that follows is Copyright © 2009


Luke Faraone <luke@faraone.cc> unless otherwise noted.

This program is free software; you can redistribute it and/or


modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,


but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
<http://gnu.org/licenses/gpl.html> for more details

backend.py
#!/usr/bin/env python
'''iMS backend'''
import serial as pys
from time import sleep

def average(seq):
return reduce(lambda x, y: x+y, seq)/len(seq)

class RobotError(Exception):
"""An error occured in the command"""
def __init_(self, value):
self.value = value
def __str__(self):
return repr(self.value)

class RobotSerialError(RobotError):
"""An error occured in the processing of the serial
connection"""
def __init_(self, value):
self.value = value
def __str__(self):
return repr(self.value)

class IduRobot:
'''A robot to control the idu* hardware'''
status = "Status not initalized"
# Env Variables
SPEED = 1/7.0 # in m/s
FWD = 80
BACK = 100
BASE = 90
UNIT = SPEED

# Measure these
RTIME = 0
LTIME = 0
TSPEED = 0

def __init__ (self, port='/dev/ttyUSB0'):


'''Initialize the class'''
# Opens a serial connection to comm. with the idu*
self.serial = pys.Serial(port, 38400, timeout=5) #timeout
is 5sec for inital read
if self.serial.readline() == "Ready: ":
self.serial.timeout = 0 # we don't want to block on
future reads
return True
else:
RobotSerialError("Unable to open a connection to the
board")

def set_servo(self, left, right):


'''Set the servo to a position'''
self.serial.write(str(right)+"r"+str(left)+"l")

def read_ir(self):
'''Get data from the infrared sensor'''
self.serial.flushInput()
self.serial.write("a")
x = 50 # try five times to get data
while x:
a = self.serial.readline()
try:
if a[1] == "1": # don't return bad data
return a
except IndexError:
print "[DEBUG]: Bad line rcv'd during read: " + a
x = x - 1 # stop an infinite loop
raise RobotSerialError("IR read did not return valid
data")

def stop(self):
self.set_servo(self.BASE, self.BASE)

def go(self, seconds):


# Correction I
self.set_servo(97, 90)
self.stop(); sleep(.5)

# main job
self.set_servo(100, 82); sleep(seconds); self.stop()

# Correction II
self.set_servo(90,86); self.stop()

def go_for(self, units): # TODO threading


# We divide by wheel size to get the number of rotations
secs = self.units / self.SPEED
#if not cm % SPEED:
# print "Distance is not divisable by the wheel size,
distance has" +
# "been rounded down to the nearest rotation."
if self.units < 0:
self.units = -self.units
self.set_servo(BACK, FWD)
else:
self.set_servo(FWD, BACK)
sleep(secs)
self.stop()

def turn(self):
self.set_servo(95,95)
sleep(1.004)
self.stop()

cliff.py
#!/usr/bin/env python
# Copyright (C) 2009 Luke Faraone <luke(at)faraone(dot)cc>

import sys
from time import sleep
import time
import backend # import our custom backend module

def average(seq):
return reduce(lambda x, y: x+y, seq)/len(seq)

def figure_time(mins):
"""Return the time in seconds after the number of minutes
passed"""
return time.time() + ( mins * 60)

def time_up(term):
if term < time.time():
return True
return False

def wheel_corr(r):
# correct for starting wheel error
r.set_servo(97, 90)
r.stop(); sleep(.5)

def start_going(r):
# go at a nice, steady clip
r.set_servo(100, 82);

def stop_going(r):
r.set_servo(97, 90)
r.stop(); sleep(.5)

def wall_check(r):
cont = True
while cont:
a = 2
b = []
while a:
st = r.read_ir()
b.append(int(st[3:]))
a -= 1
print average(b)
if average(b) > 5: # here we set the threashold
print "woot"
cont = False

def tread_carefully(r):
wheel_corr(r)
start_going(r)
wall_check(r)
stop_going(r)

def back_away(r):
r.turn()
sleep(.25)
r.turn()

def main(*args):
try:
# Ask how long to let this run, more or less
while True:
print "How long should the robot run? [2]"
inp = raw_input()
if inp == "":
mins = 1
break
try:
mins = int(inp)
except ValueError:
print "Invalid number."
else:
break

endtime = figure_time(mins)

# Give the user a few seconds to get prepped


print "Waiting for user to be ready... (3 seconds till
start)"
sleep(3)

# Create an instance of the robot, "r" on a spesific port


myRobot = backend.IduRobot(port='/dev/ttyUSB0')

# Go off into the main loop:


# pass the robot object along to the walk method, and
continue in a loop
while time_up(endtime) is False:
tread_carefully(myRobot)
back_away(myRobot) # once the above executes we _know_
we need to back up
print "We're all done here."
# Handle problems below
except KeyboardInterrupt: # Clean up and exit if the user
tries to quit with ctrl-c
print "Keyboard Interrupt, stopping the robot and exiting.
Repeat to quit now."
myRobot.stop(); myRobot.stop(); myRobot.stop() # Repeat
for good measure, make sure it got through
myRobot.serial.close() # Close up shop
return 130 # tell bash what happened and exit

except backend.RobotSerialError:
print "An error occured communicating with the robot,
please try again"
myRobot.stop(); myRobot.stop(); myRobot.stop() # Repeat
for good measure, make sure it got through
myRobot.serial.close() # Close up shop
return 2
else:
return 0 # exit errorlessly
finally:
myRobot.stop(); myRobot.stop(); myRobot.stop() # Repeat
for good measure, make sure it got through
myRobot.serial.close() # Close up shop

if __name__ == '__main__':
sys.exit(main(*sys.argv))

You might also like