从 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
我显然有一个足够复杂的约束函数,仅调用 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