I built 4 wheels robot that uses diff_driver_cont in ros2_control, the controller get encoders reading to calculate interface status and interface command.

later, I used robot_localization package to fuse encoder reading with imu, the problem is that the diff_controller depends on encoders reading even the ekf sends the odm -> base_link transformation on /tf, which cause that robot pose is right (based on ekf) but when give move order, robot moves as if the wheels have another orientation (the orientation from encoders only).

how can i solve this issue?

enter image description here

diff_cont config:

update_rate: 50

  type: diff_drive_controller/DiffDriveController

  type: joint_state_broadcaster/JointStateBroadcaster


publish_rate: 50.0

base_frame_id: base_link

left_wheel_names: ['ul_wheel_joint','ll_wheel_joint']
right_wheel_names: ['ur_wheel_joint','lr_wheel_joint']

wheels_per_side: 2
wheel_separation: 0.3
wheel_radius: 0.07

use_stamped_vel: false
enable_odom_tf: false

robot_localization config


    frequency: 50.0

    two_d_mode: true

    transform_time_offset: 0.1

    transform_timeout: 0.1

    print_diagnostics: true

    debug: false

    debug_out_file: /path/to/debug/file.txt

    permit_corrected_publication: false

    publish_acceleration: true

    publish_tf: true

    map_frame: map              # Defaults to "map" if unspecified
    odom_frame: odom            # Defaults to "odom" if unspecified
    base_link_frame: base_link      # Defaults to "base_link" if unspecified
    world_frame: odom           # Defaults to the value of odom_frame if unspecified

    odom0: /odom

    odom0_config: [true,  true,  true,
                   false, false, false,
                   false, false, false,
                   false, false, true,
                   false, false, false]

    imu0: /imu/data
    imu0_config: [false, false, false,
                  true,  true,  true,
                  false, false, false,
                  false,  false,  false,
                  false,  false,  false]
  • $\begingroup$ Did you manage to solve this problem? I have the exact same issue as you $\endgroup$
    – scorch
    Sep 24, 2023 at 10:44

1 Answer 1


What do you mean with

robot moves as if the wheels have another orientation (the orientation from encoders only)

The diff-drive robot's wheels don't have a rotation other than the rotation forward/backward.

The controller outputs (i.e., wheels' angular velocity) are calculated from the commands and kinematic parameters only. Odometry (which might be wrong in your case) is not used for this, see this code.

  • $\begingroup$ When the robot receives a rotation command, the heading calculated from encoder readings indicates a greater rotation than what actually occurs. Typically, sensor fusion should adjust the robot's heading using both the IMU and encoders. With the diff_cont issue, even though sensor fusion corrects the robot's pose, when a new movement command is sent, the robot still moves in the direction of the uncorrected pose. You can see this exact behavior in the provided video here (shorturl.at/qvwK4). $\endgroup$ Aug 23, 2023 at 12:17
  • $\begingroup$ after code investigation i found that the diff_cont calculates heading (as it sends odometry on /odom topic) code here (shorturl.at/cOSV3) I think we can subtract a correct factor (the difference between fused heading and encoder calculated heading) from the heading calculated by diff_cont. do you have any other thoughts?, or correct me if there is a better solution $\endgroup$ Aug 23, 2023 at 12:17
  • $\begingroup$ Once again, the diff_drive_controller doesn't use the heading/odometry for calculating the commands. Your robot will drive as you requested but odometry and tf frames are incorrect then? Unfortunately, I can't find a proper ros2 version of the documentation of the robot_localization package. $\endgroup$ Aug 25, 2023 at 7:53
  • $\begingroup$ But having a look at this tutorial, the EKF node can take the odometry from diff_drive_controller as input, fuse it with the IMU data and publish corrected tf. Maybe your issue is a missing remapping of the tf publishers? $\endgroup$ Aug 25, 2023 at 7:54
  • $\begingroup$ See also nav2 docs $\endgroup$ Aug 25, 2023 at 7:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.