Commit 2ed48496 authored by 张晓彤's avatar 张晓彤

分组调度算法更新

parent 391d2602
...@@ -6,6 +6,16 @@ ...@@ -6,6 +6,16 @@
# @File : alg.py # @File : alg.py
# @Software: PyCharm # @Software: PyCharm
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)
class AlgorithmBase: class AlgorithmBase:
""" """
...@@ -15,18 +25,101 @@ class AlgorithmBase: ...@@ -15,18 +25,101 @@ class AlgorithmBase:
def __init__(self): def __init__(self):
pass pass
def solve(self, *args, **kwargs):
"""
Dispatching calculation for subgroups.
"""
raise NotImplementedError
class Congestion(AlgorithmBase): class Congestion(AlgorithmBase):
""" """
class for congestion alg. class for congestion alg.
""" """
def __init__(self, group): def __init__(self, group: Group):
super().__init__() super().__init__()
self.group = group self.group = group
self.logger = get_logger("zxt.algorithm.congestion")
def solve(self): def solve(self, truck_id):
pass """
Receive a truck_id and calculate the associated route congestion.
:param truck_id: (uuid)
:return: congestion_value
"""
truck_index = truck.truck_uuid_to_index_dict[truck_id]
trip = truck.get_truck_current_trip()[truck_index]
task = truck.get_truck_current_task()[truck_id]
group_dynamic_excavator_num = len(self.group.dump_dict)
group_dynamic_dump_num = len(self.group.excavator_dict)
if task == -2:
################################################ 矿卡启动 ###############################################
try:
self.logger.info("矿卡状态:矿卡启动或故障恢复")
self.logger.info(f"涉及挖机:{list(DeviceMap.excavator_uuid_to_index_dict.keys())}")
except Exception as es:
self.logger.error(f"矿卡{truck_id}状态不匹配")
self.logger.error(es)
try:
transport_value = self.group.park_to_excavator_congestion
except Exception as es:
transport_value = np.zeros(group_dynamic_excavator_num)
self.logger.info(es)
if task in [0, 1, 2]:
################################################ 矿卡空载 ###############################################
try:
self.logger.info("矿卡状态:矿卡空载")
self.logger.info(f"涉及卸载设备:{list(DumpInfo.dump_uuid_to_index_dict.keys())}")
except Exception as es:
self.logger.error(f"矿卡{truck_id}状态不匹配")
self.logger.error(es)
# 车辆所在挖机 uuid
excavator_id = DeviceMap.excavator_index_to_uuid_dict[int(trip[1])]
# 挖机所在分组序号 index
excavator_group_index = self.group.excavator_uuid_index_dict[excavator_id]
try:
transport_value = self.group.to_dump_congestion[excavator_group_index, :]
except Exception as es:
transport_value = np.zeros(group_dynamic_dump_num)
self.logger.error(es)
elif task in [3, 4, 5]:
################################################ 矿卡重载 ###############################################
try:
self.logger.info("矿卡状态:矿卡重载")
self.logger.info(f"涉及挖机设备:{list(DeviceMap.excavator_uuid_to_index_dict.keys())}")
except Exception as es:
self.logger.error(f"矿卡{truck_id}状态不匹配")
self.logger.error(es)
try:
# 车辆所在卸点
dump_id = DeviceMap.dump_index_to_uuid_dict[int(trip[1])]
# 卸点对应分组编号
dump_group_index = self.group.dump_uuid_index_dict[dump_id]
transport_value = self.group.to_excavator_congestion[dump_group_index, :]
except Exception as es:
transport_value = np.zeros(group_dynamic_excavator_num)
self.logger.info(es)
return transport_value
class ExpectedTime(AlgorithmBase): class ExpectedTime(AlgorithmBase):
...@@ -34,9 +127,165 @@ class ExpectedTime(AlgorithmBase): ...@@ -34,9 +127,165 @@ class ExpectedTime(AlgorithmBase):
class for expected traveling time alg. class for expected traveling time alg.
""" """
def __init__(self, group): def __init__(self, group: Group):
super().__init__() super().__init__()
self.group = group self.group = group
self.logger = get_logger("zxt.algorithm.expected")
def solve(self, truck_id):
"""
Receive a truck_id and calculate the associated route travelling time.
:param truck_id: (uuid)
:return: travel_time_value
"""
truck_index = truck.truck_uuid_to_index_dict[truck_id]
trip = truck.get_truck_current_trip()[truck_index]
task = truck.get_truck_current_task()[truck_id]
truck_avl_time = pre_sch.get_truck_avl_time(truck_id=truck_id)
group_dynamic_excavator_num = len(self.group.dump_dict)
group_dynamic_dump_num = len(self.group.excavator_dict)
if task == -2:
################################################ 矿卡启动 ###############################################
try:
self.logger.info("矿卡状态:矿卡启动或故障恢复")
self.logger.info(f"涉及挖机:{list(DeviceMap.excavator_uuid_to_index_dict.keys())}")
except Exception as es:
self.logger.error(f"矿卡{truck_id}状态不匹配")
self.logger.error(es)
try:
# 挖机可用时间
excavator_val_time_global = pre_sch.get_excavator_avl_time()
excavator_val_time = np.full(len(self.group.excavator_dict), 0)
for excavator_id, excavator_index in self.group.excavator_uuid_index_dict.items():
excavator_val_time[excavator_index] = excavator_val_time_global[excavator_id]
# 车辆驶往各目的地时间
truck_reach_time = 60 * self.group.park_to_excavator_distance[0, :] / 1000 / \
truck.empty_speed[truck_id] + truck_avl_time
# 计算车辆得到服务时间
truck_service_time = np.maximum(truck_reach_time, excavator_val_time)
# 计算行程时间
transport_value = truck_service_time - truck_avl_time
self.logger.info("expected_travelling_schedule-truck_avl_time")
self.logger.info(truck_avl_time)
self.logger.info("expected_travelling_schedule-truck_service_time")
self.logger.info(truck_service_time)
self.logger.info("expected_travelling_schedule-truck_reach_time")
self.logger.info(truck_reach_time)
self.logger.info("expected_travelling_schedule-excavator_val_time")
self.logger.info(excavator_val_time)
except Exception as es:
transport_value = np.zeros(group_dynamic_excavator_num)
self.logger.info(es)
if task in [0, 1, 2]:
################################################ 矿卡空载 ###############################################
try:
self.logger.info("矿卡状态:矿卡空载")
self.logger.info(f"涉及卸载设备:{list(DeviceMap.dump_uuid_to_index_dict.keys())}")
except Exception as es:
self.logger.error(f"矿卡{truck_id}状态不匹配")
self.logger.error(es)
try:
# 全局卸点可用时间 dict
dump_val_time_global = pre_sch.get_dump_avl_time()
# 局部卸点可用时间 list
dump_val_time = np.full(len(self.group.dump_dict), 0)
for dump_id, dump_index in self.group.dump_uuid_index_dict.items():
dump_val_time[dump_index] = dump_val_time_global[dump_id]
# 车辆所在挖机 uuid
excavator_id = DeviceMap.excavator_index_to_uuid_dict[int(trip[1])]
# 挖机所在分组序号 index
excavator_group_index = self.group.excavator_uuid_index_dict[excavator_id]
# 车辆驶往各目的地时间
truck_reach_time = 60 * self.group.to_dump_distance[excavator_group_index, :] \
/ 1000 / truck.heavy_speed[truck_id] + truck_avl_time
# 车辆得到服务时间
truck_service_time = np.maximum(truck_reach_time, dump_val_time)
# 计算行程时间
transport_value = truck_service_time - truck_avl_time
self.logger.info("expected_travelling_schedule-truck_avl_time")
self.logger.info(truck_avl_time)
self.logger.info("expected_travelling_schedule-truck_service_time")
self.logger.info(truck_service_time)
self.logger.info("expected_travelling_schedule-truck_reach_time")
self.logger.info(truck_reach_time)
self.logger.info("expected_travelling_schedule-dump_val_time")
self.logger.info(dump_val_time)
except Exception as es:
transport_value = np.zeros(group_dynamic_dump_num)
self.logger.error(es)
elif task in [3, 4, 5]:
################################################ 矿卡重载 ###############################################
try:
self.logger.info("矿卡状态:矿卡重载")
self.logger.info(f"涉及挖机设备:{list(DeviceMap.excavator_uuid_to_index_dict.keys())}")
except Exception as es:
self.logger.error(f"矿卡{truck_id}状态不匹配")
self.logger.error(es)
try:
# 挖机可用时间
excavator_val_time_global = pre_sch.get_excavator_avl_time()
excavator_val_time = np.full(len(self.group.excavator_dict), 0)
for excavator_id, excavator_index in self.group.excavator_uuid_index_dict.items():
excavator_val_time[excavator_index] = excavator_val_time_global[excavator_id]
# 车辆所在卸点
dump_id = DeviceMap.dump_index_to_uuid_dict[int(trip[1])]
# 卸点对应分组编号
dump_group_index = self.group.dump_uuid_index_dict[dump_id]
# 车辆驶往各目的地时间
truck_reach_time = 60 * self.group.to_excavator_distance[dump_group_index, :] \
/ 1000 / truck.empty_speed[truck_id] + truck_avl_time
# 计算车辆得到服务时间
truck_service_time = np.maximum(truck_reach_time, excavator_val_time)
# 计算行程时间
transport_value = truck_service_time - truck_avl_time
except Exception as es:
transport_value = np.zeros(group_dynamic_dump_num)
self.logger.error(es)
return transport_value
def solve(self):
pass
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2022/6/1 16:35
# @Author : Opfer
# @Site :
# @File : dispatcher.py
# @Software: PyCharm
from data.dispatchInfo import DispatchInfo
from core.group import Group
from alg.algorithm import ExpectedTime
from settings import get_logger, session_mysql, redis5
from tables import Dispatch
from para_config import DeviceMap, get_value, global_period_para_update
from equipment import TruckInfo, ExcavatorInfo, DumpInfo
import json
import numpy as np
from datetime import datetime, timedelta
class Dispatcher:
"""
class for group dispatch program.
"""
def __init__(self, truck: TruckInfo, dump: DumpInfo, excavator: ExcavatorInfo):
self.group_list = []
self.truck = truck
self.dump = dump
self.excavator = excavator
self.submission = DispatchSubmission(dump, excavator, truck)
def period_update(self):
"""
Update global parameter and equipment information.
:return: None
"""
global_period_para_update()
self.dump.dump_para_period_update()
self.excavator.excavator_para_period_update()
self.truck.truck_para_period_update(self.dump, self.excavator)
self.truck.state_period_update()
def group_generate(self):
"""
Generate and initialize dispatch groups.
:return: None
"""
for group_id in DispatchInfo.group_set:
group = Group(group_id, self.truck, self.dump, self.excavator)
self.group_list.append(group)
def group_dispatch(self):
"""
Group dispatching logic.
:return:
"""
for group in self.group_list:
truck_dispatch_plan_dict = group.group_dispatch(ExpectedTime)
self.submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict)
class DispatchSubmission:
""" class for the submission calculated dispatch.
Description:
将调度结果按照指定格式传递到云端机群
Attribute:
"""
def __init__(self, dump, excavator, truck, group):
self.logger = self.logger = get_logger("zxt.submission")
self.dump = dump
self.excavator = excavator
self.truck = truck
self.group = group
def truck_dispatch_to_redis(self, truck_id, dispatch_seq):
"""
将truck_id对应矿卡派车计划写入redis
:param truck_id: (uuid) 矿卡uuid
:param dispatch_seq: (List[int]) 矿卡派车计划
:return: None
"""
try:
try:
group_id = self.group.dispatch_truck_group[truck_id]
record = {"truckId": truck_id}
task = self.truck.get_truck_current_task()[truck_id]
except Exception as es:
self.logger.error("调度结果写入异常-读取矿卡信息异常(uuid, group id, task)")
self.logger.error(es)
if task in [0, 1, 2]: # 卡车空载或在装载区出场前, 可变更卸载目的地
try:
item = (
session_mysql.query(Dispatch)
.filter_by(dump_id=DeviceMap.dump_index_to_uuid_dict[dispatch_seq[1]],
exactor_id=DeviceMap.excavator_index_to_uuid_dict[dispatch_seq[0]],
truck_id=truck_id,
group_id=group_id,
isauto=1, isdeleted=0, ).first())
if item is None:
raise Exception("调度计划表与实时监控不匹配")
except Exception as es:
self.logger.error(es)
item = (
session_mysql.query(Dispatch)
.filter_by(truck_id=truck_id,
# group_id=group_id,
isauto=1, isdeleted=0, ).first())
try:
record["exactorId"] = item.exactor_id
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %I:%M:%S %p")
redis5.set(truck_id, str(json.dumps(record)))
except Exception as es:
self.logger.error("调度结果写入异常-矿卡空载")
elif task in [3, 4, 5]: # 卡车重载或在卸载区出场前, 可变更装载目的地
try:
item = (
session_mysql.query(Dispatch)
.filter_by(exactor_id=DeviceMap.excavator_index_to_uuid_dict[dispatch_seq[1]],
dump_id=DeviceMap.dump_index_to_uuid_dict[dispatch_seq[0]],
truck_id=truck_id,
group_id=group_id,
isauto=1, isdeleted=0, ).first())
if item is None:
raise Exception("调度计划表与实时监控不匹配")
except Exception as es:
self.logger.error(es)
item = (
session_mysql.query(Dispatch)
.filter_by(truck_id=truck_id,
# group_id=group_id,
isauto=1, isdeleted=0, ).first())
try:
record["exactorId"] = self.excavator.excavator_index_to_uuid_dict[dispatch_seq[1]]
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %I:%M:%S %p")
redis5.set(truck_id, str(json.dumps(record)))
except Exception as es:
self.logger.error("调度结果写入异常-矿卡重载")
elif task == -2:
try:
try:
item = (
session_mysql.query(Dispatch)
.filter_by(exactor_id=DeviceMap.excavator_index_to_uuid_dict[dispatch_seq[1]],
truck_id=truck_id,
group_id=group_id,
isauto=1, isdeleted=0).first())
if item is None:
raise Exception("调度计划表与实时监控不匹配")
self.logger.info(dispatch_seq)
self.logger.info(dispatch_seq[1])
self.logger.info(DeviceMap.excavator_index_to_uuid_dict[dispatch_seq[1]])
self.logger.info("item")
print(item.id, item.truck_id, item.exactor_id, item.dump_id)
except Exception as es:
self.logger.error(es)
item = (
session_mysql.query(Dispatch)
.filter_by(truck_id=truck_id,
# group_id=group_id,
isauto=1, isdeleted=0).first())
try:
record["exactorId"] = item.exactor_id
record["dumpId"] = item.dump_id
record["loadAreaId"] = item.load_area_id
record["unloadAreaId"] = item.unload_area_id
record["dispatchId"] = item.id
record["isdeleted"] = False
record["creator"] = item.creator
record["createtime"] = item.createtime.strftime(
"%b %d, %Y %I:%M:%S %p")
redis5.set(truck_id, str(json.dumps(record)))
except Exception as es:
self.logger.error("调度结果写入异常-矿卡故障或备停区-redis写入异常")
self.logger.error(es)
except Exception as es:
self.logger.error("调度结果写入异常-矿卡故障或备停区")
self.logger.error(es)
else:
pass
except Exception as es:
self.logger.error("调度结果写入异常")
self.logger.error(f"调度结果:{dispatch_seq}")
self.logger.error(es)
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
"""
for truck_id, dispatch_plan in dispatch_plan_dict:
self.truck_dispatch_to_redis(truck_id, dispatch_plan)
class PreSchedule:
""" class for the prediction of equipments' trip.
Description:
负责处理所有预测项的计算与更新
基于矿卡最近一次装卸载时间预测其抵达目的地时间
根据矿卡请求队列及抵达信息,计算设备最早可用时间
Attribute:
equipment class: truck, excavator, dump
schedule start time
equipment available time: truck, excavator, dump
"""
def __init__(self, truck, excavator, dump):
# 设备对象域
self.truck = truck
self.excavator = excavator
self.dump = dump
# 调度开始时间
self.start_time = datetime.now()
# 真实设备可用时间
self.truck_reach_dump = np.zeros(self.truck.get_truck_num())
self.truck_reach_excavator = np.zeros(self.truck.get_truck_num())
self.excavator_avl_time = np.zeros(self.excavator.get_excavator_num())
self.dump_avl_time = np.zeros(self.dump.get_dump_num())
self.truck_avl_time = np.zeros(self.truck.get_truck_num())
self.excavator_avl_time_dict = {}
self.dump_avl_time_dict = {}
self.truck_avl_time_dict = {}
self.logger = get_logger("zxt.pre_schedule")
def update_truck_reach_time(self):
"""
更新矿卡预计抵达目的地时间
:return:
excavator_avl_ls: (list) 驶往挖机的各矿卡抵达时间
dump_avl_ls: (list) 驶往卸点的各矿卡抵达时间
"""
try:
dynamic_excavator_num = self.excavator.get_excavator_num()
dumps = self.dump.get_dump_num()
trucks = self.truck.get_truck_num()
truck_current_task = self.truck.get_truck_current_task()
truck_current_trip = self.truck.get_truck_current_trip()
truck_reach_excavator = self.truck.get_truck_reach_excavator()
truck_reach_dump = self.truck.get_truck_reach_dump()
excavator_avl_ls = [[] for _ in range(dynamic_excavator_num)]
dump_avl_ls = [[] for _ in range(dumps)]
# self.logger.info("update_truck_reach_time-trucks")
# self.logger.info(trucks)
for i in range(trucks):
task = truck_current_task[self.truck.truck_index_to_uuid_dict[i]]
end_area_index = truck_current_trip[i][1]
# self.logger.info("update_truck_reach_time-truck_current_trip")
# self.logger.info(truck_current_trip)
if task in [0, 1]: # 卡车空载行驶或正在入场
reach_time = truck_reach_excavator[i]
excavator_avl_ls[end_area_index].append(
[reach_time, i, end_area_index]
)
elif task in [3, 4]: # 卡车重载行驶或正在入场
reach_time = truck_reach_dump[i]
dump_avl_ls[end_area_index].append([reach_time, i, end_area_index])
elif task == -2:
self.truck_avl_time[i] = (
datetime.now() - self.start_time
) / timedelta(hours=0, minutes=1, seconds=0)
except Exception as es:
self.logger.error("矿卡预计抵达时间计算异常")
self.logger.error(es)
return [], []
return excavator_avl_ls, dump_avl_ls
def update_excavator_avl_time(self, excavator_avl_ls):
"""
更新挖机预计可用时间
:param
excavator_avl_ls: (list) 驶往挖机的各矿卡抵达时间
:return:
excavator_avl_time: (array) 各挖机完成所有已分配矿卡装载的时间
"""
# 初始化挖机可用时间
self.excavator_avl_time = np.full(
get_value("dynamic_excavator_num"),
(datetime.now() - self.start_time)
/ timedelta(hours=0, minutes=1, seconds=0),
)
for excavator_id in get_value("dynamic_excavator_set"):
self.excavator_avl_time_dict[excavator_id] = (datetime.now() - self.start_time) \
/ timedelta(hours=0, minutes=1, seconds=0)
loading_time = self.excavator.get_loading_time()
loading_task_time = self.excavator.get_loading_task_time()
try:
now = float(
(datetime.now() - self.start_time)
/ timedelta(hours=0, minutes=1, seconds=0)
)
for reach_ls in excavator_avl_ls:
self.logger.info("update_excavator_avl_time-excavator_avl_ls")
self.logger.info(excavator_avl_ls)
if len(reach_ls) != 0:
reach_ls = np.array(reach_ls)
tmp = reach_ls[np.lexsort(reach_ls[:, ::-1].T)]
for i in range(len(tmp)):
excavator_index = int(tmp[i][2])
excavator_id = self.excavator.excavator_index_to_uuid_dict[excavator_index]
self.excavator_avl_time[excavator_index] = (
max(tmp[i][0], self.excavator_avl_time[excavator_index])
+ loading_task_time[excavator_index]
)
self.excavator_avl_time_dict[excavator_id] = self.excavator_avl_time[excavator_index]
truck_index = int(tmp[i][1])
truck_id = self.truck.truck_index_to_uuid_dict[truck_index]
self.truck_avl_time[truck_index] = self.excavator_avl_time[excavator_index]
self.truck_avl_time_dict[truck_id] = self.truck_avl_time[truck_index]
# # 若挖机可用时间严重偏离,进行修正
# if abs(self.excavator_avl_time[excavator_index] - now) > 60:
# self.truck_avl_time[int(tmp[i][1])] = now
# if abs(self.excavator_avl_time[excavator_index] - now) > 60:
# self.excavator_avl_time[excavator_index] = now
except Exception as es:
self.logger.error("挖机可用时间计算异常")
self.logger.error(es)
return self.excavator_avl_time_dict
def update_dump_avl_time(self, dump_avl_ls):
"""
更新卸载设备预计可用时间
:param
dump_avl_ls: (list) 驶往卸点的各矿卡抵达时间
:return:
dump_avl_time: (array) 各卸点完成所有已分配矿卡卸载的时间
"""
dynamic_dump_num = self.dump.get_dump_num()
# 初始化卸载设备可用时间
self.dump_avl_time = np.full(
dynamic_dump_num,
(datetime.now() - self.start_time)
/ timedelta(hours=0, minutes=1, seconds=0),
)
for dump_id in get_value("dynamic_dump_set"):
self.dump_avl_time_dict[dump_id] = (datetime.now() - self.start_time) \
/ timedelta(hours=0, minutes=1, seconds=0)
unloading_time = self.dump.get_unloading_time()
unloading_task_time = self.dump.get_unloading_task_time()
try:
now = float(
(datetime.now() - self.start_time)
/ timedelta(hours=0, minutes=1, seconds=0)
)
for reach_ls in dump_avl_ls:
if len(reach_ls) != 0:
reach_ls = np.array(reach_ls)
tmp = reach_ls[np.lexsort(reach_ls[:, ::-1].T)]
for i in range(len(tmp)):
dump_index = int(tmp[i][2])
dump_id = self.dump.dump_index_to_uuid_dict[dump_index]
self.dump_avl_time[dump_index] = (
max(tmp[i][0], self.dump_avl_time[dump_index])
+ unloading_task_time[dump_index]
)
self.dump_avl_time_dict[dump_id] = self.dump_avl_time[dump_index]
truck_index = int(tmp[i][1])
truck_id = self.truck.truck_index_to_uuid_dict[truck_index]
self.truck_avl_time[truck_index] = self.dump_avl_time[dump_index]
self.truck_avl_time_dict[truck_id] = self.truck_avl_time[truck_index]
# # 若卸载设备可用时间严重偏离,进行修正
# if abs(self.dump_avl_time[dump_index] - now) > 60:
# self.dump_avl_time[dump_index] = now
# if abs(self.truck_avl_time[int(tmp[i][1])] - now) > 60:
# self.truck_avl_time[int(tmp[i][1])] = now
except Exception as es:
self.logger.error("卸载设备可用时间计算异常")
self.logger.error(es)
return self.dump_avl_time_dict
def _reset(self):
"""
重置设备可用时间
:return:
"""
# 真实设备可用时间
self.truck_reach_dump = np.zeros(self.truck.get_truck_num())
self.truck_reach_excavator = np.zeros(self.truck.get_truck_num())
self.excavator_avl_time = np.zeros(self.excavator.get_excavator_num())
self.dump_avl_time = np.zeros(self.dump.get_dump_num())
self.truck_avl_time = np.zeros(self.truck.get_truck_num())
self.excavator_avl_time_dict = {}
self.dump_avl_time_dict = {}
self.truck_avl_time_dict = {}
def get_dump_avl_time(self):
"""
获取卸载点最早可用时间
:return:
dump_avl_time: (array) 各卸点完成所有已分配矿卡卸载的时间
"""
self._reset()
excavator_avl_ls, dump_avl_ls = self.update_truck_reach_time()
dump_avl_time = self.update_dump_avl_time(dump_avl_ls)
return dump_avl_time
def get_excavator_avl_time(self, excavator_id=None):
"""
获取挖机最早可用时间
:param excavator_id: 挖机编号uuid
:return:
excavator_avl_time: (array) 各挖机完成所有已分配矿卡装载的时间
"""
self._reset()
excavator_avl_ls, dump_avl_ls = self.update_truck_reach_time()
if excavator_id is not None:
return self.update_excavator_avl_time(excavator_avl_ls) \
[self.excavator.excavator_uuid_to_index_dict[excavator_id]]
else:
return self.update_excavator_avl_time(excavator_avl_ls)
def get_truck_avl_time(self, truck_id=None):
"""
获取矿卡最早可用时间
:param truck_id: 矿卡编号uuid
:return: truck_avl_time: (array) 各矿卡完成当前装载或卸载任务的时间
"""
self._reset()
excavator_avl_ls, dump_avl_ls = self.update_truck_reach_time()
self.update_excavator_avl_time(excavator_avl_ls)
self.update_dump_avl_time(dump_avl_ls)
if truck_id is not None:
return self.truck_avl_time[self.truck.truck_uuid_to_index_dict[truck_id]]
else:
return self.truck_avl_time
...@@ -855,9 +855,12 @@ class PreSchedule: ...@@ -855,9 +855,12 @@ class PreSchedule:
self.truck_reach_excavator = np.zeros(self.truck.get_truck_num()) self.truck_reach_excavator = np.zeros(self.truck.get_truck_num())
self.excavator_avl_time = np.zeros(self.excavator.get_excavator_num()) self.excavator_avl_time = np.zeros(self.excavator.get_excavator_num())
self.dump_avl_time = np.zeros(self.dump.get_dump_num()) self.dump_avl_time = np.zeros(self.dump.get_dump_num())
# 卡车完成装载及卸载时间(矿卡可用时间)
self.truck_avl_time = np.zeros(self.truck.get_truck_num()) self.truck_avl_time = np.zeros(self.truck.get_truck_num())
self.excavator_avl_time_dict = {}
self.dump_avl_time_dict = {}
self.truck_avl_time_dict = {}
self.logger = get_logger("zxt.pre_schedule") self.logger = get_logger("zxt.pre_schedule")
def update_truck_reach_time(self): def update_truck_reach_time(self):
...@@ -925,6 +928,10 @@ class PreSchedule: ...@@ -925,6 +928,10 @@ class PreSchedule:
/ timedelta(hours=0, minutes=1, seconds=0), / timedelta(hours=0, minutes=1, seconds=0),
) )
for excavator_id in get_value("dynamic_excavator_set"):
self.excavator_avl_time_dict[excavator_id] = (datetime.now() - self.start_time) \
/ timedelta(hours=0, minutes=1, seconds=0)
loading_time = self.excavator.get_loading_time() loading_time = self.excavator.get_loading_time()
loading_task_time = self.excavator.get_loading_task_time() loading_task_time = self.excavator.get_loading_task_time()
...@@ -943,14 +950,19 @@ class PreSchedule: ...@@ -943,14 +950,19 @@ class PreSchedule:
reach_ls = np.array(reach_ls) reach_ls = np.array(reach_ls)
tmp = reach_ls[np.lexsort(reach_ls[:, ::-1].T)] tmp = reach_ls[np.lexsort(reach_ls[:, ::-1].T)]
for i in range(len(tmp)): for i in range(len(tmp)):
excavator_index = int(tmp[i][2]) excavator_index = int(tmp[i][2])
excavator_id = self.excavator.excavator_index_to_uuid_dict[excavator_index]
self.excavator_avl_time[excavator_index] = ( self.excavator_avl_time[excavator_index] = (
max(tmp[i][0], self.excavator_avl_time[excavator_index]) max(tmp[i][0], self.excavator_avl_time[excavator_index])
+ loading_task_time[excavator_index] + loading_task_time[excavator_index]
) )
self.truck_avl_time[ self.excavator_avl_time_dict[excavator_id] = self.excavator_avl_time[excavator_index]
int(tmp[i][1])
] = self.excavator_avl_time[excavator_index] truck_index = int(tmp[i][1])
truck_id = self.truck.truck_index_to_uuid_dict[truck_index]
self.truck_avl_time[truck_index] = self.excavator_avl_time[excavator_index]
self.truck_avl_time_dict[truck_id] = self.truck_avl_time[truck_index]
# # 若挖机可用时间严重偏离,进行修正 # # 若挖机可用时间严重偏离,进行修正
# if abs(self.excavator_avl_time[excavator_index] - now) > 60: # if abs(self.excavator_avl_time[excavator_index] - now) > 60:
...@@ -961,7 +973,7 @@ class PreSchedule: ...@@ -961,7 +973,7 @@ class PreSchedule:
self.logger.error("挖机可用时间计算异常") self.logger.error("挖机可用时间计算异常")
self.logger.error(es) self.logger.error(es)
return self.excavator_avl_time return self.excavator_avl_time_dict
def update_dump_avl_time(self, dump_avl_ls): def update_dump_avl_time(self, dump_avl_ls):
""" """
...@@ -981,6 +993,10 @@ class PreSchedule: ...@@ -981,6 +993,10 @@ class PreSchedule:
/ timedelta(hours=0, minutes=1, seconds=0), / timedelta(hours=0, minutes=1, seconds=0),
) )
for dump_id in get_value("dynamic_dump_set"):
self.dump_avl_time_dict[dump_id] = (datetime.now() - self.start_time) \
/ timedelta(hours=0, minutes=1, seconds=0)
unloading_time = self.dump.get_unloading_time() unloading_time = self.dump.get_unloading_time()
unloading_task_time = self.dump.get_unloading_task_time() unloading_task_time = self.dump.get_unloading_task_time()
...@@ -997,14 +1013,19 @@ class PreSchedule: ...@@ -997,14 +1013,19 @@ class PreSchedule:
reach_ls = np.array(reach_ls) reach_ls = np.array(reach_ls)
tmp = reach_ls[np.lexsort(reach_ls[:, ::-1].T)] tmp = reach_ls[np.lexsort(reach_ls[:, ::-1].T)]
for i in range(len(tmp)): for i in range(len(tmp)):
dump_index = int(tmp[i][2]) dump_index = int(tmp[i][2])
dump_id = self.dump.dump_index_to_uuid_dict[dump_index]
self.dump_avl_time[dump_index] = ( self.dump_avl_time[dump_index] = (
max(tmp[i][0], self.dump_avl_time[dump_index]) max(tmp[i][0], self.dump_avl_time[dump_index])
+ unloading_task_time[dump_index] + unloading_task_time[dump_index]
) )
self.truck_avl_time[ self.dump_avl_time_dict[dump_id] = self.dump_avl_time[dump_index]
int(tmp[i][1])
] = self.dump_avl_time[dump_index] truck_index = int(tmp[i][1])
truck_id = self.truck.truck_index_to_uuid_dict[truck_index]
self.truck_avl_time[truck_index] = self.dump_avl_time[dump_index]
self.truck_avl_time_dict[truck_id] = self.truck_avl_time[truck_index]
# # 若卸载设备可用时间严重偏离,进行修正 # # 若卸载设备可用时间严重偏离,进行修正
# if abs(self.dump_avl_time[dump_index] - now) > 60: # if abs(self.dump_avl_time[dump_index] - now) > 60:
...@@ -1015,7 +1036,7 @@ class PreSchedule: ...@@ -1015,7 +1036,7 @@ class PreSchedule:
self.logger.error("卸载设备可用时间计算异常") self.logger.error("卸载设备可用时间计算异常")
self.logger.error(es) self.logger.error(es)
return self.dump_avl_time return self.dump_avl_time_dict
def _reset(self): def _reset(self):
""" """
...@@ -1027,9 +1048,12 @@ class PreSchedule: ...@@ -1027,9 +1048,12 @@ class PreSchedule:
self.truck_reach_excavator = np.zeros(self.truck.get_truck_num()) self.truck_reach_excavator = np.zeros(self.truck.get_truck_num())
self.excavator_avl_time = np.zeros(self.excavator.get_excavator_num()) self.excavator_avl_time = np.zeros(self.excavator.get_excavator_num())
self.dump_avl_time = np.zeros(self.dump.get_dump_num()) self.dump_avl_time = np.zeros(self.dump.get_dump_num())
# 卡车完成装载及卸载时间(矿卡可用时间)
self.truck_avl_time = np.zeros(self.truck.get_truck_num()) self.truck_avl_time = np.zeros(self.truck.get_truck_num())
self.excavator_avl_time_dict = {}
self.dump_avl_time_dict = {}
self.truck_avl_time_dict = {}
def get_dump_avl_time(self): def get_dump_avl_time(self):
""" """
获取卸载点最早可用时间 获取卸载点最早可用时间
......
...@@ -4,4 +4,8 @@ ...@@ -4,4 +4,8 @@
# @Author : Opfer # @Author : Opfer
# @Site : # @Site :
# @File : __init__.py # @File : __init__.py
# @Software: PyCharm # @Software: PyCharm
\ No newline at end of file
from .excavator import ExcavatorInfo
from .dump import DumpInfo
from .truck import TruckInfo
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