Commit 4079af86 authored by 张晓彤's avatar 张晓彤

1.dispatcher.py 拆分-> schedule.py 2. 数据库部分字段修正 3. 解决循环调用问题 4. DispatchInfo 全局数据更新…

1.dispatcher.py 拆分-> schedule.py 2. 数据库部分字段修正 3. 解决循环调用问题 4. DispatchInfo 全局数据更新 in realtime_dispatch.py
parent dc367fbe
......@@ -8,13 +8,8 @@
from para_config import *
from equipment import ExcavatorInfo, DumpInfo, TruckInfo
from core.group import Group
from core.dispatcher import PreSchedule
dump = DumpInfo()
excavator = ExcavatorInfo()
truck = TruckInfo(dump, excavator)
pre_sch = PreSchedule(truck, excavator, dump)
# from core.group import Group
from core.schedule import PreSchedule
class AlgorithmBase:
......@@ -37,7 +32,7 @@ class Congestion(AlgorithmBase):
class for congestion alg.
"""
def __init__(self, group: Group):
def __init__(self, group):
super().__init__()
self.group = group
self.logger = get_logger("zxt.algorithm.congestion")
......@@ -135,7 +130,7 @@ class ExpectedTime(AlgorithmBase):
class for expected traveling time alg.
"""
def __init__(self, group: Group):
def __init__(self, group):
super().__init__()
self.group = group
......
This diff is collapsed.
......@@ -6,25 +6,38 @@
# @File : group.py
# @Software: PyCharm
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2022/5/30 15:35
# @Author : Opfer
# @Site :
# @File : group.py
# @Software: PyCharm
from data.dispatchInfo import DispatchInfo
from bidict import bidict
from alg.algorithm import AlgorithmBase, Congestion
from alg.algorithm import AlgorithmBase
class Group:
"""
class for group instance.
"""
def __init__(self, group_id, truck, dump, excavator):
def __init__(self, group_id, truck):
""" Generate a group obj.
:param group_id: (uuid) group_id
"""
self.to_dump_congestion = None
self.group_id = group_id
self.group_mode = 1
self.truck = truck
# group devices
self.excavator_dict = {} # excavator_id -> load_area_id
self.dump_dict = {} # dump_id -> unload_area_id
self.excavator_dict = {} # excavator_id -> unload_area_id
self.dump_dict = {} # dump_id -> load_area_id
self.truck_set = set() # truck_id
# road network info.
......@@ -32,61 +45,157 @@ class Group:
self.to_dump_distance = None
self.park_to_excavator_distance = None
self.to_excavator_congestion = None
self.to_dump_congestion = None
self.park_to_excavator_congestion = None
# self.to_excavator_congestion = None
# self.to_dump_congestion = None
# self.park_to_excavator_congestion = None
# device map
self.truck_uuid_index_dict = bidict()
self.excavator_uuid_index_dict = bidict()
self.dump_uuid_index_dict = bidict()
# device obj.
self.truck = truck
self.dump =dump
self.excavator = excavator
def update_xx_(self):
def update_group_mode(self):
"""
update above parameters.
update group mode.
:param group_mode:
:return:
"""
pass
# DispatchInfo.update_group_mode()
self.group_mode = DispatchInfo.get_group_mode(self.group_id)
def update_device_map(self):
def update_group_device(self):
"""
update above parameters.
update group devices.
:return:
"""
self.truck_uuid_index_dict = DispatchInfo.dump_group_dict
pass
# update group devices
# DispatchInfo.update_device_group_structure()
self.excavator_dict = DispatchInfo.get_excavator_dict(self.group_id)
self.dump_dict = DispatchInfo.get_dump_dict(self.group_id)
self.truck_set = DispatchInfo.get_truck_set(self.group_id)
def update_road_network_info(self, para):
def update_group_road_network(self):
"""
update group road network.
:return:
"""
# update group road network
# DispatchInfo.update_route_distance()
self.to_excavator_distance = DispatchInfo.get_to_excavator_distance(self.group_id)
self.to_dump_distance = DispatchInfo.get_to_dump_distance(self.group_id)
self.park_to_excavator_distance = DispatchInfo.get_park_to_excavator_distance(self.group_id)
def update_group_device_map(self):
"""
update group device map.
:return:
"""
pass
return
# update device map
excavator_index = 0
for i in self.excavator_dict.keys():
self.excavator_uuid_index_dict[i] = excavator_index + 1
dump_index = 0
for i in self.dump_dict.keys():
self.dump_uuid_index_dict[i] = dump_index + 1
truck_index = 0
for i in self.truck_set:
self.truck_uuid_index_dict[i] = truck_index + 1
def group_dispatch(self, solver):
self.truck_uuid_index_dict = bidict(self.truck_uuid_index_dict)
self.excavator_uuid_index_dict = bidict(self.excavator_uuid_index_dict)
self.dump_uuid_index_dict = bidict(self.dump_uuid_index_dict)
# group_excavator_dict = {group_1: {excavator_1: load_area_1}, group_2: {excavator_2: load_area_2}}
def group_dispatch(self, solver: object):
"""
Receive a alg obj. and output dispatch plan for trucks in this group.
:param solver:
:return:
dispatch plan: Dict({truck_id: match_id})
"""
assert isinstance(solver, AlgorithmBase)
s = solver(self) # algorithm init
for truck_id in self.truck_set:
value = s.solve(truck_id) # algorithm solve
truck_dispatch = {}
return value
assert issubclass(solver, AlgorithmBase)
def target_2_match_id(self, target):
pass
group = Group("group123")
s = solver(self) # algorithm init
group.group_dispatch(Congestion)
# update truck task type
for i in self.truck_set:
truck_trip = self.truck.get_truck_current_trip(i)
truck_task = self.truck.get_truck_current_task(i)
if truck_task in [-2, 3, 4]:
next_excavator_list = s.solve(i)
min_index = next_excavator_list.index(min(next_excavator_list)) + 1
next_excavator_id = self.excavator_uuid_index_dict.inverse[min_index]
next_dump_id = truck_trip[-1]
truck_dispatch[i] = [next_excavator_id, next_dump_id]
if truck_task in [0, 1]:
next_dump_list = s.solve(i)
min_index = next_dump_list.index(min(next_dump_list)) + 1
next_dump_id = self.dump_uuid_index_dict.inverse[min_index]
next_excavator_id = truck_trip[-1]
truck_dispatch[i] = [next_excavator_id, next_dump_id]
# return dispatch plan
return truck_dispatch
# from data.dispatchInfo import DispatchInfo
# from bidict import bidict
# from alg.algorithm import AlgorithmBase
#
#
# class Group_0:
# """
# class for group instance.
# """
# def __init__(self, group_id):
# """ Generate a group obj.
# :param group_id: (uuid) group_id
# """
#
# self.group_id = group_id
#
# # group devices
# self.excavator_dict = {} # excavator_id -> unload_area_id
# self.dump_dict = {} # dump_id -> load_area_id
# self.truck_set = set() # truck_id
#
# # road network info.
# self.to_excavator_distance = None
# self.to_dump_distance = None
# self.park_to_excavator_distance = None
#
# self.to_excavator_congestion = None
# self.to_dump_congestion = None
# self.park_to_excavator_congestion = None
#
# # device map
# self.truck_uuid_index_dict = bidict()
# self.excavator_uuid_index_dict = bidict()
# self.dump_uuid_index_dict = bidict()
#
# def update_xx_(self):
# """
# update above parameters.
# :return:
# """
# pass
#
# def group_dispatch(self, solver):
# """
# Receive a alg obj. and output dispatch plan for trucks in this group.
# :param solver:
# :return:
# dispatch plan: Dict({truck_id: match_id})
# """
# assert isinstance(solver, AlgorithmBase)
# s = solver(self) # algorithm init
# return s.solve() # algorithm solve
This diff is collapsed.
......@@ -128,8 +128,8 @@ class DispatchInfo:
"""
try:
for value in session_postgre.query(DiggingWorkArea).all():
cls.load_exactor_dict[value.Id] = value.Exactorld
cls.exactor_load_dict[value.Exactorld] = value.Id
cls.load_exactor_dict[value.Id] = value.ExactorId
cls.exactor_load_dict[value.ExactorId] = value.Id
except Exception as es:
logger.error("初始化数据更新异常")
logger.error(es)
......@@ -148,9 +148,11 @@ class DispatchInfo:
for item in session_postgre.query(WalkTime).all():
temp = str(item.load_area_id), str(item.unload_area_id), item.to_load_distance, item.to_unload_distance
df = pd.concat([df, pd.DataFrame([temp])], axis=0, ignore_index=True)
for team_id in list(cls.group_dump_dict.keys()):
unload_nums = list(set(cls.group_dump_dict[team_id])) # 获取同一个team_id对应的卸载区列表
exactor_nums = list(set(cls.group_excavator_dict[team_id])) # 获取同一个team_id对应的电铲列表
unload_exactor_matrix = np.zeros(
(len(unload_nums), len(exactor_nums))) # 初始化距离矩阵,记录从卸载区-->>电铲的距离,即to_load_distance,空车模式
load_exactor_matrix = np.array(
......@@ -170,3 +172,200 @@ class DispatchInfo:
except Exception as es:
logger.error("路网数据更新异常")
logger.error(es)
@classmethod
def get_group_mode(cls, group_id):
return cls.group_mode[group_id]
@classmethod
def get_excavator_dict(cls, group_id):
return cls.group_excavator_dict[group_id]
@classmethod
def get_dump_dict(cls, group_id):
return cls.group_dump_dict[group_id]
@classmethod
def get_truck_set(cls, group_id):
return cls.group_truck_dict[group_id]
@classmethod
def get_to_excavator_distance(cls, group_id):
return cls.load_distance[group_id]
@classmethod
def get_to_dump_distance(cls, group_id):
return cls.unload_distance[group_id]
@classmethod
def get_park_to_excavator_distance(cls, group_id):
return cls.park_distance[group_id]
@classmethod
def get_park_to_excavator_distance(cls, group_id):
excavators = cls.group_excavator_dict[group_id]
park_matrix = np.zeros((1, len(excavators)))
for i in range(excavators):
load_area_id = cls.exactor_load_dict[excavators[i]]
distance = session_postgre.query(WalkTimePark).filter_by(load_area_id=load_area_id).first()
park_matrix[0][i] = distance
return park_matrix
# #!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_dump_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],...}
#
# dump_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_dump_dict = {}
# cls.dump_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_dump_dict = {} -->> {group_id:unload_area_id,...}
# # dump_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_dump_dict:
# cls.group_dump_dict[valve.team_id] = [valve.unload_area_id] # 注意:一个team_id可能对应多个unload_area_id
# else:
# cls.group_dump_dict[valve.team_id].append(valve.unload_area_id)
# cls.dump_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.exactor_id, item.unload_area_id]
# cls.group_excavator_dict[item.team_id] = item.exactor_id
# cls.excavator_group_dict[item.exactor_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 i in group_excavator():
# pass
# for j in group_dump():
# 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_exactor_dict = {} # 装载区id-->>电铲编号的映射
# logger = get_logger("mqc.update_route_distance")
# try:
# for value in session_postgre.query(DiggingWorkArea).all():
# load_exactor_dict[value.Id] = value.Exactorld
# for value in session_postgre.query(WalkTime).all():
# if value.load_area_id in load_exactor_dict:
# cls.load_excavator_distance[value.load_area_id] = [load_exactor_dict[value.load_area_id],
# value.to_load_distance]
# cls.unload_excavator_distance[value.unload_area_id] = [load_exactor_dict[value.load_area_id],
# value.to_unload_distance]
# except Exception as es:
# logger.error("路网数据更新异常")
# logger.error(es)
#
#
......@@ -14,7 +14,9 @@ from equipment.excavator import ExcavatorInfo
from equipment.dump import DumpInfo
import sched
import time
from dispatcher import Dispatcher, PreSchedule
from core.dispatcher import Dispatcher
from core.schedule import PreSchedule
from data.dispatchInfo import DispatchInfo
def process(dispatcher):
......@@ -24,7 +26,7 @@ def process(dispatcher):
:return: None
"""
try:
# try:
# 更新周期参数
logger.info("#####################################周期更新开始#####################################")
......@@ -45,18 +47,31 @@ def process(dispatcher):
session_postgre.commit()
session_postgre.flush()
# 周期更新
dispatcher.dispatcher_period_update()
global_period_para_update()
# 更新数据
DispatchInfo.renew_set()
DispatchInfo.dispatch_group_init()
DispatchInfo.update_device_group_structure()
DispatchInfo.update_route_distance()
DispatchInfo.update_group_mode()
# 调度计算
dispatcher.schedule_construct()
# 调度生成
dispatcher.period_update()
dispatcher.group_generate()
logger.info("#####################################周期更新结束#####################################")
dispatcher.group_dispatch()
except Exception as es:
logger.error("最外层异常捕获")
logger.error(es)
# logger.info("#####################################周期更新结束#####################################")
#
# except Exception as es:
# logger.error("最外层异常捕获")
# logger.error(es)
def perform(inc, dispatcher):
......@@ -103,7 +118,7 @@ if __name__ == "__main__":
pre_sch = PreSchedule(truck, excavator, dump)
# 实例化矿卡调度器
dispatcher = Dispatcher(dump, excavator, truck, pre_sch, False)
dispatcher = Dispatcher(truck, dump, excavator, pre_sch, False)
logger.info(" ")
logger.info("调度系统启动")
......
......@@ -60,15 +60,15 @@ def set_log():
# 创建日志目录
if not os.path.exists(log_path):
os.mkdir(log_path)
# if not os.path.exists(log_path):
# os.mkdir(log_path)
# logging初始化工作
logging.basicConfig()
# timefilehandler = logging.handlers.TimedRotatingFileHandler(log_path + "/dispatch.log", when='M', interval=1, backupCount=60)
filehandler = logging.handlers.RotatingFileHandler(log_path + "/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")
# filehandler = logging.handlers.RotatingFileHandler(log_path + "/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的格式一样
filehandler.suffix = "%Y-%m-%d_%H-%M.log"
......
......@@ -472,16 +472,16 @@ class DumpArea(Base):
Disabled = Column(Integer)
Materials = Column(VARCHAR(36))
Priority = Column(Integer)
DumpEquipmentld = Column(VARCHAR(36))
DumpEquipmentId = Column(VARCHAR(36))
def __init__(self, Id, BindList, UnloadAbililty, Disabled, Materials, Priority, DumpEquipmentld):
def __init__(self, Id, BindList, UnloadAbililty, Disabled, Materials, Priority, DumpEquipmentId):
self.Id = Id
self.BindList = BindList
self.UnloadAbililty = UnloadAbililty
self.Disabled = Disabled
self.Materials = Materials
self.Priority = Priority
self.DumpEquipmentld = DumpEquipmentld
self.DumpEquipmentId = DumpEquipmentId
class DiggingWorkArea(Base):
......@@ -489,12 +489,12 @@ class DiggingWorkArea(Base):
Id = Column(VARCHAR(50), primary_key=True)
Material = Column(VARCHAR(36))
Exactorld = Column(VARCHAR(36))
ExactorId = Column(VARCHAR(36))
def __init__(self, Id, Material, Exactorld):
def __init__(self, Id, Material, ExactorId):
self.Id = Id
self.Material = Material
self.Exactorld = Exactorld
self.ExactorId = ExactorId
class DispatchRule(Base):
......
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