This post is a follow up on my project called Building a self-driving RC car. In Part 1, I used Arduino to hack the controller of the RC car and according to my plan, in Part 2 I had to start working on all the cool Machine Learning stuff. However, this post is going to be a crime against my initial plan, because it is going to be a major update on the hardware part, with a preparation to build Machine Learning algorithms (that’s why this section is called Part 1.5 🙂 ).
Why did I decide to get back to the hardware? Well, I spent some more time learning about DC motors and Arduino, and realised that by using the initial setup of the project I am going to face quite a few limitations:
– By using Arduino Digital Pins to drive the motors I won’t be able to control their speed.
– Since Arduino will have to be connected to Raspberry Pi, emulating a controller will be a slight overkill knowing that there are ways to make the Arduino send the signal to the motors directly.
Since I wanted to control the speed of my car and make the project as lightweight as possible, I decided to re-hack the car and get rid of the controller entirely.
So this is what this post is going to be about – I will make changes to the hardware setup and will write the scripts which will be used to collect training data for Computer Vision algorithms.
[expand title=”Components and supplies used:”]
[/expand]
[expand title=”Software used:”]
[/expand]
Car re-hacking
The goal of this part is to change how the signal is passed to the motors. In contrast to Part 1, this time I am going to reassemble the car itself by replacing its circuit board with Arduino. To start, I removed the plastic cover of the car and this is how everything looked like from the inside:
The front wheel motor turns the front wheels right and left, while the back wheel motor makes the car go forward and backward. There also are two battery cables of negative and positive polarities (in the picture you can only see one, unfortunately). My car also has four LED lights – two on the front of the car and two on the back. Front LEDs light up when the car goes forward and back LEDs light up when the car goes backwards. Up till this point, the circuit board was responsible for monitoring the behaviour of the motors and LEDs, but since I want to hack the car I will replace this circuit board with Arduino. That’s why I am going to remove the circuit board by cutting all the wires as close to the board as possible (I will need those wires to hook everything up to Arduino). After quite scary, but necessary circuit board removal operation, the car looks like this:
Since LEDs are not crucial for my car to work, I decided that for now I will leave the lights disconnected and will get back to them a bit later (sorry, lights, nothing personal 🙂 ). Instead, I am going to do some work on motor and battery wires – I will attach a male jumper wire to each of them so that it would be easy to plug them into the Arduino. To do this, I am going to strip the plastic wrapper off all the wires, carefully solder the male jumper wire to each of them, and cover up the connections with heat shrink tubing wraps. The process of one of the wires is shown below:
I repeated the process to all four DC motor wires as well as two battery connection wires and the final result looked like this:
At this point, it is a very good idea to use a multimeter and check if all connections work as expected. If they are (they were working for me) then the hardest part is finished and it’s time to write the code and put everything together.
Putting it all together
Just like in Part 1, I am going to use Arduino to control my car through the code. The difference is that instead of hardcoding of what my car should do, I am going to use Raspberry Pi which will send the commands to Arduino based on what the car sees. Those commands will depend on what keyboard keys I am going to press during the training data collection stage or what keys will be predicted by Machine Learning algorithms during the testing. Below is a diagram of how everything will work:
Arduino
I am going to start ensembling my car starting with Arduino. Just like in Part 1, I am going to first load the code into the Arduino. The code I am going to use will be different though still quite simple. Instead of using Digital Pins, this time I am going to initialize two motors. Then, my Arduino script will listen to incoming data from Raspberry Pi through the serial port and depending on what keyboard press event will be sent by Raspberry Pi, my car will go forward, backward, to the left, to the right or will not move at all.
After loading the code, I am going to attach a Motor Shield to my Arduino. A Motor Shield will control the rotation direction of the DC motor by inverting the direction of the current flow through the motor. I am going to attach a Motor Shield to Arduino by simply connecting the corresponding pins.
A Motor Shield has connections for four DC motors and an external battery source. Motors are marked with M1, M2, M3, M4 signs and the external power source is marked with GND.
In my code, I initialised two motors which were assigned to channels 1 and 2, so I am going to connect the front motor to input M1 and back motor to input M2. I will also connect battery wires of my car to an external power point (at this step it is important not to mix up positive and negative polarity wires because Motor Shield might be fried up if polarities will be switched). The final result looks like this:
Since Arduino and Raspberry Pi is going to communicate through the serial port I will need to connect them using USB cable. For this, I attached a connection cable to Arduino which will be connected to Raspberry Pi once it’s ready.
Raspberry Pi
Now it’s time to set up the Raspberry Pi. The first thing that I had to do was to get the OS ready. I used Raspbian Stretch with Desktop which I downloaded from https://www.raspberrypi.org/downloads/raspbian/. The installation of OS is very simple – I burned the image file into micro SD card (for this I used Etcher https://etcher.io/) and after it was done I inserted the card into Raspberry Pi, plugged the power on and a few minutes later my Raspberry Pi was up and running. Since Raspberry Pi will have to travel on my car, I used a 5V external battery as a power source (which compared to the size of Raspberry Pi looks like a brick, but actually its size will be very handy when I will mount everything together 😀 ).
Now it’s time to attach an eye of the car – a camera module. The thing that I learned the hard way about Raspberry Pi camera modules is that they are ridiculously fragile and sensitive to static. I ruined one camera module due to static after using it only once, so when I got a new one the first thing that I did was attaching a protective case which would cover up fragile circuits around the camera. There are cases which you can buy, I decided to be extra crafty so I made mine by myself using a little plastic box (it doesn’t look as pretty as the purchased one, but it does the job). After protecting the camera I plugged it into the Raspberry Pi.
Since Raspberry Pi originally doesn’t come with the screen there are few options of how to go around this problem – you can connect your Raspberry Pi to any screen you have using HDMI cable or you can get a mini LCD screen which can be simply attached to Raspberry Pi. I decided that I would like to see what my car sees when it drives around so I used a Raspberry Pi LCD screen (I didn’t use it for writing the code though since it is definitely the tiniest LCD screen I have ever used 🙂 ).
To finish off the construction, I secured the Raspberry Pi on my external battery using strap seal and attached the camera to it using double tape to keep it in place. I placed this battery-Raspberry Pi construction on the top of the car and connected Raspberry Pi and Arduino using the USB cable. And voilà – the car is fully assembled!
Before diving into the code which will run on the Raspberry Pi, I made sure that the camera is enabled. To do so I opened the terminal and typed the following:
sudo raspi-config
In the settings menu, I navigated to ‘Interfacing Options’, selected ‘Camera’ and chose the option to enable the camera.
I have written two scripts for Raspberry Pi. A file called ‘test_camera.py’ simply checks that the camera works as expected – it launches the camera, starts capturing frames and displays each of them on the screen. Another file, called ‘input_keys.py’ is the one which I am going to use to collect the training data for Machine Learning algorithms. In short, the script launches the camera and with every frame, it checks what keyboard key is pressed. Depending on which key is pressed, the corresponding signal is sent to Arduino so that the car would move to the corresponding direction. Lastly, each frame alongside the vector of input keys is appended to training dataset and saved as numpy array file. I will use this data to build the algorithms which will predict what key should be pressed based on real-time image data and will move the car to the (hopefully 🙂 ) right direction.
My goal for the next stage of this project is to build two algorithms – one for lane detection and another one for road sign classification so that the car would follow the lines of the roads, but would also behave correctly when specific road signs are detected (for example the car should stop next to the sign ‘Stop’ and it shouldn’t turn left when sign says that it is forbidden to do so and etc.). I am going to use my ‘input_keys.py’ script to capture some training data as I drive my car around and I will use it to build the algorithms so that my car could eventually hit the cardboard roads on its own! 🙂
I am going to finish my post here and I will write an update on Machine Learning part in my next post.
Useful links:
– Arduino Code
– Raspberry Pi Code
pretty cool stuff, did you got it working with vision?
Hey Glauber. Yes, I have started tuning the model, however, I had to put this project on hold for a while because I had to move countries quite recently. Planning to get back on working on it in a couple of weeks!
Still waiting till you get more time to work on part 2 of this project. Keep up the good work.
Hey! Got a bit busy with some things in the past few months (moved countries, changed jobs), but I am finally back on working on this project and planning to write the part 2 soon 🙂