Skip to content

sim2bot.Robot.marker

marker(marker_id: str, shape: str, position: Optional[Sequence[float]] = None, orientation: Optional[Sequence[float]] = None, scale: Optional[Union[float, Sequence[float]]] = None, color: Optional[Sequence[float]] = None, points: Optional[Sequence[Sequence[float]]] = None, from_: Optional[Sequence[float]] = None, to: Optional[Sequence[float]] = None, text: Optional[str] = None) -> None

Create or update an RViz-style visual debug marker by ID.

Parameters:

  • marker_id (str) –

    Scene-unique marker ID. Reuse it to update the same marker.

  • shape (str) –

    sphere, box, arrow, line, text, axes, or points.

  • position (Optional[Sequence[float]], default: None ) –

    World-frame [x, y, z] in metres.

  • orientation (Optional[Sequence[float]], default: None ) –

    World-frame quaternion [x, y, z, w].

  • scale (Optional[Union[float, Sequence[float]]], default: None ) –

    Uniform size or [x, y, z] dimensions in metres.

  • color (Optional[Sequence[float]], default: None ) –

    RGBA components from 0 to 1.

  • points (Optional[Sequence[Sequence[float]]], default: None ) –

    World-frame point list for a polyline or point cloud.

  • from_ (Optional[Sequence[float]], default: None ) –

    World-frame arrow start [x, y, z].

  • to (Optional[Sequence[float]], default: None ) –

    World-frame arrow end [x, y, z].

  • text (Optional[str], default: None ) –

    Label content for a text marker.

Returns:

  • None

    Reusing marker_id updates the existing marker.

Raises:

  • TypeError

    If a vector argument is not an iterable of numbers.

  • ValueError

    If a vector component cannot be converted to float.

  • RuntimeError

    If the client is not connected.

  • ConnectionClosed

    If the WebSocket closes while sending the command.

  • OSError

    If the selected transport cannot send the command.

Notes

Markers are visual-only scene helpers. They do not alter physics and are intentionally excluded from simulated camera feeds.

Examples:

Draw a target position::

sim.marker(
    "goal",
    "sphere",
    position=[0.45, 0.0, 0.35],
    scale=0.06,
    color=[0.36, 0.54, 0.92, 1.0],
)
Source code in sim2bot/client.py
def marker(
    self,
    marker_id: str,
    shape: str,
    position: Optional[Sequence[float]] = None,
    orientation: Optional[Sequence[float]] = None,
    scale: Optional[Union[float, Sequence[float]]] = None,
    color: Optional[Sequence[float]] = None,
    points: Optional[Sequence[Sequence[float]]] = None,
    from_: Optional[Sequence[float]] = None,
    to: Optional[Sequence[float]] = None,
    text: Optional[str] = None,
) -> None:
    """Create or update an RViz-style visual debug marker by ID.

    Args:
        marker_id: Scene-unique marker ID. Reuse it to update the same marker.
        shape: ``sphere``, ``box``, ``arrow``, ``line``, ``text``, ``axes``,
            or ``points``.
        position: World-frame ``[x, y, z]`` in metres.
        orientation: World-frame quaternion ``[x, y, z, w]``.
        scale: Uniform size or ``[x, y, z]`` dimensions in metres.
        color: RGBA components from 0 to 1.
        points: World-frame point list for a polyline or point cloud.
        from_: World-frame arrow start ``[x, y, z]``.
        to: World-frame arrow end ``[x, y, z]``.
        text: Label content for a text marker.

    Returns:
        Reusing ``marker_id`` updates the existing marker.

    Raises:
        TypeError: If a vector argument is not an iterable of numbers.
        ValueError: If a vector component cannot be converted to ``float``.
        RuntimeError: If the client is not connected.
        ConnectionClosed: If the WebSocket closes while sending the command.
        OSError: If the selected transport cannot send the command.

    Notes:
        Markers are visual-only scene helpers. They do not alter physics and
        are intentionally excluded from simulated camera feeds.

    Examples:
        Draw a target position::

            sim.marker(
                "goal",
                "sphere",
                position=[0.45, 0.0, 0.35],
                scale=0.06,
                color=[0.36, 0.54, 0.92, 1.0],
            )
    """
    spec: dict = {"id": marker_id, "shape": shape}
    if position is not None:
        spec["position"] = [float(v) for v in position]
    if orientation is not None:
        spec["orientation"] = [float(v) for v in orientation]
    if scale is not None:
        spec["scale"] = scale if isinstance(scale, (int, float)) else [float(v) for v in scale]
    if color is not None:
        spec["color"] = [float(v) for v in color]
    if points is not None:
        spec["points"] = [[float(v) for v in p] for p in points]
    if from_ is not None:
        spec["from"] = [float(v) for v in from_]
    if to is not None:
        spec["to"] = [float(v) for v in to]
    if text is not None:
        spec["text"] = str(text)
    self._send({"type": "marker", "marker": spec})

Practical examples

Examples use objects discovered from the current scene rather than hard-coded robot metadata.

Draw a target sphere

sim.marker(
    "goal",
    "sphere",
    position=[0.45, 0.0, 0.35],
    scale=0.06,
    color=[0.36, 0.54, 0.92, 1.0],
)

Draw a planned path

sim.marker(
    "planned-path",
    "line",
    points=[[0.3, 0.0, 0.2], [0.4, 0.1, 0.3], [0.5, 0.0, 0.4]],
    scale=0.01,
    color=[0.2, 1.0, 0.4, 1.0],
)

Update an arrow

sim.marker(
    "force",
    "arrow",
    from_=[0.4, 0.0, 0.3],
    to=[0.5, 0.0, 0.3],
    color=[1.0, 0.2, 0.2, 1.0],
)

Guidance

Usage tip

Reuse stable marker IDs every controller tick instead of creating a new marker for every sample.

Important behavior

Markers are excluded from simulated camera feeds and never affect physics.


See also