diff --git a/README.md b/README.md index e2da36f..0323a5b 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # Isaac Sim - Unitree Go2 example -This project demos testing waypoint mission execution by a Unitree Go2 quadruped in different simulated environments. +This project demonstrates testing waypoint mission execution with a Unitree Go2 quadruped in different simulated environments. go2-example-scenes ## Prerequisites -- Isaac Sim 5.0 compatible [hardware](https://docs.isaacsim.omniverse.nvidia.com/latest/installation/requirements.html) and [driver](https://docs.omniverse.nvidia.com/dev-guide/latest/common/technical-requirements.html) -- [`uv` package manager](https://docs.astral.sh/uv/getting-started/installation/) (Not mandatory, but the instructions below are using `uv`) +- Isaac Sim 5.0 compatible [hardware](https://docs.isaacsim.omniverse.nvidia.com/latest/installation/requirements.html) and [drivers](https://docs.omniverse.nvidia.com/dev-guide/latest/common/technical-requirements.html) +- [`uv` package manager](https://docs.astral.sh/uv/getting-started/installation/) (Not mandatory, but the instructions below use `uv`) - [Git LFS](https://docs.github.com/en/repositories/working-with-files/managing-large-files/installing-git-large-file-storage) ## Setup @@ -17,85 +17,100 @@ git lfs pull ``` ```sh -# create the virtual environment and install dependencies +# Create the virtual environment and install dependencies uv sync ``` -## Run teleop demo -Use **WASD** for linear motion and **QE** for turning. **R** reloads the scene and **F** jumps to the next one. +## Run Teleop Demo +Use **WASD** for linear motion and **QE** for turning. Press **R** to reload the scene and **F** to jump to the next one. ```sh uv run dataflow --teleop ``` +## Run Tests with dora-rs +This executes all the tests locally. +```sh +# Run test with dora-rs and pytest +uv run dataflow --test-all +``` +See `uv run dataflow --help` for all options ## Testing with Artefacts -Follow the instructions at [docs.artefacts.com](https://docs.artefacts.com/getting-started/) to set-up the project. +### Set up the Artefacts Dashboard +Follow these steps to set up your Artefacts project. For more details, refer to the [documentation](https://docs.artefacts.com/getting-started/). +1. Install the CLI using `pipx` (other installation methods are available). ```sh -# Launch Isaac Sim and execute multiple waypoint tests -uvx --from artefacts-cli artefacts run waypoint_missions +sudo apt install pipx +pipx ensurepath +pipx install artefacts-cli ``` -## Run tests with dora-rs -This will execute all the tests without parameterization in `artefacts.yaml` +2. Create an account at https://app.artefacts.com and log in. +3. Create a new project and follow the authentication instructions provided on the project page. +4. Update [artefacts.yaml](./artefacts.yaml) with your project name. + +### Run Tests with Artefacts + ```sh -# Run test with dora-rs and pytest -uv run dataflow --test-all +# Launch Isaac Sim and execute multiple waypoint tests +artefacts run waypoint_missions ``` -See `uv run dataflow --help` for all options +Track the job status on your project page. Test outputs for each scenario will appear there upon completion. + -## Project walkthrough +## Project Walkthrough -### Main tools: +### Main Tools - Isaac Sim for simulation - `dora-rs` as the robotics framework - - PyTorch executing the control policy + - PyTorch for executing the control policy -This repo is organized as a Python workspace with multiple Python packages. +This repository is organized as a Python workspace containing multiple packages. ### Nodes -The `dora-rs` nodes are organized as separate Python packages under `nodes/*` +`dora-rs` nodes are organized as separate Python packages located in `nodes/*`. - - [`simulation`](./nodes/simulation/) runs the Isaac Sim simulation - - It outputs observations and information about the simulation like `robot_pose`, `simulation_time`, `waypoints`. - - It listens to the low-level joint commands and applies them on the simulated robot. - - Also accepts `load_scene` input that allows the test nodes to load different scenes without restarting the simulation. - - [`navigator`](./nodes/navigator/) using the robot position and the waypoint positions, it computes and publishes the high-level 2D navigation commands. - - [`policy_controller`](./nodes/policy_controller/) takes the high-level 2D navigation commands from the `navigator` nodes and outputs the low-level joint commands to the `simulation` node - - [`tester`](./nodes/tester/) contains the test nodes that should be executed with `pytest` - - [test_waypoints_poses.py](./nodes/tester/tester/test_waypoints_poses.py) Executes multiple waypoint navigation scenarios and uses the robot and waypoint position data to determine if the waypoint mission was successful. - - [test_waypoints_report.py](./nodes/tester/tester/test_waypoints_report.py) The simplified version of the test above, that uses the internal waypoint mission state from the simulation to determine if the waypoint mission was successful. - - [`teleop`](./nodes/teleop/) implements keyboard teleop control + - [`simulation`](./nodes/simulation/) runs the Isaac Sim simulation. + - Outputs observations and simulation data, such as `robot_pose`, `simulation_time`, and `waypoints`. + - Listens for low-level joint commands and applies them to the simulated robot. + - Accepts a `load_scene` input, allowing test nodes to switch scenes without restarting the simulation. + - [`navigator`](./nodes/navigator/) computes and publishes high-level 2D navigation commands based on the robot's position and waypoints. + - [`policy_controller`](./nodes/policy_controller/) receives high-level 2D navigation commands from the `navigator` node and outputs low-level joint commands to the `simulation` node. + - [`tester`](./nodes/tester/) contains test nodes executed via `pytest`. + - [test_waypoints_poses.py](./nodes/tester/tester/test_waypoints_poses.py) Executes multiple waypoint navigation scenarios, using robot and waypoint position data to verify mission success. + - [test_waypoints_report.py](./nodes/tester/tester/test_waypoints_report.py) A simplified version of the above test that uses the simulation's internal waypoint mission state to verify success. + - [`teleop`](./nodes/teleop/) implements keyboard teleoperation control. -### Other packages - - [`msgs`](./msgs/) Implements the necessary messages as python classes using [`arrow-message`](https://github.com/hennzau/arrow-message) - - [`dataflow`](./dataflow/) Using the [`dora-rs dataflow builder`](https://github.com/dora-rs/dora/tree/main/examples/python-dataflow-builder) implements a CLI to configure and run `dora-rs` dataflows. Run `uv run dataflow --help` to see all options. +### Other Packages + - [`msgs`](./msgs/) implements necessary messages as Python classes using [`arrow-message`](https://github.com/hennzau/arrow-message). + - [`dataflow`](./dataflow/) implements a CLI to configure and run `dora-rs` dataflows using the [`dora-rs dataflow builder`](https://github.com/dora-rs/dora/tree/main/examples/python-dataflow-builder). Run `uv run dataflow --help` for options. -### Future nodes - - `teleop` for controlling the robot with keyboard or gamepad - - `dds-transport` for interfacing the real Unitree Go2 hardware +### Future Nodes + - `teleop`: Control the robot via keyboard or gamepad. + - `dds-transport`: Interface with real Unitree Go2 hardware. ## Training -Policy training is separated in a standard Isaac Lab project: https://github.com/art-e-fact/go2_isaac_lab_env. +Policy training is handled in a separate Isaac Lab project: [go2_isaac_lab_env](https://github.com/art-e-fact/go2_isaac_lab_env). Steps: - - Follow the instructions in [go2_isaac_lab_env](https://github.com/art-e-fact/go2_isaac_lab_env) train the new policy - - Use `scripts/rsl_rl/play.py` to export the trained policy. - - This will generate `logs//exported/policy.pt` and `logs//params/env.yaml`. - - Override these files in the `./nodes/policy_controller/policy` of this repo. - - Try the new policy with `uv run python -m simulation` + - Follow the instructions in the [go2_isaac_lab_env](https://github.com/art-e-fact/go2_isaac_lab_env) repository to train a new policy. + - Use `scripts/rsl_rl/play.py` to export the policy. + - This generates `logs//exported/policy.pt` and `logs//params/env.yaml`. + - Overwrite the files in `./nodes/policy_controller/policy` in this repository with the newly generated files. + - Test the new policy with `uv run python -m simulation`. ## Development ```sh -# Setup isaacsim type hints in VS Code +# Set up Isaac Sim type hints in VS Code uv run -m isaacsim --generate-vscode-settings ``` diff --git a/artefacts.yaml b/artefacts.yaml index 58ac682..4ef840c 100644 --- a/artefacts.yaml +++ b/artefacts.yaml @@ -35,10 +35,8 @@ jobs: scenarios: settings: - name: report_based_waypoint_mission_test - run: "rm -rf outputs/artefacts && uv run dataflow --test-waypoint-report" - output_dirs: ["outputs/artefacts"] + run: "uv run dataflow --test-waypoint-report" - name: pose_based_waypoint_mission_test - run: "rm -rf outputs/artefacts && uv run dataflow --test-waypoint-poses" - output_dirs: ["outputs/artefacts"] + run: "uv run dataflow --test-waypoint-poses" \ No newline at end of file diff --git a/dataflow/src/dataflow/dataflow.py b/dataflow/src/dataflow/dataflow.py index 843b5c2..4fb6b4a 100644 --- a/dataflow/src/dataflow/dataflow.py +++ b/dataflow/src/dataflow/dataflow.py @@ -1,3 +1,4 @@ +import os import typer import dora from dora.builder import DataflowBuilder @@ -5,8 +6,10 @@ from pathlib import Path workspace_path = Path(__file__).parent.parent.parent.parent -output_path = workspace_path / "outputs/artefacts" nodes_path = workspace_path / "nodes" +output_path = Path( + os.getenv("ARTEFACTS_SCENARIO_UPLOAD_DIR", workspace_path / "outputs/artefacts") +) temp_dataflow_path = output_path / "dataflow.yaml" @@ -29,7 +32,6 @@ def _create_base_dataflow() -> DataflowBuilder: args="--scene generated_pyramid --use-auto-pilot", env={ "OMNI_KIT_ACCEPT_EULA": "YES", - "OUTPUT_DIR": str(output_path), }, ) simulation.add_input("pub_status_tick", "dora/timer/millis/200") diff --git a/nodes/simulation/simulation/go2_scene.py b/nodes/simulation/simulation/go2_scene.py index 295e5b1..b65152b 100644 --- a/nodes/simulation/simulation/go2_scene.py +++ b/nodes/simulation/simulation/go2_scene.py @@ -25,7 +25,7 @@ from simulation.waypoint_mission import WaypointMission SCENE_ROOT = "/Scene" -OUTPUT_DIR = Path(os.getenv("OUTPUT_DIR", "outputs/artefacts")) +OUTPUT_DIR = Path(os.getenv("ARTEFACTS_SCENARIO_UPLOAD_DIR", "outputs/artefacts")) def add_reference(