refactor: sdk-dev changes including serial_core refactor and eskin-finger-sdk
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use eskin_finger_sdk::types::FingerSample;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FrameTiming {
|
||||
pub pts_ms: Option<u64>,
|
||||
@@ -7,50 +9,82 @@ pub struct FrameTiming {
|
||||
#[derive(Clone)]
|
||||
pub struct RecordedFrame<F> {
|
||||
pub timing: FrameTiming,
|
||||
pub frame: F
|
||||
pub frame: F,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Recording<F> {
|
||||
pub frames: Vec<RecordedFrame<F>>
|
||||
pub frames: Vec<RecordedFrame<F>>,
|
||||
}
|
||||
|
||||
impl<F> Recording<F> {
|
||||
pub fn new() -> Recording<F> { Self { frames: Vec::new() } }
|
||||
pub fn push(&mut self, ite: RecordedFrame<F>) {
|
||||
self.frames.push(ite);
|
||||
pub fn new() -> Recording<F> {
|
||||
Self {
|
||||
frames: Vec::new(),
|
||||
}
|
||||
}
|
||||
pub fn push(&mut self, item: RecordedFrame<F>) {
|
||||
self.frames.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CsvExporter<F> {
|
||||
type Error: std::error::Error + Send + Sync + 'static;
|
||||
fn csv_header(&self, recording: &Recording<F>) -> Vec<String>;
|
||||
fn csv_row(&self, item: &RecordedFrame<F>) -> anyhow::Result<Vec<String>>;
|
||||
}
|
||||
pub type FingerRecording = Recording<FingerSample>;
|
||||
|
||||
// TODO: CsvImporter
|
||||
pub trait CsvImporter<P> {
|
||||
fn load<R: std::io::Read>(&mut self, reader: R) -> anyhow::Result<Vec<P>>;
|
||||
}
|
||||
|
||||
pub fn write_csv<F, E, W>(
|
||||
recording: &Recording<F>,
|
||||
exporter: &E,
|
||||
writer: W,
|
||||
pub fn export_recording_csv<W>(
|
||||
recording: &Recording<FingerSample>,
|
||||
mut writer: W,
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
E: CsvExporter<F>,
|
||||
W: std::io::Write,
|
||||
{
|
||||
let header = exporter.csv_header(&recording);
|
||||
let mut wrt = csv::Writer::from_writer(writer);
|
||||
wrt.write_record(header)?;
|
||||
for f in &recording.frames {
|
||||
let row = exporter.csv_row(f)?;
|
||||
wrt.write_record(&row)?;
|
||||
// Infer channel count from the first sample's combined_forces (just fz)
|
||||
// We write: timestamp_us, sequence, module, fx, fy, fz
|
||||
let mut wrt = csv::Writer::from_writer(&mut writer);
|
||||
wrt.write_record(["timestamp_us", "sequence", "module", "fx", "fy", "fz"])?;
|
||||
|
||||
for frame in &recording.frames {
|
||||
let s = &frame.frame;
|
||||
wrt.write_record(&[
|
||||
s.timestamp_us.to_string(),
|
||||
s.sequence.to_string(),
|
||||
format!("{:?}", s.combined_forces.module),
|
||||
s.combined_forces.force.fx.to_string(),
|
||||
s.combined_forces.force.fy.to_string(),
|
||||
s.combined_forces.force.fz.to_string(),
|
||||
])?;
|
||||
}
|
||||
|
||||
wrt.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct FingerSampleCsvPacket {
|
||||
pub timestamp_us: u64,
|
||||
pub sequence: u32,
|
||||
pub fz: u32,
|
||||
}
|
||||
|
||||
pub fn import_csv<R: std::io::Read>(
|
||||
reader: R,
|
||||
) -> anyhow::Result<Vec<FingerSampleCsvPacket>> {
|
||||
let mut rdr = csv::Reader::from_reader(reader);
|
||||
let mut packets = Vec::new();
|
||||
|
||||
for result in rdr.records() {
|
||||
let record = result?;
|
||||
if record.len() < 6 {
|
||||
continue;
|
||||
}
|
||||
let timestamp_us = record.get(0).unwrap_or("0").parse::<u64>().unwrap_or(0);
|
||||
let sequence = record.get(1).unwrap_or("0").parse::<u32>().unwrap_or(0);
|
||||
let fz = record.get(5).unwrap_or("0").parse::<u32>().unwrap_or(0);
|
||||
|
||||
packets.push(FingerSampleCsvPacket {
|
||||
timestamp_us,
|
||||
sequence,
|
||||
fz,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(packets)
|
||||
}
|
||||
Reference in New Issue
Block a user