diff --git a/.gitignore b/.gitignore
index a0581ec..a5cbab9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,4 +34,5 @@ xcuserdata/
.project
.classpath
-.vscode/settings.json
\ No newline at end of file
+.vscode/settings.json
+**/target/**
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..bb76893
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+CarController
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..fb7f4a8
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..c1c347f
--- /dev/null
+++ b/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index ad99ec1..c4477f7 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,9 +4,10 @@
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..818a8ed
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 7bfef59..6199cc2 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460..0000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index cb9eab5..a94c097 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
This software allows for the control of an RC Car using a linux system. Currently it's been tested to work on a Traxxas Slash and raspberry pi 3b+.
-See the individuals modules for more detailed READMEs, including build instructions.
+See the individual modules for more detailed READMEs, including build instructions.
### Current Functinoality
diff --git a/SwiftyCar/Dockerfile b/SwiftyCar/Dockerfile
deleted file mode 100644
index e829502..0000000
--- a/SwiftyCar/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM vato.ddns.net:8083/swift:latest as builder
-WORKDIR /root
-COPY . .
-RUN swift build -c release
-
-FROM vato.ddns.net:8083/swift:slim
-WORKDIR /root
-COPY --from=builder /root .
-CMD [".build/x86_64-unknown-linux/release/docker-test"]
\ No newline at end of file
diff --git a/SwiftyCar/Package.resolved b/SwiftyCar/Package.resolved
deleted file mode 100644
index 2a9708e..0000000
--- a/SwiftyCar/Package.resolved
+++ /dev/null
@@ -1,106 +0,0 @@
-{
- "object": {
- "pins": [
- {
- "package": "grpc-swift",
- "repositoryURL": "https://github.com/grpc/grpc-swift.git",
- "state": {
- "branch": null,
- "revision": "640b0ef1d0be63bda0ada86786cfda678ab2aae9",
- "version": "1.0.0-alpha.19"
- }
- },
- {
- "package": "swift-log",
- "repositoryURL": "https://github.com/apple/swift-log.git",
- "state": {
- "branch": null,
- "revision": "173f567a2dfec11d74588eea82cecea555bdc0bc",
- "version": "1.4.0"
- }
- },
- {
- "package": "swift-nio",
- "repositoryURL": "https://github.com/apple/swift-nio.git",
- "state": {
- "branch": null,
- "revision": "5fc24345f92ec4c274121776c215ab0aa1ed4d50",
- "version": "2.22.0"
- }
- },
- {
- "package": "swift-nio-http2",
- "repositoryURL": "https://github.com/apple/swift-nio-http2.git",
- "state": {
- "branch": null,
- "revision": "1e68e51752be0b43c5a0ef35818c1dd24d13e77c",
- "version": "1.14.1"
- }
- },
- {
- "package": "swift-nio-ssl",
- "repositoryURL": "https://github.com/apple/swift-nio-ssl.git",
- "state": {
- "branch": null,
- "revision": "ea1dfd64193bf5af4490635a4a44c4fb43b1e1ae",
- "version": "2.9.1"
- }
- },
- {
- "package": "swift-nio-transport-services",
- "repositoryURL": "https://github.com/apple/swift-nio-transport-services.git",
- "state": {
- "branch": null,
- "revision": "bb56586c4cab9a79dce6ec4738baddb5802c5de7",
- "version": "1.9.0"
- }
- },
- {
- "package": "SwiftProtobuf",
- "repositoryURL": "https://github.com/apple/swift-protobuf.git",
- "state": {
- "branch": null,
- "revision": "0279688c9fc5a40028e1b5bb0cb56534a45a6020",
- "version": "1.12.0"
- }
- },
- {
- "package": "Swift2dCar",
- "repositoryURL": "https://vato.ddns.net/gitlab/vato007/swift2dcar.git",
- "state": {
- "branch": "master",
- "revision": "970aac902531408614db0a37a7300e9373dafb50",
- "version": null
- }
- },
- {
- "package": "SwiftRPLidar",
- "repositoryURL": "https://vato.ddns.net/gitlab/vato007/swiftrplidar.git",
- "state": {
- "branch": "master",
- "revision": "761eb0bc1a00b4627a7870ffac121a542ff0cd6b",
- "version": null
- }
- },
- {
- "package": "SwiftSerial",
- "repositoryURL": "https://vato.ddns.net/gitlab/vato007/SwiftSerial.git",
- "state": {
- "branch": "master",
- "revision": "27a5d92aa00f6e91581389485994364e16bed2c5",
- "version": null
- }
- },
- {
- "package": "SwiftyGPIO",
- "repositoryURL": "https://github.com/uraimo/SwiftyGPIO.git",
- "state": {
- "branch": null,
- "revision": "2038228e020cf12a62012b1ebe36bb9b8e6fdb6a",
- "version": "1.2.5"
- }
- }
- ]
- },
- "version": 1
-}
diff --git a/SwiftyCar/Package.swift b/SwiftyCar/Package.swift
deleted file mode 100644
index 35852aa..0000000
--- a/SwiftyCar/Package.swift
+++ /dev/null
@@ -1,35 +0,0 @@
-// swift-tools-version:5.1
-// The swift-tools-version declares the minimum version of Swift required to build this package.
-
-import PackageDescription
-
-let package = Package(
- name: "SwiftyCar",
- products: [
- // Products define the executables and libraries produced by a package, and make them visible to other packages.
- ],
- dependencies: [
- // Dependencies declare other packages that this package depends on.
- // .package(url: /* package url */, from: "1.0.0"),
- .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0-alpha.19"),
- .package(url: "https://github.com/uraimo/SwiftyGPIO.git", from: "1.0.0"),
- .package(url: "https://vato.ddns.net/gitlab/vato007/swiftrplidar.git", .branch("master")),
- .package(url: "https://vato.ddns.net/gitlab/vato007/SwiftSerial.git", .branch("master")),
- .package(url: "https://vato.ddns.net/gitlab/vato007/swift2dcar.git", .branch("master"))
- ],
- targets: [
- // Targets are the basic building blocks of a package. A target can define a module or a test suite.
- // Targets can depend on other targets in this package, and on products in packages which this package depends on.
- .target(
- name: "SwiftyCar",
- dependencies: [
- "SwiftyGPIO",
- .product(name: "GRPC", package: "grpc-swift"),
- "SwiftRPLidar",
- "SwiftSerial",
- "Swift2dCar"]),
- .testTarget(
- name: "SwiftyCarTests",
- dependencies: ["SwiftyCar"]),
- ]
-)
diff --git a/SwiftyCar/Sources/SwiftyCar/LidarProvider.swift b/SwiftyCar/Sources/SwiftyCar/LidarProvider.swift
deleted file mode 100644
index 4397fba..0000000
--- a/SwiftyCar/Sources/SwiftyCar/LidarProvider.swift
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// LidarProvider.swift
-//
-//
-// Created by Michael Pivato on 10/7/20.
-//
-
-import Foundation
-import GRPC
-import NIO
-import SwiftProtobuf
-import SwiftRPLidar
-
-class LidarProvider: Persontracking_PersonTrackingProvider {
-
- private let lidar: SwiftRPLidar
- private var shouldScan: Bool = false
-
- init(lidar: SwiftRPLidar) {
- self.lidar = lidar
- }
-
- func set_tracking_group(request: Persontracking_Int32Value, context: StatusOnlyCallContext) -> EventLoopFuture {
- return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
- }
-
- func stop_tracking(request: Google_Protobuf_Empty, context: StatusOnlyCallContext) -> EventLoopFuture {
- shouldScan = false
- return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
- }
-
- func start_tracking(request: Google_Protobuf_Empty, context: StatusOnlyCallContext) -> EventLoopFuture {
- return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
- }
-
- func record(request: Google_Protobuf_BoolValue, context: StatusOnlyCallContext) -> EventLoopFuture {
- return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
- }
-
- func save_lidar(request: MotorControl_SaveRequest, context: StatusOnlyCallContext) -> EventLoopFuture {
- return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
- }
-
- func lidar_stream(request: Persontracking_StreamMessage, context: StreamingResponseCallContext) -> EventLoopFuture {
- shouldScan = true
- try! lidar.iterScans{scan in
- _ = context.sendResponse(.with{protoScan in
- protoScan.points = scan.map{ point in
- Persontracking_Point.with{ protoPoint in
- protoPoint.angle = Double(point.angle)
- protoPoint.distance = Double(point.distance)
- // Placeholder group number.
- protoPoint.groupNumber = 0
- }
- }
- })
- return shouldScan
- }
- return context.eventLoop.makeSucceededFuture(.ok)
- }
-}
diff --git a/SwiftyCar/Sources/SwiftyCar/MotorProvider.swift b/SwiftyCar/Sources/SwiftyCar/MotorProvider.swift
deleted file mode 100644
index 86e5005..0000000
--- a/SwiftyCar/Sources/SwiftyCar/MotorProvider.swift
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// MotorProvider.swift
-//
-//
-// Created by Michael Pivato on 13/5/20.
-//
-
-import Foundation
-import GRPC
-import NIO
-import SwiftProtobuf
-import Swift2dCar
-
-class MotorProvider: MotorControl_CarControlProvider{
- private var vehicle: Vehicle2D
-
- init(vehicle: Vehicle2D){
- self.vehicle = vehicle
- }
-
- func set_throttle(request: MotorControl_ThrottleRequest, context: StatusOnlyCallContext) -> EventLoopFuture {
- self.vehicle.throttle = request.throttle
- return context.eventLoop.makeSucceededFuture(.with{ throttle in
- throttle.throttleSet = true
- })
- }
-
- func set_steering(request: MotorControl_SteeringRequest, context: StatusOnlyCallContext) -> EventLoopFuture {
- self.vehicle.steering = request.steering
- return context.eventLoop.makeSucceededFuture(.with{
- $0.steeringSet = true
- })
- }
-
- func stream_vehicle_2d(context: UnaryResponseCallContext) -> EventLoopFuture<(StreamEvent) -> Void> {
- return context.eventLoop.makeSucceededFuture({event in
- switch event{
- case .message(let movement):
- self.vehicle.throttle = movement.throttle.throttle
- self.vehicle.steering = movement.steering.steering
- case .end:
- context.responsePromise.succeed(Google_Protobuf_Empty())
- }
-
- })
- }
-
- func record(request: MotorControl_RecordingReqeust, context: StatusOnlyCallContext) -> EventLoopFuture {
- // TODO: Recording...
- return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
- }
-
- func save_recorded_data(request: MotorControl_SaveRequest, context: StatusOnlyCallContext) -> EventLoopFuture {
- // TODO Recording...
- return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
- }
-}
-
diff --git a/SwiftyCar/Sources/SwiftyCar/Vehicle.swift b/SwiftyCar/Sources/SwiftyCar/Vehicle.swift
deleted file mode 100644
index 8ba4cfe..0000000
--- a/SwiftyCar/Sources/SwiftyCar/Vehicle.swift
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Vehicle.swift
-//
-//
-// Created by Michael Pivato on 8/5/20.
-//
-
-import Foundation
-import Swift2dCar
-
-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
- }
-}
diff --git a/SwiftyCar/Sources/SwiftyCar/VehicleFactory.swift b/SwiftyCar/Sources/SwiftyCar/VehicleFactory.swift
deleted file mode 100644
index 16f1c7b..0000000
--- a/SwiftyCar/Sources/SwiftyCar/VehicleFactory.swift
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// VehicleFactory.swift
-//
-//
-// Created by Michael Pivato on 20/5/20.
-//
-
-import Foundation
-import SwiftyGPIO
-import Swift2dCar
-import SwiftSerial
-
-func getVehicle2D() throws -> Vehicle2D? {
- // TODO: Clean up this factory, or see if we can get dependency injection working.
- if let value = ProcessInfo.processInfo.environment["CAR_VEHICLE"] {
- switch value{
- case "VEHICLE_2D":
- // Get car for rpi.
- let pwms = SwiftyGPIO.hardwarePWMs(for:.RaspberryPi3)!
- return try RPiVehicle2D(withThrottlePin: PWMHardwareServo(forPin: (pwms[0]?[.P18])!)!, withSteeringPin:PWMHardwareServo(forPin: (pwms[1]?[.P19])!)!)
- case "VEHICLE_SERIAL":
- // TODO: Get from environment variable. tty won't work in macos anyway.
- // We share the serialport object, as cu will block on macOS (required by SwiftSerial), so can't open 2 of the same port.
- let serialPort = SerialPort(path: "/dev/ttyUSB0")
-
- // The port does not open/initialise inside of the ESP32ServoOutputs, as on macOS /dev/cu.* blocks.
- try serialPort.openPort()
- serialPort.setSettings(receiveRate: .baud115200, transmitRate: .baud115200, minimumBytesToRead: 1)
- guard let throttlePin = Esp32ServoOutput(forChannel: 1, forPin: 14, onPort: serialPort) else {
- print("Failed to create throttle pin.")
- return nil
- }
-
- guard let steeringPin = Esp32ServoOutput(forChannel: 2, forPin: 12, onPort: serialPort) else {
- print("Failed to create steering pin.")
- return nil
- }
-
- return try RPiVehicle2D(withThrottlePin: PWMHardwareServo(forPin: throttlePin)!, withSteeringPin: PWMHardwareServo(forPin: steeringPin)!)
- default:
- return MockVehicle()
- }
- }
- return MockVehicle()
-}
diff --git a/SwiftyCar/Sources/SwiftyCar/main.swift b/SwiftyCar/Sources/SwiftyCar/main.swift
deleted file mode 100644
index d0b56b3..0000000
--- a/SwiftyCar/Sources/SwiftyCar/main.swift
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// main.swift
-//
-//
-// Created by Michael Pivato on 8/5/20.
-//
-
-import NIO
-import GRPC
-import SwiftRPLidar
-import SwiftSerial
-
-func doServer() throws {
- // Copied from examples
- // Create an event loop group for the server to run on.
- let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
- defer {
- try! group.syncShutdownGracefully()
- }
-
- let lidar = createLidar()
- try lidar.iterMeasurements{measruement in
- print(measruement.quality)
- return false
- }
- // Create a provider using the features we read.
- let provider = try MotorProvider(vehicle: getVehicle2D()!)
- let trackingProvider = LidarProvider(lidar: lidar)
-
- // Start the server and print its address once it has started.
- let server = Server.insecure(group: group)
- .withServiceProviders([provider, trackingProvider])
- .bind(host: "localhost", port: 0)
-
- server.map {
- $0.channel.localAddress
- }.whenSuccess { address in
- print("server started on port \(address!.port!)")
- }
-
- // Wait on the server's `onClose` future to stop the program from exiting.
- _ = try server.flatMap {
- $0.onClose
- }.wait()
-}
-
-func createLidar() -> SwiftRPLidar{
- return try! SwiftRPLidar(onPort: SerialPort(path: "/dev/cu.usbserial0001"))
-
-}
-
-// Entry-Point to the Swift Car Controller
-print("Starting Server")
-do{
- try doServer()
-}
-catch{
- print("Server failed")
-}
-
-extension SerialPort: LidarSerial{
- public func setBaudrate(baudrate: Int) {
- // TODO: handle different baudrates. Only need this for now.
- switch baudrate{
- default:
- setSettings(receiveRate: .baud115200, transmitRate: .baud115200, minimumBytesToRead: 1)
- }
-
- }
-}
diff --git a/SwiftyCar/Tests/LinuxMain.swift b/SwiftyCar/Tests/LinuxMain.swift
deleted file mode 100644
index c68226f..0000000
--- a/SwiftyCar/Tests/LinuxMain.swift
+++ /dev/null
@@ -1,7 +0,0 @@
-import XCTest
-
-import SwiftyCarTests
-
-var tests = [XCTestCaseEntry]()
-tests += SwiftyCarTests.allTests()
-XCTMain(tests)
diff --git a/SwiftyCar/Tests/SwiftyCarTests/SwiftyCarTests.swift b/SwiftyCar/Tests/SwiftyCarTests/SwiftyCarTests.swift
deleted file mode 100644
index bebfbd1..0000000
--- a/SwiftyCar/Tests/SwiftyCarTests/SwiftyCarTests.swift
+++ /dev/null
@@ -1,15 +0,0 @@
-import XCTest
-@testable import SwiftyCar
-
-final class SwiftyCarTests: XCTestCase {
- func testExample() {
- // This is an example of a functional test case.
- // Use XCTAssert and related functions to verify your tests produce the correct
- // results.
-// XCTAssertEqual(SwiftyCar().text, "Hello, World!")
- }
-
- static var allTests = [
- ("testExample", testExample),
- ]
-}
diff --git a/SwiftyCar/Tests/SwiftyCarTests/XCTestManifests.swift b/SwiftyCar/Tests/SwiftyCarTests/XCTestManifests.swift
deleted file mode 100644
index 02cc67f..0000000
--- a/SwiftyCar/Tests/SwiftyCarTests/XCTestManifests.swift
+++ /dev/null
@@ -1,9 +0,0 @@
-import XCTest
-
-#if !canImport(ObjectiveC)
-public func allTests() -> [XCTestCaseEntry] {
- return [
- testCase(SwiftyCarTests.allTests),
- ]
-}
-#endif
diff --git a/SwiftyCar/build.gradle b/SwiftyCar/build.gradle
deleted file mode 100644
index 38b27e0..0000000
--- a/SwiftyCar/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-configurations{
- swift {
- canBeConsumed = false
- canBeResolved = true
- }
-}
-
-dependencies {
- swift project(path: ':protobuf', configuration: 'swift')
-}
-
-task copySwiftCode(type: Copy, dependsOn: configurations.swift) {
- // Copy python protobuf code from proto project.
- from zipTree(configurations.swift.asPath)
- into './Sources/SwiftyCar'
-}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index bff755d..7a50770 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,12 +4,11 @@ plugins{
}
android {
- compileSdkVersion 30
- buildToolsVersion "29.0.2"
+ compileSdkVersion 32
defaultConfig {
applicationId "org.vato.carcontroller"
minSdkVersion 26
- targetSdkVersion 30
+ targetSdkVersion 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -27,24 +26,25 @@ android {
buildFeatures {
mlModelBinding true
}
+ namespace 'org.vato.carcontroller'
}
dependencies {
implementation project(':protobuf')
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
- implementation 'com.google.android.material:material:1.3.0'
- implementation 'androidx.preference:preference:1.1.1'
+ implementation 'androidx.appcompat:appcompat:1.4.2'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation 'com.google.android.material:material:1.6.1'
+ implementation 'androidx.preference:preference:1.2.0'
implementation 'org.tensorflow:tensorflow-lite-support:0.1.0'
- implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1'
+ implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2'
implementation 'org.tensorflow:tensorflow-lite-gpu:2.3.0'
testImplementation 'junit:junit:4.13.2'
- androidTestImplementation 'androidx.test:runner:1.3.0'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
- implementation 'io.grpc:grpc-okhttp:1.29.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-protobuf-lite:1.29.0' // CURRENT_GRPC_VERSION
- implementation 'io.grpc:grpc-stub:1.29.0' // CURRENT_GRPC_VERSION
- implementation 'javax.annotation:javax.annotation-api:1.2'
+ androidTestImplementation 'androidx.test:runner:1.4.0'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ implementation 'io.grpc:grpc-okhttp:1.29.0'
+ implementation 'io.grpc:grpc-protobuf-lite:1.39.0'
+ implementation 'io.grpc:grpc-stub:1.39.0'
+ implementation 'javax.annotation:javax.annotation-api:1.3.2'
implementation 'org.zeromq:jeromq:0.5.2'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7afa1dd..0d4515e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
-
+
@@ -12,7 +11,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
-
+
diff --git a/app/src/main/java/org/vato/carcontroller/PiLoader.java b/app/src/main/java/org/vato/carcontroller/PiLoader.java
index 3531a87..d840a54 100644
--- a/app/src/main/java/org/vato/carcontroller/PiLoader.java
+++ b/app/src/main/java/org/vato/carcontroller/PiLoader.java
@@ -17,12 +17,12 @@ public class PiLoader implements Runnable {
private Integer steeringValue = 50;
private Integer throttleValue = 50;
- private ManagedChannel mChannel;
+ private final ManagedChannel mChannel;
- private CarControlGrpc.CarControlBlockingStub stub;
- private AtomicBoolean stop = new AtomicBoolean(false);
+ private final CarControlGrpc.CarControlBlockingStub stub;
+ private final AtomicBoolean stop = new AtomicBoolean(false);
private Thread piUpdaterThread;
- private boolean useGrpcStream;
+ private final boolean useGrpcStream;
public PiLoader(String host, Integer port, boolean useGrpcStream) {
mChannel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();
@@ -72,10 +72,10 @@ public class PiLoader implements Runnable {
try {
SteeringResponse steeringResponse = stub.setSteering(
SteeringRequest.newBuilder().setSteering((float) steeringValue / 50f - 1)
- .build());
+ .build());
ThrottleResponse throttleResponse = stub.setThrottle(
ThrottleRequest.newBuilder().setThrottle((float) throttleValue / 50f - 1)
- .build());
+ .build());
} catch (Exception e) {
System.out.println("Error");
stop();
@@ -93,9 +93,9 @@ public class PiLoader implements Runnable {
private void doStreamUpdates() {
// Stream if user sets use_grpc_streams to true. This method is more efficient but less compatible.
final CountDownLatch finishLatch = new CountDownLatch(1);
- StreamObserver responseObserver = new StreamObserver() {
+ StreamObserver responseObserver = new StreamObserver() {
@Override
- public void onNext(Empty value) {
+ public void onNext(Vehicle2DResponse value) {
finishLatch.countDown();
Log.d("PiLoader", "Finished streaming");
}
@@ -113,23 +113,23 @@ public class PiLoader implements Runnable {
}
};
StreamObserver requestStreamObserver = CarControlGrpc.newStub(mChannel)
- .streamVehicle2d(
- responseObserver);
+ .streamVehicle2d(
+ responseObserver);
while (!stop.get() && !Thread.interrupted() && finishLatch.getCount() > 0) {
requestStreamObserver.onNext(Vehicle2DRequest.newBuilder()
- .setThrottle(ThrottleRequest.newBuilder()
- .setThrottle(
- (float) throttleValue /
- 50f -
- 1)
- .build())
- .setSteering(SteeringRequest.newBuilder()
- .setSteering(
- (float) steeringValue /
- 50f -
- 1)
- .build())
- .build());
+ .setThrottle(ThrottleRequest.newBuilder()
+ .setThrottle(
+ (float) throttleValue /
+ 50f -
+ 1)
+ .build())
+ .setSteering(SteeringRequest.newBuilder()
+ .setSteering(
+ (float) steeringValue /
+ 50f -
+ 1)
+ .build())
+ .build());
try {
// Use the same update rate as a typical screen refresh rate.
TimeUnit.MILLISECONDS.sleep(200);
@@ -141,12 +141,12 @@ public class PiLoader implements Runnable {
public void saveRecording() {
// Ideally don't want to use a blocking stub here, android may complain.
- Empty done = stub.saveRecordedData(SaveRequest.newBuilder().setFile("Test").build());
+ SaveResponse done = stub.saveRecordedData(SaveRequest.newBuilder().setFile("Test").build());
}
public void record(boolean record) {
// Ideally don't want to use a blocking stub here, android may complain.
- Empty done = stub.record(RecordingReqeust.newBuilder().setRecord(record).build());
+ RecordingResponse done = stub.record(RecordingReqeust.newBuilder().setRecord(record).build());
}
}
diff --git a/build.gradle b/build.gradle
index 4eb8095..a905ce6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,10 +3,10 @@
buildscript {
repositories {
google()
- jcenter()
+ mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.16'
// NOTE: Do not place your application dependencies here; they belong
@@ -17,8 +17,7 @@ buildscript {
allprojects {
repositories {
google()
- jcenter()
- mavenLocal()
+ mavenCentral()
}
}
diff --git a/car-rs/Cargo.lock b/car-rs/Cargo.lock
new file mode 100644
index 0000000..ca8ea39
--- /dev/null
+++ b/car-rs/Cargo.lock
@@ -0,0 +1,1173 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "CoreFoundation-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b"
+dependencies = [
+ "libc",
+ "mach 0.1.2",
+]
+
+[[package]]
+name = "IOKit-sys"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a"
+dependencies = [
+ "CoreFoundation-sys",
+ "libc",
+ "mach 0.1.2",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"
+
+[[package]]
+name = "async-stream"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "axum"
+version = "0.5.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b9496f0c1d1afb7a2af4338bbe1d969cddfead41d87a9fb3aaa6d0bbc7af648"
+dependencies = [
+ "async-trait",
+ "axum-core",
+ "bitflags",
+ "bytes",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "itoa",
+ "matchit",
+ "memchr",
+ "mime",
+ "percent-encoding",
+ "pin-project-lite",
+ "serde",
+ "sync_wrapper",
+ "tokio",
+ "tower",
+ "tower-http",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "axum-core"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4f44a0e6200e9d11a1cdc989e4b358f6e3d354fbf48478f345a17f4e43f8635"
+dependencies = [
+ "async-trait",
+ "bytes",
+ "futures-util",
+ "http",
+ "http-body",
+ "mime",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bytes"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
+
+[[package]]
+name = "car-rs"
+version = "0.1.0"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "prost",
+ "rppal",
+ "serialport",
+ "tokio",
+ "tonic",
+ "tonic-build",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "either"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
+
+[[package]]
+name = "fastrand"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "futures-channel"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
+
+[[package]]
+name = "futures-task"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
+
+[[package]]
+name = "futures-util"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
+dependencies = [
+ "futures-core",
+ "futures-macro",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "heck"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "http"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "http-range-header"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
+
+[[package]]
+name = "httparse"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "hyper"
+version = "0.14.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-timeout"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
+dependencies = [
+ "hyper",
+ "pin-project-lite",
+ "tokio",
+ "tokio-io-timeout",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.127"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"
+
+[[package]]
+name = "libudev"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0"
+dependencies = [
+ "libc",
+ "libudev-sys",
+]
+
+[[package]]
+name = "libudev-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
+dependencies = [
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "mach"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "mach"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "matchit"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "mio"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "multimap"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
+
+[[package]]
+name = "nix"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-sys",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+
+[[package]]
+name = "petgraph"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143"
+dependencies = [
+ "fixedbitset",
+ "indexmap",
+]
+
+[[package]]
+name = "pin-project"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+
+[[package]]
+name = "prettyplease"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "697ae720ee02011f439e0701db107ffe2916d83f718342d65d7f8bf7b8a5fee9"
+dependencies = [
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "prost"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "399c3c31cdec40583bb68f0b18403400d01ec4289c383aa047560439952c4dd7"
+dependencies = [
+ "bytes",
+ "prost-derive",
+]
+
+[[package]]
+name = "prost-build"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f835c582e6bd972ba8347313300219fed5bfa52caf175298d860b61ff6069bb"
+dependencies = [
+ "bytes",
+ "heck",
+ "itertools",
+ "lazy_static",
+ "log",
+ "multimap",
+ "petgraph",
+ "prost",
+ "prost-types",
+ "regex",
+ "tempfile",
+ "which",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7345d5f0e08c0536d7ac7229952590239e77abf0a0100a1b1d890add6ea96364"
+dependencies = [
+ "anyhow",
+ "itertools",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dfaa718ad76a44b3415e6c4d53b17c8f99160dcb3a99b10470fce8ad43f6e3e"
+dependencies = [
+ "bytes",
+ "prost",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+
+[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "rppal"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c88c9c6248de4d337747b619d8f671055ef48a87dc21b97998833f189a0bbd4f"
+dependencies = [
+ "lazy_static",
+ "libc",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "serde"
+version = "1.0.142"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2"
+
+[[package]]
+name = "serialport"
+version = "4.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aab92efb5cf60ad310548bc3f16fa6b0d950019cb7ed8ff41968c3d03721cf12"
+dependencies = [
+ "CoreFoundation-sys",
+ "IOKit-sys",
+ "bitflags",
+ "cfg-if",
+ "libudev",
+ "mach 0.3.2",
+ "nix",
+ "regex",
+ "winapi",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
+
+[[package]]
+name = "socket2"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "sync_wrapper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
+
+[[package]]
+name = "tempfile"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "libc",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi",
+]
+
+[[package]]
+name = "tokio"
+version = "1.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581"
+dependencies = [
+ "autocfg",
+ "bytes",
+ "libc",
+ "memchr",
+ "mio",
+ "num_cpus",
+ "once_cell",
+ "parking_lot",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "winapi",
+]
+
+[[package]]
+name = "tokio-io-timeout"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
+dependencies = [
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "tonic"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "498f271adc46acce75d66f639e4d35b31b2394c295c82496727dafa16d465dd2"
+dependencies = [
+ "async-stream",
+ "async-trait",
+ "axum",
+ "base64",
+ "bytes",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-timeout",
+ "percent-encoding",
+ "pin-project",
+ "prost",
+ "prost-derive",
+ "tokio",
+ "tokio-stream",
+ "tokio-util",
+ "tower",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "tonic-build"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fbcd2800e34e743b9ae795867d5f77b535d3a3be69fd731e39145719752df8c"
+dependencies = [
+ "prettyplease",
+ "proc-macro2",
+ "prost-build",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "indexmap",
+ "pin-project",
+ "pin-project-lite",
+ "rand",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
+dependencies = [
+ "bitflags",
+ "bytes",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-range-header",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
+
+[[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
+name = "tracing"
+version = "0.1.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"
+dependencies = [
+ "cfg-if",
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "tracing-futures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
+dependencies = [
+ "pin-project",
+ "tracing",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
+
+[[package]]
+name = "want"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+dependencies = [
+ "log",
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "which"
+version = "4.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
+dependencies = [
+ "either",
+ "lazy_static",
+ "libc",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
diff --git a/car-rs/Cargo.toml b/car-rs/Cargo.toml
new file mode 100644
index 0000000..b421f4e
--- /dev/null
+++ b/car-rs/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+name = "car-rs"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+# https://github.com/golemparts/rppal
+rppal = { version = "0.13.1", optional = true }
+futures-core = "0.3"
+futures-util = "0.3"
+tokio = { version = "1", features = ["full"] }
+prost = "0.11"
+
+# https://github.com/hyperium/tonic
+tonic = "0.8.0"
+
+# https://docs.rs/serialport/4.0.1/serialport/index.html
+serialport = "4.0.1"
+
+[build-dependencies]
+tonic-build = "0.8.0"
+
+[features]
+rppal = ["dep:rppal"]
\ No newline at end of file
diff --git a/car-rs/build.rs b/car-rs/build.rs
new file mode 100644
index 0000000..b47d655
--- /dev/null
+++ b/car-rs/build.rs
@@ -0,0 +1,7 @@
+fn main() -> Result<(), Box> {
+ tonic_build::configure().compile(
+ &["../protobuf/src/main/proto/car/control/motorService.proto"],
+ &["../protobuf/src/main/proto"],
+ )?;
+ Ok(())
+}
diff --git a/car-rs/src/grpcserver.rs b/car-rs/src/grpcserver.rs
new file mode 100644
index 0000000..1c46876
--- /dev/null
+++ b/car-rs/src/grpcserver.rs
@@ -0,0 +1,89 @@
+pub mod motor_control_service {
+ tonic::include_proto!("motor_control");
+}
+
+use std::{sync::Mutex, time::Duration};
+
+use car_rs::{Servo, Vehicle};
+use futures_util::StreamExt;
+use motor_control_service::car_control_server::CarControl;
+use tokio::time;
+use tonic::{Request, Response, Status, Streaming};
+
+use self::motor_control_service::{
+ RecordingReqeust, RecordingResponse, SaveRequest, SaveResponse, SteeringRequest,
+ SteeringResponse, ThrottleRequest, ThrottleResponse, Vehicle2DRequest, Vehicle2DResponse,
+};
+
+#[derive(Debug)]
+pub struct MotorControlService
+where
+ T: Vehicle,
+{
+ // TODO: Any better way than mutex? need it over refcell to implement send, and need a smart pointer
+ // for interior mutability (since the generated protobuf functions aren't mut)
+ vehicle: Mutex,
+}
+
+impl MotorControlService {
+ pub fn new(vehicle: T) -> MotorControlService {
+ MotorControlService {
+ vehicle: Mutex::new(vehicle),
+ }
+ }
+}
+
+#[tonic::async_trait]
+impl CarControl for MotorControlService {
+ async fn set_throttle(
+ &self,
+ _request: Request,
+ ) -> Result, Status> {
+ self.vehicle
+ .lock()
+ .unwrap()
+ .set_throttle(_request.into_inner().throttle as f64);
+ Ok(Response::new(ThrottleResponse { throttle_set: true }))
+ }
+
+ async fn set_steering(
+ &self,
+ _request: Request,
+ ) -> Result, Status> {
+ self.vehicle
+ .lock()
+ .unwrap()
+ .set_steering(_request.into_inner().steering as f64);
+ Ok(Response::new(SteeringResponse { steering_set: true }))
+ }
+
+ async fn stream_vehicle_2d(
+ &self,
+ request: Request>,
+ ) -> Result, Status> {
+ let mut stream = request.into_inner();
+ while let Ok(Some(Ok(req))) = time::timeout(Duration::from_secs(3), stream.next()).await {
+ let mut vehicle = self.vehicle.lock().unwrap();
+ vehicle.set_throttle(req.throttle.unwrap().throttle as f64);
+ vehicle.set_steering(req.steering.unwrap().steering as f64);
+ }
+
+ self.vehicle.lock().unwrap().set_throttle(0.);
+
+ Ok(Response::new(Vehicle2DResponse {}))
+ }
+
+ async fn record(
+ &self,
+ _request: Request,
+ ) -> Result, Status> {
+ unimplemented!()
+ }
+
+ async fn save_recorded_data(
+ &self,
+ _request: Request,
+ ) -> Result, Status> {
+ unimplemented!()
+ }
+}
diff --git a/car-rs/src/lib.rs b/car-rs/src/lib.rs
new file mode 100644
index 0000000..80da653
--- /dev/null
+++ b/car-rs/src/lib.rs
@@ -0,0 +1,211 @@
+use std::sync::{Arc, Mutex};
+
+use serialport::SerialPort;
+
+// TODO: Should be returning results in these traits
+pub trait Servo {
+ fn get_value(&self) -> f64;
+
+ fn set_value(&mut self, value: f64);
+
+ fn min(&mut self) {
+ self.set_value(-1.);
+ }
+ fn mid(&mut self) {
+ self.set_value(0.);
+ }
+ fn max(&mut self) {
+ self.set_value(1.);
+ }
+}
+
+pub trait Vehicle {
+ fn get_throttle(&self) -> f64;
+ fn set_throttle(&mut self, throttle: f64);
+ fn get_steering(&self) -> f64;
+ fn set_steering(&mut self, steering: f64);
+}
+#[cfg(feature = "rppal")]
+pub mod rppal {
+ use rppal::pwm::{Channel, Pwm};
+
+ pub struct RpiPwmServo {
+ pwm: Pwm,
+ min_duty_cycle: f64,
+ duty_cycle_range: f64,
+ value: f64,
+ frame_width: f64,
+ }
+
+ impl RpiPwmServo {
+ pub fn new(pwm: Pwm) -> RpiPwmServo {
+ RpiPwmServo::new(pwm, 1000000)
+ }
+
+ pub fn new(pwm: Pwm, min_pulse_width: f64) -> RpiPwmServo {}
+
+ pub fn new(
+ pwm: Pwm,
+ min_pulse_width: f64,
+ max_pulse_width: f64,
+ frame_width: f64,
+ ) -> RpiPwmServo {
+ RpiPwmServo {
+ pwm,
+ min_duty_cycle: min_pulse_width / frame_width,
+ duty_cycle_range: (max_pulse_width - min_pulse_width) / frame_width,
+ frame_width,
+ }
+ }
+ }
+
+ impl Default for RpiPwmServo {
+ fn default() -> Self {
+ Self {
+ pwm: Pwm::new(Channel::Pwm0).expect("Failed to initialise Pwm servo"),
+ }
+ }
+ }
+
+ impl Servo for RpiPwmServo {
+ fn get_duty_cycle(&self) -> f64 {
+ self.pwm.duty_cycle().unwrap_or(0.)
+ }
+
+ fn set_duty_cycle(&self, pwm: f64) {
+ self.pwm
+ .set_duty_cycle(pwm)
+ .expect("Failed to write duty cycle");
+ }
+
+ fn get_frequency(&self) -> f64 {
+ self.pwm.duty_cycle().unwrap_or(0.0)
+ }
+
+ fn set_frequency(&self, frequency: f64) {
+ self.pwm
+ .set_frequency(frequency, self.get_duty_cycle())
+ .expect("Failed to set Frequency")
+ }
+ }
+}
+
+pub struct Esp32SerialPwmServo {
+ serial_port: Arc>,
+ value: f64,
+ channel: u8,
+ pin: u8,
+}
+
+impl Esp32SerialPwmServo {
+ pub fn new(serial_port: Arc>, channel: u8, pin: u8) -> Esp32SerialPwmServo {
+ let mut servo = Esp32SerialPwmServo {
+ serial_port,
+ value: 0.,
+ channel,
+ pin,
+ };
+ servo.init_pwm();
+ servo
+ }
+}
+
+impl Esp32SerialPwmServo {
+ fn init_pwm(&mut self) {
+ let bytes_written = self
+ .serial_port
+ .lock()
+ .unwrap()
+ .write(&[0, 1, self.channel, self.pin]);
+ // TODO: Better error handling (even anyhow would be better)
+ match bytes_written {
+ Ok(size) => println!("{}", size),
+ Err(err) => eprintln!("{}", err),
+ }
+ }
+}
+
+impl Servo for Esp32SerialPwmServo {
+ fn get_value(&self) -> f64 {
+ self.value
+ }
+
+ fn set_value(&mut self, value: f64) {
+ let mut temp_value = value;
+ // TODO: Panic when out of bounds?
+ if temp_value < -1. {
+ temp_value = -1.;
+ } else if temp_value > 1. {
+ temp_value = 1.;
+ }
+ self.value = temp_value;
+ let bytes_written = self
+ .serial_port
+ .lock()
+ .unwrap()
+ .write(&[self.channel, ((value + 1.) / 2. * 255.) as u8]);
+ // TODO: Better error handling
+ match bytes_written {
+ Ok(size) => println!("{}", size),
+ Err(err) => eprintln!("{}", err),
+ }
+ }
+}
+
+pub struct ServoVehicle {
+ steering_servo: T,
+ throttle_servo: T,
+}
+
+impl ServoVehicle {
+ pub fn new(steering_servo: T, throttle_servo: T) -> ServoVehicle {
+ ServoVehicle {
+ steering_servo,
+ throttle_servo,
+ }
+ }
+}
+
+impl Vehicle for ServoVehicle {
+ fn get_throttle(&self) -> f64 {
+ self.throttle_servo.get_value()
+ }
+
+ fn set_throttle(&mut self, throttle: f64) {
+ self.throttle_servo.set_value(throttle);
+ }
+
+ fn get_steering(&self) -> f64 {
+ self.steering_servo.get_value()
+ }
+
+ fn set_steering(&mut self, steering: f64) {
+ self.steering_servo.set_value(steering);
+ }
+}
+
+#[derive(Default, Debug)]
+pub struct PrintVehicle {
+ throttle: f64,
+ steering: f64,
+}
+
+impl Vehicle for PrintVehicle {
+ fn get_throttle(&self) -> f64 {
+ self.throttle
+ }
+
+ fn set_throttle(&mut self, throttle: f64) {
+ println!("New Throttle: {}", throttle);
+ self.throttle = throttle;
+ }
+
+ fn get_steering(&self) -> f64 {
+ self.steering
+ }
+
+ fn set_steering(&mut self, steering: f64) {
+ println!("New Steering: {}", steering);
+ self.steering = steering;
+ }
+}
diff --git a/car-rs/src/main.rs b/car-rs/src/main.rs
new file mode 100644
index 0000000..b66f42a
--- /dev/null
+++ b/car-rs/src/main.rs
@@ -0,0 +1,29 @@
+use std::sync::{Arc, Mutex};
+
+use car_rs::{Esp32SerialPwmServo, ServoVehicle};
+use grpcserver::{
+ motor_control_service::car_control_server::CarControlServer, MotorControlService,
+};
+
+use tonic::transport::Server;
+
+mod grpcserver;
+
+#[tokio::main]
+async fn main() -> Result<(), Box> {
+ let addr = "[::1]:10000".parse().unwrap();
+
+ let serial_port = serialport::new("", 32400)
+ .open_native()
+ .expect("Could not open serial port");
+ let serial_servo = Arc::new(Mutex::new(serial_port));
+ let steering_servo = Esp32SerialPwmServo::new(serial_servo.clone(), 1, 12);
+ let throttle_servo = Esp32SerialPwmServo::new(serial_servo.clone(), 2, 18);
+
+ let motor_control = MotorControlService::new(ServoVehicle::new(steering_servo, throttle_servo));
+
+ let svc = CarControlServer::new(motor_control);
+ Server::builder().add_service(svc).serve(addr).await?;
+
+ Ok(())
+}
diff --git a/esp32/src/main.cpp b/esp32/src/main.cpp
index e189f14..48a54dc 100644
--- a/esp32/src/main.cpp
+++ b/esp32/src/main.cpp
@@ -19,8 +19,8 @@ void setup()
void setupServos(uint8_t size, uint8_t *calibrationValues)
{
- // We assume there are 3 bytes per servo. Ignore if there aren't.
- if (size % 3 == 0)
+ // We assume there are 2 bytes per servo [channel number, pin number]. Ignore if there aren't.
+ if (size % 2 == 0)
{
for (int i = 0; i < size; i += 2)
{
@@ -33,27 +33,25 @@ void setupServos(uint8_t size, uint8_t *calibrationValues)
void modifyServo(uint8_t channel, uint8_t newAngle)
{
- if(servos.count(channel) > 0){
+ if (servos.count(channel) > 0)
+ {
servos[channel]->write(newAngle);
- }
+ }
}
void loop()
{
- uint8_t *header = new uint8_t[2];
+ uint8_t header[2];
Serial.readBytes(header, 2);
if (header[0] == 0)
{
- uint8_t *calibration = new uint8_t[2 * header[1]];
+ uint8_t calibration[2 * header[1]];
Serial.readBytes(calibration, header[1]);
setupServos(header[1], calibration);
- delete [] calibration;
}
else
{
modifyServo(header[0], header[1]);
}
-
- delete [] header;
}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index f371643..41dfb87 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/protobuf/src/main/proto/car/control/motorService.proto b/protobuf/src/main/proto/car/control/motorService.proto
index ed75f8d..b6e1ff9 100644
--- a/protobuf/src/main/proto/car/control/motorService.proto
+++ b/protobuf/src/main/proto/car/control/motorService.proto
@@ -7,8 +7,6 @@ option java_multiple_files = true;
option java_package = "org.vato.carcontroller";
option java_outer_classname = "MotorServiceProto";
-import "google/protobuf/empty.proto";
-
message ThrottleRequest{
float throttle = 1;
}
@@ -38,10 +36,22 @@ message SaveRequest{
string file = 1;
}
+message Vehicle2DResponse {
+
+}
+
+message RecordingResponse {
+
+}
+
+message SaveResponse {
+
+}
+
service CarControl{
rpc set_throttle(ThrottleRequest) returns (ThrottleResponse){}
rpc set_steering(SteeringRequest) returns (SteeringResponse){}
- rpc stream_vehicle_2d(stream Vehicle2DRequest) returns (google.protobuf.Empty){}
- rpc record(RecordingReqeust) returns (google.protobuf.Empty) {}
- rpc save_recorded_data(SaveRequest) returns (google.protobuf.Empty) {}
+ rpc stream_vehicle_2d(stream Vehicle2DRequest) returns (Vehicle2DResponse){}
+ rpc record(RecordingReqeust) returns (RecordingResponse) {}
+ rpc save_recorded_data(SaveRequest) returns (SaveResponse) {}
}