Closed SeaTechRC closed 1 month ago
Correction to the integral: I made an error and didn't include the bounds.
The definite integrals would be: $\Delta x = V \cdot \frac{\sin(\omega \cdot \Delta t + \phi_0) - \sin(\phi_0)}{\omega}$
$\Delta y = -V \cdot \frac{\cos(\omega \cdot \Delta t + \phi_0) - \cos(\phi_0)}{\omega}$
Do note, that there is a seperate case where $\omega$ is 0 and therefore we simply drive in a straight line.
Adding acceleration and deceleration would also change the form of the integral, as the $V$ would be replaced with a function $V(t)$. This might be less important, but not taking acceleration into account is another small source of error.
Thanks for bringing this up, @SeaTechRC! The current implementation is indeed rather simplistic and assumes frequent odometry measurements and a relatively slow and smooth motion. To be honest, I never really thought about using more complex formulas and expected them to be even more complicated than the ones you're proposing.
Some thoughts:
Pose.__add__
where a PoseStep
is added to a Pose
. This piece of code is rather unrelated to the application of odometers and differential wheeled robots. Changing it would introduce a nasty breaking change, which wouldn't make much sense within the rosys.geometry
module. So we would better add a new implementation within Odometer.handle_velocities
.Long story short, I don't think changing the formulas is strictly necessary, but I would probably accept a pull request. Apart from that I'd love to find a second source for these formulas - just to be sure. It's rather easy to introduce a subtle bug here that's hard to notice but would make things even more incorrect.
To comment on some of your thoughts:
Thank you for the reminder about the refresh rate. This clears it up for me 👍 I suppose this might be useful as a heads up, in case there are any special cases (low refresh rate, tight and fast turning) either in future robots developed by your company or other people using rosys for their robots. Feel free to close the issue if you think it's not applicable.
Hello,
Upon further inspection I suspect there might be an incorrect implementation of calculating a new prediction in the odometer from the linear and angular velocity given by wheels. (At least in the case of differential wheeled robots.)
To explain: Currently the new pose calculated from the linear and angular velocity is calculated such that: $$x{t + \Delta t} = x{t} + \cos(\phi{t}) \cdot \Delta t$$ $$y{t + \Delta t} = y{t} + \sin(\phi{t}) \cdot \Delta t$$ $$\phi_{t + \Delta t} = \phi + \omega \cdot \Delta t$$
When looking at the kinematics of a differential wheeled robot we find that this equates to the derivative of the robots x, y and yaw times the time elapsed since the last update. This is okay as an approximation, however, it diverges especially quick if updates are infrequent.
The correct method would be to calculate the integral of the derivative. For this, it must be taken into account that the yaw (which is $$\phi$$) changes during driving. If we substitute the yaw with its respective function, we get that the integral for the relative movement is (from $$0$$ to $$\Delta t$$) is: $\Delta x = \int\limits_0^{\Delta t} V \cos(\phi_0 + \omega \cdot t) dt$
$\Delta y = \int\limits_0^{\Delta t} V \sin(\phi_0 + \omega \cdot t) dt$
$\Delta \phi = \int\limits_0^{\Delta t} \omega$
$x{t + \Delta t} = x{t} + \Delta x$ $y{t + \Delta t} = y{t} + \Delta y$ $\phi_{t + \Delta t} = \phi + \Delta \phi$
Calculating the integrals we get:
$\Delta x = \frac{V \cdot \sin(\phi_0 + \omega \cdot \Delta t)}{\omega}$
$\Delta y = -\frac{V \cdot \cos(\phi_0 + \omega \cdot \Delta t)}{\omega}$
$\Delta \phi = \omega \cdot \Delta t$
A good way to visualize it is, that the old method, at any given point, would simply move the robot in a straight line for $\Delta t$ seconds. Which does not match the curve the robot is actually driving (a circular path).