Skip to content

Commit 17f4132

Browse files
authored
Merge pull request #111 from YuZhong-Chen/feat/ur5_ws
UR5 Workspace (Only support physical robot)
2 parents b546cec + fb8f749 commit 17f4132

File tree

571 files changed

+58727
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

571 files changed

+58727
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ The docker image of the template workspace is share by most of the workspace, al
9393
| [Unitree Go2](https://j3soon.github.io/ros2-essentials/go2-ws/) | ✔️ | ❌️ | Simulation only | [Yu-Zhong Chen](https://github.com/YuZhong-Chen), [Assume Zhan](https://github.com/Assume-Zhan), [Johnson Sun](https://github.com/j3soon) |
9494
| [Unitree H1](https://j3soon.github.io/ros2-essentials/h1-ws/) | ✔️ | ❌️ | Simulation only | [Johnson Sun](https://github.com/j3soon) |
9595
| [Hello Robot Stretch 3](https://j3soon.github.io/ros2-essentials/stretch3-ws/) | ✔️ | ❌️ | Simulation only | [@JustinShih0918](https://github.com/JustinShih0918), [Johnson Sun](https://github.com/j3soon) |
96+
| [Universal Robots UR5](https://j3soon.github.io/ros2-essentials/ur5-ws/) | ✔️ | ❌️ | Real-world support (CB3 only) | [Yu-Zhong Chen](https://github.com/YuZhong-Chen) |
9697
9798
If you have trouble using a workspace, please [open an issue](https://github.com/j3soon/ros2-essentials/issues) and tag the current maintainers mentioned above.
9899

docs/mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,5 @@ nav:
230230
- go2-ws/index.md
231231
- h1-ws/index.md
232232
- stretch3-ws/index.md
233+
- ur5-ws/index.md
233234
- dependencies.md
87.8 KB
Loading

docs/ur5-ws/index.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# Universal Robots UR5
2+
3+
[![GitHub code](https://img.shields.io/badge/code-blue?logo=github&label=github)](https://github.com/j3soon/ros2-essentials/tree/main/ur5_ws)
4+
[![GitHub last commit](https://img.shields.io/github/last-commit/j3soon/ros2-essentials?path=ur5_ws)](https://github.com/j3soon/ros2-essentials/commits/main/ur5_ws)
5+
6+
[![DockerHub image](https://img.shields.io/badge/dockerhub-j3soon/ros2--ur5--ws-important.svg?logo=docker)](https://hub.docker.com/r/j3soon/ros2-ur5-ws/tags)
7+
![Docker image arch](https://img.shields.io/badge/arch-amd64-blueviolet)
8+
![Docker image version](https://img.shields.io/docker/v/j3soon/ros2-ur5-ws)
9+
![Docker image size](https://img.shields.io/docker/image-size/j3soon/ros2-ur5-ws)
10+
11+
This workspace provides a ROS 2 Humble environment for controlling **Universal Robots UR5** manipulators. It includes the official [Universal_Robots_ROS2_Driver](https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver), description packages, **OnRobot RG2** gripper support, **servo control**, and **pose tracking**.
12+
13+
> Please note that this workspace has only been tested on the UR5 (CB3 version). In theory, it can support other models with minor configuration adjustments; please feel free to modify the settings as needed for your specific use case.
14+
15+
## Start Container
16+
17+
> Make sure your system meets the [system requirements](https://j3soon.github.io/ros2-essentials/#system-requirements) and have followed the [setup instructions](https://j3soon.github.io/ros2-essentials/#setup) before using this workspace.
18+
19+
Run the following commands in a Ubuntu desktop environment. If you are using a remote server, make sure you're using a terminal within a remote desktop session (e.g., VNC) instead of SSH (i.e., don't use `ssh -X` or `ssh -Y`).
20+
21+
```sh
22+
cd ~/ros2-essentials/ur5_ws/docker
23+
docker compose build
24+
xhost +local:docker
25+
docker compose up -d
26+
# The initial build will take a while, please wait patiently.
27+
```
28+
29+
> If your user's UID is `1000`, you may use `docker compose pull` instead of `docker compose build`.
30+
31+
The commands in the following sections assume that you are inside the Docker container:
32+
33+
```sh
34+
# in a new terminal
35+
docker exec -it ros2-ur5-ws bash
36+
```
37+
38+
If the initial build failed, rebuild the workspace inside the container:
39+
40+
```sh
41+
cd /home/ros2-essentials/ur5_ws
42+
rm -rf build install
43+
colcon build --symlink-install
44+
```
45+
46+
To stop and remove the container:
47+
48+
```sh
49+
docker compose down
50+
```
51+
52+
53+
## Simulation with URSim (CB3)
54+
55+
To test without hardware, run **URSim CB3** with the External Control URCap in Docker:
56+
57+
```sh
58+
cd ~/ros2-essentials/ur5_ws/docker/ursim
59+
docker compose up
60+
```
61+
62+
This starts a UR5 simulator at `192.168.56.101` (VNC on port 5900, Web on 6080). The ports 5900 and 6080 are forwarded to localhost, please change them in `docker/ursim/compose.yaml` if those ports conflict with existing services. Open <http://localhost:6080/vnc.html?host=localhost&port=6080> in your browser to access the URSim interface.
63+
64+
> ⚠️ Important: If you plan to switch to the physical robot, you must run `docker compose down` to remove the virtual network first. Failing to do so will cause IP address conflicts.
65+
66+
URSim provides an interface identical to the physical robot, making it ideal for rapid testing. However, please note that unlike `Gazebo` or `IsaacSim`, URSim does not possess a realistic physics engine. Therefore, it is not suitable for simulations requiring high physical fidelity.
67+
68+
Regarding the RG2 gripper: although it is not explicitly modeled in URSim, our control script operates via Digital I/O. Consequently, there is no need to disable the gripper configuration when running URSim; the code will execute without errors.
69+
70+
Since URSim aims to faithfully replicate the real robot's behavior, you should follow all the steps outlined in the subsequent sections, including calibration and bring-up.
71+
72+
## Setup Robot
73+
74+
> For URSim users, the settings are already pre-configured in the docker compose file, so you can skip this step.
75+
76+
Please refer to the [official installation](https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/doc/ur_client_library/doc/setup/robot_setup.html) guide. If the robot has been configured previously, you can typically skip this step.
77+
78+
For network setup, please refer to [this section](https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/doc/ur_client_library/doc/setup/network_setup.html) for network configuration.
79+
80+
## Robot Calibration
81+
82+
To improve accuracy, run the calibration correction and save the result to the workspace description config:
83+
84+
```sh
85+
cd /home/ros2-essentials/ur5_ws
86+
./scripts/ur5_calibration.sh
87+
```
88+
89+
You only need to run this once for each robot. This creates `default_kinematics.yaml` which is required for the subsequent steps.
90+
91+
## Bring Up Robot
92+
93+
Use the script:
94+
95+
```sh
96+
cd /home/ros2-essentials/ur5_ws
97+
./scripts/ur5_bringup.sh
98+
```
99+
100+
Or run the launch file directly:
101+
102+
```sh
103+
ros2 launch ur_robot_driver ur_control.launch.py \
104+
ur_type:=ur5 \
105+
use_rg2_gripper:=true \
106+
robot_ip:=192.168.56.101 \
107+
launch_rviz:=true
108+
```
109+
110+
> Set `use_rg2_gripper` parameter to **false** to disable the RG2 gripper.
111+
112+
Quick test for gripper actuation:
113+
114+
```sh
115+
# true = open, false = close
116+
ros2 topic pub --once /rg2/command std_msgs/msg/Bool "{data: true}"
117+
```
118+
119+
After bringing up the robot, make sure to click `Play` in the UR interface to start the control loop.
120+
121+
In the UR interface, go to `Home > Program Robot > Empty Program > Program > Structure > URCaps > External Control` and then click the Play button.
122+
123+
![](assets/ursim-external-control-running.png)
124+
125+
The UR interface control program will automatically stop if the ROS2 bring up node is stopped or crashes for safety reasons. If that happens, simply restart the bring up node and click `Play` again.
126+
127+
## Launch MoveIt 2
128+
129+
Launch MoveIt 2 for a quick test. You can move the arm by dragging the end-effector (EE) to a target position in RViz2, then clicking `Plan & Execute`.
130+
131+
```sh
132+
ros2 launch ur_moveit_config ur_moveit.launch.py \
133+
launch_rviz:=true \
134+
use_rg2_gripper:=true
135+
```
136+
137+
> Ensure the robot driver is already running before testing.
138+
139+
## Servo Control
140+
141+
The **ur_servo_control** package provides a simple example for controlling end-effector (EE) velocity. Please ensure the robot driver is launched before testing.
142+
143+
```sh
144+
ros2 launch ur_servo_control ur_servo.launch.py
145+
```
146+
147+
You can control the robot arm by publishing target velocities to the `/servo_node/delta_twist_cmds` topic.
148+
149+
For an implementation example within a ros node, refer to `ur5_ws/src/ur_servo_control/ur_servo_control/ur_servo_control.py`. Please be careful when selecting the reference frame. Use the following command to launch it:
150+
151+
```sh
152+
ros2 launch ur_servo_control ur_servo_control.launch.py
153+
```
154+
155+
The default velocities above are set to 0, you can modify the linear/angular velocities (`twist_msg.twist.{linear|angular}.{x|y|z}`) in `publish_servo_command_callback` in `ur5_ws/src/ur_servo_control/ur_servo_control/ur_servo_control.py`. But note that a constant velocity command will cause the robot to keep moving, which may be dangerous for real robot control (but fine for URSim testing).
156+
157+
## Pose Tracking
158+
159+
The **ur_pose_tracking** package provides an interface for controlling the end-effector (EE) position.
160+
161+
```sh
162+
# In terminal 1 (Launch the servo node):
163+
ros2 launch ur_servo_control ur_servo.launch.py
164+
# In terminal 2:
165+
ros2 launch ur_pose_tracking ur_pose_tracking.launch.py
166+
```
167+
168+
You can control the robot arm by publishing target pose to the `/target_pose` topic.
169+
170+
For application integration, it is recommended to refer to the **servo control implementation within the ros node**. To perform a quick test, please use the following command:
171+
172+
```sh
173+
ros2 topic pub --once /target_pose geometry_msgs/msg/PoseStamped "{header: {frame_id: 'world', stamp: {sec: 0, nanosec: 0}}, pose: {position: {x: -0.3, y: 0.0, z: 0.5}, orientation: {x: -0.35, y: 0.01, z: 0.93, w: -0.05}}}"
174+
```
175+
176+
> Note: This implementation does not account for singularities or collision avoidance and only supports linear paths between points. Consequently, it is ideal for high-density trajectory points. If your input points are sparse or require complex path planning and obstacle avoidance, please use the MoveIt planner instead.
177+
178+
## Troubleshooting
179+
180+
If you encounter issues on reproducing the examples above, consider remove all containers (`docker compose down` for URSim and workspace) and try again.
181+
182+
## References
183+
184+
- [Universal Robots ROS 2 Documentation](https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/)
185+
- [Robot Setup](https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/doc/ur_client_library/doc/setup/robot_setup.html)
186+
- [Setup URSim with Docker](https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/doc/ur_client_library/doc/setup/ursim_docker.html)
187+
- [Universal_Robots_ROS2_Driver](https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver)

tests/diff_base/docker/compose.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ services:
3535
# TODO: Set the USER_UID
3636
USER_UID: "${USER_UID:-1000}"
3737
# TODO: Set CUDA Toolkit version or set to "" if not using CUDA Toolkit
38-
# CUDA_TOOLKIT_VERSION: ""
38+
{PLACEHOLDER_#}CUDA_TOOLKIT_VERSION: "{PLACEHOLDER}"
3939
# TODO: Set Isaac Sim version or set to "" if not using Isaac Sim
40-
# ISAAC_SIM_VERSION: "5.0.0"
40+
{PLACEHOLDER_#}ISAAC_SIM_VERSION: "{PLACEHOLDER}"
4141
# TODO: Set Isaac Lab version or set to "" if not using Isaac Lab
42-
# ISAAC_LAB_VERSION: "2.3.2"
42+
{PLACEHOLDER_#}ISAAC_LAB_VERSION: "{PLACEHOLDER}"
4343
# TODO: Set to "YES" if using Isaac ROS or set to "" if not using Isaac ROS
44-
# ISAAC_ROS: ""
44+
{PLACEHOLDER_#}ISAAC_ROS: "{PLACEHOLDER}"
4545
# TODO: Set to "YES" if using Cartographer or set to "" if not using Cartographer
4646
{PLACEHOLDER_#}CARTOGRAPHER: "{PLACEHOLDER}"
4747
# TODO: Set to "YES" if using RTAB-Map or set to "" if not using RTAB-Map

ur5_ws/.devcontainer/create_env.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash -e
2+
3+
# Get the directory of this script.
4+
# Reference: https://stackoverflow.com/q/59895
5+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd)"
6+
DOCKER_DIR="${SCRIPT_DIR}/../docker"
7+
8+
# Normally, USER_UID is set during repo setup and works fine with the Docker CLI.
9+
# We need to manually write to .env because some devcontainer versions do not source ~/.bashrc,
10+
# leaving the environment variables undeclared.
11+
touch "${DOCKER_DIR}/.env"
12+
awk '!/^USER_UID=/' "${DOCKER_DIR}/.env" > "${DOCKER_DIR}/.env.tmp"
13+
echo "USER_UID=$(id -u)" >> "${DOCKER_DIR}/.env.tmp"
14+
mv "${DOCKER_DIR}/.env.tmp" "${DOCKER_DIR}/.env"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* Reference: https://aka.ms/devcontainer.json */
2+
{
3+
"name": "TODO",
4+
"dockerComposeFile": "../docker/compose.yaml",
5+
"service": "ur5-ws",
6+
// Set the USER_UID
7+
"initializeCommand": "\"${localWorkspaceFolder}\"/.devcontainer/create_env.sh",
8+
// Workspace settings
9+
"workspaceFolder": "/home/ros2-essentials/ur5_ws",
10+
// Vscode extensions
11+
"customizations": {
12+
"vscode": {
13+
"extensions": [
14+
"ms-vscode.cpptools",
15+
"ms-vscode.cpptools-themes",
16+
"twxs.cmake",
17+
"leojhonsong.python-extension-pack",
18+
"eamodio.gitlens",
19+
"mhutchie.git-graph",
20+
"streetsidesoftware.code-spell-checker",
21+
"ranch-hand-robotics.rde-pack"
22+
]
23+
}
24+
}
25+
}

ur5_ws/.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Visual Studio Code
2+
.vscode
3+
4+
# ROS2 basic directories
5+
/build
6+
/install
7+
/log
8+
9+
# Hard Links
10+
/docker/modules
11+
12+
# Docker environment variables
13+
/docker/.env

ur5_ws/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# ROS 2 Essentials Workspace
2+
3+
Please visit <https://j3soon.github.io/ros2-essentials/> for documentation.

ur5_ws/docker/.bashrc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Setup paths in `~/.profile` to allow unified environment variable across login/non-login shells
2+
# set PATH so it includes user's private bin if it exists
3+
if [ -d "$HOME/bin" ] ; then
4+
PATH="$HOME/bin:$PATH"
5+
fi
6+
# set PATH so it includes user's private bin if it exists
7+
if [ -d "$HOME/.local/bin" ] ; then
8+
PATH="$HOME/.local/bin:$PATH"
9+
fi
10+
11+
# Source global ROS2 environment
12+
source /opt/ros/$ROS_DISTRO/setup.bash
13+
# Source colcon-argcomplete
14+
source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash
15+
# Optionally perform apt update if it has not been executed yet
16+
if [ -z "$( ls -A '/var/lib/apt/lists' )" ]; then
17+
echo "apt-get update has not been executed yet. Running sudo apt-get update..."
18+
sudo apt-get update
19+
fi
20+
# Optionally perform rosdep update if it has not been executed yet
21+
if [ ! -d $HOME/.ros/rosdep/sources.cache ]; then
22+
echo "rosdep update has not been executed yet. Running rosdep update..."
23+
rosdep update --rosdistro $ROS_DISTRO
24+
cd $ROS2_WS
25+
# Ref: https://docs.ros.org/en/humble/Tutorials/Intermediate/Rosdep.html
26+
rosdep install --from-paths src --ignore-src -y -r
27+
fi
28+
# Optionally build the workspace if it has not been built yet
29+
if [ ! -f $ROS2_WS/install/setup.bash ]; then
30+
echo "Workspace has not been built yet. Building workspace..."
31+
cd $ROS2_WS
32+
# TODO: If command `arch` outputs `aarch64`, consider adding `--packages-ignore <package>` to ignore x86 packages
33+
# Ref: https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-Your-First-ROS2-Package.html
34+
if [ $(arch) == "aarch64" ]; then
35+
colcon build --symlink-install
36+
else
37+
colcon build --symlink-install
38+
fi
39+
echo "Workspace built."
40+
fi
41+
# Source gazebo environment
42+
# Ref: https://classic.gazebosim.org/tutorials?tut=ros2_installing&cat=connect_ros#InstallGazebo
43+
if [ $(arch) == "x86_64" ]; then
44+
source /usr/share/gazebo/setup.bash
45+
fi
46+
# TODO: Source other workspace environments as underlay
47+
# Source workspace environment
48+
source $ROS2_WS/install/setup.bash
49+
echo "Successfully built workspace and configured environment variables."

0 commit comments

Comments
 (0)