ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A answers.ros.org

# cmd_vel and odometry for different frames?

Hey, I have a car-like robot (a tricycle). Its angular and linear velocities, which are being published to cmd_vel, should be calculated for the center of its rear wheels, where the base_link frame is at. However, it is easiest to calculate the odometry for the front wheel (which is being steered). My question is, can I publish the odometry for the for the front wheel's frame (relative to the odom frame) and publish the joint state, so that the position of the base_link is known, or will it sabotage the functioning of the navigation stack?

edit retag close merge delete

Hi Amit,

Did you figure out how to calculate odom for a tricycle?

Sort by » oldest newest most voted

It depends what you mean by "the odometry for the front wheel". An odometry message usually has robot pose data in the world frame and robot twist data in the base_link frame. If you have the robot's velocities (including kinematic constraints) in a different coordinate system, the transform tree will take care of the shift and rotation from one frame to another. However, that only applies in an instantaneous coordinate-change sense. Such transformations don't take into account any kinematic constraints (wheel radius, steering geometry, etc.), so if you start with the twist components of the front wheel in the front_wheel frame, you'll end up with the twist of the front wheel--not the twist of the robot--in the base_link frame. If you start with the twist of the robot in the front_wheel frame, the transform will correctly give you the twist of the robot in the base_link frame.

That said, tricycle kinematic equations for the robot (base_link) frame are known, so why not use them? Here's one example of the derivation (pgs. 14-15).

more

Thank you for the answer. The reason I prefer to use the front wheel kinematics is that the odometry is the integral of the kinematics equations, so since the front wheel equations are simpler and less coupled, there will be less error and less drift. (if I am wrong about that, please let me know). My plan was indeed to use the twist components of the /front_wheel in the front wheel frame, and the geometry components of the /front_wheel in the /odom frame. Now, assuming I am also publishing the Joint angle to /tf, why wouldn't the tf and navigation package be able to calculate the geometry and twist of the /base_link and use it for navigation?

I may be unclear on your approach; could you post the equations you're considering? Drift occurs when the model doesn't quite match the physical robot--or maybe due to sensor error, but that's a separate issue. If you're using a tricycle model either way, I don't see how calculating things in a different frame would reduce drift.

The tf tree keeps track of coordinate transforms between the different frames but doesn't keep track of kinematic relationships. Specifically, the velocity of the front wheel is not the same as the velocity for the robot, so if you merely transform it into the base frame, you'll get incorrect twist components. Those relationships must be built into the node(s) using the data, e.g., a controller or odometry node. As long as the navigation components you choose/write know how to handle the data, it'll ...(more)

in the following link, page 6,link text, there is a geometric comparison of different odometric methods. You can see that if I use just the kinematic relations (the Euler method) I will have an error. I order to reduce the error I will have to use runge-kutta method. But in the kinematic equations of the tricycle there is a coupling between alpha and theta, so I am trying to bypass this complication.

The comparison on slide 6 is of different integration methods, which can all use a kinematic model. Even if you focus on the odometry of the wheel alone, at some point you need to calculate/measure the pose and velocities of the robot base for navigation--or provide enough clearance to disregard it.

All that aside, assuming you publish the correct data, using a frame other than the robot's base will only work if the navigation components you choose know how to handle it. For example, the base_local_planner assumes "the odometry is published in the frame of the base" (see source code). I suggest transforming the data into the base_link frame when publishing odometry. You can use a tf2::Buffer and the transform() funciton.