From 51ff4d44770b88da346ccf0f66c82c76113ac0ca Mon Sep 17 00:00:00 2001 From: Darren Rahnemoon Date: Wed, 6 Mar 2024 19:49:39 -0500 Subject: [PATCH 1/8] feature: wip refactoring hydra_provider - commands service - database service - serial data feed service - random data feed service --- hydra_provider/.vscode/settings.json | 3 + hydra_provider/build.rs | 16 +- hydra_provider/proto/command.proto | 0 hydra_provider/proto/data_feed.proto | 42 +++ hydra_provider/proto/health.proto | 1 - hydra_provider/proto/hydra_provider.proto | 13 - hydra_provider/src/bootstrap.rs | 36 ++ .../command_service/commands/deploy_drogue.rs | 8 + .../command_service/commands/deploy_main.rs | 8 + .../src/command_service/commands/mod.rs | 4 + .../command_service/commands/power_down.rs | 8 + .../src/command_service/commands/sendable.rs | 3 + hydra_provider/src/command_service/mod.rs | 2 + hydra_provider/src/command_service/service.rs | 6 + hydra_provider/src/connection_manager.rs | 71 ---- .../message/mod.rs} | 7 +- hydra_provider/src/data_feed_service/mod.rs | 7 + .../src/data_feed_service/random/iterator.rs | 180 ++++++++++ .../src/data_feed_service/random/mod.rs | 5 + .../src/data_feed_service/random/service.rs | 51 +++ .../src/data_feed_service/serial/iterator.rs | 51 +++ .../src/data_feed_service/serial/mod.rs | 4 + .../src/data_feed_service/serial/service.rs | 97 +++++ .../src/database_service/messages/mod.rs | 1 + .../src/database_service/messages/saveable.rs | 5 + hydra_provider/src/database_service/mod.rs | 2 + .../src/database_service/service.rs | 20 ++ hydra_provider/src/db.rs | 8 +- hydra_provider/src/greeter.rs | 22 -- hydra_provider/src/hydra_provider_proto.rs | 3 - hydra_provider/src/input/file_input.rs | 335 ------------------ hydra_provider/src/input/mod.rs | 7 - hydra_provider/src/input/random_input.rs | 236 ------------ hydra_provider/src/input/serial_input.rs | 68 ---- hydra_provider/src/main.rs | 165 ++------- 35 files changed, 592 insertions(+), 903 deletions(-) create mode 100644 hydra_provider/.vscode/settings.json create mode 100644 hydra_provider/proto/command.proto create mode 100644 hydra_provider/proto/data_feed.proto create mode 100644 hydra_provider/src/bootstrap.rs create mode 100644 hydra_provider/src/command_service/commands/deploy_drogue.rs create mode 100644 hydra_provider/src/command_service/commands/deploy_main.rs create mode 100644 hydra_provider/src/command_service/commands/mod.rs create mode 100644 hydra_provider/src/command_service/commands/power_down.rs create mode 100644 hydra_provider/src/command_service/commands/sendable.rs create mode 100644 hydra_provider/src/command_service/mod.rs create mode 100644 hydra_provider/src/command_service/service.rs delete mode 100644 hydra_provider/src/connection_manager.rs rename hydra_provider/src/{hydra_iterator.rs => data_feed_service/message/mod.rs} (64%) create mode 100644 hydra_provider/src/data_feed_service/mod.rs create mode 100644 hydra_provider/src/data_feed_service/random/iterator.rs create mode 100644 hydra_provider/src/data_feed_service/random/mod.rs create mode 100644 hydra_provider/src/data_feed_service/random/service.rs create mode 100644 hydra_provider/src/data_feed_service/serial/iterator.rs create mode 100644 hydra_provider/src/data_feed_service/serial/mod.rs create mode 100644 hydra_provider/src/data_feed_service/serial/service.rs create mode 100644 hydra_provider/src/database_service/messages/mod.rs create mode 100644 hydra_provider/src/database_service/messages/saveable.rs create mode 100644 hydra_provider/src/database_service/mod.rs create mode 100644 hydra_provider/src/database_service/service.rs delete mode 100644 hydra_provider/src/greeter.rs delete mode 100644 hydra_provider/src/hydra_provider_proto.rs delete mode 100644 hydra_provider/src/input/file_input.rs delete mode 100644 hydra_provider/src/input/mod.rs delete mode 100644 hydra_provider/src/input/random_input.rs delete mode 100644 hydra_provider/src/input/serial_input.rs diff --git a/hydra_provider/.vscode/settings.json b/hydra_provider/.vscode/settings.json new file mode 100644 index 00000000..e931c34c --- /dev/null +++ b/hydra_provider/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rust-analyzer.showUnlinkedFileNotification": false +} \ No newline at end of file diff --git a/hydra_provider/build.rs b/hydra_provider/build.rs index d4fa968a..edde24f6 100644 --- a/hydra_provider/build.rs +++ b/hydra_provider/build.rs @@ -1,5 +1,13 @@ -fn main() -> Result<(), Box> { - tonic_build::compile_protos("proto/hydra_provider.proto").unwrap(); - // No need to compile health as its provided by tonic - Ok(()) +fn main() { + // Define .proto files that need to get compiled here + // No need to compile health.proto as its provided by tonic + let protos = [ + "proto/hydra_provider.proto", + "proto/data_feed.proto", + ]; + + tonic_build::configure() + .build_server(true) + .compile(&protos, &["."]) + .unwrap_or_else(|error| panic!("Failed to compile {:?}", error)); } diff --git a/hydra_provider/proto/command.proto b/hydra_provider/proto/command.proto new file mode 100644 index 00000000..e69de29b diff --git a/hydra_provider/proto/data_feed.proto b/hydra_provider/proto/data_feed.proto new file mode 100644 index 00000000..e9affc05 --- /dev/null +++ b/hydra_provider/proto/data_feed.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package data_feed; + +service SerialDataFeed { + rpc start(Empty) returns(Empty); + rpc stop(Empty) returns(Empty); + rpc list_available_ports(Empty) returns(ListAvailablePortsResponse); + rpc configure(SerialDataFeedConfig) returns(Empty); + rpc get_status(Empty) returns(SerialDataFeedStatus); +} + +message ListAvailablePortsResponse { + repeated string ports = 1; +} +message SerialDataFeedConfig { + string port = 1; + int32 baud_rate = 2; +} +message SerialDataFeedStatus { + bool is_running = 1; + SerialDataFeedConfig config = 2; +} + +service RandomDataFeed { + rpc start(Empty) returns(Empty); + rpc stop(Empty) returns(Empty); +} + +// SHOULD DO: implement +// service FileDataFeed { +// rpc start(stream FileDataFeed) returns(Empty); +// rpc stop(Empty) returns(Empty); +// } +// message FileDataFeed { +// string name = 1; +// bytes chunk = 2; +// } + +message Empty { + +} diff --git a/hydra_provider/proto/health.proto b/hydra_provider/proto/health.proto index 56785eab..8f19e4ea 100644 --- a/hydra_provider/proto/health.proto +++ b/hydra_provider/proto/health.proto @@ -18,6 +18,5 @@ message HealthCheckResponse { service Health { rpc Check(HealthCheckRequest) returns (HealthCheckResponse); - rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } \ No newline at end of file diff --git a/hydra_provider/proto/hydra_provider.proto b/hydra_provider/proto/hydra_provider.proto index 9bfa034c..879c7486 100644 --- a/hydra_provider/proto/hydra_provider.proto +++ b/hydra_provider/proto/hydra_provider.proto @@ -5,19 +5,6 @@ package hydra_provider; message Empty { } -service Greeter { - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -message HelloRequest { - string name = 1; -} - -message HelloReply { - string message = 1; -} - - service ConnectionManager { rpc GetConnectionType (Empty) returns (ConnectionTypeMessage) {} rpc SetConnectionType (ConnectionTypeMessage) returns (Empty) {} diff --git a/hydra_provider/src/bootstrap.rs b/hydra_provider/src/bootstrap.rs new file mode 100644 index 00000000..64a629de --- /dev/null +++ b/hydra_provider/src/bootstrap.rs @@ -0,0 +1,36 @@ +use std::net::SocketAddr; + +// use crate::commands::service::CommandService; +use crate::data_feed_service::serial::{SerialDataFeedService, SerialDataFeedServer}; +use crate::data_feed_service::random::{RandomDataFeedService, RandomDataFeedServer}; +use crate::database_service::DatabaseService; + +use tonic::transport::Server; +use tonic_health::server::health_reporter; +use tonic_health::pb::health_server::HealthServer; +use tonic_health::server::HealthService; + +// Sets up the gRPC server and loads relevant services +pub async fn bootstrap( + server_port: u32, + database_address: String, +) -> () { + let server_address: SocketAddr = format!("[::1]:{}", server_port).parse().unwrap(); + + let database_service = DatabaseService::new(&database_address.as_str()).await; + let serial_data_feed_service = SerialDataFeedService::new(&database_service); + let random_data_feed_service = RandomDataFeedService::new(&database_service); + + let ( + mut health_reporter, + health_service + ) = health_reporter(); + + health_reporter.set_serving::>().await; + + Server::builder() + .add_service(health_service) + .add_service(SerialDataFeedServer::new(serial_data_feed_service)) + .add_service(RandomDataFeedServer::new(random_data_feed_service)) + .serve(server_address); +} diff --git a/hydra_provider/src/command_service/commands/deploy_drogue.rs b/hydra_provider/src/command_service/commands/deploy_drogue.rs new file mode 100644 index 00000000..a588925a --- /dev/null +++ b/hydra_provider/src/command_service/commands/deploy_drogue.rs @@ -0,0 +1,8 @@ +use super::sendable::Sendable; +use messages::command::DeployDrogue; + +impl Sendable for DeployDrogue { + fn send() { + println!("DeployDrogue was called.") + } +} \ No newline at end of file diff --git a/hydra_provider/src/command_service/commands/deploy_main.rs b/hydra_provider/src/command_service/commands/deploy_main.rs new file mode 100644 index 00000000..f484128b --- /dev/null +++ b/hydra_provider/src/command_service/commands/deploy_main.rs @@ -0,0 +1,8 @@ +use super::sendable::Sendable; +use messages::command::DeployMain; + +impl Sendable for DeployMain { + fn send() { + println!("DeployMain was called.") + } +} \ No newline at end of file diff --git a/hydra_provider/src/command_service/commands/mod.rs b/hydra_provider/src/command_service/commands/mod.rs new file mode 100644 index 00000000..22ac5d8f --- /dev/null +++ b/hydra_provider/src/command_service/commands/mod.rs @@ -0,0 +1,4 @@ +pub mod sendable; +pub mod deploy_main; +pub mod deploy_drogue; +pub mod power_down; diff --git a/hydra_provider/src/command_service/commands/power_down.rs b/hydra_provider/src/command_service/commands/power_down.rs new file mode 100644 index 00000000..804892b8 --- /dev/null +++ b/hydra_provider/src/command_service/commands/power_down.rs @@ -0,0 +1,8 @@ +use super::sendable::Sendable; +use messages::command::PowerDown; + +impl Sendable for PowerDown { + fn send() { + println!("PowerDown was called.") + } +} \ No newline at end of file diff --git a/hydra_provider/src/command_service/commands/sendable.rs b/hydra_provider/src/command_service/commands/sendable.rs new file mode 100644 index 00000000..a5c3f640 --- /dev/null +++ b/hydra_provider/src/command_service/commands/sendable.rs @@ -0,0 +1,3 @@ +pub trait Sendable { + fn send(); +} \ No newline at end of file diff --git a/hydra_provider/src/command_service/mod.rs b/hydra_provider/src/command_service/mod.rs new file mode 100644 index 00000000..414db8d0 --- /dev/null +++ b/hydra_provider/src/command_service/mod.rs @@ -0,0 +1,2 @@ +pub mod commands; +pub mod service; \ No newline at end of file diff --git a/hydra_provider/src/command_service/service.rs b/hydra_provider/src/command_service/service.rs new file mode 100644 index 00000000..3b784251 --- /dev/null +++ b/hydra_provider/src/command_service/service.rs @@ -0,0 +1,6 @@ +pub struct CommandService {} +impl CommandService { + pub fn new() -> CommandService { + CommandService {} + } +} \ No newline at end of file diff --git a/hydra_provider/src/connection_manager.rs b/hydra_provider/src/connection_manager.rs deleted file mode 100644 index 5dd5ca5f..00000000 --- a/hydra_provider/src/connection_manager.rs +++ /dev/null @@ -1,71 +0,0 @@ -use std::vec; - -use log::info; -use serialport::available_ports; - -use self::connection_manager_server::ConnectionManager; -use crate::hydra_provider_proto::hydra_provider_proto::*; - -#[derive(Default)] -pub struct ConnectionManagerImpl {} - -#[tonic::async_trait] -impl ConnectionManager for ConnectionManagerImpl { - async fn check_connection( - &self, - request: tonic::Request, - ) -> Result, tonic::Status> { - info!("[check_connection] Got a request: {:?}", request); - let reply = CheckConnectionReply { - connected: true, - connection_type: ConnectionType::Serial as i32, - errors: vec![], - }; - Ok(tonic::Response::new(reply)) - } - - async fn get_connection_type( - &self, - request: tonic::Request, - ) -> Result, tonic::Status> { - info!("[get_connection_type] Got a request: {:?}", request); - let reply = ConnectionTypeMessage { - connection_type: ConnectionType::Serial as i32, - }; - Ok(tonic::Response::new(reply)) - } - - async fn set_connection_type( - &self, - request: tonic::Request, - ) -> Result, tonic::Status> { - info!("[set_connection_type] Got a request: {:?}", request); - Ok(tonic::Response::new(Empty {})) - } - - async fn get_serial_ports( - &self, - request: tonic::Request, - ) -> Result, tonic::Status> { - info!("ConnectionManager:get_serial_ports called"); - - let serial_ports = available_ports() - .unwrap() - .iter() - // .filter(|x| matches!(x.port_type, SerialPortType::UsbPort(_))) - .map(|x| x.port_name.clone()) - .collect::>(); - - Ok(tonic::Response::new(GetSerialPortsReply { - ports: serial_ports, - })) - } - - async fn set_preferred_serial_port( - &self, - request: tonic::Request, - ) -> Result, tonic::Status> { - info!("[set_preferred_serial_port] Got a request: {:?}", request); - Ok(tonic::Response::new(Empty {})) - } -} diff --git a/hydra_provider/src/hydra_iterator.rs b/hydra_provider/src/data_feed_service/message/mod.rs similarity index 64% rename from hydra_provider/src/hydra_iterator.rs rename to hydra_provider/src/data_feed_service/message/mod.rs index 81a7a0c9..694324f2 100644 --- a/hydra_provider/src/hydra_iterator.rs +++ b/hydra_provider/src/data_feed_service/message/mod.rs @@ -1,10 +1,11 @@ use derive_more::From; use messages::mavlink::uorocketry::{HEARTBEAT_DATA, RADIO_STATUS_DATA}; use serde::{Deserialize, Serialize}; +use messages::Message; #[derive(Serialize, Deserialize, Clone, Debug, From)] pub enum HydraInput { - RocketData(messages::Message), - MavlinkRadioStatus(RADIO_STATUS_DATA), - MavlinkHeartbeat(HEARTBEAT_DATA), + Message(Message), + RadioStatus(RADIO_STATUS_DATA), + Heartbeat(HEARTBEAT_DATA), } diff --git a/hydra_provider/src/data_feed_service/mod.rs b/hydra_provider/src/data_feed_service/mod.rs new file mode 100644 index 00000000..17071527 --- /dev/null +++ b/hydra_provider/src/data_feed_service/mod.rs @@ -0,0 +1,7 @@ +pub mod random; +pub mod serial; +pub mod message; + +pub mod proto { + tonic::include_proto!("data_feed"); +} diff --git a/hydra_provider/src/data_feed_service/random/iterator.rs b/hydra_provider/src/data_feed_service/random/iterator.rs new file mode 100644 index 00000000..ac69e6e8 --- /dev/null +++ b/hydra_provider/src/data_feed_service/random/iterator.rs @@ -0,0 +1,180 @@ +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use std::time::SystemTime; +use rand::Rng; +use rand::{rngs::StdRng, SeedableRng}; + +use messages::{command::Command, health::Health, sensor::{Air, EkfNav1, EkfNav2, EkfQuat, GpsPos1, GpsPos2, GpsVel, Imu1, Imu2, Sensor, UtcTime}, state::{State, StateData}, Data, Log, Message}; + + +pub struct RandomDataFeedIterator { + pub is_running: Arc, +} + +impl Iterator for RandomDataFeedIterator { + type Item = Message; + + fn next(&mut self) -> Option { + if !self.is_running.load(Ordering::Relaxed) { + return None + } + + // SHOULD DO: move this outside. No need to initialize every iterator step + let mut std_rng = StdRng::from_entropy(); + + let time: fugit::Instant = fugit::Instant::::from_ticks( + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_millis() as u64, + ); + + // Convert timestamp to UTC time + let utc_time = UtcTime { + time_stamp: time.ticks() as u32, + day: (time.ticks() / 86400000) as i8, + year: (1970 + (time.ticks() / 86400000) / 365) as u16, + hour: ((time.ticks() % 86400000) / 3600000) as i8, + minute: ((time.ticks() % 3600000) / 60000) as i8, + month: ((time.ticks() % 31536000000) / 2592000000) as i8, + second: ((time.ticks() % 60000) / 1000) as i8, + nano_second: (time.ticks() % 1000) as i32 * 1000000, + gps_time_of_week: 0, + status: 0, + }; + + let air = Air { + air_temperature: std_rng.gen(), + altitude: std_rng.gen(), + pressure_abs: std_rng.gen(), + pressure_diff: std_rng.gen(), + status: std_rng.gen(), + time_stamp: time.ticks() as u32, + true_airspeed: std_rng.gen(), + }; + + let ekf_quat = EkfQuat { + euler_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + quaternion: [std_rng.gen(), std_rng.gen(), std_rng.gen(), std_rng.gen()], + status: std_rng.gen(), + time_stamp: time.ticks() as u32, + }; + + let ekf_nav1 = EkfNav1 { + time_stamp: time.ticks() as u32, + velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + velocity_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + }; + + let ekf_nav2 = EkfNav2 { + position: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + position_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + status: std_rng.gen(), + undulation: std_rng.gen(), + }; + + let imu1 = Imu1 { + accelerometers: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + gyroscopes: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + status: std_rng.gen(), + time_stamp: time.ticks() as u32, + }; + + let imu2 = Imu2 { + delta_angle: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + delta_velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + temperature: std_rng.gen(), + }; + + let gps_vel = GpsVel { + course: std_rng.gen(), + course_acc: std_rng.gen(), + status: std_rng.gen(), + time_of_week: std_rng.gen(), + time_stamp: time.ticks() as u32, + velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + velocity_acc: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + }; + + let gps_pos1 = GpsPos1 { + time_stamp: time.ticks() as u32, + status: std_rng.gen(), + time_of_week: std_rng.gen(), + latitude: std_rng.gen(), + longitude: std_rng.gen(), + altitude: std_rng.gen(), + undulation: std_rng.gen(), + }; + + let gps_pos2 = GpsPos2 { + latitude_accuracy: std_rng.gen(), + longitude_accuracy: std_rng.gen(), + altitude_accuracy: std_rng.gen(), + num_sv_used: std_rng.gen(), + base_station_id: std_rng.gen(), + differential_age: std_rng.gen(), + }; + + // Array of sensor messages (we will select one of it) + let sensors = [ + Sensor::new(utc_time), + Sensor::new(air), + Sensor::new(ekf_quat), + Sensor::new(ekf_nav1), + Sensor::new(ekf_nav2), + Sensor::new(imu1), + Sensor::new(imu2), + Sensor::new(gps_vel), + Sensor::new(gps_pos1), + Sensor::new(gps_pos2), + ]; + + let status = match std_rng.gen_range(0..=6) { + 0 => StateData::Initializing, + 1 => StateData::WaitForTakeoff, + 2 => StateData::Ascent, + 3 => StateData::Descent, + 4 => StateData::TerminalDescent, + 5 => StateData::WaitForRecovery, + _ => StateData::Abort, + }; + + // Return a random sensor message + let mut sensor = sensors[std_rng.gen_range(0..sensors.len())].to_owned(); + sensor.component_id = std_rng.gen(); + + let state = State { data: status }; + + let log = Log::new(messages::LogLevel::Info, messages::Event::Initialized()); + + let command = Command { + data: messages::command::CommandData::DeployDrogue({ + messages::command::DeployDrogue { val: true } + }), + }; + + let data = match std_rng.gen_range(0..=4) { + 0 => Data::State(state), + 1 => Data::Log(log), + 2 => Data::Command(command), + 3 => Data::Sensor(sensor), + 4 => Data::Health(Health { + data: messages::health::HealthData::HealthStatus(messages::health::HealthStatus { + v5: Some(1), + v3_3: std_rng.gen(), + pyro_sense: std_rng.gen(), + vcc_sense: std_rng.gen(), + int_v5: std_rng.gen(), + int_v3_3: std_rng.gen(), + ext_v5: std_rng.gen(), + ext_3v3: std_rng.gen(), + failover_sense: std_rng.gen(), + }), + status: messages::health::HealthState::Nominal, + }), + _ => Data::Sensor(sensor), + }; + + Some(Message::new(&time, messages::sender::Sender::GroundStation, data)) + } +} diff --git a/hydra_provider/src/data_feed_service/random/mod.rs b/hydra_provider/src/data_feed_service/random/mod.rs new file mode 100644 index 00000000..2355c611 --- /dev/null +++ b/hydra_provider/src/data_feed_service/random/mod.rs @@ -0,0 +1,5 @@ +pub mod service; +pub mod iterator; + +pub use service::RandomDataFeedService; +pub use crate::data_feed_service::proto::random_data_feed_server::RandomDataFeedServer; // used by bootstrap to setup a RandomDataFeedService diff --git a/hydra_provider/src/data_feed_service/random/service.rs b/hydra_provider/src/data_feed_service/random/service.rs new file mode 100644 index 00000000..2ae48d36 --- /dev/null +++ b/hydra_provider/src/data_feed_service/random/service.rs @@ -0,0 +1,51 @@ +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use tonic::{async_trait, Request, Response, Status}; +use log::info; + +use crate::database_service::DatabaseService; +use crate::data_feed_service::message::HydraInput; +use crate::data_feed_service::random::iterator::RandomDataFeedIterator; + +use crate::data_feed_service::proto::random_data_feed_server::*; +use crate::data_feed_service::proto::Empty; + +pub struct RandomDataFeedService<'a> { + iterator: RandomDataFeedIterator, + database_service: &'a DatabaseService, +} + +impl<'a> RandomDataFeedService<'_> { + pub fn new( + database_service: &'a DatabaseService, + ) -> RandomDataFeedService { + RandomDataFeedService { + iterator: RandomDataFeedIterator { + is_running: Arc::new(AtomicBool::new(false)), + }, + database_service, + } + } +} + +#[async_trait] +impl RandomDataFeed for RandomDataFeedService { + async fn start(&self, _request: Request) -> Result, Status> { + self.iterator.is_running.store(true, Ordering::Relaxed); + + let iterator = self.iterator; + tokio::spawn(async move { + info!("RandomDataFeedService has started."); + while let Some(message) = iterator.next() { + self.database_service.save(HydraInput::Message(message)); + } + }); + + Ok(Response::new(Empty {})) + } + + async fn stop(&self, _request: Request) -> Result, Status> { + self.iterator.is_running.store(false, Ordering::Relaxed); + Ok(Response::new(Empty {})) + } +} diff --git a/hydra_provider/src/data_feed_service/serial/iterator.rs b/hydra_provider/src/data_feed_service/serial/iterator.rs new file mode 100644 index 00000000..6b51d45c --- /dev/null +++ b/hydra_provider/src/data_feed_service/serial/iterator.rs @@ -0,0 +1,51 @@ +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex}; +use messages::mavlink::MavConnection; +use postcard::from_bytes; +use log::info; + +use crate::data_feed_service::message::HydraInput; +use messages::Message; +use crate::data_feed_service::proto::SerialDataFeedConfig; + +use messages::mavlink::uorocketry::MavMessage; + +pub struct SerialDataFeedIterator { + pub config: Arc>>, + pub mavlink: Arc + Send + Sync>>>>, + pub is_running: Arc, +} + +impl Iterator for SerialDataFeedIterator { + type Item = HydraInput; + + fn next(&mut self) -> Option { + if !self.is_running.load(Ordering::Relaxed) { + return None; + } + let mut mavlink_option = self.mavlink.lock().unwrap(); + if mavlink_option.is_none() { + return None; + } + + let mavlink = mavlink_option.unwrap(); + let (_, mavlink_message) = mavlink.recv().unwrap(); + let message = match &mavlink_message { + MavMessage::POSTCARD_MESSAGE(data) => { + let data: Message = from_bytes(data.message.as_slice()).unwrap(); + info!("Received rocket message: {:#?}", data); + HydraInput::Message(data) + } + MavMessage::RADIO_STATUS(data) => { + info!("Received radio status: {:?}", data); + HydraInput::RadioStatus(data.clone()) + } + MavMessage::HEARTBEAT(heartbeat) => { + info!("Received heartbeat."); + HydraInput::Heartbeat(heartbeat.clone()) + } + }; + + Some(message) + } +} diff --git a/hydra_provider/src/data_feed_service/serial/mod.rs b/hydra_provider/src/data_feed_service/serial/mod.rs new file mode 100644 index 00000000..92c1eb91 --- /dev/null +++ b/hydra_provider/src/data_feed_service/serial/mod.rs @@ -0,0 +1,4 @@ +pub mod iterator; +pub mod service; +pub use service::SerialDataFeedService; +pub use crate::data_feed_service::proto::serial_data_feed_server::SerialDataFeedServer; // used by bootstrap to setup a SerialDataFeedService diff --git a/hydra_provider/src/data_feed_service/serial/service.rs b/hydra_provider/src/data_feed_service/serial/service.rs new file mode 100644 index 00000000..e1293418 --- /dev/null +++ b/hydra_provider/src/data_feed_service/serial/service.rs @@ -0,0 +1,97 @@ +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex}; +use messages::mavlink::connect; +use serialport::{available_ports, SerialPortType}; +use tonic::{async_trait, Request, Response, Status}; +use log::info; + +use crate::data_feed_service::serial::iterator::SerialDataFeedIterator; +use crate::database_service::DatabaseService; +use crate::data_feed_service::proto::serial_data_feed_server::*; +use crate::data_feed_service::proto::{Empty, ListAvailablePortsResponse, SerialDataFeedConfig, SerialDataFeedStatus}; + +use messages::mavlink::uorocketry::MavMessage; + +pub struct SerialDataFeedService<'a> { + iterator: SerialDataFeedIterator, + database_service: &'a DatabaseService, +} + +impl<'a> SerialDataFeedService<'_> { + pub fn new( + database_service: &'a DatabaseService, + ) -> SerialDataFeedService { + SerialDataFeedService { + iterator: SerialDataFeedIterator { + is_running: Arc::new(AtomicBool::new(false)), + mavlink: Arc::new(Mutex::new(None)), + config: Arc::new(Mutex::new(None)) + }, + database_service, + } + } +} + +#[async_trait] +impl SerialDataFeed for SerialDataFeedService { + async fn start(&self, _request: Request) -> Result, Status> { + self.iterator.is_running.store(true, Ordering::Relaxed); + + let iterator = self.iterator; + tokio::spawn(async move { + info!("SerialDataFeedService has started."); + while let Some(message) = iterator.next() { + self.database_service.save(message); + } + }); + + Ok(Response::new(Empty {})) + } + + async fn stop(&self, _request: Request) -> Result, Status> { + self.iterator.is_running.store(false, Ordering::Relaxed); + Ok(Response::new(Empty {})) + } + + async fn list_available_ports( + &self, + request: Request + ) -> Result, Status> { + let ports = available_ports() + .unwrap() + .iter() + .filter(|port| matches!(port.port_type, SerialPortType::UsbPort(_))) + .map(|port| port.port_name.clone()) + .collect::>(); + Ok(Response::new( + ListAvailablePortsResponse { + ports + } + )) + } + + async fn configure( + &self, + request: Request + ) -> Result, Status> { + let config = request.into_inner(); + let address = format!("serial:{}:{}", config.port, config.baud_rate).as_str(); + + let mut mavlink = self.iterator.mavlink.lock().unwrap(); + *mavlink = Some(connect::(address).unwrap()); + + Ok(Response::new(Empty {})) + } + + async fn get_status( + &self, + request: Request + ) -> Result, Status> { + Ok(Response::new( + SerialDataFeedStatus { + is_running : self.iterator.is_running.load(Ordering::Relaxed), + config : self.iterator.config.lock().unwrap().clone(), + } + )) + } +} diff --git a/hydra_provider/src/database_service/messages/mod.rs b/hydra_provider/src/database_service/messages/mod.rs new file mode 100644 index 00000000..d31839a5 --- /dev/null +++ b/hydra_provider/src/database_service/messages/mod.rs @@ -0,0 +1 @@ +pub mod saveable; \ No newline at end of file diff --git a/hydra_provider/src/database_service/messages/saveable.rs b/hydra_provider/src/database_service/messages/saveable.rs new file mode 100644 index 00000000..5c81bc78 --- /dev/null +++ b/hydra_provider/src/database_service/messages/saveable.rs @@ -0,0 +1,5 @@ +use sqlx::PgPool; + +pub trait Saveable { + fn save(pool: &PgPool); +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/mod.rs b/hydra_provider/src/database_service/mod.rs new file mode 100644 index 00000000..9839e637 --- /dev/null +++ b/hydra_provider/src/database_service/mod.rs @@ -0,0 +1,2 @@ +pub mod service; +pub mod messages; \ No newline at end of file diff --git a/hydra_provider/src/database_service/service.rs b/hydra_provider/src/database_service/service.rs new file mode 100644 index 00000000..f9bbe830 --- /dev/null +++ b/hydra_provider/src/database_service/service.rs @@ -0,0 +1,20 @@ +use std::sync::Arc; +use sqlx::PgPool; + +use crate::data_feed_service::message::HydraInput; + +pub struct DatabaseService { + pool: Arc, +} + +impl DatabaseService { + pub async fn new(address: &str) -> DatabaseService { + DatabaseService { + pool: Arc::new(PgPool::connect(address).await.unwrap()), + } + } + + pub fn save(&self, message: HydraInput) { + + } +} \ No newline at end of file diff --git a/hydra_provider/src/db.rs b/hydra_provider/src/db.rs index 4d05ddcc..b3c2b0d5 100644 --- a/hydra_provider/src/db.rs +++ b/hydra_provider/src/db.rs @@ -1,16 +1,16 @@ -use crate::{hydra_iterator::HydraInput, rocket_data::db_save_rocket_message}; +use crate::{data_feeds::message::HydraInput, rocket_data::db_save_rocket_message}; use messages::mavlink::uorocketry::{HEARTBEAT_DATA, RADIO_STATUS_DATA}; use sqlx::postgres::{PgPool, PgQueryResult}; pub async fn db_save_hydra_input(pool: &PgPool, msg: HydraInput) -> Result<(), sqlx::Error> { match msg { - HydraInput::MavlinkRadioStatus(status) => { + HydraInput::RadioStatus(status) => { return db_save_radio_status(&pool, status).await.map(|_| ()) } - HydraInput::RocketData(data) => { + HydraInput::Message(data) => { return db_save_rocket_message(&pool, data).await; } - HydraInput::MavlinkHeartbeat(heartbeat) => { + HydraInput::Heartbeat(heartbeat) => { return db_save_rocket_heartbeat(&pool, heartbeat).await.map(|_| ()) } } diff --git a/hydra_provider/src/greeter.rs b/hydra_provider/src/greeter.rs deleted file mode 100644 index c7febcee..00000000 --- a/hydra_provider/src/greeter.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::hydra_provider_proto::hydra_provider_proto::*; -use tonic::{Request, Response, Status}; - -use self::greeter_server::Greeter; - -#[derive(Default)] -pub struct GreeterImpl {} - -#[tonic::async_trait] -impl Greeter for GreeterImpl { - async fn say_hello( - &self, - request: Request, - ) -> Result, Status> { - println!("Got a request from {:?}", request.remote_addr()); - - let reply = HelloReply { - message: format!("Hello {}!", request.into_inner().name), - }; - Ok(Response::new(reply)) - } -} diff --git a/hydra_provider/src/hydra_provider_proto.rs b/hydra_provider/src/hydra_provider_proto.rs deleted file mode 100644 index 87a86eec..00000000 --- a/hydra_provider/src/hydra_provider_proto.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod hydra_provider_proto { - tonic::include_proto!("hydra_provider"); -} diff --git a/hydra_provider/src/input/file_input.rs b/hydra_provider/src/input/file_input.rs deleted file mode 100644 index 083fac5c..00000000 --- a/hydra_provider/src/input/file_input.rs +++ /dev/null @@ -1,335 +0,0 @@ -use csv::Writer; - -use messages::{sensor, Data}; -use std::path::Path; -use std::{fs::File, io::Read}; - -use postcard::from_bytes; - -use crate::hydra_iterator::HydraInput; - -pub fn process_file(file_path: String) -> Box + Send> { - let mut file_buf: Vec = Vec::new(); - std::fs::File::open(Path::new(&file_path)) - .unwrap() - .read_to_end(&mut file_buf) - .unwrap(); - - let air_wtr = Writer::from_path("air.csv").unwrap(); - let imu1_wtr = Writer::from_path("imu1.csv").unwrap(); - let imu2_wtr = Writer::from_path("imu2.csv").unwrap(); - let gpsvel_wtr = Writer::from_path("gpsvel.csv").unwrap(); - let gpspos1_wtr = Writer::from_path("gpspos.csv").unwrap(); - let gpspos2_wtr = Writer::from_path("gpspos2.csv").unwrap(); - let ekfnav1_wtr = Writer::from_path("ekfnav1.csv").unwrap(); - let ekfnav2_wtr = Writer::from_path("ekfnav2.csv").unwrap(); - let ekfquat_wtr = Writer::from_path("ekfquat.csv").unwrap(); - - struct IteratorObj { - is_first: bool, - air_wtr: Writer, - imu1_wtr: Writer, - imu2_wtr: Writer, - gpsvel_wtr: Writer, - gpspos1_wtr: Writer, - gpspos2_wtr: Writer, - ekfnav1_wtr: Writer, - ekfnav2_wtr: Writer, - ekfquat_wtr: Writer, - remaining_buf_len: usize, - buffer: Vec, - file_buf: Vec, - } - - impl Iterator for IteratorObj { - type Item = HydraInput; - - fn next(&mut self) -> Option { - if self.remaining_buf_len == 0 { - return None; - } - - if self.buffer.len() < 64 { - self.buffer.push(self.file_buf[self.remaining_buf_len - 1]); - } else if self.buffer.len() == 64 { - let data: Result = from_bytes(&self.buffer); - // if data is error return error - if data.clone().is_err() { - // Error occurred, discard bytes until next valid message - while !self.buffer.is_empty() { - self.buffer.remove(0); - if self.buffer.len() == 64 - && from_bytes::(&self.buffer).is_ok() - { - break; - } - } - } - - if self.is_first { - self.is_first = false; - self.air_wtr - .write_record(&[ - "time_stamp", - "status", - "pressure_abs", - "altitude", - "pressure_diff", - "true_airspeed", - "air_temperature", - ]) - .unwrap(); - self.imu1_wtr - .write_record(&[ - "time_stamp", - "status", - "accelerometers[0]", - "accelerometers[1]", - "accelerometers[2]", - "gyroscopes[0]", - "gyroscopes[1]", - "gyroscopes[2]", - ]) - .unwrap(); - self.imu2_wtr - .write_record(&[ - "time_stamp", - "temperature", - "delta_velocity[0]", - "delta_velocity[1]", - "delta_velocity[2]", - "delta_angle[0]", - "delta_angle[1]", - "delta_angle[2]", - ]) - .unwrap(); - self.gpsvel_wtr - .write_record(&[ - "time_stamp", - "status", - "time_of_week", - "velocity[0]", - "velocity[1]", - "velocity[2]", - "velocity_acc[0]", - "velocity_acc[1]", - "velocity_acc[2]", - "course", - "course_acc", - ]) - .unwrap(); - self.gpspos1_wtr - .write_record(&[ - "time_stamp", - "status", - "timeOfWeek", - "latitude", - "longitude", - "altitude", - "undulation", - ]) - .unwrap(); - self.gpspos2_wtr - .write_record(&[ - "time_stamp", - "latitudeAccuracy", - "longitudeAccuracy", - "altitudeAccuracy", - "numSvUsed", - "baseStationId", - "differentialAge", - ]) - .unwrap(); - self.ekfnav1_wtr - .write_record(&[ - "time_stamp", - "velocity[0]", - "velocity[1]", - "velocity[2]", - "velocity_std_dev[0]", - "velocity_std_dev[1]", - "velocity_std_dev[2]", - ]) - .unwrap(); - self.ekfnav2_wtr - .write_record(&[ - "time_stamp", - "status", - "position[0]", - "position[1]", - "position[2]", - "position_std_dev[0]", - "position_std_dev[1]", - "position_std_dev[2]", - ]) - .unwrap(); - } - - let data_ok = data.clone().unwrap(); - - match data.clone().unwrap().data { - Data::Sensor(sensor_data) => match sensor_data.data { - sensor::SensorData::Air(air_data) => { - self.air_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &air_data.status.to_string(), - &air_data.pressure_abs.to_string(), - &air_data.altitude.to_string(), - &air_data.pressure_diff.to_string(), - &air_data.true_airspeed.to_string(), - &air_data.air_temperature.to_string(), - ]) - .unwrap(); - } - sensor::SensorData::Imu1(imu1_data) => { - self.imu1_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &imu1_data.status.to_string(), - &imu1_data.accelerometers[0].to_string(), - &imu1_data.accelerometers[1].to_string(), - &imu1_data.accelerometers[2].to_string(), - &imu1_data.gyroscopes[0].to_string(), - &imu1_data.gyroscopes[1].to_string(), - &imu1_data.gyroscopes[2].to_string(), - ]) - .unwrap(); - } - sensor::SensorData::Imu2(imu2_data) => { - self.imu2_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &imu2_data.temperature.to_string(), - &imu2_data.delta_velocity[0].to_string(), - &imu2_data.delta_velocity[1].to_string(), - &imu2_data.delta_velocity[2].to_string(), - &imu2_data.delta_angle[0].to_string(), - &imu2_data.delta_angle[1].to_string(), - &imu2_data.delta_angle[2].to_string(), - ]) - .unwrap(); - } - sensor::SensorData::GpsVel(gpsvel_data) => { - self.gpsvel_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &gpsvel_data.status.to_string(), - &gpsvel_data.time_of_week.to_string(), - &gpsvel_data.velocity[0].to_string(), - &gpsvel_data.velocity[1].to_string(), - &gpsvel_data.velocity[2].to_string(), - &gpsvel_data.velocity_acc[0].to_string(), - &gpsvel_data.velocity_acc[1].to_string(), - &gpsvel_data.velocity_acc[2].to_string(), - &gpsvel_data.course.to_string(), - &gpsvel_data.course_acc.to_string(), - ]) - .unwrap(); - } - sensor::SensorData::GpsPos1(gpspos1_data) => { - self.gpspos1_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &gpspos1_data.status.to_string(), - &gpspos1_data.time_of_week.to_string(), - &gpspos1_data.latitude.to_string(), - &gpspos1_data.longitude.to_string(), - &gpspos1_data.altitude.to_string(), - &gpspos1_data.undulation.to_string(), - ]) - .unwrap(); - } - sensor::SensorData::GpsPos2(gpspos2_data) => { - self.gpspos2_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &gpspos2_data.latitude_accuracy.to_string(), - &gpspos2_data.longitude_accuracy.to_string(), - &gpspos2_data.altitude_accuracy.to_string(), - &gpspos2_data.num_sv_used.to_string(), - &gpspos2_data.base_station_id.to_string(), - &gpspos2_data.differential_age.to_string(), - ]) - .unwrap(); - } - sensor::SensorData::EkfNav1(ekfnav1_data) => { - self.ekfnav1_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &ekfnav1_data.velocity[0].to_string(), - &ekfnav1_data.velocity[1].to_string(), - &ekfnav1_data.velocity[2].to_string(), - &ekfnav1_data.velocity_std_dev[0].to_string(), - &ekfnav1_data.velocity_std_dev[1].to_string(), - &ekfnav1_data.velocity_std_dev[2].to_string(), - ]) - .unwrap(); - } - sensor::SensorData::EkfNav2(ekfnav2_data) => self - .ekfnav2_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &ekfnav2_data.status.to_string(), - &ekfnav2_data.position[0].to_string(), - &ekfnav2_data.position[1].to_string(), - &ekfnav2_data.position[2].to_string(), - &ekfnav2_data.position_std_dev[0].to_string(), - &ekfnav2_data.position_std_dev[1].to_string(), - &ekfnav2_data.position_std_dev[2].to_string(), - ]) - .unwrap(), - sensor::SensorData::EkfQuat(ekfquat_data) => { - self.ekfquat_wtr - .write_record(&[ - &data_ok.timestamp.to_string(), - &ekfquat_data.status.to_string(), - &ekfquat_data.quaternion[0].to_string(), - &ekfquat_data.quaternion[1].to_string(), - &ekfquat_data.quaternion[2].to_string(), - &ekfquat_data.quaternion[3].to_string(), - &ekfquat_data.euler_std_dev[0].to_string(), - &ekfquat_data.euler_std_dev[1].to_string(), - &ekfquat_data.euler_std_dev[2].to_string(), - ]) - .unwrap(); - } - _ => {} - }, - _ => {} - } - - self.buffer.clear(); - self.air_wtr.flush().unwrap(); - self.imu1_wtr.flush().unwrap(); - self.imu2_wtr.flush().unwrap(); - self.gpsvel_wtr.flush().unwrap(); - self.gpspos1_wtr.flush().unwrap(); - self.gpspos2_wtr.flush().unwrap(); - self.ekfnav1_wtr.flush().unwrap(); - self.ekfnav2_wtr.flush().unwrap(); - self.ekfquat_wtr.flush().unwrap(); - - return Some(HydraInput::RocketData(data_ok)); - } - - None - } - } - - return Box::from(IteratorObj { - is_first: true, - air_wtr, - imu1_wtr, - imu2_wtr, - gpsvel_wtr, - gpspos1_wtr, - gpspos2_wtr, - ekfnav1_wtr, - ekfnav2_wtr, - ekfquat_wtr, - remaining_buf_len: file_buf.len(), - buffer: Vec::new(), - file_buf: file_buf, - }); -} diff --git a/hydra_provider/src/input/mod.rs b/hydra_provider/src/input/mod.rs deleted file mode 100644 index fd4d0fb3..00000000 --- a/hydra_provider/src/input/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod file_input; -mod random_input; -mod serial_input; - -pub use file_input::process_file; -pub use random_input::process_random_input; -pub use serial_input::process_serial; diff --git a/hydra_provider/src/input/random_input.rs b/hydra_provider/src/input/random_input.rs deleted file mode 100644 index 8db4e970..00000000 --- a/hydra_provider/src/input/random_input.rs +++ /dev/null @@ -1,236 +0,0 @@ -use crate::hydra_iterator::HydraInput; -use messages::command::Command; -use messages::health::Health; -use messages::mavlink::uorocketry::HEARTBEAT_DATA; -use messages::mavlink::uorocketry::RADIO_STATUS_DATA; -use messages::sender::Sender; -use messages::sensor::Air; -use messages::sensor::EkfNav1; -use messages::sensor::EkfNav2; -use messages::sensor::EkfQuat; -use messages::sensor::GpsPos1; -use messages::sensor::GpsPos2; -use messages::sensor::GpsVel; -use messages::sensor::Imu1; -use messages::sensor::Imu2; -use messages::sensor::Sensor; -use messages::sensor::UtcTime; -use messages::state::State; -use messages::state::StateData; -use messages::Data; -use messages::Log; -use messages::Message; -use rand::rngs::StdRng; -use rand::Rng; -use rand::SeedableRng; -use std::time::Duration; -use std::time::SystemTime; - -pub fn process_random_input() -> Box + Send> { - struct IteratorObj { - rng: StdRng, - } - - fn random_sensor(rng: &mut StdRng) -> Message { - let time: fugit::Instant = fugit::Instant::::from_ticks( - SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_millis() as u64, - ); - - // Convert timestamp to UTC time - - let utc_time = UtcTime { - time_stamp: time.ticks() as u32, - day: (time.ticks() / 86400000) as i8, - year: (1970 + (time.ticks() / 86400000) / 365) as u16, - hour: ((time.ticks() % 86400000) / 3600000) as i8, - minute: ((time.ticks() % 3600000) / 60000) as i8, - month: ((time.ticks() % 31536000000) / 2592000000) as i8, - second: ((time.ticks() % 60000) / 1000) as i8, - nano_second: (time.ticks() % 1000) as i32 * 1000000, - gps_time_of_week: 0, - status: 0, - }; - - let air = Air { - air_temperature: rng.gen(), - altitude: rng.gen(), - pressure_abs: rng.gen(), - pressure_diff: rng.gen(), - status: rng.gen(), - time_stamp: time.ticks() as u32, - true_airspeed: rng.gen(), - }; - - let ekf_quat = EkfQuat { - euler_std_dev: [rng.gen(), rng.gen(), rng.gen()], - quaternion: [rng.gen(), rng.gen(), rng.gen(), rng.gen()], - status: rng.gen(), - time_stamp: time.ticks() as u32, - }; - - let ekf_nav1 = EkfNav1 { - time_stamp: time.ticks() as u32, - velocity: [rng.gen(), rng.gen(), rng.gen()], - velocity_std_dev: [rng.gen(), rng.gen(), rng.gen()], - }; - - let ekf_nav2 = EkfNav2 { - position: [rng.gen(), rng.gen(), rng.gen()], - position_std_dev: [rng.gen(), rng.gen(), rng.gen()], - status: rng.gen(), - undulation: rng.gen(), - }; - - let imu1 = Imu1 { - accelerometers: [rng.gen(), rng.gen(), rng.gen()], - gyroscopes: [rng.gen(), rng.gen(), rng.gen()], - status: rng.gen(), - time_stamp: time.ticks() as u32, - }; - - let imu2 = Imu2 { - delta_angle: [rng.gen(), rng.gen(), rng.gen()], - delta_velocity: [rng.gen(), rng.gen(), rng.gen()], - temperature: rng.gen(), - }; - - let gps_vel = GpsVel { - course: rng.gen(), - course_acc: rng.gen(), - status: rng.gen(), - time_of_week: rng.gen(), - time_stamp: time.ticks() as u32, - velocity: [rng.gen(), rng.gen(), rng.gen()], - velocity_acc: [rng.gen(), rng.gen(), rng.gen()], - }; - - let gps_pos1 = GpsPos1 { - time_stamp: time.ticks() as u32, - status: rng.gen(), - time_of_week: rng.gen(), - latitude: rng.gen(), - longitude: rng.gen(), - altitude: rng.gen(), - undulation: rng.gen(), - }; - - let gps_pos2 = GpsPos2 { - latitude_accuracy: rng.gen(), - longitude_accuracy: rng.gen(), - altitude_accuracy: rng.gen(), - num_sv_used: rng.gen(), - base_station_id: rng.gen(), - differential_age: rng.gen(), - }; - - // Array of sensor messages (we will select one of it) - let sensors = [ - Sensor::new(utc_time), - Sensor::new(air), - Sensor::new(ekf_quat), - Sensor::new(ekf_nav1), - Sensor::new(ekf_nav2), - Sensor::new(imu1), - Sensor::new(imu2), - Sensor::new(gps_vel), - Sensor::new(gps_pos1), - Sensor::new(gps_pos2), - ]; - - let status = match rng.gen_range(0..=6) { - 0 => StateData::Initializing, - 1 => StateData::WaitForTakeoff, - 2 => StateData::Ascent, - 3 => StateData::Descent, - 4 => StateData::TerminalDescent, - 5 => StateData::WaitForRecovery, - _ => StateData::Abort, - }; - - // Return a random sensor message - let mut sensor = sensors[rng.gen_range(0..sensors.len())].to_owned(); - sensor.component_id = rng.gen(); - - let state = State { data: status }; - - let log = Log::new(messages::LogLevel::Info, messages::Event::Initialized()); - - let command = Command { - data: messages::command::CommandData::DeployDrogue({ - messages::command::DeployDrogue { val: true } - }), - }; - - let data = match rng.gen_range(0..=4) { - 0 => Data::State(state), - 1 => Data::Log(log), - 2 => Data::Command(command), - 3 => Data::Sensor(sensor), - 4 => Data::Health(Health { - data: messages::health::HealthData::HealthStatus(messages::health::HealthStatus { - v5: Some(1), - v3_3: rng.gen(), - pyro_sense: rng.gen(), - vcc_sense: rng.gen(), - int_v5: rng.gen(), - int_v3_3: rng.gen(), - ext_v5: rng.gen(), - ext_3v3: rng.gen(), - failover_sense: rng.gen(), - }), - status: messages::health::HealthState::Nominal, - }), - _ => Data::Sensor(sensor), - }; - - Message::new(&time, Sender::GroundStation, data) - } - - impl Iterator for IteratorObj { - type Item = HydraInput; - - fn next(&mut self) -> Option { - std::thread::sleep(Duration::from_millis(45)); - - let roll = self.rng.gen_range(0..=2); - match roll { - 0 => { - let msg = HydraInput::RocketData(random_sensor(&mut self.rng)); - return Some(msg); - } - 1 => { - let msg = HydraInput::MavlinkRadioStatus(RADIO_STATUS_DATA { - rxerrors: self.rng.gen(), - fixed: self.rng.gen(), - rssi: self.rng.gen(), - remrssi: self.rng.gen(), - txbuf: self.rng.gen(), - noise: self.rng.gen(), - remnoise: self.rng.gen(), - }); - return Some(msg); - } - - 2 => { - let msg = HydraInput::MavlinkHeartbeat(HEARTBEAT_DATA { - custom_mode: self.rng.gen(), - mavlink_version: self.rng.gen(), - mavtype: self.rng.gen(), - autopilot: self.rng.gen(), - base_mode: self.rng.gen(), - system_status: self.rng.gen(), - }); - return Some(msg); - } - _ => return None, - }; - } - } - - return Box::from(IteratorObj { - rng: StdRng::from_entropy(), - }); -} diff --git a/hydra_provider/src/input/serial_input.rs b/hydra_provider/src/input/serial_input.rs deleted file mode 100644 index 93227916..00000000 --- a/hydra_provider/src/input/serial_input.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::hydra_iterator::HydraInput; -use anyhow::Context; -use log::{info, trace}; -use messages::mavlink; -use messages::mavlink::uorocketry; -use messages::Message; -use postcard::from_bytes; -use serialport::{available_ports, SerialPortType}; - -pub fn process_serial( - port: &Option, - baud_rate: u32, -) -> Box + Send> { - let port = if let Some(port) = port { - port.clone() - } else { - available_ports() - .context("No serial port specified and couldn't retrieve available ports") - .unwrap() - .iter() - .filter(|x| matches!(x.port_type, SerialPortType::UsbPort(_))) - .last() - .context("No serial port specified and couldn't find any port") - .unwrap() - .port_name - .clone() - }; - - info!("Connecting to serial port: {}", port); - let link = mavlink::connect::( - format!("serial:{}:{}", port, baud_rate).as_str(), - ) - .unwrap(); - - let (_, recv_msg): (mavlink::MavHeader, uorocketry::MavMessage) = link.recv().unwrap(); - - struct IteratorObj { - recv_msg: uorocketry::MavMessage, - } - - impl Iterator for IteratorObj { - type Item = HydraInput; - - fn next(&mut self) -> Option { - let msg = match &self.recv_msg { - uorocketry::MavMessage::POSTCARD_MESSAGE(data) => { - let msg: Message = from_bytes(data.message.as_slice()).unwrap(); - trace!("Received rocket message: {:#?}", msg); - HydraInput::RocketData(msg) - } - uorocketry::MavMessage::RADIO_STATUS(data) => { - trace!("Received radio status: {:?}", data); - HydraInput::MavlinkRadioStatus(data.clone()) - } - uorocketry::MavMessage::HEARTBEAT(heartbeat) => { - trace!("Received heartbeat"); - HydraInput::MavlinkHeartbeat(heartbeat.clone()) - } - }; - - return Some(msg); - } - } - - return Box::from(IteratorObj { - recv_msg: recv_msg.clone(), - }); -} diff --git a/hydra_provider/src/main.rs b/hydra_provider/src/main.rs index ca2e5700..4ad72f07 100644 --- a/hydra_provider/src/main.rs +++ b/hydra_provider/src/main.rs @@ -1,141 +1,34 @@ -use std::sync::Arc; +mod database_service; +mod command_service; +mod data_feed_service; +mod bootstrap; -use hydra_iterator::HydraInput; -use sqlx::PgPool; -use tokio::join; -use tonic::transport::Server; -use tonic_health::pb::health_server::HealthServer; -use tonic_health::server::HealthService; -mod db; -mod input; -use crate::connection_manager::ConnectionManagerImpl; -use crate::connection_manager_server::ConnectionManagerServer; -use crate::db::db_save_hydra_input; -use crate::greeter::GreeterImpl; -use crate::greeter_server::GreeterServer; -use crate::hydra_provider_proto::hydra_provider_proto::*; -use crate::input::process_file; -use crate::input::process_random_input; -use crate::input::process_serial; -use anyhow::Result; -use clap::ArgGroup; -use clap::Parser; -use log::*; - -mod connection_manager; -mod greeter; -mod hydra_iterator; -mod hydra_provider_proto; -mod rocket_command; -mod rocket_data; -mod rocket_sensor; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let args = Args::parse(); - env_logger::Builder::from_default_env() - .filter(None, args.log) - .init(); - - if let Err(err) = run(args).await { - error!("{:?}", err) - } - - Ok(()) -} - -/// Program to read and parse data from a HYDRA system -#[derive(Parser, Debug, Clone)] -#[command(author, version, about, long_about = None)] -#[command(group( - ArgGroup::new("input") - .required(false) - .args(["serial_port", "random_input"]) -))] -struct Args { - /// Serial port to read from. If not specified, the first port found will be used. - /// Is used as default input if not other inputs are specified. - #[arg(short, long, env, default_value = "/dev/ttyUSB0")] - serial_port: Option, - - /// Baud rate to use for the serial connection - #[arg(short, long, env, default_value = "57600")] - baud_rate: u32, - - /// Pocketbase port - #[arg(short, long, env, default_value = "3001")] - pocketbase_port: u32, - - /// Simulate a source with random data for testing - #[arg(short, long, env, default_value = "false")] - random_input: bool, - - // Read from file, input path - #[arg(short, long, env, default_value = "")] - file_input: String, +use std::str::FromStr; - /// Logging level - #[arg(short, long, env, default_value = "Info")] - log: LevelFilter, -} - -async fn run(args: Args) -> Result<()> { - let (mut health_reporter, health_service) = tonic_health::server::health_reporter(); - health_reporter - .set_serving::>() - .await; - - let addr = format!("[::1]:{}", args.pocketbase_port).parse().unwrap(); - let server = Server::builder() - .add_service(health_service) - .add_service(GreeterServer::new(GreeterImpl::default())) - .add_service(ConnectionManagerServer::new( - ConnectionManagerImpl::default(), - )) - .serve(addr); - - info!("Hydra Provider listening on {}", addr); - let db_url = std::env::var("DATABASE_URL") - .unwrap_or("postgres://postgres:postgres@localhost:5432/postgres".to_string()); - - info!("Connecting to database..."); - let db_client = Arc::new(PgPool::connect(&db_url).await.unwrap()); - info!("Connected to database"); - - let message_receiver_handle = tokio::task::spawn_blocking(move || { - for msg in start_input(args) { - let db_client = db_client.clone(); - tokio::task::spawn(async move { - db_save_hydra_input(&db_client, msg).await.unwrap(); - }); - } - }); - - let result = join!(server, message_receiver_handle); - - match result { - (Err(e), _) => { - error!("Server error: {}", e); - } - (_, Err(e)) => { - error!("Processing error: {}", e); - } - - _ => {} - } +use bootstrap::bootstrap; +use clap::Parser; - Ok(()) +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct CliArgs { + // Port to serve the gRPC server on + #[arg(short, long, default_value_t = 3000)] + port: u32, + + // Postgres DB Address + #[arg( + short, + long = "db", + default_value_t = String::from_str("postgres://postgres:postgres@localhost:5432/postgres").unwrap() + )] + database_address: String, } -fn start_input(args: Args) -> Box + Send> { - if !args.file_input.is_empty() { - info!("Reading from file"); - return process_file(args.file_input); - } else if !args.random_input { - info!("Using serial input"); - return process_serial(&args.serial_port, args.baud_rate); - } else { - info!("Using random input"); - return process_random_input(); - } -} +#[tokio::main] +async fn main() { + let args = CliArgs::parse(); + bootstrap( + args.port, + args.database_address + ).await; +} \ No newline at end of file From 053a756d09abf2740bcb95dab3f4e5ffa4eec7c5 Mon Sep 17 00:00:00 2001 From: Darren Rahnemoon Date: Fri, 15 Mar 2024 17:17:15 -0400 Subject: [PATCH 2/8] fix: more bug fixes and cleanup --- hydra_provider/src/bootstrap.rs | 3 +- hydra_provider/src/data_feed_service/mod.rs | 1 - .../src/data_feed_service/random/service.rs | 4 +- .../src/data_feed_service/serial/iterator.rs | 2 +- .../src/data_feed_service/serial/service.rs | 2 +- .../database_service/hydra_input/README.md | 1 + .../hydra_input/heart_beat.rs | 25 ++ .../hydra_input/messages/README.md | 1 + .../hydra_input/messages/command/README.md | 1 + .../messages/command/deploy_drogue.rs | 21 ++ .../messages/command/deploy_main.rs | 21 ++ .../hydra_input/messages/command/mod.rs | 36 ++ .../messages/command/power_down.rs | 21 ++ .../messages/command/radio_rate_change.rs | 21 ++ .../hydra_input/messages/health.rs | 55 +++ .../hydra_input/messages/log.rs | 22 ++ .../hydra_input/messages/mod.rs | 50 +++ .../hydra_input/messages/sensor.rs | 21 ++ .../hydra_input/messages/state.rs | 21 ++ .../src/database_service/hydra_input/mod.rs | 4 + .../hydra_input/radio_status.rs | 26 ++ .../database_service/hydra_input/saveable.rs | 7 + .../src/database_service/messages/mod.rs | 1 - .../src/database_service/messages/saveable.rs | 5 - hydra_provider/src/database_service/mod.rs | 4 +- .../src/database_service/service.rs | 21 +- hydra_provider/src/db.rs | 56 --- .../message/mod.rs => hydra_input.rs} | 0 hydra_provider/src/main.rs | 1 + hydra_provider/src/rocket_command.rs | 107 ------ hydra_provider/src/rocket_data.rs | 149 -------- hydra_provider/src/rocket_sensor.rs | 320 ------------------ 32 files changed, 382 insertions(+), 648 deletions(-) create mode 100644 hydra_provider/src/database_service/hydra_input/README.md create mode 100644 hydra_provider/src/database_service/hydra_input/heart_beat.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/README.md create mode 100644 hydra_provider/src/database_service/hydra_input/messages/command/README.md create mode 100644 hydra_provider/src/database_service/hydra_input/messages/command/deploy_drogue.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/command/deploy_main.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/command/mod.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/command/power_down.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/command/radio_rate_change.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/health.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/log.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/mod.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/state.rs create mode 100644 hydra_provider/src/database_service/hydra_input/mod.rs create mode 100644 hydra_provider/src/database_service/hydra_input/radio_status.rs create mode 100644 hydra_provider/src/database_service/hydra_input/saveable.rs delete mode 100644 hydra_provider/src/database_service/messages/mod.rs delete mode 100644 hydra_provider/src/database_service/messages/saveable.rs delete mode 100644 hydra_provider/src/db.rs rename hydra_provider/src/{data_feed_service/message/mod.rs => hydra_input.rs} (100%) delete mode 100644 hydra_provider/src/rocket_command.rs delete mode 100644 hydra_provider/src/rocket_data.rs delete mode 100644 hydra_provider/src/rocket_sensor.rs diff --git a/hydra_provider/src/bootstrap.rs b/hydra_provider/src/bootstrap.rs index 64a629de..d534f4a3 100644 --- a/hydra_provider/src/bootstrap.rs +++ b/hydra_provider/src/bootstrap.rs @@ -32,5 +32,6 @@ pub async fn bootstrap( .add_service(health_service) .add_service(SerialDataFeedServer::new(serial_data_feed_service)) .add_service(RandomDataFeedServer::new(random_data_feed_service)) - .serve(server_address); + .serve(server_address) + .await; } diff --git a/hydra_provider/src/data_feed_service/mod.rs b/hydra_provider/src/data_feed_service/mod.rs index 17071527..5d27e805 100644 --- a/hydra_provider/src/data_feed_service/mod.rs +++ b/hydra_provider/src/data_feed_service/mod.rs @@ -1,6 +1,5 @@ pub mod random; pub mod serial; -pub mod message; pub mod proto { tonic::include_proto!("data_feed"); diff --git a/hydra_provider/src/data_feed_service/random/service.rs b/hydra_provider/src/data_feed_service/random/service.rs index 2ae48d36..2b86fb8e 100644 --- a/hydra_provider/src/data_feed_service/random/service.rs +++ b/hydra_provider/src/data_feed_service/random/service.rs @@ -4,7 +4,7 @@ use tonic::{async_trait, Request, Response, Status}; use log::info; use crate::database_service::DatabaseService; -use crate::data_feed_service::message::HydraInput; +use crate::hydra_input::HydraInput; use crate::data_feed_service::random::iterator::RandomDataFeedIterator; use crate::data_feed_service::proto::random_data_feed_server::*; @@ -29,7 +29,7 @@ impl<'a> RandomDataFeedService<'_> { } #[async_trait] -impl RandomDataFeed for RandomDataFeedService { +impl RandomDataFeed for RandomDataFeedService<'static> { async fn start(&self, _request: Request) -> Result, Status> { self.iterator.is_running.store(true, Ordering::Relaxed); diff --git a/hydra_provider/src/data_feed_service/serial/iterator.rs b/hydra_provider/src/data_feed_service/serial/iterator.rs index 6b51d45c..ac35744c 100644 --- a/hydra_provider/src/data_feed_service/serial/iterator.rs +++ b/hydra_provider/src/data_feed_service/serial/iterator.rs @@ -4,7 +4,7 @@ use messages::mavlink::MavConnection; use postcard::from_bytes; use log::info; -use crate::data_feed_service::message::HydraInput; +use crate::hydra_input::HydraInput; use messages::Message; use crate::data_feed_service::proto::SerialDataFeedConfig; diff --git a/hydra_provider/src/data_feed_service/serial/service.rs b/hydra_provider/src/data_feed_service/serial/service.rs index e1293418..1b6ae511 100644 --- a/hydra_provider/src/data_feed_service/serial/service.rs +++ b/hydra_provider/src/data_feed_service/serial/service.rs @@ -33,7 +33,7 @@ impl<'a> SerialDataFeedService<'_> { } #[async_trait] -impl SerialDataFeed for SerialDataFeedService { +impl SerialDataFeed for SerialDataFeedService<'static> { async fn start(&self, _request: Request) -> Result, Status> { self.iterator.is_running.store(true, Ordering::Relaxed); diff --git a/hydra_provider/src/database_service/hydra_input/README.md b/hydra_provider/src/database_service/hydra_input/README.md new file mode 100644 index 00000000..0fcd90e6 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/README.md @@ -0,0 +1 @@ +# Saveable Implementation for HydraInput \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/heart_beat.rs b/hydra_provider/src/database_service/hydra_input/heart_beat.rs new file mode 100644 index 00000000..dccc8e42 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/heart_beat.rs @@ -0,0 +1,25 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use super::saveable::SaveableData; +use messages::mavlink::uorocketry::HEARTBEAT_DATA; + +impl SaveableData for HEARTBEAT_DATA { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + _: i32 + ) -> Result { + query!( + "INSERT INTO rocket_heartbeat + (custom_mode, mavtype, autopilot, base_mode, system_status, mavlink_version) + VALUES ($1, $2, $3, $4, $5, $6)", + self.custom_mode as i32, + self.mavtype as i32, + self.autopilot as i32, + self.base_mode as i32, + self.system_status as i32, + self.mavlink_version as i32, + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/README.md b/hydra_provider/src/database_service/hydra_input/messages/README.md new file mode 100644 index 00000000..ecf2955b --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/README.md @@ -0,0 +1 @@ +# Saveable Implementation for Messages diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/README.md b/hydra_provider/src/database_service/hydra_input/messages/command/README.md new file mode 100644 index 00000000..d5f90077 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/command/README.md @@ -0,0 +1 @@ +# Saveable Implementation for Commands and CommandData \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/deploy_drogue.rs b/hydra_provider/src/database_service/hydra_input/messages/command/deploy_drogue.rs new file mode 100644 index 00000000..9a204ec4 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/command/deploy_drogue.rs @@ -0,0 +1,21 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::command::DeployDrogue; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for DeployDrogue { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_command_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_deploy_drogue_command + (rocket_command_id, val) + VALUES ($1, $2)", + rocket_command_id, + self.val + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/deploy_main.rs b/hydra_provider/src/database_service/hydra_input/messages/command/deploy_main.rs new file mode 100644 index 00000000..f3cf714d --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/command/deploy_main.rs @@ -0,0 +1,21 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::command::DeployMain; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for DeployMain { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_command_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_deploy_main_command + (rocket_command_id, val) + VALUES ($1, $2)", + rocket_command_id, + self.val + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/mod.rs b/hydra_provider/src/database_service/hydra_input/messages/command/mod.rs new file mode 100644 index 00000000..e8e82eb2 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/command/mod.rs @@ -0,0 +1,36 @@ +pub mod deploy_drogue; +pub mod deploy_main; +pub mod power_down; +pub mod radio_rate_change; + +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::command::{Command, CommandData}; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for Command { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let result = query!( + "INSERT INTO rocket_command + (rocket_message_id) + VALUES ($1)", + rocket_message_id, + ) + .execute(&mut **transaction) + .await; + + if result.is_err() { + return result; + } + + match &self.data { + CommandData::DeployDrogue(data) => data.save(transaction, rocket_message_id).await, + CommandData::DeployMain(data) => data.save(transaction, rocket_message_id).await, + CommandData::RadioRateChange(data) => data.save(transaction, rocket_message_id).await, + CommandData::PowerDown(data) => data.save(transaction, rocket_message_id).await, + } + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/power_down.rs b/hydra_provider/src/database_service/hydra_input/messages/command/power_down.rs new file mode 100644 index 00000000..79291a7c --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/command/power_down.rs @@ -0,0 +1,21 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::command::PowerDown; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for PowerDown { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_command_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_power_down_command + (rocket_command_id, board) + VALUES ($1, $2)", + rocket_command_id, + format!("{:?}", self.board) + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/radio_rate_change.rs b/hydra_provider/src/database_service/hydra_input/messages/command/radio_rate_change.rs new file mode 100644 index 00000000..d8fad609 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/command/radio_rate_change.rs @@ -0,0 +1,21 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::command::RadioRateChange; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for RadioRateChange { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_command_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_radio_rate_change_command + (rocket_command_id, rate) + VALUES ($1, $2)", + rocket_command_id, + format!("{:?}", self.rate) + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/health.rs b/hydra_provider/src/database_service/hydra_input/messages/health.rs new file mode 100644 index 00000000..3da6c3be --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/health.rs @@ -0,0 +1,55 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::health::{Health, HealthData, HealthStatus}; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for Health { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let result = query!( + "INSERT INTO rocket_health + (rocket_message_id, status) + VALUES ($1, $2)", + rocket_message_id, + format!("{:?}", self.status) + ) + .execute(&mut **transaction) + .await; + + if result.is_err() { + return result; + } + + match &self.data { + HealthData::HealthStatus(status) => status.save(transaction, rocket_message_id).await, + } + } +} + +impl SaveableData for HealthStatus { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_health_status + (rocket_health_id, v5, v3_3, pyro_sense, vcc_sense, int_v5, int_v3_3, ext_v5, ext_3v3, failover_sense) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", + rocket_message_id, + self.v5.map(|x| x as i32), + self.v3_3.map(|x| x as i32), + self.pyro_sense.map(|x| x as i32), + self.vcc_sense.map(|x| x as i32), + self.int_v5.map(|x| x as i32), + self.int_v3_3.map(|x| x as i32), + self.ext_v5.map(|x| x as i32), + self.ext_3v3.map(|x| x as i32), + self.failover_sense.map(|x| x as i32), + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/log.rs b/hydra_provider/src/database_service/hydra_input/messages/log.rs new file mode 100644 index 00000000..151320c6 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/log.rs @@ -0,0 +1,22 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::Log; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for Log { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_log + (rocket_message_id, level, event) + VALUES ($1, $2, $3)", + rocket_message_id, + format!("{:?}", self.level), + format!("{:?}", self.event) + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/mod.rs b/hydra_provider/src/database_service/hydra_input/messages/mod.rs new file mode 100644 index 00000000..7fb502d9 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/mod.rs @@ -0,0 +1,50 @@ +use messages::{Data, Message}; +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use super::saveable::SaveableData; + +pub mod health; +pub mod state; +pub mod log; +pub mod sensor; +pub mod command; + +impl SaveableData for Message { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + _: i32 + ) -> Result { + let message_type = match self.data { + Data::Health(_) => "health", + Data::State(_) => "state", + Data::Sensor(_) => "sensor", + Data::Log(_) => "log", + Data::Command(_) => "command", + }; + + let result = query!( + "INSERT INTO rocket_message + (time_stamp, sender, message_type) + VALUES ($1, $2, $3) + RETURNING id", + self.timestamp as i32, + format!("{:?}", self.sender), + message_type + ) + .fetch_one(&mut **transaction) + .await; + + if result.is_err() { + return Err(result.err().unwrap()); + } + + let record = result.unwrap(); + match &self.data { + Data::Health(data) => data.save(transaction, record.id).await, + Data::State(data) => data.save(transaction, record.id).await, + Data::Sensor(data) => data.save(transaction, record.id).await, + Data::Log(data) => data.save(transaction, record.id).await, + Data::Command(data) => data.save(transaction, record.id).await, + } + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor.rs new file mode 100644 index 00000000..fe68228b --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor.rs @@ -0,0 +1,21 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::Sensor; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for Sensor { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_sensor_message + (rocket_message_id, component_id) + VALUES ($1, $2)", + rocket_message_id, + self.component_id as i32 + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/state.rs b/hydra_provider/src/database_service/hydra_input/messages/state.rs new file mode 100644 index 00000000..322f0200 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/state.rs @@ -0,0 +1,21 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::state::State; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for State { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_state + (rocket_message_id, state) + VALUES ($1, $2)", + rocket_message_id, + format!("{:?}", *self) + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/mod.rs b/hydra_provider/src/database_service/hydra_input/mod.rs new file mode 100644 index 00000000..7e6c5215 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/mod.rs @@ -0,0 +1,4 @@ +pub mod saveable; +pub mod messages; +pub mod heart_beat; +pub mod radio_status; diff --git a/hydra_provider/src/database_service/hydra_input/radio_status.rs b/hydra_provider/src/database_service/hydra_input/radio_status.rs new file mode 100644 index 00000000..ee35d05f --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/radio_status.rs @@ -0,0 +1,26 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use super::saveable::SaveableData; +use messages::mavlink::uorocketry::RADIO_STATUS_DATA; + +impl SaveableData for RADIO_STATUS_DATA { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + _: i32 + ) -> Result { + query!( + "INSERT INTO rocket_radio_status + (rxerrors, fixed, rssi, remrssi, txbuf, noise, remnoise) + VALUES ($1, $2, $3, $4, $5, $6, $7)", + self.rxerrors as i32, + self.fixed as i32, + self.rssi as i32, + self.remrssi as i32, + self.txbuf as i32, + self.noise as i32, + self.remnoise as i32, + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/saveable.rs b/hydra_provider/src/database_service/hydra_input/saveable.rs new file mode 100644 index 00000000..208d1d71 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/saveable.rs @@ -0,0 +1,7 @@ +use sqlx::{Postgres, Transaction, Error}; +use sqlx::postgres::PgQueryResult; + + +pub trait SaveableData { + async fn save(&self, transaction: &mut Transaction<'_, Postgres>, rocket_message_id: i32) -> Result; +} diff --git a/hydra_provider/src/database_service/messages/mod.rs b/hydra_provider/src/database_service/messages/mod.rs deleted file mode 100644 index d31839a5..00000000 --- a/hydra_provider/src/database_service/messages/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod saveable; \ No newline at end of file diff --git a/hydra_provider/src/database_service/messages/saveable.rs b/hydra_provider/src/database_service/messages/saveable.rs deleted file mode 100644 index 5c81bc78..00000000 --- a/hydra_provider/src/database_service/messages/saveable.rs +++ /dev/null @@ -1,5 +0,0 @@ -use sqlx::PgPool; - -pub trait Saveable { - fn save(pool: &PgPool); -} \ No newline at end of file diff --git a/hydra_provider/src/database_service/mod.rs b/hydra_provider/src/database_service/mod.rs index 9839e637..0598e9df 100644 --- a/hydra_provider/src/database_service/mod.rs +++ b/hydra_provider/src/database_service/mod.rs @@ -1,2 +1,4 @@ pub mod service; -pub mod messages; \ No newline at end of file +pub mod hydra_input; + +pub use service::DatabaseService; \ No newline at end of file diff --git a/hydra_provider/src/database_service/service.rs b/hydra_provider/src/database_service/service.rs index f9bbe830..843e9d05 100644 --- a/hydra_provider/src/database_service/service.rs +++ b/hydra_provider/src/database_service/service.rs @@ -1,7 +1,8 @@ use std::sync::Arc; use sqlx::PgPool; -use crate::data_feed_service::message::HydraInput; +use crate::hydra_input::HydraInput; +use crate::database_service::hydra_input::saveable::SaveableData; pub struct DatabaseService { pool: Arc, @@ -14,7 +15,21 @@ impl DatabaseService { } } - pub fn save(&self, message: HydraInput) { - + pub async fn save(&self, hydra_input: HydraInput) { + let mut transaction = self.pool.begin().await.unwrap(); + let result = match hydra_input { + HydraInput::Heartbeat(message) => message.save(&mut transaction, 0).await, + HydraInput::RadioStatus(message) => message.save(&mut transaction, 0).await, + HydraInput::Message(message) => message.save(&mut transaction, 0).await + }; + + match result { + Ok(_) => transaction.commit().await, + Err(error) => { + transaction.rollback().await; + + Err(error) + } + }; } } \ No newline at end of file diff --git a/hydra_provider/src/db.rs b/hydra_provider/src/db.rs deleted file mode 100644 index b3c2b0d5..00000000 --- a/hydra_provider/src/db.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::{data_feeds::message::HydraInput, rocket_data::db_save_rocket_message}; -use messages::mavlink::uorocketry::{HEARTBEAT_DATA, RADIO_STATUS_DATA}; -use sqlx::postgres::{PgPool, PgQueryResult}; - -pub async fn db_save_hydra_input(pool: &PgPool, msg: HydraInput) -> Result<(), sqlx::Error> { - match msg { - HydraInput::RadioStatus(status) => { - return db_save_radio_status(&pool, status).await.map(|_| ()) - } - HydraInput::Message(data) => { - return db_save_rocket_message(&pool, data).await; - } - HydraInput::Heartbeat(heartbeat) => { - return db_save_rocket_heartbeat(&pool, heartbeat).await.map(|_| ()) - } - } -} - -async fn db_save_radio_status( - pool: &PgPool, - status: RADIO_STATUS_DATA, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_radio_status - (rxerrors, fixed, rssi, remrssi, txbuf, noise, remnoise) - VALUES ($1, $2, $3, $4, $5, $6, $7)", - status.rxerrors as i32, - status.fixed as i32, - status.rssi as i32, - status.remrssi as i32, - status.txbuf as i32, - status.noise as i32, - status.remnoise as i32, - ) - .execute(pool) - .await; -} - -async fn db_save_rocket_heartbeat( - pool: &PgPool, - heartbeat: HEARTBEAT_DATA, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_heartbeat - (custom_mode, mavtype, autopilot, base_mode, system_status, mavlink_version) - VALUES ($1, $2, $3, $4, $5, $6)", - heartbeat.custom_mode as i32, - heartbeat.mavtype as i32, - heartbeat.autopilot as i32, - heartbeat.base_mode as i32, - heartbeat.system_status as i32, - heartbeat.mavlink_version as i32, - ) - .execute(pool) - .await; -} diff --git a/hydra_provider/src/data_feed_service/message/mod.rs b/hydra_provider/src/hydra_input.rs similarity index 100% rename from hydra_provider/src/data_feed_service/message/mod.rs rename to hydra_provider/src/hydra_input.rs diff --git a/hydra_provider/src/main.rs b/hydra_provider/src/main.rs index 4ad72f07..5931699f 100644 --- a/hydra_provider/src/main.rs +++ b/hydra_provider/src/main.rs @@ -2,6 +2,7 @@ mod database_service; mod command_service; mod data_feed_service; mod bootstrap; +mod hydra_input; use std::str::FromStr; diff --git a/hydra_provider/src/rocket_command.rs b/hydra_provider/src/rocket_command.rs deleted file mode 100644 index 39823fc1..00000000 --- a/hydra_provider/src/rocket_command.rs +++ /dev/null @@ -1,107 +0,0 @@ -use messages::command::{self, Command, CommandData}; - -use sqlx::{postgres::PgQueryResult, Postgres, Transaction}; - -pub async fn add_rocket_command( - cmd: Command, - rocket_message_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let cmd_data = cmd.data; - let res = sqlx::query!( - "INSERT INTO rocket_command - (rocket_message_id) - VALUES ($1)", - rocket_message_id - ) - .execute(&mut **transaction) - .await; - - if res.is_err() { - return Err(res.err().unwrap()); - } - - match cmd_data { - CommandData::DeployDrogue(deploy_drogue) => { - return add_deploy_drogue_command(deploy_drogue, rocket_message_id, transaction).await; - } - CommandData::DeployMain(deploy_main) => { - return add_deploy_main_command(deploy_main, rocket_message_id, transaction).await; - } - CommandData::PowerDown(power_down) => { - return add_power_down_command(power_down, rocket_message_id, transaction).await; - } - CommandData::RadioRateChange(radio_rate_change) => { - return add_radio_rate_change_command( - radio_rate_change, - rocket_message_id, - transaction, - ) - .await; - } - } -} - -async fn add_deploy_drogue_command( - deploy_drogue: command::DeployDrogue, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_deploy_drogue_command - (rocket_command_id, val) - VALUES ($1, $2)", - rocket_command_id, - deploy_drogue.val - ) - .execute(&mut **transaction) - .await; -} - -async fn add_deploy_main_command( - deploy_main: command::DeployMain, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_deploy_main_command - (rocket_command_id, val) - VALUES ($1, $2)", - rocket_command_id, - deploy_main.val - ) - .execute(&mut **transaction) - .await; -} - -async fn add_power_down_command( - power_down: command::PowerDown, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_power_down_command - (rocket_command_id, board) - VALUES ($1, $2)", - rocket_command_id, - format!("{:?}", power_down.board) - ) - .execute(&mut **transaction) - .await; -} - -async fn add_radio_rate_change_command( - radio_rate_change: command::RadioRateChange, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_radio_rate_change_command - (rocket_command_id, rate) - VALUES ($1, $2)", - rocket_command_id, - format!("{:?}", radio_rate_change.rate) - ) - .execute(&mut **transaction) - .await; -} diff --git a/hydra_provider/src/rocket_data.rs b/hydra_provider/src/rocket_data.rs deleted file mode 100644 index 03a46de0..00000000 --- a/hydra_provider/src/rocket_data.rs +++ /dev/null @@ -1,149 +0,0 @@ -use messages::{health::Health, state::State, Data, Log, Message}; - -use sqlx::{postgres::PgQueryResult, PgPool, Postgres, Transaction}; - -use crate::{rocket_command::add_rocket_command, rocket_sensor::db_save_rocket_sensor}; - -async fn db_save_rocket_message_base( - rocket_message: Message, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let msg_type = match rocket_message.data { - Data::Health(_) => "health", - Data::State(_) => "state", - Data::Sensor(_) => "sensor", - Data::Log(_) => "log", - Data::Command(_) => "command", - }; - - let result = sqlx::query!( - "INSERT INTO rocket_message - (time_stamp, sender, message_type) - VALUES ($1, $2, $3) - RETURNING id", - rocket_message.timestamp as i32, - format!("{:?}", rocket_message.sender), - msg_type - ) - .fetch_one(&mut **transaction) - .await; - - match result { - Ok(res) => { - return Ok(res.id); - } - Err(e) => { - return Err(e); - } - } -} - -pub async fn db_save_rocket_message( - pool: &PgPool, - rocket_message: Message, -) -> Result<(), sqlx::Error> { - let mut transaction = pool.begin().await.unwrap(); - let message_id = db_save_rocket_message_base(rocket_message.clone(), &mut transaction).await?; - - match rocket_message.data { - Data::Health(health) => db_save_rocket_health(message_id, health, &mut transaction).await?, - Data::State(state) => db_save_rocket_state(message_id, state, &mut transaction).await?, - Data::Sensor(sensor) => db_save_rocket_sensor(sensor, message_id, &mut transaction).await?, - Data::Log(log) => db_save_rocket_log(message_id, log, &mut transaction).await?, - Data::Command(cmd) => add_rocket_command(cmd, message_id, &mut transaction).await?, - }; - - let transaction_result = transaction.commit().await; - - if transaction_result.is_err() { - return Err(transaction_result.err().unwrap()); - } - return Ok(()); -} - -async fn db_save_rocket_state( - rocket_message_id: i32, - state: State, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_state - (rocket_message_id, state) - VALUES ($1, $2)", - rocket_message_id, - format!("{:?}", state) - ) - .execute(&mut **transaction) - .await; -} - -async fn db_save_rocket_log( - rocket_message_id: i32, - log: Log, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let level = log.level; - let event = log.event; - return sqlx::query!( - "INSERT INTO rocket_log - (rocket_message_id, level, event) - VALUES ($1, $2, $3)", - rocket_message_id, - format!("{:?}", level), - format!("{:?}", event) - ) - .execute(&mut **transaction) - .await; -} - -async fn db_save_rocket_health( - rocket_message_id: i32, - health: Health, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let res = sqlx::query!( - "INSERT INTO rocket_health - (rocket_message_id, status) - VALUES ($1, $2)", - rocket_message_id, - format!("{:?}", health.status) - ) - .execute(&mut **transaction) - .await; - - if res.is_err() { - return res; - } - let health_status = health.data; - - match health_status { - messages::health::HealthData::HealthStatus(health_status) => { - return db_save_rocket_health_status(rocket_message_id, health_status, transaction) - .await; - } - } -} - -async fn db_save_rocket_health_status( - rocket_message_id: i32, - health_status: messages::health::HealthStatus, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_health_status - (rocket_health_id, v5, v3_3, pyro_sense, vcc_sense, int_v5, int_v3_3, ext_v5, ext_3v3, failover_sense) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", - rocket_message_id, - health_status.v5.map(|x| x as i32), - health_status.v3_3.map(|x| x as i32), - health_status.pyro_sense.map(|x| x as i32), - health_status.vcc_sense.map(|x| x as i32), - health_status.int_v5.map(|x| x as i32), - health_status.int_v3_3.map(|x| x as i32), - health_status.ext_v5.map(|x| x as i32), - health_status.ext_3v3.map(|x| x as i32), - health_status.failover_sense.map(|x| x as i32), - ) - .execute(&mut **transaction) - .await; -} diff --git a/hydra_provider/src/rocket_sensor.rs b/hydra_provider/src/rocket_sensor.rs deleted file mode 100644 index 2d8f82cb..00000000 --- a/hydra_provider/src/rocket_sensor.rs +++ /dev/null @@ -1,320 +0,0 @@ -use messages::sensor::{Sensor, UtcTime}; - -use sqlx::{postgres::PgQueryResult, Postgres, Transaction}; - -pub async fn db_save_rocket_sensor( - sensor: Sensor, - rocket_message_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let res: Result = sqlx::query!( - "INSERT INTO rocket_sensor_message - (rocket_message_id, component_id) - VALUES ($1, $2)", - rocket_message_id, - sensor.component_id as i32 - ) - .execute(&mut **transaction) - .await; - - if res.is_err() { - return Err(res.err().unwrap()); - } - let sensor_data = sensor.data; - - return match sensor_data { - messages::sensor::SensorData::UtcTime(time) => { - add_utc_time(time, rocket_message_id, transaction).await - } - messages::sensor::SensorData::Air(air) => { - add_air(air, rocket_message_id, transaction).await - } - messages::sensor::SensorData::EkfQuat(ekf_quat) => { - add_rocket_quat(ekf_quat, rocket_message_id, transaction).await - } - messages::sensor::SensorData::EkfNav1(ekf_nav_1) => { - add_rocket_nav_1(ekf_nav_1, rocket_message_id, transaction).await - } - messages::sensor::SensorData::EkfNav2(ekf_nav_2) => { - add_rocket_nav_2(ekf_nav_2, rocket_message_id, transaction).await - } - messages::sensor::SensorData::Imu1(imu_1) => { - add_imu_1(imu_1, rocket_message_id, transaction).await - } - messages::sensor::SensorData::Imu2(imu_2) => { - add_imu_2(imu_2, rocket_message_id, transaction).await - } - messages::sensor::SensorData::GpsVel(gps_vel) => { - add_gps_vel(gps_vel, rocket_message_id, transaction).await - } - messages::sensor::SensorData::GpsPos1(gps_pos_1) => { - add_gps_pos_1(gps_pos_1, rocket_message_id, transaction).await - } - messages::sensor::SensorData::GpsPos2(gps_pos_2) => { - add_gps_pos_2(gps_pos_2, rocket_message_id, transaction).await - } - }; -} - -async fn add_vec3( - vec3: [f32; 3usize], - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let id = sqlx::query!( - "INSERT INTO data_vec3 - (x, y, z) - VALUES ($1, $2, $3) RETURNING id", - vec3[0], - vec3[1], - vec3[2] - ) - .fetch_one(&mut **transaction) - .await? - .id; - - return Ok(id); -} - -async fn add_quaternion( - vec4: [f32; 4usize], - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let id = sqlx::query!( - "INSERT INTO data_quaternion - (x, y, z, w) - VALUES ($1, $2, $3, $4) RETURNING id", - vec4[0], - vec4[1], - vec4[2], - vec4[3] - ) - .fetch_one(&mut **transaction) - .await? - .id; - - return Ok(id); -} - -async fn add_utc_time( - time: UtcTime, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_sensor_utc_time - (rocket_sensor_message_id, time_stamp, status, year, month, day, hour, minute, second, nano_second, gps_time_of_week) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", - rocket_command_id, - time.time_stamp as i32, - time.status as i32, - time.year as i32, - time.month as i32, - time.day as i32, - time.hour as i32, - time.minute as i32, - time.second as i32, - time.nano_second as i32, - time.gps_time_of_week as i32, - ) - .execute(&mut **transaction) - .await; -} - -async fn add_air( - air: messages::sensor::Air, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_sensor_air - (rocket_sensor_message_id, time_stamp, status, pressure_abs, altitude, pressure_diff, true_airspeed, air_temperature) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", - rocket_command_id, - air.time_stamp as i32, - air.status as i32, - air.pressure_abs as f32, - air.altitude as f32, - air.pressure_diff as f32, - air.true_airspeed as f32, - air.air_temperature as f32, - ) - .execute(&mut **transaction) - .await; -} - -async fn add_rocket_quat( - ekf_quat: messages::sensor::EkfQuat, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let euler_std_dev = add_vec3(ekf_quat.euler_std_dev, transaction).await?; - let quaternion = add_quaternion(ekf_quat.quaternion, transaction).await?; - - return sqlx::query!( - "INSERT INTO rocket_sensor_quat - (rocket_sensor_message_id, time_stamp, quaternion, euler_std_dev, status) - VALUES ($1, $2, $3, $4, $5)", - rocket_command_id, - ekf_quat.time_stamp as i32, - quaternion, - euler_std_dev, - ekf_quat.status as i32, - ) - .execute(&mut **transaction) - .await; -} - -async fn add_rocket_nav_1( - ekf_nav_1: messages::sensor::EkfNav1, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let velocity = add_vec3(ekf_nav_1.velocity, transaction).await?; - let velocity_std_dev = add_vec3(ekf_nav_1.velocity_std_dev, transaction).await?; - - return sqlx::query!( - "INSERT INTO rocket_sensor_nav_1 - (rocket_sensor_message_id, time_stamp, velocity, velocity_std_dev) - VALUES ($1, $2, $3, $4)", - rocket_command_id, - ekf_nav_1.time_stamp as i32, - velocity, - velocity_std_dev, - ) - .execute(&mut **transaction) - .await; -} - -async fn add_rocket_nav_2( - ekf_nav_2: messages::sensor::EkfNav2, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let position = add_vec3(ekf_nav_2.position.map(|x| x as f32), transaction).await?; - let position_std_dev = add_vec3(ekf_nav_2.position_std_dev, transaction).await?; - - return sqlx::query!( - "INSERT INTO rocket_sensor_nav_2 - (rocket_sensor_message_id, position, position_std_dev, undulation, status) - VALUES ($1, $2, $3, $4, $5)", - rocket_command_id, - position, - position_std_dev, - ekf_nav_2.undulation, - ekf_nav_2.status as i32, - ) - .execute(&mut **transaction) - .await; -} - -async fn add_imu_1( - imu_1: messages::sensor::Imu1, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let accelerometers = add_vec3(imu_1.accelerometers, transaction).await?; - let gyroscopes = add_vec3(imu_1.gyroscopes, transaction).await?; - - return sqlx::query!( - "INSERT INTO rocket_sensor_imu_1 - (rocket_sensor_message_id, time_stamp, status, accelerometers, gyroscopes) - VALUES ($1, $2, $3, $4, $5)", - rocket_command_id, - imu_1.time_stamp as i32, - imu_1.status as i32, - accelerometers, - gyroscopes, - ) - .execute(&mut **transaction) - .await; -} - -async fn add_imu_2( - imu_2: messages::sensor::Imu2, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let delta_velocity = add_vec3(imu_2.delta_velocity, transaction).await?; - let delta_angle = add_vec3(imu_2.delta_angle, transaction).await?; - - return sqlx::query!( - "INSERT INTO rocket_sensor_imu_2 - (rocket_sensor_message_id, temperature, delta_velocity, delta_angle) - VALUES ($1, $2, $3, $4)", - rocket_command_id, - imu_2.temperature as f32, - delta_velocity, - delta_angle, - ) - .execute(&mut **transaction) - .await; -} - -async fn add_gps_vel( - gps_vel: messages::sensor::GpsVel, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - let velocity = add_vec3(gps_vel.velocity, transaction).await?; - let velocity_acc = add_vec3(gps_vel.velocity_acc, transaction).await?; - - return sqlx::query!( - "INSERT INTO rocket_sensor_gps_vel - (rocket_sensor_message_id, time_stamp, status, time_of_week, velocity, velocity_acc, course, course_acc) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", - rocket_command_id, - gps_vel.time_stamp as i32, - gps_vel.status as i32, - gps_vel.time_of_week as i32, - velocity, - velocity_acc, - gps_vel.course as f32, - gps_vel.course_acc as f32, - ) - .execute(&mut **transaction) - .await; -} - -async fn add_gps_pos_1( - gps_pos_1: messages::sensor::GpsPos1, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_sensor_gps_pos_1 - (rocket_sensor_message_id, time_stamp, status, time_of_week, latitude, longitude, altitude, undulation) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", - rocket_command_id, - gps_pos_1.time_stamp as i32, - gps_pos_1.status as i32, - gps_pos_1.time_of_week as i32, - gps_pos_1.latitude as f32, - gps_pos_1.longitude as f32, - gps_pos_1.altitude as f32, - gps_pos_1.undulation as f32, - - ) - .execute(&mut **transaction) - .await; -} - -async fn add_gps_pos_2( - gps_pos_2: messages::sensor::GpsPos2, - rocket_command_id: i32, - transaction: &mut Transaction<'_, Postgres>, -) -> Result { - return sqlx::query!( - "INSERT INTO rocket_sensor_gps_pos_2 - (rocket_sensor_message_id, latitude_accuracy, longitude_accuracy, altitude_accuracy, num_sv_used, base_station_id, differential_age) - VALUES ($1, $2, $3, $4, $5, $6, $7)", - rocket_command_id, - gps_pos_2.latitude_accuracy as f32, - gps_pos_2.longitude_accuracy as f32, - gps_pos_2.altitude_accuracy as f32, - gps_pos_2.num_sv_used as i32, - gps_pos_2.base_station_id as i32, - gps_pos_2.differential_age as i32, - ) - .execute(&mut **transaction) - .await; -} From 40e124f6b9d78bc30810ef5a60ff32c53356eeff Mon Sep 17 00:00:00 2001 From: Darren Rahnemoon Date: Fri, 15 Mar 2024 17:54:05 -0400 Subject: [PATCH 3/8] chore: lint --- hydra_provider/src/bootstrap.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hydra_provider/src/bootstrap.rs b/hydra_provider/src/bootstrap.rs index d534f4a3..8ccd8ab6 100644 --- a/hydra_provider/src/bootstrap.rs +++ b/hydra_provider/src/bootstrap.rs @@ -14,7 +14,7 @@ use tonic_health::server::HealthService; pub async fn bootstrap( server_port: u32, database_address: String, -) -> () { +) { let server_address: SocketAddr = format!("[::1]:{}", server_port).parse().unwrap(); let database_service = DatabaseService::new(&database_address.as_str()).await; @@ -23,13 +23,13 @@ pub async fn bootstrap( let ( mut health_reporter, - health_service + health_server ) = health_reporter(); health_reporter.set_serving::>().await; Server::builder() - .add_service(health_service) + .add_service(health_server) .add_service(SerialDataFeedServer::new(serial_data_feed_service)) .add_service(RandomDataFeedServer::new(random_data_feed_service)) .serve(server_address) From a3526a255de7f136a187f569bfb8e9d590b648df Mon Sep 17 00:00:00 2001 From: Darren Rahnemoon Date: Tue, 19 Mar 2024 12:18:52 -0400 Subject: [PATCH 4/8] fix: build errors --- hydra_provider/build.rs | 1 - hydra_provider/proto/hydra_provider.proto | 40 --------------- hydra_provider/src/bootstrap.rs | 12 +++-- .../src/data_feed_service/random/iterator.rs | 17 ++++--- .../src/data_feed_service/random/service.rs | 21 ++++---- .../src/data_feed_service/serial/iterator.rs | 15 +++--- .../src/data_feed_service/serial/service.rs | 35 +++++++------ .../hydra_input/messages/sensor.rs | 21 -------- .../hydra_input/messages/sensor/air.rs | 27 ++++++++++ .../hydra_input/messages/sensor/ekf_nav1.rs | 27 ++++++++++ .../hydra_input/messages/sensor/ekf_nav2.rs | 29 +++++++++++ .../hydra_input/messages/sensor/ekf_quat.rs | 30 +++++++++++ .../messages/sensor/gps_position1.rs | 29 +++++++++++ .../messages/sensor/gps_position2.rs | 27 ++++++++++ .../messages/sensor/gps_velocity.rs | 33 ++++++++++++ .../hydra_input/messages/sensor/imu1.rs | 30 +++++++++++ .../hydra_input/messages/sensor/imu2.rs | 28 ++++++++++ .../hydra_input/messages/sensor/mod.rs | 51 +++++++++++++++++++ .../hydra_input/messages/sensor/utc_time.rs | 30 +++++++++++ .../hydra_input/messages/sensor/utils.rs | 40 +++++++++++++++ .../src/database_service/service.rs | 10 ++-- hydra_provider/src/main.rs | 6 +-- 22 files changed, 448 insertions(+), 111 deletions(-) delete mode 100644 hydra_provider/proto/hydra_provider.proto delete mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/air.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav1.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav2.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_quat.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position1.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position2.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/gps_velocity.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/imu1.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/imu2.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/mod.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/utc_time.rs create mode 100644 hydra_provider/src/database_service/hydra_input/messages/sensor/utils.rs diff --git a/hydra_provider/build.rs b/hydra_provider/build.rs index edde24f6..dd80f029 100644 --- a/hydra_provider/build.rs +++ b/hydra_provider/build.rs @@ -2,7 +2,6 @@ fn main() { // Define .proto files that need to get compiled here // No need to compile health.proto as its provided by tonic let protos = [ - "proto/hydra_provider.proto", "proto/data_feed.proto", ]; diff --git a/hydra_provider/proto/hydra_provider.proto b/hydra_provider/proto/hydra_provider.proto deleted file mode 100644 index 879c7486..00000000 --- a/hydra_provider/proto/hydra_provider.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto3"; - -package hydra_provider; - -message Empty { -} - -service ConnectionManager { - rpc GetConnectionType (Empty) returns (ConnectionTypeMessage) {} - rpc SetConnectionType (ConnectionTypeMessage) returns (Empty) {} - - rpc GetSerialPorts (Empty) returns (GetSerialPortsReply) {} - rpc SetPreferredSerialPort (SetSerialConnectionRequest) returns (Empty) {} - - rpc CheckConnection (Empty) returns (CheckConnectionReply) {} -} - -message ConnectionTypeMessage { - ConnectionType connectionType = 1; -} - -enum ConnectionType { - SERIAL = 0; - RANDOM = 1; -} - -message GetSerialPortsReply { - repeated string ports = 1; -} - -message SetSerialConnectionRequest { - string portName = 1; -} - - -message CheckConnectionReply { - bool connected = 1; - ConnectionType connectionType = 2; - repeated string errors = 3; -} \ No newline at end of file diff --git a/hydra_provider/src/bootstrap.rs b/hydra_provider/src/bootstrap.rs index 8ccd8ab6..c0940e9f 100644 --- a/hydra_provider/src/bootstrap.rs +++ b/hydra_provider/src/bootstrap.rs @@ -1,4 +1,6 @@ use std::net::SocketAddr; +use std::sync::Arc; +use tokio::sync::Mutex; // use crate::commands::service::CommandService; use crate::data_feed_service::serial::{SerialDataFeedService, SerialDataFeedServer}; @@ -14,12 +16,12 @@ use tonic_health::server::HealthService; pub async fn bootstrap( server_port: u32, database_address: String, -) { +) -> Result<(), tonic::transport::Error> { let server_address: SocketAddr = format!("[::1]:{}", server_port).parse().unwrap(); - let database_service = DatabaseService::new(&database_address.as_str()).await; - let serial_data_feed_service = SerialDataFeedService::new(&database_service); - let random_data_feed_service = RandomDataFeedService::new(&database_service); + let database_service = Arc::new(Mutex::new(DatabaseService::new(&database_address.as_str()).await)); + let serial_data_feed_service = SerialDataFeedService::new(database_service.clone()); + let random_data_feed_service = RandomDataFeedService::new(database_service.clone()); let ( mut health_reporter, @@ -33,5 +35,5 @@ pub async fn bootstrap( .add_service(SerialDataFeedServer::new(serial_data_feed_service)) .add_service(RandomDataFeedServer::new(random_data_feed_service)) .serve(server_address) - .await; + .await } diff --git a/hydra_provider/src/data_feed_service/random/iterator.rs b/hydra_provider/src/data_feed_service/random/iterator.rs index ac69e6e8..e11e0eda 100644 --- a/hydra_provider/src/data_feed_service/random/iterator.rs +++ b/hydra_provider/src/data_feed_service/random/iterator.rs @@ -6,15 +6,16 @@ use rand::{rngs::StdRng, SeedableRng}; use messages::{command::Command, health::Health, sensor::{Air, EkfNav1, EkfNav2, EkfQuat, GpsPos1, GpsPos2, GpsVel, Imu1, Imu2, Sensor, UtcTime}, state::{State, StateData}, Data, Log, Message}; +use crate::hydra_input::HydraInput; + +#[derive(Clone)] pub struct RandomDataFeedIterator { pub is_running: Arc, } -impl Iterator for RandomDataFeedIterator { - type Item = Message; - - fn next(&mut self) -> Option { +impl RandomDataFeedIterator { + pub async fn next(&mut self) -> Option { if !self.is_running.load(Ordering::Relaxed) { return None } @@ -174,7 +175,11 @@ impl Iterator for RandomDataFeedIterator { }), _ => Data::Sensor(sensor), }; - - Some(Message::new(&time, messages::sender::Sender::GroundStation, data)) + + Some( + HydraInput::Message( + Message::new(&time, messages::sender::Sender::GroundStation, data) + ) + ) } } diff --git a/hydra_provider/src/data_feed_service/random/service.rs b/hydra_provider/src/data_feed_service/random/service.rs index 2b86fb8e..1b60e147 100644 --- a/hydra_provider/src/data_feed_service/random/service.rs +++ b/hydra_provider/src/data_feed_service/random/service.rs @@ -1,23 +1,23 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; +use tokio::sync::Mutex; use tonic::{async_trait, Request, Response, Status}; use log::info; use crate::database_service::DatabaseService; -use crate::hydra_input::HydraInput; use crate::data_feed_service::random::iterator::RandomDataFeedIterator; use crate::data_feed_service::proto::random_data_feed_server::*; use crate::data_feed_service::proto::Empty; -pub struct RandomDataFeedService<'a> { +pub struct RandomDataFeedService { iterator: RandomDataFeedIterator, - database_service: &'a DatabaseService, + database_service: Arc>, } -impl<'a> RandomDataFeedService<'_> { +impl RandomDataFeedService { pub fn new( - database_service: &'a DatabaseService, + database_service: Arc>, ) -> RandomDataFeedService { RandomDataFeedService { iterator: RandomDataFeedIterator { @@ -29,15 +29,18 @@ impl<'a> RandomDataFeedService<'_> { } #[async_trait] -impl RandomDataFeed for RandomDataFeedService<'static> { +impl RandomDataFeed for RandomDataFeedService { async fn start(&self, _request: Request) -> Result, Status> { self.iterator.is_running.store(true, Ordering::Relaxed); - let iterator = self.iterator; + let mut iterator = self.iterator.clone(); + let database_service = self.database_service.clone(); + tokio::spawn(async move { info!("RandomDataFeedService has started."); - while let Some(message) = iterator.next() { - self.database_service.save(HydraInput::Message(message)); + while let Some(message) = iterator.next().await { + // SHOULD DO: figure out how to handle database save errors better + let _ = database_service.lock().await.save(message).await; } }); diff --git a/hydra_provider/src/data_feed_service/serial/iterator.rs b/hydra_provider/src/data_feed_service/serial/iterator.rs index ac35744c..8ca92f31 100644 --- a/hydra_provider/src/data_feed_service/serial/iterator.rs +++ b/hydra_provider/src/data_feed_service/serial/iterator.rs @@ -1,5 +1,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; +use tokio::sync::Mutex; use messages::mavlink::MavConnection; use postcard::from_bytes; use log::info; @@ -10,25 +11,25 @@ use crate::data_feed_service::proto::SerialDataFeedConfig; use messages::mavlink::uorocketry::MavMessage; +#[derive(Clone)] pub struct SerialDataFeedIterator { pub config: Arc>>, pub mavlink: Arc + Send + Sync>>>>, pub is_running: Arc, } -impl Iterator for SerialDataFeedIterator { - type Item = HydraInput; - - fn next(&mut self) -> Option { +impl SerialDataFeedIterator { + pub async fn next(&mut self) -> Option { if !self.is_running.load(Ordering::Relaxed) { return None; } - let mut mavlink_option = self.mavlink.lock().unwrap(); + + let mavlink_option = self.mavlink.lock().await; if mavlink_option.is_none() { return None; } - let mavlink = mavlink_option.unwrap(); + let mavlink = mavlink_option.as_ref().unwrap(); let (_, mavlink_message) = mavlink.recv().unwrap(); let message = match &mavlink_message { MavMessage::POSTCARD_MESSAGE(data) => { diff --git a/hydra_provider/src/data_feed_service/serial/service.rs b/hydra_provider/src/data_feed_service/serial/service.rs index 1b6ae511..fe3defa7 100644 --- a/hydra_provider/src/data_feed_service/serial/service.rs +++ b/hydra_provider/src/data_feed_service/serial/service.rs @@ -1,5 +1,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; +use tokio::sync::Mutex; use messages::mavlink::connect; use serialport::{available_ports, SerialPortType}; use tonic::{async_trait, Request, Response, Status}; @@ -12,14 +13,15 @@ use crate::data_feed_service::proto::{Empty, ListAvailablePortsResponse, SerialD use messages::mavlink::uorocketry::MavMessage; -pub struct SerialDataFeedService<'a> { +#[derive(Clone)] +pub struct SerialDataFeedService { iterator: SerialDataFeedIterator, - database_service: &'a DatabaseService, + database_service: Arc>, } -impl<'a> SerialDataFeedService<'_> { +impl SerialDataFeedService { pub fn new( - database_service: &'a DatabaseService, + database_service: Arc>, ) -> SerialDataFeedService { SerialDataFeedService { iterator: SerialDataFeedIterator { @@ -33,15 +35,17 @@ impl<'a> SerialDataFeedService<'_> { } #[async_trait] -impl SerialDataFeed for SerialDataFeedService<'static> { +impl SerialDataFeed for SerialDataFeedService { async fn start(&self, _request: Request) -> Result, Status> { self.iterator.is_running.store(true, Ordering::Relaxed); - let iterator = self.iterator; + let mut iterator = self.iterator.clone(); + let database_service = self.database_service.clone(); tokio::spawn(async move { info!("SerialDataFeedService has started."); - while let Some(message) = iterator.next() { - self.database_service.save(message); + while let Some(message) = iterator.next().await { + // SHOULD DO: figure out how to handle database save errors better + let _ = database_service.lock().await.save(message).await; } }); @@ -55,7 +59,7 @@ impl SerialDataFeed for SerialDataFeedService<'static> { async fn list_available_ports( &self, - request: Request + _request: Request ) -> Result, Status> { let ports = available_ports() .unwrap() @@ -75,22 +79,23 @@ impl SerialDataFeed for SerialDataFeedService<'static> { request: Request ) -> Result, Status> { let config = request.into_inner(); - let address = format!("serial:{}:{}", config.port, config.baud_rate).as_str(); - let mut mavlink = self.iterator.mavlink.lock().unwrap(); - *mavlink = Some(connect::(address).unwrap()); + let address = format!("serial:{}:{}", config.port, config.baud_rate); + + let mut mavlink = self.iterator.mavlink.lock().await; + *mavlink = Some(connect::(address.as_str()).unwrap()); Ok(Response::new(Empty {})) } async fn get_status( &self, - request: Request + _request: Request ) -> Result, Status> { Ok(Response::new( SerialDataFeedStatus { is_running : self.iterator.is_running.load(Ordering::Relaxed), - config : self.iterator.config.lock().unwrap().clone(), + config : self.iterator.config.lock().await.clone(), } )) } diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor.rs deleted file mode 100644 index fe68228b..00000000 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor.rs +++ /dev/null @@ -1,21 +0,0 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::Sensor; -use crate::database_service::hydra_input::saveable::SaveableData; - -impl SaveableData for Sensor { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - query!( - "INSERT INTO rocket_sensor_message - (rocket_message_id, component_id) - VALUES ($1, $2)", - rocket_message_id, - self.component_id as i32 - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/air.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/air.rs new file mode 100644 index 00000000..81c204ee --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/air.rs @@ -0,0 +1,27 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::Air; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for Air { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_sensor_air + (rocket_sensor_message_id, time_stamp, status, pressure_abs, altitude, pressure_diff, true_airspeed, air_temperature) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + rocket_message_id, + self.time_stamp as i32, + self.status as i32, + self.pressure_abs as f32, + self.altitude as f32, + self.pressure_diff as f32, + self.true_airspeed as f32, + self.air_temperature as f32, + ) + .execute(&mut **transaction) + .await + } +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav1.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav1.rs new file mode 100644 index 00000000..1c288630 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav1.rs @@ -0,0 +1,27 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::EkfNav1; +use crate::database_service::hydra_input::saveable::SaveableData; +use super::utils::store_3d_vector; + +impl SaveableData for EkfNav1 { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let velocity = store_3d_vector(self.velocity, transaction).await?; + let velocity_std_dev: i32 = store_3d_vector(self.velocity_std_dev, transaction).await?; + query!( + "INSERT INTO rocket_sensor_nav_1 + (rocket_sensor_message_id, time_stamp, velocity, velocity_std_dev) + VALUES ($1, $2, $3, $4)", + rocket_message_id, + self.time_stamp as i32, + velocity, + velocity_std_dev, + ) + .execute(&mut **transaction) + .await + } +} + diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav2.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav2.rs new file mode 100644 index 00000000..caf901d2 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav2.rs @@ -0,0 +1,29 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::EkfNav2; +use crate::database_service::hydra_input::saveable::SaveableData; +use super::utils::store_3d_vector; + +impl SaveableData for EkfNav2 { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let position = store_3d_vector(self.position.map(|x| x as f32), transaction).await?; + let position_std_dev = store_3d_vector(self.position_std_dev, transaction).await?; + + query!( + "INSERT INTO rocket_sensor_nav_2 + (rocket_sensor_message_id, position, position_std_dev, undulation, status) + VALUES ($1, $2, $3, $4, $5)", + rocket_message_id, + position, + position_std_dev, + self.undulation, + self.status as i32, + ) + .execute(&mut **transaction) + .await + } +} + diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_quat.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_quat.rs new file mode 100644 index 00000000..1ebd3c9f --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_quat.rs @@ -0,0 +1,30 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::EkfQuat; +use crate::database_service::hydra_input::saveable::SaveableData; + +use super::utils::{store_3d_vector, store_quaternion}; + +impl SaveableData for EkfQuat { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let euler_std_dev = store_3d_vector(self.euler_std_dev, transaction).await?; + let quaternion = store_quaternion(self.quaternion, transaction).await?; + + query!( + "INSERT INTO rocket_sensor_quat + (rocket_sensor_message_id, time_stamp, quaternion, euler_std_dev, status) + VALUES ($1, $2, $3, $4, $5)", + rocket_message_id, + self.time_stamp as i32, + quaternion, + euler_std_dev, + self.status as i32, + ) + .execute(&mut **transaction) + .await + } +} + diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position1.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position1.rs new file mode 100644 index 00000000..b92a840f --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position1.rs @@ -0,0 +1,29 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::GpsPos1; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for GpsPos1 { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_sensor_gps_pos_1 + (rocket_sensor_message_id, time_stamp, status, time_of_week, latitude, longitude, altitude, undulation) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + rocket_message_id, + self.time_stamp as i32, + self.status as i32, + self.time_of_week as i32, + self.latitude as f32, + self.longitude as f32, + self.altitude as f32, + self.undulation as f32, + + ) + .execute(&mut **transaction) + .await + } +} + diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position2.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position2.rs new file mode 100644 index 00000000..a2ac1d3b --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position2.rs @@ -0,0 +1,27 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::GpsPos2; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for GpsPos2 { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_sensor_gps_pos_2 + (rocket_sensor_message_id, latitude_accuracy, longitude_accuracy, altitude_accuracy, num_sv_used, base_station_id, differential_age) + VALUES ($1, $2, $3, $4, $5, $6, $7)", + rocket_message_id, + self.latitude_accuracy as f32, + self.longitude_accuracy as f32, + self.altitude_accuracy as f32, + self.num_sv_used as i32, + self.base_station_id as i32, + self.differential_age as i32, + ) + .execute(&mut **transaction) + .await + } +} + diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_velocity.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_velocity.rs new file mode 100644 index 00000000..d6cb2bc9 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_velocity.rs @@ -0,0 +1,33 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::GpsVel; +use crate::database_service::hydra_input::saveable::SaveableData; + +use super::utils::store_3d_vector; + +impl SaveableData for GpsVel { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let velocity = store_3d_vector(self.velocity, transaction).await?; + let velocity_acc = store_3d_vector(self.velocity_acc, transaction).await?; + + query!( + "INSERT INTO rocket_sensor_gps_vel + (rocket_sensor_message_id, time_stamp, status, time_of_week, velocity, velocity_acc, course, course_acc) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + rocket_message_id, + self.time_stamp as i32, + self.status as i32, + self.time_of_week as i32, + velocity, + velocity_acc, + self.course as f32, + self.course_acc as f32, + ) + .execute(&mut **transaction) + .await + } +} + diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/imu1.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/imu1.rs new file mode 100644 index 00000000..86f8bdb2 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/imu1.rs @@ -0,0 +1,30 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::Imu1; +use crate::database_service::hydra_input::saveable::SaveableData; + +use super::utils::store_3d_vector; + +impl SaveableData for Imu1 { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let accelerometers = store_3d_vector(self.accelerometers, transaction).await?; + let gyroscopes = store_3d_vector(self.gyroscopes, transaction).await?; + + query!( + "INSERT INTO rocket_sensor_imu_1 + (rocket_sensor_message_id, time_stamp, status, accelerometers, gyroscopes) + VALUES ($1, $2, $3, $4, $5)", + rocket_message_id, + self.time_stamp as i32, + self.status as i32, + accelerometers, + gyroscopes, + ) + .execute(&mut **transaction) + .await + } +} + diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/imu2.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/imu2.rs new file mode 100644 index 00000000..2736ed34 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/imu2.rs @@ -0,0 +1,28 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::Imu2; +use crate::database_service::hydra_input::saveable::SaveableData; + +use super::utils::store_3d_vector; + +impl SaveableData for Imu2 { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let delta_velocity = store_3d_vector(self.delta_velocity, transaction).await?; + let delta_angle = store_3d_vector(self.delta_angle, transaction).await?; + + query!( + "INSERT INTO rocket_sensor_imu_2 + (rocket_sensor_message_id, temperature, delta_velocity, delta_angle) + VALUES ($1, $2, $3, $4)", + rocket_message_id, + self.temperature as f32, + delta_velocity, + delta_angle, + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/mod.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/mod.rs new file mode 100644 index 00000000..d0c801ad --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/mod.rs @@ -0,0 +1,51 @@ +pub mod air; +pub mod ekf_quat; +pub mod utc_time; +pub mod ekf_nav1; +pub mod ekf_nav2; +pub mod imu1; +pub mod imu2; +pub mod gps_velocity; +pub mod gps_position1; +pub mod gps_position2; +pub mod utils; + +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::{Sensor, SensorData}; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for Sensor { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let result = query!( + "INSERT INTO rocket_sensor_message + (rocket_message_id, component_id) + VALUES ($1, $2)", + rocket_message_id, + self.component_id as i32 + ) + .execute(&mut **transaction) + .await; + + if result.is_err() { + return Err(result.err().unwrap()); + } + + match &self.data { + SensorData::UtcTime(data) => data.save(transaction, rocket_message_id).await, + SensorData::Air(data) => data.save(transaction, rocket_message_id).await, + SensorData::EkfQuat(data) => data.save(transaction, rocket_message_id).await, + SensorData::EkfNav1(data) => data.save(transaction, rocket_message_id).await, + SensorData::EkfNav2(data) => data.save(transaction, rocket_message_id).await, + SensorData::Imu1(data) => data.save(transaction, rocket_message_id).await, + SensorData::Imu2(data) => data.save(transaction, rocket_message_id).await, + SensorData::GpsVel(data) => data.save(transaction, rocket_message_id).await, + SensorData::GpsPos1(data) => data.save(transaction, rocket_message_id).await, + SensorData::GpsPos2(data) => data.save(transaction, rocket_message_id).await, + } + } +} + diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/utc_time.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/utc_time.rs new file mode 100644 index 00000000..f475037e --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/utc_time.rs @@ -0,0 +1,30 @@ +use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; +use messages::sensor::UtcTime; +use crate::database_service::hydra_input::saveable::SaveableData; + +impl SaveableData for UtcTime { + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_sensor_utc_time + (rocket_sensor_message_id, time_stamp, status, year, month, day, hour, minute, second, nano_second, gps_time_of_week) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", + rocket_message_id, + self.time_stamp as i32, + self.status as i32, + self.year as i32, + self.month as i32, + self.day as i32, + self.hour as i32, + self.minute as i32, + self.second as i32, + self.nano_second as i32, + self.gps_time_of_week as i32, + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/utils.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/utils.rs new file mode 100644 index 00000000..a8cd1c90 --- /dev/null +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/utils.rs @@ -0,0 +1,40 @@ +use sqlx::{query, Error, Transaction, Postgres}; + +pub async fn store_3d_vector( + vec3: [f32; 3usize], + transaction: &mut Transaction<'_, Postgres>, +) -> Result { + let id = query!( + "INSERT INTO data_vec3 + (x, y, z) + VALUES ($1, $2, $3) RETURNING id", + vec3[0], + vec3[1], + vec3[2] + ) + .fetch_one(&mut **transaction) + .await? + .id; + + return Ok(id); +} + +pub async fn store_quaternion( + vec4: [f32; 4usize], + transaction: &mut Transaction<'_, Postgres>, +) -> Result { + let id = sqlx::query!( + "INSERT INTO data_quaternion + (x, y, z, w) + VALUES ($1, $2, $3, $4) RETURNING id", + vec4[0], + vec4[1], + vec4[2], + vec4[3] + ) + .fetch_one(&mut **transaction) + .await? + .id; + + return Ok(id); +} \ No newline at end of file diff --git a/hydra_provider/src/database_service/service.rs b/hydra_provider/src/database_service/service.rs index 843e9d05..e1090db2 100644 --- a/hydra_provider/src/database_service/service.rs +++ b/hydra_provider/src/database_service/service.rs @@ -15,7 +15,7 @@ impl DatabaseService { } } - pub async fn save(&self, hydra_input: HydraInput) { + pub async fn save(&self, hydra_input: HydraInput) -> Result<(), sqlx::Error> { let mut transaction = self.pool.begin().await.unwrap(); let result = match hydra_input { HydraInput::Heartbeat(message) => message.save(&mut transaction, 0).await, @@ -26,10 +26,12 @@ impl DatabaseService { match result { Ok(_) => transaction.commit().await, Err(error) => { - transaction.rollback().await; - + let rollback_result = transaction.rollback().await; + if rollback_result.is_err() { + return rollback_result; + } Err(error) } - }; + } } } \ No newline at end of file diff --git a/hydra_provider/src/main.rs b/hydra_provider/src/main.rs index 5931699f..98ef28fc 100644 --- a/hydra_provider/src/main.rs +++ b/hydra_provider/src/main.rs @@ -26,10 +26,10 @@ struct CliArgs { } #[tokio::main] -async fn main() { +async fn main() -> Result<(), tonic::transport::Error> { let args = CliArgs::parse(); bootstrap( args.port, args.database_address - ).await; -} \ No newline at end of file + ).await +} From 2de7876ac17e65d4b5e867d829ceeacdf4459ab2 Mon Sep 17 00:00:00 2001 From: Darren Rahnemoon Date: Tue, 19 Mar 2024 12:55:05 -0400 Subject: [PATCH 5/8] feature: logging interceptor --- hydra_provider/.gitignore | 3 +- hydra_provider/Cargo.lock | 62 +++++++++++++++++++++++++++++ hydra_provider/Cargo.toml | 1 + hydra_provider/src/bootstrap.rs | 6 ++- hydra_provider/src/main.rs | 1 + hydra_provider/src/utils/logging.rs | 15 +++++++ hydra_provider/src/utils/mod.rs | 1 + 7 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 hydra_provider/src/utils/logging.rs create mode 100644 hydra_provider/src/utils/mod.rs diff --git a/hydra_provider/.gitignore b/hydra_provider/.gitignore index 9f970225..b7c25b32 100644 --- a/hydra_provider/.gitignore +++ b/hydra_provider/.gitignore @@ -1 +1,2 @@ -target/ \ No newline at end of file +target/ +**/.DS_Store \ No newline at end of file diff --git a/hydra_provider/Cargo.lock b/hydra_provider/Cargo.lock index 66d2c11d..b820c860 100644 --- a/hydra_provider/Cargo.lock +++ b/hydra_provider/Cargo.lock @@ -45,6 +45,21 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.11" @@ -298,6 +313,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.0", +] + [[package]] name = "clap" version = "4.4.18" @@ -931,6 +960,7 @@ name = "hydra_provider" version = "0.1.0" dependencies = [ "anyhow", + "chrono", "clap", "csv", "derive_more", @@ -1001,6 +1031,29 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.5.0" @@ -2876,6 +2929,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/hydra_provider/Cargo.toml b/hydra_provider/Cargo.toml index d44011c5..0ab58243 100644 --- a/hydra_provider/Cargo.toml +++ b/hydra_provider/Cargo.toml @@ -33,3 +33,4 @@ reqwest = { version = "0.11", features = ["blocking", "json"] } rand = "0.8.5" fugit = "0.3.6" csv = "1.2.2" +chrono = "0.4.35" diff --git a/hydra_provider/src/bootstrap.rs b/hydra_provider/src/bootstrap.rs index c0940e9f..04fb04eb 100644 --- a/hydra_provider/src/bootstrap.rs +++ b/hydra_provider/src/bootstrap.rs @@ -6,6 +6,7 @@ use tokio::sync::Mutex; use crate::data_feed_service::serial::{SerialDataFeedService, SerialDataFeedServer}; use crate::data_feed_service::random::{RandomDataFeedService, RandomDataFeedServer}; use crate::database_service::DatabaseService; +use crate::utils::logging::log_request; use tonic::transport::Server; use tonic_health::server::health_reporter; @@ -30,10 +31,11 @@ pub async fn bootstrap( health_reporter.set_serving::>().await; + println!("gRPC Server running at {}", server_address); Server::builder() .add_service(health_server) - .add_service(SerialDataFeedServer::new(serial_data_feed_service)) - .add_service(RandomDataFeedServer::new(random_data_feed_service)) + .add_service(SerialDataFeedServer::with_interceptor(serial_data_feed_service, log_request)) + .add_service(RandomDataFeedServer::with_interceptor(random_data_feed_service, log_request)) .serve(server_address) .await } diff --git a/hydra_provider/src/main.rs b/hydra_provider/src/main.rs index 98ef28fc..a5ffe1bc 100644 --- a/hydra_provider/src/main.rs +++ b/hydra_provider/src/main.rs @@ -3,6 +3,7 @@ mod command_service; mod data_feed_service; mod bootstrap; mod hydra_input; +mod utils; use std::str::FromStr; diff --git a/hydra_provider/src/utils/logging.rs b/hydra_provider/src/utils/logging.rs new file mode 100644 index 00000000..caf5385c --- /dev/null +++ b/hydra_provider/src/utils/logging.rs @@ -0,0 +1,15 @@ +use chrono::Local; +use tonic::{Request, Status}; + + +// Interceptor to log every request received by the server +pub fn log_request(request: Request<()>) -> Result, Status> { + let timestmap = Local::now().format("[%Y-%m-%d][%H:%M:%S]"); + + // SHOULD DO: better logging as Request gRPC method is not shown here + // https://github.com/hyperium/tonic/issues/300 + // https://github.com/hyperium/tonic/issues/430 + + println!("{} Request Received: {:?}", timestmap, request); + Ok(request) +} diff --git a/hydra_provider/src/utils/mod.rs b/hydra_provider/src/utils/mod.rs new file mode 100644 index 00000000..cdb11a39 --- /dev/null +++ b/hydra_provider/src/utils/mod.rs @@ -0,0 +1 @@ +pub mod logging; \ No newline at end of file From 3b5da6332b7ea3cfdda0afa95989fe8d2f214c40 Mon Sep 17 00:00:00 2001 From: Darren Rahnemoon Date: Tue, 19 Mar 2024 13:14:56 -0400 Subject: [PATCH 6/8] chore: add logs --- hydra_provider/src/data_feed_service/random/service.rs | 1 + hydra_provider/src/data_feed_service/serial/service.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/hydra_provider/src/data_feed_service/random/service.rs b/hydra_provider/src/data_feed_service/random/service.rs index 1b60e147..55c3bb16 100644 --- a/hydra_provider/src/data_feed_service/random/service.rs +++ b/hydra_provider/src/data_feed_service/random/service.rs @@ -42,6 +42,7 @@ impl RandomDataFeed for RandomDataFeedService { // SHOULD DO: figure out how to handle database save errors better let _ = database_service.lock().await.save(message).await; } + info!("RandomDataFeedService has stopped."); }); Ok(Response::new(Empty {})) diff --git a/hydra_provider/src/data_feed_service/serial/service.rs b/hydra_provider/src/data_feed_service/serial/service.rs index fe3defa7..90e2ffa1 100644 --- a/hydra_provider/src/data_feed_service/serial/service.rs +++ b/hydra_provider/src/data_feed_service/serial/service.rs @@ -47,6 +47,7 @@ impl SerialDataFeed for SerialDataFeedService { // SHOULD DO: figure out how to handle database save errors better let _ = database_service.lock().await.save(message).await; } + info!("SerialDataFeedService has stopped."); }); Ok(Response::new(Empty {})) From c795ce7b2188b38e6c256566a3f6e4cf0467a57b Mon Sep 17 00:00:00 2001 From: Fernando Nogueira Date: Tue, 19 Mar 2024 18:05:32 -0400 Subject: [PATCH 7/8] chore: remove sqlx files --- hydra_provider/.gitignore | 3 ++- ...34bc1a3046e81a83c677f7bf42bbc369b6ea1.json | 15 ----------- ...15f147dc045573e2ce3aac59840593c516cf1.json | 19 -------------- ...f68405fe4838d5f04f61e86f57c9ee0f56b7f.json | 23 ----------------- ...4570424a53321983af6a6d44c6d73338b8bf9.json | 21 ---------------- ...b8dc6028396369530b716ef4c5a1b5d3acc4c.json | 20 --------------- ...1c4c270ee2f4f3d37722ee640950c4b75bad9.json | 17 ------------- ...09bb566b379c29961130a89990b6953fa0951.json | 24 ------------------ ...c7b6ebadd3e3014f065493d1b93c14490fc15.json | 20 --------------- ...f90cd50edc7f726b255341859313e67655d06.json | 15 ----------- ...53b02e5a5fe423f9a8e25fe7120bbe9a27638.json | 15 ----------- ...a2e4faaa7bb86fb17b51b9f1d412ca2f5897b.json | 25 ------------------- ...a4233bef2f53ac63344ea829e1536ad4ba45d.json | 24 ------------------ ...c989357eb728615dcb9fd1fe6791cf8816daa.json | 18 ------------- ...8817c5aaafaf4ee5b1f8bba44cdac2cb2040b.json | 15 ----------- ...bf6852d409f9432641ce21177f71240375d41.json | 15 ----------- ...8bdf537b7878fc7a7cd4690c8a8ee5578ced0.json | 15 ----------- ...360c79431680f5f4ee753f1dd06043fb9a903.json | 14 ----------- ...d73b5f81d82ab64e647f40f2708aeb920d23c.json | 18 ------------- ...85593f9fddbb3af16b1f5b26e12c22a2b4049.json | 24 ------------------ ...bd11cdfb559437ba39f8f12aeee35b9ac37fa.json | 16 ------------ ...a0ee02595f6281f5f52940444da015b150ad2.json | 18 ------------- ...e53c7736a2808eef2471478785f86cfbe250a.json | 21 ---------------- ...95332c641a970f1d03a4bbac58fd8db12d09d.json | 15 ----------- ...f7cae449d0ca29d3dcc9d930e9e19afe0f98c.json | 17 ------------- ...26ebe851c4360daed8da105ed984b506896ff.json | 21 ---------------- hydra_provider/README.md | 3 ++- 27 files changed, 4 insertions(+), 467 deletions(-) delete mode 100644 hydra_provider/.sqlx/query-04ace0b597474fd8b87231f12bd34bc1a3046e81a83c677f7bf42bbc369b6ea1.json delete mode 100644 hydra_provider/.sqlx/query-0592362f0cab8d03798f22c9a4315f147dc045573e2ce3aac59840593c516cf1.json delete mode 100644 hydra_provider/.sqlx/query-0c9b8a10dede6da739fb6905db6f68405fe4838d5f04f61e86f57c9ee0f56b7f.json delete mode 100644 hydra_provider/.sqlx/query-215500742549b342265d45e23484570424a53321983af6a6d44c6d73338b8bf9.json delete mode 100644 hydra_provider/.sqlx/query-25e634cfa9050fe14a9ca15940cb8dc6028396369530b716ef4c5a1b5d3acc4c.json delete mode 100644 hydra_provider/.sqlx/query-2799f3d8d88ac5304ea6ce1277c1c4c270ee2f4f3d37722ee640950c4b75bad9.json delete mode 100644 hydra_provider/.sqlx/query-31a8a18c07ac6cedf1fb51be91609bb566b379c29961130a89990b6953fa0951.json delete mode 100644 hydra_provider/.sqlx/query-35ba26a012ffa38583280f8385dc7b6ebadd3e3014f065493d1b93c14490fc15.json delete mode 100644 hydra_provider/.sqlx/query-3b105ffe675b9be036e0e66467ef90cd50edc7f726b255341859313e67655d06.json delete mode 100644 hydra_provider/.sqlx/query-438ca942a50eeb62bd5201761dc53b02e5a5fe423f9a8e25fe7120bbe9a27638.json delete mode 100644 hydra_provider/.sqlx/query-4d1161756549a3984f39713fc20a2e4faaa7bb86fb17b51b9f1d412ca2f5897b.json delete mode 100644 hydra_provider/.sqlx/query-66526c1b942842e10b2f903a82ea4233bef2f53ac63344ea829e1536ad4ba45d.json delete mode 100644 hydra_provider/.sqlx/query-6a008ef7be44c024bdb5c1d297ac989357eb728615dcb9fd1fe6791cf8816daa.json delete mode 100644 hydra_provider/.sqlx/query-769508703a027a73f2bc0f393e88817c5aaafaf4ee5b1f8bba44cdac2cb2040b.json delete mode 100644 hydra_provider/.sqlx/query-79053d7218175d971a732e2c606bf6852d409f9432641ce21177f71240375d41.json delete mode 100644 hydra_provider/.sqlx/query-7a240b30af0bbacb93856b09a838bdf537b7878fc7a7cd4690c8a8ee5578ced0.json delete mode 100644 hydra_provider/.sqlx/query-860b21e9726795d654a046117f6360c79431680f5f4ee753f1dd06043fb9a903.json delete mode 100644 hydra_provider/.sqlx/query-9323f9ba9042047b644aa1d9593d73b5f81d82ab64e647f40f2708aeb920d23c.json delete mode 100644 hydra_provider/.sqlx/query-95cd3b1a259fc1569c7d5c85ceb85593f9fddbb3af16b1f5b26e12c22a2b4049.json delete mode 100644 hydra_provider/.sqlx/query-9ab63ca023ddf8b83bf04f7bbdfbd11cdfb559437ba39f8f12aeee35b9ac37fa.json delete mode 100644 hydra_provider/.sqlx/query-a63c7ecfa595c504834e8fb4632a0ee02595f6281f5f52940444da015b150ad2.json delete mode 100644 hydra_provider/.sqlx/query-c2eb1b9a4e661d432cb2dbe9cc0e53c7736a2808eef2471478785f86cfbe250a.json delete mode 100644 hydra_provider/.sqlx/query-ce0f4248b40e7ffb6a8da861f0795332c641a970f1d03a4bbac58fd8db12d09d.json delete mode 100644 hydra_provider/.sqlx/query-e84c0893c6da2489dfa72be456ff7cae449d0ca29d3dcc9d930e9e19afe0f98c.json delete mode 100644 hydra_provider/.sqlx/query-fff5103c073e16107d80dfb757126ebe851c4360daed8da105ed984b506896ff.json diff --git a/hydra_provider/.gitignore b/hydra_provider/.gitignore index b7c25b32..bbb8b164 100644 --- a/hydra_provider/.gitignore +++ b/hydra_provider/.gitignore @@ -1,2 +1,3 @@ target/ -**/.DS_Store \ No newline at end of file +**/.DS_Store +.sqlx/ diff --git a/hydra_provider/.sqlx/query-04ace0b597474fd8b87231f12bd34bc1a3046e81a83c677f7bf42bbc369b6ea1.json b/hydra_provider/.sqlx/query-04ace0b597474fd8b87231f12bd34bc1a3046e81a83c677f7bf42bbc369b6ea1.json deleted file mode 100644 index faeb067e..00000000 --- a/hydra_provider/.sqlx/query-04ace0b597474fd8b87231f12bd34bc1a3046e81a83c677f7bf42bbc369b6ea1.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_deploy_drogue_command\n (rocket_command_id, val)\n VALUES ($1, $2)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Bool" - ] - }, - "nullable": [] - }, - "hash": "04ace0b597474fd8b87231f12bd34bc1a3046e81a83c677f7bf42bbc369b6ea1" -} diff --git a/hydra_provider/.sqlx/query-0592362f0cab8d03798f22c9a4315f147dc045573e2ce3aac59840593c516cf1.json b/hydra_provider/.sqlx/query-0592362f0cab8d03798f22c9a4315f147dc045573e2ce3aac59840593c516cf1.json deleted file mode 100644 index b4be1593..00000000 --- a/hydra_provider/.sqlx/query-0592362f0cab8d03798f22c9a4315f147dc045573e2ce3aac59840593c516cf1.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_heartbeat\n (custom_mode, mavtype, autopilot, base_mode, system_status, mavlink_version)\n VALUES ($1, $2, $3, $4, $5, $6)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "0592362f0cab8d03798f22c9a4315f147dc045573e2ce3aac59840593c516cf1" -} diff --git a/hydra_provider/.sqlx/query-0c9b8a10dede6da739fb6905db6f68405fe4838d5f04f61e86f57c9ee0f56b7f.json b/hydra_provider/.sqlx/query-0c9b8a10dede6da739fb6905db6f68405fe4838d5f04f61e86f57c9ee0f56b7f.json deleted file mode 100644 index e7c4f916..00000000 --- a/hydra_provider/.sqlx/query-0c9b8a10dede6da739fb6905db6f68405fe4838d5f04f61e86f57c9ee0f56b7f.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_health_status\n (rocket_health_id, v5, v3_3, pyro_sense, vcc_sense, int_v5, int_v3_3, ext_v5, ext_3v3, failover_sense)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "0c9b8a10dede6da739fb6905db6f68405fe4838d5f04f61e86f57c9ee0f56b7f" -} diff --git a/hydra_provider/.sqlx/query-215500742549b342265d45e23484570424a53321983af6a6d44c6d73338b8bf9.json b/hydra_provider/.sqlx/query-215500742549b342265d45e23484570424a53321983af6a6d44c6d73338b8bf9.json deleted file mode 100644 index 5f58c5d8..00000000 --- a/hydra_provider/.sqlx/query-215500742549b342265d45e23484570424a53321983af6a6d44c6d73338b8bf9.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_air\n (rocket_sensor_message_id, time_stamp, status, pressure_abs, altitude, pressure_diff, true_airspeed, air_temperature)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Float4", - "Float4", - "Float4", - "Float4", - "Float4" - ] - }, - "nullable": [] - }, - "hash": "215500742549b342265d45e23484570424a53321983af6a6d44c6d73338b8bf9" -} diff --git a/hydra_provider/.sqlx/query-25e634cfa9050fe14a9ca15940cb8dc6028396369530b716ef4c5a1b5d3acc4c.json b/hydra_provider/.sqlx/query-25e634cfa9050fe14a9ca15940cb8dc6028396369530b716ef4c5a1b5d3acc4c.json deleted file mode 100644 index ae0f88ce..00000000 --- a/hydra_provider/.sqlx/query-25e634cfa9050fe14a9ca15940cb8dc6028396369530b716ef4c5a1b5d3acc4c.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_radio_status \n (rxerrors, fixed, rssi, remrssi, txbuf, noise, remnoise) \n VALUES ($1, $2, $3, $4, $5, $6, $7)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "25e634cfa9050fe14a9ca15940cb8dc6028396369530b716ef4c5a1b5d3acc4c" -} diff --git a/hydra_provider/.sqlx/query-2799f3d8d88ac5304ea6ce1277c1c4c270ee2f4f3d37722ee640950c4b75bad9.json b/hydra_provider/.sqlx/query-2799f3d8d88ac5304ea6ce1277c1c4c270ee2f4f3d37722ee640950c4b75bad9.json deleted file mode 100644 index fc0c7c41..00000000 --- a/hydra_provider/.sqlx/query-2799f3d8d88ac5304ea6ce1277c1c4c270ee2f4f3d37722ee640950c4b75bad9.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_imu_2\n (rocket_sensor_message_id, temperature, delta_velocity, delta_angle)\n VALUES ($1, $2, $3, $4)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Float4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "2799f3d8d88ac5304ea6ce1277c1c4c270ee2f4f3d37722ee640950c4b75bad9" -} diff --git a/hydra_provider/.sqlx/query-31a8a18c07ac6cedf1fb51be91609bb566b379c29961130a89990b6953fa0951.json b/hydra_provider/.sqlx/query-31a8a18c07ac6cedf1fb51be91609bb566b379c29961130a89990b6953fa0951.json deleted file mode 100644 index 91a6e518..00000000 --- a/hydra_provider/.sqlx/query-31a8a18c07ac6cedf1fb51be91609bb566b379c29961130a89990b6953fa0951.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_message\n (time_stamp, sender, message_type)\n VALUES ($1, $2, $3)\n RETURNING id", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Int4", - "Text", - "Text" - ] - }, - "nullable": [ - false - ] - }, - "hash": "31a8a18c07ac6cedf1fb51be91609bb566b379c29961130a89990b6953fa0951" -} diff --git a/hydra_provider/.sqlx/query-35ba26a012ffa38583280f8385dc7b6ebadd3e3014f065493d1b93c14490fc15.json b/hydra_provider/.sqlx/query-35ba26a012ffa38583280f8385dc7b6ebadd3e3014f065493d1b93c14490fc15.json deleted file mode 100644 index c5370957..00000000 --- a/hydra_provider/.sqlx/query-35ba26a012ffa38583280f8385dc7b6ebadd3e3014f065493d1b93c14490fc15.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_gps_pos_2\n (rocket_sensor_message_id, latitude_accuracy, longitude_accuracy, altitude_accuracy, num_sv_used, base_station_id, differential_age)\n VALUES ($1, $2, $3, $4, $5, $6, $7)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Float4", - "Float4", - "Float4", - "Int4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "35ba26a012ffa38583280f8385dc7b6ebadd3e3014f065493d1b93c14490fc15" -} diff --git a/hydra_provider/.sqlx/query-3b105ffe675b9be036e0e66467ef90cd50edc7f726b255341859313e67655d06.json b/hydra_provider/.sqlx/query-3b105ffe675b9be036e0e66467ef90cd50edc7f726b255341859313e67655d06.json deleted file mode 100644 index 9d7913b3..00000000 --- a/hydra_provider/.sqlx/query-3b105ffe675b9be036e0e66467ef90cd50edc7f726b255341859313e67655d06.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_state\n (rocket_message_id, state)\n VALUES ($1, $2)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Text" - ] - }, - "nullable": [] - }, - "hash": "3b105ffe675b9be036e0e66467ef90cd50edc7f726b255341859313e67655d06" -} diff --git a/hydra_provider/.sqlx/query-438ca942a50eeb62bd5201761dc53b02e5a5fe423f9a8e25fe7120bbe9a27638.json b/hydra_provider/.sqlx/query-438ca942a50eeb62bd5201761dc53b02e5a5fe423f9a8e25fe7120bbe9a27638.json deleted file mode 100644 index 3220b5f0..00000000 --- a/hydra_provider/.sqlx/query-438ca942a50eeb62bd5201761dc53b02e5a5fe423f9a8e25fe7120bbe9a27638.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_message\n (rocket_message_id, component_id)\n VALUES ($1, $2)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "438ca942a50eeb62bd5201761dc53b02e5a5fe423f9a8e25fe7120bbe9a27638" -} diff --git a/hydra_provider/.sqlx/query-4d1161756549a3984f39713fc20a2e4faaa7bb86fb17b51b9f1d412ca2f5897b.json b/hydra_provider/.sqlx/query-4d1161756549a3984f39713fc20a2e4faaa7bb86fb17b51b9f1d412ca2f5897b.json deleted file mode 100644 index 5624fbf1..00000000 --- a/hydra_provider/.sqlx/query-4d1161756549a3984f39713fc20a2e4faaa7bb86fb17b51b9f1d412ca2f5897b.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO data_quaternion\n (x, y, z, w)\n VALUES ($1, $2, $3, $4) RETURNING id", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Float4", - "Float4", - "Float4", - "Float4" - ] - }, - "nullable": [ - false - ] - }, - "hash": "4d1161756549a3984f39713fc20a2e4faaa7bb86fb17b51b9f1d412ca2f5897b" -} diff --git a/hydra_provider/.sqlx/query-66526c1b942842e10b2f903a82ea4233bef2f53ac63344ea829e1536ad4ba45d.json b/hydra_provider/.sqlx/query-66526c1b942842e10b2f903a82ea4233bef2f53ac63344ea829e1536ad4ba45d.json deleted file mode 100644 index fc217a57..00000000 --- a/hydra_provider/.sqlx/query-66526c1b942842e10b2f903a82ea4233bef2f53ac63344ea829e1536ad4ba45d.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_utc_time\n (rocket_sensor_message_id, time_stamp, status, year, month, day, hour, minute, second, nano_second, gps_time_of_week)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "66526c1b942842e10b2f903a82ea4233bef2f53ac63344ea829e1536ad4ba45d" -} diff --git a/hydra_provider/.sqlx/query-6a008ef7be44c024bdb5c1d297ac989357eb728615dcb9fd1fe6791cf8816daa.json b/hydra_provider/.sqlx/query-6a008ef7be44c024bdb5c1d297ac989357eb728615dcb9fd1fe6791cf8816daa.json deleted file mode 100644 index ce77d37f..00000000 --- a/hydra_provider/.sqlx/query-6a008ef7be44c024bdb5c1d297ac989357eb728615dcb9fd1fe6791cf8816daa.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_quat\n (rocket_sensor_message_id, time_stamp, quaternion, euler_std_dev, status)\n VALUES ($1, $2, $3, $4, $5)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "6a008ef7be44c024bdb5c1d297ac989357eb728615dcb9fd1fe6791cf8816daa" -} diff --git a/hydra_provider/.sqlx/query-769508703a027a73f2bc0f393e88817c5aaafaf4ee5b1f8bba44cdac2cb2040b.json b/hydra_provider/.sqlx/query-769508703a027a73f2bc0f393e88817c5aaafaf4ee5b1f8bba44cdac2cb2040b.json deleted file mode 100644 index b7971128..00000000 --- a/hydra_provider/.sqlx/query-769508703a027a73f2bc0f393e88817c5aaafaf4ee5b1f8bba44cdac2cb2040b.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_health\n (rocket_message_id, status)\n VALUES ($1, $2)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Text" - ] - }, - "nullable": [] - }, - "hash": "769508703a027a73f2bc0f393e88817c5aaafaf4ee5b1f8bba44cdac2cb2040b" -} diff --git a/hydra_provider/.sqlx/query-79053d7218175d971a732e2c606bf6852d409f9432641ce21177f71240375d41.json b/hydra_provider/.sqlx/query-79053d7218175d971a732e2c606bf6852d409f9432641ce21177f71240375d41.json deleted file mode 100644 index 3ef341fb..00000000 --- a/hydra_provider/.sqlx/query-79053d7218175d971a732e2c606bf6852d409f9432641ce21177f71240375d41.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_power_down_command\n (rocket_command_id, board)\n VALUES ($1, $2)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Text" - ] - }, - "nullable": [] - }, - "hash": "79053d7218175d971a732e2c606bf6852d409f9432641ce21177f71240375d41" -} diff --git a/hydra_provider/.sqlx/query-7a240b30af0bbacb93856b09a838bdf537b7878fc7a7cd4690c8a8ee5578ced0.json b/hydra_provider/.sqlx/query-7a240b30af0bbacb93856b09a838bdf537b7878fc7a7cd4690c8a8ee5578ced0.json deleted file mode 100644 index 94fa5ce6..00000000 --- a/hydra_provider/.sqlx/query-7a240b30af0bbacb93856b09a838bdf537b7878fc7a7cd4690c8a8ee5578ced0.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_deploy_main_command\n (rocket_command_id, val)\n VALUES ($1, $2)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Bool" - ] - }, - "nullable": [] - }, - "hash": "7a240b30af0bbacb93856b09a838bdf537b7878fc7a7cd4690c8a8ee5578ced0" -} diff --git a/hydra_provider/.sqlx/query-860b21e9726795d654a046117f6360c79431680f5f4ee753f1dd06043fb9a903.json b/hydra_provider/.sqlx/query-860b21e9726795d654a046117f6360c79431680f5f4ee753f1dd06043fb9a903.json deleted file mode 100644 index 14963951..00000000 --- a/hydra_provider/.sqlx/query-860b21e9726795d654a046117f6360c79431680f5f4ee753f1dd06043fb9a903.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_command\n (rocket_message_id)\n VALUES ($1)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [] - }, - "hash": "860b21e9726795d654a046117f6360c79431680f5f4ee753f1dd06043fb9a903" -} diff --git a/hydra_provider/.sqlx/query-9323f9ba9042047b644aa1d9593d73b5f81d82ab64e647f40f2708aeb920d23c.json b/hydra_provider/.sqlx/query-9323f9ba9042047b644aa1d9593d73b5f81d82ab64e647f40f2708aeb920d23c.json deleted file mode 100644 index 532bd92d..00000000 --- a/hydra_provider/.sqlx/query-9323f9ba9042047b644aa1d9593d73b5f81d82ab64e647f40f2708aeb920d23c.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_nav_2\n (rocket_sensor_message_id, position, position_std_dev, undulation, status)\n VALUES ($1, $2, $3, $4, $5)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Float4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "9323f9ba9042047b644aa1d9593d73b5f81d82ab64e647f40f2708aeb920d23c" -} diff --git a/hydra_provider/.sqlx/query-95cd3b1a259fc1569c7d5c85ceb85593f9fddbb3af16b1f5b26e12c22a2b4049.json b/hydra_provider/.sqlx/query-95cd3b1a259fc1569c7d5c85ceb85593f9fddbb3af16b1f5b26e12c22a2b4049.json deleted file mode 100644 index 53f0b53a..00000000 --- a/hydra_provider/.sqlx/query-95cd3b1a259fc1569c7d5c85ceb85593f9fddbb3af16b1f5b26e12c22a2b4049.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO data_vec3\n (x, y, z)\n VALUES ($1, $2, $3) RETURNING id", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Float4", - "Float4", - "Float4" - ] - }, - "nullable": [ - false - ] - }, - "hash": "95cd3b1a259fc1569c7d5c85ceb85593f9fddbb3af16b1f5b26e12c22a2b4049" -} diff --git a/hydra_provider/.sqlx/query-9ab63ca023ddf8b83bf04f7bbdfbd11cdfb559437ba39f8f12aeee35b9ac37fa.json b/hydra_provider/.sqlx/query-9ab63ca023ddf8b83bf04f7bbdfbd11cdfb559437ba39f8f12aeee35b9ac37fa.json deleted file mode 100644 index 3c8448e6..00000000 --- a/hydra_provider/.sqlx/query-9ab63ca023ddf8b83bf04f7bbdfbd11cdfb559437ba39f8f12aeee35b9ac37fa.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_log\n (rocket_message_id, level, event)\n VALUES ($1, $2, $3)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "9ab63ca023ddf8b83bf04f7bbdfbd11cdfb559437ba39f8f12aeee35b9ac37fa" -} diff --git a/hydra_provider/.sqlx/query-a63c7ecfa595c504834e8fb4632a0ee02595f6281f5f52940444da015b150ad2.json b/hydra_provider/.sqlx/query-a63c7ecfa595c504834e8fb4632a0ee02595f6281f5f52940444da015b150ad2.json deleted file mode 100644 index a92ef320..00000000 --- a/hydra_provider/.sqlx/query-a63c7ecfa595c504834e8fb4632a0ee02595f6281f5f52940444da015b150ad2.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_imu_1\n (rocket_sensor_message_id, time_stamp, status, accelerometers, gyroscopes)\n VALUES ($1, $2, $3, $4, $5)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "a63c7ecfa595c504834e8fb4632a0ee02595f6281f5f52940444da015b150ad2" -} diff --git a/hydra_provider/.sqlx/query-c2eb1b9a4e661d432cb2dbe9cc0e53c7736a2808eef2471478785f86cfbe250a.json b/hydra_provider/.sqlx/query-c2eb1b9a4e661d432cb2dbe9cc0e53c7736a2808eef2471478785f86cfbe250a.json deleted file mode 100644 index dcb12267..00000000 --- a/hydra_provider/.sqlx/query-c2eb1b9a4e661d432cb2dbe9cc0e53c7736a2808eef2471478785f86cfbe250a.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_gps_vel\n (rocket_sensor_message_id, time_stamp, status, time_of_week, velocity, velocity_acc, course, course_acc)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Int4", - "Float4", - "Float4" - ] - }, - "nullable": [] - }, - "hash": "c2eb1b9a4e661d432cb2dbe9cc0e53c7736a2808eef2471478785f86cfbe250a" -} diff --git a/hydra_provider/.sqlx/query-ce0f4248b40e7ffb6a8da861f0795332c641a970f1d03a4bbac58fd8db12d09d.json b/hydra_provider/.sqlx/query-ce0f4248b40e7ffb6a8da861f0795332c641a970f1d03a4bbac58fd8db12d09d.json deleted file mode 100644 index 100e98b3..00000000 --- a/hydra_provider/.sqlx/query-ce0f4248b40e7ffb6a8da861f0795332c641a970f1d03a4bbac58fd8db12d09d.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_radio_rate_change_command\n (rocket_command_id, rate)\n VALUES ($1, $2)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Text" - ] - }, - "nullable": [] - }, - "hash": "ce0f4248b40e7ffb6a8da861f0795332c641a970f1d03a4bbac58fd8db12d09d" -} diff --git a/hydra_provider/.sqlx/query-e84c0893c6da2489dfa72be456ff7cae449d0ca29d3dcc9d930e9e19afe0f98c.json b/hydra_provider/.sqlx/query-e84c0893c6da2489dfa72be456ff7cae449d0ca29d3dcc9d930e9e19afe0f98c.json deleted file mode 100644 index 07e6dfac..00000000 --- a/hydra_provider/.sqlx/query-e84c0893c6da2489dfa72be456ff7cae449d0ca29d3dcc9d930e9e19afe0f98c.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_nav_1\n (rocket_sensor_message_id, time_stamp, velocity, velocity_std_dev)\n VALUES ($1, $2, $3, $4)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "e84c0893c6da2489dfa72be456ff7cae449d0ca29d3dcc9d930e9e19afe0f98c" -} diff --git a/hydra_provider/.sqlx/query-fff5103c073e16107d80dfb757126ebe851c4360daed8da105ed984b506896ff.json b/hydra_provider/.sqlx/query-fff5103c073e16107d80dfb757126ebe851c4360daed8da105ed984b506896ff.json deleted file mode 100644 index e56b2650..00000000 --- a/hydra_provider/.sqlx/query-fff5103c073e16107d80dfb757126ebe851c4360daed8da105ed984b506896ff.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO rocket_sensor_gps_pos_1\n (rocket_sensor_message_id, time_stamp, status, time_of_week, latitude, longitude, altitude, undulation)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Int4", - "Int4", - "Float4", - "Float4", - "Float4", - "Float4" - ] - }, - "nullable": [] - }, - "hash": "fff5103c073e16107d80dfb757126ebe851c4360daed8da105ed984b506896ff" -} diff --git a/hydra_provider/README.md b/hydra_provider/README.md index a13cb6a3..9c51ef52 100644 --- a/hydra_provider/README.md +++ b/hydra_provider/README.md @@ -23,8 +23,9 @@ cargo run -- -p 3001 # Use "cargo run -- --help" for more options ``` -This project uses SQLX to type check SQL queries. To build this project without the database running you can add a `SQLX_OFFLINE=tru` environment variable +This project uses SQLX to type check SQL queries. If by any reason you need to work with the database offline, you can first run `cargo sqlx prepare` with the database running. Alternativelly, you can set a `SQLX_OFFLINE` environment variable to `true`. ```bash +cargo sqlx prepare SQLX_OFFLINE=true cargo build ``` From 146628d0bd9c0e7858e02badcb3d4057dbfe4a3c Mon Sep 17 00:00:00 2001 From: Darren Rahnemoon Date: Tue, 19 Mar 2024 19:51:10 -0400 Subject: [PATCH 8/8] chore: lint --- hydra_provider/build.rs | 12 +- hydra_provider/src/bootstrap.rs | 49 +-- .../command_service/commands/deploy_drogue.rs | 8 +- .../command_service/commands/deploy_main.rs | 8 +- .../src/command_service/commands/mod.rs | 4 +- .../command_service/commands/power_down.rs | 8 +- .../src/command_service/commands/sendable.rs | 4 +- hydra_provider/src/command_service/mod.rs | 2 +- hydra_provider/src/command_service/service.rs | 8 +- hydra_provider/src/data_feed_service/mod.rs | 2 +- .../src/data_feed_service/random/iterator.rs | 351 +++++++++--------- .../src/data_feed_service/random/mod.rs | 6 +- .../src/data_feed_service/random/service.rs | 70 ++-- .../src/data_feed_service/serial/iterator.rs | 68 ++-- .../src/data_feed_service/serial/mod.rs | 4 +- .../src/data_feed_service/serial/service.rs | 142 ++++--- .../hydra_input/heart_beat.rs | 38 +- .../messages/command/deploy_drogue.rs | 32 +- .../messages/command/deploy_main.rs | 32 +- .../hydra_input/messages/command/mod.rs | 48 +-- .../messages/command/power_down.rs | 32 +- .../messages/command/radio_rate_change.rs | 32 +- .../hydra_input/messages/health.rs | 58 +-- .../hydra_input/messages/log.rs | 34 +- .../hydra_input/messages/mod.rs | 74 ++-- .../hydra_input/messages/sensor/air.rs | 20 +- .../hydra_input/messages/sensor/ekf_nav1.rs | 41 +- .../hydra_input/messages/sensor/ekf_nav2.rs | 43 ++- .../hydra_input/messages/sensor/ekf_quat.rs | 41 +- .../messages/sensor/gps_position1.rs | 19 +- .../messages/sensor/gps_position2.rs | 19 +- .../messages/sensor/gps_velocity.rs | 23 +- .../hydra_input/messages/sensor/imu1.rs | 43 ++- .../hydra_input/messages/sensor/imu2.rs | 38 +- .../hydra_input/messages/sensor/mod.rs | 71 ++-- .../hydra_input/messages/sensor/utc_time.rs | 18 +- .../hydra_input/messages/sensor/utils.rs | 54 +-- .../hydra_input/messages/state.rs | 32 +- .../src/database_service/hydra_input/mod.rs | 4 +- .../hydra_input/radio_status.rs | 40 +- .../database_service/hydra_input/saveable.rs | 9 +- hydra_provider/src/database_service/mod.rs | 4 +- .../src/database_service/service.rs | 54 +-- hydra_provider/src/hydra_input.rs | 8 +- hydra_provider/src/main.rs | 23 +- hydra_provider/src/utils/logging.rs | 13 +- hydra_provider/src/utils/mod.rs | 2 +- 47 files changed, 870 insertions(+), 875 deletions(-) diff --git a/hydra_provider/build.rs b/hydra_provider/build.rs index dd80f029..cff7ff79 100644 --- a/hydra_provider/build.rs +++ b/hydra_provider/build.rs @@ -1,12 +1,10 @@ fn main() { // Define .proto files that need to get compiled here // No need to compile health.proto as its provided by tonic - let protos = [ - "proto/data_feed.proto", - ]; + let protos = ["proto/data_feed.proto"]; - tonic_build::configure() - .build_server(true) - .compile(&protos, &["."]) - .unwrap_or_else(|error| panic!("Failed to compile {:?}", error)); + tonic_build::configure() + .build_server(true) + .compile(&protos, &["."]) + .unwrap_or_else(|error| panic!("Failed to compile {:?}", error)); } diff --git a/hydra_provider/src/bootstrap.rs b/hydra_provider/src/bootstrap.rs index 04fb04eb..1a09fc71 100644 --- a/hydra_provider/src/bootstrap.rs +++ b/hydra_provider/src/bootstrap.rs @@ -3,39 +3,46 @@ use std::sync::Arc; use tokio::sync::Mutex; // use crate::commands::service::CommandService; -use crate::data_feed_service::serial::{SerialDataFeedService, SerialDataFeedServer}; -use crate::data_feed_service::random::{RandomDataFeedService, RandomDataFeedServer}; +use crate::data_feed_service::random::{RandomDataFeedServer, RandomDataFeedService}; +use crate::data_feed_service::serial::{SerialDataFeedServer, SerialDataFeedService}; use crate::database_service::DatabaseService; use crate::utils::logging::log_request; use tonic::transport::Server; -use tonic_health::server::health_reporter; use tonic_health::pb::health_server::HealthServer; +use tonic_health::server::health_reporter; use tonic_health::server::HealthService; // Sets up the gRPC server and loads relevant services pub async fn bootstrap( - server_port: u32, - database_address: String, + server_port: u32, + database_address: String, ) -> Result<(), tonic::transport::Error> { - let server_address: SocketAddr = format!("[::1]:{}", server_port).parse().unwrap(); + let server_address: SocketAddr = format!("[::1]:{}", server_port).parse().unwrap(); - let database_service = Arc::new(Mutex::new(DatabaseService::new(&database_address.as_str()).await)); - let serial_data_feed_service = SerialDataFeedService::new(database_service.clone()); - let random_data_feed_service = RandomDataFeedService::new(database_service.clone()); + let database_service = Arc::new(Mutex::new( + DatabaseService::new(&database_address.as_str()).await, + )); + let serial_data_feed_service = SerialDataFeedService::new(database_service.clone()); + let random_data_feed_service = RandomDataFeedService::new(database_service.clone()); - let ( - mut health_reporter, - health_server - ) = health_reporter(); + let (mut health_reporter, health_server) = health_reporter(); - health_reporter.set_serving::>().await; + health_reporter + .set_serving::>() + .await; - println!("gRPC Server running at {}", server_address); - Server::builder() - .add_service(health_server) - .add_service(SerialDataFeedServer::with_interceptor(serial_data_feed_service, log_request)) - .add_service(RandomDataFeedServer::with_interceptor(random_data_feed_service, log_request)) - .serve(server_address) - .await + println!("gRPC Server running at {}", server_address); + Server::builder() + .add_service(health_server) + .add_service(SerialDataFeedServer::with_interceptor( + serial_data_feed_service, + log_request, + )) + .add_service(RandomDataFeedServer::with_interceptor( + random_data_feed_service, + log_request, + )) + .serve(server_address) + .await } diff --git a/hydra_provider/src/command_service/commands/deploy_drogue.rs b/hydra_provider/src/command_service/commands/deploy_drogue.rs index a588925a..c2985e73 100644 --- a/hydra_provider/src/command_service/commands/deploy_drogue.rs +++ b/hydra_provider/src/command_service/commands/deploy_drogue.rs @@ -2,7 +2,7 @@ use super::sendable::Sendable; use messages::command::DeployDrogue; impl Sendable for DeployDrogue { - fn send() { - println!("DeployDrogue was called.") - } -} \ No newline at end of file + fn send() { + println!("DeployDrogue was called.") + } +} diff --git a/hydra_provider/src/command_service/commands/deploy_main.rs b/hydra_provider/src/command_service/commands/deploy_main.rs index f484128b..15ef61e8 100644 --- a/hydra_provider/src/command_service/commands/deploy_main.rs +++ b/hydra_provider/src/command_service/commands/deploy_main.rs @@ -2,7 +2,7 @@ use super::sendable::Sendable; use messages::command::DeployMain; impl Sendable for DeployMain { - fn send() { - println!("DeployMain was called.") - } -} \ No newline at end of file + fn send() { + println!("DeployMain was called.") + } +} diff --git a/hydra_provider/src/command_service/commands/mod.rs b/hydra_provider/src/command_service/commands/mod.rs index 22ac5d8f..40549554 100644 --- a/hydra_provider/src/command_service/commands/mod.rs +++ b/hydra_provider/src/command_service/commands/mod.rs @@ -1,4 +1,4 @@ -pub mod sendable; -pub mod deploy_main; pub mod deploy_drogue; +pub mod deploy_main; pub mod power_down; +pub mod sendable; diff --git a/hydra_provider/src/command_service/commands/power_down.rs b/hydra_provider/src/command_service/commands/power_down.rs index 804892b8..386c3aa4 100644 --- a/hydra_provider/src/command_service/commands/power_down.rs +++ b/hydra_provider/src/command_service/commands/power_down.rs @@ -2,7 +2,7 @@ use super::sendable::Sendable; use messages::command::PowerDown; impl Sendable for PowerDown { - fn send() { - println!("PowerDown was called.") - } -} \ No newline at end of file + fn send() { + println!("PowerDown was called.") + } +} diff --git a/hydra_provider/src/command_service/commands/sendable.rs b/hydra_provider/src/command_service/commands/sendable.rs index a5c3f640..79743c5d 100644 --- a/hydra_provider/src/command_service/commands/sendable.rs +++ b/hydra_provider/src/command_service/commands/sendable.rs @@ -1,3 +1,3 @@ pub trait Sendable { - fn send(); -} \ No newline at end of file + fn send(); +} diff --git a/hydra_provider/src/command_service/mod.rs b/hydra_provider/src/command_service/mod.rs index 414db8d0..0af8d112 100644 --- a/hydra_provider/src/command_service/mod.rs +++ b/hydra_provider/src/command_service/mod.rs @@ -1,2 +1,2 @@ pub mod commands; -pub mod service; \ No newline at end of file +pub mod service; diff --git a/hydra_provider/src/command_service/service.rs b/hydra_provider/src/command_service/service.rs index 3b784251..3827ba84 100644 --- a/hydra_provider/src/command_service/service.rs +++ b/hydra_provider/src/command_service/service.rs @@ -1,6 +1,6 @@ pub struct CommandService {} impl CommandService { - pub fn new() -> CommandService { - CommandService {} - } -} \ No newline at end of file + pub fn new() -> CommandService { + CommandService {} + } +} diff --git a/hydra_provider/src/data_feed_service/mod.rs b/hydra_provider/src/data_feed_service/mod.rs index 5d27e805..c92ab6e7 100644 --- a/hydra_provider/src/data_feed_service/mod.rs +++ b/hydra_provider/src/data_feed_service/mod.rs @@ -2,5 +2,5 @@ pub mod random; pub mod serial; pub mod proto { - tonic::include_proto!("data_feed"); + tonic::include_proto!("data_feed"); } diff --git a/hydra_provider/src/data_feed_service/random/iterator.rs b/hydra_provider/src/data_feed_service/random/iterator.rs index e11e0eda..6b42a59d 100644 --- a/hydra_provider/src/data_feed_service/random/iterator.rs +++ b/hydra_provider/src/data_feed_service/random/iterator.rs @@ -1,185 +1,192 @@ +use rand::Rng; +use rand::{rngs::StdRng, SeedableRng}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::SystemTime; -use rand::Rng; -use rand::{rngs::StdRng, SeedableRng}; -use messages::{command::Command, health::Health, sensor::{Air, EkfNav1, EkfNav2, EkfQuat, GpsPos1, GpsPos2, GpsVel, Imu1, Imu2, Sensor, UtcTime}, state::{State, StateData}, Data, Log, Message}; +use messages::{ + command::Command, + health::Health, + sensor::{ + Air, EkfNav1, EkfNav2, EkfQuat, GpsPos1, GpsPos2, GpsVel, Imu1, Imu2, Sensor, UtcTime, + }, + state::{State, StateData}, + Data, Log, Message, +}; use crate::hydra_input::HydraInput; - #[derive(Clone)] pub struct RandomDataFeedIterator { - pub is_running: Arc, + pub is_running: Arc, } impl RandomDataFeedIterator { - pub async fn next(&mut self) -> Option { - if !self.is_running.load(Ordering::Relaxed) { - return None - } - - // SHOULD DO: move this outside. No need to initialize every iterator step - let mut std_rng = StdRng::from_entropy(); - - let time: fugit::Instant = fugit::Instant::::from_ticks( - SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_millis() as u64, - ); - - // Convert timestamp to UTC time - let utc_time = UtcTime { - time_stamp: time.ticks() as u32, - day: (time.ticks() / 86400000) as i8, - year: (1970 + (time.ticks() / 86400000) / 365) as u16, - hour: ((time.ticks() % 86400000) / 3600000) as i8, - minute: ((time.ticks() % 3600000) / 60000) as i8, - month: ((time.ticks() % 31536000000) / 2592000000) as i8, - second: ((time.ticks() % 60000) / 1000) as i8, - nano_second: (time.ticks() % 1000) as i32 * 1000000, - gps_time_of_week: 0, - status: 0, - }; - - let air = Air { - air_temperature: std_rng.gen(), - altitude: std_rng.gen(), - pressure_abs: std_rng.gen(), - pressure_diff: std_rng.gen(), - status: std_rng.gen(), - time_stamp: time.ticks() as u32, - true_airspeed: std_rng.gen(), - }; - - let ekf_quat = EkfQuat { - euler_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - quaternion: [std_rng.gen(), std_rng.gen(), std_rng.gen(), std_rng.gen()], - status: std_rng.gen(), - time_stamp: time.ticks() as u32, - }; - - let ekf_nav1 = EkfNav1 { - time_stamp: time.ticks() as u32, - velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - velocity_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - }; - - let ekf_nav2 = EkfNav2 { - position: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - position_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - status: std_rng.gen(), - undulation: std_rng.gen(), - }; - - let imu1 = Imu1 { - accelerometers: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - gyroscopes: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - status: std_rng.gen(), - time_stamp: time.ticks() as u32, - }; - - let imu2 = Imu2 { - delta_angle: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - delta_velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - temperature: std_rng.gen(), - }; - - let gps_vel = GpsVel { - course: std_rng.gen(), - course_acc: std_rng.gen(), - status: std_rng.gen(), - time_of_week: std_rng.gen(), - time_stamp: time.ticks() as u32, - velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - velocity_acc: [std_rng.gen(), std_rng.gen(), std_rng.gen()], - }; - - let gps_pos1 = GpsPos1 { - time_stamp: time.ticks() as u32, - status: std_rng.gen(), - time_of_week: std_rng.gen(), - latitude: std_rng.gen(), - longitude: std_rng.gen(), - altitude: std_rng.gen(), - undulation: std_rng.gen(), - }; - - let gps_pos2 = GpsPos2 { - latitude_accuracy: std_rng.gen(), - longitude_accuracy: std_rng.gen(), - altitude_accuracy: std_rng.gen(), - num_sv_used: std_rng.gen(), - base_station_id: std_rng.gen(), - differential_age: std_rng.gen(), - }; - - // Array of sensor messages (we will select one of it) - let sensors = [ - Sensor::new(utc_time), - Sensor::new(air), - Sensor::new(ekf_quat), - Sensor::new(ekf_nav1), - Sensor::new(ekf_nav2), - Sensor::new(imu1), - Sensor::new(imu2), - Sensor::new(gps_vel), - Sensor::new(gps_pos1), - Sensor::new(gps_pos2), - ]; - - let status = match std_rng.gen_range(0..=6) { - 0 => StateData::Initializing, - 1 => StateData::WaitForTakeoff, - 2 => StateData::Ascent, - 3 => StateData::Descent, - 4 => StateData::TerminalDescent, - 5 => StateData::WaitForRecovery, - _ => StateData::Abort, - }; - - // Return a random sensor message - let mut sensor = sensors[std_rng.gen_range(0..sensors.len())].to_owned(); - sensor.component_id = std_rng.gen(); - - let state = State { data: status }; - - let log = Log::new(messages::LogLevel::Info, messages::Event::Initialized()); - - let command = Command { - data: messages::command::CommandData::DeployDrogue({ - messages::command::DeployDrogue { val: true } - }), - }; - - let data = match std_rng.gen_range(0..=4) { - 0 => Data::State(state), - 1 => Data::Log(log), - 2 => Data::Command(command), - 3 => Data::Sensor(sensor), - 4 => Data::Health(Health { - data: messages::health::HealthData::HealthStatus(messages::health::HealthStatus { - v5: Some(1), - v3_3: std_rng.gen(), - pyro_sense: std_rng.gen(), - vcc_sense: std_rng.gen(), - int_v5: std_rng.gen(), - int_v3_3: std_rng.gen(), - ext_v5: std_rng.gen(), - ext_3v3: std_rng.gen(), - failover_sense: std_rng.gen(), - }), - status: messages::health::HealthState::Nominal, - }), - _ => Data::Sensor(sensor), - }; - - Some( - HydraInput::Message( - Message::new(&time, messages::sender::Sender::GroundStation, data) - ) - ) - } + pub async fn next(&mut self) -> Option { + if !self.is_running.load(Ordering::Relaxed) { + return None; + } + + // SHOULD DO: move this outside. No need to initialize every iterator step + let mut std_rng = StdRng::from_entropy(); + + let time: fugit::Instant = fugit::Instant::::from_ticks( + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_millis() as u64, + ); + + // Convert timestamp to UTC time + let utc_time = UtcTime { + time_stamp: time.ticks() as u32, + day: (time.ticks() / 86400000) as i8, + year: (1970 + (time.ticks() / 86400000) / 365) as u16, + hour: ((time.ticks() % 86400000) / 3600000) as i8, + minute: ((time.ticks() % 3600000) / 60000) as i8, + month: ((time.ticks() % 31536000000) / 2592000000) as i8, + second: ((time.ticks() % 60000) / 1000) as i8, + nano_second: (time.ticks() % 1000) as i32 * 1000000, + gps_time_of_week: 0, + status: 0, + }; + + let air = Air { + air_temperature: std_rng.gen(), + altitude: std_rng.gen(), + pressure_abs: std_rng.gen(), + pressure_diff: std_rng.gen(), + status: std_rng.gen(), + time_stamp: time.ticks() as u32, + true_airspeed: std_rng.gen(), + }; + + let ekf_quat = EkfQuat { + euler_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + quaternion: [std_rng.gen(), std_rng.gen(), std_rng.gen(), std_rng.gen()], + status: std_rng.gen(), + time_stamp: time.ticks() as u32, + }; + + let ekf_nav1 = EkfNav1 { + time_stamp: time.ticks() as u32, + velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + velocity_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + }; + + let ekf_nav2 = EkfNav2 { + position: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + position_std_dev: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + status: std_rng.gen(), + undulation: std_rng.gen(), + }; + + let imu1 = Imu1 { + accelerometers: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + gyroscopes: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + status: std_rng.gen(), + time_stamp: time.ticks() as u32, + }; + + let imu2 = Imu2 { + delta_angle: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + delta_velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + temperature: std_rng.gen(), + }; + + let gps_vel = GpsVel { + course: std_rng.gen(), + course_acc: std_rng.gen(), + status: std_rng.gen(), + time_of_week: std_rng.gen(), + time_stamp: time.ticks() as u32, + velocity: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + velocity_acc: [std_rng.gen(), std_rng.gen(), std_rng.gen()], + }; + + let gps_pos1 = GpsPos1 { + time_stamp: time.ticks() as u32, + status: std_rng.gen(), + time_of_week: std_rng.gen(), + latitude: std_rng.gen(), + longitude: std_rng.gen(), + altitude: std_rng.gen(), + undulation: std_rng.gen(), + }; + + let gps_pos2 = GpsPos2 { + latitude_accuracy: std_rng.gen(), + longitude_accuracy: std_rng.gen(), + altitude_accuracy: std_rng.gen(), + num_sv_used: std_rng.gen(), + base_station_id: std_rng.gen(), + differential_age: std_rng.gen(), + }; + + // Array of sensor messages (we will select one of it) + let sensors = [ + Sensor::new(utc_time), + Sensor::new(air), + Sensor::new(ekf_quat), + Sensor::new(ekf_nav1), + Sensor::new(ekf_nav2), + Sensor::new(imu1), + Sensor::new(imu2), + Sensor::new(gps_vel), + Sensor::new(gps_pos1), + Sensor::new(gps_pos2), + ]; + + let status = match std_rng.gen_range(0..=6) { + 0 => StateData::Initializing, + 1 => StateData::WaitForTakeoff, + 2 => StateData::Ascent, + 3 => StateData::Descent, + 4 => StateData::TerminalDescent, + 5 => StateData::WaitForRecovery, + _ => StateData::Abort, + }; + + // Return a random sensor message + let mut sensor = sensors[std_rng.gen_range(0..sensors.len())].to_owned(); + sensor.component_id = std_rng.gen(); + + let state = State { data: status }; + + let log = Log::new(messages::LogLevel::Info, messages::Event::Initialized()); + + let command = Command { + data: messages::command::CommandData::DeployDrogue({ + messages::command::DeployDrogue { val: true } + }), + }; + + let data = match std_rng.gen_range(0..=4) { + 0 => Data::State(state), + 1 => Data::Log(log), + 2 => Data::Command(command), + 3 => Data::Sensor(sensor), + 4 => Data::Health(Health { + data: messages::health::HealthData::HealthStatus(messages::health::HealthStatus { + v5: Some(1), + v3_3: std_rng.gen(), + pyro_sense: std_rng.gen(), + vcc_sense: std_rng.gen(), + int_v5: std_rng.gen(), + int_v3_3: std_rng.gen(), + ext_v5: std_rng.gen(), + ext_3v3: std_rng.gen(), + failover_sense: std_rng.gen(), + }), + status: messages::health::HealthState::Nominal, + }), + _ => Data::Sensor(sensor), + }; + + Some(HydraInput::Message(Message::new( + &time, + messages::sender::Sender::GroundStation, + data, + ))) + } } diff --git a/hydra_provider/src/data_feed_service/random/mod.rs b/hydra_provider/src/data_feed_service/random/mod.rs index 2355c611..c0040eae 100644 --- a/hydra_provider/src/data_feed_service/random/mod.rs +++ b/hydra_provider/src/data_feed_service/random/mod.rs @@ -1,5 +1,5 @@ -pub mod service; pub mod iterator; +pub mod service; -pub use service::RandomDataFeedService; -pub use crate::data_feed_service::proto::random_data_feed_server::RandomDataFeedServer; // used by bootstrap to setup a RandomDataFeedService +pub use crate::data_feed_service::proto::random_data_feed_server::RandomDataFeedServer; +pub use service::RandomDataFeedService; // used by bootstrap to setup a RandomDataFeedService diff --git a/hydra_provider/src/data_feed_service/random/service.rs b/hydra_provider/src/data_feed_service/random/service.rs index 55c3bb16..c0d0c8cf 100644 --- a/hydra_provider/src/data_feed_service/random/service.rs +++ b/hydra_provider/src/data_feed_service/random/service.rs @@ -1,55 +1,53 @@ +use log::info; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use tokio::sync::Mutex; use tonic::{async_trait, Request, Response, Status}; -use log::info; -use crate::database_service::DatabaseService; use crate::data_feed_service::random::iterator::RandomDataFeedIterator; +use crate::database_service::DatabaseService; use crate::data_feed_service::proto::random_data_feed_server::*; use crate::data_feed_service::proto::Empty; pub struct RandomDataFeedService { - iterator: RandomDataFeedIterator, - database_service: Arc>, + iterator: RandomDataFeedIterator, + database_service: Arc>, } impl RandomDataFeedService { - pub fn new( - database_service: Arc>, - ) -> RandomDataFeedService { - RandomDataFeedService { - iterator: RandomDataFeedIterator { - is_running: Arc::new(AtomicBool::new(false)), - }, - database_service, - } - } + pub fn new(database_service: Arc>) -> RandomDataFeedService { + RandomDataFeedService { + iterator: RandomDataFeedIterator { + is_running: Arc::new(AtomicBool::new(false)), + }, + database_service, + } + } } #[async_trait] impl RandomDataFeed for RandomDataFeedService { - async fn start(&self, _request: Request) -> Result, Status> { - self.iterator.is_running.store(true, Ordering::Relaxed); - - let mut iterator = self.iterator.clone(); - let database_service = self.database_service.clone(); - - tokio::spawn(async move { - info!("RandomDataFeedService has started."); - while let Some(message) = iterator.next().await { - // SHOULD DO: figure out how to handle database save errors better - let _ = database_service.lock().await.save(message).await; - } - info!("RandomDataFeedService has stopped."); - }); - - Ok(Response::new(Empty {})) - } - - async fn stop(&self, _request: Request) -> Result, Status> { - self.iterator.is_running.store(false, Ordering::Relaxed); - Ok(Response::new(Empty {})) - } + async fn start(&self, _request: Request) -> Result, Status> { + self.iterator.is_running.store(true, Ordering::Relaxed); + + let mut iterator = self.iterator.clone(); + let database_service = self.database_service.clone(); + + tokio::spawn(async move { + info!("RandomDataFeedService has started."); + while let Some(message) = iterator.next().await { + // SHOULD DO: figure out how to handle database save errors better + let _ = database_service.lock().await.save(message).await; + } + info!("RandomDataFeedService has stopped."); + }); + + Ok(Response::new(Empty {})) + } + + async fn stop(&self, _request: Request) -> Result, Status> { + self.iterator.is_running.store(false, Ordering::Relaxed); + Ok(Response::new(Empty {})) + } } diff --git a/hydra_provider/src/data_feed_service/serial/iterator.rs b/hydra_provider/src/data_feed_service/serial/iterator.rs index 8ca92f31..033af0f6 100644 --- a/hydra_provider/src/data_feed_service/serial/iterator.rs +++ b/hydra_provider/src/data_feed_service/serial/iterator.rs @@ -1,52 +1,52 @@ +use log::info; +use messages::mavlink::MavConnection; +use postcard::from_bytes; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use tokio::sync::Mutex; -use messages::mavlink::MavConnection; -use postcard::from_bytes; -use log::info; +use crate::data_feed_service::proto::SerialDataFeedConfig; use crate::hydra_input::HydraInput; use messages::Message; -use crate::data_feed_service::proto::SerialDataFeedConfig; use messages::mavlink::uorocketry::MavMessage; #[derive(Clone)] pub struct SerialDataFeedIterator { - pub config: Arc>>, - pub mavlink: Arc + Send + Sync>>>>, - pub is_running: Arc, + pub config: Arc>>, + pub mavlink: Arc + Send + Sync>>>>, + pub is_running: Arc, } impl SerialDataFeedIterator { - pub async fn next(&mut self) -> Option { - if !self.is_running.load(Ordering::Relaxed) { - return None; - } + pub async fn next(&mut self) -> Option { + if !self.is_running.load(Ordering::Relaxed) { + return None; + } - let mavlink_option = self.mavlink.lock().await; - if mavlink_option.is_none() { - return None; - } + let mavlink_option = self.mavlink.lock().await; + if mavlink_option.is_none() { + return None; + } - let mavlink = mavlink_option.as_ref().unwrap(); - let (_, mavlink_message) = mavlink.recv().unwrap(); - let message = match &mavlink_message { - MavMessage::POSTCARD_MESSAGE(data) => { - let data: Message = from_bytes(data.message.as_slice()).unwrap(); - info!("Received rocket message: {:#?}", data); - HydraInput::Message(data) - } - MavMessage::RADIO_STATUS(data) => { - info!("Received radio status: {:?}", data); - HydraInput::RadioStatus(data.clone()) - } - MavMessage::HEARTBEAT(heartbeat) => { - info!("Received heartbeat."); - HydraInput::Heartbeat(heartbeat.clone()) - } - }; + let mavlink = mavlink_option.as_ref().unwrap(); + let (_, mavlink_message) = mavlink.recv().unwrap(); + let message = match &mavlink_message { + MavMessage::POSTCARD_MESSAGE(data) => { + let data: Message = from_bytes(data.message.as_slice()).unwrap(); + info!("Received rocket message: {:#?}", data); + HydraInput::Message(data) + } + MavMessage::RADIO_STATUS(data) => { + info!("Received radio status: {:?}", data); + HydraInput::RadioStatus(data.clone()) + } + MavMessage::HEARTBEAT(heartbeat) => { + info!("Received heartbeat."); + HydraInput::Heartbeat(heartbeat.clone()) + } + }; - Some(message) - } + Some(message) + } } diff --git a/hydra_provider/src/data_feed_service/serial/mod.rs b/hydra_provider/src/data_feed_service/serial/mod.rs index 92c1eb91..06c38f2b 100644 --- a/hydra_provider/src/data_feed_service/serial/mod.rs +++ b/hydra_provider/src/data_feed_service/serial/mod.rs @@ -1,4 +1,4 @@ pub mod iterator; pub mod service; -pub use service::SerialDataFeedService; -pub use crate::data_feed_service::proto::serial_data_feed_server::SerialDataFeedServer; // used by bootstrap to setup a SerialDataFeedService +pub use crate::data_feed_service::proto::serial_data_feed_server::SerialDataFeedServer; +pub use service::SerialDataFeedService; // used by bootstrap to setup a SerialDataFeedService diff --git a/hydra_provider/src/data_feed_service/serial/service.rs b/hydra_provider/src/data_feed_service/serial/service.rs index 90e2ffa1..a3d93ebe 100644 --- a/hydra_provider/src/data_feed_service/serial/service.rs +++ b/hydra_provider/src/data_feed_service/serial/service.rs @@ -1,103 +1,97 @@ +use log::info; +use messages::mavlink::connect; +use serialport::{available_ports, SerialPortType}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use tokio::sync::Mutex; -use messages::mavlink::connect; -use serialport::{available_ports, SerialPortType}; use tonic::{async_trait, Request, Response, Status}; -use log::info; +use crate::data_feed_service::proto::serial_data_feed_server::*; +use crate::data_feed_service::proto::{ + Empty, ListAvailablePortsResponse, SerialDataFeedConfig, SerialDataFeedStatus, +}; use crate::data_feed_service::serial::iterator::SerialDataFeedIterator; use crate::database_service::DatabaseService; -use crate::data_feed_service::proto::serial_data_feed_server::*; -use crate::data_feed_service::proto::{Empty, ListAvailablePortsResponse, SerialDataFeedConfig, SerialDataFeedStatus}; use messages::mavlink::uorocketry::MavMessage; #[derive(Clone)] pub struct SerialDataFeedService { - iterator: SerialDataFeedIterator, - database_service: Arc>, + iterator: SerialDataFeedIterator, + database_service: Arc>, } impl SerialDataFeedService { - pub fn new( - database_service: Arc>, - ) -> SerialDataFeedService { - SerialDataFeedService { - iterator: SerialDataFeedIterator { - is_running: Arc::new(AtomicBool::new(false)), - mavlink: Arc::new(Mutex::new(None)), - config: Arc::new(Mutex::new(None)) - }, - database_service, - } - } + pub fn new(database_service: Arc>) -> SerialDataFeedService { + SerialDataFeedService { + iterator: SerialDataFeedIterator { + is_running: Arc::new(AtomicBool::new(false)), + mavlink: Arc::new(Mutex::new(None)), + config: Arc::new(Mutex::new(None)), + }, + database_service, + } + } } #[async_trait] impl SerialDataFeed for SerialDataFeedService { - async fn start(&self, _request: Request) -> Result, Status> { - self.iterator.is_running.store(true, Ordering::Relaxed); + async fn start(&self, _request: Request) -> Result, Status> { + self.iterator.is_running.store(true, Ordering::Relaxed); - let mut iterator = self.iterator.clone(); - let database_service = self.database_service.clone(); - tokio::spawn(async move { - info!("SerialDataFeedService has started."); - while let Some(message) = iterator.next().await { - // SHOULD DO: figure out how to handle database save errors better - let _ = database_service.lock().await.save(message).await; - } - info!("SerialDataFeedService has stopped."); - }); + let mut iterator = self.iterator.clone(); + let database_service = self.database_service.clone(); + tokio::spawn(async move { + info!("SerialDataFeedService has started."); + while let Some(message) = iterator.next().await { + // SHOULD DO: figure out how to handle database save errors better + let _ = database_service.lock().await.save(message).await; + } + info!("SerialDataFeedService has stopped."); + }); - Ok(Response::new(Empty {})) - } + Ok(Response::new(Empty {})) + } - async fn stop(&self, _request: Request) -> Result, Status> { - self.iterator.is_running.store(false, Ordering::Relaxed); - Ok(Response::new(Empty {})) - } + async fn stop(&self, _request: Request) -> Result, Status> { + self.iterator.is_running.store(false, Ordering::Relaxed); + Ok(Response::new(Empty {})) + } - async fn list_available_ports( - &self, - _request: Request - ) -> Result, Status> { - let ports = available_ports() - .unwrap() - .iter() - .filter(|port| matches!(port.port_type, SerialPortType::UsbPort(_))) - .map(|port| port.port_name.clone()) - .collect::>(); - Ok(Response::new( - ListAvailablePortsResponse { - ports - } - )) - } + async fn list_available_ports( + &self, + _request: Request, + ) -> Result, Status> { + let ports = available_ports() + .unwrap() + .iter() + .filter(|port| matches!(port.port_type, SerialPortType::UsbPort(_))) + .map(|port| port.port_name.clone()) + .collect::>(); + Ok(Response::new(ListAvailablePortsResponse { ports })) + } - async fn configure( - &self, - request: Request - ) -> Result, Status> { - let config = request.into_inner(); + async fn configure( + &self, + request: Request, + ) -> Result, Status> { + let config = request.into_inner(); - let address = format!("serial:{}:{}", config.port, config.baud_rate); + let address = format!("serial:{}:{}", config.port, config.baud_rate); - let mut mavlink = self.iterator.mavlink.lock().await; - *mavlink = Some(connect::(address.as_str()).unwrap()); + let mut mavlink = self.iterator.mavlink.lock().await; + *mavlink = Some(connect::(address.as_str()).unwrap()); - Ok(Response::new(Empty {})) - } + Ok(Response::new(Empty {})) + } - async fn get_status( - &self, - _request: Request - ) -> Result, Status> { - Ok(Response::new( - SerialDataFeedStatus { - is_running : self.iterator.is_running.load(Ordering::Relaxed), - config : self.iterator.config.lock().await.clone(), - } - )) - } + async fn get_status( + &self, + _request: Request, + ) -> Result, Status> { + Ok(Response::new(SerialDataFeedStatus { + is_running: self.iterator.is_running.load(Ordering::Relaxed), + config: self.iterator.config.lock().await.clone(), + })) + } } diff --git a/hydra_provider/src/database_service/hydra_input/heart_beat.rs b/hydra_provider/src/database_service/hydra_input/heart_beat.rs index dccc8e42..869faf83 100644 --- a/hydra_provider/src/database_service/hydra_input/heart_beat.rs +++ b/hydra_provider/src/database_service/hydra_input/heart_beat.rs @@ -1,25 +1,25 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; use super::saveable::SaveableData; use messages::mavlink::uorocketry::HEARTBEAT_DATA; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for HEARTBEAT_DATA { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - _: i32 - ) -> Result { - query!( - "INSERT INTO rocket_heartbeat + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + _: i32, + ) -> Result { + query!( + "INSERT INTO rocket_heartbeat (custom_mode, mavtype, autopilot, base_mode, system_status, mavlink_version) VALUES ($1, $2, $3, $4, $5, $6)", - self.custom_mode as i32, - self.mavtype as i32, - self.autopilot as i32, - self.base_mode as i32, - self.system_status as i32, - self.mavlink_version as i32, - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file + self.custom_mode as i32, + self.mavtype as i32, + self.autopilot as i32, + self.base_mode as i32, + self.system_status as i32, + self.mavlink_version as i32, + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/deploy_drogue.rs b/hydra_provider/src/database_service/hydra_input/messages/command/deploy_drogue.rs index 9a204ec4..3e87a95e 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/command/deploy_drogue.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/command/deploy_drogue.rs @@ -1,21 +1,21 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::command::DeployDrogue; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::command::DeployDrogue; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for DeployDrogue { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_command_id: i32, - ) -> Result { - query!( - "INSERT INTO rocket_deploy_drogue_command + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_command_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_deploy_drogue_command (rocket_command_id, val) VALUES ($1, $2)", - rocket_command_id, - self.val - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file + rocket_command_id, + self.val + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/deploy_main.rs b/hydra_provider/src/database_service/hydra_input/messages/command/deploy_main.rs index f3cf714d..5b4ff971 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/command/deploy_main.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/command/deploy_main.rs @@ -1,21 +1,21 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::command::DeployMain; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::command::DeployMain; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for DeployMain { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_command_id: i32, - ) -> Result { - query!( - "INSERT INTO rocket_deploy_main_command + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_command_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_deploy_main_command (rocket_command_id, val) VALUES ($1, $2)", - rocket_command_id, - self.val - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file + rocket_command_id, + self.val + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/mod.rs b/hydra_provider/src/database_service/hydra_input/messages/command/mod.rs index e8e82eb2..28c4ff95 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/command/mod.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/command/mod.rs @@ -3,34 +3,34 @@ pub mod deploy_main; pub mod power_down; pub mod radio_rate_change; -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::command::{Command, CommandData}; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::command::{Command, CommandData}; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for Command { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let result = query!( - "INSERT INTO rocket_command + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let result = query!( + "INSERT INTO rocket_command (rocket_message_id) VALUES ($1)", - rocket_message_id, - ) - .execute(&mut **transaction) - .await; + rocket_message_id, + ) + .execute(&mut **transaction) + .await; - if result.is_err() { - return result; - } + if result.is_err() { + return result; + } - match &self.data { - CommandData::DeployDrogue(data) => data.save(transaction, rocket_message_id).await, - CommandData::DeployMain(data) => data.save(transaction, rocket_message_id).await, - CommandData::RadioRateChange(data) => data.save(transaction, rocket_message_id).await, - CommandData::PowerDown(data) => data.save(transaction, rocket_message_id).await, - } - } -} \ No newline at end of file + match &self.data { + CommandData::DeployDrogue(data) => data.save(transaction, rocket_message_id).await, + CommandData::DeployMain(data) => data.save(transaction, rocket_message_id).await, + CommandData::RadioRateChange(data) => data.save(transaction, rocket_message_id).await, + CommandData::PowerDown(data) => data.save(transaction, rocket_message_id).await, + } + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/power_down.rs b/hydra_provider/src/database_service/hydra_input/messages/command/power_down.rs index 79291a7c..4759fc3f 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/command/power_down.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/command/power_down.rs @@ -1,21 +1,21 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::command::PowerDown; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::command::PowerDown; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for PowerDown { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_command_id: i32, - ) -> Result { - query!( - "INSERT INTO rocket_power_down_command + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_command_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_power_down_command (rocket_command_id, board) VALUES ($1, $2)", - rocket_command_id, - format!("{:?}", self.board) - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file + rocket_command_id, + format!("{:?}", self.board) + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/command/radio_rate_change.rs b/hydra_provider/src/database_service/hydra_input/messages/command/radio_rate_change.rs index d8fad609..b9655c7d 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/command/radio_rate_change.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/command/radio_rate_change.rs @@ -1,21 +1,21 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::command::RadioRateChange; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::command::RadioRateChange; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for RadioRateChange { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_command_id: i32, - ) -> Result { - query!( - "INSERT INTO rocket_radio_rate_change_command + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_command_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_radio_rate_change_command (rocket_command_id, rate) VALUES ($1, $2)", - rocket_command_id, - format!("{:?}", self.rate) - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file + rocket_command_id, + format!("{:?}", self.rate) + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/health.rs b/hydra_provider/src/database_service/hydra_input/messages/health.rs index 3da6c3be..6a5668d4 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/health.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/health.rs @@ -1,40 +1,40 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::health::{Health, HealthData, HealthStatus}; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::health::{Health, HealthData, HealthStatus}; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for Health { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let result = query!( - "INSERT INTO rocket_health + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let result = query!( + "INSERT INTO rocket_health (rocket_message_id, status) VALUES ($1, $2)", - rocket_message_id, - format!("{:?}", self.status) - ) - .execute(&mut **transaction) - .await; + rocket_message_id, + format!("{:?}", self.status) + ) + .execute(&mut **transaction) + .await; - if result.is_err() { - return result; - } + if result.is_err() { + return result; + } - match &self.data { - HealthData::HealthStatus(status) => status.save(transaction, rocket_message_id).await, - } - } + match &self.data { + HealthData::HealthStatus(status) => status.save(transaction, rocket_message_id).await, + } + } } impl SaveableData for HealthStatus { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - query!( + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( "INSERT INTO rocket_health_status (rocket_health_id, v5, v3_3, pyro_sense, vcc_sense, int_v5, int_v3_3, ext_v5, ext_3v3, failover_sense) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", @@ -51,5 +51,5 @@ impl SaveableData for HealthStatus { ) .execute(&mut **transaction) .await - } -} \ No newline at end of file + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/log.rs b/hydra_provider/src/database_service/hydra_input/messages/log.rs index 151320c6..91e9e6b5 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/log.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/log.rs @@ -1,22 +1,22 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::Log; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::Log; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for Log { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - query!( - "INSERT INTO rocket_log + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_log (rocket_message_id, level, event) VALUES ($1, $2, $3)", - rocket_message_id, - format!("{:?}", self.level), - format!("{:?}", self.event) - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file + rocket_message_id, + format!("{:?}", self.level), + format!("{:?}", self.event) + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/mod.rs b/hydra_provider/src/database_service/hydra_input/messages/mod.rs index 7fb502d9..951890d6 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/mod.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/mod.rs @@ -1,50 +1,50 @@ -use messages::{Data, Message}; -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; use super::saveable::SaveableData; +use messages::{Data, Message}; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; +pub mod command; pub mod health; -pub mod state; pub mod log; pub mod sensor; -pub mod command; +pub mod state; impl SaveableData for Message { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - _: i32 - ) -> Result { - let message_type = match self.data { - Data::Health(_) => "health", - Data::State(_) => "state", - Data::Sensor(_) => "sensor", - Data::Log(_) => "log", - Data::Command(_) => "command", - }; + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + _: i32, + ) -> Result { + let message_type = match self.data { + Data::Health(_) => "health", + Data::State(_) => "state", + Data::Sensor(_) => "sensor", + Data::Log(_) => "log", + Data::Command(_) => "command", + }; - let result = query!( - "INSERT INTO rocket_message + let result = query!( + "INSERT INTO rocket_message (time_stamp, sender, message_type) VALUES ($1, $2, $3) RETURNING id", - self.timestamp as i32, - format!("{:?}", self.sender), - message_type - ) - .fetch_one(&mut **transaction) - .await; + self.timestamp as i32, + format!("{:?}", self.sender), + message_type + ) + .fetch_one(&mut **transaction) + .await; - if result.is_err() { - return Err(result.err().unwrap()); - } + if result.is_err() { + return Err(result.err().unwrap()); + } - let record = result.unwrap(); - match &self.data { - Data::Health(data) => data.save(transaction, record.id).await, - Data::State(data) => data.save(transaction, record.id).await, - Data::Sensor(data) => data.save(transaction, record.id).await, - Data::Log(data) => data.save(transaction, record.id).await, - Data::Command(data) => data.save(transaction, record.id).await, - } - } -} \ No newline at end of file + let record = result.unwrap(); + match &self.data { + Data::Health(data) => data.save(transaction, record.id).await, + Data::State(data) => data.save(transaction, record.id).await, + Data::Sensor(data) => data.save(transaction, record.id).await, + Data::Log(data) => data.save(transaction, record.id).await, + Data::Command(data) => data.save(transaction, record.id).await, + } + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/air.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/air.rs index 81c204ee..d3cdf698 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/air.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/air.rs @@ -1,14 +1,14 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::Air; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::Air; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for Air { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - query!( + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( "INSERT INTO rocket_sensor_air (rocket_sensor_message_id, time_stamp, status, pressure_abs, altitude, pressure_diff, true_airspeed, air_temperature) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", @@ -23,5 +23,5 @@ impl SaveableData for Air { ) .execute(&mut **transaction) .await - } -} \ No newline at end of file + } +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav1.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav1.rs index 1c288630..ce333a07 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav1.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav1.rs @@ -1,27 +1,26 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::EkfNav1; -use crate::database_service::hydra_input::saveable::SaveableData; use super::utils::store_3d_vector; +use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::EkfNav1; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for EkfNav1 { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let velocity = store_3d_vector(self.velocity, transaction).await?; - let velocity_std_dev: i32 = store_3d_vector(self.velocity_std_dev, transaction).await?; - query!( - "INSERT INTO rocket_sensor_nav_1 + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let velocity = store_3d_vector(self.velocity, transaction).await?; + let velocity_std_dev: i32 = store_3d_vector(self.velocity_std_dev, transaction).await?; + query!( + "INSERT INTO rocket_sensor_nav_1 (rocket_sensor_message_id, time_stamp, velocity, velocity_std_dev) VALUES ($1, $2, $3, $4)", - rocket_message_id, - self.time_stamp as i32, - velocity, - velocity_std_dev, - ) - .execute(&mut **transaction) - .await - } + rocket_message_id, + self.time_stamp as i32, + velocity, + velocity_std_dev, + ) + .execute(&mut **transaction) + .await + } } - diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav2.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav2.rs index caf901d2..a00dd61e 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav2.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_nav2.rs @@ -1,29 +1,28 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::EkfNav2; -use crate::database_service::hydra_input::saveable::SaveableData; use super::utils::store_3d_vector; +use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::EkfNav2; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for EkfNav2 { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let position = store_3d_vector(self.position.map(|x| x as f32), transaction).await?; - let position_std_dev = store_3d_vector(self.position_std_dev, transaction).await?; + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let position = store_3d_vector(self.position.map(|x| x as f32), transaction).await?; + let position_std_dev = store_3d_vector(self.position_std_dev, transaction).await?; - query!( - "INSERT INTO rocket_sensor_nav_2 + query!( + "INSERT INTO rocket_sensor_nav_2 (rocket_sensor_message_id, position, position_std_dev, undulation, status) VALUES ($1, $2, $3, $4, $5)", - rocket_message_id, - position, - position_std_dev, - self.undulation, - self.status as i32, - ) - .execute(&mut **transaction) - .await - } + rocket_message_id, + position, + position_std_dev, + self.undulation, + self.status as i32, + ) + .execute(&mut **transaction) + .await + } } - diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_quat.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_quat.rs index 1ebd3c9f..dcc50d04 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_quat.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/ekf_quat.rs @@ -1,30 +1,29 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::EkfQuat; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::EkfQuat; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; use super::utils::{store_3d_vector, store_quaternion}; impl SaveableData for EkfQuat { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let euler_std_dev = store_3d_vector(self.euler_std_dev, transaction).await?; - let quaternion = store_quaternion(self.quaternion, transaction).await?; + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let euler_std_dev = store_3d_vector(self.euler_std_dev, transaction).await?; + let quaternion = store_quaternion(self.quaternion, transaction).await?; - query!( - "INSERT INTO rocket_sensor_quat + query!( + "INSERT INTO rocket_sensor_quat (rocket_sensor_message_id, time_stamp, quaternion, euler_std_dev, status) VALUES ($1, $2, $3, $4, $5)", - rocket_message_id, - self.time_stamp as i32, - quaternion, - euler_std_dev, - self.status as i32, - ) - .execute(&mut **transaction) - .await - } + rocket_message_id, + self.time_stamp as i32, + quaternion, + euler_std_dev, + self.status as i32, + ) + .execute(&mut **transaction) + .await + } } - diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position1.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position1.rs index b92a840f..b53f59b2 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position1.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position1.rs @@ -1,14 +1,14 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::GpsPos1; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::GpsPos1; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for GpsPos1 { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - query!( + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( "INSERT INTO rocket_sensor_gps_pos_1 (rocket_sensor_message_id, time_stamp, status, time_of_week, latitude, longitude, altitude, undulation) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", @@ -24,6 +24,5 @@ impl SaveableData for GpsPos1 { ) .execute(&mut **transaction) .await - } + } } - diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position2.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position2.rs index a2ac1d3b..ae410e57 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position2.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_position2.rs @@ -1,14 +1,14 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::GpsPos2; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::GpsPos2; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for GpsPos2 { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - query!( + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( "INSERT INTO rocket_sensor_gps_pos_2 (rocket_sensor_message_id, latitude_accuracy, longitude_accuracy, altitude_accuracy, num_sv_used, base_station_id, differential_age) VALUES ($1, $2, $3, $4, $5, $6, $7)", @@ -22,6 +22,5 @@ impl SaveableData for GpsPos2 { ) .execute(&mut **transaction) .await - } + } } - diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_velocity.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_velocity.rs index d6cb2bc9..5e0f4053 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_velocity.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/gps_velocity.rs @@ -1,19 +1,19 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::GpsVel; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::GpsVel; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; use super::utils::store_3d_vector; impl SaveableData for GpsVel { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let velocity = store_3d_vector(self.velocity, transaction).await?; - let velocity_acc = store_3d_vector(self.velocity_acc, transaction).await?; + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let velocity = store_3d_vector(self.velocity, transaction).await?; + let velocity_acc = store_3d_vector(self.velocity_acc, transaction).await?; - query!( + query!( "INSERT INTO rocket_sensor_gps_vel (rocket_sensor_message_id, time_stamp, status, time_of_week, velocity, velocity_acc, course, course_acc) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", @@ -28,6 +28,5 @@ impl SaveableData for GpsVel { ) .execute(&mut **transaction) .await - } + } } - diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/imu1.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/imu1.rs index 86f8bdb2..84ea4187 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/imu1.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/imu1.rs @@ -1,30 +1,29 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::Imu1; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::Imu1; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; use super::utils::store_3d_vector; impl SaveableData for Imu1 { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let accelerometers = store_3d_vector(self.accelerometers, transaction).await?; - let gyroscopes = store_3d_vector(self.gyroscopes, transaction).await?; - - query!( - "INSERT INTO rocket_sensor_imu_1 + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let accelerometers = store_3d_vector(self.accelerometers, transaction).await?; + let gyroscopes = store_3d_vector(self.gyroscopes, transaction).await?; + + query!( + "INSERT INTO rocket_sensor_imu_1 (rocket_sensor_message_id, time_stamp, status, accelerometers, gyroscopes) VALUES ($1, $2, $3, $4, $5)", - rocket_message_id, - self.time_stamp as i32, - self.status as i32, - accelerometers, - gyroscopes, - ) - .execute(&mut **transaction) - .await - } + rocket_message_id, + self.time_stamp as i32, + self.status as i32, + accelerometers, + gyroscopes, + ) + .execute(&mut **transaction) + .await + } } - diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/imu2.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/imu2.rs index 2736ed34..9876a820 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/imu2.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/imu2.rs @@ -1,28 +1,28 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::Imu2; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::Imu2; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; use super::utils::store_3d_vector; impl SaveableData for Imu2 { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let delta_velocity = store_3d_vector(self.delta_velocity, transaction).await?; - let delta_angle = store_3d_vector(self.delta_angle, transaction).await?; + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let delta_velocity = store_3d_vector(self.delta_velocity, transaction).await?; + let delta_angle = store_3d_vector(self.delta_angle, transaction).await?; - query!( - "INSERT INTO rocket_sensor_imu_2 + query!( + "INSERT INTO rocket_sensor_imu_2 (rocket_sensor_message_id, temperature, delta_velocity, delta_angle) VALUES ($1, $2, $3, $4)", - rocket_message_id, - self.temperature as f32, - delta_velocity, - delta_angle, - ) - .execute(&mut **transaction) - .await - } + rocket_message_id, + self.temperature as f32, + delta_velocity, + delta_angle, + ) + .execute(&mut **transaction) + .await + } } diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/mod.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/mod.rs index d0c801ad..afa525ed 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/mod.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/mod.rs @@ -1,51 +1,50 @@ pub mod air; -pub mod ekf_quat; -pub mod utc_time; pub mod ekf_nav1; pub mod ekf_nav2; -pub mod imu1; -pub mod imu2; -pub mod gps_velocity; +pub mod ekf_quat; pub mod gps_position1; pub mod gps_position2; +pub mod gps_velocity; +pub mod imu1; +pub mod imu2; +pub mod utc_time; pub mod utils; -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::{Sensor, SensorData}; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::{Sensor, SensorData}; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for Sensor { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - let result = query!( - "INSERT INTO rocket_sensor_message + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + let result = query!( + "INSERT INTO rocket_sensor_message (rocket_message_id, component_id) VALUES ($1, $2)", - rocket_message_id, - self.component_id as i32 - ) - .execute(&mut **transaction) - .await; + rocket_message_id, + self.component_id as i32 + ) + .execute(&mut **transaction) + .await; - if result.is_err() { - return Err(result.err().unwrap()); - } + if result.is_err() { + return Err(result.err().unwrap()); + } - match &self.data { - SensorData::UtcTime(data) => data.save(transaction, rocket_message_id).await, - SensorData::Air(data) => data.save(transaction, rocket_message_id).await, - SensorData::EkfQuat(data) => data.save(transaction, rocket_message_id).await, - SensorData::EkfNav1(data) => data.save(transaction, rocket_message_id).await, - SensorData::EkfNav2(data) => data.save(transaction, rocket_message_id).await, - SensorData::Imu1(data) => data.save(transaction, rocket_message_id).await, - SensorData::Imu2(data) => data.save(transaction, rocket_message_id).await, - SensorData::GpsVel(data) => data.save(transaction, rocket_message_id).await, - SensorData::GpsPos1(data) => data.save(transaction, rocket_message_id).await, - SensorData::GpsPos2(data) => data.save(transaction, rocket_message_id).await, - } - } + match &self.data { + SensorData::UtcTime(data) => data.save(transaction, rocket_message_id).await, + SensorData::Air(data) => data.save(transaction, rocket_message_id).await, + SensorData::EkfQuat(data) => data.save(transaction, rocket_message_id).await, + SensorData::EkfNav1(data) => data.save(transaction, rocket_message_id).await, + SensorData::EkfNav2(data) => data.save(transaction, rocket_message_id).await, + SensorData::Imu1(data) => data.save(transaction, rocket_message_id).await, + SensorData::Imu2(data) => data.save(transaction, rocket_message_id).await, + SensorData::GpsVel(data) => data.save(transaction, rocket_message_id).await, + SensorData::GpsPos1(data) => data.save(transaction, rocket_message_id).await, + SensorData::GpsPos2(data) => data.save(transaction, rocket_message_id).await, + } + } } - diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/utc_time.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/utc_time.rs index f475037e..468672b5 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/utc_time.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/utc_time.rs @@ -1,14 +1,14 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::sensor::UtcTime; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::sensor::UtcTime; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for UtcTime { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - query!( + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( "INSERT INTO rocket_sensor_utc_time (rocket_sensor_message_id, time_stamp, status, year, month, day, hour, minute, second, nano_second, gps_time_of_week) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", @@ -26,5 +26,5 @@ impl SaveableData for UtcTime { ) .execute(&mut **transaction) .await - } + } } diff --git a/hydra_provider/src/database_service/hydra_input/messages/sensor/utils.rs b/hydra_provider/src/database_service/hydra_input/messages/sensor/utils.rs index a8cd1c90..d2ac74ef 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/sensor/utils.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/sensor/utils.rs @@ -1,40 +1,40 @@ -use sqlx::{query, Error, Transaction, Postgres}; +use sqlx::{query, Error, Postgres, Transaction}; pub async fn store_3d_vector( - vec3: [f32; 3usize], - transaction: &mut Transaction<'_, Postgres>, + vec3: [f32; 3usize], + transaction: &mut Transaction<'_, Postgres>, ) -> Result { - let id = query!( - "INSERT INTO data_vec3 + let id = query!( + "INSERT INTO data_vec3 (x, y, z) VALUES ($1, $2, $3) RETURNING id", - vec3[0], - vec3[1], - vec3[2] - ) - .fetch_one(&mut **transaction) - .await? - .id; + vec3[0], + vec3[1], + vec3[2] + ) + .fetch_one(&mut **transaction) + .await? + .id; - return Ok(id); + return Ok(id); } pub async fn store_quaternion( - vec4: [f32; 4usize], - transaction: &mut Transaction<'_, Postgres>, + vec4: [f32; 4usize], + transaction: &mut Transaction<'_, Postgres>, ) -> Result { - let id = sqlx::query!( - "INSERT INTO data_quaternion + let id = sqlx::query!( + "INSERT INTO data_quaternion (x, y, z, w) VALUES ($1, $2, $3, $4) RETURNING id", - vec4[0], - vec4[1], - vec4[2], - vec4[3] - ) - .fetch_one(&mut **transaction) - .await? - .id; + vec4[0], + vec4[1], + vec4[2], + vec4[3] + ) + .fetch_one(&mut **transaction) + .await? + .id; - return Ok(id); -} \ No newline at end of file + return Ok(id); +} diff --git a/hydra_provider/src/database_service/hydra_input/messages/state.rs b/hydra_provider/src/database_service/hydra_input/messages/state.rs index 322f0200..c35af349 100644 --- a/hydra_provider/src/database_service/hydra_input/messages/state.rs +++ b/hydra_provider/src/database_service/hydra_input/messages/state.rs @@ -1,21 +1,21 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; -use messages::state::State; use crate::database_service::hydra_input::saveable::SaveableData; +use messages::state::State; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for State { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - rocket_message_id: i32, - ) -> Result { - query!( - "INSERT INTO rocket_state + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result { + query!( + "INSERT INTO rocket_state (rocket_message_id, state) VALUES ($1, $2)", - rocket_message_id, - format!("{:?}", *self) - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file + rocket_message_id, + format!("{:?}", *self) + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/mod.rs b/hydra_provider/src/database_service/hydra_input/mod.rs index 7e6c5215..b41844cb 100644 --- a/hydra_provider/src/database_service/hydra_input/mod.rs +++ b/hydra_provider/src/database_service/hydra_input/mod.rs @@ -1,4 +1,4 @@ -pub mod saveable; -pub mod messages; pub mod heart_beat; +pub mod messages; pub mod radio_status; +pub mod saveable; diff --git a/hydra_provider/src/database_service/hydra_input/radio_status.rs b/hydra_provider/src/database_service/hydra_input/radio_status.rs index ee35d05f..31ee11b1 100644 --- a/hydra_provider/src/database_service/hydra_input/radio_status.rs +++ b/hydra_provider/src/database_service/hydra_input/radio_status.rs @@ -1,26 +1,26 @@ -use sqlx::{query, Postgres, Transaction, postgres::PgQueryResult, Error}; use super::saveable::SaveableData; use messages::mavlink::uorocketry::RADIO_STATUS_DATA; +use sqlx::{postgres::PgQueryResult, query, Error, Postgres, Transaction}; impl SaveableData for RADIO_STATUS_DATA { - async fn save( - &self, - transaction: &mut Transaction<'_, Postgres>, - _: i32 - ) -> Result { - query!( - "INSERT INTO rocket_radio_status + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + _: i32, + ) -> Result { + query!( + "INSERT INTO rocket_radio_status (rxerrors, fixed, rssi, remrssi, txbuf, noise, remnoise) VALUES ($1, $2, $3, $4, $5, $6, $7)", - self.rxerrors as i32, - self.fixed as i32, - self.rssi as i32, - self.remrssi as i32, - self.txbuf as i32, - self.noise as i32, - self.remnoise as i32, - ) - .execute(&mut **transaction) - .await - } -} \ No newline at end of file + self.rxerrors as i32, + self.fixed as i32, + self.rssi as i32, + self.remrssi as i32, + self.txbuf as i32, + self.noise as i32, + self.remnoise as i32, + ) + .execute(&mut **transaction) + .await + } +} diff --git a/hydra_provider/src/database_service/hydra_input/saveable.rs b/hydra_provider/src/database_service/hydra_input/saveable.rs index 208d1d71..bd1bc4f6 100644 --- a/hydra_provider/src/database_service/hydra_input/saveable.rs +++ b/hydra_provider/src/database_service/hydra_input/saveable.rs @@ -1,7 +1,10 @@ -use sqlx::{Postgres, Transaction, Error}; use sqlx::postgres::PgQueryResult; - +use sqlx::{Error, Postgres, Transaction}; pub trait SaveableData { - async fn save(&self, transaction: &mut Transaction<'_, Postgres>, rocket_message_id: i32) -> Result; + async fn save( + &self, + transaction: &mut Transaction<'_, Postgres>, + rocket_message_id: i32, + ) -> Result; } diff --git a/hydra_provider/src/database_service/mod.rs b/hydra_provider/src/database_service/mod.rs index 0598e9df..356c9d60 100644 --- a/hydra_provider/src/database_service/mod.rs +++ b/hydra_provider/src/database_service/mod.rs @@ -1,4 +1,4 @@ -pub mod service; pub mod hydra_input; +pub mod service; -pub use service::DatabaseService; \ No newline at end of file +pub use service::DatabaseService; diff --git a/hydra_provider/src/database_service/service.rs b/hydra_provider/src/database_service/service.rs index e1090db2..ec9daa0e 100644 --- a/hydra_provider/src/database_service/service.rs +++ b/hydra_provider/src/database_service/service.rs @@ -1,37 +1,37 @@ -use std::sync::Arc; use sqlx::PgPool; +use std::sync::Arc; -use crate::hydra_input::HydraInput; use crate::database_service::hydra_input::saveable::SaveableData; +use crate::hydra_input::HydraInput; pub struct DatabaseService { - pool: Arc, + pool: Arc, } impl DatabaseService { - pub async fn new(address: &str) -> DatabaseService { - DatabaseService { - pool: Arc::new(PgPool::connect(address).await.unwrap()), - } - } + pub async fn new(address: &str) -> DatabaseService { + DatabaseService { + pool: Arc::new(PgPool::connect(address).await.unwrap()), + } + } - pub async fn save(&self, hydra_input: HydraInput) -> Result<(), sqlx::Error> { - let mut transaction = self.pool.begin().await.unwrap(); - let result = match hydra_input { - HydraInput::Heartbeat(message) => message.save(&mut transaction, 0).await, - HydraInput::RadioStatus(message) => message.save(&mut transaction, 0).await, - HydraInput::Message(message) => message.save(&mut transaction, 0).await - }; + pub async fn save(&self, hydra_input: HydraInput) -> Result<(), sqlx::Error> { + let mut transaction = self.pool.begin().await.unwrap(); + let result = match hydra_input { + HydraInput::Heartbeat(message) => message.save(&mut transaction, 0).await, + HydraInput::RadioStatus(message) => message.save(&mut transaction, 0).await, + HydraInput::Message(message) => message.save(&mut transaction, 0).await, + }; - match result { - Ok(_) => transaction.commit().await, - Err(error) => { - let rollback_result = transaction.rollback().await; - if rollback_result.is_err() { - return rollback_result; - } - Err(error) - } - } - } -} \ No newline at end of file + match result { + Ok(_) => transaction.commit().await, + Err(error) => { + let rollback_result = transaction.rollback().await; + if rollback_result.is_err() { + return rollback_result; + } + Err(error) + } + } + } +} diff --git a/hydra_provider/src/hydra_input.rs b/hydra_provider/src/hydra_input.rs index 694324f2..78e96b7b 100644 --- a/hydra_provider/src/hydra_input.rs +++ b/hydra_provider/src/hydra_input.rs @@ -1,11 +1,11 @@ use derive_more::From; use messages::mavlink::uorocketry::{HEARTBEAT_DATA, RADIO_STATUS_DATA}; -use serde::{Deserialize, Serialize}; use messages::Message; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, From)] pub enum HydraInput { - Message(Message), - RadioStatus(RADIO_STATUS_DATA), - Heartbeat(HEARTBEAT_DATA), + Message(Message), + RadioStatus(RADIO_STATUS_DATA), + Heartbeat(HEARTBEAT_DATA), } diff --git a/hydra_provider/src/main.rs b/hydra_provider/src/main.rs index a5ffe1bc..93ec309d 100644 --- a/hydra_provider/src/main.rs +++ b/hydra_provider/src/main.rs @@ -1,7 +1,7 @@ -mod database_service; +mod bootstrap; mod command_service; mod data_feed_service; -mod bootstrap; +mod database_service; mod hydra_input; mod utils; @@ -13,24 +13,21 @@ use clap::Parser; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct CliArgs { - // Port to serve the gRPC server on - #[arg(short, long, default_value_t = 3000)] - port: u32, + // Port to serve the gRPC server on + #[arg(short, long, default_value_t = 3000)] + port: u32, - // Postgres DB Address - #[arg( + // Postgres DB Address + #[arg( short, long = "db", default_value_t = String::from_str("postgres://postgres:postgres@localhost:5432/postgres").unwrap() )] - database_address: String, + database_address: String, } #[tokio::main] async fn main() -> Result<(), tonic::transport::Error> { - let args = CliArgs::parse(); - bootstrap( - args.port, - args.database_address - ).await + let args = CliArgs::parse(); + bootstrap(args.port, args.database_address).await } diff --git a/hydra_provider/src/utils/logging.rs b/hydra_provider/src/utils/logging.rs index caf5385c..f2971846 100644 --- a/hydra_provider/src/utils/logging.rs +++ b/hydra_provider/src/utils/logging.rs @@ -1,15 +1,14 @@ use chrono::Local; use tonic::{Request, Status}; - // Interceptor to log every request received by the server pub fn log_request(request: Request<()>) -> Result, Status> { - let timestmap = Local::now().format("[%Y-%m-%d][%H:%M:%S]"); + let timestmap = Local::now().format("[%Y-%m-%d][%H:%M:%S]"); - // SHOULD DO: better logging as Request gRPC method is not shown here - // https://github.com/hyperium/tonic/issues/300 - // https://github.com/hyperium/tonic/issues/430 + // SHOULD DO: better logging as Request gRPC method is not shown here + // https://github.com/hyperium/tonic/issues/300 + // https://github.com/hyperium/tonic/issues/430 - println!("{} Request Received: {:?}", timestmap, request); - Ok(request) + println!("{} Request Received: {:?}", timestmap, request); + Ok(request) } diff --git a/hydra_provider/src/utils/mod.rs b/hydra_provider/src/utils/mod.rs index cdb11a39..31348d2f 100644 --- a/hydra_provider/src/utils/mod.rs +++ b/hydra_provider/src/utils/mod.rs @@ -1 +1 @@ -pub mod logging; \ No newline at end of file +pub mod logging;