From 6947396234ecc4dfab85e4848704c2c7db17669c Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Fri, 31 Oct 2025 15:31:49 +0100 Subject: [PATCH] protobuf instaed of json --- Cargo.lock | 80 ++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 6 ++++ src/main.rs | 47 +++++++++++++++++++-------- src/trap/tracks.rs | 64 ++++++++++++++++++++++++++++++++++++- 4 files changed, 182 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 429df6e..76e0e48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,6 +221,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + [[package]] name = "approx" version = "0.3.2" @@ -3429,6 +3435,9 @@ dependencies = [ "nannou", "nannou_egui", "nannou_laser", + "prost", + "prost-build", + "prost-types", "serde", "serde_json", "serde_repr", @@ -3841,6 +3850,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + [[package]] name = "naga" version = "0.13.0" @@ -5015,6 +5030,58 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +[[package]] +name = "prost" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" +dependencies = [ + "heck", + "itertools 0.13.0", + "log", + "multimap", + "once_cell", + "petgraph 0.6.5", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.101", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" +dependencies = [ + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "prost-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72" +dependencies = [ + "prost", +] + [[package]] name = "quick-xml" version = "0.37.5" @@ -5897,6 +5964,19 @@ version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.0.7", + "windows-sys 0.59.0", +] + [[package]] name = "termcolor" version = "1.4.1" diff --git a/Cargo.toml b/Cargo.toml index f00332d..8dd706d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,9 @@ homography = { git = "https://github.com/azazdeaz/homography" } nalgebra = "0.30.0" cv-core = "0.15.0" geo = "0.30.0" +prost = "0.14.1" +prost-types = "0.14.1" +prost-build = "0.14.1" [dev-dependencies] @@ -39,3 +42,6 @@ opt-level = 3 [[bin]] name="laserspace" path="src/main.rs" + +[build-dependencies] +prost-build = "0.14.1" diff --git a/src/main.rs b/src/main.rs index c12ffbc..2cc2618 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,9 +14,10 @@ use nannou_laser::{self as laser}; use serde_json::Result; use laserspace::trap::filters::{MappedPoint, PointFilters}; use laserspace::trap::laser::{shape_rect, LaserPoints, LaserSpace, StreamSource, STREAM_SOURCES, TMP_DESK_CLUBMAX, Corner}; -use laserspace::trap::tracks::{CoordinateSpace, RenderableLayers}; +use laserspace::trap::tracks::{CoordinateSpace, RenderableLayers, renderable}; use laserspace::trap::utils::{closest_edge, split_on_blank}; use laserspace::trap::{laser::{python_cv_h_into_mat3, LaserModel, TMP_PYTHON_LASER_H, DacConfig}, tracks::{RenderableLines}}; +use prost::Message; use zmq::Socket; use std::sync::{mpsc, Arc}; use std::time::{Instant, Duration}; @@ -158,23 +159,41 @@ fn zmq_receive(model: &mut GuiModel) { let layers: RenderableLayers; if items[0].is_readable() { - let json = subscriber.recv_string(0).unwrap().unwrap(); - // dbg!(&json[4..]); + let message = subscriber.recv_bytes(0).unwrap(); - // let msg: Frame = serde_json::from_str(&json[4..]).expect("No valid json?"); - let res: Result = serde_json::from_str(&json); + // Deserialize using prost + layers = match renderable::RenderableLayers::decode(&*message) { + Ok(protobuf_layers) => { + // println!("Received layers: {:?}", layers.layers); + RenderableLayers::from(protobuf_layers) + } + Err(e) => { + eprintln!("Failed to decode protobuf: {:?}", e); + RenderableLayers::new() + } + }; + + // let protobuf_layers: renderable::RenderableLayers = renderable::RenderableLayers::from(message); + + // Deserialize using prost's From trait + + + // let json = subscriber.recv_string(0).unwrap().unwrap(); + // // dbg!(&json[4..]); + + // let res: Result = serde_json::from_str(&json); model.lost_alpha = 1.; model.connected = true; - layers = match res { - Ok(layers) => layers, // if Ok(255), set x to 255 - Err(_e) => { - println!("No valid json?"); - println!("{}", _e); - // empty if invalid - RenderableLayers::new() - }, // if Err("some message"), panic with error message "some message" - }; + // layers = match res { + // Ok(layers) => layers, // if Ok(255), set x to 255 + // Err(_e) => { + // println!("No valid json?"); + // println!("{}", _e); + // // empty if invalid + // RenderableLayers::new() + // }, // if Err("some message"), panic with error message "some message" + // }; } else if model.last_update < Instant::now() - Duration::from_millis(100){ // set lines empty, if no new input for > 100ms (10fps) model.connected = false; diff --git a/src/trap/tracks.rs b/src/trap/tracks.rs index 363252d..f8403a1 100644 --- a/src/trap/tracks.rs +++ b/src/trap/tracks.rs @@ -1,11 +1,22 @@ -use bevy::prelude::*; +use bevy::{prelude::*, render}; use serde::{Serialize,Deserialize}; use std::time::Instant; use nannou_laser as laser; use serde_repr::*; + +// use renderable; + + + use crate::trap::laser::LaserPoints; +// Assuming generated protobuf code is in renderable.rs +pub mod renderable { + include!(concat!(env!("OUT_DIR"), "/renderable.rs")); +} + + #[derive(Serialize,Deserialize)] pub struct Frame { pub tracks: std::collections::HashMap @@ -250,3 +261,54 @@ impl From for TrackBundle{ pub struct Trajectory { pub points: Vec, } + + + +// Implement From trait for deserialization +impl From for RenderableLayers { + fn from(protobuf_message: renderable::RenderableLayers) -> Self { + let mut layers_map = std::collections::HashMap::new(); + + for (key, protobuf_lines) in protobuf_message.layers { + + let mut lines = Vec::new(); + for pb_line in protobuf_lines.lines { // Use .points instead of .lines + let mut line = Vec::new(); + for protobuf_point in pb_line.points { // Use .points instead of .lines + let point = RenderablePoint { + position: Vec2 { + x: protobuf_point.position.unwrap().x, + y: protobuf_point.position.unwrap().y, + }, + color: Srgba { + red: protobuf_point.color.unwrap().red, + green: protobuf_point.color.unwrap().green, + blue: protobuf_point.color.unwrap().blue, + alpha: protobuf_point.color.unwrap().alpha, + }, + }; + line.push(point); + } + lines.push(RenderableLine{ + points: line + }); + } + let lines_object = RenderableLines { + lines, + space: match protobuf_lines.space { + 0 => CoordinateSpace::Image, + 1 => CoordinateSpace::Image, + 2 => CoordinateSpace::UndistortedImage, + 3 => CoordinateSpace::World, + 4 => CoordinateSpace::Laser, + 8 => CoordinateSpace::RawLaser, + _ => CoordinateSpace::RawLaser, + // renderable::CoordinateSpace::RawLaser => CoordinateSpace::RawLaser, + }, + }; + layers_map.insert(key as u8, lines_object); + } + + RenderableLayers(layers_map) + } +} \ No newline at end of file