Untitled
unknown
python
3 years ago
19 kB
7
Indexable
import cv2
import pyzbar.pyzbar as pyzbar
import math
import RPi.GPIO as GPIO
import time, sys
import pandas as pd
import gspread
from oauth2client.service_account import ServiceAccountCredentials
misstime = 0 ##global variable to check how many times of frame it misses
# set of items that can be bought
# items = {"Apple-1", "Apple-2", "Orange Juice-1", "Lays-1", "Biscuit-1", "Biscuit-2", "Banana-2"}
# set of items that can be bought
# set of items that can be bought
Item_name = ["Juice", "LaysChips", "Biscuit", "Cake", "Maggi", "Bananas", "NoteBook", "Shampoo"]
Price = [20, 20, 20, 15, 10, 30, 50, 170]
items = {Item_name[i]: Price[i] for i in range(len(Item_name))}
# def get_object(barcode):
# # showimg(int(page)+1)
# if page == 1:
# return "salad"
# elif page==2:
# return "starters"
# elif page==3:
# return "maincourse"
# elif page==4:
# return "desserts"
# elif page==5:
# return "desserts"
GPIO.setmode(GPIO.BOARD) # programming the GPIO by BCM pin numbers
# TRIG = 17
# ECHO = 27
m11=16
m12=15
m21=18
m22=22
GPIO.setup(m11,GPIO.OUT)
GPIO.setup(m12,GPIO.OUT)
GPIO.setup(m21,GPIO.OUT)
GPIO.setup(m22,GPIO.OUT)
def stop():
print("stop")
GPIO.output(m11, 0)
GPIO.output(m12, 0)
GPIO.output(m21, 0)
GPIO.output(m22, 0)
def forward():
GPIO.output(m11, 1)
GPIO.output(m12, 0)
GPIO.output(m21, 1)
GPIO.output(m22, 0)
print ("Forward")
def back():
GPIO.output(m11, 0)
GPIO.output(m12, 1)
GPIO.output(m21, 0)
GPIO.output(m22, 1)
print ("back")
def left():
GPIO.output(m11, 0)
GPIO.output(m12, 0)
GPIO.output(m21, 1)
GPIO.output(m22, 0)
print ("left")
def right():
GPIO.output(m11, 1)
GPIO.output(m12, 0)
GPIO.output(m21, 0)
GPIO.output(m22, 0)
print ("right")
def findmin(comp1,comp2,comp3,comp4):
'''find the minimum vale of four variables'''
if comp1 > comp2: ##compare two values first, figure out the larger value
comp5 = comp2
comp7 = 2
else:
comp5 = comp1
comp7 = 1
if comp3 > comp4: ##compare the rest of two values first, figure out the larger value
comp6 = comp4
comp8 = 4
else:
comp6 = comp3
comp8 = 3
if comp5 > comp6: ##compare the larger two values and find the largest
return comp8
else:
return comp7
def change_speed1(d,diff):
k0 = 0.7
print("change speed 1")
if d <= 130: ##move forward at this distance
# GPIO.output(18, GPIO.HIGH)
# GPIO.output(22, GPIO.LOW)
if d <=80:
d=80
if d<90: ##change duty cycle to control robot rotation
k = diff*k0 ##determine duty cycle according to the width and length of detected image
if abs(k)>2.5:
k=1.25*k
elif d<100 and d>=90:
k = 5*diff/6*k0
if abs(k)>2.5:
k=1.25*k
elif d<110 and d>=100:
k = 2*diff/3*k0
if abs(k)>2.5:
k=1.25*k
elif d<120 and d>=110:
k = 5*diff/9*k0
if abs(k)>2.5:
k=1.25*k
else:
k = 5*diff/11*k0
if abs(k)>2.5:
k=1.25*k
prop = 0.2*d+61 - k
elif d >= 130 and d <= 150: ##stop motor at this distance
prop = 100
else:
print("ch1 werk")
GPIO.output(16, GPIO.HIGH)
GPIO.output(15, GPIO.LOW) ##robot move backward at this distance
if d >= 250:
d = 250
prop = 130 - 0.2*d
print(prop)
GPIO.output(16, GPIO.HIGH)
GPIO.output(15, GPIO.LOW)
motor1_speed.ChangeDutyCycle(prop) ##change duty cycle to change speed
GPIO.output(16, GPIO.HIGH)
GPIO.output(15, GPIO.LOW)
#time.sleep(1)
def change_speed2(d,diff):
k0 = 0.7
print("change speed 2")
if d <= 130: ##move forward at this distance
# GPIO.output(18, GPIO.HIGH)
# GPIO.output(22, GPIO.LOW)
if d <=80:
d=80
if d<90: ##change duty cycle to control robot rotation
k = diff*k0 ##determine duty cycle according to the width and length of detected image
if abs(k)>2.5:
k=1.25*k
elif d<100 and d>=90:
k = 5*diff/6*k0
if abs(k)>2.5:
k=1.25*k
elif d<110 and d>=100:
k = 2*diff/3*k0
if abs(k)>2.5:
k=1.25*k
elif d<120 and d>=110:
k = 5*diff/9*k0
if abs(k)>2.5:
k=1.25*k
else:
k = 5*diff/11*k0
if abs(k)>2.5:
k=1.25*k
prop = 0.2*d+61 - k
elif d >= 130 and d <= 150: ##stop motor at this distance
prop = 100
else:
print("ch2 werk")
GPIO.output(18, GPIO.HIGH)
GPIO.output(22, GPIO.LOW) ##robot move backward at this distance
if d >= 250:
d = 250
prop = 130 - 0.2*d
print(prop)
GPIO.output(18, GPIO.HIGH)
GPIO.output(22, GPIO.LOW)
motor2_speed.ChangeDutyCycle(prop) ##change duty cycle to change speed
GPIO.output(18, GPIO.HIGH)
GPIO.output(22, GPIO.LOW)
# time.sleep(1)
def avoid_left():
'''when robot need to turn left to avoid obstacle'''
print("avoid left")
motor1_speed.ChangeDutyCycle(100) ##control two motors to turn right 90 degree
GPIO.output(18, GPIO.LOW)
GPIO.output(22, GPIO.HIGH)
motor2_speed.ChangeDutyCycle(75)
time.sleep(2.4)
GPIO.output(18, GPIO.HIGH)
GPIO.output(22, GPIO.LOW)
motor1_speed.ChangeDutyCycle(75)
motor2_speed.ChangeDutyCycle(75)
time.sleep(1)
while True:
time.sleep(0.1)
sensorLowerLeft = obstacle(35,33) ##after turning right, move forward and detect whether it has passed obstacle
print('Lower left distance is : ', sensorLowerLeft)
GPIO.output(18, GPIO.HIGH)
GPIO.output(22, GPIO.LOW)
motor1_speed.ChangeDutyCycle(75)
motor2_speed.ChangeDutyCycle(75)
if sensorLowerLeft > 80: ##after passing obstacle, turn left to back to its original track
print('Break distance is : ', sensorLowerLeft)
break
motor1_speed.ChangeDutyCycle(100) ##control two motors to turn left 90 degree
motor2_speed.ChangeDutyCycle(75)
time.sleep(0.5)
def avoid_right():
'''when robot need to turn right to avoid obstacle'''
print("avoid right")
motor2_speed.ChangeDutyCycle(100) ##control two motors to turn left 90 degree
GPIO.output(16, GPIO.HIGH)
GPIO.output(15, GPIO.LOW)
motor1_speed.ChangeDutyCycle(75)
time.sleep(2.4)
GPIO.output(16, GPIO.LOW)
GPIO.output(15, GPIO.HIGH)
motor1_speed.ChangeDutyCycle(75)
motor2_speed.ChangeDutyCycle(75)
time.sleep(1)
while True:
time.sleep(0.1)
sensorLowerRight = obstacle(36,38) ##after turning left, move forward and detect whether it has passed obstacle
print('Lower right distance is : ', sensorLowerRight)
GPIO.output(16, GPIO.LOW)
GPIO.output(15, GPIO.HIGH)
motor1_speed.ChangeDutyCycle(75)
motor2_speed.ChangeDutyCycle(75)
if sensorLowerRight > 80: ##after passing obstacle, turn right to back to its original track
print('Break distance is : ', sensorLowerRight)
break
motor2_speed.ChangeDutyCycle(100) ##control two motors to turn right 90 degree
motor1_speed.ChangeDutyCycle(75)
time.sleep(0.5)
def getlen(po1,po2):
'''find distance between two points'''
xlen = po1.x - po2.x
ylen = po1.y - po2.y
plen = math.sqrt(xlen**2+ylen**2)
return plen
def obstacle(TRIG, ECHO):
print("obstacle")
i=0
avgDistance=0
for i in range(5):
GPIO.output(TRIG, False) #Set TRIG as LOW
time.sleep(0.001) #Delay
GPIO.output(TRIG, True) #Set TRIG as HIGH
time.sleep(0.00001) #Delay of 0.00001 seconds
GPIO.output(TRIG, False) #Set TRIG as LOW
while GPIO.input(ECHO)==0:
pass #Check whether the ECHO is LOW
pulse_start = time.time()
while GPIO.input(ECHO)==1: #Check whether the ECHO is HIGH
pass
pulse_end = time.time()
pulse_duration = pulse_end - pulse_start #time to get back the pulse to sensor
distance = pulse_duration * 17150 #Multiply pulse duration by 17150 (34300/2) to get distance
distance = round(distance,2) #Round to two decimal points
avgDistance=avgDistance+distance
avgDistance=avgDistance/5 ##average the distance value and return the value
return avgDistance
def decodeDisplay(image, orders):
global misstime
barcodes = pyzbar.decode(image)
flag = 0
for barcode in barcodes: ##process every capture of frame of camera
misstime = 0
flag = 1
barcodeData = barcode.data.decode("utf-8")
print("barcodedata")
barcodeType = barcode.type
if barcodeData == 'avni.mittal2002@gmail.com': ##check if the information of QRcode mathces
(p1,p2,p3,p4) = barcode.polygon ##get four points from image
(x, y, w, h) = barcode.rect
print("Before obstacle")
sensor_back_left = obstacle(31,29) ##get distance from two front ultrasonic sensors
sensor_back_right = obstacle(40,37)
print("sensorRight Distance: {} sensorLeft Distance:{}".format(sensor_back_right, sensor_back_left))
## for rotation
p_ref = Point(x,y)
p1x = getlen(p1,p_ref)
p2x = getlen(p2,p_ref)
p3x = getlen(p3,p_ref)
p4x = getlen(p4,p_ref)
p_min = findmin(p1x, p2x, p3x, p4x) ##find the point that is closest to the reference point
if p_min == 1:
diff = getlen(p1,p2) - getlen(p3,p4) ##find the difference between two vertical lines of the image
distance = (getlen(p1,p2) + getlen(p3,p4))/2 ##find distance between target and camera
elif p_min == 2:
diff = getlen(p2,p3) - getlen(p4,p1)
distance = (getlen(p2,p3) + getlen(p2,p3))/2
elif p_min == 3:
diff = getlen(p3,p4) - getlen(p1,p2)
distance = (getlen(p3,p4) + getlen(p1,p2))/2
else:
diff = getlen(p4,p1) - getlen(p2,p3)
distance = (getlen(p4,p1) + getlen(p2,p3))/2
if sensor_back_right >= 40 and sensor_back_left >= 40: ##check if there is obstacle in front of robot
print("No obstacle")
change_speed1(distance,diff)
change_speed2(distance,diff)
elif sensor_back_left < 40: ##if there is obstacle, change speed and direction accordingly
print("Obstacle on the left")
if distance >= 130:
change_speed1(distance,diff)
change_speed2(distance,diff)
else:
print("Avoid left")
avoid_left()
else:
print("Obstacle on the right")
if distance >= 130:
change_speed1(distance,diff)
change_speed2(distance,diff)
else:
print("Avoid right")
avoid_right()
if barcodeData in Item_name:
if barcodeData not in orders:
orders.add(barcodeData)
data=[]
for i in orders:
data.append([i, items[i]])
df = pd.DataFrame(data, columns=["ItemName", "Price"], index=None)
df.to_csv("data.csv", index=None)
scope = ["https://spreadsheets.google.com/feeds", 'https://www.googleapis.com/auth/spreadsheets',
"https://www.googleapis.com/auth/drive.file", "https://www.googleapis.com/auth/drive"]
credentials = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(credentials)
spreadsheet = client.open('CSV-to-Google-Sheet')
with open('data.csv', 'r') as file_obj:
content = file_obj.read()
client.import_csv(spreadsheet.id, data=content)
if flag == 0:
misstime += 1
## print("[INFO] misstime: {} ".format(misstime))
if misstime > 10:
d1 = 140 ##stop the robot if nothing is detected
# forward()
sensor_left_front = obstacle(31,29) ##get distance from two front ultrasonic sensors
sensor_right_front = obstacle(40,37)
# sensor_back_left = obstacle(35,33) ##get distance from two front ultrasonic sensors
# sensor_back_right = obstacle(36,38)
avgDistance = (sensor_left_front+sensor_right_front)/2
flag=0
if avgDistance < 15: #Check whether the distance is within 15 cm range
count=count+1
stop()
time.sleep(1)
back()
time.sleep(1.5)
if (count%3 ==1) & (flag==0):
right()
flag=1
else:
left()
flag=0
time.sleep(1.5)
stop()
time.sleep(1)
else:
forward()
flag=0
# change_speed1(d1,0)
# change_speed2(d1,0)
# print("Before obstacle")
# sensor_left_front = obstacle(31,29) ##get distance from two front ultrasonic sensors
# sensor_right_front = obstacle(40,37)
# # print("sensorRight Distance: {} sensorLeft Distance:{}".format(sensor_right_front, sensor_left_front))
# sensor_back_left = obstacle(35,33) ##get distance from two front ultrasonic sensors
# sensor_back_right = obstacle(36,38)
# if obstacle on right
# ## for rotation
# if sensor_back_right >= 40 and sensor_back_left >= 40: ##check if there is obstacle in front of robot
# print("No obstacle")
# change_speed1(min(sensor_back_right, sensor_back_left),0)
# change_speed2(min(sensor_back_right, sensor_back_left),0)
# elif sensor_back_left < 40: ##if there is obstacle, change speed and direction accordingly
# print("Obstacle on the left")
# print("Avoid left")
# avoid_left()
# else:
# print("Obstacle on the right")
# print("Avoid right")
# avoid_right()
# if sensor_right_front >= 30 and sensor_left_front >= 30: ##check if there is obstacle in front of robot
# print("No obstacle")
# change_speed1(min(sensor_right_front, sensor_left_front),0)
# change_speed2(min(sensor_right_front, sensor_left_front),0)
# elif sensor_left_front < 30: ##if there is obstacle, change speed and direction accordingly
# print("Obstacle on the left")
# print("Avoid left")
# avoid_left()
# else:
# print("Obstacle on the right")
# print("Avoid right")
# avoid_right()
# ## return image
def detect():
camera = cv2.VideoCapture(-1) ##initialize camera
camera.set(cv2.CAP_PROP_FRAME_WIDTH,640)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT,400)
# items that are bought by the user
orders = set()
print("working")
while True:
ret, frame = camera.read() ##read from camera
if ret == True:
c = cv2.waitKey(5)
cv2.imshow('video',frame)
if c == 27: ##press 'esc' to exit program
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
decodeDisplay(gray,orders) ##image processing
## print("[INFO] c: {} ".format( c ))
## cv2.imshow("camera", im)
else:
break
camera.release()
cv2.destroyAllWindows() ##finish program and close windows
GPIO.cleanup()
class Point():
'''create an object class of the Point of the detected figure'''
def __init__(self,xParam,yParam):
self.x=xParam
self.y=yParam
if __name__ == '__main__':
GPIO.setmode(GPIO.BOARD)
GPIO.setup(40,GPIO.OUT) ##right ultrasonic sensor
GPIO.setup(37,GPIO.IN)
GPIO.cleanup() ##clear all GPIO pins before running program
GPIO.setmode(GPIO.BOARD)
GPIO.setup(40,GPIO.OUT) ##right ultrasonic sensor
GPIO.setup(37,GPIO.IN)
GPIO.setup(31,GPIO.OUT) ##left ultrasonic sensor
GPIO.setup(29,GPIO.IN)
GPIO.setup(35,GPIO.OUT) ##lower left ultrasonic sensor
GPIO.setup(33,GPIO.IN)
GPIO.setup(36,GPIO.OUT) ##lower right ultrasonic sensor
GPIO.setup(38,GPIO.IN)
# 12,13 --> speed control
# 16,17 -> motor left-> 12 en
# 18,19 -> motor left-> 13 en
GPIO.setup(12,GPIO.OUT) ##12-16, motor on the left
GPIO.setup(32,GPIO.OUT) ##13-18, motor on the right
GPIO.setup(16,GPIO.OUT) # in1
GPIO.setup(15,GPIO.OUT) # in2
GPIO.setup(18,GPIO.OUT) #in3
GPIO.setup(22,GPIO.OUT) #in4
# intializing parameters
GPIO.output(16, GPIO.LOW)
GPIO.output(15, GPIO.LOW)
GPIO.output(18, GPIO.LOW)
GPIO.output(22, GPIO.LOW)
motor1_speed = GPIO.PWM(12, 1000) #en1
motor2_speed = GPIO.PWM(32, 1000) #en2
motor1_speed.start(100)
motor2_speed.start(100)
print("Setup ok")
detect()
Editor is loading...