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-2026, 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"""This script demonstrates different types of markers.
  7
  8.. code-block:: bash
  9
 10    # Usage with default PhysX physics and default kit visualizer.
 11    uv run python scripts/demos/markers.py
 12
 13"""
 14
 15"""Parse CLI first so we can decide whether to launch Isaac Sim Kit."""
 16
 17import argparse
 18from typing import TYPE_CHECKING
 19
 20from isaaclab.app import add_launcher_args, launch_simulation
 21
 22# add argparse arguments
 23parser = argparse.ArgumentParser(
 24    description="This script demonstrates different types of markers.",
 25    conflict_handler="resolve",
 26)
 27parser.add_argument("--physics", default="isaacsim_physx", choices=["isaacsim_physx"], help="Physics backend.")
 28add_launcher_args(parser)
 29parser.set_defaults(visualizer=["kit"])
 30args_cli = parser.parse_args()
 31
 32import torch
 33
 34import isaaclab.sim as sim_utils
 35
 36##
 37# Pre-defined configs
 38##
 39from isaaclab.markers.visualization_markers_cfg import VisualizationMarkersCfg
 40from isaaclab.physics import PhysicsCfg
 41from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR
 42from isaaclab.utils.math import quat_from_angle_axis
 43
 44if TYPE_CHECKING:
 45    from isaaclab.markers import VisualizationMarkers
 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 marker_cfg.class_type(marker_cfg)
 97
 98
 99def main():
100    """Main function."""
101    with launch_simulation(cfg=PhysicsCfg(), launcher_args=args_cli) as physics_cfg:
102        # Load kit helper
103        sim_cfg = sim_utils.SimulationCfg(dt=0.01, device=args_cli.device, physics=physics_cfg)
104        sim = sim_utils.SimulationContext(sim_cfg)
105        # Set main camera
106        sim.set_camera_view([0.0, 18.0, 12.0], [0.0, 3.0, 0.0])
107
108        # Spawn things into stage
109        # Lights
110        cfg = sim_utils.DomeLightCfg(intensity=3000.0, color=(0.75, 0.75, 0.75))
111        cfg.func("/World/Light", cfg)
112
113        # create markers
114        my_visualizer = define_markers()
115
116        # define a grid of positions where the markers should be placed
117        num_markers_per_type = 5
118        grid_spacing = 2.0
119        # Calculate the half-width and half-height
120        half_width = (num_markers_per_type - 1) / 2.0
121        half_height = (my_visualizer.num_prototypes - 1) / 2.0
122        # Create the x and y ranges centered around the origin
123        x_range = torch.arange(-half_width * grid_spacing, (half_width + 1) * grid_spacing, grid_spacing)
124        y_range = torch.arange(-half_height * grid_spacing, (half_height + 1) * grid_spacing, grid_spacing)
125        # Create the grid
126        x_grid, y_grid = torch.meshgrid(x_range, y_range, indexing="ij")
127        x_grid = x_grid.reshape(-1)
128        y_grid = y_grid.reshape(-1)
129        z_grid = torch.zeros_like(x_grid)
130        # marker locations
131        marker_locations = torch.stack([x_grid, y_grid, z_grid], dim=1)
132        marker_indices = torch.arange(my_visualizer.num_prototypes).repeat(num_markers_per_type)
133
134        # Play the simulator
135        sim.reset()
136        # Now we are ready!
137        print("[INFO]: Setup complete...")
138
139        # Yaw angle
140        yaw = torch.zeros_like(marker_locations[:, 0])
141        # Step while a visualizer window is still open (or none exist, e.g. headless); works for kit and newton.
142        while sim.is_headless_or_exist_active_visualizer():
143            # rotate the markers around the z-axis for visualization
144            marker_orientations = quat_from_angle_axis(yaw, torch.tensor([0.0, 0.0, 1.0]))
145            # visualize
146            my_visualizer.visualize(marker_locations, marker_orientations, marker_indices=marker_indices)
147            # roll corresponding indices to show how marker prototype can be changed
148            if yaw[0].item() % (0.5 * torch.pi) < 0.01:
149                marker_indices = torch.roll(marker_indices, 1)
150            # perform step
151            sim.step()
152            # increment yaw
153            yaw += 0.01
154
155
156if __name__ == "__main__":
157    # run the main function
158    main()

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.markers import VisualizationMarkers


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.

# Now we are ready!
print("[INFO]: Setup complete...")

# Yaw angle
yaw = torch.zeros_like(marker_locations[:, 0])
# Step while a visualizer window is still open (or none exist, e.g. headless); works for kit and newton.
while sim.is_headless_or_exist_active_visualizer():

Executing the Script#

To run the accompanying script, execute the following command:

python 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.