0

在 MIT6.832 HW2 "Cart-Pole: Linearization and LQR Balncing" 中,carpole 定义为:

# instantiate the cart-pole and the scene graph
cartpole, scene_graph = AddMultibodyPlantSceneGraph(builder, time_step=0.0)
urdf_path = FindResource('models/undamped_cartpole.urdf')
Parser(cartpole).AddModelFromFile(urdf_path)
cartpole.Finalize()

稍后,carpole 的驱动输入端口设置为 0:

# fix the input port to zero and get its index for the lqr function
cartpole.get_actuation_input_port().FixValue(context, [0])
input_i = cartpole.get_actuation_input_port().get_index() # input_i = 3

但是,输入端口的索引是 3,而不是 0,这让我很困惑。


这里一个额外的相关问题是,当定义一个新系统时(例如,继承自 VectorSystem),我们可以在哪里定义输入和输出端口?

我一直在研究 HW1 的 Cartpole 模型,发现端口的使用非常混乱。有时它使用get_xxx_port(),而在其他情况下它使用get_xxx_port(0),括号内有一个特定的端口号。

4

1 回答 1

0

这是一个非常合理的问题。

drake 中的系统可以有多个输入端口(或没有输入端口)。通常,可以使用该get_input_port(index)方法访问它们。但是,如果您正在构建一个具有多个输入的更复杂的系统,例如MultibodyPlant,那么您不需要通过某些索引来区分不同的输入端口,而是通过名称来区分。如此多的系统为自己添加了额外的方法,这些方法提供了访问同一端口的额外方法。例如MultibodyPlant提供(c++ 等价物)

def get_actuation_input_port():
  return get_input_port(3)

这样就没有人需要记住扭矩进入端口 3。但是您可以使用任何一种方法获得对端口的引用。

与端口索引不同,我们需要能够在给定上下文的情况下评估系统的输入端口。当端口在图表中“连接”到另一个系统时,类似的调用u = cartpole.get_actuation_input_port().Eval(context)将调用另一个系统的输出方法。但是能够将输入设置为常量值也很有用,因此我们也提供了该接口。这就是您上面的代码段中发生的事情:

cartpole.get_actuation_input_port().FixValue(context, [0])

这一行将上下文中输入端口的值设置为一个向量——这里恰好是一个大小为 1 的向量,唯一的元素为零。对于一个有四个执行器的机器人,它可能是

my_robot.get_actuation_input_port().FixValue(context, [0, 0, 0, 0])
于 2020-04-21T22:10:54.480 回答