3. 交通信号灯状态机控制
任务说明
实现一个交通信号灯状态机控制器,管理红、黄、绿三种灯的正常时序切换,并支持紧急模式(紧急车辆通过时强制红灯,结束后恢复原状态)。本案例使用 Python 实现,不依赖第三方库,可直接运行验证。
状态定义与转换逻辑
- 正常模式:绿(5s) → 黄(2s) → 红(5s) → 绿,循环切换
- 紧急模式:任意状态收到紧急信号后立即进入红灯;紧急解除后回到紧急前的状态,并重新计时
完整实现
import time
from enum import Enum
class LightState(Enum):
RED = "红灯"
YELLOW = "黄灯"
GREEN = "绿灯"
class TrafficLightFSM:
def __init__(self):
self.state = LightState.RED
self.remaining_time = 5
self.emergency = False
self.prev_state = None
self.prev_remaining = 0
self._state_durations = {
LightState.RED: 5,
LightState.YELLOW: 2,
LightState.GREEN: 5,
}
def _next_normal_state(self):
order = [LightState.GREEN, LightState.YELLOW, LightState.RED]
return order[(order.index(self.state) + 1) % 3]
def tick(self, dt=1):
"""推进时间,dt为经过的秒数"""
if self.emergency:
return # 紧急模式下不推进正常时序
self.remaining_time -= dt
if self.remaining_time <= 0:
self.state = self._next_normal_state()
self.remaining_time = self._state_durations[self.state]
def trigger_emergency(self):
"""进入紧急模式:强制红灯"""
if not self.emergency:
self.emergency = True
self.prev_state = self.state
self.prev_remaining = self.remaining_time
self.state = LightState.RED
self.remaining_time = 999 # 紧急模式持续期间红灯常亮
def release_emergency(self):
"""解除紧急模式:恢复紧急前状态并重新计时"""
if self.emergency:
self.emergency = False
self.state = self.prev_state
self.remaining_time = self._state_durations[self.prev_state]
def get_status(self):
return {
"当前灯": self.state.value,
"剩余秒数": self.remaining_time if not self.emergency else "紧急中",
"紧急模式": self.emergency,
}
# 最小验证闭环
if __name__ == "__main__":
fsm = TrafficLightFSM()
print("初始:", fsm.get_status())
# 模拟正常时序:红灯5秒后变绿
for _ in range(5):
fsm.tick()
print("5秒后:", fsm.get_status())
# 触发紧急模式
fsm.trigger_emergency()
print("紧急触发:", fsm.get_status())
# 紧急期间tick不应改变状态
fsm.tick()
fsm.tick()
print("紧急2秒后:", fsm.get_status())
# 解除紧急,应回到红灯并重新计时5秒
fsm.release_emergency()
print("紧急解除:", fsm.get_status())
# 再走5秒应切换到绿灯
for _ in range(5):
fsm.tick()
print("再5秒后:", fsm.get_status())
运行与验证
- 将代码保存为
traffic_light_fsm.py - 运行
python traffic_light_fsm.py - 预期输出(确定性逻辑推导):
初始: {'当前灯': '红灯', '剩余秒数': 5, '紧急模式': False}
5秒后: {'当前灯': '绿灯', '剩余秒数': 5, '紧急模式': False}
紧急触发: {'当前灯': '红灯', '剩余秒数': '紧急中', '紧急模式': True}
紧急2秒后: {'当前灯': '红灯', '剩余秒数': '紧急中', '紧急模式': True}
紧急解除: {'当前灯': '红灯', '剩余秒数': 5, '紧急模式': False}
再5秒后: {'当前灯': '绿灯', '剩余秒数': 5, '紧急模式': False}
通过标准:程序无异常退出,输出与上述顺序一致,且紧急模式期间状态不随 tick 变化,解除后正确恢复。
关键设计说明
- 状态枚举:使用
LightState枚举限定合法状态,避免非法赋值。 - 紧急模式处理:通过
prev_state和prev_remaining保存现场,解除时恢复并重置完整时长,保证时序正确。 - tick 驱动:外部每秒调用一次
tick()模拟时间推进,紧急模式下 tick 不改变任何状态。