从 pydrake 中的成本或约束中检索符号函数

Retrieve symbolic function from cost or constraint in pydrake

我显然有一个足够复杂的约束函数,仅调用 prog.AddConstraint() 就需要超过 1 分钟,大概是因为它花费了很长时间来构造符号函数(尽管如果您有其他见解,为什么需要这么长时间很长一段时间,我将不胜感激)。我想做的是拉出符号约束函数并缓存它,这样一旦它被创建,我不需要等待 1 分钟,它可以直接从磁盘加载它。

我的问题是我不知道如何访问该功能。打印时我可以清楚地看到表达式,例如在这个简化的示例中:

from pydrake.all import MathematicalProgram

prog = MathematicalProgram()
x = prog.NewContinuousVariables(2, "x")
c = prog.AddConstraint(x[0] * x[1] == 1)
print(c)

我得到输出:

ExpressionConstraint
0 <= (-1 + (x(0) * x(1))) <= 0

我知道我可以解析那个字符串并提取出代表函数的部分,但似乎应该有更好的方法来做到这一点?我想我可以提取表达式函数和 upper/lower 边界,然后在我的 AddConstraint 调用中使用它。

在我的实际用例中,我需要对轨迹中的多个时间步应用相同的约束,所以我认为在我第一次调用 AddConstraint 时创建一次符号函数会很有帮助timestep 然后所有后续时间步不必重新创建符号函数,我可以只使用缓存版本并将其应用于相关变量。该表达式涉及协方差矩阵的 Cholesky 分解,因此应用了很多约束条件。

非常感谢任何帮助。

In my real use-case, I need to apply the same constraint to multiple timesteps in a trajectory, so I think it would be helpful to create the symbolic function once when I call AddConstraint for the first timestep and then all subsequent timesteps shouldn't have to re-create the symbolic function, I can just use the cached version and apply it to the relevant variables. The expression involves a Cholesky decomposition of a covariance matrix so there are a lot of constraints being applied.

我强烈建议使用函数求值而不是符号表达式来编写此约束。一个例子是,如果你想强加约束lb <= my_evaluator(x) <= ub,那么你可以这样调用它

def my_evaluator(x):
    # Do Cholesky decomposition and other things to evaluate it. Return the evaluation result.
    return result

prog.AddConstraint(my_evaluator, lb, ub, x)

当您的约束在决策变量中是线性的时,使用符号表达式添加约束很方便,否则最好避免使用符号表达式添加约束。 (计算一个符号表达式,尤其是涉及 Cholesky 分解的表达式,真的很耗时)。

有关添加通用非线性约束的更多详细信息,您可以参考我们的tutorial