Skip to content

Commit

Permalink
Finalized the example with the self-driving car.
Browse files Browse the repository at this point in the history
  • Loading branch information
petrmanek committed May 21, 2016
1 parent 1b9a619 commit b823d3b
Show file tree
Hide file tree
Showing 30 changed files with 37,627 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
@@ -1,3 +1,6 @@
[submodule "SwiftyJSON"]
path = SwiftyJSON
url = https://github.com/SwiftyJSON/SwiftyJSON.git
[submodule "Swift-AI"]
path = Swift-AI
url = https://github.com/collinhundley/Swift-AI.git
403 changes: 403 additions & 0 deletions ExampleCar/ExampleCar.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions ExampleCar/ExampleCar/AppDelegate.swift
@@ -0,0 +1,18 @@
import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {



func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
}

func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}


}

@@ -0,0 +1,58 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
694 changes: 694 additions & 0 deletions ExampleCar/ExampleCar/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions ExampleCar/ExampleCar/CarChromosome.swift
@@ -0,0 +1,42 @@
import Revolver

struct NeuralNetWeight: Randomizable, CustomStringConvertible, CustomDebugStringConvertible {
let weight: Float

init(_ weight: Float) {
self.weight = weight
}

init(generator: EntropyGenerator) {
// Generate Float between +/- 1/sqrt(numInputNodes).
// This interval is optimal for sigmoid activation.

let bound = Float(1) / sqrt(Float(5))
self.weight = generator.nextInRange(min: -bound, max: bound)
}

var description: String { return weight.description }
var debugDescription: String { return weight.debugDescription }
}

final class CarChromosome: RangeInitializedArray {
typealias Element = NeuralNetWeight
static let initializationRange = 82...82

let array: [NeuralNetWeight]

required init(array: [NeuralNetWeight]) {
self.array = array
}

var description: String { return array.description }
var debugDescription: String { return array.debugDescription }

func toFFNN() -> FFNN {
return FFNN(inputs: 5,
hidden: 10,
outputs: 2,
weights: array.map { $0.weight },
activationFunction: .Sigmoid)
}
}
19 changes: 19 additions & 0 deletions ExampleCar/ExampleCar/CarControlParameters.swift
@@ -0,0 +1,19 @@

enum CarSteering {

case HardLeft
case Left
case Neutral
case Right
case HardRight

}

struct CarControlParameters {

let steering: CarSteering
let acceleration: Double

static let neutral = CarControlParameters(steering: .Neutral, acceleration: 0)

}
14 changes: 14 additions & 0 deletions ExampleCar/ExampleCar/CarDetectorMeasurements.swift
@@ -0,0 +1,14 @@

typealias CarDetectorOutput = Bool

struct CarDetectorMeasurements {

let frontLeft: CarDetectorOutput
let frontMiddle: CarDetectorOutput
let frontRight: CarDetectorOutput

let under: CarDetectorOutput

let back: CarDetectorOutput

}
6 changes: 6 additions & 0 deletions ExampleCar/ExampleCar/CarDriver.swift
@@ -0,0 +1,6 @@

protocol CarDriver {

func drive(data: CarDetectorMeasurements) -> CarControlParameters

}
27 changes: 27 additions & 0 deletions ExampleCar/ExampleCar/CarEvaluator.swift
@@ -0,0 +1,27 @@
import Revolver

class CarEvaluator: SequentialEvaluator<CarChromosome> {
static let maxDuration = NSTimeInterval(60 * 60) // 1 hour
static let maxDistance = CarSimulation.maxVelocity * CarEvaluator.maxDuration
static let attempts = 3

let generator = MersenneTwister(seed: 4242)
let sim = CarSimulation()

override func evaluateChromosome(individual: CarChromosome) -> Fitness {
sim.reset()
sim.randomizeTrack(generator)
sim.controlProgram = NetDriver(net: individual.toFFNN())

var results = [Fitness]()
results.reserveCapacity(CarEvaluator.attempts)
for _ in 1...CarEvaluator.attempts {
sim.randomizeCar(generator)

let outcome = sim.run(maxDuration: CarEvaluator.maxDuration)
results.append(Fitness(outcome.distanceTraveledOnTrack) / Fitness(CarEvaluator.maxDistance))
}

return results.reduce(0, combine: +) / Fitness(CarEvaluator.attempts)
}
}

0 comments on commit b823d3b

Please sign in to comment.