minot-cli 0.10.2__tar.gz → 0.11.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {minot_cli-0.10.2 → minot_cli-0.11.1}/Cargo.lock +29 -29
- {minot_cli-0.10.2 → minot_cli-0.11.1}/Cargo.toml +17 -17
- {minot_cli-0.10.2 → minot_cli-0.11.1}/PKG-INFO +1 -1
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/Cargo.toml +19 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/gen_c.rs +74 -24
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_bagread/src/lib.rs +18 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_coord/src/lib.rs +4 -2
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/README.md +17 -8
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/src/lib.rs +9 -1
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_sea/src/lib.rs +12 -1
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_sea/src/net.rs +78 -54
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_sea/src/ship.rs +273 -173
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_wind/src/ros2_r2r.rs +2 -1
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/build.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/app.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/coord.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/event.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/gen_c.rs.patch +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/gen_c.rs.patch2 +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/gen_c_tests.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/handler.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/minot.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/runner.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/tui.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/minot/src/ui.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_bagread/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_bagread/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_bagread/examples/stream_probe.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_bagread/src/qos.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_bagread/test/metadata-v5.yml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_bagread/test/metadata-v9.yml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_coord/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_coord/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/default.rl +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/cleanup.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/core/marina.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/core/mod.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/io/bag.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/io/db3_transform.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/io/mcap_transform.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/io/mod.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/io/pack.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/io/transform_progress.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/lib.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/model/bag_ref.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/model/mod.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/progress.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/driver.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/folder.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/gdrive.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/gdrive_auth.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/http.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/minot/block_store.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/minot/mod.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/minot/protocol.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/minot/remote_file.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/mod.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/ssh.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/stub.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/registry/transfer_progress.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/storage/cache.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/storage/config.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_dataset/src/storage/mod.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_flow/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_flow/src/lib.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/src/buffer.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/src/format.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/src/init.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/src/lib.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/src/logger.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/src/pane.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_log/src/tests.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_mtc/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_mtc/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_mtc/src/lib.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_net/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_net/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_net/examples/c_interop_layout.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_net/examples/c_interop_pc2.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_net/examples/c_interop_test.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_net/src/bin_layout.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_net/src/c_interop_test.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_net/src/lib.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/examples/be_node.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/examples/be_sub.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/examples/be_sub_drop.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/examples/be_sub_error.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/examples/pub.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/examples/smol.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_pubsub/examples/sub.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_scope/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_scope/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_scope/examples/test.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_scope/src/lib.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_sea/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_sea/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_sea/src/client.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_sea/src/coordinator.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_sea/src/network.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_service/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_service/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_service/examples/bad_service_client.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_service/examples/basic_service_client.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_service/examples/basic_service_client2.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_service/examples/basic_service_server.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_service/src/lib.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_wind/Cargo.toml +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_wind/README.md +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_wind/src/hiroz.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_wind/src/lib.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_wind/src/mt_pubsub.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_wind/src/ros1.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/mt_wind/src/ros2.rs +0 -0
- {minot_cli-0.10.2 → minot_cli-0.11.1}/pyproject.toml +0 -0
|
@@ -441,9 +441,9 @@ dependencies = [
|
|
|
441
441
|
|
|
442
442
|
[[package]]
|
|
443
443
|
name = "bindgen"
|
|
444
|
-
version = "0.
|
|
444
|
+
version = "0.72.1"
|
|
445
445
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
446
|
-
checksum = "
|
|
446
|
+
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
|
|
447
447
|
dependencies = [
|
|
448
448
|
"bitflags 2.13.1",
|
|
449
449
|
"cexpr",
|
|
@@ -3802,7 +3802,7 @@ dependencies = [
|
|
|
3802
3802
|
|
|
3803
3803
|
[[package]]
|
|
3804
3804
|
name = "minot"
|
|
3805
|
-
version = "0.
|
|
3805
|
+
version = "0.11.1"
|
|
3806
3806
|
dependencies = [
|
|
3807
3807
|
"anyhow",
|
|
3808
3808
|
"bytesize",
|
|
@@ -3929,7 +3929,7 @@ dependencies = [
|
|
|
3929
3929
|
|
|
3930
3930
|
[[package]]
|
|
3931
3931
|
name = "mt_action"
|
|
3932
|
-
version = "0.
|
|
3932
|
+
version = "0.11.1"
|
|
3933
3933
|
dependencies = [
|
|
3934
3934
|
"anyhow",
|
|
3935
3935
|
"log",
|
|
@@ -3944,7 +3944,7 @@ dependencies = [
|
|
|
3944
3944
|
|
|
3945
3945
|
[[package]]
|
|
3946
3946
|
name = "mt_bagread"
|
|
3947
|
-
version = "0.
|
|
3947
|
+
version = "0.11.1"
|
|
3948
3948
|
dependencies = [
|
|
3949
3949
|
"anyhow",
|
|
3950
3950
|
"camino",
|
|
@@ -3965,7 +3965,7 @@ dependencies = [
|
|
|
3965
3965
|
|
|
3966
3966
|
[[package]]
|
|
3967
3967
|
name = "mt_coord"
|
|
3968
|
-
version = "0.
|
|
3968
|
+
version = "0.11.1"
|
|
3969
3969
|
dependencies = [
|
|
3970
3970
|
"anyhow",
|
|
3971
3971
|
"fs2",
|
|
@@ -3979,7 +3979,7 @@ dependencies = [
|
|
|
3979
3979
|
|
|
3980
3980
|
[[package]]
|
|
3981
3981
|
name = "mt_dataset"
|
|
3982
|
-
version = "0.
|
|
3982
|
+
version = "0.11.1"
|
|
3983
3983
|
dependencies = [
|
|
3984
3984
|
"anyhow",
|
|
3985
3985
|
"async-trait",
|
|
@@ -4022,7 +4022,7 @@ dependencies = [
|
|
|
4022
4022
|
|
|
4023
4023
|
[[package]]
|
|
4024
4024
|
name = "mt_flow"
|
|
4025
|
-
version = "0.
|
|
4025
|
+
version = "0.11.1"
|
|
4026
4026
|
dependencies = [
|
|
4027
4027
|
"anyhow",
|
|
4028
4028
|
"env_logger",
|
|
@@ -4036,7 +4036,7 @@ dependencies = [
|
|
|
4036
4036
|
|
|
4037
4037
|
[[package]]
|
|
4038
4038
|
name = "mt_log"
|
|
4039
|
-
version = "0.
|
|
4039
|
+
version = "0.11.1"
|
|
4040
4040
|
dependencies = [
|
|
4041
4041
|
"env_filter 2.0.0",
|
|
4042
4042
|
"env_logger",
|
|
@@ -4048,7 +4048,7 @@ dependencies = [
|
|
|
4048
4048
|
|
|
4049
4049
|
[[package]]
|
|
4050
4050
|
name = "mt_mtc"
|
|
4051
|
-
version = "0.
|
|
4051
|
+
version = "0.11.1"
|
|
4052
4052
|
dependencies = [
|
|
4053
4053
|
"anyhow",
|
|
4054
4054
|
"ariadne",
|
|
@@ -4061,7 +4061,7 @@ dependencies = [
|
|
|
4061
4061
|
|
|
4062
4062
|
[[package]]
|
|
4063
4063
|
name = "mt_net"
|
|
4064
|
-
version = "0.
|
|
4064
|
+
version = "0.11.1"
|
|
4065
4065
|
dependencies = [
|
|
4066
4066
|
"anyhow",
|
|
4067
4067
|
"rkyv 0.8.18",
|
|
@@ -4071,7 +4071,7 @@ dependencies = [
|
|
|
4071
4071
|
|
|
4072
4072
|
[[package]]
|
|
4073
4073
|
name = "mt_pubsub"
|
|
4074
|
-
version = "0.
|
|
4074
|
+
version = "0.11.1"
|
|
4075
4075
|
dependencies = [
|
|
4076
4076
|
"anyhow",
|
|
4077
4077
|
"async-trait",
|
|
@@ -4090,7 +4090,7 @@ dependencies = [
|
|
|
4090
4090
|
|
|
4091
4091
|
[[package]]
|
|
4092
4092
|
name = "mt_rat"
|
|
4093
|
-
version = "0.
|
|
4093
|
+
version = "0.11.1"
|
|
4094
4094
|
dependencies = [
|
|
4095
4095
|
"anyhow",
|
|
4096
4096
|
"async-trait",
|
|
@@ -4105,7 +4105,7 @@ dependencies = [
|
|
|
4105
4105
|
|
|
4106
4106
|
[[package]]
|
|
4107
4107
|
name = "mt_scope"
|
|
4108
|
-
version = "0.
|
|
4108
|
+
version = "0.11.1"
|
|
4109
4109
|
dependencies = [
|
|
4110
4110
|
"anyhow",
|
|
4111
4111
|
"env_logger",
|
|
@@ -4118,7 +4118,7 @@ dependencies = [
|
|
|
4118
4118
|
|
|
4119
4119
|
[[package]]
|
|
4120
4120
|
name = "mt_sea"
|
|
4121
|
-
version = "0.
|
|
4121
|
+
version = "0.11.1"
|
|
4122
4122
|
dependencies = [
|
|
4123
4123
|
"anyhow",
|
|
4124
4124
|
"async-trait",
|
|
@@ -4135,7 +4135,7 @@ dependencies = [
|
|
|
4135
4135
|
|
|
4136
4136
|
[[package]]
|
|
4137
4137
|
name = "mt_service"
|
|
4138
|
-
version = "0.
|
|
4138
|
+
version = "0.11.1"
|
|
4139
4139
|
dependencies = [
|
|
4140
4140
|
"anyhow",
|
|
4141
4141
|
"log",
|
|
@@ -4149,7 +4149,7 @@ dependencies = [
|
|
|
4149
4149
|
|
|
4150
4150
|
[[package]]
|
|
4151
4151
|
name = "mt_wind"
|
|
4152
|
-
version = "0.
|
|
4152
|
+
version = "0.11.1"
|
|
4153
4153
|
dependencies = [
|
|
4154
4154
|
"anyhow",
|
|
4155
4155
|
"async-trait",
|
|
@@ -5442,9 +5442,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
|
|
5442
5442
|
|
|
5443
5443
|
[[package]]
|
|
5444
5444
|
name = "r2r"
|
|
5445
|
-
version = "0.9.
|
|
5445
|
+
version = "0.9.7"
|
|
5446
5446
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
5447
|
-
checksum = "
|
|
5447
|
+
checksum = "1fe8623ef13a4f3c25f4ef407c6032eee9e1c95d0912d8ed758f616cbb95a6cd"
|
|
5448
5448
|
dependencies = [
|
|
5449
5449
|
"force-send-sync",
|
|
5450
5450
|
"futures",
|
|
@@ -5470,9 +5470,9 @@ dependencies = [
|
|
|
5470
5470
|
|
|
5471
5471
|
[[package]]
|
|
5472
5472
|
name = "r2r_actions"
|
|
5473
|
-
version = "0.9.
|
|
5473
|
+
version = "0.9.7"
|
|
5474
5474
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
5475
|
-
checksum = "
|
|
5475
|
+
checksum = "441f4aca2b1dfe553ab40f03bd869445d02dccd7ddff4c5f32e3a681fcd47c57"
|
|
5476
5476
|
dependencies = [
|
|
5477
5477
|
"bindgen",
|
|
5478
5478
|
"r2r_common",
|
|
@@ -5482,9 +5482,9 @@ dependencies = [
|
|
|
5482
5482
|
|
|
5483
5483
|
[[package]]
|
|
5484
5484
|
name = "r2r_common"
|
|
5485
|
-
version = "0.9.
|
|
5485
|
+
version = "0.9.7"
|
|
5486
5486
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
5487
|
-
checksum = "
|
|
5487
|
+
checksum = "786a8b50036ed5d38a1dfbee73c711e270acd9a518b73351c66d541c1fa05422"
|
|
5488
5488
|
dependencies = [
|
|
5489
5489
|
"bindgen",
|
|
5490
5490
|
"os_str_bytes",
|
|
@@ -5494,9 +5494,9 @@ dependencies = [
|
|
|
5494
5494
|
|
|
5495
5495
|
[[package]]
|
|
5496
5496
|
name = "r2r_macros"
|
|
5497
|
-
version = "0.9.
|
|
5497
|
+
version = "0.9.7"
|
|
5498
5498
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
5499
|
-
checksum = "
|
|
5499
|
+
checksum = "743bfcbea83d856d97d222b3c3545d4848ba81572f1d52dc5b6bff4899b8583d"
|
|
5500
5500
|
dependencies = [
|
|
5501
5501
|
"proc-macro2",
|
|
5502
5502
|
"quote",
|
|
@@ -5505,9 +5505,9 @@ dependencies = [
|
|
|
5505
5505
|
|
|
5506
5506
|
[[package]]
|
|
5507
5507
|
name = "r2r_msg_gen"
|
|
5508
|
-
version = "0.9.
|
|
5508
|
+
version = "0.9.7"
|
|
5509
5509
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
5510
|
-
checksum = "
|
|
5510
|
+
checksum = "db410864937e12357cd65f3e82c6fb7c8372d0493f154886952522bad87817c9"
|
|
5511
5511
|
dependencies = [
|
|
5512
5512
|
"bindgen",
|
|
5513
5513
|
"force-send-sync",
|
|
@@ -5523,9 +5523,9 @@ dependencies = [
|
|
|
5523
5523
|
|
|
5524
5524
|
[[package]]
|
|
5525
5525
|
name = "r2r_rcl"
|
|
5526
|
-
version = "0.9.
|
|
5526
|
+
version = "0.9.7"
|
|
5527
5527
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
5528
|
-
checksum = "
|
|
5528
|
+
checksum = "7c0420d9ea790fe2b4f66f7a88c8a7901491075d2fed4037010b03173392a22a"
|
|
5529
5529
|
dependencies = [
|
|
5530
5530
|
"bindgen",
|
|
5531
5531
|
"paste",
|
|
@@ -4,12 +4,12 @@ members = ["minot", "mt_pubsub", "mt_coord", "mt_bagread", "mt_mtc", "mt_sea", "
|
|
|
4
4
|
resolver = "3"
|
|
5
5
|
|
|
6
6
|
[workspace.package]
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.11.1"
|
|
8
8
|
keywords = ["robotics"]
|
|
9
9
|
license = "MIT OR Apache-2.0"
|
|
10
|
-
repository = "https://codeberg.org/stelzo/minot"
|
|
10
|
+
repository = "https://codeberg.org/stelzo/minot.git"
|
|
11
11
|
edition = "2024"
|
|
12
|
-
authors = ["
|
|
12
|
+
authors = ["stelzo <stelzo@steado.de>"]
|
|
13
13
|
categories = ["science::robotics"]
|
|
14
14
|
documentation = "https://uos.github.io/minot"
|
|
15
15
|
homepage = "https://uos.github.io/minot"
|
|
@@ -28,19 +28,19 @@ exclude = [
|
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
[workspace.dependencies]
|
|
31
|
-
mt_sea = { path = "mt_sea", version = "0.
|
|
32
|
-
mt_coord = { path = "mt_coord", version = "0.
|
|
33
|
-
mt_pubsub = { path = "mt_pubsub", version = "0.
|
|
34
|
-
mt_service = { path = "mt_service", version = "0.
|
|
35
|
-
mt_action = { path = "mt_action", version = "0.
|
|
36
|
-
mt_scope = { path = "mt_scope", version = "0.
|
|
37
|
-
mt_bagread = { path = "mt_bagread", version = "0.
|
|
38
|
-
mt_net = { path = "mt_net", version = "0.
|
|
39
|
-
mt_flow = { path = "mt_flow", version = "0.
|
|
40
|
-
mt_dataset = { path = "mt_dataset", version = "0.
|
|
41
|
-
mt_wind = { path = "mt_wind", version = "0.
|
|
42
|
-
mt_mtc = { path = "mt_mtc", version = "0.
|
|
43
|
-
mt_log = { path = "mt_log", version = "0.
|
|
31
|
+
mt_sea = { path = "mt_sea", version = "0.11.1", default-features = false }
|
|
32
|
+
mt_coord = { path = "mt_coord", version = "0.11.1", default-features = false }
|
|
33
|
+
mt_pubsub = { path = "mt_pubsub", version = "0.11.1", default-features = false }
|
|
34
|
+
mt_service = { path = "mt_service", version = "0.11.1", default-features = false }
|
|
35
|
+
mt_action = { path = "mt_action", version = "0.11.1", default-features = false }
|
|
36
|
+
mt_scope = { path = "mt_scope", version = "0.11.1", default-features = false }
|
|
37
|
+
mt_bagread = { path = "mt_bagread", version = "0.11.1", default-features = false }
|
|
38
|
+
mt_net = { path = "mt_net", version = "0.11.1", default-features = false }
|
|
39
|
+
mt_flow = { path = "mt_flow", version = "0.11.1", default-features = false }
|
|
40
|
+
mt_dataset = { path = "mt_dataset", version = "0.11.1", default-features = false }
|
|
41
|
+
mt_wind = { path = "mt_wind", version = "0.11.1", default-features = false }
|
|
42
|
+
mt_mtc = { path = "mt_mtc", version = "0.11.1", default-features = false }
|
|
43
|
+
mt_log = { path = "mt_log", version = "0.11.1", default-features = false }
|
|
44
44
|
|
|
45
45
|
# Tools
|
|
46
46
|
anyhow = "1.0"
|
|
@@ -88,7 +88,7 @@ rkyv = { version = "0.8.18" }
|
|
|
88
88
|
serde = { version = "1.0", features = ["derive"] }
|
|
89
89
|
|
|
90
90
|
# ROS
|
|
91
|
-
r2r = "0.9.
|
|
91
|
+
r2r = "0.9.7"
|
|
92
92
|
hiroz = { version = "0.2.0", git = "https://github.com/ZettaScaleLabs/hiroz.git", tag = "v0.2.0" }
|
|
93
93
|
hiroz-msgs = { version = "0.2.0", git = "https://github.com/ZettaScaleLabs/hiroz.git", tag = "v0.2.0", default-features = false, features = [
|
|
94
94
|
"std_msgs",
|
|
@@ -109,6 +109,25 @@ assets = [
|
|
|
109
109
|
],
|
|
110
110
|
]
|
|
111
111
|
|
|
112
|
+
[package.metadata.binstall]
|
|
113
|
+
pkg-fmt = "tgz"
|
|
114
|
+
bin-dir = "minot-{ target }/min/{ bin }{ binary-ext }"
|
|
115
|
+
|
|
116
|
+
[package.metadata.binstall.overrides.x86_64-unknown-linux-gnu]
|
|
117
|
+
pkg-url = "https://uos-robotics.codeberg.page/ppa/bin/minot-{ version }-x86_64-unknown-linux-gnu.tar.gz"
|
|
118
|
+
|
|
119
|
+
[package.metadata.binstall.overrides.x86_64-unknown-linux-musl]
|
|
120
|
+
pkg-url = "https://uos-robotics.codeberg.page/ppa/bin/minot-{ version }-x86_64-unknown-linux-musl.tar.gz"
|
|
121
|
+
|
|
122
|
+
[package.metadata.binstall.overrides.aarch64-unknown-linux-gnu]
|
|
123
|
+
pkg-url = "https://uos-robotics.codeberg.page/ppa/bin/minot-{ version }-aarch64-unknown-linux-gnu.tar.gz"
|
|
124
|
+
|
|
125
|
+
[package.metadata.binstall.overrides.armv7-unknown-linux-gnueabihf]
|
|
126
|
+
pkg-url = "https://uos-robotics.codeberg.page/ppa/bin/minot-{ version }-armv7-unknown-linux-gnueabihf.tar.gz"
|
|
127
|
+
|
|
128
|
+
[package.metadata.binstall.overrides.aarch64-apple-darwin]
|
|
129
|
+
pkg-url = "https://uos-robotics.codeberg.page/ppa/bin/minot-{ version }-aarch64-apple-darwin.tar.gz"
|
|
130
|
+
|
|
112
131
|
[package.metadata.generate-rpm]
|
|
113
132
|
|
|
114
133
|
[[package.metadata.generate-rpm.assets]]
|
|
@@ -295,7 +295,7 @@ fn ffi_lib_rs() -> String {
|
|
|
295
295
|
use std::ffi::{c_char, CStr, CString};
|
|
296
296
|
use std::sync::{Arc, LazyLock, Mutex, OnceLock};
|
|
297
297
|
|
|
298
|
-
use mt_pubsub::{Node, NodeConfig, Qos};
|
|
298
|
+
use mt_pubsub::{Durability, Node, NodeConfig, Qos, Reliability};
|
|
299
299
|
pub mod generated;
|
|
300
300
|
|
|
301
301
|
static RT: LazyLock<Mutex<Option<Arc<tokio::runtime::Runtime>>>> =
|
|
@@ -369,20 +369,31 @@ fn parse_level(filter: &str) -> Option<log::LevelFilter> {
|
|
|
369
369
|
}
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
pub(crate) fn qos_from_i32(
|
|
373
|
-
match
|
|
374
|
-
0 =>
|
|
375
|
-
1 =>
|
|
376
|
-
|
|
377
|
-
|
|
372
|
+
pub(crate) fn qos_from_i32(reliability: i32, durability: i32) -> Option<Qos> {
|
|
373
|
+
let reliability = match reliability {
|
|
374
|
+
0 => Reliability::Reliable,
|
|
375
|
+
1 => Reliability::TryReliable,
|
|
376
|
+
2 => Reliability::BestEffort,
|
|
377
|
+
_ => return None,
|
|
378
|
+
};
|
|
379
|
+
let durability = match durability {
|
|
380
|
+
0 => Durability::Volatile,
|
|
381
|
+
1 => Durability::TransientLocal,
|
|
382
|
+
_ => return None,
|
|
383
|
+
};
|
|
384
|
+
Some(Qos::new(reliability, durability))
|
|
378
385
|
}
|
|
379
386
|
|
|
380
387
|
#[no_mangle]
|
|
381
|
-
pub unsafe extern "C" fn mt_node_init(
|
|
388
|
+
pub unsafe extern "C" fn mt_node_init(
|
|
389
|
+
name: *const c_char,
|
|
390
|
+
reliability: i32,
|
|
391
|
+
durability: i32,
|
|
392
|
+
) -> i32 {
|
|
382
393
|
if name.is_null() {
|
|
383
394
|
return -1;
|
|
384
395
|
}
|
|
385
|
-
let Some(mode) = qos_from_i32(
|
|
396
|
+
let Some(mode) = qos_from_i32(reliability, durability) else {
|
|
386
397
|
return -1;
|
|
387
398
|
};
|
|
388
399
|
let name_str = match CStr::from_ptr(name).to_str() {
|
|
@@ -492,11 +503,12 @@ fn go_core_file() -> String {
|
|
|
492
503
|
|
|
493
504
|
/*
|
|
494
505
|
#include <stdlib.h>
|
|
506
|
+
#include <stdint.h>
|
|
495
507
|
#cgo darwin CFLAGS: -mmacosx-version-min=26.2
|
|
496
508
|
#cgo darwin LDFLAGS: -L${SRCDIR}/../../ffi/target/release -lminot_ffi -framework Security -framework CoreFoundation -mmacosx-version-min=26.2
|
|
497
|
-
#cgo linux LDFLAGS: -L${SRCDIR}/../../ffi/target/release -lminot_ffi -lpthread -ldl
|
|
509
|
+
#cgo linux LDFLAGS: -L${SRCDIR}/../../ffi/target/release -lminot_ffi -lpthread -ldl -lm
|
|
498
510
|
|
|
499
|
-
extern int mt_node_init(const char* name, int
|
|
511
|
+
extern int mt_node_init(const char* name, int reliability, int durability);
|
|
500
512
|
extern void mt_sleep_ms(uint64_t ms);
|
|
501
513
|
extern int mt_node_shutdown_cancelled(void);
|
|
502
514
|
extern int mt_configure_logging(const char* filter);
|
|
@@ -512,13 +524,37 @@ import (
|
|
|
512
524
|
"unsafe"
|
|
513
525
|
)
|
|
514
526
|
|
|
515
|
-
type
|
|
527
|
+
type Reliability int
|
|
516
528
|
|
|
517
529
|
const (
|
|
518
|
-
|
|
519
|
-
|
|
530
|
+
ReliabilityReliable Reliability = iota
|
|
531
|
+
ReliabilityTryReliable
|
|
532
|
+
ReliabilityBestEffort
|
|
520
533
|
)
|
|
521
534
|
|
|
535
|
+
type Durability int
|
|
536
|
+
|
|
537
|
+
const (
|
|
538
|
+
DurabilityVolatile Durability = iota
|
|
539
|
+
DurabilityTransientLocal
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
type Qos struct {
|
|
543
|
+
Reliability Reliability
|
|
544
|
+
Durability Durability
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
var (
|
|
548
|
+
QosReliable = Qos{Reliability: ReliabilityReliable}
|
|
549
|
+
QosTryReliable = Qos{Reliability: ReliabilityTryReliable}
|
|
550
|
+
QosBestEffort = Qos{Reliability: ReliabilityBestEffort}
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
func (q Qos) TransientLocal() Qos {
|
|
554
|
+
q.Durability = DurabilityTransientLocal
|
|
555
|
+
return q
|
|
556
|
+
}
|
|
557
|
+
|
|
522
558
|
type Node struct {
|
|
523
559
|
Name string
|
|
524
560
|
shutdown chan struct{}
|
|
@@ -585,7 +621,7 @@ return cb, ok
|
|
|
585
621
|
func NewNode(name string, nodeQos Qos) (*Node, error) {
|
|
586
622
|
cName := C.CString(name)
|
|
587
623
|
defer C.free(unsafe.Pointer(cName))
|
|
588
|
-
if C.mt_node_init(cName, C.int(nodeQos)) != 0 {
|
|
624
|
+
if C.mt_node_init(cName, C.int(nodeQos.Reliability), C.int(nodeQos.Durability)) != 0 {
|
|
589
625
|
return nil, fmt.Errorf("failed to initialize Minot node")
|
|
590
626
|
}
|
|
591
627
|
n := &Node{Name: name, shutdown: make(chan struct{})}
|
|
@@ -767,9 +803,9 @@ fn go_typed_message_spec(
|
|
|
767
803
|
|
|
768
804
|
let root_c = format!("minot_{}", root_go.to_snake_case());
|
|
769
805
|
out.push_str(&format!(
|
|
770
|
-
"extern uintptr_t mt_create_{root_safe}_publisher(const char* topic, int
|
|
806
|
+
"extern uintptr_t mt_create_{root_safe}_publisher(const char* topic, int reliability, int durability);\n"
|
|
771
807
|
));
|
|
772
|
-
out.push_str(&format!("extern uintptr_t mt_create_{root_safe}_subscriber(const char* topic, uint32_t queue_size, int
|
|
808
|
+
out.push_str(&format!("extern uintptr_t mt_create_{root_safe}_subscriber(const char* topic, uint32_t queue_size, int reliability, int durability, uintptr_t callback_handle);\n"));
|
|
773
809
|
out.push_str(&format!("extern int mt_{root_safe}_publisher_publish(uintptr_t publisher_handle, const {root_c}* message);\n"));
|
|
774
810
|
out.push_str(&format!("extern void mt_register_{root_safe}_callback(uintptr_t handle, void (*callback)(const {root_c}*, uintptr_t));\n"));
|
|
775
811
|
out.push_str(&format!(
|
|
@@ -781,7 +817,7 @@ fn go_typed_message_spec(
|
|
|
781
817
|
out.push_str(&format!("extern int mt_{root_safe}_service_request(uintptr_t client_handle, const {root_c}* request, uint64_t timeout_ms, {root_c}** out_response);\n"));
|
|
782
818
|
out.push_str(&format!("extern void mt_register_{root_safe}_service_callback(uintptr_t handle, int (*callback)(const {root_c}* request, {root_c}* response, uintptr_t));\n"));
|
|
783
819
|
out.push_str(&format!("extern uintptr_t mt_create_{root_safe}_service_server(const char* topic, uintptr_t callback_handle);\n"));
|
|
784
|
-
out.push_str(&format!("extern uintptr_t mt_create_{root_safe}_action_client(const char* topic, int
|
|
820
|
+
out.push_str(&format!("extern uintptr_t mt_create_{root_safe}_action_client(const char* topic, int reliability, int durability);\n"));
|
|
785
821
|
out.push_str(&format!("extern int mt_{root_safe}_action_wait_for_server(uintptr_t client_handle, uint64_t timeout_ms);\n"));
|
|
786
822
|
out.push_str(&format!("extern int mt_{root_safe}_action_send_goal(uintptr_t client_handle, uint64_t goal_id, const {root_c}* goal, uint64_t timeout_ms, int* out_accepted, uint64_t* out_time_ms);\n"));
|
|
787
823
|
out.push_str(&format!("extern int mt_{root_safe}_action_cancel_goal(uintptr_t client_handle, uint64_t goal_id, uint64_t timeout_ms);\n"));
|
|
@@ -866,10 +902,10 @@ fn go_typed_message_spec(
|
|
|
866
902
|
.get(root)
|
|
867
903
|
.ok_or_else(|| anyhow!("missing root type"))?;
|
|
868
904
|
let root_c_type = format!("C.minot_{}", root_type.to_snake_case());
|
|
869
|
-
out.push_str(&format!("func create{root_go}Publisher(topic string, qos Qos) (uintptr, error) {{\n\tcTopic := C.CString(topic)\n\tdefer C.free(unsafe.Pointer(cTopic))\n\th := C.mt_create_{root_safe}_publisher(cTopic, C.int(qos))\n\tif h == 0 {{\n\t\treturn 0, fmt.Errorf(\"failed to create publisher for topic %s\", topic)\n\t}}\n\treturn uintptr(h), nil\n}}\n\n"));
|
|
905
|
+
out.push_str(&format!("func create{root_go}Publisher(topic string, qos Qos) (uintptr, error) {{\n\tcTopic := C.CString(topic)\n\tdefer C.free(unsafe.Pointer(cTopic))\n\th := C.mt_create_{root_safe}_publisher(cTopic, C.int(qos.Reliability), C.int(qos.Durability))\n\tif h == 0 {{\n\t\treturn 0, fmt.Errorf(\"failed to create publisher for topic %s\", topic)\n\t}}\n\treturn uintptr(h), nil\n}}\n\n"));
|
|
870
906
|
out.push_str(&format!("func publish{root_go}(handle uintptr, msg {root_type}) error {{\n\tcMsg := toC{root_type}(msg)\n\tdefer freeC{root_type}(&cMsg)\n\tif C.mt_{root_safe}_publisher_publish(C.uintptr_t(handle), (*{root_c_type})(unsafe.Pointer(&cMsg))) != 0 {{\n\t\treturn fmt.Errorf(\"publish failed\")\n\t}}\n\treturn nil\n}}\n\n"));
|
|
871
907
|
out.push_str(&format!("//export Go{root_go}Callback\nfunc Go{root_go}Callback(message *{root_c_type}, handle C.uintptr_t) {{\n\tif cb, ok := GetHandler(uintptr(handle)); ok {{\n\t\tif typedCb, ok := cb.(func({root_type})); ok {{\n\t\t\tif message == nil {{\n\t\t\t\tvar zero {root_type}\n\t\t\t\ttypedCb(zero)\n\t\t\t\treturn\n\t\t\t}}\n\t\t\ttypedCb(cToGo{root_type}(*message))\n\t\t}}\n\t}}\n}}\n\n"));
|
|
872
|
-
out.push_str(&format!("func create{root_go}Subscriber(topic string, queueSize int, qos Qos, callback func({root_type})) (uintptr, error) {{\n\th := RegisterHandler(callback)\n\tcTopic := C.CString(topic)\n\tdefer C.free(unsafe.Pointer(cTopic))\n\tC.registerGo{root_go}Callback(C.uintptr_t(h))\n\ts := C.mt_create_{root_safe}_subscriber(cTopic, C.uint32_t(queueSize), C.int(qos), C.uintptr_t(h))\n\tif s == 0 {{\n\t\treturn 0, fmt.Errorf(\"failed to create subscriber for topic %s\", topic)\n\t}}\n\treturn uintptr(s), nil\n}}\n\n"));
|
|
908
|
+
out.push_str(&format!("func create{root_go}Subscriber(topic string, queueSize int, qos Qos, callback func({root_type})) (uintptr, error) {{\n\th := RegisterHandler(callback)\n\tcTopic := C.CString(topic)\n\tdefer C.free(unsafe.Pointer(cTopic))\n\tC.registerGo{root_go}Callback(C.uintptr_t(h))\n\ts := C.mt_create_{root_safe}_subscriber(cTopic, C.uint32_t(queueSize), C.int(qos.Reliability), C.int(qos.Durability), C.uintptr_t(h))\n\tif s == 0 {{\n\t\treturn 0, fmt.Errorf(\"failed to create subscriber for topic %s\", topic)\n\t}}\n\treturn uintptr(s), nil\n}}\n\n"));
|
|
873
909
|
out.push_str(&format!("var {root_go}Spec = MessageSpec[{root_type}]{{\n\tCreatePublisher: create{root_go}Publisher,\n\tPublish: publish{root_go},\n\tCreateSubscriber: create{root_go}Subscriber,\n}}\n\n"));
|
|
874
910
|
out.push_str(&format!("func (n *Node) New{root_go}Publisher(topic string, qos Qos) (*Publisher[{root_type}], error) {{\n\treturn newPublisher(topic, qos, {root_go}Spec)\n}}\n\n"));
|
|
875
911
|
out.push_str(&format!("func (n *Node) New{root_go}Subscriber(topic string, queueSize int, qos Qos, callback func({root_type})) (*Subscriber[{root_type}], error) {{\n\treturn newSubscriber(topic, queueSize, qos, {root_go}Spec, callback)\n}}\n"));
|
|
@@ -887,7 +923,7 @@ fn go_typed_message_spec(
|
|
|
887
923
|
out.push_str(&format!(
|
|
888
924
|
"type {root_go}ActionClient struct {{\n\thandle uintptr\n\ttopic string\n}}\n\n"
|
|
889
925
|
));
|
|
890
|
-
out.push_str(&format!("func (n *Node) New{root_go}ActionClient(topic string, feedbackQos Qos) (*{root_go}ActionClient, error) {{\n\tcTopic := C.CString(topic)\n\tdefer C.free(unsafe.Pointer(cTopic))\n\th := C.mt_create_{root_safe}_action_client(cTopic, C.int(feedbackQos))\n\tif h == 0 {{\n\t\treturn nil, fmt.Errorf(\"failed to create action client for topic %s\", topic)\n\t}}\n\treturn &{root_go}ActionClient{{handle: uintptr(h), topic: topic}}, nil\n}}\n\n"));
|
|
926
|
+
out.push_str(&format!("func (n *Node) New{root_go}ActionClient(topic string, feedbackQos Qos) (*{root_go}ActionClient, error) {{\n\tcTopic := C.CString(topic)\n\tdefer C.free(unsafe.Pointer(cTopic))\n\th := C.mt_create_{root_safe}_action_client(cTopic, C.int(feedbackQos.Reliability), C.int(feedbackQos.Durability))\n\tif h == 0 {{\n\t\treturn nil, fmt.Errorf(\"failed to create action client for topic %s\", topic)\n\t}}\n\treturn &{root_go}ActionClient{{handle: uintptr(h), topic: topic}}, nil\n}}\n\n"));
|
|
891
927
|
out.push_str(&format!("func (c *{root_go}ActionClient) WaitForServer(timeoutMs uint64) bool {{\n\treturn C.mt_{root_safe}_action_wait_for_server(C.uintptr_t(c.handle), C.uint64_t(timeoutMs)) != 0\n}}\n\n"));
|
|
892
928
|
out.push_str(&format!("func (c *{root_go}ActionClient) SendGoal(goalID uint64, goal {root_type}, timeoutMs uint64) (bool, uint64, error) {{\n\tcGoal := toC{root_type}(goal)\n\tdefer freeC{root_type}(&cGoal)\n\tvar accepted C.int\n\tvar timeMs C.uint64_t\n\tres := C.mt_{root_safe}_action_send_goal(C.uintptr_t(c.handle), C.uint64_t(goalID), (*{root_c_type})(unsafe.Pointer(&cGoal)), C.uint64_t(timeoutMs), &accepted, &timeMs)\n\tif res != 0 {{\n\t\treturn false, 0, fmt.Errorf(\"send goal failed\")\n\t}}\n\treturn accepted != 0, uint64(timeMs), nil\n}}\n\n"));
|
|
893
929
|
out.push_str(&format!("func (c *{root_go}ActionClient) CancelGoal(goalID uint64, timeoutMs uint64) error {{\n\tif C.mt_{root_safe}_action_cancel_goal(C.uintptr_t(c.handle), C.uint64_t(goalID), C.uint64_t(timeoutMs)) != 0 {{\n\t\treturn fmt.Errorf(\"cancel goal failed\")\n\t}}\n\treturn nil\n}}\n\n"));
|
|
@@ -1012,15 +1048,15 @@ fn rust_typed_message_module(
|
|
|
1012
1048
|
out.push_str(&format!("#[no_mangle]\npub extern \"C\" fn mt_register_{}_callback(handle: usize, callback: extern \"C\" fn(*const {}, usize)) {{\n {}_CALLBACKS.lock().unwrap().insert(handle, callback);\n}}\n\n", root_safe, root_c, root_safe.to_ascii_uppercase()));
|
|
1013
1049
|
out.push_str(&format!("#[no_mangle]\npub extern \"C\" fn mt_register_{}_service_callback(handle: usize, callback: extern \"C\" fn(*const {}, *mut {}, usize) -> i32) {{\n {}_SERVICE_CALLBACKS.lock().unwrap().insert(handle, callback);\n}}\n\n", root_safe, root_c, root_c, root_safe.to_ascii_uppercase()));
|
|
1014
1050
|
|
|
1015
|
-
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_create_{}_publisher(topic: *const c_char,
|
|
1051
|
+
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_create_{}_publisher(topic: *const c_char, reliability: i32, durability: i32) -> usize {{\n if topic.is_null() {{ return 0; }}\n let Some(q) = qos_from_i32(reliability, durability) else {{ return 0; }};\n let topic_str = match CStr::from_ptr(topic).to_str() {{ Ok(s) => s.to_owned(), Err(_) => return 0 }};\n let node_lock = NODE.lock().unwrap();\n let Some(node) = node_lock.as_ref().cloned() else {{ return 0; }};\n drop(node_lock);\n let rt_lock = RT.lock().unwrap();\n let Some(rt) = rt_lock.as_ref().cloned() else {{ return 0; }};\n drop(rt_lock);\n let publisher = match rt.block_on(async {{ node.create_publisher::<{}>(topic_str, q).await }}) {{ Ok(p) => p, Err(_) => return 0 }};\n let handle = rand::random::<usize>();\n {}_PUBLISHERS.lock().unwrap().insert(handle, publisher);\n handle\n}}\n\n", root_safe, root_mod_type, root_safe.to_ascii_uppercase()));
|
|
1016
1052
|
|
|
1017
1053
|
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_{}_publisher_publish(publisher_handle: usize, message: *const {}) -> i32 {{\n let rust_msg = match {}_to_rust(message) {{ Ok(m) => m, Err(_) => return -3 }};\n let publishers = {}_PUBLISHERS.lock().unwrap();\n let publisher = match publishers.get(&publisher_handle) {{ Some(p) => p.clone(), None => return -1 }};\n drop(publishers);\n let publish_fut = async move {{ publisher.publish(&rust_msg).await }};\n let result = if tokio::runtime::Handle::try_current().is_ok() {{ tokio::task::block_in_place(|| tokio::runtime::Handle::current().block_on(publish_fut)) }} else {{ let rt_lock = RT.lock().unwrap(); let Some(rt) = rt_lock.as_ref().cloned() else {{ return -4; }}; drop(rt_lock); rt.block_on(publish_fut) }};\n if result.is_ok() {{ 0 }} else {{ -2 }}\n}}\n\n", root_safe, root_c, root_go.to_snake_case(), root_safe.to_ascii_uppercase()));
|
|
1018
1054
|
|
|
1019
|
-
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_create_{}_subscriber(topic: *const c_char, queue_size: u32,
|
|
1055
|
+
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_create_{}_subscriber(topic: *const c_char, queue_size: u32, reliability: i32, durability: i32, callback_handle: usize) -> usize {{\n if topic.is_null() {{ return 0; }}\n let Some(q) = qos_from_i32(reliability, durability) else {{ return 0; }};\n let topic_str = match CStr::from_ptr(topic).to_str() {{ Ok(s) => s.to_owned(), Err(_) => return 0 }};\n let node_lock = NODE.lock().unwrap();\n let Some(node) = node_lock.as_ref().cloned() else {{ return 0; }};\n drop(node_lock);\n let rt_lock = RT.lock().unwrap();\n let Some(rt) = rt_lock.as_ref().cloned() else {{ return 0; }};\n drop(rt_lock);\n let mut subscriber = match rt.block_on(async {{ node.create_subscriber::<{}>(topic_str, queue_size as usize, q).await }}) {{ Ok(s) => s, Err(_) => return 0 }};\n let handle = rand::random::<usize>();\n rt.spawn(async move {{\n while let Some(msg) = subscriber.next().await {{\n let c_msg = {}_from_rust(&msg);\n let cb_opt = {{ let map = {}_CALLBACKS.lock().unwrap(); map.get(&callback_handle).copied() }};\n if let Some(cb) = cb_opt {{\n let boxed = Box::new(c_msg);\n cb(Box::as_ref(&boxed), callback_handle);\n let raw = Box::into_raw(boxed);\n mt_free_{}_message(raw);\n }}\n }}\n }});\n handle\n}}\n", root_safe, root_mod_type, root_go.to_snake_case(), root_safe.to_ascii_uppercase(), root_safe));
|
|
1020
1056
|
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_create_{}_service_client(topic: *const c_char) -> usize {{\n if topic.is_null() {{ return 0; }}\n let topic_str = match CStr::from_ptr(topic).to_str() {{ Ok(s) => s.to_owned(), Err(_) => return 0 }};\n let node_lock = NODE.lock().unwrap();\n let Some(node) = node_lock.as_ref().cloned() else {{ return 0; }};\n drop(node_lock);\n let rt_lock = RT.lock().unwrap();\n let Some(rt) = rt_lock.as_ref().cloned() else {{ return 0; }};\n drop(rt_lock);\n let client = match rt.block_on(async {{ ServiceClient::<{}, {}>::new(node, topic_str).await }}) {{ Ok(c) => c, Err(_) => return 0 }};\n let handle = rand::random::<usize>();\n {}_SERVICE_CLIENTS.lock().unwrap().insert(handle, client);\n handle\n}}\n\n", root_safe, root_mod_type, root_mod_type, root_safe.to_ascii_uppercase()));
|
|
1021
1057
|
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_{}_service_request(client_handle: usize, request: *const {}, timeout_ms: u64, out_response: *mut *mut {}) -> i32 {{\n if out_response.is_null() {{ return -1; }}\n let req = match {}_to_rust(request) {{ Ok(v) => v, Err(_) => return -2 }};\n let clients = {}_SERVICE_CLIENTS.lock().unwrap();\n let Some(client) = clients.get(&client_handle) else {{ return -3; }};\n let fut = client.request(req, Some(Duration::from_millis(timeout_ms)));\n let result = if tokio::runtime::Handle::try_current().is_ok() {{ tokio::task::block_in_place(|| tokio::runtime::Handle::current().block_on(fut)) }} else {{ let rt_lock = RT.lock().unwrap(); let Some(rt) = rt_lock.as_ref().cloned() else {{ return -4; }}; drop(rt_lock); rt.block_on(fut) }};\n match result {{\n Ok(resp) => {{\n let c_resp = {}_from_rust(&resp);\n *out_response = Box::into_raw(Box::new(c_resp));\n 0\n }}\n Err(_) => -5,\n }}\n}}\n\n", root_safe, root_c, root_c, root_go.to_snake_case(), root_safe.to_ascii_uppercase(), root_go.to_snake_case()));
|
|
1022
1058
|
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_create_{}_service_server(topic: *const c_char, callback_handle: usize) -> usize {{\n if topic.is_null() {{ return 0; }}\n let topic_str = match CStr::from_ptr(topic).to_str() {{ Ok(s) => s.to_owned(), Err(_) => return 0 }};\n let cb_opt = {{ let cbs = {}_SERVICE_CALLBACKS.lock().unwrap(); cbs.get(&callback_handle).copied() }};\n let Some(cb) = cb_opt else {{ return 0; }};\n let node_lock = NODE.lock().unwrap();\n let Some(node) = node_lock.as_ref().cloned() else {{ return 0; }};\n drop(node_lock);\n let rt_lock = RT.lock().unwrap();\n let Some(rt) = rt_lock.as_ref().cloned() else {{ return 0; }};\n drop(rt_lock);\n let server = match rt.block_on(async {{ ServiceServer::<{}, {}>::new(node, topic_str).await }}) {{ Ok(s) => s, Err(_) => return 0 }};\n let server_clone = server.clone();\n rt.spawn(async move {{\n let callback = std::sync::Arc::new(move |req: {}| {{\n let c_req = {}_from_rust(&req);\n let mut c_resp: {} = unsafe {{ std::mem::zeroed() }};\n let rc = cb(&c_req as *const {}, &mut c_resp as *mut {}, callback_handle);\n std::future::ready(if rc != 0 {{\n Err(\"service callback failed\".to_string())\n }} else {{\n match {}_to_rust(&c_resp as *const {}) {{\n Ok(v) => Ok(v),\n Err(_) => Err(\"service callback response conversion failed\".to_string()),\n }}\n }})\n }});\n let _ = ServiceServer::start(server_clone, callback).await;\n }});\n let handle = rand::random::<usize>();\n {}_SERVICE_SERVERS.lock().unwrap().insert(handle, server);\n handle\n}}\n\n", root_safe, root_safe.to_ascii_uppercase(), root_mod_type, root_mod_type, root_mod_type, root_go.to_snake_case(), root_c, root_c, root_c, root_go.to_snake_case(), root_c, root_safe.to_ascii_uppercase()));
|
|
1023
|
-
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_create_{}_action_client(topic: *const c_char,
|
|
1059
|
+
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_create_{}_action_client(topic: *const c_char, reliability: i32, durability: i32) -> usize {{\n if topic.is_null() {{ return 0; }}\n let Some(q) = qos_from_i32(reliability, durability) else {{ return 0; }};\n let topic_str = match CStr::from_ptr(topic).to_str() {{ Ok(s) => s.to_owned(), Err(_) => return 0 }};\n let node_lock = NODE.lock().unwrap();\n let Some(node) = node_lock.as_ref().cloned() else {{ return 0; }};\n drop(node_lock);\n let rt_lock = RT.lock().unwrap();\n let Some(rt) = rt_lock.as_ref().cloned() else {{ return 0; }};\n drop(rt_lock);\n let client = match rt.block_on(async {{ ActionClient::<{}, {}, {}>::new(node, topic_str, q).await }}) {{ Ok(c) => c, Err(_) => return 0 }};\n let handle = rand::random::<usize>();\n {}_ACTION_CLIENTS.lock().unwrap().insert(handle, client);\n handle\n}}\n\n", root_safe, root_mod_type, root_mod_type, root_mod_type, root_safe.to_ascii_uppercase()));
|
|
1024
1060
|
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_{}_action_wait_for_server(client_handle: usize, timeout_ms: u64) -> i32 {{\n let clients = {}_ACTION_CLIENTS.lock().unwrap();\n let Some(client) = clients.get(&client_handle) else {{ return 0; }};\n let fut = ActionClient::<{}, {}, {}>::wait_for_action_server(client.clone(), Duration::from_millis(timeout_ms));\n let ready = if tokio::runtime::Handle::try_current().is_ok() {{ tokio::task::block_in_place(|| tokio::runtime::Handle::current().block_on(fut)) }} else {{ let rt_lock = RT.lock().unwrap(); let Some(rt) = rt_lock.as_ref().cloned() else {{ return 0; }}; drop(rt_lock); rt.block_on(fut) }};\n if ready {{ 1 }} else {{ 0 }}\n}}\n\n", root_safe, root_safe.to_ascii_uppercase(), root_mod_type, root_mod_type, root_mod_type));
|
|
1025
1061
|
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_{}_action_send_goal(client_handle: usize, goal_id: u64, goal: *const {}, timeout_ms: u64, out_accepted: *mut i32, out_time_ms: *mut u64) -> i32 {{\n if out_accepted.is_null() || out_time_ms.is_null() {{ return -1; }}\n let goal_msg = match {}_to_rust(goal) {{ Ok(v) => v, Err(_) => return -2 }};\n let clients = {}_ACTION_CLIENTS.lock().unwrap();\n let Some(client) = clients.get(&client_handle) else {{ return -3; }};\n let req = ActionSendGoalRequest {{ id: goal_id, goal: goal_msg }};\n let fut = ActionClient::<{}, {}, {}>::send_goal(client.clone(), req, Some(Duration::from_millis(timeout_ms)));\n let result = if tokio::runtime::Handle::try_current().is_ok() {{ tokio::task::block_in_place(|| tokio::runtime::Handle::current().block_on(fut)) }} else {{ let rt_lock = RT.lock().unwrap(); let Some(rt) = rt_lock.as_ref().cloned() else {{ return -4; }}; drop(rt_lock); rt.block_on(fut) }};\n match result {{\n Ok(resp) => {{\n *out_accepted = if resp.accepted {{ 1 }} else {{ 0 }};\n *out_time_ms = resp.time.unwrap_or(0) as u64;\n 0\n }}\n Err(_) => -5,\n }}\n}}\n\n", root_safe, root_c, root_go.to_snake_case(), root_safe.to_ascii_uppercase(), root_mod_type, root_mod_type, root_mod_type));
|
|
1026
1062
|
out.push_str(&format!("#[no_mangle]\npub unsafe extern \"C\" fn mt_{}_action_cancel_goal(client_handle: usize, goal_id: u64, timeout_ms: u64) -> i32 {{\n let clients = {}_ACTION_CLIENTS.lock().unwrap();\n let Some(client) = clients.get(&client_handle) else {{ return -1; }};\n let req = ActionCancelGoalRequest {{ id: Some(goal_id), time: None }};\n let fut = ActionClient::<{}, {}, {}>::cancel_goal(client.clone(), req, Some(Duration::from_millis(timeout_ms)));\n let result = if tokio::runtime::Handle::try_current().is_ok() {{ tokio::task::block_in_place(|| tokio::runtime::Handle::current().block_on(fut)) }} else {{ let rt_lock = RT.lock().unwrap(); let Some(rt) = rt_lock.as_ref().cloned() else {{ return -2; }}; drop(rt_lock); rt.block_on(fut) }};\n if result.is_ok() {{ 0 }} else {{ -3 }}\n}}\n\n", root_safe, root_safe.to_ascii_uppercase(), root_mod_type, root_mod_type, root_mod_type));
|
|
@@ -2421,6 +2457,20 @@ fn c_and_go_scalar(ty: &Type) -> Result<(&'static str, &'static str)> {
|
|
|
2421
2457
|
mod tests {
|
|
2422
2458
|
use super::*;
|
|
2423
2459
|
|
|
2460
|
+
#[test]
|
|
2461
|
+
fn go_qos_combines_reliability_and_durability() {
|
|
2462
|
+
let go = go_core_file();
|
|
2463
|
+
assert!(go.contains("type Reliability int"));
|
|
2464
|
+
assert!(go.contains("type Durability int"));
|
|
2465
|
+
assert!(go.contains("type Qos struct"));
|
|
2466
|
+
assert!(go.contains("func (q Qos) TransientLocal() Qos"));
|
|
2467
|
+
|
|
2468
|
+
let ffi = ffi_lib_rs();
|
|
2469
|
+
assert!(ffi.contains("1 => Reliability::TryReliable"));
|
|
2470
|
+
assert!(ffi.contains("1 => Durability::TransientLocal"));
|
|
2471
|
+
assert!(ffi.contains("Some(Qos::new(reliability, durability))"));
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2424
2474
|
#[test]
|
|
2425
2475
|
fn test_parse_and_generate_simple_struct() {
|
|
2426
2476
|
let input = "
|
|
@@ -139,6 +139,9 @@ where
|
|
|
139
139
|
where
|
|
140
140
|
E: de::Error,
|
|
141
141
|
{
|
|
142
|
+
if value.trim().is_empty() {
|
|
143
|
+
return Ok(Vec::new());
|
|
144
|
+
}
|
|
142
145
|
serde_yml::from_str(value).map_err(de::Error::custom)
|
|
143
146
|
}
|
|
144
147
|
|
|
@@ -1629,6 +1632,21 @@ rosbag2_bagfile_information:
|
|
|
1629
1632
|
);
|
|
1630
1633
|
}
|
|
1631
1634
|
|
|
1635
|
+
#[test]
|
|
1636
|
+
fn empty_qos_profile_string_is_an_empty_list() {
|
|
1637
|
+
let metadata: TopicMetadata = serde_yml::from_str(
|
|
1638
|
+
r#"
|
|
1639
|
+
name: /ouster/points
|
|
1640
|
+
type: sensor_msgs/msg/PointCloud2
|
|
1641
|
+
serialization_format: cdr
|
|
1642
|
+
offered_qos_profiles: ""
|
|
1643
|
+
"#,
|
|
1644
|
+
)
|
|
1645
|
+
.expect("empty QoS profile string should parse");
|
|
1646
|
+
|
|
1647
|
+
assert!(metadata.offered_qos_profiles.is_empty());
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1632
1650
|
#[test]
|
|
1633
1651
|
fn both_formats_parse_without_errors() {
|
|
1634
1652
|
let v5_result = std::fs::read_to_string("test/metadata-v5.yml").and_then(|contents| {
|
|
@@ -5,7 +5,7 @@ use mt_sea::net::{self, Packet};
|
|
|
5
5
|
use mt_sea::{coordinator::CoordinatorImpl, net::PacketKind};
|
|
6
6
|
|
|
7
7
|
use mt_net::{ActionPlan, COMPARE_NODE_NAME, RatPubRegisterKind, Rules, VariableHuman};
|
|
8
|
-
use mt_sea::{Coordinator, Qos, ShipKind, WindData};
|
|
8
|
+
use mt_sea::{Coordinator, Qos, Reliability, ShipKind, WindData};
|
|
9
9
|
|
|
10
10
|
const EMBEDDED_COORDINATOR_READY_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);
|
|
11
11
|
|
|
@@ -1095,7 +1095,9 @@ fn run_coordinator_with_ready(
|
|
|
1095
1095
|
node_mode,
|
|
1096
1096
|
} => {
|
|
1097
1097
|
// Track BE publishers
|
|
1098
|
-
if kind == net::RatPubRegisterKind::Publish
|
|
1098
|
+
if kind == net::RatPubRegisterKind::Publish
|
|
1099
|
+
&& node_mode.reliability_mode() == Reliability::BestEffort
|
|
1100
|
+
{
|
|
1099
1101
|
coordinator
|
|
1100
1102
|
.be_publisher_vars
|
|
1101
1103
|
.write()
|
|
@@ -48,15 +48,15 @@ If you have multiple Minot networks on the same physical network, use the `MINOT
|
|
|
48
48
|
|
|
49
49
|
## Delivery modes
|
|
50
50
|
|
|
51
|
-
`Qos`
|
|
52
|
-
|
|
53
|
-
when the node stops answering.
|
|
51
|
+
`Qos` combines `Reliability` and `Durability`. Reliability also controls failure
|
|
52
|
+
handling and congestion behavior.
|
|
54
53
|
|
|
55
|
-
| | Wire | Congestion | Peer monitoring | On loss | Send dispatch |
|
|
56
|
-
|
|
57
|
-
| `Reliable` | reliable | `Block` | yes | torpedoes the run | inline, unbounded retry |
|
|
58
|
-
| `TryReliable` | reliable | `BlockFirst` | no | rest keeps running | spawned, retry within budget |
|
|
59
|
-
| `BestEffort` | best-effort | `Drop` | no | rest keeps running | spawned, single attempt |
|
|
54
|
+
| | Wire | Congestion | Peer monitoring | On loss | Send dispatch | Durability |
|
|
55
|
+
|---|---|---|---|---|---|---|
|
|
56
|
+
| `Reliable` | reliable | `Block` | yes | torpedoes the run | inline, unbounded retry | volatile |
|
|
57
|
+
| `TryReliable` | reliable | `BlockFirst` | no | rest keeps running | spawned, retry within budget | volatile |
|
|
58
|
+
| `BestEffort` | best-effort | `Drop` | no | rest keeps running | spawned, single attempt | volatile |
|
|
59
|
+
| `.transient_local()` | preserves base mode | preserves base mode | preserves base mode | preserves base mode | preserves base mode | replay latest sample to late subscribers |
|
|
60
60
|
|
|
61
61
|
`Reliable` is the default and the strict one: peers heartbeat-monitor each other, and a
|
|
62
62
|
node that stops answering tears the whole run down. That is what you want for a
|
|
@@ -70,6 +70,15 @@ publisher's loop.
|
|
|
70
70
|
|
|
71
71
|
`BestEffort` tries once and moves on.
|
|
72
72
|
|
|
73
|
+
Transient-local durability combines with every reliability mode. It retains the latest
|
|
74
|
+
sample and replays it to late subscribers. It is disabled by default.
|
|
75
|
+
|
|
76
|
+
```rust
|
|
77
|
+
let publisher = node
|
|
78
|
+
.create_publisher::<Transform>("/tf_static".to_owned(), Qos::Reliable.transient_local())
|
|
79
|
+
.await?;
|
|
80
|
+
```
|
|
81
|
+
|
|
73
82
|
Note that reliable wire delivery is close to free over TCP, which already retransmits and
|
|
74
83
|
orders. The meaningful difference between `Reliable` and `TryReliable` is the failure
|
|
75
84
|
policy, not the wire.
|
|
@@ -5,7 +5,9 @@ use std::{marker::PhantomData, sync::Arc};
|
|
|
5
5
|
use mt_sea::{net::Packet, ship::NetworkShipImpl, *};
|
|
6
6
|
use tokio_util::sync::CancellationToken;
|
|
7
7
|
|
|
8
|
-
pub use mt_sea::{
|
|
8
|
+
pub use mt_sea::{
|
|
9
|
+
ArchivedMessage, Durability, NodeOptions, Qos, ReconnectPolicy, Reliability, Timing,
|
|
10
|
+
};
|
|
9
11
|
|
|
10
12
|
#[derive(Debug, Clone, Copy, Default)]
|
|
11
13
|
pub enum CoordMode {
|
|
@@ -217,6 +219,12 @@ impl<T: Sendable> Publisher<T> {
|
|
|
217
219
|
}
|
|
218
220
|
|
|
219
221
|
pub async fn publish(&self, data: &T) -> anyhow::Result<()> {
|
|
222
|
+
if self.qos.is_transient_local() {
|
|
223
|
+
self.ship
|
|
224
|
+
.get_cannon()
|
|
225
|
+
.retain(data, VariableType::StaticOnly, &self.topic)
|
|
226
|
+
.await?;
|
|
227
|
+
}
|
|
220
228
|
self.ensure_registered().await?;
|
|
221
229
|
match self.ship.ask_for_action(&self.topic).await {
|
|
222
230
|
Ok((mt_sea::Action::Sail, _)) => {
|