ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

I'd recommend having a quick look at REP-105, just so you have a solid understanding of the assumptions about coordinate frames in ROS. With the exeception of the earth frame, r_l conforms to those standards.

In your case, you want the base_link_frame to be the coordinate frame that is "affixed" to your robot's origin. All velocities that you generate from your wheel encoder data should be given in this frame. So, if your robot is moving forward at 1.0 meters/sec, the x component of velocity in the base_link frame will be 1.0, no matter which way your robot is facing.

For your wheel odometry, you need to at least fill out your base_link velocity, and set the child_frame_id in the nav_msgs/Odometry message to be base_link (or whatever you want to name your robot's base frame).

I'd recommend having a quick look at REP-105, just so you have a solid understanding of the assumptions about coordinate frames in ROS. With the exeception exception of the earth frame, r_l conforms to those standards.

In your case, you want the base_link_frame to be the coordinate frame that is "affixed" to your robot's origin. All velocities that you generate from your wheel encoder data should be given in this frame. So, if your robot is moving forward at 1.0 meters/sec, the x component of velocity in the base_link frame will be 1.0, no matter which way your robot is facing.

For your wheel odometry, you need to at least fill out your base_link velocity, and set the child_frame_id in the nav_msgs/Odometry message to be base_link (or whatever you want to name your robot's base frame).

I'd recommend having a quick look at REP-105, just so you have a solid understanding of the assumptions about coordinate frames in ROS. With the exception of the earth frame, r_l conforms to those standards.

In your case, you want the base_link_frame to be the coordinate frame that is "affixed" to your robot's origin. All velocities that you generate from your wheel encoder data should be given in this frame. So, if your robot is moving forward at 1.0 meters/sec, the x component of velocity in the base_link frame will be 1.0, no matter which way your robot is facing.

For your wheel odometry, you need to at least fill out your base_link velocity, and set the child_frame_id in the nav_msgs/Odometry message to be base_link (or whatever you want to name your robot's base frame).

EDIT in response to comment questions:

what about the parent frame id of wheel odometry as "odom" is already being used by rtabmap?

That's up to you. Nothing will happen if you also make that frame odom, since publishing odometry messages doesn't actually do anything to the tf tree. Those frame_id values just describe what frame the data is in. However, if you make that frame odom and then try to fuse the pose data from both rtabmap and your odometry into the EKF, you definitely will have problems, because, as you stated, they aren't the same frame. But you should just use the velocity data from your odometry anyway. The EKF doesn't like having two sources of pose data, unless they both agree, and they won't.

also, the camera_link frame is not at the center of the robot. Lets say i publish a static transform from camera_link to base_link, what do i set my wheel odom child frame to be? Sorry. I'm very confused about this.

Wheel odometry child_frame_id should be the base_link_frame value, whatever that is. Doesn't matter if there are sensors mounted to your robot. The robot's velocity is relative to its centroid, no matter what's affixed to it.

I'm afraid this particular setup is a bit awkward for r_l. First, if rtabmap is publishing data into a frame that is relative to base_link, that's going to be an issue. All pose data for the EKF needs to either be in the world frame (e.g., odom), or needs to have a transform _to_ that world frame. The rule basically comes down to this: don't fuse pose data that comes from a frame_id that is a child of the base_link_frame.

If your camera is not mounted at the origin, you'll actually have to do some extra legwork. I really don't know enough about rtabmap to say with certainty what its data looks like. If it were me, I'd do this:

  • Set the rtabmap frame_id for pose data to, e.g., odom_camera.
  • Set your EKF frames to odom_frame: odom, base_link_frame: base_link, world_frame: odom
  • Set your wheel odom frames as frame_id: odom, child_frame_id: base_link
  • Create a node or modify the rtabmap (or even the EKF) source so that you take the actual mounting position of your camera, which we'll call T_cam, and rotate it by your current EKF output yaw value: R_ekf * T_cam. The result becomes your odom->odom_cam transform, and you would publish that transform if you did this in an independent node, or just use the transform directly within the code. If you publish the transform, then then the EKF will know how to transform from odom_cam to odom, and you're golden.