You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带计时器重置的有限状态机:车库门智能家居集成状态同步问题

解决方案:基于时间追踪的FSM优化实现

核心思路是通过追踪状态时间戳和延迟关闭任务队列,完全模拟实际车库门的物理行为,解决无状态反馈下的特殊场景同步问题。以下是具体实现方案:


关键设计点

  1. 时间戳追踪:记录每个状态的开始时间,用于计算状态剩余时长
  2. 延迟关闭任务:用户触发关闭时,不立即切换状态,而是计算需要等待的总时长(当前状态剩余时间 + 保持开启时间 + 关闭时间),到点后再进入关闭状态
  3. 优先级处理:待执行的关闭任务优先于自动状态流转,确保用户操作覆盖默认行为

完整伪代码实现

import time

# 常量定义(匹配实际门的物理参数)
OPENING_DUR = 14.5  # 开门耗时(秒)
OPEN_HOLD_DUR = 40  # 保持开启时长(秒)
CLOSING_DUR = 14    # 关门耗时(秒)

# 状态枚举
class GarageDoorState:
    CLOSED = "closed"
    OPENING = "opening"
    OPEN = "open"
    CLOSING = "closing"

# 状态管理核心变量
current_state = GarageDoorState.CLOSED
state_start_time = 0  # 当前状态开始的时间戳(time.time())
pending_close_trigger_time = None  # 用户触发关闭的时间戳
pending_close_total_delay = None   # 触发关闭后需等待的总时长(直到进入Closing状态)

def send_rf_open_signal():
    """发送RF开门信号的实际执行逻辑"""
    print("[Hardware] Sending RF open signal...")

def trigger_open():
    """用户通过智能家居触发开门操作"""
    global current_state, state_start_time, pending_close_trigger_time, pending_close_total_delay
    if current_state != GarageDoorState.CLOSED:
        return  # 非关闭状态下不重复触发开门
    
    send_rf_open_signal()
    current_state = GarageDoorState.OPENING
    state_start_time = time.time()
    # 取消之前的待关闭任务
    pending_close_trigger_time = None
    pending_close_total_delay = None

def trigger_close():
    """用户通过智能家居触发关闭操作(实际门不会立即响应)"""
    global pending_close_trigger_time, pending_close_total_delay
    now = time.time()

    # 已关闭或正在关闭时,无需操作
    if current_state in [GarageDoorState.CLOSED, GarageDoorState.CLOSING]:
        return

    # 计算从触发关闭到进入Closing状态的总等待时长
    total_wait = 0
    if current_state == GarageDoorState.OPENING:
        # 剩余开门时长 + 保持开启时长 + 关门时长
        elapsed_opening = now - state_start_time
        remaining_opening = max(0.0, OPENING_DUR - elapsed_opening)
        total_wait = remaining_opening + OPEN_HOLD_DUR + CLOSING_DUR
    elif current_state == GarageDoorState.OPEN:
        # 剩余保持时长 + 关门时长
        elapsed_hold = now - state_start_time
        remaining_hold = max(0.0, OPEN_HOLD_DUR - elapsed_hold)
        total_wait = remaining_hold + CLOSING_DUR

    # 记录关闭任务参数
    pending_close_trigger_time = now
    pending_close_total_delay = total_wait

def update_state():
    """每间隔固定时间(如0.1s)调用,更新FSM状态"""
    global current_state, state_start_time, pending_close_trigger_time, pending_close_total_delay
    now = time.time()

    # 优先处理待执行的关闭任务
    if pending_close_trigger_time is not None:
        elapsed_since_trigger = now - pending_close_trigger_time
        if elapsed_since_trigger >= pending_close_total_delay:
            # 到达延迟时间,进入Closing状态
            current_state = GarageDoorState.CLOSING
            state_start_time = now
            # 清空待关闭任务
            pending_close_trigger_time = None
            pending_close_total_delay = None
        return  # 有pending任务时,跳过自动状态流转

    # 自动状态流转逻辑(模拟门的默认行为)
    if current_state == GarageDoorState.OPENING:
        elapsed = now - state_start_time
        if elapsed >= OPENING_DUR:
            current_state = GarageDoorState.OPEN
            state_start_time = now
    elif current_state == GarageDoorState.OPEN:
        elapsed = now - state_start_time
        if elapsed >= OPEN_HOLD_DUR:
            current_state = GarageDoorState.CLOSING
            state_start_time = now
    elif current_state == GarageDoorState.CLOSING:
        elapsed = now - state_start_time
        if elapsed >= CLOSING_DUR:
            current_state = GarageDoorState.CLOSED
            state_start_time = now

# 主循环示例
while True:
    update_state()
    print(f"Current FSM State: {current_state}")
    time.sleep(0.1)

特殊场景验证

  1. 刚触发开门就关闭:调用trigger_open后立即执行trigger_close,计算总等待时长为14.5+40+14=68.5s,到期后进入Closing状态,完全匹配实际门的行为
  2. Opening中途关闭:开门5秒后触发关闭,剩余开门时长9.5s,总等待时长9.5+40+14=63.5s,到期后进入Closing,同步实际门的剩余开门→保持→关闭流程
  3. Open状态中途关闭:保持开启10秒后触发关闭,剩余保持时长30s,总等待时长30+14=44s,到期后进入Closing,模拟实际门的剩余保持→关闭流程
  4. 自动关闭:Open状态保持40秒后,自动进入Closing状态,14秒后回到Closed,符合门的默认自动关闭逻辑

内容的提问来源于stack exchange,提问作者LuMa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:15:57