Mapping body IDs after using multiple newton model builders compositionally #3108
|
I'm trying to use newton model builders in a compositional manner by having a scene level model builder followed by model builders for each robot, individual asset etc. However when I make free floating objects like a floating box in the code below, after creating a robot arm builder, the body ID returned to me is is there a easy way to map the builders/bodies we make to the actual body ids we need once we run the simulation and want to fetch data from self.scene = newton.ModelBuilder()
# code to create a FR3 robot arm model builder and then add it to self.scene with add_builder
builder = newton.ModelBuilder()
body = builder.add_body(
xform=wp.transform(wp.vec3(0.3, 0.0, 0.7), wp.quat_identity()),
)
self.body = body
print("BODY:", self.body) # this prints 0, which in the global model state during simulation is incorrect?
builder.add_shape_box(
body=self.body,
hx=0.1,
hy=0.1,
hz=0.1,
cfg=newton.ModelBuilder.ShapeConfig(mu=0.3),
)
self.scene.add_builder(builder)
builder = newton.ModelBuilder()
builder.add_ground_plane(cfg=newton.ModelBuilder.ShapeConfig(mu=0.3))
self.scene.add_builder(builder) |
Replies: 2 comments 1 reply
|
My own workaround at the moment is to use this value as the body ID immediately after adding a builder to my root scene model builder self.body = len(self.scene.body_q) - 1not sure if this is how newton is intended to be used, but going off of the newton tutorials/examples alone I didn't figure this out until some trial and error later. Definitely like the compositional aspect of the model builders though! I imagine if I am adding a complex articulation I would need to count the DOFs to get the correct body ids and map them accordingly, which might get more untuitive. |
|
The body id you get from self.scene = newton.ModelBuilder()
# code to create a FR3 robot arm model builder and then add it to self.scene with add_builder
builder = newton.ModelBuilder()
body = builder.add_body(
xform=wp.transform(wp.vec3(0.3, 0.0, 0.7), wp.quat_identity()),
)
# Make sure you offset the body index of the number of bodies that are already in the global scene builder
# to get the correct global body index:
self.body = body + self.scene.body_count
self.scene.add_builder(builder)
...Another option is to assign a unique label to this body you are adding: self.scene = newton.ModelBuilder()
# code to create a FR3 robot arm model builder and then add it to self.scene with add_builder
builder = newton.ModelBuilder()
body = builder.add_body(
xform=wp.transform(wp.vec3(0.3, 0.0, 0.7), wp.quat_identity()),
label="my_body",
)
self.scene.add_builder(builder)
...
self.body = self.scene.body_label.index("my_body") |
The body id you get from
ModelBuilder.add_body()is always the local index of the body within that ModelBuilder.When you compose builders using a
sceneModelBuilder, you can increment the body index by the number of bodies (ModelBuilder.body_count) that come before it in the scene from the other builders: