Skip to content

Commit

Permalink
Add namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
rafal-gorecki committed Jan 2, 2024
1 parent 3d74f75 commit ad69c57
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 115 deletions.
30 changes: 10 additions & 20 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@
ARG ROS_DISTRO=humble
ARG PREFIX=

# =========================== package builder ===============================
FROM husarnet/ros:$ROS_DISTRO-ros-base AS pkg-builder

SHELL ["/bin/bash", "-c"]

WORKDIR /ros2_ws

# install everything needed
# Setup workspace
RUN git clone https://github.com/Slamtec/sllidar_ros2.git /ros2_ws/src/sllidar_ros2 && \
cp /ros2_ws/src/sllidar_ros2/launch/sllidar_a1_launch.py \
/ros2_ws/src/sllidar_ros2/launch/sllidar_launch.py && \
rosdep update --rosdistro $ROS_DISTRO && \
rosdep install --from-paths src --ignore-src -y

# Create health check package
# Create healthcheck package
RUN cd src/ && \
source /opt/ros/$ROS_DISTRO/setup.bash && \
ros2 pkg create healthcheck_pkg --build-type ament_cmake --dependencies rclcpp sensor_msgs && \
Expand All @@ -25,34 +24,25 @@ RUN cd src/ && \
install(TARGETS healthcheck_node DESTINATION lib/${PROJECT_NAME})' \
/ros2_ws/src/healthcheck_pkg/CMakeLists.txt

COPY ./healthcheck.cpp /ros2_ws/src/healthcheck_pkg/src/
COPY ./husarion_utils/healthcheck.cpp /ros2_ws/src/healthcheck_pkg/src/

# Build
RUN source /opt/ros/$ROS_DISTRO/setup.bash && \
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release && \
echo $(cat /ros2_ws/src/sllidar_ros2/package.xml | grep '<version>' | sed -r 's/.*<version>([0-9]+.[0-9]+.[0-9]+)<\/version>/\1/g') > /version.txt && \
rm -rf build log

# Second stage - Deploy the built packages
FROM husarnet/ros:${PREFIX}${ROS_DISTRO}-ros-core
# =========================== final stage ===============================
FROM husarnet/ros:${PREFIX}${ROS_DISTRO}-ros-core AS final-stage

ARG PREFIX
ENV PREFIX_ENV=$PREFIX

SHELL ["/bin/bash", "-c"]

COPY --from=pkg-builder /ros2_ws /ros2_ws
COPY --from=pkg-builder /version.txt /version.txt
COPY ./husarion_utils /husarion_utils

RUN echo $(cat /ros2_ws/src/sllidar_ros2/package.xml | grep '<version>' | sed -r 's/.*<version>([0-9]+.[0-9]+.[0-9]+)<\/version>/\1/g') > /version.txt

# Run healthcheck in background
RUN entrypoint_file=$(if [ -f "/ros_entrypoint.sh" ]; then echo "/ros_entrypoint.sh"; else echo "/vulcanexus_entrypoint.sh"; fi) && \
sed -i '/test -f "\/ros2_ws\/install\/setup.bash" && source "\/ros2_ws\/install\/setup.bash"/a \
ros2 run healthcheck_pkg healthcheck_node &' \
$entrypoint_file

COPY ./healthcheck.sh /
HEALTHCHECK --interval=2s --timeout=1s --start-period=20s --retries=1 \
CMD ["/healthcheck.sh"]
CMD ["/husarion_utils/healthcheck.sh"]

# Ensure LIDAR stops spinning on container shutdown
STOPSIGNAL SIGINT
81 changes: 50 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,70 @@ The repository includes a GitHub Actions workflow that automatically deploys bui

[![ROS Docker Image](https://github.com/husarion/rplidar-docker/actions/workflows/ros-docker-image.yaml/badge.svg)](https://github.com/husarion/rplidar-docker/actions/workflows//ros-docker-image.yaml)


## Prepare Environment

**1. Plugin the Device**
1. Plugin the Device

You can use `lsusb` command to check if the device is visible.

## Demo

**1. Clone the Repository**
1. Clone the Repository

```bash
git clone https://github.com/husarion/rplidar-docker.git
cd rplidar-docker/demo
```

2. Select the Appropriate Baudrate

```bash
export RPLIDAR_BAUDRATE=<baudrate>
```

Replace `<baudrate>` with appropriate baudrate for your LiDAR from below table.

| **Product Name** | **Baudrate** |
| ---------------- | ------------- |
| RPlidar A2M8 | **`115200`** |
| RPlidar A2M12 | **`256000`** |
| RPlidar A3 | **`256000`** |
| RPlidar S1 | **`256000`** |
| RPlidar S2 | **`1000000`** |
| RPlidar S3 | **`1000000`** |

3. Activate the Device

```bash
git clone https://github.com/husarion/rplidar-docker.git
cd rplidar-docker/demo
```
```bash
docker compose up rplidar
```

**2. Select the Appropriate Baudrate**
4. Launch Visualization

```bash
export RPLIDAR_BAUDRATE=<baudrate>
```
```bash
xhost local:root
docker compose up rviz
```

Replace `<baudrate>` with appropriate baudrate for your LiDAR from below table.
> [!NOTE]
> To use the latest version of the image, run the `docker compose pull` command.
| **Product Name** | **Baudrate** |
| ---------------- | ------------- |
| RPlidar A2M8 | **`115200`** |
| RPlidar A2M12 | **`256000`** |
| RPlidar A3 | **`256000`** |
| RPlidar S1 | **`256000`** |
| RPlidar S2 | **`1000000`** |
| RPlidar S3 | **`1000000`** |
## Parameters

**3. Activate the Device**
The original launch has been modified with the new parameters:

```bash
docker compose up rplidar
```
| **Product Name** | **Description** | **Default Value** |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| `launch_file` | Name of launch file from repo `sllidar_ros2` to run | `sllidar_launch.py` |
| `serial_baudrate` | Baudrate of connected lidar (depend on your RPlidar model) | `115200` |
| `serial_port` | USB port of connected lidar | `/dev/ttyUSB0` |
| `robot_namespace` | Namespace which will appear in front of all topics (including `/tf` and `/tf_static`). | `env("ROS_NAMESPACE")` (`""` if not specified) |
| `device_namespace` | Sensor namespace that will appear before all non absolute topics and TF frames, used for distinguishing multiple cameras on the same robot. | `""` |

**4. Launch Visualization**
Using both `device_namespace` and `robot_namespace` makes:

```bash
xhost local:root
docker compose up rviz
```
- Topic: `/<robot_namespace>/<device_namespace>/<default_topic>`
- Topic TF: `/<robot_namesace>/tf`
- URDF Links: `<device_namespace>_link`

> [!NOTE]
> You can run the visualization on any device, provided that it is connected to the computer to which the sensor is connected.
If any of the namespaces are missing, the field with `/` is omitted for topics, or replaced with default ones for URDF links.
7 changes: 7 additions & 0 deletions demo/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# =======================================
# Namespace config
# =======================================
# To use multimle devices on multible robot you have to specify following field

# Uncomment to add robot namespace
# ROS_NAMESPACE=robot
33 changes: 17 additions & 16 deletions demo/compose.yaml
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
# Quick Start
# docker compose up
x-common-config:
&common-config
network_mode: host
ipc: host
env_file: .env

services:

rplidar:
image: husarion/rplidar:humble
restart: unless-stopped
network_mode: host
ipc: host
# image: husarion/rplidar:humble
build:
context: ..
dockerfile: Dockerfile
<<: *common-config
devices:
- /dev/ttyUSB0
environment:
- ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-0}
- RMW_IMPLEMENTATION=${RMW_IMPLEMENTATION:-rmw_fastrtps_cpp}
command: >
ros2 launch sllidar_ros2 sllidar_launch.py
serial_baudrate:=${RPLIDAR_BAUDRATE:-256000}
serial_baudrate:=${RPLIDAR_BAUDRATE:-115200}
device_namespace:=lidar
rviz:
image: husarion/rviz2:humble
restart: on-failure
network_mode: host
ipc: host
<<: *common-config
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw
- ./default.rviz:/root/.rviz2/default.rviz
- ./rviz.launch.py:/ros2_ws/rviz.launch.py
environment:
- DISPLAY=${DISPLAY:?err}
- LIBGL_ALWAYS_SOFTWARE=1
- ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-0}
- RMW_IMPLEMENTATION=${RMW_IMPLEMENTATION:-rmw_fastrtps_cpp}
command: >
ros2 launch rviz.launch.py
device_namespace:=lidar
2 changes: 1 addition & 1 deletion demo/default.rviz
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Visualization Manager:
Filter size: 10
History Policy: Keep Last
Reliability Policy: Reliable
Value: /scan
Value: scan
Use Fixed Frame: true
Use rainbow: true
Value: true
Expand Down
66 changes: 66 additions & 0 deletions demo/rviz.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from launch import LaunchDescription
from launch_ros.actions import Node, PushRosNamespace
from launch.actions import DeclareLaunchArgument, OpaqueFunction
from launch.substitutions import EnvironmentVariable, LaunchConfiguration


def replace_rviz_fixed_frame(input_file, output_file, fix_frame):
with open(input_file, "r") as file:
rviz_content = file.read()

rviz_content = rviz_content.replace("Fixed Frame: laser", f"Fixed Frame: {fix_frame}")

with open(output_file, "w") as file:
file.write(rviz_content)


def launch_setup(context, *args, **kwargs):
robot_namespace = LaunchConfiguration("robot_namespace").perform(context)
device_namespace = LaunchConfiguration("device_namespace").perform(context)

default_rviz_conf = "/root/.rviz2/default.rviz"
rviz_conf = "/root/.rviz2/modified_default.rviz"
if device_namespace:
frame_id = f"{device_namespace}_link"
else:
frame_id = "laser"
replace_rviz_fixed_frame(default_rviz_conf, rviz_conf, frame_id)

remapping = []
if robot_namespace:
remapping.append(("/clicked_point", f"/{robot_namespace}/clicked_point"))
remapping.append(("/goal_pose", f"/{robot_namespace}/goal_pose"))
remapping.append(("/initialpose", f"/{robot_namespace}/initialpose"))
remapping.append(("/tf", f"/{robot_namespace}/tf"))
remapping.append(("/tf_static", f"/{robot_namespace}/tf_static"))

rviz = Node(
package="rviz2",
executable="rviz2",
name="rviz2",
namespace=device_namespace,
remappings=remapping,
arguments=["-d", rviz_conf],
output="screen",
)

return [PushRosNamespace(robot_namespace), rviz]


def generate_launch_description():
return LaunchDescription(
[
DeclareLaunchArgument(
"robot_namespace",
default_value=EnvironmentVariable("ROS_NAMESPACE", default_value=""),
description="Namespace which will appear in front of all topics (including /tf and /tf_static).",
),
DeclareLaunchArgument(
"device_namespace",
default_value="",
description="Sensor namespace that will appear after all topics and TF frames, used for distinguishing multiple cameras on the same robot.",
),
OpaqueFunction(function=launch_setup),
PushRosNamespace(LaunchConfiguration("robot_namespace")),
]
)
47 changes: 0 additions & 47 deletions healthcheck.cpp

This file was deleted.

Loading

0 comments on commit ad69c57

Please sign in to comment.