Skip to content

Commit

Permalink
Support ROS2 Jazzy (#334)
Browse files Browse the repository at this point in the history
* Use cuda::std::complex instead of thrust::complex
thrust types do not have a consistent ABI between TUs compiled with and without nvcc

* Support ROS2 jazzy

* Use std::complex in host code & cuda::std::complex in device code

* Remove debugging leftover

* Support ROS2 Jazzy standalone on Windows

* Update docs
  • Loading branch information
msz-rai authored Sep 27, 2024
1 parent c7ea149 commit 51e09e8
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 88 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ if (RGL_BUILD_PCL_EXTENSION)
endif()

if (RGL_BUILD_ROS2_EXTENSION)
if (WIN32) # Workaround for compilation on Windows. fastcdr must be found from the top-level of cmake.
find_package(fastcdr REQUIRED)
endif()
add_subdirectory(extensions/ros2)
endif()

Expand Down
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ And more:

## Runtime requirements

|Hardware|Requirement|
|:--|:--|
|GPU|CUDA-enabled|
| Hardware | Requirement |
|:---------|:-------------|
| GPU | CUDA-enabled |

|Software|Requirement|
|:--|:--|
|Nvidia Driver (Linux)|>=515.43.04|
|Nvidia Driver (Windows)|>=472.50|
| Software | Requirement |
|:--------------|:-------------------------------------------------------------------------------------------------|
| Nvidia Driver | - Ubuntu 22.04 `>=515.43.04` <br/> - Ubuntu 24.04 `>=555.42.02` <br/> - Windows 10/11 `>=472.50` |

## Usage

Expand All @@ -62,8 +61,8 @@ An introduction to the RGL API along with an example can be found [here](docs/Us

`RobotecGPULidar` library can be built with extensions enhancing RGL with additional functions:
- `PCL` - adds nodes and functions for point cloud processing that uses [Point Cloud Library](https://pointclouds.org/). See [documentation](docs/PclExtension.md).
- `ROS2` - adds a node to publish point cloud messages to [ROS2](https://www.ros.org/). Check [ROS2 extension doc](docs/Ros2Extension.md) for more information, build instructions, and usage.
- `UDP` - adds a node to publish raw lidar packets, as emitted by physical lidar. Only available in the closed-source version.
- `ROS2` - adds a nodes for point cloud publishing to [ROS2](https://www.ros.org/). See [documentation](docs/Ros2Extension.md).
- `UDP` - adds a nodes for raw lidar packets publishing, as emitted by physical lidar. Only available in the closed-source version.

## Building in Docker (Linux)

Expand Down Expand Up @@ -94,9 +93,11 @@ docker build \
--output=build .
```

## Building on Ubuntu 22
## Building on Ubuntu 22/24

1. Install [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) **11.7+**.
1. Install [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads)
- Ubuntu 22.04: **11.7+**
- Ubuntu 24.04: **12.6+**
2. Download [NVidia OptiX](https://developer.nvidia.com/designworks/optix/downloads/legacy) **7.2**.
1. You may be asked to create a Nvidia account to download
3. Export environment variable:
Expand Down
72 changes: 37 additions & 35 deletions docs/Ros2Extension.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# RGL ROS2 extension

The extension introduces the node to publish [PointCloud2](https://docs.ros2.org/foxy/api/sensor_msgs/msg/PointCloud2.html) messages to ROS2. RGL creates a ROS2 node named `RobotecGPULidar` and registers publishers based on constructed RGL nodes.
The extension introduces nodes to publish [PointCloud2](https://docs.ros2.org/foxy/api/sensor_msgs/msg/PointCloud2.html) messages to ROS2. RGL creates a ROS2 node named `RobotecGPULidar` and registers publishers based on constructed RGL nodes.

Supported ROS2 distributions:
- Humble
- Jazzy

Supported DDS implementations for ROS2 standalone build:
- Eclipse Cyclone DDS
Expand All @@ -14,24 +15,29 @@ Supported DDS implementations for ROS2 standalone build:
RGL ROS2 extension can be built in two flavors:

- **standalone** - ROS2 installation is not required on the target machine. RGL build will include all required ROS2 dependencies.
- **overlay** - Assumes the existence of supported ROS2 installation on the target machine. RGL will try to use the existing installation of ROS2 dependencies.
- **overlay** - Assumes the existence of supported ROS2 installation on the target machine. RGL will use ROS2 libraries already installed on the system.

Before building RGL PCL extension, it is necessary to get the required dependencies.
Before building RGL ROS2 extension, it is necessary to get the required dependencies.
For some, the process has been automated - run `setup.py --install-ros2-deps` to get them.

### Ubuntu 22
### Ubuntu 22/24

#### Prerequisites

- Requirements listed in the main [README](../README.md) (section `Building on Ubuntu`).
- ROS2 installed on the system and sourced.
- Requirements listed in the main [README](../README.md#building-on-ubuntu-2224).
- ROS2 installed on the system and sourced:
- ROS2 Humble for Ubuntu 22
- ROS2 Jazzy for Ubuntu 24
- Radar messages installed:
```bash
apt install -y ros-${ROS_DISTRO}-radar-msgs
```
- For standalone build:
- ROS2 `cyclonedds` and `fastrtps` packages.
- `patchelf` tool.
```bash
apt install -y ros-${ROS_DISTRO}-cyclonedds ros-${ROS_DISTRO}-rmw-cyclonedds-cpp
apt install -y ros-${ROS_DISTRO}-fastrtps ros-${ROS_DISTRO}-rmw-fastrtps-cpp
apt install -y ros-${ROS_DISTRO}-radar-msgs
apt install patchelf
```

Expand All @@ -40,45 +46,38 @@ For some, the process has been automated - run `setup.py --install-ros2-deps` to

#### Steps for standalone
1. Use script `setup.py` with option `--with-ros2-standalone`
- You can specify run-time search path(s) of RGL dependencies by adding the option `--lib-rpath <paths>`. This can be useful if you want RGL to search for ROS2 libraries in a different directory than RGL, e.g., if you work with a library providing its own ROS2 libraries, such as [ROS2ForUnity](https://github.com/RobotecAI/ros2-for-unity).
2. Copy all ROS2 libraries from `<build-dir>/ros2_standalone/` to `libRobotecGPULidar.so` location (or location defined with `--lib-rpath`).
- You can specify run-time search path(s) of RGL dependencies by adding the option `--lib-rpath <paths>`. This can be useful if you want RGL to search for ROS2 libraries in a different directory than RGL, e.g., if you work with a library that also provides its ROS2 libraries, such as [ROS2ForUnity](https://github.com/RobotecAI/ros2-for-unity).
2. Copy all ROS2 libraries from `<build-dir>/lib/ros2_standalone/` to `libRobotecGPULidar.so` location (or location defined with `--lib-rpath`).

#### Tips for integrating RGL with [AWSIM](https://github.com/tier4/AWSIM/tree/main)

AWSIM project includes two ROS-based plugins: [ROS2ForUnity](https://github.com/RobotecAI/ros2-for-unity) and [RGLUnityPlugin](https://github.com/tier4/AWSIM/tree/main/Assets/RGLUnityPlugin). Since AWSIM is configured to run in a standalone mode (where ROS does not need to be installed on the host machine), all necessary ROS libraries are included within the project.
Ros2ForUnity and RGLUnityPlugin share a common set of ROS libraries (e.g., `librcl.so`).
To avoid duplication - since Unity does not support having multiple instances of the same libraries - one of the solutions is to store all ROS libraries in a single plugin.
In this case, the ROS libraries are stored in the ROS2ForUnity plugin, and RGL is configured with a runtime search path to access them.

#### Tips for integrating RGL + ROS2 standalone with Unity and [ROS2ForUnity](https://github.com/RobotecAI/ros2-for-unity) plugin.
1. Build RGL with the command:
```bash
./setup.py --with-ros2-standalone --lib-rpath \$ORIGIN/../../../../Ros2ForUnity/Plugins/Linux/x86_64/
```
*$ORIGIN represents the directory in which an object (library) originated. It is resolved at run-time.*\
*Your rpath may differ. It depends on your relative location between RGLUnityPlugin and Ros2ForUnity.*
2. Copy library `<build-dir>/libRobotecGPULidar.so` to the appropriate directory in your RGLUnityPlugin.
3. Copy all ROS2 libraries from `<build-dir>/ros2_standalone/` to `Ros2ForUnity\Plugins\Linux\x86_64` directory. Skip for duplicates.

RGL's ROS2 standalone build is dependent on ROS2ForUnity's ROS2 standalone build. RobotecGPULidar library will find ROS2 because we have set the appropriate rpath for the ROS2 libraries in ROS2ForUnity.
2. Copy library `<build-dir>/lib/libRobotecGPULidar.so` to the appropriate directory in your RGLUnityPlugin.
3. Copy all ROS2 libraries from `<build-dir>/lib/ros2_standalone/` to `Ros2ForUnity\Plugins\Linux\x86_64` directory. **Skip for duplicates**.

### Windows

#### Prerequisites

- Requirements listed in the main [README](../README.md) (section `Building on Windows`).
- ROS2 installed on the system and sourced.
- Fixed ROS2 logging macros in rclcpp package to make it compile with C++20. More about this bug: [github PR](https://github.com/ros2/rclcpp/pull/2063).
- Requirements listed in the main [README](../README.md#building-on-windows).
- ROS2 installed on the system and sourced. We recommend installation from a pre-built binary package:
- [ROS2 Humble](https://docs.ros.org/en/humble/Installation/Windows-Install-Binary.html)
- [ROS2 Jazzy](https://docs.ros.org/en/jazzy/Installation/Windows-Install-Binary.html)
- [ROS2 Humble only] Fixed ROS2 logging macros in rclcpp package to make it compile with C++20. More about this bug: [github PR](https://github.com/ros2/rclcpp/pull/2063).
- Use `fix_ros2_humble.py` script to apply those changes:
```bash
python ros2_standalone\fix_ros2_humble.py <your-path-to-ros2>
```
- For standalone build:
- If you have installed ROS2 from pre-built binaries, there is `rmw_cyclonedds_cpp` package missing. You need to build this one from the source:
1. Make sure you have installed [ROS2 prerequisites](https://docs.ros.org/en/humble/Installation/Alternatives/Windows-Development-Setup.html#installing-prerequisites).
2. A good practice is to disable Windows path limits, [see](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry).
3. Run `x64 Native Tools Command Prompt for VS 2019`, setup development folder (e.g., `C:\rosrmw`), clone ROS2 repos, and build:
```bash
md \rosrmw\src
cd \rosrmw
vcs import --input https://raw.githubusercontent.com/ros2/ros2/humble/ros2.repos src
colcon build --merge-install --packages-up-to rmw_cyclonedds_cpp
```
4. Before building RGL, source `rosrmw` workspace: `call C:\rosrmw\install\setup.bat`.


#### Steps for overlay
1. Run `x64 Native Tools Command Prompt for VS 2019` and navigate to RGL repository.
Expand All @@ -87,14 +86,17 @@ RGL's ROS2 standalone build is dependent on ROS2ForUnity's ROS2 standalone build
#### Steps for standalone
1. Run `x64 Native Tools Command Prompt for VS 2019` and navigate to RGL repository.
2. Run `python setup.py --with-ros2-standalone` command to build RGL with ROS2 extension and install ROS2 libraries.
3. Copy all ROS2 libraries from `<build-dir>/ros2_standalone/` into `RobotecGPULidar.dll` location, or extend environment variable `Path` appropriately.
3. Copy all ROS2 libraries from `<build-dir>/lib/ros2_standalone/` into `RobotecGPULidar.dll` location, or extend environment variable `Path` appropriately.

#### Tips for integrating RGL with [AWSIM](https://github.com/tier4/AWSIM/tree/main)

See description from [Ubuntu section](#tips-for-integrating-rgl-with-awsim) for more details.

#### Tips for integrating RGL + ROS2 standalone with Unity and [ROS2ForUnity](https://github.com/RobotecAI/ros2-for-unity) plugin.
1. Build RGL with ROS2 standalone as described above.
2. Copy `<build-dir>/RobotecGPULidar.dll` and all depend libraries located in `<build-dir>` to the appropriate directory in your RGLUnityPlugin.
3. Copy all ROS2 libraries from `<build-dir>/ros2_standalone/` to `Ros2ForUnity\Plugins\Windows\x86_64` directory. Skip for duplicates.
2. Copy `<build-dir>/RobotecGPULidar.dll` and all dependent libraries located in `<build-dir>` to the appropriate directory in your RGLUnityPlugin.
3. Copy all ROS2 libraries from `<build-dir>/lib/ros2_standalone/` to `Ros2ForUnity\Plugins\Windows\x86_64` directory. Skip for duplicates.

RGL's ROS2 standalone build is dependent on ROS2ForUnity's ROS2 standalone build. RobotecGPULidar library will find ROS2 because ROS2ForUnity sets the environment variable `Path` for the ROS2 libraries.
*Note:* On Windows there is no `-rpath` linker flag to modify an executable’s search path. Instead, the `Path` environment variable can be set. ROS2ForUnity handles this automatically before the simulation starts.

## Usage

Expand Down
7 changes: 5 additions & 2 deletions extensions/ros2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

if (NOT $ENV{ROS_DISTRO} STREQUAL "humble")
message(FATAL_ERROR "ROS $ENV{ROS_DISTRO} not supported. Only humble is available.")
set(SUPPORTED_ROS_DISTROS humble jazzy)

list(FIND SUPPORTED_ROS_DISTROS $ENV{ROS_DISTRO} ROS_DISTRO_INDEX)
if (ROS_DISTRO_INDEX EQUAL -1)
message(FATAL_ERROR "ROS $ENV{ROS_DISTRO} not supported. Choose one of: '${SUPPORTED_ROS_DISTROS}'.")
endif()

find_package(rclcpp REQUIRED)
Expand Down
3 changes: 1 addition & 2 deletions extensions/ros2/install_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


class Config:
SUPPORTED_ROS_DISTROS = ["humble"]
SUPPORTED_ROS_DISTROS = ["humble", "jazzy"]

# Paths relative to project root
RADAR_MSGS_DIR = os.path.join("external", "radar_msgs")
Expand Down Expand Up @@ -39,7 +39,6 @@ def install_ros2_deps(cfg):
run_subprocess_command("sudo apt-get install -y python3-colcon-common-extensions")
# Clone radar msgs
if not os.path.isdir(cfg.RADAR_MSGS_DIR):
run_subprocess_command("ls")
run_subprocess_command(
f"git clone --single-branch --depth 1 https://github.com/ros-perception/radar_msgs.git {cfg.RADAR_MSGS_DIR}")
run_subprocess_command(f"cd {cfg.RADAR_MSGS_DIR} && git checkout {cfg.RADAR_MSGS_COMMIT} && cd ..")
Expand Down
36 changes: 30 additions & 6 deletions ros2_standalone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ set(REQ_THIRD_PARTY_STANDALONE_LIBS "")
set(REQ_STANDALONE_DLLS "")

set(INSTALL_DESTINATION_DIR "lib/ros2_standalone")
set(ROS_DISTRO "$ENV{ROS_DISTRO}")

# Extend REQ_THIRD_PARTY_STANDALONE_LIBS with _library_name third party dependencies
macro(get_standalone_third_party_dependencies _library_name)
Expand Down Expand Up @@ -104,6 +105,12 @@ macro(get_standalone_dependencies _library_name)
endif()
endif()

# Get rosidl_dynamic_typesupport_fastrtps
if("${_library_name}" STREQUAL "rosidl_dynamic_typesupport_fastrtps")
fetch_target_lib(rosidl_dynamic_typesupport_fastrtps::rosidl_dynamic_typesupport_fastrtps)
list(APPEND REQ_STANDALONE_LIBS ${rosidl_dynamic_typesupport_fastrtps_rosidl_dynamic_typesupport_fastrtps_LIB_PATH})
endif()

# If library is msgs, fetch all targets to get libraries for dynamic type support
# Those libraries are not listed in <XX>_LIBRARIES (which stands for libraries to link against to use <XX>)
if(${_library_name} MATCHES ".*\_msgs$")
Expand All @@ -116,12 +123,20 @@ macro(get_standalone_dependencies _library_name)
endif()

# Get spdlog and dependency
if(UNIX AND "${_library_name}" STREQUAL "spdlog")
if("${_library_name}" STREQUAL "spdlog")
include(${${_library_name}_CONFIG})
fetch_target_lib(spdlog::spdlog)
list(APPEND REQ_STANDALONE_LIBS ${spdlog_spdlog_LIB_PATH})
fetch_target_lib(fmt::fmt)
list(APPEND REQ_STANDALONE_LIBS ${fmt_fmt_LIB_PATH})
if(UNIX)
fetch_target_lib(fmt::fmt)
list(APPEND REQ_STANDALONE_LIBS ${fmt_fmt_LIB_PATH})
endif()
endif()

# Get yaml
if(WIN32 AND "${_library_name}" STREQUAL "yaml")
fetch_target_lib(yaml)
list(APPEND REQ_STANDALONE_LIBS ${yaml_LIB_PATH})
endif()

# We skip python libs
Expand Down Expand Up @@ -223,14 +238,23 @@ set(ros2_standalone_libs
rosidl_typesupport_cpp
rosidl_typesupport_introspection_c
rosidl_typesupport_introspection_cpp
spdlog
tracetools
yaml
tinyxml2
)

if(UNIX)
list(APPEND ros2_standalone_libs iceoryx_binding_c iceoryx_posh iceoryx_hoofs)
list(APPEND ros2_standalone_libs spdlog iceoryx_binding_c iceoryx_posh iceoryx_hoofs)
endif()

if(ROS_DISTRO STREQUAL "humble")
list(APPEND ros2_standalone_libs yaml)
endif()

if(ROS_DISTRO STREQUAL "jazzy")
list(APPEND ros2_standalone_libs rcl_logging_spdlog rcl_interfaces rosidl_dynamic_typesupport_fastrtps)
if(WIN32)
list(APPEND ros2_standalone_libs yaml spdlog)
endif()
endif()

foreach(ros2_standalone_lib ${ros2_standalone_libs})
Expand Down
Loading

0 comments on commit 51e09e8

Please sign in to comment.