基于深度学习的自动避障小车_5_运动控制2_socket

Introduction

本文简要说明了建立socket连接的python代码,梳理了项目结构

raspberrypi基于深度学习的自动避障智能小车_目录

1. 建立socket server

auto_car(小车端)里,

server = TCPServer(('', 8001), ResponseHandler)
server.serve_forever()

即可建立一个TCPServer。绑定了8001端口,对于连接的响应由ResponseHandler类完成,每监听到一个连接请求,就会新建一个实例来接收。

2. ResponseHandler 类


class ResponseHandler(BaseRequestHandler):
    global my_car

    def handle(self):
        empty_limit = 100
        # self.request.settimeout(3)
        while True:
            try:
                # 接收控制指令。与客户端约定好mapping
                operation = self.request.recv(block_size).strip()
                if operation.decode('utf8') == '':
                    empty_limit -= 1
                    if empty_limit <= 0:
                        break
                    continue
                print("limt ", empty_limit)
                opers = filter(None, operation.decode('utf8').split("_"))
                for oper in opers:
                    if oper == 'start':
                        pass
                    elif oper == 'snapshot':
                        cam.check()
                        send_size = 0
                        file_size = os.path.getsize('/home/pi/motion/lastsnap.jpg')
                        print(file_size)
                        self.request.sendall(bytes(str(file_size), 'utf8'))
                        with open('/home/pi/motion/lastsnap.jpg', 'rb')as fin:
                            r = fin.read(block_size)
                            while r:
                                self.request.send(r)
                                r = fin.read(block_size)
                    elif oper:
                        my_car.exec_operation(int(oper))
                    else:
                        pass
            except TimeoutError:
                print("a client quited")
                break

这是个自定义的类,继承于BaseRequestHandleroperation = self.request.recv(block_size).strip()用来接收客户端发送来的数据。

empty的部分,原意是因为客户端socket在退出后,server的响应总是接收空数据,没有处理退出的异常。这里设了个阀值,如果接收到了empty_limit次的空数据,就退出这个响应,但是现在并不能正常工作。等读者给个建议吧。

尔后的opers = filter(None, operation.decode('utf8').split("_"))则是因为socket的send并不是立刻发送的,有个缓冲队列,满了或者定时发送。而如果不加区分的发送数据,数据会黏连在一起,无法分出。因此才有了前一章的formulate_operation函数在发送数据前后加_,server端则split出来执行每个指令即可。

主要指令有两个:

  • snapshot: 表示需要拍照,调用cam的check函数,发送http get指令给motion的server来抓拍,然后读取图片内容。先发送图片大小回去,然后分段发送回图片数据。
  • 其他控制码: 直行、转弯,直接交给小车执行即可。

3. socket客户端

小车(socket server)发送给web_server( socket client )的只有图片数据,在web_server项目的entry.py里,包含的ControlSocket客户端类里get_pic函数则是先发送抓拍请求,然后接收图片数据。


class ControlSocket:
    def __init__(self, socket_ip):
        """"""
        self.socket = socket(AF_INET, SOCK_STREAM)
        self.socket.connect((socket_ip, 8001))
        self.socket.sendall(bytes('_start_', "utf-8"))
        self.block_size = 2048

    def get_pic(self, file_name):
        """从socket接收到文件,并写入本地文件"""
        sleep(0.5)
        self.socket.sendall(bytes(formulate_operation('snapshot'), 'utf8'))
        file_size = int(self.socket.recv(self.block_size))
        recv_data_size = 0
        data = b''
        with open(file_name, 'wb') as fout:
            while recv_data_size < file_size:
                data = self.socket.recv(self.block_size)
                fout.write(data)
                recv_data_size += len(data)
                # print(recv_data_size)
    # 其他代码略去

sleep是因为如果之前在运行,那么直接抓拍的话,图像会非常模糊,sleep一下等小车停止运动。

这里还有个问题是关于接收图片不完全的问题,参考之前写的文章:

Python Socket传输文件不完整

Reference

python cookbook 创建TCP服务器

路漫漫其修远兮,吾将上下而求索

文章若未注明转载皆为原创,如需转载请注明出处FindHao博客及文章链接,文章markdown格式源码现已开放,欢迎转载。文章源码地址:

分享到:

You may like..(由于采用了谷歌的推荐系统,需要对本站关闭广告过滤~)

Find

新浪微博(FindSpace博客)QQ群:不安分的Coder(375670127) 不安分的Coder

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*