px4_ros_com
px4_ros_com copied to clipboard
Problems including frame_transforms.h
Problem
I'm trying to make use of the helper functions inside the frame_transforms.cpp file. But when I try to include the header with:
#include <px4_ros_com/frame_transforms.h>
I get the following error in colcon build:
/usr/bin/ld: CMakeFiles/sub_pub.dir/src/examples/advertisers/sub_pub.cpp.o: in function `_GLOBAL__sub_I_main':
/home/chris/px4_ros_com_ros2/src/px4_ros_com/include/px4_ros_com/frame_transforms.h:173: undefined reference to `px4_ros_com::frame_transforms::utils::quaternion::quaternion_from_euler(double, double, double)'
/usr/bin/ld: CMakeFiles/sub_pub.dir/src/examples/advertisers/sub_pub.cpp.o: in function `__static_initialization_and_destruction_0':
/home/chris/px4_ros_com_ros2/src/px4_ros_com/include/px4_ros_com/frame_transforms.h:180: undefined reference to `px4_ros_com::frame_transforms::utils::quaternion::quaternion_from_euler(double, double, double)'
More details
While i am using a slightly older version of px4_ros_com (7e25c34) and px4_msgs (daee121) i did double check the CMakeLists.txt and package.xml files:
Changes to CMakeLists
I added Eigen3 to the CMakeLists.txt file:
find_package(Eigen3 REQUIRED)
ament_target_dependencies(${target}
rclcpp
px4_msgs
nav_msgs
Eigen3
)
My take
So it seems like the compiler gets confused and tries to compile the body of the "quaternion_from_euler" function before it has been declared in the header. Why this happens I don't know.
My solution
To combat this issue i just moved the body of the "quaternion_from_euler" from the .cpp file to the header file:
Eigen::Quaterniond quaternion_from_euler(const Eigen::Vector3d &euler)
{
// YPR is ZYX axes
return Eigen::Quaterniond(Eigen::AngleAxisd(euler.z(), Eigen::Vector3d::UnitZ()) *
Eigen::AngleAxisd(euler.y(), Eigen::Vector3d::UnitY()) *
Eigen::AngleAxisd(euler.x(), Eigen::Vector3d::UnitX()));
}
Eigen::Quaterniond quaternion_from_euler(const double roll, const double pitch, const double yaw)
{
return quaternion_from_euler(Eigen::Vector3d(roll, pitch, yaw));
}
Definitely not an elegant solution, but it works, any clue as to how to fix this properly?
PX4 dev call: Since we already have frames in the odometry message: https://github.com/PX4/PX4-Autopilot/blob/d81ca65c6fcd84263a5044b6233eb00be2dbcd8e/msg/VehicleOdometry.msg#L5-L8 possibly ENU needs to be added but we can just convert on the PX4 side as the first thing.
Problem
I'm trying to make use of the helper functions inside the frame_transforms.cpp file. But when I try to include the header with:
#include <px4_ros_com/frame_transforms.h>
I get the following error in colcon build:/usr/bin/ld: CMakeFiles/sub_pub.dir/src/examples/advertisers/sub_pub.cpp.o: in function `_GLOBAL__sub_I_main': /home/chris/px4_ros_com_ros2/src/px4_ros_com/include/px4_ros_com/frame_transforms.h:173: undefined reference to `px4_ros_com::frame_transforms::utils::quaternion::quaternion_from_euler(double, double, double)' /usr/bin/ld: CMakeFiles/sub_pub.dir/src/examples/advertisers/sub_pub.cpp.o: in function `__static_initialization_and_destruction_0': /home/chris/px4_ros_com_ros2/src/px4_ros_com/include/px4_ros_com/frame_transforms.h:180: undefined reference to `px4_ros_com::frame_transforms::utils::quaternion::quaternion_from_euler(double, double, double)'
More details
While i am using a slightly older version of px4_ros_com (7e25c34) and px4_msgs (daee121) i did double check the CMakeLists.txt and package.xml files:
Changes to CMakeLists
I added Eigen3 to the CMakeLists.txt file:
find_package(Eigen3 REQUIRED) ament_target_dependencies(${target} rclcpp px4_msgs nav_msgs Eigen3 )
My take
So it seems like the compiler gets confused and tries to compile the body of the "quaternion_from_euler" function before it has been declared in the header. Why this happens I don't know.
My solution
To combat this issue i just moved the body of the "quaternion_from_euler" from the .cpp file to the header file:
Eigen::Quaterniond quaternion_from_euler(const Eigen::Vector3d &euler) { // YPR is ZYX axes return Eigen::Quaterniond(Eigen::AngleAxisd(euler.z(), Eigen::Vector3d::UnitZ()) * Eigen::AngleAxisd(euler.y(), Eigen::Vector3d::UnitY()) * Eigen::AngleAxisd(euler.x(), Eigen::Vector3d::UnitX())); } Eigen::Quaterniond quaternion_from_euler(const double roll, const double pitch, const double yaw) { return quaternion_from_euler(Eigen::Vector3d(roll, pitch, yaw)); }
Definitely not an elegant solution, but it works, any clue as to how to fix this properly?
Frame transforms is a shared library. How are you linking the library to your executable/package in the cmakelist?
See: https://www.theconstructsim.com/how-to-create-a-ros2-c-library/
Hi, I'm facing the same issue. I guess it's already linked in the CMakelist.txt
# Add frame_transforms lib
add_library(frame_transforms SHARED src/lib/frame_transforms.cpp)
ament_target_dependencies(frame_transforms Eigen3 geometry_msgs sensor_msgs)
target_include_directories(frame_transforms PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/${PROJECT_NAME}>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}>
)
However, the example on https://www.theconstructsim.com/how-to-create-a-ros2-c-library/ creates another package and then includes that package using ament_target_dependencies in the CMakeList. I guess there is a way to include the transform library without creating another package. Any help in figuring out how to do it will be appreciated.