Untitled

 avatar
unknown
python
3 years ago
19 kB
3
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...