If there’s one topic that gets a lot of attention lately in the media, the public policy sphere, and in general health and wellness discussions, it is how to make the roadways safer According to the Centers for Disease Control, fatalities from traffic incidents happen on an annual basis upwards of 33,000 people. Many of these accidents are preventable, and an alarming number of them are a result of distracted driving.

Why Self-Driving Cars?

Safety

Convenience

Efficiency

Affordability

* Software Simulation

1 - Finding Lane Lines

Code

2 - Advanced Lane Finding

Code

3 - Behavioral Cloning

Code

4 - Vehicle Detection

Code

Project

Step 1: Components We Need

Step 2: Connecting

Step 3: Wiring Pi and Components

Step 4: Software Required

Step 5: Installing dependencies from PiP

install opencv

sudo add-apt-repository ppa:orangain/opencv

sudo apt-get update

sudo apt-get install python-opencv

install tensorflow

sudo apt-get update

sudo apt-get install python-pip python-dev

wget https://github.com/samjabrahams/tensorflow-on-raspberry-pi/releases/download/v0.12.1/tensorflow-0.12.1-cp27-none-linux_armv7l.whl

sudo pip install tensorflow-0.12.1-cp27-none-linux_armv7l.whl

sudo pip install mock

sudo pip2 install tensorflow-0.12.1-cp27-none-linux_armv7l.whl

install the python RPi.GPIO library

sudo apt-get install python-rpi.gpio

instal nodejs

sudo apt-get install nodejs

sudo apt-get install npm

install socket.io

npm install socket.io express johnny-five

install remot3.it

sudo apt-get install weavedconnectd


var args = process.argv.slice(2);
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var bodyParser = require('body-parser');

app.use(bodyParser.json());       


if (args.indexOf("noArduino") == -1) {
  var five = require("johnny-five")
    , board, servo;
  
  var arduinoServos = {};
  var throttleTimeout;
  var accelerationServo = {
    pin: 9,
    range: [0, 180], 
    type: "standard",   
    startAt: 90,          
    center: false
  };
  var steeringServo = {
    pin: 10, 
    range: [40, 100], 
    type: "standard", 
    startAt: 75, 
    center: true, 
  };
}


stringValues = {
  //throttle
  'forward': 65,
  'reverse': 105,
  'stop': 90,
  'throttleTime': 500,
  //steering
  'left': 40,
  'right': 100,
  'neutral': 75,
};

serverStatus = {
  hasArduino: false,
  hasCamera: false,
  currentAI: 'none',
};

// Start server
http.listen(80, function(){
  console.log('Starting server, listening on *:80');
});

app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});

// allow commands to be send via http call - GET only accepts command
app.get('/command/', function (req, res) {
  processRobotCommand (req.query.command);
  res.send('command: ' + req.query.command);
  
  // Eventually replace with json so commands can be sent back
  res.json({ 'state': serverStatus.currentAI });
});
// POST can look for timestamp(ms), command, and status
app.post('/command/', function (req, res) {
  processRobotCommand (req.body.command);
  
  updateRobotStatus (req.body.status);
});

io.on('connection', function (socket) {
  console.log('A user has connected ');
  socket.emit('robot status', { data: 'server connected' });
  
  // Robot commands
  socket.on('robot command', function (data) {
    processRobotCommand (data.data);
  });
  
  // Status update - gets forwarded to the webpage
  socket.on('robot update', function (data) {
    var updatedData = data.data;
    updateRobotStatus (updatedData);
  });
});

// Interprets and acts on a given command (expects strings split by "-")
function processRobotCommand (command) {
  var parsedCommand = command.split("-");
  console.log('----- Command: -----');
  console.log(parsedCommand);
  
  if (serverStatus.hasArduino) {
    // commands to johnny five
    // A bit convoluted here: commands are split between '-', with an arbitrary order for each section
    if (parsedCommand[0] == 'manual') {
      if (parsedCommand[1] == 'throttle') {
        if (parsedCommand.length < 4) {
          parsedCommand[3] = stringValues['throttleTime'];
        }
        if (parsedCommand[2] in stringValues) {
          accelChange(stringValues[parsedCommand[2]], parsedCommand[3]);
        }
        else {
          accelChange(parseInt(parsedCommand[2]), parsedCommand[3]);
        }
      }
      else if (parsedCommand[1] == 'turn') {
        if (parsedCommand[2] in stringValues) {
          steerChange(stringValues[parsedCommand[2]]);
        }
        else {
          steerChange(parseInt(parsedCommand[2]));
        }
      }
    }
    // AI commands - to be forwarded to opencv
    else if (parsedCommand[0] == 'face') {
      console.log('facing');
      if (parsedCommand[1] == 'begin') {
        serverStatus.currentAI = 'face';
      }
      else {
        serverStatus.currentAI = 'none';
      }
    }
    else if (parsedCommand[0] == 'red') {
      if (parsedCommand[1] == 'begin') {
        serverStatus.currentAI = 'red';
      }
      else {
        serverStatus.currentAI = 'none';
      }
    }
    else {    // parsedCommand[0] = 'stop'
      steerChange(stringValues['neutral']);
      accelChange(stringValues['stop']);
    }
  }
}

// Broadcasts an update to the robot status
function updateRobotStatus (updatedData) {
  updatedData['Time'] = new Date();
  updatedData['Arduino Attached'] = serverStatus.hasArduino;
  
  socket.broadcast.emit('robot status', { 'data': updatedData });
}

// ----- Johnny Five -----
// These should only be called or accessed if "noArduino" is not an option

function steerChange (value) {
  arduinoServos.steering.to(value);
  
  board.repl.inject({
    s: arduinoServos
  });
}

function accelChange (value, accelFor) {
  // Throttle has an automatic timeout so car doesn't run into things
  if (accelFor) {
    if (throttleTimeout) {
      clearTimeout(throttleTimeout);
    }
    throttleTimeout = setTimeout(function(){accelChange(stringValues['stop'])}, accelFor);
  }
  
  arduinoServos.acceleration.to(value);
  
  board.repl.inject({
    s: arduinoServos
  });
}

if (args.indexOf("noArduino") == -1) {
  board = new five.Board();

  board.on("ready", function() {
    arduinoServos = {
      acceleration: new five.Servo(accelerationServo),
      steering: new five.Servo(steeringServo)
    };
    acceleration = arduinoServos.acceleration;
    steering = arduinoServos.steering;
   
    // Inject the `servo` hardware into
    // the Repl instance's context;
    // allows direct command line access
    board.repl.inject({
      s: arduinoServos
    });
    
    serverStatus.hasArduino = true;
  });
}

whole project is on this Github repo

Thanks for reading !