Python 在 pyDrake 中将两个植物添加到场景图时出现绑定错误

Python bindings error when adding two plants to a scene graph in pyDrake

我想要在同一个构建器和场景图中有两个植物。 (我不希望它们在同一个工厂,因为我想分离它们的动态,但我希望它们相互影响,因此使它们保持在同一个构建器和场景图上。)

我的实现如下:

from pydrake.multibody.plant import AddMultibodyPlantSceneGraph
from pydrake.systems.framework import DiagramBuilder

builder = DiagramBuilder()
plant1, scene_graph  = AddMultibodyPlantSceneGraph(builder, 0.0)
plant2  = AddMultibodyPlantSceneGraph(builder, 0.0, scene_graph)

当我运行这个时,我得到错误:

Traceback (most recent call last):
  File "/filepath/2plants1scene.py", line 6, in <module>
    plant2  = AddMultibodyPlantSceneGraph(builder, 0.0, scene_graph)
RuntimeError: C++ object must be owned by pybind11 when attempting to release to C++

这是绑定问题吗? AddMultibodyPlantSceneGraph 的文档使它看起来好像可以将植物添加到现有场景中。

错误消息看起来类似于 2018 年的这个问题:https://github.com/RobotLocomotion/drake/issues/8160

提前感谢您的任何想法。

Is this a bindings issue?

关于您的特定错误消息,您正试图获取一个对象(其所有权受 unique_ptr<> 管辖)并试图将其从其拥有的数据中传递出去两次 (或更多)。

来自 C++ API:
https://drake.mit.edu/doxygen_cxx/classdrake_1_1multibody_1_1_multibody_plant.html#aac66563a5f3eb9e2041bd4fa8d438827 请注意,scene_graph 参数是 unique_ptr<>.

因此,就错误消息而言,这是一个绑定错误;然而,它更像是一个语义问题 w/ C++ API.

The documentation for AddMultibodyPlantSceneGraph makes it seem as though it can add plants to already existing scenes.

作为参考,这里是该方法的核心实现:
https://github.com/RobotLocomotion/drake/blob/v0.32.0/multibody/plant/multibody_plant.cc#L3346-L3370

对于您的用例,您应该只将 SceneGraph 添加到 DiagramBuilder 一次 。由于您想将一个 SceneGraph 连接到多个 MultibodyPlant 实例,我建议您不要使用 AddMultibodyPlantSceneGraph,因为它是 1:1 配对的糖分。

相反,您应该手动注册并连接 SceneGraph;我认为它看起来像这样:

def register_plant_with_scene_graph(scene_graph, plant):
    plant.RegsterAsSourceForSceneGraph(scene_graph)
    builder.Connect(
        plant.get_geometry_poses_output_port(),
        scene_graph.get_source_pose_port(plant.get_source_id()),
    )
    builder.Connect(
        scene_graph.get_query_output_port(),
        plant.get_geometry_query_input_port(),
    )

builder = DiagramBuilder()
scene_graph = builder.AddSystem(SceneGraph())
plant_1 = builder.AddSystem(MultibodyPlant(time_step=0.0))
register_plant_with_scene_graph(scene_graph, plant_1)
plant_2 = builder.AddSystem(MultibodyPlant(time_step=0.0))
register_plant_with_scene_graph(scene_graph, plant_2)

正如 Sean 上面警告的那样,您需要谨慎处理此配对。