一、服務器
(1)簡單講解
C/S結構實現控制,樹莓派運行服務器,中斷通過訪問網頁實現控制小車,使用UDP通信。其中使用多線程控制小車的自動避障功能,寫的不好的地方請批評指正。
(2)代碼實現
創建server.py
from http.server import BaseHTTPRequestHandler,HTTPServer
import time
import socket
import urllib
from carCtrl import CAR
from camera_control import Camera
from threading import Thread
global loop
global direction
loop =True
class CarServer(BaseHTTPRequestHandler):
carControl = CAR()
cameraControler = Camera()
i=0
def get_host_ip(self):
'''
This method is used for getting local ip address
The car server will deploy on this ip
'''
try:
serverSocket = socket.socket(socket.AF_INET
,socket.SOCK_DGRAM)
serverSocket.connect(("192.168.0.12",80))
localIP = serverSocket.getsockname()[0]
finally:
return localIP
def do_GET(self):
'''
Define the car control GUI for client
For the first deition, it will only return direction control GUI
'''
localIP = CarServer.get_host_ip(self)
#when this GET method is called,then should init the car
self.carControl.reset()
#read control page html file from control.html
controlPageFile = open("control.html")
controlPageGUI = controlPageFile.read()
controlPageFile.close()
controlPageGUI = controlPageGUI.replace(
"requestAddress","http://"+ localIP +":9090/")
controlPageGUI = controlPageGUI.replace(
"cameraAddress","http://"+ localIP +":8080/")
self.send_response(200)
self.send_header("Content-type","text/html")
self.end_headers()
self.wfile.write(controlPageGUI.encode())
def do_POST(self):
length = int(self.headers['Content-Length'])
qs = self.rfile.read(length)
global direction
direction = 'S'
direction = qs.decode()
print(direction)
cameraDirection = ['HR','HL','VU','VD','GL','GF','GR','GU','GD','RESET']
if direction in cameraDirection:
#control camera
self.cameraControler.cameraRotation(direction)
elif direction =="Auto":
if self.i == 0:
thread = Thread(target = self.auto)
self.i = 2
if self.i == 2:
thread.start()
self.i = 1
else:
#control car move
# self.carControl.CarMove(direction)
loop = False
if self.i== 1:
stop_thread(thread)
self.i = 2
self.carControl.CarMove(direction,loop)
self.send_response(200)
def auto(self):
global loop
global direction
loop = True
while loop:
self.carControl.CarMove(direction,loop)
if __name__ == "__main__":
raspCarServer = CarServer
hostIP = raspCarServer.get_host_ip(raspCarServer)
hostPort = 9090
myServer = HTTPServer((hostIP,hostPort),raspCarServer)
print(time.asctime(),"Server Starts - %s:%s" %(hostIP,hostPort))
try:
myServer.serve_forever()
except KeyboardInterrupt:
pass
二、網頁
(1)簡單講解
網頁視頻的框體大小設計是需要和樹莓派中改的分辨率一致,不然無法鋪滿視頻框體。
在網頁中添加了點擊和觸摸兩種操控方式,手機和電腦均可使用。不過在手機上進行點擊操作時,會產生兩次指令,請批評指正。
(2)代碼
創建control.html
<html>
<script>
function directionBtnDown(direction) {
var url = "requestAddress"
var request = new XMLHttpRequest();
request.open("POST", url);
request.send(direction)
}
function directionBtnUp() {
var url = "requestAddress"
var request = new XMLHttpRequest();
request.open("POST", url);
request.send("S")
}
</script>
<style type="text/css">
span.car {
-webkit-touch-callout:none; /*系統默認菜單被禁用*/
-webkit-user-select:none; /*webkit瀏覽器*/
-khtml-user-select:none; /*早期瀏覽器*/
-moz-user-select:none;/*火狐*/
-ms-user-select:none; /*IE10*/
user-select:none;
position: absolute;
margin-top: 30%;
height: 480px;
}
span.camera {
position: absolute;
margin-top: 5%;
margin-left: 300px;
height: 480px;
width: 640px;
background-color: blue
}
span.camera_control {
position: absolute;
margin-top: 30%;
margin-left: 950px;
height: 480px;
background-color: blue
}
button.top {
position: absolute;
height: 50px;
width: 90px;
margin-left: 100px;
}
button.left {
position: absolute;
height: 50px;
width: 90px;
margin-top: 60px;
}
button.center {
position: absolute;
height: 50px;
width: 90px;
margin-top: 60px;
margin-left: 100px;
}
button.right {
position: absolute;
height: 50px;
width: 90px;
margin-top: 60px;
margin-left: 200px;
}
button.bottom {
position: absolute;
height: 50px;
width: 90px;
margin-top: 120px;
margin-left: 100px;
}
button.bleft {
position: absolute;
height: 50px;
width: 90px;
margin-top: 180px;
}
button.bcenter {
position: absolute;
height: 50px;
width: 90px;
margin-top: 180px;
margin-left: 100px;
}
button.bright {
position: absolute;
height: 50px;
width: 90px;
margin-top: 180px;
margin-left: 200px;
}
button.bbottom {
position: absolute;
height: 50px;
width: 90px;
margin-top: 240px;
margin-left: 100px;
}
</style>
<head>
<title>control page</title>
<meta name="viewport"
content="
height = 1080px ,
width = 1920px ,
initial-scale =0.5,
minimum-scale = 0.5 ,
maximum-scale = 1.0 ,
user-scalable = "yes"
" />
</head>
<body>
<span id="car_control" class="car">
<button class="top drectionBtn" id="F" ontouchstart="directionBtnDown('F')" ontouchend="directionBtnUp()"οnmοusedοwn="directionBtnDown('F')" οnmοuseup="directionBtnUp()">F</button>
<button class="left drectionBtn" id="L" ontouchstart="directionBtnDown('L')" ontouchend="directionBtnUp()" onmousedown="directionBtnDown('L')" onmouseup="directionBtnUp()">L</button>
<button class="right drectionBtn" id="R" ontouchstart="directionBtnDown('R')" ontouchend="directionBtnUp()"οnmοusedοwn="directionBtnDown('R')" οnmοuseup="directionBtnUp()">R</button>
<button class="center drectionBtn" id="B" ontouchstart="directionBtnDown('B')" ontouchend="directionBtnUp()"οnmοusedοwn="directionBtnDown('B')" οnmοuseup="directionBtnUp()">B</button>
<button class="bleft drectionBtn" id="AUTO" onmousedown="directionBtnDown('Auto')">Auto</button>
<button class="bcenter drectionBtn" id="S" onmousedown="directionBtnDown('S')">Stop</button>
<button class="bright drectionBtn" id="E" onmousedown="directionBtnDown('E')">exit</button>
</span>
<span id="camera_view" class="camera">
<img id="view" src="cameraAddress?action=stream" />
</span>
<span id="camera_control" class="camera_control">
<button class="top drectionBtn" id="VU" onmousedown="directionBtnDown('VU')">Up</button>
<button class="left drectionBtn" id="HL" onmousedown="directionBtnDown('HL')">Left</button>
<button class="right drectionBtn" id="HR" onmousedown="directionBtnDown('HR')">Right</button>
<button class="center drectionBtn" id="VD" onmousedown="directionBtnDown('VD')">Down</button>
<button class="bleft drectionBtn" id="GL" onmousedown="directionBtnDown('GL')">L_pro</button>
<button class="bcenter drectionBtn" id="GF" onmousedown="directionBtnDown('GF')">F_pro</button>
<button class="bright drectionBtn" id="GR" onmousedown="directionBtnDown('GR')">R_pro</button>
<button class="bottom drectionBtn" id="GU" onmousedown="directionBtnDown('GU')">U_pro</button>
<button class="bbottom drectionBtn" id="GD" onmousedown="directionBtnDown('GD')">D_pro</button>
</span>
</body>
</html>
三、app實現思路
(1)方案——AS
使用AS自己寫一個,不過可能耗時久一點,可以通過訪問控制頁面實現,也可以耗點力氣,把功能全部集中在APP中,跳過網頁進行控制。
(2)方案——MIT-APP
使用簡易創建app的工具,直接嵌入一個瀏覽器內核,直接訪問,在裏面將小車的IP寫成默認,每次點開即可,無需每次重複輸入IP。
下附MIT-APP的鏈接
MIT-APP,此鏈接可以直接訪問,後續開發需要科學上網
無法科學上網的有離線版,需要的可以留言或者私信,我會掛上去。