# Play Motion 2

[play_motion2](https://github.com/pal-robotics/play_motion2) is a ROS 2 tool for executing pre-recorded joint motions on the robot. A motion is defined as a sequence of joint waypoints in a YAML file. play_motion2 takes care of safely approaching the first waypoint (optionally using MoveIt 2 for collision-free planning) and then executing the full trajectory just by interpolating between the rest of the waypoints.

play_motion2 supports simultaneous trajectories across multiple joint groups within a single motion.

**This is the recommended interface for:**
- Triggering pre-defined robot poses and motions from scripts or the terminal
- Playback of recorded motion sequences

## Overview

| Parameter | Value |
|---|---|
| Package | `play_motion2` |
| Manager node | `/play_motion2_mgr` |
| Executor node | `/play_motion2_executor` |
| Motions file | `kangaroo_bringup/config/kangaroo_motions.yaml` |

## Action

| Action | Type | Description |
|---|---|---|
| `/play_motion2` | `play_motion2_msgs/action/PlayMotion2` | Execute a named motion, with optional planning skip and timeout |

**Goal fields:**

| Field | Type | Description |
|---|---|---|
| `motion_name` | `string` | Key of the motion to execute |
| `skip_planning` | `bool` | Skip MoveIt 2 planning for the approach to the first waypoint |

**Result fields:**

| Field | Type | Description |
|---|---|---|
| `success` | `bool` | Whether the motion completed successfully |
| `error` | `string` | Error message if the motion failed |

## Services

| Service | Type | Description |
|---|---|---|
| `/play_motion2/list_motions` | `play_motion2_msgs/srv/ListMotions` | Returns the keys of all available motions |
| `/play_motion2/is_motion_ready` | `play_motion2_msgs/srv/IsMotionReady` | Checks whether a motion can currently be executed |
| `/play_motion2/get_motion_info` | `play_motion2_msgs/srv/GetMotionInfo` | Returns the full definition of a motion |
| `/play_motion2/add_motion` | `play_motion2_msgs/srv/AddMotion` | Adds a new motion at runtime |
| `/play_motion2/remove_motion` | `play_motion2_msgs/srv/RemoveMotion` | Removes an existing motion at runtime |

## Motion YAML Format

All motions are defined in `kangaroo_bringup/config/motions` folder under the `/play_motion2_mgr` namespace:

```yaml
/play_motion2_mgr:
  ros__parameters:
    motions:
      motion_name:
        joints: [joint1, joint2]
        positions: [0.0,  0.0,
                    0.5,  0.25]
        times_from_start: [0.5, 1.0]
        meta:
          name: Motion Name
          usage: example
          description: 'A short description'
```

- `joints`: list of joints involved in this motion.
- `positions`: flat list read as a matrix: each row is one waypoint, each column corresponds to one joint (in the same order as `joints`).
- `times_from_start`: time in seconds to reach each waypoint from the start of execution. An approach time to the first waypoint is calculated automatically; if it exceeds the first `times_from_start` value, the approach takes priority.

## Motion Planner Configuration

The approach behaviour is configured under `/play_motion2_executor`:

```yaml
/play_motion2_executor:
  ros__parameters:
    motion_planner:
      disable_motion_planning: false
      planning_groups:           # MoveIt 2 groups, in order of preference
        - planning_group_1
        - planning_group_2
      exclude_from_planning_joints:
        - joint_1
        - joint_2
      joint_tolerance: 0.01

      approach_velocity: 0.5     # max velocity for non-planned approach (rad/s)
      approach_min_duration: 0.5 # minimum approach duration (s)
```

| Parameter | Default | Description |
|---|---|---|
| `disable_motion_planning` | `false` | Disable MoveIt 2 planning for all approach moves |
| `planning_groups` | — | MoveIt 2 groups used for collision-free approach planning (required when planning is enabled) |
| `exclude_from_planning_joints` | — | Joints excluded from MoveIt 2 planning |
| `joint_tolerance` | `0.01` | Joint tolerance used during planned approach |
| `approach_velocity` | `0.5` | Maximum joint velocity for non-planned approach |
| `approach_min_duration` | `0.5` | Minimum duration of the approach phase |

> **Note:** It is strongly recommended to keep planning enabled. Disabling it may cause collisions when the robot approaches the first waypoint of a motion.

## Usage

### Run a motion from the terminal

```bash
ros2 run play_motion2 run_motion <motion_name> [<skip_planning> <timeout>]
```

| Argument | Default | Description |
|---|---|---|
| `motion_name` | — | Key of the motion to run |
| `skip_planning` | `false` | Skip collision-free planning for the approach |
| `timeout` | `120` | Seconds to wait for the motion to complete |

### Send a goal directly via the action CLI

```bash
ros2 action send_goal /play_motion2 play_motion2_msgs/action/PlayMotion2 \
  "{motion_name: 'motion_name', skip_planning: false}"
```

### List available motions

```bash
ros2 service call /play_motion2/list_motions play_motion2_msgs/srv/ListMotions
```

### Check if a motion is ready

```bash
ros2 service call /play_motion2/is_motion_ready play_motion2_msgs/srv/IsMotionReady \
  "motion_key: 'motion_name'"
```

## Planning Behaviour

Whether a goal is planned depends on the combination of the `disable_motion_planning` parameter and the `skip_planning` goal field:

| `disable_motion_planning` | `skip_planning` | Result |
|:---:|:---:|---|
| `false` | `false` | Approach planned with MoveIt 2 |
| `false` | `true` | Approach executed without planning |
| `true` | `false` | Goal rejected |
| `true` | `true` | Approach executed without planning |

`````{tip}
PlayMotion2 plans a collision-free trajectory only for the approach to the first waypoint. All subsequent waypoints are linearly interpolated. Always validate motion sequences in simulation first to ensure no self-collisions occur between waypoints.
`````

## Video Reference

Standing up motion:

<video width="800" controls>
  <source src="/_static/videos/standing_up_edited.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>

## Further Reading

- [PlayMotion2 — GitHub repository](https://github.com/pal-robotics/play_motion2)
