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 上面警告的那样,您需要谨慎处理此配对。
我想要在同一个构建器和场景图中有两个植物。 (我不希望它们在同一个工厂,因为我想分离它们的动态,但我希望它们相互影响,因此使它们保持在同一个构建器和场景图上。)
我的实现如下:
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 上面警告的那样,您需要谨慎处理此配对。