Add consistent error and info messages, tweak image blurring. Remove penny requirement.
This commit is contained in:
parent
4ca4d0c3cd
commit
4eac873412
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user