5.3. Vulcanexus HRI Pose Detection Tutorial¶
5.3.1. Quickview¶
This tutorial will explore the process of implementing pose detection capabilities within the Vulcanexus framework. It will cover the necessary steps to set up the environment, integrate the pose detection model and visualize the results in RViz2.
A deeper explanation of the pose detection package can be found in the Human Pose recognition section.
5.3.2. Prerequisites¶
Before starting this tutorial, ensure you have the following prerequisites:
A working installation of Vulcanexus with HRI modules.
Docker and Docker Compose installed on your system.
Familiarity with ROS 2 concepts and tools.
Webcam or a ROS 2 compatible video input device.
GPU hardware to load the pose detection model.
5.3.3. Initial Setup¶
The tutorial will make use of the Vulcanexus docker image in order to simplify the setup process. However, it is also possible to run the tutorial on a native installation of Vulcanexus.
In order to run the tutorial, it is also necessary to have a ROS 2 node publishing images on a known topic.
Images are expected to be in sensor_msgs/msg/Image format and topic /color/image_raw.
The next section describes how to set up a simple image publisher using a webcam.
If you already have a node publishing images, you can skip this section and proceed to the next one (Run the Face Detection Node).
To improve communication performance, we will increase sockets buffer sizes by setting an XML configuration file before running any ROS 2 nodes.
First, ensure your system has enabled system sockets buffer sizes of 11 MB or higher (see this guide).
Then, download the following XML file and save it as ~/image.xml:
wget https://raw.githubusercontent.com/eProsima/agile-hri/refs/heads/main/hri_detection_display/config/image.xml -O ~/image.xml
Then, export the following environment variable to every terminal where ROS 2 nodes will be run:
export FASTDDS_DEFAULT_PROFILES_FILE="~/image.xml"
5.3.3.1. Use a webcam as image source¶
In case of using Docker, it is needed to give access to the webcam device inside the container.
Usually, the webcam is located at /dev/video0.
Run Vulcanexus docker image with the following command, replacing <VULCANEXUS_DISTRO> with your Vulcanexus distribution:
docker run --device /dev/video0 -it --rm --net host --ipc host ubuntu-vulcanexus:<VULCANEXUS_DISTRO>-hri
To publish images from a webcam, you can use the usb_cam package. Install it with the following command:
apt update && \
apt install -y ros-${VULCANEXUS_DISTRO}-usb-cam
Note
Package usb_cam is already included in the Vulcanexus Docker image.
After sourcing the Vulcanexus installation, run the usb_cam node to publish images from the webcam:
source /opt/vulcanexus/${VULCANEXUS_DISTRO}/setup.bash && \
ros2 run usb_cam usb_cam_node_exe --ros-args -r /image_raw:=/color/image_raw -r /image_raw/compressed:=/color/image_raw/compressed -r /camera_info:=/color/camera_info
After this command, the node should be publishing 640x480 images on the /image_raw topic at 30 frames per second.
To check it, attach a new terminal to the running container and subscribe to the topic following the steps below:
docker exec -it "$(docker ps --quiet | head -n 1)" bash
source /opt/vulcanexus/${VULCANEXUS_DISTRO}/setup.bash
ros2 topic list
ros2 topic echo /color/image_raw --no-arr
Warning
If there are other docker containers running in your system, "$(docker ps --quiet | head -n 1)" should be replaced with the container ID of the Vulcanexus container to avoid attaching to the wrong container.
If images are being published correctly, you should see the output of the ros2 topic echo command updating at 30 Hz.
At this point, this node can be left running in the background while proceeding to the next section.
Nonetheless, if you prefer to run the entire tutorial using only Docker and one terminal, you can stop the Docker container and enable the local_webcam service included in the compose.yaml file used in the following section.
5.3.4. Run the Pose Detection Node¶
Now that there is a node publishing images on the network, we can proceed to run the pose detection node.
The pose detection node subscribes to a topic of type sensor_msgs/msg/Image and publishes the detected bodies as hri_msgs/msg/Skeleton2DList messages on a keyed topic name /humans/bodies.
Similarly to the face recognition module, hri_pose_detect package requires to also run the hri_id_manager node, which is responsible for managing the IDs of the detected poses.
The ID manager provides a service that assigns a unique ID to each detected pose.
If the hri_face_detect node is also running, the ID manager will ensure that the same ID is assigned to the same person across both packages.
To run both nodes simultaneously, create a compose.yaml file with the following content:
x-common-config:
&common-config
network_mode: host
ipc: host
x-common-variables:
&common-variables
ROS_DOMAIN_ID: 42
services:
id_manager:
image: ubuntu-vulcanexus:<VULCANEXUS_DISTRO>-hri
<<: *common-config
environment:
<<: *common-variables
command: >
ros2 launch hri_id_manager id_manager.launch.py
pose_detect_2D:
image: ubuntu-vulcanexus:<VULCANEXUS_DISTRO>-hri
<<: *common-config
environment:
<<: *common-variables
FASTDDS_DEFAULT_PROFILES_FILE: ~/image.xml
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
command: >
ros2 launch hri_pose_detect pose_detect.launch.py rgb_camera_topic:=/color/image_raw
# Run ($xhost local:root) before starting this container to be able to display RViz2
detection_display_2D:
image: ubuntu-vulcanexus:<VULCANEXUS_DISTRO>-hri
<<: *common-config
privileged: true
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw
environment:
<<: *common-variables
DISPLAY: ":1"
LIBGL_ALWAYS_SOFTWARE: 1
FASTDDS_DEFAULT_PROFILES_FILE: ~/image.xml
profiles: ["display"]
command: >
ros2 launch hri_detection_display person_detection_display.launch.py rgb_camera_topic:=/color/image_raw rviz:=True
# Not needed if there is already a node publishing images on /color/image_raw
local_webcam:
image: ubuntu-vulcanexus:<VULCANEXUS_DISTRO>-hri
<<: *common-config
environment:
<<: *common-variables
FASTDDS_DEFAULT_PROFILES_FILE: ~/image.xml
devices:
- /dev/video0
profiles: ["usb_cam"]
command: >
ros2 run usb_cam usb_cam_node_exe --ros-args -r /image_raw:=/color/image_raw -r /image_raw/compressed:=/color/image_raw/compressed -r /camera_info:=/color/camera_info
Note
The ROS_DOMAIN_ID environment variable at the top of the file can be used to set the ROS 2 domain ID for all the nodes.
To start the pose detection node along with the ID manager, run the following command in the same directory where the compose.yaml file is located:
docker compose up -d
At this point, the pose detection node should be running and publishing the detected bodies on the /humans/bodies topic.
To verify it, attach a new terminal to one of the running containers and subscribe to the topic:
docker exec -it "$(docker ps --quiet | head -n 1)" bash
source /opt/vulcanexus/${VULCANEXUS_DISTRO}/setup.bash
ros2 topic list
ros2 topic echo /humans/bodies --no-arr
Warning
If there are other docker containers running in your system, "$(docker ps --quiet | head -n 1)" should be replaced with the container ID of one of the Vulcanexus containers to avoid attaching to the wrong container.
If bodies are being detected correctly, you should see the output of the ros2 topic echo command updating at 30 Hz with the list of detected bodies.
However, the most intuitive way to visualize the detected bodies is by using RViz2.
To do so, Vulcanexus includes an HRI package called hri_detection_display that provides a convenient way to visualize the detected bodies in RViz2.
This package subscribes to the /humans/bodies topic and displays the detected bodies as bounding boxes over the input images.
It also paints the skeleton of each detected body by connecting visible keypoints with lines.
To execute it, run the following command in the same terminal where the compose.yaml file is located:
docker compose --profile display up -d
This command will start the hri_detection_display node in a new container and launch RViz2 to visualize the detected faces.
The compose.yaml file includes an optional service local_webcam which can be used to publish images from a webcam, alternatively to the setup explained in the previous section.
It is provided in case the user wants to run the entire tutorial using only Docker and one terminal.
To enable it, run the following command instead:
docker compose --profile display --profile usb_cam up -d
To stop all the running containers, use the following command:
docker compose --profile display --profile usb_cam down
Note
If you are running the tutorial on a native installation of Vulcanexus, you can run the nodes in separate terminals instead of using Docker Compose.
Just make sure to source the Vulcanexus installation in each terminal before running the nodes and use the compose.yaml file as a reference for the commands to run each node.
5.3.5. Use 3D Pose Detection¶
The hri_pose_detect package also supports a 3D pose detection model that can be used to detect human bodies in 3D space.
To use the 3D model, the input images must be accompanied by depth images and camera information.
The depth images must be published on a topic of type sensor_msgs/msg/Image and name /depth/image_raw.
Conventional webcams do not provide depth information, so specialized hardware is required to continue with this section.
To run the 3D pose detection node, substitute the pose_detect_2D service in the compose.yaml file as follows:
pose_detect_3D:
image: ubuntu-vulcanexus:{VULCANEXUS_DISTRO}-hri
<<: *common-config
environment:
<<: *common-variables
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
command: >
ros2 launch hri_pose_detect pose_detect.launch.py use_depth:=True rgb_camera_topic:=/color/image_raw depth_camera_topic:=/depth/image_raw
Similarly, the hri_detection_display package includes an extension to support 3D display, using ROS 2 markers to represent human bodies.
To use this feature replace the detection_display_2D service as follows:
detection_display_3D:
image: ubuntu-vulcanexus:{VULCANEXUS_DISTRO}-hri
<<: *common-config
privileged: true
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw
environment:
<<: *common-variables
DISPLAY: ":1"
LIBGL_ALWAYS_SOFTWARE: 1
profiles: ["display"]
command: >
ros2 launch hri_detection_display skel_3D_display.launch.py pub_static_tf:=True
After modifying the compose.yaml file, re-run the previous command to start the 3D pose detection node along with the ID manager:
docker compose --profile display up -d
Note
If you are running the tutorial on a native installation of Vulcanexus, you can run the nodes in separate terminals instead of using Docker Compose.
Just make sure to source the Vulcanexus installation in each terminal before running the nodes and use the compose.yaml file as a reference for the commands to run each node.