Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no_std compatible #18

Merged
merged 1 commit into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ r2r = { version = "0.8.4", optional = true }
rayon = { version = "1", optional = true }
nalgebra = { version = "0", optional = true }
rpcl2_derive = { path = "./rpcl2_derive", optional = true }
type-layout = { version = "0.2", optional = true }
type-layout = { git = "https://github.com/stelzo/type-layout", branch = "syn2", optional = true }

[dev-dependencies]
rand = "0.8"
Expand All @@ -51,8 +51,9 @@ r2r_msg = ["dep:r2r"]
rayon = ["dep:rayon"]
derive = ["dep:rpcl2_derive", "dep:type-layout"]
nalgebra = ["dep:nalgebra"]
std = []

default = ["derive"]
default = ["derive", "std"]

[package.metadata.docs.rs]
features = ["derive", "nalgebra", "rayon"]
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ The results are measured on an Intel i7-14700 with benchmarks from [this reposit

For minimizing the conversion overhead in general, always use the functions that best fit your use case.

## `#[no_std]`

The `_iter` conversions are compatible with `#[no_std]` environments when an allocator is provided. This is due to the fact that names for point fields do not have a maximum length, and PointCloud2 data vectors can have arbitrary sizes. Use `default-features = false` to disable std for this crate.

## License

[MIT](https://choosealicense.com/licenses/mit/)
35 changes: 26 additions & 9 deletions src/iterator.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
//! Iterator implementations for PointCloud2Msg including a parallel iterator for rayon.
//! Iterator implementations for [`PointCloud2Msg`] including a parallel iterator for rayon.
use crate::{
Endian, FieldDatatype, Fields, MsgConversionError, PointCloud2Msg, PointConvertible, PointData,
RPCL2Point,
};

/// The PointCloudIterator provides a an iterator abstraction of the PointCloud2Msg.
#[cfg(not(feature = "std"))]
use alloc::string::String;

#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

#[cfg(not(feature = "std"))]
use alloc::borrow::ToOwned;

/// The PointCloudIterator provides a an iterator abstraction of the [`PointCloud2Msg`].
///
/// The iterator is defined at compile time, so the point has to be described via template arguments.
///
Expand All @@ -19,7 +28,7 @@ use crate::{
/// let msg: r2r::sensor_msgs::msg::PointCloud2 = internal_msg.into();
/// let converted: ros_pointcloud2::PointCloud2Msg = msg.into();
///
/// ros_pointcloud2 supports r2r, rclrs and rosrust as conversion targets out of the box via feature flags.
/// `ros_pointcloud2` supports r2r, rclrs and rosrust as conversion targets out of the box via feature flags.
///
pub struct PointCloudIterator<const N: usize, C>
where
Expand All @@ -28,7 +37,7 @@ where
iteration: usize,
iteration_back: usize,
data: ByteBufferView<N>,
phantom_c: std::marker::PhantomData<C>, // internally used for pdata names array
phantom_c: core::marker::PhantomData<C>, // internally used for pdata names array
}

#[cfg(feature = "rayon")]
Expand Down Expand Up @@ -156,7 +165,10 @@ where
}

struct ByteBufferView<const N: usize> {
#[cfg(feature = "rayon")]
data: std::sync::Arc<[u8]>,
#[cfg(not(feature = "rayon"))]
data: Vec<u8>,
start_point_idx: usize,
end_point_idx: usize,
point_step_size: usize,
Expand All @@ -176,7 +188,10 @@ impl<const N: usize> ByteBufferView<N> {
endian: Endian,
) -> Self {
Self {
#[cfg(feature = "rayon")]
data: std::sync::Arc::<[u8]>::from(data),
#[cfg(not(feature = "rayon"))]
data,
start_point_idx,
end_point_idx,
point_step_size,
Expand All @@ -191,7 +206,7 @@ impl<const N: usize> ByteBufferView<N> {
self.end_point_idx - self.start_point_idx + 1
}

#[inline(always)]
#[inline]
fn point_at(&self, idx: usize) -> RPCL2Point<N> {
let offset = (self.start_point_idx + idx) * self.point_step_size;
let mut pdata = [PointData::default(); N];
Expand Down Expand Up @@ -244,8 +259,8 @@ where
{
type Error = MsgConversionError;

/// Convert a PointCloud2Msg into an iterator.
/// Converting a PointCloud2Msg into an iterator is a fallible operation since the message could contain a subset of the required fields.
/// Convert a [`PointCloud2Msg`] into an iterator.
/// The conversion to an iterator is a fallible operation since the message could contain a subset of the required fields.
///
/// The theoretical time complexity is O(n) where n is the number of fields defined in the message for a single point which is typically small.
/// It therefore has a constant time complexity O(1) for practical purposes.
Expand Down Expand Up @@ -332,7 +347,7 @@ where
iteration: 0,
iteration_back: cloud_length - 1,
data,
phantom_c: std::marker::PhantomData,
phantom_c: core::marker::PhantomData,
})
}
}
Expand All @@ -342,16 +357,18 @@ where
C: Fields<N>,
{
#[inline]
#[must_use]
fn from_byte_buffer_view(data: ByteBufferView<N>) -> Self {
Self {
iteration: 0,
iteration_back: data.len() - 1,
data,
phantom_c: std::marker::PhantomData,
phantom_c: core::marker::PhantomData,
}
}

#[inline]
#[must_use]
pub fn split_at(self, point_index: usize) -> (Self, Self) {
let (left_data, right_data) = self.data.split_at(point_index);
(
Expand Down
Loading
Loading