From 5f97863e5c9323d1d695b5b26e20970e08462568 Mon Sep 17 00:00:00 2001 From: Hongbo Miao <3375461+hongbo-miao@users.noreply.github.com> Date: Thu, 21 Nov 2024 19:04:59 -0800 Subject: [PATCH] feat(iads): add iads data producer --- README.md | 15 +- .../iads/iads-data-producer/Cargo.lock | 566 ++++++++++++++++++ .../iads/iads-data-producer/Cargo.toml | 13 + .../iads/iads-data-producer/Makefile | 21 + .../iads/iads-data-producer/src/main.rs | 132 ++++ 5 files changed, 740 insertions(+), 7 deletions(-) create mode 100644 data-visualization/iads/iads-data-producer/Cargo.lock create mode 100644 data-visualization/iads/iads-data-producer/Cargo.toml create mode 100644 data-visualization/iads/iads-data-producer/Makefile create mode 100644 data-visualization/iads/iads-data-producer/src/main.rs diff --git a/README.md b/README.md index 0ff1cd7499..bcae731f11 100644 --- a/README.md +++ b/README.md @@ -325,6 +325,7 @@ make kubernetes-clean - **Metabase** - Data visualization - **Apache Superset** - Data visualization - **Tableau** - Data visualization +- **IADS** - Data visualization ### Data Analytics @@ -578,9 +579,9 @@ make kubernetes-clean ## Simulation - **AnyLogic** - Simulation modeling tool -- **NI LabVIEW** - Graphical programming environment -- **NI VeriStand** - Real-time testing and simulation - - **niveristand** - NI VeriStand API library +- **LabVIEW** - Graphical programming environment +- **VeriStand** - Real-time testing and simulation + - **niveristand** - VeriStand API library - **npTDMS** - TDMS files reading and writing - **PyVISA** - Virtual instrument software architecture (VISA) API library - **MATLAB** - Programming and numeric computing platform @@ -860,13 +861,13 @@ The following presents a model of a radar-based air defense system. Bombers are ![AnyLogic screenshot](https://github.com/hongbo-miao/hongbomiao.com/assets/3375461/dc2c8c2e-8acc-4df5-8a1a-fdf1da7c6f43) -### NI LabVIEW - Graphical Programming Environment +### LabVIEW - Graphical Programming Environment -![NI LabVIEW screenshot](https://github.com/hongbo-miao/hongbomiao.com/assets/3375461/acf44d58-a3f4-433b-9045-f4d913b05dfd) +![LabVIEW screenshot](https://github.com/hongbo-miao/hongbomiao.com/assets/3375461/acf44d58-a3f4-433b-9045-f4d913b05dfd) -### NI VeriStand - Real-Time Testing and Simulation +### VeriStand - Real-Time Testing and Simulation -![NI VeriStand screenshot](https://github.com/hongbo-miao/hongbomiao.com/assets/3375461/dc7d0c92-7d55-4251-9d39-c53eaac699e2) +![VeriStand screenshot](https://github.com/hongbo-miao/hongbomiao.com/assets/3375461/dc7d0c92-7d55-4251-9d39-c53eaac699e2) ### CoppeliaSim - Robot Simulation diff --git a/data-visualization/iads/iads-data-producer/Cargo.lock b/data-visualization/iads/iads-data-producer/Cargo.lock new file mode 100644 index 0000000000..400e182c28 --- /dev/null +++ b/data-visualization/iads/iads-data-producer/Cargo.lock @@ -0,0 +1,566 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clippy" +version = "0.0.302" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d911ee15579a3f50880d8c1d59ef6e79f9533127a3bd342462f5d584f5e8c294" +dependencies = [ + "term", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "iads-data-producer" +version = "1.0.0" +dependencies = [ + "clippy", + "rand", + "tokio", +] + +[[package]] +name = "libc" +version = "0.2.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.7", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.9.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e256ff62cee3e03def855c4d4260106d2bb1696fdc01af03e9935b993720a5" +dependencies = [ + "rand_chacha", + "rand_core", + "zerocopy", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d299e9db34f6623b2a9e86c015d6e173d5f46d64d4b9b8cc46ae8a982a50b04c" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e93f5a5e3c528cda9acb0928c31b2ba868c551cc46e67b778075e34aab9906" +dependencies = [ + "getrandom 0.2.15", + "zerocopy", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom 0.1.16", + "redox_syscall 0.1.57", + "rust-argon2", +] + +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "syn" +version = "2.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "term" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +dependencies = [ + "byteorder", + "dirs", + "winapi", +] + +[[package]] +name = "tokio" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[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" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/data-visualization/iads/iads-data-producer/Cargo.toml b/data-visualization/iads/iads-data-producer/Cargo.toml new file mode 100644 index 0000000000..25c0922f52 --- /dev/null +++ b/data-visualization/iads/iads-data-producer/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "iads-data-producer" +version = "1.0.0" +rust-version = "1.80" +edition = "2021" + +[dependencies] +rand = "0.9.0-alpha.2" +tokio = { version = "1.41.0", features = ["full"] } + +[dev-dependencies] +clippy = "0.0.302" + diff --git a/data-visualization/iads/iads-data-producer/Makefile b/data-visualization/iads/iads-data-producer/Makefile new file mode 100644 index 0000000000..b2048694b2 --- /dev/null +++ b/data-visualization/iads/iads-data-producer/Makefile @@ -0,0 +1,21 @@ +cargo-clean: + cargo clean +cargo-update: + cargo update +cargo-test: + cargo test --all-features +cargo-build: + cargo build +cargo-run: + cargo run +cargo-run-release: + cargo run --release + +lint-rust-rustfmt: + cargo fmt --all -- --check +lint-rust-rustfmt-fix: + cargo fmt --all +lint-rust-clippy: + cargo clippy +lint-rust-clippy-fix: + cargo clippy --fix --allow-dirty --allow-staged diff --git a/data-visualization/iads/iads-data-producer/src/main.rs b/data-visualization/iads/iads-data-producer/src/main.rs new file mode 100644 index 0000000000..ea6af5d5b3 --- /dev/null +++ b/data-visualization/iads/iads-data-producer/src/main.rs @@ -0,0 +1,132 @@ +use rand::Rng; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpListener; +use tokio::time::{sleep, Duration}; + +// Constants for packet structure +const HEADER_SIZE: i32 = 32; +const TAG_SIZE: i32 = 2; +const VALUE_SIZE: i32 = 4; +const TIME_PAIR_SIZE: i32 = (TAG_SIZE * 2) + (VALUE_SIZE * 2); // 2 tags + 2 values +const SIGNAL_PAIR_SIZE: i32 = (TAG_SIZE * 2) + (VALUE_SIZE * 2); // 2 tags + 2 values + +// Configuration signals +struct StreamConfig { + num_signals: i32, + rate_hz: f64, + port: u16, +} + +impl Default for StreamConfig { + fn default() -> Self { + StreamConfig { + num_signals: 4, + rate_hz: 50.0, + port: 49000, + } + } +} + +fn calculate_packet_size(num_signals: i32) -> i32 { + let signal_pairs = (num_signals + 1) / 2; + HEADER_SIZE + TIME_PAIR_SIZE + (signal_pairs * SIGNAL_PAIR_SIZE) +} + +async fn send_data_stream( + mut stream: tokio::net::TcpStream, + config: &StreamConfig, +) -> std::io::Result<()> { + let packet_size = calculate_packet_size(config.num_signals); + let mut rng = rand::thread_rng(); + + // Calculate the interval in milliseconds from Hz + let interval_ms = (1000.0 / config.rate_hz) as u64; + // Calculate time increment in nanoseconds from Hz + let time_increment = (1.0 / config.rate_hz * 1_000_000_000.0) as i64; + + let mut time = 0i64; + let mut packet_counter = 0i32; + let mut buffer = vec![0u8; packet_size as usize]; + + // Handshake + stream.write_all(&[1u8]).await?; + stream.write_all(&100i32.to_le_bytes()).await?; + + loop { + let mut offset = 0usize; + + // Header + buffer[offset..offset + VALUE_SIZE as usize] + .copy_from_slice(&(packet_size - VALUE_SIZE).to_le_bytes()); + buffer[offset + VALUE_SIZE as usize..offset + VALUE_SIZE as usize * 2] + .copy_from_slice(&packet_counter.to_le_bytes()); + buffer[offset + VALUE_SIZE as usize * 2..offset + VALUE_SIZE as usize * 3] + .copy_from_slice(&packet_counter.to_le_bytes()); + for i in 3..8 { + buffer[offset + VALUE_SIZE as usize * i..offset + VALUE_SIZE as usize * (i + 1)] + .copy_from_slice(&0i32.to_le_bytes()); + } + offset += HEADER_SIZE as usize; + + // Time tags and values + for tag in [1u16, 2u16] { + buffer[offset..offset + TAG_SIZE as usize].copy_from_slice(&tag.to_le_bytes()); + offset += TAG_SIZE as usize; + } + + let time_high = (time >> 32) as u32; + let time_low = (time & 0xFFFFFFFF) as u32; + buffer[offset..offset + VALUE_SIZE as usize].copy_from_slice(&time_high.to_le_bytes()); + offset += VALUE_SIZE as usize; + buffer[offset..offset + VALUE_SIZE as usize].copy_from_slice(&time_low.to_le_bytes()); + offset += VALUE_SIZE as usize; + + // Signals with random values + for n in (0..config.num_signals).step_by(2) { + // Tags + buffer[offset..offset + TAG_SIZE as usize] + .copy_from_slice(&((3 + n) as u16).to_le_bytes()); + offset += TAG_SIZE as usize; + buffer[offset..offset + TAG_SIZE as usize] + .copy_from_slice(&((4 + n) as u16).to_le_bytes()); + offset += TAG_SIZE as usize; + + // Random values + let value1: f32 = rng.gen_range(0.0..100.0); + let value2: f32 = rng.gen_range(0.0..100.0); + + buffer[offset..offset + VALUE_SIZE as usize].copy_from_slice(&value1.to_le_bytes()); + offset += VALUE_SIZE as usize; + buffer[offset..offset + VALUE_SIZE as usize].copy_from_slice(&value2.to_le_bytes()); + offset += VALUE_SIZE as usize; + } + + if let Err(e) = stream.write_all(&buffer).await { + println!("Send error: {}", e); + return Ok(()); + } + + packet_counter += 1; + time += time_increment; + sleep(Duration::from_millis(interval_ms)).await; + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let config = StreamConfig::default(); + let listener = TcpListener::bind(("0.0.0.0", config.port)).await?; + println!("Listening on port {} at {} Hz", config.port, config.rate_hz); + + loop { + println!("Waiting for client connection..."); + match listener.accept().await { + Ok((stream, _)) => { + println!("Client connected"); + send_data_stream(stream, &config).await?; + println!("Client disconnected"); + } + Err(e) => println!("Accept failed: {}", e), + } + } +}