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

适配Drake变量的numpy.sign()与numpy.clip()替代方案咨询

Drake中处理符号变量的sign与clip替代方案

问题描述

当尝试用numpy的np.sign()和np.clip()处理Drake的符号变量时会触发报错,示例代码如下:

from pydrake.all import Variable
q = Variable('q')
u = 1 + np.sign(q) # 无法运行
u = 1 + np.clip(q, -1, 1) # 无法运行
# 将u传入SymbolicVectorSystem的动力学模型

报错信息:

RuntimeError: You should not call __bool__ / __nonzero__ on Formula. If you are trying to make a map with Variable, Expression, or Polynomial as keys (and then access the map in Python), please use pydrake.common.containers.EqualToDict`.

错误原因

numpy的sign和clip函数内部会尝试对输入值进行布尔判断(比如判断是否大于0),而Drake的符号变量(Variable/Expression)对应的Formula对象不允许直接调用__bool__方法——符号表达式在未赋值前无法确定布尔值,因此触发了上述错误。

解决方案

1. 符号表达式层面直接实现(最简便)

无需额外搭建系统模块,直接用Drake的IfThenElse函数构建等价的符号表达式,生成的结果可直接传入SymbolicVectorSystem的动力学模型:

  • sign函数等价实现:
    from pydrake.all import IfThenElse, Variable
    q = Variable('q')
    sign_q = IfThenElse(q > 0, 1, IfThenElse(q < 0, -1, 0))
    u = 1 + sign_q
    
  • clip函数等价实现:
    clip_q = IfThenElse(q > 1, 1, IfThenElse(q < -1, -1, q))
    u = 1 + clip_q
    

2. 系统模块层面组合(适合复杂系统拆分)

如果需要将功能作为独立模块嵌入系统,可使用Drake内置模块:

  • 饱和函数(clip等价):直接用Saturation模块,无需手动搭建:
    from pydrake.all import Saturation
    saturation = Saturation(min_value=-1, max_value=1)
    # 将saturation模块与其他系统连接
    
  • 符号函数:可以用PiecewiseAffineSystem实现分段线性的符号函数,或者用上述IfThenElse表达式构建SymbolicVectorSystem作为独立模块,比port switch的方式更直接。

方案对比

  • 符号表达式层面的实现最简洁,适合将函数直接嵌入动力学方程或控制器的符号表达式中,是这类场景的最优解。
  • 系统模块层面的拆分适合需要功能模块化复用的复杂系统,你考虑的port switch+Saturation方式可行,但并非最简便的选择。

内容的提问来源于stack exchange,提问作者Shao Yuan Chew Chia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:27:54