Skip to content
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
14f20b5
Remove lockfiles from being tracked
mxgrey Jul 18, 2025
8cc8959
Port draft action implementation from #410
mxgrey Jul 18, 2025
593a0ef
Rework readiness for waitables
mxgrey Jul 20, 2025
ac35d16
Reworking action server goal handle lifecycles
mxgrey Jul 26, 2025
a61b5f0
Fleshing out the state machines for action server goals -- cancelling…
mxgrey Jul 27, 2025
7340ec7
Finished action server goal state machine API -- need to finish actio…
mxgrey Jul 27, 2025
cedbb8f
Progress on action_server implementation
mxgrey Jul 28, 2025
03b44c9
Action server finished -- needs testing
mxgrey Jul 28, 2025
cd7fd50
Creating action server and action goal receiver -- needs testing
mxgrey Jul 28, 2025
01ab153
Introducing action clients into the wait set processing
mxgrey Jul 28, 2025
7d64c9c
Incorporate action clients into wait sets
mxgrey Jul 29, 2025
61dc709
Fleshing out implementation of action clients
mxgrey Jul 29, 2025
d767c71
Implementing goal status client
mxgrey Jul 30, 2025
50bb189
Implementing goal result client
mxgrey Jul 30, 2025
176b5f2
CancellationClient API in progress
mxgrey Jul 30, 2025
b115469
Finish action cancellation request API
mxgrey Jul 31, 2025
5225df8
Finish API for action clients -- needs testing
mxgrey Jul 31, 2025
a9bd493
Link against rcl_action
mxgrey Aug 5, 2025
d201992
Add initial tests and improve ergonomics
mxgrey Aug 10, 2025
7451d20
Add co-author credit
mxgrey Aug 10, 2025
8420bea
Merge remote-tracking branch 'origin/main' into async_actions
mxgrey Aug 11, 2025
bf861a6
Re-export traits from rosidl_runtime_rs
mxgrey Oct 9, 2025
3605b7a
Update with main
mxgrey Oct 9, 2025
4110a3c
Update bindings to include actions -- added script for automating the…
mxgrey Oct 10, 2025
eb58314
Apply cargo fmt
mxgrey Oct 10, 2025
4864c76
Update bindings for kilted
mxgrey Oct 10, 2025
0fef720
Update bindings for humble
mxgrey Oct 10, 2025
3e1d070
Update bindings for rolling
mxgrey Oct 10, 2025
2a6e50e
Fix use of serde
mxgrey Oct 10, 2025
2be387d
Use desktop image so it includes rcl_action which we need for action …
mxgrey Oct 10, 2025
cef318d
Fix serde
mxgrey Oct 10, 2025
d7b0734
Finish documentation for GoalClientStream
mxgrey Oct 10, 2025
6113ae1
Enable serde for goal status info
mxgrey Oct 10, 2025
ea27c3f
Fix action cancellation pipeline
mxgrey Oct 10, 2025
7c2975b
More trait re-exports
mxgrey Oct 11, 2025
1693a83
Merge remote-tracking branch 'origin/main' into async_actions
mxgrey Oct 13, 2025
7a6b153
Add tests for action cancellation
mxgrey Oct 13, 2025
9d3bdc5
Fix use of action client options
mxgrey Oct 13, 2025
0715c5f
Fix style
mxgrey Oct 13, 2025
9641731
Remove use of .clear_poison because it is not stable in 1.75
mxgrey Oct 17, 2025
801d95e
chore: revert bindings-related changes (#5)
esteve Oct 27, 2025
b4619e9
update rosidl_runtime_rs for action support (#6)
esteve Oct 27, 2025
8d278b8
revert bindings generation changes
esteve Oct 27, 2025
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
12 changes: 6 additions & 6 deletions .github/workflows/generate-bindings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,21 @@ jobs:
- kilted
- rolling
include:
# Note: We use desktop because the base image does not include rcl_action
# Humble Hawksbill (May 2022 - May 2027)
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-humble-ros-base-latest
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-humble-desktop-latest
ros_distribution: humble
ros_version: 2
# Jazzy Jalisco (May 2024 - May 2029)
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-jazzy-ros-base-latest
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-jazzy-desktop-latest
ros_distribution: jazzy
ros_version: 2
# Kilted Kaiju (May 2025 - Dec 2026)
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-kilted-ros-base-latest
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-kilted-desktop-latest
ros_distribution: kilted
ros_version: 2
# Rolling Ridley (June 2020 - Present)
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-rolling-ros-base-latest
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-rolling-desktop-latest
ros_distribution: rolling
ros_version: 2
runs-on: ubuntu-latest
Expand Down Expand Up @@ -80,8 +81,7 @@ jobs:
- name: Generate bindings
run: |
. /opt/ros/${{ matrix.ros_distribution }}/setup.sh
cd rclrs/src
../generate_bindings.py rcl_wrapper.h ${{ matrix.ros_distribution }} .
cargo run --bin rclrs_generate_bindings

- name: Submit PR
run: |
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[workspace]
members = [
"rclrs",
"generate_bindings",
]
resolver = "2"
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,8 @@ ros2 launch examples_rclrs_minimal_pub_sub minimal_pub_sub.launch.xml
Further documentation articles:
- [Tutorial on writing your first node with `rclrs`](docs/writing-your-first-rclrs-node.md)
- [Contributor's guide](docs/CONTRIBUTING.md)

> [!TIP]
> For maintainers: To (re-)generate bindings for a certain ROS distro, source that distro
> and then run `cargo run --bin rclrs_generate_bindings` from this root directory of the repo.
> Remember to commit the new or changed binding file.
20 changes: 20 additions & 0 deletions generate_bindings/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "rclrs_generate_bindings"
version = "0.5.1"
# This project is not military-sponsored, Jacob's employment contract just requires him to use this email address
authors = ["Esteve Fernandez <[email protected]>", "Nikolai Morin <[email protected]>", "Jacob Hassold <[email protected]>"]
edition = "2021"
license = "Apache-2.0"
description = "A ROS 2 client library for developing robotics applications in Rust"
rust-version = "1.75"

[[bin]]
name = "rclrs_generate_bindings"
path = "src/main.rs"

[dependencies]
# Needed to generate the bindings
bindgen = "0.70"

# Needed to ensure the generator is being called from the correct workspace directory
cargo-manifest = "0.17"
102 changes: 102 additions & 0 deletions generate_bindings/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use cargo_manifest::Manifest;
use std::{fs::read_dir, path::Path};

const AMENT_PREFIX_PATH: &str = "AMENT_PREFIX_PATH";
const ROS_DISTRO: &str = "ROS_DISTRO";
const BINDGEN_WRAPPER: &str = "rclrs/src/rcl_wrapper.h";

fn get_env_var_or_abort(env_var: &'static str) -> String {
if let Ok(value) = std::env::var(env_var) {
value
} else {
panic!(
"{} environment variable not set - please source ROS 2 installation first.",
env_var
);
}
}

fn main() {
let ros_distro = get_env_var_or_abort(ROS_DISTRO);
let ament_prefix_paths = get_env_var_or_abort(AMENT_PREFIX_PATH);

let Ok(workspace) = Manifest::from_path("Cargo.toml")
.map_err(|_| ())
.and_then(|manifest| manifest.workspace.ok_or(()))
else {
panic!(
" > ERROR: Run the generate_bindings script from the root Cargo workspace of ros2_rust"
);
};

let has_rclrs = workspace
.members
.iter()
.find(|member| *member == "rclrs")
.is_some();
if !has_rclrs {
panic!(
" > ERROR: Run the generate_bindings script from the root Cargo workspace of ros2_rust. \
Could not find rclrs in this workspace. Members include {:?}",
workspace.members,
);
}

let mut builder = bindgen::Builder::default()
.header(BINDGEN_WRAPPER)
.derive_copy(false)
.allowlist_type("rcl_.*")
.allowlist_type("rmw_.*")
.allowlist_type("rcutils_.*")
.allowlist_type("rosidl_.*")
.allowlist_function("rcl_.*")
.allowlist_function("rmw_.*")
.allowlist_function("rcutils_.*")
.allowlist_function("rosidl_.*")
.allowlist_var("rcl_.*")
.allowlist_var("rmw_.*")
.allowlist_var("rcutils_.*")
.allowlist_var("rosidl_.*")
.layout_tests(false)
.default_enum_style(bindgen::EnumVariation::Rust {
non_exhaustive: false,
});

for ament_prefix_path in ament_prefix_paths.split(':').map(Path::new) {
// Locate the ament index
let ament_index = ament_prefix_path.join("share/ament_index/resource_index/packages");
if !ament_index.is_dir() {
continue;
}

// Old-style include directory
let include_dir = ament_prefix_path.join("include");

// Including the old-style packages
builder = builder.clang_arg(format!("-isystem{}", include_dir.display()));

// Search for and include new-style-converted package paths
for dir_entry in read_dir(&ament_index).unwrap().filter_map(|p| p.ok()) {
let package = dir_entry.file_name();
let package_include_dir = include_dir.join(&package);

if package_include_dir.is_dir() {
let new_style_include_dir = package_include_dir.join(&package);

// CycloneDDS is a special case - it needs to be included as if it were a new-style path, but
// doesn't actually have a secondary folder within it called "CycloneDDS"
// TODO(jhdcs): if this changes in future, remove this check
if package == "CycloneDDS" || new_style_include_dir.is_dir() {
builder =
builder.clang_arg(format!("-isystem{}", package_include_dir.display()));
}
}
}
}

let bindings = builder.generate().expect("Unable to generate bindings");
let bindings_path = format!("rclrs/src/rcl_bindings_generated_{ros_distro}.rs");
bindings
.write_to_file(bindings_path)
.expect("Failed to generate bindings");
}
18 changes: 18 additions & 0 deletions rclrs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ path = "src/lib.rs"
# Needed for dynamically finding type support libraries
ament_rs = { version = "0.2", optional = true }

# Needed to create the GoalClientStream
async-stream = "*"

# Needed for uploading documentation to docs.rs
cfg-if = "1.0.0"

# Needed for clients
futures = "0.3"

# Needed for racing futures
futures-lite = { version = "2.6", features = ["std", "race"] }

# Needed for the runtime-agnostic timeout feature
async-std = "1.13"

Expand All @@ -36,6 +42,18 @@ rosidl_runtime_rs = "0.4"
serde = { version = "1", optional = true, features = ["derive"] }
serde-big-array = { version = "0.5.1", optional = true }

# Needed to watch for the cancel signal for actions. Note that this only brings
# in the sync module of tokio, which is a fairly light weight dependency. The
# channels in this module work with any async runtime, so this does not lock us
# into the tokio runtime.
tokio = { version = "1", features = ["sync"] }

# Needed to combine concurrent streams for easier ergonomics in action clients
tokio-stream = "0.1"

# Needed by action clients to generate UUID values for their goals
uuid = { version = "1", features = ["v4"] }

[dev-dependencies]
# Needed for e.g. writing yaml files in tests
tempfile = "3.3.0"
Expand Down
1 change: 1 addition & 0 deletions rclrs/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ fn main() {
}

println!("cargo:rustc-link-lib=dylib=rcl");
println!("cargo:rustc-link-lib=dylib=rcl_action");
println!("cargo:rustc-link-lib=dylib=rcl_yaml_param_parser");
println!("cargo:rustc-link-lib=dylib=rcutils");
println!("cargo:rustc-link-lib=dylib=rmw");
Expand Down
61 changes: 0 additions & 61 deletions rclrs/generate_bindings.py

This file was deleted.

Loading