ros2_rust
ros2_rust copied to clipboard
Add rosout logging to rclrs
The purpose of this PR is to add logging macros that replicate the logging interface provided by the rclcpp and rclpy interfaces, while aiming to provide an idiomatic rust interface.
This work is based on the initial work from here and here.
Examples of the interfaces provided:
log_debug!(&node.name(), "Simple message");
log_debug!(&node.name(), "Simple message {some_variable}");
log_fatal!(&node.name(), "Simple message from {}", node.name());
log_warn!(&node.name(), LogConditions::once(), "Only log this the first time");
log_error!(&node.name(),
LogConditions::skip_first_throttle(Duration::from_millis(1000)),
"Noisy error that we expect the first time");
log_info!(&node.name(), LogConditions { occurs: LoggingOccurrence::Always,
publish_interval: Duration::from_millis(1000),
log_if_true: count % 10 == 0, },
"Manually constructed LogConditions");
The macros make use of the LogConditions struct which provides the control over the logging, e.g. throttling, occurrence (once, skip first), etc.
The most common control constructs can be instantiated using the provided builder functions, e.g.
/// Only log the message on the first occurrence
LogConditions::once()
/// Only log the message at the specified duration
LogConditions::throttle(Duration)
/// Only log the message if the condition is true.
LogConditions::log_if_true(<some expression>)
Known Issues
~~1. The is currently an issue on node closure (as we process the rcl_node_fini call) where the "impl" pointer appears to be "null" when we try too fini the rosout publisher (in rcl_logging_rosout_fini_publisher_for_node). The rest of the node closure occurs successfully. Note: the rosout usage can be disabled with --ros-args --disable-rosout-logs and the error will not occur.~~
This issue has been addressed in the latest commit. I believe that the issue was caused by the rcl_node variable in builder.rs going out of scope during the "drop" sequence. The fix is to allocate the rcl_node on the heap (using Box).
(As a side note: technically, we may have the same issue with the Context object).
2. We use static variables to facilitate the "once", "skip_first", and throttling functionality, however, I believe it would be preferred
to use the lazy_static. At this moment, our rust compiler is 1.79 and therefore the lazy_static is not regarded as stable.