Commit c81d437a authored by 张晓彤's avatar 张晓彤

代码优化v2

parent 39eaec24
...@@ -9,7 +9,7 @@ from core.group import Group ...@@ -9,7 +9,7 @@ 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 data.dispatchInfo import DispatchInfo
from core.dispatcher import DispatchSubmission from core.submit import DispatchSubmission
config = { config = {
"DEBUG": True, # some Flask specific configs "DEBUG": True, # some Flask specific configs
......
...@@ -5,23 +5,15 @@ ...@@ -5,23 +5,15 @@
# @Site : # @Site :
# @File : dispatcher.py # @File : dispatcher.py
# @Software: PyCharm # @Software: PyCharm
from core.submit import DispatchSubmission
from data.dispatchInfo import DispatchInfo 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, redis5 from settings import get_logger
from tables import DispatchSetting
from data.para_config import get_value
from equipment import TruckInfo, ExcavatorInfo, DumpInfo from equipment import TruckInfo, ExcavatorInfo, DumpInfo
from core.schedule import PreSchedule from core.schedule import PreSchedule
import json
import uuid
from tables import session_mysql, session_postgre
from graph.graph_load import graph_construct from graph.graph_load import graph_construct
from core.util import POST from core.group import GroupDispatcher
from graph.topo_graph import Topo
from core.group import CurrentTruck
from typing import List
class Dispatcher: class Dispatcher:
...@@ -81,7 +73,11 @@ class Dispatcher: ...@@ -81,7 +73,11 @@ class Dispatcher:
# try: # try:
truck_dispatch_plan_dict = group.group_dispatch(ExpectedTime) # truck_dispatch_plan_dict = group.group_dispatch(ExpectedTime)
group_dispatcher = GroupDispatcher(group)
truck_dispatch_plan_dict = group_dispatcher.group_dispatch(ExpectedTime)
if truck_dispatch_plan_dict is None: if truck_dispatch_plan_dict is None:
self.logger.error(f'分组 {group.group_id} 调度异常') self.logger.error(f'分组 {group.group_id} 调度异常')
...@@ -95,297 +91,3 @@ class Dispatcher: ...@@ -95,297 +91,3 @@ class Dispatcher:
self.submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict) self.submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict)
def redis_format(truck_id, group_id, dispatch_id, item):
record = {"truckId": truck_id, "dispatchId": dispatch_id, "exactorId": item.exactor_id, "dumpId": item.dump_id,
"loadAreaId": item.load_area_id, "unloadAreaId": item.unload_area_id, "groupId": item.group_id,
"isdeleted": False, "isTemp": False, "haulFlag": -1, "groupName": DispatchInfo.group_name[group_id]}
return record
class DispatchSubmission:
""" class for the submission calculated dispatch.
Description:
将调度结果按照指定格式传递到云端机群
Attribute:
"""
def __init__(self, dump: DumpInfo, excavator: ExcavatorInfo, truck: TruckInfo, topo: Topo):
self.logger = get_logger("zxt.submission")
self.dump = dump
self.excavator = excavator
self.truck = truck
self.topo = topo
def truck_dispatch_to_redis(self, truck_id: str, truck_info: CurrentTruck, dispatch_seq: List[int], group_mode: int):
"""
将truck_id对应矿卡派车计划写入redis
:param group_mode: (int)
:param truck_id: (uuid) 矿卡uuid
:param truck_info: (object)
:param dispatch_seq: (List[int]) 矿卡派车计划
:return: None
"""
self.logger.info(f'调度车辆编号 {get_value("truck_uuid_to_name_dict")[truck_id]} {truck_id}')
self.logger.info(f'车辆任务 {truck_info.get_task()}')
self.logger.info(f'配对挖机 {dispatch_seq[0]}')
self.logger.info(f'配对卸点 {dispatch_seq[1]}')
# try:
if truck_id not in DispatchInfo.truck_group_dict:
group_id = None
self.logger.error(f'调度结果写入异常-读取矿卡 {truck_id} 所在分组信息异常')
else:
group_id = DispatchInfo.truck_group_dict[truck_id]
record = {"truckId": truck_id}
# if group_id is None or DispatchInfo.get_group_mode(group_id) is None:
# group_mode = 3
# self.logger.error("调度模式读取异常-设置为固定派车模式")
# else:
# group_mode = DispatchInfo.get_group_mode(group_id)
self.logger.info(f'调度模式 {group_mode}')
if group_mode == 3:
self.logger.info("固定派车模式")
self.fixed_dispatch_mode(group_id, truck_id)
else:
self.logger.info("动态调度模式")
self.dynamic_dispatch_mode(dispatch_seq, group_id, record, truck_info.get_sate(),
truck_info.get_task(), truck_id)
# except Exception as es:
# self.logger.error("调度结果写入异常")
# self.logger.error(f"调度结果:{dispatch_seq}")
# self.logger.error(es)
def dynamic_dispatch_mode(self, dispatch_seq, group_id, record, state, task, truck_id):
"""
write dispatch plan in dynamic dispatch mode.
:param dispatch_seq:
:param group_id:
:param record:
:param state:
:param task:
:param truck_id:
:return:
"""
if (task in [1, 2]) or (task == 3 and state == 2): # 车辆位于卸载区,或车辆重载等待
self.logger.info(f'卸载区内或重载等待,请求装载区 {truck_id}')
# 查询车辆相关派车计划 dispatch_seq[next_excavator_id, next_unload_area_id]
if dispatch_seq[1] is None or [dispatch_seq[1]] not in DispatchInfo.unload_area_dump_dict:
# 无法查询到目标卸载点
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id, isdeleted=0, ).first())
else:
dump_id = DispatchInfo.unload_area_dump_dict[dispatch_seq[1]]
try:
item = (session_mysql.query(DispatchSetting).filter_by(dump_id=dump_id, group_id=group_id,
isdeleted=0, ).first())
if item is None:
raise Exception(f'{truck_id} 无法找到派车计划 {dump_id} {group_id}')
if dispatch_seq[0] is None:
raise Exception("调度计划挖机与实时监控不匹配")
except Exception as es:
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id, isdeleted=0, ).first())
self.logger.error(es)
# 其余调度信息写入
try:
redis_format(truck_id, group_id, str(uuid.uuid1()), item)
# # 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]
if task == 3 and state == 2 and self.truck.get_truck_locate_dict()[truck_id] in self.topo.cross_bf_lanes:
# try:
# if truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]:
self.logger.info("二次调度前往卸载区")
record["isTemp"] = True
redis5.set(truck_id, str(json.dumps(record)))
POST(truck_id)
self.logger.info(f'redis 注入 {record}')
# else:
# self.logger.info("车辆已完成二次调度-无需更改派车计划")
# except Exception as es:
# self.logger.error(es)
# self.logger.error("二次调度失败")
# record["isTemp"] = False
# redis5.set(truck_id, str(json.dumps(record)))
else:
self.logger.info("调度前往卸载区")
record["isTemp"] = False
redis5.set(truck_id, str(json.dumps(record)))
self.logger.info(f'redis 注入 {record}')
# redis5.set(truck_id, str(json.dumps(record)))
except Exception as es:
self.logger.error("调度结果写入异常-矿卡空载")
self.logger.error(es)
redis5.set(truck_id, str(json.dumps(record)))
# redis5.set(truck_id, str(json.dumps(record)))
# finally:
# redis5.set(truck_id, str(json.dumps(record)))
elif (task in [4, 5]) or (task == 0 and state == 2): # 卡车重载或在卸载区出场前, 可变更装载目的地
self.logger.info(f'调度2 {truck_id}')
# 查询车辆相关派车计划
try:
item = (session_mysql.query(DispatchSetting).filter_by(exactor_id=dispatch_seq[0], group_id=group_id,
isdeleted=0, ).first())
if item is None:
raise Exception("调度计划配置异常")
if dispatch_seq[0] is None:
raise Exception("调度计划表与实时监控不匹配")
except Exception as es:
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id, isdeleted=0, ).first())
self.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]
if task == 0 and state == 2 and self.truck.get_truck_locate_dict()[truck_id] in self.topo.cross_bf_lanes:
# 车辆停车等待
# try:
# if truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]:
self.logger.info("二次调度前往装载区")
record["isTemp"] = True
# 若尚未二次调度
redis5.set(truck_id, str(json.dumps(record)))
POST(truck_id)
self.logger.info(f'redis 注入 {record}')
# else:
# self.logger.info("车辆已完成二次调度-无需更改派车计划")
# except Exception as es:
# self.logger.error(es)
# self.logger.error("二次调度失败")
# record["isTemp"] = False
# redis5.set(truck_id, str(json.dumps(record)))
else:
self.logger.info("调度前往装载区")
record["isTemp"] = False
redis5.set(truck_id, str(json.dumps(record)))
self.logger.info(f'redis 注入 {record}')
# redis5.set(truck_id, str(json.dumps(record)))
except Exception as es:
self.logger.error("调度结果写入异常-矿卡重载")
redis5.set(truck_id, str(json.dumps(record)))
# finally:
# redis5.set(truck_id, str(json.dumps(record)))
elif task == -2:
self.logger.info(f'调度3 {truck_id}')
try:
# 查询车辆相关派车计划
try:
item = (session_mysql.query(DispatchSetting).filter_by(exactor_id=dispatch_seq[0],
group_id=group_id, isdeleted=0).first())
if item is None:
raise Exception("调度计划配置异常")
if dispatch_seq[0] is None:
raise Exception("调度计划表与实时监控不匹配")
except Exception as es:
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id,
isdeleted=0, ).first())
self.logger.error(es)
# 调度信息写入
# try:
self.logger.info(f'redis 注入 {record}')
record = redis_format(truck_id, group_id, str(uuid.uuid1()), item)
redis5.set(truck_id, str(json.dumps(record)))
# except Exception as es:
# self.logger.error("调度结果写入异常-矿卡故障或备停区-redis写入异常")
# self.logger.error(es)
# finally:
# redis5.set(truck_id, str(json.dumps(record)))
except Exception as es:
self.logger.error("调度结果写入异常-矿卡故障或备停区")
self.logger.error(es)
else:
pass
def fixed_dispatch_mode(self, group_id, truck_id):
"""
write dispatch plan in fixed dispatch method.
:param group_id:
:param record:
:param truck_id:
:return:
"""
try:
item = session_mysql.query(DispatchSetting).filter_by(truck_id=truck_id, isdeleted=0, ).first()
except Exception as es:
item = None
self.logger.error(es)
session_postgre.rollback()
session_mysql.rollback()
if item is None:
self.logger.error(f'车辆 {truck_id} 无派车计划-无法执行固定派车')
return
record = redis_format(truck_id, group_id, item.id, item)
redis5.set(truck_id, str(json.dumps(record)))
self.logger.info(f'redis 注入 {record}')
def group_dispatch_to_redis(self, group: Group, dispatch_plan_dict):
"""
Update the dispatch plan in the group to redis
:param group: (Group)
:param dispatch_plan_dict: (Dict)
:return: None
"""
self.logger.info(f'调度分组: {group.group_id} {DispatchInfo.group_name[group.group_id]}')
self.logger.info(f'组内车辆 {group.truck_set}')
self.logger.info(f'组内挖机 {group.excavator}')
self.logger.info(f'组内卸点 {group.dump}')
self.logger.info(f'调度模式 {group.group_mode}')
self.logger.info("dispatch_plan_dict")
self.logger.info(dispatch_plan_dict)
for truck_id, dispatch_plan in dispatch_plan_dict.items():
try:
self.logger.info(f'======================================= 调度车辆 =======================================')
self.truck_dispatch_to_redis(truck_id, group.truck_info_list[truck_id], dispatch_plan, group.group_mode)
self.logger.info("======================================== 完成写入 =======================================")
except Exception as es:
self.logger.error("group_dispatch_to_redis_error")
self.logger.error(es)
...@@ -241,6 +241,13 @@ class Group: ...@@ -241,6 +241,13 @@ class Group:
self.update_group_road_network() self.update_group_road_network()
self.update_device_material() self.update_device_material()
class GroupDispatcher:
def __init__(self, group: Group):
self.logger = logging.getLogger("zxt.GroupDispatcher")
self.group = group
def group_dispatch(self, Solver) -> Mapping[str, List[str]]: def group_dispatch(self, Solver) -> Mapping[str, List[str]]:
""" """
Receive a Alg obj. and output dispatch plan for trucks in this group. Receive a Alg obj. and output dispatch plan for trucks in this group.
...@@ -249,24 +256,24 @@ class Group: ...@@ -249,24 +256,24 @@ class Group:
dispatch plan: Dict({truck_id: match_id}) dispatch plan: Dict({truck_id: match_id})
""" """
truck_dispatch = {} truck_dispatch = {}
self.truck_info_list = {} self.group.truck_info_list = {}
assert issubclass(Solver, AlgorithmBase) assert issubclass(Solver, AlgorithmBase)
solver = Solver(self, self.truck, self.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_name} 调度计算-调度模式 {self.group_mode}') self.logger.info(f'分组 {self.group.group_name} 调度计算-调度模式 {self.group.group_mode}')
for truck_id in list(self.truck_set): for truck_id in list(self.group.truck_set):
self.logger.info(f'调度车辆 {truck_id}') self.logger.info(f'调度车辆 {truck_id}')
# try: # try:
# get truck index from mapping # get truck index from mapping
try: try:
if truck_id not in self.truck.truck_uuid_to_index_dict: if truck_id not in self.group.truck.truck_uuid_to_index_dict:
raise CoreException(102, f'truck.truck dict 中不存在 {truck_id}') raise CoreException(102, f'truck.truck dict 中不存在 {truck_id}')
truck_idx = self.truck.truck_uuid_to_index_dict[truck_id] truck_idx = self.group.truck.truck_uuid_to_index_dict[truck_id]
except CoreException as es: except CoreException as es:
es.with_traceback_info() es.with_traceback_info()
self.logger.error(es) self.logger.error(es)
...@@ -274,12 +281,12 @@ class Group: ...@@ -274,12 +281,12 @@ class Group:
# get truck trip from truck obj. # get truck trip from truck obj.
try: try:
truck_trip_info_list = self.truck.get_truck_current_trip() truck_trip_info_list = self.group.truck.get_truck_current_trip()
if truck_idx >= len(truck_trip_info_list): if truck_idx >= len(truck_trip_info_list):
raise CoreException(103, f'truck.truck trip 中不存在 {truck_idx} 号矿卡 {truck_id}') raise CoreException(103, f'truck.truck trip 中不存在 {truck_idx} 号矿卡 {truck_id}')
truck_trip = self.truck.get_truck_current_trip()[truck_idx] truck_trip = self.group.truck.get_truck_current_trip()[truck_idx]
except CoreException as es: except CoreException as es:
es.with_traceback_info() es.with_traceback_info()
self.logger.error(es) self.logger.error(es)
...@@ -287,7 +294,7 @@ class Group: ...@@ -287,7 +294,7 @@ class Group:
# get truck task from truck obj. # get truck task from truck obj.
try: try:
truck_task_list = self.truck.get_truck_current_task() truck_task_list = self.group.truck.get_truck_current_task()
if truck_id not in truck_task_list: if truck_id not in truck_task_list:
raise CoreException(102, f'truck.truck task 中不存在矿卡 {truck_id}') raise CoreException(102, f'truck.truck task 中不存在矿卡 {truck_id}')
...@@ -300,10 +307,10 @@ class Group: ...@@ -300,10 +307,10 @@ class Group:
continue continue
# Construct a truck obj. # Construct a truck obj.
truck_info = CurrentTruck(truck_id, self.group_id, truck_trip, truck_task, truck_info = CurrentTruck(truck_id, self.group.group_id, truck_trip, truck_task,
self.truck.get_truck_current_state()[truck_id]) self.group.truck.get_truck_current_state()[truck_id])
self.truck_info_list[truck_id] = truck_info self.group.truck_info_list[truck_id] = truck_info
# Construct a test case for redispatch # Construct a test case for redispatch
# truck_task = 0 # truck_task = 0
...@@ -318,16 +325,16 @@ class Group: ...@@ -318,16 +325,16 @@ class Group:
try: try:
# 全智能模式 # 全智能模式
if self.group_mode == 1: if self.group.group_mode == 1:
self.logger.info("全智能模式调度") self.logger.info("全智能模式调度")
self.full_dynamic_mode(truck_id, solver, truck_dispatch, truck_info, truck_task, truck_trip) self.full_dynamic_mode(truck_id, solver, truck_dispatch, truck_info, truck_task, truck_trip)
# 空车智能模式 # 空车智能模式
elif self.group_mode == 2: elif self.group.group_mode == 2:
self.logger.info("空车智能模式调度") self.logger.info("空车智能模式调度")
self.semi_dynamic_mode(truck_id, solver, truck_dispatch, truck_info, truck_task, truck_trip) self.semi_dynamic_mode(truck_id, solver, truck_dispatch, truck_info, truck_task, truck_trip)
# 定铲派车 # 定铲派车
elif self.group_mode == 3: elif self.group.group_mode == 3:
self.logger.info("固定模式调度") self.logger.info("固定模式调度")
try: try:
truck_dispatch[truck_id] = DispatchInfo.get_truck_match(truck_id) truck_dispatch[truck_id] = DispatchInfo.get_truck_match(truck_id)
...@@ -336,7 +343,7 @@ class Group: ...@@ -336,7 +343,7 @@ class Group:
self.logger.error(es) self.logger.error(es)
# 分流配比模式 # 分流配比模式
elif self.group_mode == 4: elif self.group.group_mode == 4:
self.logger.info("分流配比模式调度") self.logger.info("分流配比模式调度")
self.ratio_mode(truck_id, truck_dispatch, truck_task) self.ratio_mode(truck_id, truck_dispatch, truck_task)
...@@ -361,12 +368,12 @@ class Group: ...@@ -361,12 +368,12 @@ class Group:
try: try:
if i in self.truck.truck_dump_bind: if i in self.group.truck.truck_dump_bind:
dump_uuid_to_unload_area_uuid_dict = get_value("dump_uuid_to_unload_area_uuid_dict") dump_uuid_to_unload_area_uuid_dict = get_value("dump_uuid_to_unload_area_uuid_dict")
next_unload_area_id = dump_uuid_to_unload_area_uuid_dict[self.truck.truck_dump_bind[i]] next_unload_area_id = dump_uuid_to_unload_area_uuid_dict[self.group.truck.truck_dump_bind[i]]
else: else:
next_unload_area_id = DistributionRatio(next_exactor_id, self.truck).ratio_main() next_unload_area_id = DistributionRatio(next_exactor_id, self.group.truck).ratio_main()
except Exception as es: except Exception as es:
...@@ -393,13 +400,13 @@ class Group: ...@@ -393,13 +400,13 @@ class Group:
if truck_task in [-2, 3, 4, 5]: if truck_task in [-2, 3, 4, 5]:
try: try:
if i in self.truck.truck_excavator_bind: if i in self.group.truck.truck_excavator_bind:
next_excavator_id = self.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)
# min_index = next_excavator_list.index(min(next_excavator_list)) # min_index = next_excavator_list.index(min(next_excavator_list))
min_index = np.argmin(next_excavator_value) min_index = np.argmin(next_excavator_value)
next_excavator_id = self.excavator_uuid_index_dict.inverse[min_index] next_excavator_id = self.group.excavator_uuid_index_dict.inverse[min_index]
if truck_task == -2: if truck_task == -2:
next_unload_area_id = "Park" next_unload_area_id = "Park"
else: else:
...@@ -423,19 +430,19 @@ class Group: ...@@ -423,19 +430,19 @@ class Group:
# 车辆停止或者车辆位于卸载区内, 调度车辆前往装载区 # 车辆停止或者车辆位于卸载区内, 调度车辆前往装载区
if truck_task in [-2, 4, 5]: if truck_task in [-2, 4, 5]:
try: try:
if i in self.truck.truck_excavator_bind: if i in self.group.truck.truck_excavator_bind:
try: try:
if i not in self.truck.truck_excavator_bind: if i not in self.group.truck.truck_excavator_bind:
raise CoreException(102, f'truck.excavator bind 中不存在 {i}') raise CoreException(102, f'truck.excavator bind 中不存在 {i}')
except CoreException as es: except CoreException as es:
es.with_traceback_info() es.with_traceback_info()
self.logger.error(es) self.logger.error(es)
return return
next_excavator_id = self.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)
min_index = np.argmin(next_excavator_value) min_index = np.argmin(next_excavator_value)
next_excavator_id = self.excavator_uuid_index_dict.inverse[min_index] next_excavator_id = self.group.excavator_uuid_index_dict.inverse[min_index]
self.logger.info(f'目标挖机 {min_index} {next_excavator_id}') self.logger.info(f'目标挖机 {min_index} {next_excavator_id}')
...@@ -454,28 +461,28 @@ class Group: ...@@ -454,28 +461,28 @@ class Group:
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)
# self.logger.info(f'车辆 {i}') # self.logger.info(f'车辆 {truck_id}')
# self.logger.info(f'group distance {self.to_unload_area_distance}') # self.logger.info(f'group distance {self.to_unload_area_distance}')
# self.logger.info(f'walk available {self.group_walk_available}') # self.logger.info(f'walk available {self.group_walk_available}')
# #
# self.logger.info(self.unload_area_uuid_index_dict) # self.logger.info(self.unload_area_uuid_index_dict)
# self.logger.info(self.excavator_uuid_index_dict) # self.logger.info(self.excavator_uuid_index_dict)
if i in self.truck.truck_dump_bind: if i in self.group.truck.truck_dump_bind:
dump_uuid_to_unload_area_uuid_dict = get_value("dump_uuid_to_unload_area_uuid_dict") dump_uuid_to_unload_area_uuid_dict = get_value("dump_uuid_to_unload_area_uuid_dict")
next_unload_area_id = dump_uuid_to_unload_area_uuid_dict[self.truck.truck_dump_bind[i]] next_unload_area_id = dump_uuid_to_unload_area_uuid_dict[self.group.truck.truck_dump_bind[i]]
else: else:
tmp = self.group_walk_available[ tmp = self.group.group_walk_available[
self.excavator_uuid_index_dict[next_excavator_id], :].flatten() self.group.excavator_uuid_index_dict[next_excavator_id], :].flatten()
# self.logger.info(f'group_walk_available_pick {tmp}') # self.logger.info(f'group_walk_available_pick {tmp}')
# self.logger.info(f'next_excavator_id {next_excavator_id}') # self.logger.info(f'next_excavator_id {next_excavator_id}')
# self.logger.info(next_unload_area_value) # self.logger.info(next_unload_area_value)
next_unload_area_value *= self.group_walk_available[ next_unload_area_value *= self.group.group_walk_available[
self.excavator_uuid_index_dict[next_excavator_id], :].flatten() self.group.excavator_uuid_index_dict[next_excavator_id], :].flatten()
# self.logger.info(next_unload_area_value) # self.logger.info(next_unload_area_value)
min_index = np.argmin(next_unload_area_value) min_index = np.argmin(next_unload_area_value)
next_unload_area_id = self.unload_area_uuid_index_dict.inverse[min_index] next_unload_area_id = self.group.unload_area_uuid_index_dict.inverse[min_index]
self.logger.info(f'目标卸点 {min_index} {next_unload_area_id}') self.logger.info(f'目标卸点 {min_index} {next_unload_area_id}')
# next_excavator_id = self.excavator_uuid_index_dict.inverse[truck_trip[-1]] # next_excavator_id = self.excavator_uuid_index_dict.inverse[truck_trip[-1]]
...@@ -489,14 +496,14 @@ class Group: ...@@ -489,14 +496,14 @@ class Group:
truck_dispatch[i] = [None, None] truck_dispatch[i] = [None, None]
elif truck_task == 0: elif truck_task == 0:
try: try:
truck_locate = self.truck.get_truck_locate_dict()[i] truck_locate = self.group.truck.get_truck_locate_dict()[i]
except Exception as es: except Exception as es:
self.logger.error("车辆位置信息丢失") self.logger.error("车辆位置信息丢失")
self.logger.error(es) self.logger.error(es)
self.logger.info(self.truck.truck_is_temp) self.logger.info(self.group.truck.truck_is_temp)
try: try:
truck_is_temp = self.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("车辆临时字段异常")
...@@ -505,82 +512,35 @@ class Group: ...@@ -505,82 +512,35 @@ class Group:
self.logger.info("潜在二次调度车辆状态") self.logger.info("潜在二次调度车辆状态")
self.logger.info(f'车辆 {i}') self.logger.info(f'车辆 {i}')
self.logger.info(f'车辆位置 {truck_locate}') self.logger.info(f'车辆位置 {truck_locate}')
self.logger.info(f'车辆状态 {self.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)}')
self.logger.info(self.topo.cross_bf_lanes) self.logger.info(self.group.topo.cross_bf_lanes)
self.logger.info(self.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[i] == 2) \ # if (truck_locate in self.topo.cross_bf_lanes) and (self.truck.truck_current_state[truck_id] == 2) \
# and (not truck_is_temp): # and (not truck_is_temp):
if (truck_locate in self.topo.cross_bf_lanes) and (self.truck.truck_current_state[i] == 2): if (truck_locate in self.group.topo.cross_bf_lanes) and (self.group.truck.truck_current_state[i] == 2):
self.logger.info("触发二次调度") self.logger.info("触发二次调度")
# 当前绑定卸载区
# if truck_trip[0] == -1:
next_unload_area_id = session_mysql.query(EquipmentPair).filter_by(truck_id=i,
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=i, isdeleted=0).first()
current_excavator_id = item.exactor_id
current_load_area_id = item.load_area_id
self.logger.info(f'truck_id {i}')
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.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)
# 排除下一个路段阻塞的装载区 self.redispatch_to_excavator(i, truck_dispatch, truck_locate)
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, i, load_area_dict)
next_excavator_id = best_excavator_id
truck_dispatch[i] = [next_excavator_id, next_unload_area_id]
self.logger.info(f'二次调度结果 {i}')
self.logger.info(truck_dispatch[i])
elif truck_task == 3: elif truck_task == 3:
try: try:
truck_locate = self.truck.get_truck_locate_dict()[i] truck_locate = self.group.truck.get_truck_locate_dict()[i]
except Exception as es: except Exception as es:
self.logger.error("车辆位置信息丢失") self.logger.error("车辆位置信息丢失")
self.logger.error(es) self.logger.error(es)
try: try:
truck_is_temp = self.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)
self.logger.info(f'车辆位置 {truck_locate}') self.logger.info(f'车辆位置 {truck_locate}')
self.logger.info(f'车辆状态 {self.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)}')
# 车辆当前位于交叉路口前,且排队等待 # 车辆当前位于交叉路口前,且排队等待
if (truck_locate in self.topo.cross_bf_lanes) and (self.truck.truck_current_state[i] == 2) \ if (truck_locate in self.group.topo.cross_bf_lanes) and (self.group.truck.truck_current_state[i] == 2) \
and (not truck_is_temp): and (not truck_is_temp):
# 当前绑定装载区 # 当前绑定装载区
...@@ -597,7 +557,7 @@ class Group: ...@@ -597,7 +557,7 @@ class Group:
else: else:
current_dump_id = get_value("dump_index_to_uuid_dict")[truck_trip[-1]] 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] current_unload_area_id = DispatchInfo.dump_unload_area_dict[current_dump_id]
unload_area_dict, unload_area_lane_dict = self.topo.get_unload_target_node_real(truck_locate, unload_area_dict, unload_area_lane_dict = self.group.topo.get_unload_target_node_real(truck_locate,
current_unload_area_id, current_unload_area_id,
True) True)
...@@ -626,12 +586,12 @@ class Group: ...@@ -626,12 +586,12 @@ class Group:
traveling_time = value[0] / heavy_speed traveling_time = value[0] / heavy_speed
now = float( now = float(
(datetime.now() - self.pre_sch.start_time) / timedelta(hours=0, minutes=1, (datetime.now() - self.group.pre_sch.start_time) / timedelta(hours=0, minutes=1,
seconds=0)) seconds=0))
reach_time = now + traveling_time reach_time = now + traveling_time
trip_time = max(reach_time, trip_time = max(reach_time,
self.pre_sch.get_dump_avl_time()[dump_id]) - now self.group.pre_sch.get_dump_avl_time()[dump_id]) - now
if min_trip_time > trip_time: if min_trip_time > trip_time:
best_dump_id = dump_id best_dump_id = dump_id
...@@ -640,12 +600,59 @@ class Group: ...@@ -640,12 +600,59 @@ class Group:
truck_dispatch[i] = [next_excavator_id, next_unload_area_id] truck_dispatch[i] = [next_excavator_id, next_unload_area_id]
# res = redispatch_request(i, 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(res)
self.logger.info(f'二次调度结果 {i}') self.logger.info(f'二次调度结果 {i}')
self.logger.info(truck_dispatch[i]) self.logger.info(truck_dispatch[i])
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): def get_best_excavator(self, current_excavator_id, truck_id, load_area_dict):
""" """
get best excavator get best excavator
...@@ -663,21 +670,133 @@ class Group: ...@@ -663,21 +670,133 @@ class Group:
excavator_id = DispatchInfo.load_excavator_dict[load_area] excavator_id = DispatchInfo.load_excavator_dict[load_area]
else: else:
continue continue
if value[-1] == 1 and excavator_id in self.excavator: if value[-1] == 1 and excavator_id in self.group.excavator:
traveling_time = 60 * (value[0] / 1000) / empty_speed traveling_time = 60 * (value[0] / 1000) / empty_speed
self.logger.info(f'load_area {load_area}') self.logger.info(f'load_area {load_area}')
self.logger.info(f'traveling_time {traveling_time}') 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:
"""
redispatch controller
"""
def __init__(self, group: Group):
self.logger = get_logger("zxt.ReDispatcher")
self.group = group
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 excavator
: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.excavator:
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( now = float(
(datetime.now() - self.pre_sch.start_time) / timedelta(hours=0, minutes=1, seconds=0)) (datetime.now() - self.group.pre_sch.start_time) / timedelta(hours=0, minutes=1, seconds=0))
reach_time = now + traveling_time reach_time = now + traveling_time
self.logger.info(f'reach_time {reach_time}') self.logger.info(f'reach_time {reach_time}')
trip_time = max(reach_time, self.pre_sch.get_excavator_avl_time(truck_id=truck_id)[excavator_id]) - now 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}') self.logger.info(f'trip_time {trip_time}')
...@@ -693,10 +812,10 @@ class Group: ...@@ -693,10 +812,10 @@ class Group:
def get_congestion_lanes(self): def get_congestion_lanes(self):
# 存在车辆拥堵的路段 # 存在车辆拥堵的路段
truck_locate_dict = self.truck.get_truck_locate_dict() truck_locate_dict = self.group.truck.get_truck_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.truck.truck_current_state[key] == 2: if self.group.truck.truck_current_state[key] == 2:
congestion_lane_list.append(value) congestion_lane_list.append(value)
print("congestion_lane_list") print("congestion_lane_list")
......
...@@ -180,7 +180,7 @@ class PreSchedule: ...@@ -180,7 +180,7 @@ class PreSchedule:
# # 若挖机可用时间严重偏离,进行修正 # # 若挖机可用时间严重偏离,进行修正
# if abs(self.excavator_avl_time[excavator_index] - now) > 60: # if abs(self.excavator_avl_time[excavator_index] - now) > 60:
# self.truck_avl_time[int(tmp[i][1])] = now # self.truck_avl_time[int(tmp[truck_id][1])] = now
# if abs(self.excavator_avl_time[excavator_index] - now) > 60: # if abs(self.excavator_avl_time[excavator_index] - now) > 60:
# self.excavator_avl_time[excavator_index] = now # self.excavator_avl_time[excavator_index] = now
...@@ -252,8 +252,8 @@ class PreSchedule: ...@@ -252,8 +252,8 @@ class PreSchedule:
# # 若卸载设备可用时间严重偏离,进行修正 # # 若卸载设备可用时间严重偏离,进行修正
# if abs(self.dump_avl_time[dump_index] - now) > 60: # if abs(self.dump_avl_time[dump_index] - now) > 60:
# self.dump_avl_time[dump_index] = now # self.dump_avl_time[dump_index] = now
# if abs(self.truck_avl_time[int(tmp[i][1])] - now) > 60: # if abs(self.truck_avl_time[int(tmp[truck_id][1])] - now) > 60:
# self.truck_avl_time[int(tmp[i][1])] = now # self.truck_avl_time[int(tmp[truck_id][1])] = now
count = 0 count = 0
self.logger.info("update_dump_avl_time-dump_avl_ls") self.logger.info("update_dump_avl_time-dump_avl_ls")
......
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2022/10/18 12:32
# @Author : Opfer
# @Site :
# @File : submit.py
# @Software: PyCharm
import json
import uuid
from typing import List
from core.group import CurrentTruck, Group
from core.util import POST
from data.dispatchInfo import DispatchInfo
from data.para_config import get_value
from equipment import DumpInfo, ExcavatorInfo, TruckInfo
from graph.topo_graph import Topo
from settings import get_logger, redis5
from tables import session_mysql, DispatchSetting
class DispatchSubmission:
""" class for the submission calculated dispatch.
Description:
将调度结果按照指定格式传递到云端机群
Attribute:
"""
def __init__(self, dump: DumpInfo, excavator: ExcavatorInfo, truck: TruckInfo, topo: Topo):
self.logger = get_logger("zxt.submission")
self.dump = dump
self.excavator = excavator
self.truck = truck
self.topo = topo
def truck_dispatch_to_redis(self, truck_id: str, truck_info: CurrentTruck, dispatch_seq: List[int], group_mode: int):
"""
将truck_id对应矿卡派车计划写入redis
:param group_mode: (int)
:param truck_id: (uuid) 矿卡uuid
:param truck_info: (object)
:param dispatch_seq: (List[int]) 矿卡派车计划
:return: None
"""
self.logger.info(f'调度车辆编号 {get_value("truck_uuid_to_name_dict")[truck_id]} {truck_id}')
self.logger.info(f'车辆任务 {truck_info.get_task()}')
self.logger.info(f'配对挖机 {dispatch_seq[0]}')
self.logger.info(f'配对卸点 {dispatch_seq[1]}')
# try:
if truck_id not in DispatchInfo.truck_group_dict:
group_id = None
self.logger.error(f'调度结果写入异常-读取矿卡 {truck_id} 所在分组信息异常')
else:
group_id = DispatchInfo.truck_group_dict[truck_id]
record = {"truckId": truck_id}
# if group_id is None or DispatchInfo.get_group_mode(group_id) is None:
# group_mode = 3
# self.logger.error("调度模式读取异常-设置为固定派车模式")
# else:
# group_mode = DispatchInfo.get_group_mode(group_id)
self.logger.info(f'调度模式 {group_mode}')
if group_mode == 3:
self.logger.info("固定派车模式")
self.fixed_dispatch_mode(group_id, truck_id)
else:
self.logger.info("动态调度模式")
self.dynamic_dispatch_mode(dispatch_seq, group_id, record, truck_info.get_sate(),
truck_info.get_task(), truck_id)
# except Exception as es:
# self.logger.error("调度结果写入异常")
# self.logger.error(f"调度结果:{dispatch_seq}")
# self.logger.error(es)
def dynamic_dispatch_mode(self, dispatch_seq, group_id, record, state, task, truck_id):
"""
write dispatch plan in dynamic dispatch mode.
:param dispatch_seq:
:param group_id:
:param record:
:param state:
:param task:
:param truck_id:
:return:
"""
if (task in [1, 2]) or (task == 3 and state == 2): # 车辆位于装载区,或车辆重载等待
if task in [1, 2]:
self.logger.info(f'车辆 {truck_id} 装载区调度')
else:
self.logger.info(f'车辆 {truck_id} 重载二次调度')
# 查询车辆相关派车计划 dispatch_seq[next_excavator_id, next_unload_area_id]
if dispatch_seq[1] is None or (dispatch_seq[1] not in DispatchInfo.unload_area_dump_dict):
# 无法查询到目标卸载点
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id, isdeleted=0, ).first())
else:
dump_id = DispatchInfo.unload_area_dump_dict[dispatch_seq[1]]
try:
item = (session_mysql.query(DispatchSetting).filter_by(dump_id=dump_id, group_id=group_id,
isdeleted=0, ).first())
if item is None:
raise Exception(f'车辆 {truck_id} 无法找到派车计划 {dump_id} {group_id}')
if dispatch_seq[0] is None:
raise Exception("调度计划挖机与实时监控不匹配")
except Exception as es:
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id, isdeleted=0, ).first())
self.logger.error(es)
# 其余调度信息写入
# try:
record = redis_format(truck_id, group_id, str(uuid.uuid1()), item)
# 车辆重载等待,且前方道路阻塞
if task == 3 and state == 2 and truck_id in self.truck.get_truck_locate_dict() and \
self.truck.get_truck_locate_dict()[truck_id] in self.topo.cross_bf_lanes:
# try:
# if truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]:
self.logger.info("二次调度前往卸载区")
record["isTemp"] = True # 避免反复修改
POST(truck_id)
# else:
# self.logger.info("车辆已完成二次调度-无需更改派车计划")
# except Exception as es:
# self.logger.error(es)
# self.logger.error("二次调度失败")
# record["isTemp"] = False
# redis5.set(truck_id, str(json.dumps(record)))
else:
self.logger.info("调度前往卸载区")
record["isTemp"] = False
self.logger.info(f'redis 注入 {record}')
redis5.set(truck_id, str(json.dumps(record)))
# self.logger.error("调度结果写入异常-矿卡空载")
elif (task in [-2, 4, 5]) or (task == 0 and state == 2): # 车辆位于备停区或位于卸载区,或车辆空载等待
if task == -2:
self.logger.info(f'车辆 {truck_id} 备停区调度')
elif task in [4, 5]:
self.logger.info(f'车辆 {truck_id} 卸载区调度')
else:
self.logger.info(f'车辆 {truck_id} 空载二次调度')
# 查询车辆相关派车计划 dispatch_seq[next_excavator_id, next_unload_area_id]
if dispatch_seq[0] is None:
# 无法查询到目标挖机
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id, isdeleted=0, ).first())
else:
excavator_id = dispatch_seq[0]
try:
item = (session_mysql.query(DispatchSetting).filter_by(exactor_id=excavator_id, group_id=group_id,
isdeleted=0, ).first())
if item is None:
raise Exception(f' 车辆 {truck_id} 无法找到派车计划 {excavator_id} {group_id}')
if dispatch_seq[0] is None:
raise Exception("调度计划挖机与实时监控不匹配")
except Exception as es:
item = (session_mysql.query(DispatchSetting).filter_by(group_id=group_id, isdeleted=0, ).first())
self.logger.error(es)
# 调度信息写入
# try:
record = redis_format(truck_id, group_id, str(uuid.uuid1()), item)
# 车辆重载等待,且前方道路阻塞
if task == 0 and state == 2 and truck_id in self.truck.get_truck_locate_dict() and \
self.truck.get_truck_locate_dict()[truck_id] in self.topo.cross_bf_lanes:
# 车辆停车等待
# try:
# if truck_id in self.truck.truck_is_temp and not self.truck.truck_is_temp[truck_id]:
self.logger.info("二次调度前往装载区")
record["isTemp"] = True # 避免反复修改
POST(truck_id)
# else:
# self.logger.info("车辆已完成二次调度-无需更改派车计划")
# except Exception as es:
# self.logger.error(es)
# self.logger.error("二次调度失败")
# record["isTemp"] = False
# redis5.set(truck_id, str(json.dumps(record)))
else:
self.logger.info("调度前往装载区")
record["isTemp"] = False
self.logger.info(f'redis 注入 {record}')
redis5.set(truck_id, str(json.dumps(record)))
# self.logger.error("调度结果写入异常-矿卡重载")
else:
pass
def fixed_dispatch_mode(self, group_id, truck_id):
"""
write dispatch plan in fixed dispatch method.
:param group_id:
:param record:
:param truck_id:
:return:
"""
item = session_mysql.query(DispatchSetting).filter_by(truck_id=truck_id, isdeleted=0, ).first()
if item is None:
self.logger.error(f'车辆 {truck_id} 无派车计划-无法执行固定派车')
return
record = redis_format(truck_id, group_id, item.id, item)
self.logger.info(f'redis 注入 {record}')
redis5.set(truck_id, str(json.dumps(record)))
def group_dispatch_to_redis(self, group: Group, dispatch_plan_dict):
"""
Update the dispatch plan in the group to redis
:param group: (Group)
:param dispatch_plan_dict: (Dict)
:return: None
"""
self.logger.info(f'调度分组: {group.group_id} {DispatchInfo.group_name[group.group_id]}')
self.logger.info(f'组内车辆 {group.truck_set}')
self.logger.info(f'组内挖机 {group.excavator}')
self.logger.info(f'组内卸点 {group.dump}')
self.logger.info(f'调度模式 {group.group_mode}')
self.logger.info("dispatch_plan_dict")
self.logger.info(dispatch_plan_dict)
print(group.truck_info_list)
for truck_id, dispatch_plan in dispatch_plan_dict.items():
try:
self.logger.info(f'======================================= 调度车辆 =======================================')
self.truck_dispatch_to_redis(truck_id, group.truck_info_list[truck_id], dispatch_plan, group.group_mode)
self.logger.info("======================================== 完成写入 =======================================")
except Exception as es:
self.logger.error("group_dispatch_to_redis_error")
self.logger.error(es)
def redis_format(truck_id, group_id, dispatch_id, item):
record = {"truckId": truck_id, "dispatchId": dispatch_id, "exactorId": item.exactor_id, "dumpId": item.dump_id,
"loadAreaId": item.load_area_id, "unloadAreaId": item.unload_area_id, "groupId": item.group_id,
"isdeleted": False, "isTemp": False, "haulFlag": -1, "groupName": DispatchInfo.group_name[group_id]}
return record
\ No newline at end of file
...@@ -349,10 +349,10 @@ class DispatchInfo: ...@@ -349,10 +349,10 @@ class DispatchInfo:
# # unload->load distance # # unload->load distance
# unload_load_distance = np.zeros((len(unload_areas), len(load_areas))) # unload_load_distance = np.zeros((len(unload_areas), len(load_areas)))
# for i in range(len(unload_areas)): # for truck_id in range(len(unload_areas)):
# for j in range(len(load_areas)): # for j in range(len(load_areas)):
# distance = int(session_postgre.query(WalkTime).filter_by(unload_area_id=unload_areas[i], load_area_id=load_areas[j]).first().to_load_distance) # 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[i][j] = distance # unload_load_distance[truck_id][j] = distance
# cls.load_distance[item] = unload_load_distance # cls.load_distance[item] = unload_load_distance
...@@ -445,17 +445,17 @@ class DispatchInfo: ...@@ -445,17 +445,17 @@ class DispatchInfo:
# cls.truck_uuid_index_dict = {} # cls.truck_uuid_index_dict = {}
# cls.dump_uuid_index_dict = {} # cls.dump_uuid_index_dict = {}
# #
# for i in range(len(cls.group_excavator_dict[group_id])): # 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])[i]] = i # cls.excavator_uuid_index_dict[group_id][list(cls.group_excavator_dict[group_id])[truck_id]] = truck_id
# #
# for i in range(len(cls.group_unload_area_dict[group_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])[i]] = i # cls.unload_area_uuid_index_dict[group_id][list(cls.group_unload_area_dict[group_id])[truck_id]] = truck_id
# #
# for i in range(len(cls.group_dump_dict[group_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])[i]] = i # cls.dump_uuid_index_dict[group_id][list(cls.group_dump_dict[group_id])[truck_id]] = truck_id
# #
# for i in range(len(cls.group_truck_dict[group_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])[i]] = i # 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.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.unload_area_uuid_index_dict = bidict(DispatchInfo.unload_area_uuid_to_index_dict[self.group_id])
...@@ -681,7 +681,7 @@ class DispatchInfo: ...@@ -681,7 +681,7 @@ class DispatchInfo:
# @classmethod # @classmethod
# def get_group_road_info(cls,group_id, truck_info): # def get_group_road_info(cls,group_id, truck_info):
# if truck_info == 1: # if truck_info == 1:
# for i in group_excavator(): # for truck_id in group_excavator():
# pass # pass
# for j in group_unload_area(): # for j in group_unload_area():
# pass # pass
......
...@@ -148,7 +148,10 @@ class TruckInfo(WalkManage): ...@@ -148,7 +148,10 @@ class TruckInfo(WalkManage):
# try: # try:
item = item.decode(encoding="utf-8") item = item.decode(encoding="utf-8")
key_value_dict = redis2.hgetall(item) # reids str可以自动转为bytes key_value_dict = redis2.hgetall(item) # reids str可以自动转为bytes
if str_to_byte("type") in key_value_dict:
device_type = int(key_value_dict[str_to_byte("type")]) device_type = int(key_value_dict[str_to_byte("type")])
else:
continue
if device_type == 1: if device_type == 1:
if truck_name_to_uuid_dict[item] in self.dynamic_truck_set: if truck_name_to_uuid_dict[item] in self.dynamic_truck_set:
# currentTask = int(key_value_dict[str_to_byte("currentTask")]) # currentTask = int(key_value_dict[str_to_byte("currentTask")])
......
...@@ -163,7 +163,7 @@ class Topo(): ...@@ -163,7 +163,7 @@ class Topo():
# 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(i_startpoint), str(i_endpoint),
float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i]) float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i])
# son_lane_num = sum(1 for i in 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 = i_endpoint).all())
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=i_endpoint).all()) son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=i_endpoint).all())
# 可以添加的节点:分叉口或终点 # 可以添加的节点:分叉口或终点
...@@ -227,7 +227,7 @@ class Topo(): ...@@ -227,7 +227,7 @@ class Topo():
load_saved_lane.append([str(load_i_startpoint), str(load_i_endpoint), load_saved_lane.append([str(load_i_startpoint), str(load_i_endpoint),
float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i]) float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i])
# son_lane_num = sum(1 for i in 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 = load_i_endpoint).all())
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=load_i_endpoint).all()) son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=load_i_endpoint).all())
nodes = list(self.load_G.nodes) nodes = list(self.load_G.nodes)
...@@ -239,8 +239,8 @@ class Topo(): ...@@ -239,8 +239,8 @@ class Topo():
lanes = {} lanes = {}
for lane_info in load_saved_lane: for lane_info in load_saved_lane:
lanes[lane_info[-1]] = list([lane_info[2], lane_info[2]]) lanes[lane_info[-1]] = list([lane_info[2], lane_info[2]])
# lanes.append(i[0]) # lanes.append(truck_id[0])
# lanes.append(i[1]) # lanes.append(truck_id[1])
# self.load_G.add_edge(load_saved_lane[0][0], load_saved_lane[-1][1], real_distance = sum(n[2] for n in load_saved_lane), lane = lanes) # self.load_G.add_edge(load_saved_lane[0][0], load_saved_lane[-1][1], real_distance = sum(n[2] for n in load_saved_lane), lane = lanes)
self.load_G.add_edge(load_saved_lane[0][0], load_saved_lane[-1][1], self.load_G.add_edge(load_saved_lane[0][0], load_saved_lane[-1][1],
real_distance=sum(value[0] for value in lanes.values()), real_distance=sum(value[0] for value in lanes.values()),
...@@ -275,7 +275,7 @@ class Topo(): ...@@ -275,7 +275,7 @@ class Topo():
load_saved_lane.append([str(load_i_startpoint), str(load_i_endpoint), load_saved_lane.append([str(load_i_startpoint), str(load_i_endpoint),
float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i]) float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i])
# son_lane_num = sum(1 for i in 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 = load_i_endpoint).all())
son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=load_i_endpoint).all()) son_lane_num = len(session_postgre.query(Lane).filter_by(StartNodeId=load_i_endpoint).all())
nodes = list(self.load_G.nodes) nodes = list(self.load_G.nodes)
...@@ -287,8 +287,8 @@ class Topo(): ...@@ -287,8 +287,8 @@ class Topo():
lanes = {} lanes = {}
for lane_info in load_saved_lane: for lane_info in load_saved_lane:
lanes[lane_info[-1]] = list([lane_info[2], lane_info[2]]) lanes[lane_info[-1]] = list([lane_info[2], lane_info[2]])
# lanes.append(i[0]) # lanes.append(truck_id[0])
# lanes.append(i[1]) # lanes.append(truck_id[1])
# self.load_G.add_edge(load_saved_lane[0][0], load_saved_lane[-1][1], real_distance = sum(n[2] for n in load_saved_lane), lane = lanes) # self.load_G.add_edge(load_saved_lane[0][0], load_saved_lane[-1][1], real_distance = sum(n[2] for n in load_saved_lane), lane = lanes)
self.load_G.add_edge(load_saved_lane[0][0], load_saved_lane[-1][1], self.load_G.add_edge(load_saved_lane[0][0], load_saved_lane[-1][1],
real_distance=sum(value[0] for value in lanes.values()), real_distance=sum(value[0] for value in lanes.values()),
......
...@@ -17,7 +17,7 @@ from core.group import Group ...@@ -17,7 +17,7 @@ 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 data.dispatchInfo import DispatchInfo
from core.dispatcher import DispatchSubmission from core.submit import DispatchSubmission
from graph.graph_load import graph_construct from graph.graph_load import graph_construct
config = { config = {
......
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