diff --git a/mote_bringup/config/record.yaml b/mote_bringup/config/record.yaml new file mode 100644 index 0000000..51f1701 --- /dev/null +++ b/mote_bringup/config/record.yaml @@ -0,0 +1,22 @@ +# Rosbag recording streams — consumed by record_launch.py. +# Each stream writes to ~/.mote/bags/// with its own segment +# length and rolling disk cap (enforced by bag_pruner). + +streams: + lite: + topics: + - /tf + - /tf_static + - /scan_filtered + split: 600 # seconds per bag segment + max_gb: 2.0 # rolling disk cap + + perception: + topics: + - /tf + - /tf_static + - /scan_filtered + - /image_raw/compressed + - /camera_info + split: 60 + max_gb: 10.0 diff --git a/mote_bringup/launch/record_launch.py b/mote_bringup/launch/record_launch.py new file mode 100644 index 0000000..6f77bfc --- /dev/null +++ b/mote_bringup/launch/record_launch.py @@ -0,0 +1,76 @@ +"""Record rosbags for perception development, split by purpose with disk caps. + +Streams are defined in config/record.yaml. Each enabled stream is recorded in +parallel under ~/.mote/bags// with its own segment length and +rolling disk cap (bag_pruner deletes the oldest segments once a stream exceeds +its cap so continuous recording never fills the disk). + +The compressed image stream is recorded rather than raw; republish it to +/image_raw on playback with image_transport. +""" + +import os +from datetime import datetime + +import yaml +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import ExecuteProcess + + +def _load_streams(): + config_path = os.path.join( + get_package_share_directory("mote_bringup"), "config", "record.yaml" + ) + with open(config_path) as f: + return yaml.safe_load(f)["streams"] + + +def _bags_dir(kind): + base = os.path.join(os.path.expanduser("~/.mote/bags"), kind) + os.makedirs(base, exist_ok=True) + return base + + +def _record(kind, topics, split): + output = os.path.join(_bags_dir(kind), datetime.now().strftime("%Y%m%d_%H%M%S")) + return ExecuteProcess( + cmd=[ + "ros2", + "bag", + "record", + "--max-bag-duration", + str(split), + "-o", + output, + *topics, + ], + output="screen", + ) + + +def _pruner(kind, max_gb, interval): + return ExecuteProcess( + cmd=[ + "ros2", + "run", + "mote_bringup", + "bag_pruner", + "--dir", + _bags_dir(kind), + "--max-gb", + str(max_gb), + "--interval", + str(interval), + ], + output="screen", + ) + + +def generate_launch_description(): + actions = [] + for name, stream in _load_streams().items(): + split = stream["split"] + actions.append(_record(name, stream["topics"], split)) + actions.append(_pruner(name, stream["max_gb"], split)) + return LaunchDescription(actions) diff --git a/mote_bringup/launch/rviz_launch.py b/mote_bringup/launch/rviz_launch.py index f793876..76c8da2 100644 --- a/mote_bringup/launch/rviz_launch.py +++ b/mote_bringup/launch/rviz_launch.py @@ -5,17 +5,21 @@ def generate_launch_description(): - rviz_config = PathJoinSubstitution([ - FindPackageShare("mote_bringup"), - "config", - "mote.rviz", - ]) + rviz_config = PathJoinSubstitution( + [ + FindPackageShare("mote_bringup"), + "config", + "mote.rviz", + ] + ) - return LaunchDescription([ - Node( - package="rviz2", - executable="rviz2", - arguments=["-d", rviz_config], - output="screen", - ) - ]) + return LaunchDescription( + [ + Node( + package="rviz2", + executable="rviz2", + arguments=["-d", rviz_config], + output="screen", + ) + ] + ) diff --git a/mote_bringup/mote_bringup/bag_pruner.py b/mote_bringup/mote_bringup/bag_pruner.py new file mode 100644 index 0000000..8be7a5c --- /dev/null +++ b/mote_bringup/mote_bringup/bag_pruner.py @@ -0,0 +1,97 @@ +"""Enforce a rolling disk budget on a rosbag2 output tree. + +Periodically sums the size of every .mcap segment under a directory and deletes +the oldest segments once the total exceeds a cap, so a robot that records +continuously never fills its disk. The newest segment (the one currently being +written) is never deleted. Run directories left empty by pruning are removed +along with their now-stale metadata. + +Each .mcap segment is self-contained, so pruning older segments out of a still +active run does not affect playback of the segments that remain. +""" + +import argparse +import os +import shutil +import time + + +EMPTY_RUN_MIN_AGE_SECONDS = 120.0 + + +def _segments(root): + files = [] + for dirpath, _dirnames, filenames in os.walk(root): + for name in filenames: + if not name.endswith(".mcap"): + continue + path = os.path.join(dirpath, name) + try: + st = os.stat(path) + except FileNotFoundError: + continue + files.append((path, st.st_mtime, st.st_size)) + files.sort(key=lambda f: f[1]) # oldest first + return files + + +def _remove_empty_runs(root): + now = time.time() + for entry in os.scandir(root): + if not entry.is_dir(): + continue + try: + age = now - entry.stat().st_mtime + except FileNotFoundError: + continue + if age < EMPTY_RUN_MIN_AGE_SECONDS: + continue + has_mcap = any( + name.endswith(".mcap") + for _d, _sub, names in os.walk(entry.path) + for name in names + ) + if not has_mcap: + shutil.rmtree(entry.path, ignore_errors=True) + print(f"bag_pruner: removed empty run {entry.path}", flush=True) + + +def prune(root, cap_bytes): + segs = _segments(root) + total = sum(s[2] for s in segs) + # Keep the newest segment regardless of the cap — it is still being written. + for path, _mtime, size in segs[:-1]: + if total <= cap_bytes: + break + try: + os.remove(path) + print(f"bag_pruner: removed {path} ({size / 1e6:.0f} MB)", flush=True) + except FileNotFoundError: + pass + total -= size + _remove_empty_runs(root) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--dir", required=True, help="rosbag2 output tree to prune") + parser.add_argument( + "--max-gb", type=float, required=True, help="disk cap for the tree, in GB" + ) + parser.add_argument( + "--interval", type=float, default=30.0, help="seconds between sweeps" + ) + args = parser.parse_args() + + cap_bytes = int(args.max_gb * 1e9) + os.makedirs(args.dir, exist_ok=True) + try: + while True: + prune(args.dir, cap_bytes) + time.sleep(args.interval) + except KeyboardInterrupt: + pass + + +if __name__ == "__main__": + main() diff --git a/mote_bringup/setup.py b/mote_bringup/setup.py index 7c61e01..4a031c2 100644 --- a/mote_bringup/setup.py +++ b/mote_bringup/setup.py @@ -24,6 +24,7 @@ entry_points={ "console_scripts": [ "odom_tf_relay = mote_bringup.odom_tf_relay:main", + "bag_pruner = mote_bringup.bag_pruner:main", ], }, ) diff --git a/mote_bringup/systemd/install.sh b/mote_bringup/systemd/install.sh index 47cc77c..42fe887 100755 --- a/mote_bringup/systemd/install.sh +++ b/mote_bringup/systemd/install.sh @@ -13,4 +13,4 @@ for unit in "$SRC_DIR"/*.service; do done sudo systemctl daemon-reload -sudo systemctl enable mote-bringup mote-slam mote-nav +sudo systemctl enable mote-bringup mote-slam mote-nav mote-record diff --git a/mote_bringup/systemd/mote-record.service b/mote_bringup/systemd/mote-record.service new file mode 100644 index 0000000..6da2aef --- /dev/null +++ b/mote_bringup/systemd/mote-record.service @@ -0,0 +1,16 @@ +[Unit] +Description=Mote Data Recording +After=mote-bringup.service +Wants=mote-bringup.service + +[Service] +Type=simple +User=@USER@ +WorkingDirectory=@HOME@/Mote +ExecStart=@HOME@/.pixi/bin/pixi run record +Restart=on-failure +RestartSec=5 +Environment=HOME=@HOME@ + +[Install] +WantedBy=multi-user.target diff --git a/pixi.lock b/pixi.lock index ed66d9d..556edb9 100644 --- a/pixi.lock +++ b/pixi.lock @@ -258,6 +258,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-devel-2.15.3-h49c6c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lttng-ust-2.13.9-hf5eda4c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-4.4.5-py312h3d67a73_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py312h8a5da7c_1.conda @@ -548,6 +549,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-joint-state-broadcaster-4.37.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-joint-trajectory-controller-4.37.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-kdl-parser-2.11.0-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-keyboard-handler-0.3.2-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-kinematics-interface-1.7.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-laser-filters-2.0.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-laser-geometry-2.7.2-np2py312h2ed9cc7_16.conda @@ -558,10 +560,12 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-launch-xml-3.4.10-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-launch-yaml-3.4.10-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-libcurl-vendor-3.4.4-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-liblz4-vendor-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-libstatistics-collector-1.7.4-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-libyaml-vendor-1.6.3-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-lifecycle-msgs-2.0.3-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-map-msgs-2.4.1-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-mcap-vendor-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-mecanum-drive-controller-4.37.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-message-filters-4.11.10-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-nav-2d-msgs-1.3.11-np2py312h2ed9cc7_16.conda @@ -638,6 +642,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2-control-4.43.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2-control-test-assets-4.43.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2-controllers-4.37.0-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2bag-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2cli-0.32.8-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2controlcli-4.43.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2launch-0.26.11-np2py312h2ed9cc7_16.conda @@ -648,8 +653,13 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2run-0.32.8-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2service-0.32.8-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2topic-0.32.8-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-compression-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-cpp-0.26.9-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-interfaces-0.26.9-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-py-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-storage-0.26.9-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-storage-mcap-0.26.9-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-transport-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosgraph-msgs-2.0.3-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosidl-adapter-4.6.7-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosidl-cli-4.6.7-np2py312h2ed9cc7_16.conda @@ -729,6 +739,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-xacro-2.1.1-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-yaml-cpp-vendor-9.0.1-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-zstd-image-transport-4.0.6-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-zstd-vendor-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros2-distro-mutex-0.14.0-jazzy_16.conda - conda: https://prefix.dev/mote/linux-64/scservo-linux-1.0.0-hb0f4dca_0.conda linux-aarch64: @@ -973,6 +984,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-devel-2.15.3-h869d058_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lttng-ust-2.13.9-h8d236e2_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-4.4.5-py312he78555a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lzo-2.10-h80f16a2_1002.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py312hd077ced_1.conda @@ -1260,6 +1272,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-joint-state-broadcaster-4.37.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-joint-trajectory-controller-4.37.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-kdl-parser-2.11.0-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-keyboard-handler-0.3.2-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-kinematics-interface-1.7.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-laser-filters-2.0.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-laser-geometry-2.7.2-np2py312h61f2ce4_16.conda @@ -1270,10 +1283,12 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-launch-xml-3.4.10-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-launch-yaml-3.4.10-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-libcurl-vendor-3.4.4-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-liblz4-vendor-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-libstatistics-collector-1.7.4-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-libyaml-vendor-1.6.3-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-lifecycle-msgs-2.0.3-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-map-msgs-2.4.1-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-mcap-vendor-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-mecanum-drive-controller-4.37.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-message-filters-4.11.10-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-nav-2d-msgs-1.3.11-np2py312h61f2ce4_16.conda @@ -1350,6 +1365,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2-control-4.43.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2-control-test-assets-4.43.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2-controllers-4.37.0-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2bag-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2cli-0.32.8-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2controlcli-4.43.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2launch-0.26.11-np2py312h61f2ce4_16.conda @@ -1360,8 +1376,13 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2run-0.32.8-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2service-0.32.8-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2topic-0.32.8-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-compression-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-cpp-0.26.9-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-interfaces-0.26.9-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-py-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-storage-0.26.9-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-storage-mcap-0.26.9-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-transport-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosgraph-msgs-2.0.3-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosidl-adapter-4.6.7-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosidl-cli-4.6.7-np2py312h61f2ce4_16.conda @@ -1441,6 +1462,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-xacro-2.1.1-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-yaml-cpp-vendor-9.0.1-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-zstd-image-transport-4.0.6-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-zstd-vendor-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros2-distro-mutex-0.14.0-jazzy_16.conda - conda: https://prefix.dev/mote/linux-aarch64/scservo-linux-1.0.0-he8cfe8b_0.conda dev: @@ -4325,6 +4347,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-joint-state-broadcaster-4.37.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-joint-trajectory-controller-4.37.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-kdl-parser-2.11.0-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-keyboard-handler-0.3.2-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-kinematics-interface-1.7.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-laser-filters-2.0.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-laser-geometry-2.7.2-np2py312h2ed9cc7_16.conda @@ -4335,10 +4358,12 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-launch-xml-3.4.10-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-launch-yaml-3.4.10-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-libcurl-vendor-3.4.4-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-liblz4-vendor-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-libstatistics-collector-1.7.4-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-libyaml-vendor-1.6.3-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-lifecycle-msgs-2.0.3-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-map-msgs-2.4.1-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-mcap-vendor-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-mecanum-drive-controller-4.37.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-message-filters-4.11.10-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-nav-2d-msgs-1.3.11-np2py312h2ed9cc7_16.conda @@ -4419,6 +4444,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2-control-cmake-0.3.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2-control-test-assets-4.43.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2-controllers-4.37.0-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2bag-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2cli-0.32.8-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2controlcli-4.43.0-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2launch-0.26.11-np2py312h2ed9cc7_16.conda @@ -4429,8 +4455,13 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2run-0.32.8-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2service-0.32.8-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-ros2topic-0.32.8-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-compression-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-cpp-0.26.9-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-interfaces-0.26.9-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-py-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-storage-0.26.9-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-storage-mcap-0.26.9-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosbag2-transport-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosgraph-msgs-2.0.3-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosidl-adapter-4.6.7-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-rosidl-cli-4.6.7-np2py312h2ed9cc7_16.conda @@ -4512,6 +4543,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-xacro-2.1.1-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-yaml-cpp-vendor-9.0.1-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-zstd-image-transport-4.0.6-np2py312h2ed9cc7_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros-jazzy-zstd-vendor-0.26.9-np2py312h2ed9cc7_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-64/ros2-distro-mutex-0.14.0-jazzy_16.conda - conda: https://prefix.dev/mote/linux-64/scservo-linux-1.0.0-hb0f4dca_0.conda linux-aarch64: @@ -5184,6 +5216,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-joint-state-broadcaster-4.37.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-joint-trajectory-controller-4.37.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-kdl-parser-2.11.0-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-keyboard-handler-0.3.2-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-kinematics-interface-1.7.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-laser-filters-2.0.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-laser-geometry-2.7.2-np2py312h61f2ce4_16.conda @@ -5194,10 +5227,12 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-launch-xml-3.4.10-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-launch-yaml-3.4.10-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-libcurl-vendor-3.4.4-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-liblz4-vendor-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-libstatistics-collector-1.7.4-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-libyaml-vendor-1.6.3-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-lifecycle-msgs-2.0.3-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-map-msgs-2.4.1-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-mcap-vendor-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-mecanum-drive-controller-4.37.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-message-filters-4.11.10-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-nav-2d-msgs-1.3.11-np2py312h61f2ce4_16.conda @@ -5278,6 +5313,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2-control-cmake-0.3.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2-control-test-assets-4.43.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2-controllers-4.37.0-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2bag-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2cli-0.32.8-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2controlcli-4.43.0-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2launch-0.26.11-np2py312h61f2ce4_16.conda @@ -5288,8 +5324,13 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2run-0.32.8-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2service-0.32.8-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-ros2topic-0.32.8-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-compression-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-cpp-0.26.9-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-interfaces-0.26.9-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-py-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-storage-0.26.9-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-storage-mcap-0.26.9-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosbag2-transport-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosgraph-msgs-2.0.3-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosidl-adapter-4.6.7-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-rosidl-cli-4.6.7-np2py312h61f2ce4_16.conda @@ -5371,6 +5412,7 @@ environments: - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-xacro-2.1.1-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-yaml-cpp-vendor-9.0.1-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-zstd-image-transport-4.0.6-np2py312h61f2ce4_16.conda + - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros-jazzy-zstd-vendor-0.26.9-np2py312h61f2ce4_16.conda - conda: https://conda.anaconda.org/robostack-jazzy/linux-aarch64/ros2-distro-mutex-0.14.0-jazzy_16.conda - conda: https://prefix.dev/mote/linux-aarch64/scservo-linux-1.0.0-he8cfe8b_0.conda packages: @@ -10709,6 +10751,7 @@ packages: - lz4-c >=1.10.0,<1.11.0a0 license: BSD-3-Clause license_family: BSD + run_exports: {} size: 44154 timestamp: 1765026394687 - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda @@ -18265,6 +18308,7 @@ packages: - lz4-c >=1.10.0,<1.11.0a0 license: BSD-3-Clause license_family: BSD + run_exports: {} size: 51745 timestamp: 1765026442641 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.10.0-h5ad3122_1.conda diff --git a/pixi.toml b/pixi.toml index 97742e0..a89698c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -28,6 +28,7 @@ robot = "ros2 launch mote_bringup robot_launch.py" slam = "ros2 launch mote_bringup slam_launch.py" teleop = "ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args -p stamped:=true -r /cmd_vel:=/diff_drive_controller/cmd_vel" perception = "ros2 launch mote_perception perception_launch.py" +record = "ros2 launch mote_bringup record_launch.py" [dependencies] @@ -68,6 +69,10 @@ ros-jazzy-ros2lifecycle = ">=0.18.0" ros-jazzy-ros2run = ">=0.18.0" ros-jazzy-rosbag2-cpp = ">=0.26.0" ros-jazzy-rosbag2-storage = ">=0.26.0" +# `ros2 bag record` CLI verb, recorder, and storage plugins (pixi run record) +ros-jazzy-ros2bag = ">=0.26.0" +ros-jazzy-rosbag2-transport = ">=0.26.0" +ros-jazzy-rosbag2-storage-mcap = ">=0.26.0" ros-jazzy-slam-toolbox = ">=2.8.4,<3" ros-jazzy-teleop-twist-keyboard = ">=1.0.0" ros-jazzy-v4l2-camera = ">=0.7.1,<0.8"