Skip to content

Patch and rebuild #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ad9667f
Wrap slice::from_raw_parts to be compatible with rcl (#419)
mxgrey Oct 3, 2024
06ee9bf
Add std::error::Error impls to Error enums of `parameter` module (#413)
alluring-mushroom Oct 9, 2024
dad5a51
Action message support (#417)
nwn Oct 26, 2024
f45a66f
Add a .repos file for jazzy (#425)
mxgrey Oct 30, 2024
b4e975c
Use latest stable Rust CI + Fix Test Errors (#420)
mxgrey Nov 15, 2024
066dd7c
Update vendored interface packages (#423)
nwn Nov 15, 2024
217f42c
Add rosout logging to rclrs (#422)
geoff-imdex Nov 24, 2024
885f415
Add Publisher::can_loan_msgs (#434)
mvukov Nov 25, 2024
a604ad7
Installs rust toolchain 1.75 in docker workflow. See #420. (#436)
agalbachicar Nov 26, 2024
3eba2b0
Update for clippy 1.83 (#441)
mxgrey Dec 2, 2024
506a60c
Fix GHA status labels (#438)
jballoffet Dec 2, 2024
6ac2ae1
Fix GHA set-output command warning (#439)
jballoffet Dec 2, 2024
f706824
chore: remove references to installing cargo-ament-build via cargo (#…
esteve Dec 4, 2024
7f53a4e
Fix buffer overflow for bounded sequence example (#444)
mxgrey Dec 9, 2024
31e4563
Minor fixes to pub sub tutorial (#437)
tulku Dec 9, 2024
8511a01
Add a step to Minimal CI for setting precise dependency versions
mxgrey Dec 19, 2024
c221925
Check what the working directory is
mxgrey Dec 19, 2024
cefdffb
Refine patching logic
mxgrey Dec 19, 2024
ef4de0f
Source ROS distro before running colcon build
mxgrey Dec 19, 2024
678f3a5
Check value of variable
mxgrey Dec 19, 2024
1dd2eb8
use .sh instead of .bash
mxgrey Dec 19, 2024
164cb78
Use cargo add instead of cargo update
mxgrey Dec 19, 2024
cbfdc82
Remove debug output
mxgrey Dec 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .github/workflows/rust-minimal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Rust Minimal

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Run the CI at 02:22 UTC every Tuesday
# We pick an arbitrary time outside of most of the world's work hours
# to minimize the likelihood of running alongside a heavy workload.
- cron: '22 2 * * 2'

env:
CARGO_TERM_COLOR: always

jobs:
build:
strategy:
matrix:
ros_distribution:
- humble
- iron
- rolling
include:
# Humble Hawksbill (May 2022 - May 2027)
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-humble-ros-base-latest
ros_distribution: humble
ros_version: 2
# Iron Irwini (May 2023 - November 2024)
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-iron-ros-base-latest
ros_distribution: iron
ros_version: 2
# Rolling Ridley (June 2020 - Present)
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-rolling-ros-base-latest
ros_distribution: rolling
ros_version: 2
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.ros_distribution == 'rolling' }}
container:
image: ${{ matrix.docker_image }}
steps:
- uses: actions/checkout@v4

- name: Search packages in this repository
id: list_packages
run: |
{
echo 'package_list<<EOF'
colcon list --names-only
echo EOF
} >> "$GITHUB_OUTPUT"

- name: Setup ROS environment
uses: ros-tooling/[email protected]
with:
required-ros-distributions: ${{ matrix.ros_distribution }}
use-ros2-testing: ${{ matrix.ros_distribution == 'rolling' }}

- name: Setup Rust
uses: dtolnay/[email protected]
with:
components: clippy, rustfmt

- name: Install colcon-cargo and colcon-ros-cargo
run: |
sudo pip3 install git+https://github.com/colcon/colcon-cargo.git
sudo pip3 install git+https://github.com/colcon/colcon-ros-cargo.git

- name: Check formatting of Rust packages
run: |
for path in $(colcon list | awk '$3 == "(ament_cargo)" { print $2 }'); do
cd $path
rustup toolchain install nightly
cargo +nightly fmt -- --check
cd -
done

- name: Build and test
id: build
continue-on-error: true
uses: ros-tooling/[email protected]
with:
package-name: ${{ steps.list_packages.outputs.package_list }}
target-ros2-distro: ${{ matrix.ros_distribution }}
vcs-repo-file-url: ros2_rust_${{ matrix.ros_distribution }}.repos

# We need specific versions of some dependencies to be compatible with v1.75
# of the compiler, but we can't specify those versions until after action-ros-ci
# has run and failed.
- name: Patch Dependencies and Rebuild
run: |
cd ${{ steps.build.outputs.ros-workspace-directory-name }}
cd $(colcon list | awk '$1 == "rclrs" { print $2 }')
cargo add home@=0.5.9
cd -
. /opt/ros/${{ matrix.ros_distribution }}/setup.sh
colcon build

- name: Run clippy on Rust packages
run: |
cd ${{ steps.build.outputs.ros-workspace-directory-name }}
. /opt/ros/${{ matrix.ros_distribution }}/setup.sh
for path in $(colcon list | awk '$3 == "(ament_cargo)" { print $2 }'); do
cd $path
echo "Running clippy in $path"
# Run clippy for all features except generate_docs (needed for docs.rs)
if [ "$(basename $path)" = "rclrs" ]; then
cargo clippy --no-deps --all-targets -F default,dyn_msg -- -D warnings
else
cargo clippy --no-deps --all-targets --all-features -- -D warnings
fi
cd -
done

- name: Run cargo test on Rust packages
run: |
cd ${{ steps.build.outputs.ros-workspace-directory-name }}
. install/setup.sh
for path in $(colcon list | awk '$3 == "(ament_cargo)" && $1 != "examples_rclrs_minimal_pub_sub" && $1 != "examples_rclrs_minimal_client_service" && $1 != "rust_pubsub" { print $2 }'); do
cd $path
echo "Running cargo test in $path"
# Run cargo test for all features except generate_docs (needed for docs.rs)
if [ "$(basename $path)" = "rclrs" ]; then
cargo test -F default,dyn_msg
elif [ "$(basename $path)" = "rosidl_runtime_rs" ]; then
cargo test -F default
else
cargo test --all-features
fi
cd -
done

- name: Rustdoc check
run: |
cd ${{ steps.build.outputs.ros-workspace-directory-name }}
. /opt/ros/${{ matrix.ros_distribution }}/setup.sh
for path in $(colcon list | awk '$3 == "(ament_cargo)" && $1 != "examples_rclrs_minimal_pub_sub" && $1 != "examples_rclrs_minimal_client_service" && $1 != "rust_pubsub" { print $2 }'); do
cd $path
echo "Running rustdoc check in $path"
cargo rustdoc -- -D warnings
cd -
done
23 changes: 13 additions & 10 deletions .github/workflows/rust.yml → .github/workflows/rust-stable.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
name: Rust
name: Rust Stable

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * *'
# Run the CI at 02:22 UTC every Tuesday
# We pick an arbitrary time outside of most of the world's work hours
# to minimize the likelihood of running alongside a heavy workload.
- cron: '22 2 * * 2'

env:
CARGO_TERM_COLOR: always
Expand Down Expand Up @@ -42,7 +45,11 @@ jobs:
- name: Search packages in this repository
id: list_packages
run: |
echo ::set-output name=package_list::$(colcon list --names-only)
{
echo 'package_list<<EOF'
colcon list --names-only
echo EOF
} >> "$GITHUB_OUTPUT"

- name: Setup ROS environment
uses: ros-tooling/[email protected]
Expand All @@ -51,7 +58,7 @@ jobs:
use-ros2-testing: ${{ matrix.ros_distribution == 'rolling' }}

- name: Setup Rust
uses: dtolnay/rust-toolchain@1.74.0
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt

Expand All @@ -69,10 +76,6 @@ jobs:
cd -
done

- name: Install cargo-ament-build
run: |
cargo install --debug cargo-ament-build

- name: Build and test
id: build
uses: ros-tooling/[email protected]
Expand All @@ -90,9 +93,9 @@ jobs:
echo "Running clippy in $path"
# Run clippy for all features except generate_docs (needed for docs.rs)
if [ "$(basename $path)" = "rclrs" ]; then
cargo clippy --all-targets -F default,dyn_msg -- -D warnings
cargo clippy --no-deps --all-targets -F default,dyn_msg -- -D warnings
else
cargo clippy --all-targets --all-features -- -D warnings
cargo clippy --no-deps --all-targets --all-features -- -D warnings
fi
cd -
done
Expand Down
5 changes: 2 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ RUN apt-get update && apt-get install -y \
python3-pip \
&& rm -rf /var/lib/apt/lists/*

# Install Rust and the cargo-ament-build plugin
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain 1.74.0 -y
# Install Rust
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain 1.75.0 -y
ENV PATH=/root/.cargo/bin:$PATH
RUN cargo install cargo-ament-build

RUN pip install --upgrade pytest

Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
ROS 2 for Rust
==============

| Target | Status |
|----------|--------|
| **Ubuntu 20.04** | [![Build Status](https://github.com/ros2-rust/ros2_rust/actions/workflows/rust.yml/badge.svg?branch=main)](https://github.com/ros2-rust/ros2_rust/actions/workflows/rust.yml?branch=main) |
[![Minimal Version Status](https://github.com/ros2-rust/ros2_rust/actions/workflows/rust-minimal.yml/badge.svg?branch=main)](https://github.com/ros2-rust/ros2_rust/actions/workflows/rust-minimal.yml)
[![Stable CI Status](https://github.com/ros2-rust/ros2_rust/actions/workflows/rust-stable.yml/badge.svg?branch=main)](https://github.com/ros2-rust/ros2_rust/actions/workflows/rust-stable.yml)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

Introduction
------------

This is a set of projects (the `rclrs` client library, code generator, examples and more) that
enables developers to write ROS 2 applications in Rust.

Installation
------------

Follow the [instructions in the documentation directory](docs/building.md).

Features and limitations
------------------------

Expand All @@ -37,7 +42,6 @@ Here are the steps for building the `ros2_rust` examples in a vanilla Ubuntu Foc
# Assuming you installed the minimal version of ROS 2, you need these additional packages:
sudo apt install -y git libclang-dev python3-pip python3-vcstool # libclang-dev is required by bindgen
# Install these plugins for cargo and colcon:
cargo install --debug cargo-ament-build # --debug is faster to install
pip install git+https://github.com/colcon/colcon-cargo.git
pip install git+https://github.com/colcon/colcon-ros-cargo.git

Expand Down
1 change: 0 additions & 1 deletion docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ The exact steps may differ between platforms, but as an example, here is how you
# Assuming you installed the minimal version of ROS 2, you need these additional packages:
sudo apt install -y git libclang-dev python3-pip python3-vcstool # libclang-dev is required by bindgen
# Install these plugins for cargo and colcon:
cargo install cargo-ament-build
pip install git+https://github.com/colcon/colcon-cargo.git
pip install git+https://github.com/colcon/colcon-ros-cargo.git
```
Expand Down
49 changes: 49 additions & 0 deletions docs/message-generation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# `ros2_rust` Message Generation

The `ros2_rust` project strives to maintain consistency with the upstream ROS 2 message generation
system. To this end, it provides two main packages: `rosidl_generator_rs` and `rosidl_runtime_rs`.
These packages provide the infrastructure required for defining and using ROS 2 messages, services,
and actions in Rust.

At a high level, the `rosidl_generator_rs` package handles generation of interface crates from the
`.msg`, `.srv`, and `.action` files defined by a user. The `rosidl_runtime_rs` package provides
common functionality shared across message packages, such as support types and traits. Each of these
packages is described in more detail below.

## `rosidl_generator_rs`

`rosidl_generator_rs` follows a very similar pattern to the other message generation packages for
ROS 2. To tie into this pipeline, it registers itself as a `"rosidl_generate_idl_interfaces"`
extension with `ament`. Doing so ensures that message packages calling `rosidl_generate_interfaces`
will invoke the Rust language generator in addition to any others. This is accomplished using the
various CMake scripts under the `cmake` directory. When this happens, the input interface files will
be converted into IDL files which, along with additional metadata, are fed into the `generate_rs`
function of `rosidl_generator_rs/__init__.py`.

From here, the IDL files are parsed into an internal representation using the upstream
[`rosidl_parser`](https://github.com/ros2/rosidl/tree/rolling/rosidl_parser) package. This abstract
representation is then used to instantiate the various template files under the `resource`
subdirectory, producing a full Rust crate for each package.

For each input message type, two `struct`s are generated:

- An ergonomic representation of the message, using more idiomatic `std` types like `Vec` and
`String` for sequence and string fields. These are placed directly in the `msg` submodule of the
crate.
- A FFI-suitable `struct` that is ABI-compatible with the layout expected by the RMW layer. While
less ergonomic, these avoid the conversion overhead when passed to RMW. These `struct`s are placed
under the `msg::rmw` submodule.

All the produced `struct`s implement the standard traits from `std` when possible, such as `Clone`,
`PartialEq`, and `Debug`. Additionally, when the generated crate's `serde` feature is enabled, these
structs implement the `Serialize` and `Deserialize` traits.

## `rosidl_runtime_rs`

`rosidl_runtime_rs` is a runtime support package, providing `Message`, `Service`, and `Action`
traits that are implemented by the corresponding structs generated by `rosidl_generator_rs`. These
allow for generic interaction with these various interface types, both in client libraries like
`rclrs` and in user code.

The package also provides a number of string and sequence types that are ABI-compatible with their
`rosidl_runtime_c` equivalents. This allows for more ergonomic use of the RMW-native message types.
7 changes: 3 additions & 4 deletions docs/writing_a_simple_publisher_and_subscriber.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ To construct a node, replace the code in your `main.rs` file with the following:
```rust
/// Creates a SimplePublisherNode, initializes a node and publisher, and provides
/// methods to publish a simple "Hello World" message on a loop in separate threads.

use rclrs::{create_node, Context, Node, Publisher, RclrsError, QOS_PROFILE_DEFAULT};
use std::{env, sync::Arc, thread, time::Duration};
use std_msgs::msg::String as StringMsg;
Expand All @@ -103,12 +102,12 @@ struct SimplePublisherNode {
publisher: Arc<Publisher<StringMsg>>,
}
impl SimplePublisherNode {
fn new(context: &context) -> result<self, RclrsError> {
fn new(context: &Context) -> Result<Self, RclrsError> {
let node = create_node(context, "simple_publisher").unwrap();
let publisher = node
.create_publisher("publish_hello", qos_profile_default)
.create_publisher("publish_hello", QOS_PROFILE_DEFAULT)
.unwrap();
ok(self { node, publisher })
Ok(Self { node, publisher })
}
fn publish_data(&self, increment: i32) -> Result<i32, RclrsError> {
let msg: StringMsg = StringMsg {
Expand Down
2 changes: 1 addition & 1 deletion examples/message_demo/src/message_demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn check_default_values() {
assert_eq!(msg.float_seq_unbounded, seq![6.0]);
assert_eq!(msg.string_member.to_string(), "Χαίρετε 你好");
assert_eq!(msg.wstring_member.to_string(), "αντίο σου 再见");
assert_eq!(msg.bounded_string_member.to_string(), "äöü");
assert_eq!(msg.bounded_string_member.to_string(), "aou");
assert_eq!(msg.bounded_wstring_member.to_string(), "äöü");
assert_eq!(
msg.string_array.clone().map(|s| s.to_string()),
Expand Down
2 changes: 1 addition & 1 deletion examples/rclrs_example_msgs/msg/VariousTypes.msg
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ float32[] float_seq_unbounded [6.0]
# String types
string string_member "Χαίρετε 你好"
wstring wstring_member "αντίο σου 再见"
string<=3 bounded_string_member "äöü"
string<=3 bounded_string_member "aou"
wstring<=3 bounded_wstring_member "äöü"

# Array/sequence of string type
Expand Down
7 changes: 6 additions & 1 deletion rclrs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = ["Esteve Fernandez <[email protected]>", "Nikolai Morin <nnmmgit@gmail
edition = "2021"
license = "Apache-2.0"
description = "A ROS 2 client library for developing robotics applications in Rust"
rust-version = "1.63"
rust-version = "1.75"

[lib]
path = "src/lib.rs"
Expand All @@ -29,6 +29,10 @@ libloading = { version = "0.8", optional = true }
# Needed for the Message trait, among others
rosidl_runtime_rs = "0.4"

# Needed for serliazation and deserialization of vendored messages
serde = { version = "1", optional = true, features = ["derive"] }
serde-big-array = { version = "0.5.1", optional = true }

[dev-dependencies]
# Needed for e.g. writing yaml files in tests
tempfile = "3.3.0"
Expand All @@ -46,6 +50,7 @@ cfg-if = "1.0.0"
[features]
default = []
dyn_msg = ["ament_rs", "libloading"]
serde = ["dep:serde", "dep:serde-big-array", "rosidl_runtime_rs/serde"]
# This feature is solely for the purpose of being able to generate documetation without a ROS installation
# The only intended usage of this feature is for docs.rs builders to work, and is not intended to be used by end users
generate_docs = ["rosidl_runtime_rs/generate_docs"]
Expand Down
1 change: 1 addition & 0 deletions rclrs/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fn main() {
}
};

println!("cargo:rustc-check-cfg=cfg(ros_distro, values(\"humble\", \"iron\", \"jazzy\", \"rolling\"))");
println!("cargo:rustc-cfg=ros_distro=\"{ros_distro}\"");

let mut builder = bindgen::Builder::default()
Expand Down
Loading
Loading