Skip to content

Commit 91c60c6

Browse files
committed
feat: implement animation recorder
1 parent 0437d62 commit 91c60c6

25 files changed

+3516
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(motion_recorder_msgs)
3+
4+
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
5+
add_compile_options(-Wall -Wextra -Wpedantic)
6+
endif()
7+
8+
# find dependencies
9+
find_package(ament_cmake REQUIRED)
10+
find_package(std_msgs REQUIRED)
11+
find_package(rosidl_default_generators REQUIRED)
12+
13+
rosidl_generate_interfaces(${PROJECT_NAME}
14+
"srv/SaveMotion.srv"
15+
"srv/LoadMotion.srv"
16+
"srv/ListMotions.srv"
17+
DEPENDENCIES std_msgs
18+
)
19+
20+
if(BUILD_TESTING)
21+
find_package(ament_lint_auto REQUIRED)
22+
# the following line skips the linter which checks for copyrights
23+
# comment the line when a copyright and license is added to all source files
24+
set(ament_cmake_copyright_FOUND TRUE)
25+
# the following line skips cpplint (only works in a git repo)
26+
# comment the line when this package is in a git repo and when
27+
# a copyright and license is added to all source files
28+
set(ament_cmake_cpplint_FOUND TRUE)
29+
ament_lint_auto_find_test_dependencies()
30+
endif()
31+
32+
ament_package()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>motion_recorder_msgs</name>
5+
<version>0.0.0</version>
6+
<description>Message definitions for motion recorder package</description>
7+
<maintainer email="[email protected]">kpatch</maintainer>
8+
<license>Apache-2.0</license>
9+
10+
<buildtool_depend>ament_cmake</buildtool_depend>
11+
12+
<depend>std_msgs</depend>
13+
<build_depend>rosidl_default_generators</build_depend>
14+
<exec_depend>rosidl_default_runtime</exec_depend>
15+
<member_of_group>rosidl_interface_packages</member_of_group>
16+
17+
<test_depend>ament_lint_auto</test_depend>
18+
<test_depend>ament_lint_common</test_depend>
19+
20+
<export>
21+
<build_type>ament_cmake</build_type>
22+
</export>
23+
</package>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Empty request
2+
---
3+
bool success # Whether the operation was successful
4+
string message # Success/error message
5+
string[] motion_list # List of available motion names
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
string name # Motion name to load
2+
---
3+
bool success # Whether the operation was successful
4+
string message # Additional information or error message
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
string name # Motion name to save
2+
---
3+
bool success # Whether the operation was successful
4+
string message # Additional information or error message
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Motion Recorder
2+
3+
A ROS2 package for recording and playing back motion sequences for Dynamixel servo-controlled robot head. This package allows you to manually position your robot's head and record the motion for later playback.
4+
5+
## Features
6+
7+
- Record head motion by manually moving it with torque disabled
8+
- Mark keyframes during recording to identify important positions
9+
- Save and load motion sequences
10+
- Play back recorded motion sequences with smooth interpolation
11+
- User-friendly Qt-based interface
12+
13+
## Requirements
14+
15+
- ROS2 (Jazzy or compatible)
16+
- Python 3
17+
- PyQt5
18+
- Dynamixel SDK
19+
- XM540-W270 Dynamixel servo motors
20+
21+
## Installation
22+
23+
1. Clone this repository into your ROS2 workspace:
24+
25+
```bash
26+
cd /path/to/your/workspace/src
27+
git clone https://github.com/yourusername/motion_recorder.git
28+
```
29+
30+
2. Install dependencies:
31+
32+
```bash
33+
sudo apt-get install python3-pyqt5
34+
pip3 install dynamixel-sdk
35+
```
36+
37+
3. Build the package:
38+
39+
```bash
40+
cd /path/to/your/workspace
41+
colcon build --packages-select motion_recorder
42+
```
43+
44+
4. Source the workspace:
45+
46+
```bash
47+
source /path/to/your/workspace/install/setup.bash
48+
```
49+
50+
## Usage
51+
52+
### Launch the Motion Recorder
53+
54+
```bash
55+
ros2 launch motion_recorder motion_recorder.launch.py
56+
```
57+
58+
### Launch Parameters
59+
60+
The launch file accepts several parameters:
61+
62+
- `serial_port`: Serial port for connecting to Dynamixel servos (default: '/dev/ttyUSB0')
63+
- `baudrate`: Baudrate for Dynamixel communication (default: 1000000)
64+
- `sampling_rate`: Sampling rate in Hz for motion recording (default: 50.0)
65+
- `motion_files_dir`: Directory to store motion files (default: ~/.ros/motion_files)
66+
67+
Example with custom parameters:
68+
69+
```bash
70+
ros2 launch motion_recorder motion_recorder.launch.py serial_port:=/dev/ttyUSB1 baudrate:=57600
71+
```
72+
73+
### Recording Motion
74+
75+
1. Launch the motion recorder
76+
2. Click "Disable Torque" to allow manual positioning
77+
3. Click "Start Recording" to begin recording
78+
4. Manually move the robot head to create your motion
79+
5. Click "Mark Keyframe" at important positions
80+
6. Click "Stop Recording" when finished
81+
7. Enter a name for your motion and click "Save Motion"
82+
83+
### Playing Back Motion
84+
85+
1. Launch the motion recorder
86+
2. Select a motion from the "Motion Library" tab or load a motion
87+
3. Click "Play Motion" to play back the recorded motion
88+
4. Click "Stop Playback" to stop the motion
89+
90+
## License
91+
92+
Apache License 2.0
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
Launch file for the motion recorder package.
6+
Launches both the recorder node and the UI node.
7+
"""
8+
9+
import os
10+
from launch import LaunchDescription
11+
from launch.actions import DeclareLaunchArgument
12+
from launch.substitutions import LaunchConfiguration, EnvironmentVariable, PathJoinSubstitution
13+
from launch_ros.actions import Node
14+
15+
def generate_launch_description():
16+
"""Generate launch description for motion recorder."""
17+
18+
# Declare launch arguments
19+
serial_port = LaunchConfiguration('serial_port', default='/dev/ttyUSB0')
20+
baudrate = LaunchConfiguration('baudrate', default='1000000')
21+
sampling_rate = LaunchConfiguration('sampling_rate', default='50.0')
22+
motion_files_dir = LaunchConfiguration(
23+
'motion_files_dir',
24+
default=PathJoinSubstitution([EnvironmentVariable('HOME'), '.ros/motion_files'])
25+
)
26+
27+
# Create list of declared arguments
28+
declared_arguments = [
29+
DeclareLaunchArgument(
30+
'serial_port',
31+
default_value='/dev/ttyUSB0',
32+
description='Serial port for connecting to Dynamixel servos'
33+
),
34+
DeclareLaunchArgument(
35+
'baudrate',
36+
default_value='1000000',
37+
description='Baudrate for Dynamixel communication'
38+
),
39+
DeclareLaunchArgument(
40+
'sampling_rate',
41+
default_value='50.0',
42+
description='Sampling rate in Hz for motion recording'
43+
),
44+
DeclareLaunchArgument(
45+
'motion_files_dir',
46+
default_value=PathJoinSubstitution([EnvironmentVariable('HOME'), '.ros/motion_files']),
47+
description='Directory to store motion files'
48+
),
49+
]
50+
51+
# Configure nodes
52+
recorder_node = Node(
53+
package='motion_recorder',
54+
executable='recorder_node',
55+
name='motion_recorder',
56+
output='screen',
57+
parameters=[{
58+
'port': serial_port,
59+
'baudrate': baudrate,
60+
'sampling_rate': sampling_rate,
61+
'motion_files_dir': motion_files_dir,
62+
}],
63+
emulate_tty=True
64+
)
65+
66+
ui_node = Node(
67+
package='motion_recorder',
68+
executable='recorder_ui',
69+
name='motion_recorder_ui',
70+
output='screen',
71+
emulate_tty=True
72+
)
73+
74+
# Return launch description
75+
return LaunchDescription(
76+
declared_arguments + [recorder_node, ui_node]
77+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
Motion Recorder Package
6+
Provides tools for recording and playing back motion
7+
sequences for Dynamixel servo-controlled robot head
8+
"""
9+
10+
__author__ = 'Your Name'
11+
__version__ = '0.1.0'
12+
__license__ = 'Apache-2.0'

0 commit comments

Comments
 (0)