I'm using a two-fixed-wheeled differential robot with Nav2 on ROS2 Humble, I succesfully achieved to code a standard odom publisher which publishes on /odom and /tf topics like this:
void OdomPublisherNode::timerCallback()
{
// Calculate current time and dt
current_time = now();
double dt = (current_time - last_time).seconds();
// Calculate delta x, delta y and delta th
double delta_x = (vx * cos(th) - vy * sin(th)) * dt;
double delta_y = (vx * sin(th) + vy * cos(th)) * dt;
double delta_th = vth * dt;
x += delta_x;
y += delta_y;
th += delta_th;
//Only for logging
degrees = fmod((th * 180.0)/M_PI,360);
RCLCPP_DEBUG(this->get_logger(), "Position on X: %.2f | Position on Y: %.2f | Orientation (TH) : %.2f º", x , y, degrees );
// Create TransformStamped
geometry_msgs::msg::TransformStamped odom_trans;
odom_trans.header.stamp = current_time;
odom_trans.header.frame_id = "odom";
odom_trans.child_frame_id = "base_link";
odom_trans.transform.translation.x = x;
odom_trans.transform.translation.y = y;
odom_trans.transform.translation.z = 0.0;
// Create tf2::Quaternion
tf2::Quaternion tf2_quat;
tf2_quat.setRPY(0, 0, th); // RPY: Roll, Pitch, Yaw
// Create geometry_msgs::msg::Quaternion and fill
geometry_msgs::msg::Quaternion odom_quat;
odom_quat.x = tf2_quat.x();
odom_quat.y = tf2_quat.y();
odom_quat.z = tf2_quat.z();
odom_quat.w = tf2_quat.w();
odom_trans.transform.rotation = odom_quat;
// Publish tf
tf_broadcaster->sendTransform(odom_trans);
// Create odom msg
nav_msgs::msg::Odometry odom;
odom.header.stamp = current_time;
odom.header.frame_id = "odom";
// Fill position and orientation and speed
odom.pose.pose.position.x = x;
odom.pose.pose.position.y = y;
odom.pose.pose.position.z = 0.0;
odom.pose.pose.orientation = odom_quat;
odom.child_frame_id = "base_link";
odom.twist.twist.linear.x = vx;
odom.twist.twist.linear.y = vy;
odom.twist.twist.angular.z = vth;
// Publish odometry on /odom
odom_pub->publish(odom);
tf2_msgs::msg::TFMessage tf_message;
tf_message.transforms.push_back(odom_trans);
last_time = current_time;
}
Describe the bug I connected a D435i Intel Realsense camera with integrated IMU, which publishes on camera/camera/imu topic
While using the EKF node, my robot does not recognize that it is stationary, even though its wheels are spinning (constantly slipping). So, in Rviz2, when executing Nav2, the robot appears to move as if it never slipped. (I already changed the nav2_params.yaml setting to read from /odometry/filtered topic, which is publishing the EKF node)
To Reproduce Steps to reproduce the behavior:
/camera/camera/imu (SensorIMU) Message example:
header:
stamp:
sec: 1710490254
nanosec: 384912640
frame_id: camera_imu_optical_frame
orientation:
x: 0.0
y: 0.0
z: 0.0
w: 0.0
orientation_covariance:
- -1.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
- 0.0
angular_velocity:
x: 0.001745329238474369
y: -0.012217304669320583
z: 0.0
angular_velocity_covariance:
- 0.01
- 0.0
- 0.0
- 0.0
- 0.01
- 0.0
- 0.0
- 0.0
- 0.01
linear_acceleration:
x: -0.19613298773765564
y: -9.688969612121582
z: -0.0784531980752945
linear_acceleration_covariance:
- 0.01
- 0.0
- 0.0
- 0.0
- 0.01
- 0.0
- 0.0
- 0.0
- 0.01
/odom (Odometry) message:
header:
stamp:
sec: 1710490360
nanosec: 225816625
frame_id: odom
child_frame_id: base_link
pose:
pose:
position:
x: 0.3328242252657941
y: -0.0003743422538225482
z: 0.0
orientation:
x: 0.0
y: 0.0
z: -0.016578521394064526
w: 0.9998625668702606
covariance:
- 0.0
- 0.0 .... (all zeros)
twist:
twist:
linear:
x: 0.20350000000000001
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: -0.0482142857142857
covariance:
- 0.0
- 0.0 (all zeros) ....
EKF config file:
ekf_filter_node:
ros__parameters:
use_sim_time: false
frequency: 10.0
sensor_timeout: 0.1
two_d_mode: true
transform_time_offset: 0.0
transform_timeout: 0.0
print_diagnostics: true
publish_tf: true
publish_acceleration: false
reset_on_time_jump: true
odom0: odom # Odometry published from node mentioned above
odom0_config: [true, true, false,
false, false, true,
false, false, false,
false, false, false,
false, false, false]
odom0_queue_size: 5
odom0_nodelay: false
odom0_differential: false
odom0_relative: false
odom0_pose_rejection_threshold: 5.0
odom0_twist_rejection_threshold: 1.0
imu0: camera/camera/imu # Intel Realsense D435i IMU topic using unite_imu_method=2
imu0_config: [false, false, false,
false, false, false,
false, false, false,
true, true, true,
true, true, true]
imu0_nodelay: false
imu0_differential: false
imu0_relative: true
imu0_queue_size: 7
imu0_pose_rejection_threshold: 0.8 # Note the difference in parameter names
imu0_twist_rejection_threshold: 0.8 #
imu0_linear_acceleration_rejection_threshold: 0.8 #
imu0_remove_gravitational_acceleration: true
process_noise_covariance: [0.05, 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, 0.05, 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, 0.06, 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, 0.03, 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, 0.03, 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, 0.06, 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, 0.025, 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, 0.025, 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, 0.04, 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, 0.01, 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, 0.01, 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, 0.02, 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, 0.2, 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, 0.2, 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, 0.2]
initial_estimate_covariance: [1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9, 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, 1e-9]
Expected behavior I expected that the EKF filter node smoothed something on its /tf and /odom publications but it is not doing it.
Desktop (please complete the following information):
- OS: Ubuntu 22.04
- ROS Distribution: Humble
robot_localization
Package Version: 3.5.2