Robot_localization with IMU and conventions
I tried to go through most of the answered topics about this, but still some things are not clear for me, so I have some more questions :) .
I want to do a multi-sensor fusion with robot_localization
. As a first step I want to use r_l
with one IMU, and later fuse one more IMU and GPS.
The IMU I am using is an SBG that uses the NED notation.
Since r_l
uses ENU notation, I convert the measurements from the IMU from NED -> ENU.
I have deactivated the magnetometer, since it is prone to errors for the environment that I will be using it.
1) I suppose that ENU is valid only if we know the "true north", which in my case I don't, because I don't use the magnetometer. In ENU I suppose we consider that Y axis is looking forward and X to the right, like:
Also, in r_l
documentation it is mentioned:
IMU is placed in its neutral right-side-up position on a flat surface will:
- Measure +9.81 meters per second squared for the Z axis.
- If the sensor is rolled +90 degrees (left side up), the acceleration should be +9.81 meters per second squared for the Y axis.
- If the sensor is pitched +90 degrees (front side down), it should read -9.81 meters per second squared for the X axis.
which results in the ROS convention that X is looking forward and Y to the left, like:
My question is what is the difference between these 2, since no magnetometers are used, and why should I provide the r_l
with IMU data in ENU notation and not just convert NED to the ROS convention and provide it to the r_l
. Additionally, when I provide IMU data in ENU notation Y axis is pointing forward, which is different from the ROS notation in which the X axis is pointing forward. When I move my robot forward, the r_l
outputs movement in the Y axis, but I expected it to output motion in X axis.
2) Since I will fuse many sensors I want everything to be referenced in relevance to the base_link
, which is considered to be the "center" of my robot. If my IMU is not placed on the robot's center, I have two options: a) configure the lever arm alignment of my IMU with the offsets of the IMU in relevance to the robot's center, b) declare a static transformation between the IMU and the center of robot (base_link
).
- If I use the tf2 for a static transformation between the IMU and the
base_link
, will ther_l
transform "automatically" the provided IMU data from the IMU reference frame, using the declared static transformation, and feed them as input to the EKF, or I have to do the transformation with tf2 myself and then provide the transformed data to the EKF? - Does tf2 take into account also the forces except the orientation? For example if I have my IMU placed far from the robot's center the accelerometers will measure different values compared to the case that the IMU would be placed in the robot's center. I suppose that configuring the lever arm alignment, instead of using tf2, will end up in more accurate results since it takes into account the forces and not only the translation/rotation offsets?
My .launch file:
<launch>
<!-- 'sbg imu node', reads the SBG Imu output values, writes the covariance and publishes the message -->
<node pkg="robot_localization_ros1" type="sbg_imu_node" name="sbg_imu_node" output="screen" />
<node pkg="tf2_ros" type="static_transform_publisher" name="sbg_to_base_link" args="0 0 0 0 0 0 base_link sbg_imu" />
<!-- robot_localization EKF node for the SBG Imu frame -->
<node pkg="robot_localization" type="ekf_localization_node" name="robot_localization_ekf_node_sbg_imu" clear_params="true">
<param name="frequency" value="200" />
<param name="sensor_timeout" value="0.2" />
<param name="two_d_mode" value="true" />
<param name="publish_tf" value="true" />
<param name="dynamic_process_noise_covariance" value="false" />
<rosparam param="initial_state">[0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0]</rosparam>
<param name="odom_frame" value="odom" />
<param name="base_link_frame" value="base_link" />
<param name="world_frame" value="odom" />
<param name="debug" value="false" />
<param name="imu0" value="sensors/sbgImu" />
<rosparam param="imu0_config">[false, false, false, <!--x, y, z-->
false, false, false, <!--roll, pitch, yaw-->
false, false, false, <!--linVel_x, linVel_y, linVel_z-->
true, true, true, <!--angVel_x, angVel_y, angVel_z-->
true, true, true] <!--linAcc_x, linAcc_y, linAcc_z-->
</rosparam>
<param name="imu0_queue_size" value="10" />
<param name="imu0_remove_gravitational_acceleration" value="true" />
<param name="imu0_differential" value="false" />
<param name="imu0_relative" value="false" />
<remap from="odometry/filtered" to="odometry/filtered_sbg_imu"/>
</node>
</launch>
Asked by GeorgeG on 2020-02-12 06:10:51 UTC
Answers
For the mag data, you'd have to either rotate the IMU so that the "new" X-axis (east) points forward, or just provide a static transform for that data. For the accelerometer and gyro, you can just negate the Y and Z axis values so that everything is ROS-conformant.
The EKF will transform the IMU data using the static transforms you provide before fusing the data. However, I think you'd be wise to just set the lever arms using the SBG calibration tool. I've worked with that exact sensor in the past in an underwater robotics application, and I went that route, rather than using static transforms.
Asked by Tom Moore on 2020-03-23 04:25:23 UTC
Comments