ros2_control - rolling
Loading...
Searching...
No Matches
imu_transform.hpp
1// Copyright 2025 AIT Austrian Institute of Technology GmbH
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*
16 * Authors: Christoph Froehlich
17 * Adapted from
18 * https://github.com/ros-perception/imu_pipeline/blob/jazzy/imu_transformer/include/imu_transformer/tf2_sensor_msgs.h
19 */
20
21#ifndef IMU_SENSOR_BROADCASTER__IMU_TRANSFORM_HPP_
22#define IMU_SENSOR_BROADCASTER__IMU_TRANSFORM_HPP_
23
24#include <Eigen/Dense>
25#include "sensor_msgs/msg/imu.hpp"
26
27namespace imu_sensor_broadcaster
28{
33Eigen::Quaterniond quat_from_euler(double roll, double pitch, double yaw)
34{
35 return Eigen::Quaterniond(
36 Eigen::AngleAxisd(yaw, Eigen::Vector3d::UnitZ()) *
37 Eigen::AngleAxisd(pitch, Eigen::Vector3d::UnitY()) *
38 Eigen::AngleAxisd(roll, Eigen::Vector3d::UnitX()));
39}
40
44inline void transform_covariance(
45 std::array<double, 9> & out, const std::array<double, 9> & in, Eigen::Quaterniond r)
46{
47 Eigen::Map<const Eigen::Matrix<double, 3, 3, Eigen::RowMajor> > cov_in(in.data());
48 Eigen::Map<Eigen::Matrix<double, 3, 3, Eigen::RowMajor> > cov_out(out.data());
49 cov_out = r * cov_in * r.inverse();
50}
51
55inline void do_transform(
56 sensor_msgs::msg::Imu & imu_out, const sensor_msgs::msg::Imu & imu_in, const Eigen::Quaterniond r)
57{
58 imu_out.header = imu_in.header;
59
60 Eigen::Vector3d vel =
61 r * Eigen::Vector3d(
62 imu_in.angular_velocity.x, imu_in.angular_velocity.y, imu_in.angular_velocity.z);
63
64 imu_out.angular_velocity.x = vel.x();
65 imu_out.angular_velocity.y = vel.y();
66 imu_out.angular_velocity.z = vel.z();
67
68 transform_covariance(imu_out.angular_velocity_covariance, imu_in.angular_velocity_covariance, r);
69
70 Eigen::Vector3d accel =
71 r * Eigen::Vector3d(
72 imu_in.linear_acceleration.x, imu_in.linear_acceleration.y, imu_in.linear_acceleration.z);
73
74 imu_out.linear_acceleration.x = accel.x();
75 imu_out.linear_acceleration.y = accel.y();
76 imu_out.linear_acceleration.z = accel.z();
77
78 transform_covariance(
79 imu_out.linear_acceleration_covariance, imu_in.linear_acceleration_covariance, r);
80
81 // Orientation expresses attitude of the new frame_id in a fixed world frame. This is why the
82 // transform here applies in the opposite direction.
83 Eigen::Quaterniond orientation =
84 Eigen::Quaterniond(
85 imu_in.orientation.w, imu_in.orientation.x, imu_in.orientation.y, imu_in.orientation.z) *
86 r.inverse();
87
88 imu_out.orientation.w = orientation.w();
89 imu_out.orientation.x = orientation.x();
90 imu_out.orientation.y = orientation.y();
91 imu_out.orientation.z = orientation.z();
92
93 // Orientation is measured relative to the fixed world frame, so it doesn't change when applying a
94 // static transform to the sensor frame.
95 imu_out.orientation_covariance = imu_in.orientation_covariance;
96}
97} // namespace imu_sensor_broadcaster
98#endif // IMU_SENSOR_BROADCASTER__IMU_TRANSFORM_HPP_