From 4b3b960d222ac82033a1891e3a2a6b959d38e175 Mon Sep 17 00:00:00 2001
From: Piv <18462828+Piv200@users.noreply.github.com>
Date: Wed, 6 May 2020 21:44:42 +0930
Subject: [PATCH] iOS simple controller works
---
.vscode/launch.json | 4 +-
.../xcshareddata/swiftpm/Package.resolved | 4 +-
.../CarController/ContentView.swift | 14 +++-
CarControlleriOS/CarController/PiLoader.swift | 67 +++++++++----------
.../CarController/ServerData.swift | 18 +++--
.../CarController/Settings.bundle/Root.plist | 42 +++---------
.../CarController/SimpleControllerView.swift | 38 ++++++-----
7 files changed, 90 insertions(+), 97 deletions(-)
diff --git a/.vscode/launch.json b/.vscode/launch.json
index ffe4adf..7c79804 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -10,9 +10,9 @@
"request": "launch",
"module": "car",
"env": {
- "CAR_LIDAR": "LIDAR_RPLIDAR",
+ "CAR_LIDAR": "LIDAR_MOCK",
"CAR_VEHICLE": "CAR_MOCK",
- "LIDAR_DEVICE": "/dev/tty.usbserial-0001"
+ // "LIDAR_DEVICE": "/dev/tty.usbserial-0001"
}
},
{
diff --git a/CarControlleriOS/CarController.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CarControlleriOS/CarController.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
index c90f41d..12fe0a3 100644
--- a/CarControlleriOS/CarController.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/CarControlleriOS/CarController.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -24,8 +24,8 @@
"repositoryURL": "https://github.com/apple/swift-nio.git",
"state": {
"branch": null,
- "revision": "e876fb37410e0036b98b5361bb18e6854739572b",
- "version": "2.16.0"
+ "revision": "40bdad80882d307abe2c0bb36cf3bd4d3e03fe04",
+ "version": "2.16.1"
}
},
{
diff --git a/CarControlleriOS/CarController/ContentView.swift b/CarControlleriOS/CarController/ContentView.swift
index 5f8de90..7044469 100644
--- a/CarControlleriOS/CarController/ContentView.swift
+++ b/CarControlleriOS/CarController/ContentView.swift
@@ -15,16 +15,26 @@ struct ContentView: View {
NavigationLink(destination: SimpleControllerView()){
Text("Simple Controller")
}
-
// TODO: Change these when other functionality is implemented
+ NavigationLink(destination: SimpleControllerView()){
+ Text("Gamepad controller")
+ }
NavigationLink(destination: SimpleControllerView()){
Text("SLAM Controller")
}
NavigationLink(destination: SimpleControllerView()){
- Text("Tracking Controller")
+ Text("Lidar Tracking Controller")
+ }
+ NavigationLink(destination: SimpleControllerView()){
+ Text("Mono Camera Tracking Controller")
+ }
+ NavigationLink(destination: SimpleControllerView()){
+ Text("Hybrid Lidar Camera Tracking Controller")
}
}
+ .navigationBarTitle(Text("Controllers"))
}
+ .navigationViewStyle(StackNavigationViewStyle())
}
}
diff --git a/CarControlleriOS/CarController/PiLoader.swift b/CarControlleriOS/CarController/PiLoader.swift
index 3e007dd..1c42a58 100644
--- a/CarControlleriOS/CarController/PiLoader.swift
+++ b/CarControlleriOS/CarController/PiLoader.swift
@@ -15,42 +15,32 @@ class PiLoader: ObservableObject {
// Find a cleaner way to handle these properties
@Published var throttle: Float = 0.5
@Published var steering: Float = 0.5
- let port: Int = 50051
var stopped = false
- func makeClient(port: Int, group: EventLoopGroup) -> MotorControl_CarControlClient {
- let channel = ClientConnection.insecure(group: group)
- // TODO: Pass the host in based on the settings.
- .connect(host: "10.0.0.55", port: port)
-
- return MotorControl_CarControlClient(channel: channel)
- }
-
- func startUpdating() {
- let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
- defer {
- try? group.syncShutdownGracefully()
- }
- let client = makeClient(port: self.port, group: group)
- let options = CallOptions(timeout: .seconds(rounding: 10))
- let call = client.stream_vehicle_2d(callOptions: options)
-
- call.response.whenFailure { error in
- print("RecordRoute Failed: \(error)")
- self.stop()
- }
-
- call.status.whenComplete { _ in
- print("Finished RecordRoute")
- self.stop()
- }
-
- call.response.whenSuccess { summary in
- print("Finished")
- self.stop()
- }
-
- DispatchQueue.global(qos: .userInteractive).async{
+ func startUpdating(forPort port: Int, atHost host: String) {
+ DispatchQueue.global(qos: .background).async{
+ let group = PlatformSupport.makeEventLoopGroup(loopCount: 1)
+ defer {
+ try? group.syncShutdownGracefully()
+ }
+ let client = makeClient(port: port, host: host, group: group)
+ let options = CallOptions(timeout: .seconds(rounding: 10))
+ let call = client.stream_vehicle_2d(callOptions: options)
+
+ call.response.whenFailure { error in
+ print("Failed: \(error)")
+ self.stop()
+ }
+
+ call.status.whenComplete { _ in
+ print("Finished")
+ self.stop()
+ }
+
+ call.response.whenSuccess { summary in
+ print("Finished")
+ self.stop()
+ }
// Running in background. Do the update thread stuff.
while (!self.stopped){
call.sendMessage(self.createProto(), promise: nil)
@@ -74,3 +64,12 @@ class PiLoader: ObservableObject {
}
}
}
+
+func makeClient(port: Int, host: String, group: EventLoopGroup) -> MotorControl_CarControlClient {
+ let channel = ClientConnection.insecure(group: group)
+ // TODO: Pass the host in based on the settings.
+ .connect(host: host, port: port)
+
+
+ return MotorControl_CarControlClient(channel: channel)
+}
diff --git a/CarControlleriOS/CarController/ServerData.swift b/CarControlleriOS/CarController/ServerData.swift
index e23830e..c049235 100644
--- a/CarControlleriOS/CarController/ServerData.swift
+++ b/CarControlleriOS/CarController/ServerData.swift
@@ -8,20 +8,18 @@
import Foundation
+struct UserKeys{
+ static let host = "host"
+ static let port = "port"
+}
+
final class ServerData: ObservableObject{
- // TODO: Find a way to save/represent this stuff in iOS settings/preferences (user can access via settings app).
- // Then load the below values ar runtime, from settings.
- // Ideally want to be able to open this settings page from within the app as well.
-
-
- @Published var port: Int = 50051
- @Published var grpcPort: Int = 50050
- @Published var host: String = "10.0.0.53"
+ @Published var host: String = UserDefaults.standard.string(forKey: UserKeys.host) ?? "10.0.0.53"
+ @Published var grpcPort: Int = UserDefaults.standard.integer(forKey: UserKeys.port)
func load(){
- // Load the server values from settings, if they had been
- // previously saved.
+ // Load the server values from settings, if they had been previously saved.
}
func save(){
diff --git a/CarControlleriOS/CarController/Settings.bundle/Root.plist b/CarControlleriOS/CarController/Settings.bundle/Root.plist
index b1b6fea..1261bd8 100644
--- a/CarControlleriOS/CarController/Settings.bundle/Root.plist
+++ b/CarControlleriOS/CarController/Settings.bundle/Root.plist
@@ -6,23 +6,15 @@
Root
PreferenceSpecifiers
-
- Type
- PSGroupSpecifier
- Title
- Group
-
Type
PSTextFieldSpecifier
Title
- Name
+ Host
Key
- name_preference
+ host
DefaultValue
-
- IsSecure
-
+ 10.0.0.53
KeyboardType
Alphabet
AutocapitalizationType
@@ -32,29 +24,17 @@
Type
- PSToggleSwitchSpecifier
+ PSTextFieldSpecifier
Title
- Enabled
+ Port
Key
- enabled_preference
+ port
DefaultValue
-
-
-
- Type
- PSSliderSpecifier
- Key
- slider_preference
- DefaultValue
- 0.5
- MinimumValue
- 0
- MaximumValue
- 1
- MinimumValueImage
-
- MaximumValueImage
-
+ 50051
+ IsSecure
+
+ KeyboardType
+ NumberPad
diff --git a/CarControlleriOS/CarController/SimpleControllerView.swift b/CarControlleriOS/CarController/SimpleControllerView.swift
index ee5188f..fa866ec 100644
--- a/CarControlleriOS/CarController/SimpleControllerView.swift
+++ b/CarControlleriOS/CarController/SimpleControllerView.swift
@@ -10,27 +10,33 @@ import SwiftUI
struct SimpleControllerView: View {
@EnvironmentObject var server: ServerData
-
- // Need lazy so that we can initialise with local properties.
@ObservedObject var grpcController: PiLoader = PiLoader()
var body: some View {
- HStack{
- Slider(value: $grpcController.throttle, in: 0...1){_ in
- self.grpcController.throttle = 0.5
+ VStack (alignment: .trailing, spacing: 0){
+ Spacer()
+ HStack{
+ // Move this up a bit, due to being rotated.
+ Slider(value: self.$grpcController.throttle, in: 0...1){_ in
+ self.grpcController.throttle = 0.5
+ }
+ .offset(x: 200)
+ .frame(width: 300)
+ .rotationEffect(.degrees(270))
+ Spacer()
+ Slider(value: self.$grpcController.steering, in: 0...1){_ in
+ self.grpcController.steering = 0.5
+ }
+ .frame(width:300)
+ .offset(x: -50, y: -200)
+ .padding()
}
- .rotationEffect(.degrees(270))
-
- Slider(value: $grpcController.steering, in: 0...1){_ in
- self.grpcController.steering = 0.5
+ .onAppear(){
+ self.grpcController.startUpdating(forPort: self.server.grpcPort, atHost: self.server.host)
+ }
+ .onDisappear(){
+ self.grpcController.stop()
}
- }
- .onAppear(){
- self.grpcController.startUpdating()
- }
- .onDisappear(){
- // Stop the gRPC updater.
- self.grpcController.stop()
}
}
}