diff --git a/Sources/Swift2dCar/Servo.swift b/Sources/Swift2dCar/Servo.swift index bbf2fe3..8f1c1a3 100644 --- a/Sources/Swift2dCar/Servo.swift +++ b/Sources/Swift2dCar/Servo.swift @@ -10,12 +10,12 @@ import Foundation import SwiftyGPIO -enum ServoError: Error{ +public enum ServoError: Error{ case invalidMinPulseWidth case invalidMaxPulseWidth } -protocol Servo { +public protocol Servo { var value: Float {get set} var minPulseWidth: Float {get} @@ -40,25 +40,25 @@ public class PWMHardwareServo : Servo{ private var device: PWMOutput private var currentPulseWIdth: Float - var minPulseWidth: Float { + public var minPulseWidth: Float { get{ return minDc * frameWidth } } - var maxPulseWidth: Float{ + public var maxPulseWidth: Float{ get{ return (dcRange * frameWidth) + minPulseWidth } } - var pulseWidth: Float{ + public var pulseWidth: Float{ get{ return internalValue * frameWidth } } - var value: Float{ + public var value: Float{ get{ internalValue } @@ -71,7 +71,7 @@ public class PWMHardwareServo : Servo{ } - init?(forPin pin: PWMOutput, startingAt initialValue: Float = 0, withMinPulseWidth minPulseWidth: Float = 1000000, + public init?(forPin pin: PWMOutput, startingAt initialValue: Float = 0, withMinPulseWidth minPulseWidth: Float = 1000000, withMaxPulseWidth maxPulseWidth: Float = 2000000, withFrameWidth frameWidth: Float = 20000000) throws { if(minPulseWidth >= maxPulseWidth){ throw ServoError.invalidMinPulseWidth @@ -95,19 +95,19 @@ public class PWMHardwareServo : Servo{ self.device.startPWM(period: Int(self.frameWidth), duty: self.minDc + self.dcRange * ((internalValue - self.minValue) / self.valueRange) * 100) } - func min(){ + public func min(){ self.value = -1 } - func mid(){ + public func mid(){ self.value = 0 } - func max() { + public func max() { self.value = 1 } - func detach(){ + public func detach(){ self.device.stopPWM() } } diff --git a/Sources/Swift2dCar/Vehicle.swift b/Sources/Swift2dCar/Vehicle.swift index 19d94d1..a3cf981 100644 --- a/Sources/Swift2dCar/Vehicle.swift +++ b/Sources/Swift2dCar/Vehicle.swift @@ -12,19 +12,15 @@ import SwiftyGPIO protocol Vehicle2D{ var throttle: Float {get set} var steering: Float {get set} - mutating func move2D(magnitude: Float, angle: Float) } class MockVehicle: Vehicle2D { var throttle: Float = 0 var steering: Float = 0 - - func move2D(magnitude: Float, angle: Float) { - - } } -class RPiVehicle2D: Vehicle2D{ +public class RPiVehicle2D: Vehicle2D{ + public var pwmThrottle: Servo public var pwmSteering: Servo @@ -51,13 +47,6 @@ class RPiVehicle2D: Vehicle2D{ pwmSteering = withSteeringPin } - func calibrate(){ - // Define a function that indicates how the throttle/steering should be set for given magnitude/angle to move. - } - - func move2D(magnitude: Float, angle: Float) { - - } func stop(){ pwmThrottle.detach() @@ -65,3 +54,46 @@ class RPiVehicle2D: Vehicle2D{ } } + +public typealias ThrottleHandler = (_ magnitude: Float) -> Float +public typealias SteeringHandler = (_ angle: Float) -> Float + + +public class IntelligentPiCar : RPiVehicle2D { + + private var vehicleLength: Float? + private var throttleFunc: ThrottleHandler? + private var steeringFunc: SteeringHandler? + + /**: + Calibration function for how the car moves (acoording to a bicycle model) for a given throttle/steering angle. This sets the way the + - Parameters + - carLength + */ + func calibrate(vehicleLength: Float, throttleFunc: @escaping ThrottleHandler, steeringFunc: @escaping SteeringHandler){ + // Define a function that indicates how the throttle/steering should be set for given magnitude/angle to move. + self.vehicleLength = vehicleLength + self.throttleFunc = throttleFunc + self.steeringFunc = steeringFunc + } + + /** + Move the car by the given magnitude and angle, depending on how the is known to move with apriori throttle/steering. + */ + func move2D(magnitude: Float, angle: Float) { + if let throttleFunc = self.throttleFunc { + self.pwmThrottle.value = throttleFunc(magnitude) + } + + if let steeringFunc = steeringFunc { + self.pwmSteering.value = steeringFunc(angle) + } + } + + /** + Move to the coordinates relative to the car. You must first calibrate the car. A bicycle model is assumed. + */ + func moveRelativeTo2D(x: Float, y: Float) { + // TODO: This function, has a lot of edge cases. Also is really + } +}