Skip to content

Commit

Permalink
Merge branch 'main' into dynamic_messages_3
Browse files Browse the repository at this point in the history
  • Loading branch information
esteve authored Jan 9, 2024
2 parents 50d42c5 + 812b91a commit 13723d2
Show file tree
Hide file tree
Showing 67 changed files with 3,294 additions and 350 deletions.
43 changes: 27 additions & 16 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * *'

env:
CARGO_TERM_COLOR: always
Expand All @@ -14,45 +16,42 @@ jobs:
strategy:
matrix:
ros_distribution:
- foxy
- galactic
- humble
- iron
- rolling
include:
# Foxy Fitzroy (June 2020 - May 2023)
- docker_image: rostooling/setup-ros-docker:ubuntu-focal-ros-foxy-ros-base-latest
ros_distribution: foxy
ros_version: 2
# Galactic Geochelone (May 2021 - November 2022)
- docker_image: rostooling/setup-ros-docker:ubuntu-focal-ros-galactic-ros-base-latest
ros_distribution: galactic
ros_version: 2
# 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@v2
- uses: actions/checkout@v4

- name: Search packages in this repository
id: list_packages
run: |
echo ::set-output name=package_list::$(colcon list --names-only)
- name: Setup ROS environment
uses: ros-tooling/setup-ros@v0.3
uses: ros-tooling/setup-ros@v0.7
with:
required-ros-distributions: ${{ matrix.ros_distribution }}
use-ros2-testing: ${{ matrix.ros_distribution == 'rolling' }}

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

Expand All @@ -75,7 +74,7 @@ jobs:
- name: Build and test
id: build
uses: ros-tooling/action-ros-ci@v0.2
uses: ros-tooling/action-ros-ci@v0.3
with:
package-name: ${{ steps.list_packages.outputs.package_list }}
target-ros2-distro: ${{ matrix.ros_distribution }}
Expand All @@ -88,7 +87,12 @@ jobs:
for path in $(colcon list | awk '$3 == "(ament_cargo)" { print $2 }'); do
cd $path
echo "Running clippy in $path"
cargo clippy --all-targets --all-features -- -D warnings
# 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
else
cargo clippy --all-targets --all-features -- -D warnings
fi
cd -
done
Expand All @@ -99,7 +103,14 @@ jobs:
for path in $(colcon list | awk '$3 == "(ament_cargo)" && $1 != "examples_rclrs_minimal_pub_sub" && $1 != "examples_rclrs_minimal_client_service" { print $2 }'); do
cd $path
echo "Running cargo test in $path"
cargo test --all-features
# 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
Expand Down
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM ros:foxy as base
ARG ROS_DISTRO=humble
FROM ros:$ROS_DISTRO as base
ARG DEBIAN_FRONTEND=noninteractive

# Install dependencies
Expand All @@ -11,7 +12,7 @@ RUN apt-get update && apt-get install -y \
&& 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.63.0 -y
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain 1.74.0 -y
ENV PATH=/root/.cargo/bin:$PATH
RUN cargo install cargo-ament-build

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Here are the steps for building the `ros2_rust` examples in a vanilla Ubuntu Foc
<!--- These steps should be kept in sync with docs/Building.md --->
```shell
# Install Rust, e.g. as described in https://rustup.rs/
# Install ROS 2 as described in https://docs.ros.org/en/foxy/Installation.html
# Install ROS 2 as described in https://docs.ros.org/en/humble/Installation.html
# 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:
Expand All @@ -43,8 +43,8 @@ pip install git+https://github.com/colcon/colcon-ros-cargo.git

mkdir -p workspace/src && cd workspace
git clone https://github.com/ros2-rust/ros2_rust.git src/ros2_rust
vcs import src < src/ros2_rust/ros2_rust_foxy.repos
. /opt/ros/foxy/setup.sh
vcs import src < src/ros2_rust/ros2_rust_humble.repos
. /opt/ros/humble/setup.sh
colcon build
```

Expand Down
17 changes: 9 additions & 8 deletions docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This is a more detailed guide on how to build ROS 2 packages written in Rust that expands on the minimal steps in the README.

In this guide, the Foxy distribution of ROS 2 is used, but newer distributions can be used by simply replacing 'foxy' with the distribution name everywhere.
In this guide, the Humble distribution of ROS 2 is used, but newer distributions can be used by simply replacing 'humble' with the distribution name everywhere.


## Choosing a workspace directory and cloning `ros2_rust`
Expand All @@ -24,7 +24,7 @@ git clone https://github.com/ros2-rust/ros2_rust.git src/ros2_rust

## Environment setup

Building `rclrs` requires a standard [ROS 2 installation](https://docs.ros.org/en/foxy/Installation.html), and a few extensions.
Building `rclrs` requires a standard [ROS 2 installation](https://docs.ros.org/en/humble/Installation.html), and a few extensions.
These extensions are: `colcon-cargo`, `colcon-ros-cargo`, `cargo-ament-build`. The first two are `colcon` plugins, and the third is a `cargo` plugin.

The `libclang` library is also required for automatically generating FFI bindings with `bindgen`. See the [`bindgen` docs](https://rust-lang.github.io/rust-bindgen/requirements.html) on how to install it. As a side note, on Ubuntu the `clang` package is not required, only the `libclang-dev` package.
Expand All @@ -41,7 +41,7 @@ The exact steps may differ between platforms, but as an example, here is how you
<!--- These steps should be kept in sync with README.md --->
```shell
# Install Rust, e.g. as described in https://rustup.rs/
# Install ROS 2 as described in https://docs.ros.org/en/foxy/Installation.html
# Install ROS 2 as described in https://docs.ros.org/en/humble/Installation.html
# 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:
Expand All @@ -56,7 +56,8 @@ Build the Docker image with

```shell
# Make sure to run this in the workspace directory
docker build -t ros2_rust_dev - < src/ros2_rust/Dockerfile
# ROS_DISTRO can be humble|iron|rolling
docker build -f src/ros2_rust/Dockerfile --build-arg "ROS_DISTRO=humble" -t ros2_rust_dev
```

and then run it with
Expand All @@ -75,7 +76,7 @@ As you can see, this maps the workspace directory to `/workspace` inside the con

```shell
# Make sure to run this in the workspace directory
vcs import src < src/ros2_rust/ros2_rust_foxy.repos
vcs import src < src/ros2_rust/ros2_rust_humble.repos
```

This uses the [`vcs` tool](https://github.com/dirk-thomas/vcstool), which is preinstalled in the Docker image.
Expand All @@ -87,13 +88,13 @@ The list of needed repositories should very rarely change, so you typically only
### Sourcing the ROS 2 installation

Before building, the ROS 2 installation, and ideally _only_ the ROS 2 installation, should be sourced.
Sourcing an installation populates a few environment variables such as `$AMENT_PREFIX_PATH`, so if you are not sure, you can check that the `$AMENT_PREFIX_PATH` environment variable contains the ROS 2 installation, e.g. `/opt/ros/foxy`.
Sourcing an installation populates a few environment variables such as `$AMENT_PREFIX_PATH`, so if you are not sure, you can check that the `$AMENT_PREFIX_PATH` environment variable contains the ROS 2 installation, e.g. `/opt/ros/humble`.

In the pre-made Docker image, sourcing is already done for you. Otherwise, if `$AMENT_PREFIX_PATH` is empty, you need to source the ROS 2 installation yourself:

```shell
# You can also do `source /opt/ros/foxy/setup.bash` in bash
. /opt/ros/foxy/setup.sh
# You can also do `source /opt/ros/humble/setup.bash` in bash
. /opt/ros/humble/setup.sh
````

If `$AMENT_PREFIX_PATH` contains undesired paths, exit and reopen your shell. If the problem persists, it's probably because of a sourcing command in your `~/.bashrc` or similar.
Expand Down
14 changes: 7 additions & 7 deletions docs/writing-your-first-rclrs-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ use std::sync::Arc;
use std_msgs::msg::String as StringMsg;

struct RepublisherNode {
node: rclrs::Node,
node: Arc<rclrs::Node>,
_subscription: Arc<rclrs::Subscription<StringMsg>>,
data: Option<StringMsg>,
}

impl RepublisherNode {
fn new(context: &rclrs::Context) -> Result<Self, rclrs::RclrsError> {
let mut node = rclrs::Node::new(context, "republisher")?;
let node = rclrs::Node::new(context, "republisher")?;
let data = None;
let _subscription = node.create_subscription(
"in_topic",
Expand All @@ -76,7 +76,7 @@ Next, add a main function to launch it:
fn main() -> Result<(), rclrs::RclrsError> {
let context = rclrs::Context::new(std::env::args())?;
let republisher = RepublisherNode::new(&context)?;
rclrs::spin(&republisher.node)
rclrs::spin(republisher.node)
}
```

Expand Down Expand Up @@ -114,14 +114,14 @@ use std::sync::{Arc, Mutex}; // (1)
use std_msgs::msg::String as StringMsg;

struct RepublisherNode {
node: rclrs::Node,
node: Arc<rclrs::Node>,
_subscription: Arc<rclrs::Subscription<StringMsg>>,
data: Arc<Mutex<Option<StringMsg>>>, // (2)
}

impl RepublisherNode {
fn new(context: &rclrs::Context) -> Result<Self, rclrs::RclrsError> {
let mut node = rclrs::Node::new(context, "republisher")?;
let node = rclrs::Node::new(context, "republisher")?;
let data = Arc::new(Mutex::new(None)); // (3)
let data_cb = Arc::clone(&data);
let _subscription = {
Expand Down Expand Up @@ -190,7 +190,7 @@ fn main() -> Result<(), rclrs::RclrsError> {
republisher.republish()?;
}
});
rclrs::spin(&republisher.node)
rclrs::spin(republisher.node)
}
```

Expand All @@ -212,7 +212,7 @@ fn main() -> Result<(), rclrs::RclrsError> {
republisher_other_thread.republish()?;
}
});
rclrs::spin(&republisher.node)
rclrs::spin(Arc::clone(&republisher.node))
}
```

Expand Down
8 changes: 4 additions & 4 deletions examples/message_demo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "examples_rclrs_message_demo"
version = "0.3.1"
version = "0.4.1"
authors = ["Nikolai Morin <[email protected]>"]
edition = "2021"

Expand All @@ -12,13 +12,13 @@ path = "src/message_demo.rs"
anyhow = {version = "1", features = ["backtrace"]}

[dependencies.rclrs]
version = "0.3"
version = "0.4"

[dependencies.rosidl_runtime_rs]
version = "0.3"
version = "0.4"

[dependencies.rclrs_example_msgs]
version = "0.3"
version = "0.4"
features = ["serde"]

[dependencies.serde_json]
Expand Down
2 changes: 1 addition & 1 deletion examples/message_demo/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>examples_rclrs_message_demo</name>
<version>0.3.1</version>
<version>0.4.1</version>
<description>Package containing an example of message-related functionality in rclrs.</description>
<maintainer email="[email protected]">Nikolai Morin</maintainer>
<license>Apache License 2.0</license>
Expand Down
7 changes: 4 additions & 3 deletions examples/message_demo/src/message_demo.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::convert::TryInto;
use std::env;
use std::sync::Arc;

use anyhow::{Error, Result};
use rosidl_runtime_rs::{seq, BoundedSequence, Message, Sequence};
Expand Down Expand Up @@ -132,7 +133,7 @@ fn demonstrate_pubsub() -> Result<(), Error> {
println!("================== Interoperability demo ==================");
// Demonstrate interoperability between idiomatic and RMW-native message types
let context = rclrs::Context::new(env::args())?;
let mut node = rclrs::create_node(&context, "message_demo")?;
let node = rclrs::create_node(&context, "message_demo")?;

let idiomatic_publisher = node.create_publisher::<rclrs_example_msgs::msg::VariousTypes>(
"topic",
Expand All @@ -159,10 +160,10 @@ fn demonstrate_pubsub() -> Result<(), Error> {
)?;
println!("Sending idiomatic message.");
idiomatic_publisher.publish(rclrs_example_msgs::msg::VariousTypes::default())?;
rclrs::spin_once(&node, None)?;
rclrs::spin_once(Arc::clone(&node), None)?;
println!("Sending RMW-native message.");
direct_publisher.publish(rclrs_example_msgs::msg::rmw::VariousTypes::default())?;
rclrs::spin_once(&node, None)?;
rclrs::spin_once(Arc::clone(&node), None)?;

Ok(())
}
Expand Down
6 changes: 3 additions & 3 deletions examples/minimal_client_service/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "examples_rclrs_minimal_client_service"
version = "0.3.1"
version = "0.4.1"
authors = ["Esteve Fernandez <[email protected]>"]
edition = "2021"

Expand All @@ -21,10 +21,10 @@ anyhow = {version = "1", features = ["backtrace"]}
tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread", "time"] }

[dependencies.rclrs]
version = "0.3"
version = "0.4"

[dependencies.rosidl_runtime_rs]
version = "0.3"
version = "0.4"

[dependencies.example_interfaces]
version = "*"
2 changes: 1 addition & 1 deletion examples/minimal_client_service/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>examples_rclrs_minimal_client_service</name>
<version>0.3.1</version>
<version>0.4.1</version>
<description>Package containing an example of the client-service mechanism in rclrs.</description>
<maintainer email="[email protected]">Esteve Fernandez</maintainer>
<license>Apache License 2.0</license>
Expand Down
8 changes: 5 additions & 3 deletions examples/minimal_client_service/src/minimal_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ use anyhow::{Error, Result};
fn main() -> Result<(), Error> {
let context = rclrs::Context::new(env::args())?;

let mut node = rclrs::create_node(&context, "minimal_client")?;
let node = rclrs::create_node(&context, "minimal_client")?;

let client = node.create_client::<example_interfaces::srv::AddTwoInts>("add_two_ints")?;

let request = example_interfaces::srv::AddTwoInts_Request { a: 41, b: 1 };

println!("Starting client");

std::thread::sleep(std::time::Duration::from_millis(500));
while !client.service_is_ready()? {
std::thread::sleep(std::time::Duration::from_millis(10));
}

client.async_send_request_with_callback(
&request,
Expand All @@ -28,5 +30,5 @@ fn main() -> Result<(), Error> {
std::thread::sleep(std::time::Duration::from_millis(500));

println!("Waiting for response");
rclrs::spin(&node).map_err(|err| err.into())
rclrs::spin(node).map_err(|err| err.into())
}
Loading

0 comments on commit 13723d2

Please sign in to comment.