From 152fce79a3b4edc72c2b1216da82b610f659614e Mon Sep 17 00:00:00 2001 From: stelzo Date: Thu, 21 Mar 2024 11:45:34 +0100 Subject: [PATCH] ROS2 testing (#12) * add humble tests * simpler names * fix linking problem with r2r v0.7 * tidy and badges * cargo publish on release --- .github/workflows/crates.yml | 22 +++++++++ ...2r_galactic_20.04.yml => r2r_galactic.yml} | 2 +- .github/workflows/r2r_humble.yml | 17 +++++++ .github/workflows/r2r_iron.yml | 17 +++++++ ...st_noetic_20.04.yml => rosrust_noetic.yml} | 2 +- .github/workflows/{ubuntu.yml => tests.yml} | 2 +- Cargo.toml | 6 +-- README.md | 45 +++++++++++-------- tests/Dockerfile_r2r_galactic | 4 +- tests/Dockerfile_r2r_humble | 22 +++++++++ tests/Dockerfile_r2r_iron | 22 +++++++++ tests/r2r_msg_test.rs | 5 ++- tests/{r2r_20.04_test.bash => r2r_test.bash} | 8 ++-- 13 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 .github/workflows/crates.yml rename .github/workflows/{r2r_galactic_20.04.yml => r2r_galactic.yml} (93%) create mode 100644 .github/workflows/r2r_humble.yml create mode 100644 .github/workflows/r2r_iron.yml rename .github/workflows/{rosrust_noetic_20.04.yml => rosrust_noetic.yml} (99%) rename .github/workflows/{ubuntu.yml => tests.yml} (91%) create mode 100644 tests/Dockerfile_r2r_humble create mode 100644 tests/Dockerfile_r2r_iron rename tests/{r2r_20.04_test.bash => r2r_test.bash} (78%) diff --git a/.github/workflows/crates.yml b/.github/workflows/crates.yml new file mode 100644 index 0000000..0764c7b --- /dev/null +++ b/.github/workflows/crates.yml @@ -0,0 +1,22 @@ +on: + release: + types: [created] + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Publish to crates.io + uses: actions-rs/cargo@v1 + with: + command: publish + args: --token ${{ secrets.CRATES_IO_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/r2r_galactic_20.04.yml b/.github/workflows/r2r_galactic.yml similarity index 93% rename from .github/workflows/r2r_galactic_20.04.yml rename to .github/workflows/r2r_galactic.yml index 2b904a7..99180aa 100644 --- a/.github/workflows/r2r_galactic_20.04.yml +++ b/.github/workflows/r2r_galactic.yml @@ -1,4 +1,4 @@ -name: galactic_r2r_test +name: r2r_galactic on: push: diff --git a/.github/workflows/r2r_humble.yml b/.github/workflows/r2r_humble.yml new file mode 100644 index 0000000..2f8721d --- /dev/null +++ b/.github/workflows/r2r_humble.yml @@ -0,0 +1,17 @@ +name: r2r_humble + +on: + push: + pull_request: + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + tests_humble: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: docker build . --file ./tests/Dockerfile_r2r_humble --tag r2r_humble + - run: docker run r2r_humble cargo test --features r2r_msg diff --git a/.github/workflows/r2r_iron.yml b/.github/workflows/r2r_iron.yml new file mode 100644 index 0000000..a773884 --- /dev/null +++ b/.github/workflows/r2r_iron.yml @@ -0,0 +1,17 @@ +name: r2r_iron + +on: + push: + pull_request: + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + tests_humble: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: docker build . --file ./tests/Dockerfile_r2r_iron --tag r2r_iron + - run: docker run r2r_iron cargo test --features r2r_msg diff --git a/.github/workflows/rosrust_noetic_20.04.yml b/.github/workflows/rosrust_noetic.yml similarity index 99% rename from .github/workflows/rosrust_noetic_20.04.yml rename to .github/workflows/rosrust_noetic.yml index d8fce57..a5acf78 100644 --- a/.github/workflows/rosrust_noetic_20.04.yml +++ b/.github/workflows/rosrust_noetic.yml @@ -1,4 +1,4 @@ -name: Ubuntu 20.04 Noetic from rosrust +name: rosrust_noetic on: push: diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/tests.yml similarity index 91% rename from .github/workflows/ubuntu.yml rename to .github/workflows/tests.yml index 8295460..8066730 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,4 @@ -name: Pure latest Ubuntu without integrations +name: Tests on: push: diff --git a/Cargo.toml b/Cargo.toml index 044627c..a97e861 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "ros_pointcloud2" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["Christopher Sieh "] description = "Customizable conversions for working with sensor_msgs/PointCloud2." repository = "https://github.com/stelzo/ros_pointcloud2" license = "MIT" -keywords = ["ros", "rosrust", "pointcloud2", "pointcloud", "message",] +keywords = ["ros", "pointcloud2", "pointcloud", "message"] categories = ["science::robotics", "encoding", "data-structures", "api-bindings"] readme = "README.md" documentation = "https://docs.rs/ros_pointcloud2" @@ -19,7 +19,7 @@ num-traits = "0.2.15" fallible-iterator = "0.3.0" rosrust_msg = { version = "0.1", optional = true } rosrust = { version = "0.9.11", optional = true } -r2r = { version = "0.8.0", optional = true } +r2r = { version = "0.8.4", optional = true } [features] rosrust_msg = ["dep:rosrust_msg", "dep:rosrust"] diff --git a/README.md b/README.md index 8ef4357..aba9a92 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,21 @@ -# ROS PointCloud2 - -Customizable conversions to and from the `sensor_msgs/PointCloud2` ROS message. +

+

ROS PointCloud2

+

Customizable conversions to and from the PointCloud2 ROS message.

+

+

+

Providing a memory efficient way for message conversion while allowing user defined types without the cost of iterations. +Instead of converting the entire cloud into a `Vec`, you get an iterable type that converts each point from the message on the fly. -Instead of converting the entire cloud into a `Vec`, you get an `Iterator` that converts each point from the message on the fly. -An example for using this crate is [this filter node](https://github.com/stelzo/cloudfilter). It is also a good starting point for -implementing ROS1 nodes in Rust inside a catkin environment. - -To keep the crate a general purpose library for the problem and support ROS1 and ROS2, it uses its own type for the message. +To keep the crate a general purpose library for the problem and support ROS1 and ROS2, it uses its own type for the message `ros_types::PointCloud2Msg`. ```rust -use ros_pointcloud2::fallible_iterator::FallibleIterator; -use ros_pointcloud2::pcl_utils::PointXYZ; -use ros_pointcloud2::ros_types::PointCloud2Msg; -use ros_pointcloud2::ConvertXYZ; +use ros_pointcloud2::{ + fallible_iterator::FallibleIterator, + pcl_utils::PointXYZ, + ros_types::PointCloud2Msg, + ConvertXYZ, +}; // Your points (here using the predefined type PointXYZ). let cloud_points = vec![ @@ -29,9 +31,9 @@ let cloud_points = vec![ }, ]; -let cloud_copy = cloud_points.clone(); // Only for checking equality later. +let cloud_copy = cloud_points.clone(); // For checking equality later. -// Vector -> Convert -> Message +// Vector -> Converter -> Message let internal_msg: PointCloud2Msg = ConvertXYZ::try_from(cloud_points) .unwrap() .try_into() @@ -43,13 +45,14 @@ let internal_msg: PointCloud2Msg = ConvertXYZ::try_from(cloud_points) // Back to this crate's message type. // let internal_msg: PointCloud2Msg = msg.into(); -// Message -> Convert -> Vector +// Message -> Converter -> Vector let convert: ConvertXYZ = ConvertXYZ::try_from(internal_msg).unwrap(); let new_cloud_points = convert .map(|point: PointXYZ| { - // Insert your point business logic here or use other methods like .for_each(). - // I will just copy the points into a vector as an example. - // Also, since we are using a fallible iterator, we need to return a Result. + // Insert your point business logic here + // or use other methods like .for_each(). + + // We are using a fallible iterator so we need to return a Result. Ok(point) }) .collect::>() @@ -81,9 +84,13 @@ impl From for PointCloud2Msg { ## Integrations -There are currently 2 integrations for common ROS crates such as rosrust for ROS1 and R2R for ROS2 (Galactic). +There are currently 2 integrations for common ROS crates such as rosrust for ROS1 and R2R for ROS2. - [rosrust_msg](https://github.com/adnanademovic/rosrust) + - [![Tests](https://github.com/stelzo/ros_pointcloud2/actions/workflows/rosrust_noetic.yml/badge.svg)](https://github.com/stelzo/ros_pointcloud2/actions/workflows/rosrust_noetic.yml) - [r2r_msg](https://github.com/sequenceplanner/r2r) + - [![Tests](https://github.com/stelzo/ros_pointcloud2/actions/workflows/r2r_galactic.yml/badge.svg)](https://github.com/stelzo/ros_pointcloud2/actions/workflows/r2r_galactic.yml) + - [![Tests](https://github.com/stelzo/ros_pointcloud2/actions/workflows/r2r_humble.yml/badge.svg)](https://github.com/stelzo/ros_pointcloud2/actions/workflows/r2r_humble.yml) + - [![Tests](https://github.com/stelzo/ros_pointcloud2/actions/workflows/r2r_iron.yml/badge.svg)](https://github.com/stelzo/ros_pointcloud2/actions/workflows/r2r_iron.yml) You can use them by enabling the corresponding feature. Example: ```toml diff --git a/tests/Dockerfile_r2r_galactic b/tests/Dockerfile_r2r_galactic index db2cd5c..4060918 100644 --- a/tests/Dockerfile_r2r_galactic +++ b/tests/Dockerfile_r2r_galactic @@ -18,5 +18,5 @@ RUN curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | bash -s -- -y RUN echo 'source $HOME/.cargo/env' >> $HOME/.bashrc COPY . /r2r -RUN chmod +x /r2r/tests/r2r_20.04_test.bash -ENTRYPOINT [ "/r2r/tests/r2r_20.04_test.bash" ] +RUN chmod +x /r2r/tests/r2r_test.bash +ENTRYPOINT [ "/r2r/tests/r2r_test.bash" ] diff --git a/tests/Dockerfile_r2r_humble b/tests/Dockerfile_r2r_humble new file mode 100644 index 0000000..db92067 --- /dev/null +++ b/tests/Dockerfile_r2r_humble @@ -0,0 +1,22 @@ +# syntax=docker/dockerfile:1 +FROM ros:humble + +# Update default packages +RUN apt-get update + +# Get Ubuntu packages +RUN apt-get install -y \ + build-essential \ + curl \ + libclang-dev + +# Get ros test messages +RUN apt-get install -y ros-humble-test-msgs ros-humble-example-interfaces + +# Get Rust +RUN curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | bash -s -- -y +RUN echo 'source $HOME/.cargo/env' >> $HOME/.bashrc + +COPY . /r2r +RUN chmod +x /r2r/tests/r2r_test.bash +ENTRYPOINT [ "/r2r/tests/r2r_test.bash" ] diff --git a/tests/Dockerfile_r2r_iron b/tests/Dockerfile_r2r_iron new file mode 100644 index 0000000..a89d8c5 --- /dev/null +++ b/tests/Dockerfile_r2r_iron @@ -0,0 +1,22 @@ +# syntax=docker/dockerfile:1 +FROM ros:iron + +# Update default packages +RUN apt-get update + +# Get Ubuntu packages +RUN apt-get install -y \ + build-essential \ + curl \ + libclang-dev + +# Get ros test messages +RUN apt-get install -y ros-iron-test-msgs ros-iron-example-interfaces + +# Get Rust +RUN curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | bash -s -- -y +RUN echo 'source $HOME/.cargo/env' >> $HOME/.bashrc + +COPY . /r2r +RUN chmod +x /r2r/tests/r2r_test.bash +ENTRYPOINT [ "/r2r/tests/r2r_test.bash" ] diff --git a/tests/r2r_msg_test.rs b/tests/r2r_msg_test.rs index 373bfa9..fb430ed 100644 --- a/tests/r2r_msg_test.rs +++ b/tests/r2r_msg_test.rs @@ -5,6 +5,7 @@ fn convertxyz_r2r_msg() { use ros_pointcloud2::pcl_utils::PointXYZ; use ros_pointcloud2::ros_types::PointCloud2Msg; use ros_pointcloud2::ConvertXYZ; + use r2r::sensor_msgs::msg::PointCloud2; let cloud = vec![ PointXYZ { @@ -25,8 +26,8 @@ fn convertxyz_r2r_msg() { ]; let copy = cloud.clone(); let internal_cloud: PointCloud2Msg = ConvertXYZ::try_from(cloud).unwrap().try_into().unwrap(); - let rosrust_msg_cloud: r2r::sensor_msgs::msg::PointCloud2 = internal_cloud.into(); - let convert_back_internal: PointCloud2Msg = rosrust_msg_cloud.into(); + let r2r_msg_cloud: PointCloud2 = internal_cloud.into(); + let convert_back_internal: PointCloud2Msg = r2r_msg_cloud.into(); let to_convert: ConvertXYZ = ConvertXYZ::try_from(convert_back_internal).unwrap(); let back_to_type = to_convert.map(|point| Ok(point)).collect::>(); assert_eq!(copy, back_to_type.unwrap()); diff --git a/tests/r2r_20.04_test.bash b/tests/r2r_test.bash similarity index 78% rename from tests/r2r_20.04_test.bash rename to tests/r2r_test.bash index 6a3acd4..322fe92 100644 --- a/tests/r2r_20.04_test.bash +++ b/tests/r2r_test.bash @@ -5,15 +5,17 @@ # run rustup to test with latest rust version rustup update +if [ -e "/opt/ros/iron/setup.bash" ]; then + source "/opt/ros/iron/setup.bash" +fi + if [ -e "/opt/ros/humble/setup.bash" ]; then source "/opt/ros/humble/setup.bash" fi + if [ -e "/opt/ros/galactic/setup.bash" ]; then source "/opt/ros/galactic/setup.bash" fi -if [ -e "/opt/ros/foxy/setup.bash" ]; then - source "/opt/ros/foxy/setup.bash" -fi cd /r2r/ || exit