cargo: clean up dependencies and improve build times
This commit is contained in:
116
Cargo.lock
generated
116
Cargo.lock
generated
@@ -137,12 +137,6 @@ dependencies = [
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.4"
|
||||
@@ -343,6 +337,18 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938"
|
||||
dependencies = [
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.12"
|
||||
@@ -576,24 +582,6 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embassy-net"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0558a231a47e7d4a06a28b5278c92e860f1200f24821d2f365a2f40fe3f3c7b2"
|
||||
dependencies = [
|
||||
"document-features",
|
||||
"embassy-net-driver",
|
||||
"embassy-sync 0.7.2",
|
||||
"embassy-time 0.5.0",
|
||||
"embedded-io-async",
|
||||
"embedded-nal-async",
|
||||
"heapless",
|
||||
"log",
|
||||
"managed",
|
||||
"smoltcp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embassy-net-driver"
|
||||
version = "0.2.0"
|
||||
@@ -773,25 +761,6 @@ dependencies = [
|
||||
"embedded-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-nal"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c56a28be191a992f28f178ec338a0bf02f63d7803244add736d026a471e6ed77"
|
||||
dependencies = [
|
||||
"nb 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-nal-async"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76959917cd2b86f40a98c28dd5624eddd1fa69d746241c8257eac428d83cb211"
|
||||
dependencies = [
|
||||
"embedded-io-async",
|
||||
"embedded-nal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-storage"
|
||||
version = "0.3.1"
|
||||
@@ -916,7 +885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3887eda2917deef3d99e7a5c324f9190714e99055361ad36890dffd0a995b49"
|
||||
dependencies = [
|
||||
"bitfield 0.19.2",
|
||||
"bitflags 2.9.4",
|
||||
"bitflags",
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"critical-section",
|
||||
@@ -1110,7 +1079,6 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
"portable_atomic_enum",
|
||||
"rand_core 0.9.3",
|
||||
"smoltcp",
|
||||
"xtensa-lx-rt",
|
||||
]
|
||||
|
||||
@@ -1623,15 +1591,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kfilter"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d320a64bfb4ff8e33add1458241eff87b02a29abf9c19549a02500795928afa"
|
||||
dependencies = [
|
||||
"nalgebra 0.33.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.3"
|
||||
@@ -1709,12 +1668,6 @@ dependencies = [
|
||||
"imgref",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "managed"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
|
||||
|
||||
[[package]]
|
||||
name = "maybe-async-cfg"
|
||||
version = "0.2.4"
|
||||
@@ -1995,7 +1948,7 @@ version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
@@ -2114,7 +2067,7 @@ version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
@@ -2280,19 +2233,15 @@ dependencies = [
|
||||
name = "renderbug-embassy"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bleps",
|
||||
"critical-section",
|
||||
"csv-core",
|
||||
"csv",
|
||||
"embassy-embedded-hal 0.5.0",
|
||||
"embassy-executor",
|
||||
"embassy-net",
|
||||
"embassy-sync 0.7.2",
|
||||
"embassy-time 0.5.0",
|
||||
"embedded-graphics",
|
||||
"embedded-hal-async",
|
||||
"embedded-io",
|
||||
"embedded-io-async",
|
||||
"esp-alloc",
|
||||
"esp-backtrace",
|
||||
"esp-bootloader-esp-idf",
|
||||
@@ -2305,18 +2254,14 @@ dependencies = [
|
||||
"figments-render",
|
||||
"futures",
|
||||
"image",
|
||||
"kfilter",
|
||||
"log",
|
||||
"micromath",
|
||||
"mpu6050-dmp",
|
||||
"nalgebra 0.33.2",
|
||||
"nmea",
|
||||
"rgb",
|
||||
"rmp",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smart-leds",
|
||||
"smart-leds-trait",
|
||||
"smoltcp",
|
||||
"ssd1306",
|
||||
"static_cell",
|
||||
"xtensa-lx-rt",
|
||||
@@ -2447,19 +2392,6 @@ dependencies = [
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.9"
|
||||
@@ -2551,20 +2483,6 @@ dependencies = [
|
||||
"rgb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smoltcp"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dad095989c1533c1c266d9b1e8d70a1329dd3723c3edac6d03bbd67e7bf6f4bb"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"byteorder",
|
||||
"cfg-if",
|
||||
"heapless",
|
||||
"log",
|
||||
"managed",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ssd1306"
|
||||
version = "0.10.0"
|
||||
|
||||
85
Cargo.toml
85
Cargo.toml
@@ -9,26 +9,23 @@ name = "renderbug-embassy"
|
||||
path = "./src/bin/main.rs"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
simulation = ["dep:csv-core", "dep:rmp"]
|
||||
default = ["real-output"]
|
||||
real-output = []
|
||||
simulation = ["dep:rmp"]
|
||||
radio = [
|
||||
"dep:embassy-net",
|
||||
"dep:smoltcp",
|
||||
"dep:bleps",
|
||||
"dep:serde_json",
|
||||
"dep:serde",
|
||||
"dep:esp-wifi"
|
||||
]
|
||||
motion = ["mpu", "gps"]
|
||||
max-usb-power = []
|
||||
wokwi = ["max-usb-power"]
|
||||
headless = []
|
||||
mpu = ["dep:mpu6050-dmp"]
|
||||
gps = ["dep:nmea"]
|
||||
oled = []
|
||||
oled = ["dep:ssd1306", "dep:embedded-graphics"]
|
||||
demo = []
|
||||
|
||||
[dependencies]
|
||||
# The basic requirements for all features
|
||||
figments = { path = "../figments/figments/", features = ["alloc"] }
|
||||
figments-render = { path = "../figments/figments-render/", features = ["smart-leds", "micromath"], default-features = false }
|
||||
esp-bootloader-esp-idf = { version = "0.2.0", features = ["esp32s3"] }
|
||||
@@ -37,17 +34,6 @@ esp-hal = { version = "=1.0.0-rc.0", features = [
|
||||
"log-04",
|
||||
"unstable",
|
||||
] }
|
||||
log = "0.4.27"
|
||||
|
||||
embassy-net = { version = "0.7.0", optional = true, features = [
|
||||
"dhcpv4",
|
||||
"log",
|
||||
"medium-ethernet",
|
||||
"tcp",
|
||||
"udp",
|
||||
] }
|
||||
embedded-io = "0.6.1"
|
||||
embedded-io-async = "0.6.1"
|
||||
esp-alloc = "0.8.0"
|
||||
esp-backtrace = { version = "0.17.0", features = [
|
||||
"esp32s3",
|
||||
@@ -67,33 +53,34 @@ esp-hal-embassy = { version = "0.9.0", features = [
|
||||
"esp32s3",
|
||||
"log-04"
|
||||
] }
|
||||
log = "0.4.27"
|
||||
static_cell = "2.1.1"
|
||||
rgb = "0.8.52"
|
||||
# esp-hal-smartled = { version = "0.15.0", features = ["esp32c3"] }
|
||||
esp-hal-smartled = { git = "https://github.com/esp-rs/esp-hal-community.git", features = ["esp32s3"] }
|
||||
smart-leds = "0.4.0"
|
||||
embassy-sync = "0.7.2"
|
||||
embassy-embedded-hal = "0.5.0"
|
||||
embedded-hal-async = "1.0.0"
|
||||
nalgebra = { version = "0.33.2", default-features = false, features = ["alloc", "libm"] }
|
||||
xtensa-lx-rt = { version = "*", features = ["float-save-restore"] }
|
||||
futures = { version = "0.3.31", default-features = false, features = ["async-await"] }
|
||||
micromath = "2.1.0"
|
||||
|
||||
# Telemetry outputs
|
||||
esp-wifi = { version = "0.15.0", optional = true, features = [
|
||||
"builtin-scheduler",
|
||||
"esp-alloc",
|
||||
"esp32s3",
|
||||
"log-04",
|
||||
"smoltcp",
|
||||
"wifi",
|
||||
"ble"
|
||||
] }
|
||||
smoltcp = { version = "0.12.0", optional = true, default-features = false, features = [
|
||||
"log",
|
||||
"medium-ethernet",
|
||||
"multicast",
|
||||
"proto-dhcpv4",
|
||||
"proto-dns",
|
||||
"proto-ipv4",
|
||||
"socket-dns",
|
||||
"socket-icmp",
|
||||
"socket-raw",
|
||||
"socket-tcp",
|
||||
"socket-udp",
|
||||
] }
|
||||
static_cell = "2.1.1"
|
||||
# esp-hal-smartled = { version = "0.15.0", features = ["esp32c3"] }
|
||||
esp-hal-smartled = { git = "https://github.com/esp-rs/esp-hal-community.git", features = ["esp32s3"] }
|
||||
smart-leds = "0.4.0"
|
||||
rgb = "0.8.52"
|
||||
bleps = { git = "https://github.com/bjoernQ/bleps", optional = true, package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [ "macros", "async"] }
|
||||
embedded-graphics = { version = "0.8.1", features = ["nalgebra_support"], optional = true}
|
||||
ssd1306 = { version = "0.10.0", features = ["async"], optional = true }
|
||||
|
||||
# Sensors
|
||||
nmea = { version = "0.7.0", optional = true, default-features = false, features = [
|
||||
"GGA",
|
||||
"GSA",
|
||||
@@ -104,23 +91,10 @@ nmea = { version = "0.7.0", optional = true, default-features = false, features
|
||||
"GLL",
|
||||
"GST",
|
||||
] }
|
||||
embassy-sync = "0.7.2"
|
||||
mpu6050-dmp = { version = "0.6.1", features = ["async"], optional = true }
|
||||
embassy-embedded-hal = "0.5.0"
|
||||
embedded-hal-async = "1.0.0"
|
||||
smart-leds-trait = "0.3.1"
|
||||
anyhow = { version = "1.0.99", default-features = false }
|
||||
nalgebra = { version = "0.33.2", default-features = false }
|
||||
bleps = { git = "https://github.com/bjoernQ/bleps", optional = true, package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [ "macros", "async"] }
|
||||
serde_json = {version = "1.0.145", optional = true, default-features = false, features = ["alloc"] }
|
||||
csv-core = {version = "0.1.12", optional = true }
|
||||
serde = { version = "1.0.228", optional = true, default-features = false, features = ["derive"] }
|
||||
kfilter = "0.4.0"
|
||||
|
||||
# Simulation
|
||||
rmp = { version = "0.8.14", optional = true, default-features = false }
|
||||
xtensa-lx-rt = { version = "*", features = ["float-save-restore"] }
|
||||
futures = { version = "0.3.31", default-features = false, features = ["async-await"] }
|
||||
ssd1306 = { version = "0.10.0", features = ["async"] }
|
||||
embedded-graphics = { version = "0.8.1", features = ["nalgebra_support"] }
|
||||
|
||||
[profile.dev]
|
||||
# Rust debug is too slow.
|
||||
@@ -137,5 +111,6 @@ opt-level = 's'
|
||||
overflow-checks = false
|
||||
|
||||
[build-dependencies]
|
||||
image = "0.25.8"
|
||||
rmp = "0.8"
|
||||
image = "0.25"
|
||||
rmp = "0.8"
|
||||
csv = "1.3"
|
||||
|
||||
108
build.rs
108
build.rs
@@ -3,13 +3,22 @@ use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use image::GenericImageView;
|
||||
use rmp;
|
||||
use csv::Reader;
|
||||
|
||||
fn main() {
|
||||
linker_be_nice();
|
||||
// make sure linkall.x is the last linker script (otherwise might cause problems with flip-link)
|
||||
println!("cargo:rustc-link-arg=-Tlinkall.x");
|
||||
|
||||
#[cfg(feature="simulation")]
|
||||
write_sim_data();
|
||||
|
||||
#[cfg(feature="oled")]
|
||||
compile_assets();
|
||||
|
||||
}
|
||||
|
||||
fn compile_assets() {
|
||||
let asset_path = Path::new("assets");
|
||||
|
||||
let mut image_output = File::create(Path::new("target/images.rs")).unwrap();
|
||||
@@ -55,13 +64,100 @@ fn main() {
|
||||
println!("cargo::rerun-if-changed={fname_str}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*let test_data_path = Path::new("test-data");
|
||||
let gps_data = File::open(test_data_path.join("LocationGps.csv")).unwrap();
|
||||
let accel_data = File::open(test_data_path.join("AccelerometerUncalibrated.csv")).unwrap();
|
||||
let gyro_data = File::open(test_data_path.join("GyroscopeUncalibrated.csv")).unwrap();
|
||||
let mut test_data_output = File::create(Path::new("target/test_data.rs")).unwrap();*/
|
||||
fn write_sim_data() {
|
||||
let test_data_path = Path::new("test-data");
|
||||
let output_path = Path::new("target");
|
||||
let gps_input = test_data_path.join("LocationGps.csv");
|
||||
let gyro_input = test_data_path.join("GyroscopeUncalibrated.csv");
|
||||
let accel_input = test_data_path.join("AccelerometerUncalibrated.csv");
|
||||
|
||||
let gps_output = output_path.join("gps_test_data.msgpack");
|
||||
let motion_output = output_path.join("motion_test_data.msgpack");
|
||||
|
||||
println!("cargo::rerun-if-changed={}", gps_input.to_str().unwrap());
|
||||
if !gps_output.exists() || gps_output.metadata().unwrap().modified().unwrap() < gps_input.metadata().unwrap().modified().unwrap() {
|
||||
let mut gps_data = Reader::from_reader(File::open(gps_input).unwrap());
|
||||
let headers = gps_data.headers().unwrap();
|
||||
let (timestamp_idx, lat_idx, lon_idx) = (
|
||||
headers.iter().position(|x| { x == "seconds_elapsed" }).unwrap(),
|
||||
headers.iter().position(|x| { x == "longitude" }).unwrap(),
|
||||
headers.iter().position(|x| { x == "latitude" }).unwrap(),
|
||||
);
|
||||
let mut gps_output = File::create(gps_output).unwrap();
|
||||
let mut last_stamp = 0.0;
|
||||
for record in gps_data.records().flatten() {
|
||||
let (timestamp, lat, lon) = (
|
||||
record.get(timestamp_idx).unwrap().parse().unwrap(),
|
||||
record.get(lat_idx).unwrap().parse().unwrap(),
|
||||
record.get(lon_idx).unwrap().parse().unwrap()
|
||||
);
|
||||
let next_delay = timestamp - last_stamp;
|
||||
last_stamp = timestamp;
|
||||
rmp::encode::write_array_len(&mut gps_output, 3).unwrap();
|
||||
rmp::encode::write_f64(&mut gps_output, next_delay).unwrap();
|
||||
rmp::encode::write_f64(&mut gps_output, lat).unwrap();
|
||||
rmp::encode::write_f64(&mut gps_output, lon).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
println!("cargo::rerun-if-changed={}", accel_input.to_str().unwrap());
|
||||
println!("cargo::rerun-if-changed={}", gyro_input.to_str().unwrap());
|
||||
let rebuild_motion = {
|
||||
if motion_output.exists() {
|
||||
let motion_stamp = motion_output.metadata().unwrap().modified().unwrap();
|
||||
motion_stamp < accel_input.metadata().unwrap().modified().unwrap() || motion_stamp < gyro_input.metadata().unwrap().modified().unwrap()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
};
|
||||
if rebuild_motion {
|
||||
let mut accel_data = Reader::from_reader(File::open(accel_input).unwrap());
|
||||
let mut gyro_data = Reader::from_reader(File::open(gyro_input).unwrap());
|
||||
let headers = accel_data.headers().unwrap();
|
||||
let (timestamp_idx, accel_x_idx, accel_y_idx, accel_z_idx) = (
|
||||
headers.iter().position(|x| { x == "seconds_elapsed" }).unwrap(),
|
||||
headers.iter().position(|x| { x == "x" }).unwrap(),
|
||||
headers.iter().position(|x| { x == "y" }).unwrap(),
|
||||
headers.iter().position(|x| { x == "z" }).unwrap(),
|
||||
);
|
||||
|
||||
let headers = gyro_data.headers().unwrap();
|
||||
let (gyro_x_idx, gyro_y_idx, gyro_z_idx) = (
|
||||
headers.iter().position(|x| { x == "x" }).unwrap(),
|
||||
headers.iter().position(|x| { x == "y" }).unwrap(),
|
||||
headers.iter().position(|x| { x == "z" }).unwrap(),
|
||||
);
|
||||
|
||||
let mut motion_output = File::create(motion_output).unwrap();
|
||||
let mut last_stamp = 0.0;
|
||||
for (accel_record, gyro_record) in accel_data.records().flatten().zip(gyro_data.records().flatten()) {
|
||||
let (timestamp, accel_x, accel_y, accel_z) = (
|
||||
accel_record.get(timestamp_idx).unwrap().parse().unwrap(),
|
||||
accel_record.get(accel_x_idx).unwrap().parse().unwrap(),
|
||||
accel_record.get(accel_y_idx).unwrap().parse().unwrap(),
|
||||
accel_record.get(accel_z_idx).unwrap().parse().unwrap()
|
||||
);
|
||||
let (gyro_x, gyro_y, gyro_z) = (
|
||||
gyro_record.get(gyro_x_idx).unwrap().parse().unwrap(),
|
||||
gyro_record.get(gyro_y_idx).unwrap().parse().unwrap(),
|
||||
gyro_record.get(gyro_z_idx).unwrap().parse().unwrap()
|
||||
);
|
||||
let next_delay = timestamp - last_stamp;
|
||||
if next_delay >= 0.02 {
|
||||
last_stamp = timestamp;
|
||||
rmp::encode::write_array_len(&mut motion_output, 7).unwrap();
|
||||
rmp::encode::write_f64(&mut motion_output, next_delay).unwrap();
|
||||
rmp::encode::write_f64(&mut motion_output, accel_x).unwrap();
|
||||
rmp::encode::write_f64(&mut motion_output, accel_y).unwrap();
|
||||
rmp::encode::write_f64(&mut motion_output, accel_z).unwrap();
|
||||
rmp::encode::write_f64(&mut motion_output, gyro_x).unwrap();
|
||||
rmp::encode::write_f64(&mut motion_output, gyro_y).unwrap();
|
||||
rmp::encode::write_f64(&mut motion_output, gyro_z).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn linker_be_nice() {
|
||||
|
||||
@@ -79,13 +79,8 @@ async fn main(spawner: Spawner) {
|
||||
#[allow(unused_variables)]
|
||||
let hi_spawn = hi_exec.start(esp_hal::interrupt::Priority::max());
|
||||
|
||||
#[cfg(not(feature="headless"))]
|
||||
{
|
||||
wdt.enable();
|
||||
hi_spawn.must_spawn(renderbug_embassy::tasks::render::render(peripherals.RMT, peripherals.GPIO5.degrade(), surfaces, safety_surfaces, garage.display.clone(), wdt));
|
||||
}
|
||||
#[cfg(feature="headless")]
|
||||
garage.display.notify_render_is_running(true);
|
||||
wdt.enable();
|
||||
hi_spawn.must_spawn(renderbug_embassy::tasks::render::render(peripherals.RMT, peripherals.GPIO5.degrade(), surfaces, safety_surfaces, garage.display.clone(), wdt));
|
||||
|
||||
#[cfg(feature="motion")]
|
||||
{
|
||||
|
||||
@@ -8,9 +8,11 @@ use figments_render::{
|
||||
gamma::{GammaCurve, WithGamma}, output::{Brightness, GammaCorrected, OutputAsync}, power::AsMilliwatts, smart_leds::PowerManagedWriterAsync
|
||||
};
|
||||
use smart_leds::SmartLedsWriteAsync;
|
||||
|
||||
pub const NUM_PIXELS: usize = 178;
|
||||
// FIXME: We need a way to specify a different buffer format from the 'native' hardware output, due to sometimes testing with GRB strips instead of RGB
|
||||
pub struct BikeOutput<T: SmartLedsWriteAsync> {
|
||||
pixbuf: [T::Color; 178],
|
||||
pixbuf: [T::Color; NUM_PIXELS],
|
||||
writer: PowerManagedWriterAsync<T>,
|
||||
controls: DisplayControls
|
||||
}
|
||||
@@ -24,18 +26,18 @@ impl<T:SmartLedsWriteAsync> GammaCorrected for BikeOutput<T> where T::Color: Pix
|
||||
impl<T: SmartLedsWriteAsync> BikeOutput<T> where T::Color: PixelBlend<Rgb<u8>> + PixelFormat + WithGamma + 'static, T::Error: core::fmt::Debug {
|
||||
pub fn new(target: T, max_mw: u32, controls: DisplayControls) -> Self {
|
||||
Self {
|
||||
pixbuf: [Default::default(); 178],
|
||||
pixbuf: [Default::default(); NUM_PIXELS],
|
||||
writer: PowerManagedWriterAsync::new(target, max_mw),
|
||||
controls
|
||||
}
|
||||
}
|
||||
|
||||
pub fn blank(&mut self) {
|
||||
self.pixbuf = [Default::default(); 178];
|
||||
self.pixbuf = [Default::default(); NUM_PIXELS];
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: SmartLedsWriteAsync + 'a> OutputAsync<'a, SegmentSpace> for BikeOutput<T> where T::Color: PixelBlend<Rgb<u8>> + Debug + 'static + AsMilliwatts + PixelFormat + WithGamma, [T::Color; 178]: AsMilliwatts + WithGamma + Copy, T::Error: core::fmt::Debug {
|
||||
impl<'a, T: SmartLedsWriteAsync + 'a> OutputAsync<'a, SegmentSpace> for BikeOutput<T> where T::Color: PixelBlend<Rgb<u8>> + Debug + 'static + AsMilliwatts + PixelFormat + WithGamma, [T::Color; NUM_PIXELS]: AsMilliwatts + WithGamma + Copy, T::Error: core::fmt::Debug {
|
||||
async fn commit_async(&mut self) -> Result<(), T::Error> {
|
||||
self.writer.controls().set_brightness(self.controls.brightness());
|
||||
self.writer.controls().set_on(self.controls.is_on());
|
||||
@@ -52,7 +54,7 @@ impl<'a, T: SmartLedsWriteAsync + 'a> OutputAsync<'a, SegmentSpace> for BikeOutp
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: SmartLedsWriteAsync> Sample<'a, SegmentSpace> for BikeOutput<T> where T::Color: Debug + PixelFormat + 'a, [T::Color; 178]: Sample<'a, SegmentSpace, Output = T::Color> {
|
||||
impl<'a, T: SmartLedsWriteAsync> Sample<'a, SegmentSpace> for BikeOutput<T> where T::Color: Debug + PixelFormat + 'a, [T::Color; NUM_PIXELS]: Sample<'a, SegmentSpace, Output = T::Color> {
|
||||
type Output = T::Color;
|
||||
|
||||
fn sample(&mut self, rect: &Rectangle<SegmentSpace>) -> impl Iterator<Item = (Coordinates<SegmentSpace>, &'a mut T::Color)> {
|
||||
@@ -74,12 +76,12 @@ pub struct Segment {
|
||||
length: usize,
|
||||
}
|
||||
|
||||
impl<'a, T: PixelFormat> Sample<'a, SegmentSpace> for [T; 178] where T: 'static {
|
||||
impl<'a, T: PixelFormat> Sample<'a, SegmentSpace> for [T; NUM_PIXELS] where T: 'static {
|
||||
type Output = T;
|
||||
|
||||
fn sample(&mut self, rect: &Rectangle<SegmentSpace>) -> impl Iterator<Item = (Coordinates<SegmentSpace>, &'a mut Self::Output)> {
|
||||
let bufref = unsafe {
|
||||
&mut *(self as *mut [T; 178])
|
||||
&mut *(self as *mut [T; NUM_PIXELS])
|
||||
};
|
||||
SegmentIter {
|
||||
pixbuf: bufref,
|
||||
@@ -97,7 +99,7 @@ impl CoordinateSpace for SegmentSpace {
|
||||
}
|
||||
|
||||
pub struct SegmentIter<'a, Format: PixelFormat> {
|
||||
pixbuf: &'a mut [Format; 178],
|
||||
pixbuf: &'a mut [Format; NUM_PIXELS],
|
||||
cur: Coordinates<SegmentSpace>,
|
||||
end: Coordinates<SegmentSpace>,
|
||||
}
|
||||
@@ -129,7 +131,7 @@ impl<'a, Format: PixelFormat> Iterator for SegmentIter<'a, Format> {
|
||||
}
|
||||
|
||||
let bufref = unsafe {
|
||||
&mut *(self.pixbuf as *mut [Format; 178])
|
||||
&mut *(self.pixbuf as *mut [Format; NUM_PIXELS])
|
||||
};
|
||||
|
||||
Some((pixel_coords, &mut bufref[offset]))
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use embassy_sync::{channel::DynamicSender, pubsub::DynPublisher};
|
||||
use embassy_time::{Duration, Instant};
|
||||
use nalgebra::{Rotation3, Vector2, Vector3};
|
||||
use nalgebra::{Rotation3, Vector2, Vector3, ComplexField, RealField};
|
||||
use log::*;
|
||||
//use micromath::F32Ext;
|
||||
use nalgebra::{ComplexField, RealField};
|
||||
|
||||
use core::fmt::Debug;
|
||||
|
||||
|
||||
@@ -2,14 +2,20 @@
|
||||
pub mod mpu;
|
||||
#[cfg(feature="gps")]
|
||||
pub mod gps;
|
||||
pub mod render;
|
||||
pub mod motion;
|
||||
pub mod ui;
|
||||
#[cfg(feature="radio")]
|
||||
pub mod wifi;
|
||||
#[cfg(feature="simulation")]
|
||||
pub mod simulation;
|
||||
pub mod predict;
|
||||
#[cfg(feature="demo")]
|
||||
pub mod demo;
|
||||
#[cfg(feature="oled")]
|
||||
pub mod oled;
|
||||
|
||||
// Prediction engines
|
||||
pub mod predict;
|
||||
pub mod motion;
|
||||
|
||||
// Graphics stack
|
||||
pub mod ui;
|
||||
pub mod safetyui;
|
||||
pub mod oled;
|
||||
pub mod render;
|
||||
@@ -1,25 +1,23 @@
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
use esp_hal::{gpio::AnyPin, rmt::Rmt, time::Rate, timer::timg::Wdt};
|
||||
use esp_hal_smartled::{buffer_size_async, SmartLedsAdapterAsync};
|
||||
use figments::{prelude::*, surface::{BufferedSurfacePool, Surfaces}};
|
||||
use figments::{prelude::*, surface::Surfaces};
|
||||
use figments_render::gamma::GammaCurve;
|
||||
use figments_render::output::{GammaCorrected, OutputAsync};
|
||||
use log::{info, warn};
|
||||
use rgb::Rgba;
|
||||
use nalgebra::ComplexField;
|
||||
use micromath::F32Ext;
|
||||
|
||||
use crate::display::{BikeOutput, DisplayControls, SegmentSpace, Uniforms};
|
||||
|
||||
//TODO: Import the bike surfaces from renderbug-prime, somehow make those surfaces into tasks
|
||||
use crate::display::NUM_PIXELS;
|
||||
use crate::{display::{BikeOutput, DisplayControls, Uniforms}, tasks::ui::UiSurfacePool};
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn render(rmt: esp_hal::peripherals::RMT<'static>, gpio: AnyPin<'static>, surfaces: BufferedSurfacePool<Uniforms, SegmentSpace, Rgba<u8>>, safety_surfaces: BufferedSurfacePool<Uniforms, SegmentSpace, Rgba<u8>>, mut controls: DisplayControls, mut wdt: Wdt<esp_hal::peripherals::TIMG0<'static>>) {
|
||||
pub async fn render(rmt: esp_hal::peripherals::RMT<'static>, gpio: AnyPin<'static>, surfaces: UiSurfacePool, safety_surfaces: UiSurfacePool, mut controls: DisplayControls, mut wdt: Wdt<esp_hal::peripherals::TIMG0<'static>>) {
|
||||
let frequency: Rate = Rate::from_mhz(80);
|
||||
let rmt = Rmt::new(rmt, frequency)
|
||||
.expect("Failed to initialize RMT").into_async();
|
||||
let rmt_channel = rmt.channel0;
|
||||
|
||||
let rmt_buffer = [0u32; buffer_size_async(178)];
|
||||
let rmt_buffer = [0u32; buffer_size_async(NUM_PIXELS)];
|
||||
|
||||
//let target = SmartLedsAdapterAsync::new(rmt_channel, gpio, rmt_buffer);
|
||||
let target = SmartLedsAdapterAsync::new(rmt_channel, gpio, rmt_buffer);
|
||||
@@ -40,8 +38,6 @@ pub async fn render(rmt: esp_hal::peripherals::RMT<'static>, gpio: AnyPin<'stati
|
||||
|
||||
let mut output = BikeOutput::new(target, MAX_POWER_MW, controls.clone());
|
||||
output.set_gamma(GammaCurve::new(1.3));
|
||||
//#[cfg(not(feature="wokwi"))]
|
||||
//output.set_gamma(GammaCurve::new(2.1));
|
||||
|
||||
info!("Rendering started! {}ms since boot", Instant::now().as_millis());
|
||||
controls.notify_render_is_running(true);
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::Breaker;
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn motion_simulation_task(events: DynamicSender<'static, Measurement>) {
|
||||
let mut rd = rmp::decode::Bytes::new(include_bytes!("../../test-data/motion.msgpack"));
|
||||
let mut rd = rmp::decode::Bytes::new(include_bytes!("../../target/motion_test_data.msgpack"));
|
||||
let mut runtime_secs = Breaker::default();
|
||||
let mut runtime = Duration::default();
|
||||
events.send(Measurement::SensorOnline(SensorSource::IMU)).await;
|
||||
@@ -39,7 +39,7 @@ pub async fn motion_simulation_task(events: DynamicSender<'static, Measurement>)
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn location_simulation_task(events: DynamicSender<'static, Measurement>) {
|
||||
let mut rd = rmp::decode::Bytes::new(include_bytes!("../../test-data/gps.msgpack"));
|
||||
let mut rd = rmp::decode::Bytes::new(include_bytes!("../../target/gps_test_data.msgpack"));
|
||||
let mut runtime_secs = Breaker::default();
|
||||
let mut runtime = Duration::default();
|
||||
events.send(Measurement::SensorOnline(SensorSource::GPS)).await;
|
||||
|
||||
@@ -200,9 +200,9 @@ impl<S: Debug + Surface<Uniforms = Uniforms, CoordinateSpace = SegmentSpace, Pix
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="headless")]
|
||||
#[cfg(not(feature="real-output"))]
|
||||
pub type UiSurfacePool = NullBufferPool<NullSurface<Uniforms, SegmentSpace, Rgba<u8>>>;
|
||||
#[cfg(not(feature="headless"))]
|
||||
#[cfg(feature="real-output")]
|
||||
pub type UiSurfacePool = BufferedSurfacePool<Uniforms, SegmentSpace, Rgba<u8>>;
|
||||
|
||||
#[embassy_executor::task]
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,39 +0,0 @@
|
||||
import click
|
||||
import csv
|
||||
import umsgpack
|
||||
|
||||
@click.command
|
||||
@click.argument('gps-data', type=click.File('r'))
|
||||
@click.argument('accelerometer-data', type=click.File('r'))
|
||||
@click.argument('gyro-data', type=click.File('r'))
|
||||
@click.argument('gps-output', type=click.File('wb'))
|
||||
@click.argument('motion-output', type=click.File('wb'))
|
||||
def main(gps_data, accelerometer_data, gyro_data, gps_output, motion_output):
|
||||
gps_reader = csv.DictReader(gps_data)
|
||||
last_stamp = 0
|
||||
for row in gps_reader:
|
||||
next_delay = float(row['seconds_elapsed']) - last_stamp
|
||||
# We only one one update per second, to cut down on size
|
||||
if next_delay < 1:
|
||||
continue
|
||||
last_stamp = float(row['seconds_elapsed'])
|
||||
umsgpack.pack([float(next_delay), float(row['latitude']), float(row['longitude'])], gps_output)
|
||||
|
||||
accel_reader = csv.DictReader(accelerometer_data)
|
||||
gyro_reader = csv.DictReader(gyro_data)
|
||||
#motion_writer = csv.writer(motion_output, SampleDataDialect)
|
||||
last_stamp = 0
|
||||
for (accel_row, gyro_row) in zip(accel_reader, gyro_reader):
|
||||
next_delay = float(accel_row['seconds_elapsed']) - last_stamp
|
||||
# Only one update every 100ms, to cut down on size
|
||||
if next_delay < 0.02:
|
||||
continue
|
||||
last_stamp = float(accel_row['seconds_elapsed'])
|
||||
umsgpack.pack([
|
||||
next_delay,
|
||||
float(accel_row['x']), float(accel_row['y']), float(accel_row['z']),
|
||||
float(gyro_row['x']), float(gyro_row['y']), float(gyro_row['z'])
|
||||
], motion_output)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user