robot localization package does not fuse imu data

asked 2022-05-12 14:03:34 -0500

Husam gravatar image

updated 2022-05-12 14:11:21 -0500

Hi ! I'm using ros2 galactic to build a differential drive robot. I'm trying to fuse the encoder wheels odometry with the bno055 imu data I'm publishing the odom msg and the odom to base_link tf in the odom node , and publishing the imu msg and base_link to imu_link tf using urdf file .

everything looks fine up to this point So , now i'm trying to fuse the odom data with the imu data using robot localization package this is my ekf config file

ekf config file

ekf_filter_node: ros__parameters:

    frequency: 30.0

    two_d_mode: true

    publish_acceleration: true

    publish_tf: false

    #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" ifunspecified
    world_frame: odom           # Defaults to the value ofodom_frame if unspecified

    odom0: /odometry
    odom0_config: [false,  false,  false,
                   false, false, true,
                   true, true, false,
                   false, false, true,
                   false, false, false]

    imu0: bno055/imu
    imu0_config: [false, false, false,
                  false,  false,  true,
                  false, false, false,
                  false, false, true,
                  true, false, false]

the ekf_filter_node subscribe to both topics and also everything looks fine , however when I hold the robot and rotate the wheels using keyboard teleport the robot in rviz moves even though the physical robot stand still. it looks like there is no imu at all . note : I checked the Imu data in rviz in looks fine as well. any help will be great. this is my odom code

def __init__(self):

        super().__init__('odometry_node')                                   #node name
        self.nodename = "odometry_node"
        self.get_logger().info(f"-I- {self.nodename} started") 


        #### parameters #######
        self.rate_hz = self.declare_parameter("rate_hz", 10.0).value # the rate at which to publish the transform
        self.create_timer(1.0/self.rate_hz, self.update)
        self.base_width = float(self.declare_parameter('base_width', 0.185).value)  # The wheel base width in meters
        self.gear_ratio = float(self.declare_parameter('gear_ratio', 20).value)  # The gearbox ratio
        self.wheel_radius = float(self.declare_parameter('wheel_radius', 0.05).value)  # The wheel radius in meter
        self.base_frame_id = self.declare_parameter('base_frame_id',
                                                'base_link').value  # the name of the base frame of the robot
        self.odom_frame_id = self.declare_parameter('odom_frame_id',
                                                'odom').value  # the name of the odometry reference frame

        #internal data
        self.angle_left = 0.0
        self.angle_right = 0.0  
        self.omega_left = 0.0
        self.omega_right = 0.0          
        self.x = 0.0
        self.y = 0.0
        self.th = 0.0
        self.dx = 0.0
        self.dr = 0.0
        self.then = self.get_clock().now()

        #subscriptions
        self.create_subscription(Float32, "left_angle", self.lwheel_callback, 10)
        self.create_subscription(Float32, "right_angle", self.rwheel_callback, 10)
        self.create_subscription(Float32, "left_omega", self.lomega_callback, 10)
        self.create_subscription(Float32, "right_omega", self.romega_callback, 10)

        self.odom_pub = self.create_publisher(Odometry, "odom", 10)
        self.odom_broadcaster = TransformBroadcaster(self)

    def update(self):
        now = self.get_clock().now()
        elapsed = now - self.then
        self.then = now
        elapsed = elapsed.nanoseconds / NS_TO_SEC

        #calculate odometry


        #forward kinematics
        self.dr = (self.wheel_radius/( 2* self.base_width))*(self.omega_right - self.omega_left)
        self.dx = 0.5 * self.wheel_radius * (self.omega_right + self.omega_left)
        #Compute odometry in typical way given the velocities of the robot
        delta_x = (self.dx * cos(self.th)) * elapsed
        delta_y = (self.dx * sin(self.th)) * elapsed
        delta_th ...
(more)
edit retag flag offensive close merge delete