Hi,
I am using Isaac Sim 2022.2.0.
I am trying to make the “Joint Control Omni Graph with Python Scripting”. I followed the online tutorial using visual scripting: 7.1.10. Joint Control: Extension Python Scripting — Omniverse IsaacSim latest documentation . It works great.
But when I try to integrate it with my own code using franka robot from the server (_FRANKA_PANDA_ARM_INSTANCEABLE_USD = f"{ISAAC_ORBIT_NUCLEUS_DIR}/Robots/FrankaEmika/panda_instanceable.usd"). It does not work at all.
While the robot joint positions are not zeros, the topic “/joint_states” publishes always :
header:
seq: 10716
stamp:
secs: 126
nsecs: 379997175
frame_id: ‘’
name:
-
panda_joint1
-
panda_joint2
-
panda_joint3
-
panda_joint4
-
panda_joint5
-
panda_joint6
-
panda_joint7
-
panda_finger_joint1
-
panda_finger_joint2
position: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
velocity: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
effort: [0.0, -3.611, 0.0, -3.8255, 0.0, 1.6987, 0.0, 0.0, 0.0]
And the “/joint_command” topis is not getting executed.
In addition, I get this warning during execution:
2024-01-08 14:31:38 [131,497ms] [Warning] [omni.graph.core.plugin] /ActionGraph/ArticulationController: OmniGraph Warning: Index put requires the source and destination dtypes match, got Float for the destination and Double for the source.
(from compute() at line 110 in /home/xxx/xxx/_isaac_sim/exts/omni.isaac.core_nodes/omni/isaac/core_nodes/ogn/nodes/OgnIsaacArticulationController.py)
Could you please take at look at my implementation below and let me know what was the issue? Thanks!
Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES, ETH Zurich, and University of Toronto
All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
“”"
This script demonstrates how to use the physics engine to simulate a single-arm manipulator.
We currently support the following robots:
- Franka Emika Panda
- Universal Robot UR10
From the default configuration file for these robots, zero actions imply a default pose.
“”"
“”“Launch Isaac Sim Simulator first.”“”
import argparse
from omni.isaac.kit import SimulationApp
add argparse arguments
parser = argparse.ArgumentParser(“Welcome to Orbit: Omniverse Robotics Environments!”)
parser.add_argument(“–robot”, type=str, default=“franka_panda”, help=“Name of the robot.”)
args_cli = parser.parse_args()
This sample enables a livestream server to connect to when running headless
CONFIG = {
“width”: 1280,
“height”: 720,
“window_width”: 1920,
“window_height”: 1080,
“headless”: False,
“renderer”: “RayTracedLighting”,
“display_options”: 3286, # Set display options to show default grid
}
launch omniverse app
simulation_app = SimulationApp(launch_config=CONFIG)
“”“Rest everything follows.”“”
import torch
import omni.isaac.core.utils.prims as prim_utils
from omni.isaac.core.simulation_context import SimulationContext
from omni.isaac.core.utils.extensions import enable_extension
from omni.isaac.core.utils.viewports import set_camera_view
import omni.isaac.orbit.utils.kit as kit_utils
from omni.isaac.orbit.robots.single_arm import SingleArmManipulator
from omni.isaac.core.utils.carb import set_carb_setting
from omni.isaac.orbit.robots.config.franka_roma import ROMA_FRANKA_PANDA_ARM_WITH_PANDA_HAND_CFG
from omni.isaac.orbit.robots.config.franka import FRANKA_PANDA_ARM_WITH_PANDA_HAND_CFG
enable_extension(“omni.isaac.ros_bridge”)
import omni.graph.core as og
from omni.isaac.core_nodes.scripts.utils import set_target_prims
“”"
Main
“”"
def main():
“”“Spawns a single arm manipulator and applies random joint commands.”“”
# Default Livestream settings
simulation_app.set_setting("/app/window/drawMouse", True)
simulation_app.set_setting("/app/livestream/proto", "ws")
simulation_app.set_setting("/app/livestream/websocket/framerate_limit", 120)
simulation_app.set_setting("/ngx/enabled", False)
# Note: Only one livestream extension can be enabled at a time
# Enable Native Livestream extension
# Default App: Streaming Client from the Omniverse Launcher
enable_extension("omni.kit.livestream.native")
# Load kit helper
sim = SimulationContext(physics_dt=0.01, rendering_dt=0.01, backend="torch", device="cuda:0")
# Set main camera
set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])
# ############# Added this change to solve bud related to GPU instancind
# Enable fltacache which avoids passing data over to USD structure
# this speed up the read-write operation of GPU buffers
if sim.get_physics_context().use_gpu_pipeline:
sim.get_physics_context().enable_flatcache(True)
# Enable hydra scene-graph instancing
# this is needed to visualize the scene when flatcache is enabled
set_carb_setting(sim._settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
# ###############
# Spawn things into stage
# Ground-plane
kit_utils.create_ground_plane("/World/defaultGroundPlane", z_position=-1.05)
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (0.75, 0.75, 0.75)},
)
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (1.0, 1.0, 1.0)},
)
# Robots
robot_cfg = FRANKA_PANDA_ARM_WITH_PANDA_HAND_CFG
# enable filling buffers for dyamic variables
robot_cfg.data_info.enable_coriolis = True
robot_cfg.data_info.enable_mass_matrix = True
robot_cfg.data_info.enable_gravity = True
robot_cfg.data_info.enable_jacobian = True
# -- Spawn robot
robot = SingleArmManipulator(cfg=robot_cfg)
robot.spawn("/World/myRobot", translation=(0.0, 0.0, 0.0))
# Play the simulator
sim.reset()
# Acquire handles
# Initialize handles
robot.initialize("/World/myRobot.*")
# Reset states
robot.reset_buffers()
keys = og.Controller.Keys # Usually handy to keep this name short as it is used often
controller = og.Controller()
(graph, nodes, prims, name_to_object_map) = og.Controller.edit(
{"graph_path": "/ActionGraph", "evaluator_name": "execution"},
{
og.Controller.Keys.CREATE_NODES: [
("OnPlaybackTick", "omni.graph.action.OnPlaybackTick"),
("PublishJointState", "omni.isaac.ros_bridge.ROS1PublishJointState"),
("SubscribeJointState", "omni.isaac.ros_bridge.ROS1SubscribeJointState"),
("ArticulationController", "omni.isaac.core_nodes.IsaacArticulationController"),
("ReadSimTime", "omni.isaac.core_nodes.IsaacReadSimulationTime"),
],
og.Controller.Keys.CONNECT: [
("OnPlaybackTick.outputs:tick", "PublishJointState.inputs:execIn"),
("OnPlaybackTick.outputs:tick", "SubscribeJointState.inputs:execIn"),
("OnPlaybackTick.outputs:tick", "ArticulationController.inputs:execIn"),
("ReadSimTime.outputs:simulationTime", "PublishJointState.inputs:timeStamp"),
("SubscribeJointState.outputs:execOut", "ArticulationController.inputs:execIn"),
("SubscribeJointState.outputs:jointNames", "ArticulationController.inputs:jointNames"),
("SubscribeJointState.outputs:positionCommand", "ArticulationController.inputs:positionCommand"),
("SubscribeJointState.outputs:velocityCommand", "ArticulationController.inputs:velocityCommand"),
("SubscribeJointState.outputs:effortCommand", "ArticulationController.inputs:effortCommand"),
],
og.Controller.Keys.SET_VALUES: [
# # Setting topic names to joint state publisher and subscriber.
("PublishJointState.inputs:topicName", "/joint_states"),
("SubscribeJointState.inputs:topicName", "/joint_command"),
# Providing path to /panda robot to Articulation Controller node
# Providing the robot path is equivalent to setting the targetPrim in Articulation Controller node
("ArticulationController.inputs:usePath", True),
("ArticulationController.inputs:robotPath", "/World/myRobot"),
],
},
)
set_target_prims(
primPath="/ActionGraph" + "/PublishJointState", inputName="inputs:targetPrim", targetPrimPaths=["/World/myRobot"]
)
# Now we are ready!
print("[INFO]: Setup complete...")
# dummy actions
actions = torch.rand(robot.count, robot.num_actions, device=robot.device)
has_gripper = robot.cfg.meta_info.tool_num_dof > 0
# Define simulation stepping
sim_dt = sim.get_physics_dt()
# episode counter
sim_time = 0.0
ep_step_count = 0
# Simulate physics
while simulation_app.is_running():
# If simulation is stopped, then exit.
if sim.is_stopped():
break
# # If simulation is paused, then skip.
# if not sim.is_playing():
# sim.step(render=not args_cli.headless)
# continue
# reset
if ep_step_count % 1000 == 0:
sim_time = 0.0
ep_step_count = 0
# reset dof state
dof_pos, dof_vel = robot.get_default_dof_state()
robot.set_dof_state(dof_pos, dof_vel)
robot.reset_buffers()
# reset command
actions = torch.rand(robot.count, robot.num_actions, device=robot.device)
# reset gripper
if has_gripper:
actions[:, -1] = -1
print("[INFO]: Resetting robots state...")
# change the gripper action
if ep_step_count % 200 == 0 and has_gripper:
# flip command for the gripper
actions[:, -1] = -actions[:, -1]
print(f"[INFO]: [Step {ep_step_count:03d}]: Flipping gripper command...")
# apply action to the robot
# robot.apply_action(actions)
# perform step
sim.step()
# update sim-time
sim_time += sim_dt
ep_step_count += 1
# note: to deal with timeline events such as stopping, we need to check if the simulation is playing
if sim.is_playing():
# update buffers
robot.update_buffers(sim_dt)
# # print dynamic parameters
# print("ee_jacobian : ", robot.data.ee_jacobian[:])
# print("mass_matrix : ", robot.data.mass_matrix[:])
# print("coriolis : ", robot.data.coriolis[:])
# print("gravity : ", robot.data.gravity[:])
if name == “main”:
# Run the main function
main()
# Close the simulator
simulation_app.close()