Skip to content
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

Add: UDP stream option to ping1d example #34

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ clap = { version = "4.5.4", features = ["derive"] }

[dev-dependencies]
tracing-test = "0.2.4"
udp-stream = "0.0.11"

[build-dependencies]
convert_case = "0.6.0"
Expand Down
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ https://docs.bluerobotics.com/ping-rs/bluerobotics_ping/
To run examples use:

```shell
cargo run --example ping_1d -- --port-name /dev/ttyUSB0
cargo run --example ping_1d -- --serial-port /dev/ttyUSB0
```

Should output:
Expand Down Expand Up @@ -34,4 +34,20 @@ The distance to target is: 4538 mm
Waiting for 30 profiles...
Received 30 profiles
Turning-off the continuous messages stream from Ping1D
```
```
### **Pro tip** :grey_exclamation:
For external use via UDP, consider using [bridges](https://github.com/patrickelectric/bridges) to share your serial device to the network. Detailed instructions can be found [here](https://github.com/patrickelectric/bridges?tab=readme-ov-file#install-zap).

#### On the host :satellite: (Where ping device is connected):

```shell
bridges --port /dev/ttyUSB0:115200 -u 0.0.0.0:8080
```

#### On the client :computer::

```shell
cargo run --example ping_1d -- --udp-address 192.168.0.191 --udp-port 8080
```

Enjoy exploring with ping-rs! :ocean:
85 changes: 73 additions & 12 deletions examples/ping_1d.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use clap::Parser;
use std::{convert::TryFrom, path::PathBuf};
use std::{
convert::TryFrom,
net::{IpAddr, SocketAddr},
path::PathBuf,
str::FromStr,
};
use udp_stream::UdpStream;

use bluerobotics_ping::{
device::{Ping1D, PingDevice},
Expand All @@ -12,15 +18,14 @@ use tokio_serial::{SerialPort, SerialPortBuilderExt};

#[tokio::main]
async fn main() -> Result<(), PingError> {
println!("Parsing user provided values...");
let args = Args::parse();

let port =
tokio_serial::new(args.port_name.to_string_lossy(), args.baud_rate).open_native_async()?;
port.clear(tokio_serial::ClearBuffer::All)?;
println!("Parsing user provided values and creating port...");
let port = create_port().await;

println!("Creating your Ping 1D device");
let ping1d = Ping1D::new(port);
let ping1d = match port {
Port::Serial(port) => Ping1D::new(port),
Port::Udp(port) => Ping1D::new(port),
};

// Creating a subscription channel which will receive 30 Profile measurements, we'll check this after the next methods!
let mut subscribed = ping1d.subscribe();
Expand Down Expand Up @@ -136,8 +141,64 @@ async fn main() -> Result<(), PingError> {
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
#[arg(short, long)]
port_name: PathBuf,
#[arg(short, long, default_value_t = 115200)]
baud_rate: u32,
#[arg(long, group = "source",
conflicts_with_all = ["udp_address"])]
serial_port: Option<PathBuf>,
#[arg(long, default_value_t = 115200)]
serial_baud_rate: u32,
#[arg(long, group = "source",
conflicts_with_all = ["serial_port"])]
udp_address: Option<IpAddr>,
#[arg(long, default_value_t = 8080)]
udp_port: u32,
}

enum Port {
Serial(tokio_serial::SerialStream),
Udp(udp_stream::UdpStream),
}

async fn create_port() -> Port {
let args = Args::parse();

let port = match (args.serial_port, args.udp_address) {
(Some(serial_port), None) => {
println!("Using serial port: {:?}", serial_port);
let port = tokio_serial::new(serial_port.to_string_lossy(), args.serial_baud_rate)
.open_native_async()
.map_err(|e| {
eprintln!("Error opening serial port: {}", e);
e
})
.unwrap();
port.clear(tokio_serial::ClearBuffer::All).unwrap();
Port::Serial(port)
}
(None, Some(udp_address)) => {
println!("Using UDP address: {}", udp_address);
let socket_addr = SocketAddr::from_str(&format!("{}:{}", udp_address, args.udp_port))
.map_err(|e| {
eprintln!("Error parsing UDP address: {}", e);
e
})
.unwrap();
let port = UdpStream::connect(socket_addr)
.await
.map_err(|e| {
eprintln!("Error connecting to UDP socket: {}", e);
e
})
.unwrap();
Port::Udp(port)
}
(None, None) => {
eprintln!("Error: either serial_port_name or udp_address must be provided");
std::process::exit(1);
}
(Some(_), Some(_)) => {
eprintln!("Error: serial_port_name and udp_address are mutually exclusive");
std::process::exit(1);
}
};
port
}
Loading