From ce86a1cecb0b21f4e934dfb66a979c6cd0c10d91 Mon Sep 17 00:00:00 2001 From: alban Date: Thu, 29 Jun 2023 22:36:00 +0200 Subject: [PATCH 01/12] wip: add worldstate --- src/main.rs | 65 ++++++++++++++++++++++++++++++++++++----------- src/redis_ctrl.rs | 13 ++++++++++ src/worldstate.rs | 23 +++++++++++++++++ 3 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 src/worldstate.rs diff --git a/src/main.rs b/src/main.rs index 2cf7953..874ae54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ mod errors; mod point; mod transformer; mod device; +mod worldstate; use device::device_factory; use std::sync::atomic::{AtomicBool, Ordering}; @@ -15,10 +16,11 @@ use std::sync::Arc; use redis_ctrl::{RedisCtrl, Order}; use conf::Conf; use errors::LJResult; -use point::Point; +use point::{Point, Color}; use transformer::Transformers; use log::{LevelFilter, info, /* warn, */ error}; use env_logger::Builder; +use worldstate::WorldState; const DEFAULT_CONF_FILE: &str = "settings.toml"; @@ -31,6 +33,7 @@ pub fn main() { } } + fn run_all() -> LJResult<()> { // Setup configuration file and set up logs let filename = std::env::args().nth(1).unwrap_or_else(|| { @@ -47,6 +50,8 @@ fn run_all() -> LJResult<()> { // Setup Redis Service let mut rs = RedisCtrl::new(&config.redis_url, &config.laser_id)?; + let mut world_state = rs.init_world_state(); + // Setup handler for interrupt Signals let running = Arc::new(AtomicBool::new(true)); let r = running.clone(); @@ -61,20 +66,49 @@ fn run_all() -> LJResult<()> { //dbg!(tracer); // Setup geometry transformers on points lists - let transformers = config.get_transformers(); + let transformers = config.get_transformers(); // Dispatch based on redis requests while running.load(Ordering::SeqCst) { - rs.set_status( tracer.status())?; - let order = rs.get_order(config.laser_id)?; - if order != Order::Draw { - info!("Order: {:?}", order); - } + rs.set_status(tracer.status())?; - let frame = get_next_frame(&config, &transformers, - &mut rs, order == Order::Black)?; - // For now, draw all the time - tracer.draw(frame, 2_000)?; + let order = rs.get_order(config.laser_id)?; + // 0 : Draw Normal point list + // 2 : Draw BLACK point list + // 3 : Draw GRID point list + + // /worldstate.rs + // /edh.rs + + // 1 : Get the new EDH = reread redis key /EDH/lasernumber + // 4 : Resampler Change (longs and shorts lsteps) + // 5 : Client Key Change = reread redis key /clientkey + // 6 : Max Intensity Change = reread redis key /intensity + // 7 : kpps change = reread redis key /kpps + // 8 : color balance change = reread redis keys /red /green /blue + + match order { + Order::Draw => { + let frame = get_next_frame( + &config, + &transformers, + &mut rs, + // order == Order::Black, + &world_state + )?; + // For now, draw all the time + tracer.draw(frame, 2_000)?; + } + Order::Edh => { + let world_state.edh = rs.get_edh(), + } + + // Order::ClientKey => rs.client_key(), + // Order::ColorBalance => {}, + _ => { + info!("Order: {:?}", order); + } + } } info!("Exiting, stoping device."); @@ -101,17 +135,18 @@ fn get_next_frame( config: &Conf, transformers: &[Box], rs: &mut RedisCtrl, - _black: bool, + world_state : &WorldState ) -> LJResult> { let line = rs.get(&format!("/pl/{}/0", config.laser_id))?; let mut line: Vec = line.into_iter() - .map(|tpl| tpl.into()) - .collect(); + .map(|tpl| tpl.into()) + .collect(); for transformer in transformers { - line = transformer.apply(&line); + line = transformer.apply(&line, world_state); } //info!("Line: {:?}", line); Ok(line) } + diff --git a/src/redis_ctrl.rs b/src/redis_ctrl.rs index 448ed43..cbffc7c 100644 --- a/src/redis_ctrl.rs +++ b/src/redis_ctrl.rs @@ -2,6 +2,7 @@ use redis::{Client, Commands, Connection}; use ron::de::from_str; use crate::device::Status; use crate::errors::{LJError, LJResult}; +use crate::worldstate::{WorldState}; #[repr(u8)] #[derive(Debug, PartialEq)] @@ -96,4 +97,16 @@ impl RedisCtrl { self.set(lack_key, status.lack.to_string())?; Ok(()) } + + pub fn init_world_state( &mut self) -> LJResult{ + WorldState + } + + pub fn get_edh( &mut self ) -> LJResult<()> { + + // Get new EDH + let edh = self.get("/EDH/1"); + EDH( edh ) + + } } diff --git a/src/worldstate.rs b/src/worldstate.rs new file mode 100644 index 0000000..097b19b --- /dev/null +++ b/src/worldstate.rs @@ -0,0 +1,23 @@ + + +pub struct EDH { + pub matrix: Matrix3 +} + +#[derive(Debug, Default )] +impl EDH { + +} + +pub struct WorldState { + pub edh: EDH, + pub resampler: Vec, + pub client_key: u8, + pub intensity: u8, + pub kpps: u32, + pub color: Color +} + +impl WorldState{ + +} From f307fea63c6cc5274a23dfeab33fe64c64cf05e4 Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Thu, 29 Jun 2023 23:24:56 +0200 Subject: [PATCH 02/12] fix code + dummy dac --- copyme.settings.toml | 3 +++ src/conf.rs | 2 ++ src/device.rs | 9 +++++--- src/device/dummy.rs | 36 ++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 6 ++--- src/point.rs | 4 ++-- src/redis_ctrl.rs | 15 ++++++------- src/transformer.rs | 7 +++++- src/transformer/flip_horizontal.rs | 4 +++- src/transformer/flip_vertical.rs | 4 +++- src/transformer/grid.rs | 4 +++- src/transformer/replicate.rs | 4 +++- src/transformer/rotate.rs | 4 +++- src/transformer/translate.rs | 3 ++- src/worldstate.rs | 8 ++++--- 16 files changed, 88 insertions(+), 26 deletions(-) create mode 100644 src/device/dummy.rs diff --git a/copyme.settings.toml b/copyme.settings.toml index f440bc0..5f9eaff 100644 --- a/copyme.settings.toml +++ b/copyme.settings.toml @@ -15,6 +15,9 @@ redis_url = "redis://127.0.0.1:6379/" [dac.helios] id = 0 +# For dummy dac: +# [dac.dummy] + # For Etherdream. IP of the DAC # [dac.etherdream] # url = "192.168.1.68" diff --git a/src/conf.rs b/src/conf.rs index 01827c3..1cc1b3e 100644 --- a/src/conf.rs +++ b/src/conf.rs @@ -19,6 +19,8 @@ pub enum DacFamily { Helios(HeliosConf), #[serde(rename = "etherdream")] Etherdream(EtherDreamConf), + #[serde(rename = "dummy")] + Dummy, } #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/src/device.rs b/src/device.rs index 0947bf2..c97276c 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,9 +1,11 @@ mod helios; +mod dummy; use std::fmt; use crate::conf::{Conf, DacFamily /*EtherDreamConf, HeliosConf*/}; use crate::device::helios::HeliosDevice; +use crate::device::dummy::DummyDevice; use crate::errors::LJResult; use crate::point::Point; use serde::Serialize; @@ -57,9 +59,10 @@ pub trait Device { } pub fn device_factory(config: &Conf) -> LJResult> { - let device = match &config.dac { - DacFamily::Helios(conf) => Box::new(HeliosDevice::new(conf)?), - DacFamily::Etherdream(_conf) => todo!(), + let device : Box = match &config.dac { + DacFamily::Helios(conf) => Box::new(HeliosDevice::new(conf)?), + DacFamily::Etherdream(_conf) => todo!(), + DacFamily::Dummy => Box::new(DummyDevice::new()?) }; Ok(device) } diff --git a/src/device/dummy.rs b/src/device/dummy.rs new file mode 100644 index 0000000..8a9ed9b --- /dev/null +++ b/src/device/dummy.rs @@ -0,0 +1,36 @@ +use crate::device::{Device, Status, PlaybackState}; +use crate::errors::{LJError, LJResult}; +use crate::point::Point; + +pub struct DummyDevice { + state: PlaybackState +} + +impl DummyDevice { + pub fn new() -> LJResult { + Ok(Self { state: PlaybackState::IDLE }) + } +} + +impl Device for DummyDevice { + fn status(&self) -> Status { + Status { + last_traced_at: "never".to_string(), + properties: vec!["foo".to_string()], + playback_state: self.state, + capacity: 0, + lack: "lack".to_string() + } + } + + fn draw(&mut self, + line: Vec, + speed: u32, + ) -> LJResult<()> { + Ok(()) + } + + fn stop(&mut self) -> LJResult<()> { + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index b183c49..9048f40 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,3 +4,4 @@ pub mod errors; pub mod device; pub mod point; pub mod transformer; +pub mod worldstate; diff --git a/src/main.rs b/src/main.rs index 874ae54..6a1103b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use std::sync::Arc; use redis_ctrl::{RedisCtrl, Order}; use conf::Conf; use errors::LJResult; -use point::{Point, Color}; +use point::Point; use transformer::Transformers; use log::{LevelFilter, info, /* warn, */ error}; use env_logger::Builder; @@ -50,7 +50,7 @@ fn run_all() -> LJResult<()> { // Setup Redis Service let mut rs = RedisCtrl::new(&config.redis_url, &config.laser_id)?; - let mut world_state = rs.init_world_state(); + let mut world_state = rs.init_world_state()?; // Setup handler for interrupt Signals let running = Arc::new(AtomicBool::new(true)); @@ -100,7 +100,7 @@ fn run_all() -> LJResult<()> { tracer.draw(frame, 2_000)?; } Order::Edh => { - let world_state.edh = rs.get_edh(), + world_state.edh = rs.get_edh()?; } // Order::ClientKey => rs.client_key(), diff --git a/src/point.rs b/src/point.rs index 1d43bfe..44fa9b4 100644 --- a/src/point.rs +++ b/src/point.rs @@ -1,11 +1,11 @@ -#[derive(Debug,Clone,Copy)] +#[derive(Debug,Clone,Copy,Default)] pub struct Point { pub x: f32, pub y: f32, pub color: Color } -#[derive(Debug,Clone,Copy)] +#[derive(Debug,Clone,Copy,Default)] pub struct Color { r: u8, g: u8, diff --git a/src/redis_ctrl.rs b/src/redis_ctrl.rs index cbffc7c..b78af9e 100644 --- a/src/redis_ctrl.rs +++ b/src/redis_ctrl.rs @@ -2,7 +2,7 @@ use redis::{Client, Commands, Connection}; use ron::de::from_str; use crate::device::Status; use crate::errors::{LJError, LJResult}; -use crate::worldstate::{WorldState}; +use crate::worldstate::{WorldState,EDH}; #[repr(u8)] #[derive(Debug, PartialEq)] @@ -99,14 +99,13 @@ impl RedisCtrl { } pub fn init_world_state( &mut self) -> LJResult{ - WorldState + Ok(WorldState::default()) } - pub fn get_edh( &mut self ) -> LJResult<()> { - - // Get new EDH - let edh = self.get("/EDH/1"); - EDH( edh ) - + pub fn get_edh( &mut self ) -> LJResult { + // Get new EDH + let edh : String = self.connection.get("/EDH/0")?; + let edh : Vec> = from_str(&edh)?; + Ok(EDH { matrix: edh }) } } diff --git a/src/transformer.rs b/src/transformer.rs index 19d4445..6132658 100644 --- a/src/transformer.rs +++ b/src/transformer.rs @@ -7,6 +7,7 @@ mod flip_vertical; mod grid; use crate::point::Point; +use crate::worldstate::WorldState; // re-export transformers to be abe to use it directly from transformer:: pub use translate::Translate; @@ -17,5 +18,9 @@ pub use flip_vertical::FlipVertical; pub use grid::Grid; pub trait Transformers { - fn apply(&self, point_list: &[Point]) -> Vec; + fn apply( + &self, + point_list: &[Point], + world_state: &WorldState + ) -> Vec; } diff --git a/src/transformer/flip_horizontal.rs b/src/transformer/flip_horizontal.rs index d156739..ed9cec3 100644 --- a/src/transformer/flip_horizontal.rs +++ b/src/transformer/flip_horizontal.rs @@ -1,5 +1,7 @@ use crate::transformer::Transformers; use crate::point::Point; +use crate::worldstate::WorldState; + use serde::{Serialize,Deserialize}; /// Flip Horizontal @@ -10,7 +12,7 @@ pub struct FlipHorizontal { } impl Transformers for FlipHorizontal { - fn apply(&self, point_list: &[Point]) -> Vec { + fn apply(&self, point_list: &[Point], _ws: &WorldState) -> Vec { point_list.iter() .map(| pt | { let dx = pt.x - self.x; diff --git a/src/transformer/flip_vertical.rs b/src/transformer/flip_vertical.rs index fc741c7..19529e8 100644 --- a/src/transformer/flip_vertical.rs +++ b/src/transformer/flip_vertical.rs @@ -1,5 +1,7 @@ use crate::transformer::Transformers; use crate::point::Point; +use crate::worldstate::WorldState; + use serde::{Serialize,Deserialize}; /// Flip Vertical @@ -10,7 +12,7 @@ pub struct FlipVertical { } impl Transformers for FlipVertical { - fn apply(&self, point_list: &[Point]) -> Vec { + fn apply(&self, point_list: &[Point], _ws: &WorldState) -> Vec { point_list.iter() .map(| pt | { let dy = pt.y - self.y; diff --git a/src/transformer/grid.rs b/src/transformer/grid.rs index 25258ff..7a9d37b 100644 --- a/src/transformer/grid.rs +++ b/src/transformer/grid.rs @@ -1,5 +1,7 @@ use crate::transformer::Transformers; use crate::point::Point; +use crate::worldstate::WorldState; + use serde::{Serialize,Deserialize}; /// Translate @@ -44,7 +46,7 @@ fn square_box(size: f32, color: u32) -> Vec<(f32, f32, u32)> { } impl Transformers for Grid { - fn apply(&self, _point_list: &[Point]) -> Vec { + fn apply(&self, _point_list: &[Point], _ws: &WorldState) -> Vec { let mut sq1 = square_box(1000.0, 255 << 8); let mut line = square_box(2000.0, 255); line.append(&mut sq1); diff --git a/src/transformer/replicate.rs b/src/transformer/replicate.rs index 99258ae..a5e5ab2 100644 --- a/src/transformer/replicate.rs +++ b/src/transformer/replicate.rs @@ -1,5 +1,7 @@ use crate::transformer::Transformers; use crate::point::Point; +use crate::worldstate::WorldState; + use serde::{Serialize,Deserialize}; /// Replicate @@ -12,7 +14,7 @@ pub enum Replicate { } impl Transformers for Replicate { - fn apply(&self, point_list: &[Point]) -> Vec { + fn apply(&self, point_list: &[Point], _ws: &WorldState) -> Vec { let mut point_list2 = vec![]; match self { Replicate::Until(n) => { diff --git a/src/transformer/rotate.rs b/src/transformer/rotate.rs index 60fc109..0dac920 100644 --- a/src/transformer/rotate.rs +++ b/src/transformer/rotate.rs @@ -1,5 +1,7 @@ use crate::transformer::Transformers; use crate::point::Point; +use crate::worldstate::WorldState; + use serde::{Serialize,Deserialize}; //use std::f32::consts::PI; @@ -14,7 +16,7 @@ pub struct Rotate { } impl Transformers for Rotate { - fn apply(&self, point_list: &[Point]) -> Vec { + fn apply(&self, point_list: &[Point], _ws: &WorldState) -> Vec { point_list.iter() .map(| pt | { let dx = pt.x - self.cx; diff --git a/src/transformer/translate.rs b/src/transformer/translate.rs index c3f4fec..a0262a1 100644 --- a/src/transformer/translate.rs +++ b/src/transformer/translate.rs @@ -1,5 +1,6 @@ use crate::transformer::Transformers; use crate::point::Point; +use crate::worldstate::WorldState; use serde::{Serialize,Deserialize}; /// Translate @@ -11,7 +12,7 @@ pub struct Translate { } impl Transformers for Translate { - fn apply(&self, point_list: &[Point]) -> Vec { + fn apply(&self, point_list: &[Point], _ws: &WorldState) -> Vec { point_list.iter() .map(| pt | { Point { x: pt.x + self.x, diff --git a/src/worldstate.rs b/src/worldstate.rs index 097b19b..41eeef7 100644 --- a/src/worldstate.rs +++ b/src/worldstate.rs @@ -1,14 +1,16 @@ +use crate::point::Color; - +#[derive(Debug, Default)] pub struct EDH { - pub matrix: Matrix3 + pub matrix: Vec> //Matrix3 } -#[derive(Debug, Default )] + impl EDH { } +#[derive(Debug, Default)] pub struct WorldState { pub edh: EDH, pub resampler: Vec, From 63c700f12de4251da84e3f7beaf60e716ed6b3f5 Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Thu, 29 Jun 2023 23:27:54 +0200 Subject: [PATCH 03/12] get edh --- src/redis_ctrl.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/redis_ctrl.rs b/src/redis_ctrl.rs index b78af9e..e7e80fa 100644 --- a/src/redis_ctrl.rs +++ b/src/redis_ctrl.rs @@ -3,6 +3,7 @@ use ron::de::from_str; use crate::device::Status; use crate::errors::{LJError, LJResult}; use crate::worldstate::{WorldState,EDH}; +use log::info; #[repr(u8)] #[derive(Debug, PartialEq)] @@ -99,7 +100,13 @@ impl RedisCtrl { } pub fn init_world_state( &mut self) -> LJResult{ - Ok(WorldState::default()) + let edh = self.get_edh()?; + info!("EDH: {:?}", edh); + + Ok(WorldState { + edh, + ..WorldState::default() + }) } pub fn get_edh( &mut self ) -> LJResult { From 5470a9b78acad755e63301d3a1840f3b7a627ecd Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Sat, 1 Jul 2023 14:34:30 +0200 Subject: [PATCH 04/12] add homography crate, use Matrix3 to store EDH --- Cargo.toml | 3 +++ src/device/dummy.rs | 6 ++++-- src/redis_ctrl.rs | 3 ++- src/worldstate.rs | 14 ++++++++++---- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9789221..65d03bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,11 @@ config = "0.13.3" ctrlc = "3.4.0" env_logger = "0.10.0" helios-dac = { version = "0.1", default-features = false, features = ["native"] } + log = "0.4.18" redis = "0.23.0" ron = "0.8.0" serde = { version = "1.0.163", features = ["derive"] } toml = "0.7.4" +homography = { git = "https://github.com/azazdeaz/homography" } +nalgebra = "0.32.2" diff --git a/src/device/dummy.rs b/src/device/dummy.rs index 8a9ed9b..e4c9e42 100644 --- a/src/device/dummy.rs +++ b/src/device/dummy.rs @@ -1,6 +1,7 @@ use crate::device::{Device, Status, PlaybackState}; -use crate::errors::{LJError, LJResult}; +use crate::errors::LJResult; use crate::point::Point; +use log::debug; pub struct DummyDevice { state: PlaybackState @@ -27,7 +28,8 @@ impl Device for DummyDevice { line: Vec, speed: u32, ) -> LJResult<()> { - Ok(()) + debug!("Draw Line at speed {speed} : {:?}", line); + Ok(()) } fn stop(&mut self) -> LJResult<()> { diff --git a/src/redis_ctrl.rs b/src/redis_ctrl.rs index e7e80fa..ee2efe7 100644 --- a/src/redis_ctrl.rs +++ b/src/redis_ctrl.rs @@ -113,6 +113,7 @@ impl RedisCtrl { // Get new EDH let edh : String = self.connection.get("/EDH/0")?; let edh : Vec> = from_str(&edh)?; - Ok(EDH { matrix: edh }) + let edh = EDH::new(edh)?; + Ok(edh) } } diff --git a/src/worldstate.rs b/src/worldstate.rs index 41eeef7..38b1bd0 100644 --- a/src/worldstate.rs +++ b/src/worldstate.rs @@ -1,13 +1,19 @@ use crate::point::Color; - +use nalgebra::base::Matrix3; +use crate::errors::LJResult; #[derive(Debug, Default)] pub struct EDH { - pub matrix: Vec> //Matrix3 + pub matrix: Matrix3 } impl EDH { - + pub fn new(vec: Vec>) -> LJResult { + let matrix = Matrix3::new(vec[0][0], vec[0][1], vec[0][2], + vec[1][0], vec[1][1], vec[1][2], + vec[2][0], vec[2][1], vec[2][2]); + Ok(EDH { matrix }) + } } #[derive(Debug, Default)] @@ -20,6 +26,6 @@ pub struct WorldState { pub color: Color } -impl WorldState{ +impl WorldState { } From 42773aa2a2f2bb2bd53c486a4382ce3c47268b2d Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Sat, 1 Jul 2023 14:44:51 +0200 Subject: [PATCH 05/12] add error handling --- src/errors.rs | 6 +++++- src/worldstate.rs | 10 ++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index ff40f33..1173dbe 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -9,7 +9,8 @@ pub type LJResult = Result>; pub enum LJError { Config(ConfigError), RedisConnect(RedisError), - HeliosDeviceMissing + HeliosDeviceMissing, + BadEDH } impl fmt::Display for LJError { @@ -26,6 +27,9 @@ impl fmt::Display for LJError { }, HeliosDeviceMissing => { write!(f, "helios device not found") + }, + BadEDH => { + write!(f, "EDH matrix is not a 3x3 matrix") } } } diff --git a/src/worldstate.rs b/src/worldstate.rs index 38b1bd0..d51536b 100644 --- a/src/worldstate.rs +++ b/src/worldstate.rs @@ -1,14 +1,20 @@ use crate::point::Color; use nalgebra::base::Matrix3; -use crate::errors::LJResult; +use crate::errors::{LJError,LJResult}; + #[derive(Debug, Default)] pub struct EDH { pub matrix: Matrix3 } - impl EDH { pub fn new(vec: Vec>) -> LJResult { + if vec.len() != 3 || + vec[0].len() != 3 || + vec[1].len() != 3 || + vec[2].len() != 3 { + return Err(Box::new(LJError::BadEDH)); + } let matrix = Matrix3::new(vec[0][0], vec[0][1], vec[0][2], vec[1][0], vec[1][1], vec[1][2], vec[2][0], vec[2][1], vec[2][2]); From ddf44460aefdb77dfc0d6953f6905fa5218046ab Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Sat, 1 Jul 2023 14:54:37 +0200 Subject: [PATCH 06/12] fetch the right edh for this laser --- src/redis_ctrl.rs | 3 ++- src/worldstate.rs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/redis_ctrl.rs b/src/redis_ctrl.rs index ee2efe7..5f6eea0 100644 --- a/src/redis_ctrl.rs +++ b/src/redis_ctrl.rs @@ -111,7 +111,8 @@ impl RedisCtrl { pub fn get_edh( &mut self ) -> LJResult { // Get new EDH - let edh : String = self.connection.get("/EDH/0")?; + let edh_key = format!("/EDH/{}", self.laser_id); + let edh : String = self.connection.get(edh_key)?; let edh : Vec> = from_str(&edh)?; let edh = EDH::new(edh)?; Ok(edh) diff --git a/src/worldstate.rs b/src/worldstate.rs index d51536b..aaf26e7 100644 --- a/src/worldstate.rs +++ b/src/worldstate.rs @@ -15,6 +15,9 @@ impl EDH { vec[2].len() != 3 { return Err(Box::new(LJError::BadEDH)); } + // + // [FIX] Not sure of the order, if is it's vec[x][y] or vec[y][x] ... + // let matrix = Matrix3::new(vec[0][0], vec[0][1], vec[0][2], vec[1][0], vec[1][1], vec[1][2], vec[2][0], vec[2][1], vec[2][2]); From ee9e3f1da0b3919ffa723f968a9eb40c918ff693 Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Sat, 1 Jul 2023 16:01:11 +0200 Subject: [PATCH 07/12] add homography transformer --- src/conf.rs | 8 +++++--- src/transformer.rs | 2 ++ src/transformer/homography.rs | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/transformer/homography.rs diff --git a/src/conf.rs b/src/conf.rs index 1cc1b3e..815211c 100644 --- a/src/conf.rs +++ b/src/conf.rs @@ -46,8 +46,9 @@ pub enum TransformConf { #[serde(rename = "flip_vertical")] FlipV(transformer::FlipVertical), #[serde(rename = "grid")] - Grid(transformer::Grid) - + Grid(transformer::Grid), + #[serde(rename = "homography")] + Homography(transformer::Homography) } @@ -70,7 +71,8 @@ impl Conf { TransformConf::Rotate(r) => Box::new(*r), TransformConf::FlipH(r) => Box::new(*r), TransformConf::FlipV(r) => Box::new(*r), - TransformConf::Grid(r) => Box::new(*r) + TransformConf::Grid(r) => Box::new(*r), + TransformConf::Homography(r) => Box::new(*r), }; v.push(t); } diff --git a/src/transformer.rs b/src/transformer.rs index 6132658..aa25291 100644 --- a/src/transformer.rs +++ b/src/transformer.rs @@ -5,6 +5,7 @@ mod rotate; mod flip_horizontal; mod flip_vertical; mod grid; +mod homography; use crate::point::Point; use crate::worldstate::WorldState; @@ -16,6 +17,7 @@ pub use rotate::Rotate; pub use flip_horizontal::FlipHorizontal; pub use flip_vertical::FlipVertical; pub use grid::Grid; +pub use self::homography::Homography; pub trait Transformers { fn apply( diff --git a/src/transformer/homography.rs b/src/transformer/homography.rs new file mode 100644 index 0000000..bda21c3 --- /dev/null +++ b/src/transformer/homography.rs @@ -0,0 +1,36 @@ +use crate::transformer::Transformers; +use crate::point::Point; +use crate::worldstate::WorldState; +use serde::{Serialize,Deserialize}; +use log::info; +use nalgebra::Matrix3; + +/// Homography + +#[derive(Serialize,Deserialize,Debug,Clone,Copy)] +pub struct Homography {} + +impl Transformers for Homography { + fn apply(&self, point_list: &[Point], ws: &WorldState) -> Vec { + let m = ws.edh.matrix; + + point_list.iter() + .map(| point | { + + // THIS IS CERTAINLY ALL WRONG! NEEDS DEBUGING!!! + + let p = Matrix3::new(point.x, point.y, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0); + let dot = p.tr_dot(&m); + let new_p = Point { x: point.x / dot, y: point.y / dot, + ..*point + }; + + info!("{:?} => {:?}", point, new_p); + + new_p + }) + .collect() + } +} From 3d53982e7292533faf700a389da50eb6a381440d Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Sat, 1 Jul 2023 17:14:01 +0200 Subject: [PATCH 08/12] fix homography calculation + test --- src/point.rs | 4 +-- src/transformer/homography.rs | 65 ++++++++++++++++++++++++++++------- src/worldstate.rs | 8 +++++ 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/point.rs b/src/point.rs index 44fa9b4..5eb6d42 100644 --- a/src/point.rs +++ b/src/point.rs @@ -1,11 +1,11 @@ -#[derive(Debug,Clone,Copy,Default)] +#[derive(Debug,Clone,Copy,Default,PartialEq)] pub struct Point { pub x: f32, pub y: f32, pub color: Color } -#[derive(Debug,Clone,Copy,Default)] +#[derive(Debug,Clone,Copy,Default,PartialEq)] pub struct Color { r: u8, g: u8, diff --git a/src/transformer/homography.rs b/src/transformer/homography.rs index bda21c3..0713583 100644 --- a/src/transformer/homography.rs +++ b/src/transformer/homography.rs @@ -1,9 +1,10 @@ use crate::transformer::Transformers; use crate::point::Point; -use crate::worldstate::WorldState; +use crate::worldstate::{WorldState,EDH}; use serde::{Serialize,Deserialize}; use log::info; use nalgebra::Matrix3; +use nalgebra::Matrix1x3; /// Homography @@ -12,25 +13,63 @@ pub struct Homography {} impl Transformers for Homography { fn apply(&self, point_list: &[Point], ws: &WorldState) -> Vec { - let m = ws.edh.matrix; + let edh : &EDH = &ws.edh; point_list.iter() .map(| point | { - - // THIS IS CERTAINLY ALL WRONG! NEEDS DEBUGING!!! + let p = Matrix1x3::new(point.x, point.y, 1.0); + let p = p * edh.matrix; + let new_p = Point { x: p[0] / p[2], y: p[1] / p[2], ..*point }; - let p = Matrix3::new(point.x, point.y, 1.0, - 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0); - let dot = p.tr_dot(&m); - let new_p = Point { x: point.x / dot, y: point.y / dot, - ..*point - }; - - info!("{:?} => {:?}", point, new_p); + dbg!("{:?} => {:?}", point, new_p); new_p }) .collect() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_homography_identity() { + let p0 = Point { x: -1500.0, y: 1500.0, ..Point::default() }; + + let edh = EDH::new(vec![ + vec![ 1.0, 0.0, 0.0 ], + vec![ 0.0, 1.0, 0.0 ], + vec![ 0.0, 0.0, 1.0 ] + ]).unwrap(); + + let ws = WorldState { edh : edh, ..WorldState::default() }; + + let homography = Homography{}; + let result = homography.apply(&[p0], &ws); + + assert_eq!(result, vec![Point { x: -1500.0, + y: 1500.0, + ..Point::default() }]); + } + + #[test] + fn test_homography_rotation() { + let p0 = Point { x: -1500.0, y: 1500.0, ..Point::default() }; + + let edh = EDH::new(vec![ + vec![ 1.24107321e-03, 1.00500127e-03, 7.15439347e-01], + vec![-9.93223912e-04, 1.22652939e-03,-6.98671238e-01], + vec![ 1.06017142e-17,-4.69459541e-17, 3.32700590e-05] + ]).unwrap(); + + let ws = WorldState { edh : edh, ..WorldState::default() }; + + let homography = Homography{}; + let result = homography.apply(&[p0], &ws); + + assert_eq!(result, vec![Point { x: 10860.557, + y: 79078.87, + ..Point::default() }]); + } +} diff --git a/src/worldstate.rs b/src/worldstate.rs index aaf26e7..8377212 100644 --- a/src/worldstate.rs +++ b/src/worldstate.rs @@ -18,9 +18,17 @@ impl EDH { // // [FIX] Not sure of the order, if is it's vec[x][y] or vec[y][x] ... // + /* let matrix = Matrix3::new(vec[0][0], vec[0][1], vec[0][2], vec[1][0], vec[1][1], vec[1][2], vec[2][0], vec[2][1], vec[2][2]); + */ + + // this is the matrix already transposed. + let matrix = Matrix3::new(vec[0][0], vec[1][0], vec[2][0], + vec[0][1], vec[1][1], vec[2][1], + vec[0][2], vec[1][2], vec[2][2]); + Ok(EDH { matrix }) } } From 6c0678ca1dbd0ba7a8d18ef04f2d283c7247e44a Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Sat, 1 Jul 2023 17:17:33 +0200 Subject: [PATCH 09/12] cleanup --- src/transformer/homography.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/transformer/homography.rs b/src/transformer/homography.rs index 0713583..f054319 100644 --- a/src/transformer/homography.rs +++ b/src/transformer/homography.rs @@ -2,8 +2,7 @@ use crate::transformer::Transformers; use crate::point::Point; use crate::worldstate::{WorldState,EDH}; use serde::{Serialize,Deserialize}; -use log::info; -use nalgebra::Matrix3; +use log::debug; use nalgebra::Matrix1x3; /// Homography @@ -21,7 +20,7 @@ impl Transformers for Homography { let p = p * edh.matrix; let new_p = Point { x: p[0] / p[2], y: p[1] / p[2], ..*point }; - dbg!("{:?} => {:?}", point, new_p); + debug!("{:?} => {:?}", point, new_p); new_p }) From 1d61235e51fa02ccb05d159bd086f85e0dd51dcb Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Sat, 1 Jul 2023 17:19:48 +0200 Subject: [PATCH 10/12] cleanup --- src/transformer/homography.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformer/homography.rs b/src/transformer/homography.rs index f054319..3fe1f95 100644 --- a/src/transformer/homography.rs +++ b/src/transformer/homography.rs @@ -33,7 +33,7 @@ mod tests { use super::*; #[test] - fn test_homography_identity() { + fn identity_matrix_let_point_unchanged() { let p0 = Point { x: -1500.0, y: 1500.0, ..Point::default() }; let edh = EDH::new(vec![ @@ -53,7 +53,7 @@ mod tests { } #[test] - fn test_homography_rotation() { + fn rotation_matrix_rotate_the_point() { let p0 = Point { x: -1500.0, y: 1500.0, ..Point::default() }; let edh = EDH::new(vec![ From 2b0a2ce06d91124a868e70f705991e6f15743047 Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Sat, 1 Jul 2023 17:42:31 +0200 Subject: [PATCH 11/12] refacto --- Cargo.toml | 1 - src/transformer/homography.rs | 12 +----------- src/worldstate.rs | 15 +++++++++++++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 65d03bf..61520a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,5 +17,4 @@ redis = "0.23.0" ron = "0.8.0" serde = { version = "1.0.163", features = ["derive"] } toml = "0.7.4" -homography = { git = "https://github.com/azazdeaz/homography" } nalgebra = "0.32.2" diff --git a/src/transformer/homography.rs b/src/transformer/homography.rs index 3fe1f95..8f1091f 100644 --- a/src/transformer/homography.rs +++ b/src/transformer/homography.rs @@ -2,8 +2,6 @@ use crate::transformer::Transformers; use crate::point::Point; use crate::worldstate::{WorldState,EDH}; use serde::{Serialize,Deserialize}; -use log::debug; -use nalgebra::Matrix1x3; /// Homography @@ -15,15 +13,7 @@ impl Transformers for Homography { let edh : &EDH = &ws.edh; point_list.iter() - .map(| point | { - let p = Matrix1x3::new(point.x, point.y, 1.0); - let p = p * edh.matrix; - let new_p = Point { x: p[0] / p[2], y: p[1] / p[2], ..*point }; - - debug!("{:?} => {:?}", point, new_p); - - new_p - }) + .map(| point | edh.apply(point)) .collect() } } diff --git a/src/worldstate.rs b/src/worldstate.rs index 8377212..426dc1c 100644 --- a/src/worldstate.rs +++ b/src/worldstate.rs @@ -1,6 +1,7 @@ -use crate::point::Color; -use nalgebra::base::Matrix3; +use crate::point::{Point,Color}; +use nalgebra::base::{Matrix3,Matrix1x3}; use crate::errors::{LJError,LJResult}; +use log::debug; #[derive(Debug, Default)] pub struct EDH { @@ -31,6 +32,16 @@ impl EDH { Ok(EDH { matrix }) } + + pub fn apply(&self, point: &Point) -> Point { + let p = Matrix1x3::new(point.x, point.y, 1.0); + let p = p * self.matrix; + let new_p = Point { x: p[0] / p[2], y: p[1] / p[2], ..*point }; + + debug!("{:?} => {:?}", point, new_p); + + new_p + } } #[derive(Debug, Default)] From e5e8ad878b7abf4f6038cea2ff152547202d626f Mon Sep 17 00:00:00 2001 From: Marc Planard Date: Thu, 6 Jul 2023 20:26:06 +0200 Subject: [PATCH 12/12] micro-cleanup --- src/worldstate.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/worldstate.rs b/src/worldstate.rs index 426dc1c..bf5ecc9 100644 --- a/src/worldstate.rs +++ b/src/worldstate.rs @@ -16,15 +16,7 @@ impl EDH { vec[2].len() != 3 { return Err(Box::new(LJError::BadEDH)); } - // - // [FIX] Not sure of the order, if is it's vec[x][y] or vec[y][x] ... - // - /* - let matrix = Matrix3::new(vec[0][0], vec[0][1], vec[0][2], - vec[1][0], vec[1][1], vec[1][2], - vec[2][0], vec[2][1], vec[2][2]); - */ - + // this is the matrix already transposed. let matrix = Matrix3::new(vec[0][0], vec[1][0], vec[2][0], vec[0][1], vec[1][1], vec[2][1],