px4_ros_com icon indicating copy to clipboard operation
px4_ros_com copied to clipboard

Problems including frame_transforms.h

Open ripdk12 opened this issue 2 years ago • 3 comments

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?

ripdk12 avatar Nov 22 '22 21:11 ripdk12

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.

MaEtUgR avatar Nov 23 '22 16:11 MaEtUgR

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/

dirksavage88 avatar Dec 04 '22 01:12 dirksavage88

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.

ugupta62 avatar Apr 27 '23 02:04 ugupta62