-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added ROS2-like Rust Examples (#104)
- Loading branch information
1 parent
ebd39c1
commit 6b68bfb
Showing
12 changed files
with
422 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,30 @@ | ||
# Examples of Zenoh Python applications communicating with ROS 2 Nodes | ||
|
||
|
||
## Messages Publication: [talker.py](talker.py) | ||
## Messages Publication: [talker.py](src/talker.py) | ||
|
||
This code mimics the ROS 2 [Topics "talker" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/topics/talker.cpp). It's compatible with the ROS 2 [Topics "listener" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/topics/listener.cpp) running those commands: | ||
- `ros2 run demo_nodes_cpp listener` | ||
- `zenho-bridge-ros2dds` | ||
- `zenoh-bridge-ros2dds` | ||
- `python ./talker.py` | ||
|
||
## Messages Subscription: [listener.py](listener.py) | ||
## Messages Subscription: [listener.py](src/listener.py) | ||
|
||
This code mimics the ROS 2 [Topics "listener" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/topics/listener.cpp). It's compatible with the ROS 2 [Topics "talker" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/topics/talker.cpp) running those commands: | ||
- `ros2 run demo_nodes_cpp talker` | ||
- `zenho-bridge-ros2dds` | ||
- `zenoh-bridge-ros2dds` | ||
- `python ./listener.py` | ||
|
||
## Services Client: [add_two_ints_client.py](add_two_ints_client.py) | ||
## Services Client: [add_two_ints_client.py](src/add_two_ints_client.py) | ||
|
||
This code mimics the ROS 2 [Services "add_two_ints_client" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/services/add_two_ints_client.cpp). It's compatible with the ROS 2 [Services "add_two_ints_server" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/services/add_two_ints_server.cpp) running those commands: | ||
- `ros2 run demo_nodes_cpp add_two_ints_server` | ||
- `zenho-bridge-ros2dds` | ||
- `zenoh-bridge-ros2dds` | ||
- `python ./add_two_ints_client.py` | ||
|
||
## Actions Client: [fibonnacci_action_client.py](fibonnacci_action_client.py) | ||
## Actions Client: [fibonnacci_action_client.py](src/fibonnacci_action_client.py) | ||
|
||
This code mimics the ROS 2 [Actions "fibonnacci_action_client" demo](https://github.com/ros2/demos/blob/rolling/action_tutorials/action_tutorials_cpp/src/fibonacci_action_client.cpp). It's compatible with the ROS 2 [Actions "fibonnacci_action_server" demo](https://github.com/ros2/demos/blob/rolling/action_tutorials/action_tutorials_cpp/src/fibonacci_action_server.cpp) running those commands: | ||
- `ros2 run action_tutorials_cpp fibonacci_action_server` | ||
- `zenho-bridge-ros2dds` | ||
- `zenoh-bridge-ros2dds` | ||
- `python ./fibonnacci_action_client.py` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "rust_examples" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[workspace] | ||
[dependencies] | ||
async-std = { version = "1.12.0" } | ||
futures = { version = "0.3.28" } | ||
zenoh = { version = "0.10.1-rc" } | ||
clap = { version = "4.4.11", features = ["derive"] } | ||
env_logger = { version = "0.10.0" } | ||
serde = {version = "1" } | ||
serde_derive = {version = "1"} | ||
cdr = {version = "0.2.4"} | ||
log = { version = "0.4.21"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Examples of Zenoh Rust applications communicating with ROS 2 Nodes | ||
|
||
## Building the examples | ||
In order to build the examples you will need to: | ||
* [Install Rust and Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html) | ||
* [Clone the repository](https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds) | ||
|
||
Once this is done, compile by running the following: | ||
``` | ||
cd examples/rust | ||
cargo build | ||
``` | ||
|
||
## Messages Publication: [talker.rs](src/bin/talker.rs) | ||
|
||
This code mimics the ROS 2 [Topics "talker" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/topics/talker.cpp). It's compatible with the ROS 2 [Topics "listener" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/topics/listener.cpp) running those commands: | ||
- `ros2 run demo_nodes_cpp listener` | ||
- `zenoh-bridge-ros2dds` | ||
- `cargo run --bin talker` | ||
|
||
## Messages Subscription: [listener.rs](src/bin/listener.rs) | ||
|
||
This code mimics the ROS 2 [Topics "listener" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/topics/listener.cpp). It's compatible with the ROS 2 [Topics "talker" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/topics/talker.cpp) running those commands: | ||
- `ros2 run demo_nodes_cpp talker` | ||
- `zenoh-bridge-ros2dds` | ||
- `cargo run --bin listener` | ||
|
||
## Services Client: [add_two_ints_client.rs](src/bin/add_two_ints_client.rs) | ||
|
||
This code mimics the ROS 2 [Services "add_two_ints_client" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/services/add_two_ints_client.cpp). It's compatible with the ROS 2 [Services "add_two_ints_server" demo](https://github.com/ros2/demos/blob/rolling/demo_nodes_cpp/src/services/add_two_ints_server.cpp) running those commands: | ||
- `ros2 run demo_nodes_cpp add_two_ints_server` | ||
- `zenoh-bridge-ros2dds` | ||
- `cargo run --bin add_two_ints_client` | ||
|
||
## Actions Client: [fibonnacci_action_client.rs](src/bin/fibonnacci_action_client.rs) | ||
|
||
This code mimics the ROS 2 [Actions "fibonnacci_action_client" demo](https://github.com/ros2/demos/blob/rolling/action_tutorials/action_tutorials_cpp/src/fibonacci_action_client.cpp). It's compatible with the ROS 2 [Actions "fibonnacci_action_server" demo](https://github.com/ros2/demos/blob/rolling/action_tutorials/action_tutorials_cpp/src/fibonacci_action_server.cpp) running those commands: | ||
- `ros2 run action_tutorials_cpp fibonacci_action_server` | ||
- `zenoh-bridge-ros2dds` | ||
- `cargo run --bin fibonnacci_action_client` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[toolchain] | ||
channel = "1.72.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// | ||
// Copyright (c) 2023 ZettaScale Technology | ||
// | ||
// This program and the accompanying materials are made available under the | ||
// terms of the Eclipse Public License 2.0 which is available at | ||
// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 | ||
// which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
// | ||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
// | ||
// Contributors: | ||
// ZettaScale Zenoh Team, <[email protected]> | ||
// | ||
use cdr::{CdrLe, Infinite}; | ||
use clap::{App, Arg}; | ||
use serde::{Deserialize, Serialize}; | ||
use zenoh::config::Config; | ||
use zenoh::prelude::r#async::*; | ||
|
||
#[derive(Serialize, PartialEq, Debug)] | ||
struct AddTwoIntsRequest { | ||
a: i64, | ||
b: i64, | ||
} | ||
|
||
#[derive(Deserialize, PartialEq, Debug)] | ||
struct AddTwoIntsResponse { | ||
sum: i64, | ||
} | ||
|
||
#[async_std::main] | ||
async fn main() { | ||
env_logger::init(); | ||
|
||
let config = parse_args(); | ||
|
||
let session = zenoh::open(config).res().await.unwrap(); | ||
|
||
let req = AddTwoIntsRequest { a: 2, b: 3 }; | ||
let buf = cdr::serialize::<_, _, CdrLe>(&req, Infinite).unwrap(); | ||
let replies = session | ||
.get("add_two_ints") | ||
.with_value(buf) | ||
.res() | ||
.await | ||
.unwrap(); | ||
|
||
while let Ok(reply) = replies.recv_async().await { | ||
match cdr::deserialize_from::<_, AddTwoIntsResponse, _>( | ||
reply.sample.unwrap().payload.reader(), | ||
cdr::size::Infinite, | ||
) { | ||
Ok(res) => { | ||
println!("Result of add_two_ints: {}", res.sum); | ||
} | ||
Err(e) => log::warn!("Error decoding message: {}", e), | ||
} | ||
} | ||
} | ||
|
||
fn parse_args() -> Config { | ||
let args = App::new("zenoh sub example") | ||
.arg(Arg::from_usage( | ||
"-c, --config=[FILE] 'A configuration file.'", | ||
)) | ||
.get_matches(); | ||
|
||
let config = if let Some(conf_file) = args.value_of("config") { | ||
Config::from_file(conf_file).unwrap() | ||
} else { | ||
Config::default() | ||
}; | ||
|
||
config | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
// | ||
// Copyright (c) 2023 ZettaScale Technology | ||
// | ||
// This program and the accompanying materials are made available under the | ||
// terms of the Eclipse Public License 2.0 which is available at | ||
// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 | ||
// which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
// | ||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
// | ||
// Contributors: | ||
// ZettaScale Zenoh Team, <[email protected]> | ||
// | ||
use cdr::{CdrLe, Infinite}; | ||
use clap::{App, Arg}; | ||
use serde::{Deserialize, Serialize}; | ||
use zenoh::config::Config; | ||
use zenoh::prelude::r#async::*; | ||
|
||
#[derive(Deserialize, PartialEq, Debug)] | ||
struct Time { | ||
sec: u32, | ||
nsec: u32, | ||
} | ||
|
||
#[derive(Serialize, PartialEq, Debug)] | ||
struct FibonacciSendGoalRequest { | ||
goal_id: [u8; 16], | ||
order: i32, | ||
} | ||
|
||
#[derive(Deserialize, PartialEq, Debug)] | ||
struct FibonacciSendGoalResponse { | ||
accepted: bool, | ||
stamp: Time, | ||
} | ||
|
||
#[derive(Serialize, PartialEq, Debug)] | ||
struct FibonacciGetResultRequest { | ||
goal_id: [u8; 16], | ||
} | ||
|
||
#[derive(Deserialize, PartialEq, Debug)] | ||
struct FibonacciGetResultResponse { | ||
status: i8, | ||
sequence: Vec<i32>, | ||
} | ||
|
||
#[derive(Deserialize, PartialEq, Debug)] | ||
struct FibonacciFeedback { | ||
goal_id: [u8; 16], | ||
partial_sequence: Vec<i32>, | ||
} | ||
|
||
#[async_std::main] | ||
async fn main() { | ||
env_logger::init(); | ||
|
||
let config = parse_args(); | ||
|
||
let session = zenoh::open(config).res().await.unwrap(); | ||
|
||
let _subscriber = session | ||
.declare_subscriber("fibonacci/_action/feedback") | ||
.callback(|sample| { | ||
match cdr::deserialize_from::<_, FibonacciFeedback, _>( | ||
sample.value.payload.reader(), | ||
cdr::size::Infinite, | ||
) { | ||
Ok(msg) => { | ||
println!( | ||
"Next number in sequence received: {:?}", | ||
msg.partial_sequence | ||
); | ||
} | ||
Err(e) => log::warn!("Error decoding message: {}", e), | ||
}; | ||
}) | ||
.res() | ||
.await | ||
.unwrap(); | ||
|
||
let goal_id: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | ||
let req = FibonacciSendGoalRequest { | ||
goal_id: goal_id, | ||
order: 10, | ||
}; | ||
|
||
let buf = cdr::serialize::<_, _, CdrLe>(&req, Infinite).unwrap(); | ||
println!("Sending goal"); | ||
let replies = session | ||
.get("fibonacci/_action/send_goal") | ||
.with_value(buf) | ||
.res() | ||
.await | ||
.unwrap(); | ||
|
||
while let Ok(reply) = replies.recv_async().await { | ||
match cdr::deserialize_from::<_, FibonacciSendGoalResponse, _>( | ||
reply.sample.unwrap().payload.reader(), | ||
cdr::size::Infinite, | ||
) { | ||
Ok(res) => { | ||
if res.accepted { | ||
println!("Goal accepted by server, waiting for result"); | ||
} else { | ||
println!("Goal rejected :("); | ||
return; | ||
} | ||
} | ||
Err(e) => log::warn!("Error decoding message: {}", e), | ||
} | ||
} | ||
|
||
let req = FibonacciGetResultRequest { goal_id: goal_id }; | ||
let buf = cdr::serialize::<_, _, CdrLe>(&req, Infinite).unwrap(); | ||
let replies = session | ||
.get("fibonacci/_action/get_result") | ||
.with_value(buf) | ||
.res() | ||
.await | ||
.unwrap(); | ||
while let Ok(reply) = replies.recv_async().await { | ||
match cdr::deserialize_from::<_, FibonacciGetResultResponse, _>( | ||
reply.sample.unwrap().payload.reader(), | ||
cdr::size::Infinite, | ||
) { | ||
Ok(res) => { | ||
println!("Result: {:?}", res.sequence); | ||
} | ||
Err(e) => log::warn!("Error decoding message: {}", e), | ||
} | ||
} | ||
} | ||
|
||
fn parse_args() -> Config { | ||
let args = App::new("zenoh sub example") | ||
.arg(Arg::from_usage( | ||
"-c, --config=[FILE] 'A configuration file.'", | ||
)) | ||
.get_matches(); | ||
|
||
let config = if let Some(conf_file) = args.value_of("config") { | ||
Config::from_file(conf_file).unwrap() | ||
} else { | ||
Config::default() | ||
}; | ||
|
||
config | ||
} |
Oops, something went wrong.