代数环错误 - 帮助修复虚假依赖
Algebraic loop error - help fixing spurious dependency
tldr:为什么我的工厂被标记为直接馈通,我如何覆盖此标签?
我在 Drake 中创建了一个工厂,它接受电压输入 phi
并使用它加上系统状态 Lam
来计算其导数 Lam_d
。然后我将系统插入 FittedValueIteration
以生成我的控制策略。值迭代成功地生成了一个策略(经过检查,它看起来非常合理),但是当我尝试使用图表构建器将它连接到我的系统时,我收到以下消息,表明我有直接馈通:
RuntimeError: Reported algebraic loop detected in DiagramBuilder:
InputPort[0] (phi) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>) is direct-feedthrough to
OutputPort[0] (Lam) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>) is connected to
InputPort[0] (u0) of System ::drake/systems/BarycentricMeshSystem@0000000005c6d300 (BarycentricMeshSystem<double>) is direct-feedthrough to
OutputPort[0] (y0) of System ::drake/systems/BarycentricMeshSystem@0000000005c6d300 (BarycentricMeshSystem<double>) is connected to
InputPort[0] (phi) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>)
我相信 vi_policy(错误消息中引用的重心网格)确实存在直接馈通,因为它只是进入一个状态并根据该状态吐出输出。然而,我的工厂使用控制器的输入来产生加速度,所以我对它被标记的原因感到困惑。我的工厂如下图,供参考:
class DEAContinuousSys(LeafSystem):
def __init__(self):
LeafSystem.__init__(self)
self.DeclareContinuousState(2) # two state variables: lam, lam_d
self.DeclareVectorOutputPort('Lam', BasicVector(2), self.CopyStateOut) # two outputs: lam_d, lam_dd
self.input_port = self.DeclareVectorInputPort('phi', BasicVector(1))
def DoCalcTimeDerivatives(self, context, derivatives):
Lam = context.get_continuous_state_vector().get_value() # get state, cast as regular array
phi = self.input_port.Eval(context)
Lam_d = DEA.dynamics(Lam, None, phi) # derive acceleration (no timestep required)
derivatives.get_mutable_vector().SetAtIndex(0, Lam_d[0]) # set velocity
derivatives.get_mutable_vector().SetAtIndex(1, Lam_d[1]) # set acceleration
def CopyStateOut(self, context, output):
Lam = context.get_continuous_state_vector().CopyToVector()
output.SetFromVector(Lam)
我认为这个直接馈通通知是错误的,但我在解析文档以解决此问题时遇到了问题。所以我还在想办法:
- 为什么将其标记为直接馈通?
- 如何添加标签以表明它不是直接馈通?有什么好的例子可以参考吗?
编辑:重新阅读文档,我看到 1. 的答案是默认所有 LeafSystems 都将设置为直接馈通以避免意外循环。如果我的植物是符号表达的简单组合,它就可以得到正确的解释。
默认情况下,OutputPort
的声明依赖于所有 来源——包括输入端口。看来您的输出端口仅取决于您的连续状态。您可以修改您的声明以明确拼写出来。那应该会让你的代数环消失。
尝试:
self.DeclareVectorOutputPort('Lam', BasicVector(2), self.CopyStateOut,
prerequisites_of_calc=set([self.xc_ticket()]))
(我不是 100% 肯定 pydrake 的拼写,但我还是会花钱买这个。)
tldr:为什么我的工厂被标记为直接馈通,我如何覆盖此标签?
我在 Drake 中创建了一个工厂,它接受电压输入 phi
并使用它加上系统状态 Lam
来计算其导数 Lam_d
。然后我将系统插入 FittedValueIteration
以生成我的控制策略。值迭代成功地生成了一个策略(经过检查,它看起来非常合理),但是当我尝试使用图表构建器将它连接到我的系统时,我收到以下消息,表明我有直接馈通:
RuntimeError: Reported algebraic loop detected in DiagramBuilder:
InputPort[0] (phi) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>) is direct-feedthrough to
OutputPort[0] (Lam) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>) is connected to
InputPort[0] (u0) of System ::drake/systems/BarycentricMeshSystem@0000000005c6d300 (BarycentricMeshSystem<double>) is direct-feedthrough to
OutputPort[0] (y0) of System ::drake/systems/BarycentricMeshSystem@0000000005c6d300 (BarycentricMeshSystem<double>) is connected to
InputPort[0] (phi) of System ::drake/pydrake/(anonymous)/Impl@000000000648eec0 (Impl<double>::PyLeafSystemBase<drake::pydrake::(anonymous)::Impl<double>::LeafSystemPublic>)
我相信 vi_policy(错误消息中引用的重心网格)确实存在直接馈通,因为它只是进入一个状态并根据该状态吐出输出。然而,我的工厂使用控制器的输入来产生加速度,所以我对它被标记的原因感到困惑。我的工厂如下图,供参考:
class DEAContinuousSys(LeafSystem):
def __init__(self):
LeafSystem.__init__(self)
self.DeclareContinuousState(2) # two state variables: lam, lam_d
self.DeclareVectorOutputPort('Lam', BasicVector(2), self.CopyStateOut) # two outputs: lam_d, lam_dd
self.input_port = self.DeclareVectorInputPort('phi', BasicVector(1))
def DoCalcTimeDerivatives(self, context, derivatives):
Lam = context.get_continuous_state_vector().get_value() # get state, cast as regular array
phi = self.input_port.Eval(context)
Lam_d = DEA.dynamics(Lam, None, phi) # derive acceleration (no timestep required)
derivatives.get_mutable_vector().SetAtIndex(0, Lam_d[0]) # set velocity
derivatives.get_mutable_vector().SetAtIndex(1, Lam_d[1]) # set acceleration
def CopyStateOut(self, context, output):
Lam = context.get_continuous_state_vector().CopyToVector()
output.SetFromVector(Lam)
我认为这个直接馈通通知是错误的,但我在解析文档以解决此问题时遇到了问题。所以我还在想办法:
- 为什么将其标记为直接馈通?
- 如何添加标签以表明它不是直接馈通?有什么好的例子可以参考吗?
编辑:重新阅读文档,我看到 1. 的答案是默认所有 LeafSystems 都将设置为直接馈通以避免意外循环。如果我的植物是符号表达的简单组合,它就可以得到正确的解释。
默认情况下,OutputPort
的声明依赖于所有 来源——包括输入端口。看来您的输出端口仅取决于您的连续状态。您可以修改您的声明以明确拼写出来。那应该会让你的代数环消失。
尝试:
self.DeclareVectorOutputPort('Lam', BasicVector(2), self.CopyStateOut,
prerequisites_of_calc=set([self.xc_ticket()]))
(我不是 100% 肯定 pydrake 的拼写,但我还是会花钱买这个。)