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
3ad4cb99
Commit
3ad4cb99
authored
Feb 09, 2023
by
张晓彤
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
穿越装载区代码优化
parent
85a08dd5
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
534 additions
and
2 deletions
+534
-2
app.py
app.py
+534
-2
No files found.
app.py
View file @
3ad4cb99
...
...
@@ -12,6 +12,7 @@ from data.dispatchInfo import DispatchInfo
from
core.submit
import
DispatchSubmission
from
core.group
import
GroupDispatcher
from
core.group
import
group_direct2redis
import
uuid
config
=
{
"DEBUG"
:
True
,
# some Flask specific configs
...
...
@@ -194,4 +195,535 @@ def dispatch_request():
print
(
f
'调度时耗 {rtd_end_time - rtd_start_time}'
)
return
jsonify
(
msg
=
"success"
,
code
=
0
)
\ No newline at end of file
return
jsonify
(
msg
=
"success"
,
code
=
0
)
@app.route
(
"/go_through"
,
methods
=
[
"POST"
])
def
redispatch_request
():
# 获取报文数据
data_json
=
request
.
get_json
()
# 车辆id
request_truck_id
=
data_json
.
get
(
"truck_id"
)
# request_truck_id = '0349fbdf-3c37-4fb3-867f-bea98a42af4a'
# 调度开始时间
rtd_start_time
=
datetime
.
now
()
# 初始化日志
set_log
()
# 获取日志器
logger
=
get_logger
(
"zxt.Request"
)
# 更新周期参数
logger
.
info
(
"#####################################请求调度更新开始#####################################"
)
'''
1. 更新全局参数信息
'''
try
:
# 清空数据库缓存
session_mysql
.
commit
()
session_mysql
.
flush
()
# 清空数据库缓存
session_postgre
.
commit
()
session_postgre
.
flush
()
except
Exception
as
es
:
logger
.
error
(
"数据库访问异常"
)
logger
.
error
(
es
)
return
jsonify
(
msg
=
"未知异常, 请联系管理员"
,
code
=
501
)
try
:
# 全局参数更新
global_period_para_update
()
# get_global_para_from_cache(cache)
except
Exception
as
es
:
logger
.
error
(
"全局参数更新异常"
)
logger
.
error
(
es
)
session_mysql
.
rollback
()
session_postgre
.
rollback
()
return
jsonify
(
msg
=
"未知异常, 请联系管理员"
,
code
=
502
)
try
:
# 更新调度信息
DispatchInfo
.
reset
()
DispatchInfo
.
update_device_group_structure
()
DispatchInfo
.
update_route_distance
()
DispatchInfo
.
update_group_mode
()
DispatchInfo
.
update_group_name
()
except
Exception
as
es
:
logger
.
error
(
"调度信息更新异常"
)
logger
.
error
(
es
)
session_mysql
.
rollback
()
session_postgre
.
rollback
()
return
jsonify
(
msg
=
"未知异常, 请联系管理员"
,
code
=
503
)
logger
.
info
(
"Dispatchinfo,更新后信息"
)
logger
.
info
(
"group_set"
)
logger
.
info
(
DispatchInfo
.
group_set
)
logger
.
info
(
"group_excavator_dict"
)
logger
.
info
(
DispatchInfo
.
group_excavator_dict
)
logger
.
info
(
"group_unload_area_dict"
)
logger
.
info
(
DispatchInfo
.
group_unload_area_dict
)
logger
.
info
(
"group_truck_dict"
)
logger
.
info
(
DispatchInfo
.
group_truck_dict
)
logger
.
info
(
"group_mode"
)
logger
.
info
(
DispatchInfo
.
group_mode
)
logger
.
info
(
"load_distance"
)
logger
.
info
(
DispatchInfo
.
load_distance
)
logger
.
info
(
"unload_distance"
)
logger
.
info
(
DispatchInfo
.
unload_distance
)
try
:
# # 实例化设备对象
dump
=
DumpInfo
()
excavator
=
ExcavatorInfo
()
truck
=
TruckInfo
(
dump
,
excavator
)
# 设备信息更新
dump
.
dump_para_period_update
()
excavator
.
excavator_para_period_update
()
truck
.
truck_para_period_update
(
dump
,
excavator
)
truck
.
state_period_update
()
except
Exception
as
es
:
logger
.
error
(
"对象实例化异常"
)
logger
.
error
(
es
)
session_mysql
.
rollback
()
session_postgre
.
rollback
()
return
jsonify
(
msg
=
"未知异常, 请联系管理员"
,
code
=
504
)
'''
2. 读取二次调度所需信息(车辆位置、分组、挖机等)
'''
try
:
truck_uuid_to_name_dict
=
get_value
(
"truck_uuid_to_name_dict"
)
# 获取请调车辆名
request_truck_name
=
truck_uuid_to_name_dict
[
request_truck_id
]
except
Exception
as
es
:
logger
.
error
(
es
)
return
jsonify
(
msg
=
"数据库异常, 车辆编号未知"
,
code
=
510
)
try
:
# 读取请调车辆所属分组
group_id
=
DispatchInfo
.
truck_group_dict
[
request_truck_id
]
# 读取分组挖机集合
excavators_id
=
DispatchInfo
.
get_excavator
(
group_id
)
# 读取车辆位置信息
truck_locates_dict
=
get_trucks_locate
()
logger
.
info
(
"truck_locates_dict"
)
logger
.
info
(
truck_locates_dict
)
closer_area_id
=
'7ff73575-2134-afd4-1065-d5d60e8751c9'
further_area_id
=
'79584290-1134-8b85-f4cc-1dcf64fc3456'
logger
.
info
(
"近端装载区id"
)
logger
.
info
(
closer_area_id
)
logger
.
info
(
"远端装载区id"
)
logger
.
info
(
further_area_id
)
# 读取两个挖机id
if
closer_area_id
in
DispatchInfo
.
load_excavator_dict
and
further_area_id
in
DispatchInfo
.
load_excavator_dict
:
closer_excavator_id
,
further_excavator_id
=
DispatchInfo
.
load_excavator_dict
[
closer_area_id
],
\
DispatchInfo
.
load_excavator_dict
[
further_area_id
]
else
:
return
jsonify
(
msg
=
"装载点信息错误"
,
code
=
506
)
# 读取挖机状态
closer_excavator_state
,
further_excavator_state
=
get_excavator_state
(
closer_excavator_id
),
\
get_excavator_state
(
further_excavator_id
)
# 读取两个装载区入场点id
closer_entrance_node_id
=
session_postgre
.
query
(
DiggingWorkArea
)
.
filter_by
(
Id
=
closer_area_id
)
.
first
()
.
EntranceNodeId
further_entrance_node_id
=
session_postgre
.
query
(
DiggingWorkArea
)
.
filter_by
(
Id
=
further_area_id
)
.
first
()
.
EntranceNodeId
logger
.
info
(
"近端装载区入场点"
)
logger
.
info
(
closer_entrance_node_id
)
logger
.
info
(
"远端装载区入场点"
)
logger
.
info
(
further_entrance_node_id
)
except
Exception
as
es
:
logger
.
error
(
"读取装载区及车辆信息异常"
)
logger
.
error
(
es
)
return
jsonify
(
msg
=
"未知异常, 请联系管理员"
,
code
=
505
)
try
:
# 读取请调车辆所在路段信息
request_truck_lane_id
=
truck_locates_dict
[
request_truck_id
]
logger
.
info
(
"request_truck_lane_id:"
)
logger
.
info
(
request_truck_lane_id
)
logger
.
info
(
truck_locates_dict
)
except
Exception
as
es
:
logger
.
error
(
f
'车辆 {request_truck_name} 位置信息不可用'
)
logger
.
error
(
es
)
return
jsonify
(
msg
=
f
'车辆 {request_truck_name} 位置信息不可用, 请联系管理员'
,
code
=
505
)
'''
3. 调度判断逻辑
'''
# 车辆已驶过第一个装载点,车辆只能驶往远端装载区
if
not
truck_pass_first_area
(
request_truck_id
,
request_truck_lane_id
,
closer_entrance_node_id
,
further_entrance_node_id
):
logger
.
info
(
"车辆已经过近端装载区"
)
target_excavator
=
DispatchInfo
.
load_excavator_dict
[
further_area_id
]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[further_area_id])
# 车辆未驶过第一个装载点,进入二次调度逻辑
else
:
# 近端挖机空闲
if
closer_excavator_state
==
0
:
logger
.
info
(
"近端挖机空闲, 调度车辆前往"
)
target_excavator
=
DispatchInfo
.
load_excavator_dict
[
closer_area_id
]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[closer_area_id])
# 远端挖机空闲
elif
further_excavator_state
==
0
:
logger
.
info
(
"远端挖机空闲, 调度车辆前往"
)
target_excavator
=
DispatchInfo
.
load_excavator_dict
[
further_area_id
]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[further_area_id])
# 两挖机均不空闲
else
:
# 两装载点间路段集合
lane_set
=
get_lanes_between_entrances
(
closer_entrance_node_id
,
further_entrance_node_id
)
# 选择合适装载区
target_excavator
=
area_choose
(
excavators_id
,
closer_area_id
,
further_area_id
,
lane_set
,
logger
,
truck
,
truck_locates_dict
)
# 派车计划写入redis
truck_dispatch_to_redis
(
request_truck_id
,
group_id
,
target_excavator
)
# except Exception as es:
# logger.error(" ")
# logger.error(es)
# session_mysql.rollback()
# session_postgre.rollback()
# return jsonify(msg="未知异常, 请联系管理员", code=504)
logger
.
info
(
"#####################################请求调度更新结束#####################################"
)
# 调度结束时间
rtd_end_time
=
datetime
.
now
()
print
(
f
'调度时耗 {rtd_end_time - rtd_start_time}'
)
return
jsonify
(
msg
=
"success"
,
code
=
0
)
def
area_choose
(
excavators_id
,
closer_area_id
,
further_area_id
,
lane_set
,
logger
,
truck
,
truck_locates_dict
):
"""
两装载区均不空闲,执行二次调度
:param excavators_id: 挖机集合
:param closer_area_id: 近端装载区id
:param further_area_id: 远端装载区id
:param lane_set: 近端及远端装载区间路段集合
:param logger: 日志器
:param truck: 车辆对象
:param truck_locates_dict: 车辆位置
:return: target_excavator
"""
logger
.
info
(
"excavator_hold_truck_list"
)
logger
.
info
(
truck
.
excavator_hold_truck_list
)
logger
.
info
(
list
(
excavators_id
)[
0
])
logger
.
info
(
list
(
excavators_id
)[
1
])
logger
.
info
(
truck
.
excavator_hold_truck_list
[
list
(
excavators_id
)[
0
]])
logger
.
info
(
truck
.
excavator_hold_truck_list
[
list
(
excavators_id
)[
1
]])
# 统计驶往两装载区的车辆
arrival_truck_set
=
truck
.
excavator_hold_truck_list
[
list
(
excavators_id
)[
0
]]
\
+
truck
.
excavator_hold_truck_list
[
list
(
excavators_id
)[
1
]]
# 统计车辆抵达时间
arrival_truck_reach_time
=
[
truck
.
cur_truck_reach_excavator
[
truck
.
truck_uuid_to_index_dict
[
truck_id
]]
for
\
truck_id
in
arrival_truck_set
]
# arrival_truck_set = ['309705a0-5ddf-4559-b6c4-ee17a57677ad', '899705a0-5ddf-4559-b6c4-ee17a57677ad']
#
# arrival_truck_reach_time = [8.04, 6.05]
logger
.
info
(
"arrival_truck_reach_time"
)
logger
.
info
(
arrival_truck_reach_time
)
logger
.
info
(
"arrival_truck_set"
)
logger
.
info
(
arrival_truck_set
)
arrival_truck_list
=
list
(
zip
(
np
.
array
(
arrival_truck_set
),
np
.
array
(
arrival_truck_reach_time
)))
arrival_truck_list
=
sorted
(
arrival_truck_list
,
key
=
lambda
item
:
item
[
1
])
logger
.
info
(
"arrival_truck_list"
)
logger
.
info
(
arrival_truck_list
)
logger
.
info
(
"arrival_truck_list"
)
logger
.
info
(
arrival_truck_list
)
# 统计不同状态车辆数量
goto_closer_area_num
=
0
goto_further_area_num
=
0
for
truck_id
,
reach_time
in
arrival_truck_list
:
if
truck_id
in
truck_locates_dict
:
truck_lane_id
=
truck_locates_dict
[
truck_id
]
# 车辆已经经过近端装载区
if
truck_lane_id
in
lane_set
:
# 前往远端装载区车辆数加1
goto_further_area_num
+=
1
# 车辆未经过近端装载区
else
:
# 前往近端或近端装载区车辆数加1
goto_closer_area_num
+=
1
else
:
continue
# goto_further_area_num -= 1
logger
.
info
(
"goto_further_area_num-goto_closer_area_num"
)
logger
.
info
(
goto_further_area_num
)
logger
.
info
(
goto_closer_area_num
)
# 默认当前请调车辆与近端装载点前没有车辆,因此前往近端装载区的车辆仅其本身
goto_closer_area_num
=
1
# 在远处排队等待的车辆更少
if
goto_closer_area_num
>
goto_further_area_num
:
logger
.
info
(
"远端挖机排队时间短, 调度车辆前往"
)
target_excavator
=
DispatchInfo
.
load_excavator_dict
[
further_area_id
]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[further_area_id])
else
:
logger
.
info
(
"近端挖机排队时间短, 调度车辆前往"
)
target_excavator
=
DispatchInfo
.
load_excavator_dict
[
closer_area_id
]
# truck_dispatch_to_redis(request_truck_id, group_id, DispatchInfo.load_excavator_dict[closer_area_id])
return
target_excavator
def
area_analysis
(
load_area_uuid
):
"""
Analysis which area is closer.
:param load_area_uuid:
:return: closer_area_uuid, further_area_uuid
"""
try
:
excavator_uuid_to_load_area_uuid_dict
=
get_value
(
"excavator_uuid_to_load_area_uuid_dict"
)
load_area_uuid
=
list
(
load_area_uuid
)
load_area_uuid
[
0
]
=
excavator_uuid_to_load_area_uuid_dict
[
load_area_uuid
[
0
]]
load_area_uuid
[
1
]
=
excavator_uuid_to_load_area_uuid_dict
[
load_area_uuid
[
1
]]
distance_a
=
session_postgre
.
query
(
WalkTimePark
)
\
.
filter_by
(
load_area_id
=
load_area_uuid
[
0
])
.
first
()
.
park_load_distance
distance_b
=
session_postgre
.
query
(
WalkTimePark
)
\
.
filter_by
(
load_area_id
=
load_area_uuid
[
1
])
.
first
()
.
park_load_distance
if
distance_a
>
distance_b
:
return
load_area_uuid
[
1
],
load_area_uuid
[
0
]
else
:
return
load_area_uuid
[
0
],
load_area_uuid
[
1
]
except
Exception
as
es
:
logger
.
error
(
"装载区距离分析异常"
)
logger
.
error
(
es
)
return
load_area_uuid
[
0
],
load_area_uuid
[
1
]
def
truck_pass_first_area
(
truck_id
,
lane_id
,
closer_entrance_node_id
,
further_entrance_node_id
):
"""
Truck has gone through the first area.
:param truck_id:
:param lane_id:
:param closer_entrance_node_id:
:param further_entrance_node_id:
:return:
"""
# try:
def
backtracking
(
root_node
):
from
collections
import
deque
que
=
deque
([
root_node
])
while
que
:
size
=
len
(
que
)
for
_
in
range
(
size
):
cur_node
=
que
.
popleft
()
if
cur_node
is
None
:
continue
logger
.
info
(
cur_node
)
if
cur_node
==
closer_entrance_node_id
:
logger
.
info
(
"closer_entrance_node"
)
return
0
if
cur_node
==
further_entrance_node_id
:
logger
.
info
(
"further_entrance_node"
)
return
1
for
item
in
session_postgre
.
query
(
Lane
)
.
filter_by
(
StartNodeId
=
cur_node
)
.
all
():
if
item
:
que
.
append
(
item
.
EndNodeId
)
node_id
=
session_postgre
.
query
(
Lane
)
.
filter_by
(
Id
=
lane_id
)
.
first
()
.
EndNodeId
if
backtracking
(
root_node
=
node_id
)
==
0
:
return
True
else
:
return
False
# except Exception as es:
# logger.error("车辆行驶位置判断异常")
# logger.error(es)
# return True
def
get_trucks_locate
():
"""
get trucks locates.
:return: truck_locate_dict
"""
try
:
truck_name_to_uuid_dict
=
get_value
(
"truck_name_to_uuid_dict"
)
truck_locate_dict
=
{}
device_name_set
=
redis2
.
keys
()
for
item
in
device_name_set
:
item
=
item
.
decode
(
encoding
=
'utf-8'
)
key_value_dict
=
redis2
.
hgetall
(
item
)
if
str_to_byte
(
'type'
)
in
key_value_dict
:
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'
)]
# logger.error(item)
# logger.error(eval(truck_locate))
if
eval
(
truck_locate
)
is
not
''
:
truck_locate_dict
[
truck_name_to_uuid_dict
[
item
]]
=
eval
(
truck_locate
)
logger
.
error
(
truck_locate_dict
)
else
:
continue
return
truck_locate_dict
except
Exception
as
es
:
logger
.
error
(
"车辆所在路段读取异常"
)
logger
.
error
(
es
)
return
{}
def
truck_dispatch_to_redis
(
truck_id
,
group_id
,
excavator_id
):
"""
write truck dispatch to redis.
:param truck_id:
:param group_id:
:param excavator_id:
:return:
"""
# 查询车辆相关派车计划
record
=
{}
try
:
# dump_id = DispatchInfo.unload_area_dump_dict[unload_area_id]
item
=
(
session_mysql
.
query
(
DispatchSetting
)
.
filter_by
(
exactor_id
=
excavator_id
,
group_id
=
group_id
,
isdeleted
=
0
,
)
.
first
())
if
item
is
None
:
raise
Exception
(
"调度计划配置异常"
)
except
Exception
as
es
:
item
=
(
session_mysql
.
query
(
DispatchSetting
)
.
filter_by
(
group_id
=
group_id
,
isdeleted
=
0
,
)
.
first
())
logger
.
error
(
es
)
# 其余调度信息写入
try
:
# record["dispatchId"] = item.id
record
[
"dispatchId"
]
=
str
(
uuid
.
uuid1
())
record
[
"exactorId"
]
=
item
.
exactor_id
record
[
"loadAreaId"
]
=
item
.
load_area_id
record
[
"dumpId"
]
=
item
.
dump_id
record
[
"unloadAreaId"
]
=
item
.
unload_area_id
record
[
"groupId"
]
=
group_id
record
[
"isdeleted"
]
=
False
record
[
"isTemp"
]
=
False
record
[
"haulFlag"
]
=
-
1
record
[
"groupName"
]
=
DispatchInfo
.
group_name
[
group_id
]
logger
.
info
(
f
'{truck_id} redis 注入 {record}'
)
except
Exception
as
es
:
logger
.
error
(
"调度结果写入异常-矿卡空载"
)
logger
.
error
(
es
)
finally
:
redis5
.
set
(
truck_id
,
str
(
json
.
dumps
(
record
)))
def
get_lanes_between_entrances
(
closer_node_id
,
further_node_id
):
"""
get lanes between two entrance nodes.
:param closer_node_id:
:param further_node_id:
:return: lane set
"""
try
:
max_find_it
=
100
next_node_id
=
closer_node_id
lane_set
=
[]
while
max_find_it
>
0
and
next_node_id
!=
further_node_id
:
item
=
session_postgre
.
query
(
Lane
)
.
filter_by
(
StartNodeId
=
next_node_id
,
Type
=
2
)
.
first
()
if
item
:
next_lane_id
=
item
.
Id
next_node_id
=
item
.
EndNodeId
lane_set
.
append
(
next_lane_id
)
max_find_it
-=
1
max_find_it
-=
1
return
lane_set
except
Exception
as
es
:
logger
.
error
(
"获取装载区间路段异常"
)
logger
.
error
(
es
)
return
[]
def
get_excavator_state
(
excavator_id
):
"""
get group_excavators state.
:param excavator_id:
:return: state
"""
try
:
logger
.
error
(
excavator_id
)
device_name
=
session_mysql
.
query
(
Equipment
)
.
filter_by
(
id
=
excavator_id
,
device_type
=
2
)
.
first
()
.
device_name
key_value_dict
=
redis2
.
hgetall
(
device_name
)
if
str_to_byte
(
'online'
)
in
key_value_dict
:
is_online
=
key_value_dict
[
str_to_byte
(
'online'
)]
else
:
logger
.
warning
(
f
'挖机 {device_name} 不在线'
)
return
0
key_set
=
key_value_dict
.
keys
()
state
=
100
if
(
str_to_byte
(
'online'
)
in
key_set
)
and
(
bytes
.
decode
(
is_online
)
in
[
"true"
or
"True"
]):
if
str_to_byte
(
'workState'
)
in
key_set
:
state
=
key_value_dict
[
str_to_byte
(
'workState'
)]
else
:
logger
.
warning
(
f
'挖机 {device_name} 状态未知'
)
return
0
return
int
(
float
(
byte_to_str
(
state
)))
except
Exception
as
es
:
logger
.
error
(
"挖机状态读取异常"
)
logger
.
error
(
es
)
return
0
if
__name__
==
"__main__"
:
app
.
run
(
host
=
'0.0.0.0'
,
port
=
80
)
\ No newline at end of file
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