首页 > 解决方案 > 在 pyDrake 中将两个植物添加到场景图中时出现 Python 绑定错误

问题描述

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

我的实现如下:

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

提前感谢您的任何想法。

标签: pybind11drake

解决方案


这是绑定问题吗?

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

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

所以,这是一个绑定错误,因为错误消息有点糟糕;然而,它更多的是带有 C++ API 的语义问题。

的文档AddMultibodyPlantSceneGraph使它看起来好像可以将植物添加到已经存在的场景中。

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

对于您的用例,您应该只添加SceneGraphDiagramBuilder one。由于您想将一个实例连接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)

正如肖恩在上面警告的那样,你需要小心这个配对。


推荐阅读