diff --git a/Cargo.lock b/Cargo.lock index 1e8017a..5f2187c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,17 +17,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if 1.0.4", - "cipher", - "cpufeatures 0.2.17", -] - [[package]] name = "ahash" version = "0.8.12" @@ -66,12 +55,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - [[package]] name = "anstream" version = "1.0.0" @@ -377,12 +360,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" -[[package]] -name = "assert_approx_eq" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c07dab4369547dbe5114677b33fbbf724971019f3818172d59a97a61c774ffd" - [[package]] name = "async-channel" version = "2.5.0" @@ -519,12 +496,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64ct" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - [[package]] name = "bigdecimal" version = "0.4.10" @@ -581,7 +552,7 @@ dependencies = [ "arrayvec", "cc", "cfg-if 1.0.4", - "constant_time_eq 0.4.2", + "constant_time_eq", "cpufeatures 0.3.0", ] @@ -677,26 +648,6 @@ dependencies = [ "bytes", ] -[[package]] -name = "bzip2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" -dependencies = [ - "cc", - "pkg-config", -] - [[package]] name = "camino" version = "1.2.2" @@ -708,9 +659,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082" +checksum = "dd0061da739915fae12ea00e16397555ed4371a6bb285431aab930f61b0aa4ba" dependencies = [ "serde", "serde_core", @@ -730,12 +681,6 @@ dependencies = [ "thiserror 2.0.18", ] -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - [[package]] name = "cc" version = "1.2.60" @@ -853,43 +798,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "clang" version = "2.0.0" @@ -912,9 +820,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -934,9 +842,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -956,6 +864,19 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaa6b4b263a5d737e9bf6b7c09b72c41a5480aec4d7219af827f6564e950b6a5" +[[package]] +name = "color-eyre" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d" +dependencies = [ + "backtrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", +] + [[package]] name = "colorchoice" version = "1.0.5" @@ -1028,11 +949,12 @@ dependencies = [ [[package]] name = "const_format" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" dependencies = [ "const_format_proc_macros", + "konst", ] [[package]] @@ -1046,12 +968,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "constant_time_eq" version = "0.4.2" @@ -1119,44 +1035,6 @@ dependencies = [ "cfg-if 1.0.4", ] -[[package]] -name = "criterion" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap", - "criterion-plot", - "futures", - "is-terminal", - "itertools 0.10.5", - "num-traits", - "once_cell", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "tokio", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools 0.10.5", -] - [[package]] name = "cros-codecs" version = "0.0.6" @@ -2222,21 +2100,20 @@ dependencies = [ ] [[package]] -name = "fastrand" -version = "2.4.1" +name = "eyre" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] [[package]] -name = "filetime" -version = "0.2.27" +name = "fastrand" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" -dependencies = [ - "cfg-if 1.0.4", - "libc", - "libredox", -] +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "find-msvc-tools" @@ -2575,12 +2452,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - [[package]] name = "hex" version = "0.4.3" @@ -2593,15 +2464,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5491a308e0214554f07a81d8944abe45f552871c12e3c3c6e7e5d354039a6c4c" -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - [[package]] name = "http" version = "1.4.0" @@ -2863,6 +2725,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9f1a0777d972970f204fdf8ef319f1f4f8459131636d7e3c96c5d59570d0fa6" +[[package]] +name = "indenter" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + [[package]] name = "indexmap" version = "1.9.3" @@ -2908,15 +2776,6 @@ dependencies = [ "cfb", ] -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - [[package]] name = "io-extras" version = "0.18.4" @@ -2961,17 +2820,6 @@ dependencies = [ "serde", ] -[[package]] -name = "is-terminal" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.61.2", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -3099,6 +2947,21 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "lazy_static" version = "1.5.0" @@ -3192,10 +3055,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags 2.11.1", "libc", - "plain", - "redox_syscall 0.7.4", ] [[package]] @@ -3218,9 +3078,9 @@ checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "local-ip-address" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a59a0cb1c7f84471ad5cd38d768c2a29390d17f1ff2827cdf49bc53e8ac70b" +checksum = "d7b0187df4e614e42405b49511b82ff7a1774fbd9a816060ee465067847cac22" dependencies = [ "libc", "neli", @@ -3710,12 +3570,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "oorandom" -version = "11.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" - [[package]] name = "opencv" version = "0.94.4" @@ -3763,6 +3617,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "owo-colors" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" + [[package]] name = "parking" version = "2.2.1" @@ -3787,40 +3647,17 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if 1.0.4", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link 0.2.1", ] -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest", - "hmac", - "password-hash", - "sha2", -] - [[package]] name = "peg" version = "0.8.5" @@ -3892,7 +3729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared 0.11.3", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -3966,40 +3803,6 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - -[[package]] -name = "plotters" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" - -[[package]] -name = "plotters-svg" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" -dependencies = [ - "plotters-backend", -] - [[package]] name = "ply-rs-bw" version = "3.0.0" @@ -4120,9 +3923,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] @@ -4261,9 +4064,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "rand_core 0.6.4", ] @@ -5171,15 +4974,6 @@ dependencies = [ "bitflags 2.11.1", ] -[[package]] -name = "redox_syscall" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" -dependencies = [ - "bitflags 2.11.1", -] - [[package]] name = "redox_users" version = "0.5.2" @@ -5452,9 +5246,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.12" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "ring", "rustls-pki-types", @@ -5718,17 +5512,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if 1.0.4", - "cpufeatures 0.2.17", - "digest", -] - [[package]] name = "sha2" version = "0.10.9" @@ -5921,35 +5704,26 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" name = "sw9s" version = "0.1.0" dependencies = [ - "anyhow", - "assert_approx_eq", "bluerobotics-ping", "bytes", - "cc", "chrono", - "criterion", + "color-eyre", "derive-getters", - "flate2", "futures", "itertools 0.13.0", "num-traits", "opencv", - "proc-macro2", - "quote", - "rayon", "rerun", "ros2-client", "ros2-interfaces-jazzy-serde", "serde", "serde_json", - "syn 2.0.117", - "tar", + "thiserror 2.0.18", "tokio", "tokio-serial", "tokio-util", "toml", "uuid", - "zip-extract", ] [[package]] @@ -6011,17 +5785,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "tar" -version = "0.4.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" -dependencies = [ - "filetime", - "libc", - "xattr", -] - [[package]] name = "tempfile" version = "3.27.0" @@ -6137,21 +5900,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "tokio" -version = "1.52.0" +version = "1.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776" +checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" dependencies = [ "bytes", "libc", @@ -6441,9 +6194,9 @@ checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "unescaper" @@ -6545,9 +6298,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -6605,11 +6358,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.57.1", ] [[package]] @@ -6618,7 +6371,7 @@ version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.51.0", ] [[package]] @@ -6749,14 +6502,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.6", + "webpki-roots 1.0.7", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" dependencies = [ "rustls-pki-types", ] @@ -7186,6 +6939,12 @@ dependencies = [ "wit-bindgen-rust-macro", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "wit-bindgen-core" version = "0.51.0" @@ -7281,16 +7040,6 @@ dependencies = [ "winapi-build", ] -[[package]] -name = "xattr" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" -dependencies = [ - "libc", - "rustix", -] - [[package]] name = "xxhash-rust" version = "0.8.15" @@ -7400,67 +7149,8 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "aes", - "byteorder", - "bzip2", - "constant_time_eq 0.1.5", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "pbkdf2", - "sha1", - "zstd", -] - -[[package]] -name = "zip-extract" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e109e5a291403b4c1e514d39f8a22d3f98d257e691a52bb1f16051bb1ffed63e" -dependencies = [ - "log", - "thiserror 1.0.69", - "zip", -] - [[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml index 61d31f9..763513b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,6 @@ annotated_streams = ["logging"] opencv = { version = "0.94.2", default-features = false, features = ["dnn", "imgcodecs", "imgproc", "videoio", "cudaimgproc", "cudafilters"], optional = true } # Vision processing tokio-serial = "5.4.1" # Async serial comms tokio = { version = "1.38.0", features = ["full"] } # Async runtime -anyhow = "1.0.86" # Error handling itertools = "0.13.0" # Enhance iterators num-traits = "0.2.19" # Numeric generics derive-getters = "0.4.0" # Getter macro @@ -46,22 +45,6 @@ serde_json = "1.0.140" tokio-util = { version = "0.7.15" } ros2-client = "0.8.2" ros2-interfaces-jazzy-serde = { version = "0.0.4", features = ["sensor_msgs"] } +thiserror = "2.0.18" +color-eyre = { version = "0.6.5", default-features = false } rerun = { version = "0.29.2", default-features = false, features = ["sdk", "server", "ecolor"] } - -[build-dependencies] -quote = { version = "1.0.36", optional = true } -syn = { version = "2.0.68", features = ["full", "fold"], optional = true } -proc-macro2 = { version = "1.0.86", optional = true } -cc = { version = "1.0.99", optional = true } - -[dev-dependencies] -assert_approx_eq = "1.1.0" # Floating point eq -criterion = { version = "0.5.1", features = ["async_tokio"] } # Benchmarking -rayon = "1.10.0" - -[target.'cfg(target_os = "linux")'.dev-dependencies] -flate2 = "1.0.30" # Decompressing gz -tar = "0.4.40" # Unpacking tar - -[target.'cfg(not(target_os = "linux"))'.dev-dependencies] -zip-extract = "0.1.3" # Decompressing zip diff --git a/src/comms/auv_control_board/mod.rs b/src/comms/auv_control_board/mod.rs index ab47c40..9dc5804 100644 --- a/src/comms/auv_control_board/mod.rs +++ b/src/comms/auv_control_board/mod.rs @@ -1,12 +1,18 @@ +//! Low-level implementation of the [AUVControlBoard] communication protocol +//! +//! The high-level messaging specification is implemented in the [control_board](crate::comms::control_board) module +//! +//! [AUVControlBoard]: https://github.com/ncsurobotics/AUVControlBoard + use core::fmt::Debug; use std::sync::Arc; -use anyhow::Result; use tokio::{io::AsyncWriteExt, sync::Mutex}; -use self::util::{crc_itt16_false, AcknowledgeErr}; - -use super::auv_control_board::util::{END_BYTE, ESCAPE_BYTE, START_BYTE}; +use crate::comms::{ + auv_control_board::util::{crc_itt16_false, AcknowledgeErr, END_BYTE, ESCAPE_BYTE, START_BYTE}, + control_board::util::Result, +}; pub mod response; pub mod util; diff --git a/src/comms/auv_control_board/response.rs b/src/comms/auv_control_board/response.rs index 5d89d7e..02e3596 100644 --- a/src/comms/auv_control_board/response.rs +++ b/src/comms/auv_control_board/response.rs @@ -1,3 +1,4 @@ +//! Response parsing use bytes::BufMut; use tokio::io::AsyncReadExt; @@ -194,7 +195,7 @@ mod tests { ) .collect::>>() .await, - vec![vec![]] + Vec::>::new() ); assert_eq!( diff --git a/src/comms/auv_control_board/util.rs b/src/comms/auv_control_board/util.rs index 1e4fc32..b571c62 100644 --- a/src/comms/auv_control_board/util.rs +++ b/src/comms/auv_control_board/util.rs @@ -1,5 +1,7 @@ +//! Helper utilities for communicating with the control board +//! // Implementing -use std::{error::Error, fmt::Display}; +use thiserror::Error; pub const START_BYTE: u8 = 253; pub const END_BYTE: u8 = 254; @@ -38,23 +40,20 @@ pub fn crc_itt16_false(bytes: &[u8]) -> u16 { crc } -#[derive(Debug)] +#[derive(Error, Debug)] pub enum AcknowledgeErr { + #[error("unknown message")] UnknownMsg, + #[error("invalid arguments")] InvalidArguments, + #[error("invalid command")] InvalidCommand, + #[error("reserved")] Reserved, + #[error("undefined: '{0}'")] Undefined(u8), } -impl Display for AcknowledgeErr { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{self:?}") - } -} - -impl Error for AcknowledgeErr {} - impl From for AcknowledgeErr { fn from(value: u8) -> Self { match value { diff --git a/src/comms/control_board/mod.rs b/src/comms/control_board/mod.rs index d7cd4ee..3b1fdd9 100644 --- a/src/comms/control_board/mod.rs +++ b/src/comms/control_board/mod.rs @@ -1,7 +1,12 @@ +//! High-level implementation of the [AUVControlBoard] messaging specification +//! +//! The underlying communication protocol is implemented in the [auv_control_board](crate::comms::auv_control_board) module +//! +//! [AUVControlBoard]: https://github.com/ncsurobotics/AUVControlBoard + use core::fmt::Debug; use std::{ops::Deref, sync::Arc, time::Duration}; -use anyhow::{anyhow, bail, Result}; use tokio::{ io::{self, AsyncRead, AsyncWrite, AsyncWriteExt, WriteHalf}, net::TcpStream, @@ -12,7 +17,8 @@ use tokio_serial::{DataBits, Parity, SerialStream, StopBits}; use self::{ response::ResponseMap, - util::{Angles, BNO055AxisConfig}, + util::{Angles, BNO055AxisConfig, ControlBoardError, Result}, + vehicle_definition::{MotorMatrix, PidAxes, VehicleDefinition}, }; use super::auv_control_board::{AUVControlBoard, MessageId}; @@ -20,15 +26,22 @@ use crate::logln; pub mod response; pub mod util; +pub mod vehicle_definition; +/// Status of the control board's sensors pub enum SensorStatuses { + /// IMU ready ImuNr, + /// Depth sensor ready DepthNr, + /// Sensors healthy AllGood, } +/// The last yaw reported by the control board pub static LAST_YAW: std::sync::Mutex> = std::sync::Mutex::new(None); +/// Represents a control board #[derive(Debug)] pub struct ControlBoard where @@ -46,14 +59,15 @@ impl Deref for ControlBoard { } impl ControlBoard { - pub async fn new(comm_out: T, comm_in: U, msg_id: Option) -> Result + pub async fn new( + comm_out: T, + comm_in: U, + msg_id: Option, + vehicle_defintion: &VehicleDefinition, + ) -> Result where U: 'static + AsyncRead + Unpin + Send, { - const THRUSTER_INVS: [bool; 8] = [true, true, false, false, true, false, false, true]; - #[allow(clippy::approx_constant)] - const DOF_SPEEDS: [f32; 6] = [0.7071, 0.7071, 1.0, 0.4413, 1.0, 0.8139]; - let msg_id = msg_id.unwrap_or_default(); let responses = ResponseMap::new(comm_in).await; let this = Self { @@ -61,9 +75,11 @@ impl ControlBoard { initial_angles: Arc::default(), }; - this.init_matrices().await?; - this.thruster_inversion_set(&THRUSTER_INVS).await?; - this.relative_dof_speed_set_batch(&DOF_SPEEDS).await?; + this.init_matrices(&vehicle_defintion.motor_matrix).await?; + this.thruster_inversion_set(&vehicle_defintion.thruster_inversions) + .await?; + this.relative_dof_speed_set_batch(&vehicle_defintion.dof_speeds) + .await?; this.bno055_imu_axis_config(BNO055AxisConfig::P6).await?; loop { @@ -76,7 +92,7 @@ impl ControlBoard { // Control board needs time to get its life together sleep(Duration::from_secs(5)).await; - this.stab_tune().await?; + this.stab_tune(&vehicle_defintion.pid_axes).await?; let inner_clone = this.inner.clone(); @@ -103,41 +119,36 @@ impl ControlBoard { Ok(this) } - async fn init_matrices(&self) -> Result<()> { - self.motor_matrix_set(3, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0) - .await?; - self.motor_matrix_set(4, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0) - .await?; - self.motor_matrix_set(1, -1.0, 1.0, 0.0, 0.0, 0.0, -1.0) - .await?; - self.motor_matrix_set(2, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0) - .await?; - self.motor_matrix_set(7, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0) - .await?; - self.motor_matrix_set(8, 0.0, 0.0, -1.0, -1.0, 1.0, 0.0) - .await?; - self.motor_matrix_set(5, 0.0, 0.0, -1.0, 1.0, -1.0, 0.0) - .await?; - self.motor_matrix_set(6, 0.0, 0.0, -1.0, 1.0, 1.0, 0.0) - .await?; + async fn init_matrices(&self, motor_matrix: &MotorMatrix) -> Result<()> { + for (i, _row) in motor_matrix.0.iter().enumerate() { + // If the row is defined for the thruster, then set it + if let Some(row) = _row { + self.motor_matrix_set(i as u8, row.x, row.y, row.z, row.pitch, row.roll, row.yaw) + .await?; + } + } self.motor_matrix_update().await } - async fn stab_tune(&self) -> Result<()> { - self.stability_assist_pid_tune('X', 0.8, 0.0, 0.0, 0.6, false) - .await?; - self.stability_assist_pid_tune('Y', 2.0, 0.0, 0.0, 0.1, false) + async fn stab_tune(&self, axes: &PidAxes) -> Result<()> { + for axis in axes { + self.stability_assist_pid_tune( + axis.which, + axis.kp, + axis.ki, + axis.kd, + axis.limit, + axis.invert, + ) .await?; - self.stability_assist_pid_tune('Z', 4.0, 0.0, 0.0, 1.0, false) - .await?; - self.stability_assist_pid_tune('D', 1.5, 0.0, 0.0, 1.0, false) - .await + } + Ok(()) } } impl ControlBoard> { - pub async fn serial(port_name: &str) -> Result { + pub async fn serial(port_name: &str, vehicle_defintion: &VehicleDefinition) -> Result { const BAUD_RATE: u32 = 9600; const DATA_BITS: DataBits = DataBits::Eight; const PARITY: Parity = Parity::None; @@ -148,14 +159,19 @@ impl ControlBoard> { .parity(PARITY) .stop_bits(STOP_BITS); let (comm_in, comm_out) = io::split(SerialStream::open(&port_builder)?); - Self::new(comm_out, comm_in, None).await + Self::new(comm_out, comm_in, None, vehicle_defintion).await } } impl ControlBoard> { /// Both connections are necessary for the simulator to run, /// but the one that doesn't feed forward to control board is unnecessary - pub async fn tcp(host: &str, port: &str, dummy_port: String) -> Result { + pub async fn tcp( + host: &str, + port: &str, + dummy_port: String, + vehicle_defintion: VehicleDefinition, + ) -> Result { let host = host.to_string(); let host_clone = host.clone(); tokio::spawn(async move { @@ -170,7 +186,7 @@ impl ControlBoard> { let stream = TcpStream::connect(host.to_string() + ":" + port).await?; let (comm_in, comm_out) = io::split(stream); - Self::new(comm_out, comm_in, None).await + Self::new(comm_out, comm_in, None, &vehicle_defintion).await } } @@ -199,7 +215,7 @@ impl ControlBoard { message.extend(MOTOR_MATRIX_SET); if !(1..=8).contains(&thruster) { - bail!("{thruster} is outside the allowed range 1-8.") + return Err(ControlBoardError::ThrusterIndexing(thruster)); }; message.extend(thruster.to_le_bytes()); @@ -219,7 +235,7 @@ impl ControlBoard { /// /// # Arguments: /// * `inversions` - Array of invert statuses, with motor 1 at index 0 - pub async fn thruster_inversion_set(&self, inversions: &[bool; 8]) -> Result<()> { + pub async fn thruster_inversion_set(&self, inversions: &Vec) -> Result<()> { const THRUSTER_INVERSION_SET: [u8; 4] = *b"TINV"; let mut message = Vec::from(THRUSTER_INVERSION_SET); @@ -351,7 +367,7 @@ impl ControlBoard { None => { self.set_initial_angle().await?; let angle = - (*self.initial_angles.lock().await).ok_or(anyhow!("Initial Yaw set Error"))?; + (*self.initial_angles.lock().await).ok_or(ControlBoardError::InitialYawSet)?; *angle.yaw() } }; @@ -419,7 +435,7 @@ impl ControlBoard { message.extend(STAB_TUNE); if !['X', 'Y', 'Z', 'D'].contains(&which) { - bail!("{which} is not a valid PID tune, pick from [X, Y, Z, D]") + return Err(ControlBoardError::InvalidPidTuneAxis(which)); } message.push(which as u8); diff --git a/src/comms/control_board/response.rs b/src/comms/control_board/response.rs index 6264836..90a5394 100644 --- a/src/comms/control_board/response.rs +++ b/src/comms/control_board/response.rs @@ -1,3 +1,4 @@ +//! Response parsing use std::{ collections::HashMap, sync::{ diff --git a/src/comms/control_board/util.rs b/src/comms/control_board/util.rs index f3b7686..b508549 100644 --- a/src/comms/control_board/util.rs +++ b/src/comms/control_board/util.rs @@ -1,7 +1,45 @@ +//! Utilities for parsing interacting with the control board use std::f32::consts::PI; -use anyhow::bail; +use color_eyre::eyre::bail; use derive_getters::Getters; +use thiserror::Error; + +/// An error occuring trying to communicate with the control board. +#[derive(Error, Debug)] +pub enum ControlBoardError { + /// Tried passing a malformed [vehicle definition](super::vehicle_definition::VehicleDefinition). + /// + /// The number of thrusters in the [motor matrix](super::vehicle_definition::MotorMatrix) and [thruster inversions vector](super::vehicle_definition::ThrusterInversions) do not match. + #[error("number of motor matrix rows and number of thruster inversions do not match: {rows:?} rows, {inversions:?} inversions")] + ThrusterMismatch { rows: u8, inversions: usize }, + + /// Tried passing a thruster index outside of the supported range, 1-8 inclusive. + #[error("thruster index '{0}' is outside of the allowed range 1-8")] + ThrusterIndexing(u8), + + /// An error occured while initializing comms with a control board through the serial backend. + #[error("failed to initialize serial comms with control board")] + InitSerial(#[from] tokio_serial::Error), + + /// An error occured while initializing comms with a control board through the TCP backend. + #[error("tcp connect failed")] + TcpConnect(#[from] tokio::io::Error), + + /// An error occured getting the initial yaw. + #[error("failed to set initial yaw")] + InitialYawSet, + + /// Tried tuning PID parameters for an axis that is not X, Y, Z, or D. + #[error("{0} is not a valid PID tune, pick from [X, Y, Z, D]")] + InvalidPidTuneAxis(char), + + /// Received an error from the control board itself. + #[error("acknowledge failed")] + AcknowledgeErr(#[from] crate::comms::auv_control_board::util::AcknowledgeErr), +} + +pub type Result = core::result::Result; /// See , /// page 25 @@ -18,7 +56,7 @@ pub enum BNO055AxisConfig { } impl TryFrom for BNO055AxisConfig { - type Error = anyhow::Error; + type Error = color_eyre::eyre::Error; fn try_from(value: u8) -> Result { match value { diff --git a/src/comms/control_board/vehicle_definition.rs b/src/comms/control_board/vehicle_definition.rs new file mode 100644 index 0000000..a60930c --- /dev/null +++ b/src/comms/control_board/vehicle_definition.rs @@ -0,0 +1,158 @@ +//! Tools for describing the vehicle to the control board + +use crate::comms::control_board::util::{ControlBoardError, Result}; + +/// Thruster inversions used to invert the positive and negative direction of thrusters. +/// +/// If `true`, the thruster of the corresponding index will be inverted +pub type ThrusterInversions = Vec; + +/// Used to set relative speeds of motion in each Degree of Freedom (DoF). +/// +/// There are two groups: linear (x, y, z) and angular (xrot, yrot, zrot). Expected in the format `[x, y, z, xrot, yrot, zrot]`. +/// +/// Within each group, use 1.0 for the fastest DoF. Other DoFs in the group are percentages of the fastest speed (from 0.0 to 1.0). +pub type DofSpeeds = [f32; 6]; + +/// Contains all parameters needed to describe a vehicle to the control board. +pub struct VehicleDefinition { + pub(crate) motor_matrix: MotorMatrix, + pub(crate) thruster_inversions: ThrusterInversions, + pub(crate) dof_speeds: DofSpeeds, + pub(crate) pid_axes: PidAxes, +} + +impl VehicleDefinition { + /// Contructs a new populated `VehicleDefinition` + pub fn new( + motor_matrix: MotorMatrix, + thruster_inversions: ThrusterInversions, + dof_speeds: DofSpeeds, + pid_axes: PidAxes, + ) -> Result { + let rows = motor_matrix.0.iter().map(|r| r.is_some() as u8).sum(); + let inversions = thruster_inversions.len(); + + if rows != inversions as u8 { + Err(ControlBoardError::ThrusterMismatch { rows, inversions }) + } else { + Ok(Self { + motor_matrix, + thruster_inversions, + dof_speeds, + pid_axes, + }) + } + } +} + +/// Contains a *populated* motor matrix. +/// Can only be created using [`MotorMatrixBuilder`]. +#[derive(Debug)] +pub struct MotorMatrix(pub(crate) [Option; 8]); + +impl MotorMatrix { + /// Creates a new [`MotorMatrixBuilder`] + pub fn builder(thrusters_in_use: u8) -> MotorMatrixBuilder { + MotorMatrixBuilder::new(thrusters_in_use) + } +} + +/// A builder for [`MotorMatrix`]. This struct makes it cleaner to define thruster parameters, +/// as well as validate that the correct amount of thrusters have a definition. +#[derive(Debug)] +pub struct MotorMatrixBuilder { + pub(crate) params: [Option; 8], + pub(crate) thrusters_in_use: u8, +} + +impl MotorMatrixBuilder { + /// Creates an unpopulated builder. + pub fn new(thrusters_in_use: u8) -> Self { + MotorMatrixBuilder { + params: [None, None, None, None, None, None, None, None], + thrusters_in_use, + } + } + + /// Sets the parameters for a specific thruster. + pub fn set_row(mut self, thruster: u8, parameters: MotorMatrixRowParams) -> Self { + let thruster_index = thruster - 1; + self.params[thruster_index as usize] = Some(parameters); + self + } + + /// Build the populated [`MotorMatrix`] + pub fn build(self) -> MotorMatrix { + // Make sure that we currently have parameters for `thrusters_in_use` thrusters. + let thrusters_defined = self.params.iter().filter(|x| x.is_some()).count(); + + assert_eq!(thrusters_defined, self.thrusters_in_use as usize); + + // Make sure that all of the arrays contain `Some()` + MotorMatrix(self.params) + } +} + +/// Each row corresponds to a line of self.motor_matrix_set(...); +/// Can either be created manually, or the parameters can be dumped into [`Self::new`] +/// for shorter code. +#[derive(Debug)] +pub struct MotorMatrixRowParams { + pub(crate) x: f32, + pub(crate) y: f32, + pub(crate) z: f32, + pub(crate) pitch: f32, + pub(crate) roll: f32, + pub(crate) yaw: f32, +} + +impl MotorMatrixRowParams { + pub fn new(x: f32, y: f32, z: f32, pitch: f32, roll: f32, yaw: f32) -> Self { + Self { + x, + y, + z, + pitch, + roll, + yaw, + } + } +} + +impl From<[f32; 6]> for MotorMatrixRowParams { + fn from(vals: [f32; 6]) -> Self { + Self { + x: vals[0], + y: vals[1], + z: vals[2], + pitch: vals[3], + roll: vals[4], + yaw: vals[5], + } + } +} + +pub type PidAxes = [PidAxis; 4]; + +pub struct PidAxis { + pub(crate) which: char, + pub(crate) kp: f32, + pub(crate) ki: f32, + pub(crate) kd: f32, + pub(crate) limit: f32, + pub(crate) invert: bool, +} + +impl From<(char, f32, f32, f32, f32, bool)> for PidAxis { + fn from(value: (char, f32, f32, f32, f32, bool)) -> Self { + Self { + which: value.0, + kp: value.1, + ki: value.2, + kd: value.3, + limit: value.4, + invert: value.5, + } + } +} diff --git a/src/comms/meb/mod.rs b/src/comms/meb/mod.rs index aa3298b..d53dc7b 100644 --- a/src/comms/meb/mod.rs +++ b/src/comms/meb/mod.rs @@ -1,24 +1,39 @@ +//! Implements communication protocol for the main electronics board (MEB). + use std::sync::Arc; -use anyhow::Result; +use thiserror::Error; use tokio::{ io::{AsyncReadExt, AsyncWrite, AsyncWriteExt, WriteHalf}, sync::Mutex, }; use tokio_serial::{DataBits, Parity, SerialStream, StopBits}; +use crate::comms::control_board::util::ControlBoardError; + use self::response::Statuses; use super::auv_control_board::{AUVControlBoard, MessageId}; pub mod response; +#[derive(Error, Debug)] +pub enum MebError { + #[error("failed to initialized serial comms with MEB")] + InitSerial(#[from] tokio_serial::Error), + #[error("sending message failed")] + SendMessage(#[from] ControlBoardError), +} + +pub type Result = core::result::Result; + #[derive(Debug)] pub struct MainElectronicsBoard { board: AUVControlBoard, } impl MainElectronicsBoard { + /// Returns a MEB instance using the given IO backend. pub async fn new(read_connection: T, write_connection: C) -> Self where T: 'static + AsyncReadExt + Unpin + Send, @@ -32,6 +47,11 @@ impl MainElectronicsBoard { } } + /// Returns a MEB instance using the serial backend. + /// + /// # Errors + /// + /// This function will return an error if the serial port cannot be opened. pub async fn serial(port_name: &str) -> Result>> { const BAUD_RATE: u32 = 57600; const DATA_BITS: DataBits = DataBits::Eight; @@ -48,26 +68,32 @@ impl MainElectronicsBoard { } impl MainElectronicsBoard { + /// Returns the temperature sensor value of this [`MainElectronicsBoard`]. pub async fn temperature(&self) -> Option { (*self.board.responses().temp().read().await).map(f32::from_le_bytes) } + /// Returns the humidity sensor value of this [`MainElectronicsBoard`]. pub async fn humidity(&self) -> Option { (*self.board.responses().humid().read().await).map(f32::from_le_bytes) } + /// Returns the leak sensor value of this [`MainElectronicsBoard`]. pub async fn leak(&self) -> Option { *self.board.responses().leak().read().await } + /// Returns the thruster arm state of this [`MainElectronicsBoard`]. pub async fn thruster_arm(&self) -> Option { *self.board.responses().thruster_arm().read().await } + /// Returns the system voltage of this [`MainElectronicsBoard`]. pub async fn system_voltage(&self) -> Option { (*self.board.responses().system_voltage().read().await).map(f32::from_le_bytes) } + /// Returns the shutdown cause of this [`MainElectronicsBoard`]. pub async fn shutdown_cause(&self) -> Option { *self.board.responses().shutdown().read().await } @@ -75,16 +101,21 @@ impl MainElectronicsBoard { #[derive(Debug, Copy, Clone)] pub enum MebCmd { + /// Trigger torpedo 1 T1Trig = 0x3, + /// Trigger torpedo 2 T2Trig = 0x4, + /// Trigger dropper 1 D1Trig = 0x1, + /// Trigger dropper 2 D2Trig = 0x2, + /// Reset relevant peripheral Reset = 0x0, } impl MainElectronicsBoard { - pub async fn send_msg(&self, cmd: MebCmd) -> anyhow::Result<()> { + pub async fn send_msg(&self, cmd: MebCmd) -> Result<()> { let formatted_cmd: [u8; 4] = [b'M', b'S', b'B', cmd as u8]; - self.board.write_out_basic(formatted_cmd.to_vec()).await + Ok(self.board.write_out_basic(formatted_cmd.to_vec()).await?) } } diff --git a/src/comms/meb/response.rs b/src/comms/meb/response.rs index 3c99a48..6f9aa5c 100644 --- a/src/comms/meb/response.rs +++ b/src/comms/meb/response.rs @@ -1,3 +1,5 @@ +//! Response parsing and handling + use std::sync::{ mpsc::{channel, Sender, TryRecvError}, Arc, @@ -64,7 +66,6 @@ impl Statuses { let shutdown: Lock<_> = Arc::default(); let ack_map: Arc> = Arc::default(); let (_tx, rx) = channel::<()>(); // Signals struct destruction to thread - // let temp_clone = temp.clone(); let humid_clone = humid.clone(); let leak_clone = leak.clone(); diff --git a/src/comms/mod.rs b/src/comms/mod.rs index 5f015ad..f4943b6 100644 --- a/src/comms/mod.rs +++ b/src/comms/mod.rs @@ -1,3 +1,5 @@ +//! Communications implementations for various subsystems + pub mod auv_control_board; pub mod control_board; #[cfg(feature = "meb")] diff --git a/src/comms/zed_ros2.rs b/src/comms/zed_ros2.rs index 67f7fe0..60e0823 100644 --- a/src/comms/zed_ros2.rs +++ b/src/comms/zed_ros2.rs @@ -1,4 +1,8 @@ -use anyhow::Result; +//! Implements communication with our external vision stack +//! +//! ROS2 and Stereolabs ZED cameras + +use color_eyre::eyre::Result; use futures::StreamExt; use ros2_client::{ Context, MessageTypeName, Name, NodeName, NodeOptions, DEFAULT_SUBSCRIPTION_QOS, diff --git a/src/config/bin.rs b/src/config/bin.rs index 5be1270..c5c414f 100644 --- a/src/config/bin.rs +++ b/src/config/bin.rs @@ -1,5 +1,8 @@ +//! Configuration for the bin mission + use serde::{Deserialize, Serialize}; +/// Bin mission config submodule #[derive(Debug, Serialize, Deserialize)] pub struct Config { pub depth: f32, diff --git a/src/config/coinflip.rs b/src/config/coinflip.rs index 809ce91..c0148a8 100644 --- a/src/config/coinflip.rs +++ b/src/config/coinflip.rs @@ -1,5 +1,8 @@ +//! Configuration for missions that handle the coinflip task + use serde::{Deserialize, Serialize}; +/// Coinflip mission config submodule #[derive(Debug, Serialize, Deserialize)] pub struct Config { pub depth: f32, diff --git a/src/config/gate.rs b/src/config/gate.rs index 6065edd..074c771 100644 --- a/src/config/gate.rs +++ b/src/config/gate.rs @@ -1,6 +1,9 @@ +//! Configuration for the gate family of missions + use super::Side; use serde::{Deserialize, Serialize}; +/// Gate mission config submodule #[derive(Debug, Serialize, Deserialize)] pub struct Config { pub depth: f32, diff --git a/src/config/mod.rs b/src/config/mod.rs index 30a6397..c65d9ca 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,3 +1,5 @@ +//! External configuration, parsable from a config file + pub mod bin; pub mod coinflip; pub mod gate; @@ -10,11 +12,12 @@ pub mod spin; use std::fs::read_to_string; use crate::vision::Yuv; -use anyhow::Result; +use color_eyre::eyre::Result; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::ops::RangeInclusive; +/// Time to wait on graceful shutdown before hard shutdown pub const SHUTDOWN_TIMEOUT: u64 = 5; // Default values @@ -30,23 +33,41 @@ const ZED_DEPTH_TOPIC: &str = ZED_IMAGE_TOPIC; const ZED_CLOUD_TOPIC: &str = "point_cloud/cloud_registered"; const ZED_POSE_TOPIC: &str = "pose"; +/// Top-level configuration #[derive(Debug, Serialize, Deserialize)] pub struct Config { + /// The path to the control board serial port pub control_board_path: String, + /// The backup path to the control board serial port pub control_board_backup_path: String, + /// The path to the main electronics board serial port pub meb_path: String, + /// The path to the front camera video device pub front_cam_path: String, + /// The path to the bottom camera video device pub bottom_cam_path: String, - pub sonar: sonar::Config, - pub missions: Missions, + /// The active color profile used for vision. Must be in `color_profiles` pub color_profile: String, + /// The available color profiles usable for vision pub color_profiles: HashMap, + /// The [`Side`] the shark prop is on pub shark: Side, + /// The [`Side`] the saw fish prop is on pub saw_fish: Side, + /// BlueRobotics Ping360 sonar config submodule + pub sonar: sonar::Config, + /// Missions config submodule + pub missions: Missions, + /// ZED ROS2 subsystem config submodule pub zed_ros2: ZedRos2Config, } impl Config { + /// Generates a populated [`Config`] from a `config.toml` file in the current directory. + /// + /// # Errors + /// + /// This function will return an error if `config.toml` does not exist. pub fn new() -> Result { let config_string = read_to_string(CONFIG_FILE)?; Ok(toml::from_str(&config_string)?) @@ -54,6 +75,7 @@ impl Config { } impl Config { + /// Returns the configured [`ColorProfile`] if it exists in `color_profiles`. pub fn get_color_profile(&self) -> Option<&ColorProfile> { self.color_profiles.get(&self.color_profile) } @@ -78,6 +100,7 @@ impl Default for Config { } } +/// ZED ROS2 subsystem config submodule. #[derive(Debug, Serialize, Deserialize)] pub struct ZedRos2Config { pub namespace: String, @@ -97,6 +120,9 @@ impl Default for ZedRos2Config { } } +/// Missions config submodule. +/// +/// Each submodule corresponds to a [mission](crate::missions). #[derive(Debug, Default, Serialize, Deserialize)] pub struct Missions { pub gate: gate::Config, diff --git a/src/config/octagon.rs b/src/config/octagon.rs index 5844c1b..ff33dd1 100644 --- a/src/config/octagon.rs +++ b/src/config/octagon.rs @@ -1,5 +1,8 @@ +//! Configuration for the octagon family of missions + use serde::{Deserialize, Serialize}; +/// Octagon mission config submodule #[derive(Debug, Serialize, Deserialize)] pub struct Config {} diff --git a/src/config/path_align.rs b/src/config/path_align.rs index 72bab3c..4832a30 100644 --- a/src/config/path_align.rs +++ b/src/config/path_align.rs @@ -1,5 +1,8 @@ +//! Configuration for the path align mission + use serde::{Deserialize, Serialize}; +/// Path align mission config submodule #[derive(Debug, Serialize, Deserialize)] pub struct Config { pub depth: f32, diff --git a/src/config/slalom.rs b/src/config/slalom.rs index 97404e4..99301c5 100644 --- a/src/config/slalom.rs +++ b/src/config/slalom.rs @@ -1,8 +1,11 @@ +//! Configuration for the slalom family of missions + use std::ops::RangeInclusive; use super::Side; use serde::{Deserialize, Serialize}; +/// Slalom mission config submodule #[derive(Debug, Serialize, Deserialize)] pub struct Config { pub depth: f32, diff --git a/src/config/sonar.rs b/src/config/sonar.rs index 66e39cb..fea839f 100644 --- a/src/config/sonar.rs +++ b/src/config/sonar.rs @@ -1,6 +1,9 @@ +//! Configuration for the BlueRobotics Ping360 sonar module + use serde::{Deserialize, Serialize}; use std::path::PathBuf; +/// Sonar config submodule #[derive(Debug, Serialize, Deserialize)] pub struct Config { pub serial_port: PathBuf, diff --git a/src/lib.rs b/src/lib.rs index c8a9c92..cdd4637 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +//! Supporting library for `sw9s`, the high-level autonamous driver program for [SeaWolf IX](https://aquapackrobotics.org/seawolves/seawolfIX/), [AquaPack Robotics'](https://aquapackrobotics.org/) 9th gen autonamous underwater vehicle (AUV). + use std::{ fs::{create_dir, File}, sync::{LazyLock, Mutex}, diff --git a/src/main.rs b/src/main.rs index 32b0e04..157a145 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use color_eyre::eyre::{bail, Result}; use std::env::temp_dir; use std::env; @@ -6,7 +6,10 @@ use std::process::exit; use std::time::Duration; use sw9s_lib::{ comms::{ - control_board::{ControlBoard, SensorStatuses}, + control_board::{ + vehicle_definition::{MotorMatrix, VehicleDefinition}, + ControlBoard, SensorStatuses, + }, meb::MainElectronicsBoard, zed_ros2::ZedRos2, }, @@ -49,7 +52,7 @@ async fn config() -> &'static Config { CONFIG_CELL .get_or_init(|| async { Config::new().unwrap_or_else(|e| { - logln!("Error getting config file: {:#?}\nUsing default config", e); + logln!("Error getting config file: {e}\nUsing default config"); Config::default() }) }) @@ -61,17 +64,43 @@ async fn control_board() -> &'static ControlBoard> { let config = config().await; CONTROL_BOARD_CELL .get_or_init(|| async { - let board = ControlBoard::serial(config.control_board_path.as_str()).await; + let motor_matrix = MotorMatrix::builder(8) + .set_row(1, [-1.0, 1.0, 0.0, 0.0, 0.0, -1.0].into()) + .set_row(2, [1.0, 1.0, 0.0, 0.0, 0.0, 1.0].into()) + .set_row(3, [-1.0, -1.0, 0.0, 0.0, 0.0, 1.0].into()) + .set_row(4, [1.0, -1.0, 0.0, 0.0, 0.0, -1.0].into()) + .set_row(5, [0.0, 0.0, -1.0, 1.0, -1.0, 0.0].into()) + .set_row(6, [0.0, 0.0, -1.0, 1.0, 1.0, 0.0].into()) + .set_row(7, [0.0, 0.0, -1.0, -1.0, -1.0, 0.0].into()) + .set_row(8, [0.0, 0.0, -1.0, -1.0, 1.0, 0.0].into()) + .build(); + let vehicle_def = VehicleDefinition::new( + motor_matrix, + [true, true, false, false, true, false, false, true].into(), + [0.7071, 0.7071, 1.0, 0.4413, 1.0, 0.8139], + [ + ('X', 0.8, 0.0, 0.0, 0.6, false).into(), + ('Y', 2.0, 0.0, 0.0, 0.1, false).into(), + ('Z', 4.0, 0.0, 0.0, 1.0, false).into(), + ('D', 1.5, 0.0, 0.0, 1.0, false).into(), + ], + ) + .inspect_err(|e| logln!("Invalid vehicle definition: {:#?}", e)) + .unwrap(); + let board = + ControlBoard::serial(config.control_board_path.as_str(), &vehicle_def).await; match board { Ok(x) => x, Err(e) => { - logln!("Error initializing control board: {:#?}", e); - let backup_board = - ControlBoard::serial(config.control_board_backup_path.as_str()) - .await - .unwrap(); + logln!("Error initializing control board: {e}"); + let backup_board = ControlBoard::serial( + config.control_board_backup_path.as_str(), + &vehicle_def, + ) + .await + .unwrap(); backup_board.reset().await.unwrap(); - ControlBoard::serial(config.control_board_path.as_str()) + ControlBoard::serial(config.control_board_path.as_str(), &vehicle_def) .await .unwrap() } @@ -150,6 +179,7 @@ static SHUTDOWN_GUARD: Semaphore = Semaphore::const_new(1); #[tokio::main] async fn main() { + color_eyre::install().unwrap(); let (shutdown_tx, mission_ct) = shutdown_handler().await; let stream = rerun::RecordingStreamBuilder::new("SWS9") diff --git a/src/missions/action.rs b/src/missions/action.rs index 2e81436..7d1bb60 100644 --- a/src/missions/action.rs +++ b/src/missions/action.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use core::fmt::Debug; use std::{marker::PhantomData, sync::Arc, thread}; diff --git a/src/missions/comms.rs b/src/missions/comms.rs index 5321fb2..db9d167 100644 --- a/src/missions/comms.rs +++ b/src/missions/comms.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use tokio::io::WriteHalf; use tokio_serial::SerialStream; @@ -22,9 +22,10 @@ impl Action for StartBno055<'_, T> {} impl>> ActionExec> for StartBno055<'_, T> { async fn execute(&mut self) -> Result<()> { - self.context + Ok(self + .context .get_control_board() .bno055_periodic_read(true) - .await + .await?) } } diff --git a/src/missions/extra.rs b/src/missions/extra.rs index 3146c95..4809d49 100644 --- a/src/missions/extra.rs +++ b/src/missions/extra.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use std::marker::PhantomData; -use anyhow::{anyhow, bail}; +use color_eyre::eyre::{anyhow, bail, Result}; use crate::logln; @@ -112,8 +112,8 @@ impl ActionMod for AlwaysTrue { fn modify(&mut self, _input: &T) {} } -impl ActionExec> for AlwaysTrue { - async fn execute(&mut self) -> anyhow::Result<()> { +impl ActionExec> for AlwaysTrue { + async fn execute(&mut self) -> Result<()> { Ok(()) } } @@ -159,8 +159,8 @@ impl ActionMod for AlwaysFalse { fn modify(&mut self, _input: &T) {} } -impl ActionExec> for AlwaysFalse { - async fn execute(&mut self) -> anyhow::Result<()> { +impl ActionExec> for AlwaysFalse { + async fn execute(&mut self) -> Result<()> { bail!("") } } @@ -197,7 +197,7 @@ impl, U: Send + Sync> ActionMod for UnwrapAction { } } -impl>, U: Send + Sync> ActionExec for UnwrapAction { +impl>, U: Send + Sync> ActionExec for UnwrapAction { async fn execute(&mut self) -> U { self.action.execute().await.unwrap() } @@ -217,8 +217,8 @@ impl CountTrue { impl Action for CountTrue {} -impl ActionMod> for CountTrue { - fn modify(&mut self, input: &anyhow::Result) { +impl ActionMod> for CountTrue { + fn modify(&mut self, input: &Result) { if input.is_ok() { self.count += 1; if self.count > self.target { @@ -259,8 +259,8 @@ impl ActionMod for CountTrue { } } -impl ActionExec> for CountTrue { - async fn execute(&mut self) -> anyhow::Result<()> { +impl ActionExec> for CountTrue { + async fn execute(&mut self) -> Result<()> { logln!("Check true count: {} ? {}", self.count, self.target); if self.count < self.target { Ok(()) @@ -284,8 +284,8 @@ impl CountFalse { impl Action for CountFalse {} -impl ActionMod> for CountFalse { - fn modify(&mut self, input: &anyhow::Result) { +impl ActionMod> for CountFalse { + fn modify(&mut self, input: &Result) { if input.is_err() { self.count += 1; if self.count > self.target { @@ -326,8 +326,8 @@ impl ActionMod for CountFalse { } } -impl ActionExec> for CountFalse { - async fn execute(&mut self) -> anyhow::Result<()> { +impl ActionExec> for CountFalse { + async fn execute(&mut self) -> Result<()> { logln!("Check false count: {} ? {}", self.count, self.target); if self.count < self.target { Ok(()) @@ -363,13 +363,10 @@ impl, U: ActionMod, V: Send + Sync> ActionMod for InOrderF } } -impl< - T: ActionExec>, - U: ActionExec>, - V: Send + Sync + Default, - > ActionExec> for InOrderFail +impl>, U: ActionExec>, V: Send + Sync + Default> + ActionExec> for InOrderFail { - async fn execute(&mut self) -> anyhow::Result { + async fn execute(&mut self) -> Result { if !self.finished_first { let ret = self.first.execute().await; self.finished_first = ret.is_err(); @@ -453,10 +450,10 @@ impl + Send + Sync + Clone> Ac } } -impl + Send + Sync + Clone> ActionMod> +impl + Send + Sync + Clone> ActionMod> for ToVec { - fn modify(&mut self, input: &anyhow::Result) { + fn modify(&mut self, input: &Result) { if let Ok(input) = input { self.value = input.clone().into_iter().collect(); } else { @@ -504,10 +501,10 @@ impl + Send + Sync + Clone> Ac } } -impl + Send + Sync + Clone> ActionMod> +impl + Send + Sync + Clone> ActionMod> for IsSome { - fn modify(&mut self, input: &anyhow::Result) { + fn modify(&mut self, input: &Result) { if let Ok(input) = input { self.value = input.clone().into_iter().collect(); } else { @@ -543,8 +540,8 @@ impl ActionMod for AlwaysBetterTrue { fn modify(&mut self, _input: &T) {} } -impl ActionExec> for AlwaysBetterTrue { - async fn execute(&mut self) -> anyhow::Result<()> { +impl ActionExec> for AlwaysBetterTrue { + async fn execute(&mut self) -> Result<()> { Ok(()) } } @@ -570,8 +567,8 @@ impl ActionMod for AlwaysBetterFalse { fn modify(&mut self, _input: &T) {} } -impl ActionExec> for AlwaysBetterFalse { - async fn execute(&mut self) -> anyhow::Result<()> { +impl ActionExec> for AlwaysBetterFalse { + async fn execute(&mut self) -> Result<()> { bail!("") } } diff --git a/src/missions/movement.rs b/src/missions/movement.rs index 10c143d..b65e728 100644 --- a/src/missions/movement.rs +++ b/src/missions/movement.rs @@ -6,7 +6,7 @@ use crate::vision::Offset2D; use crate::vision::RelPos; use crate::vision::RelPosAngle; -use anyhow::Result; +use color_eyre::eyre::Result; use core::fmt::Debug; use derive_getters::Getters; use num_traits::abs; @@ -132,7 +132,7 @@ impl>> ActionExec> cur_angles = cntrl_board.responses().get_angles().await; } - cntrl_board + Ok(cntrl_board .stability_2_speed_set( 0.0, speed, @@ -141,7 +141,7 @@ impl>> ActionExec> *cur_angles.unwrap().yaw(), self.target_depth, ) - .await + .await?) } } @@ -163,10 +163,11 @@ impl<'a, T> ZeroMovement<'a, T> { impl>> ActionExec> for ZeroMovement<'_, T> { async fn execute(&mut self) -> Result<()> { - self.context + Ok(self + .context .get_control_board() .stability_2_speed_set_initial_yaw(0.0, 0.0, 0.0, 0.0, self.target_depth) - .await + .await?) } } @@ -214,10 +215,11 @@ where impl>> ActionExec> for AdjustMovement<'_, T> { async fn execute(&mut self) -> Result<()> { - self.context + Ok(self + .context .get_control_board() .stability_2_speed_set_initial_yaw(self.x, 0.5, 0.0, 0.0, self.target_depth) - .await + .await?) } } @@ -335,10 +337,11 @@ impl>> ActionExec> } logln!("Setting x to {x}"); - self.context + Ok(self + .context .get_control_board() .stability_2_speed_set(x, 0.5, 0.0, 0.0, yaw, self.target_depth) - .await + .await?) } } @@ -410,10 +413,11 @@ impl>> ActionExec> for Cen y = 0.0; } - self.context + Ok(self + .context .get_control_board() .stability_2_speed_set(x, y, 0.0, 0.0, yaw, self.target_depth) - .await + .await?) } } @@ -570,7 +574,7 @@ impl Stability2Pos { //logln!("Stability 2 speed set: {:#?}", self); - board + Ok(board .stability_2_speed_set( self.x, self.y, @@ -579,7 +583,7 @@ impl Stability2Pos { self.target_yaw.unwrap(), self.target_depth, ) - .await + .await?) } /// Sets speed, bounded to [-1, 1] @@ -1350,8 +1354,8 @@ impl ActionMod> for OffsetToPose } } -impl ActionMod> for OffsetToPose { - fn modify(&mut self, input: &anyhow::Result) { +impl ActionMod> for OffsetToPose { + fn modify(&mut self, input: &color_eyre::eyre::Result) { if let Ok(input) = input { self.offset = input.clone(); } else { @@ -1417,8 +1421,8 @@ impl ActionMod> for BoxToPose { } } -impl ActionMod> for BoxToPose { - fn modify(&mut self, input: &anyhow::Result) { +impl ActionMod> for BoxToPose { + fn modify(&mut self, input: &color_eyre::eyre::Result) { if let Ok(input) = input { self.input = input.clone(); } else { @@ -1575,7 +1579,7 @@ impl Stability1Pos { pub async fn exec(&mut self, board: &ControlBoard>) -> Result<()> { logln!("Stability 1 speed set: {:#?}", self); - board + Ok(board .stability_1_speed_set( self.x, self.y, @@ -1584,7 +1588,7 @@ impl Stability1Pos { self.yaw_speed, self.target_depth, ) - .await + .await?) } /// Sets speed, bounded to [-1, 1] @@ -2450,7 +2454,7 @@ impl GlobalPos { /// Executes the position in stability assist pub async fn exec(&mut self, board: &ControlBoard>) -> Result<()> { - board + Ok(board .global_speed_set( self.x, self.y, @@ -2459,7 +2463,7 @@ impl GlobalPos { self.roll_speed, self.yaw_speed, ) - .await + .await?) } pub const fn const_default() -> Self { diff --git a/src/missions/vision.rs b/src/missions/vision.rs index d5f83e2..d83cbba 100644 --- a/src/missions/vision.rs +++ b/src/missions/vision.rs @@ -11,7 +11,7 @@ use crate::vision::{ Angle2D, Draw, DrawRect2d, Offset2D, RelPos, RelPosAngle, VisualDetection, VisualDetector, }; -use anyhow::{anyhow, Result}; +use color_eyre::eyre::{anyhow, Result}; use num_traits::{Float, FromPrimitive, Num}; use opencv::core::{Mat, Rect2d}; use uuid::Uuid; @@ -783,9 +783,9 @@ impl< } impl - ActionMod>>> for DetectTarget + ActionMod>>> for DetectTarget { - fn modify(&mut self, input: &anyhow::Result>>) { + fn modify(&mut self, input: &Result>>) { #[allow(clippy::all)] { self.results = input.as_ref().map(|valid| valid.clone()).ok() @@ -846,8 +846,8 @@ impl ActionMod>> for Average { } } -impl ActionMod>> for Average { - fn modify(&mut self, input: &anyhow::Result>) { +impl ActionMod>> for Average { + fn modify(&mut self, input: &Result>) { if let Ok(input) = input { self.values.clone_from(input); } else { @@ -991,8 +991,8 @@ impl ActionMod>> for MidPoint { } } -impl ActionMod>> for MidPoint { - fn modify(&mut self, input: &anyhow::Result>) { +impl ActionMod>> for MidPoint { + fn modify(&mut self, input: &Result>) { if let Ok(input) = input { self.values.clone_from(input); } else { diff --git a/src/video_source/appsink.rs b/src/video_source/appsink.rs index a261ed4..a158376 100644 --- a/src/video_source/appsink.rs +++ b/src/video_source/appsink.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use color_eyre::eyre::{anyhow, Result}; use opencv::{ prelude::Mat, videoio::{VideoCapture, VideoCaptureAPIs, VideoCaptureTrait}, diff --git a/src/vision/bin.rs b/src/vision/bin.rs index 8238cab..d3324fc 100644 --- a/src/vision/bin.rs +++ b/src/vision/bin.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use derive_getters::Getters; use opencv::{core::Size, prelude::Mat}; diff --git a/src/vision/gate.rs b/src/vision/gate.rs index f855ea5..a2b3c0d 100644 --- a/src/vision/gate.rs +++ b/src/vision/gate.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use opencv::{core::Size, prelude::Mat}; use crate::load_onnx; diff --git a/src/vision/gate_cv.rs b/src/vision/gate_cv.rs index fa0c77e..d327bbe 100644 --- a/src/vision/gate_cv.rs +++ b/src/vision/gate_cv.rs @@ -1,6 +1,7 @@ use crate::config::ColorProfile; use super::{image_prep::resize, MatWrapper, PosVector, VisualDetection, VisualDetector, Yuv}; +use color_eyre::eyre::Result; use opencv::{ core::{in_range, Point, Scalar, Size, Vector}, imgproc::{ @@ -76,7 +77,7 @@ impl VisualDetector for GateCV { fn detect( &mut self, input_image: &Mat, - ) -> anyhow::Result>> { + ) -> Result>> { self.image = resize(input_image, &self.size)?.into(); let mut yuv_image = Mat::default(); diff --git a/src/vision/gate_poles.rs b/src/vision/gate_poles.rs index 39ac59d..8dd483b 100644 --- a/src/vision/gate_poles.rs +++ b/src/vision/gate_poles.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use derive_getters::Getters; use opencv::core::{multiply, BORDER_CONSTANT, CV_8U}; use opencv::imgproc::{dilate, morphology_default_border_value}; diff --git a/src/vision/image_prep.rs b/src/vision/image_prep.rs index 411b3ac..f1643ce 100644 --- a/src/vision/image_prep.rs +++ b/src/vision/image_prep.rs @@ -11,7 +11,7 @@ use opencv::{ prelude::{Mat, MatSizeTraitConst, MatTrait, MatTraitConst, MatTraitConstManual}, }; -use anyhow::Result; +use color_eyre::eyre::Result; /// Creates a new Mat with the specified size /// diff --git a/src/vision/mod.rs b/src/vision/mod.rs index a9e8c16..e65a119 100644 --- a/src/vision/mod.rs +++ b/src/vision/mod.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use derive_getters::Getters; use itertools::Itertools; use num_traits::{zero, FromPrimitive, Num}; @@ -480,7 +480,7 @@ impl Mul<&Mat> for PosVector { } impl Draw for VisualDetection> { - fn draw(&self, canvas: &mut Mat) -> anyhow::Result<()> { + fn draw(&self, canvas: &mut Mat) -> Result<()> { let color = if self.class { Scalar::from((0.0, 255.0, 0.0)) } else { diff --git a/src/vision/nn_cv2.rs b/src/vision/nn_cv2.rs index 07ed464..fbdd1c0 100644 --- a/src/vision/nn_cv2.rs +++ b/src/vision/nn_cv2.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use derive_getters::Getters; use opencv::{ core::{Rect2d, Scalar, Size, VecN, Vector, CV_32F}, diff --git a/src/vision/octagon.rs b/src/vision/octagon.rs index 327db21..87884b4 100644 --- a/src/vision/octagon.rs +++ b/src/vision/octagon.rs @@ -1,4 +1,5 @@ use super::{image_prep::resize, MatWrapper, Offset2D, VisualDetection, VisualDetector}; +use color_eyre::eyre::Result; use opencv::{ core::{in_range, Point, Size, VecN, Vector}, imgproc::{find_contours, CHAIN_APPROX_SIMPLE, RETR_TREE}, @@ -90,7 +91,7 @@ impl VisualDetector for Octagon { fn detect( &mut self, input_image: &Mat, - ) -> anyhow::Result>> { + ) -> Result>> { let image = resize(input_image, &self.size)?; self.image.0 = image.clone(); diff --git a/src/vision/path_cv.rs b/src/vision/path_cv.rs index e16334a..0846560 100644 --- a/src/vision/path_cv.rs +++ b/src/vision/path_cv.rs @@ -1,5 +1,6 @@ use super::{image_prep::resize, MatWrapper, PosVector, VisualDetection, VisualDetector, Yuv}; use crate::{config::ColorProfile, vision::Draw}; +use color_eyre::eyre::Result; use opencv::{ core::{in_range, Point, Scalar, Size, Vector}, imgproc::{ @@ -11,7 +12,7 @@ use opencv::{ use std::ops::RangeInclusive; impl Draw for VisualDetection { - fn draw(&self, canvas: &mut Mat) -> anyhow::Result<()> { + fn draw(&self, canvas: &mut Mat) -> Result<()> { let color = if self.class { logln!("Drawing true: {:#?}", self.position()); Scalar::from((0.0, 255.0, 0.0)) @@ -106,7 +107,7 @@ impl VisualDetector for PathCV { fn detect( &mut self, input_image: &Mat, - ) -> anyhow::Result>> { + ) -> Result>> { self.image = resize(input_image, &self.size)?.into(); let mut yuv_image = Mat::default(); @@ -215,7 +216,7 @@ impl VisualDetector for PathCV { fn detect( &mut self, input_image: &Mat, - ) -> anyhow::Result>> { + ) -> Result>> { self.image = resize(input_image, &self.size)?.into(); let mut yuv_image = Mat::default(); diff --git a/src/vision/slalom.rs b/src/vision/slalom.rs index 2eb2375..c0ac82e 100644 --- a/src/vision/slalom.rs +++ b/src/vision/slalom.rs @@ -1,6 +1,7 @@ use crate::config::ColorProfile; use super::{image_prep::resize, MatWrapper, PosVector, VisualDetection, VisualDetector, Yuv}; +use color_eyre::eyre::Result; use opencv::{ core::{in_range, Point, Scalar, Size, Vector}, imgproc::{ @@ -71,7 +72,7 @@ impl VisualDetector for Slalom { fn detect( &mut self, input_image: &Mat, - ) -> anyhow::Result>> { + ) -> Result>> { let areas = self.area_bounds.clone(); let min_area = areas.start(); let max_area = areas.end(); diff --git a/src/vision/slalom_yolo.rs b/src/vision/slalom_yolo.rs index e9a52c9..aba1280 100644 --- a/src/vision/slalom_yolo.rs +++ b/src/vision/slalom_yolo.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use derive_getters::Getters; use opencv::{core::Size, prelude::Mat}; diff --git a/src/vision/yolo_model.rs b/src/vision/yolo_model.rs index d85837a..af10278 100644 --- a/src/vision/yolo_model.rs +++ b/src/vision/yolo_model.rs @@ -7,7 +7,7 @@ use super::{ nn_cv2::{YoloClass, YoloDetection}, Draw, DrawRect2d, RelPos, VisualDetection, VisualDetector, }; -use anyhow::Result; +use color_eyre::eyre::Result; use opencv::{ core::{Point, Rect2d, Scalar, Size}, imgproc::{self, LINE_AA},