如何解决如何处理 Drake 中的代数环?
我在Drake中写了一个线性系统和一个简单的状态反馈控制器的代码,但是当连接两个系统时,出现了以下错误信息,
RuntimeError: Reported algebraic loop detected in DiagramBuilder:
。然后,我用 Drake 中的 LinearSystem
替换了我的线性系统,这次程序运行了。我的线性系统建模方式有什么问题,为什么 LinearSystem
有效?
这是我的代码片段:
class SimpleContinuousTimeSystem(LeafSystem):
def __init__(self,A,B,C):
LeafSystem.__init__(self)
num_state = A.shape[0]
num_input = B.shape[1]
num_output = C.shape[0]
# Define the state vector
self.DeclareContinuousState(num_state) # Three state variables,x1,x2,x3
# Define the input
self.DeclareVectorInputPort("u",BasicVector(num_input))
# Define the output
self.DeclareVectorOutputPort("y",BasicVector(num_output),self.CalcOutputY)
self._A = A
self._B = B
self._C = C
def DoCalcTimeDerivatives(self,context,derivatives):
# Get the state vector
x = context.get_continuous_state_vector().CopyToVector()
# Get the input
u = self.get_input_port(0).Eval(context)
xdot = self._A @ x + self._B @ u
derivatives.get_mutable_vector().SetFromVector(xdot)
# y = Cx
def CalcOutputY(self,output):
x = context.get_continuous_state_vector().CopyToVector()
y = self._C @ x
output.SetFromVector(y)
class SimpleStateFeedbackController(LeafSystem):
def __init__(self,K,num_state,num_input):
LeafSystem.__init__(self)
self.DeclareVectorInputPort("x",BasicVector(num_state))
self.DeclareVectorOutputPort("u",BasicVector(num_input),self.DoCalcOutput)
self._K = K
def DoCalcOutput(self,output):
x = self.get_input_port(0).Eval(context)
u = self._K @ x
output.SetFromVector(u)
if __name__ == "__main__":
A = np.array([[-1,0],[1,-1,[0,1,0]])
B = np.array([1,1]).reshape(3,1)
C = np.identity(3)
D = np.zeros((3,1))
K = np.zeros((1,3))
# Create a simple block diagram containing our system.
builder = DiagramBuilder()
system = builder.AddSystem(SimpleContinuousTimeSystem(A,C))
# system = builder.AddSystem(LinearSystem(A,C,D,0))
controller = builder.AddSystem(SimpleStateFeedbackController(K,3,1))
builder.Connect(system.get_output_port(0),controller.get_input_port(0))
builder.Connect(controller.get_output_port(0),system.get_input_port(0))
logger = LogOutput(system.get_output_port(0),builder)
diagram = builder.Build()
# Set the initial conditions,x1(0),x2(0),x3(0)
context = diagram.CreateDefaultContext()
context.SetContinuousState([0.5,0.5,0.5])
# Create the simulator
simulator = Simulator(diagram,context)
simulator.AdvanceTo(10)
# Plot the results.
plt.figure()
plt.plot(logger.sample_times(),logger.data().transpose())
plt.xlabel('t')
plt.ylabel('y(t)')
解决方法
好问题。我绝对可以看出这是多么令人困惑。长话短说,我相信您只需要将 IndexOf 传递给您对 DeclareVectorOutputPort
的调用,该调用不包括输入端口(仅状态)。
我很确定我们在 C++ 代码中没有它的原因是 C++ 代码也支持符号标量类型,因此该图能够通过评估系统。但是你的 python 类只支持双打,所以图逻辑的内省能力有限,必须假设最坏的情况。在这种情况下,您可以简单地显式声明(非)依赖项。
恕我直言,检查 D=0 并在此处声明非依赖关系对 TimeVaryingAffineSystem
基类来说是一个很好的改进。这将避免转换为符号的重大费用。我们欢迎公关! :-)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。