Skip to content

Commit

Permalink
rc.3
Browse files Browse the repository at this point in the history
  • Loading branch information
stelzo committed May 21, 2024
1 parent d7d51e0 commit b5fc791
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 49 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ros_pointcloud2"
version = "0.5.0-rc.2"
version = "0.5.0-rc.3"
edition = "2021"
authors = ["Christopher Sieh <stelzo@steado.de>"]
description = "Customizable conversions for working with sensor_msgs/PointCloud2."
Expand Down Expand Up @@ -32,10 +32,10 @@ rust-version = "1.63"
[dependencies]
rosrust_msg = { version = "0.1", optional = true }
rosrust = { version = "0.9.11", optional = true }
r2r = { version = "0.8.4", optional = true }
r2r = { version = "0.9", optional = true }
rayon = { version = "1", optional = true }
nalgebra = { version = "0.32.5", optional = true, default-features = false }
rpcl2-derive = { version = "0.2.0", optional = true }
nalgebra = { version = "0.32", optional = true, default-features = false }
rpcl2-derive = { version = "0.2", optional = true }
memoffset = { version = "0.9", optional = true }

sensor_msgs = { version = "*", optional = true }
Expand Down
43 changes: 16 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

ros_pointcloud2 uses its own type for the message `PointCloud2Msg` to keep the library framework agnostic. ROS1 and ROS2 are supported with feature flags.

Get started with the example below, check out the other use cases in the `examples` folder or see the [Documentation](https://docs.rs/ros_pointcloud2/0.5.0-rc.1/) for a complete guide.
Get started with the example below, check out the other use cases in the `examples` folder or see the [Documentation](https://docs.rs/ros_pointcloud2/0.5.0-rc.3/) for a complete guide.

## Quickstart

Expand Down Expand Up @@ -57,9 +57,9 @@ You can use `rosrust` and `r2r` by enabling the respective feature:

```toml
[dependencies]
ros_pointcloud2 = { version = "*", features = ["r2r_msg", "derive"]}
ros_pointcloud2 = { version = "*", features = ["r2r_msg"]}
# or
ros_pointcloud2 = { version = "*", features = ["rosrust_msg", "derive"]}
ros_pointcloud2 = { version = "*", features = ["rosrust_msg"]}
```

### rclrs (ros2_rust)
Expand All @@ -68,7 +68,7 @@ Features do not work properly with `rcrls` because the messages are linked exter

```toml
[dependencies]
ros_pointcloud2 = { git = "https://github.com/stelzo/ros_pointcloud2", tag = "v0.5.0-rc.1_rclrs" }
ros_pointcloud2 = { git = "https://github.com/stelzo/ros_pointcloud2", tag = "v0.5.0-rc.3_rclrs" }
```

Also, indicate the following dependencies to your linker inside the `package.xml` of your package.
Expand All @@ -84,32 +84,21 @@ Please open an issue or PR if you need other integrations.
## Performance

This library offers a speed up when compared to PointCloudLibrary (PCL) conversions but the specific factor depends heavily on the use case and system.
The `_vec` conversions are on average ~6x faster than PCL while the single core iteration `_iter` functions are around ~2x faster.
Parallelization with `_par_iter` gives a ~9x speed up compared to an OpenMP accelerated PCL pipeline.

The results are measured on an Intel i7-14700 with benchmarks from [this repository](https://github.com/stelzo/ros_pcl_conv_bench).
See [this repository](https://github.com/stelzo/ros_pcl_conv_bench) for a detailed benchmark.

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

## `no_std` Environments

The `_iter` conversions are compatible with `#[no_std]` environments if 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. Only `nalgebra` can be added as an additional feature in this case.

## License

Licensed under either of

- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

### type-layout

For compatibility reasons, a patched version of `type-layout` is included in this repository. The original crate can be found [here](https://crates.io/crates/type-layout). After the patch is applied on the original `type-layout` crate ([PR](https://github.com/LPGhatguy/type-layout/pull/9)), the local dependency will be changed to the original crate.
### License

`type-layout` is licensed under MIT or Apache-2.0 and Copyright by Lucien Greathouse. The changes are highlighted in the diff of the PR.
<sup>
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
</sup>

### Contribution
<br>

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.
</sub>
13 changes: 10 additions & 3 deletions src/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,16 @@ where
return Err(MsgConversionError::DataLengthMismatch);
}

let last_offset = offsets.last().expect("Dimensionality is 0.");
let last_offset = match offsets.last() {
Some(offset) => *offset,
None => return Err(MsgConversionError::DataLengthMismatch),
};

let last_pdata = match pdata.last() {
Some(pdata) => pdata,
None => return Err(MsgConversionError::DataLengthMismatch),
};

let last_pdata = pdata.last().expect("Dimensionality is 0.");
let size_with_last_pdata = last_offset + last_pdata.1.size();
if size_with_last_pdata > point_step_size {
return Err(MsgConversionError::DataLengthMismatch);
Expand Down Expand Up @@ -496,4 +503,4 @@ mod test {
let first_right = right.next();
assert!(first_right.is_none());
}
}
}
28 changes: 15 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
//! - [`try_into_iter`](PointCloud2Msg::try_into_iter)
//!
//! These feature predictable performance but they do not scale well with large clouds. Learn more about that in the [performance section](https://github.com/stelzo/ros_pointcloud2?tab=readme-ov-file#performance) of the repository.
//! The iterators are useful when your conversions are more complex than a simple copy or you the cloud is small enough.
//! The iterators are useful when your conversions are more complex than a simple copy or the cloud is small enough.
//!
//! When the cloud is getting larger or you are doing a lot of processing per point, switch to the parallel iterators.
//! - [`try_into_par_iter`](PointCloud2Msg::try_into_par_iter) requires `rayon` feature
//! - [`try_from_par_iter`](PointCloud2Msg::try_from_par_iter) requires `rayon` + `derive` feature
//! - [`try_from_par_iter`](PointCloud2Msg::try_from_par_iter) requires `rayon` feature
//!
//! For ROS interoperability, there are integrations avialable with feature flags. If you miss a message type, please open an issue or a PR.
//! See the [`ros`] module for more information on how to integrate more libraries.
Expand Down Expand Up @@ -56,10 +56,10 @@
//! - r2r_msg — Integration for the ROS2 library [r2r](https://github.com/sequenceplanner/r2r).
//! - rosrust_msg — Integration with the [rosrust](https://github.com/adnanademovic/rosrust) library for ROS1 message types.
//! - (rclrs_msg) — Integration for ROS2 [rclrs](https://github.com/ros2-rust/ros2_rust) but it currently needs [this workaround](https://github.com/stelzo/ros_pointcloud2?tab=readme-ov-file#rclrs-ros2_rust).
//! - derive *(enabled by default)* — Enables the `_vec` functions and offers helpful custom point derive macros for the [`PointConvertible`] trait.
//! - rayon — Parallel iterator support for `_par_iter` functions. [`PointCloud2Msg::try_from_par_iter`] additionally needs the 'derive' feature.
//! - derive — Offers implementations for the [`PointConvertible`] trait needed for custom points.
//! - rayon — Parallel iterator support for `_par_iter` functions.
//! - nalgebra — Predefined points offer a nalgebra typed getter for coordinates (e.g. [`xyz`](points::PointXYZ::xyz)).
//! - std *(enabled by default)* — Use the standard library. `no_std` only works standalone or with the 'nalgebra' feature.
//! - std *(enabled by default)* — Omit this feature to use this library in no_std environments. ROS integrations and 'rayon' will not work with no_std.
//!
//! # Custom Points
//! Implement [`PointConvertible`] for your point with the `derive` feature or manually.
Expand Down Expand Up @@ -125,10 +125,11 @@
//! ```
#![crate_type = "lib"]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc(html_root_url = "https://docs.rs/ros_pointcloud2/0.5.0-rc.2")]
#![doc(html_root_url = "https://docs.rs/ros_pointcloud2/0.5.0-rc.3")]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#![warn(clippy::unwrap_used)]
#![warn(clippy::expect_used)]
#![warn(clippy::cargo)]
#![warn(clippy::std_instead_of_core)]
#![warn(clippy::alloc_instead_of_core)]
Expand Down Expand Up @@ -474,7 +475,7 @@ fn ordered_field_names<const N: usize, C: PointConvertible<N>>() -> Vec<String>
name,
ty: _,
size: _,
} => name.to_string(),
} => name.as_ref().into(),
_ => unreachable!("Fields must be filtered before."),
})
.collect()
Expand All @@ -492,12 +493,13 @@ impl PointCloud2Msg {
let field_names = ordered_field_names::<N, C>();
debug_assert!(field_names.len() == N);

let layout = KnownLayoutInfo::try_from(C::layout())?;
debug_assert!(field_names.len() <= layout.fields.len());
let target_layout = KnownLayoutInfo::try_from(C::layout())?;
debug_assert!(field_names.len() <= target_layout.fields.len());
debug_assert!(self.fields.len() <= target_layout.fields.len());

let mut offset: u32 = 0;
let mut field_counter = 0;
for f in layout.fields.iter() {
for f in target_layout.fields.iter() {
match f {
PointField::Field {
datatype,
Expand Down Expand Up @@ -913,13 +915,13 @@ pub trait PointConvertible<const N: usize>:
fn layout() -> LayoutDescription;
}

#[derive(Debug)]
#[derive(Debug, Clone)]
enum PointField {
Padding(u32),
Field { size: u32, datatype: u8, count: u32 },
}

#[derive(Debug)]
#[derive(Debug, Clone)]
struct KnownLayoutInfo {
fields: Vec<PointField>,
}
Expand Down Expand Up @@ -1445,4 +1447,4 @@ impl FromBytes for u8 {
fn from_le_bytes(bytes: PointDataBuffer) -> Self {
Self::from_le_bytes([bytes[0]])
}
}
}
2 changes: 1 addition & 1 deletion src/points.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,4 +817,4 @@ impl PointConvertible<6> for PointXYZNormal {
LayoutField::padding(8),
])
}
}
}
2 changes: 1 addition & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ pub use crate::ros::*;
pub use rayon::prelude::*;

#[cfg(feature = "derive")]
pub use rpcl2_derive::*;
pub use rpcl2_derive::*;

0 comments on commit b5fc791

Please sign in to comment.