From d039822e61dae56f2bf26afd47453652b242957b Mon Sep 17 00:00:00 2001 From: Ultra Date: Mon, 4 Aug 2025 23:17:16 -0400 Subject: [PATCH] Deprecate old mission_scheduler and add a new one --- .gitignore | 16 + autonomy/src/mission_planner_legacy/README.md | 1 + .../__init__.py | 0 .../base_mission.py | 0 .../gate_mission.py | 0 .../gate_mission_tester.py | 0 .../gate_tester_visualizer.py | 0 .../mission_manager.py | 0 .../mission_tree.py | 0 .../prequalification_mission.py | 0 .../slalom_mission.py | 0 .../slalom_visualizer.py | 0 .../tagging_mission.py | 0 .../tagging_mission_test.py | 0 .../task_parameters.py | 0 .../test_gate_mission.py | 0 .../test_slalom.py | 0 .../test_slalom_integration.py | 0 .../tests.hss | 0 .../types.py | 0 mission-planner-c/Cargo.lock | 817 ++++++++++++++++++ mission-planner-c/Cargo.toml | 13 + mission-planner-c/bindings.h | 46 + mission-planner-c/build.rs | 34 + mission-planner-c/src/cmission_example.c | 27 + mission-planner-c/src/cmission_example.h | 2 + mission-planner-c/src/lib.rs | 133 +++ mission-planner-c/src/main.rs | 29 + mission-planner/Cargo.lock | 174 ++++ mission-planner/Cargo.toml | 10 + .../src/concurrent_mission_example.rs | 36 + mission-planner/src/lib.rs | 2 + mission-planner/src/main.rs | 39 + mission-planner/src/mission.rs | 80 ++ mission-planner/src/mission_example.rs | 49 ++ mission-planner/src/mission_scheduler.rs | 187 ++++ 36 files changed, 1695 insertions(+) create mode 100644 autonomy/src/mission_planner_legacy/README.md rename autonomy/src/{mission_planner => mission_planner_legacy}/__init__.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/base_mission.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/gate_mission.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/gate_mission_tester.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/gate_tester_visualizer.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/mission_manager.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/mission_tree.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/prequalification_mission.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/slalom_mission.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/slalom_visualizer.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/tagging_mission.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/tagging_mission_test.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/task_parameters.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/test_gate_mission.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/test_slalom.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/test_slalom_integration.py (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/tests.hss (100%) rename autonomy/src/{mission_planner => mission_planner_legacy}/types.py (100%) create mode 100644 mission-planner-c/Cargo.lock create mode 100644 mission-planner-c/Cargo.toml create mode 100644 mission-planner-c/bindings.h create mode 100644 mission-planner-c/build.rs create mode 100644 mission-planner-c/src/cmission_example.c create mode 100644 mission-planner-c/src/cmission_example.h create mode 100644 mission-planner-c/src/lib.rs create mode 100644 mission-planner-c/src/main.rs create mode 100644 mission-planner/Cargo.lock create mode 100644 mission-planner/Cargo.toml create mode 100644 mission-planner/src/concurrent_mission_example.rs create mode 100644 mission-planner/src/lib.rs create mode 100644 mission-planner/src/main.rs create mode 100644 mission-planner/src/mission.rs create mode 100644 mission-planner/src/mission_example.rs create mode 100644 mission-planner/src/mission_scheduler.rs diff --git a/.gitignore b/.gitignore index 6b8e127..9b144e1 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,19 @@ best.pt .venv-formatters autonomy/src/autonomy.egg-info hydrus_software_stack.egg-info + +# Generated by Cargo +# will have compiled files and executables +debug +target + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Generated by cargo mutants +# Contains mutation testing data +**/mutants.out*/ + diff --git a/autonomy/src/mission_planner_legacy/README.md b/autonomy/src/mission_planner_legacy/README.md new file mode 100644 index 0000000..4e58ba3 --- /dev/null +++ b/autonomy/src/mission_planner_legacy/README.md @@ -0,0 +1 @@ +This code has been deprecated in favor of mission-planner at the root directory. diff --git a/autonomy/src/mission_planner/__init__.py b/autonomy/src/mission_planner_legacy/__init__.py similarity index 100% rename from autonomy/src/mission_planner/__init__.py rename to autonomy/src/mission_planner_legacy/__init__.py diff --git a/autonomy/src/mission_planner/base_mission.py b/autonomy/src/mission_planner_legacy/base_mission.py similarity index 100% rename from autonomy/src/mission_planner/base_mission.py rename to autonomy/src/mission_planner_legacy/base_mission.py diff --git a/autonomy/src/mission_planner/gate_mission.py b/autonomy/src/mission_planner_legacy/gate_mission.py similarity index 100% rename from autonomy/src/mission_planner/gate_mission.py rename to autonomy/src/mission_planner_legacy/gate_mission.py diff --git a/autonomy/src/mission_planner/gate_mission_tester.py b/autonomy/src/mission_planner_legacy/gate_mission_tester.py similarity index 100% rename from autonomy/src/mission_planner/gate_mission_tester.py rename to autonomy/src/mission_planner_legacy/gate_mission_tester.py diff --git a/autonomy/src/mission_planner/gate_tester_visualizer.py b/autonomy/src/mission_planner_legacy/gate_tester_visualizer.py similarity index 100% rename from autonomy/src/mission_planner/gate_tester_visualizer.py rename to autonomy/src/mission_planner_legacy/gate_tester_visualizer.py diff --git a/autonomy/src/mission_planner/mission_manager.py b/autonomy/src/mission_planner_legacy/mission_manager.py similarity index 100% rename from autonomy/src/mission_planner/mission_manager.py rename to autonomy/src/mission_planner_legacy/mission_manager.py diff --git a/autonomy/src/mission_planner/mission_tree.py b/autonomy/src/mission_planner_legacy/mission_tree.py similarity index 100% rename from autonomy/src/mission_planner/mission_tree.py rename to autonomy/src/mission_planner_legacy/mission_tree.py diff --git a/autonomy/src/mission_planner/prequalification_mission.py b/autonomy/src/mission_planner_legacy/prequalification_mission.py similarity index 100% rename from autonomy/src/mission_planner/prequalification_mission.py rename to autonomy/src/mission_planner_legacy/prequalification_mission.py diff --git a/autonomy/src/mission_planner/slalom_mission.py b/autonomy/src/mission_planner_legacy/slalom_mission.py similarity index 100% rename from autonomy/src/mission_planner/slalom_mission.py rename to autonomy/src/mission_planner_legacy/slalom_mission.py diff --git a/autonomy/src/mission_planner/slalom_visualizer.py b/autonomy/src/mission_planner_legacy/slalom_visualizer.py similarity index 100% rename from autonomy/src/mission_planner/slalom_visualizer.py rename to autonomy/src/mission_planner_legacy/slalom_visualizer.py diff --git a/autonomy/src/mission_planner/tagging_mission.py b/autonomy/src/mission_planner_legacy/tagging_mission.py similarity index 100% rename from autonomy/src/mission_planner/tagging_mission.py rename to autonomy/src/mission_planner_legacy/tagging_mission.py diff --git a/autonomy/src/mission_planner/tagging_mission_test.py b/autonomy/src/mission_planner_legacy/tagging_mission_test.py similarity index 100% rename from autonomy/src/mission_planner/tagging_mission_test.py rename to autonomy/src/mission_planner_legacy/tagging_mission_test.py diff --git a/autonomy/src/mission_planner/task_parameters.py b/autonomy/src/mission_planner_legacy/task_parameters.py similarity index 100% rename from autonomy/src/mission_planner/task_parameters.py rename to autonomy/src/mission_planner_legacy/task_parameters.py diff --git a/autonomy/src/mission_planner/test_gate_mission.py b/autonomy/src/mission_planner_legacy/test_gate_mission.py similarity index 100% rename from autonomy/src/mission_planner/test_gate_mission.py rename to autonomy/src/mission_planner_legacy/test_gate_mission.py diff --git a/autonomy/src/mission_planner/test_slalom.py b/autonomy/src/mission_planner_legacy/test_slalom.py similarity index 100% rename from autonomy/src/mission_planner/test_slalom.py rename to autonomy/src/mission_planner_legacy/test_slalom.py diff --git a/autonomy/src/mission_planner/test_slalom_integration.py b/autonomy/src/mission_planner_legacy/test_slalom_integration.py similarity index 100% rename from autonomy/src/mission_planner/test_slalom_integration.py rename to autonomy/src/mission_planner_legacy/test_slalom_integration.py diff --git a/autonomy/src/mission_planner/tests.hss b/autonomy/src/mission_planner_legacy/tests.hss similarity index 100% rename from autonomy/src/mission_planner/tests.hss rename to autonomy/src/mission_planner_legacy/tests.hss diff --git a/autonomy/src/mission_planner/types.py b/autonomy/src/mission_planner_legacy/types.py similarity index 100% rename from autonomy/src/mission_planner/types.py rename to autonomy/src/mission_planner_legacy/types.py diff --git a/mission-planner-c/Cargo.lock b/mission-planner-c/Cargo.lock new file mode 100644 index 0000000..9abe928 --- /dev/null +++ b/mission-planner-c/Cargo.lock @@ -0,0 +1,817 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.59.0", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bindgen" +version = "0.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f72209734318d0b619a5e0f5129918b848c416e122a3c4ce054e03cb87b726f" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "cbindgen" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975982cdb7ad6a142be15bdf84aea7ec6a9e5d4d797c004d43185b24cfe4e684" +dependencies = [ + "clap", + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml", +] + +[[package]] +name = "cc" +version = "1.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +dependencies = [ + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi", +] + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown 0.15.4", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.3", +] + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mission-planner-c" +version = "0.1.0" +dependencies = [ + "bindgen", + "cbindgen", + "cc", + "mission_planner", +] + +[[package]] +name = "mission_planner" +version = "0.1.0" +dependencies = [ + "dashmap", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "prettyplease" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.60.2", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] diff --git a/mission-planner-c/Cargo.toml b/mission-planner-c/Cargo.toml new file mode 100644 index 0000000..bb5a254 --- /dev/null +++ b/mission-planner-c/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "mission-planner-c" +version = "0.1.0" +edition = "2024" +crate-type = ["staticlib"] + +[dependencies] +mission_planner = {path = "../mission-planner" } + +[build-dependencies] +bindgen = "0.72.0" +cbindgen = "0.29.0" +cc = "1.2.31" diff --git a/mission-planner-c/bindings.h b/mission-planner-c/bindings.h new file mode 100644 index 0000000..dcd158f --- /dev/null +++ b/mission-planner-c/bindings.h @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +typedef enum CMissionResult { + Ok, + Err, + ErrSkip, +} CMissionResult; + +typedef struct CMissionPtr CMissionPtr; + +typedef struct CTask CTask; + +typedef struct MissionMapPtr MissionMapPtr; + +typedef enum CMissionResult (*CTaskFunc)(struct MissionMapPtr *data); + +typedef enum OptionFunction_CTaskFunc_Tag { + Some_CTaskFunc, + None_CTaskFunc, +} OptionFunction_CTaskFunc_Tag; + +typedef struct OptionFunction_CTaskFunc { + OptionFunction_CTaskFunc_Tag tag; + union { + struct { + CTaskFunc some; + }; + }; +} OptionFunction_CTaskFunc; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct CTask *ctask_create(const char *name_ptr, + struct OptionFunction_CTaskFunc task_func, + struct OptionFunction_CTaskFunc repair_task_func); + +struct CMissionPtr *cmission_create(const char *name_ptr, struct CTask *task_array, intptr_t size); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/mission-planner-c/build.rs b/mission-planner-c/build.rs new file mode 100644 index 0000000..46d993b --- /dev/null +++ b/mission-planner-c/build.rs @@ -0,0 +1,34 @@ +use std::env; +use std::path::PathBuf; + +fn main() { + println!("cargo::rerun-if-changed=src/cmission_example.c"); + println!("cargo::rerun-if-changed=src/cmission_example.h"); + let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let mut config: cbindgen::Config = Default::default(); + config.language = cbindgen::Language::C; + config.cpp_compat = true; + + cbindgen::Builder::new() + .with_crate(crate_dir) + .with_config(config) + .generate() + .expect("Unable to generate bindings") + .write_to_file("bindings.h"); + + let bindings = bindgen::Builder::default() + .header("src/cmission_example.h") + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); + + cc::Build::new() + .file("src/cmission_example.c") + .compile("cmission_example.o"); + +} \ No newline at end of file diff --git a/mission-planner-c/src/cmission_example.c b/mission-planner-c/src/cmission_example.c new file mode 100644 index 0000000..604ddc8 --- /dev/null +++ b/mission-planner-c/src/cmission_example.c @@ -0,0 +1,27 @@ +#include "../bindings.h" +#include "cmission_example.h" + +#include "stdio.h" + +enum CMissionResult foo(struct MissionMapPtr *data) { + printf("Hello world!\n"); + return Ok; +} + + +CMissionPtr* cmission_example_create() { + struct OptionFunction_CTaskFunc foo_option; + foo_option.tag = Some_CTaskFunc; + foo_option.some = &foo; + + struct OptionFunction_CTaskFunc null_option; + null_option.tag = None_CTaskFunc; + null_option.some = NULL; + + struct CTask *task = ctask_create("foo", foo_option, null_option); + CTask *task_array[1] = {task}; + + struct CMissionPtr *mission = cmission_create("mission_example", *task_array, 1); + + return mission; +} \ No newline at end of file diff --git a/mission-planner-c/src/cmission_example.h b/mission-planner-c/src/cmission_example.h new file mode 100644 index 0000000..78b9d26 --- /dev/null +++ b/mission-planner-c/src/cmission_example.h @@ -0,0 +1,2 @@ +typedef struct CMissionPtr CMissionPtr; +CMissionPtr* cmission_example_create(); \ No newline at end of file diff --git a/mission-planner-c/src/lib.rs b/mission-planner-c/src/lib.rs new file mode 100644 index 0000000..619b2c4 --- /dev/null +++ b/mission-planner-c/src/lib.rs @@ -0,0 +1,133 @@ +use mission_planner::mission::{Mission, MissionResult, MissionHashMap}; +use std::ffi::{c_char, CStr}; + +#[repr(C)] +pub enum CMissionResult { + Ok, + Err, + ErrSkip +} + +#[repr(C)] +pub enum OptionFunction { + Some(T), + None +} + +pub struct MissionMapPtr; + + +type CTaskFunc = unsafe extern "C" fn(data: *mut MissionMapPtr) -> CMissionResult; + +pub struct CTask { + name: String, + task_func: OptionFunction, + repair_task_func: OptionFunction, +} + +#[unsafe(no_mangle)] +pub extern "C" fn ctask_create(name_ptr: *const c_char, task_func: OptionFunction, repair_task_func: OptionFunction) -> *mut CTask { + + let name; + unsafe { + let temp = CStr::from_ptr(name_ptr); + name = temp.to_str().expect("Failed to get string literal!"); + }; + let name = name.to_string(); + let ctask = CTask { + name, + task_func, + repair_task_func + }; + let ctask_box = Box::new(ctask); + Box::into_raw(ctask_box) + +} + +fn run_with(func: &OptionFunction, data: &MissionHashMap) -> CMissionResult { + let OptionFunction::Some(func) = func else { + return CMissionResult::Err + }; + let data_ptr = Box::new(data); + let data_ptr = Box::into_raw(data_ptr) as *mut MissionMapPtr; + unsafe { func(data_ptr) } +} + +pub struct CMission { + name: String, + task_list: Vec>, +} + +impl CMission { + fn new(name: String, task_list: Vec>) -> Self { + CMission { + name: name, + task_list + } + } +} + +impl Mission for CMission { + fn run(&self, data: &MissionHashMap) -> MissionResult { + let mut res = CMissionResult::Err; + for task in &self.task_list { + let task_res = run_with(&task.task_func, data); + res = match task_res { + CMissionResult::Ok | CMissionResult::ErrSkip => task_res, + CMissionResult::Err => { + let task_res = run_with(&task.repair_task_func, data); + task_res + } + }; + if let CMissionResult::Err = res { + break + } + } + match res { + CMissionResult::Ok => Ok(()), + CMissionResult::Err => Err(false), + CMissionResult::ErrSkip => Err(true), + } + } + + fn name(&self) -> &String { + &self.name + } + +} + +pub struct CMissionPtr; + +#[unsafe(no_mangle)] +//TODO: Change to array +pub extern "C" fn cmission_create(name_ptr: *const c_char, task_array: *mut CTask, size: isize) -> *mut CMissionPtr { + let mut task_list = Vec::new(); + for i in 0..size { + unsafe { + let task = task_array.offset(i); + let task = Box::from_raw(task); + task_list.push(task); + + } + } + + let name; + unsafe { + let temp = CStr::from_ptr(name_ptr); + name = temp.to_str().expect("Failed to get string literal!"); + }; + let c_mission = CMission::new(name.to_string(), task_list); + let mission_box = Box::new(c_mission); + Box::into_raw(mission_box) as *mut CMissionPtr +} + + +#[cfg(test)] +mod tests { + //use super::*; + + //TODO: Write tests + +} + + diff --git a/mission-planner-c/src/main.rs b/mission-planner-c/src/main.rs new file mode 100644 index 0000000..ec37504 --- /dev/null +++ b/mission-planner-c/src/main.rs @@ -0,0 +1,29 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + + +use std::thread::sleep; + +use mission_planner_c::{CMission}; +use mission_planner::mission_scheduler::{MissionScheduler}; +use mission_planner::mission::Mission; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +fn main() { + let mission: Box; + unsafe { + let mission_ptr = cmission_example_create(); + let mission_box = Box::from_raw(mission_ptr as *mut CMission); + mission = mission_box; + } + + let scheduler = MissionScheduler::start(); + scheduler.push_back(mission); + scheduler.run(); + while ! scheduler.is_waiting() { + sleep(std::time::Duration::from_millis(100)); + } + scheduler.stop(); +} \ No newline at end of file diff --git a/mission-planner/Cargo.lock b/mission-planner/Cargo.lock new file mode 100644 index 0000000..fb996dc --- /dev/null +++ b/mission-planner/Cargo.lock @@ -0,0 +1,174 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "mission_planner" +version = "0.1.0" +dependencies = [ + "dashmap", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/mission-planner/Cargo.toml b/mission-planner/Cargo.toml new file mode 100644 index 0000000..f20880f --- /dev/null +++ b/mission-planner/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "mission_planner" +version = "0.1.0" +edition = "2024" + +[lib] +name = "mission_planner" + +[dependencies] +dashmap = "6.1.0" diff --git a/mission-planner/src/concurrent_mission_example.rs b/mission-planner/src/concurrent_mission_example.rs new file mode 100644 index 0000000..be148f1 --- /dev/null +++ b/mission-planner/src/concurrent_mission_example.rs @@ -0,0 +1,36 @@ +use crate::mission::{CommonMission, MissionResult, Mission, MissionHashMap, Task}; + +pub struct ConcExampleMission { + common: CommonMission, +} + +fn conc_example(data: &MissionHashMap) -> MissionResult { + if data.contains_key("flag_request") { + println!("Wrote flag"); + data.insert("flag".to_string(), "true".to_string()); + } + Ok(()) +} + +impl ConcExampleMission { + pub fn new() -> Self { + let name = "example-mission"; + let task = Task::new("conc-example-task".to_string(), Some(conc_example), None); + let mut task_list: Vec = Vec::new(); + task_list.push(task); + let mut repair_task_list: Vec = Vec::new(); + Self { + common: CommonMission::new(name.to_string(), &mut task_list, &mut repair_task_list) + } + } +} + +impl Mission for ConcExampleMission { + fn run(&self, data: &MissionHashMap) -> MissionResult { + self.common.run(data) + } + + fn name(&self) -> &String { + &self.common.name + } +} \ No newline at end of file diff --git a/mission-planner/src/lib.rs b/mission-planner/src/lib.rs new file mode 100644 index 0000000..1069367 --- /dev/null +++ b/mission-planner/src/lib.rs @@ -0,0 +1,2 @@ +pub mod mission; +pub mod mission_scheduler; \ No newline at end of file diff --git a/mission-planner/src/main.rs b/mission-planner/src/main.rs new file mode 100644 index 0000000..7a96a89 --- /dev/null +++ b/mission-planner/src/main.rs @@ -0,0 +1,39 @@ +mod mission; +mod mission_example; +mod mission_scheduler; +mod concurrent_mission_example; + +use std::collections::VecDeque; +use std::time::Duration; + +use crate::{ + mission_scheduler::{MissionScheduler, MissionBox}, + mission_example::ExampleMission, + concurrent_mission_example::ConcExampleMission, +}; + +fn main() { + let foo: MissionBox = Box::new(ExampleMission::new()); + let bar: MissionBox = Box::new(ConcExampleMission::new()); + + let mission_list = VecDeque::from(vec![ + foo + ]); + let conc_mission_list = VecDeque::from(vec![ + bar + ]); + + let scheduler = MissionScheduler::start(); + scheduler.append(mission_list); + scheduler.conc_append(conc_mission_list); + let data = scheduler.get_data(); + + scheduler.run(); + while ! scheduler.is_waiting() { + println!("{:#?}", data); + std::thread::sleep(Duration::from_secs(1)); + } + scheduler.stop(); + + +} diff --git a/mission-planner/src/mission.rs b/mission-planner/src/mission.rs new file mode 100644 index 0000000..9055d28 --- /dev/null +++ b/mission-planner/src/mission.rs @@ -0,0 +1,80 @@ +use dashmap::DashMap; + +pub type MissionHashMap = DashMap; +pub type MissionResult = Result<(), bool>; + +pub struct Task { + pub name: String, + func: Option MissionResult>, + repair_func: Option MissionResult> +} + +fn run_with(func: Option MissionResult>, data: &MissionHashMap) -> MissionResult { + let Some(func) = func else { + return Err(false); + }; + func(data) +} + +impl Task { + pub fn new(name: String, func: Option< fn(&MissionHashMap) -> MissionResult>, + repair_func: Option MissionResult>) -> Task { + Task { + name, + func, + repair_func, + } + } +} + +pub struct CommonMission { + pub name: String, + task_list: Vec, + safety_task_list: Vec, +} + +impl CommonMission { + pub fn new(name: String, task_list: &mut Vec, repair_task_list: &mut Vec) -> Self { + let mut common = CommonMission { + name, + task_list: Vec::new(), + safety_task_list: Vec::new(), + }; + common.task_list.append(task_list); + common.safety_task_list.append(repair_task_list); + common + } + + pub fn run(&self, data: &DashMap) -> MissionResult { + if self.task_list.is_empty() { + return Ok(()) + } + + let mut res = Ok(()); + for task in &self.task_list { + let task_res = run_with(task.func, data); + res = match task_res { + Ok(_) => task_res, + Err(skip) => { + if skip { + task_res + } else { + run_with(task.repair_func, data) + } + }, + + }; + if let Err(skip) = res { + if ! skip { + break + } + } + } + res + } +} + +pub trait Mission : Send + Sync { + fn run(&self, data: &DashMap) -> MissionResult; + fn name(&self) -> &String; +} \ No newline at end of file diff --git a/mission-planner/src/mission_example.rs b/mission-planner/src/mission_example.rs new file mode 100644 index 0000000..c3a676a --- /dev/null +++ b/mission-planner/src/mission_example.rs @@ -0,0 +1,49 @@ +use dashmap::DashMap; + +use std::thread::sleep; +use crate::mission::{CommonMission, MissionResult, Mission, MissionHashMap, Task}; + +pub struct ExampleMission { + common: CommonMission, +} + +fn example(data: &MissionHashMap) -> MissionResult { + println!("Hello world!"); + Err(false) +} + +fn repair_example(data: &MissionHashMap) -> MissionResult { + println!("Requested flag"); + data.insert("flag_request".to_string(), "true".to_string()); + + while ! data.contains_key("flag") { + sleep(std::time::Duration::from_millis(100)); + } + println!("Got flag!"); + + Ok(()) +} + +impl ExampleMission { + pub fn new() -> Self { + let name = "example-mission"; + let task = Task::new("example-task".to_string(), Some(example), Some(repair_example)); + let mut task_list: Vec = Vec::new(); + task_list.push(task); + let mut repair_task_list: Vec = Vec::new(); + Self { + common: CommonMission::new(name.to_string(), &mut task_list, &mut repair_task_list) + } + } +} + +impl Mission for ExampleMission { + fn run(&self, data: &DashMap) -> MissionResult { + self.common.run(data) + } + + fn name(&self) -> &String { + &self.common.name + } + +} \ No newline at end of file diff --git a/mission-planner/src/mission_scheduler.rs b/mission-planner/src/mission_scheduler.rs new file mode 100644 index 0000000..cd1fb25 --- /dev/null +++ b/mission-planner/src/mission_scheduler.rs @@ -0,0 +1,187 @@ +use dashmap::DashMap; +use crate::mission::{Mission, MissionHashMap}; +use std::collections::VecDeque; +use std::sync::{Arc, Mutex}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::thread::{self, sleep}; + +pub type MissionBox = Box; +pub type MissionVec = VecDeque; +struct MissionThreadData { + mission_list: Arc>, + conc_mission_list: Arc>, + mission_data: Arc>, + run: AtomicBool, + stop: AtomicBool, + waiting: AtomicBool, + +} + +impl MissionThreadData { + fn new() -> Self { + Self { + mission_list: Arc::new(Mutex::new(VecDeque::new())), + conc_mission_list: Arc::new(Mutex::new(VecDeque::new())), + mission_data: Arc::new(DashMap::new()), + run: AtomicBool::new(false), + stop: AtomicBool::new(false), + waiting: AtomicBool::new(false), + } + } + + fn pop_front(&self) -> Option { + self.mission_list.lock().unwrap().pop_front() + } + + fn push_back(&self, mission: MissionBox) { + self.mission_list.lock().unwrap().push_back(mission); + } + + fn append(&self, mut mission_vec: MissionVec) { + self.mission_list.lock().unwrap().append(&mut mission_vec); + } + + fn conc_push_back(&self, mission: MissionBox) { + self.conc_mission_list.lock().unwrap().push_back(mission); + } + + fn conc_append(&self, mut mission_vec: MissionVec) { + self.conc_mission_list.lock().unwrap().append(&mut mission_vec); + } +} +pub struct MissionScheduler { + normal_handle: thread::JoinHandle<()>, + concurrent_handle: thread::JoinHandle<()>, + scheduler_data : Arc, +} + +impl MissionScheduler { + fn new(normal_handle: thread::JoinHandle<()>, concurrent_handle: thread::JoinHandle<()>, scheduler_data: Arc) -> Self { + Self { + normal_handle, + concurrent_handle, + scheduler_data, + } + } + + pub fn push_back(&self, mission: MissionBox) { + self.scheduler_data.push_back(mission); + } + + pub fn conc_push_back(&self, mission: MissionBox) { + self.scheduler_data.conc_push_back(mission); + } + + pub fn append(&self, mission_vec: MissionVec) { + self.scheduler_data.append(mission_vec); + } + + pub fn conc_append(&self, mission_vec: MissionVec) { + self.scheduler_data.conc_append(mission_vec); + } + + pub fn get_data(&self) -> Arc { + self.scheduler_data.mission_data.clone() + } + + pub fn is_waiting(&self) -> bool { + self.scheduler_data.waiting.load(Ordering::Relaxed) + } + + // pub fn concurrent_append(&mut self, mission: &mut Vec + Send >>) { + // self.concurrent_mission_list.append(mission); + // } + + pub fn start() -> Self { + let scheduler_data = Arc::new(MissionThreadData::new()); + + let scheduler_data_normal = scheduler_data.clone(); + let normal_func = move || { + let mut stop = false; + let data = &scheduler_data_normal.mission_data; + + while ! stop { + let run = scheduler_data_normal.run.load(Ordering::Relaxed); + stop = scheduler_data_normal.stop.load(Ordering::Relaxed); + if ! run { + sleep(std::time::Duration::from_millis(1)); + continue + } + + + let mission = scheduler_data_normal.pop_front(); + let Some(mission) = mission else { + println!("Waiting for missions..."); + scheduler_data_normal.waiting.store(true, Ordering::Relaxed); + sleep(std::time::Duration::from_secs(3)); + continue; + }; + let res = mission.run(data); + match res { + Ok(_) => (), + Err(skip) => { + if skip { + println!("{} mission skipped!", mission.name()); + } + else { + println!("{} mission failed!", mission.name()); + scheduler_data_normal.stop.store(true, Ordering::Relaxed); + stop = true; + } + } + }; + + + sleep(std::time::Duration::from_millis(1)); + } + }; + + let scheduler_data_conc = scheduler_data.clone(); + let concurrent_func = move || { + let mut stop = false; + let conc_mission_list = scheduler_data_conc.conc_mission_list.clone(); + let data = &scheduler_data_conc.mission_data; + while ! stop { + let run = scheduler_data_conc.run.load(Ordering::Relaxed); + stop = scheduler_data_conc.stop.load(Ordering::Relaxed); + if ! run { + sleep(std::time::Duration::from_millis(1)); + continue + } + + let getter = conc_mission_list.lock().unwrap(); + for mission in &*getter { + let res = mission.run(data); + match res { + Ok(_) => (), + Err(skip) => { + if skip { + println!("{} mission skipped!", mission.name()); + } + else { + println!("{} mission failed!", mission.name()); + scheduler_data_conc.stop.store(true, Ordering::Relaxed); + stop = true; + } + } + }; + }; + + sleep(std::time::Duration::from_millis(100)); + } + }; + let normal_handle = thread::spawn(normal_func); + let conc_handle = thread::spawn(concurrent_func); + MissionScheduler::new(normal_handle, conc_handle, scheduler_data.clone()) + } + + pub fn run(&self) { + self.scheduler_data.run.store(true, Ordering::Relaxed); + } + + pub fn stop(self) { + self.scheduler_data.stop.store(true, Ordering::Relaxed); + self.normal_handle.join().expect("Failed to join mission handle!"); + self.concurrent_handle.join().expect("Failed to join concurrent mission handle!"); + } +} \ No newline at end of file