Self-Driving Pi Car

Build Status License

Introduction

Self-Driving Pi Car is a deep neural network based self-driving car, that combines Lego Mindstorms NXT with the computational power of a Raspberry Pi 3.

This repository was created by Paula Moraes and Felipe Salvatore.

Robot driving on a track

You can read more about the project on Medium

Getting Started

Install

The first thing you need to do is to install all the libraries for the Raspberry Pi. To do so, open a terminal in Raspberry Pi and run:

$ cd raspi_utils/
$ bash install.sh

In the computer that you will perform the training -- protip: don't train the model in the Raspberry Pi! -- install all the requirements by runnig:

$ pip install -r requirements.txt

Usage

Attention: in the master branch all python code is written for Python 2. If you would like to run this project in Python 3, please switch to the python3 branch of this repository.

Collecting data

Before doing any kind of training you need to collect the track data. So in the Raspberry Pi -- with the assembled robot -- run the data collection script:

  $ cd self_driving/data_collection/ 
  $ python DataCollector.py -n <images_folder_name>

Pressing q will stop execution and save all images and pickle file.

Inside the folder <images_folder_name> there will be subdirectories organized by timestamps similar to 2018-02-17-23-27-02 with the collected *.png images. All the associated labels are saved in a pickle file 2018-02-17-23-27-02_pickle in <images_folder_name>.

Compress <images_folder_name> directory and export it from Raspberry Pi to other computer (using scp command, cloud, email, etc).

  $ tar cvf <images_folder_name>.tar <images_folder_name>

Attention: please continue following the instructions in the computer that will be use for training.

Generating npy and tfrecords

Before generating tfrecords, you need to transform the untar <images_folder_name> containing all folders of images and pickles into a tuple of np.arrays. Running the following script will result in the creation of <npy_files_name>_90_160_3_data.npy and <npy_files_name>_90_160_3_labels.npy files:

  $ cd self_driving/data_manipulation/
  $ python img2array.py <images_folder_path> <npy_folder_path> <npy_files_name>

To generate tfrecords from *.npy and augment or manipulate (e.g. binarize) the data, run:

  $ cd ../ml_training/ 
  $ python generate_tfrecords.py <npy_data_path> <npy_labels_path> -n <name_tfrecords> 

Resulting in <name_tfrecords>_train.tfrecords, <name_tfrecords>_test.tfrecords and <name_tfrecords>_valid.tfrecords files.

Hyperparameters optimization

Attention: all code in this section can be runned on both Python 2 and 3 with TensorFlow 1.2.1 (and above) and with GPU support, if possible.

Now it's time to test different architectures, learning rates and optimizers, in the hopes of improving accuracy.

Best architecture search

Running the following script will create architecture_results.txt file with the results for a given configuration passed through optional arguments.

  $ python best_architecture.py -n <name_tfrecords>

Best learning rate search

Running the following script will create learning_rate_results.txt file with the results for a given configuration passed through optional arguments.

  $ python best_learning_rate.py -n <name_tfrecords>

Best optimizer search

Running the following script will create optimizer_results.txt file with the results for a given configuration passed through optional arguments.

  $ python best_optimizer.py -n <name_tfrecords>

Training the model

Attention: back to Python 2

After searching for an appropriate combination of hyperparameters, you must train the model running this script with additional arguments relative to the model:

  $ python train.py -n <name_tfrecords> -v

The result will be a checkpoints directory with all files needed to deploy the model.

Accuracy test

You can test for accuracy with the script:

  $ python acc_test.py -n <name_tfrecords>

Simulation

Before going live, it's possible to simulate the model in action with track images. This simulation script uses checkpoints and <images_folder_path> to generate new images, saved on <output_images_folder_path>, with a stamp of the probabilities for each class.

  $ cd ../
  $ python simulation.py <images_folder_path> <output_images_folder_path>

Example:

Self-driving

Attention: this section must be run on Raspberry Pi.

After training the model and loading its checkpoints to Raspberry Pi, there will be two modes available: regular and debug.

On regular mode, the car will take an action based on the model's prediction given an image took by the camera. Pressing q will stop the execution:

$ python DiffController.py 

The debug mode works in the same way as regular, but also creates a debug-run directory containing all images taken during execution with a stamp of the probabilities for each class. Pressing q will stop the execution:

$ python DiffController.py -d

Running the tests

There is two kind of tests: the ones from the Raspberry Pi and the ones for the training computer. In the Raspberry Pi run

$ python setup.py test 

These tests serve to check if the conection with the NXT robot is working.

And in the training computer

  $ bash test_script.sh 

These last tests check if the image manipulation functions and the tensorflow model are doing what they suppose to be doing.

Built With

Citation

  @misc{self_driving_pi_car2018,
    author = {Paula Moraes and Felipe Salvatore},
    title = {Self-Driving Pi Car},
    year = {2018},
    howpublished = {\url{https://github.com/felipessalvatore/self_driving_pi_car}},
    note = {commit xxxxxxx}
  }