Python Simpy仿真实现AGV运行过程
一、实现目的
simpy提供了一个离散时间仿真的库,本人想通过此仿真库实现对AGV在车间运行过程的的模拟,一个简单的场景可以描述为:仿真时间开始,初始电量为某个值的AGV在车间开始运行,直到其电量的低于某个阈值时就去充电区去充电。
显然此场景用普通的单线程流程控制语句很容易实现,此处仅仅是通过此场景学会Simpy的建模与仿真,便于实现更复杂的场景与功能。
二、所需基础知识
可以参考简书的这篇文章:Python SimPy 仿真系列 (1)
或者Simpy的: 官方链接
三、逻辑关系
要实现此场景,有两个主要过程需要描述:运行和充电。同时还有一些辅助进程:SOC监控与SOC实时记录,以及两个事件:充电进程激活与充电停止事件。并且此对象还得具有一个属性,Container作为一个可以消耗、存储并且具有容量限制的容器,用来表示AGV的SOC。
在初始时刻,AGV进程开始运行,其SOC初值为一个[20,40]的随机量,每秒消耗一定值的电量。同时SOC监控与实时记录进程也开始运行,在监控到SOC低于一定阈值时,立即要求AGV停止运行,前往充电区,在到达充电区之后,激活充电过程,然后充电进程开始执行,开始以一定的充电速度充电,充满之后,执行充电结束事件,然后AGV返回工作区继续运行。
四、代码实现
运行条件:
python >= 3.5
安装simpy
from random import seed, randint
seed(23)
import simpy
import matplotlib.pyplot as plt
AGV_power_curve=[]
class AGV:
def __init__(self, env):
self.env = env
self.run_proc = env.process(self.run(env)) #AGV运行
self.charing_proc = env.process(self.charging(env)) #充电过程
self.charging_reactivate = env.event()
self.charging_stop = env.event()
self.SOC_monitor_proc = env.process(self.SOC_monitor(env))
self.SOC = simpy.Container(env,init=randint(20, 40),capacity=100)
self.charging_speed = 2 #每秒充电1%/s
self.csp_speed = 0.5 #消耗速度1%/s
self.charging_flag = 0 #充电标志
self.SOC_record_proc = env.process(self.SOC_record(env))
self.SOC_threshold = 20
def run(self, env):
"""AGV运行进程"""
print("开始运行 时间: ", env.now)
print("AGV初始电量:", self.SOC.level)
while True:
# run 20-40 s
print("持续运行 时间: ", env.now)
yield self.SOC.get(self.csp_speed)
yield env.timeout(1) #让其每秒消耗1% 的电量
if self.charging_flag == 1:
print("暂停运行 时间: ", env.now)
yield self.charging_stop
def charging(self, env):
"""电池充电进程"""
while True:
print("充电进程处于休眠状态 时间:", env.now)
yield self.charging_reactivate # 休眠直到充电事件被激活
print("充电激活 时间:", env.now)
print("开始充电")
charing_power = self.SOC.capacity - self.SOC.level
for i in range(int(charing_power/self.charging_speed)):
self.SOC.put(self.charging_speed)
yield env.timeout(1)
print("充电结束 时间:", env.now)
print("充电结束后的电量:", self.SOC.level)
self.charging_stop.succeed()
self.charging_stop = env.event()
self.charging_flag = 0
def SOC_monitor(self,env):
while True:
if self.SOC.level/self.SOC.capacity *100 < self.SOC_threshold:
self.charging_flag = 1
print("电量不足,请求充电,即将前往充电区 时间:", env.now)
yield env.timeout(2)
print("到达充电区 时间:", env.now)
self.charging_reactivate.succeed()
self.charging_reactivate = env.event()
yield self.charging_stop
yield env.timeout(1) #每隔2s检查一下
def SOC_record(self,env):
while True:
AGV_power_curve.append(self.SOC.level)
yield env.timeout(1)
def main():
env = simpy.Environment()
agv = AGV(env)
env.run(until=2000)
plt.plot(AGV_power_curve)
if __name__ == '__main__':
main()