简体   繁体   English

为什么 DecomposeLumpedParameters 会返回未简化的表达式?

[英]Why might DecomposeLumpedParameters return unsimplified expressions?

I am trying to perform system identification on an object attached to a KUKA iiwa using Drake in Python. My goal is to do lumped parameter estimation using least squares, which involves decomposing the multibody equations using symbolic.DecomposeLumpedParameters .我正在尝试使用 Python 中的 Drake 对连接到 KUKA iiwa 的 object 执行系统识别。我的目标是使用最小二乘法进行集中参数估计,这涉及使用symbolic.DecomposeLumpedParameters分解多体方程。

The issue I am running into is that the resulting symbolic equation in the parameters I am trying to estimate roughly resemble the form I would expect, however they contain terms in the denominator that could be simplified.我遇到的问题是,我试图估计的参数中生成的符号方程大致类似于我期望的形式,但是它们在分母中包含可以简化的项。 This prevents the entire equation from being simplified as a polynomial, and it returns hundreds of terms with small coefficients.这可以防止整个方程被简化为多项式,并且它会返回数百个系数较小的项。

This is challenging to deal with computationally, and it also is inconsistent in the parameters that are found for the exact same system, given different inputs for the state and velocities.这在计算上很难处理,并且在给定 state 和速度的不同输入的情况下,为完全相同的系统找到的参数也不一致。

The modified ManipulationStation I am using would be too large to put here, but the same problem occurs with a normal iiwa model in this example.我使用的修改后的 ManipulationStation 太大而无法放在这里,但在这个例子中,普通的 iiwa model 也会出现同样的问题。 Here I load up a 7-DOF iiwa as my plant, and try to estimate the parameters of the 7th link:这里我加载了一个 7-DOF iiwa 作为我的工厂,并尝试估计第 7 个链接的参数:

import numpy as np
import pydrake.symbolic as sym
from pydrake.all import (
    Parser, AddMultibodyPlantSceneGraph, SpatialInertia_, RotationalInertia_, DiagramBuilder,
    FindResourceOrThrow,
)

# Create the plant
builder = DiagramBuilder()
plant, scene_graph = AddMultibodyPlantSceneGraph(builder,
                                                 time_step=0)
Parser(plant, scene_graph).AddModelFromFile(
    FindResourceOrThrow("drake/manipulation/models/iiwa_description/sdf/iiwa14_no_collision.sdf"))
plant.WeldFrames(plant.world_frame(), plant.GetFrameByName("iiwa_link_0"))
plant.Finalize()
diagram = builder.Build()

context = plant.CreateDefaultContext()
sym_plant = plant.ToSymbolic()
sym_context = sym_plant.CreateDefaultContext()
sym_context.SetTimeStateAndParametersFrom(context)
sym_plant.FixInputPortsFrom(plant, context, sym_context)

state = sym_context.get_continuous_state()

# Random state/command inputs
# (Normally these are recorded from the robot executing a trajectory)
q = np.random.random(size=state.num_q())
v = np.random.random(size=state.num_v())
vd = np.random.random(size=state.num_v())
tau = np.random.random(size=state.num_q())  # Remove -1  for fully actuated system

# Parameters
I = sym.MakeVectorVariable(6, 'I')  # Inertia tensor/mass matrix
m = sym.Variable('m')  # mass
cx = sym.Variable('cx')  # center of mass
cy = sym.Variable('cy')
cz = sym.Variable('cz')

sym_plant.get_actuation_input_port().FixValue(sym_context, tau)
sym_plant.SetPositions(sym_context, q)
sym_plant.SetVelocities(sym_context, v)

obj = sym_plant.GetBodyByName('iiwa_link_7')
inertia = SpatialInertia_[sym.Expression].MakeFromCentralInertia(m, [cx, cy, cz],
                                                                 RotationalInertia_[sym.Expression](
                                                                     I[0], I[1], I[2], I[3], I[4], I[5]))
obj.SetSpatialInertiaInBodyFrame(sym_context, inertia)

derivatives = sym_context.Clone().get_mutable_continuous_state()
derivatives.SetFromVector(np.hstack((0 * v, vd)))
residual = sym_plant.CalcImplicitTimeDerivativesResidual(
    sym_context, derivatives)

W, alpha, w0 = sym.DecomposeLumpedParameters(residual[2:],
                                             [m, cx, cy, cz, I[0], I[1], I[2], I[3], I[4], I[5]])

return W, alpha, w0

The output I see when running this is too large to paste here, while some of the parameters are okay (ie m , m * cx , m * cy , m * cz ), the lumped parameters involving the inertial parameters are very long and contain terms with m in the denominator.运行时看到的 output 太大不能贴在这里,虽然有些参数没问题(即m , m * cx , m * cy , m * cz ),涉及惯性参数的集总参数很长,包含分母为m的项。

Here is an example of a term that could be simplified: ((7.0279621408873449 * (I(5) * m) - 7.0279621408873449 * (pow(m, 2) * cy * cz)) / m)这是一个可以简化的术语示例: ((7.0279621408873449 * (I(5) * m) - 7.0279621408873449 * (pow(m, 2) * cy * cz)) / m)

Is there a reason this may be happening, or is there a way to avoid it?是否有可能发生这种情况的原因,或者是否有办法避免这种情况? Thank you!谢谢!

I just checked the code (thanks for the reproduction).我刚刚检查了代码(感谢复制)。 The m in the denominator is happening in the MakeFromCentralInertia step.分母中的m发生在MakeFromCentralInertia步骤中。 If you add如果你添加

display(Math(ToLatex(inertia.CopyToFullMatrix6(), 2)))

right after the inertia is created, you'll see it.惯性一产生,你就会看到它。 I think we need a different way to construct that SpatialInertia .我认为我们需要一种不同的方式来构造SpatialInertia

My recommendation is to change to parameterizing the inertia with the UnitInertia instead of the RotationalInertia :我的建议是更改为使用UnitInertia而不是RotationalInertia参数化惯性:

G = sym.MakeVectorVariable(6, 'G')  # Inertia tensor/mass matrix
m = sym.Variable('m')  # mass
cx = sym.Variable('cx')  # center of mass
cy = sym.Variable('cy')
cz = sym.Variable('cz')

sym_plant.get_actuation_input_port().FixValue(sym_context, tau)
sym_plant.SetPositions(sym_context, q)
sym_plant.SetVelocities(sym_context, v)

obj = sym_plant.GetBodyByName('iiwa_link_7')
inertia = SpatialInertia_[sym.Expression](
    m, [cx, cy, cz], UnitInertia_[sym.Expression](G[0], G[1], G[2], G[3],
                                                        G[4], G[5]))
display(Math(ToLatex(inertia.CopyToFullMatrix6(), 2)))

which results in这导致符号惯性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM