Issue with custom messages depending on builtin_interfaces
I'm having trouble when working with custom messages that use the builtin_interfaces/msg/Header. When trying to fill in the timestamp it the build complains that the vendored Time is not the same as the one for the message.
I saw in https://github.com/ros2-rust/ros2_rust/issues/385 that the interfaces are vendored and that we should remove the builtin_interfaces from the workspace, however when I do that the custom messages fail to build because they depend on them.
error: failed to select a version for the requirement `builtin_interfaces = "*"`
version 1.2.1 is yanked
location searched: crates.io index
required by package `custom_msgs v0.0.1 (<...>/install/custom_msgs/share/custom_msgs/rust)`
... which satisfies dependency `custom_msgs = "*"` (locked to 0.0.1) of package `test v0.1.0`
---
Failed <<< test [1.47s, exited with code 1]
And this is due because the generated rust crate for the message package contains this:
[package]
name = "custom_msgs"
version = "0.0.1"
edition = "2021"
[dependencies]
rosidl_runtime_rs = "0.4"
serde = { version = "1", optional = true, features = ["derive"] }
serde-big-array = { version = "0.5.1", optional = true }
service_msgs = "*"
geometry_msgs = "*"
builtin_interfaces = "*" # <----- This fails during build of a ros2_rust node that depends on this custom message package
std_msgs = "*"
[features]
serde = ['dep:serde', 'dep:serde-big-array', 'rosidl_runtime_rs/serde', 'service_msgs/serde', 'geometry_msgs/serde', 'builtin_interfaces/se
rde', 'std_msgs/serde']
How should I get this working?
Have you built your workspace with your custom package and then sourced the $ws/install/setup.bash before colcon build your package?
I had the same issue and resolved with the source.
Yes, I quickly double checked but I can confirm that this doesn't change anything for me. If I add the builtin_interfaces packages to my custom messages, as it should be and then try to put rclrs time inside of the message timestamp field it errors.
fn publish_gimbal_pose(gimbal_pub: &Publisher<GimbalPose>, gimbal_controller: &GimbalController) {
let t = rclrs::Clock::system().now();
let timestamp = t.to_ros_msg().unwrap();
let mut msg = axr_msgs::msg::GimbalPose::default();
msg.header.frame_id = String::new();
msg.header.stamp = timestamp;
msg.pitch = gimbal_controller.pitch().get::<radian>();
msg.roll = gimbal_controller.roll().get::<radian>();
msg.yaw = gimbal_controller.yaw().get::<radian>();
if let Err(e) = gimbal_pub.publish(&msg) {
error!("Failed to publish GimbalPose: {}", e);
}
}
With the following error:
error[E0308]: mismatched types
--> src/main.rs:225:24
|
225 | msg.header.stamp = timestamp;
| ---------------- ^^^^^^^^^ expected `builtin_interfaces::msg::Time`, found `Time`
| |
| expected due to the type of this binding
|
= note: `Time` and `builtin_interfaces::msg::Time` have similar names, but are actually distinct types
note: `Time` is defined in crate `rclrs`
--> ros2-dev/install/rclrs/share/rclrs/rust/src/vendor/builtin_interfaces/msg.rs:223:1
|
223 | pub struct Time {
| ^^^^^^^^^^^^^^^
note: `builtin_interfaces::msg::Time` is defined in crate `builtin_interfaces`
--> ros2-dev/install/builtin_interfaces/share/builtin_interfaces/rust/src/msg.rs:185:1
|
185 | pub struct Time {
| ^^^^^^^^^^^^^^^
I have to resort to this hack to work around it:
fn hack_convert_vendored_time_to_workspace_time(
time: rclrs::Time,
) -> builtin_interfaces::msg::Time {
let t = time.to_ros_msg().unwrap();
builtin_interfaces::msg::Time {
sec: t.sec,
nanosec: t.nanosec,
}
}
The error message is different. This is a known issue: https://github.com/ros2-rust/ros2_rust/issues/385