I followed the basic C++ publisher tutorial to create a minimal publisher. This works. I then followed the basic launch file tutorial to create a launch file for the minimal publisher. This also works. I then try to follow the composable node tutorial to modify the minimal publisher, and this does not work; after updating the C++ code, launch file, package.xml, and CMakeLists.txt, running the launch file fails with the following error with ROS2 Humble (Ubuntu 20.04, NVIDIA ROS2 buildfarm):
user@computer:~/workspaces/composable$ ros2 launch cpp_pubsub talker.launch.py
[INFO] [launch]: All log files can be found below /home/bgarage/.ros/log/2024-06-26-10-57-31-278954-bgarage-tp101-1016491
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [component_container-1]: process started with pid [1016547]
[component_container-1] [INFO] [1719424651.596867939] [a_buncha_nodes]: Load Library: /home/bgarage/workspaces/composable/install/cpp_pubsub/lib/libtalker_component.a
[component_container-1] [ERROR] [1719424651.596994147] [a_buncha_nodes]: Failed to load library: Could not load library dlopen error: /home/bgarage/workspaces/composable/install/cpp_pubsub/lib/libtalker_component.a: invalid ELF header, at /tmp/binarydeb/ros-humble-rcutils-5.1.6/src/shared_library.c:99
[ERROR] [launch_ros.actions.load_composable_nodes]: Failed to load node 'test_name' of type 'talker::MinimalPublisher' in container '/a_buncha_nodes': Failed to load library: Could not load library dlopen error: /home/bgarage/workspaces/composable/install/cpp_pubsub/lib/libtalker_component.a: invalid ELF header, at /tmp/binarydeb/ros-humble-rcutils-5.1.6/src/shared_library.c:99
And the following error with ROS2 Foxy (Ubuntu 20.04):
bgarage@bgarage-tp101:~/workspaces/composable$ ros2 launch cpp_pubsub talker.launch.py
[INFO] [launch]: All log files can be found below /home/bgarage/.ros/log/2024-06-26-11-04-36-659513-bgarage-tp101-1026834
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [component_container-1]: process started with pid [1026852]
[component_container-1] [INFO] [1719425077.001315326] [a_buncha_nodes]: Load Library: /home/bgarage/workspaces/composable/install/cpp_pubsub/lib/libtalker_component.a
[component_container-1] [ERROR] [1719425077.001467709] [a_buncha_nodes]: Failed to load library: Could not load library LoadLibrary error: /home/bgarage/workspaces/composable/install/cpp_pubsub/lib/libtalker_component.a: invalid ELF header, at /tmp/binarydeb/ros-foxy-rcutils-1.1.5/src/shared_library.c:84
[ERROR] [launch_ros.actions.load_composable_nodes]: Failed to load node 'test_name' of type 'talker::MinimalPublisher' in container '/a_buncha_nodes': Failed to load library: Could not load library LoadLibrary error: /home/bgarage/workspaces/composable/install/cpp_pubsub/lib/libtalker_component.a: invalid ELF header, at /tmp/binarydeb/ros-foxy-rcutils-1.1.5/src/shared_library.c:84
Any idea why this is happening? I made sure to delete logs/
, build/
, and install/
between attempts with different ROS2 distros.
CPP:
#include <chrono>
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using namespace std::chrono_literals;
namespace talker
{
/* This example creates a subclass of Node and uses std::bind() to register a
* member function as a callback from the timer. */
class MinimalPublisher : public rclcpp::Node
{
public:
MinimalPublisher(const rclcpp::NodeOptions & options)
: Node("minimal_publisher", options), count_(0)
{
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
timer_ = this->create_wall_timer(
500ms, std::bind(&MinimalPublisher::timer_callback, this));
}
private:
void timer_callback()
{
auto message = std_msgs::msg::String();
message.data = "Hello, world! " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
size_t count_;
};
}
#include "rclcpp_components/register_node_macro.hpp"
RCLCPP_COMPONENTS_REGISTER_NODE(talker::MinimalPublisher)
Launch file:
from launch import LaunchDescription
from launch_ros.actions import Node
from launch_ros.actions import ComposableNodeContainer
from launch_ros.descriptions import ComposableNode
def generate_launch_description():
ld = LaunchDescription()
ld.add_action(ComposableNodeContainer(
name='a_buncha_nodes',
namespace='',
package='rclcpp_components',
executable='component_container',
composable_node_descriptions=[
ComposableNode(
package='cpp_pubsub',
plugin='talker::MinimalPublisher',
name='test_name',
# ..
extra_arguments=[{'use_intra_process_comms': True}],
),
]
))
return ld
CMakeLists.txt:
cmake_minimum_required(VERSION 3.8)
project(cpp_pubsub)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(rclcpp_components REQUIRED)
add_library(talker_component src/publisher_member_function.cpp)
ament_target_dependencies(talker_component rclcpp std_msgs rclcpp_components)
rclcpp_components_register_node(
talker_component
PLUGIN "talker::MinimalPublisher"
EXECUTABLE talker
)
install(TARGETS talker_component
EXPORT export_talker_component
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(DIRECTORY
launch
DESTINATION share/${PROJECT_NAME}/
)
ament_package()
```