OpenArm Teaching Function Tutorial¶
Overview¶
The OpenArm teaching feature provides a full trajectory recording/playback system for bimanual robots.
- Record trajectory: real-time recording of all joint states (both arms + both grippers)
- Playback trajectory: accurate replay with speed scaling and selective playback
- Multi-controller coordination: automatic synchronization of left arm, right arm, left gripper, and right gripper controllers
System Architecture¶
Based on ROS 2 Action interfaces, with two core modules:
1. Recording module (record_joint_states_always)¶
- Subscribes to
/joint_statesand samples at fixed frequency - Supports interactive control (start/pause/clear/save)
- Exports standard YAML trajectory files
2. Playback module (play_joint_trajectory)¶
- Loads YAML trajectory and auto-groups joints
- Uses FollowJointTrajectory Action for arms
- Uses GripperCommand Action for grippers
- Supports parallel multi-controller execution and time synchronization
Quick Start¶
Environment preparation¶
cd ~/openarmx_robotstride_ws-cc
colcon build --packages-select openarm_utils
source install/setup.bash
Step 1: Launch robot control system (MoveIt)¶
ros2 launch openarm_bimanual_moveit_config demo.launch.py
Step 2: Tune KP/KD¶
Since teaching requires manual repositioning, set KP/KD to low values.
Video in production, coming soon.
Step 3: Record trajectory¶
ros2 run openarm_utils record_joint_states_always --rate 20
Recording parameters¶
| Parameter | Description | Default |
|---|---|---|
| --rate | Sampling frequency (Hz) | 10 |
| --topic | Joint state topic | /joint_states |
| --outfile | Output file path | Auto-generated |
Interactive controls¶
| Key | Function |
|---|---|
| SPACE or p | Start/Pause |
| c | Clear all recorded data (confirm required) |
| w | Save and exit (confirm required) |
| q | Exit without saving |
Suggested sampling rates¶
- Coarse motion: 5-10 Hz
- General teaching: 10-20 Hz (recommended)
- Fine manipulation: 20-50 Hz
Step 4: Playback trajectory¶
Playback all joints¶
ros2 run openarm_utils play_joint_trajectory joint_states_stream_20231215_143052.yaml --all-joints
Selective playback¶
ros2 run openarm_utils play_joint_trajectory <yaml_file> --left-arm
ros2 run openarm_utils play_joint_trajectory <yaml_file> --right-arm
ros2 run openarm_utils play_joint_trajectory <yaml_file> --both-arms
ros2 run openarm_utils play_joint_trajectory <yaml_file> --joints openarm_left_joint1 openarm_left_joint2
Playback parameters¶
| Parameter | Description | Default |
|---|---|---|
| --all-joints | Replay all joints | Yes |
| --left-arm | Left arm only | No |
| --right-arm | Right arm only | No |
| --both-arms | Both arms without grippers | No |
| --joints | Specific joints | - |
| --rate-scale | Playback speed scale | 1.0 |
| --action | Specify single Action | Auto detect |
| --sync-feedback | Enable feedback sync | No |
| --sync-margin | Trigger lead time (s) | 0.0 |
Speed control¶
ros2 run openarm_utils play_joint_trajectory <yaml_file> --all-joints --rate-scale 2.0
ros2 run openarm_utils play_joint_trajectory <yaml_file> --all-joints --rate-scale 0.5
Advanced Features¶
Multi-controller synchronization¶
Auto grouping¶
| Joint prefix | Controller | Action type |
|---|---|---|
| openarm_left_joint* | Left arm controller | FollowJointTrajectory |
| openarm_right_joint* | Right arm controller | FollowJointTrajectory |
| openarm_left_finger* | Left gripper controller | GripperCommand |
| openarm_right_finger* | Right gripper controller | GripperCommand |
Sync modes¶
ros2 run openarm_utils play_joint_trajectory <yaml_file> --all-joints
ros2 run openarm_utils play_joint_trajectory <yaml_file> --all-joints --sync-feedback
ros2 run openarm_utils play_joint_trajectory <yaml_file> --all-joints --sync-feedback --sync-margin 0.05
Single controller test¶
ros2 run openarm_utils play_joint_trajectory <yaml_file> --action /left_gripper_controller/gripper_cmd
ros2 run openarm_utils play_joint_trajectory <yaml_file> --action /right_joint_trajectory_controller/follow_joint_trajectory
Trajectory File Format¶
joint_names:
- openarm_left_joint1
- openarm_left_joint2
- ...
points:
- positions: [0.0, -0.5, 0.3, ...]
time_from_start: 0.05
Practical Examples¶
Case 1: Bimanual coordinated grasp¶
ros2 run openarm_utils record_joint_states_always --rate 20
ros2 run openarm_utils play_joint_trajectory joint_states_stream_*.yaml --all-joints
ros2 run openarm_utils play_joint_trajectory joint_states_stream_*.yaml --all-joints --rate-scale 0.5
Case 2: Single-arm precise operation¶
ros2 run openarm_utils record_joint_states_always --rate 50
ros2 run openarm_utils play_joint_trajectory joint_states_stream_*.yaml --left-arm
Case 3: Gripper-only test¶
ros2 run openarm_utils record_joint_states_always --rate 10
ros2 run openarm_utils play_joint_trajectory joint_states_stream_*.yaml \
--action /left_gripper_controller/gripper_cmd \
--joints openarm_left_finger_joint1 openarm_left_finger_joint2