Running ROS bridge with Python API

I am trying to use the Python API to start up Isaac Sim, load in a robot via URDF, and then create ROS topics to publish camera feeds to. To achieve the last step, I copied this code from the example:

    from pxr import PhysicsSchema, Sdf
    import omni.usd
    import omni.kit
    import omni.isaac.RosBridgeSchema as ROSSchema

    stage = omni.usd.get_context().get_stage()
    camera_prim = ROSSchema.RosCamera.Define(stage, Sdf.Path("/ROS_Camera"))

    # adding prefix to the publisher topic in case multiple cameras are added
    camera_prim.CreateRosNodePrefixAttr("")
    camera_prim.CreateEnabledAttr(True)

    # publisher topic for camera_info
    camera_prim.CreateCameraInfoPubTopicAttr("/camera_info")
    # publisher topic for rgb
    camera_prim.CreateRgbPubTopicAttr("/rgb")
    # publisher topic for depth
    camera_prim.CreateDepthPubTopicAttr("/depth")
    camera_prim.CreateFrameIdAttr("/sim_camera")

    # enable RGB
    camera_prim.CreateRgbEnabledAttr(True)
    # enable depth
    camera_prim.CreateDepthEnabledAttr(True)
    camera_prim.CreateQueueSizeAttr(10)

    editor = omni.kit.editor.get_editor_interface()
    if not editor.is_playing():
        editor.play()

However, this does not seem to be creating the topic. I have roscore running in a different terminal, and when I rostopic list, it does not list any of the topics that this code should be creating. Am I missing some step?

I understand that omni.isaac.ros_bridge has an object that allows one to start up roscore from within Python. However, when roscore runs this way, it throws an error. In my final use case, I will have roscore running separately anyway, so I don’t want the Python API code to run it for me. Is it possible for this ROS bridge stuff to use a ROS core in a different process/terminal?

Hi wchen,

does Omniverse have the same ROS_MASTER_URI variable in the environment as your separate terminal?
If not, you can set it with

import os
os.environ["ROS_MASTER_URI"]="ip_of_roscore:11311"

In my experience roscore is started automatically, when not given another ROS_MASTER_URI

Yes, Omniverse does have the same ROS_MASTER_URI. The script is likewise able to interface with ROS topics with rospy (ie I was able to write custom subscribers and publishers in the script, and when I ran it, they were able to receive/send data). However, when I run the actual above code, it doesn’t do anything – /rgb and /depth are not topics that exist when I run rostopic list.

Hi,

Could you provide more details about how are you launching your script?
Have you included omni.isaac.ros_bridge in the experience config file if you are starting the Isaac Sim directly from a python file?
What errors are you getting?

Ah, I did not include that. Now that I have, it seems to be creating the topics. Is there a document/resource on the full Python API ROS bridge usage, including stuff like adding it to the config file + getting cameras to publish data and the like?

I’m encountering new issues now.

2021-06-10 19:03:28 [7,917ms] [Warning] [carb.sensors.plugin] Uninitialized sensor passed in, no sensor data
2021-06-10 19:03:28 [7,917ms] [Warning] [carb.sensors.plugin] Uninitialized sensor passed in, no sensor data
++ DC: Stage Pause
Refreshing context
Exiting OmniKitHelper

Getting these error messages when I run the code in my original post. rostopic list now lists stuff like /rgb and /depth, but nothing is being published to them. However, I currently have my simulator time.sleep() for 40 seconds before shutting off. Right before turning off, the DC: Stage Pause thing appears in the log, and it publishes an image to the topic (I can see that via rostopic echo /rgb). Otherwise, nothing is published.

kit.play()
time.sleep(40)
kit.stop()
editor.stop()

is the code I am running to keep the simulator alive for 40 seconds, run right after editor.play() in the code at the top. Also kit = OmniKitHelper(config=CONFIG). Is there something that I have to include in my code to have it consistently publish images, or is the sleep somehow blocking the publishing or something? What’s the preferred way to keep the simulator alive when running via Python API?

EDIT:
Figured it out, gotta repeatedly call kit.update(dt) a bunch to repeatedly simulate forward dt seconds at a time, each time causes the topic to get published to.