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

离散回调中修改的State未在连续回调中生效,求解析

问题描述

以下是我实现的Drake LeafSystem代码:

class TestSystem(LeafSystem):
    def __init__(self, num_internal_bodies, internal_object_list):
        self.dummy_idx = self.DeclareDiscreteState(1)

        self.spatial_forces_output_port = self.DeclareAbstractOutputPort(
            "spatial_forces_output", lambda: forces_cls(),
            self.DoCalcAbstractOutput
        )

        self.DeclarePeriodicDiscreteUpdateEvent(
            period_sec=2e-3,  # 原注释有误,实际为2ms步长
            offset_sec=0.0,  # 第一个事件在t=0触发
            update=self.Update)  # 调用下方定义的Update方法


    def Update(self, context, discrete_state):
        context.get_mutable_discrete_state(self.dummy_idx).set_value([1.0])


    def DoCalcAbstractOutput(self, context, spatial_out):
        is_on = context.get_mutable_discrete_state(self.dummy_idx).value()
        # 打印is_on得到的是0.0,而非预期的1.0

我遇到的问题是:离散状态在Update方法中被设置为1.0,但在DoCalcAbstractOutput中读取到的值始终是初始的0.0,无任何报错,状态修改的结果完全没被输出计算感知到。

原因分析

这是Drake中事件执行顺序优先级导致的问题:

  • 默认情况下,DeclarePeriodicDiscreteUpdateEvent的优先级为0,输出端口的计算(DoCalcAbstractOutput)优先级也为0。
  • 初始时刻(t=0),同优先级事件按声明顺序执行——你先声明了输出端口,再声明离散更新事件,因此输出计算先执行,此时离散状态还未被Update修改,读取到的是初始值0.0。
  • 后续时间步中,如果输出计算的触发时机未依赖离散状态更新,也可能出现读取旧值的情况。

另外,DoCalcAbstractOutput中使用get_mutable_discrete_state不符合规范,该方法用于修改状态,输出计算逻辑应仅读取状态,改用get_discrete_state更合理,但这不是值不更新的核心原因。

解决方案

方案1:提高离散更新事件的优先级

声明离散更新事件时,显式设置更高优先级(如priority=1),确保它在输出计算前执行:

self.DeclarePeriodicDiscreteUpdateEvent(
    period_sec=2e-3,
    offset_sec=0.0,
    update=self.Update,
    priority=1  # 设置更高优先级
)

方案2:让输出端口依赖离散状态

通过DeclareAbstractOutputPort的dependencies参数,明确指定输出依赖离散状态,让Drake自动处理执行顺序:

self.spatial_forces_output_port = self.DeclareAbstractOutputPort(
    "spatial_forces_output", 
    lambda: forces_cls(),
    self.DoCalcAbstractOutput,
    dependencies=[self.dummy_idx]  # 声明依赖离散状态
)

方案3:修正状态读取方式(规范代码)

在DoCalcAbstractOutput中改用只读方法读取离散状态:

def DoCalcAbstractOutput(self, context, spatial_out):
    is_on = context.get_discrete_state(self.dummy_idx).value()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:12:58