# Ackermann Motion Model Does not Drive in an Arc, but Turns on the Spot

Im trying to implement an ackermann motion model which estimates the x,y and theta for a robot I have.

I have a gazebo simulation running which publishes a steering angle for the virtual tricycle wheel and I have a linear velocity for the back wheel.

I publish the ground truth odometry and transform which I can display in Rviz.

I then use the published values to compute a deltaX, deltaY and deltaTheta for a pose update. If the steering angle is 0, it works fine as the deltaX = linear velocity. However, when I have both values non zero, my robot moves in an arc, but my motion model turns on the spot instead.

The formulae for motion estimation and pose update are taken from "Simultaneous Localization and Mapping for Mobile Robotics" by Juan Antonio Fernandez-Madrigal.

Any ideas where I have made a mistake?

Edit: I will provide the formulae I use here

$u = (v,alpha)$ , where v is the linear velocity form the driving wheels and alpha is the steering angle (in radians)

$l = wheel base$ i.e the distance between the front and back wheel

$w = \frac{v*sin(alpha)}{l}$

$dx = \frac{l * sin(w)}{tan(alpha)}$

$dy = \frac{l * (1-cos(w))}{tan(alpha)}$

Pose Update:

$x_{new} = x + (dx*cos(theta) - dy*sin(theta))*dt$

$y_{new} = y + (dx*sin(theta) + dy*cos(theta))*dt$

$theta_{new} = theta + w*dt$

Ofcourse if alpha = 0 then $delta_x = v$

edit #2. I fixed the problem, but I do not understand the solution.

The first issue was that I did not incorporate the linear velocity into my equation when rotating.

This gives :

$dx = \frac{v*l * sin(w)}{tan(alpha)}$

$dy = \frac{v*l * (1-cos(w))}{tan(alpha)}$

Now the robot drives in an arc! But the arc is wrong.

Now I changed the update equation to:

$dx = \frac{v*l * cos(w)}{tan(alpha)}$

$dy = \frac{v*l *sin(w)}{tan(alpha)}$

The rotational arc now seems correct. The rotational speed is still lower (not such an issue), but I dont understand why this works rotation works. I.e. why the $1-cos(x)$ factor gets changed to $sin(x)$ etc.