Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
I
integrated-scheduling-v3
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张晓彤
integrated-scheduling-v3
Commits
c4e5134f
Commit
c4e5134f
authored
Nov 08, 2022
by
张晓彤
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
代码优化v3
parent
8edf3046
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
336 additions
and
194 deletions
+336
-194
algorithm.py
alg/algorithm.py
+5
-2
app.py
app.py
+25
-1
__init__.py
core/__init__.py
+8
-0
group.py
core/group.py
+258
-190
submit.py
core/submit.py
+3
-0
realtime_dispatch.py
realtime_dispatch.py
+37
-1
No files found.
alg/algorithm.py
View file @
c4e5134f
...
@@ -223,7 +223,7 @@ class ExpectedTime(AlgorithmBase):
...
@@ -223,7 +223,7 @@ class ExpectedTime(AlgorithmBase):
self
.
logger
.
error
(
es
)
self
.
logger
.
error
(
es
)
transport_value
=
np
.
zeros
(
group_dynamic_excavator_num
)
transport_value
=
np
.
zeros
(
group_dynamic_excavator_num
)
if
task
in
[
1
,
2
]:
if
task
in
[
0
,
1
,
2
]:
################################################ 矿卡空载 ###############################################
################################################ 矿卡空载 ###############################################
# try:
# try:
...
@@ -290,7 +290,7 @@ class ExpectedTime(AlgorithmBase):
...
@@ -290,7 +290,7 @@ class ExpectedTime(AlgorithmBase):
self
.
logger
.
error
(
es
)
self
.
logger
.
error
(
es
)
transport_value
=
np
.
zeros
(
group_dynamic_unload_area_num
)
transport_value
=
np
.
zeros
(
group_dynamic_unload_area_num
)
elif
task
in
[
4
,
5
]:
elif
task
in
[
3
,
4
,
5
]:
################################################ 矿卡重载 ###############################################
################################################ 矿卡重载 ###############################################
# try:
# try:
...
@@ -369,6 +369,9 @@ class DistributionRatio(object):
...
@@ -369,6 +369,9 @@ class DistributionRatio(object):
@desc:计算分流配比模式下,卡车与卸载区的对应关系
@desc:计算分流配比模式下,卡车与卸载区的对应关系
"""
"""
# TODO:
# 统一与预期等待时间的接口
def
__init__
(
self
,
exactor_id
,
truck
):
def
__init__
(
self
,
exactor_id
,
truck
):
self
.
truck
=
truck
self
.
truck
=
truck
self
.
exactor_id
=
exactor_id
self
.
exactor_id
=
exactor_id
...
...
app.py
View file @
c4e5134f
...
@@ -10,6 +10,8 @@ from flask_caching import Cache
...
@@ -10,6 +10,8 @@ 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.submit
import
DispatchSubmission
from
core.submit
import
DispatchSubmission
from
core.group
import
GroupDispatcher
from
realtime_dispatch
import
group_direct2redis
config
=
{
config
=
{
"DEBUG"
:
True
,
# some Flask specific configs
"DEBUG"
:
True
,
# some Flask specific configs
...
@@ -140,9 +142,29 @@ def dispatch_request():
...
@@ -140,9 +142,29 @@ def dispatch_request():
try
:
try
:
# # 调度分组派车计划计算
# try:
# truck_dispatch_plan_dict = group.group_dispatch(ExpectedTime)
# except Exception as es:
# logger.error(es)
# logger.error(f'分组{group.group_id} 调度计算异常')
#
# try:
#
# logger.info(f'调度分组: {group.group_id} {DispatchInfo.group_name[group.group_id]}')
# submission.group_dispatch_to_redis(group, truck_dispatch_plan_dict)
# except Exception as es:
# logger.error(es)
# logger.error(f'分组{group.group_id} 调度写入异常')
# 调度分组派车计划计算
# 调度分组派车计划计算
try
:
try
:
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
:
logger
.
error
(
f
'分组 {group.group_id} 调度异常'
)
except
Exception
as
es
:
except
Exception
as
es
:
logger
.
error
(
es
)
logger
.
error
(
es
)
logger
.
error
(
f
'分组{group.group_id} 调度计算异常'
)
logger
.
error
(
f
'分组{group.group_id} 调度计算异常'
)
...
@@ -152,9 +174,11 @@ def dispatch_request():
...
@@ -152,9 +174,11 @@ def dispatch_request():
logger
.
info
(
f
'调度分组: {group.group_id} {DispatchInfo.group_name[group.group_id]}'
)
logger
.
info
(
f
'调度分组: {group.group_id} {DispatchInfo.group_name[group.group_id]}'
)
submission
.
group_dispatch_to_redis
(
group
,
truck_dispatch_plan_dict
)
submission
.
group_dispatch_to_redis
(
group
,
truck_dispatch_plan_dict
)
except
Exception
as
es
:
except
Exception
as
es
:
group_direct2redis
(
group
)
logger
.
error
(
es
)
logger
.
error
(
es
)
logger
.
error
(
f
'分组{group.group_id} 调度写入异常'
)
logger
.
error
(
f
'分组{group.group_id} 调度写入异常'
)
except
Exception
as
es
:
except
Exception
as
es
:
logger
.
error
(
"最外层异常捕获"
)
logger
.
error
(
"最外层异常捕获"
)
logger
.
error
(
es
)
logger
.
error
(
es
)
...
...
core/__init__.py
0 → 100644
View file @
c4e5134f
#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2022/10/29 22:07
# @Author : Opfer
# @Site :
# @File : __init__.py
# @Software: PyCharm
\ No newline at end of file
core/group.py
View file @
c4e5134f
...
@@ -131,12 +131,12 @@ class Group:
...
@@ -131,12 +131,12 @@ class Group:
update group devices.
update group devices.
:return:
:return:
"""
"""
# update group devices
# init group devices
# DispatchInfo.update_device_group_structure()
self
.
group_excavators
=
{}
self
.
group_excavators
=
{}
self
.
group_unload_areas
=
{}
self
.
group_unload_areas
=
{}
self
.
group_dumps
=
{}
self
.
group_dumps
=
{}
self
.
group_trucks
=
set
()
self
.
group_trucks
=
set
()
# update group devices
self
.
group_excavators
=
DispatchInfo
.
get_excavator
(
self
.
group_id
)
self
.
group_excavators
=
DispatchInfo
.
get_excavator
(
self
.
group_id
)
self
.
group_unload_areas
=
DispatchInfo
.
get_unload_area
(
self
.
group_id
)
self
.
group_unload_areas
=
DispatchInfo
.
get_unload_area
(
self
.
group_id
)
self
.
group_dumps
=
DispatchInfo
.
get_dump
(
self
.
group_id
)
self
.
group_dumps
=
DispatchInfo
.
get_dump
(
self
.
group_id
)
...
@@ -147,10 +147,11 @@ class Group:
...
@@ -147,10 +147,11 @@ class Group:
update group road network.
update group road network.
:return:
:return:
"""
"""
#
DispatchInfo.update_route_distance()
#
init group road network
self
.
to_excavator_distance
=
None
self
.
to_excavator_distance
=
None
self
.
to_unload_area_distance
=
None
self
.
to_unload_area_distance
=
None
self
.
park_to_excavator_distance
=
None
self
.
park_to_excavator_distance
=
None
# update group road network
self
.
to_excavator_distance
=
DispatchInfo
.
get_to_excavator_distance
(
self
.
group_id
)
self
.
to_excavator_distance
=
DispatchInfo
.
get_to_excavator_distance
(
self
.
group_id
)
self
.
to_unload_area_distance
=
DispatchInfo
.
get_to_unload_area_distance
(
self
.
group_id
)
self
.
to_unload_area_distance
=
DispatchInfo
.
get_to_unload_area_distance
(
self
.
group_id
)
self
.
park_to_excavator_distance
=
DispatchInfo
.
get_park_to_excavator_distance
(
self
.
group_id
)
self
.
park_to_excavator_distance
=
DispatchInfo
.
get_park_to_excavator_distance
(
self
.
group_id
)
...
@@ -160,11 +161,9 @@ class Group:
...
@@ -160,11 +161,9 @@ class Group:
update group device map.
update group device map.
:return:
:return:
"""
"""
# excavator_index = 0
# update devices(excavators, unload_areas, dumps) bidirectional map within a group
self
.
excavator_uuid_index_dict
=
DispatchInfo
.
get_group_excavator_dict
(
self
.
group_id
)
self
.
excavator_uuid_index_dict
=
DispatchInfo
.
get_group_excavator_dict
(
self
.
group_id
)
self
.
unload_area_uuid_index_dict
=
DispatchInfo
.
get_group_unload_area_dict
(
self
.
group_id
)
self
.
unload_area_uuid_index_dict
=
DispatchInfo
.
get_group_unload_area_dict
(
self
.
group_id
)
# self.truck_uuid_index_dict = DispatchInfo.get_group_truck_dict(self.group_id)
self
.
dump_uuid_index_dict
=
DispatchInfo
.
get_group_dump_dict
(
self
.
group_id
)
self
.
dump_uuid_index_dict
=
DispatchInfo
.
get_group_dump_dict
(
self
.
group_id
)
def
update_device_material
(
self
):
def
update_device_material
(
self
):
...
@@ -236,19 +235,31 @@ class Group:
...
@@ -236,19 +235,31 @@ class Group:
class
GroupDispatcher
:
class
GroupDispatcher
:
"""
Group controller responsible for group dispatching.
"""
def
__init__
(
self
,
group
:
Group
):
def
__init__
(
self
,
group
:
Group
):
"""
Receive a group obj.
:param group:
"""
self
.
logger
=
logging
.
getLogger
(
"zxt.GroupDispatcher"
)
self
.
logger
=
logging
.
getLogger
(
"zxt.GroupDispatcher"
)
self
.
group
=
group
self
.
group
=
group
self
.
redispatcher
=
ReDispatcher
(
self
.
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
all trucks with
in this group.
:param Solver:
:param Solver:
:return:
:return:
dispatch plan: Dict({truck_id: match_id})
dispatch plan: Dict({truck_id: match_id})
"""
"""
# init truck dispatch plan dictionary.
truck_dispatch
=
{}
truck_dispatch
=
{}
# init dictionary including all truck obj. within this group.
self
.
group
.
truck_info_list
=
{}
self
.
group
.
truck_info_list
=
{}
assert
issubclass
(
Solver
,
AlgorithmBase
)
assert
issubclass
(
Solver
,
AlgorithmBase
)
...
@@ -262,44 +273,31 @@ class GroupDispatcher:
...
@@ -262,44 +273,31 @@ class GroupDispatcher:
# try:
# try:
# get truck index from mapping
# get truck index from mapping
try
:
if
truck_id
not
in
self
.
group
.
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}'
)
self
.
logger
.
error
(
f
'truck.truck dict 中不存在 {truck_id}'
)
truck_idx
=
self
.
group
.
truck
.
truck_uuid_to_index_dict
[
truck_id
]
except
CoreException
as
es
:
es
.
with_traceback_info
()
self
.
logger
.
error
(
es
)
continue
continue
else
:
truck_idx
=
self
.
group
.
truck
.
truck_uuid_to_index_dict
[
truck_id
]
# get truck trip from truck obj.
# get truck trip from truck obj.
try
:
truck_trip_info_list
=
self
.
group
.
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}'
)
self
.
logger
.
error
(
f
'truck.truck trip 中不存在 {truck_idx} 号矿卡 {truck_id}'
)
truck_trip
=
self
.
group
.
truck
.
get_truck_current_trip
()[
truck_idx
]
except
CoreException
as
es
:
es
.
with_traceback_info
()
self
.
logger
.
error
(
es
)
continue
continue
else
:
truck_trip
=
self
.
group
.
truck
.
get_truck_current_trip
()[
truck_idx
]
# get truck task from truck obj.
# get truck task from truck obj.
try
:
truck_task_list
=
self
.
group
.
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}'
)
self
.
logger
.
error
(
f
'truck.truck task 中不存在矿卡 {truck_id}'
)
truck_task
=
truck_task_list
[
truck_id
]
except
CoreException
as
es
:
es
.
with_traceback_info
()
self
.
logger
.
error
(
es
)
continue
continue
else
:
truck_task
=
truck_task_list
[
truck_id
]
# Construct a truck obj.
# Construct a truck obj.
and add it to group truck dictionary.
truck_info
=
CurrentTruck
(
truck_id
,
self
.
group
.
group_id
,
truck_trip
,
truck_task
,
truck_info
=
CurrentTruck
(
truck_id
,
self
.
group
.
group_id
,
truck_trip
,
truck_task
,
self
.
group
.
truck
.
get_truck_current_state
()[
truck_id
])
self
.
group
.
truck
.
get_truck_current_state
()[
truck_id
])
...
@@ -320,7 +318,7 @@ class GroupDispatcher:
...
@@ -320,7 +318,7 @@ class GroupDispatcher:
# 全智能模式
# 全智能模式
if
self
.
group
.
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
WW
_mode
(
truck_id
,
solver
,
truck_dispatch
,
truck_info
,
truck_task
,
truck_trip
)
# 空车智能模式
# 空车智能模式
elif
self
.
group
.
group_mode
==
2
:
elif
self
.
group
.
group_mode
==
2
:
...
@@ -341,6 +339,7 @@ class GroupDispatcher:
...
@@ -341,6 +339,7 @@ class GroupDispatcher:
self
.
ratio_mode
(
truck_id
,
truck_dispatch
,
truck_task
)
self
.
ratio_mode
(
truck_id
,
truck_dispatch
,
truck_task
)
except
Exception
as
es
:
except
Exception
as
es
:
self
.
logger
.
error
(
"调度调用异常"
)
self
.
logger
.
error
(
es
)
self
.
logger
.
error
(
es
)
# return dispatch plan
# return dispatch plan
...
@@ -356,7 +355,6 @@ class GroupDispatcher:
...
@@ -356,7 +355,6 @@ class GroupDispatcher:
next_unload_area_id
=
"Park"
next_unload_area_id
=
"Park"
# 空载模式下,计算下一次卸载区的位置,按照分流配比的模式进行计算
# 空载模式下,计算下一次卸载区的位置,按照分流配比的模式进行计算
elif
truck_task
in
[
0
,
1
,
2
]:
elif
truck_task
in
[
0
,
1
,
2
]:
try
:
try
:
...
@@ -375,7 +373,6 @@ class GroupDispatcher:
...
@@ -375,7 +373,6 @@ class GroupDispatcher:
self
.
logger
.
error
(
es
)
self
.
logger
.
error
(
es
)
# 重载模式下,按照固定派车进行计算
# 重载模式下,按照固定派车进行计算
elif
truck_task
in
[
3
,
4
,
5
]:
elif
truck_task
in
[
3
,
4
,
5
]:
try
:
try
:
...
@@ -390,6 +387,10 @@ class GroupDispatcher:
...
@@ -390,6 +387,10 @@ class GroupDispatcher:
truck_dispatch
[
i
]
=
[
next_exactor_id
,
next_unload_area_id
]
truck_dispatch
[
i
]
=
[
next_exactor_id
,
next_unload_area_id
]
def
semi_dynamic_mode
(
self
,
i
,
s
,
truck_dispatch
,
truck_info
,
truck_task
,
truck_trip
):
def
semi_dynamic_mode
(
self
,
i
,
s
,
truck_dispatch
,
truck_info
,
truck_task
,
truck_trip
):
# TODO:
# 和全智能调度很像,是否可以合并合;
# 加入二次调度;
if
truck_task
in
[
-
2
,
3
,
4
,
5
]:
if
truck_task
in
[
-
2
,
3
,
4
,
5
]:
try
:
try
:
...
@@ -516,7 +517,8 @@ class GroupDispatcher:
...
@@ -516,7 +517,8 @@ class GroupDispatcher:
if
(
truck_locate
in
self
.
group
.
topo
.
cross_bf_lanes
)
and
(
self
.
group
.
truck
.
truck_current_state
[
i
]
==
2
):
if
(
truck_locate
in
self
.
group
.
topo
.
cross_bf_lanes
)
and
(
self
.
group
.
truck
.
truck_current_state
[
i
]
==
2
):
self
.
logger
.
info
(
"触发二次调度"
)
self
.
logger
.
info
(
"触发二次调度"
)
self
.
redispatch_to_excavator
(
i
,
truck_dispatch
,
truck_locate
)
# self.redispatch_to_excavator(i, truck_dispatch, truck_locate)
self
.
redispatcher
.
redispatch_to_excavator
(
i
,
truck_dispatch
,
truck_locate
)
elif
truck_task
==
3
:
elif
truck_task
==
3
:
try
:
try
:
...
@@ -537,71 +539,185 @@ class GroupDispatcher:
...
@@ -537,71 +539,185 @@ class GroupDispatcher:
if
(
truck_locate
in
self
.
group
.
topo
.
cross_bf_lanes
)
and
(
self
.
group
.
truck
.
truck_current_state
[
i
]
==
2
)
\
if
(
truck_locate
in
self
.
group
.
topo
.
cross_bf_lanes
)
and
(
self
.
group
.
truck
.
truck_current_state
[
i
]
==
2
)
\
and
(
not
truck_is_temp
):
and
(
not
truck_is_temp
):
self
.
redispatch_to_dump
(
i
,
truck_dispatch
,
truck_locate
,
truck_trip
)
# self.redispatch_to_dump(i, truck_dispatch, truck_locate, truck_trip)
self
.
redispatcher
.
redispatch_to_dump
(
i
,
truck_dispatch
,
truck_locate
,
truck_trip
)
# def redispatch_to_dump(self, truck_id: str, truck_dispatch: Mapping[str, List[str]], truck_locate: str, truck_trip: List[int]):
# """
# redispatch truck to dumps.
# :param truck_id:
# :param truck_dispatch:
# :param truck_locate:
# :param truck_trip:
# :return:
# """
# # 当前绑定装载区
# if truck_trip[0] == -1:
# next_excavator_id = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id,
# isdeleted=0).first().exactor_id
# else:
# next_excavator_id = get_value("excavator_index_to_uuid_dict")[truck_trip[0]]
# # 当前绑定卸载区
# if truck_trip[-1] == -1:
# item = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id, isdeleted=0).first()
# current_dump_id = item.dump_id
# current_unload_area_id = item.unload_area_id
# else:
# current_dump_id = get_value("dump_index_to_uuid_dict")[truck_trip[-1]]
# current_unload_area_id = DispatchInfo.dump_unload_area_dict[current_dump_id]
# unload_area_dict, unload_area_lane_dict = self.group.topo.get_unload_target_node_real(truck_locate,
# current_unload_area_id,
# True)
# # 获取拥堵路段
# congestion_lane_dict = self.get_congestion_lanes()
# # 获取当前交叉口下一路段集合
# next_lane_list = get_cross_next_lanes(truck_locate)
# # 交叉口下一路段可达的装载区
# next_lane_load_area_dict = get_lane_reach_load_areas(unload_area_lane_dict,
# next_lane_list)
# # 排除下一个路段阻塞的装载区
# delete_congestion_load_area(congestion_lane_dict, unload_area_dict,
# next_lane_load_area_dict)
# min_trip_time = 10000000
# best_dump_id = current_dump_id
# for unload_area, value in unload_area_dict.items():
# # 车辆不需要掉头
# if value[-1] == 1 and unload_area in DispatchInfo.unload_area_dump_dict:
# dump_id = DispatchInfo.unload_area_dump_dict[unload_area]
#
# traveling_time = value[0] / heavy_speed
#
# now = float(
# (datetime.now() - self.group.pre_sch.start_time) / timedelta(hours=0, minutes=1,
# seconds=0))
# reach_time = now + traveling_time
#
# trip_time = max(reach_time,
# self.group.pre_sch.get_dump_avl_time()[dump_id]) - now
#
# if min_trip_time > trip_time:
# best_dump_id = dump_id
# next_unload_area_id = DispatchInfo.dump_unload_area_dict[best_dump_id]
# truck_dispatch[truck_id] = [next_excavator_id, next_unload_area_id]
# # res = redispatch_request(truck_id, next_excavator_id, next_unload_area_id)
# # self.logger.info(res)
# self.logger.info(f'二次调度结果 {truck_id}')
# self.logger.info(truck_dispatch[truck_id])
#
# def redispatch_to_excavator(self, truck_id, truck_dispatch, truck_locate):
# """
# redispatch truck to excavators.
# :param truck_id:
# :param truck_dispatch:
# :param truck_locate:
# :return:
# """
# # 当前绑定卸载区
# # if truck_trip[0] == -1:
# next_unload_area_id = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id,
# isdeleted=0).first().unload_area_id
# # else:
# # dump_id = get_value("dump_index_to_uuid_dict")[truck_trip[0]]
# # next_unload_area_id = get_value("dump_uuid_to_unload_area_uuid_dict")[dump_id]
# # 当前绑定装载区
# # if truck_trip[-1] == -1:
# item = session_mysql.query(EquipmentPair).filter_by(truck_id=truck_id, isdeleted=0).first()
# current_excavator_id = item.exactor_id
# current_load_area_id = item.load_area_id
# self.logger.info(f'truck_id {truck_id}')
# self.logger.info(f'current_load_area_id {current_load_area_id}')
# # else:
# # current_excavator_id = get_value("excavator_index_to_uuid_dict")[truck_trip[-1]]
# # current_load_area_id = DispatchInfo.excavator_load_dict[current_excavator_id]
# load_area_dict, load_area_lane_dict = self.group.topo.get_load_target_node_real(truck_locate,
# current_load_area_id, True)
# self.logger.info("所有可达装载区")
# self.logger.info(load_area_dict)
# # 获取拥堵路段
# congestion_lane_dict = self.get_congestion_lanes()
# # 获取当前交叉口下一路段集合
# next_lane_list = get_cross_next_lanes(truck_locate)
# # 交叉口下一路段可达的装载区
# next_lane_load_area_dict = get_lane_reach_load_areas(load_area_lane_dict, next_lane_list)
# # 排除下一个路段阻塞的装载区
# delete_congestion_load_area(congestion_lane_dict, load_area_dict,
# next_lane_load_area_dict)
# self.logger.info("剔除堵塞装载区")
# self.logger.info(load_area_dict)
# # 获取最佳挖机
# best_excavator_id = self.get_best_excavator(current_excavator_id, truck_id, load_area_dict)
# next_excavator_id = best_excavator_id
# truck_dispatch[truck_id] = [next_excavator_id, next_unload_area_id]
# self.logger.info(f'二次调度结果 {truck_id}')
# self.logger.info(truck_dispatch[truck_id])
#
# def get_best_excavator(self, current_excavator_id, truck_id, load_area_dict):
# """
# get best group_excavators
# :param current_excavator_id: 当前车辆配对挖机
# :param truck_id:
# :param load_area_dict: 备选装载区
# :return:
# """
# min_trip_time = 10000000
# best_excavator_id = current_excavator_id
# try:
# for load_area, value in load_area_dict.items():
# # 车辆不需要掉头
# if load_area in DispatchInfo.load_excavator_dict:
# excavator_id = DispatchInfo.load_excavator_dict[load_area]
# else:
# continue
# if value[-1] == 1 and excavator_id in self.group.group_excavators:
# traveling_time = 60 * (value[0] / 1000) / empty_speed
#
# self.logger.info(f'load_area {load_area}')
# self.logger.info(f'traveling_time {traveling_time}')
#
# now = float(
# (datetime.now() - self.group.pre_sch.start_time) / timedelta(hours=0, minutes=1, seconds=0))
#
# reach_time = now + traveling_time
#
# self.logger.info(f'reach_time {reach_time}')
#
# trip_time = max(reach_time,
# self.group.pre_sch.get_excavator_avl_time(truck_id=truck_id)[excavator_id]) - now
#
# self.logger.info(f'trip_time {trip_time}')
#
# if min_trip_time > trip_time:
# best_excavator_id = excavator_id
# min_trip_time = trip_time
#
# except Exception as es:
# self.logger.error("寻找最佳装载区异常")
# self.logger.error(f'exception {es}')
# self.logger.error(f'in line {es.__traceback__.tb_lineno}')
# return best_excavator_id
#
# def get_congestion_lanes(self):
# # 存在车辆拥堵的路段
# truck_locate_dict = self.group.truck.get_truck_locate_dict()
# congestion_lane_list = []
# for key, value in truck_locate_dict.items():
# if self.group.truck.truck_current_state[key] == 2:
# congestion_lane_list.append(value)
#
# print("congestion_lane_list")
# print(list(set(congestion_lane_list)))
# return list(set(congestion_lane_list))
def
redispatch_to_dump
(
self
,
truck_id
,
truck_dispatch
,
truck_locate
,
truck_trip
)
:
class
ReDispatcher
:
"""
"""
redispatch truck to dumps.
redispatch controller
:param truck_id:
:param truck_dispatch:
:param truck_locate:
:param truck_trip:
:return:
"""
"""
# 当前绑定装载区
def
__init__
(
self
,
group
:
Group
):
if
truck_trip
[
0
]
==
-
1
:
self
.
logger
=
get_logger
(
"zxt.ReDispatcher"
)
next_excavator_id
=
session_mysql
.
query
(
EquipmentPair
)
.
filter_by
(
truck_id
=
truck_id
,
self
.
group
=
group
isdeleted
=
0
)
.
first
()
.
exactor_id
else
:
next_excavator_id
=
get_value
(
"excavator_index_to_uuid_dict"
)[
truck_trip
[
0
]]
# 当前绑定卸载区
if
truck_trip
[
-
1
]
==
-
1
:
item
=
session_mysql
.
query
(
EquipmentPair
)
.
filter_by
(
truck_id
=
truck_id
,
isdeleted
=
0
)
.
first
()
current_dump_id
=
item
.
dump_id
current_unload_area_id
=
item
.
unload_area_id
else
:
current_dump_id
=
get_value
(
"dump_index_to_uuid_dict"
)[
truck_trip
[
-
1
]]
current_unload_area_id
=
DispatchInfo
.
dump_unload_area_dict
[
current_dump_id
]
unload_area_dict
,
unload_area_lane_dict
=
self
.
group
.
topo
.
get_unload_target_node_real
(
truck_locate
,
current_unload_area_id
,
True
)
# 获取拥堵路段
congestion_lane_dict
=
self
.
get_congestion_lanes
()
# 获取当前交叉口下一路段集合
next_lane_list
=
get_cross_next_lanes
(
truck_locate
)
# 交叉口下一路段可达的装载区
next_lane_load_area_dict
=
get_lane_reach_load_areas
(
unload_area_lane_dict
,
next_lane_list
)
# 排除下一个路段阻塞的装载区
delete_congestion_load_area
(
congestion_lane_dict
,
unload_area_dict
,
next_lane_load_area_dict
)
min_trip_time
=
10000000
best_dump_id
=
current_dump_id
for
unload_area
,
value
in
unload_area_dict
.
items
():
# 车辆不需要掉头
if
value
[
-
1
]
==
1
and
unload_area
in
DispatchInfo
.
unload_area_dump_dict
:
dump_id
=
DispatchInfo
.
unload_area_dump_dict
[
unload_area
]
traveling_time
=
value
[
0
]
/
heavy_speed
now
=
float
(
(
datetime
.
now
()
-
self
.
group
.
pre_sch
.
start_time
)
/
timedelta
(
hours
=
0
,
minutes
=
1
,
seconds
=
0
))
reach_time
=
now
+
traveling_time
trip_time
=
max
(
reach_time
,
self
.
group
.
pre_sch
.
get_dump_avl_time
()[
dump_id
])
-
now
if
min_trip_time
>
trip_time
:
best_dump_id
=
dump_id
next_unload_area_id
=
DispatchInfo
.
dump_unload_area_dict
[
best_dump_id
]
truck_dispatch
[
truck_id
]
=
[
next_excavator_id
,
next_unload_area_id
]
# res = redispatch_request(truck_id, next_excavator_id, next_unload_area_id)
# self.logger.info(res)
self
.
logger
.
info
(
f
'二次调度结果 {truck_id}'
)
self
.
logger
.
info
(
truck_dispatch
[
truck_id
])
def
redispatch_to_excavator
(
self
,
truck_id
,
truck_dispatch
,
truck_locate
):
def
redispatch_to_excavator
(
self
,
truck_id
:
str
,
truck_dispatch
:
Mapping
[
str
,
List
[
str
]],
truck_locate
:
str
):
"""
"""
redispatch truck to excavators.
redispatch truck to excavators.
:param truck_id:
:param truck_id:
...
@@ -628,6 +744,9 @@ class GroupDispatcher:
...
@@ -628,6 +744,9 @@ class GroupDispatcher:
# current_load_area_id = DispatchInfo.excavator_load_dict[current_excavator_id]
# 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
,
load_area_dict
,
load_area_lane_dict
=
self
.
group
.
topo
.
get_load_target_node_real
(
truck_locate
,
current_load_area_id
,
True
)
current_load_area_id
,
True
)
# TODO
# topo 放到 group 里面不太合理
self
.
logger
.
info
(
"所有可达装载区"
)
self
.
logger
.
info
(
"所有可达装载区"
)
self
.
logger
.
info
(
load_area_dict
)
self
.
logger
.
info
(
load_area_dict
)
# 获取拥堵路段
# 获取拥堵路段
...
@@ -648,120 +767,69 @@ class GroupDispatcher:
...
@@ -648,120 +767,69 @@ class GroupDispatcher:
self
.
logger
.
info
(
f
'二次调度结果 {truck_id}'
)
self
.
logger
.
info
(
f
'二次调度结果 {truck_id}'
)
self
.
logger
.
info
(
truck_dispatch
[
truck_id
])
self
.
logger
.
info
(
truck_dispatch
[
truck_id
])
def
get_best_excavator
(
self
,
current_excavator_id
,
truck_id
,
load_area_dict
):
def
redispatch_to_dump
(
self
,
truck_id
:
str
,
truck_dispatch
:
Mapping
[
str
,
List
[
str
]],
truck_locate
:
str
,
truck_trip
:
List
[
int
]):
"""
get best group_excavators
:param current_excavator_id: 当前车辆配对挖机
:param truck_id:
:param load_area_dict: 备选装载区
:return:
"""
min_trip_time
=
10000000
best_excavator_id
=
current_excavator_id
try
:
for
load_area
,
value
in
load_area_dict
.
items
():
# 车辆不需要掉头
if
load_area
in
DispatchInfo
.
load_excavator_dict
:
excavator_id
=
DispatchInfo
.
load_excavator_dict
[
load_area
]
else
:
continue
if
value
[
-
1
]
==
1
and
excavator_id
in
self
.
group
.
group_excavators
:
traveling_time
=
60
*
(
value
[
0
]
/
1000
)
/
empty_speed
self
.
logger
.
info
(
f
'load_area {load_area}'
)
self
.
logger
.
info
(
f
'traveling_time {traveling_time}'
)
now
=
float
(
(
datetime
.
now
()
-
self
.
group
.
pre_sch
.
start_time
)
/
timedelta
(
hours
=
0
,
minutes
=
1
,
seconds
=
0
))
reach_time
=
now
+
traveling_time
self
.
logger
.
info
(
f
'reach_time {reach_time}'
)
trip_time
=
max
(
reach_time
,
self
.
group
.
pre_sch
.
get_excavator_avl_time
(
truck_id
=
truck_id
)[
excavator_id
])
-
now
self
.
logger
.
info
(
f
'trip_time {trip_time}'
)
if
min_trip_time
>
trip_time
:
best_excavator_id
=
excavator_id
min_trip_time
=
trip_time
except
Exception
as
es
:
self
.
logger
.
error
(
"寻找最佳装载区异常"
)
self
.
logger
.
error
(
f
'exception {es}'
)
self
.
logger
.
error
(
f
'in line {es.__traceback__.tb_lineno}'
)
return
best_excavator_id
def
get_congestion_lanes
(
self
):
# 存在车辆拥堵的路段
truck_locate_dict
=
self
.
group
.
truck
.
get_truck_locate_dict
()
congestion_lane_list
=
[]
for
key
,
value
in
truck_locate_dict
.
items
():
if
self
.
group
.
truck
.
truck_current_state
[
key
]
==
2
:
congestion_lane_list
.
append
(
value
)
print
(
"congestion_lane_list"
)
print
(
list
(
set
(
congestion_lane_list
)))
return
list
(
set
(
congestion_lane_list
))
class
ReDispatcher
:
"""
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
excavator
s.
redispatch truck to
dump
s.
:param truck_id:
:param truck_id:
:param truck_dispatch:
:param truck_dispatch:
:param truck_locate:
:param truck_locate:
:param truck_trip:
:return:
: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:
if
truck_trip
[
0
]
==
-
1
:
next_excavator_id
=
session_mysql
.
query
(
EquipmentPair
)
.
filter_by
(
truck_id
=
truck_id
,
isdeleted
=
0
)
.
first
()
.
exactor_id
else
:
next_excavator_id
=
get_value
(
"excavator_index_to_uuid_dict"
)[
truck_trip
[
0
]]
# 当前绑定卸载区
if
truck_trip
[
-
1
]
==
-
1
:
item
=
session_mysql
.
query
(
EquipmentPair
)
.
filter_by
(
truck_id
=
truck_id
,
isdeleted
=
0
)
.
first
()
item
=
session_mysql
.
query
(
EquipmentPair
)
.
filter_by
(
truck_id
=
truck_id
,
isdeleted
=
0
)
.
first
()
current_excavator_id
=
item
.
exactor_id
current_dump_id
=
item
.
dump_id
current_load_area_id
=
item
.
load_area_id
current_unload_area_id
=
item
.
unload_area_id
self
.
logger
.
info
(
f
'truck_id {truck_id}'
)
else
:
self
.
logger
.
info
(
f
'current_load_area_id {current_load_area_id}'
)
current_dump_id
=
get_value
(
"dump_index_to_uuid_dict"
)[
truck_trip
[
-
1
]]
# else:
current_unload_area_id
=
DispatchInfo
.
dump_unload_area_dict
[
current_dump_id
]
# current_excavator_id = get_value("excavator_index_to_uuid_dict")[truck_trip[-1]]
unload_area_dict
,
unload_area_lane_dict
=
self
.
group
.
topo
.
get_unload_target_node_real
(
truck_locate
,
# current_load_area_id = DispatchInfo.excavator_load_dict[current_excavator_id]
current_unload_area_id
,
load_area_dict
,
load_area_lane_dict
=
self
.
group
.
topo
.
get_load_target_node_real
(
truck_locate
,
True
)
current_load_area_id
,
True
)
self
.
logger
.
info
(
"所有可达装载区"
)
self
.
logger
.
info
(
load_area_dict
)
# 获取拥堵路段
# 获取拥堵路段
congestion_lane_dict
=
self
.
get_congestion_lanes
()
congestion_lane_dict
=
self
.
get_congestion_lanes
()
# 获取当前交叉口下一路段集合
# 获取当前交叉口下一路段集合
next_lane_list
=
get_cross_next_lanes
(
truck_locate
)
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
)
next_lane_load_area_dict
=
get_lane_reach_load_areas
(
unload_area_lane_dict
,
next_lane_list
)
# 排除下一个路段阻塞的装载区
# 排除下一个路段阻塞的装载区
delete_congestion_load_area
(
congestion_lane_dict
,
load_area_dict
,
delete_congestion_load_area
(
congestion_lane_dict
,
un
load_area_dict
,
next_lane_load_area_dict
)
next_lane_load_area_dict
)
self
.
logger
.
info
(
"剔除堵塞装载区"
)
min_trip_time
=
10000000
self
.
logger
.
info
(
load_area_dict
)
best_dump_id
=
current_dump_id
# 获取最佳挖机
for
unload_area
,
value
in
unload_area_dict
.
items
():
best_excavator_id
=
self
.
get_best_excavator
(
current_excavator_id
,
truck_id
,
load_area_dict
)
# 车辆不需要掉头
next_excavator_id
=
best_excavator_id
if
value
[
-
1
]
==
1
and
unload_area
in
DispatchInfo
.
unload_area_dump_dict
:
dump_id
=
DispatchInfo
.
unload_area_dump_dict
[
unload_area
]
traveling_time
=
value
[
0
]
/
heavy_speed
now
=
float
(
(
datetime
.
now
()
-
self
.
group
.
pre_sch
.
start_time
)
/
timedelta
(
hours
=
0
,
minutes
=
1
,
seconds
=
0
))
reach_time
=
now
+
traveling_time
trip_time
=
max
(
reach_time
,
self
.
group
.
pre_sch
.
get_dump_avl_time
()[
dump_id
])
-
now
if
min_trip_time
>
trip_time
:
best_dump_id
=
dump_id
next_unload_area_id
=
DispatchInfo
.
dump_unload_area_dict
[
best_dump_id
]
truck_dispatch
[
truck_id
]
=
[
next_excavator_id
,
next_unload_area_id
]
truck_dispatch
[
truck_id
]
=
[
next_excavator_id
,
next_unload_area_id
]
# res = redispatch_request(truck_id, next_excavator_id, next_unload_area_id)
# self.logger.info(res)
self
.
logger
.
info
(
f
'二次调度结果 {truck_id}'
)
self
.
logger
.
info
(
f
'二次调度结果 {truck_id}'
)
self
.
logger
.
info
(
truck_dispatch
[
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
:
str
,
truck_id
:
str
,
load_area_dict
):
"""
"""
get best group_excavators
get best group_excavators
:param current_excavator_id: 当前车辆配对挖机
:param current_excavator_id: 当前车辆配对挖机
...
...
core/submit.py
View file @
c4e5134f
...
@@ -120,6 +120,9 @@ class DispatchSubmission:
...
@@ -120,6 +120,9 @@ class DispatchSubmission:
record
=
redis_format
(
truck_id
,
group_id
,
str
(
uuid
.
uuid1
()),
item
)
record
=
redis_format
(
truck_id
,
group_id
,
str
(
uuid
.
uuid1
()),
item
)
# TODO:
# 判断了两次是否拥堵,需要改善
# 车辆重载等待,且前方道路阻塞
# 车辆重载等待,且前方道路阻塞
if
task
==
3
and
state
==
2
and
truck_id
in
self
.
truck
.
get_truck_locate_dict
()
and
\
if
task
==
3
and
state
==
2
and
truck_id
in
self
.
truck
.
get_truck_locate_dict
()
and
\
self
.
truck
.
get_truck_locate_dict
()[
truck_id
]
in
self
.
topo
.
cross_bf_lanes
:
self
.
truck
.
get_truck_locate_dict
()[
truck_id
]
in
self
.
topo
.
cross_bf_lanes
:
...
...
realtime_dispatch.py
View file @
c4e5134f
...
@@ -18,6 +18,7 @@ from core.dispatcher import Dispatcher
...
@@ -18,6 +18,7 @@ from core.dispatcher import Dispatcher
from
core.schedule
import
PreSchedule
from
core.schedule
import
PreSchedule
from
data.dispatchInfo
import
DispatchInfo
from
data.dispatchInfo
import
DispatchInfo
from
util
import
CoreException
from
util
import
CoreException
from
core.group
import
Group
def
direct2redis
():
def
direct2redis
():
...
@@ -35,7 +36,7 @@ def direct2redis():
...
@@ -35,7 +36,7 @@ def direct2redis():
try
:
try
:
truck_disp
=
{}
truck_disp
=
[]
for
item
in
session_mysql
.
query
(
DispatchSetting
)
.
filter_by
(
isdeleted
=
0
,
)
.
all
():
for
item
in
session_mysql
.
query
(
DispatchSetting
)
.
filter_by
(
isdeleted
=
0
,
)
.
all
():
if
item
is
None
:
if
item
is
None
:
raise
CoreException
(
101
,
"无可用派车计划"
)
raise
CoreException
(
101
,
"无可用派车计划"
)
...
@@ -49,6 +50,41 @@ def direct2redis():
...
@@ -49,6 +50,41 @@ def direct2redis():
# 写入redis
# 写入redis
redis5
.
set
(
item
.
truck_id
,
str
(
json
.
dumps
(
record
)))
redis5
.
set
(
item
.
truck_id
,
str
(
json
.
dumps
(
record
)))
truck_disp
.
append
(
item
.
truck_id
)
except
CoreException
as
ce
:
logger
.
error
(
ce
)
session_postgre
.
rollback
()
session_mysql
.
rollback
()
def
group_direct2redis
(
group
:
Group
):
"""
根据分组车辆直接读取数据库写入redis
:return: None
"""
# 清空数据库缓存
session_mysql
.
commit
()
session_mysql
.
flush
()
# 清空数据库缓存
session_postgre
.
commit
()
session_postgre
.
flush
()
try
:
for
truck_id
in
group
.
group_trucks
:
item
=
session_mysql
.
query
(
DispatchSetting
)
.
filter_by
(
truck_id
=
truck_id
,
isdeleted
=
0
,
)
.
first
()
if
item
is
None
:
raise
CoreException
(
101
,
"无可用派车计划"
)
record
=
{
"truckId"
:
item
.
truck_id
,
"dispatchId"
:
item
.
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
[
item
.
group_id
]}
logger
.
info
(
f
'写入redis调度结果: {record}'
)
# 写入redis
redis5
.
set
(
item
.
truck_id
,
str
(
json
.
dumps
(
record
)))
except
CoreException
as
ce
:
except
CoreException
as
ce
:
logger
.
error
(
ce
)
logger
.
error
(
ce
)
session_postgre
.
rollback
()
session_postgre
.
rollback
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment