From d876fcbb2e7d72e5825b8540a4a89e7eb98888b2 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Sat, 6 Aug 2022 20:34:00 +0930 Subject: [PATCH] Add grpc rust codegen + stubs, add rppal compile feature for raspberry pi compilation. This is because rppal won't compile on mac, so we only want to bring in the dependency when actually compiling for the raspberry pi, and so will manually need to enable the dependency. --- car-rs/Cargo.lock | 255 ++++++++++++++++++ car-rs/Cargo.toml | 15 +- car-rs/build.rs | 7 + car-rs/src/grpcserver.rs | 52 ++++ car-rs/src/lib.rs | 72 +++-- car-rs/src/main.rs | 6 +- .../main/proto/car/control/motorService.proto | 20 +- 7 files changed, 395 insertions(+), 32 deletions(-) create mode 100644 car-rs/build.rs create mode 100644 car-rs/src/grpcserver.rs diff --git a/car-rs/Cargo.lock b/car-rs/Cargo.lock index 59e39b4..6828f6b 100644 --- a/car-rs/Cargo.lock +++ b/car-rs/Cargo.lock @@ -2,6 +2,36 @@ # 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.58" @@ -111,9 +141,12 @@ checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" name = "car-rs" version = "0.1.0" dependencies = [ + "prost", "rppal", + "serialport", "tokio", "tonic", + "tonic-build", ] [[package]] @@ -128,6 +161,21 @@ 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" @@ -209,6 +257,12 @@ 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" @@ -304,6 +358,15 @@ dependencies = [ "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" @@ -331,6 +394,26 @@ version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +[[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" @@ -350,6 +433,24 @@ 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" @@ -380,6 +481,23 @@ dependencies = [ "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" @@ -425,6 +543,16 @@ 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" @@ -457,12 +585,28 @@ 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.40" @@ -482,6 +626,26 @@ dependencies = [ "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" @@ -495,6 +659,16 @@ dependencies = [ "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.20" @@ -543,6 +717,32 @@ 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" @@ -565,6 +765,23 @@ version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" +[[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" @@ -616,6 +833,20 @@ 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.0" @@ -715,6 +946,19 @@ dependencies = [ "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" @@ -837,6 +1081,17 @@ 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" diff --git a/car-rs/Cargo.toml b/car-rs/Cargo.toml index ecc0a23..e426dab 100644 --- a/car-rs/Cargo.toml +++ b/car-rs/Cargo.toml @@ -7,11 +7,22 @@ edition = "2021" [dependencies] # https://github.com/golemparts/rppal -rppal = "0.13.1" +rppal = { version = "0.13.1", optional = true } 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] -target = "armv7-unknown-linux-gnueabihf" \ No newline at end of file +target = "armv7-unknown-linux-gnueabihf" + +[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..d505fa4 --- /dev/null +++ b/car-rs/src/grpcserver.rs @@ -0,0 +1,52 @@ +pub mod motor_control_service { + tonic::include_proto!("motor_control"); +} + +use motor_control_service::car_control_server::CarControl; +use tonic::{Request, Response, Status, Streaming}; + +use self::motor_control_service::{ + RecordingReqeust, RecordingResponse, SaveRequest, SaveResponse, SteeringRequest, + SteeringResponse, ThrottleRequest, ThrottleResponse, Vehicle2DRequest, Vehicle2DResponse, +}; + +#[derive(Debug)] +struct MotorControlService {} + +#[tonic::async_trait] +impl CarControl for MotorControlService { + async fn set_throttle( + &self, + _request: Request, + ) -> Result, Status> { + unimplemented!() + } + + async fn set_steering( + &self, + _request: Request, + ) -> Result, Status> { + unimplemented!() + } + + async fn stream_vehicle_2d( + &self, + _request: Request>, + ) -> Result, Status> { + unimplemented!() + } + + 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 index 316703c..cf782b5 100644 --- a/car-rs/src/lib.rs +++ b/car-rs/src/lib.rs @@ -1,8 +1,8 @@ -use rppal::pwm::{Channel, Pwm}; +use serialport::SerialPort; pub trait Servo { fn get_duty_cycle(&self) -> f64; - // TODO: Some kind of error handling here, in case we fail to set the duty cycel + // TODO: Some kind of error handling here, in case we fail to set the duty cycle fn set_duty_cycle(&self, pwm: f64); fn get_frequency(&self) -> f64; @@ -14,43 +14,69 @@ pub trait Vechicle { fn get_throttle_servo() -> T; fn get_steering_servo() -> T; } +#[cfg(feature = "rppal")] +pub mod rppal { + use rppal::pwm::{Channel, Pwm}; -pub struct RpiPwmServo { - pwm: Pwm, -} - -impl RpiPwmServo { - pub fn new(pwm: Pwm) -> RpiPwmServo { - RpiPwmServo { pwm } + pub struct RpiPwmServo { + pwm: Pwm, } -} -impl Default for RpiPwmServo { - fn default() -> Self { - Self { - pwm: Pwm::new(Channel::Pwm0).expect("Failed to initialise Pwm servo"), + impl RpiPwmServo { + pub fn new(pwm: Pwm) -> RpiPwmServo { + RpiPwmServo { pwm } + } + } + + 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") } } } -impl Servo for RpiPwmServo { +pub struct Esp32SerialPwmServo { + serial_port: T, +} + +impl Servo for Esp32SerialPwmServo { fn get_duty_cycle(&self) -> f64 { - self.pwm.duty_cycle().unwrap_or(0.) + todo!() } fn set_duty_cycle(&self, pwm: f64) { - self.pwm - .set_duty_cycle(pwm) - .expect("Failed to write duty cycle"); + todo!() } fn get_frequency(&self) -> f64 { - self.pwm.duty_cycle().unwrap_or(0.0) + todo!() } fn set_frequency(&self, frequency: f64) { - self.pwm - .set_frequency(frequency, self.get_duty_cycle()) - .expect("Failed to set Frequency") + todo!() } } diff --git a/car-rs/src/main.rs b/car-rs/src/main.rs index 84eb175..9ee1c2b 100644 --- a/car-rs/src/main.rs +++ b/car-rs/src/main.rs @@ -1,4 +1,6 @@ -use std::error::Error; +use crate::grpcserver::motor_control_service; + +mod grpcserver; #[tokio::main] -fn main() {} +async fn main() {} 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) {} }