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

路径修改

parents bdb62c7a b6bf7ded
File added
# Default ignored files
/workspace.xml
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData">
<serverData>
<paths name="root@172.16.0.103:22">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData>
</component>
</project>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="Python 3.7 (waytous)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (waytous)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/integrated-scheduling-v3.iml" filepath="$PROJECT_DIR$/.idea/integrated-scheduling-v3.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
{
"para": {
<<<<<<< HEAD
"log_path": "E:\\Pycharm Projects\\Waytous\\",
"empty_speed": 25,
"heavy_speed": 22,
=======
"log_path": "/usr/local/fleet-log/dispatch",
"empty_speed": 17,
"heavy_speed": 17,
>>>>>>> new
"dump_target_mass": 5000,
"excavator_target_mass": 5000
},
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2021/7/26 14:35
# @Author : Opfer
# @Site :
# @File : path_plannner.py
# @Software: PyCharm
from equipment.truck import TruckInfo, DumpInfo, ExcavatorInfo
# from path_plan.priority_control import PriorityController
from path_plan.priority_control import PriorityController
from path_plan.topo_graph import *
from para_config import *
from tables import *
M = 1000000
class PathPlanner(WalkManage):
def __init__(self, topo):
# 路段类
self.lane = LaneInfo()
self.lane.lane_speed_generate()
self.topo = topo
# 生成的拓扑图
self.unload_G = self.topo.get_unload_G()
self.load_G = self.topo.get_load_G()
# 设备类
self.dump = DumpInfo()
self.excavator = ExcavatorInfo()
self.truck = TruckInfo(self.dump, self.excavator)
self.truck.update_truck_size()
# 控制类
self.controller = PriorityController(self.dump, self.excavator, self.truck)
# 路线行驶成本
self.rout_cost = np.array((unload_area_num, load_area_num))
# 路段集合
self.lane_set = {}
self.logger = get_logger("zxt.path_planner")
try:
self.truck_length = float(sum(self.truck.get_length().values())) / len(self.truck.get_length())
except Exception as es:
self.logger.error("无矿卡数据")
self.logger.error(es)
self.truck_length = 3
# 装载区数量
self.num_of_load_area = len(set(update_load_area()))
# 卸载区数量
self.num_of_unload_area = len(set(update_unload_area()))
# 备停区数量
self.num_of_park_area = len(set(update_park_area()))
# 路网行驶成本信息
self.cost_to_load_area = np.full((self.num_of_unload_area, self.num_of_load_area), M)
self.cost_to_unload_area = np.full((self.num_of_unload_area, self.num_of_load_area), M)
# 路网信息(备停区)
self.cost_park_to_load_area = np.full((self.num_of_park_area, self.num_of_load_area), M)
# 设备路网成本信息
self.cost_to_excavator = np.zeros_like(get_value("distance_to_excavator"))
self.cost_to_dump = np.zeros_like(get_value("distance_to_dump"))
self.cost_park_to_excavator = np.zeros_like(get_value("distance_park_to_excavator"))
def update_load_G_locked_distance(self, source_node, target_node, alpha, beta):
_, park_path = nx.single_source_dijkstra(self.load_G, source=source_node, target=target_node,weight="real_distance")
for i in range(len(park_path) - 1):
data = dict(self.load_G[park_path[i]][park_path[i + 1]]['lane'])
for u, v in data.items():
u_lane_cost = self.lane_cost_generate(u)
data[u] = [v[0], beta * u_lane_cost]
self.load_G[park_path[i]][park_path[i + 1]]['locked_distance'] = sum([beta * sum(i[0] for i in list(data.values())) , alpha * sum(i[-1] for i in list(data.values()))])
def update_unload_G_locked_distance(self, source_node, target_node, alpha, beta):
_, park_path = nx.single_source_dijkstra(self.unload_G, source=source_node, target=target_node,weight="real_distance")
for i in range(len(park_path) - 1):
data = dict(self.unload_G[park_path[i]][park_path[i + 1]]['lane'])
for u, v in data.items():
u_lane_cost = self.lane_cost_generate(u)
data[u] = [v[0], beta * u_lane_cost]
self.unload_G[park_path[i]][park_path[i + 1]]['locked_distance'] = sum([beta * sum(i[0] for i in list(data.values())) , alpha * sum(i[-1] for i in list(data.values()))])
def path_cost_generate(self, load_area_id, unload_area_id, is_park):
# self.logger.info("path_拓扑图输出")
# self.logger.info(self.load_G.edges(data=True))
# self.logger.info(self.unload_G.edges(data=True))
# 卸载道路阻塞成本初始化
cost_to_unload_blockage = 0
# 装载道路阻塞成本初始化
cost_to_load_blockage = 0
# 卸载道路总成本初始化
to_unload_cost = 0
# 装载道路总成本初始化
to_load_cost = 0
# 修正因子
weight = 60
# 阻塞成本权重
alpha = 1
# 距离成本权重
beta = 1
session_mysql.commit()
# 距离成本启用
rule1 = session_mysql.query(DispatchRule).filter_by(id=1).first()
if rule1.disabled == 0:
beta = rule1.rule_weight
# 拥堵成本启用
rule2 = session_mysql.query(DispatchRule).filter_by(id=2).first()
if rule2.disabled == 0:
alpha = rule2.rule_weight
beta /= beta
alpha = alpha / beta * weight
# 备停区处理
if is_park:
try:
# 获取从指定备停区到装载区的指定路径并完成cost更新
park_source_node = str(session_postgre.query(Node).filter_by(Name="测试备停区出场点").first().Id)
park_end_node = str(session_postgre.query(DiggingWorkArea).filter_by(Id=load_area_id).first().EntranceNodeId)
self.update_load_G_locked_distance(park_source_node, park_end_node, alpha, beta)
to_load_cost = nx.dijkstra_path_length(self.load_G, source=park_source_node, target=park_end_node,
weight="locked_distance")
except Exception as es:
self.logger.error(f"从备停区到装载区{load_area_id}cost更新异常")
self.logger.error(es)
else:
try:
# from load_G part
load_source_node = str(session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().ExitNodeId)
load_end_node =str(session_postgre.query(DiggingWorkArea).filter_by(Id=load_area_id).first().EntranceNodeId)
self.update_load_G_locked_distance(load_source_node, load_end_node, alpha, beta)
to_load_cost = nx.dijkstra_path_length(self.load_G, source=load_source_node, target=load_end_node, weight="locked_distance")
except Exception as es:
self.logger.error(f"从卸载区{unload_area_id}到装载区{load_area_id}cost更新异常")
self.logger.error(es)
try:
# from unload_G part
unload_source_node = str(session_postgre.query(DiggingWorkArea).filter_by(Id=load_area_id).first().ExitNodeId)
unload_end_node = str(session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().EntranceNodeId)
self.update_unload_G_locked_distance(unload_source_node, unload_end_node, alpha, beta)
to_unload_cost = nx.dijkstra_path_length(self.unload_G, source=unload_source_node, target=unload_end_node, weight="locked_distance")
except Exception as es:
self.logger.error(f"从装载区{load_area_id}到卸载区{unload_area_id}cost更新异常")
self.logger.error(es)
# print("拥堵因子-挖机")
# print(alpha, cost_to_load_blockage)
# print("拥堵因子-卸点")
# print(alpha, cost_to_unload_blockage)
return to_load_cost, to_unload_cost
def lane_cost_generate(self, lane_id):
try:
# 读取路段记录
lane_rec = session_postgre.query(Lane).filter_by(Id=lane_id).first()
# 道路长度
lane_length = lane_rec.Length
# 车辆自由行驶时的速度
clear_speed = lane_rec.MaxSpeed
# 1. 计算阻塞时车辆密度=路段长度/车辆长度
truck_density = lane_length / self.truck_length
# 2. 读取实际车流速度
actual_speed = self.lane.lane_speed_dict[lane_id]
# 3. 计算路段阻塞程度=(1-实际路段速度)/路段最高速度
lane_blockage = (1 - actual_speed / clear_speed) * truck_density
except Exception as es:
self.logger.error('路段拥堵成本计算异常')
self.logger.error(es)
return lane_blockage
def walk_cost_cal(self):
self.excavator.para_period_update()
self.dump.para_period_update()
self.truck.para_period_update(self.dump, self.excavator)
self.truck.state_period_update()
self.period_walk_para_load()
self.period_map_para_load()
# self.controller.period_update(self.dump, self.excavator, self.truck)
# 计算行驶成本前,更新路网速度信息
self.lane.lane_speed_generate()
try:
# 读取路网成本
for walk_time in session_postgre.query(WalkTime).all():
load_area_id, unload_area_id = str(walk_time.load_area_id), str(walk_time.unload_area_id)
unload_area_index = unload_area_uuid_to_index_dict[unload_area_id]
load_area_index = load_area_uuid_to_index_dict[load_area_id]
self.cost_to_load_area[unload_area_index][load_area_index], self.cost_to_unload_area[unload_area_index][load_area_index] = \
self.path_cost_generate(load_area_id, unload_area_id, False)
# 读取备停区路网成本
for walk_time_park in session_postgre.query(WalkTimePark).all():
park_area_index = park_uuid_to_index_dict[str(walk_time_park.park_area_id)]
load_area_index = load_area_uuid_to_index_dict[str(walk_time_park.load_area_id)]
self.cost_park_to_load_area[park_area_index][load_area_index], _ = \
self.path_cost_generate(str(walk_time_park.load_area_id), str(walk_time_park.park_area_id), True)
except Exception as es:
self.logger.error('路网信息计成本计算异常')
self.logger.error(es)
self.cost_to_excavator = np.zeros_like(get_value("distance_to_excavator"))
self.cost_to_dump = np.zeros_like(get_value("distance_to_dump"))
self.cost_park_to_excavator = np.zeros_like(get_value("distance_park_to_excavator"))
self.logger.info("distance_park_to_excavator")
self.logger.info(self.distance_park_to_excavator)
# try:
# 路网权重
walk_to_excavator_weight, walk_to_dump_weight, park_walk_weight = self.controller.weighted_walk_calc()
# # 路网禁用关系
# walk_available = self.controller.walk_available_calc()
# group_walk_available = self.controller.update_group_walk_available()
self.logger.info("path_weight")
self.logger.info(walk_to_excavator_weight)
self.logger.info(walk_to_dump_weight)
self.logger.info(park_walk_weight)
# self.logger.info("walk_avail")
# self.logger.info(walk_available)
# except Exception as es:
# self.logger.error("无派车计划可用")
for i in range(get_value("dynamic_dump_num")):
for j in range(get_value("dynamic_excavator_num")):
load_area_index = self.excavator_index_to_load_area_index_dict[j]
unload_area_index = self.dump_index_to_unload_area_index_dict[i]
self.logger.info("cost_to_excavator")
self.logger.info(self.cost_to_excavator)
# self.cost_to_excavator[i][j] = self.cost_to_load_area[unload_area_index][load_area_index] / walk_weight[i][j] + group_walk_available[i][j]
self.cost_to_excavator[i][j] = self.cost_to_load_area[unload_area_index][load_area_index] / \
walk_to_excavator_weight[i][j]
# self.cost_to_dump[i][j] = self.cost_to_unload_area[unload_area_index][load_area_index] / walk_weight[i][j] + walk_available[i][j] + group_walk_available[i][j]
self.cost_to_dump[i][j] = self.cost_to_unload_area[unload_area_index][load_area_index] / \
walk_to_dump_weight[j][i]
for j in range(get_value("dynamic_excavator_num")):
load_area_index = self.excavator_index_to_load_area_index_dict[j]
self.cost_park_to_excavator[0][j] = self.cost_park_to_load_area[0][load_area_index] / park_walk_weight[0][j]
self.logger.info("真实路网距离-驶往挖机:")
self.logger.info(self.distance_to_excavator)
self.logger.info("真实路网距离-驶往卸点:")
self.logger.info(self.distance_to_dump)
self.logger.info("真实备停区路网距离-驶往挖机:")
self.logger.info(self.distance_park_to_excavator)
self.logger.info("阻塞路网距离-驶往挖机:")
self.logger.info(self.cost_to_excavator)
self.logger.info("阻塞路网距离-驶往卸点:")
self.logger.info(self.cost_to_dump)
self.logger.info("阻塞备停区路网距离-驶往挖机:")
self.logger.info(self.cost_park_to_excavator)
return self.cost_to_excavator, self.cost_to_dump, self.cost_park_to_excavator
class LaneInfo:
def __init__(self):
self.lane_speed_dict = {}
self.logger = get_logger("zxt.laneinfo")
def update_truck_speed(self):
# 读取矿卡实时速度信息
try:
truck_speed_dict = {}
device_name_set = redis2.keys()
for item in device_name_set:
item = item.decode(encoding='utf-8')
# json_value = json.loads(redis2.get(item))
key_value_dict = redis2.hgetall(item)
device_type = key_value_dict[str_to_byte('type')]
if device_type == str_to_byte("1") and str_to_byte('speed') in key_value_dict.keys():
truck_speed = float(key_value_dict[str_to_byte('speed')])
truck_speed_dict[truck_name_to_uuid_dict[item]] = truck_speed
except Exception as es:
self.logger.error(f'矿卡{item}实时速度读取异常')
self.logger.error(es)
print("truck_speed_dict")
print(truck_speed_dict)
return truck_speed_dict
def update_truck_loacate(self):
# 读取矿卡所在路段信息
try:
truck_locate_dict = {}
device_name_set = redis2.keys()
for item in device_name_set:
item = item.decode(encoding='utf-8')
# json_value = json.loads(redis2.get(item))
key_value_dict = redis2.hgetall(item)
device_type = key_value_dict[str_to_byte('type')]
is_online = key_value_dict[str_to_byte('online')]
key_set = key_value_dict.keys()
if (device_type == str_to_byte("1")) \
and (str_to_byte('online') in key_set) \
and (bytes.decode(is_online) in ["true" or "True"]) \
and (str_to_byte('laneId') in key_set):
truck_locate = key_value_dict[str_to_byte('laneId')]
truck_locate_dict[truck_name_to_uuid_dict[item]] = eval(truck_locate)
except Exception as es:
self.logger.error(f'矿卡{item}所在路段信息读取异常')
self.logger.error(es)
print("truck_locate_dict")
print(truck_locate_dict)
return truck_locate_dict
def lane_speed_generate(self):
# truck -> lane
truck_locate_dict = self.update_truck_loacate()
self.logger.info("矿卡位于路段:")
self.logger.info(truck_locate_dict)
# truck -> speed
truck_speed_dict = self.update_truck_speed()
self.logger.info("矿卡当前速度:")
self.logger.info(truck_speed_dict)
try:
# lane_set, 用到的路段集合
lane_set = []
for walk_time in session_postgre.query(WalkTime).all():
for lane in walk_time.to_load_lanes:
lane_set.append(lane)
for lane in walk_time.to_unload_lanes:
lane_set.append(lane)
for walk_time_park in session_postgre.query(WalkTimePark).all():
for lane in walk_time_park.park_load_lanes:
lane_set.append(lane)
lane_set = set(lane_set)
except Exception as es:
self.logger.error('所用路网路段集合读取异常')
self.logger.info(es)
# lane -> speed, 各路段平均行驶速度
self.lane_speed_dict = {}
# lane -> num, 各路段行驶车辆
lane_trucks_dict = {}
# used lane, 存在行驶矿卡的路段
tmp_lane_set = []
try:
# 初始化
for lane_id in lane_set:
self.lane_speed_dict[str(lane_id)] = 0
lane_trucks_dict[str(lane_id)] = 0
# 对于各路段信息
print("truck_locate_dict")
print(truck_locate_dict.keys())
for truck in truck_locate_dict.keys():
lane_id = truck_locate_dict[truck]
self.logger.info("lane_speed_generate-lane_id")
self.logger.info(lane_id)
if lane_id in lane_set:
self.lane_speed_dict[truck_locate_dict[truck]] = self.lane_speed_dict[truck_locate_dict[truck]] + \
truck_speed_dict[truck]
# 该路段矿卡数量加一
lane_trucks_dict[truck_locate_dict[truck]] = lane_trucks_dict[truck_locate_dict[truck]] + 1
# 记录存在行驶矿卡的路段
tmp_lane_set.append(lane_id)
# 存在矿卡的路段
print("存在矿卡的路段:")
print(tmp_lane_set)
self.logger.info("存在矿卡的路段:")
self.logger.info(tmp_lane_set)
# 对不存在的矿卡路段,实时速度设置为最高
for lane_id in lane_set:
if lane_id not in tmp_lane_set:
self.lane_speed_dict[str(lane_id)] = session_postgre.query(Lane).filter_by(
Id=lane_id).first().MaxSpeed
lane_trucks_dict[str(lane_id)] = 1
# 各路段实时速度取平均
for lane in lane_trucks_dict:
self.lane_speed_dict[lane] = self.lane_speed_dict[lane] / lane_trucks_dict[lane]
except Exception as es:
self.logger.error("路段实时速度计算异常")
self.logger.error(es)
return self.lane_speed_dict
# path_planner = PathPlanner()
#
# path_planner.walk_cost()
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2021/9/3 14:44
# @Author : Opfer
# @Site :
# @File : priority_control.py
# @Software: PyCharm
from equipment.truck import *
from equipment.dump import *
from equipment.excavator import *
from para_config import *
from path_plan.topo_graph import *
class PriorityController():
def __init__(self, dump, excavator, truck):
# 设备类
self.dump = dump
self.excavator = excavator
self.truck = truck
# 获取日志器
self.logger = get_logger("zxt.prio")
def weighted_walk_calc(self):
"""
计算运输路线权重, 权重影响因素:设备优先级, 物料优先级,
:return:
walk_weight: 卸载-装载区 路网权重
park_walk_weight: 备停区-装载区 路网权重
"""
dynamic_dump_num = get_value("dynamic_dump_num")
dynamic_excavator_num = get_value("dynamic_excavator_num")
dynamic_dump_set = get_value("dynamic_dump_set")
dynamic_excavator_set = get_value("dynamic_excavator_set")
walk_to_excavator_weight = np.ones((dynamic_dump_num, dynamic_excavator_num))
walk_to_dump_weight = np.ones((dynamic_excavator_num, dynamic_dump_num))
excavator_priority = self.excavator.excavator_priority_coefficient
excavator_material_priority = self.excavator.excavator_material_priority
dump_priority = self.dump.dump_priority_coefficient
dump_material_priority = np.ones(dynamic_dump_num)
park_walk_weight = np.ones((park_num, dynamic_excavator_num))
rule6 = session_mysql.query(DispatchRule).filter_by(id=6).first()
if not rule6.disabled:
for dump_id in dynamic_dump_set:
for excavator_id in dynamic_excavator_set:
dump_index = self.dump.dump_uuid_to_index_dict[dump_id]
excavator_inedx = self.excavator.excavator_uuid_to_index_dict[excavator_id]
walk_to_excavator_weight[dump_index][excavator_inedx] += excavator_priority[excavator_inedx]
walk_to_dump_weight[excavator_inedx][dump_index] += dump_priority[dump_index]
park_walk_weight = park_walk_weight * self.excavator.excavator_priority_coefficient
rule7 = session_mysql.query(DispatchRule).filter_by(id=7).first()
if not rule7.disabled:
for dump_id in dynamic_dump_set:
for excavator_id in dynamic_excavator_set:
dump_index = self.dump.dump_uuid_to_index_dict[dump_id]
excavator_inedx = self.excavator.excavator_uuid_to_index_dict[excavator_id]
walk_to_excavator_weight[dump_index][excavator_inedx] += excavator_material_priority[excavator_inedx]
walk_to_dump_weight[excavator_inedx][dump_index] += dump_material_priority[dump_index]
park_walk_weight = park_walk_weight * self.excavator.excavator_material_priority
try:
walk_to_excavator_weight = walk_to_excavator_weight - (walk_to_excavator_weight.min() - 1)
walk_to_dump_weight = walk_to_dump_weight - (walk_to_dump_weight.min() - 1)
park_walk_weight = park_walk_weight - (park_walk_weight.min() - 1)
except Exception as es:
self.logger.errro(es)
self.logger.error("优先级归一化异常")
return walk_to_excavator_weight, walk_to_dump_weight, park_walk_weight
def walk_available_calc(self):
"""
计算路网可通行性(物料, 地图, 分组三者综合)
:return:
walk_available: 路网可通行性(dump_num, excavator_num)
"""
map_walk_available = self.update_map_walk_available()
group_walk_available = self.update_group_walk_available()
material_walk_available = self.update_material_walk_available()
walk_available = map_walk_available * group_walk_available * material_walk_available
return walk_available
def update_group_walk_available(self):
"""
计算调度分组间的路网可通行性, 不同分组间路网不可通行
:return:
group_walk_available: 调度分组路网可通行性矩阵(dump_num, excavator_num)
"""
group_walk_available = np.zeros((get_value("dynamic_dump_num"), get_value("dynamic_excavator_num")))
for dump_id in get_value("dynamic_dump_set"):
for excavator_id in get_value("dynamic_excavator_set"):
item = session_mysql.query(Dispatch).filter_by(dump_id=dump_id, exactor_id=excavator_id, isauto=1,
isdeleted=0).first()
if item is not None:
dump_index = self.dump.dump_uuid_to_index_dict[dump_id]
excavator_index = self.excavator.excavator_uuid_to_index_dict[excavator_id]
group_walk_available[dump_index][excavator_index] = 1
return group_walk_available
def update_material_walk_available(self):
"""
更新物料兼容性下路网可通行性
:return:
walk_available: 物料兼容路网可通行性矩阵(dump_num, excavator_num)
"""
dynamic_dump_num = get_value("dynamic_dump_num")
dynamic_excavator_num = get_value("dynamic_excavator_num")
dynamic_dump_set = get_value("dynamic_dump_set")
dynamic_excavator_set = get_value("dynamic_excavator_set")
walk_available = np.ones((dynamic_dump_num, dynamic_excavator_num))
try:
for dump_id in dynamic_dump_set:
for excavator_id in dynamic_excavator_set:
dump_index = self.dump.dump_uuid_to_index_dict[dump_id]
excavator_inedx = self.excavator.excavator_uuid_to_index_dict[excavator_id]
# 两设备处理物料不同, 相关路网不可通行
if self.excavator.excavator_material[excavator_id] != self.dump.dump_material[dump_id]:
walk_available[dump_index][excavator_inedx] = 0
except Exception as es:
self.logger.info(es)
self.logger.info("error-12")
return walk_available
def update_map_walk_available(self):
"""
更新物理路网可通行性
:return:
walk_available: 物理路网可通行性矩阵(dump_num, excavator_num)
"""
dynamic_dump_num = get_value("dynamic_dump_num")
dynamic_excavator_num = get_value("dynamic_excavator_num")
walk_available = np.ones((dynamic_dump_num, dynamic_excavator_num))
walk_manage.period_walk_para_update()
for dump_index in range(dynamic_dump_num):
for excavator_index in range(dynamic_excavator_num):
if walk_manage.distance_to_excavator[dump_index][excavator_index] > M / 2:
walk_available[dump_index][excavator_index] = 0
return walk_available
from topo_graph import *
import networkx as nx
import matplotlib.pyplot as plt
#
# topo = Topo()
# topo.generate_topo_graph()
# load_G = topo.get_load_G()
# pos = nx.shell_layout(load_G)
# nx.draw(load_G, pos, with_labels=True, node_color='red', edge_color='blue', font_size=18, width=5, node_size=600,
# alpha=0.5)
# plt.show()
# from para_config import *
from settings import *
import numpy as np
import sched
import time
import matplotlib.pyplot as plt
# from path_plan.path_plannner import *
import networkx as nx
class Topo():
""" class for the topo.
Description:
根据设备状态计算调度价值
Attribute:
equipment class: None
"""
def __init__(self):
# to unload graph
self.unload_G = nx.Graph()
self.unload_G_nodes = np.array(self.unload_G)
self.unload_G_num_of_nodes = self.unload_G.number_of_nodes()
self.unload_G_edges = np.array(self.unload_G)
self.unload_G_num_of_edges = self.unload_G.number_of_edges()
self.unload_G_all_nodes = []
self.unload_G_digging_nodes = []
self.unload_G_dump_nodes = []
# self.unload_path_dict = {}
# to load graph
self.load_G = nx.Graph()
self.load_G_nodes = np.array(self.load_G)
self.load_G_num_of_nodes = self.load_G.number_of_nodes()
self.load_G_edges = np.array(self.load_G)
self.load_G_num_of_edges = self.load_G.number_of_edges()
self.load_G_all_nodes = []
self.load_G_digging_nodes = []
self.load_G_dump_nodes = []
# self.load_path_dict = {}
self.work_area_distance_info = []
# self.laneinfo = LaneInfo()
# 获取日志器
self.logger = get_logger("zxt.topo")
"""
unload_G funcions
"""
def get_unload_G(self):
return self.unload_G
def get_unload_G_nodes(self):
return self.unload_G_nodes
def get_unload_G_num_of_nodes(self):
return self.unload_G_num_of_nodes
def get_unload_G_edges(self):
return self.unload_G_edges
def get_unload_G_num_of_edges(self):
return self.unload_G_num_of_edges
"""
load_G functions
"""
def get_load_G(self):
return self.load_G
def get_load_G_nodes(self):
return self.load_G_nodes
def get_load_G_num_of_nodes(self):
return self.load_G_num_of_nodes
def get_load_G_edges(self):
return self.load_G_edges
def get_load_G_num_of_edges(self):
return self.load_G_num_of_edges
def get_work_area_distance_info(self):
try:
for item in session_postgre.query(WalkTime).all():
self.work_area_distance_info.append([[str(item.load_area_id), str(item.unload_area_id)], item.to_unload_lanes, item.to_load_lanes])
except Exception as es:
self.logger.error(es)
self.logger.error("获取地图信息出错")
"""
generate_topo_graph: unload_G and load_G
"""
def generate_topo_graph(self):
self.get_work_area_distance_info()
trip = self.work_area_distance_info
for item in trip:
# path_node_for_trip= []
# unload_G
Exitnode_for_digging = str(session_postgre.query(DiggingWorkArea).filter_by(Id =item[0][0]).first().ExitNodeId)
Entrancenode_for_dump = str(session_postgre.query(DumpArea).filter_by(Id=item[0][1]).first().EntranceNodeId)
# path_node_for_trip.append(Exitnode_for_digging) # add start node for trip
# find the exitnodeid for diggingarea, find the entrancenodeid for dumparea
if Exitnode_for_digging not in self.unload_G_all_nodes:
self.unload_G_all_nodes.append(Exitnode_for_digging)
self.unload_G_digging_nodes.append(Exitnode_for_digging)
if Entrancenode_for_dump not in self.unload_G_all_nodes:
self.unload_G_all_nodes.append(Entrancenode_for_dump)
self.unload_G_dump_nodes.append(Entrancenode_for_dump)
self.unload_G.add_node(Exitnode_for_digging, name='digging')
self.unload_G.add_node(Entrancenode_for_dump, name='dump')
try:
unload_saved_lane = []
for i in item[1]:
i_startpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().StartNodeId)
i_endpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().EndNodeId)
unload_saved_lane.append([str(i_startpoint), str(i_endpoint), 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 = len(session_postgre.query(Lane).filter_by(StartNodeId=i_endpoint).all())
# 可以添加的节点:分叉口或终点
if son_lane_num > 1 or i_endpoint in self.unload_G_dump_nodes:
# print("item",item[0])
# print(unload_saved_lane)
# print("\n")
lanes = {}
for lane_info in unload_saved_lane:
lanes[lane_info[-1]] = list([lane_info[2],lane_info[2]])
self.unload_G.add_edge(unload_saved_lane[0][0], unload_saved_lane[-1][1], real_distance = sum(value[0] for value in lanes.values()),
locked_distance = sum(value[1] for value in lanes.values()),lane = lanes)
self.unload_G.add_node(unload_saved_lane[0][0])
self.unload_G.add_node(unload_saved_lane[-1][1])
# self.unload_G_land_edges_map[lanes] = [unload_saved_lane[0][0], unload_saved_lane[-1][1]]
# if [unload_saved_lane[0][0], unload_saved_lane[-1][1]] not in self.unload_G_edges:
# self.unload_G_edges.append([unload_saved_lane[0][0], unload_saved_lane[-1][1]])
unload_saved_lane = []
if i_startpoint not in self.unload_G_all_nodes:
self.unload_G_all_nodes.append(i_startpoint)
if i_endpoint not in self.unload_G_all_nodes:
self.unload_G_all_nodes.append(i_endpoint)
except Exception as es:
self.logger.error(es)
self.logger.error("去卸载区拓扑图出错")
# path_node_for_trip.append(Exitnode_for_digging) # add node for trip
# if i_endpoint in self.unload_G_dump_nodes:
# load_G
Entrancenode_for_digging = str(session_postgre.query(DiggingWorkArea).filter_by(Id =item[0][0]).first().EntranceNodeId)
Exitnode_for_dump = str(session_postgre.query(DumpArea).filter_by(Id=item[0][1]).first().ExitNodeId)
# find the exitnodeid for dumparea, entrancenodeid for diggingarea,
if Exitnode_for_dump not in self.load_G_all_nodes:
self.load_G_all_nodes.append(Exitnode_for_dump)
self.load_G_dump_nodes.append(Exitnode_for_dump)
if Entrancenode_for_digging not in self.load_G_all_nodes:
self.load_G_all_nodes.append(Entrancenode_for_digging)
self.load_G_digging_nodes.append(Entrancenode_for_digging)
self.load_G.add_node(Exitnode_for_dump, name='dump')
self.load_G.add_node(Entrancenode_for_digging, name='digging')
try:
load_saved_lane = []
# 处理特殊点:备停区出场点
lane_p = ["7b9c8e89-7134-63ac-9c44-f183674b090c", "7e120229-b426-461b-91a4-05e01fb37ed8"]
lane_park_dict = {}
lane_parks= []
for i in lane_p:
i_startpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().StartNodeId)
i_endpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().EndNodeId)
lane_parks.append([str(i_startpoint), str(i_endpoint),
float(session_postgre.query(Lane).filter_by(Id=i).first().Length), i])
for l in lane_parks:
lane_park_dict[l[-1]] = list([l[2], l[2]])
self.load_G.add_edge(lane_parks[0][0], lane_parks[-1][1],
real_distance=sum(value[0] for value in lane_park_dict.values()),
locked_distance=sum(value[-1] for value in lane_park_dict.values()), lane=lane_park_dict)
self.load_G.add_node(lane_parks[0][0])
self.load_G.add_node(lane_parks[-1][1])
# lane_park = session_postgre.query(Lane).filter_by(Id="7b9c8e89-7134-63ac-9c44-f183674b090c").first()
# lane_park_startnode = str(lane_park.StartNodeId)
# lane_park_endnode = str(lane_park.EndNodeId)
# lane_park_length = lane_park.Length
# self.load_G.add_edge("d346992e-d134-63ac-9b08-76812d6e3b1d", "1c85bc2c-9134-6281-1265-fd19d0dcbd52",
# real_distance=lane_park_length,
# locked_distance=lane_park_length, lane={"7b9c8e89-7134-63ac-9c44-f183674b090c": [lane_park_length,lane_park_length]})
# self.load_G.add_node("d346992e-d134-63ac-9b08-76812d6e3b1d")
# self.load_G.add_node("1c85bc2c-9134-6281-1265-fd19d0dcbd52")
for i in item[2]:
i_startpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().StartNodeId)
i_endpoint = str(session_postgre.query(Lane).filter_by(Id=i).first().EndNodeId)
load_saved_lane.append([str(i_startpoint), str(i_endpoint), 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 = len(session_postgre.query(Lane).filter_by(StartNodeId=i_endpoint).all())
# 可以添加的节点:分叉口或终点
if son_lane_num > 1 or i_endpoint in self.load_G_digging_nodes:
# print("item",item[0])
# print(load_saved_lane)
# print("\n")
lanes = {}
for lane_info in load_saved_lane:
lanes[lane_info[-1]] = list([lane_info[2],lane_info[2]])
# lanes.append(i[0])
# lanes.append(i[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(value[0] for value in lanes.values()), locked_distance = sum(value[-1] for value in lanes.values()), lane=lanes)
self.load_G.add_node(load_saved_lane[0][0])
self.load_G.add_node(load_saved_lane[-1][1])
# self.load_G_land_edges_map[lanes] = [load_saved_lane[0][0], load_saved_lane[-1][1]]
# if [load_saved_lane[0][0], load_saved_lane[-1][1]] not in self.load_G_edges:
# self.load_G_edges.append([load_saved_lane[0][0], load_saved_lane[-1][1]])
load_saved_lane = []
if i_startpoint not in self.load_G_all_nodes:
self.load_G_all_nodes.append(i_startpoint)
if i_endpoint not in self.load_G_all_nodes:
self.load_G_all_nodes.append(i_endpoint)
except Exception as es:
self.logger.error(es)
self.logger.error("去装载区拓扑图生成失败")
# """
# update blocked distance for graph
# """
# def update_blocked_distance(self):
#
def return_node_path(self, source_node, target_node):
try:
distance, path = nx.single_source_dijkstra(self.unload_G, source=source_node, target=target_node, weight="real_distance")
except Exception as es:
self.logger.error(es)
self.logger.error("dijkstra最短路径生成失败")
return list(path)
"""
unload source node for reschedule
"""
def get_unload_source_node(self, truck_location_lane):
try:
# truck_location_lane = self.laneinfo.update_truck_loacate()[truck_id]
for (startnode,endnode,lane) in self.unload_G.edges.data('lane'):
if truck_location_lane in lane:
return startnode
except Exception as es:
self.logger.error(es)
self.logger.error("卸载图,矿卡所在路段返回失败")
"""
unload_G target
"""
def get_unload_target_node_real(self, truck_location_lane,pre_target):
source_node = self.get_unload_source_node(truck_location_lane)
target_list = []
for (u, wt) in self.unload_G.nodes.data('name'):
# select next reachable target
if wt == 'dump' and u != pre_target :
target_list.append(u)
if not len(target_list):
self.logger.error("当前无可去卸载区!")
path_length_map = {}
# build the path_length_map from source node
for i in target_list:
try:
distance, path = nx.single_source_dijkstra(self.unload_G, source=source_node, target=i, weight="real_distance")
path_length_map[distance] = path
# print(path)
except Exception as es:
self.logger.info(es)
self.logger.info(f"卸载图中{source_node} 与 {i} 之间道路不通")
# return the target area's entrance point and target area
min_dis_path = path_length_map[sorted(list(path_length_map.keys()))[0]]
entrance_point = min_dis_path[-1]
target_dump_area = str(session_postgre.query(DumpArea).filter_by(EntranceNodeId=entrance_point).first().Id)
# target_dump_area_name = str(session_postgre.query(DumpArea).filter_by(EntranceNodeId=entrance_point).first().Name)
return min_dis_path, entrance_point, target_dump_area
"""
load source node for reschedule
"""
def get_load_source_node (self, truck_location_lane):
try:
# truck_location_lane = self.laneinfo.update_truck_loacate()[truck_id]
for (startnode,endnode,lane) in self.load_G.edges.data('lane'):
if truck_location_lane in lane:
return startnode
except Exception as es:
self.logger.error(es)
self.logger.error("装载图,矿卡所在路段返回失败")
"""
load_G target
"""
def get_load_target_node_real(self, truck_location_lane,pre_target ):
source_node = self.get_load_source_node(truck_location_lane)
target_list = []
for (node, wt) in self.load_G.nodes.data('name'):
# select next reachable target
if wt == 'digging' and node != pre_target :
target_list.append(node)
if not len(target_list):
self.logger.error("当前无可去装载区!")
# print(target_list)
path_length_map = {}
# build the path_length_map from source node
for i in target_list:
try:
distance, path = nx.single_source_dijkstra(self.load_G, source=source_node, target= i, weight="real_distance")
path_length_map[distance] = path
# print(path)
except Exception as es:
self.logger.info(es)
self.logger.info(f"装载图中{source_node} 与 {i} 之间道路不通")
# return the target area's entrance point and target area
min_dis_path = path_length_map[sorted(list(path_length_map.keys()))[0]]
entrance_point = min_dis_path[-1]
target_digging_area = str(session_postgre.query(DiggingWorkArea).filter_by(EntranceNodeId=entrance_point).first().Id)
# target_digging_area_name = str(session_postgre.query(DiggingWorkArea).filter_by(EntranceNodeId=entrance_point).first().Name)
return min_dis_path, entrance_point, target_digging_area
"""
update load_G locked_distance
"""
def update_load_G_locked_distance(self, path, alpha, beta):
for i in range(len(path) - 1):
data = dict(self.load_G[path[i]][path[i + 1]]['lane'])
for u, v in data.items():
data[u] = [v[0], v[0]]
self.load_G[path[i]][path[i + 1]]['locked_distance'] = sum(i[-1] for i in list(data.values()))
# """
# update unload_G locked_distance
# """
# def update_unload_G_locked_distance(self, path):
# for i in range(len(path) - 1):
# data = dict(self.unload_G[path[i]][path[i + 1]]['lane'])
# for u, v in data.items():
# data[u] = [v[0], v[0]]
# self.unload_G[path[i]][path[i + 1]]['locked_distance'] = sum(i[-1] for i in list(data.values()))
......@@ -47,6 +47,9 @@ dump_target_mass = para_config["dump_target_mass"]
# 挖机目标装载量
excavator_target_mass = para_config["excavator_target_mass"]
logger = logging.getLogger("zxt")
logger.setLevel(logging.INFO)
def set_log():
......@@ -62,9 +65,6 @@ def set_log():
# logging初始化工作
logging.basicConfig()
logger = logging.getLogger("zxt")
logger.setLevel(logging.INFO)
# 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)
......
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