{"id":30388029,"url":"https://github.com/mit-spark/awesome-dcist-t4","last_synced_at":"2025-08-21T06:06:42.621Z","repository":{"id":310870188,"uuid":"940846318","full_name":"MIT-SPARK/Awesome-DCIST-T4","owner":"MIT-SPARK","description":"Curated list of papers and resources focused on the MIT DCIST stack intended to keep pace with the anticipated surge of research in the coming months. ","archived":false,"fork":false,"pushed_at":"2025-08-20T19:18:31.000Z","size":6446,"stargazers_count":6,"open_issues_count":40,"forks_count":0,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-08-20T19:32:24.783Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MIT-SPARK.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-02-28T22:48:20.000Z","updated_at":"2025-08-20T15:44:33.000Z","dependencies_parsed_at":"2025-08-20T19:42:40.157Z","dependency_job_id":null,"html_url":"https://github.com/MIT-SPARK/Awesome-DCIST-T4","commit_stats":null,"previous_names":["mit-spark/awesome-dcist-t4"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/MIT-SPARK/Awesome-DCIST-T4","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MIT-SPARK%2FAwesome-DCIST-T4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MIT-SPARK%2FAwesome-DCIST-T4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MIT-SPARK%2FAwesome-DCIST-T4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MIT-SPARK%2FAwesome-DCIST-T4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MIT-SPARK","download_url":"https://codeload.github.com/MIT-SPARK/Awesome-DCIST-T4/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MIT-SPARK%2FAwesome-DCIST-T4/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271435923,"owners_count":24759328,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-21T02:00:08.990Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-21T06:06:40.941Z","updated_at":"2025-08-21T06:06:42.564Z","avatar_url":"https://github.com/MIT-SPARK.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 😁 Awesome DCIST T4 😁\n\n\u003cdiv align=\"center\"\u003e\n  A curated collection of resources focused on the MIT DCIST 🪖 stack and related technologies.\n\n  [**Browse the CRA**](https://arl.devcom.army.mil/cras/dcist-cra/) | [**Contribute**](CONTRIBUTING.md)\n\u003c/div\u003e\n\n\n## Contents\n\n- [Installation](#installation)\n- [Documentation](#documentation)\n- [Tools \u0026 Utilities](#tools-utilities)\n- [Sponsors](#sponsors)\n\n\n## Installation\n\nInstall dependencies:\n```bash\nsudo apt install pipx python3-virtualenv python3-colcon-clean wget\npipx install -f tmuxp\npipx install -f pre-commit\necho 'export PATH=$PATH:$HOME/.local/bin' \u003e\u003e ~/.zshrc\n```\n\nSet up semantic inference dependencies [here](https://github.com/MIT-SPARK/semantic_inference/blob/ros2/docs/closed_set.md#getting-dependencies)\n*(Required to run hydra online but not required for running from a bag with semantic inference data)*\n\nMake your workspace (feel free to choose a different path):\n```bash\nmkdir -p ~/colcon_ws/src \u0026\u0026 cd ~/colcon_ws\n```\n\nSet up your environment variables (make sure you are in your workspace this):\n```bash\necho export ADT4_WS=$(pwd) \u003e\u003e ~/.zshrc\necho export ADT4_DLS_PKG=${ADT4_WS}/src/awesome_dcist_t4/dcist_launch_system \u003e\u003e ~/.zshrc\necho export ADT4_ENV=${HOME}/environments/dcist \u003e\u003e ~/.zshrc\n\n# Source to update changes\nsource ~/.zshrc\n```\n\nYou may want to leave these unspecified on development machines:\n```bash\necho export ADT4_OUTPUT_DIR=${HOME}/adt4_output/init \u003e\u003e ~/.zshrc\necho export ADT4_ROBOT_NAME=spot \u003e\u003e ~/.zshrc\n```\n\nYou also will want to set up any secrets you have (**do not commit anywhere**):\n```bash\necho export ADT4_BOSDYN_USERNAME=user \u003e\u003e ~/.zshrc\necho export ADT4_BOSDYN_PASSWORD=pass \u003e\u003e ~/.zshrc\necho export ADT4_BOSDYN_IP=\"192.168.80.3\" \u003e\u003e ~/.zshrc\necho export ADT4_OPENAI_API_KEY=key \u003e\u003e ~/.zshrc\necho export ADT4_DEEPGRAM_API_KEY=key \u003e\u003e ~/.zshrc\n```\n\nSet up the ROS workspace and dependencies:\n```bash\n# Set up the ROS packages\ncd ${ADT4_WS}\ngit clone git@github.com:MIT-SPARK/Awesome-DCIST-T4.git src/awesome_dcist_t4 --recursive\nvcs import src \u003c src/awesome_dcist_t4/install/packages.yaml\nrosdep install --from-paths src --ignore-src -r -y --rosdistro jazzy\necho 'build: {symlink-install: true, cmake-args: [-DCMAKE_BUILD_TYPE=RelWithDebInfo]}' \u003e colcon_defaults.yaml\n```\n\nYou probably want to add some scripts to your path for convenience:\n```bash\necho 'export PATH=$PATH:$ADT4_WS/src/awesome_dcist_t4/dcist_launch_system/bin' \u003e\u003e ~/.zshrc\n```\n\nSet up the Python environments and packages:\n```bash\nbash ${ADT4_WS}/src/awesome_dcist_t4/install/python_setup.bash\nsudo ln -s ${ADT4_WS}/src/fast_downward/fast-downward.py /usr/local/bin/fast-downward\n```\n\nYou probably want to use Zenoh (see bottom of README for details):\n```bash\necho export RMW_IMPLEMENTATION=rmw_zenoh_cpp \u003e\u003e ~/.zshrc\nsource ~/.zshrc\n```\n\nThen, build the workspace as follows:\n```bash\npushd ${ADT4_WS}  # this is CRUCIAL to get colcon to behave properly\ncolcon build --continue-on-error\npopd\n```\n\nIf building the workspace is too memory intensive, set the `MAKEFLAGS` environment\nvariable to restrict the number of parallel jobs and add the argument `--executor sequential`\nto the `colcon build` command.\n\n## Python environments\n\nDifferent nodes can use different python environments; we have two (`roman` and `spark_env`) currently.\nYou should periodically rerun the python setup script to make sure everything is installed and up to date!\n\n\u003e :bangbang: **Important** \u003c/br\u003e\n\u003e The `spark_dsg` package needs to build python bindings every time it is updated. This means that you need to manually pip install `spark_dsg`!\n\u003e You can do this without running the full python setup script by running\n\u003e    ```bash\n\u003e    source ${ADT4_ENV}/spark_env/bin/activate\n\u003e    pip install ${ADT4_WS}/src/awesome_dcist_t4/spark_dsg\n\u003e    ```\n\n\n### Environment Variable Summary\n\n| Environment Variable Name         | Description                                                       |\n|-----------------------------------|-------------------------------------------------------------------|\n| ADT4\\_WS                          | Colcon workspace root                                             |\n| ADT4\\_ENV                         | Directory of Python venvs                                         |\n| ADT4\\_OUTPUT\\_DIR                 | Output directory (logs, data, etc)                                |\n| ADT4\\_BOSDYN\\_USERNAME            | Spot username                                                     |\n| ADT4\\_BOSDYN\\_PASSWORD            | Spot password                                                     |\n| ADT4\\_BOSDYN\\_IP                  | Spot IP (e.g, 192.168.80.3 for wifi)                              |\n| ADT4\\_PRIOR\\_MAP                  | Path to ADT4 output logging directory that includes stored map    |\n| ADT4\\_ROBOT\\_NAME                 | Robot name (e.g. \"spot\")                                          |\n| ADT4\\_DLS\\_PKG                    | Path to dicst\\_launch\\_system package                             |\n| ADT4\\_SIM\\_TIME                   | Use sim time? true/false                                          |\n| ADT4\\_OPENAI\\_API\\_KEY            | OpenAI API Key                                                    |\n| ADT4\\_DEEPGRAM\\_API\\_KEY          | Deepgram API Key                                                  |\n| MAKEFLAGS=\"-j 4\"                  | # of parallel jobs for colcon build                               |\n\nNote that while some of these environment variables can be set to dummy values\n(e.g., API Keys for functionality you aren't using), all of them need to be set\nto *something* in order to launch the system properly.\n\n### Silvus Network Computer IPs\n\n| Hostname      | Description           | IP              |\n|---------------|-----------------------|-----------------|\n| euclid        | Jasper Jockey         | 192.167.70.3    |\n| hamilton      | Topaz Jockey          | 192.167.70.2    |\n| russell       | Aaron's laptop        | 192.167.70.101  |\n| bonsai        | RRG dev computer      | ???.???.??.???  |\n| willow        | RRG base station      | 192.167.70.100  |\n\n### MIT Network Computer IPs\n| Hostname      | Description           | IP              |\n|---------------|-----------------------|-----------------|\n| euclid        | Jasper Jockey         | 10.29.219.68    |\n| hamilton      | Topaz Jockey          | 10.29.225.80    |\n| russell       | Aaron's laptop        | 10.29.129.166   |\n| bonsai        | RRG dev computer      | ???.???.??.???  |\n| willow        | RRG base station      | 10.29.170.228   |\n\n## Running in the Field\n\nWe have a new command line tool, `run-adt4` that should be used to launch tmuxp files on the robot. This is designed to ensure that (1) environment variables are set correctly and (2) that we don't accidentally overwrite previous outputs by not changing the output directory. To use it, you can just run\n```shell\nrun-adt4\n```\nfrom any directory (assuming you have the `bin` directory of `dcist_launch_system` on your path).\n\nThis will result in an interactive session that looks similar to this:\n```\nrobot name to use? hamilton\noutput directory? ~/test_adt4\n(1) base_station-default_params (2) data_collection-real_spot (3) real_spot-real_spot (4) real_spot_relocalize-real_spot_relocalize (5) spot_bag-bag (6) spot_bag_relocalize-relocalize (7) spot_prior_dsg-spot_prior_dsg\nWhat session do you want to load? [1]: 2\nLoading /home/nathan/dcist_ws/src/awesome_dcist_t4/dcist_launch_system/tmux/autogenerated/data_collection-real_spot.yaml...\n              Environment Variables\n┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓\n┃ Environment Variable ┃                  Value ┃\n┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩\n│ ADT4_ROBOT_NAME      │               hamilton │\n│ ADT4_OUTPUT_DIR      │ /home/nathan/test_adt4 │\n│ ADT4_PRIOR_MAP       │                    --- │\n│ ADT4_SIM_TIME        │                  false │\n└──────────────────────┴────────────────────────┘\nAre the settings correct? [y/N]:\n```\n\n`run-adt4` will use environment variables `ADT4_ROBOT_NAME`, `ADT4_OUTPUT_DIR` and `ADT4_PRIOR_MAP` if they are specified instead of prompting you for inputs (you can also specify both by command line arg).\nSee `run-adt4 --help` for a list of options:\n```\nUsage: run-adt4 [OPTIONS] [SESSION_PATH]\n\nOptions:\n  --tmuxp-args TEXT      args to forward to tmuxp\n  -n, --robot-name TEXT  robot name to use\n  -o, --output-dir PATH  output for adt4\n  -p, --prior-map        prior map\n  -s, --sim-time         use sim time\n  -y, --yes              skip env variable check\n  -f, --force            clear output if it exists\n  --help                 Show this message and exit.\n```\n\n\u003e :warning: **Warning** \u003c/br\u003e\n\u003e Note tmuxp does weird things with `.zshrc` versus the environment used to invoke tmuxp and you may want to remove `ADT4_OUTPUT_DIR` and `ADT4_PRIOR_MAP` from your `.zshrc` (the base launch component should forward these correctly though from the environment that invoked tmuxp).\n\nYou can also point it at a specific tmuxp session file (via absolute path)\n```bash\nrun-adt4 $ADT4_WS/src/dcist_launch_system/tmux/autogenerated/real_spot-real_spot.yaml\n```\nor just by the filename (assumed relative to the autogenerated directory):\n```shell\nrun-adt4 real_spot-real_spot.yaml\n```\n\n\u003e :exclamation: **Note** \u003c/br\u003e\n\u003e If you specify `run-adt4 --prior-map` without the map path, the script will prompt you to enter a path (which makes use of readline for command history, which may be slightly more convenient in some cases).\n\n## Example System Configurations\n\n### Hydra with Bag\n\nIf you want to see hydra running on real Spot data, get the bag from Aaron (and\nconvert by `pipx install rosbags; rosbags-convert --src\nspot_hydra_twocam_test.bag --dst spot_hydra_twocam_test`).\n\nMake sure you have an override file for the tf qos, e.g., `~/.tf_overrides.yaml`\nlooks like\n\n```yaml\n/tf_static: {depth: 1, durability: transient_local}\n```\n\nThen run\n```bash\nADT4_SIM_TIME=true tmuxp load dcist_launch_system/tmux/autogenerated/spot_bag-bag.yaml\n```\n\nIn a separate window, source the workspace and then run the bag\n\n```\nsource /path/to/workspace/install/setup.zsh # if not source already\nros2 run ianvs play_rosbag /path/to/spot_hydra_twocam_test --clock\n```\n\n### Prior Scene Graph and Movable Spot\n\nAlternatively, you can drive spot around (and plan in?) a prior scene graph.\n\nFirst, a quick discussion on logging.\nDuring each session, a directory is created from the path set in `$ADT4_OUTPUT_DIR`.\nHydra scene graphs and ROMAN maps are stored in this directory (see [below](#saving-a-map))\nBefore using a prior scene graph, you need to set the `ADT4_PRIOR_MAP` environment variable to\nthe absolute path of the adt4 output directory used when creating the original scene graph\n(if you `ls $ADT4_PRIOR_MAP` you should see `hydra` and `roman` subdirectories).\n\nThen run\n```\nADT4_SIM_TIME=false tmuxp load dcist_launch_system/tmux/autogenerated/spot_prior_dsg-spot_prior_dsg.yaml\n```\n\nThere will be controls for moving spot around in one of the windows. You can\nsend spot a plan with:\n\n```\nros2 topic pub /hilbert/omniplanner_node/language_planner/language_goal omniplanner_msgs/msg/LanguageGoalMsg \"{robot_id: 'hilbert', domain_type: 'goto_points', command: 'R(70) R(23)'}\" -1\n```\n\nYou can also manually specify the list of string symbols, instead of relying on the \"language\" module to do it for you:\n```\nros2 topic pub /hilbert/omniplanner_node/goto_points/goto_points_goal omniplanner_msgs/msg/GotoPointsGoalMsg \"{robot_id: 'hilbert', point_names_to_visit: ['R(70)']}\" -1\n```\n\nYou can try out the TSP planner with:\n```\nros2 topic pub /hilbert/omniplanner_node/tsp_planner/solve_tsp_goal omniplanner_msgs/msg/GotoPointsGoalMsg \"{robot_id: 'hilbert', point_names_to_visit: ['R(69)', 'R(35)', 'R(71)', 'R(83)']}\" -1\n```\n\nThis should result in a planned path appearing in RVIZ, and spot following the\nplan.\n\nYou can also send PDDL goals such as:\n```\nros2 topic pub /hilbert/omniplanner_node/visit_objects_pddl/pddl_goal omniplanner_msgs/msg/PddlGoalMsg \"{robot_id: 'hilbert', pddl_goal: '(or (visited-place r116) (and (visited-place r69) (visited-place r83)))'}\" -1\n```\nCurrently you can use `visited-place` and `visited-object` predicates and\ngeneral conjunctions/disjunctions/negations to specify goals.\n\nThis example shows how to send region-grounded goals. It should work, although currently it will take a *long* time to plan (~2+ minutes).\n\n```\nros2 topic pub /hilbert/omniplanner_node/region_rearrange_objects_pddl/pddl_goal omniplanner_msgs/msg/PddlGoalMsg \"{robot_id: 'hilbert', pddl_goal: '(and (visited-region r70) (at-place p1042) (object-in-place o94 p2157))'}\" -1\n```\n\n\n### Catalog of Supported Launch Configurations\n\n| Tmux Launch Name                                 | Description                                                                                        |\n|--------------------------------------------------|----------------------------------------------------------------------------------------------------|\n| `base_station-real_spot.yaml`                    | Runs base station planner, language interface, and visualizer                                      |\n| `data_collection-real_spot.yaml`                 | Runs real spot interface for collecting sensor/robot data                                          |\n| `real_spot_relocalize-real_spot_relocalize.yaml` | Runs online spot interface for relocalizing in a prior scene graph                                 |\n| `real_spot-real_spot.yaml`                       | Runs online spot interface for building a scene graph and planning in current scene graph          |\n| `spot_bag_relocalize-relocalize.yaml`            | Runs with single spot robot, based on a bag, using sim time and relocalizes in a prior scene graph |\n| `spot_bag-bag.yaml`                              | Runs with single spot robot, based on a bag, using sim time                                        |\n| `spot_prior_dsg-spot_prior_dsg.yaml`             | Runs with a single spot robot and a prior scene graph                                              |\n\n\n\n## Tools \u0026 Utilities\n\n### Saving a Scene Graph\n\nMost of the launch configurations launch a scene graph saver node. You can save\na scene graph from the commandline by running\n\n```\nros2 service call /dsg_saver/save_dsg dcist_launch_system_msgs/srv/SaveDsg \"{save_path: '', include_mesh: true}\"\n```\nIf you leave `save_path`, it will default to saving under `$ADT4_OUTPUT_DIR`\n\n## Configuring Parameters\n\nThis section will give some technical explanation about how parameters are\nmanaged in ADT4. The following section builds on this and explains the full\npower of the `experiment_manifest.yaml` file that allows composing overrides\nand generating tmux launch files.\n\nAll ROS nodes in `ADT4` load their config from\n`dcist_launch_system/config/\u003cexperiment_key\u003e/\u003cnode_name\u003e.yaml`. The yaml files\nunder the `\u003cexperiment_key\u003e` directory have a full set of the yaml parameters\nthat are necessary to run the stack. However, most parameters are the same\nbetween different configurations, usually requiring only a small number of\nparameters to be changed from different robot or autonomy configurations.\n\nTo make it possible to keep track of which parameters can be shared between\nconfigurations vs. which are system-specific, the system-specific\nconfigurations are automatically generated from files that explicitly factorize\nwhich parameters should be different for a given configuration.\n\nIn `dcist_launch_system/config_generation/base_params`, we store a full set of\n*all* the parameters. Then, in\n`dcist_launch_system/config_generation/experiment_overrides/\u003cexperiment_key\u003e`\nwe have override files that specify specific parameters that should be\noverridden for a given configuration. We use `config_utilities` to do this yaml templating.\nFor example, consider `base_params/spot_executor_node.yaml`:\n\n```yaml\n/**:\n    ros__parameters:\n        odom_frame: \"map\"\n        body_frame: \"body\"\n        use_fake_spot_pose: false\n        fake_spot_external_pose: true\n        spot_ip: \"10.0.0.3\"\n        bosdyn_client_username: \"$(env BOSDYN_CLIENT_USERNAME)\"\n        bosdyn_client_password: \"$(env BOSDYN_CLIENT_PASSWORD)\"\n        .....\n```\n\n`use_fake_spot_pose` and `fake_external_pose` need to be changed depending on\nwhether we are running from a bag that provides a pose for spot, or a\n\"simulated\" spot where spot controls its own pose. In\n`config_generation/experiment_overrides/spot_prior_dsg/spot_executor_node_overlay.yaml`\nwe specify that for the `spot_prior_dsg` parameter setting, these two flags should be\nflipped:\n\n```yaml\n---\n/**:\n    ros__parameters:\n        use_fake_spot_pose: true\n        fake_spot_external_pose: false\n```\n\nThe naming of this file is important -- our compositor will update a `\u003cnode\nname\u003e.yaml` base param file by searching for `\u003cnode name\u003e_overlay.yaml` file.\nThis specifies the values that should be used in the `base_params` file.\n\nTo do the generation, run `generate_configs.py`, which can be found in\n`config_generation`. `generate_configs.py` takes three arguments -- a root\ndirectory for the parameter specifications live (i.e.,\n`dcist_launch_system/config_generation`), the directory where you want to\noutput config files (normally `dcist_launch_system/config`) and where to output\nthe generated tmux launch files (normally\n`dcist_launch_system/tmux/autogenerated`). There is also a verbose and quiet\nflag.\n\nThere is a script that has the correct input/output directories filled in, so\nyou should normally be able to run\n`dcist_launch_system/scripts/generate_configs.sh`. But you can also run the\npython script directly to control input/output directories, e.g.,:\n```bash\ncd dcist_launch_system/config_generation\n./generate_configs.py . ../config ../tmux/autogenerated\n```\nYou will need to source your workspace to make sure `composite-configs` (the\nexecutable from `config_utilities` that handles compositing the YAML) is\navaiable on the path.\n\n## Config Generation \"Experiment Manifest\"\n\nThe config generation process is controlled by a file called\n`experiment_manifest.yaml` found in the root directory that\n`generate_configs.py` is invoked with (e.g.,\n`dcist_launch_system/config_generation/experiment_manifest.yaml`. There are\nthree parts of this file -- `launch_configs`, `configs`, and `experiments`.\n\nThe `launch_configs` allow you to build up a tmuxp file composed of reusable\nwindows. Each item under launch configs is a name for a group of windows. A\nname with no children is a \"window primitive\", and a yaml file with the same\nname should be present in `config_generation/launch_components`. Note that the\nlaunch specification is composable, in the sense that the children of a launch\nconfig don't need to be primitives.\n\nThe `configs` follow a similar compositional logic. A config with no children\nshould be a directory under `experiment_overrides`. A parameter grouping that\ndoes have children will apply all descendant primitive configs as overrides.\n\nFinally, the `experiments` section generates launch files for the specified\ncombination of launch config X parameter grouping X {other variables}. The\nsyntax and semantics of these {other variables} is going to change soon, but\nroughly they map to environment variables that are set in the tmux file.\n\n## Zenoh\nMiddleware is, of course, a personal choice, though in this project, the\ndefault is to use Zenoh.\n### Installation\n```bash\nsudo apt update \u0026\u0026 sudo apt install ros-jazzy-rmw-zenoh-cpp\n```\n### Setting Default RMW\n```bash\necho export RMW_IMPLEMENTATION=rmw_zenoh_cpp \u003e\u003e ~/.zshrc\n```\n### Starting Zenoh Router\n```bash\nros2 run rmw_zenoh_cpp rmw_zenohd\n```\nBy default, the tmux launch files will start the zenoh router for you, so you\nprobably don't need to run this command manually.\n\n### Connecting Multiple Zenoh Routers\nTo connect multiple Zenoh routers across laptops, copy\n[DEFAULT_RMW_ZENOH_ROUTER_CONFIG.json5](https://github.com/ros2/rmw_zenoh/blob/rolling/rmw_zenoh_cpp/config/DEFAULT_RMW_ZENOH_ROUTER_CONFIG.json5)\nto a location of your choosing (e.g., your home directory) and modify the\n`connect` block to include the endpoint(s) that the other host's `Zenoh router(s)`\nis listening on. For example, if another `Zenoh router` is listening on IP address\n`192.168.1.1` and port `7447` (the default) on its host, modify the config file to connect to\nthis router as shown below:\n\n```json5\n/// ... preceding parts of the config file.\n{\n  connect: {\n    endpoints: [\"tcp/192.168.1.1:7447\"],\n  },\n}\n/// ... following parts of the config file.\n```\nThen, start the `Zenoh router` after setting the `ZENOH_ROUTER_CONFIG_URI` environment variable to the absolute path of the modified config file.\n\n```bash\necho export ZENOH_ROUTER_CONFIG_URI=/path/to/DEFAULT_RMW_ZENOH_ROUTER_CONFIG.json5 \u003e\u003e ~/.zshrc\n```\nFor additional instructions, please refer [here](https://github.com/ros2/rmw_zenoh/).\n\n### Saving a Map\n\nA current session's map will be saved to the `$ADT4_OUTPUT_DIR` directory when you either:\n\n* Press enter in the bottom pane in the `core` tmux window.\nThis will automatically cause ROMAN and Hydra to log their outputs.\n* Or use `Ctrl-c` on the ROMAN mapping node (top right pane in the `roman` tmux window) and call the service: `ros2 service call /${ADT4_ROBOT_NAME}/shutdown std_srvs/Empty` to have Hydra shutdown\n\nAfter doing one of these two options, the following paths should exist:\n* `$ADT4_OUTPUT_DIR/roman/roman_map.pkl`\n* `$ADT4_OUTPUT_DIR/hydra`\n\n## Sponsors\n\nA big thank you to our sponsors for their generous support:\n\n* [ARL Distributed and Collaborative Intelligent Systems and Technology Collaborative Research Alliance (DCIST\nCRA) agreement W911NF-17-2-0181](https://arl.devcom.army.mil/cras/dcist-cra/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmit-spark%2Fawesome-dcist-t4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmit-spark%2Fawesome-dcist-t4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmit-spark%2Fawesome-dcist-t4/lists"}