Когда я запускаю на клиенте Rasberry Pi 3 B +, получаю ошибку connection.write (stream.read ()) Файл "/usr/lib/python3.5/socket.py", строка 594, вwrite return self._sock.send (b) BrokenPipeError: [Errno 32] Сломанный канал
серверный сайт:
while True:
stream_bytes += self.rfile.read(1024)
first = stream_bytes.find(b'\xff\xd8')
last = stream_bytes.find(b'\xff\xd9')
клиентский сайт:
import io
import socket
import struct
import time
import picamera
# create socket and bind host
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('192.168.1.100', 8000))
connection = client_socket.makefile('wb')
try:
with picamera.PiCamera() as camera:
camera.resolution = (320, 240) # pi camera resolution
camera.framerate = 15 # 15 frames/sec
time.sleep(2) # give 2 secs for camera to initilize
start = time.time()
stream = io.BytesIO()
# send jpeg format video stream
for foo in camera.capture_continuous(stream, 'jpeg', use_video_port = True):
connection.write(struct.pack('<L', stream.tell()))
connection.flush()
stream.seek(0)
connection.write(stream.read())
if time.time() - start > 600:
break
stream.seek(0)
stream.truncate()
connection.write(struct.pack('<L', 0))
finally:
connection.close()
client_socket.close()
Общий код сервера:
import sys
import threading
import socketserver
import numpy as np
import socket
from model import NeuralNetwork
from rc_driver_helper import *
# distance data measured by ultrasonic sensor
sensor_data = None
class SensorDataHandler(socketserver.BaseRequestHandler):
data = " "
def handle(self):
global sensor_data
while self.data:
self.data = self.request.recv(1024)
sensor_data = round(float(self.data), 1)
# print "{} sent:".format(self.client_address[0])
print(sensor_data)
class VideoStreamHandler(socketserver.StreamRequestHandler):
# h1: stop sign, measured manually
# h2: traffic light, measured manually
h1 = 5.5 # cm
h2 = 5.5
# load trained neural network
nn = NeuralNetwork()
nn.load_model("saved_model/nn_model.xml")
obj_detection = ObjectDetection()
rc_car = RCControl("COM11")
# cascade classifiers
stop_cascade = cv2.CascadeClassifier("cascade_xml/stop_sign.xml")
light_cascade = cv2.CascadeClassifier("cascade_xml/traffic_light.xml")
d_to_camera = DistanceToCamera()
# hard coded thresholds for stopping, sensor 30cm, other two 25cm
d_sensor_thresh = 30
d_stop_light_thresh = 25
d_stop_sign = d_stop_light_thresh
d_light = d_stop_light_thresh
stop_start = 0 # start time when stop at the stop sign
stop_finish = 0
stop_time = 0
drive_time_after_stop = 0
def handle(self):
global sensor_data
stream_bytes = b' '
stop_flag = False
stop_sign_active = True
try:
# stream video frames one by one
while True:
stream_bytes += self.rfile.read(1024)
first = stream_bytes.find(b'\xff\xd8')
last = stream_bytes.find(b'\xff\xd9')
if first != -1 and last != -1:
jpg = stream_bytes[first:last + 2]
stream_bytes = stream_bytes[last + 2:]
gray = cv2.imdecode(np.frombuffer(jpg, dtype=np.uint8),cv2.IMREAD_GRAYSCALE)
image = cv2.imdecode(np.frombuffer(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
# lower half of the image
height, width = gray.shape
roi = gray[int(height/2):height, :]
# object detection
v_param1 = self.obj_detection.detect(self.stop_cascade, gray, image)
v_param2 = self.obj_detection.detect(self.light_cascade, gray, image)
# distance measurement
if v_param1 > 0 or v_param2 > 0:
d1 = self.d_to_camera.calculate(v_param1, self.h1, 300, image)
d2 = self.d_to_camera.calculate(v_param2, self.h2, 100, image)
self.d_stop_sign = d1
self.d_light = d2
cv2.imshow('image', image)
# cv2.imshow('mlp_image', roi)
# reshape image
image_array = roi.reshape(1, int(height/2) * width).astype(np.float32)
# neural network makes prediction
prediction = self.nn.predict(image_array)
# stop conditions
if sensor_data and int(sensor_data) < d_sensor_thresh: #
print("Stop, obstacle in front")
self.rc_car.stop()
sensor_data = None
elif 0 < self.d_stop_sign < d_stop_light_thresh and stop_sign_active:
print("Stop sign ahead")
self.rc_car.stop()
# stop for 5 seconds
if stop_flag is False:
self.stop_start = cv2.getTickCount()
stop_flag = True
self.stop_finish = cv2.getTickCount()
self.stop_time = (self.stop_finish - self.stop_start) / cv2.getTickFrequency()
print("Stop time: %.2fs" % self.stop_time)
# 5 seconds later, continue driving
if self.stop_time > 5:
print("Waited for 5 seconds")
stop_flag = False
stop_sign_active = False
elif 0 < self.d_light < d_stop_light_thresh:
# print("Traffic light ahead")
if self.obj_detection.red_light:
print("Red light")
self.rc_car.stop()
elif self.obj_detection.green_light:
print("Green light")
pass
elif self.obj_detection.yellow_light:
print("Yellow light flashing")
pass
self.d_light = d_stop_light_thresh
self.obj_detection.red_light = False
self.obj_detection.green_light = False
self.obj_detection.yellow_light = False
else:
self.rc_car.steer(prediction)
self.stop_start = cv2.getTickCount()
self.d_stop_sign = d_stop_light_thresh
if stop_sign_active is False:
self.drive_time_after_stop = (self.stop_start - self.stop_finish) / cv2.getTickFrequency()
if self.drive_time_after_stop > 5:
stop_sign_active = True
if cv2.waitKey(1) & 0xFF == ord('q'):
print("car stopped")
self.rc_car.stop()
break
finally:
cv2.destroyAllWindows()
sys.exit()
class Server(object):
def __init__(self, host, port1, port2):
self.host = host
self.port1 = port1
self.port2 = port2
def video_stream(self, host, port):
s = socketserver.TCPServer((host, port), VideoStreamHandler)
s.serve_forever()
def sensor_stream(self, host, port):
s = socketserver.TCPServer((host, port), SensorDataHandler)
s.serve_forever()
def start(self):
sensor_thread = threading.Thread(target=self.sensor_stream, args=(self.host,self.port2))
sensor_thread.daemon = True
sensor_thread.start()
self.video_stream(self.host, self.port1)
if __name__ == '__main__':
p1, p2 = 8000, 8002 #first Video stream than ultrasonic
#h = socket.gethostname() #Host is the server IP
h = "192.168.0.107"
ts = Server(h, p1, p2)
ts.start()
rc_driver_helper.py Файл:
import serial
import cv2
import math
class RCControl(object):
def __init__(self, serial_port):
#self.serial_port = serial.Serial(serial_port, 115200, timeout=1)
self.serial_port = serial.Serial('COM11', 9600, timeout=1) # windows
def steer(self, prediction):
if prediction == 2:
self.serial_port.write(chr(1).encode())
print("Forward")
elif prediction == 0:
self.serial_port.write(chr(7).encode())
print("Left")
elif prediction == 1:
self.serial_port.write(chr(6).encode())
print("Right")
else:
self.stop()
def stop(self):
self.serial_port.write(chr(0).encode())
class DistanceToCamera(object):
def __init__(self):
# camera params
self.alpha = 8.0 * math.pi / 180 # degree measured manually
self.v0 = 119.865631204 # from camera matrix
self.ay = 332.262498472 # from camera matrix
def calculate(self, v, h, x_shift, image):
# compute and return the distance from the target point to the camera
d = h / math.tan(self.alpha + math.atan((v - self.v0) / self.ay))
if d > 0:
cv2.putText(image, "%.1fcm" % d,
(image.shape[1] - x_shift, image.shape[0] - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
return d
class ObjectDetection(object):
def __init__(self):
self.red_light = False
self.green_light = False
self.yellow_light = False
def detect(self, cascade_classifier, gray_image, image):
# y camera coordinate of the target point 'P'
v = 0
# minimum value to proceed traffic light state validation
threshold = 150
# detection
cascade_obj = cascade_classifier.detectMultiScale(
gray_image,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30))
# draw a rectangle around the objects
for (x_pos, y_pos, width, height) in cascade_obj:
cv2.rectangle(image, (x_pos + 5, y_pos + 5), (x_pos + width - 5, y_pos + height - 5), (255, 255, 255), 2)
v = y_pos + height - 5
# print(x_pos+5, y_pos+5, x_pos+width-5, y_pos+height-5, width, height)
# stop sign
if width / height == 1:
cv2.putText(image, 'STOP', (x_pos, y_pos - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
# traffic lights
else:
roi = gray_image[y_pos + 10:y_pos + height - 10, x_pos + 10:x_pos + width - 10]
mask = cv2.GaussianBlur(roi, (25, 25), 0)
(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(mask)
# check if light is on
if maxVal - minVal > threshold:
cv2.circle(roi, maxLoc, 5, (255, 0, 0), 2)
# Red light
if 1.0 / 8 * (height - 30) < maxLoc[1] < 4.0 / 8 * (height - 30):
cv2.putText(image, 'Red', (x_pos + 5, y_pos - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
self.red_light = True
# Green light
elif 5.5 / 8 * (height - 30) < maxLoc[1] < height - 30:
cv2.putText(image, 'Green', (x_pos + 5, y_pos - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0),2)
self.green_light = True
# yellow light
# elif 4.0/8*(height-30) < maxLoc[1] < 5.5/8*(height-30):
# cv2.putText(image, 'Yellow', (x_pos+5, y_pos - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)
# self.yellow_light = True
return v
Ошибка клиентского сайта:
connection.write(stream.read())
File "/usr/lib/python3.5/socket.py", line 594, in write
return self._sock.send(b)
BrokenPipeError: [Errno 32] Broken pipe
Ошибка сайта сервера:
runfile('C:/Users/Shafaeit/Desktop/org/computer/rc_driver.py', wdir='C:/Users/Shafaeit/Desktop/org/computer')
runfile('C:/Users/Shafaeit/Desktop/org/computer/rc_driver.py', wdir='C:/Users/Shafaeit/Desktop/org/computer')
192.168.0.103:33876 connected
----------------------------------------
Exception happened during processing of request from ('192.168.0.103', 33876)
Traceback (most recent call last):
File "C:/Users/Shafaeit/Desktop/org/computer/rc_driver.py", line 81, in handle
stream_bytes += self.rfile.read(1024)
AttributeError: 'VideoStreamHandler' object has no attribute 'rfile'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\socketserver.py", line 717, in __init__
self.handle()
File "C:/Users/Shafaeit/Desktop/org/computer/rc_driver.py", line 177, in handle
self.wfile.close()
AttributeError: 'VideoStreamHandler' object has no attribute 'wfile'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\socketserver.py", line 313, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\ProgramData\Anaconda3\lib\socketserver.py", line 344, in process_request
self.finish_request(request, client_address)
File "C:\ProgramData\Anaconda3\lib\socketserver.py", line 357, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\ProgramData\Anaconda3\lib\socketserver.py", line 719, in __init__
self.finish()
File "C:\ProgramData\Anaconda3\lib\socketserver.py", line 774, in finish
if not self.wfile.closed:
AttributeError: 'VideoStreamHandler' object has no attribute 'wfile'
----------------------------------------