Robotics StackExchange | Archived questions

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.

image description

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:

image description

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:

image description

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).

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

Comments

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