Browse Source

Signed-off-by: Caner <5658514@qq.com>

Caner 4 years ago
parent
commit
90961f52d8
7 changed files with 445 additions and 0 deletions
  1. 79 0
      Contrl.client/control.py
  2. 27 0
      Contrl.client/main.py
  3. 63 0
      Contrl.client/video.py
  4. 104 0
      Pi.service/controlServer.py
  5. 94 0
      Pi.service/main.py
  6. 46 0
      Pi.service/videoServer.py
  7. 32 0
      test.py

+ 79 - 0
Contrl.client/control.py

@@ -0,0 +1,79 @@
+import time
+import threading
+import math
+from socket import *
+# pip3 install smbus ->PCF8591芯片
+import smbus
+
+
+class ControlServer(threading.Thread):
+    def __init__(self, ADDR):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        # 连接socket
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.sock.connect_ex(ADDR)
+
+        # 初始化smbus  1表示scl.1  0表示scl.0
+        self.BUS = smbus.SMBus(1)
+        # 寄存器地址
+        self.ADR = 0x48
+        # 电位器地址->对应模块in1,in2
+        self.P1 = 0x41
+        self.P2 = 0x42
+        self.P3 = 0x43
+        self.P4 = 0x44
+        # 方向值
+        self.CENTER = 0
+        # 最终方向
+        self.CON = 'Center'
+        # 方向误差
+        self.VD = 10
+
+    def __del__(self):
+        self.sock.close()
+        pass
+
+    def run(self):
+        # 数模初始值
+        self.BUS.write_byte(self.ADR, self.P1)
+        self.CENTER = self.BUS.read_byte(self.ADR)
+        while True:
+            data = self.Orientation()
+            self.sock.sendall(data)
+            time.sleep(0.03)
+
+    # 电压值误差根据实际情况调整
+    def Residual(self, v):
+        # 中间值
+        vs = self.CENTER
+        # 误差值
+        vd = self.VD
+        if math.fabs(v - vs) > vd:
+            return v
+        elif math.fabs(v - vs) < vd:
+            return vs
+        else:
+            return vs
+
+    # 区分方向
+    def Orientation(self):
+        self.BUS.write_byte(self.ADR, self.P1)
+        v0 = self.BUS.read_byte(self.ADR)
+        time.sleep(0.02)
+        self.BUS.write_byte(self.ADR, self.P2)
+        v1 = self.BUS.read_byte(self.ADR)
+        time.sleep(0.02)
+        self.BUS.write_byte(self.ADR, self.P3)
+        v2 = self.BUS.read_byte(self.ADR)
+        time.sleep(0.02)
+        self.BUS.write_byte(self.ADR, self.P4)
+        v3 = self.BUS.read_byte(self.ADR)
+
+        # 接入socket 发送数据
+        # db = '{"type":"conctrl","data":{"v0":%s,"v1":%s,"v2":"%s","v3":"%s"}}' % (
+        #     v0, v1, v2, v3)
+        db = '{"type":"conctrl","data":[{"name":"MOTOR","value":[%s,%s]},{"name":"SERVO","value":[%s,%s]}]}' % (
+            v0, v1, v2, v3)
+        data = str.encode(db)
+        return data

+ 27 - 0
Contrl.client/main.py

@@ -0,0 +1,27 @@
+import time
+import sys
+# from control import ControlServer
+from video import VideoServer
+# 控制服务配置
+HOST = '172.16.102.9'
+PORT = 49800
+ADDR = (HOST, PORT)
+
+# 视频服务配置
+VPORT = 49700
+VADDR = (HOST, VPORT)
+
+if __name__ == '__main__':
+    # # 发送控制信息
+    # ctr = ControlServer(ADDR)
+    # ctr.start()
+    # 接收视频
+    video = VideoServer(VADDR)
+    video.start()
+# not sendd.is_alive() or
+    while True:
+        time.sleep(1)
+        if not video.is_alive():
+            print("Client close")
+            sys.exit(0)
+        pass

+ 63 - 0
Contrl.client/video.py

@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import cv2
+import struct
+import pickle
+import zlib
+
+
+class VideoServer(threading.Thread):
+    def __init__(self, VADDR):
+        threading.Thread.__init__(self)
+        print('video server start')
+        self.setDaemon(True)
+        self.ADDR = VADDR
+        self.sock = socket(AF_INET, SOCK_STREAM)
+
+    def __del__(self):
+        self.sock.close()
+        try:
+            cv2.destroyAllWindows()
+        except:
+            pass
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("video client  connected...")
+        data = "".encode("utf-8")
+        payload_size = struct.calcsize("L")
+        cv2.namedWindow('Remote', cv2.WINDOW_NORMAL)
+        while True:
+            try:
+                while len(data) < payload_size:
+                    data += self.sock.recv(81920)
+                packed_size = data[:payload_size]
+                data = data[payload_size:]
+                msg_size = struct.unpack("L", packed_size)[0]
+                while len(data) < msg_size:
+                    data += self.sock.recv(81920)
+                zframe_data = data[:msg_size]
+                data = data[msg_size:]
+                frame_data = zlib.decompress(zframe_data)
+                frame = pickle.loads(frame_data)
+                try:
+                    cv2.imshow('Remote', frame)
+                    key = cv2.waitKey(10)
+                    if key == ord('q'):
+                        print('client exit')
+                        cv2.destroyAllWindows()
+                        self.sock.close()
+
+                except:
+                    print('video server error')
+                    cv2.destroyAllWindows()
+                    self.sock.close()
+            except:
+                self.sock.close()
+                try:
+                    cv2.destroyAllWindows()
+                except:
+                    pass
+                print('server close')
+                break

+ 104 - 0
Pi.service/controlServer.py

@@ -0,0 +1,104 @@
+import threading
+import time
+import json
+import math
+
+
+class ControlServer(threading.Thread):
+    def __init__(self, client, USERLIST, MSLIST, PI):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.client = client
+        self.userList = USERLIST
+        self.mslist = MSLIST
+        self.pi = PI
+
+    def Calibration(self):
+        # 手动动校准
+        speed = 0
+        while True:
+            speed += 1
+            for s in self.mslist:
+                for d in s['pinList']:
+                    if s['name'] == 'MOTOR':
+                        # Set ESC speed via PWM
+                        self.pi.set_servo_pulsewidth(
+                            d, speed * 1000 / 7 + 1000)
+                    else:
+                        self.pi.set_servo_pulsewidth(d, 1500)
+            time.sleep(2)
+            print(speed)
+            if speed > 3:
+                break
+
+    def changePWM(self, params):
+        # 改变占空比
+        try:
+            # 传来的数据格式同配置
+            data = json.loads(params)
+            num = data['data']
+            for j, s in enumerate(self.mslist):
+                for i, d in enumerate(s['pinList']):
+                    if s['name'] == 'MOTOR':
+                        # Set ESC speed via PWM
+                        dd = math.floor(self.ratioPwm(num[j]['value'][i]))
+                        self.pi.set_servo_pulsewidth(
+                            d, round(dd * 1000 / 7 + 1000))
+                        print(dd)
+                    else:
+                        dds = math.floor(self.ratioSPwm(num[j]['value'][i]))
+                        self.pi.set_servo_pulsewidth(d, dds)
+                        print(dds)
+        except:
+            print('参数错误')
+        pass
+
+    def ratioPwm(self, v):
+        # 换算比例:摇杆范围0-256
+        num = 2
+        if v >= 133 and v <= 256:
+            num = math.floor(((2 / 61) * v - (144 / 61)) * 10) / 10
+        elif v >= 0 and v < 123:
+            num = math.floor(((4 / 132 * v) - 2) * 10) / 10
+        else:
+            num = 2
+        return num
+
+    def ratioSPwm(self, v):
+        #  换算比例:摇杆范围0-256
+        num = math.floor((256 / 2000) * 1000) / 1000
+        a = (v / num) + 500
+        if a > 2500:
+            a = 2500
+        return a
+
+    def __del__(self):
+        if self.client in self.userList:
+            self.userList.remove(self.client)
+        self.client.close()
+        if self.pi is not None:
+            self.pi.stop()
+
+    def run(self):
+        while True:
+            try:
+                msg = self.client.recv(1024)
+                if not msg:
+                    self.userList.remove(self.client)
+                    self.client.close()
+                    print('clinet exit1:', len(self.userList))
+                    break
+                self.changePWM(msg)
+                # print('客户信息', msg, time.ctime())
+            except:
+                self.userList.remove(self.client)
+                self.client.close()
+                print('client exit2:', len(self.userList))
+                break
+
+# 校准 ESC
+# ESC_GPIO  =  13
+# pi.set_servo_pulsewidth(ESC_GPIO,  2000 )  # 最大油门。
+# sleep( 2 )
+# pi.set_servo_pulsewidth(ESC_GPIO,  1000 )  # 最小油门。
+# 睡觉( 2 )

+ 94 - 0
Pi.service/main.py

@@ -0,0 +1,94 @@
+from socket import *
+import time
+import subprocess
+# import pigpio
+# from controlServer import ControlServer
+from videoServer import VideoServer
+# 控制服务配置
+HOST = '0.0.0.0'
+PORT = 49800
+ADDR = (HOST, PORT)
+# 电调+舵机配置
+MSLIST = [
+    {
+        "name": 'MOTOR',
+        "pinList": [13, 16]
+    },
+    {
+        "name": 'SERVO',
+        "pinList": [12, 19]
+    },
+]
+# 用户列表配置
+USERLIST = []
+# PI配置
+PI = None
+# 视频服务配置
+VPORT = 49700
+VADDR = (HOST, VPORT)
+FX = 0.5  # 缩放
+SPD = 0.1  # fps=>越小,FPS越高,cpu消耗越大
+
+
+# def Calibration():
+#     # 自动校准
+#     global PI, MSLIST
+#     # 启动pigpiod服务
+#     port = subprocess.check_output(
+#         "ps -ef |grep pigpiod |awk '{print $2}'", shell=True).decode().split('\n')
+#     if '' in port and len(port) <= 3:
+#         subprocess.run('pigpiod', shell=True)
+#     time.sleep(0.5)
+#     PI = pigpio.pi()
+#     print('开始自动校准')
+#     # 校准服务
+#     speed = 0
+#     while True:
+#         speed += 1
+#         for s in MSLIST:
+#             for d in s['pinList']:
+#                 if s['name'] == 'MOTOR':
+#                     # Set ESC speed via PWM
+#                     PI.set_servo_pulsewidth(
+#                         d, speed * 1000 / 7 + 1000)
+#                 else:
+#                     PI.set_servo_pulsewidth(d, 1500)
+#         time.sleep(2)
+#         print(speed)
+#         if speed > 2:
+#             break
+
+
+def loopServer(SOCK):
+    # 服务监听
+    global USERLIST
+    while True:
+        print('Waiting For Contorl Client Connection ...')
+        client, addr = SOCK.accept()  # 会阻塞
+        print('New control User', addr)
+        # 增加线程
+        if client not in USERLIST and len(USERLIST) < 2:
+            USERLIST.append(client)
+            # 接收
+            # contrl = ControlServer(client, USERLIST, MSLIST, PI)
+            # contrl.start()
+        else:
+            # 不允许连接
+            print('不允许连接')
+            client.close()
+
+
+if __name__ == '__main__':
+    # 启动校准服务
+    # Calibration()
+    print('1S后启动视频服务')
+    time.sleep(1)
+    # 视频服务
+    VideoServer(VADDR, SPD, FX).start()
+    print('1S后启动控制服务')
+    time.sleep(1)
+    # 启动socket服务
+    SOCK = socket(AF_INET, SOCK_STREAM)
+    SOCK.bind(ADDR)
+    SOCK.listen(1)
+    loopServer(SOCK)

+ 46 - 0
Pi.service/videoServer.py

@@ -0,0 +1,46 @@
+from socket import *
+import threading
+import time
+import cv2
+import struct
+import pickle
+import zlib
+
+
+class VideoServer(threading.Thread):
+    def __init__(self, ADDR, SPD, FX):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.cap = cv2.VideoCapture(
+            'C:/Users/Caner/Desktop/ichat0.2/Video_Socket/132.mp4')
+        self.spd = SPD
+        self.fx = FX
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.sock.bind(ADDR)
+        self.sock.listen(1)
+        pass
+
+    def __del__(self):
+        self.sock.close()
+        self.cap.release()
+        pass
+
+    def run(self):
+        # 添加用户
+        while True:
+            print('Waiting For Video Client Connection ...')
+            client, addr = self.sock.accept()  # 会阻塞
+            print('New video User ', addr)
+            while self.cap.isOpened():
+                time.sleep(self.spd)
+                res, frame = self.cap.read()
+                if res:
+                    sframe = cv2.resize(frame, (0, 0), fx=self.fx, fy=self.fx)
+                    data = pickle.dumps(sframe)
+                    zdata = zlib.compress(data, zlib.Z_BEST_COMPRESSION)
+                    try:
+                        client.sendall(struct.pack("L", len(zdata)) + zdata)
+                    except:
+                        print('video client exit')
+                        client.close()
+                        break

+ 32 - 0
test.py

@@ -0,0 +1,32 @@
+import pigpio
+import subprocess
+import time
+
+subprocess.run('pigpiod', shell=True)
+pi = pigpio.pi()
+MSLIST = [
+    {
+        "name": 'MOTOR',
+        "pinList": [13, 16]
+    },
+    {
+        "name": 'SERVO',
+        "pinList": [12, 19]
+    },
+]
+# 自动校准
+speed = 0
+while True:
+    speed += 1
+    for s in MSLIST:
+        for d in s['pinList']:
+            if s['name'] == 'MOTOR':
+                # Set ESC speed via PWM
+                pi.set_servo_pulsewidth(
+                    d, speed * 1000 / 7 + 1000)
+            else:
+                pi.set_servo_pulsewidth(d, 1500)
+    time.sleep(2)
+    print(speed)
+    if speed > 3:
+        break