Skip to content

sim2bot.Robot.move_trajectory

move_trajectory(points: Iterable[tuple[float, Sequence[float]]], robot: int = 0, loop: bool = False) -> None

Play timestamped joint waypoints on one robot.

Parameters:

  • points (Iterable[tuple[float, Sequence[float]]]) –

    (t, q) pairs. t is seconds from trajectory start and must increase strictly; q contains joint positions in radians.

  • robot (int, default: 0 ) –

    Robot index returned by describe.

  • loop (bool, default: False ) –

    Repeat from the first point after the last point.

Returns:

  • None

    Playback is started asynchronously in the browser.

Raises:

  • TypeError

    If a waypoint is not a (time, joints) pair.

  • ValueError

    If a waypoint time or joint value cannot convert 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

The browser interpolates by simulation time. Physics mode servos through the normal controller; kinematics-only mode applies the interpolated target directly. The last point remains held until a new motion, stop, reset, or trajectory-stop command arrives.

Motion-panel exports store t in milliseconds. Divide those values by 1000 before passing them here.

Examples:

Play a two-second out-and-back motion::

home = sim.describe()[0].home
bent = [value + 0.2 for value in home]
sim.move_trajectory([(0.0, home), (1.0, bent), (2.0, home)])
Source code in sim2bot/client.py
def move_trajectory(
    self,
    points: Iterable[tuple[float, Sequence[float]]],
    robot: int = 0,
    loop: bool = False,
) -> None:
    """Play timestamped joint waypoints on one robot.

    Args:
        points: ``(t, q)`` pairs. ``t`` is seconds from trajectory start and
            must increase strictly; ``q`` contains joint positions in radians.
        robot: Robot index returned by
            [`describe`][sim2bot.client.Robot.describe].
        loop: Repeat from the first point after the last point.

    Returns:
        Playback is started asynchronously in the browser.

    Raises:
        TypeError: If a waypoint is not a ``(time, joints)`` pair.
        ValueError: If a waypoint time or joint value cannot convert 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:
        The browser interpolates by simulation time. Physics mode servos
        through the normal controller; kinematics-only mode applies the
        interpolated target directly. The last point remains held until a new
        motion, stop, reset, or trajectory-stop command arrives.

        Motion-panel exports store ``t`` in milliseconds. Divide those values
        by 1000 before passing them here.

    Examples:
        Play a two-second out-and-back motion::

            home = sim.describe()[0].home
            bent = [value + 0.2 for value in home]
            sim.move_trajectory([(0.0, home), (1.0, bent), (2.0, home)])
    """
    self._send(
        {
            "type": "joint_trajectory",
            "points": [{"t": float(t), "q": [float(v) for v in q]} for t, q in points],
            "robot": robot,
            "loop": loop,
        }
    )

Practical examples

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

Play an out-and-back trajectory

home = arm.home
bent = list(home)
bent[0] += 0.3
sim.move_trajectory(
    [(0.0, home), (1.0, bent), (2.0, home)],
    robot=arm.index,
)

Convert a Motion-panel export

points = [
    (frame["t"] / 1000.0, frame["q"])
    for frame in recording["trajectory"]
]
sim.move_trajectory(points, robot=arm.index)

Loop until explicitly stopped

sim.move_trajectory(points, robot=arm.index, loop=True)
# Later:
sim.stop_trajectory(robot=arm.index)

Guidance

Usage tip

Start at t=0.0, use strictly increasing timestamps, and keep every waypoint in discovered joint order.

Common error

App recordings use milliseconds; this API uses seconds. Forgetting to divide by 1000 makes playback roughly 1000× slower.


See also