Set Mass and PhysicalMaterial properties to Prim

I am unable to set the mass and apply PhysicMaterial to a Prim. Either the RigidPrim have a mass attribute but not a apply_physics_material one, or the GeometryPrim have a apply_physics_material method but no mass property…

I have reached an impasse. Has anyone a solution ?

Hi @loic.sacre

A possible practical solution is to use commands for them.
You can see the commands of the actions under the menu Window > Commands

For example:

import omni
import omni.kit.commands

stage = omni.usd.get_context().get_stage()

omni.kit.commands.execute('CreatePrimWithDefaultXform', 
                          prim_type='Cube',
	                      attributes={'size': 0.5},
	                      select_new_prim=False)
omni.kit.commands.execute('AddPhysicsComponent',
                          usd_prim=stage.GetPrimAtPath("/World/Cube"),
                          component='PhysicsCollisionAPI')

omni.kit.commands.execute('AddRigidBodyMaterialCommand', 
                          stage=stage, 
                          path='/World/PhysicsMaterial')

omni.kit.commands.execute('BindMaterialExt',
                          material_path='/World/PhysicsMaterial',
                          prim_path=['/World/Cube'],
                          strength=['weakerThanDescendants'],
                          material_purpose='physics')

Hi @toni.sm , thank you for your answer but I don’t understand how to set the mass for example.

I have forgotten to specify it but I would like to load objects dynamically in a Gym Env and randomize their physical properties.

I would like to perform something like this:

prim = GeometryPrim(prim_path=prim_path,
             position=np.array([x, y, z]),
             orientation=np.array([w, x, y, z]),
             name=name,
             scale=np.array([scale]*3))

prim.apply_physics_material(
      PhysicsMaterial(
          prim_path=self.prim_path + "/physics_material",
          static_friction=0.75,
          dynamic_friction=None,
          restitution=None
      )        
)

prim.set_mass(mass) # Exist only for RigidPrim

Hi @loic.sacre

The idea of using the commands is to do the steps manually from the UI (e.g., add the mass) and inspect the commands executed and use the ones that are necessary.

In any case, what about having an Xfrom, as a rigid prim, and parent of the geometric prim as shown below? Then, it is possible to use both APIs (apply_physics_material and set_mass), and even more, you can have several geometric prims with different geometries under see same rigid prim for more complex shapes

import numpy as np
from omni.isaac.core.utils.prims import define_prim
from omni.isaac.core.materials import PhysicsMaterial
from omni.isaac.core.prims import RigidPrim, GeometryPrim

define_prim("/rigid_prim")
define_prim("/rigid_prim/geometry_prim", prim_type="Cube")

rigid_prim = RigidPrim(prim_path="/rigid_prim",
                       position=np.array([0, 0, 0]),
                       orientation=np.array([1, 0, 0, 0]),
                       name="rigid_prim",
                       scale=np.array([1] * 3))

geometry_prim = GeometryPrim(prim_path="/rigid_prim/geometry_prim",
                             position=np.array([0, 0, 0]),
                             orientation=np.array([1, 0, 0, 0]),
                             name="geometry_prim",
                             scale=np.array([1] * 3))

geometry_prim.apply_physics_material(
      PhysicsMaterial(
          prim_path= "/rigid_prim/physics_material",
          static_friction=0.75,
          dynamic_friction=None,
          restitution=None
      )        
)

rigid_prim.set_mass(5.0)

1 Like

Hi @toni.sm, when I am following your instructions using one of my objects imported from an URDF as follows:

urdf_interface = _urdf.acquire_urdf_interface()
imported_robot = urdf_interface.parse_urdf(root_path, file_name, import_config)
init_prim_path = urdf_interface.import_robot(root_path, file_name, imported_robot, import_config, prim_path)

rigid_prim_path = "/World/envs/env_0/block02_0/"
define_prim(rigid_prim_path)
rigid_prim = RigidPrim(prim_path=rigid_prim_path,
                    position=np.array([0, 0, 0]),
                    orientation=np.array([1, 0, 0, 0]),
                    name=name + "_rigid_prim",
                    scale=np.array([1] * 3))
        
geometry_prim_path = os.path.join(rigid_prim_path, "geometry_prim")
move_prim(init_prim_path, geometry_prim_path)
geometry_prim = GeometryPrim(prim_path=geometry_prim_path,
                       position=np.array([0, 0, 0]),
                       orientation=np.array([1, 0, 0, 0]),
                             name=name+"_geometry_prim",
                             scale=np.array([1]*3))



geometry_prim.apply_physics_material(
            PhysicsMaterial(
                prim_path=os.path.join(rigid_prim_path, "physics_material"),
                static_friction=None,
                dynamic_friction=None,
                restitution=None)
)

rigid_prim.set_mass(mass)

I have the following error:

[Error] [omni.physicsschema.plugin] Rigid Body of (/World/envs/env_0/block02_0/geometry_prim/block_2_base_link) missing xformstack reset when child of rigid body (/World/envs/env_0/block02_0) in hierarchy. Simulation of multiple RigidBodyAPI's in a hierarchy will cause unpredicted results. Please fix the hierarchy or use XformStack reset.

Do you know how I could avoid it?

Follow the discussion here Give a mass to a loaded urdf

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.