import RPi.GPIO as GPIO import time import threading import lirc # https://github.com/tompreston/python-lirc from l293d import L293D class Robot(): def __init__(self, motor_left_pin1=17, motor_left_pin2=27, motor_right_pin1=23, motor_right_pin2=24, line_follow_pin_left=19, line_follow_pin_right=6 ): GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) # init modules self.motor = L293D(motor_left_pin1, motor_left_pin2, motor_right_pin1, motor_right_pin2) self.line_follow_pin_left = line_follow_pin_left self.line_follow_pin_right = line_follow_pin_right GPIO.setup(self.line_follow_pin_left, GPIO.IN) GPIO.setup(self.line_follow_pin_right, GPIO.IN) def lineFollowModeOn(self): status_left = False status_right = False while True: status_left = bool(GPIO.input(self.line_follow_pin_left)) # False: not on line / sensor too distant from bottom status_right = bool(GPIO.input(self.line_follow_pin_right)) # True: on line if status_left and status_right: # one the line, follow straight on self.motor.forward() elif status_left: # line is on the left, move left (motor right) self.motor.forwardRight() elif status_right: # line is on the right, move right (motor left) self.motor.forwardLeft() else: # have gone astray, search line. first go back some cm self.motor.backward() time.sleep(7.5/self.motor.DIST_PER_SEC) self.motor.stop() # rotate x degrees to search the line degrees_to_search = 45.0 self.motor.forwardRight() s = GPIO.wait_for_edge(self.line_follow_pin_left, GPIO.RISING, timeout=int(1000 * self.motor.SEC_PER_TURN / 360.0 * degrees_to_search)) self.motor.stop() if s is not None: # line found, continue continue else: # nothing found, go back to original position self.motor.backwardRight() time.sleep(self.motor.SEC_PER_TURN / 360.0 * degrees_to_search) # search in other side self.motor.forwardLeft() s = GPIO.wait_for_edge(self.line_follow_pin_right, GPIO.RISING, timeout=int(1000 * self.motor.SEC_PER_TURN / 360.0 * degrees_to_search)) self.motor.stop() if s is not None: # line found, continue continue else: # line could not be found, go back to original position, stop self.motor.backwardLeft() time.sleep(self.motor.SEC_PER_TURN / 360.0 * degrees_to_search) self.motor.stop() break time.sleep(0.001) def IRControl(self): sockid = lirc.init("robot_ir", "lircrc") dist_per_leypress = 30.0 #cm while True: #self.motor.stop() code = lirc.nextcode()[0] print(code) if code == "FORWARD": self.motor.forward() time.sleep(dist_per_leypress / self.motor.DIST_PER_SEC) self.motor.stop() elif code == "LEFT_FORWARD": # 30 degree turn left, then stop self.motor.forwardRight() time.sleep(self.motor.SEC_PER_TURN / 360.0 * 30.0) self.motor.stop() elif code == "RIGHT_FORWARD": # 30 degree turn right, then stop self.motor.forwardLeft() time.sleep(self.motor.SEC_PER_TURN / 360.0 * 30.0) self.motor.stop() elif code == "LEFT": self.motor.forwardRight() time.sleep(self.motor.SEC_PER_TURN / 360.0 * 90.0) self.motor.stop() elif code == "RIGHT": self.motor.forwardLeft() time.sleep(self.motor.SEC_PER_TURN / 360.0 * 90.0) self.motor.stop() elif code == "BACKWARD": self.motor.backward() time.sleep(dist_per_leypress / self.motor.DIST_PER_SEC) self.motor.stop() elif code == "LEFT_BACKWARD": # 30 degree turn left back, then stop self.motor.backwardRight() time.sleep(self.motor.SEC_PER_TURN / 360.0 * 30.0) self.motor.stop() elif code == "RIGHT_BACKWARD": # 30 degree turn right back, then stop self.motor.backwardLeft() time.sleep(self.motor.SEC_PER_TURN / 360.0 * 30.0) self.motor.stop() elif code == "STOP": self.motor.stop() elif code == "LINE_FOLLOW_ON": self.lineFollowModeOn()