Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Argus update #4

Merged
merged 16 commits into from
Oct 26, 2024
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ jobs:
name: "Run Host Tests"
with:
command: make
args: test-messages
args: test


10 changes: 8 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
name = "messages"
path = "src/lib.rs"

[dependencies]
derive_more = "0.99.17"
serde = {version = "1.0.150", default-features = false, features = ["derive"]}
Expand All @@ -17,14 +21,16 @@ mavlink = { git = "https://github.com/uorocketry/rust-mavlink.git", features = [
bitflags = { version = "2.3.1", features = ["serde"] }
proptest = { version = "1.2.0", optional = true }
proptest-derive = { version = "0.3.0", optional = true }
proptest-arbitrary-interop = { version = "0.1.0", optional = true }
messages-proc-macros-lib = { path = "messages-proc-macros-lib" }
chrono = {version = "0.4.0", features = ["serde"], default-features = false}
chrono = { git = "https://github.com/uorocketry/chrono", features = ["serde", "arbitrary"], default-features = false}

[dev-dependencies]
proptest = "1.2.0"
proptest-derive = "0.3.0"
postcard = { version = "1.0.4", features = ["alloc"] }
proptest-arbitrary-interop = "0.1.0"

[features]
default = ["mavlink/embedded-hal-02", "mavlink/uorocketry"]
std = ["chrono/std", "mavlink/std", "mavlink/tcp", "mavlink/udp", "mavlink/direct-serial", "mavlink/serde", "dep:proptest", "dep:proptest-derive"]
std = ["chrono/std", "mavlink/std", "mavlink/tcp", "mavlink/udp", "mavlink/direct-serial", "mavlink/serde", "dep:proptest-arbitrary-interop", "dep:proptest", "dep:proptest-derive"]
9 changes: 2 additions & 7 deletions Makefile.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
[env]
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true

[config]
default_to_workspace = false

# -----------------------
# Host Testing
# -----------------------

[tasks.test-messages]
[tasks.test]
command = "cargo"
args = ["test", "-p", "messages", "--target", "${CARGO_MAKE_RUST_TARGET_TRIPLE}", "--features", "std", "--no-default-features"]
args = ["test", "--target", "${CARGO_MAKE_RUST_TARGET_TRIPLE}", "--features", "std", "--no-default-features"]
env = {RUST_MIN_STACK = "8388608"}
4 changes: 1 addition & 3 deletions messages-proc-macros-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ use quote::quote;
pub fn common_derives(args: TokenStream, input: TokenStream) -> TokenStream {
let mut output = TokenStream::from(quote! {
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
#[cfg_attr(feature = "ts", ts(export))]
#[cfg_attr(std, derive(proptest_derive::Arbitrary))]
#[cfg_attr(all(feature = "std", test), derive(proptest_derive::Arbitrary))]
});

// Allow to omit the defmt::Format derive. Useful if this should be manually implemented.
Expand Down
9 changes: 9 additions & 0 deletions proptest-regressions/lib.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 61b4824c090c01db4b55ba9e9fcc0fb7bbb6843574b2b802fbc377e8f839c62d # shrinks to msg = Message { timestamp: FormattedNaiveDateTime(-0001-01-01T00:00:00.000000001), node: PressureBoard, data: Sensor(Sensor { data: EkfNavAcc(EkfNavAcc { status: EkfStatus { status: 268435456 }, velocity_std_dev: Some([0.0, 0.0, 0.0]), position_std_dev: Some([-0.0, 0.0, 0.0]) }) }) }
cc 1b5e64b2da76dcb68777a6b6564de7a77d5f4b6ab26e1f36432e2df7d11f828b # shrinks to msg = Message { timestamp: FormattedNaiveDateTime(0000-01-01T00:00:00.000000001), node: PressureBoard, data: Sensor(Sensor { component_id: 0, data: Imu2(Imu2 { temperature: Some(0.0), delta_velocity: Some([0.0, 0.0, 0.0]), delta_angle: Some([0.0, 0.0, 0.0]) }) }) }
cc dba5d5b40143101de3363dadb069654a4e5b62704479ee3824b993edba0b0efd # shrinks to msg = Message { timestamp: FormattedNaiveDateTime(0000-01-01T00:00:00), node: PressureBoard, data: Sensor(Sensor { component_id: 0, data: SbgData(EkfQuat(EkfQuat { time_stamp: 268435456, quaternion: Some([0.0, 0.0, 0.0, 0.0]), euler_std_dev: Some([0.0, 0.0, 0.0]), status: EkfStatus { status: 268435456 } })) }) }
49 changes: 39 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
#![no_main]

//! # Messages
//!
Expand All @@ -10,10 +9,11 @@ use crate::command::Command;
use crate::node::Node;
use crate::sensor::Sensor;
use crate::state::State;
use chrono::NaiveDateTime;
use derive_more::From;
/// This is to help control versions.
pub use mavlink;
use chrono::NaiveDateTime;

use messages_proc_macros_lib::common_derives;

pub mod command;
Expand All @@ -23,15 +23,28 @@ pub mod sensor;
pub mod sensor_status;
pub mod state;

pub const MAX_SIZE: usize = 64;
pub const MAX_SIZE_CAN: usize = 64;
pub const MAX_SIZE_RADIO: usize = 255;

use defmt::Format;
pub use logging::{ErrorContext, Event, Log, LogLevel};

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[cfg_attr(all(feature = "std", test), derive(proptest_derive::Arbitrary))]
pub struct FormattedNaiveDateTime(pub NaiveDateTime);

impl Format for FormattedNaiveDateTime {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "");
}
}

/// Topmost message. Encloses all the other possible messages, and is the only thing that should
/// be sent over the wire.
#[common_derives(NoFormat)]
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[cfg_attr(all(feature = "std", test), derive(proptest_derive::Arbitrary))]
pub struct Message {
pub timestamp: NaiveDateTime,
pub timestamp: FormattedNaiveDateTime,

/// The original sender of this message.
pub node: Node,
Expand All @@ -51,7 +64,7 @@ pub enum Data {
}

impl Message {
pub fn new(timestamp: NaiveDateTime, node: Node, data: impl Into<Data>) -> Self {
pub fn new(timestamp: FormattedNaiveDateTime, node: Node, data: impl Into<Data>) -> Self {
Message {
timestamp,
node,
Expand All @@ -60,18 +73,34 @@ impl Message {
}
}

#[cfg(test)]
#[cfg(all(test, feature = "std"))]
mod test {
use crate::{Message, MAX_SIZE};
use crate::{Message, MAX_SIZE_CAN, MAX_SIZE_RADIO};
use proptest::prelude::*;

proptest! {
#[test]
fn message_size(msg: Message) {
let bytes = postcard::to_allocvec(&msg).unwrap();

dbg!(msg);
assert!(dbg!(bytes.len()) <= MAX_SIZE);
dbg!(msg.clone());

match msg.data {
crate::Data::Sensor(sensor) => {
match sensor.data {
crate::sensor::SensorData::SbgData(_) => {
assert!(bytes.len() <= MAX_SIZE_RADIO);
}
_ => {
assert!(bytes.len() <= MAX_SIZE_CAN);
}
}
}
_ => {
assert!(bytes.len() <= MAX_SIZE_CAN);
}

}
}
}
}
2 changes: 1 addition & 1 deletion src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use messages_proc_macros_lib::common_derives;
pub enum Node {
PressureBoard,
TemperatureBoard,
StrainBoard,
StrainBoard,
}

impl From<Node> for u16 {
Expand Down
29 changes: 24 additions & 5 deletions src/sensor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,35 @@ use messages_proc_macros_lib::common_derives;
#[common_derives]
pub struct Sensor {
/// Used to differentiate between multiple components on the same sender. Unused right now.
// pub component_id: u8,
pub component_id: u8,
pub data: SensorData,
}

#[common_derives]
#[derive(From)]
pub enum SensorData {
// UtcTime(UtcTime),
// Air(Air),
// EkfQuat(EkfQuat),
// EkfNav1(EkfNav1),
// EkfNav2(EkfNav2),
// EkfNavAcc(EkfNavAcc),
// Imu1(Imu1),
// Imu2(Imu2),
NavPosLlh(NavPosLlh),
// GpsVel(GpsVel),
// GpsVelAcc(GpsVelAcc),
// GpsPos1(GpsPos1),
// GpsPos2(GpsPos2),
// GpsPosAcc(GpsPosAcc),
ResetReason(ResetReason),
RecoverySensing(RecoverySensing),
SbgData(SbgData),
}

#[common_derives]
#[derive(From)]
pub enum SbgData {
UtcTime(UtcTime),
Air(Air),
EkfQuat(EkfQuat),
Expand All @@ -22,14 +44,11 @@ pub enum SensorData {
EkfNavAcc(EkfNavAcc),
Imu1(Imu1),
Imu2(Imu2),
NavPosLlh(NavPosLlh),
GpsVel(GpsVel),
GpsVelAcc(GpsVelAcc),
GpsPos1(GpsPos1),
GpsPos2(GpsPos2),
GpsPosAcc(GpsPosAcc),
ResetReason(ResetReason),
RecoverySensing(RecoverySensing),
}

#[common_derives]
Expand Down Expand Up @@ -245,7 +264,7 @@ pub struct RecoverySensing {
impl Sensor {
pub fn new(data: impl Into<SensorData>) -> Self {
Sensor {
// component_id: 0,
component_id: 0,
data: data.into(),
}
}
Expand Down
Loading