added threading handler for capturing VRPN input

This commit is contained in:
Hartmut Seichter 2022-12-20 23:23:03 +01:00
parent 6c8c9d70cb
commit d39fd7b0f6
7 changed files with 119 additions and 102 deletions

View file

@ -1,3 +1,4 @@
use bevy::prelude::*;
extern crate bytes;
@ -13,7 +14,7 @@ use std::{
net::{SocketAddr, TcpStream},
};
use std::sync::mpsc::{Receiver,channel};
use std::sync::mpsc::{channel, Receiver};
use vrpn::{
codec::peek_u32,
@ -23,67 +24,98 @@ use vrpn::{
message::MessageSize,
sync_io::{read_cookie, write_cookie, EndpointSyncTcp},
tracker::PoseReport,
unbuffer, CookieData, Message, Result, SequencedGenericMessage, TypeDispatcher, Unbuffer, TypedBodylessHandler,
unbuffer, CookieData, Message, Result, SequencedGenericMessage, TypeDispatcher,
TypedBodylessHandler, Unbuffer,
};
struct TrackerProxy;
#[derive(Resource, Debug)]
pub struct Tracker;
#[derive(Resource,Debug)]
struct Tracker;
impl Tracker {
pub fn start_tracker(&self) {
impl FromWorld for Tracker {
fn from_world(world: &mut World) -> Self {
let (sender, receiver): (_, Receiver<PoseReport>) = channel();
std::thread::spawn(move || {
let (sender, receiver): (_, Receiver<PoseReport>) = channel();
let addr: SocketAddr = "127.0.0.1:3883".parse().unwrap();
let mut stream = TcpStream::connect(addr).unwrap();
stream.set_nodelay(true).unwrap();
// We first write our cookie, then read and check the server's cookie, before the loop.
write_cookie(&mut stream, CookieData::from(MAGIC_DATA)).unwrap();
let cookie_buf = read_cookie(&mut stream).unwrap();
let mut cookie_buf = Bytes::from(&cookie_buf[..]);
CookieData::unbuffer_ref(&mut cookie_buf)
.and_then(|msg| check_ver_nonfile_compatible(msg.version)).unwrap();
let mut endpoint = EndpointSyncTcp::new(stream);
let mut dispatcher = TypeDispatcher::new();
//let _ = dispatcher.add_typed_handler(Box::new(TrackerHandler {}), None).unwrap();
let _ = dispatcher.add_typed_handler(Box::new( Tracker {} ), None).unwrap();
// setup a channel
// let (tx, rx) = mpsc::channel();
.and_then(|msg| check_ver_nonfile_compatible(msg.version))
.unwrap();
// Not actually doing anything with the messages here, just receiving them and printing them.
loop {
// vrpn implementation is rather verbose - we need to see what specific errors
// should be handled properly!
endpoint.poll_endpoint(&mut dispatcher).unwrap_or_else(|err| {
info!("error from tracker thread {:?}",err);
})
// dispatcher.han
let mut buf = BytesMut::new();
// Read the message header and padding
buf.resize(24, 0);
stream.read_exact(buf.as_mut()).unwrap();
// Peek the size field, to compute the MessageSize.
let total_len = peek_u32(&buf.clone().freeze()).unwrap().unwrap();
let size = MessageSize::from_length_field(total_len);
// Read the body of the message
let mut body_buf = BytesMut::new();
body_buf.resize(size.padded_body_size(), 0);
stream.read_exact(body_buf.as_mut()).unwrap();
// Combine the body with the header
buf.extend_from_slice(&body_buf[..]);
let mut buf = buf.freeze();
// Unbuffer the message.
let unbuffered = SequencedGenericMessage::unbuffer_ref(&mut buf).unwrap();
let message = Message::from(unbuffered);
// let result: Message<PoseReport> = Message::try_from_generic(&message)?;
let result = Message::<PoseReport>::try_from_generic(&message);
match result {
Ok(result) => { eprintln!("Ok! {:?}",result.body);},
Err(_) => {}
}
// match result {
// Ok(i) => i,
// _ => false
// }
// match result {
// Message<PoseReport> => println!("")
// }
// eprintln!(
// "{:?} {:?}",
// typed_message.body.sensor, typed_message.body.pos
// );
}
});
Self {}
}
}
// pub fn setup_threaded_tracker_simple(mut commands: Commands) {
// commands.spawn(Tracker::new());
// }
// impl TypedBodylessHandler for Tracker {
// type Item = PoseReport;
// fn handle_typed_bodyless(&mut self, header: &vrpn::MessageHeader) -> Result<HandlerCode> {
@ -92,41 +124,13 @@ impl Tracker {
// }
// }
impl TypedHandler for Tracker {
type Item = PoseReport;
fn handle_typed(&mut self, msg: &Message<PoseReport>) -> Result<HandlerCode> {
println!("{:?}\n {:?}", msg.header, msg.body);
Ok(HandlerCode::ContinueProcessing)
}
}
impl FromWorld for Tracker {
fn from_world(world: &mut World) -> Self {
Self {}
}
}
// impl TypedHandler for Tracker {
// type Item = PoseReport;
// fn handle_typed(&mut self, msg: &Message<PoseReport>) -> Result<HandlerCode> {
// println!("{:?}\n {:?}", msg.header, msg.body);
// Ok(HandlerCode::ContinueProcessing)
// }
// }
#[derive(Debug)]
struct TrackerHandler;
@ -151,27 +155,29 @@ pub fn setup_threaded_tracker(mut commands: Commands) {
let mut cookie_buf = Bytes::from(&cookie_buf[..]);
CookieData::unbuffer_ref(&mut cookie_buf)
.and_then(|msg| check_ver_nonfile_compatible(msg.version)).unwrap();
.and_then(|msg| check_ver_nonfile_compatible(msg.version))
.unwrap();
let mut endpoint = EndpointSyncTcp::new(stream);
let mut dispatcher = TypeDispatcher::new();
let _ = dispatcher.add_typed_handler(Box::new(TrackerHandler {}), None).unwrap();
let _ = dispatcher
.add_typed_handler(Box::new(TrackerHandler {}), None)
.unwrap();
// setup a channel
// let (tx, rx) = mpsc::channel();
loop {
// vrpn implementation is rather verbose - we need to see what specific errors
// vrpn implementation is rather verbose - we need to see what specific errors
// should be handled properly!
endpoint.poll_endpoint(&mut dispatcher).unwrap_or_else(|err| {
info!("error from tracker thread {:?}",err);
})
endpoint
.poll_endpoint(&mut dispatcher)
.unwrap_or_else(|err| {
info!("error from tracker thread {:?}", err);
})
// dispatcher.han
}
});
}