mirror of
https://github.com/ruvnet/RuView
synced 2026-08-10 20:31:42 +00:00
feat: add RTL8720F Realtek radar beta support (#1356)
* docs(adr): plan RTL8720F radar SDK integration * feat(hardware): add Rust RTL8720F radar simulator * feat(ruview): ingest RTL8720F radar frames
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
//! Rust-only RTL8720F radar simulator for pre-hardware integration.
|
||||
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, Write},
|
||||
net::{SocketAddr, UdpSocket},
|
||||
path::PathBuf,
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use clap::Parser;
|
||||
use wifi_densepose_hardware::rtl8720f::{
|
||||
simulator::{Rtl8720fSimulator, SimulatorConfig},
|
||||
RadarFrame, ReportType,
|
||||
};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(
|
||||
name = "rtl8720f-sim",
|
||||
about = "Emit synthetic ADR-264 RTL8720F radar frames"
|
||||
)]
|
||||
struct Args {
|
||||
#[arg(long, default_value_t = 100)]
|
||||
frames: u32,
|
||||
#[arg(long, default_value = "0x8720f123456789ab", value_parser = parse_u64)]
|
||||
seed: u64,
|
||||
#[arg(long, default_value_t = 40)]
|
||||
bandwidth: u16,
|
||||
#[arg(long, default_value_t = 15)]
|
||||
interval_ms: u64,
|
||||
/// UDP destination; each frame is one datagram.
|
||||
#[arg(long)]
|
||||
udp: Option<SocketAddr>,
|
||||
/// Replay file; LE u32 length followed by ADR-264 bytes.
|
||||
#[arg(long)]
|
||||
output: Option<PathBuf>,
|
||||
#[arg(long)]
|
||||
realtime: bool,
|
||||
}
|
||||
|
||||
fn parse_u64(value: &str) -> Result<u64, String> {
|
||||
if let Some(hex) = value
|
||||
.strip_prefix("0x")
|
||||
.or_else(|| value.strip_prefix("0X"))
|
||||
{
|
||||
u64::from_str_radix(hex, 16).map_err(|error| error.to_string())
|
||||
} else {
|
||||
value.parse::<u64>().map_err(|error| error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn emit(
|
||||
frame: RadarFrame,
|
||||
socket: Option<&UdpSocket>,
|
||||
destination: Option<SocketAddr>,
|
||||
output: &mut Option<File>,
|
||||
) -> Result<usize, Box<dyn std::error::Error>> {
|
||||
let wire = frame.to_bytes()?;
|
||||
if let (Some(socket), Some(destination)) = (socket, destination) {
|
||||
let sent = socket.send_to(&wire, destination)?;
|
||||
if sent != wire.len() {
|
||||
return Err(io::Error::new(io::ErrorKind::WriteZero, "partial UDP datagram").into());
|
||||
}
|
||||
}
|
||||
if let Some(file) = output {
|
||||
file.write_all(&(wire.len() as u32).to_le_bytes())?;
|
||||
file.write_all(&wire)?;
|
||||
}
|
||||
Ok(wire.len())
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = Args::parse();
|
||||
if args.udp.is_none() && args.output.is_none() {
|
||||
return Err("select at least one sink with --udp or --output".into());
|
||||
}
|
||||
let config = SimulatorConfig {
|
||||
seed: args.seed,
|
||||
bandwidth_mhz: args.bandwidth,
|
||||
frame_period_us: args.interval_ms * 1_000,
|
||||
..SimulatorConfig::default()
|
||||
};
|
||||
let mut simulator = Rtl8720fSimulator::new(config)?;
|
||||
let socket = args.udp.map(|_| UdpSocket::bind("0.0.0.0:0")).transpose()?;
|
||||
let mut output = args.output.as_ref().map(File::create).transpose()?;
|
||||
let mut bytes_emitted = emit(
|
||||
simulator.capabilities_frame(),
|
||||
socket.as_ref(),
|
||||
args.udp,
|
||||
&mut output,
|
||||
)?;
|
||||
|
||||
for index in 0..args.frames {
|
||||
let report_type = match index % 16 {
|
||||
15 => ReportType::Interference,
|
||||
value if value % 4 == 1 => ReportType::RangeNear,
|
||||
value if value % 4 == 3 => ReportType::RangeFar,
|
||||
_ => ReportType::Cfr,
|
||||
};
|
||||
bytes_emitted += emit(
|
||||
simulator.next_frame(report_type),
|
||||
socket.as_ref(),
|
||||
args.udp,
|
||||
&mut output,
|
||||
)?;
|
||||
if args.realtime {
|
||||
thread::sleep(Duration::from_millis(args.interval_ms));
|
||||
}
|
||||
}
|
||||
eprintln!(
|
||||
"emitted {} synthetic RTL8720F frames ({} bytes, seed={:#x})",
|
||||
args.frames + 1,
|
||||
bytes_emitted,
|
||||
args.seed
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user