Browse Source

新版本
Signed-off-by: caner <5658514@qq.com>

caner 3 years ago
parent
commit
028e81cea8
5 changed files with 68 additions and 209 deletions
  1. 49 56
      Pwm.js
  2. 12 3
      README.md
  3. 6 79
      index.js
  4. 0 68
      lib/videoSource.js
  5. 1 3
      package.json

+ 49 - 56
lib/Pwm.js → Pwm.js

@@ -20,12 +20,12 @@ class ContrlService {
             s2: 3
             s2: 3
         }
         }
         // prio init
         // prio init
-        RPIO.init({ mapping: "gpio" });
+        //RPIO.init({ mapping: "gpio" });
         // 继电器解锁
         // 继电器解锁
-        RPIO.open(22, RPIO.OUTPUT, RPIO.HIGH);
-        RPIO.open(23, RPIO.OUTPUT, RPIO.HIGH);
+        //RPIO.open(6, RPIO.OUTPUT, RPIO.HIGH);
+        //RPIO.open(13, RPIO.OUTPUT, RPIO.HIGH);
         // 开灯
         // 开灯
-        RPIO.open(22, RPIO.OUTPUT, RPIO.HIGH);
+        //RPIO.open(19, RPIO.OUTPUT, RPIO.HIGH);
         // init PWM
         // init PWM
         this.PWM = new Pca9685Driver(this.pwmOption, er => {
         this.PWM = new Pca9685Driver(this.pwmOption, er => {
             if (er) {
             if (er) {
@@ -36,45 +36,55 @@ class ContrlService {
         this.Snum = 0
         this.Snum = 0
         // 解锁状态
         // 解锁状态
         this.enable = false
         this.enable = false
+        // 摇杆解锁
+        this.contrlEnable = false
+        // 摇杆中立值110-120
+        this.centerNum = 120
     }
     }
     // 设置pwm
     // 设置pwm
-    async changPWM (params) {
+    async changPWM(params) {
         const { v0, v1, v2, v3 } = params
         const { v0, v1, v2, v3 } = params
         if (typeof (v0) == 'number' || typeof (v3) == 'number') {
         if (typeof (v0) == 'number' || typeof (v3) == 'number') {
+            // 内八解锁
             if (this.enable) {
             if (this.enable) {
-                // 解锁之后需要2秒给电调中立值
-                if (this.Snum >= 50 && this.Snum <= 61) this.Snum++
-                if (this.Snum >= 60) {
-                   if (Math.abs(+v2 - 128) < 20) {
-                        console.log('前后', v3)
-                        this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(Math.abs(+v3 - 256)));
-                        this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(Math.abs(+v3 - 256)));
+                //中位值
+                if (!this.contrlEnable) {
+                    this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(Math.abs(this.centerNum)));
+                    this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(Math.abs(this.centerNum)));
+                }
+                //上推解锁
+                if (!this.contrlEnable && +v3 > 200) this.contrlEnable = true
+                // PWM操作
+                if (this.contrlEnable) {
+                    // 注意中位误差
+                    if (Math.abs(+v2 - this.centerNum) < 20) {
+                        this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(Math.abs(+v3 - 255)));
+                        this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(Math.abs(+v3 - 255)));
                     } else {
                     } else {
-                        // 分左右
-                        if ((+v2 - 128) > 20) {
+                        // 分左右 注意左右误差
+                        if ((+v2 - this.centerNum) > 20) {
                             // 右
                             // 右
-                            console.log('右', +v2);
-                            const a = 128 - (+v2 - 128)
-                            const b = 128 + (+v2 - 128)
+                            const a = this.centerNum - (+v2 - this.centerNum)
+                            const b = this.centerNum + (+v2 - this.centerNum)
                             this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(+a));
                             this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(+a));
                             this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(+b));
                             this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(+b));
-                        } else if (+v2 - 128 < -20) {
+                        } else if (+v2 - this.centerNum < -20) {
                             // 左
                             // 左
-                            console.log('左', +v2);
-                            const a = 128 - (+v2 - 128)
-                            const b = 128 + (+v2 - 128)
+                            const a = this.centerNum - (+v2 - this.centerNum)
+                            const b = this.centerNum + (+v2 - this.centerNum)
                             this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(+a));
                             this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(+a));
                             this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(+b));
                             this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(+b));
                         }
                         }
                     }
                     }
-                    //云台
-                    if (v0 || v1) {
-                        console.log('云台', v0, v1)
-                        const a = +v1 > 200 ? 200 : +v1
-                        this.PWM.setPulseLength(this.MoAndSero.s1, this.Servo2pwm(+v0));
-                        this.PWM.setPulseLength(this.MoAndSero.s2, this.Servo2pwm(+a));
-                    }
+
                 }
                 }
+                //云台
+                if (v0 || v1) {
+                    const a = +v1 > 200 ? 200 : +v1
+                    this.PWM.setPulseLength(this.MoAndSero.s1, this.Servo2pwm(+v0));
+                    this.PWM.setPulseLength(this.MoAndSero.s2, this.Servo2pwm(+a));
+                }
+                console.log('前后', v3, '左右', v2, '云台', v0, v1)
             } else {
             } else {
                 this.unLOCK(v0, v1, v2, v3)
                 this.unLOCK(v0, v1, v2, v3)
             }
             }
@@ -91,8 +101,8 @@ class ContrlService {
      * @param {*} v2 
      * @param {*} v2 
      * @param {*} v3 
      * @param {*} v3 
      */
      */
-    unLOCK (v0, v1, v2, v3) {
-        // 未解锁=>进行解锁:发送端的频率是0.04S,0.05*60 = 3S        
+    unLOCK(v0, v1, v2, v3) {
+        // 未解锁=>进行解锁:发送端的频率是0.05S,0.05*60 = 3S        
         // 内八 :v0<50,v1>200,v2>200,v3<50
         // 内八 :v0<50,v1>200,v2>200,v3<50
         if (+v0 <= 60 && +v1 >= 190 && +v3 >= 190 && +v2 <= 60) {
         if (+v0 <= 60 && +v1 >= 190 && +v3 >= 190 && +v2 <= 60) {
             if (this.Snum >= 0 && this.Snum <= 51) this.Snum++
             if (this.Snum >= 0 && this.Snum <= 51) this.Snum++
@@ -100,48 +110,31 @@ class ContrlService {
             this.Snum = 0
             this.Snum = 0
         }
         }
         if (this.Snum == 50) {
         if (this.Snum == 50) {
-            RPIO.open(23, RPIO.OUTPUT, RPIO.HIGH);
+            // RPIO.open(19, RPIO.OUTPUT, RPIO.HIGH);
             this.enable = true
             this.enable = true
         }
         }
         console.log('解锁中', v0, v1, v2, v3)
         console.log('解锁中', v0, v1, v2, v3)
     }
     }
     /**
     /**
-     * 电调换算比例:摇杆范围0-256,PWM范围500~1500~2500
+     * 电调换算比例:摇杆范围0-255,PWM范围500~1500~2500
      * @param {number} v 
      * @param {number} v 
      * @returns 
      * @returns 
      */
      */
-    Motor2pwm (v) {
-        // 分为6挡位,中值128,步进256/6
-        const num = parseInt(256 / 6)
-        // 方向调换
-        const dirc = Math.abs(v - 256)
-        // 真实值
-        let value = 128
-        // 步进取中间值
-        if (dirc > 0 && dirc < num) {
-            value = num / 2
-        } else if (dirc > num && dirc <= num * 2) {
-            value = num + (num / 2)
-        } else if (dirc > num * 2 && dirc < 128) {
-            value = 128 - (num / 2)
-        } else if (dirc > 128 && dirc <= (128 + num)) {
-            value = 128 + (num / 2)
-        } else if (dirc > (128 + num) && dirc <= (128 + num * 2)) {
-            value = 128 + num + (num / 2)
-        } else if (dirc > (128 + num * 2) && dirc <= 256) {
-            value = 256 - (num / 2)
+    Motor2pwm(v) {
+        if (v === 0) {
+            return parseInt(10 / (256 / 1000)) + 1000
+        } else if (v >= 200) {
+            return parseInt(200 / (256 / 1000)) + 1000
         } else {
         } else {
-            value = 128
+            return parseInt((v - 5) / (256 / 1000)) + 1000
         }
         }
-
-        return parseInt(value / (256 / 2000)) + 500
     }
     }
     /**
     /**
      * 舵机换算比例:摇杆范围0-256,PWM范围1000~1500~2000
      * 舵机换算比例:摇杆范围0-256,PWM范围1000~1500~2000
      * @param {number} v 
      * @param {number} v 
      * @returns 
      * @returns 
      */
      */
-    Servo2pwm (v) {
+    Servo2pwm(v) {
         return parseInt(v / (256 / 1000)) + 1000
         return parseInt(v / (256 / 1000)) + 1000
     }
     }
 }
 }

+ 12 - 3
README.md

@@ -2,14 +2,23 @@
 ```
 ```
 接收遥控信号,传输视频信息
 接收遥控信号,传输视频信息
 ```
 ```
+## TODO
+```
+1. 新版视频方案
+
+```
+
 ## 安装
 ## 安装
 ```
 ```
-1. apt install ffmpeg
-2. sudo npm install 
+1. sudo npm install 
 ```
 ```
 
 
 ## 启动
 ## 启动
 ```
 ```
 1. node index.js
 1. node index.js
 ```
 ```
-
+## 注意
+```
+1. 电调需自行找中位可参考:[sensor] (https://git.caner.top/Caner/sensor)
+2. 注意摇杆间的中位误差
+```

+ 6 - 79
index.js

@@ -1,9 +1,7 @@
 
 
 // wrt + socket + contrl
 // wrt + socket + contrl
 const io = require("socket.io-client")
 const io = require("socket.io-client")
-const RTCVideoSource = require('./lib/videoSource')
-//const PWM = require('./lib/Pwm')
-const { RTCPeerConnection, MediaStream } = require("wrtc")
+const PWM = require('./Pwm')
 const HOST = 'ws://10.10.3.196:7896'
 const HOST = 'ws://10.10.3.196:7896'
 class CarServer {
 class CarServer {
     constructor(HOST) {
     constructor(HOST) {
@@ -17,94 +15,23 @@ class CarServer {
             }
             }
         });
         });
         this.socket.on('connect', () => {
         this.socket.on('connect', () => {
-            this.connect()
+            console.log(`连接成功`)
         })
         })
         this.socket.on('leaved', user => {
         this.socket.on('leaved', user => {
             console.log(`${user.name}离开${user.roomID}房间`)
             console.log(`${user.name}离开${user.roomID}房间`)
-            // 用户离开移除RTC
-            this.destroyed()
         })
         })
         this.socket.on('joined', user => {
         this.socket.on('joined', user => {
             console.log(`${user.name}加入${user.roomID}房间`)
             console.log(`${user.name}加入${user.roomID}房间`)
-            // 发送offer
-            this.createOffer()
         })
         })
         this.socket.on('msg', data => {
         this.socket.on('msg', data => {
             console.log('用户信息', data.type);
             console.log('用户信息', data.type);
-            this.msg(data)
+            if (data.type === 'conctrl') {
+                PWM.changPWM(data.conctrl)
+            }
         })
         })
         this.socket.on('connect_error', err => {
         this.socket.on('connect_error', err => {
             console.log('连接错误', err)
             console.log('连接错误', err)
-            this.destroyed()
-        })
-    }
-    // 连接
-    connect() {
-        console.log('连接成功,开始初始化webrtc')
-        // 初始化rtc
-        this.webRTC = new RTCPeerConnection()
-        // 初始化媒体源
-        this.mediaStream = new MediaStream()
-        this.videoSource = new RTCVideoSource()
-        // 加入媒体源
-        const videoTrack = this.videoSource.createTrack()
-        this.mediaStream.addTrack(videoTrack)
-        this.webRTC.addTrack(videoTrack, this.mediaStream)
-        // 开始媒体
-        this.videoSource.start()
-        // 监听ice
-        this.webRTC.onicecandidate = event => {
-            if (event.candidate) {
-                // 发送ICE
-                this.socket.emit('msg', {
-                    type: 'candidate',
-                    candidate: event.candidate
-                })
-            }
-        }
-        // 监听ice状态
-        this.webRTC.oniceconnectionstatechange = () => {
-            if (this.webRTC.iceConnectionState === 'failed' || this.webRTC.iceConnectionState === 'closed' || this.webRTC.iceConnectionState === "disconnected") {
-                console.log('ICE 连接失败')
-                this.destroyed()
-            }
-        }        
-    }
-    // 用户信息
-    msg(data){
-        if (data.type === 'answer') {
-            // 设置本地应答
-            this.webRTC.setRemoteDescription(data.answer)
-        } else if (data.type === 'candidate') {
-            // 本地设置ICE
-            this.webRTC.addIceCandidate(data.candidate)
-        } else if (data.type === 'conctrl') {
-            // 控制信息
-            //PWM.changPWM(data.conctrl)
-        } else if (data.type === 'startRTC') {
-            // 向其它房间人发送offer
-            this.createOffer()
-        }
-    }
-    // 创建offer
-    async createOffer() {
-        // 创建offer
-        const offer = await this.webRTC.createOffer()
-        this.webRTC.setLocalDescription(offer)
-        // 发送offer
-        this.socket.emit('msg', {
-            type: 'offer',
-            offer: offer
         })
         })
-    }
-
-    destroyed() {
-        if (this.webRTC) this.webRTC.close()
-        if (this.videoSource) this.videoSource.stop()
-        this.webRTC = null
-        this.mediaStream = null
-        this.videoSource = null     
-        process.exit(1) 
-    }    
+    }  
 }
 }
 new CarServer(HOST)
 new CarServer(HOST)

+ 0 - 68
lib/videoSource.js

@@ -1,68 +0,0 @@
-const { RTCVideoSource } = require('wrtc').nonstandard;
-const ffmpeg = require('fluent-ffmpeg')
-
-class VideoSourceService extends RTCVideoSource {
-    constructor() {
-        super() //videosource int
-        this.command = null // 存储视频源
-        this.cache = Buffer.alloc(0)
-    }
-
-    // 创建通道
-    createTrack() {
-        const track = super.createTrack()
-        return track
-    }
-
-
-    // 获取视频源
-    async start() {
-        if (this.command !== null) this.stop()
-        const width = 400, height = 300
-        // libx264编码后花屏
-        this.command = ffmpeg('/dev/video0')
-            .size(`${width}x${height}`)
-            .outputOptions(['-pix_fmt yuv420p'])
-            .format("rawvideo")
-            .on('start', () => {
-                console.log('Video start !');
-            })
-            .on('error', (err) => {
-                console.log('Video processing An error occurred: ' + err.message);
-                // 退出进程
-                process.exit(1)
-            })
-        this.ffstream = this.command.pipe();
-        this.ffstream.on('data', (buffer) => {
-            this.cache = Buffer.concat([this.cache, buffer])
-        });
-
-        // 整理buffer
-        const frameSize = width * height * 1.5;
-        const processData = () => {
-            while (this.cache.length > frameSize) {
-                const buffer = this.cache.slice(0, frameSize)
-                this.cache = this.cache.slice(frameSize)
-                this.onFrame({
-                    width,
-                    height,
-                    data: new Uint8ClampedArray(buffer)
-                })
-            }
-            if (this.command !== null) {
-                setTimeout(() => processData())
-            }
-        }
-        processData()
-    }
-
-    // 停止获取
-    stop() {
-        console.log("Video source stop");
-        if (this.command != null) {
-            this.command.kill("SIGHUP")
-            this.command = null
-        }
-    }
-}
-module.exports = VideoSourceService

+ 1 - 3
package.json

@@ -12,8 +12,6 @@
     "socket.io-client": "^4.4.1",
     "socket.io-client": "^4.4.1",
     "i2c-bus": "^5.2.2",
     "i2c-bus": "^5.2.2",
     "pca9685": "^5.0.0",
     "pca9685": "^5.0.0",
-    "rpio": "^2.4.2",
-    "wrtc": "^0.4.7",
-    "fluent-ffmpeg": "^2.1.2"
+    "rpio": "^2.4.2"
   }
   }
 }
 }