Add consistent error and info messages, tweak image blurring. Remove penny requirement.
This commit is contained in:
		
										
											Binary file not shown.
										
									
								
							@@ -10,15 +10,21 @@ pwm = gpio.PWM(13, 100)
 | 
			
		||||
pwm.start(13)
 | 
			
		||||
verbose = True
 | 
			
		||||
 | 
			
		||||
print("Initializing Grbl...")
 | 
			
		||||
print("[ INFO ] Initializing Grbl...")
 | 
			
		||||
ser.write(b'\r\n\r\n')
 | 
			
		||||
time.sleep(2)
 | 
			
		||||
ser.write(b'$RST=#\n')
 | 
			
		||||
time.sleep(1)
 | 
			
		||||
ser.flushInput()
 | 
			
		||||
print("[ INFO ] Grbl is ready.")
 | 
			
		||||
 | 
			
		||||
def goToBin(bin):
 | 
			
		||||
    print("[ INFO ] Delivering item to bin: " + str(bin))
 | 
			
		||||
    adjustedBin = math.floor(bin / 2)
 | 
			
		||||
    if adjustedBin > 11:
 | 
			
		||||
        print("[ INFO ] All bins full! Using overflow bin.")
 | 
			
		||||
        bin = 0;
 | 
			
		||||
        adjustedBin = 0;
 | 
			
		||||
    distance = adjustedBin * 18
 | 
			
		||||
    delay = 0.5 + 0.93 * adjustedBin
 | 
			
		||||
    command = 'G0 X-'
 | 
			
		||||
@@ -26,37 +32,40 @@ def goToBin(bin):
 | 
			
		||||
    command += '\n'
 | 
			
		||||
    ser.write(b'$X\n')
 | 
			
		||||
    time.sleep(1)
 | 
			
		||||
    print(command)
 | 
			
		||||
    print("[ INFO ] Sending command to Grbl: " + command)
 | 
			
		||||
    ser.write(command.encode('utf-8'))
 | 
			
		||||
    # s.write("$C\n")
 | 
			
		||||
    while True:
 | 
			
		||||
        grbl_out = str(ser.readline().strip()) # Wait for grbl response with carriage return
 | 
			
		||||
        print(grbl_out.find('error'))
 | 
			
		||||
        if int(grbl_out.find('error')) >= 0 :
 | 
			
		||||
            print("REC:",grbl_out)
 | 
			
		||||
            print("  Grbl reported error!")
 | 
			
		||||
            print("[ EXIT ] Grbl reported an error.")
 | 
			
		||||
            quit()
 | 
			
		||||
        elif int(grbl_out.find('ok')) >= 0 :
 | 
			
		||||
            if verbose: print('REC:',grbl_out)
 | 
			
		||||
            if verbose: print('[ INFO ] Grbl message: ',grbl_out)
 | 
			
		||||
            break
 | 
			
		||||
    print("[ INFO ] Waiting for " + str(delay) + " seconds.")
 | 
			
		||||
    time.sleep(delay)
 | 
			
		||||
    if bin % 2 == 0: # tilt to left
 | 
			
		||||
        print("[ INFO ] Titling motor to left side.")
 | 
			
		||||
        pwm.ChangeDutyCycle(5)
 | 
			
		||||
        time.sleep(1)
 | 
			
		||||
        pwm.ChangeDutyCycle(14)
 | 
			
		||||
    else:
 | 
			
		||||
        print("[ INFO ] Titling motor to right side.")
 | 
			
		||||
        pwm.ChangeDutyCycle(25)
 | 
			
		||||
        time.sleep(1)
 | 
			
		||||
        pwm.ChangeDutyCycle(13)
 | 
			
		||||
    time.sleep(1)
 | 
			
		||||
    print("[ INFO ] Sending command to Grbl: G0 X0")
 | 
			
		||||
    ser.write(b'G0 X0\n')
 | 
			
		||||
    while True:
 | 
			
		||||
        grbl_out = str(ser.readline().strip()) # Wait for grbl response with carriage return
 | 
			
		||||
        if int(grbl_out.find('error')) >= 0 :
 | 
			
		||||
            print("REC:",grbl_out)
 | 
			
		||||
            print("  Grbl reported error!")
 | 
			
		||||
            print("[ EXIT ] Grbl reported an error.")
 | 
			
		||||
            quit()
 | 
			
		||||
        elif int(grbl_out.find('ok')) >= 0 :
 | 
			
		||||
            if verbose: print('REC:',grbl_out)
 | 
			
		||||
            if verbose: print('[ INFO ] Grbl message: ',grbl_out)
 | 
			
		||||
            break
 | 
			
		||||
    print("[ INFO ] Waiting for " + str(delay) + " seconds.")
 | 
			
		||||
    time.sleep(delay)
 | 
			
		||||
@@ -4,4 +4,4 @@ pixels = neopixel.NeoPixel(board.D18, 24)
 | 
			
		||||
def ledOff():
 | 
			
		||||
        pixels.fill((0,0,0))
 | 
			
		||||
def ledOn():
 | 
			
		||||
        pixels.fill((50,50,50))
 | 
			
		||||
        pixels.fill((0,0,0))
 | 
			
		||||
							
								
								
									
										41
									
								
								detect.py
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								detect.py
									
									
									
									
									
								
							@@ -98,7 +98,7 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
        cv2.waitKey(0)
 | 
			
		||||
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 | 
			
		||||
    gray = cv2.GaussianBlur(gray, (7, 7), 0)
 | 
			
		||||
 | 
			
		||||
    gray = cv2.GaussianBlur(gray, (7, 7), 0)
 | 
			
		||||
    # perform edge detection, then perform a dilation + erosion to
 | 
			
		||||
    # close gaps in between object edges
 | 
			
		||||
    edged = cv2.Canny(gray, 50, 100)
 | 
			
		||||
@@ -107,6 +107,8 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
    edged = cv2.dilate(edged, None, iterations=1)
 | 
			
		||||
    edged = cv2.erode(edged, None, iterations=1)
 | 
			
		||||
    edged = cv2.dilate(edged, None, iterations=1)
 | 
			
		||||
    #edged = cv2.erode(edged, None, iterations=1)
 | 
			
		||||
    #edged = cv2.dilate(edged, None, iterations=1)
 | 
			
		||||
    if show and not quick:
 | 
			
		||||
        cv2.imshow("Item Sorter", edged)
 | 
			
		||||
        cv2.waitKey(0)
 | 
			
		||||
@@ -122,6 +124,7 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
    num = 0
 | 
			
		||||
 | 
			
		||||
    # Calibration loop
 | 
			
		||||
    """
 | 
			
		||||
    for c in cnts:
 | 
			
		||||
        # if the contour is not sufficiently large, ignore it
 | 
			
		||||
        if cv2.contourArea(c) < 100:
 | 
			
		||||
@@ -170,8 +173,8 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
            # and near(mean_val[0], 63, 40) is True and near(mean_val[1], 108, 40) is True and near(mean_val[2], 104, 40) is True:
 | 
			
		||||
            pixelsPerMetric = smaller(dA, dB) / calibration_width
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
    #pixelsPerMetric = 25
 | 
			
		||||
            """
 | 
			
		||||
    pixelsPerMetric = 25
 | 
			
		||||
    orig = image.copy()
 | 
			
		||||
    objtype = "Unknown"
 | 
			
		||||
    objname = ""
 | 
			
		||||
@@ -181,42 +184,22 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
        num += 1
 | 
			
		||||
        # if the contour is not sufficiently large, ignore it
 | 
			
		||||
        #pixelsPerMetric = 75
 | 
			
		||||
        if cv2.contourArea(c) < 100 or pixelsPerMetric is None:
 | 
			
		||||
        if cv2.contourArea(c) < 300 or pixelsPerMetric is None:
 | 
			
		||||
            continue
 | 
			
		||||
        # compute the rotated bounding box of the contour
 | 
			
		||||
 | 
			
		||||
        box = cv2.minAreaRect(c)
 | 
			
		||||
        box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
 | 
			
		||||
        box = np.array(box, dtype="int")
 | 
			
		||||
 | 
			
		||||
        # order the points in the contour such that they appear
 | 
			
		||||
        # in top-left, top-right, bottom-right, and bottom-left
 | 
			
		||||
        # order, then draw the outline of the rotated bounding
 | 
			
		||||
        # box
 | 
			
		||||
        #box = perspective.order_points(box)
 | 
			
		||||
 | 
			
		||||
        # loop over the original points and draw them
 | 
			
		||||
        # for (x, y) in box:
 | 
			
		||||
        #cv2.circle(orig, (int(x), int(y)), 5, (0, 0, 255), -1)
 | 
			
		||||
 | 
			
		||||
        # unpack the ordered bounding box, then compute the midpoint
 | 
			
		||||
        # between the top-left and top-right coordinates, followed by
 | 
			
		||||
        # the midpoint between bottom-left and bottom-right coordinates
 | 
			
		||||
        (tl, tr, br, bl) = box
 | 
			
		||||
        (tltrX, tltrY) = midpoint(tl, tr)
 | 
			
		||||
        (blbrX, blbrY) = midpoint(bl, br)
 | 
			
		||||
 | 
			
		||||
        # compute the midpoint between the top-left and top-right points,
 | 
			
		||||
        # followed by the midpoint between the top-right and bottom-right
 | 
			
		||||
        (tlblX, tlblY) = midpoint(tl, bl)
 | 
			
		||||
        (trbrX, trbrY) = midpoint(tr, br)
 | 
			
		||||
        # draw the midpoints on the image
 | 
			
		||||
        #cv2.circle(orig, (int(tltrX), int(tltrY)), 5, (255, 0, 0), -1)
 | 
			
		||||
        #cv2.circle(orig, (int(blbrX), int(blbrY)), 5, (255, 0, 0), -1)
 | 
			
		||||
        #cv2.circle(orig, (int(tlblX), int(tlblY)), 5, (255, 0, 0), -1)
 | 
			
		||||
        #cv2.circle(orig, (int(trbrX), int(trbrY)), 5, (255, 0, 0), -1)
 | 
			
		||||
 | 
			
		||||
        # draw lines between the midpoints
 | 
			
		||||
    # compute the Euclidean distance between the midpoints
 | 
			
		||||
        dA = np.linalg.norm(np.array((tltrX, tltrY, 0)) -
 | 
			
		||||
                            np.array((blbrX, blbrY, 0)))
 | 
			
		||||
@@ -255,7 +238,7 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
        if circular and itemwr == 0.75:
 | 
			
		||||
            objtype = "Penny"
 | 
			
		||||
            iteml = 0
 | 
			
		||||
        else:
 | 
			
		||||
        """else:
 | 
			
		||||
            
 | 
			
		||||
            if circular and near(radius * 2 / pixelsPerMetric, 0.4, 0.03):
 | 
			
		||||
                # Keps nut or spacer
 | 
			
		||||
@@ -298,6 +281,7 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
                if itemhr == 0.1875 and rectangular:
 | 
			
		||||
                    objtype = "Axle"
 | 
			
		||||
                    iteml = (radius * 2 / pixelsPerMetric + itemw) / 2
 | 
			
		||||
                    """
 | 
			
		||||
        rows, cols = orig.shape[:2]
 | 
			
		||||
        [vx, vy, xx, yy] = cv2.fitLine(c, cv2.DIST_L2, 0, 0.01, 0.01)
 | 
			
		||||
        lefty = int((-xx*vy/vx) + yy)
 | 
			
		||||
@@ -337,7 +321,7 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
                        0.6, (50, 50, 220), 2)
 | 
			
		||||
        output = ""
 | 
			
		||||
        objname = objtype;
 | 
			
		||||
        
 | 
			
		||||
        """
 | 
			
		||||
        if objtype == "Screw" or objtype == "Standoff":
 | 
			
		||||
            output = str(iteml) + "in"
 | 
			
		||||
            objname += str(iteml)
 | 
			
		||||
@@ -345,6 +329,7 @@ def detect(calibration_width, img_file, show, quick):
 | 
			
		||||
            output = "{:.2f}in".format(iteml)
 | 
			
		||||
            objname += str(itemwr)
 | 
			
		||||
        #print(objname)
 | 
			
		||||
        """
 | 
			
		||||
        list.append(objname)
 | 
			
		||||
        if circular:
 | 
			
		||||
            cv2.putText(orig, output,  # print data
 | 
			
		||||
@@ -385,8 +370,8 @@ def magicSort(contour):
 | 
			
		||||
            name += ", " + str(abs(int(humoments[i][0])))
 | 
			
		||||
            #magicNumber2 += abs(humoments[i][0])
 | 
			
		||||
        #magicNumber += humoments[i][0]           
 | 
			
		||||
    print(str(humoments))
 | 
			
		||||
    #print(str(humoments))
 | 
			
		||||
    #print(magicNumber)
 | 
			
		||||
    #name = "Unknown: " + str(int(magicNumber1)) + ", " + str(int(magicNumber2))
 | 
			
		||||
    print(name)
 | 
			
		||||
    #print(name)
 | 
			
		||||
    return name
 | 
			
		||||
@@ -15,13 +15,13 @@ while True:
 | 
			
		||||
        data = s.recv(1024)
 | 
			
		||||
        #control_pixel.ledOn()
 | 
			
		||||
        if not data: break
 | 
			
		||||
        print("Found "+str(data))
 | 
			
		||||
        print("[ INFO ] Item name: "+ str(data)[2:len(str(data))-1])
 | 
			
		||||
        selectedBin = sort.sort(str(data)[2:len(str(data))-1])
 | 
			
		||||
        control_pixel.ledOff()
 | 
			
		||||
        control_motor.goToBin(selectedBin)
 | 
			
		||||
        control_pixel.ledOn()
 | 
			
		||||
        s.sendall(b'Continue')
 | 
			
		||||
    except socket.error:
 | 
			
		||||
        print("Error Occured.")
 | 
			
		||||
        print("[ EXIT ] Socket connection error.")
 | 
			
		||||
        break
 | 
			
		||||
s.close()
 | 
			
		||||
@@ -30,11 +30,11 @@ def go():
 | 
			
		||||
                #control_motor.goToBin(selectedBin)
 | 
			
		||||
 | 
			
		||||
def sendString(string):
 | 
			
		||||
    print("Found " + string)
 | 
			
		||||
    print("[ INFO ] Item found: " + string)
 | 
			
		||||
    try:
 | 
			
		||||
        conn.sendall(string.encode('utf-8'))
 | 
			
		||||
    except socket.error:
 | 
			
		||||
        print("Error Occured.")
 | 
			
		||||
        print("[ EXIT ] Socket connection error.")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if not video:
 | 
			
		||||
@@ -49,22 +49,22 @@ else :
 | 
			
		||||
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 | 
			
		||||
    #s.setsockopt(s, socket.SOL_SOCKET, socket.SO_REUSEADDR)
 | 
			
		||||
    s.bind((host, port))
 | 
			
		||||
    print("waiting for connection")
 | 
			
		||||
    print("[ INFO ] TCP stream initialized. Waiting for client...")
 | 
			
		||||
    s.listen(1)
 | 
			
		||||
    conn, addr = s.accept()
 | 
			
		||||
    print('Connected to', addr)
 | 
			
		||||
    print('[ INFO ] Connected to ', addr)
 | 
			
		||||
    time.sleep(2)
 | 
			
		||||
    waitForPi = True
 | 
			
		||||
    while waitForPi is True:
 | 
			
		||||
        try:
 | 
			
		||||
            print("waiting for data")
 | 
			
		||||
            print("[ INFO ] Waiting for confirmation message.")
 | 
			
		||||
            data = conn.recv(1024)
 | 
			
		||||
            if not data: break
 | 
			
		||||
            encoding = 'utf-8'
 | 
			
		||||
            print ("Client: "+str(data))
 | 
			
		||||
            print ("[ INFO ] Message recieved: "+str(data))
 | 
			
		||||
            waitForPi = False
 | 
			
		||||
        except socket.error:
 | 
			
		||||
            print("Error Occured.")
 | 
			
		||||
            print("[ EXIT ] Socket connection error.")
 | 
			
		||||
            break
 | 
			
		||||
    # server command for imx135 camera ./video2stdout | gst-launch-1.0 -v fdsrc ! h264parse !  rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=192.168.43.152 port=5001
 | 
			
		||||
    # server command for udp: ./video2stdout | gst-launch-1.0 -v fdsrc !  h264parse ! rtph264pay config-interval=10 pt=96 ! udpsink host=192.168.43.40 port=9000
 | 
			
		||||
@@ -75,7 +75,7 @@ else :
 | 
			
		||||
        ret = capture.grab()
 | 
			
		||||
        x+=1
 | 
			
		||||
        if not ret:
 | 
			
		||||
            print('empty frame')
 | 
			
		||||
            print('[ EXIT ] Empty frame received.')
 | 
			
		||||
            break
 | 
			
		||||
        #print('frame')
 | 
			
		||||
        if x > 1:
 | 
			
		||||
@@ -84,13 +84,13 @@ else :
 | 
			
		||||
            items,output = detect.detect(calibration_width, frame, True, True)
 | 
			
		||||
            cv2.imshow('Item Sorter', output)
 | 
			
		||||
            x = 0
 | 
			
		||||
            if "Penny" in items and len(items) > 1:
 | 
			
		||||
                items.remove("Penny")
 | 
			
		||||
            if len(items) > 0:
 | 
			
		||||
                #items.remove("Penny")
 | 
			
		||||
                itema = items[0]
 | 
			
		||||
                valid = True
 | 
			
		||||
                for item in items:
 | 
			
		||||
                    if item != itema:
 | 
			
		||||
                        print("Too many items!")
 | 
			
		||||
                        print("[ INFO ] More than one object present.")
 | 
			
		||||
                        valid = False
 | 
			
		||||
                        break
 | 
			
		||||
                if valid:
 | 
			
		||||
@@ -113,10 +113,12 @@ else :
 | 
			
		||||
                                    waitForPi = False
 | 
			
		||||
                                    capture = cv2.VideoCapture('udpsrc port=9000 caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" ! rtph264depay ! avdec_h264 ! videoconvert ! appsink sync=false', cv2.CAP_GSTREAMER)
 | 
			
		||||
                            except socket.error:
 | 
			
		||||
                                print("Error Occured.")
 | 
			
		||||
                                print("[ EXIT ] Socket connection error.")
 | 
			
		||||
                                break
 | 
			
		||||
                        
 | 
			
		||||
        if cv2.waitKey(1)&0xFF == ord('q'):
 | 
			
		||||
            print("[ EXIT ] Shutting down.")
 | 
			
		||||
            s.shutdown(1)
 | 
			
		||||
            s.close()
 | 
			
		||||
            break
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user