from fastapi import APIRouter from starlette.requests import Request from tortoise.queryset import QuerySet, Prefetch from models.agv import ( Agv ) from models.warehouse import ( Hole, Vacancy ) from helper import respond_to from tortoise.contrib.pydantic import pydantic_model_creator import requests from typing import List, Any import asyncio import threading import os from multiprocessing import current_process from multiprocessing import Process from plc.tools import ( bytes_to_int_list, float2intList, intList2Float ) import json import struct import time import math from pydantic import BaseModel from typing import Optional from conf import setting from cam.getParam import getParam from cam.axis import ( labelMapBigDisk, labelMapLittleDisk, labelMapLittleBox, labelMapBigBox ) from plc.cmd import( cmd_type, setSubPaths, pass_door, setLayer, moveArm, taskNum, setTasks, clear_batch, readStatus, write_batch, write_batch_float, #Cam related readCamStatus, setCamIntList, camDone, doorReady, write_task_batch ) from algorithm.genpath import ( genPath, getAgvStop ) import traceback #second capture count CNT = 0 LASTITEM = None LASTX = None LASTY = None LABELMAP = [] class PutboxM(BaseModel): start: str stops: list[str] class OrderM(BaseModel): ordertype: int layer: int stop: str class FullOrder(BaseModel): ordertype_start: int layer_start: int stop_start: str ordertype_end: int layer_end: int stop_end: str class assignM(BaseModel): data: Any agv_router = APIRouter(prefix='/agv') # ip = "http://127.0.0.1:8000" # # Lin's # ip = "http://192.168.192.222:8000" # Cental Control ip = "http://192.168.192.230:8005" endpoint_getassgin = "{}/api/scheduler/assign/".format(ip) endpoint_done = "{}/api/scheduler/assign/done/".format(ip) endpoint_failed = "{}/api/scheduler/assign/failed/".format(ip) # doorIP = "http://192.168.192.19:8000" doorIP = "http://192.168.192.230:8000" endpoint_opendoor = "{}/api/rms/auto/agv/door".format(doorIP) ISDOOROPEN = False def openDoor(): global ISDOOROPEN dataObj = { "action":"open" } dataObj = json.dumps(dataObj) res = requests.post(endpoint_opendoor, data=dataObj) print("openDoor: ", res.status_code, res.text) if 400 > res.status_code: resObj = res.json() if resObj and "data" in resObj.keys(): dataObj = resObj["data"] if dataObj and "action" in dataObj.keys() and "success" in dataObj.keys(): if dataObj["success"]: ISDOOROPEN = True def closeDoor(): global ISDOOROPEN dataObj = { "action":"close" } dataObj = json.dumps(dataObj) res = requests.post(endpoint_opendoor, data=dataObj) print("closeDoor: ", res.status_code, res.text) if 400 > res.status_code: resObj = res.json() if resObj and "data" in resObj.keys(): dataObj = resObj["data"] if dataObj and "action" in dataObj.keys() and "success" in dataObj.keys(): if dataObj["success"]: ISDOOROPEN = False def checkCamAxis(x, y): checkX = None checkY = None #for test xMin = -10000 xMax = 10000 #for test yMin = -10000 yMax = 10000 if xMin < x and xMax > x: checkX = x if yMin < x and yMax > x: checkY = y return checkX, checkY def checkGrabAxis(x, y): checkX = None checkY = None #for test xMin = -10000 xMax = 10000 #for test yMin = -10000 yMax = 10000 if xMin < x and xMax > x: checkX = x if yMin < x and yMax > x: checkY = y return checkX, checkY def getCamStatus(qrcodes = []): global CNT global LASTITEM global LASTX global LASTY status = readCamStatus() xStatus = list(status) # print("getCamStatus: ", xStatus) xValue = intList2Float(xStatus[0:2]) # print("xValue: ", xValue) yValue = intList2Float(xStatus[2:4]) # print("yValue: ", yValue) zValue = intList2Float(xStatus[4:6]) # print("zValue: ", zValue) rValue = intList2Float(xStatus[6:8]) # print("rValue: ", rValue) if 1 == xStatus[9]: print("getCamStatus Triger {}".format(xStatus[9])) item, qrcode = getParam() print("item -> QRCode: ", item, qrcode) if item: if len(qrcodes) > 0: # if len(qrcodes) > 0 and qrcode == qrcodes.pop[0]: if qrcode in qrcodes: print("qrcode detected! ", qrcode) else: print("qrcode is not detected!") #The oritention of camera matter the sign value #toward AGV is 1, Backward AGV is -1 armX, armY, sign = getArmXY(xValue, yValue) dx = item[3] * setting.DXCAMREALRATIO * sign dy = item[4] * setting.DYCAMREALRATIO * sign if 0 == CNT % 2: LASTITEM = item LASTX = xValue LASTY = yValue print("xValue + dx: ", xValue, dx, xValue + dx) print("yValue + dy: ", yValue, dy, yValue + dy) # XList = float2intList(xValue + dx) # YList = float2intList(yValue + dy) x = xValue + dy y = yValue + dx checkX, checkY = checkCamAxis(x, y) if checkX and checkY: XList = float2intList(checkX) YList = float2intList(checkY) else: print(F"Abnorm Value checkX: {checkX}, checkY: {checkY}") return print("Set LASTITEM: ", LASTITEM) else: # armX, armY = getArmXY(xValue, yValue) print("armX + dx: ", armX, dx, armX + dx) print("armY + dy: ", armY, dy, armY + dy) # XList = float2intList(armX + dx) # YList = float2intList(armY + dy) if LASTITEM: distance = math.dist([item[3], item[4]], [0, 0]) distanceLast = math.dist([LASTITEM[3], LASTITEM[4]], [0, 0]) ldx = LASTITEM[3] * setting.DXCAMREALRATIO * sign ldy = LASTITEM[4] * setting.DYCAMREALRATIO * sign if distance < distanceLast: x = armX + dy + ldy y = armY + dx + ldx checkX, checkY = checkGrabAxis(x, y) if checkX and checkY: XList = float2intList(checkX) YList = float2intList(checkY) else: print(F"Abnorm Value checkX: {checkX}, checkY: {checkY}") return else: x = armX + ldy y = armY + ldx checkX, checkY = checkGrabAxis(x, y) if checkX and checkY: XList = float2intList(checkX) YList = float2intList(checkY) else: print(F"Abnorm Value checkX: {checkX}, checkY: {checkY}") return LASTITEM = None else: print("Get LASTITEM Error: ", LASTITEM) # raise Exception("Miss the first item") print("XList: {}, YList: {}".format(XList, YList)) # 拍照完成, # 工控机返回玻璃门 res = [ 1, 2 ] + XList + YList setCamIntList(res) CNT = CNT + 1 time.sleep(1) #clear cam finish when triger cam finish clearCamFinish = [ 0 ] setCamIntList(clearCamFinish) else: # XList = float2intList(LASTX) # YList = float2intList(LASTY) # res = [ 0, 2 ] + XList + YList # setCamIntList(res) print("Find No Object!") else: #clear cam finish when triger cam finish clearCamFinish = [ 0 ] setCamIntList(clearCamFinish) def clearCmd(qrcodes = []): #wait 1 second after send cmd time.sleep(1) status = readStatus() print("getAgvStatus: ", status) cnt = 0 while 1 != status[0]: # print("cnt: ", cnt) cnt = cnt + 1 time.sleep(0.1) status = readStatus() # print("getAgvStatus: ", status) getCamStatus(qrcodes = []) #PLC terminate by timeout if cnt > setting.PLCTIMEOUT: print("PLC Timeout, Exit!") break clear_batch() print("clear_batch: ") #get camera axis related arm axis def getArmXY(x, y): # labelMap = [ # #Big x, y, x1, y1, Label, num, sign # [ 259.9213, -199.1091, 238.0209, -107.0088, "B1", 401, 1],#1 # [ 118.2232, -113.7113, 133.223, -107.9106, "B2", 404, 1],#2 # [ 298.0214, -9.1093, 242.2205, -0.7079, "B3", 402, 1],#3 # [ 187.2214, -7.0099, 138.2216, -1.9102, "B4", 405, 1],#4 # [ 298.4224, 93.9812, 246.2243, 106.5838, "B5", 403, 1],#5 # [ 195.8225, 98.182, 141.224, 108.6835, "B6", 406, 1],#6 # # #little # # [219.2259, -134.5134, 274.2259, -139.5131, "L1", 301, -1],#1 # # [141.2238, -131.5109, 187.1251, -136.5126, "L2", 305, -1],#2 # # # [, "L3", 309, -1],#3 # # [225.2205, -44.5074, 277.2257, -51.5123, "L4", 302, -1],#4 # # [139.2199, -44.5065, 190.0238, -48.612, "L5", 306, -1], #5 # # # [, "L6", 310, -1],#6 # # [228.7183, 40.4935, 284.5179, 40.4931, "L7", 303, -1],#7 # # [142.4177, 40.4924, 198.2177, 42.5925, "L8", 307, -1],#8 # # # [, "L9", 311, -1],#9 # # [233.2122, 132.0875, 284.0166, 130.4906, "L10", 304, -1],#10 # # # [, "L11", 308, -1],#11 # # [145.0099, 132.0864, 196.1168, 132.5911, "L12", 312, -1],#12 # #big disk # [12.2261, -215.5127, -44.7728, -205.5122, "BD1", 102, 1],#1 # [-144.6989, -209.1089, -164.6981, -204.1083, "BD2", 101, 1],#2 # #little disk # [45.8251, 147.7807, -4.1743, 149.881, "LD1", 205, 1],#1 # [-42.3746, 145.6784, -92.3706, 154.079, "LD2", 203, 1],#2 # [-130.5713, 151.79761, -180.57, 154.0777, "LD3", 201, 1],#3 # [48.6326, 246.1763, -2.0666, 248.9752, "LD4", 206, 1],#4 # [-39.5668, 248.2769, -89.1668, 253.9755, "LD5", 204, 1],#5 # [-125.6693, 248.2777, -174.2673, 254.8755, "LD6", 202, 1],#6 # ] global LABELMAP #find nearest LABELMAP.sort(key = lambda item: math.dist([x, y], [ item[0], item[1] ] )) # print("labelMap: ", labelMap) nearestItem = LABELMAP[0] #return corresponding arm x and y value return nearestItem[2], nearestItem[3], nearestItem[6] @agv_router.get("/status") async def read_status(): status = readStatus() statusRes = { "done": status[0], #任务完成状态 "stop": status[2], #AGV当前所在站点 "battery": status[3], #AGV当前电量 "charging": status[4], #AGV充电状态 "busy": status[5], #设备忙闲状态 "abnorm": status[6], #设备异常状态 "alarm": status[7] #报警信息 } return respond_to(code=200, data=statusRes) @agv_router.get("/charge", summary='充电测试') async def charge(): clear_batch() orderType = 4 layer = 0 end = "01-4002-0" vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 vl_output[0] = orderType #是否经过玻璃门 vl_output[1] = 2 #取框层数 vl_output[2] = layer #手臂是否需要动作 vl_output[3] = 2 #D21010-D21059 #AGV站点号 # vl_output[10] = 311 status = readStatus() start = status[2] startStop = getAgvStop(start) paths = genPath(startStop, end) print("Path: ", paths) cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 print("T1: ", vl_output) write_batch(vl_output) clearCmd() return respond_to(data={"status": "Hello World!"}) @agv_router.get("/wait", summary='去一号点等待') async def wait(): clear_batch() orderType = 4 layer = 0 end = "01-0000-0" vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 vl_output[0] = orderType #是否经过玻璃门 vl_output[1] = 2 #取框层数 vl_output[2] = layer #手臂是否需要动作 vl_output[3] = 2 #D21010-D21059 #AGV站点号 # vl_output[10] = 311 status = readStatus() start = status[2] startStop = getAgvStop(start) paths = genPath(startStop, end) print("Path: ", paths) cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 print("T1: ", vl_output) write_batch(vl_output) clearCmd() # if ISDOOROPEN: closeDoor() return respond_to(data={"status": "Hello World!"}) ''' Label '01-0115-3-5' ''' def getEndStopLayer(label): parts = label.split('-') if len(parts) > 2: return "{}-{}".format(parts[0], parts[1]), int(parts[2]) elif len(parts) > 2: return "{}-{}".format(parts[0], parts[1]), 0 elif len(parts) > 1: return "{}-0000".format(parts[0]), 0 else: raise Exception("Wrong Label") # def checkPassDoor(label): # parts = label.split('-') # inDoorStop = ["08", "09", "10", "11"] # #if check pass door, return True # for stop in inDoorStop: # if stop == parts[0]: # # pass # return 1 # #If not return, return False # # not pass # return 2 def checkPassDoor(startLabel, endLabel): startParts = startLabel.split('-') endParts = endLabel.split('-') # inDoorStop = ["08", "09", "10", "11"] inDoorStop = ["13", "14", "15", "16", "17", "18", "19", "20"] if ((startParts[0] in inDoorStop) and \ (endParts[0] not in inDoorStop)) or \ ((startParts[0] not in inDoorStop) and \ (endParts[0] in inDoorStop)): openDoor() return 1 #If not return, return False # not pass return 2 def checkMoveArm(label): parts = label.split('-') if len(parts) > 3: # Move Arm return 1 else: # Don't Move Arm return 2 def returnBox(startStop, layerSrc): vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 vl_output[0] = 2 #是否经过玻璃门 vl_output[1] = 1 #取框层数 vl_output[2] = layerSrc #手臂是否需要动作 vl_output[3] = 2 paths = [startStop] cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 print("returnBox: ", vl_output) write_batch(vl_output) async def getAvaiableHole(taskBody, label): # print("taskBody['typetask']: ", taskBody["typetask"]) if 1 == taskBody["typetask"]: #Standard A vacancy = await Vacancy.get_or_none(number = "Right", is_active = True) if vacancy: await vacancy.fetch_related("holes") holes = await vacancy.holes for hole in holes: print(' 1 == taskBody["typetask"] Hole: ', hole) holesLen = len(holes) print('holesLen < setting.AGVCAP[taskBody["typetask"]]: ', holesLen, setting.AGVCAP[taskBody["typetask"]], taskBody["typetask"], holesLen < setting.AGVCAP[taskBody["typetask"]]) if holesLen < setting.AGVCAP[taskBody["typetask"]]: hole = await Hole.create( number = holesLen + 1, traynum = vacancy.number, code = taskBody["code"], name = taskBody["name"], height = taskBody["height"], bottle = taskBody["bottle"], cap = taskBody["cap"], typetask = taskBody["typetask"], orderid = taskBody["orderid"], coordinates = taskBody["coordinates"], coordinatessrc = label ) await vacancy.holes.add(hole) #update state return hole.number + setting.LITDISKDIFF else: return -1 elif 3 == taskBody["typetask"]: #Standard B vacancy = await Vacancy.get_or_none(number = "Left", is_active = True) # print("vacancy: ", vacancy) if vacancy: await vacancy.fetch_related("holes") holes = await vacancy.holes # print("holes: ", holes, setting.AGVCAP[taskBody["typetask"]]) holesLen = len(holes) for hole in holes: print(' 3 == taskBody["typetask"] Hole: ', hole) print('holesLen < setting.AGVCAP[taskBody["typetask"]]: ', holesLen, setting.AGVCAP[taskBody["typetask"]], taskBody["typetask"], holesLen < setting.AGVCAP[taskBody["typetask"]]) if holesLen < setting.AGVCAP[taskBody["typetask"]]: hole = await Hole.create( number = holesLen + 1, traynum = vacancy.number, code = taskBody["code"], name = taskBody["name"], height = taskBody["height"], bottle = taskBody["bottle"], cap = taskBody["cap"], typetask = taskBody["typetask"], orderid = taskBody["orderid"], coordinates = taskBody["coordinates"], coordinatessrc = label ) await vacancy.holes.add(hole) #update state return hole.number + setting.BIGDISKDIFF else: return -1 elif 5 == taskBody["typetask"]: pass elif 7 == taskBody["typetask"]: pass elif 9 == taskBody["typetask"]: #Non Standard pass return -1 async def getHoleDestNumber(destLabel): hole = await Hole.get_or_none(coordinatessrc = destLabel, is_active = True) if hole: if "Right" == hole.traynum: return hole.number + setting.LITDISKDIFF elif "Left" == hole.traynum: return hole.number + setting.BIGDISKDIFF else: raise Exception("Cannot match Hole traynum!") else: print("getHoleDestNumber -> Can not find hole: ", destLabel) async def getAllTask(tasks = []): global CNT global LABELMAP # clear all register related in PLC clear_batch() CNT = 0 LABELMAP = [] print("getAllTask: ", tasks) task = tasks[0] destLabel = list(task.keys())[0] if 'Return' == destLabel: print("Return Task!") return taskBody = task[destLabel] srcLabel = taskBody["coordinates"] print(F"getAllTask: srcLabel: {srcLabel}") # endSrc, layerSrc = getEndStopLayer(srcLabel) tasktype = taskBody["typetask"] if 1 == tasktype: # little box LABELMAP = labelMapBigDisk + labelMapLittleDisk + labelMapLittleBox elif 3 == tasktype: # big box LABELMAP = labelMapBigDisk + labelMapLittleDisk + labelMapBigBox else: print("Cannot Match") print("LABELMAP: ", LABELMAP) vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 取货 vl_output[0] = 1 #取框层数 vl_output[2] = layerSrc #手臂是否需要动作 vl_output[3] = checkMoveArm(srcLabel) status = readStatus() start = status[2] startStop = getAgvStop(start) #是否经过玻璃门 # vl_output[1] = checkPassDoor(endSrc) vl_output[1] = checkPassDoor(startStop, endSrc) paths = [] paths = genPath(startStop, endSrc) # print("Path: ", paths) cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 # print("T1: ", vl_output) write_batch(vl_output) qrcodes = [] if 1 == checkMoveArm(srcLabel): totalTask = len(tasks) vl_output = [] for _ in range(100): vl_output.append(0) # total tasks vl_output[0] = totalTask idx = 1 for task in tasks: destLabel = list(task.keys())[0] qrcodes.append(task[destLabel]["code"]) #check AGV坐标系统 for who to get diff tasktype = task[destLabel]["typetask"] diff = 0 if 1 == tasktype: #小框 diff = 300 elif 3 == tasktype: #大框 diff = 400 else: print("getAllTask Cannot match taskType: ", tasktype) #AGV Related Operation getLabel = int(task[destLabel]["coordinates"].split("-")[-1]) + diff putLabel = await getAvaiableHole(task[destLabel], destLabel) if 0 > putLabel: raise Exception("Cannot find avaible Hole! putLabel: ", putLabel) vl_output[idx] = getLabel vl_output[idx + 1] = putLabel vl_output[idx + 2] = task[destLabel]["height"] vl_output[idx + 3] = task[destLabel]["cap"] #update next task index idx = idx + 4 print("getAllTask Sub Tasks: ", vl_output) write_task_batch(vl_output) #clear final task clearCmd(qrcodes) #if need to get single bottle, # return box after get task finish if 1 == checkMoveArm(srcLabel): #return box after get returnBox(paths[-1], layerSrc) clearCmd() async def putAllTask(tasks = []): global CNT global LABELMAP # clear all register related in PLC clear_batch() CNT = 0 LABELMAP = [] #first get last put tasks.reverse() print("putAllTask: ", tasks) task = tasks[0] destLabel = list(task.keys())[0] if 'Return' == destLabel: print("Return Task!") return #second round endDest, layerDest = getEndStopLayer(destLabel) taskBody = task[destLabel] tasktype = taskBody["typetask"] if 1 == tasktype: # little box LABELMAP = labelMapBigDisk + labelMapLittleDisk + labelMapLittleBox elif 3 == tasktype: # big box LABELMAP = labelMapBigDisk + labelMapLittleDisk + labelMapBigBox else: print("Cannot Match") # print("LABELMAP: ", LABELMAP) vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 放 vl_output[0] = 2 #if return single, first need to get a box if 1 == checkMoveArm(destLabel): #放单只试剂,需要先取一个框 vl_output[0] = 1 # #是否经过玻璃门 # vl_output[1] = checkPassDoor(endDest) #取框层数 vl_output[2] = layerDest #手臂是否需要动作 vl_output[3] = checkMoveArm(destLabel) status = readStatus() start = status[2] startStop = getAgvStop(start) #是否经过玻璃门 # vl_output[1] = checkPassDoor(end) vl_output[1] = checkPassDoor(startStop, endDest) paths = genPath(startStop, endDest) print("Path2: ", paths) cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 print("T2: ", vl_output) write_batch(vl_output) if 1 == checkMoveArm(destLabel): totalTask = len(tasks) vl_output = [] for _ in range(100): vl_output.append(0) # total tasks vl_output[0] = totalTask idx = 1 for task in tasks: destLabel = list(task.keys())[0] #check AGV坐标系统 for who to get diff tasktype = task[destLabel]["typetask"] diff = 0 if 1 == tasktype: # 小框 diff = 300 elif 3 == tasktype: # 大框 diff = 400 else: print("putAllTask Cannot match taskType: ", tasktype) #AGV Related Operation getLabel = await getHoleDestNumber(destLabel) putLabel = int(destLabel.split("-")[-1]) + diff print("putAllTask getLabel putLabel ", destLabel, getLabel, putLabel) if 0 > putLabel: raise Exception("Cannot find avaible Hole!") vl_output[idx] = getLabel vl_output[idx + 1] = putLabel vl_output[idx + 2] = task[destLabel]["height"] vl_output[idx + 3] = task[destLabel]["cap"] #update next task index idx = idx + 4 print("putAllTask Sub Tasks: ", vl_output) write_task_batch(vl_output) #clear final task clearCmd() #if need to get single bottle, # return box after get task finish if 1 == checkMoveArm(destLabel): #return box after get returnBox(paths[-1], layerDest) clearCmd() async def clearHoles(): holes = await Hole.all().filter(is_active = True) for hole in holes: hole.is_active = False await hole.save() vacancies = await Vacancy.all() for vacany in vacancies: await vacany.holes.clear() async def doJob(obj): print("Obj: ", obj) try: assignment = obj print("1 assignment ", assignment) if assignment: # clear previous holes # await clearHoles() agvs = await Agv.filter( agvid = assignment["agvid"], is_valid = True, is_active = True, ) agv = None if len(agvs) > 0: agv = agvs[0] agv.curorder = assignment["orderid"] agv.curitinerary = assignment["itinerary"] await agv.save() else: agv = await Agv.create( agvid = assignment["agvid"], curorder = assignment["orderid"], curitinerary = assignment["itinerary"] ) wholeBoxLabel = None wholeBoxTask = None taskDic = {} print("2 assignment ", assignment["cmd"]) #Combine all task in same box for task in assignment["cmd"]: print("Task: ", task) destLabel = list(task.keys())[0] parts = task[destLabel]["coordinates"].split("-") # change label '01-0154-1-1' -> '01-0154-1' if len(parts) > 3: taskLabel = "-".join(parts[0:3]) else: wholeBoxLabel = "-".join(parts) wholeBoxTask = task continue try: taskDic[taskLabel].append(task) except: taskDic[taskLabel] = [task] taskDicKeys = list(taskDic.keys()) taskDicKeys.sort() #Whole get task will put at the end of task list if wholeBoxLabel and wholeBoxTask: taskDic[wholeBoxLabel] = [wholeBoxTask] taskDicKeys.append(wholeBoxLabel) print("3 assignment ", taskDicKeys) for key in taskDicKeys: await getAllTask(taskDic[key]) #where to put in AGV plate in getting task !!! #where to get from AGV plate in putting task !!! ################# ### put whole task! ################# print("4 Return Box") wholeBoxLabel = None wholeBoxTask = None taskDic = {} #Combine all task in same box for task in assignment["cmd"]: print("Task: ", task) destLabel = list(task.keys())[0] parts = destLabel.split("-") # change label '01-0154-1-1' -> '01-0154-1' if len(parts) > 3: taskLabel = "-".join(parts[0:3]) else: wholeBoxLabel = "-".join(parts) wholeBoxTask = task continue try: taskDic[taskLabel].append(task) except: taskDic[taskLabel] = [task] taskDicKeys = list(taskDic.keys()) taskDicKeys.sort() #Whole get task will put at the end of task list if wholeBoxLabel and wholeBoxTask: taskDic[wholeBoxLabel] = [wholeBoxTask] taskDicKeys.insert(0, wholeBoxLabel) print("5 assignment ", taskDicKeys) for key in taskDicKeys: await putAllTask(taskDic[key]) # await clearHoles() # Job is Done return True else: # Job Failed return False except Exception as e: traceback.print_exc() print("getassgin: ", e) # Job Failed return False @agv_router.get("/getassgin") async def getassgin(): res = requests.get(endpoint_getassgin) obj = None if res.status_code < 300: obj = res.json() #do job in sync process if obj and "data" in obj.keys() \ and "id" in obj["data"].keys(): #clear holes await clearHoles() status = await doJob(obj) #clear holes await clearHoles() try: assignment_id = obj["data"]["id"] if status: print("Assignment {} is done!".format(assignment_id)) #tell schedule task is done res = requests.get(endpoint_done + assignment_id) objDone = None if res.status_code < 300: objDone = res.json() print("objDone: ", objDone) else: print("Assignment {} is failed!".format(assignment_id)) #tell schedule task is Failed res = requests.get(endpoint_failed + assignment_id) objDone = None if res.status_code < 300: objDone = res.json() print("objFailed: ", objDone) except Exception as e: traceback.print_exc() print("getassgin: ", e) return respond_to(code=501, data=e) return respond_to(code=res.status_code, data=obj) def task(): print("Run task!") os.system("curl http://127.0.0.1:8003/api/scheduler/agv/getassgin") @agv_router.get("/asyncassgin") async def asyncassgin(): # create a new daemon process process = Process(target=task, daemon=True) # start the new process process.start() return respond_to(data={"status": "Hello World!"}) @agv_router.get("/done/{assignment_id}") async def get_done(assignment_id: str): # print("assignment_id: ", endpoint_done + assignment_id) res = requests.get(endpoint_done + assignment_id) obj = None if res.status_code < 300: obj = res.json() return respond_to(code=res.status_code, data=obj) #'http://localhost:8000/api/scheduler/assign/done/e56ea677-4dd1-46e6-8e4f-c7f25ff5893a' @agv_router.get("/failed/{assignment_id}") async def get_failed(assignment_id: str): # print("assignment_id: ", endpoint_failed + assignment_id) res = requests.get(endpoint_failed + assignment_id) obj = None if res.status_code < 300: obj = res.json() return respond_to(code=res.status_code, data=obj) @agv_router.get('/list', summary="列出所有AGV小车的状态") async def index(request: Request, page_no: int = 1, page_size: int = 20): """ 列出所有AGV小车的状态 :param page_no: 1 :param page_size: 20 :return: """ offset = (page_no - 1) * page_size query = QuerySet(Agv).filter(is_valid=True, is_active=True) count = await query.count() agvs = await query.limit(page_size).offset(offset) return respond_to(code=200, data=dict(count=count, data=agvs)) @agv_router.post("/oneloop", summary='整箱取放') async def oneloop(request: Request, fullOrder: FullOrder): orderType = fullOrder.ordertype_start layer = fullOrder.layer_start end = fullOrder.stop_start vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 vl_output[0] = orderType # #是否经过玻璃门 # vl_output[1] = checkPassDoor(end) #取框层数 vl_output[2] = layer #手臂是否需要动作 vl_output[3] = 2 #D21010-D21059 #AGV站点号 # vl_output[10] = 311 status = readStatus() start = status[2] startStop = getAgvStop(start) #是否经过玻璃门 # vl_output[1] = checkPassDoor(end) # vl_output[1] = checkPassDoor(start, end) vl_output[1] = checkPassDoor(startStop, end) paths = genPath(startStop, end) print("Path: ", paths) cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 print("T1: ", vl_output) write_batch(vl_output) clearCmd() #second round orderType = fullOrder.ordertype_end layer = fullOrder.layer_end end = fullOrder.stop_end vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 vl_output[0] = orderType #是否经过玻璃门 # vl_output[1] = checkPassDoor(end) #取框层数 vl_output[2] = layer #手臂是否需要动作 vl_output[3] = 2 #D21010-D21059 #AGV站点号 # vl_output[10] = 311 status = readStatus() start = status[2] startStop = getAgvStop(start) #是否经过玻璃门 # vl_output[1] = checkPassDoor(end) vl_output[1] = checkPassDoor(startStop, end) paths = genPath(startStop, end) print("Path: ", paths) cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 print("T1: ", vl_output) write_batch(vl_output) clearCmd() return respond_to(data={"status": "Hello World!"}) def taskLoop(): print("Run task oneloop!") os.system("curl http://127.0.0.1:8003/api/scheduler/agv/oneloop") @agv_router.get("/asynoneloop") async def asynoneloop(): # create a new daemon process process = Process(target=taskLoop, daemon=True) # start the new process process.start() return respond_to(data={"status": "Hello World!"}) def doTask(getStop, end, layer = 1): vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 vl_output[0] = 1 #是否经过玻璃门 vl_output[1] = 2 #取框层数 vl_output[2] = layer #手臂是否需要动作 vl_output[3] = 2 #D21010-D21059 #AGV站点号 # vl_output[10] = 311 status = readStatus() start = status[2] startStop = getAgvStop(start) paths = genPath(startStop, getStop) print("Path: ", paths) cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 print("T1: ", vl_output) write_batch(vl_output) clearCmd() ################# vl_output = [] for _ in range(100): vl_output.append(0) #任务类型 vl_output[0] = 2 #是否经过玻璃门 vl_output[1] = 2 #取框层数 vl_output[2] = layer #手臂是否需要动作 vl_output[3] = 2 #D21010-D21059 #AGV站点号 # vl_output[10] = 311 status = readStatus() start = status[2] startStop = getAgvStop(start) paths = genPath(startStop, end) print("Path: ", paths) cnt = 10 for path in paths: vl_output[cnt] = path cnt = cnt + 1 print("T1: ", vl_output) write_batch(vl_output) clearCmd() #摆框 @agv_router.post("/putbox", summary='摆框') async def putbox(request: Request, putboxm: PutboxM): clear_batch() stops = putboxm.stops print("stops: ", stops) for stop in putboxm.stops: print("Current Stop: ", stop) doTask(putboxm.start, stop) return respond_to(data={"status": "Hello World!"}) async def mainJob(obj): print("main(args): \n 》》》》", obj) #do job in sync process if obj and "id" in obj.keys(): #clear holes await clearHoles() status = await doJob(obj) #clear holes await clearHoles() try: assignment_id = obj["id"] if status: print("Assignment {} is done!".format(assignment_id)) #tell schedule task is done res = requests.get(endpoint_done + assignment_id) objDone = None if res.status_code < 300: objDone = res.json() print("objDone: ", objDone) else: print("Assignment {} is failed!".format(assignment_id)) #tell schedule task is Failed res = requests.get(endpoint_failed + assignment_id) objDone = None if res.status_code < 300: objDone = res.json() print("objFailed: ", objDone) except Exception as e: traceback.print_exc() print("getassgin: ", e) return respond_to(code=501, data=e) from tortoise import Tortoise, run_async async def init(): # Here we create a SQLite DB using file "db.sqlite3" # also specify the app name of "models" # which contain models from "app.models" await Tortoise.init( config={ "connections": { "default": setting.DB_URL }, "apps": { "models": { "models": ["aerich.models", "models"], "default_connection": "default" } }, 'use_tz': False, # 'timezone': setting.TIMEZONE } ) # Generate the schema # await Tortoise.generate_schemas() def taskPost(args): # run_async is a helper function to run simple async Tortoise scripts. run_async(init()) print("taskPost(args): ", args) asyncio.run( mainJob(args) ) @agv_router.post("/postassgin", summary='推送数据并执行') async def postassgin(assign: assignM): # create a new daemon process process = Process(target=taskPost, daemon=True, args=(assign.data,)) # start the new process process.start() return respond_to(data={"status": "Hello World!"}) def runCharge(): print("runCharge: ") asyncio.run( charge() ) @agv_router.get("/asynccharge", summary='异步充电') async def asynccharge(): # create a new daemon process process = Process(target=runCharge, daemon=True, args=()) # start the new process process.start() return respond_to(data={"status": "异步充电"}) def runWait(): print("runWait: ") asyncio.run( wait() ) @agv_router.get("/asyncwait", summary='异步去一号点等待') async def asyncwait(): # create a new daemon process process = Process(target=runWait, daemon=True, args=()) # start the new process process.start() return respond_to(data={"status": "异步去一号点等待"})