【问题标题】:Sympy: 'Mul' object has no attribute 'cos' for layered functionsSympy:“Mul”对象没有分层函数的“cos”属性
【发布时间】:2019-07-15 21:50:23
【问题描述】:

总结

我有一个 Jupyter-Lab 笔记本,我一直试图用它来用 Sympy 开发机械臂的雅可比行列式。我有表达式,然后在后续表达式中使用,依此类推。我在尝试运行lambdified final 表达式时收到消息'Mul' object has no attribute 'cos'

我尝试过的

以下其他问题,例如

Sympy to numpy causes the AttributeError: 'Symbol' object has no attribute 'cos'

What causes this error (AttributeError: 'Mul' object has no attribute 'cos') in Python?

我确保使用以下方法调用 sympy:

import sympy as sp

然后使用 sp 前缀调用所有内容:

sp.cos()
sp.pi

这是我的代码(我为冗长的部分道歉)

# symbolic analysis
import sympy as sp

# Variables
theta1, theta2, theta3, theta4, theta5, theta6 = sp.symbols('theta1 theta2 theta3 theta4 theta5 theta6')
# Constants (undecided)
a1, a2, a3 = sp.symbols('a1 a2 a3')
d1, d4, d6 = sp.symbols('d1 d4 d6')
# Constants (predetermined)
d2, d3, d5, a4, a5, a6, alpha2, alpha6 = 0, 0, 0, 0, 0, 0, 0, 0
alpha1, alpha3, alpha5 = (sp.pi/2,)*3
alpha4 = -sp.pi/2

# rotation around x
def rotx(angle):
    return sp.Matrix([[1, 0, 0, 0], [0, sp.cos(angle), -sp.sin(angle), 0], [0, sp.sin(angle), sp.cos(angle), 0], [0, 0, 0, 1]])

# rotation around y
def roty(angle):
    return sp.Matrix([[sp.cos(angle), 0, sp.sin(angle), 0], [0, 1, 0, 0], [-sp.sin(angle), 0, sp.cos(angle), 0], [0, 0, 0, 1]])

# rotation around z
def rotz(angle):
    return sp.Matrix([[sp.cos(angle), -sp.sin(angle), 0, 0], [sp.sin(angle), sp.cos(angle), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])

# Translation in either x, y or z
def trans(x,y,z):
    return sp.Matrix([[1, 0, 0, x], [0, 1, 0, y], [0, 0, 0, z], [0, 0, 0, 1]])

def dh_matrix(d, theta, a, alpha):
    return trans(0,0,d)*rotz(theta)*trans(a,0,0)*rotx(alpha)

t_0_1 = dh_matrix(d1, theta1, a1, alpha1)
t_1_2 = dh_matrix(d2, theta2, a2, alpha2)
t_2_3 = dh_matrix(d3, theta3, a3, alpha3)
t_3_4 = dh_matrix(d4, theta4, a4, alpha4)
t_4_5 = dh_matrix(d5, theta5, a5, alpha5)
t_5_6 = dh_matrix(d6, theta6, a6, alpha6)
t_0_6 = t_0_1 * t_1_2 * t_2_3 * t_3_4 * t_4_5 * t_5_6

last_column = t_0_6.col(-1)
x = last_column.row(0)
y = last_column.row(1)
z = last_column.row(2)

# Partial derivatives of x
dxd1 = sp.diff(x,theta1)
dxd2 = sp.diff(x,theta2)
dxd3 = sp.diff(x,theta3)
dxd4 = sp.diff(x,theta4)
dxd5 = sp.diff(x,theta5)
dxd6 = sp.diff(x,theta6)
# Partial derivates of y
dyd1 = sp.diff(y,theta1)
dyd2 = sp.diff(y,theta2)
dyd3 = sp.diff(y,theta3)
dyd4 = sp.diff(y,theta4)
dyd5 = sp.diff(y,theta5)
dyd6 = sp.diff(y,theta6)
# Partial derivates of z
dzd1 = sp.diff(z,theta1)
dzd2 = sp.diff(z,theta2)
dzd3 = sp.diff(z,theta3)
dzd4 = sp.diff(z,theta4)
dzd5 = sp.diff(z,theta5)
dzd6 = sp.diff(z,theta6)

jacobian = sp.Matrix([[dxd1,dxd2,dxd3,dxd4,dxd5,dxd6], [dyd1,dyd2,dyd3,dyd4,dyd5,dyd6], [dzd1,dzd2,dzd3,dzd4,dzd5,dzd6]])
jacobian_numeric = sp.lambdify([theta1,theta2,theta3,theta4,theta5,theta6,a1,a2,a3,d1,d4,d6],jacobian)
jacobian_numeric(0,sp.pi/2,0,0,0,0,0,0,0,1,0.3,0.1)

预期输出

包含数值的 3x6 矩阵

实际输出

以下错误归因于最后一行:

AttributeError: 'Mul' 对象没有属性 'cos'

我认为这与我如何将函数和多个表达式组合在一起有关,但我不太确定如何确定它到底在哪里失败。

追溯

它有点巨大;我用...删除了表达式的其余部分

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-21-d0f45c1787c2> in <module>
----> 1 current_jacobian = jacobian_numeric(0,sp.pi/2,0,0,0,0,0,0,0,1,0.3,0.1) # add pi/2 to theta2 because of the initial offset between x_2 and x_3
      2 current_jacobian

<lambdifygenerated-1> in _lambdifygenerated(theta1, theta2, theta3, theta4, theta5, theta6, a1, a2, a3, d1, d4, d6)
      1 def _lambdifygenerated(theta1, theta2, theta3, theta4, theta5, theta6, a1, a2, a3, d1, d4, d6):
----> 2     return (array([[array([[-a1*sin(theta1) - a2*sin(theta1)*cos(theta2) + a3*sin(theta1)*sin(theta2)*sin(theta3) - a3*sin(theta1)*cos(theta2)*cos(theta3) +...

AttributeError: 'Mul' object has no attribute 'cos'

【问题讨论】:

  • 欢迎来到 StackOverflow!你能添加回溯吗?
  • 添加回溯到最初的问题,减去我用...切断的其余表达式

标签: python jupyter sympy


【解决方案1】:

我不完全确定为什么,但是当我在代码 jacobian_numeric(0,np.pi/2,0,0,0,0,0,0,0,1,0.3,0.1) 的最后一行将 sp.pi 替换为 np.pi 时,错误消失了。我已经看到了其他几个类似问题的问题,但目前没有很好的答案。这可能是simpy 中的一个错误,或者希望其他人有更好的解释。

【讨论】:

  • 哇,这非常简单,谢谢!我想知道是不是因为,一旦lambdify-ed,应该只提供数值作为表达式jacobian_numeric 的参数,而sp.pi 是符号
  • 带有符号的 numpy 数组将具有 object dtype。 np.cos 将计算委托给每个对象的 cos 方法。
【解决方案2】:

使用lambdify 创建可执行函数后,您将不再处于sympy 的“符号数学”世界中,并且必须传入数值,而不是符号值。

您可以将来自 numpy 的 ? 传递为 np.pi(正如您在 BenT 的回答中指出的那样),或者您可以将来自 sympy 的 ? 数值评估为 sp.N(sp.pi)N 函数将符号值转换为数字值,包括像?这样的值。

【讨论】:

  • 这提供了与@BenT 相同的“什么”,但提供了一个非常受欢迎的“为什么”。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
  • 2013-04-29
  • 2020-01-27
相关资源
最近更新 更多