Python server gracefully shutdown and send scan data to converter

This commit is contained in:
Lukas Droste
2021-08-16 20:52:35 +02:00
parent e45f0312e0
commit de049999ee
5 changed files with 200 additions and 118 deletions

View File

@@ -4,10 +4,12 @@ import time
import PyLidar3 import PyLidar3
import asyncio import asyncio
import websockets import websockets
from concurrent.futures import ThreadPoolExecutor import threading
import collections
import requests
f = open("PointCloudWeb.Scanner\datafile.txt","wt") # f = open("PointCloudWeb.Scanner\datafile.txt","wt")
f.write("y, x, z\n") # f.write("y, x, z\n")
arduino_status = False arduino_status = False
arduino_port = "COM9" arduino_port = "COM9"
@@ -18,30 +20,34 @@ lidar_port = "COM6"
lidar_chunk_size = 20000 lidar_chunk_size = 20000
lidar = None lidar = None
scan_progress = 0 scan_progress = 0
_executor = ThreadPoolExecutor(1) scan_running = False
newMessage = "" stop_scan = False
lastMessage = "" ws_message_queue = collections.deque(maxlen=100)
scan_id = "32a3acd0-4d67-4281-bf9c-3eefc093eca4"
async def init(websocket): async def init():
global arduino global arduino, ws_message_queue, arduino_status, lidar, lidar_status
arduino = serial.Serial(port=arduino_port, baudrate=arduino_baud)
try: try:
await websocket.send("arduino connected " + arduino_port) arduino = serial.Serial(port=arduino_port, baudrate=arduino_baud)
global arduino_status ws_message_queue.appendleft("arduino connected " + arduino_port)
arduino_status = True arduino_status = True
except: except:
await websocket.send("can not connect to arduino! " + arduino_port) ws_message_queue.appendleft("can not connect to arduino! " + arduino_port)
arduino_status = False
try: try:
global lidar
lidar = PyLidar3.YdLidarX4(port=lidar_port,chunk_size=lidar_chunk_size) #PyLidar3.your_version_of_lidar(port,chunk_size) lidar = PyLidar3.YdLidarX4(port=lidar_port,chunk_size=lidar_chunk_size) #PyLidar3.your_version_of_lidar(port,chunk_size)
if(lidar.Connect()): if(lidar.Connect()):
global lidar_status
lidar_status = True lidar_status = True
await websocket.send("lidar connected " + lidar_port) ws_message_queue.appendleft("lidar connected " + lidar_port)
else: else:
raise ValueError raise ValueError
except: except:
await websocket.send("can not connect to lidar! " + lidar_port) ws_message_queue.appendleft("can not connect to lidar! " + lidar_port)
lidar_status = False
if( arduino_status == True and lidar_status == True):
ws_message_queue.appendleft("<connection>true")
else:
ws_message_queue.appendleft("<connection>false")
def arduino_write_read(x): def arduino_write_read(x):
arduino.write(bytes(x, 'utf-8')) arduino.write(bytes(x, 'utf-8'))
@@ -50,130 +56,161 @@ def arduino_write_read(x):
def setY(y): def setY(y):
tmp = arduino_write_read("<set><"+str(y)+">") tmp = arduino_write_read("<set><"+str(y)+">")
print(tmp)
# def getY():
# print(arduino_write_read("<get>"))
# def resetY():
# print(arduino_write_read("<reset>"))
# def zerotY():
# print(arduino_write_read("<zero>"))
def filterY(data): def filterY(data):
temp = data[data.find("<"):data.find(">")] temp = data[data.find("<"):data.find(">")]
return temp + data[data.find("><"):data.find(">", data.find("><")+2)+1] return temp + data[data.find("><"):data.find(">", data.find("><")+2)+1]
def senddata(data,posy): def senddata(data,posy):
temp ="{\"Id\": "+scan_id+",\"ScanPoints\":["
for x,y in data.items(): for x,y in data.items():
f.write(str(posy) + ", " + str(x) + ", " + str(y) + "\n") temp += ("{\"RAY\":" + str(posy) + ",\"RAX\":" + str(x) + ",\"DistanceMM\":" + str(y) + "},")
# f.write("{\"RAY\":" + str(posy) + ",\"RAX\":" + str(x) + ",\"DistanceMM\":" + str(y) + "},")
l = len(temp)
temp = temp[:l-1] + "]}"
r = requests.put(url='http://localhost:35588/scandata', data=temp, headers={'content-type': 'application/json'})
#print(r.status_code)
def startScaner(websocket, mode):
global scan_progress def startScaner(mode):
global lidar global scan_progress, lidar, stop_scan, scan_id
if lidar_status == True: if lidar_status == True:
print(lidar.GetDeviceInfo()) ws_message_queue.appendleft(str(lidar.GetDeviceInfo()))
gen = lidar.StartScanning() gen = lidar.StartScanning()
if mode == "0": if mode == "0":
print("Mode 0") print("Mode 0")
for y in range(18): ws_message_queue.appendleft("<scan>running")
for y in range(19):
if(stop_scan == True):
break
print("send data")
senddata(next(gen),y*10) senddata(next(gen),y*10)
time.sleep(2) time.sleep(2)
setY( y*10) setY( y*10)
time.sleep(2) time.sleep(2)
scan_progress = y/18*100 scan_progress = round(y/18*100)
print(str(scan_progress) + " %") ws_message_queue.appendleft("<progress>" + str(scan_progress))
requests.put(url='http://localhost:35588/scandata', data='finished/'+scan_id, headers={'content-type': 'application/json'})
setY(0) setY(0)
lidar.StopScanning() lidar.StopScanning()
lidar.Disconnect()
elif mode == "1": elif mode == "1":
print("Mode 1") ws_message_queue.appendleft("<scan>running")
for y in range(90): for y in range(91):
if(stop_scan == True):
break
senddata(next(gen),y*2) senddata(next(gen),y*2)
time.sleep(1) time.sleep(1)
setY(y*2) setY(y*2)
time.sleep(1) time.sleep(1)
scan_progress = y/90*100 scan_progress = round(y/90*100)
print(str(scan_progress) + " %") ws_message_queue.appendleft("<progress>" + str(scan_progress))
requests.put(url='http://localhost:35588/scandata', data='finished/'+scan_id, headers={'content-type': 'application/json'})
setY(0) setY(0)
lidar.StopScanning() lidar.StopScanning()
lidar.Disconnect()
elif mode == "2": elif mode == "2":
print("Mode 2") ws_message_queue.appendleft("<scan>running")
for y in range(360): for y in range(361):
if(stop_scan == True):
break
senddata(next(gen),y*0.5) senddata(next(gen),y*0.5)
time.sleep(1) time.sleep(1)
setY(y*0.5) setY(y*0.5)
time.sleep(1) time.sleep(1)
scan_progress = y/360*100 scan_progress = round(y/360*100)
print(str(scan_progress) + " %") ws_message_queue.appendleft("<progress>" + str(scan_progress))
requests.put(url='http://localhost:35588/scandata', data='finished/'+scan_id, headers={'content-type': 'application/json'})
setY(0) setY(0)
lidar.StopScanning() lidar.StopScanning()
lidar.Disconnect()
elif mode == "3":
print(scan_progress)
scan_progress += 1
print(scan_progress)
else: else:
print("mode error") ws_message_queue.appendleft("mode error")
#f.close()
f.close() if(stop_scan == True):
print("scan stoped") stop_scan = False
ws_message_queue.appendleft("<scan>canceld")
ws_message_queue.appendleft("scan canceld !")
else: else:
print("Error connecting to device") ws_message_queue.appendleft("<scan>finished")
ws_message_queue.appendleft("scan finished")
else:
ws_message_queue.appendleft("Error connecting to device")
async def wsfilter(websocket, message): async def wsfilter(message):
command = message[message.find("<")+1:message.find(">")] command = message[message.find("<")+1:message.find(">")]
value = message[message.find("><")+2:message.find(">", message.find("><")+2)] value = message[message.find("><")+2:message.find(">", message.find("><")+2)]
await wsaction(websocket, command,value) await wsaction(command,value)
async def wsaction(websocket, command, value): async def wsaction(command, value):
global ws_message_queue, stop_scan
if command == "start": if command == "start":
if value == "0": if value == "0":
await websocket.send("start scan resolution 0") ws_message_queue.appendleft("start scan on low resolution")
await loop.run_in_executor(_executor, startScaner(websocket, value)) x = threading.Thread(target=startScaner, args=(value))
x.start()
elif value =="1": elif value =="1":
await websocket.send("start scan resolution 1") ws_message_queue.appendleft("start scan on medium resolution")
await loop.run_in_executor(_executor, startScaner(websocket, value)) x = threading.Thread(target=startScaner, args=(value))
x.start()
elif value =="2": elif value =="2":
await websocket.send("start scan resolution 2") ws_message_queue.appendleft("start scan on high resolution")
await loop.run_in_executor(_executor, startScaner(websocket, value)) x = threading.Thread(target=startScaner, args=(value))
elif value =="3": x.start()
await websocket.send("start scan test")
await loop.run_in_executor(_executor, startScaner(websocket, value))
else: else:
await websocket.send("mode error") ws_message_queue.appendleft("mode error")
elif command == "connect" and arduino and lidar != None: elif command == "connect" and arduino and lidar != None:
await websocket.send("try to connect to Adruino and LIDAR") ws_message_queue.appendleft("try to connect to Adruino and LIDAR")
await init(websocket) await init()
elif command == "status": elif command == "status":
await websocket.send("progress: " + scan_progress) ws_message_queue.appendleft("progress: " + scan_progress)
elif command == "stop":
stop_scan = True
elif command == "init":
await init()
else: else:
await websocket.send("command error") ws_message_queue.appendleft("command error")
async def wscom(websocket, path): async def producer_handler(websocket, path):
await websocket.send("Websocket connected")
await init(websocket)
while True: while True:
data2 = await websocket.recv() global ws_message_queue
await wsfilter(websocket, data2) if len(ws_message_queue) > 0:
print({data2}) message = ws_message_queue.pop()
if scan_progress != lastMessage: print(message)
await websocket.send(scan_progress) await websocket.send(message)
lastMessage = scan_progress await asyncio.sleep(0.01)
async def main(): async def consumer_handler(websocket, path):
server = await websockets.serve(wscom, 'localhost', 6789) async for message in websocket:
await server.wait_closed() await wsfilter(message)
async def handler(websocket, path):
print("Start Websocket Connection at ")
await init()
consumer_task = asyncio.ensure_future(consumer_handler(websocket, path))
producer_task = asyncio.ensure_future(producer_handler(websocket, path))
done, pending = await asyncio.wait([consumer_task, producer_task], return_when=asyncio.FIRST_COMPLETED)
for task in pending:
task.cancel()
try:
ws_server = websockets.serve(handler, 'localhost', 6789)
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.run_until_complete(main()) loop.run_until_complete(ws_server)
#asyncio.run(main()) loop.run_forever()
finally:
#while True: print("shutting down server")
# startScaner(input("Scan Modus(0,1,2):")) ws_message_queue.appendleft("shutting down server")
#wsfilter(input("Befehlt Eingeben:")) stop_scan = True
# for x in range(18): print("set stop_scan")
# setY(x*10) try:
# time.sleep(1) setY(0)
print("reset stepper")
except:
print("can´t reset stepper")
ws_message_queue.appendleft("<connection>false")
print("Status an UI senden")
try:
lidar.Disconnect()
print("LIDAR Disconnecten")
except:
print("can´t disconnecten lidar")
loop.close()
print("server down")

View File

@@ -4,7 +4,6 @@ import time
import PyLidar3 import PyLidar3
import asyncio import asyncio
import websockets import websockets
from concurrent.futures import ThreadPoolExecutor
import threading import threading
import collections import collections
@@ -20,7 +19,8 @@ lidar_port = "COM6"
lidar_chunk_size = 20000 lidar_chunk_size = 20000
lidar = None lidar = None
scan_progress = 0 scan_progress = 0
messageQeue = ['test', 'test1', 'abc'] scan_running = False
stop_scan = False
ws_message_queue = collections.deque(maxlen=100) ws_message_queue = collections.deque(maxlen=100)
async def init(): async def init():
@@ -40,6 +40,7 @@ async def init():
ws_message_queue.appendleft("lidar connected " + lidar_port) ws_message_queue.appendleft("lidar connected " + lidar_port)
except: except:
ws_message_queue.appendleft("can not connect to lidar! " + lidar_port) ws_message_queue.appendleft("can not connect to lidar! " + lidar_port)
ws_message_queue.appendleft("<connection>true")
def arduino_write_read(x): def arduino_write_read(x):
data1 = x data1 = x
@@ -47,7 +48,6 @@ def arduino_write_read(x):
def setY(y): def setY(y):
tmp = arduino_write_read("<set><"+str(y)+">") tmp = arduino_write_read("<set><"+str(y)+">")
print(tmp)
def filterY(data): def filterY(data):
temp = data[data.find("<"):data.find(">")] temp = data[data.find("<"):data.find(">")]
@@ -58,12 +58,14 @@ def senddata(data,posy):
f.write(str(posy) + ", " + str(x) + ", " + str(y) + "\n") f.write(str(posy) + ", " + str(x) + ", " + str(y) + "\n")
def startScaner(mode): def startScaner(mode):
global scan_progress, lidar, messageQeue global scan_progress, lidar, stop_scan
if lidar_status == True: if lidar_status == True:
ws_message_queue.appendleft("start scan mode: " + mode) ws_message_queue.appendleft("start scan mode: " + mode)
if mode == "0": if mode == "0":
ws_message_queue.appendleft("<scan>running") ws_message_queue.appendleft("<scan>running")
for y in range(19): for y in range(19):
if(stop_scan == True):
break
time.sleep(0.2) time.sleep(0.2)
setY( y*10) setY( y*10)
scan_progress = round(y/18*100) scan_progress = round(y/18*100)
@@ -72,14 +74,19 @@ def startScaner(mode):
elif mode == "1": elif mode == "1":
ws_message_queue.appendleft("<scan>running") ws_message_queue.appendleft("<scan>running")
for y in range(91): for y in range(91):
if(stop_scan == True):
break
time.sleep(0.2) time.sleep(0.2)
setY(y*2) setY(y*2)
scan_progress = round(y/90*100) scan_progress = round(y/90*100)
ws_message_queue.appendleft("<progress>" + str(scan_progress)) ws_message_queue.appendleft("<progress>" + str(scan_progress))
setY(0) setY(0)
elif mode == "2": elif mode == "2":
ws_message_queue.appendleft("<scan>running") ws_message_queue.appendleft("<scan>running")
for y in range(361): for y in range(361):
if(stop_scan == True):
break
time.sleep(0.1) time.sleep(0.1)
setY(y*0.5) setY(y*0.5)
scan_progress = round(y/360*100) scan_progress = round(y/360*100)
@@ -89,6 +96,11 @@ def startScaner(mode):
ws_message_queue.appendleft("mode error") ws_message_queue.appendleft("mode error")
f.close() f.close()
if(stop_scan == True):
stop_scan = False
ws_message_queue.appendleft("<scan>canceld")
ws_message_queue.appendleft("scan canceld !")
else:
ws_message_queue.appendleft("<scan>finished") ws_message_queue.appendleft("<scan>finished")
ws_message_queue.appendleft("scan finished") ws_message_queue.appendleft("scan finished")
else: else:
@@ -100,7 +112,7 @@ async def wsfilter(message):
await wsaction(command,value) await wsaction(command,value)
async def wsaction(command, value): async def wsaction(command, value):
global ws_message_queue global ws_message_queue, stop_scan
if command == "start": if command == "start":
if value == "0": if value == "0":
ws_message_queue.appendleft("start scan on low resolution") ws_message_queue.appendleft("start scan on low resolution")
@@ -121,6 +133,8 @@ async def wsaction(command, value):
await init() await init()
elif command == "status": elif command == "status":
ws_message_queue.appendleft("progress: " + scan_progress) ws_message_queue.appendleft("progress: " + scan_progress)
elif command == "stop":
stop_scan = True
else: else:
ws_message_queue.appendleft("command error") ws_message_queue.appendleft("command error")
@@ -137,7 +151,7 @@ async def consumer_handler(websocket, path):
await wsfilter(message) await wsfilter(message)
async def handler(websocket, path): async def handler(websocket, path):
print("Start Websocket Connection") print("Start Websocket Connection at ")
await init() await init()
consumer_task = asyncio.ensure_future(consumer_handler(websocket, path)) consumer_task = asyncio.ensure_future(consumer_handler(websocket, path))
producer_task = asyncio.ensure_future(producer_handler(websocket, path)) producer_task = asyncio.ensure_future(producer_handler(websocket, path))

View File

@@ -115,9 +115,9 @@ namespace PointCloudWeb.Server.Models
{ {
// + 0.001 Otherwise points are outside of the bounding box by a floating-error, then Potree-Converter fails // + 0.001 Otherwise points are outside of the bounding box by a floating-error, then Potree-Converter fails
stringBuilder.AppendLine(string.Join(',', stringBuilder.AppendLine(string.Join(',',
(point.X + 0.001).ToString(CultureInfo.InvariantCulture), (point.X + 0.1).ToString(CultureInfo.InvariantCulture),
(point.Y + 0.001).ToString(CultureInfo.InvariantCulture), (point.Y + 0.1).ToString(CultureInfo.InvariantCulture),
(point.Z + 0.001).ToString(CultureInfo.InvariantCulture) (point.Z + 0.1).ToString(CultureInfo.InvariantCulture)
) )
); );
} }

Binary file not shown.

View File

@@ -1,19 +1,21 @@
<template> <template>
<div class="ui"> <div class="ui">
<h1>Welcome to PointCloudWeb</h1> <h1>Welcome to PointCloudWeb</h1>
<div v-if="connection_status && !scan_status"> <div v-if="connection_status && !scan_status && scanner_status">
<button class="button" v-on:click="sendMessage('<start><0>')" >Start Scan: low</button> <button class="button" v-on:click="sendMessage('<start><0>')" >Start Scan: low</button>
<button class="button button2" v-on:click="sendMessage('<start><1>')" >Start Scan: medium</button> <button class="button button2" v-on:click="sendMessage('<start><1>')" >Start Scan: medium</button>
<button class="button button3" v-on:click="sendMessage('<start><2>')" >Start Scan: high</button> <button class="button button3" v-on:click="sendMessage('<start><2>')" >Start Scan: high</button>
</div> </div>
<div class="progressbar" v-if="connection_status"> <button v-if="scan_status && connection_status" class="button button4" v-on:click="sendMessage('<stop>')" >cancel</button>
<div :style="{width: progress + '%'}"></div> <button v-if="!scanner_status && connection_status" class="button button4" v-on:click="sendMessage('<init>')" >Init. Scanner</button>
<div class="progressbar" v-if="connection_status && scanner_status">
<div :style="{width: progress + '%', 'background-color': progress_color}"></div>
</div> </div>
<p v-if="connection_status">{{progress}} %</p> <p v-if="connection_status && scanner_status">{{progress}} %</p>
<div> <div>
<h1 v-if="!connection_status">status: disconnected</h1> <h1 v-if="!connection_status">Scan Server: disconnected</h1>
<h1 v-if="connection_status">status: connected</h1> <h1 v-if="connection_status">Scan Server: connected</h1>
<button v-if="!connection_status" v-on:click="connectWS" >Connect</button> <button v-if="!connection_status" v-on:click="connectWS">Connect to Scan Server</button>
<ul> <ul>
<div class="value" v-for="(item, index) in logs" :key="item.id"> <div class="value" v-for="(item, index) in logs" :key="item.id">
<li>{{logs[index]}}</li> <li>{{logs[index]}}</li>
@@ -21,7 +23,7 @@
</ul> </ul>
</div> </div>
<!--<button v-on:click="connection_status = !connection_status" >test</button>--> <!--<button v-on:click="connection_status = !connection_status" >test</button>-->
<button v-on:click="logs = []" >clear logs</button> <button v-on:click="progress = 0, logs = []" >clear logs</button>
</div> </div>
</template> </template>
@@ -33,7 +35,9 @@ export default {
logs: [], logs: [],
connection_status: false, connection_status: false,
scan_status: false, scan_status: false,
scanner_status: false,
progress: 0, progress: 0,
progress_color: "yellow",
command: "", command: "",
value: "" value: ""
}; };
@@ -54,13 +58,20 @@ export default {
if(event.data) if(event.data)
that.msgFilter(event.data) that.msgFilter(event.data)
} }
this.wsConnection.onclose = function(){
that.connection_status = false
that.scanner_status = false
that.scan_status = false
that.logs.push("Websocket Connection closed");
}
}, },
msgFilter(message){ msgFilter(message){
let that = this let that = this
if(message.search("<") != -1){ if(message.search("<") != -1){
that.command = message.substr(message.search("<")+1, message.search(">")-1) that.command = message.substr(message.search("<")+1, message.search(">")-1)
that.value = message.substr(message.search(">")+1) that.value = message.substr(message.search(">")+1)
console.log("command: " + that.command + " / value: " + that.value) //console.log("command: " + that.command + " / value: " + that.value)
this.action(that.command, that.value) this.action(that.command, that.value)
} }
else{ else{
@@ -78,13 +89,29 @@ export default {
that.logs.push(value); that.logs.push(value);
} }
else if(command == "scan"){ else if(command == "scan"){
if(value == "running") if(value == "running"){
that.scan_status = true that.scan_status = true
that.progress_color = "yellow"
}
else if(value == "finished"){
that.scan_status = false
that.progress_color = "greenyellow"
}
else{
that.scan_status = false
that.progress_color = "red"
that.progress = "canceld"
}
}
else if(command == "connection"){
if(value == "true")
that.scanner_status = true
else else
that.scanner_status = false
that.scan_status = false that.scan_status = false
} }
else else
that.logs.push("Unknow command: " + value); that.logs.push("Unknow command: " + value)
} }
}, },
@@ -122,7 +149,6 @@ li {
} }
.progressbar>div { .progressbar>div {
background-color: greenyellow;
/* Adjust with JavaScript */ /* Adjust with JavaScript */
height: 20px; height: 20px;
border-radius: 4px; border-radius: 4px;
@@ -141,7 +167,12 @@ li {
cursor: pointer; cursor: pointer;
} }
.button2 {background-color: #008CBA;} /* Blue */ .button:hover{
.button3 {background-color: #f44336;} /* Red */ background-color: #e9962a;
}
.button2 {background-color: #00ba9b;}
.button3 {background-color: #008cff}
.button4 {background-color: #f44336;} /* Red */
</style> </style>