|
Download README.md from penji2803/TurtleBotJEPA-PPO: direct link, hf CLI and curl.
- Browser
- Download file 15.1 kB
-
https://huggingface.co/penji2803/TurtleBotJEPA-PPO/resolve/main/README.md
- Command line
-
hf download hf://penji2803/TurtleBotJEPA-PPO/README.md
-
curl -L -o README.md https://huggingface.co/penji2803/TurtleBotJEPA-PPO/resolve/main/README.md
15.1 kB
| license: mit | |
| library_name: pytorch | |
| pipeline_tag: reinforcement-learning | |
| tags: | |
| - robotics | |
| - turtlebot3 | |
| - ros2 | |
| - reinforcement-learning | |
| - ppo | |
| - jepa | |
| - lidar | |
| - collision-avoidance | |
| - navigation | |
| base_model: penji2803/lidar-vjepa-turtlebot3 | |
| datasets: | |
| - penji2803/turtlebot3-moving-obstacles-lidar-1.5m | |
| # TurtleBotJEPA-PPO: run a JEPA + PPO navigation policy on a real TurtleBot3 | |
| Download this repository to a laptop, follow the guide below, and a **TurtleBot3 Burger with an LDS-02 lidar** drives to | |
| places you click on a map of your room, avoiding obstacles. Everything runs on the laptop; the robot only needs the | |
| standard ROBOTIS software. | |
| ``` | |
| robot (bringup) ββ /scan, /odom βββΊ laptop ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ /cmd_vel βββΊ robot | |
| β LDS-02 cleaning β last 20 scans β frozen LiDAR V-JEPA encoder β 1024 numbers | |
| β β risk / clearance heads (8 directions, next 1 s) β 16 numbers | |
| β goal distance + angle + 3 Γ 24 front beams + 16 βββΊ PPO policy βββΊ 5 turn rates | |
| β collision shield (learned risk + footprint check) + hard safety stops | |
| ``` | |
| | Part | Where it comes from | | |
| |---|---| | |
| | LiDAR encoder | [penji2803/lidar-vjepa-turtlebot3](https://huggingface.co/penji2803/lidar-vjepa-turtlebot3): self-supervised V-JEPA-style model, frozen | | |
| | Training data | [penji2803/turtlebot3-moving-obstacles-lidar-1.5m](https://huggingface.co/datasets/penji2803/turtlebot3-moving-obstacles-lidar-1.5m) | | |
| | Policy | PPO (sb3-contrib MaskablePPO), trained in Gazebo, then fine-tuned with a simulated LDS-02 sensor model | | |
| ## How good is it? Read this first | |
| | Test | Result | | |
| |---|---| | |
| | Simulation, 200 fixed episodes, 4 moving obstacles, LDS-02 sensor model | 38.5 % goals reached, the rest collisions | | |
| | Gazebo rehearsal of this exact program, 8 trips, static pillars, half speed | 7 / 8 goals, 1 safety stop | | |
| | Real TurtleBot3 Burger (LDS-02) | Early tests only: it reaches simple goals. The hard safety stop ended runs where the learned risk missed a box; the shield was then hardened. | | |
| **It is a research model and is not safe for unattended use.** Rules: | |
| - **Space:** use a clear, flat area of at least 3 Γ 3 m. | |
| - **Obstacles:** soft ones only (cardboard, foam), **taller than 20 cm**; the lidar plane is about 18 cm high. | |
| - **Supervision:** never let it drive at people or pets; keep a hand on **Ctrl+C**. | |
| - **Last resort:** pick the robot up or switch it off. | |
| ## What you need | |
| - **Robot:** a TurtleBot3 **Burger** with an **LDS-02** lidar (shipped 2022β2025; the model is printed on the sensor), a Raspberry Pi 4 and a charged battery. | |
| - LDS-01 and LDS-03 are untested; the code reads any lidar format, but the model was tuned for LDS-02. | |
| - **Laptop:** Ubuntu 22.04 with ROS 2 Humble (no GPU needed). | |
| - **Network:** one Wi-Fi network that both the laptop and the robot can join. A phone hotspot or home router works best; university Wi-Fi often blocks ROS 2. | |
| --- | |
| ## Part A: Laptop setup (once) | |
| 1. **Install ROS 2 Humble** by following the [official guide](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html) (the `ros-humble-desktop` variant). Then install the TurtleBot3, mapping and localization packages: | |
| ```bash | |
| sudo apt install ros-humble-turtlebot3 ros-humble-turtlebot3-msgs ros-humble-turtlebot3-cartographer ros-humble-turtlebot3-navigation2 ros-humble-turtlebot3-teleop ros-humble-turtlebot3-gazebo ros-humble-cartographer-ros ros-humble-navigation2 ros-humble-nav2-bringup python3-pip | |
| ``` | |
| 2. **Download this repository** into `~/TurtleBotJEPA-PPO`: | |
| ```bash | |
| pip install -U huggingface_hub | |
| ``` | |
| ```bash | |
| hf download penji2803/TurtleBotJEPA-PPO --local-dir ~/TurtleBotJEPA-PPO | |
| ``` | |
| 3. **Install the Python packages** for the system Python that ROS 2 uses. CPU-only PyTorch is enough: | |
| ```bash | |
| pip install --user torch --index-url https://download.pytorch.org/whl/cpu | |
| ``` | |
| ```bash | |
| pip install --user -r ~/TurtleBotJEPA-PPO/requirements.txt | |
| ``` | |
| 4. **Check the install** (no robot needed): | |
| ```bash | |
| cd ~/TurtleBotJEPA-PPO && python3 tests/test_adapter.py | |
| ``` | |
| It should end with `ALL TESTS PASSED`. | |
| ## Part B: Robot setup (once) | |
| 1. **Prepare the Raspberry Pi** with the ROBOTIS image for ROS 2 Humble and connect it to your Wi-Fi: see the ROBOTIS [SBC setup](https://emanual.robotis.com/docs/en/platform/turtlebot3/sbc_setup/) and [OpenCR setup](https://emanual.robotis.com/docs/en/platform/turtlebot3/opencr_setup/) guides. Note the robot's IP address. | |
| 2. **Log in to the robot** from the laptop (the ROBOTIS default password is `turtlebot`): | |
| ```bash | |
| ssh ubuntu@ROBOT_IP | |
| ``` | |
| 3. **On the robot, set the lidar model, robot model and channel** (once): | |
| ```bash | |
| echo 'export LDS_MODEL=LDS-02' >> ~/.bashrc | |
| ``` | |
| ```bash | |
| echo 'export TURTLEBOT3_MODEL=burger' >> ~/.bashrc | |
| ``` | |
| ```bash | |
| echo 'export ROS_DOMAIN_ID=30' >> ~/.bashrc | |
| ``` | |
| `ROS_DOMAIN_ID` is the "channel" laptop and robot talk on; it must be the same on both (this repo's default is 30). | |
| ## Part C: Try it without a robot (optional) | |
| This needs a 360-ray simulated Burger. The ROBOTIS default Gazebo Burger is 360 rays; if you changed it, for example for the ROBOTIS DQN tutorial, restore it. | |
| **Terminal 1:** start Gazebo: | |
| ```bash | |
| bash ~/TurtleBotJEPA-PPO/tools/sim_demo.sh | |
| ``` | |
| **Terminal 2:** drive 1 m ahead in the simulated world: | |
| ```bash | |
| cd ~/TurtleBotJEPA-PPO && source setup_terminal.sh sim && python3 run_policy.py --goal 1.0 0.0 --simulate-lds02 | |
| ``` | |
| `--simulate-lds02` makes the clean simulated lidar behave like an LDS-02. Use it only in simulation. | |
| --- | |
| ## Part D: Start of every session | |
| 1. **Switch the robot on** and wait about 1 minute. | |
| 2. **Terminal A:** start the robot's bringup and leave it running for the whole session: | |
| ```bash | |
| ssh ubuntu@ROBOT_IP | |
| ``` | |
| ```bash | |
| ros2 launch turtlebot3_bringup robot.launch.py | |
| ``` | |
| 3. **In every new laptop terminal**, run this first: | |
| ```bash | |
| cd ~/TurtleBotJEPA-PPO && source setup_terminal.sh | |
| ``` | |
| It prints `Ready: ROS 2 humble, ROS_DOMAIN_ID=30, TURTLEBOT3_MODEL=burger ...`. | |
| 4. **Pre-flight check** (the robot does not move): | |
| ```bash | |
| python3 check_robot.py | |
| ``` | |
| - All lines should say `OK`. | |
| - Hold a box about 30 cm in front of the robot: **AHEAD** must drop. Then on its left: **LEFT** must drop. | |
| - If left and right are swapped, check `LDS_MODEL` on the robot and restart the bringup. | |
| ## Part E: Map your room (once per room) | |
| **Terminal B:** start mapping; RViz opens and the map grows as the robot moves: | |
| ```bash | |
| ros2 launch turtlebot3_cartographer cartographer.launch.py | |
| ``` | |
| **Terminal C:** drive the robot by hand. Keys: `w`/`x` faster or slower, `a`/`d` turn, `s` stop; the terminal must have focus. | |
| ```bash | |
| ros2 run turtlebot3_teleop teleop_keyboard | |
| ``` | |
| **Mapping tips:** | |
| - **Go slowly:** about 0.1 m/s, and turn slowly. | |
| - **Close the loop:** drive around the whole room and come back to where you started. | |
| - **Finish when the walls in RViz look solid.** | |
| **Terminal D:** save the map: | |
| ```bash | |
| mkdir -p ~/maps && ros2 run nav2_map_server map_saver_cli -f ~/maps/my_room | |
| ``` | |
| Then press **Ctrl+C** in terminals B and C. | |
| ## Part F: Click places on the map, the robot drives there | |
| **Terminal B:** start localization on your map (map server + AMCL only; it never drives the robot): | |
| ```bash | |
| ros2 launch nav2_bringup localization_launch.py map:=$HOME/maps/my_room.yaml params_file:=$(ros2 pkg prefix turtlebot3_navigation2)/share/turtlebot3_navigation2/param/burger.yaml use_sim_time:=False | |
| ``` | |
| **Terminal C:** open RViz: | |
| ```bash | |
| rviz2 -d rviz/map_goals.rviz | |
| ``` | |
| **Terminal D:** start the driving program: | |
| ```bash | |
| python3 map_goals.py | |
| ``` | |
| **Then, in RViz:** | |
| 1. **Tell it where the robot is:** click **"2D Pose Estimate"**, click where the robot really is on the map, and drag in the direction it faces. The red laser dots must line up with the walls; if not, do it again. | |
| 2. **Send it somewhere:** use **"Publish Point"** (one click) or **"2D Goal Pose"** to click a place. The robot drives there at half speed and then waits for the next click. | |
| 3. **Change your mind:** click a new place at any time to replace the goal. | |
| 4. **Stop:** press **Ctrl+C** in terminal D. | |
| **Rules for map goals:** | |
| - **Localization must be confident:** the robot refuses a goal while AMCL is unsure of its position (it prints why). | |
| - **Goal placement:** choose goals 0.8β3 m away and at least 0.5 m from walls and furniture. | |
| - **The policy doesn't plan routes.** It heads for the goal and avoids what its lidar sees; to get around a wall or into another room, click intermediate points (the doorway first). | |
| - **Don't start `navigation2.launch.py`:** Nav2's own driver would fight this program for the wheels. | |
| ## Part G: Or a goal measured from the start (no map needed) | |
| Put the robot on a taped start mark facing "ahead". The goal is X m ahead and Y m to the **left** (negative = right). | |
| 1. **Dry run** (the wheels never move): | |
| ```bash | |
| python3 run_policy.py --goal 1.0 0.0 --dry-run | |
| ``` | |
| 2. **Real run:** | |
| ```bash | |
| python3 run_policy.py --goal 1.5 0.5 | |
| ``` | |
| ## Part H: Check the learned collision risk on your robot (strongly recommended) | |
| The risk predictions were learned in simulation. These tools measure, and if needed adapt, them on your real sensor, using the robot's own future scans as labels (no manual labelling). | |
| 1. **Record 10 minutes** of driving by hand near (not into) boxes and walls: | |
| ```bash | |
| python3 real_heads_check.py record --minutes 10 | |
| ``` | |
| While it records, drive with `ros2 run turtlebot3_teleop teleop_keyboard` in another terminal. | |
| 2. **Evaluate:** | |
| ```bash | |
| python3 real_heads_check.py eval "logs/record_*.npz" | |
| ``` | |
| You want **GO**: front-direction AUROC β₯ 0.90. | |
| - **NO-GO with enough close approaches:** add `--finetune`, then copy `policy/heads_real.safetensors` over `policy/heads.safetensors` (keep a backup). | |
| - The footprint shield and the safety stops work either way. | |
| ## Shutting down | |
| 1. **Ctrl+C** in all laptop terminals, then in terminal A (the bringup). | |
| 2. **On the robot:** | |
| ```bash | |
| sudo shutdown now | |
| ``` | |
| 3. Wait about 30 s, then switch the power off. | |
| --- | |
| ## Options | |
| | Option (`run_policy.py` and `map_goals.py`) | Default | Meaning | | |
| |---|---|---| | |
| | `--speed-scale` | 0.5 | 0.5 = 0.10 m/s and half turn rates, with decision rate and lidar frame timing slowed to match (the policy sees the same geometry); 1.0 = training speed 0.20 m/s; 0.3 = slower | | |
| | `--geo-horizon` | 1.2 | seconds of path the footprint shield checks (1.5 = turns away earlier) | | |
| | `--geo-radius` | 0.17 | the shield blocks paths passing closer than this (m) to any lidar point | | |
| | `--shield-tau` | 0.6 | learned-risk threshold of the shield (0.8 = less cautious) | | |
| | `--safety-front` / `--safety-any` | 0.22 / 0.17 | hard stop distances (m): ahead Β±30Β° / any direction | | |
| | `--angle-offset` | 0 | rotate the lidar data (radians), e.g. 3.14159 if front and back are swapped | | |
| | `--stamped` | off | the robot runs ROS 2 Jazzy (TwistStamped `cmd_vel`) | | |
| | `--dry-run` (`run_policy.py`) | off | never move the wheels | | |
| | `ROS_DOMAIN_ID` (environment) | 30 | `TB3_DOMAIN_ID=31 source setup_terminal.sh` if your robot uses another channel | | |
| Logs: `logs/run_*.csv` / `logs/mapgoal_*.csv` (every decision) and `.npz` (the cleaned lidar frames). | |
| ## How it works | |
| - **LDS-02 β training format** (`lds02.py`, `lds02_adapter.py`): | |
| - every scan, whatever its point count or direction, is mapped onto the simulator's 360-ray grid; | |
| - invalid readings (the LDS-02 sees nothing below 0.16 m, and reports 0 or inf) become "no return" (3.5 m), unless an obstacle was just seen close by (near-field hold); | |
| - ranges are clipped to 0.12β3.5 m; | |
| - unit tests check that this is identical to the training pipeline. | |
| - **Policy input:** the goal distance and angle, the last 3 front scans (24 beams), and 8 risk + 8 clearance values from the JEPA heads. | |
| - **Collision shield:** an action is blocked if | |
| - the learned risk of the directions it heads into (the highest value over ~0.6 s) is above 0.6, or | |
| - the arc the robot would drive over the next 1.2 s passes within 0.17 m of any lidar point (footprint check). | |
| - **Hard safety stops**, independent of the network: something closer than 0.22 m ahead (Β±30Β°) or 0.17 m anywhere, stale sensor data (> 0.5 s), timeout, Ctrl+C. | |
| - **Speed scaling:** speeds and timing are scaled together, so at half speed the robot moves the same 2 cm between decisions as in training. | |
| ## Troubleshooting | |
| | Problem | Fix | | |
| |---|---| | |
| | `KeyError: 'TURTLEBOT3_MODEL'` | Run `source setup_terminal.sh` in that terminal, or `echo 'export TURTLEBOT3_MODEL=burger' >> ~/.bashrc` | | |
| | `NO SENSOR DATA`, or `ros2 topic list` shows no `/scan` / `/odom` | The bringup isn't running, or `ROS_DOMAIN_ID` differs between laptop and robot, or the Wi-Fi blocks ROS 2 traffic (try a phone hotspot) | | |
| | Left and right swapped in `check_robot.py` | `LDS_MODEL` on the robot doesn't match the sensor; fix it and restart the bringup | | |
| | Frequent `SAFETY STOP` | Goals too close to obstacles, or approach too head-on; try `--geo-horizon 1.5`, goals further from obstacles, or `--speed-scale 0.3` | | |
| | `AMCL is unsure where the robot is` | Use "2D Pose Estimate" again; drive a little with teleop so AMCL can match the walls | | |
| | Robot circles near the goal | Click a goal a little further away or at a different angle | | |
| | `SENSORS LOST` | Wi-Fi drop-outs; move closer to the router | | |
| ## Limitations | |
| - **Simulation-trained:** one arena with cylinders. Real rooms, furniture and people are different; expect collisions to be stopped by the shield and safety stops rather than avoided gracefully. | |
| - **No route planning:** the policy is reactive. | |
| - **Learned risk:** the JEPA risk predictions were unreliable on a real box in our tests; do Part H. | |
| - **Sensor tuning:** the LDS-02 behaviour was modelled from the datasheet; LDS-01 and LDS-03 are untested. | |
| ## Files | |
| | File | What it is | | |
| |---|---| | |
| | `map_goals.py` | Click goals in RViz (AMCL) and the robot drives there | | |
| | `run_policy.py` | One goal relative to the start pose | | |
| | `check_robot.py`, `real_heads_check.py` | Pre-flight check; real-data check and fine-tuning of the risk heads | | |
| | `lds02.py`, `lds02_adapter.py`, `v6_policy.py`, `tb3_jepa_agent.py`, `tb3_policy_core.py` | ROS-free core (numpy + torch + safetensors) | | |
| | `policy/` | Policy, heads, frozen JEPA encoder (all safetensors) and `policy_config.json` | | |
| | `rviz/map_goals.rviz`, `setup_terminal.sh`, `tools/sim_demo.sh`, `tests/` | RViz layout, terminal setup, Gazebo demo, unit tests | | |
| | `media/gazebo_demo.mp4` | A Gazebo-rendered run (an earlier version of this policy, in simulation) | | |
| ## License and credits | |
| MIT. Built on ROBOTIS [TurtleBot3](https://emanual.robotis.com/docs/en/platform/turtlebot3/overview/) (ROS 2 packages, Stage 3 | |
| world, reward design). The encoder follows V-JEPA (Bardes et al., 2024), adapted to 2-D lidar. | |