Pet project: RC Car
A month ago I realised I never had RC car. While I could head down to amazon and buy a nice RC car for 25 pounds I have decided to make it much more expensive and complicated!
I spent a few days looking for programmable RC car (or at least some that would be easy to control with Rapsberry Pi or an Arduino). I could not find anything. However after all that searching, the creeps of Amazon noticed the pattern and recommended Freenove 4WD Smart Car Kit for Raspberry Pi 4. It is a basic RC car kit that provides everything apart from Rapsberry Pi and batteries.
The 18650 batteries are a bit hard to get in UK - they seem to be available only through smaller 3rd party sellers. I did find them on Amazon even though the car manual said to look for them on eBay.
The physical quality of the car is reasonable - nothing broke down so far, however some of the screws need regular tightening. Few of the screws are under the Pi board so it needs to be removed to reach them.
The Freenove has GitHub repository with python code. I don't want to critize them too much but the code reads like a research code - garbage that nobody bothered to refactor once they made it to work. I did refactor some of it here and also added debugging information that helps to see which registers on the car are actually being used.
I always wanted to use Rapsberry Pi for a project but I could never think of something interesting or useful to me. I mean sure I could use it for something like a media storage but usually I thought my laptop can do a better job of that. Having a platform like this enabled me to do something that my laptop can't do: move. (At least so far. Please don't add wheels to my laptop!)
This was also an excuse to try out Rust. It was my first time using Rust ever so I ordered printed edition of Rust book - which is an excellent read (I am still in the middle), however my copy came somehow demaged and the cover page unglued after few hours of reading.
Anyway the goal of the project was to rewrite the provided code into rust and add an some controlling mechanism of the car to use outside the wifi range.
Progress (so far)
I rewrote the original code and added support for controlling the code with PS4 wireless controller.
Here one of the wheels felt off during the run, this happens fairly frequently and it is trivially to fix, previously I also tried adding piece of plastic bag in the wheel join which made for a tighter fit and prevented this type of failure.
I thought for a long time about an appropriate method of control for the car, I came up with these options:
- Mobile app via bluetooth
- I would have to create the app but also deal with bluetooth pairing issues, this did not sound very robust.
- Mobile app via wifi
- This would require setting up the Pi as an access point. My Fujifilm camera uses something similar to this and I hate it - my Android phone usually keeps disconnecting from the WiFI as there is no internet
- PS4 gamepad controller
- The controller is a natural fit for this vehicle because the wheels are fixed - the steering is done by diverging the speed of each side - just like tanks. Because the controller has two joysticks each side can be controlled by using the Y coordinate of each joystick.
- This seemed like a best choice however I did not have one and I did not want buy it and never use after I am done with this project. After some deliberation I went ahead and bought it. Luckily my friend recently bought a PS4 and only has one controller so I plan to give her the controller as a chrismass gift once I am done with this project.
The PS4 controller works quite well; there are no connections issues as all of the pairing is abstracted by the dongle. The steering is a bit harsh and I have not figured out how to do it smoothly; usually I am only able to steer with the car stopped.
You can see most of the code for the joystick here. The code for controlling the motors is here. I still plan to do some refactoring so the code is in quite rough shape.
I spent most of my workdays working with Python, NPM and Kubernetes, so it is hard to describe just how pleasant it is when rust finishes compiling and you get one executable - not two, not two thousand, not some weird binary blob in docker register, no, you get one nice little executable!
Anyway I am really happy with the Rust toolchain and the language itself. I still don't understand how to use mutable pointers and the implications of the borrowing system - usually I just try every possible combination of
*, &, mut and at same point the compiller is happy and then I am happy too.
Naturally you might be asking how much I spent on this and question all my life decisions just like I am doing right now. In GBP it comes down to:
- 25 - PS4 Controller
- 91 - Rapsberry pi + accessories (the 128GB micro SD card was probably more expensive than the Pi...)
- 14 - 18650 Batteries with USB charger
- 60 - Freenove car kit
Overall it adds to 190 GBP, however I can reuse the Rapsberry PI, controller and the SD card for future projects. Lookin at this table I definetely feel like I spent way too much money on a toy, however I have to admit that I ordered most of it while being drunk so I hope it is more socially acceptable?
There are still quite a few parts I have not explored:
- Tiltable camera
- Ultrasound sensor for obstacle detection
- LED strip for FUN
I want to finish reading the Rust book. I also just found Rust Discovery that covers a lot of the things that I skipped over - like the I2C protocol that I blindly used.
I plan to start doing more of my projects in Rust, hopefully I will come up with some other hardware projects. (Perhaps a watch? That sounds dorky enough!)