Hello All,
Is there a way to convert Action Graphs to scripts ?
Thank you
Sandeep
Hello All,
Is there a way to convert Action Graphs to scripts ?
Thank you
Sandeep
Hi @quark01 - I do not think it is possible. But you can develop the action graph using scripts. OmniGraph — Omniverse Extensions documentation
I thought you could add the ability to convert the action graph to a script for model migration, or is there a good way to copy the action graph to another robot
Hi @litao_bate - While there isn’t a direct way to convert an Action Graph to a script, you can replicate the logic of an Action Graph in a script using the Omniverse Kit’s Python API. This can be useful for model migration or copying behaviors between robots.
As for copying an Action Graph to another robot, you can do this by duplicating the Action Graph and then changing the target nodes to reference the new robot. Here’s a general process:
Remember that the specifics of this process can vary depending on the structure of your Action Graph and the characteristics of your robots.
yes, its possible. but not fun at all.
this, for example, is an action graph with two nodes, one for instantiating the usd files in stage and one for scattering them:
keys = og.Controller.Keys
_, _, _, nodes = og.Controller.edit(
self.graph,
{
keys.CREATE_NODES: [
("OgnScatter2D", "omni.replicator.core.OgnScatter2D"),
("OgnSamplePopulation", "omni.replicator.core.OgnSamplePopulation")
],
keys.CONNECT: [
("OgnSamplePopulation.outputs:prims", "OgnScatter2D.inputs:prims")
],
keys.SET_VALUES: [
("OgnSamplePopulation.inputs:paths", rand_usd_paths),
("OgnSamplePopulation.inputs:mode", 'scene_instance'),
("OgnSamplePopulation.inputs:useCache", False),
("OgnSamplePopulation.inputs:withReplacements", False),
("OgnSamplePopulation.inputs:populationName", f"{self.assets_name}_ScatterPopulation"),
("OgnScatter2D.inputs:surfacePrims", self.surface_prims_path), #surfacePrims are the surfaces to scatter on, must be a list of paths
("OgnScatter2D.inputs:checkForCollisions", self.check_for_collision),
]
},
)
If you want to also rotate the prims (which must be done before the scattering otherwise you are risking having collisions), it become exponentially more difficult. this graph:
can be built with this:
def init_graph(self, surface_prims_path, rand_usd_paths):
self.graph = og.Controller.create_graph(
graph_id = {
"graph_path" : f"/Root/ScatterGraphs/{self.assets_name}Graph",
"fc_backing_type" : og.GraphBackingType.GRAPH_BACKING_TYPE_FABRIC_WITHOUT_HISTORY, #TODO: MIGHT NEED TO REMOVE THIS
"pipeline_stage" : og.GraphPipelineStage.GRAPH_PIPELINE_STAGE_ONDEMAND
}
)
keys = og.Controller.Keys
_, _, _, nodes = og.Controller.edit(
self.graph,
{
keys.CREATE_NODES: [
("OgnScatter2D", "omni.replicator.core.OgnScatter2D"),
("OgnSamplePopulation", "omni.replicator.core.OgnSamplePopulation"),
("OgnCount1", "omni.replicator.core.OgnCount"),
("OgnCount2", "omni.replicator.core.OgnCount"),
("OgnSampleUniform", "omni.replicator.core.OgnSampleUniform"),
("PerAxisPose", "omni.replicator.core.OgnPerAxisPose"),
("OgnWritePrimAttribute", "omni.replicator.core.OgnWritePrimAttribute"),
],
keys.CONNECT: [
("OgnSamplePopulation.outputs:prims", "OgnCount1.inputs:prims"),
("OgnCount1.outputs:count", "OgnSampleUniform.inputs:numSamples"),
("OgnSampleUniform.outputs:samples", "PerAxisPose.inputs:fullValues"),
("OgnSamplePopulation.outputs:prims", "OgnCount2.inputs:prims"),
("OgnCount2.outputs:count", "PerAxisPose.inputs:numSamples"),
("OgnSamplePopulation.outputs:prims", "PerAxisPose.inputs:prims"),
("PerAxisPose.outputs:samples", "OgnWritePrimAttribute.inputs:values"),
("OgnSamplePopulation.outputs:prims", "OgnWritePrimAttribute.inputs:prims"),
("OgnSamplePopulation.outputs:exec", "OgnScatter2D.inputs:execIn"),
("OgnSamplePopulation.outputs:exec", "PerAxisPose.inputs:exec"),
("PerAxisPose.outputs:exec", "OgnWritePrimAttribute.inputs:execIn"),
("OgnSamplePopulation.outputs:prims", "OgnScatter2D.inputs:prims"),
],
keys.SET_VALUES: [
("OgnSamplePopulation.inputs:paths", rand_usd_paths),
("OgnSamplePopulation.inputs:mode", 'scene_instance'),
("OgnSamplePopulation.inputs:useCache", False),
("OgnSamplePopulation.inputs:withReplacements", False),
("OgnSamplePopulation.inputs:populationName", f"{self.assets_name}_ScatterPopulation"),
("OgnCount1.inputs:mode", 'prims'),
("OgnSampleUniform.inputs:lower", [0,0,0]),
("OgnSampleUniform.inputs:upper", [0,0,180]),
("OgnSampleUniform.inputs:outputType", "float3[]"),
("OgnCount2.inputs:mode", 'prims'),
("PerAxisPose.inputs:mode", "rotation"),
("OgnWritePrimAttribute.inputs:attribute", "xformOp:rotateXYZ"),
("OgnWritePrimAttribute.inputs:attributeType", "double3"),
#("OgnScatter2D.inputs:surfacePrims", surface_prims_path), #do this in edit graph only
("OgnScatter2D.inputs:checkForCollisions", self.check_for_collision),
]
},
)