Ag.get_character() does not work when trying to run as an extension

Hi!

Much like People animations in Standalone App - Omniverse / Isaac Sim - NVIDIA Developer Forums I’m trying to get a navmesh loaded and a character moving to a desired goal via animations. However, unlike the previous post, instead of a standalone app I’m building an extension using the scripting template ( 3.1. Isaac Sim Extension Templates — Omniverse IsaacSim latest documentation (nvidia.com))

Prior to running the Run scenario method, and within the setup scenario method I’ve managed to load the standard biped setup asset and a sample character in the environment. I have also programmatically assigned both the character_behavior Python script, and an animation graph from the biped setup to the corresponding skeleton root.

However, on clicking the RUN method of my extension (or even the play button on the left), the character_behavior.py script continues to fail since it can’t succesfully call init_character() due to not being able to obtain the active character instance (Line 113 of character_behavior.py), and thus on_update() within the script keeps failing…

Since it seems like I can’t call ag.get_character() during setup when paused, how do I go about getting this to work? (Navmesh and character script work as expected when loading my mesh manually via the GUI). Do I need to explicitly initialise action graph somehow?

Thanks!

This is the block of code I use to programmatically add the two components to the SkelRoot

f self._biped_setup_prim is None:
            add_reference_to_stage(self._biped_usd_path, self._biped_setup_prim_path)
            biped_xform = XFormPrim(self._biped_setup_prim_path)
            biped_xform.set_world_pose(
                position=[0, 0, 0], orientation=[0.70711, 0.70711, 0, 0]
            )
            self._biped_setup_prim = self._stage.GetPrimAtPath(
                self._biped_setup_prim_path
            )

            self._biped_setup_prim.GetAttribute("visibility").Set("invisible")

        # Load the character USD
        add_reference_to_stage(
            self._character_path_dict[character_name],
            f"/World/Character_{self._character_count}",
        )

        # Set the character's transform
        character_prim = self._stage.GetPrimAtPath(
            f"/World/Character_{self._character_count}"
        )
        xform = XFormPrim(f"/World/Character_{self._character_count}")
        xform.set_world_pose(position=position, orientation=orientation)

        # Add animation graph entry for the character
        # These need to be attached to the sub prim of the character
        # below 'ManRoot' and is of the type 'SkelRoot'
        skel_root_prim = None
        for child_prim in Usd.PrimRange(character_prim):
            print(child_prim.GetTypeName())
            if child_prim.IsA(UsdSkel.Root):
                skel_root_prim = child_prim
                break
        
        if skel_root_prim is None:
            carb.log_error(f"Could not find 'SkelRoot' for character {character_name}. Not proceeding.")
            return None
        omni.kit.commands.execute('ApplyAnimationGraphAPICommand',
        paths=[Sdf.Path(skel_root_prim.GetPath())],
        animation_graph_path=Sdf.Path(self._biped_setup_prim_path + "/CharacterAnimation/AnimationGraph"))

        # Add behaviour script entry for the character
        omni.kit.commands.execute('ApplyScriptingAPICommand', paths=[Sdf.Path(skel_root_prim.GetPath())])
        omni.kit.commands.execute('RefreshScriptingPropertyWindowCommand')
        attr = skel_root_prim.GetAttribute("omni:scripting:scripts")
        attr.Set([self.script_path])

Possibly related - Just prior to not being able to initialize the character, I see the error

2024-03-08 08:20:54 [Warning] [omni.anim.graph.core.plugin] getCharacter - /World/Character_0/female_adult_business_02/ManRoot/female_adult_business_02 is not a SkelRoot prim or does not apply AnimationGraphAPI

Screenshot showing seemingly correct assignment of properties in the skelroot prim

Note that if I manually click the Animation Graph entry and reselect the exact same path and then click play then it seems to work - so somehow the GUI on click performs an extra method call that I’m missing?

It seems like a play->Stop->Play cycle seems to work - so for some reason the very first time I run the scenario I can’t get it to work :/

Aha! I figured it out! Had to add an XFormPrim of the generated prim to the world. So, in setup_scene(),

world = World.instance()
world.scene.add(XFormPrim(
                prim.GetPath().pathString, name=prim.GetPath().pathString + "_xform"
            ))

Perhaps the world.reset() behaviour on post_load was causing the issue? Anyway issue is resolved! :)

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