Add consistent error and info messages, tweak image blurring. Remove penny requirement.

video
Cole Deck 5 years ago
parent 4ca4d0c3cd
commit 4eac873412

Binary file not shown.

@ -10,15 +10,21 @@ pwm = gpio.PWM(13, 100)
pwm.start(13) pwm.start(13)
verbose = True verbose = True
print("Initializing Grbl...") print("[ INFO ] Initializing Grbl...")
ser.write(b'\r\n\r\n') ser.write(b'\r\n\r\n')
time.sleep(2) time.sleep(2)
ser.write(b'$RST=#\n') ser.write(b'$RST=#\n')
time.sleep(1) time.sleep(1)
ser.flushInput() ser.flushInput()
print("[ INFO ] Grbl is ready.")
def goToBin(bin): def goToBin(bin):
print("[ INFO ] Delivering item to bin: " + str(bin))
adjustedBin = math.floor(bin / 2) adjustedBin = math.floor(bin / 2)
if adjustedBin > 11:
print("[ INFO ] All bins full! Using overflow bin.")
bin = 0;
adjustedBin = 0;
distance = adjustedBin * 18 distance = adjustedBin * 18
delay = 0.5 + 0.93 * adjustedBin delay = 0.5 + 0.93 * adjustedBin
command = 'G0 X-' command = 'G0 X-'
@ -26,37 +32,40 @@ def goToBin(bin):
command += '\n' command += '\n'
ser.write(b'$X\n') ser.write(b'$X\n')
time.sleep(1) time.sleep(1)
print(command) print("[ INFO ] Sending command to Grbl: " + command)
ser.write(command.encode('utf-8')) ser.write(command.encode('utf-8'))
# s.write("$C\n") # s.write("$C\n")
while True: while True:
grbl_out = str(ser.readline().strip()) # Wait for grbl response with carriage return grbl_out = str(ser.readline().strip()) # Wait for grbl response with carriage return
print(grbl_out.find('error')) print(grbl_out.find('error'))
if int(grbl_out.find('error')) >= 0 : if int(grbl_out.find('error')) >= 0 :
print("REC:",grbl_out) print("[ EXIT ] Grbl reported an error.")
print(" Grbl reported error!")
quit() quit()
elif int(grbl_out.find('ok')) >= 0 : elif int(grbl_out.find('ok')) >= 0 :
if verbose: print('REC:',grbl_out) if verbose: print('[ INFO ] Grbl message: ',grbl_out)
break break
print("[ INFO ] Waiting for " + str(delay) + " seconds.")
time.sleep(delay) time.sleep(delay)
if bin % 2 == 0: # tilt to left if bin % 2 == 0: # tilt to left
print("[ INFO ] Titling motor to left side.")
pwm.ChangeDutyCycle(5) pwm.ChangeDutyCycle(5)
time.sleep(1) time.sleep(1)
pwm.ChangeDutyCycle(14) pwm.ChangeDutyCycle(14)
else: else:
print("[ INFO ] Titling motor to right side.")
pwm.ChangeDutyCycle(25) pwm.ChangeDutyCycle(25)
time.sleep(1) time.sleep(1)
pwm.ChangeDutyCycle(13) pwm.ChangeDutyCycle(13)
time.sleep(1) time.sleep(1)
print("[ INFO ] Sending command to Grbl: G0 X0")
ser.write(b'G0 X0\n') ser.write(b'G0 X0\n')
while True: while True:
grbl_out = str(ser.readline().strip()) # Wait for grbl response with carriage return grbl_out = str(ser.readline().strip()) # Wait for grbl response with carriage return
if int(grbl_out.find('error')) >= 0 : if int(grbl_out.find('error')) >= 0 :
print("REC:",grbl_out) print("[ EXIT ] Grbl reported an error.")
print(" Grbl reported error!")
quit() quit()
elif int(grbl_out.find('ok')) >= 0 : elif int(grbl_out.find('ok')) >= 0 :
if verbose: print('REC:',grbl_out) if verbose: print('[ INFO ] Grbl message: ',grbl_out)
break break
print("[ INFO ] Waiting for " + str(delay) + " seconds.")
time.sleep(delay) time.sleep(delay)

@ -4,4 +4,4 @@ pixels = neopixel.NeoPixel(board.D18, 24)
def ledOff(): def ledOff():
pixels.fill((0,0,0)) pixels.fill((0,0,0))
def ledOn(): def ledOn():
pixels.fill((50,50,50)) pixels.fill((0,0,0))

@ -98,7 +98,7 @@ def detect(calibration_width, img_file, show, quick):
cv2.waitKey(0) cv2.waitKey(0)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0) gray = cv2.GaussianBlur(gray, (7, 7), 0)
gray = cv2.GaussianBlur(gray, (7, 7), 0)
# perform edge detection, then perform a dilation + erosion to # perform edge detection, then perform a dilation + erosion to
# close gaps in between object edges # close gaps in between object edges
edged = cv2.Canny(gray, 50, 100) 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.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1) edged = cv2.erode(edged, None, iterations=1)
edged = cv2.dilate(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: if show and not quick:
cv2.imshow("Item Sorter", edged) cv2.imshow("Item Sorter", edged)
cv2.waitKey(0) cv2.waitKey(0)
@ -122,6 +124,7 @@ def detect(calibration_width, img_file, show, quick):
num = 0 num = 0
# Calibration loop # Calibration loop
"""
for c in cnts: for c in cnts:
# if the contour is not sufficiently large, ignore it # if the contour is not sufficiently large, ignore it
if cv2.contourArea(c) < 100: 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: # 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 pixelsPerMetric = smaller(dA, dB) / calibration_width
continue continue
"""
#pixelsPerMetric = 25 pixelsPerMetric = 25
orig = image.copy() orig = image.copy()
objtype = "Unknown" objtype = "Unknown"
objname = "" objname = ""
@ -181,42 +184,22 @@ def detect(calibration_width, img_file, show, quick):
num += 1 num += 1
# if the contour is not sufficiently large, ignore it # if the contour is not sufficiently large, ignore it
#pixelsPerMetric = 75 #pixelsPerMetric = 75
if cv2.contourArea(c) < 100 or pixelsPerMetric is None: if cv2.contourArea(c) < 300 or pixelsPerMetric is None:
continue continue
# compute the rotated bounding box of the contour # compute the rotated bounding box of the contour
box = cv2.minAreaRect(c) box = cv2.minAreaRect(c)
box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box) box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
box = np.array(box, dtype="int") 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 # unpack the ordered bounding box, then compute the midpoint
# between the top-left and top-right coordinates, followed by # between the top-left and top-right coordinates, followed by
# the midpoint between bottom-left and bottom-right coordinates # the midpoint between bottom-left and bottom-right coordinates
(tl, tr, br, bl) = box (tl, tr, br, bl) = box
(tltrX, tltrY) = midpoint(tl, tr) (tltrX, tltrY) = midpoint(tl, tr)
(blbrX, blbrY) = midpoint(bl, br) (blbrX, blbrY) = midpoint(bl, br)
# compute the midpoint between the top-left and top-right points, # compute the midpoint between the top-left and top-right points,
# followed by the midpoint between the top-right and bottom-right # followed by the midpoint between the top-right and bottom-right
(tlblX, tlblY) = midpoint(tl, bl) (tlblX, tlblY) = midpoint(tl, bl)
(trbrX, trbrY) = midpoint(tr, br) (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 # compute the Euclidean distance between the midpoints
dA = np.linalg.norm(np.array((tltrX, tltrY, 0)) - dA = np.linalg.norm(np.array((tltrX, tltrY, 0)) -
np.array((blbrX, blbrY, 0))) np.array((blbrX, blbrY, 0)))
@ -255,7 +238,7 @@ def detect(calibration_width, img_file, show, quick):
if circular and itemwr == 0.75: if circular and itemwr == 0.75:
objtype = "Penny" objtype = "Penny"
iteml = 0 iteml = 0
else: """else:
if circular and near(radius * 2 / pixelsPerMetric, 0.4, 0.03): if circular and near(radius * 2 / pixelsPerMetric, 0.4, 0.03):
# Keps nut or spacer # Keps nut or spacer
@ -298,6 +281,7 @@ def detect(calibration_width, img_file, show, quick):
if itemhr == 0.1875 and rectangular: if itemhr == 0.1875 and rectangular:
objtype = "Axle" objtype = "Axle"
iteml = (radius * 2 / pixelsPerMetric + itemw) / 2 iteml = (radius * 2 / pixelsPerMetric + itemw) / 2
"""
rows, cols = orig.shape[:2] rows, cols = orig.shape[:2]
[vx, vy, xx, yy] = cv2.fitLine(c, cv2.DIST_L2, 0, 0.01, 0.01) [vx, vy, xx, yy] = cv2.fitLine(c, cv2.DIST_L2, 0, 0.01, 0.01)
lefty = int((-xx*vy/vx) + yy) lefty = int((-xx*vy/vx) + yy)
@ -337,7 +321,7 @@ def detect(calibration_width, img_file, show, quick):
0.6, (50, 50, 220), 2) 0.6, (50, 50, 220), 2)
output = "" output = ""
objname = objtype; objname = objtype;
"""
if objtype == "Screw" or objtype == "Standoff": if objtype == "Screw" or objtype == "Standoff":
output = str(iteml) + "in" output = str(iteml) + "in"
objname += str(iteml) objname += str(iteml)
@ -345,6 +329,7 @@ def detect(calibration_width, img_file, show, quick):
output = "{:.2f}in".format(iteml) output = "{:.2f}in".format(iteml)
objname += str(itemwr) objname += str(itemwr)
#print(objname) #print(objname)
"""
list.append(objname) list.append(objname)
if circular: if circular:
cv2.putText(orig, output, # print data cv2.putText(orig, output, # print data
@ -385,8 +370,8 @@ def magicSort(contour):
name += ", " + str(abs(int(humoments[i][0]))) name += ", " + str(abs(int(humoments[i][0])))
#magicNumber2 += abs(humoments[i][0]) #magicNumber2 += abs(humoments[i][0])
#magicNumber += humoments[i][0] #magicNumber += humoments[i][0]
print(str(humoments)) #print(str(humoments))
#print(magicNumber) #print(magicNumber)
#name = "Unknown: " + str(int(magicNumber1)) + ", " + str(int(magicNumber2)) #name = "Unknown: " + str(int(magicNumber1)) + ", " + str(int(magicNumber2))
print(name) #print(name)
return name return name

@ -15,13 +15,13 @@ while True:
data = s.recv(1024) data = s.recv(1024)
#control_pixel.ledOn() #control_pixel.ledOn()
if not data: break 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]) selectedBin = sort.sort(str(data)[2:len(str(data))-1])
control_pixel.ledOff() control_pixel.ledOff()
control_motor.goToBin(selectedBin) control_motor.goToBin(selectedBin)
control_pixel.ledOn() control_pixel.ledOn()
s.sendall(b'Continue') s.sendall(b'Continue')
except socket.error: except socket.error:
print("Error Occured.") print("[ EXIT ] Socket connection error.")
break break
s.close() s.close()

@ -30,11 +30,11 @@ def go():
#control_motor.goToBin(selectedBin) #control_motor.goToBin(selectedBin)
def sendString(string): def sendString(string):
print("Found " + string) print("[ INFO ] Item found: " + string)
try: try:
conn.sendall(string.encode('utf-8')) conn.sendall(string.encode('utf-8'))
except socket.error: except socket.error:
print("Error Occured.") print("[ EXIT ] Socket connection error.")
if not video: if not video:
@ -49,22 +49,22 @@ else :
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.setsockopt(s, socket.SOL_SOCKET, socket.SO_REUSEADDR) #s.setsockopt(s, socket.SOL_SOCKET, socket.SO_REUSEADDR)
s.bind((host, port)) s.bind((host, port))
print("waiting for connection") print("[ INFO ] TCP stream initialized. Waiting for client...")
s.listen(1) s.listen(1)
conn, addr = s.accept() conn, addr = s.accept()
print('Connected to', addr) print('[ INFO ] Connected to ', addr)
time.sleep(2) time.sleep(2)
waitForPi = True waitForPi = True
while waitForPi is True: while waitForPi is True:
try: try:
print("waiting for data") print("[ INFO ] Waiting for confirmation message.")
data = conn.recv(1024) data = conn.recv(1024)
if not data: break if not data: break
encoding = 'utf-8' encoding = 'utf-8'
print ("Client: "+str(data)) print ("[ INFO ] Message recieved: "+str(data))
waitForPi = False waitForPi = False
except socket.error: except socket.error:
print("Error Occured.") print("[ EXIT ] Socket connection error.")
break 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 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 # 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() ret = capture.grab()
x+=1 x+=1
if not ret: if not ret:
print('empty frame') print('[ EXIT ] Empty frame received.')
break break
#print('frame') #print('frame')
if x > 1: if x > 1:
@ -84,13 +84,13 @@ else :
items,output = detect.detect(calibration_width, frame, True, True) items,output = detect.detect(calibration_width, frame, True, True)
cv2.imshow('Item Sorter', output) cv2.imshow('Item Sorter', output)
x = 0 x = 0
if "Penny" in items and len(items) > 1: if len(items) > 0:
items.remove("Penny") #items.remove("Penny")
itema = items[0] itema = items[0]
valid = True valid = True
for item in items: for item in items:
if item != itema: if item != itema:
print("Too many items!") print("[ INFO ] More than one object present.")
valid = False valid = False
break break
if valid: if valid:
@ -113,10 +113,12 @@ else :
waitForPi = False 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) 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: except socket.error:
print("Error Occured.") print("[ EXIT ] Socket connection error.")
break break
if cv2.waitKey(1)&0xFF == ord('q'): if cv2.waitKey(1)&0xFF == ord('q'):
print("[ EXIT ] Shutting down.")
s.shutdown(1)
s.close() s.close()
break break

Loading…
Cancel
Save