Custom homography per laser

This commit is contained in:
Ruben van de Ven 2025-05-21 18:50:18 +02:00
parent f921968386
commit 7ae6768edb
2 changed files with 68 additions and 7 deletions

View file

@ -8,13 +8,16 @@ use nannou::lyon::geom::euclid::Transform2D;
use nannou::{geom::Rect, math::map_range as nannou_map_range};
use nannou::prelude::*;
use nannou_egui::{self, egui, Egui};
use nannou_laser::DacId;
use nannou_laser::{self as laser, util::map_range};
use serde_json::Result;
use serde::{Serialize,Deserialize};
use trap_rust::trap::tracks::CoordinateSpace;
use trap_rust::trap::{laser::{apply_homography_matrix, python_cv_h_into_mat3, LaserModel, TMP_PYTHON_LASER_H}, tracks::{LaserPoints, RenderableLines}};
use trap_rust::trap::{laser::{apply_homography_matrix, python_cv_h_into_mat3, LaserModel, TMP_PYTHON_LASER_H, DacConfig}, tracks::{LaserPoints, RenderableLines}};
use zmq::Socket;
use std::sync::{mpsc, Arc};
use std::time::{Instant, Duration};
use std::collections::HashMap;
fn main() {
nannou::app(model).update(update).run();
@ -29,6 +32,7 @@ struct Model {
laser_model: LaserModel,
// A copy of the laser settings so that we can control them with the GUI.
laser_settings: LaserSettings,
per_laser_config: DacConfigMap,
// For receiving newly detected DACs.
dac_rx: mpsc::Receiver<laser::DetectedDac>,
// The UI for control over laser parameters and settings.
@ -153,6 +157,30 @@ fn zmq_receive(model: &mut Model) {
}
// #[derive(Serialize, Deserialize)]
// #[serde(remote = "DacId")]
// pub enum DacIdSerializable {
// EtherDream { mac_address: [u8; 6] },
// Helios { id: u32 },
// }
// DEPRECATED
type DacConfigMap = HashMap<DacId, DacConfig>;
// Some hardcoded config. Not spending time on reading/writing config atm.
fn get_dac_configs() -> DacConfigMap{
let mut dac_configs: DacConfigMap = HashMap::new();
dac_configs.insert(
DacId::Helios { id: 926298163 },
DacConfig{homography: python_cv_h_into_mat3(TMP_PYTHON_LASER_H)}
);
dac_configs
}
fn model(app: &App) -> Model {
// Create a window to receive keyboard events.
let w_id_lasersettings = app
@ -213,6 +241,9 @@ fn model(app: &App) -> Model {
{
let dac = res.expect("error occurred during DAC detection");
if detected.insert(dac.id()) {
// DacId::EtherDream { mac_address: () }
dbg!(&detected);
println!("{:#?}", dac);
if dac_tx.send(dac).is_err() {
break;
@ -244,6 +275,7 @@ fn model(app: &App) -> Model {
last_update: Instant::now(),
lost_alpha: 1.,
connected: true,
per_laser_config: get_dac_configs()
// dimming_factor: 1.,
}
}
@ -263,19 +295,19 @@ fn model(app: &App) -> Model {
// frame.add_lines(points);
// }
const LASER_H: Mat3 = python_cv_h_into_mat3(TMP_PYTHON_LASER_H);
fn laser_frame_producer(model: &mut LaserModel, frame: &mut laser::Frame){
let points: LaserPoints = (&model.current_lines).into();
let space = &model.current_lines.space;
let pointno = points.len();
dbg!(model.config.homography);
let mut new_points = Vec::new();
for point in points.into_iter() {
let p = point.position;
let new_position = match space {
CoordinateSpace::World => apply_homography_matrix(LASER_H, &p),
CoordinateSpace::World => apply_homography_matrix(model.config.homography, &p),
CoordinateSpace::Laser => p,
_ => panic!("Invalid coordinate space"),
@ -328,9 +360,13 @@ fn update(_app: &App, model: &mut Model, update: Update) {
// First, check for new laser DACs.
for dac in model.dac_rx.try_recv() {
println!("Detected DAC {:?}!", dac.id());
let config = match model.per_laser_config.contains_key(&dac.id()) {
true => &model.per_laser_config[&dac.id()],
false => &DacConfig::default(),
};
let stream = model
.laser_api
.new_frame_stream(model.laser_model.clone(), laser_frame_producer)
.new_frame_stream(model.laser_model.with_config(config), laser_frame_producer)
.detected_dac(dac)
.build()
.expect("failed to establish stream with newly detected DAC");

View file

@ -1,7 +1,7 @@
use bevy::prelude::*;
use nannou_laser as laser;
use std::time::Instant;
use serde::{Deserialize, Serialize};
use super::tracks::{LaserPoints, RenderableLines};
pub const TMP_PYTHON_LASER_H: [[f32;3];3] = [[ 2.47442963e+02, -7.01714050e+01, -9.71749119e+01],
@ -34,6 +34,7 @@ pub struct LaserModel{
pub t: Instant, // register start time, so that animations can be moving
pub current_lines: RenderableLines,
pub dimming: f32,
pub config: DacConfig, // per dac configuration
}
impl LaserModel{
@ -41,9 +42,16 @@ impl LaserModel{
Self{
t: Instant::now(),
current_lines: RenderableLines::new(),
dimming: 0.3
dimming: 0.3,
config: DacConfig::default(),
}
}
pub fn with_config(&self, config: &DacConfig) -> Self{
LaserModel{
config: config.clone(),
.. self.clone()}
}
}
#[derive(Component)]
@ -57,4 +65,21 @@ pub struct LaserApi{
#[derive(Component)]
pub struct LaserTimer {
pub timer: Timer,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct DacConfig{
// #[serde(with = "DacIdSerializable")]
// id: DacId,
pub homography: Mat3
}
const LASER_H: Mat3 = python_cv_h_into_mat3(TMP_PYTHON_LASER_H);
impl Default for DacConfig{
fn default() -> DacConfig{
DacConfig { homography: Mat3::IDENTITY }
}
}