test some laser linedrawing
This commit is contained in:
commit
655f64c913
8 changed files with 6070 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
5694
Cargo.lock
generated
Normal file
5694
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
20
Cargo.toml
Normal file
20
Cargo.toml
Normal file
|
@ -0,0 +1,20 @@
|
|||
[package]
|
||||
name = "trap_rust"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
bevy = "0.15.3"
|
||||
bevy_nannou = { git = "https://github.com/nannou-org/nannou", branch = "bevy-refactor", version = "0.1.0", features = ["wayland"] }
|
||||
iyes_perf_ui = "0.4.0"
|
||||
nannou_laser = { git = "https://github.com/nannou-org/nannou", branch = "bevy-refactor", version = "0.19.0" }
|
||||
serde = "1.0.219"
|
||||
serde_json = "1.0.140"
|
||||
zmq = "0.10.0"
|
||||
|
||||
|
||||
|
||||
# Enable max optimizations for dependencies, but not for our code:
|
||||
# (tip from bevy examples for fast compilation/performance trade-off)
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 3
|
153
src/main.rs
Normal file
153
src/main.rs
Normal file
|
@ -0,0 +1,153 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy::render::view::RenderLayers;
|
||||
use bevy::window::WindowResolution;
|
||||
use bevy_nannou::prelude::*;
|
||||
use bevy_nannou::NannouPlugin;
|
||||
use iyes_perf_ui::prelude::*;
|
||||
use trap::zmqplugin::ZmqPlugin;
|
||||
// use iyes_perf_ui::PerfUiPlugin;
|
||||
|
||||
use nannou_laser as laser;
|
||||
use std::fs;
|
||||
|
||||
mod trap;
|
||||
|
||||
fn main() {
|
||||
let mut app = App::new();
|
||||
// app.add_plugins((DefaultPlugins, NannouPlugin))
|
||||
app.add_plugins((DefaultPlugins, NannouPlugin))
|
||||
// .add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin)
|
||||
// .add_plugins(bevy::diagnostic::EntityCountDiagnosticsPlugin)
|
||||
// .add_plugins(bevy::diagnostic::SystemInformationDiagnosticsPlugin)
|
||||
// .add_plugins(PerfUiPlugin)
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Update, update)
|
||||
|
||||
|
||||
.add_plugins(ZmqPlugin {
|
||||
// url: "tcp://localhost:5558".to_string(),
|
||||
url: "tcp://100.109.175.82:99173".to_string(),
|
||||
// url: "tcp://127.0.0.1:99173".to_string(),
|
||||
filter: "".to_string()
|
||||
})
|
||||
|
||||
|
||||
.run();
|
||||
}
|
||||
|
||||
struct LaserModel{
|
||||
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct LaserApi{
|
||||
_laser_api: laser::Api,
|
||||
laser_stream: laser::FrameStream<LaserModel>,
|
||||
}
|
||||
|
||||
|
||||
fn setup(mut commands: Commands) {
|
||||
// Spawn a camera for our main window
|
||||
commands.spawn((render::NannouCamera, RenderLayers::none()));
|
||||
|
||||
let path = "your_future_points_test.json";
|
||||
// let file = File::open(path)?;
|
||||
let data = fs::read_to_string(path).expect("Unable to read file");
|
||||
// let reader = BufReader::new(file);
|
||||
|
||||
|
||||
// let res: serde_json::Value = serde_json::from_str(&data).expect("Unable to parse");
|
||||
let res: serde_json::Value = serde_json::from_str(&data).expect("Unable to parse");
|
||||
// let max = res[0].iter().cloned().fold(0./0., f64::max);
|
||||
|
||||
println!("{}",res);
|
||||
|
||||
// let u = serde_json::from_reader(reader)?;
|
||||
|
||||
|
||||
// Initialise the state that we want to live on the laser thread and spawn the stream.
|
||||
let laser_model = LaserModel {
|
||||
|
||||
};
|
||||
let _laser_api = laser::Api::new();
|
||||
// dacs = _laser_api.detect_dacs()
|
||||
let laser_stream = _laser_api
|
||||
.new_frame_stream(laser_model, laser_frame_producer)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let api = LaserApi {
|
||||
_laser_api,
|
||||
laser_stream,
|
||||
};
|
||||
commands.spawn(api);
|
||||
// create a simple Perf UI with default settings
|
||||
// and all entries provided by the crate:
|
||||
// commands.spawn(PerfUiDefaultEntries::default());
|
||||
|
||||
}
|
||||
|
||||
pub fn laser_frame_producer(_laser: &mut LaserModel, frame: &mut laser::Frame){
|
||||
// Simple constructors for white or blank points.
|
||||
let lit_p = |position| laser::Point::new(position, [1.0; 3]);
|
||||
|
||||
let positions = trap::shapes::YOU;
|
||||
|
||||
// let tl = [-1.0, 1.0];
|
||||
// let tr = [1.0, 1.0];
|
||||
// let br = [1.0, -1.0];
|
||||
// let bl = [-1.0, -1.0];
|
||||
// let positions = [tl, tr, br, bl, tl];
|
||||
let points = positions.iter().cloned().map(lit_p);
|
||||
frame.add_lines(points);
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct WindowColor(Color);
|
||||
|
||||
// fn receive_tracks(mut commands: Commands){
|
||||
|
||||
// }
|
||||
|
||||
fn update(
|
||||
mut commands: Commands,
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
draws: Query<(&Draw, Option<&WindowColor>)>,
|
||||
mut count: Local<usize>,
|
||||
) {
|
||||
if keys.just_pressed(KeyCode::Space) {
|
||||
// Increment the count to track the number of windows
|
||||
*count += 1;
|
||||
// We need a render layer to make sure we only render the camera for this window
|
||||
let layer = RenderLayers::layer(*count);
|
||||
// Spawn a new window with a unique title, resolution, and background color
|
||||
let entity = commands
|
||||
.spawn((
|
||||
Window {
|
||||
title: "Nannou".to_string(),
|
||||
resolution: WindowResolution::new(400.0, 400.0),
|
||||
..Default::default()
|
||||
},
|
||||
layer.clone(),
|
||||
WindowColor(match *count {
|
||||
1 => RED.into(),
|
||||
2 => GREEN.into(),
|
||||
3 => BLUE.into(),
|
||||
_ => PURPLE.into(),
|
||||
}),
|
||||
))
|
||||
.id();
|
||||
// Spawn a camera for our new window with the matching render layer
|
||||
commands.spawn((render::NannouCamera::for_window(entity), layer.clone()));
|
||||
}
|
||||
|
||||
for (draw, window_color) in draws.iter() {
|
||||
if let Some(window_color) = window_color {
|
||||
draw.background().color(window_color.0);
|
||||
} else {
|
||||
draw.background().color(DIM_GRAY);
|
||||
}
|
||||
|
||||
draw.ellipse().color(LIGHT_GRAY).w_h(100.0, 100.0);
|
||||
}
|
||||
}
|
10
src/trap/mod.rs
Normal file
10
src/trap/mod.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
pub mod zmqplugin;
|
||||
// pub use zmqplugin::ZmqPlugin;
|
||||
|
||||
// mod grid;
|
||||
// pub use grid::GridPlugin;
|
||||
pub mod tracks;
|
||||
// pub use tracks::Frame;
|
||||
// pub use grid::GridPlugin;
|
||||
|
||||
pub mod shapes;
|
1
src/trap/shapes.rs
Normal file
1
src/trap/shapes.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub static YOU: [[f32; 2]; 107] = [[0.33800762191421707, 0.5879238779522781], [0.3268223414326286, 0.613215363578254], [0.3226602260682412, 0.6362631583205897], [0.3246304342549215, 0.656942657636883], [0.33184212442653593, 0.6751284478643268], [0.3434052641373563, 0.6906975427013294], [0.3584298209416543, 0.7035253376054891], [0.37602576239370183, 0.7134856097935934], [0.3953022469273653, 0.7204553729640508], [0.41536843297651127, 0.7243100225744593], [0.4353350972158167, 0.7249249540824171], [0.45431139807914817, 0.7221747538251168], [0.4714073031207774, 0.715936435500967], [0.485731970774571, 0.7060837763267552], [0.4963953685948006, 0.6924937900008901], [0.5025074641357381, 0.6750410628605643], [0.5031782249516551, 0.6536017994837813], [0.4979367429667209, 0.6156370609510401], [0.495441415637061, 0.6098526591742117], [0.49274380820609914, 0.6109951371863647], [0.48588165804953437, 0.6284511008083113], [0.47563576635839183, 0.6567800244354363], [0.4483724543049251, 0.7310726509211836], [0.4321592996253773, 0.7735563269170086], [0.41319918117015, 0.8153910883478571], [0.39072262543389086, 0.8534197473926095], [0.3639585406704372, 0.8844899709525775], [0.34872846728321644, 0.8964325881334402], [0.3321382624948419, 0.9054461894474517], [0.3140916409770938, 0.9111504883041646], [0.2944915082813474, 0.913132833296923], [0.2750572452686684, 0.9099529901044575], [0.2660768178912704, 0.9053814598150352], [0.25953427029476256, 0.8983016562694696], [0.2557823789758154, 0.8880420095314384], [0.25624276848637845, 0.8783568382811047], [0.26040892945279187, 0.8692380513144162], [0.26777516162180093, 0.8606856486313729], [0.2900842294341821, 0.8452880873202742], [0.31912275165667403, 0.8321479719397045], [0.3811944235421673, 0.812583440541787], [0.42160998778228187, 0.8019070967950742], [0.49081243779886885, 0.7746211293702616], [0.5572031944073599, 0.7415256774360592], [0.6047414455745159, 0.7169089982280263], [0.6265949785987653, 0.7023529221383434], [0.6461862109700545, 0.6832625352978777], [0.6747886172941396, 0.6504235745321262], [0.6790462088663415, 0.6442863962586273], [0.6805236627262503, 0.6418986819428599], [0.6800851194666279, 0.6419496565283881], [0.6619365487778236, 0.6567581781844957], [0.6446132809023312, 0.6681611120550849], [0.6283426786740135, 0.6820836468674905], [0.6133472502043029, 0.704449353108236], [0.6046807615441253, 0.7304221181153968], [0.6058523678908658, 0.7516235000930489], [0.6150544942592907, 0.7681109465899622], [0.6304771383029509, 0.7799386686732853], [0.650313534157018, 0.7871633047713831], [0.6727552977158532, 0.7898414933126199], [0.6959940448738178, 0.7880282544845498], [0.7182205824048677, 0.7817794175951324], [0.7281687177868938, 0.7736663672921168], [0.736318987628549, 0.7592688788018546], [0.7423380343228877, 0.7406186534618217], [0.7458933093833694, 0.719746583489089], [0.746652264323454, 0.6986835611007274], [0.7442799232953856, 0.6794612876342129], [0.7384453560534343, 0.664109846186211], [0.7288135867498442, 0.6546609380941979], [0.7050189738735022, 0.6490747708166453], [0.6933522667508152, 0.6453706176016053], [0.6853816216391161, 0.6377122929663164], [0.6858387746680583, 0.6366288807437436], [0.6884870257543025, 0.6371839373417159], [0.6949154873736761, 0.6398305701871495], [0.724901489590666, 0.6511493555355974], [0.7563560453431076, 0.6588983016562695], [0.8062269906384769, 0.6641600116513339], [0.8559361118528048, 0.6620765266079246], [0.8748695293346603, 0.6517707600067966], [0.8919500610885905, 0.6430087951388046], [0.8884870257543025, 0.6461789288864077], [0.8834785704460681, 0.6483052973112929], [0.8578132711928863, 0.6987588092984117], [0.8479743670655632, 0.7289422368942723], [0.8479500934534069, 0.7415418598441635], [0.8527562686603394, 0.7510595431706193], [0.8640677719251402, 0.7602398232881035], [0.875913294657378, 0.7659926693691288], [0.8881067391638551, 0.7686069373983543], [0.9004862813635298, 0.7683706742400337], [0.9250997240899419, 0.7605044056606064], [0.9483538445356053, 0.7447006659060936], [0.9688650468076154, 0.7232703028537677], [0.9852335526049633, 0.6985209278992808], [0.9960757660347437, 0.6727633889199052], [1.0, 0.6483052973112929], [0.9940691474298291, 0.6771059381346539], [0.9864795980289828, 0.7059518897007064], [0.9756373845992022, 0.7351692275327492], [0.969253424602115, 0.7562063580681442], [0.9650459984950361, 0.7754237768122275], [0.9650459984950361, 0.7754237768122275], [0.9650459984950361, 0.7754237768122275], [0.9650459984950361, 0.7754237768122275]];
|
92
src/trap/tracks.rs
Normal file
92
src/trap/tracks.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
use bevy::prelude::*;
|
||||
use serde::{Serialize,Deserialize};
|
||||
|
||||
#[derive(Serialize,Deserialize)]
|
||||
pub struct Frame {
|
||||
pub tracks: std::collections::HashMap<String, Track>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Component, Debug)]
|
||||
pub struct Detection{
|
||||
track_id: u64,
|
||||
l: f32,
|
||||
t: f32,
|
||||
w: f32,
|
||||
h: f32,
|
||||
conf: f32,
|
||||
state: u8,
|
||||
frame_nr: u64,
|
||||
det_class: u8,
|
||||
}
|
||||
|
||||
impl Detection {
|
||||
fn to_point(&self) -> Vec2 {
|
||||
let x = self.l + self.w/2.;
|
||||
let y = self.t + self.h;
|
||||
Vec2::new(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Component, Debug)]
|
||||
pub struct Track {
|
||||
pub track_id: u64,
|
||||
// nr: u32,
|
||||
pub history: Vec<Vec2>, // projected foot coordintes //Vec<Detection>, // history
|
||||
pub predictor_history: Option<Vec<Vec2>>, // history
|
||||
pub predictions: Option<Vec<Vec<Vec2>>>,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// check: https://www.reddit.com/r/bevy/comments/y1km8n/how_to_link_components_in_bevy_or_am_i_too_oop/
|
||||
#[derive(Serialize, Deserialize, Component)]
|
||||
pub struct PredictedTrajectory{
|
||||
person: Entity,
|
||||
points: Vec<Vec2>,
|
||||
}
|
||||
|
||||
// #[derive(Bundle)]
|
||||
// pub struct TrackBundle {
|
||||
// track: Track,
|
||||
// // label: TextBundle,
|
||||
// }
|
||||
|
||||
// impl From<Track> for TrackBundle{
|
||||
// fn from(track: Track) -> Self {
|
||||
// let name = track.track_id.to_string();
|
||||
// TrackBundle{
|
||||
// track: track,
|
||||
// // label: TextBundle{
|
||||
// // text: Text::from_section(name, TextStyle::default()),
|
||||
// // transform: Transform::from_translation(250. * Vec3::Y),
|
||||
// // ..default()
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[derive(Bundle)]
|
||||
// pub struct TrackBundle {
|
||||
// pub history: TrajectoryBundle,
|
||||
// pub time: Time,
|
||||
|
||||
// }
|
||||
|
||||
// #[derive(Bundle)]
|
||||
// pub struct TrajectoryBundle {
|
||||
// pub line: PolylineBundle
|
||||
// // pub trajectory: Trajectory,
|
||||
// }
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Trajectory {
|
||||
pub points: Vec<Vec3>,
|
||||
}
|
||||
|
||||
fn spawn_track() {
|
||||
|
||||
}
|
||||
|
||||
fn draw_tracks() {
|
||||
// evyr ææææááá
|
||||
}
|
99
src/trap/zmqplugin.rs
Normal file
99
src/trap/zmqplugin.rs
Normal file
|
@ -0,0 +1,99 @@
|
|||
|
||||
use zmq::Socket;
|
||||
use serde_json::Result;
|
||||
use bevy::{ecs::system::SystemState, prelude::*};
|
||||
|
||||
use super::tracks::{Frame, Track};
|
||||
|
||||
|
||||
// use trap::{Frame, Track, TrackBundle};
|
||||
// use tracks::Frame;
|
||||
|
||||
// Because of world.insert_non_send_resource, this is an exclusive system
|
||||
// see: https://bevy-cheatbook.github.io/programming/exclusive.html
|
||||
fn setup_zmq(world: &mut World, params: &mut SystemState<Res<ZmqSettings>>) {
|
||||
let settings = params.get(world);
|
||||
let url = &settings.url;
|
||||
let context = zmq::Context::new();
|
||||
let subscriber = context.socket(zmq::SUB).unwrap();
|
||||
assert!(subscriber.connect(url).is_ok());
|
||||
|
||||
// let filter = "10001";
|
||||
let filter = &settings.filter; //"msgs";
|
||||
assert!(subscriber.set_subscribe(filter.as_bytes()).is_ok());
|
||||
world.insert_non_send_resource(subscriber);
|
||||
}
|
||||
|
||||
fn receive_zmq_messsages(mut commands: Commands, subscriber: NonSend<Socket>, mut tracks_q: Query<&mut Track>) {
|
||||
let mut items = [
|
||||
subscriber.as_poll_item(zmq::POLLIN)
|
||||
];
|
||||
let _nr = zmq::poll(&mut items, 0).unwrap();
|
||||
if items[0].is_readable() {
|
||||
let json = subscriber.recv_string(0).unwrap().unwrap();
|
||||
// dbg!(&json[4..]);
|
||||
|
||||
// let msg: Frame = serde_json::from_str(&json[4..]).expect("No valid json?");
|
||||
let res: Result<Frame> = serde_json::from_str(&json);
|
||||
|
||||
let msg = match res {
|
||||
Ok(msg) => msg, // if Ok(255), set x to 255
|
||||
Err(_e) => {
|
||||
println!("No valid json? {json}");
|
||||
return
|
||||
}, // if Err("some message"), panic with error message "some message"
|
||||
};
|
||||
|
||||
for (_track_id, new_track) in msg.tracks.into_iter() {
|
||||
let mut done = false;
|
||||
for mut track in tracks_q.iter_mut() {
|
||||
if track.track_id == new_track.track_id {
|
||||
// track.nr += 1;
|
||||
track.history = new_track.history.clone();
|
||||
track.predictor_history = new_track.predictor_history.clone();
|
||||
track.predictions = new_track.predictions.clone();
|
||||
// TODO match lenghts of points and drawn_points
|
||||
done = true;
|
||||
// dbg!(&track);
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !done {
|
||||
// CREATE
|
||||
// let track = Track{
|
||||
// id: json.clone(),
|
||||
// nr: 0,
|
||||
// points: Vec::new()
|
||||
// };
|
||||
dbg!(&new_track.predictor_history);
|
||||
// commands.spawn(TrackBundle::from(new_track));
|
||||
commands.spawn(new_track);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
struct ZmqSettings {
|
||||
url: String,
|
||||
filter: String
|
||||
}
|
||||
|
||||
pub struct ZmqPlugin {
|
||||
pub url: String,
|
||||
pub filter: String
|
||||
}
|
||||
|
||||
impl Plugin for ZmqPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
let settings = ZmqSettings{
|
||||
url: self.url.clone(),
|
||||
filter: self.filter.clone()
|
||||
};
|
||||
app
|
||||
.insert_resource(settings)
|
||||
.add_systems(Startup, setup_zmq)
|
||||
.add_systems(Update, receive_zmq_messsages);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue