use re_chunk::{Chunk, ChunkId};
use re_sdk_types::archetypes::{CoordinateFrame, Pinhole};
use super::super::Ros2MessageParser;
use super::super::definitions::sensor_msgs;
use super::super::util::suffix_image_plane_frame_ids;
use crate::Error;
use crate::parsers::cdr;
use crate::parsers::decode::{MessageParser, ParserContext};
pub struct CameraInfoMessageParser {
image_from_cameras: Vec<[f32; 9]>,
resolutions: Vec<(f32, f32)>,
frame_ids: Vec<String>,
}
impl Ros2MessageParser for CameraInfoMessageParser {
fn new(num_rows: usize) -> Self {
Self {
image_from_cameras: Vec::with_capacity(num_rows),
resolutions: Vec::with_capacity(num_rows),
frame_ids: Vec::with_capacity(num_rows),
}
}
}
impl MessageParser for CameraInfoMessageParser {
fn append(&mut self, ctx: &mut ParserContext, msg: &mcap::Message<'_>) -> anyhow::Result<()> {
let sensor_msgs::CameraInfo {
header,
width,
height,
k,
..
} = cdr::try_decode_message::<sensor_msgs::CameraInfo>(&msg.data)?;
ctx.add_timestamp_cell(crate::util::TimestampCell::from_nanos_ros2(
header.stamp.as_nanos() as u64,
ctx.time_type(),
));
self.frame_ids.push(header.frame_id);
let k_transposed = [
k[0], k[3], k[6], k[1], k[4], k[7], k[2], k[5], k[8], ];
self.image_from_cameras.push(k_transposed.map(|x| x as f32));
self.resolutions.push((width as f32, height as f32));
Ok(())
}
fn finalize(self: Box<Self>, ctx: ParserContext) -> anyhow::Result<Vec<Chunk>> {
let Self {
image_from_cameras,
resolutions,
frame_ids,
} = *self;
let entity_path = ctx.entity_path().clone();
let timelines = ctx.build_timelines();
let image_plane_frame_ids = suffix_image_plane_frame_ids(frame_ids.clone());
let mut components: Vec<_> = Pinhole::update_fields()
.with_many_image_from_camera(image_from_cameras)
.with_many_resolution(resolutions)
.with_many_parent_frame(frame_ids.clone())
.with_many_child_frame(image_plane_frame_ids)
.columns_of_unit_batches()
.map_err(|err| Error::Other(anyhow::anyhow!(err)))?
.collect();
components.extend(
CoordinateFrame::update_fields()
.with_many_frame(frame_ids)
.columns_of_unit_batches()
.map_err(|err| Error::Other(anyhow::anyhow!(err)))?,
);
let pinhole_chunk = Chunk::from_auto_row_ids(
ChunkId::new(),
entity_path.clone(),
timelines.clone(),
components.into_iter().collect(),
)?;
Ok(vec![pinhole_chunk])
}
}