Creating Visualization Markers

Creating Visualization Markers#

Visualization markers are useful to debug the state of the environment. They can be used to visualize the frames, commands, and other information in the simulation.

While Isaac Sim provides its own isaacsim.util.debug_draw extension, it is limited to rendering only points, lines and splines. For cases, where you need to render more complex shapes, you can use the markers.VisualizationMarkers class.

This guide is accompanied by a sample script markers.py in the IsaacLab/scripts/demos directory.

Code for markers.py
  1# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
  2# All rights reserved.
  3#
  4# SPDX-License-Identifier: BSD-3-Clause
  5
  6# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
  7# All rights reserved.
  8#
  9# SPDX-License-Identifier: BSD-3-Clause
 10
 11"""This script demonstrates different types of markers.
 12
 13.. code-block:: bash
 14
 15    # Usage
 16    ./isaaclab.sh -p scripts/demos/markers.py
 17
 18"""
 19
 20"""Launch Isaac Sim Simulator first."""
 21
 22import argparse
 23
 24from isaaclab.app import AppLauncher
 25
 26# add argparse arguments
 27parser = argparse.ArgumentParser(description="This script demonstrates different types of markers.")
 28# append AppLauncher cli args
 29AppLauncher.add_app_launcher_args(parser)
 30# parse the arguments
 31args_cli = parser.parse_args()
 32
 33# launch omniverse app
 34app_launcher = AppLauncher(args_cli)
 35simulation_app = app_launcher.app
 36
 37"""Rest everything follows."""
 38
 39import torch
 40
 41import isaaclab.sim as sim_utils
 42from isaaclab.markers import VisualizationMarkers, VisualizationMarkersCfg
 43from isaaclab.sim import SimulationContext
 44from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR
 45from isaaclab.utils.math import quat_from_angle_axis
 46
 47
 48def define_markers() -> VisualizationMarkers:
 49    """Define markers with various different shapes."""
 50    marker_cfg = VisualizationMarkersCfg(
 51        prim_path="/Visuals/myMarkers",
 52        markers={
 53            "frame": sim_utils.UsdFileCfg(
 54                usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/UIElements/frame_prim.usd",
 55                scale=(0.5, 0.5, 0.5),
 56            ),
 57            "arrow_x": sim_utils.UsdFileCfg(
 58                usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/UIElements/arrow_x.usd",
 59                scale=(1.0, 0.5, 0.5),
 60                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 1.0)),
 61            ),
 62            "cube": sim_utils.CuboidCfg(
 63                size=(1.0, 1.0, 1.0),
 64                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 0.0, 0.0)),
 65            ),
 66            "sphere": sim_utils.SphereCfg(
 67                radius=0.5,
 68                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0)),
 69            ),
 70            "cylinder": sim_utils.CylinderCfg(
 71                radius=0.5,
 72                height=1.0,
 73                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 0.0, 1.0)),
 74            ),
 75            "cone": sim_utils.ConeCfg(
 76                radius=0.5,
 77                height=1.0,
 78                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 1.0, 0.0)),
 79            ),
 80            "mesh": sim_utils.UsdFileCfg(
 81                usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Blocks/DexCube/dex_cube_instanceable.usd",
 82                scale=(10.0, 10.0, 10.0),
 83            ),
 84            "mesh_recolored": sim_utils.UsdFileCfg(
 85                usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Blocks/DexCube/dex_cube_instanceable.usd",
 86                scale=(10.0, 10.0, 10.0),
 87                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 0.25, 0.0)),
 88            ),
 89            "robot_mesh": sim_utils.UsdFileCfg(
 90                usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/ANYbotics/ANYmal-C/anymal_c.usd",
 91                scale=(2.0, 2.0, 2.0),
 92                visual_material=sim_utils.GlassMdlCfg(glass_color=(0.0, 0.1, 0.0)),
 93            ),
 94        },
 95    )
 96    return VisualizationMarkers(marker_cfg)
 97
 98
 99def main():
100    """Main function."""
101    # Load kit helper
102    sim_cfg = sim_utils.SimulationCfg(dt=0.01, device=args_cli.device)
103    sim = SimulationContext(sim_cfg)
104    # Set main camera
105    sim.set_camera_view([0.0, 18.0, 12.0], [0.0, 3.0, 0.0])
106
107    # Spawn things into stage
108    # Lights
109    cfg = sim_utils.DomeLightCfg(intensity=3000.0, color=(0.75, 0.75, 0.75))
110    cfg.func("/World/Light", cfg)
111
112    # create markers
113    my_visualizer = define_markers()
114
115    # define a grid of positions where the markers should be placed
116    num_markers_per_type = 5
117    grid_spacing = 2.0
118    # Calculate the half-width and half-height
119    half_width = (num_markers_per_type - 1) / 2.0
120    half_height = (my_visualizer.num_prototypes - 1) / 2.0
121    # Create the x and y ranges centered around the origin
122    x_range = torch.arange(-half_width * grid_spacing, (half_width + 1) * grid_spacing, grid_spacing)
123    y_range = torch.arange(-half_height * grid_spacing, (half_height + 1) * grid_spacing, grid_spacing)
124    # Create the grid
125    x_grid, y_grid = torch.meshgrid(x_range, y_range, indexing="ij")
126    x_grid = x_grid.reshape(-1)
127    y_grid = y_grid.reshape(-1)
128    z_grid = torch.zeros_like(x_grid)
129    # marker locations
130    marker_locations = torch.stack([x_grid, y_grid, z_grid], dim=1)
131    marker_indices = torch.arange(my_visualizer.num_prototypes).repeat(num_markers_per_type)
132
133    # Play the simulator
134    sim.reset()
135    # Now we are ready!
136    print("[INFO]: Setup complete...")
137
138    # Yaw angle
139    yaw = torch.zeros_like(marker_locations[:, 0])
140    # Simulate physics
141    while simulation_app.is_running():
142        # rotate the markers around the z-axis for visualization
143        marker_orientations = quat_from_angle_axis(yaw, torch.tensor([0.0, 0.0, 1.0]))
144        # visualize
145        my_visualizer.visualize(marker_locations, marker_orientations, marker_indices=marker_indices)
146        # roll corresponding indices to show how marker prototype can be changed
147        if yaw[0].item() % (0.5 * torch.pi) < 0.01:
148            marker_indices = torch.roll(marker_indices, 1)
149        # perform step
150        sim.step()
151        # increment yaw
152        yaw += 0.01
153
154
155if __name__ == "__main__":
156    # run the main function
157    main()
158    # close sim app
159    simulation_app.close()

Configuring the markers#

The VisualizationMarkersCfg class provides a simple interface to configure different types of markers. It takes in the following parameters:

  • prim_path: The corresponding prim path for the marker class.

  • markers: A dictionary specifying the different marker prototypes handled by the class. The key is the name of the marker prototype and the value is its spawn configuration.

Note

In case the marker prototype specifies a configuration with physics properties, these are removed. This is because the markers are not meant to be simulated.

Here we show all the different types of markers that can be configured. These range from simple shapes like cones and spheres to more complex geometries like a frame or arrows. The marker prototypes can also be configured from USD files.

from isaaclab.utils.math import quat_from_angle_axis


def define_markers() -> VisualizationMarkers:
    """Define markers with various different shapes."""
    marker_cfg = VisualizationMarkersCfg(
        prim_path="/Visuals/myMarkers",
        markers={
            "frame": sim_utils.UsdFileCfg(
                usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/UIElements/frame_prim.usd",
                scale=(0.5, 0.5, 0.5),
            ),
            "arrow_x": sim_utils.UsdFileCfg(
                usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/UIElements/arrow_x.usd",
                scale=(1.0, 0.5, 0.5),
                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 1.0)),
            ),
            "cube": sim_utils.CuboidCfg(
                size=(1.0, 1.0, 1.0),
                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 0.0, 0.0)),
            ),
            "sphere": sim_utils.SphereCfg(
                radius=0.5,
                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0)),
            ),
            "cylinder": sim_utils.CylinderCfg(
                radius=0.5,
                height=1.0,
                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 0.0, 1.0)),
            ),
            "cone": sim_utils.ConeCfg(
                radius=0.5,
                height=1.0,
                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 1.0, 0.0)),
            ),
            "mesh": sim_utils.UsdFileCfg(
                usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Blocks/DexCube/dex_cube_instanceable.usd",
                scale=(10.0, 10.0, 10.0),
            ),
            "mesh_recolored": sim_utils.UsdFileCfg(
                usd_path=f"{ISAAC_NUCLEUS_DIR}/Props/Blocks/DexCube/dex_cube_instanceable.usd",
                scale=(10.0, 10.0, 10.0),
                visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(1.0, 0.25, 0.0)),
            ),
            "robot_mesh": sim_utils.UsdFileCfg(
                usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Robots/ANYbotics/ANYmal-C/anymal_c.usd",

Drawing the markers#

To draw the markers, we call the visualize method. This method takes in as arguments the pose of the markers and the corresponding marker prototypes to draw.

print("[INFO]: Setup complete...")

# Yaw angle
yaw = torch.zeros_like(marker_locations[:, 0])
# Simulate physics
while simulation_app.is_running():
    # rotate the markers around the z-axis for visualization

Executing the Script#

To run the accompanying script, execute the following command:

./isaaclab.sh -p scripts/demos/markers.py

The simulation should start, and you can observe the different types of markers arranged in a grid pattern. The markers will rotating around their respective axes. Additionally every few rotations, they will roll forward on the grid.

To stop the simulation, close the window, or use Ctrl+C in the terminal.