当创建一个具有le
或ge
且左手边为标量的公式时,返回的公式具有.shape == ()
,即为未大小对象。这会在向公式中添加约束时引发问题。
我不确定这是不是一个bug。
prog = MathematicalProgram()
q = prog.NewContinuousVariables(1, 'q')
z = prog.NewContinuousVariables(2, 'z')
r = prog.NewContinuousVariables(rows=2, cols=3, name='r')
constraint = prog.AddConstraint(le(q, r[0,2] + 2*r[1,0])) # works
constraint2 = prog.AddConstraint(z[1] <= r[0,2] + 2*r[1,0]) # works
# constraint2 = prog.AddConstraint(le(z[1], r[0,2] + 2*r[1,0])) # fails
constraint2 = prog.AddConstraint(le([z[1]], r[0,2] + 2*r[1,0])) # works
formula = le(z[1], r[0,2] + 2*r[1,0])
print(formula.shape)
# > ()
TL;DR
目前,您可用的解决方案:
- 重新格式化为严格的向量值(正如您所做的那样(
- 传递直接对象值(使用
ndarray.item
( - 将标量数组重新整形/取消缩放为一维数组
还将发布德雷克问题。
Longform
宋浩的帖子总体上是正确的,有一些小的更正:
le(x, y)
是np.asarray(x) <= np.asarray(y)
的另一种书写方式。(参见:图纸#11171,numpy.vectorize
文档(- 虽然它确实是不可迭代的,但这并不是重要的部分。更重要的部分是CCD_;标量阵列";
array(<Formula>, dtype=object)
- 如前所述,这是一个0维数组(空形状(;然而;空数组";可能有点用词不当,因为它有数据。您可以使用
np.item()
检索内容 - 同样正确。然而,这里的细微差别是
np.vectorize
将返回"0";标量阵列";,而这些反过来又不能由我们使用CCD_ 12的Python绑定来解释
对于第(4(点,我在夜间drake-20201104-bionic.tar.gz
上重新运行了您的示例,并得到了以下错误消息:
TypeError: AddConstraint(): incompatible function arguments. The following argument types are supported:
1. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, func: function, lb: numpy.ndarray[numpy.float64[m, 1]], ub: numpy.ndarray[numpy.float64[m, 1]], vars: numpy.ndarray[object[m, 1]], description: str = '') -> drake::solvers::Binding<drake::solvers::Constraint>
2. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, arg0: pydrake.symbolic.Expression, arg1: float, arg2: float) -> drake::solvers::Binding<drake::solvers::Constraint>
3. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, arg0: pydrake.symbolic.Formula) -> drake::solvers::Binding<drake::solvers::Constraint>
4. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, constraint: drake::solvers::Constraint, vars: numpy.ndarray[object[m, 1]]) -> drake::solvers::Binding<drake::solvers::Constraint>
5. (self: pydrake.solvers.mathematicalprogram.MathematicalProgram, formulas: numpy.ndarray[object[m, n], flags.f_contiguous]) -> drake::solvers::Binding<drake::solvers::Constraint>
Invoked with: <pydrake.solvers.mathematicalprogram.MathematicalProgram object at 0x7f6eb081cdf0>, array(<Formula "(z(1) <= (2 * r(1,0) + r(0,2)))">, dtype=object)
需要注意的最重要的一点是,重载(3(可能捕获了原始标量<Formula>
,而(5(可能捕获1维或2维数组,但都没有设置为捕获array(<Formula>)
。
这或多或少是pydrake
和/或pybind11
的问题。我现在将提交一份德雷克问题。
FWIW我发布了一个NumPy问题,询问0-dim数组的正确术语:
https://github.com/numpy/numpy/issues/17744
le(x,y)
是编写np.array(x <= y)
的另一种方式- CCD_ 20形成了一个不可迭代的符号公式
- 结果,
np.array(x <= y)
创建了一个空数组。你可以通过检查它的形状(()
(或尝试np.array(x <= y)[0]
(这会给你一个错误(来判断这一点 - 这并不是德雷克象征性的具体表现。
np.array(42)
会给您一个空数组