Commit 23d1dc84 authored by 张晓彤's avatar 张晓彤

代码优化&穿越装载区

parent 77024ac7
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# @Software: PyCharm # @Software: PyCharm
from data.para_config import * from data.para_config import *
from equipment import DumpInfo from data.equipment import DumpInfo
from data.dispatchInfo import DispatchInfo from data.dispatchInfo import DispatchInfo
# from core.group import Group # from core.group import Group
from util import CoreException from util import CoreException
...@@ -181,20 +181,13 @@ class ExpectedTime(AlgorithmBase): ...@@ -181,20 +181,13 @@ class ExpectedTime(AlgorithmBase):
# self.logger.error(es) # self.logger.error(es)
try: try:
# 全局挖机可用时间 dict group_excavator_avl_time_ls = self.get_excavators_avl_time()
excavator_val_time_dict = self.pre_sch.get_excavator_avl_time()
# 局部挖机可用时间 list
group_excavator_avl_time_ls = np.full(len(self.group.group_excavators), 0.0)
self.logger.info("self.group.excavator_uuid_index_dict") # TODO: 获取车辆位置信息
self.logger.info(self.group.excavator_uuid_index_dict) truck_locate = self.group.truck_info_list[truck_id].get_area_locate()
for excavator_id, excavator_index in self.group.excavator_uuid_index_dict.items():
group_excavator_avl_time_ls[excavator_index] = excavator_val_time_dict[excavator_id]
# 车辆驶往各目的地时间 # 车辆驶往各目的地时间
truck_reach_time_ls = 60 * self.group.park_to_excavator_distance[0, :] / 1000 / \ truck_reach_time_ls = 60 * self.group.park_to_excavator_distance[truck_locate, :] / 1000 / \
self.truck.empty_speed[truck_id] + truck_avl_time self.truck.empty_speed[truck_id] + truck_avl_time
# 计算车辆得到服务时间 # 计算车辆得到服务时间
...@@ -357,6 +350,17 @@ class ExpectedTime(AlgorithmBase): ...@@ -357,6 +350,17 @@ class ExpectedTime(AlgorithmBase):
return transport_value return transport_value
def get_excavators_avl_time(self):
# 全局挖机可用时间 dict
excavator_val_time_dict = self.pre_sch.get_excavator_avl_time()
# 局部挖机可用时间 list
group_excavator_avl_time_ls = np.full(len(self.group.group_excavators), 0.0)
self.logger.info("self.group.excavator_uuid_index_dict")
self.logger.info(self.group.excavator_uuid_index_dict)
for excavator_id, excavator_index in self.group.excavator_uuid_index_dict.items():
group_excavator_avl_time_ls[excavator_index] = excavator_val_time_dict[excavator_id]
return group_excavator_avl_time_ls
class DistributionRatio(object): class DistributionRatio(object):
""" """
......
from flask import Flask, request from flask import Flask, request
from flask.json import jsonify from flask.json import jsonify
from data.para_config import * from data.equipment.truck import TruckInfo
from equipment.truck import TruckInfo from data.equipment.excavator import ExcavatorInfo
from equipment.excavator import ExcavatorInfo from data.equipment.dump import DumpInfo
from equipment.dump import DumpInfo
from core.dispatcher import PreSchedule from core.dispatcher import PreSchedule
from core.group import Group from core.group import Group
from flask_caching import Cache from flask_caching import Cache
from alg.algorithm import ExpectedTime from alg.algorithm import ExpectedTime
from data.dispatchInfo import DispatchInfo
from core.submit import DispatchSubmission from core.submit import DispatchSubmission
from core.group import GroupDispatcher from core.group import GroupDispatcher
from core.group import group_direct2redis from core.group import group_direct2redis
import uuid
from core.util import POST from core.util import POST
from util.area_analysis import * from util.area_analysis import *
......
...@@ -7,25 +7,25 @@ ...@@ -7,25 +7,25 @@
"excavator_target_mass": 5000 "excavator_target_mass": 5000
}, },
"mysql": { "mysql": {
"host": "172.16.0.51", "host": "172.16.0.103",
"port": "3306", "port": "3306",
"user": "root", "user": "root",
"password": "Huituo@123", "password": "Huituo@123",
"database": "ht_zhunneng" "database": "ht_zhunneng"
}, },
"postgresql": { "postgresql": {
"host": "172.16.0.51", "host": "172.16.0.103",
"port": "5432", "port": "5432",
"user": "postgres", "user": "postgres",
"password": "Huituo@123", "password": "Huituo@123",
"database": "gis_zhunneng" "database": "gis_zhunneng"
}, },
"redis": { "redis": {
"host": "172.16.0.51", "host": "172.16.0.103",
"password": "Huituo@123" "password": "Huituo@123"
}, },
"gothrough": { "gothrough": {
"closer_area_name": "哈1010平盘", "closer_area_name": "哈装测试",
"further_area_name": "哈1026平盘" "further_area_name": "哈装2"
} }
} }
\ No newline at end of file
...@@ -10,7 +10,7 @@ from data.dispatchInfo import DispatchInfo ...@@ -10,7 +10,7 @@ from data.dispatchInfo import DispatchInfo
from core.group import Group from core.group import Group
from alg.algorithm import ExpectedTime from alg.algorithm import ExpectedTime
from settings import get_logger from settings import get_logger
from equipment import TruckInfo, ExcavatorInfo, DumpInfo from data.equipment import TruckInfo, ExcavatorInfo, DumpInfo
from core.schedule import PreSchedule from core.schedule import PreSchedule
from graph.graph_load import graph_construct from graph.graph_load import graph_construct
from core.group import GroupDispatcher from core.group import GroupDispatcher
...@@ -80,7 +80,7 @@ class Dispatcher: ...@@ -80,7 +80,7 @@ class Dispatcher:
""" """
for group in self.group_list.values(): for group in self.group_list.values():
# try: try:
# truck_dispatch_plan_dict = group.group_dispatch(ExpectedTime) # truck_dispatch_plan_dict = group.group_dispatch(ExpectedTime)
...@@ -92,9 +92,9 @@ class Dispatcher: ...@@ -92,9 +92,9 @@ class Dispatcher:
self.logger.error(f'分组 {group.group_id} 调度异常') self.logger.error(f'分组 {group.group_id} 调度异常')
continue continue
# except Exception as es: except Exception as es:
# self.logger.error(es) self.logger.error(es)
# self.logger.error(f'分组{group.group_id} 调度异常') self.logger.error(f'分组{group.group_id} 调度异常')
# 派车计划输出 # 派车计划输出
self.submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict) self.submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict)
......
...@@ -9,13 +9,11 @@ ...@@ -9,13 +9,11 @@
from data.dispatchInfo import * from data.dispatchInfo import *
from bidict import bidict from bidict import bidict
from alg.algorithm import AlgorithmBase, DistributionRatio from alg.algorithm import AlgorithmBase, DistributionRatio
import numpy as np
# from settings import get_logger # from settings import get_logger
from data.para_config import get_value
from core.util import * from core.util import *
from typing import Mapping, List from typing import Mapping, List
from util import CoreException from util import CoreException
from equipment import TruckInfo, ExcavatorInfo, DumpInfo from data.equipment import TruckInfo, ExcavatorInfo, DumpInfo
from core.schedule import PreSchedule from core.schedule import PreSchedule
from graph.topo_graph import Topo from graph.topo_graph import Topo
from util.area_analysis import * from util.area_analysis import *
...@@ -112,12 +110,22 @@ class CurrentTruck: ...@@ -112,12 +110,22 @@ class CurrentTruck:
""" """
def __init__(self, truck_id: str, group_id: str, trip: List[int], task: int, state: int): def __init__(self, truck_id: str, group_id: str, trip: List[int], task: int, state: int,
lane_locate: str, area_locate: str, name: str, combined_excavator: str, combined_dump: str,
combined_load_area: str, combined_unload_area: str):
self._lane_locate = lane_locate
self._area_locate = area_locate
self._truck_id = truck_id self._truck_id = truck_id
self._group_id = group_id self._group_id = group_id
self._trip = trip self._trip = trip
self._task = task self._task = task
self._state = state self._state = state
self._name = name
self._combined_excavator = combined_excavator
self._combined_dump = combined_dump
self.has_changed = False
self._combined_load_area = combined_load_area
self._combined_unload_area = combined_unload_area
def get_truck_id(self): def get_truck_id(self):
return self._truck_id return self._truck_id
...@@ -134,6 +142,30 @@ class CurrentTruck: ...@@ -134,6 +142,30 @@ class CurrentTruck:
def get_sate(self): def get_sate(self):
return self._state return self._state
def get_lane_locate(self):
return self._lane_locate
def get_area_locate(self):
return self._area_locate
def get_name(self):
return self._name
def get_combined_excavator(self):
return self._combined_excavator
def get_combined_dump(self):
return self._combined_dump
def get_has_changed(self):
return self.has_changed
def get_combined_load_area(self):
return self._combined_load_area
def get_combined_unload_area(self):
return self._combined_unload_area
class Group: class Group:
""" """
...@@ -349,8 +381,15 @@ class GroupDispatcher: ...@@ -349,8 +381,15 @@ class GroupDispatcher:
""" """
self.logger = logging.getLogger("zxt.GroupDispatcher") self.logger = logging.getLogger("zxt.GroupDispatcher")
self.group = group self.group = group
self.gothrough_active = False
if self.group.topo is not None: if self.group.topo is not None:
self.redispatcher = ReDispatcher(self.group) self.redispatcher = ReDispatcher(self.group)
with open(json_file, encoding='UTF-8') as f:
load_value = json.load(f)
if "gothrough" in load_value:
self.gothrough_active = True
self.gothroghdispatcher = GoThroughDispatcher(self.group) self.gothroghdispatcher = GoThroughDispatcher(self.group)
def group_dispatch(self, Solver) -> Mapping[str, List[str]]: def group_dispatch(self, Solver) -> Mapping[str, List[str]]:
...@@ -362,16 +401,93 @@ class GroupDispatcher: ...@@ -362,16 +401,93 @@ class GroupDispatcher:
""" """
# init truck dispatch plan dictionary. # init truck dispatch plan dictionary.
truck_dispatch = {} truck_dispatch_list = {}
# init dictionary including all truck obj. within this group.
self.group.truck_info_list = {}
assert issubclass(Solver, AlgorithmBase) assert issubclass(Solver, AlgorithmBase)
solver = Solver(self.group, self.group.truck, self.group.pre_sch) # solver algorithm init solver = Solver(self.group, self.group.truck, self.group.pre_sch) # solver algorithm init
self.logger.info(f'分组 {self.group.group_name} 调度计算-调度模式 {self.group.group_mode}') self.logger.info(f'分组 {self.group.group_name} 调度计算-调度模式 {self.group.group_mode}')
# construct all truck obj. within this group
self.group_truck_construct()
# assignment a dispatch plan for each truck
for truck_id in list(self.group.group_trucks):
# Construct a test case for redispatch
# truck_task = 0
# if truck_id != "f704aa5e-24d9-4822-b634-ae81ca5ff0be":
# self.truck.get_truck_locate_dict()[truck_id] = "8961f641-c134-8be8-f4eb-95e6e2c374b7"
# self.truck.truck_is_temp[truck_id] = False
# self.truck.truck_current_state[truck_id] = 2
# except Exception as es:
# self.logger.error("车辆调度信息读取异常")
# self.logger.error(es)
if truck_id not in self.group.truck_info_list:
self.logger.error(f'group.truck_info_list 不存在车辆 {truck_id}')
self.logger.info(self.group.truck_info_list.keys())
continue
truck_info = self.group.truck_info_list[truck_id]
try:
self.truck_dispatch(solver, truck_dispatch_list, truck_id, truck_info)
except Exception as es:
self.logger.error("调度调用异常")
self.logger.error(es)
return truck_dispatch_list
def truck_dispatch(self, solver, truck_dispatch_list, truck_id, truck_info):
"""
Receive a alg. solver and a truck obj.
According to given dispatch mode assign a proper dispatch plan for the truck.
:param solver:
:param truck_dispatch_list:
:param truck_id:
:param truck_info:
"""
# get truck task and trip
truck_task = truck_info.get_task()
truck_trip = truck_info.get_trip()
# 全智能模式
if self.group.group_mode == 1:
self.logger.info("全智能模式调度")
self.full_dynamic_mode(truck_id, solver, truck_dispatch_list, truck_info, truck_task, truck_trip)
# 空车智能模式
elif self.group.group_mode == 2:
self.logger.info("空车智能模式调度")
self.semi_dynamic_mode(truck_id, solver, truck_dispatch_list, truck_info, truck_task, truck_trip)
# 定铲派车
elif self.group.group_mode == 3:
self.logger.info("固定模式调度")
try:
truck_dispatch_list[truck_id] = DispatchInfo.get_truck_match(truck_id)
except Exception as es:
self.logger.error("固定派车-计算异常")
self.logger.error(es)
# 分流配比模式
elif self.group.group_mode == 4:
self.logger.info("分流配比模式调度")
self.ratio_mode(truck_id, truck_dispatch_list, truck_task)
def group_truck_construct(self):
"""
Construct truck obj. for each physical mining truck within dispatching info.
and store them in a dictionary.
"""
# init dictionary including all truck obj. within this group.
self.group.truck_info_list = {}
for truck_id in list(self.group.group_trucks): for truck_id in list(self.group.group_trucks):
self.logger.info(f'调度车辆 {truck_id}') self.logger.info(f'调度车辆 {truck_id}')
...@@ -402,53 +518,76 @@ class GroupDispatcher: ...@@ -402,53 +518,76 @@ class GroupDispatcher:
else: else:
truck_task = truck_task_list[truck_id] truck_task = truck_task_list[truck_id]
# Construct a truck obj. and add it to group truck dictionary. # get truck lane_id from truck obj.
truck_info = CurrentTruck(truck_id, self.group.group_id, truck_trip, truck_task, truck_lane_locate_dict = self.group.truck.get_truck_lane_locate_dict()
self.group.truck.get_truck_current_state()[truck_id])
self.group.truck_info_list[truck_id] = truck_info if truck_id not in truck_lane_locate_dict:
self.logger.warning(f'truck.truck lane dict 中不存在矿卡 {truck_id}')
# continue
truck_lane_locate = None
else:
truck_lane_locate = truck_lane_locate_dict[truck_id]
# Construct a test case for redispatch # get truck area locate from truck obj.
# truck_task = 0 truck_area_locate_dict = self.group.truck.get_truck_area_locate_dict()
# if truck_id != "f704aa5e-24d9-4822-b634-ae81ca5ff0be":
# self.truck.get_truck_locate_dict()[truck_id] = "8961f641-c134-8be8-f4eb-95e6e2c374b7"
# self.truck.truck_is_temp[truck_id] = False
# self.truck.truck_current_state[truck_id] = 2
# except Exception as es: if truck_id not in truck_area_locate_dict:
# self.logger.error("车辆调度信息读取异常") self.logger.warning(f'truck.truck area dict 中不存在矿卡 {truck_id}')
# self.logger.error(es) # continue
truck_area_locate = None
else:
truck_area_locate = truck_area_locate_dict[truck_id]
try: # get truck name form dict.
# 全智能模式 truck_uuid_to_name_dict = get_value("truck_uuid_to_name_dict")
if self.group.group_mode == 1:
self.logger.info("全智能模式调度")
self.full_dynamic_mode(truck_id, solver, truck_dispatch, truck_info, truck_task, truck_trip)
# 空车智能模式 # 获取请调车辆名
elif self.group.group_mode == 2: if truck_id not in truck_uuid_to_name_dict:
self.logger.info("空车智能模式调度") # raise CoreException(102, f'truck_uuid_to_name_dict 缺失车辆 {truck_id} 信息')
self.semi_dynamic_mode(truck_id, solver, truck_dispatch, truck_info, truck_task, truck_trip) self.logger.error(f'truck_uuid_to_name_dict 缺失车辆 {truck_id} 信息')
# 定铲派车 truck_name = truck_uuid_to_name_dict[truck_id]
elif self.group.group_mode == 3:
self.logger.info("固定模式调度")
try:
truck_dispatch[truck_id] = DispatchInfo.get_truck_match(truck_id)
except Exception as es:
self.logger.error("固定派车-计算异常")
self.logger.error(es)
# 分流配比模式
elif self.group.group_mode == 4:
self.logger.info("分流配比模式调度")
self.ratio_mode(truck_id, truck_dispatch, truck_task)
except Exception as es: # 获取车辆当前派车计划
self.logger.error("调度调用异常") if truck_task in [0, 1, 5]:
self.logger.error(es)
excavator_index = int(truck_trip[1])
dump_index = int(truck_trip[0])
else:
dump_index = int(truck_trip[1])
excavator_index = int(truck_trip[0])
if excavator_index == -1:
current_truck_goto_excavator_id = None
current_load_area_id = None
else:
# if excavator_index not in self.group.excavator_info.excavator_index_to_uuid_dict:
# # raise CoreException(111, f'excavator_index_to_uuid_dict 缺失 {excavator_index} 号挖机信息')
# self.logger.error(f'excavator_index_to_uuid_dict 缺失 {excavator_index} 号挖机信息')
current_truck_goto_excavator_id = self.group.excavator_info.excavator_index_to_uuid_dict[
excavator_index]
current_load_area_id = DispatchInfo.excavator_load_dict[current_truck_goto_excavator_id]
if dump_index == -1:
current_truck_goto_dump_id = None
current_unload_area_id = None
else:
# if dump_index not in self.group.dump_info.dump_index_to_uuid_dict:
# # raise CoreException(111, f'dump_index_to_uuid_dict 缺失 {dump_index} 号卸点信息')
# self.logger.error(f'dump_index_to_uuid_dict 缺失 {dump_index} 号卸点信息')
current_truck_goto_dump_id = self.group.dump_info.dump_index_to_uuid_dict[dump_index]
current_unload_area_id = DispatchInfo.dump_unload_area_dict[current_truck_goto_dump_id]
# return dispatch plan # Construct a truck obj. and add it to group truck dictionary.
return truck_dispatch truck_info = CurrentTruck(truck_id, self.group.group_id, truck_trip, truck_task,
self.group.truck.get_truck_current_state()[truck_id], truck_lane_locate,
truck_area_locate, truck_name, combined_excavator=current_truck_goto_excavator_id,
combined_dump=current_truck_goto_dump_id, combined_load_area=current_load_area_id,
combined_unload_area=current_unload_area_id)
self.group.truck_info_list[truck_id] = truck_info
def ratio_mode(self, i, truck_dispatch, truck_task): def ratio_mode(self, i, truck_dispatch, truck_task):
next_exactor_id = DispatchInfo.get_truck_exactor(i) # 获取该卡车对应的exactor_id next_exactor_id = DispatchInfo.get_truck_exactor(i) # 获取该卡车对应的exactor_id
...@@ -494,6 +633,16 @@ class GroupDispatcher: ...@@ -494,6 +633,16 @@ class GroupDispatcher:
def semi_dynamic_mode(self, i, s, truck_dispatch, truck_info, truck_task, truck_trip): def semi_dynamic_mode(self, i, s, truck_dispatch, truck_info, truck_task, truck_trip):
# TODO:和全智能调度很像,是否可以合并合; # TODO:和全智能调度很像,是否可以合并合;
# 获取车辆任务信息
try:
truck_task = truck_info.get_task()
if truck_task is None:
raise Exception("车辆任务信息丢失")
except Exception as es:
self.logger.error(es)
truck_dispatch[i] = [None, None]
return
# 加入二次调度; # 加入二次调度;
if truck_task in [-2, 3, 4, 5]: if truck_task in [-2, 3, 4, 5]:
try: try:
...@@ -526,24 +675,39 @@ class GroupDispatcher: ...@@ -526,24 +675,39 @@ class GroupDispatcher:
def full_dynamic_mode(self, i: str, s: AlgorithmBase, truck_dispatch: Mapping[str, List[str]], def full_dynamic_mode(self, i: str, s: AlgorithmBase, truck_dispatch: Mapping[str, List[str]],
truck_info: CurrentTruck, truck_task: int, truck_trip: List[int]): truck_info: CurrentTruck, truck_task: int, truck_trip: List[int]):
# 车辆停止或者车辆位于卸载区内, 调度车辆前往装载区
if truck_task in [-2, 3, 4, 5]: # 获取车辆任务信息
# if truck_task == 3 and self.group.truck.truck_current_state[i] == 2:
if truck_task == 3:
if self.group.topo is not None:
try: try:
truck_locate = self.group.truck.get_truck_locate_dict()[i] truck_task = truck_info.get_task()
if truck_task is None:
raise Exception("车辆任务信息丢失")
except Exception as es: except Exception as es:
self.logger.error("车辆位置信息丢失")
self.logger.error(es) self.logger.error(es)
truck_dispatch[i] = [None, None] truck_dispatch[i] = [None, None]
return return
# 获取车辆位置信息
try:
truck_locate = self.group.truck.get_truck_lane_locate_dict()[i]
except Exception as es:
self.logger.error("车辆位置信息丢失")
self.logger.error(es)
truck_locate = None
# 获取车辆临时字段
try: try:
truck_is_temp = self.group.truck.truck_is_temp[i] truck_is_temp = self.group.truck.truck_is_temp[i]
except Exception as es: except Exception as es:
truck_is_temp = False truck_is_temp = False
self.logger.error("车辆临时字段异常") self.logger.error("车辆临时字段异常")
self.logger.error(es) self.logger.error(es)
# 车辆停止或者车辆位于卸载区内, 调度车辆前往装载区
if truck_task in [-2, 3, 4, 5]:
# if truck_task == 3 and self.group.truck.truck_current_state[i] == 2:
if truck_task == 3:
if self.group.topo is not None and truck_locate is not None:
self.logger.info(f'车辆位置 {truck_locate}') self.logger.info(f'车辆位置 {truck_locate}')
self.logger.info(f'车辆状态 {self.group.truck.truck_current_state[i]}') self.logger.info(f'车辆状态 {self.group.truck.truck_current_state[i]}')
self.logger.info(f'车辆临时 {truck_is_temp} {type(truck_is_temp)}') self.logger.info(f'车辆临时 {truck_is_temp} {type(truck_is_temp)}')
...@@ -551,11 +715,13 @@ class GroupDispatcher: ...@@ -551,11 +715,13 @@ class GroupDispatcher:
if (truck_locate in self.group.topo.cross_bf_lanes) and (not truck_is_temp): if (truck_locate in self.group.topo.cross_bf_lanes) and (not truck_is_temp):
# self.redispatch_to_dump(i, truck_dispatch, truck_locate, truck_trip) # self.redispatch_to_dump(i, truck_dispatch, truck_locate, truck_trip)
self.redispatcher.redispatch_to_dump(i, truck_dispatch, truck_locate, truck_trip) self.redispatcher.redispatch_to_dump(i, truck_dispatch, truck_locate, truck_trip)
self.group.truck_info_list[i].has_changed = True
else: else:
pass pass
else: else:
try: try:
if i in self.group.truck.truck_excavator_bind: if i in self.group.truck.truck_excavator_bind:
# 处理车辆-挖机绑定调度
try: try:
if i not in self.group.truck.truck_excavator_bind: if i not in self.group.truck.truck_excavator_bind:
raise CoreException(102, f'truck.group_excavators bind 中不存在 {i}') raise CoreException(102, f'truck.group_excavators bind 中不存在 {i}')
...@@ -565,6 +731,7 @@ class GroupDispatcher: ...@@ -565,6 +731,7 @@ class GroupDispatcher:
return return
next_excavator_id = self.group.truck.truck_excavator_bind[i] next_excavator_id = self.group.truck.truck_excavator_bind[i]
else: else:
# 非绑定正常调度
next_excavator_value = s.solve(truck_info) next_excavator_value = s.solve(truck_info)
self.logger.info(f'车辆排斥修正 {i}, {self.group.truck_excavator_exclude_modify[i]}') self.logger.info(f'车辆排斥修正 {i}, {self.group.truck_excavator_exclude_modify[i]}')
min_index = np.argmin(next_excavator_value + self.group.truck_excavator_exclude_modify[i]) min_index = np.argmin(next_excavator_value + self.group.truck_excavator_exclude_modify[i])
...@@ -587,21 +754,25 @@ class GroupDispatcher: ...@@ -587,21 +754,25 @@ class GroupDispatcher:
elif truck_task in [0, 1, 2]: elif truck_task in [0, 1, 2]:
# if truck_task == 0 and self.group.truck.truck_current_state[i] == 2: # if truck_task == 0 and self.group.truck.truck_current_state[i] == 2:
if truck_task == 0: if truck_task == 0:
if self.group.topo is not None: if self.group.topo is not None and truck_locate is not None:
if i in self.group.truck.get_truck_locate_dict():
truck_locate = self.group.truck.get_truck_locate_dict()[i] # # 获取车辆位置信息
else: # if i in self.group.truck.get_truck_lane_locate_dict():
self.logger.error(f'车辆 {i} 位置信息丢失') # truck_locate = self.group.truck.get_truck_lane_locate_dict()[i]
truck_dispatch[i] = [None, None] # else:
return # self.logger.error(f'车辆 {i} 位置信息丢失')
# truck_dispatch[i] = [None, None]
# return
#
# # 获取车辆临时字段
# self.logger.info(self.group.truck.truck_is_temp)
# try:
# truck_is_temp = self.group.truck.truck_is_temp[i]
# except Exception as es:
# truck_is_temp = False
# self.logger.error("车辆临时字段异常")
# self.logger.error(es)
self.logger.info(self.group.truck.truck_is_temp)
try:
truck_is_temp = self.group.truck.truck_is_temp[i]
except Exception as es:
truck_is_temp = False
self.logger.error("车辆临时字段异常")
self.logger.error(es)
# 车辆当前位于交叉路口前,且排队等待 # 车辆当前位于交叉路口前,且排队等待
self.logger.info("潜在二次调度车辆状态") self.logger.info("潜在二次调度车辆状态")
self.logger.info(f'车辆 {i}') self.logger.info(f'车辆 {i}')
...@@ -611,22 +782,21 @@ class GroupDispatcher: ...@@ -611,22 +782,21 @@ class GroupDispatcher:
self.logger.info(self.group.topo.cross_bf_lanes) self.logger.info(self.group.topo.cross_bf_lanes)
self.logger.info(self.group.truck.truck_current_state) self.logger.info(self.group.truck.truck_current_state)
self.logger.info(truck_is_temp) self.logger.info(truck_is_temp)
# if (truck_locate in self.topo.cross_bf_lanes) and (self.truck.truck_current_state[truck_id] == 2) \
# and (not truck_is_temp):
# if (truck_locate in self.group.topo.cross_bf_lanes) and (
# self.group.truck.truck_current_state[i] == 2):
if (truck_locate in self.group.topo.cross_bf_lanes) and (not truck_is_temp): if (truck_locate in self.group.topo.cross_bf_lanes) and (not truck_is_temp):
self.logger.info("触发二次调度") self.logger.info("触发二次调度")
# self.redispatch_to_excavator(i, truck_dispatch, truck_locate)
self.redispatcher.redispatch_to_excavator(i, truck_dispatch, truck_locate) self.redispatcher.redispatch_to_excavator(i, truck_dispatch, truck_locate)
self.group.truck_info_list[i].has_changed = True
# 穿越装载区判断 # 穿越装载区判断
if self.gothrough_active:
self.gothroghdispatcher.update_lanes_info() self.gothroghdispatcher.update_lanes_info()
self.gothroghdispatcher.redispatch_request(request_truck_id=i, truck=self.group.truck) self.gothroghdispatcher.redispatch_request(request_truck_id=i, truck=self.group.truck,
truck_dispatch=truck_dispatch, truck_info=truck_info)
else: else:
pass pass
else: else:
# 车辆位于装载区内
try: try:
next_excavator_id = get_value("excavator_index_to_uuid_dict")[truck_trip[-1]] next_excavator_id = get_value("excavator_index_to_uuid_dict")[truck_trip[-1]]
next_unload_area_value = s.solve(truck_info) next_unload_area_value = s.solve(truck_info)
...@@ -666,172 +836,6 @@ class GroupDispatcher: ...@@ -666,172 +836,6 @@ class GroupDispatcher:
# TODO:车辆在空载状态是否应该如何计算,是计算下一次卸载区还是继续计算当前最优挖机 # TODO:车辆在空载状态是否应该如何计算,是计算下一次卸载区还是继续计算当前最优挖机
# def redispatch_to_dump(self, truck_id: str, truck_dispatch: Mapping[str, List[str]], truck_locate: str, truck_trip: List[int]):
# """
# redispatch truck to dumps.
# :param truck_id:
# :param truck_dispatch:
# :param truck_locate:
# :param truck_trip:
# :return:
# """
# # 当前绑定装载区
# if truck_trip[0] == -1:
# next_excavator_id = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id,
# isdeleted=0).first().exactor_id
# else:
# next_excavator_id = get_value("excavator_index_to_uuid_dict")[truck_trip[0]]
# # 当前绑定卸载区
# if truck_trip[-1] == -1:
# item = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id, isdeleted=0).first()
# current_dump_id = item.dump_id
# current_unload_area_id = item.unload_area_id
# else:
# current_dump_id = get_value("dump_index_to_uuid_dict")[truck_trip[-1]]
# current_unload_area_id = DispatchInfo.dump_unload_area_dict[current_dump_id]
# unload_area_dict, unload_area_lane_dict = self.group.topo.get_unload_target_node_real(truck_locate,
# current_unload_area_id,
# True)
# # 获取拥堵路段
# congestion_lane_dict = self.get_congestion_lanes()
# # 获取当前交叉口下一路段集合
# next_lane_list = get_cross_next_lanes(truck_locate)
# # 交叉口下一路段可达的装载区
# next_lane_load_area_dict = get_lane_reach_load_areas(unload_area_lane_dict,
# next_lane_list)
# # 排除下一个路段阻塞的装载区
# delete_congestion_load_area(congestion_lane_dict, unload_area_dict,
# next_lane_load_area_dict)
# min_trip_time = 10000000
# best_dump_id = current_dump_id
# for unload_area, value in unload_area_dict.items():
# # 车辆不需要掉头
# if value[-1] == 1 and unload_area in DispatchInfo.unload_area_dump_dict:
# dump_id = DispatchInfo.unload_area_dump_dict[unload_area]
#
# traveling_time = value[0] / heavy_speed
#
# now = float(
# (datetime.now() - self.group.pre_sch.start_time) / timedelta(hours=0, minutes=1,
# seconds=0))
# reach_time = now + traveling_time
#
# trip_time = max(reach_time,
# self.group.pre_sch.get_dump_avl_time()[dump_id]) - now
#
# if min_trip_time > trip_time:
# best_dump_id = dump_id
# next_unload_area_id = DispatchInfo.dump_unload_area_dict[best_dump_id]
# truck_dispatch[truck_id] = [next_excavator_id, next_unload_area_id]
# # res = redispatch_request(truck_id, next_excavator_id, next_unload_area_id)
# # self.logger.info(res)
# self.logger.info(f'二次调度结果 {truck_id}')
# self.logger.info(truck_dispatch[truck_id])
#
# def redispatch_to_excavator(self, truck_id, truck_dispatch, truck_locate):
# """
# redispatch truck to excavators.
# :param truck_id:
# :param truck_dispatch:
# :param truck_locate:
# :return:
# """
# # 当前绑定卸载区
# # if truck_trip[0] == -1:
# next_unload_area_id = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id,
# isdeleted=0).first().unload_area_id
# # else:
# # dump_id = get_value("dump_index_to_uuid_dict")[truck_trip[0]]
# # next_unload_area_id = get_value("dump_uuid_to_unload_area_uuid_dict")[dump_id]
# # 当前绑定装载区
# # if truck_trip[-1] == -1:
# item = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id, isdeleted=0).first()
# current_excavator_id = item.exactor_id
# current_load_area_id = item.load_area_id
# self.logger.info(f'truck_id {truck_id}')
# self.logger.info(f'current_load_area_id {current_load_area_id}')
# # else:
# # current_excavator_id = get_value("excavator_index_to_uuid_dict")[truck_trip[-1]]
# # current_load_area_id = DispatchInfo.excavator_load_dict[current_excavator_id]
# load_area_dict, load_area_lane_dict = self.group.topo.get_load_target_node_real(truck_locate,
# current_load_area_id, True)
# self.logger.info("所有可达装载区")
# self.logger.info(load_area_dict)
# # 获取拥堵路段
# congestion_lane_dict = self.get_congestion_lanes()
# # 获取当前交叉口下一路段集合
# next_lane_list = get_cross_next_lanes(truck_locate)
# # 交叉口下一路段可达的装载区
# next_lane_load_area_dict = get_lane_reach_load_areas(load_area_lane_dict, next_lane_list)
# # 排除下一个路段阻塞的装载区
# delete_congestion_load_area(congestion_lane_dict, load_area_dict,
# next_lane_load_area_dict)
# self.logger.info("剔除堵塞装载区")
# self.logger.info(load_area_dict)
# # 获取最佳挖机
# best_excavator_id = self.get_best_excavator(current_excavator_id, truck_id, load_area_dict)
# next_excavator_id = best_excavator_id
# truck_dispatch[truck_id] = [next_excavator_id, next_unload_area_id]
# self.logger.info(f'二次调度结果 {truck_id}')
# self.logger.info(truck_dispatch[truck_id])
#
# def get_best_excavator(self, current_excavator_id, truck_id, load_area_dict):
# """
# get best group_excavators
# :param current_excavator_id: 当前车辆配对挖机
# :param truck_id:
# :param load_area_dict: 备选装载区
# :return:
# """
# min_trip_time = 10000000
# best_excavator_id = current_excavator_id
# try:
# for load_area, value in load_area_dict.items():
# # 车辆不需要掉头
# if load_area in DispatchInfo.load_excavator_dict:
# excavator_id = DispatchInfo.load_excavator_dict[load_area]
# else:
# continue
# if value[-1] == 1 and excavator_id in self.group.group_excavators:
# traveling_time = 60 * (value[0] / 1000) / empty_speed
#
# self.logger.info(f'load_area {load_area}')
# self.logger.info(f'traveling_time {traveling_time}')
#
# now = float(
# (datetime.now() - self.group.pre_sch.start_time) / timedelta(hours=0, minutes=1, seconds=0))
#
# reach_time = now + traveling_time
#
# self.logger.info(f'reach_time {reach_time}')
#
# trip_time = max(reach_time,
# self.group.pre_sch.get_excavator_avl_time(truck_id=truck_id)[excavator_id]) - now
#
# self.logger.info(f'trip_time {trip_time}')
#
# if min_trip_time > trip_time:
# best_excavator_id = excavator_id
# min_trip_time = trip_time
#
# except Exception as es:
# self.logger.error("寻找最佳装载区异常")
# self.logger.error(f'exception {es}')
# self.logger.error(f'in line {es.__traceback__.tb_lineno}')
# return best_excavator_id
#
# def get_congestion_lanes(self):
# # 存在车辆拥堵的路段
# truck_locate_dict = self.group.truck.get_truck_locate_dict()
# congestion_lane_list = []
# for key, value in truck_locate_dict.items():
# if self.group.truck.truck_current_state[key] == 2:
# congestion_lane_list.append(value)
#
# print("congestion_lane_list")
# print(list(set(congestion_lane_list)))
# return list(set(congestion_lane_list))
class ReDispatcher: class ReDispatcher:
""" """
...@@ -850,14 +854,8 @@ class ReDispatcher: ...@@ -850,14 +854,8 @@ class ReDispatcher:
:return: :return:
""" """
# 当前绑定卸载区 # 当前绑定卸载区
# if truck_trip[0] == -1:
next_unload_area_id = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id, next_unload_area_id = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id,
isdeleted=0).first().unload_area_id isdeleted=0).first().unload_area_id
# else:
# dump_id = get_value("dump_index_to_uuid_dict")[truck_trip[0]]
# next_unload_area_id = get_value("dump_uuid_to_unload_area_uuid_dict")[dump_id]
# 当前绑定装载区
# if truck_trip[-1] == -1:
item = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id, isdeleted=0).first() item = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id, isdeleted=0).first()
current_excavator_id = item.exactor_id current_excavator_id = item.exactor_id
current_load_area_id = item.load_area_id current_load_area_id = item.load_area_id
...@@ -998,7 +996,7 @@ class ReDispatcher: ...@@ -998,7 +996,7 @@ class ReDispatcher:
def get_congestion_lanes(self): def get_congestion_lanes(self):
# 存在车辆拥堵的路段 # 存在车辆拥堵的路段
truck_locate_dict = self.group.truck.get_truck_locate_dict() truck_locate_dict = self.group.truck.get_truck_area_locate_dict()
congestion_lane_list = [] congestion_lane_list = []
for key, value in truck_locate_dict.items(): for key, value in truck_locate_dict.items():
if self.group.truck.truck_current_state[key] == 2: if self.group.truck.truck_current_state[key] == 2:
...@@ -1016,10 +1014,11 @@ class GoThroughDispatcher: ...@@ -1016,10 +1014,11 @@ class GoThroughDispatcher:
def __init__(self, group: Group): def __init__(self, group: Group):
self.logger = get_logger("zxt.GoThroughDispatcher") self.logger = get_logger("zxt.GoThroughDispatcher")
self.group = group self.group = group
self.gothrough_check_lanes = []
def update_lanes_info(self): def update_lanes_info(self):
try: # try:
with open(json_file, encoding='UTF-8') as f: with open(json_file, encoding='UTF-8') as f:
load_value = json.load(f) load_value = json.load(f)
gothrough_config = load_value["gothrough"] gothrough_config = load_value["gothrough"]
...@@ -1065,10 +1064,10 @@ class GoThroughDispatcher: ...@@ -1065,10 +1064,10 @@ class GoThroughDispatcher:
self.logger.info("远端装载区入场点") self.logger.info("远端装载区入场点")
self.logger.info(self.further_entrance_node_id) self.logger.info(self.further_entrance_node_id)
except Exception as es: # except Exception as es:
self.logger.error("读取装载区及车辆信息异常") # self.logger.error("读取装载区及车辆信息异常")
self.logger.error(es) # self.logger.error(es)
return # return
''' '''
2. 寻找车辆穿越装载区自动判定区域 2. 寻找车辆穿越装载区自动判定区域
...@@ -1129,8 +1128,9 @@ class GoThroughDispatcher: ...@@ -1129,8 +1128,9 @@ class GoThroughDispatcher:
try: try:
# 多回溯一个路段 # 多回溯一个路段
if lowest_common_ancestor.Length < 200: if lowest_common_ancestor.Length < 200:
item = session_postgre.query(Lane).filter_by(EndNodeId=lowest_common_ancestor.StartNodeId).first() items = session_postgre.query(Lane).filter_by(EndNodeId=lowest_common_ancestor.StartNodeId).all()
self.gothrough_check_lanes.append(item.Id) for item in items:
self.gothrough_check_lanes.append(str(item.Id))
self.logger.info("gothrough_check_lanes") self.logger.info("gothrough_check_lanes")
self.logger.info(self.gothrough_check_lanes) self.logger.info(self.gothrough_check_lanes)
...@@ -1139,8 +1139,8 @@ class GoThroughDispatcher: ...@@ -1139,8 +1139,8 @@ class GoThroughDispatcher:
self.logger.error("穿越装载区交叉口判断异常") self.logger.error("穿越装载区交叉口判断异常")
self.logger.error(es) self.logger.error(es)
def redispatch_request(self, request_truck_id: str, truck: TruckInfo, truck_dispatch: Mapping[str, List[str]],
def redispatch_request(self, request_truck_id: str, truck: TruckInfo): truck_info: CurrentTruck):
# 调度开始时间 # 调度开始时间
rtd_start_time = datetime.now() rtd_start_time = datetime.now()
...@@ -1241,6 +1241,7 @@ class GoThroughDispatcher: ...@@ -1241,6 +1241,7 @@ class GoThroughDispatcher:
self.logger.info("request_truck_lane_id:") self.logger.info("request_truck_lane_id:")
self.logger.info(request_truck_lane_id) self.logger.info(request_truck_lane_id)
self.logger.info(self.gothrough_check_lanes)
self.logger.info(truck_locates_dict) self.logger.info(truck_locates_dict)
except Exception as es: except Exception as es:
...@@ -1336,6 +1337,7 @@ class GoThroughDispatcher: ...@@ -1336,6 +1337,7 @@ class GoThroughDispatcher:
if request_truck_lane_id in self.gothrough_check_lanes: if request_truck_lane_id in self.gothrough_check_lanes:
self.logger.info(f'穿越装载区判定-车辆 {request_truck_id} 触发')
# 选择合适装载区 # 选择合适装载区
target_excavator = None target_excavator = None
try: try:
...@@ -1349,9 +1351,13 @@ class GoThroughDispatcher: ...@@ -1349,9 +1351,13 @@ class GoThroughDispatcher:
if (target_excavator is not None) and (current_truck_goto_excavator_id != target_excavator): if (target_excavator is not None) and (current_truck_goto_excavator_id != target_excavator):
self.logger.info(f'更新车辆 {request_truck_name} 派车计划前往 {target_excavator}') self.logger.info(f'更新车辆 {request_truck_name} 派车计划前往 {target_excavator}')
# 派车计划写入redis # 派车计划写入redis
truck_dispatch_to_redis(request_truck_id, group_id, target_excavator) # truck_dispatch_to_redis(request_truck_id, group_id, target_excavator)
truck_dispatch[request_truck_id] = [target_excavator, truck_info.get_combined_unload_area()]
POST(request_truck_id) self.group.truck_info_list[request_truck_id].has_changed = True
# POST(request_truck_id)
else: else:
# 派车计划未更改 # 派车计划未更改
self.logger.info("派车计划未变动") self.logger.info("派车计划未变动")
...@@ -1362,3 +1368,6 @@ class GoThroughDispatcher: ...@@ -1362,3 +1368,6 @@ class GoThroughDispatcher:
rtd_end_time = datetime.now() rtd_end_time = datetime.now()
print(f'调度时耗 {rtd_end_time - rtd_start_time}') print(f'调度时耗 {rtd_end_time - rtd_start_time}')
else:
self.logger.info(f'穿越装载区判定-车辆 {request_truck_id} 未触发')
\ No newline at end of file
...@@ -13,7 +13,7 @@ from core.group import CurrentTruck, Group ...@@ -13,7 +13,7 @@ from core.group import CurrentTruck, Group
from core.util import POST from core.util import POST
from data.dispatchInfo import DispatchInfo from data.dispatchInfo import DispatchInfo
from data.para_config import get_value from data.para_config import get_value
from equipment import DumpInfo, ExcavatorInfo, TruckInfo from data.equipment import DumpInfo, ExcavatorInfo, TruckInfo
from graph.topo_graph import Topo from graph.topo_graph import Topo
from settings import get_logger, redis5 from settings import get_logger, redis5
from tables import session_mysql, DispatchSetting from tables import session_mysql, DispatchSetting
...@@ -74,14 +74,14 @@ class DispatchSubmission: ...@@ -74,14 +74,14 @@ class DispatchSubmission:
else: else:
self.logger.info("动态调度模式") self.logger.info("动态调度模式")
self.dynamic_dispatch_mode(dispatch_seq, group_id, record, truck_info.get_sate(), self.dynamic_dispatch_mode(dispatch_seq, group_id, record, truck_info.get_sate(),
truck_info.get_task(), truck_id) truck_info.get_task(), truck_id, truck_info.get_has_changed())
# except Exception as es: # except Exception as es:
# self.logger.error("调度结果写入异常") # self.logger.error("调度结果写入异常")
# self.logger.error(f"调度结果:{dispatch_seq}") # self.logger.error(f"调度结果:{dispatch_seq}")
# self.logger.error(es) # self.logger.error(es)
def dynamic_dispatch_mode(self, dispatch_seq, group_id, record, state, task, truck_id): def dynamic_dispatch_mode(self, dispatch_seq, group_id, record, state, task, truck_id, has_changed):
""" """
write dispatch plan in dynamic dispatch mode. write dispatch plan in dynamic dispatch mode.
:param dispatch_seq: :param dispatch_seq:
...@@ -126,8 +126,10 @@ class DispatchSubmission: ...@@ -126,8 +126,10 @@ class DispatchSubmission:
if self.topo is not None: if self.topo is not None:
# 车辆重载等待,且前方道路阻塞 # 车辆重载等待,且前方道路阻塞
if task == 3 and state == 2 and truck_id in self.truck.get_truck_locate_dict() and \ # if task == 3 and state == 2 and truck_id in self.truck.get_truck_lane_locate_dict() and \
self.truck.get_truck_locate_dict()[truck_id] in self.topo.cross_bf_lanes: # self.truck.get_truck_lane_locate_dict()[truck_id] in self.topo.cross_bf_lanes:
if has_changed and (truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]):
# try: # try:
# if truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]: # if truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]:
self.logger.info("二次调度前往卸载区") self.logger.info("二次调度前往卸载区")
...@@ -184,8 +186,9 @@ class DispatchSubmission: ...@@ -184,8 +186,9 @@ class DispatchSubmission:
if self.topo is not None: if self.topo is not None:
# 车辆重载等待,且前方道路阻塞 # 车辆重载等待,且前方道路阻塞
if task == 0 and state == 2 and truck_id in self.truck.get_truck_locate_dict() and \ # if task == 0 and state == 2 and truck_id in self.truck.get_truck_lane_locate_dict() and \
self.truck.get_truck_locate_dict()[truck_id] in self.topo.cross_bf_lanes: # self.truck.get_truck_lane_locate_dict()[truck_id] in self.topo.cross_bf_lanes:
if has_changed and (truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]):
# 车辆停车等待 # 车辆停车等待
# try: # try:
# if truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]: # if truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]:
......
#!E:\Pycharm Projects\Waytous #!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# @Time : 2022/8/29 15:51 # @Time : 2023/4/19 19:19
# @Author : Opfer # @Author : Opfer
# @Site : # @Site :
# @File : __init__.py # @File : __init__.py.py
# @Software: PyCharm # @Software: PyCharm
\ No newline at end of file
...@@ -4,13 +4,12 @@ ...@@ -4,13 +4,12 @@
# @Site : # @Site :
# @File : dispatchInfo.py # @File : dispatchInfo.py
# @Software: PyCharm # @Software: PyCharm
import numpy as np
from settings import * # 分组数据处理
from tables import *
import pandas as pd from data.para_config import *
from tables import DispatchMatch, DispatchEquipment
from bidict import bidict from bidict import bidict
from settings import get_logger
logger = get_logger("zxt.dispatchInfo") logger = get_logger("zxt.dispatchInfo")
...@@ -123,18 +122,6 @@ class DispatchInfo: ...@@ -123,18 +122,6 @@ class DispatchInfo:
cls.load_area_uuid_to_index_dict = {} cls.load_area_uuid_to_index_dict = {}
cls.unload_area_uuid_to_index_dict = {} cls.unload_area_uuid_to_index_dict = {}
# cls.group_unload_area_dict = {} # cls.group_unload_area_dict.keys() 相当于所有的team_id
# cls.unload_area_group_dict = {} # cls.unload_area_group_dict.keys() 相当于所有的卸载区 unload_area_id
# cls.group_excavator_dict = {}
# cls.excavator_group_dict = {}
# cls.load_excavator_dict = {} # cls.load_excavator_dict.keys() 相当于所有的装载区 load_area_id
# cls.excavator_load_dict = {}
# cls.group_truck_dict = {}
# cls.truck_group_dict = {}
# cls.group_mode = {}
# cls.load_distance = {} # to_load_diatance-->>空车模式
# cls.unload_distance = {} # to_unload_distance-->>重车模式
@classmethod @classmethod
def update_device_group_structure(cls): def update_device_group_structure(cls):
""" """
...@@ -347,16 +334,6 @@ class DispatchInfo: ...@@ -347,16 +334,6 @@ class DispatchInfo:
group_unload_area_uuid_to_index = {} group_unload_area_uuid_to_index = {}
try: try:
# # unload->load distance
# unload_load_distance = np.zeros((len(unload_areas), len(load_areas)))
# for truck_id in range(len(unload_areas)):
# for j in range(len(load_areas)):
# distance = int(session_postgre.query(WalkTime).filter_by(unload_area_id=unload_areas[truck_id], load_area_id=load_areas[j]).first().to_load_distance)
# unload_load_distance[truck_id][j] = distance
# cls.load_distance[item] = unload_load_distance
group_excavator_count = 0 group_excavator_count = 0
group_dump_count = 0 group_dump_count = 0
group_load_area_count = 0 group_load_area_count = 0
...@@ -440,39 +417,6 @@ class DispatchInfo: ...@@ -440,39 +417,6 @@ class DispatchInfo:
logger.error("路网距离更新异常-调度部分和路网部分不一致") logger.error("路网距离更新异常-调度部分和路网部分不一致")
logger.error(es) logger.error(es)
# @classmethod
# def update_device_dict(cls):
# cls.excavator_uuid_index_dict = {}
# cls.unload_area_uuid_index_dict = {}
# cls.truck_uuid_index_dict = {}
# cls.dump_uuid_index_dict = {}
# for group_id in cls.group_set:
# cls.excavator_uuid_index_dict = {}
# cls.unload_area_uuid_index_dict = {}
# cls.truck_uuid_index_dict = {}
# cls.dump_uuid_index_dict = {}
#
# for truck_id in range(len(cls.group_excavator_dict[group_id])):
# cls.excavator_uuid_index_dict[group_id][list(cls.group_excavator_dict[group_id])[truck_id]] = truck_id
#
# for truck_id in range(len(cls.group_unload_area_dict[group_id])):
# cls.unload_area_uuid_index_dict[group_id][list(cls.group_unload_area_dict[group_id])[truck_id]] = truck_id
#
# for truck_id in range(len(cls.group_dump_dict[group_id])):
# cls.dump_uuid_index_dict[group_id][list(cls.group_dump_dict[group_id])[truck_id]] = truck_id
#
# for truck_id in range(len(cls.group_truck_dict[group_id])):
# cls.truck_uuid_index_dict[group_id][list(cls.group_truck_dict[group_id])[truck_id]] = truck_id
#
# # self.excavator_uuid_index_dict = bidict(DispatchInfo.excavator_uuid_to_index_dict[self.group_id])
# # self.unload_area_uuid_index_dict = bidict(DispatchInfo.unload_area_uuid_to_index_dict[self.group_id])
# # self.dump_uuid_index_dict = bidict(DispatchInfo.dump_uuid_to_index_dict[self.group_id])
#
# cls.excavator_uuid_index_dict = bidict(cls.excavator_uuid_index_dict)
# cls.unload_area_uuid_index_dict = bidict(cls.unload_area_uuid_index_dict)
# cls.truck_uuid_index_dict = bidict(cls.truck_uuid_index_dict)
# cls.dump_uuid_index_dict = bidict(cls.dump_uuid_index_dict)
@classmethod @classmethod
def get_group_excavator_dict(cls, group_id): def get_group_excavator_dict(cls, group_id):
return cls.excavator_uuid_to_index_dict[group_id] return cls.excavator_uuid_to_index_dict[group_id]
...@@ -531,18 +475,19 @@ class DispatchInfo: ...@@ -531,18 +475,19 @@ class DispatchInfo:
@classmethod @classmethod
def get_park_to_excavator_distance(cls, group_id): def get_park_to_excavator_distance(cls, group_id):
excavators = cls.group_excavator_dict[group_id] excavators = cls.group_excavator_dict[group_id]
park_matrix = np.ones((1, len(excavators))) park_area_set = get_value("park_uuid_to_index_dict").keys()
park_matrix = np.ones((len(park_area_set), len(excavators)))
try: try:
b = excavators
for i in range(len(excavators)): for i in range(len(excavators)):
load_area_id = cls.excavator_load_dict[excavators[i]] load_area_id = cls.excavator_load_dict[excavators[i]]
for park_idx in range(len(park_area_set)):
try: try:
distance = session_postgre.query(WalkTimePark).filter_by(load_area_id=load_area_id).first().park_load_distance distance = session_postgre.query(WalkTimePark).filter_by(load_area_id=load_area_id).first().park_load_distance
park_matrix[0][i] = distance park_matrix[park_idx][i] = distance
except Exception as es: except Exception as es:
logger.warning("查询不到距离,设置为100000000") logger.warning("查询不到距离,设置为100000000")
logger.warning(es) logger.warning(es)
park_matrix[0][i] = 100000000 # 设置为一个很大的数字 park_matrix[park_idx][i] = 100000000 # 设置为一个很大的数字
except Exception as es: except Exception as es:
logger.error("park->load距离更新异常, 存在备停区不可达的装载区") logger.error("park->load距离更新异常, 存在备停区不可达的装载区")
logger.error(es) logger.error(es)
...@@ -551,6 +496,13 @@ class DispatchInfo: ...@@ -551,6 +496,13 @@ class DispatchInfo:
return park_matrix return park_matrix
@classmethod @classmethod
def get_park_set(cls):
park_areas_set = set()
for item in session_postgre.query(WalkTimePark).all():
park_areas_set.add(item.park_area_id)
return park_areas_set
@classmethod
def get_truck_exactor(cls, truck_id): def get_truck_exactor(cls, truck_id):
return cls.truck_exactor_dict[truck_id] return cls.truck_exactor_dict[truck_id]
...@@ -563,161 +515,4 @@ class DispatchInfo: ...@@ -563,161 +515,4 @@ class DispatchInfo:
return cls.exactor_unload_dict[exactor_id] return cls.exactor_unload_dict[exactor_id]
# #!E:\Pycharm Projects\Waytous
# # -*- coding: utf-8 -*-
# # @Time : 2022/5/30 14:45
# # @Author : Opfer
# # @Site :
# # @File : dispatchInfo.py
# # @Software: PyCharm
# from settings import *
#
# logger = get_logger("mqc.dispatchInfo")
#
#
# class DispatchInfo:
# """
# class for dispatch group info.
# """
#
# # dispatch groups
# group_set = set()
#
# # device group structure
# group_unload_area_dict = {} # team_id -> dict {unload_area_id, unload_area_id, ...}
# # {group_id:unload_area_id,...}
# group_excavator_dict = {} # team_id -> dict {[excavator_id, load_area_id], ...}
# # {group_id: [excavator_id, unload_area_id], ...}
# group_truck_dict = {} # team_id -> dict {truck_id, ...}
# # {group_id:[truck_id,truck_id],...}
#
# unload_area_group_dict = {} # unload_area_id -> team_id
# excavator_group_dict = {} # excavator_id -> team_id
# truck_group_dict = {} # truck_id -> team_id
#
# # group feature
# group_mode = {} # 四种模式:全智能、空车智能、定铲定铲和分流配比模式
# # {mode_name:mode_code}
#
# # route_distance(路网距离)
# load_excavator_distance = {} # 装载区-挖机(电铲)的距离 数据格式 -->> {load_area_id:[excavator_uuid, to_load_distance],}
# unload_excavator_distance = {} # 卸载区-挖机(电铲)的距离 数据格式 -->> {unload_area_id:[excavator_uuid, to_unload_distance],}
#
# @classmethod
# def renew_set(cls):
# """
# @date:2022/6/2 19:50
# @author:maqc
# @desc:实例化对象,可直接访问
# """
# cls.group_unload_area_dict = {}
# cls.unload_area_group_dict = {}
#
# cls.group_excavator_dict = {}
# cls.excavator_group_dict = {}
#
# cls.group_truck_dict = {}
# cls.truck_group_dict = {}
#
# cls.group_mode = {}
# cls.load_excavator_distance = {}
# cls.unload_excavator_distance = {}
#
# @classmethod
# def update_device_group_structure(cls):
# """
# @date:2022/6/2 19:49
# @author:maqc
# @desc:分组与卸载区、挖机、矿卡的映射和反映射
# """
# logger = get_logger("mqc.update_device_group_structure")
# try:
# # group_unload_area_dict = {} -->> {group_id:unload_area_id,...}
# # unload_area_group_dict = {} # unload_area_id -> team_id
# group_code_dict = {} # group_code-->>team_id的映射
# for valve in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
# group_code_dict[valve.group_code] = valve.team_id
# if valve.team_id not in cls.group_unload_area_dict:
# cls.group_unload_area_dict[valve.team_id] = [valve.unload_area_id] # 注意:一个team_id可能对应多个unload_area_id
# else:
# cls.group_unload_area_dict[valve.team_id].append(valve.unload_area_id)
# cls.unload_area_group_dict[valve.unload_area_id] = valve.team_id # 一个unload_area_id只对应一个team_id
# # group_excavator_dict = {} -->> {group_id: [excavator_id, unload_area_id], ...} # 一个team_id对应一组excavator_id, unload_area_id
# # excavator_group_dict = {} -->> excavator_id -> team_id 一个excavator_id只对应一个team_id
# for item in session_mysql.query(DispatchMatch).filter_by(group_type=1).all():
# # cls.group_excavator_dict[item.team_id] = [item.excavator_id, item.unload_area_id]
# cls.group_excavator_dict[item.team_id] = item.excavator_id
# cls.excavator_group_dict[item.excavator_id] = item.team_id
# # group_truck_dict = {} -->> {group_id:[truck_id,truck_id],...}
# # truck_group_dict = {} -->> truck_id -> team_id
# for key in session_mysql.query(DispatchEquipment).filter_by(group_type=1).all():
# if key.group_code in group_code_dict:
# if key.group_code not in cls.group_truck_dict:
# cls.group_truck_dict[key.group_code] = [key.equipment_id]
# else:
# cls.group_truck_dict[key.group_code].append(key.equipment_id)
# cls.truck_group_dict[key.equipment_id] = group_code_dict[key.group_code]
# except Exception as es:
# logger.error("分组到卸载区的数据更新异常")
# logger.error(es)
#
# @classmethod
# def update_group_mode(cls):
# """
# @date:2022/6/2 19:49
# @author:maqc
# @desc:处理其它类型的数据
# """
# logger = get_logger("mqc.update_group_mode")
# try:
# for value in session_mysql.query(DispatchMode).all():
# cls.group_mode[value.mode_name] = value.mode_code
# except Exception as es:
# logger.error("派车模式数据更新异常")
# logger.error(es)
#
# @classmethod
# def dispatch_group_init(cls):
# """
# update basic paras (group_set, dict, num ...)
# :return:
# """
# pass
#
#
# @classmethod
# def get_group_road_info(cls,group_id, truck_info):
# if truck_info == 1:
# for truck_id in group_excavator():
# pass
# for j in group_unload_area():
# pass
# if truck_info == 2:
# pass
# @classmethod
# # 距离-->>数据格式:矩阵-->>to_load_distance
# def update_route_distance(cls):
# """
# @date:2022/6/2 19:50
# @author:maqc
# @desc:更新路网距离,返回矩阵格式数据
# """
# load_excavator_dict = {} # 装载区id-->>电铲编号的映射
# logger = get_logger("mqc.update_route_distance")
# try:
# for value in session_postgre.query(DiggingWorkArea).all():
# load_excavator_dict[value.Id] = value.Exactorld
# for value in session_postgre.query(WalkTime).all():
# if value.load_area_id in load_excavator_dict:
# cls.load_excavator_distance[value.load_area_id] = [load_excavator_dict[value.load_area_id],
# value.to_load_distance]
# cls.unload_excavator_distance[value.unload_area_id] = [load_excavator_dict[value.load_area_id],
# value.to_unload_distance]
# except Exception as es:
# logger.error("路网数据更新异常")
# logger.error(es)
#
#
...@@ -85,10 +85,12 @@ class TruckInfo(WalkManage): ...@@ -85,10 +85,12 @@ class TruckInfo(WalkManage):
# 对象域 # 对象域
self._dump = dump self._dump = dump
self._excavator = excavator self._excavator = excavator
# 车辆位置信息 # 车辆车道位置信息
self.truck_locate_dict = {} self.truck_lane_locate_dict = {}
# 车辆临时调度 # 车辆临时调度
self.truck_is_temp = {} self.truck_is_temp = {}
# 车辆区域位置信息
self.truck_area_locate_dict = {}
def get_truck_current_trip(self): def get_truck_current_trip(self):
return self.truck_current_trip return self.truck_current_trip
...@@ -132,8 +134,11 @@ class TruckInfo(WalkManage): ...@@ -132,8 +134,11 @@ class TruckInfo(WalkManage):
def get_excavator_hold_truck_num(self): def get_excavator_hold_truck_num(self):
return self.excavator_hold_truck_num return self.excavator_hold_truck_num
def get_truck_locate_dict(self): def get_truck_lane_locate_dict(self):
return self.truck_locate_dict return self.truck_lane_locate_dict
def get_truck_area_locate_dict(self):
return self.truck_area_locate_dict
################################################ short term update ################################################ ################################################ short term update ################################################
...@@ -219,18 +224,20 @@ class TruckInfo(WalkManage): ...@@ -219,18 +224,20 @@ class TruckInfo(WalkManage):
key_value_dict = redis5.get(truck_name_to_uuid_dict[item]) # reids str可以自动转为bytes key_value_dict = redis5.get(truck_name_to_uuid_dict[item]) # reids str可以自动转为bytes
if key_value_dict is None: if key_value_dict is None:
raise CoreException(108, f'车辆{item}不存在于redis5') # raise CoreException(108, f'车辆{item}不存在于redis5')
self.logger.warning(f'车辆{item}不存在于redis5')
isTemp = True
else:
key_value_dict = json.loads(byte_to_str(key_value_dict)) key_value_dict = json.loads(byte_to_str(key_value_dict))
if truck_name_to_uuid_dict[item] in self.dynamic_truck_set: if "isTemp" in key_value_dict:
try:
isTemp = key_value_dict["isTemp"] isTemp = key_value_dict["isTemp"]
else:
isTemp = True
if truck_name_to_uuid_dict[item] in self.dynamic_truck_set:
self.truck_is_temp[truck_name_to_uuid_dict[item]] = bool(isTemp) self.truck_is_temp[truck_name_to_uuid_dict[item]] = bool(isTemp)
except Exception as es: else:
self.logger.error(item) continue
self.logger.error(es)
self.truck_is_temp[truck_name_to_uuid_dict[item]] = True
# print(f'here3 {item} {bool(isTemp)}') # print(f'here3 {item} {bool(isTemp)}')
except Exception as es: except Exception as es:
...@@ -525,15 +532,15 @@ class TruckInfo(WalkManage): ...@@ -525,15 +532,15 @@ class TruckInfo(WalkManage):
print("self.excavator_hold_truck_num") print("self.excavator_hold_truck_num")
print(self.excavator_hold_truck_num) print(self.excavator_hold_truck_num)
def update_trucks_locate(self): def update_trucks_lane_locate(self):
""" """
get trucks locates. get trucks locates.
:return: truck_locate_dict :return: truck_lane_locate_dict
""" """
truck_uuid_to_name_dict = get_value("truck_uuid_to_name_dict") truck_uuid_to_name_dict = get_value("truck_uuid_to_name_dict")
self.truck_locate_dict = {} self.truck_lane_locate_dict = {}
for truck_id in self.dynamic_truck_set: for truck_id in self.dynamic_truck_set:
try: try:
# item = item.decode(encoding='utf-8') # item = item.decode(encoding='utf-8')
...@@ -548,7 +555,7 @@ class TruckInfo(WalkManage): ...@@ -548,7 +555,7 @@ class TruckInfo(WalkManage):
and (str_to_byte('laneId') in key_set): and (str_to_byte('laneId') in key_set):
truck_locate = key_value_dict[str_to_byte('laneId')] truck_locate = key_value_dict[str_to_byte('laneId')]
if eval(truck_locate) is not '': if eval(truck_locate) is not '':
self.truck_locate_dict[truck_id] = eval(truck_locate) self.truck_lane_locate_dict[truck_id] = eval(truck_locate)
except Exception as es: except Exception as es:
self.logger.error(es) self.logger.error(es)
self.logger.error(f'车辆 {truck_id} 位置信息丢失') self.logger.error(f'车辆 {truck_id} 位置信息丢失')
...@@ -638,6 +645,9 @@ class TruckInfo(WalkManage): ...@@ -638,6 +645,9 @@ class TruckInfo(WalkManage):
item = session_mysql.query(Equipment).filter_by(id=excavator_id).first() item = session_mysql.query(Equipment).filter_by(id=excavator_id).first()
if item.bind_list is not None: if item.bind_list is not None:
for truck_name in json.loads(item.bind_list): for truck_name in json.loads(item.bind_list):
if truck_name not in truck_name_to_uuid_dict:
self.logger.error(f'truck_name_to_uuid_dict 不存在 {truck_name}')
continue
self.truck_excavator_bind[ self.truck_excavator_bind[
truck_name_to_uuid_dict[truck_name] truck_name_to_uuid_dict[truck_name]
] = excavator_id ] = excavator_id
...@@ -953,4 +963,4 @@ class TruckInfo(WalkManage): ...@@ -953,4 +963,4 @@ class TruckInfo(WalkManage):
self.update_truck_speed() self.update_truck_speed()
# 矿卡位置更新 # 矿卡位置更新
self.update_trucks_locate() self.update_trucks_lane_locate()
...@@ -11,7 +11,9 @@ from settings import * ...@@ -11,7 +11,9 @@ from settings import *
from tables import * from tables import *
import numpy as np import numpy as np
# 全局参数设定 '''
全局参数设定
'''
# 空载任务集合 # 空载任务集合
empty_task_set = [0, 1, 5] empty_task_set = [0, 1, 5]
...@@ -27,69 +29,17 @@ M = 100000000 ...@@ -27,69 +29,17 @@ M = 100000000
logger = get_logger("zxt.para") logger = get_logger("zxt.para")
# # 装载区、卸载区、备停区在调度算法运行器件默认不发生改变,提前计算部分参量
# # (uuid,index(id)映射关系, 装载区数量, 卸载区数量, 备停区数量, 以及初次统计动态调度矿卡)
# (
# load_area_uuid_to_index_dict,
# unload_area_uuid_to_index_dict,
# load_area_index_to_uuid_dict,
# unload_area_index_to_uuid_dict,
# ) = build_work_area_uuid_index_map()
#
# load_area_num, unload_area_num = len(load_area_uuid_to_index_dict), len(
# unload_area_uuid_to_index_dict
# )
#
# park_uuid_to_index_dict, park_index_to_uuid_dict = build_park_uuid_index_map()
#
# park_num = len(park_uuid_to_index_dict)
#
# truck_uuid_to_name_dict, truck_name_to_uuid_dict = build_truck_uuid_name_map()
#
# excavator_uuid_to_name_dict, dump_uuid_to_name_dict = build_equipment_uuid_name_map()
#
# # 矿卡集合
# group_trucks = set(update_total_truck())
#
# # 固定派车矿卡集合
# fixed_truck_set = set(update_fixdisp_truck())
#
# # 动态派车矿卡集合
# # dynamic_truck_set = group_trucks.difference(fixed_truck_set)
# dynamic_truck_set = update_dynamic_truck()
#
# dynamic_truck_num = len(dynamic_truck_set)
#
# logger.info("可用于动态派车的矿卡:")
# logger.info(dynamic_truck_set)
#
# # 用于动态调度的挖机及卸载设备
# dynamic_excavator_set = set(update_autodisp_excavator())
# dynamic_excavator_num = len(dynamic_excavator_set)
#
# dynamic_dump_set = set(update_autodisp_dump())
# dynamic_dump_num = len(dynamic_dump_set)
#
# global global_dict
global_dict = {} global_dict = {}
# global_dict["dynamic_truck_set"] = dynamic_truck_set
# global_dict["dynamic_truck_num"] = dynamic_truck_num
# global_dict["dynamic_excavator_set"] = dynamic_excavator_set
# global_dict["dynamic_excavator_num"] = dynamic_excavator_num
# global_dict["dynamic_dump_set"] = dynamic_dump_set
# global_dict["dynamic_dump_num"] = dynamic_dump_num
# global_dict["park_num"] = park_num
def get_value(name): def get_value(name):
return global_dict[name] return global_dict[name]
# 设备映射类, 存储除工作区以外的映射关系
# 其余设备类继承该类
class DeviceMap: class DeviceMap:
"""
设备映射类, 存储除工作区以外的映射关系, 其余设备类继承该类
"""
excavator_uuid_to_index_dict = {} excavator_uuid_to_index_dict = {}
dump_uuid_to_index_dict = {} dump_uuid_to_index_dict = {}
excavator_index_to_uuid_dict = {} excavator_index_to_uuid_dict = {}
...@@ -103,50 +53,6 @@ class DeviceMap: ...@@ -103,50 +53,6 @@ class DeviceMap:
truck_uuid_to_index_dict = {} truck_uuid_to_index_dict = {}
truck_index_to_uuid_dict = {} truck_index_to_uuid_dict = {}
# def __init__(cls):
# cls.excavator_uuid_to_index_dict = {}
# cls.dump_uuid_to_index_dict = {}
# cls.excavator_index_to_uuid_dict = {}
# cls.dump_index_to_uuid_dict = {}
#
# cls.dump_uuid_to_unload_area_uuid_dict = {}
# cls.excavator_uuid_to_load_area_uuid_dict = {}
# cls.excavator_index_to_load_area_index_dict = {}
# cls.dump_index_to_unload_area_index_dict = {}
#
# cls.truck_uuid_to_index_dict = {}
# cls.truck_index_to_uuid_dict = {}
# def get_excavator_uuid_to_index_dict(cls):
# return cls.excavator_uuid_to_index_dict
#
# def get_dump_uuid_to_index_dict(cls):
# return cls.dump_uuid_to_index_dict
#
# def get_excavator_index_to_uuid_dict(cls):
# return cls.excavator_index_to_uuid_dict
#
# def get_dump_index_to_uuid_dict(cls):
# return cls.dump_index_to_uuid_dict
#
# def get_dump_uuid_to_unload_area_uuid_dict(cls):
# return cls.dump_uuid_to_unload_area_uuid_dict
#
# def get_excavator_uuid_to_load_area_uuid_dict(cls):
# return cls.excavator_uuid_to_load_area_uuid_dict
#
# def get_excavator_index_to_load_area_index_dict(cls):
# return cls.excavator_index_to_load_area_index_dict
#
# def get_dump_index_to_unload_area_index_dict(cls):
# return cls.dump_index_to_unload_area_index_dict
#
# def get_truck_uuid_to_index_dict(cls):
# return cls.truck_uuid_to_index_dict
#
# def get_truck_index_to_uuid_dict(cls):
# return cls.truck_index_to_uuid_dict
@classmethod @classmethod
def reset(cls): def reset(cls):
cls.excavator_uuid_to_index_dict = {} cls.excavator_uuid_to_index_dict = {}
...@@ -193,58 +99,19 @@ class DeviceMap: ...@@ -193,58 +99,19 @@ class DeviceMap:
"dump_index_to_unload_area_index_dict" "dump_index_to_unload_area_index_dict"
] ]
truck_map_dict = update_truck_uuid_index_map(get_value("dynamic_truck_set")) truck_map_dict = build_truck_uuid_index_map(get_value("dynamic_truck_set"))
cls.truck_uuid_to_index_dict = truck_map_dict["truck_uuid_to_index_dict"] cls.truck_uuid_to_index_dict = truck_map_dict["truck_uuid_to_index_dict"]
cls.truck_index_to_uuid_dict = truck_map_dict["truck_index_to_uuid_dict"] cls.truck_index_to_uuid_dict = truck_map_dict["truck_index_to_uuid_dict"]
# def period_map_para_load(cls):
# # 装载关系映射
# cls.excavator_uuid_to_index_dict = device_map.excavator_uuid_to_index_dict
# cls.dump_uuid_to_index_dict = device_map.dump_uuid_to_index_dict
# cls.excavator_index_to_uuid_dict = device_map.excavator_index_to_uuid_dict
# cls.dump_index_to_uuid_dict = device_map.dump_index_to_uuid_dict
#
# cls.dump_uuid_to_unload_area_uuid_dict = (
# device_map.dump_uuid_to_unload_area_uuid_dict
# )
# cls.excavator_uuid_to_load_area_uuid_dict = (
# device_map.excavator_uuid_to_load_area_uuid_dict
# )
# cls.excavator_index_to_load_area_index_dict = (
# device_map.excavator_index_to_load_area_index_dict
# )
# cls.dump_index_to_unload_area_index_dict = (
# device_map.dump_index_to_unload_area_index_dict
# )
#
# cls.truck_uuid_to_index_dict = device_map.truck_uuid_to_index_dict
# cls.truck_index_to_uuid_dict = device_map.truck_index_to_uuid_dict
# 路网信息类 #
class WalkManage(DeviceMap): class WalkManage(DeviceMap):
# def __init__(cls): """
# # # 工作区和设备不具备一一对应关系, 为方便就计算, 算法维护两套路网: 面向路网和面向设备 路网信息类
# """
# # 路网真实距离 # 工作区和设备不具备一一对应关系, 为方便就计算, 算法维护两套路网: 面向路网和面向设备
# cls.walk_time_to_excavator = np.full((dynamic_dump_num, dynamic_excavator_num), M, dtype=float)
# cls.walk_time_to_dump = np.full((dynamic_dump_num, dynamic_excavator_num), M, dtype=float)
# cls.walk_time_park_to_excavator = np.full((park_num, dynamic_excavator_num), M, dtype=float)
# cls.walk_time_park_to_load_area = np.full((park_num, load_area_num), M, dtype=float)
# cls.walk_time_to_load_area = np.full((unload_area_num, load_area_num), M, dtype=float)
# cls.walk_time_to_unload_area = np.full((unload_area_num, load_area_num), M, dtype=float)
#
# # 路网行驶时间
# cls.distance_to_excavator = np.full((dynamic_dump_num, dynamic_excavator_num), M, dtype=float)
# cls.distance_to_dump = np.full((dynamic_dump_num, dynamic_excavator_num), M, dtype=float)
# cls.distance_park_to_excavator = np.full((park_num, dynamic_excavator_num), M, dtype=float)
# cls.distance_park_to_load_area = np.full((park_num, load_area_num), M, dtype=float)
# cls.distance_to_load_area = np.full((unload_area_num, load_area_num), M, dtype=float)
# cls.distance_to_unload_area = np.full((unload_area_num, load_area_num), M, dtype=float)
# # 工作区和设备不具备一一对应关系, 为方便就计算, 算法维护两套路网: 面向路网和面向设备
# 路网真实距离 # 路网真实距离
walk_time_to_excavator = None walk_time_to_excavator = None
...@@ -262,49 +129,9 @@ class WalkManage(DeviceMap): ...@@ -262,49 +129,9 @@ class WalkManage(DeviceMap):
distance_to_load_area = None distance_to_load_area = None
distance_to_unload_area = None distance_to_unload_area = None
# def get_walk_time_to_load_area(cls):
# return cls.walk_time_to_load_area
#
# def get_walk_time_to_unload_area(cls):
# return cls.walk_time_to_unload_area
#
# def get_walk_time_to_excavator(cls):
# return cls.walk_time_to_excavator
#
# def get_walk_time_to_dump(cls):
# return cls.walk_time_to_dump
#
# def get_walk_time_park_to_load_area(cls):
# return cls.walk_time_park_to_load_area
#
# def get_walk_time_park_to_excavator(cls):
# return cls.walk_time_park_to_excavator
#
# def get_distance_to_load_area(cls):
# return cls.distance_to_load_area
#
# def get_distance_to_unload_area(cls):
# return cls.distance_to_unload_area
#
# def get_distance_to_excavator(cls):
# return cls.distance_to_excavator
#
# def get_distance_to_dump(cls):
# return cls.distance_to_dump
#
# def get_distance_park_to_load_area(cls):
# return cls.distance_park_to_load_area
#
# def get_distance_park_to_excavator(cls):
# return cls.distance_park_to_excavator
@classmethod @classmethod
def reset(cls): def reset(cls):
# dynamic_excavator_num
# dynamic_dump_num
# park_num
# 路网真实距离 # 路网真实距离
cls.walk_time_to_excavator = np.full( cls.walk_time_to_excavator = np.full(
(dynamic_dump_num, dynamic_excavator_num), M (dynamic_dump_num, dynamic_excavator_num), M
...@@ -450,7 +277,8 @@ def global_period_para_update(): ...@@ -450,7 +277,8 @@ def global_period_para_update():
truck_uuid_to_name_dict, truck_name_to_uuid_dict = build_truck_uuid_name_map() truck_uuid_to_name_dict, truck_name_to_uuid_dict = build_truck_uuid_name_map()
excavator_uuid_to_name_dict, dump_uuid_to_name_dict = build_equipment_uuid_name_map() excavator_uuid_to_name_dict = build_excavator_uuid_name_map()
dump_uuid_to_name_dict = build_dump_uuid_name_map()
global_dict = {"park_num": park_num, "load_area_num": load_area_num, "unload_area_num": unload_area_num, global_dict = {"park_num": park_num, "load_area_num": load_area_num, "unload_area_num": unload_area_num,
"truck_uuid_to_name_dict": truck_uuid_to_name_dict, "truck_uuid_to_name_dict": truck_uuid_to_name_dict,
......
...@@ -14,6 +14,11 @@ from tables import * ...@@ -14,6 +14,11 @@ from tables import *
logger = get_logger("zxt.static_data_process") logger = get_logger("zxt.static_data_process")
'''
area uuid index map building
'''
def build_work_area_uuid_index_map(): def build_work_area_uuid_index_map():
# load_area_id <-> load_area_index # load_area_id <-> load_area_index
# unload_area_id <-> unload_area_index # unload_area_id <-> unload_area_index
...@@ -71,7 +76,7 @@ def build_park_uuid_index_map(): ...@@ -71,7 +76,7 @@ def build_park_uuid_index_map():
if park_num < 1: if park_num < 1:
raise Exception("无备停区路网信息") raise Exception("无备停区路网信息")
except Exception as es: except Exception as es:
logger.info("备停区路网读取") logger.error("备停区路网读取")
logger.error(es) logger.error(es)
session_postgre.rollback() session_postgre.rollback()
session_mysql.rollback() session_mysql.rollback()
...@@ -79,6 +84,11 @@ def build_park_uuid_index_map(): ...@@ -79,6 +84,11 @@ def build_park_uuid_index_map():
return park_uuid_to_index_dict, park_index_to_uuid_dict return park_uuid_to_index_dict, park_index_to_uuid_dict
'''
equipment uuid name map building
'''
def build_truck_uuid_name_map(): def build_truck_uuid_name_map():
# truck_id <-> truck_name # truck_id <-> truck_name
truck_uuid_to_name_dict = {} truck_uuid_to_name_dict = {}
...@@ -100,11 +110,9 @@ def build_truck_uuid_name_map(): ...@@ -100,11 +110,9 @@ def build_truck_uuid_name_map():
return truck_uuid_to_name_dict, truck_name_to_uuid_dict return truck_uuid_to_name_dict, truck_name_to_uuid_dict
def build_equipment_uuid_name_map(): def build_excavator_uuid_name_map():
# excavator_id <-> excavator_name # excavator_id <-> excavator_name
# dump_id <-> dump_name
excavator_uuid_to_name_dict = {} excavator_uuid_to_name_dict = {}
dump_uuid_to_name_dict = {}
try: try:
for item in session_mysql.query(Equipment).filter_by(device_type=2).all(): for item in session_mysql.query(Equipment).filter_by(device_type=2).all():
...@@ -118,8 +126,13 @@ def build_equipment_uuid_name_map(): ...@@ -118,8 +126,13 @@ def build_equipment_uuid_name_map():
logger.warning(es) logger.warning(es)
session_postgre.rollback() session_postgre.rollback()
session_mysql.rollback() session_mysql.rollback()
return excavator_uuid_to_name_dict
def build_dump_uuid_name_map():
# dump_id <-> dump_name
dump_uuid_to_name_dict = {}
try: try:
for item in session_mysql.query(Equipment).filter_by(device_type=3).all(): for item in session_mysql.query(Equipment).filter_by(device_type=3).all():
truck_id = item.id truck_id = item.id
...@@ -132,7 +145,7 @@ def build_equipment_uuid_name_map(): ...@@ -132,7 +145,7 @@ def build_equipment_uuid_name_map():
logger.warning(es) logger.warning(es)
session_postgre.rollback() session_postgre.rollback()
session_mysql.rollback() session_mysql.rollback()
return excavator_uuid_to_name_dict, dump_uuid_to_name_dict return dump_uuid_to_name_dict
def update_deveices_map(unload_area_uuid_to_index_dict, load_area_uuid_to_index_dict): def update_deveices_map(unload_area_uuid_to_index_dict, load_area_uuid_to_index_dict):
...@@ -210,7 +223,7 @@ def update_deveices_map(unload_area_uuid_to_index_dict, load_area_uuid_to_index_ ...@@ -210,7 +223,7 @@ def update_deveices_map(unload_area_uuid_to_index_dict, load_area_uuid_to_index_
} }
def update_truck_uuid_index_map(dynamic_truck_set): def build_truck_uuid_index_map(dynamic_truck_set):
truck_uuid_to_index_dict = {} truck_uuid_to_index_dict = {}
truck_index_to_uuid_dict = {} truck_index_to_uuid_dict = {}
...@@ -229,6 +242,7 @@ def update_truck_uuid_index_map(dynamic_truck_set): ...@@ -229,6 +242,7 @@ def update_truck_uuid_index_map(dynamic_truck_set):
"truck_index_to_uuid_dict": truck_index_to_uuid_dict, "truck_index_to_uuid_dict": truck_index_to_uuid_dict,
} }
def update_total_truck(): def update_total_truck():
# 矿卡集合 # 矿卡集合
truck_list = [] truck_list = []
......
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2022/8/29 15:26
# @Author : Opfer
# @Site :
# @File : gothrough_digging.py
# @Software: PyCharm
from flask import request
from flask.json import jsonify
from data.para_config import *
from equipment.truck import TruckInfo
from equipment.excavator import ExcavatorInfo
from equipment.dump import DumpInfo
from data.dispatchInfo import DispatchInfo
from app import app
import uuid
@app.route("/go_through", methods=["POST"])
def redispatch_request():
# 获取报文数据
data_json = request.get_json()
# 车辆id
request_truck_id = data_json.get("truck_id")
request_truck_id = 'fb266860-f5b9-4180-8a52-40e638d048ed'
# 调度开始时间
rtd_start_time = datetime.now()
return jsonify(msg="success", code=0)
# 初始化日志
set_log()
# 获取日志器
logger = get_logger("zxt.Request")
# 更新周期参数
logger.info("#####################################请求调度更新开始#####################################")
try:
# 清空数据库缓存
session_mysql.commit()
session_mysql.flush()
# 清空数据库缓存
session_postgre.commit()
session_postgre.flush()
except Exception as es:
logger.error("数据库访问异常")
logger.error(es)
return jsonify(msg="未知异常, 请联系管理员", code=501)
try:
# 全局参数更新
global_period_para_update()
# get_global_para_from_cache(cache)
except Exception as es:
logger.error("全局参数更新异常")
logger.error(es)
session_mysql.rollback()
session_postgre.rollback()
return jsonify(msg="未知异常, 请联系管理员", code=502)
try:
# 更新调度信息
DispatchInfo.reset()
DispatchInfo.update_device_group_structure()
group_id = DispatchInfo.truck_group_dict[request_truck_id]
DispatchInfo.update_route_distance()
DispatchInfo.update_group_mode()
DispatchInfo.update_group_name()
except Exception as es:
logger.error("调度信息更新异常")
logger.error(es)
session_mysql.rollback()
session_postgre.rollback()
return jsonify(msg="未知异常, 请联系管理员", code=503)
logger.info("Dispatchinfo,更新后信息")
logger.info("group_set")
logger.info(DispatchInfo.group_set)
logger.info("group_excavator_dict")
logger.info(DispatchInfo.group_excavator_dict)
logger.info("group_unload_area_dict")
logger.info(DispatchInfo.group_unload_area_dict)
logger.info("group_truck_dict")
logger.info(DispatchInfo.group_truck_dict)
logger.info("group_mode")
logger.info(DispatchInfo.group_mode)
logger.info("load_distance")
logger.info(DispatchInfo.load_distance)
logger.info("unload_distance")
logger.info(DispatchInfo.unload_distance)
try:
# # 实例化设备对象
dump = DumpInfo()
excavator = ExcavatorInfo()
truck = TruckInfo(dump, excavator)
# 设备信息更新
dump.dump_para_period_update()
excavator.excavator_para_period_update()
truck.truck_para_period_update(dump, excavator)
truck.state_period_update()
except Exception as es:
logger.error("对象实例化异常")
logger.error(es)
session_mysql.rollback()
session_postgre.rollback()
return jsonify(msg="未知异常, 请联系管理员", code=504)
try:
# 读取挖机集合
excavators_id = DispatchInfo.get_excavator(group_id)
# 读取车辆位置信息
truck_locates_dict = get_trucks_locate()
logger.info("truck_locates_dict")
logger.info(truck_locates_dict)
# 装载区区分
# closer_area_id, further_area_id = area_analysis(excavators_id)
# closer_area_id = 'f1d5f017-5134-65a0-f657-89eed06eacc1'
# further_area_id = 'ef89f721-5134-3ef1-91e2-95b4e5004675'
closer_area_id = '7ff73575-2134-afd4-1065-d5d60e8751c9'
further_area_id = '79584290-1134-8b85-f4cc-1dcf64fc3456'
closer_excavator_id, further_excavator_id = DispatchInfo.load_excavator_dict[closer_area_id], \
DispatchInfo.load_excavator_dict[further_area_id]
logger.info("近端装载区")
logger.info(closer_area_id)
logger.info("远端装载区")
logger.info(further_area_id)
# 读取挖机状态
closer_excavator_state, further_excavator_state = get_excavator_state(closer_excavator_id), \
get_excavator_state(further_excavator_id)
# 装载区入场点
closer_entrance_node_id = session_postgre.query(DiggingWorkArea).filter_by(Id=closer_area_id).first().EntranceNodeId
further_entrance_node_id = session_postgre.query(DiggingWorkArea).filter_by(
Id=further_area_id).first().EntranceNodeId
logger.info("近端装载区入场点")
logger.info(closer_entrance_node_id)
logger.info("远端装载区入场点")
logger.info(further_entrance_node_id)
except Exception as es:
logger.error("读取装载区及车辆信息异常")
logger.error(es)
return jsonify(msg="未知异常, 请联系管理员", code=505)
# 目的地
target_excavator = None
# try:
try:
request_truck_lane_id = truck_locates_dict[request_truck_id]
logger.info("request_truck_lane_id:")
logger.info(request_truck_lane_id)
logger.info(truck_locates_dict)
except Exception as es:
logger.error("车辆位置信息不可用")
logger.error(es)
return jsonify(msg="车辆位置信息不可用, 请联系管理员", code=505)
# 车辆位置判断
if not truck_pass_first_area(request_truck_id, request_truck_lane_id, closer_entrance_node_id, further_entrance_node_id):
logger.info("车辆已经过近端装载区")
target_excavator = DispatchInfo.load_excavator_dict[further_area_id]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[further_area_id])
else:
# 近端挖机空闲
if closer_excavator_state == 1:
logger.info("近端挖机空闲, 调度车辆前往")
target_excavator = DispatchInfo.load_excavator_dict[closer_area_id]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[closer_area_id])
# 远端挖机空闲
elif further_excavator_state == 1:
logger.info("远端挖机空闲, 调度车辆前往")
target_excavator = DispatchInfo.load_excavator_dict[further_area_id]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[further_area_id])
# 两挖机均不空闲
else:
logger.info(" ")
logger.info(truck.excavator_hold_truck_list)
logger.info(list(excavators_id)[0])
logger.info(list(excavators_id)[1])
logger.info(truck.excavator_hold_truck_list[list(excavators_id)[0]])
logger.info(truck.excavator_hold_truck_list[list(excavators_id)[1]])
# 统计驶往两装载区的车辆
arrival_truck_set = truck.excavator_hold_truck_list[list(excavators_id)[0]]\
+ truck.excavator_hold_truck_list[list(excavators_id)[1]]
# 统计车辆抵达时间
arrival_truck_reach_time = [truck.cur_truck_reach_excavator[truck.truck_uuid_to_index_dict[truck_id]] for \
truck_id in arrival_truck_set]
# arrival_truck_set = ['309705a0-5ddf-4559-b6c4-ee17a57677ad', '899705a0-5ddf-4559-b6c4-ee17a57677ad']
#
# arrival_truck_reach_time = [8.04, 6.05]
logger.info("arrival_truck_reach_time")
logger.info(arrival_truck_reach_time)
logger.info("arrival_truck_set")
logger.info(arrival_truck_set)
arrival_truck_list = list(zip(np.array(arrival_truck_set), np.array(arrival_truck_reach_time)))
arrival_truck_list = sorted(arrival_truck_list, key=lambda item: item[1])
logger.info("arrival_truck_list")
logger.info(arrival_truck_list)
logger.info("arrival_truck_list")
logger.info(arrival_truck_list)
lane_set = get_lanes_between_entrances(closer_entrance_node_id, further_entrance_node_id)
# 统计不同状态车辆数量
goto_closer_area_num = 0
goto_further_area_num = 0
for truck_id, reach_time in arrival_truck_list:
truck_lane_id = truck_locates_dict[truck_id]
# # 车辆已经经过近端装载区
if truck_lane_id in lane_set:
goto_closer_area_num += 1
# # 车辆未经过近端装载区
else:
goto_further_area_num += 1
goto_further_area_num -= 1
logger.info("goto_further_area_num-goto_closer_area_num")
logger.info(goto_further_area_num)
logger.info(goto_closer_area_num)
goto_closer_area_num = 1
# 在远处排队等待的车辆更少
if goto_closer_area_num > goto_further_area_num:
logger.info("远端挖机排队时间短, 调度车辆前往")
target_excavator = DispatchInfo.load_excavator_dict[further_area_id]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[further_area_id])
else:
logger.info("近端挖机排队时间短, 调度车辆前往")
target_excavator = DispatchInfo.load_excavator_dict[closer_area_id]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[closer_area_id])
truck_dispatch_to_redis(request_truck_id, group_id, target_excavator)
# except Exception as es:
# logger.error(" ")
# logger.error(es)
# session_mysql.rollback()
# session_postgre.rollback()
# return jsonify(msg="未知异常, 请联系管理员", code=504)
logger.info("#####################################请求调度更新结束#####################################")
# 调度结束时间
rtd_end_time = datetime.now()
print(f'调度时耗 {rtd_end_time - rtd_start_time}')
return jsonify(msg="success", code=0)
def area_analysis(load_area_uuid):
"""
Analysis which area is closer.
:param load_area_uuid:
:return: closer_area_uuid, further_area_uuid
"""
try:
excavator_uuid_to_load_area_uuid_dict = get_value("excavator_uuid_to_load_area_uuid_dict")
load_area_uuid = list(load_area_uuid)
load_area_uuid[0] = excavator_uuid_to_load_area_uuid_dict[load_area_uuid[0]]
load_area_uuid[1] = excavator_uuid_to_load_area_uuid_dict[load_area_uuid[1]]
distance_a = session_postgre.query(WalkTimePark)\
.filter_by(load_area_id=load_area_uuid[0]).first().park_load_distance
distance_b = session_postgre.query(WalkTimePark)\
.filter_by(load_area_id=load_area_uuid[1]).first().park_load_distance
if distance_a > distance_b:
return load_area_uuid[1], load_area_uuid[0]
else:
return load_area_uuid[0], load_area_uuid[1]
except Exception as es:
logger.error("装载区距离分析异常")
logger.error(es)
return load_area_uuid[0], load_area_uuid[1]
def truck_pass_first_area(truck_id, lane_id, closer_entrance_node_id, further_entrance_node_id):
"""
Truck has gone through the first area.
:param truck_id:
:param lane_id:
:param closer_entrance_node_id:
:param further_entrance_node_id:
:return:
"""
# try:
def backtracking(root_node):
from collections import deque
que = deque([root_node])
while que:
size = len(que)
for _ in range(size):
cur_node = que.popleft()
if cur_node is None:
continue
logger.info(cur_node)
if cur_node == closer_entrance_node_id:
logger.info("closer_entrance_node")
return 0
if cur_node == further_entrance_node_id:
logger.info("further_entrance_node")
return 1
for item in session_postgre.query(Lane).filter_by(StartNodeId=cur_node).all():
if item:
que.append(item.EndNodeId)
node_id = session_postgre.query(Lane).filter_by(Id=lane_id).first().EndNodeId
if backtracking(root_node=node_id) == 0:
return True
else:
return False
# except Exception as es:
# logger.error("车辆行驶位置判断异常")
# logger.error(es)
# return True
def get_trucks_locate():
"""
get trucks locates.
:return: truck_locate_dict
"""
try:
truck_name_to_uuid_dict = get_value("truck_name_to_uuid_dict")
truck_locate_dict = {}
device_name_set = redis2.keys()
for item in device_name_set:
item = item.decode(encoding='utf-8')
key_value_dict = redis2.hgetall(item)
device_type = key_value_dict[str_to_byte('type')]
is_online = key_value_dict[str_to_byte('online')]
key_set = key_value_dict.keys()
if (device_type == str_to_byte("1")) \
and (str_to_byte('online') in key_set) \
and (bytes.decode(is_online) in ["true" or "True"]) \
and (str_to_byte('laneId') in key_set):
truck_locate = key_value_dict[str_to_byte('laneId')]
if eval(truck_locate) is not '':
truck_locate_dict[truck_name_to_uuid_dict[item]] = eval(truck_locate)
return truck_locate_dict
except Exception as es:
logger.error("车辆所在路段读取异常")
logger.error(es)
return {}
def truck_dispatch_to_redis(truck_id, group_id, excavator_id):
"""
write truck dispatch to redis.
:param truck_id:
:param group_id:
:param excavator_id:
:return:
"""
# 查询车辆相关派车计划
record = {}
try:
# dump_id = DispatchInfo.unload_area_dump_dict[unload_area_id]
item = (session_mysql.query(DispatchSetting).filter_by(exactor_id=excavator_id, group_id=group_id,
isdeleted=0, ).first())
if item is None:
raise Exception("调度计划配置异常")
except Exception as es:
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id, isdeleted=0, ).first())
logger.error(es)
# 其余调度信息写入
try:
# record["dispatchId"] = item.id
record["dispatchId"] = str(uuid.uuid1())
record["exactorId"] = item.exactor_id
record["loadAreaId"] = item.load_area_id
record["dumpId"] = item.dump_id
record["unloadAreaId"] = item.unload_area_id
record["groupId"] = group_id
record["isdeleted"] = False
record["isTemp"] = False
record["haulFlag"] = -1
record["groupName"] = DispatchInfo.group_name[group_id]
logger.info(f'redis 注入 {record}')
except Exception as es:
logger.error("调度结果写入异常-矿卡空载")
logger.error(es)
finally:
redis5.set(truck_id, str(json.dumps(record)))
def get_lanes_between_entrances(closer_node_id, further_node_id):
"""
get lanes between two entrance nodes.
:param closer_node_id:
:param further_node_id:
:return: lane set
"""
try:
max_find_it = 100
next_node_id = closer_node_id
lane_set = []
while max_find_it > 0 and next_node_id != further_node_id:
item = session_postgre.query(Lane).filter_by(StartNodeId=next_node_id, Type=2).first()
if item:
next_lane_id = item.Id
next_node_id = item.EndNodeId
lane_set.append(next_lane_id)
max_find_it -= 1
max_find_it -= 1
return lane_set
except Exception as es:
logger.error("获取装载区间路段异常")
logger.error(es)
return []
def get_excavator_state(excavator_id):
"""
get group_excavators state.
:param excavator_id:
:return: state
"""
try:
device_name = session_mysql.query(Equipment).filter_by(equipment_id=excavator_id, device_type=2).first().device_name
key_value_dict = redis2.hgetall(device_name)
is_online = key_value_dict[str_to_byte('online')]
key_set = key_value_dict.keys()
state = 100
if (str_to_byte('online') in key_set) and (bytes.decode(is_online) in ["true" or "True"]):
state = key_value_dict[str_to_byte('workState')]
return state
except Exception as es:
logger.error("挖机状态读取异常")
logger.error(es)
return 0
...@@ -97,6 +97,7 @@ class Topo(): ...@@ -97,6 +97,7 @@ class Topo():
return self.load_G_num_of_edges return self.load_G_num_of_edges
def get_work_area_distance_info(self): def get_work_area_distance_info(self):
# self.work_area_distance_info -> [[load_area_id, unload_area_id], to_unload_lanes, to_load_lanes]
try: try:
for item in session_postgre.query(WalkTime).all(): for item in session_postgre.query(WalkTime).all():
self.work_area_distance_info.append( self.work_area_distance_info.append(
...@@ -154,21 +155,21 @@ class Topo(): ...@@ -154,21 +155,21 @@ class Topo():
if Entrancenode_for_dump not in self.unload_G_all_nodes: if Entrancenode_for_dump not in self.unload_G_all_nodes:
self.unload_G_all_nodes.append(Entrancenode_for_dump) self.unload_G_all_nodes.append(Entrancenode_for_dump)
self.unload_G_dump_nodes.append(Entrancenode_for_dump) self.unload_G_dump_nodes.append(Entrancenode_for_dump)
try: try:
unload_saved_lane = [] unload_saved_lane = []
for i in item[1]: # for each lane in a to_unload route for lane_id in item[1]: # for each lane in a to_unload route
i_startpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().StartNodeId) lane_startpoint = str(session_postgre.query(Lane).filter_by(Id=lane_id).first().StartNodeId)
i_endpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().EndNodeId) lane_endpoint = str(session_postgre.query(Lane).filter_by(Id=lane_id).first().EndNodeId)
# add [start_point, end_point, length, lane_id] to unload_saved_lane # add [start_point, end_point, length, lane_id] to unload_saved_lane
unload_saved_lane.append([str(i_startpoint), str(i_endpoint), unload_saved_lane.append([str(lane_startpoint), str(lane_endpoint),
float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i]) float(session_postgre.query(Lane).filter_by(Id=lane_id).first().Length),
# son_lane_num = sum(1 for truck_id in session_postgre.query(Lane).filter_by(StartNodeId = i_endpoint).all()) lane_id])
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=i_endpoint).all()) # son_lane_num = sum(1 for truck_id in session_postgre.query(Lane).filter_by(StartNodeId = lane_endpoint).all())
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=lane_endpoint).all())
# 可以添加的节点:分叉口或终点 # 可以添加的节点:分叉口或终点
if son_lane_num > 1 or i_endpoint in self.unload_G_dump_nodes: if son_lane_num > 1 or lane_endpoint in self.unload_G_dump_nodes:
# print("item",item[0]) # print("item",item[0])
# print(unload_saved_lane) # print(unload_saved_lane)
# print("\n") # print("\n")
...@@ -188,17 +189,17 @@ class Topo(): ...@@ -188,17 +189,17 @@ class Topo():
# if [unload_saved_lane[0][0], unload_saved_lane[-1][1]] not in self.unload_G_edges: # if [unload_saved_lane[0][0], unload_saved_lane[-1][1]] not in self.unload_G_edges:
# self.unload_G_edges.append([unload_saved_lane[0][0], unload_saved_lane[-1][1]]) # self.unload_G_edges.append([unload_saved_lane[0][0], unload_saved_lane[-1][1]])
unload_saved_lane = [] unload_saved_lane = []
if i_startpoint not in self.unload_G_all_nodes: if lane_startpoint not in self.unload_G_all_nodes:
self.unload_G_all_nodes.append(i_startpoint) self.unload_G_all_nodes.append(lane_startpoint)
if i_endpoint not in self.unload_G_all_nodes: if lane_endpoint not in self.unload_G_all_nodes:
self.unload_G_all_nodes.append(i_endpoint) self.unload_G_all_nodes.append(lane_endpoint)
except Exception as es: except Exception as es:
self.logger.error(es) self.logger.error(es)
self.logger.error("去卸载区拓扑图出错") self.logger.error("去卸载区拓扑图出错")
session_mysql.rollback() session_mysql.rollback()
session_postgre.rollback() session_postgre.rollback()
# path_node_for_trip.append(Exitnode_for_digging) # add node for trip # path_node_for_trip.append(Exitnode_for_digging) # add node for trip
# if i_endpoint in self.unload_G_dump_nodes: # if lane_endpoint in self.unload_G_dump_nodes:
# load_G # load_G
Entrancenode_for_digging = str( Entrancenode_for_digging = str(
...@@ -216,24 +217,26 @@ class Topo(): ...@@ -216,24 +217,26 @@ class Topo():
self.load_G_all_nodes.append(Entrancenode_for_digging) self.load_G_all_nodes.append(Entrancenode_for_digging)
self.load_G_digging_nodes.append(Entrancenode_for_digging) self.load_G_digging_nodes.append(Entrancenode_for_digging)
self.load_G.add_node(Exitnode_for_dump, name='group_dumps', type=digging_name) self.load_G.add_node(Exitnode_for_dump, name='group_dumps', type=dump_name)
self.load_G.add_node(Entrancenode_for_digging, name='digging', type=dump_name) self.load_G.add_node(Entrancenode_for_digging, name='digging', type=digging_name)
try: try:
load_saved_lane = [] load_saved_lane = []
for i in item[2]: # [[str(item.load_area_id), str(item.unload_area_id)], item.to_unload_lanes, item.to_load_lanes] for lane_id in item[
load_i_startpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().StartNodeId) 2]: # [[str(item.load_area_id), str(item.unload_area_id)], item.to_unload_lanes, item.to_load_lanes]
load_i_endpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().EndNodeId) lane_startpoint = str(session_postgre.query(Lane).filter_by(Id=lane_id).first().StartNodeId)
lane_endpoint = str(session_postgre.query(Lane).filter_by(Id=lane_id).first().EndNodeId)
load_saved_lane.append([str(load_i_startpoint), str(load_i_endpoint), load_saved_lane.append([str(lane_startpoint), str(lane_endpoint),
float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i]) float(session_postgre.query(Lane).filter_by(Id=lane_id).first().Length),
# son_lane_num = sum(1 for truck_id in session_postgre.query(Lane).filter_by(StartNodeId = load_i_endpoint).all()) lane_id])
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=load_i_endpoint).all()) # son_lane_num = sum(1 for truck_id in session_postgre.query(Lane).filter_by(StartNodeId = lane_endpoint).all())
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=lane_endpoint).all())
nodes = list(self.load_G.nodes) nodes = list(self.load_G.nodes)
# 可以添加的节点:分叉口或终点 # 可以添加的节点:分叉口或终点
if son_lane_num > 1 or load_i_endpoint in self.load_G_digging_nodes or load_i_endpoint in nodes: if son_lane_num > 1 or lane_endpoint in self.load_G_digging_nodes or lane_endpoint in nodes:
# print("item",item[0]) # print("item",item[0])
# print(load_saved_lane) # print(load_saved_lane)
# print("\n") # print("\n")
...@@ -252,36 +255,46 @@ class Topo(): ...@@ -252,36 +255,46 @@ class Topo():
# if [load_saved_lane[0][0], load_saved_lane[-1][1]] not in self.load_G_edges: # if [load_saved_lane[0][0], load_saved_lane[-1][1]] not in self.load_G_edges:
# self.load_G_edges.append([load_saved_lane[0][0], load_saved_lane[-1][1]]) # self.load_G_edges.append([load_saved_lane[0][0], load_saved_lane[-1][1]])
load_saved_lane = [] load_saved_lane = []
if load_i_startpoint not in self.load_G_all_nodes: if lane_startpoint not in self.load_G_all_nodes:
self.load_G_all_nodes.append(load_i_startpoint) self.load_G_all_nodes.append(lane_startpoint)
if load_i_endpoint not in self.load_G_all_nodes: if lane_endpoint not in self.load_G_all_nodes:
self.load_G_all_nodes.append(load_i_endpoint) self.load_G_all_nodes.append(lane_endpoint)
except Exception as es: except Exception as es:
self.logger.error(es) self.logger.error(es)
self.logger.error("去装载区拓扑图生成失败") self.logger.error("去装载区拓扑图生成失败")
session_mysql.rollback() session_mysql.rollback()
session_postgre.rollback() session_postgre.rollback()
print(self.load_G.nodes.data()) print(self.load_G.nodes.data())
# park_to_load_G
for item in park_trip:
Entrancenode_for_digging = str(
session_postgre.query(DiggingWorkArea).filter_by(Id=item[0][1]).first().EntranceNodeId)
digging_name = str(
session_postgre.query(DiggingWorkArea).filter_by(Id=item[0][1]).first().Name)
Exitnode_for_park = str(session_postgre.query(ParkArea).filter_by(Id=item[0][0]).first().ExitNodeId)
park_name = str(session_postgre.query((ParkArea).filter_by(Id=item[0][0]).first().Name))
self.load_G.add_node(Exitnode_for_park, name='park', type=park_name)
self.load_G.add_node(Entrancenode_for_digging, name='digging', type=digging_name)
for k in park_trip:
try: try:
load_saved_lane = [] load_saved_lane = []
for i in k[1]: for lane_id in item[1]:
load_i_startpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().StartNodeId) lane_startpoint = str(session_postgre.query(Lane).filter_by(Id=lane_id).first().StartNodeId)
load_i_endpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().EndNodeId) lane_endpoint = str(session_postgre.query(Lane).filter_by(Id=lane_id).first().EndNodeId)
load_saved_lane.append([str(load_i_startpoint), str(load_i_endpoint), load_saved_lane.append([str(lane_startpoint), str(lane_endpoint),
float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i]) float(session_postgre.query(Lane).filter_by(Id=lane_id).first().Length),
# son_lane_num = sum(1 for truck_id in session_postgre.query(Lane).filter_by(StartNodeId = load_i_endpoint).all()) lane_id])
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=load_i_endpoint).all()) # son_lane_num = sum(1 for truck_id in session_postgre.query(Lane).filter_by(StartNodeId = lane_endpoint).all())
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=lane_endpoint).all())
nodes = list(self.load_G.nodes) nodes = list(self.load_G.nodes)
# 可以添加的节点:分叉口或终点 # 可以添加的节点:分叉口或终点
if son_lane_num > 1 or load_i_endpoint in self.load_G_digging_nodes or load_i_endpoint in nodes: if son_lane_num > 1 or lane_endpoint in self.load_G_digging_nodes or lane_endpoint in nodes:
# print("item",item[0]) # print("item",item[0])
# print(load_saved_lane) # print(load_saved_lane)
# print("\n") # print("\n")
...@@ -300,10 +313,10 @@ class Topo(): ...@@ -300,10 +313,10 @@ class Topo():
# if [load_saved_lane[0][0], load_saved_lane[-1][1]] not in self.load_G_edges: # if [load_saved_lane[0][0], load_saved_lane[-1][1]] not in self.load_G_edges:
# self.load_G_edges.append([load_saved_lane[0][0], load_saved_lane[-1][1]]) # self.load_G_edges.append([load_saved_lane[0][0], load_saved_lane[-1][1]])
load_saved_lane = [] load_saved_lane = []
if load_i_startpoint not in self.load_G_all_nodes: if lane_startpoint not in self.load_G_all_nodes:
self.load_G_all_nodes.append(load_i_startpoint) self.load_G_all_nodes.append(lane_startpoint)
if load_i_endpoint not in self.load_G_all_nodes: if lane_endpoint not in self.load_G_all_nodes:
self.load_G_all_nodes.append(load_i_endpoint) self.load_G_all_nodes.append(lane_endpoint)
except Exception as es: except Exception as es:
self.logger.error(es) self.logger.error(es)
self.logger.error("备停区部分装载拓扑图生成失败") self.logger.error("备停区部分装载拓扑图生成失败")
...@@ -354,10 +367,11 @@ class Topo(): ...@@ -354,10 +367,11 @@ class Topo():
distance, path = nx.single_source_dijkstra(self.unload_G, source=source_node, target=i, distance, path = nx.single_source_dijkstra(self.unload_G, source=source_node, target=i,
weight="real_distance") weight="real_distance")
unload_area_id = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first(EntranceNodeId=i).first().Id unload_area_id = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first(
EntranceNodeId=i).first().Id
unload_area_lane_dict[str(unload_area_id)] = [] unload_area_lane_dict[str(unload_area_id)] = []
for j in range(len(path) - 1): for j in range(len(path) - 1):
unload_area_lane_dict[str(unload_area_id)] += self.load_G[path[j]][path[j+1]]['lane'] unload_area_lane_dict[str(unload_area_id)] += self.load_G[path[j]][path[j + 1]]['lane']
path_length_map[distance] = path path_length_map[distance] = path
# print(path) # print(path)
...@@ -402,7 +416,6 @@ class Topo(): ...@@ -402,7 +416,6 @@ class Topo():
data[u] = [v[0], v[0]] data[u] = [v[0], v[0]]
self.load_G[path[i]][path[i + 1]]['locked_distance'] = sum(i[-1] for i in list(data.values())) self.load_G[path[i]][path[i + 1]]['locked_distance'] = sum(i[-1] for i in list(data.values()))
""" """
return relative distance between node and lane (graph_type: 0=load, 1=unload) return relative distance between node and lane (graph_type: 0=load, 1=unload)
""" """
...@@ -455,7 +468,6 @@ class Topo(): ...@@ -455,7 +468,6 @@ class Topo():
if not len(target_list): if not len(target_list):
self.logger.error("当前无可去装载区!") self.logger.error("当前无可去装载区!")
load_area_lane_dict = {} load_area_lane_dict = {}
# print(target_list) # print(target_list)
...@@ -469,7 +481,7 @@ class Topo(): ...@@ -469,7 +481,7 @@ class Topo():
load_area_id = session_postgre.query(DiggingWorkArea).filter_by(EntranceNodeId=i).first().Id load_area_id = session_postgre.query(DiggingWorkArea).filter_by(EntranceNodeId=i).first().Id
load_area_lane_dict[str(load_area_id)] = [] load_area_lane_dict[str(load_area_id)] = []
for j in range(len(path) - 1): for j in range(len(path) - 1):
load_area_lane_dict[str(load_area_id)] += self.load_G[path[j]][path[j+1]]['lane'] load_area_lane_dict[str(load_area_id)] += self.load_G[path[j]][path[j + 1]]['lane']
path_length_map[distance] = path path_length_map[distance] = path
# print(path) # print(path)
...@@ -490,6 +502,50 @@ class Topo(): ...@@ -490,6 +502,50 @@ class Topo():
return reachable_destinations, load_area_lane_dict return reachable_destinations, load_area_lane_dict
def get_park_target_node_real(self, truck_location_lane):
# source_node = self.get_load_edge_node(truck_location_lane)
source_node, end_node = self.get_load_edge_node(truck_location_lane)
distance_source_node, distance_end_node = self.relative_distance(truck_location_lane, graph_type=0)
# update target_list
target_list = []
for (node, att) in self.load_G.nodes.data('name'):
# select next reachable target
if att == 'park':
target_list.append(node)
park_area_lane_dict = {}
# print(target_list)
path_length_map = {}
# build the path_length_map from source node
for i in target_list:
try:
distance, path = nx.single_source_dijkstra(self.load_G, source=source_node, target=i,
weight="real_distance")
load_area_id = session_postgre.query(DiggingWorkArea).filter_by(EntranceNodeId=i).first().Id
park_area_lane_dict[str(load_area_id)] = []
for j in range(len(path) - 1):
park_area_lane_dict[str(load_area_id)] += self.load_G[path[j]][path[j + 1]]['lane']
path_length_map[distance] = path
# print(path)
except Exception as es:
self.logger.info(es)
self.logger.info(f"装载图中{source_node} 与 {i} 之间道路不通")
reachable_destinations = {}
# 如果列表最后是标识符,0表示需要掉头的目的地,1表示不需要掉头的目的地
for k, v in path_length_map.items():
entrance_point = v[-1]
target_digging_area = str(
session_postgre.query(ParkArea).filter_by(EntranceNodeId=entrance_point).first().Id)
reachable_destinations[target_digging_area] = k + distance_source_node
return reachable_destinations, park_area_lane_dict
def update_cross_nodes(self): def update_cross_nodes(self):
""" """
get cross nodes. get cross nodes.
...@@ -511,6 +567,6 @@ class Topo(): ...@@ -511,6 +567,6 @@ class Topo():
lanes = session_postgre.query(Lane).filter_by(EndNodeId=node_id).first() lanes = session_postgre.query(Lane).filter_by(EndNodeId=node_id).first()
if lanes is not None: if lanes is not None:
self.cross_bf_lanes.append(str(lanes.Id)) self.cross_bf_lanes.append(str(lanes.Id))
def get_cross_nodes(self): def get_cross_nodes(self):
return self.cross_nodes return self.cross_nodes
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
# 实时调度模块 # 实时调度模块
from data.para_config import * from data.para_config import *
from equipment.truck import TruckInfo from data.equipment import TruckInfo
from equipment.excavator import ExcavatorInfo from data.equipment import ExcavatorInfo
from equipment.dump import DumpInfo from data.equipment import DumpInfo
import sched import sched
import time import time
from core.dispatcher import Dispatcher from core.dispatcher import Dispatcher
......
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
# 实时调度模块 # 实时调度模块
from data.para_config import * from data.para_config import *
from equipment.truck import TruckInfo from data.equipment import TruckInfo
from equipment.excavator import ExcavatorInfo from data.equipment import ExcavatorInfo
from equipment.dump import DumpInfo from data.equipment import DumpInfo
import sched import sched
import time import time
from core.dispatcher import Dispatcher from core.dispatcher import Dispatcher
...@@ -188,4 +188,4 @@ if __name__ == "__main__": ...@@ -188,4 +188,4 @@ if __name__ == "__main__":
logger.info(" ") logger.info(" ")
logger.info("调度系统启动") logger.info("调度系统启动")
main(20, dispatcher) main(30, dispatcher)
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2022/8/3 17:53
# @Author : Opfer
# @Site :
# @File : redispatch.py
# @Software: PyCharm
from flask import Flask, request
from flask.json import jsonify
from data.para_config import *
from equipment.truck import TruckInfo
from equipment.excavator import ExcavatorInfo
from equipment.dump import DumpInfo
from core.dispatcher import PreSchedule
from core.group import Group
from flask_caching import Cache
from alg.algorithm import ExpectedTime
from data.dispatchInfo import DispatchInfo
from core.submit import DispatchSubmission
from graph.graph_load import graph_construct
config = {
"DEBUG": True, # some Flask specific configs
"CACHE_TYPE": "SimpleCache", # Flask-Caching related configs
"CACHE_DEFAULT_TIMEOUT": 300
}
app = Flask(__name__)
app.config.from_mapping(config)
cache = Cache(app)
def update_truck_loacate(truck_id):
# 读取矿卡所在路段信息
try:
truck_locate_dict = {}
device_name_set = redis2.keys()
for item in device_name_set:
item = item.decode(encoding='utf-8')
# json_value = json.loads(redis2.get(item))
key_value_dict = redis2.hgetall(item)
device_type = key_value_dict[str_to_byte('type')]
is_online = key_value_dict[str_to_byte('online')]
key_set = key_value_dict.keys()
if (device_type == str_to_byte("1")) \
and (str_to_byte('online') in key_set) \
and (bytes.decode(is_online) in ["true" or "True"]) \
and (str_to_byte('laneId') in key_set):
truck_locate = key_value_dict[str_to_byte('laneId')]
truck_locate_dict[get_value("truck_name_to_uuid_dict")[item]] = eval(truck_locate)
except Exception as es:
logger.error(" ")
return truck_locate_dict[truck_id]
@app.route("/redispatch", methods=["POST"])
def dispatch_request():
# 获取报文数据
data_json = request.get_json()
# 车辆id
truck_id = data_json.get("truck_id")
# 调度开始时间
rtd_start_time = datetime.now()
# 初始化日志
set_log()
# 获取日志器
logger = get_logger("zxt.truck-request")
# 更新周期参数
logger.info("#####################################请求调度更新开始#####################################")
try:
# 清空数据库缓存
session_mysql.commit()
session_mysql.flush()
# 清空数据库缓存
session_postgre.commit()
session_postgre.flush()
except Exception as es:
logger.error("数据库访问异常")
logger.error(es)
return jsonify(msg="未知异常, 请联系管理员", code=501)
try:
# 全局参数更新
global_period_para_update()
# get_global_para_from_cache(cache)
except Exception as es:
logger.error("全局参数更新异常")
logger.error(es)
session_mysql.rollback()
session_postgre.rollback()
return jsonify(msg="未知异常, 请联系管理员", code=502)
try:
# 更新调度信息
DispatchInfo.reset()
DispatchInfo.update_device_group_structure()
if group_id not in DispatchInfo.truck_group_dict:
raise Exception("请求调度车辆不存在")
DispatchInfo.update_route_distance()
DispatchInfo.update_group_mode()
DispatchInfo.update_group_name()
except Exception as es:
logger.error("调度信息更新异常")
logger.error(es)
session_mysql.rollback()
session_postgre.rollback()
return jsonify(msg="未知异常, 请联系管理员", code=503)
logger.info("Dispatchinfo,更新后信息")
logger.info("group_set")
logger.info(DispatchInfo.group_set)
logger.info("group_excavator_dict")
logger.info(DispatchInfo.group_excavator_dict)
logger.info("group_unload_area_dict")
logger.info(DispatchInfo.group_unload_area_dict)
logger.info("group_truck_dict")
logger.info(DispatchInfo.group_truck_dict)
logger.info("group_mode")
logger.info(DispatchInfo.group_mode)
logger.info("load_distance")
logger.info(DispatchInfo.load_distance)
logger.info("unload_distance")
logger.info(DispatchInfo.unload_distance)
try:
# 实例化设备对象
dump = DumpInfo()
excavator = ExcavatorInfo()
truck = TruckInfo(dump, excavator)
group_id = DispatchInfo.truck_group_dict[truck_id]
# 设备信息更新
dump.dump_para_period_update()
excavator.excavator_para_period_update()
truck.truck_para_period_update(dump, excavator)
truck.state_period_update()
# 实例化调度预测器
pre_sch = PreSchedule(truck, excavator, dump)
# 实例化输出器
submission = DispatchSubmission(dump, excavator, truck)
# 实例化调度分组
group = Group(group_id, truck, pre_sch)
# 更新调度分组信息
group.info_update()
truck_trip = truck.get_truck_current_trip()[truck.truck_uuid_to_index_dict[truck_id]]
truck_task = truck.get_truck_current_task()[truck_id]
truck_lane = update_truck_loacate(truck_id)
excavators = DispatchInfo.group_excavator_dict[group_id]
dumps = DispatchInfo.dump_group_dict[group_id]
topo = graph_construct()
next_target = None
if truck_task in [-2, 0]:
excavator_distance_dict = topo.get_load_target_node_real(truck_lane, None)
MAX_DIS = 100000000
for excavator_id in excavators:
if excavator_distance_dict[excavator_id] < MAX_DIS:
next_target = excavator_id
MAX_DIS = excavator_distance_dict[excavator_id]
elif truck_task == 3:
dump_distance_dict = topo.get_unload_target_node_real(truck_lane, None)
MAX_DIS = 100000000
for dump_id in dumps:
if dump_distance_dict[dump_id] < MAX_DIS:
next_target = dump_id
MAX_DIS = dump_distance_dict[dump_id]
except Exception as es:
logger.error("对象实例化异常")
logger.error(es)
session_mysql.rollback()
session_postgre.rollback()
return jsonify(msg="未知异常, 请联系管理员", code=504)
try:
# 调度分组派车计划计算
try:
truck_dispatch_plan_dict = group.group_dispatch(ExpectedTime)
except Exception as es:
logger.error(es)
logger.error(f'分组{group.group_id} 调度计算异常')
try:
logger.info(f'调度分组: {group.group_id} {DispatchInfo.group_name[group.group_id]}')
submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict)
except Exception as es:
logger.error(es)
logger.error(f'分组{group.group_id} 调度写入异常')
except Exception as es:
logger.error("最外层异常捕获")
logger.error(es)
return jsonify(msg="未知异常, 请联系管理员", code=505)
session_mysql.close()
session_postgre.close()
logger.info("#####################################请求调度更新结束#####################################")
# 调度结束时间
rtd_end_time = datetime.now()
print(f'调度时耗 {rtd_end_time - rtd_start_time}')
return jsonify(msg="success", code=0)
\ No newline at end of file
...@@ -69,8 +69,8 @@ def set_log(): ...@@ -69,8 +69,8 @@ def set_log():
# timefilehandler = logging.handlers.TimedRotatingFileHandler(log_path + "/dispatch.log", when='M', interval=1, backupCount=60) # timefilehandler = logging.handlers.TimedRotatingFileHandler(log_path + "/dispatch.log", when='M', interval=1, backupCount=60)
filehandler = logging.handlers.RotatingFileHandler(log_path + "/dispatch.log", maxBytes=30*1024*1024, backupCount=10, encoding="utf-8") # filehandler = logging.handlers.RotatingFileHandler(log_path + "/dispatch.log", maxBytes=30*1024*1024, backupCount=10, encoding="utf-8")
# filehandler = logging.handlers.RotatingFileHandler("./Logs/dispatch.log", maxBytes=3 * 1024 * 1024, backupCount=10, encoding="utf-8") filehandler = logging.handlers.RotatingFileHandler("./Logs/dispatch.log", maxBytes=3 * 1024 * 1024, backupCount=10, encoding="utf-8")
# 设置后缀名称,跟strftime的格式一样 # 设置后缀名称,跟strftime的格式一样
filehandler.suffix = "%Y-%m-%d_%H-%M.log" filehandler.suffix = "%Y-%m-%d_%H-%M.log"
......
...@@ -406,6 +406,21 @@ class DiggingWorkArea(Base): ...@@ -406,6 +406,21 @@ class DiggingWorkArea(Base):
self.ExitNodeId = ExitNodeId self.ExitNodeId = ExitNodeId
class ParkArea(Base):
__tablename__ = 'Geo_ParkSpot'
Id = Column(VARCHAR(50), primary_key=True)
Name = Column(VARCHAR(36))
EntranceNodeId = Column(VARCHAR(50))
ExitNodeId = Column(VARCHAR(50))
def __init__(self, Id, Name, EntranceNodeId, ExitNodeId):
self.Id = Id
self.Name = Name
self.EntranceNodeId = EntranceNodeId
self.ExitNodeId = ExitNodeId
class DispatchRule(Base): class DispatchRule(Base):
__tablename__ = 'sys_dispatch_rule' __tablename__ = 'sys_dispatch_rule'
......
No preview for this file type
...@@ -192,7 +192,7 @@ def truck_pass_first_area(truck_id, lane_id, closer_entrance_node_id, further_en ...@@ -192,7 +192,7 @@ def truck_pass_first_area(truck_id, lane_id, closer_entrance_node_id, further_en
def get_trucks_locate(): def get_trucks_locate():
""" """
get trucks locates. get trucks locates.
:return: truck_locate_dict :return: truck_lane_locate_dict
""" """
try: try:
...@@ -306,9 +306,8 @@ def get_excavator_state(excavator_id): ...@@ -306,9 +306,8 @@ def get_excavator_state(excavator_id):
:param excavator_id: :param excavator_id:
:return: state :return: state
""" """
try: # try:
logger.error(excavator_id)
device_name = session_mysql.query(Equipment).filter_by(id=excavator_id, device_type=2).first().device_name device_name = session_mysql.query(Equipment).filter_by(id=excavator_id, device_type=2).first().device_name
key_value_dict = redis2.hgetall(device_name) key_value_dict = redis2.hgetall(device_name)
...@@ -318,7 +317,7 @@ def get_excavator_state(excavator_id): ...@@ -318,7 +317,7 @@ def get_excavator_state(excavator_id):
logger.warning(f'挖机 {device_name} 不在线') logger.warning(f'挖机 {device_name} 不在线')
return 0 return 0
key_set = key_value_dict.keys() key_set = key_value_dict.keys()
state = 100 state = str_to_byte('100')
if (str_to_byte('online') in key_set) and (bytes.decode(is_online) in ["true" or "True"]): if (str_to_byte('online') in key_set) and (bytes.decode(is_online) in ["true" or "True"]):
if str_to_byte('workState') in key_set: if str_to_byte('workState') in key_set:
state = key_value_dict[str_to_byte('workState')] state = key_value_dict[str_to_byte('workState')]
...@@ -328,7 +327,7 @@ def get_excavator_state(excavator_id): ...@@ -328,7 +327,7 @@ def get_excavator_state(excavator_id):
return int(float(byte_to_str(state))) return int(float(byte_to_str(state)))
except Exception as es: # except Exception as es:
logger.error("挖机状态读取异常") # logger.error("挖机状态读取异常")
logger.error(es) # logger.error(es)
return 0 # return 0
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment