Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems including frame_transforms.h #169

Open
ripdk12 opened this issue Nov 22, 2022 · 3 comments
Open

Problems including frame_transforms.h #169

ripdk12 opened this issue Nov 22, 2022 · 3 comments

Comments

@ripdk12
Copy link

ripdk12 commented Nov 22, 2022

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?

@MaEtUgR
Copy link
Member

MaEtUgR commented Nov 23, 2022

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.

@dirksavage88
Copy link

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/

@ugupta62
Copy link

ugupta62 commented Apr 27, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants