We used model-predictive control which evaluated about 10k trajectories with look-ahead, which works really well even when tires begin to degrade after a few minutes. You can see the effects in the video towards the end, where the car starts to slide, but the controller manages to catch it in time.
Our CV was a bit more complex as we had to deal with missing line segments. We pre-processed the camera image with a distance transform, then used an optimization pass written in opencl to fit a 3rd-order polynomial to the image.
Instead, we built an empirical transfer function from (target yaw rate, speed) -> steering wheel angle. To get to this function, we measured the yaw rate during a steady-state circular test at different speeds and steering wheel angles. Then do some kind of regression to get a continuous function. During the test, also eyeball when the tires start to slip, then use this to limit max lateral velocity.
Of course this does not take into account changing tire conditions at all. We thought about estimating the slip angle from CV or using controller oscillations as indicators, but never got around to it.
I had some of the vehicle parameters as part of my EKF for a while, but it led to some instabilities in the control.
The main problem is that it's really hard to know what the car's instantaneous lateral velocity is. I think the best you can do is check the difference of velocity*gyro yaw rate and lateral accelerometer measurement to get a noisy lateral acceleration measurement, and that can tell you how well your tires are hooking up. I might try fitting a least-squares model on the fly with something like that.
And when you’re ready to get a little more serious you can get an imu and gps. Maybe even get a more beefy computer and add a camera!
That is exactly what I was planning to do next. I realized that when the angle was greater, it would see the distance to the wall as higher than it really is, because of trigonometry. And that is a positive feedback loop which makes it worse. (I just realized that is only true when it headed towards the wall at an angle, but is the opposite when heading away from the wall at an angle. It reacts later (steer right) when it's angle towards the wall, but it should react sooner (steer left) when it's angled away from the wall... hmm...) Getting the angle, I could set a target angle and distance together, and steer as needed.
That was a fun time in uni
One of the guys built a very fast line-following robot, much faster than what we see here. It was simpler though, it was a solid black line.
_=0;k;main(){while(_<641){for(k=0;"##K#8(38D-##C]L5870.X7\\M_b;90\\"
"MC-M/NZGB6Q,I0VGB6a0FbN<VG.6Q\\bNb7^@`X=N@`XQaOVX:^]NX=:Z8PY]B`:>P"
"NY8^$#SM):XA"[_/6]-35>>_++%6&1;k++);putchar(k[" _/\\\n,`)('<-"]);}}
[0] - bottom of OP's homepage https://www.a1k0n.net/If you don't mind I would love to add this article in my next WeeklyRobotics (https://weeklyrobotics.com/) issue.
Sure, that sounds good!
It had to be a little more complex than line following, because at one point in the track there are a bunch of line crossings. So you had to do some mapping and tracking too in order to stay in the right lane.
It's really fun seeing how fast you can make them go. One team maxed out the speed on the platform.