Add lidar streaming support to SwiftyCar
This commit is contained in:
@@ -13,13 +13,15 @@ let package = Package(
|
|||||||
// .package(url: /* package url */, from: "1.0.0"),
|
// .package(url: /* package url */, from: "1.0.0"),
|
||||||
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0-alpha.12"),
|
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0-alpha.12"),
|
||||||
.package(url: "https://github.com/uraimo/SwiftyGPIO.git", from: "1.0.0"),
|
.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("dtr_support"))
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
// 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.
|
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
||||||
.target(
|
.target(
|
||||||
name: "SwiftyCar",
|
name: "SwiftyCar",
|
||||||
dependencies: ["SwiftyGPIO", .product(name: "GRPC", package: "grpc-swift")]),
|
dependencies: ["SwiftyGPIO", .product(name: "GRPC", package: "grpc-swift"), "SwiftRPLidar"]),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "SwiftyCarTests",
|
name: "SwiftyCarTests",
|
||||||
dependencies: ["SwiftyCar"]),
|
dependencies: ["SwiftyCar"]),
|
||||||
|
|||||||
61
SwiftyCar/Sources/SwiftyCar/LidarProvider.swift
Normal file
61
SwiftyCar/Sources/SwiftyCar/LidarProvider.swift
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// 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<Google_Protobuf_Empty> {
|
||||||
|
return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop_tracking(request: Google_Protobuf_Empty, context: StatusOnlyCallContext) -> EventLoopFuture<Google_Protobuf_Empty> {
|
||||||
|
shouldScan = false
|
||||||
|
return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
func start_tracking(request: Google_Protobuf_Empty, context: StatusOnlyCallContext) -> EventLoopFuture<Google_Protobuf_Empty> {
|
||||||
|
return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
func record(request: Google_Protobuf_BoolValue, context: StatusOnlyCallContext) -> EventLoopFuture<Google_Protobuf_Empty> {
|
||||||
|
return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
func save_lidar(request: MotorControl_SaveRequest, context: StatusOnlyCallContext) -> EventLoopFuture<Google_Protobuf_Empty> {
|
||||||
|
return context.eventLoop.makeSucceededFuture(Google_Protobuf_Empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
func lidar_stream(request: Persontracking_StreamMessage, context: StreamingResponseCallContext<Persontracking_PointScan>) -> EventLoopFuture<GRPCStatus> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,8 +19,8 @@ class MotorProvider: MotorControl_CarControlProvider{
|
|||||||
|
|
||||||
func set_throttle(request: MotorControl_ThrottleRequest, context: StatusOnlyCallContext) -> EventLoopFuture<MotorControl_ThrottleResponse> {
|
func set_throttle(request: MotorControl_ThrottleRequest, context: StatusOnlyCallContext) -> EventLoopFuture<MotorControl_ThrottleResponse> {
|
||||||
self.vehicle.throttle = request.throttle
|
self.vehicle.throttle = request.throttle
|
||||||
return context.eventLoop.makeSucceededFuture(.with{
|
return context.eventLoop.makeSucceededFuture(.with{ throttle in
|
||||||
$0.throttleSet = true
|
throttle.throttleSet = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
import NIO
|
import NIO
|
||||||
import GRPC
|
import GRPC
|
||||||
|
import SwiftRPLidar
|
||||||
|
import SwiftSerial
|
||||||
|
|
||||||
func doServer() throws {
|
func doServer() throws {
|
||||||
// Copied from examples
|
// Copied from examples
|
||||||
@@ -19,10 +21,11 @@ func doServer() throws {
|
|||||||
|
|
||||||
// Create a provider using the features we read.
|
// Create a provider using the features we read.
|
||||||
let provider = try MotorProvider(vehicle: getVehicle2D())
|
let provider = try MotorProvider(vehicle: getVehicle2D())
|
||||||
|
let trackingProvider = LidarProvider(lidar: createLidar())
|
||||||
|
|
||||||
// Start the server and print its address once it has started.
|
// Start the server and print its address once it has started.
|
||||||
let server = Server.insecure(group: group)
|
let server = Server.insecure(group: group)
|
||||||
.withServiceProviders([provider])
|
.withServiceProviders([provider, trackingProvider])
|
||||||
.bind(host: "localhost", port: 0)
|
.bind(host: "localhost", port: 0)
|
||||||
|
|
||||||
server.map {
|
server.map {
|
||||||
@@ -37,6 +40,11 @@ func doServer() throws {
|
|||||||
}.wait()
|
}.wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createLidar() -> SwiftRPLidar{
|
||||||
|
return try! SwiftRPLidar(onPort: SerialPort(path: "/dev/cu.usbserial0001"))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Entry-Point to the Swift Car Controller
|
// Entry-Point to the Swift Car Controller
|
||||||
print("Starting Server")
|
print("Starting Server")
|
||||||
do{
|
do{
|
||||||
@@ -45,3 +53,14 @@ try doServer()
|
|||||||
catch{
|
catch{
|
||||||
print("Server failed")
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user