Real-Env is a collection of real-world robot controllers and peripherals for robotic manipulation research, initially developed during research project Gated Memory Policy at REALab (Stanford University). Currently, it supports ARX5 setups (including bimanual) and UR5-WSG50, compatible with UMI and iPhUMI data collection devices.
- gated-memory-policy for single arm (UR5 & ARX) UMI and iPhUMI in-the-wild deployment.
- behavior-prompting-policy for bimanual-ARX iPhUMI experiments (e.g. cloth folding) and behavior prompting.
Compatibility is not guranteed across branches (experiments for one project might not work in another branch). To reproduce experiments, please check out the corresponding branch for each project. Please keep the main branch README up-to-date and this section updated when new projects are added to this repo.
- Our repository is tested on Ubuntu 24.04 and 22.04 Linux desktop/laptop.
- An NVIDIA GPU is recommended for hardware accelerated video recording (see robologger)
- Miniforge3 or any conda distribution
# Inside the real-env directory
conda env create -f env.yaml
conda activate real-env- Connect UR5 to the computer through Ethernet, ensure the ip address on the computer is set to the same subnet as UR5 ip address, but the last section should be different.
- For example, if the UR5 ip address is 192.168.2.124, your computer's ip address of the corresponding ethernet connection should be set to 192.168.2.x, where x is a different number than 124. To test connection, run
ping 192.168.2.124on the computer.
- Update the
robot_ipin thereal_env/configs/controllers/ur5_cartesian.yaml. - Enable the UR5 control box, drag the robot end-effector to a neutral position, record the home pose on the control box, and update
home_pose_xyz_wxyzinreal_env/configs/tasks/umi_ur5.yaml. - Based on which direction the robot end-effector is pointing at, refer to
real_env/configs/agents/spacemouse_agent.yamland updatespacemouse_agent.pose_orientation_typesinreal_env/configs/tasks/umi_ur5.yaml. Incorrect setting will result in unaligned spacemouse control. conda activate real-envand runur5. Run again it it fails. You should seeUR5 is connectedif connection is successful.
- Mount WSG50 on the UR5 using the following part: iPhone Compatible WSG50 Mount and follow UMI Hardware Guide to install fin-ray fingers.
- Connect the WSG50 to the computer through Ethernet, using the same subnet rule as UR5.
- Update the
robot_ipin thereal_env/configs/controllers/wsg50.yaml. - Open WSG50 config panel in the browser. In motion -> manual control, press
ACKon the right side and thenManual Homingbutton. The gripper should move to the widest position and run into idle mode. In scripting -> interactive scripting, create a new script and paste the file fromreal_env/controllers/wsg50_scripts.lua. Save and run the script. conda activate real-envand runwsg50. You should seeright_end_effector is connectedif connection is successful.
- Follow arx5-sdk to setup ARX5 controller. Ensure you can run all test scripts successfully.
- Follow UMI-on-Legs 3D Printing Guide and Assembly Guide to install UMI gripper on ARX5.
conda activate real-envand runarx5 <model>.<model>can beX5_iphumi,X5_umi,L5_iphumi,L5_umi. Please choose the correct model based on your actual hardware. The robot should reset to home pose if connection is successful. If unable to connect, please runsudo slcand -o -f -s8 /dev/arxcan0 can0 && sudo ifconfig can0 up(SLCAN) orsudo ip link set up can0 type can bitrate 1000000(candleLight) again.- For bimanual, run
iphumi_arx5_bimanual <model>using<model>based on instructions in the previous step. You will need to set the relative transform between your two arms in iphumi_arx5_bimanual.yaml. Press thevkey to open a pose viewer showing the relative base to base transforms to verify you have set it correctly.
Notice: Sometimes there might be a jump when the robot boots up. This behavior is not reliably reproducible in our setup. Please raise an issue or PR if you can reproduce it.
- Follow iPhUMI to install the iPhone app and print the iPhone mount.
- Connect the iphone to the computer through a (at least) USB3.0 cable.
conda activate real-envthen runiphone wrist. If all 3 videos pop up (main, ultrawide, depth), connection is successful. The iPhone UDID will be printed in the terminal. - To connect to multiple iPhones, record the UDID of each iphone and update the
iphone_udidin iphone_wrist.yaml for wrist view and iphone_third.yaml for third person view. - If you are doing bimanual deployment, then use iphone_wrist_left.yaml and iphone_wrist_right.yaml instead.
- Find the device name of the webcam / GoPro. It should be something like
/dev/video0or/dev/video1. - Run
v4l2-ctl --list-formats-ext -d /dev/videoXto get the supported resolution, image format, fps etc. For example, when using the Elgato capture card, the image formatNV12supports 3840x2160@30fps and 1920x1080@120fps. - Update the
camera_id,cam_img_formatandcamera_configsin the corresponding yaml file, e.g.real_env/configs/peripherals/gopro0.yaml,real_env/configs/peripherals/webcam0.yaml. conda activate real-envand runwebcam 0orgopro 0. The image stream should pop up in a new window.
- Purchase the latest generation of 3Dconnexion SpaceMouse and use a usb cable to connect to the computer. Earlier generations may have drifting issues.
- Enable the spacenavd service:
sudo apt install libspnav-dev spacenavd sudo systemctl enable spacenavd.service sudo systemctl start spacenavd.service conda activate real-envand runspacemouse_server. You should see the SpaceMouse readout in the terminal.
We employ a decoupled architecture for different components. Each component (UR5, WSG50, iPhone, SpaceMouse, Policy, etc.) runs an independent server process in the background, as shown in the last section. We don't need to shut down the server process unless encountering connection issues.
The task script (e.g. real_env/tasks/iphumi_ur5_task.py) will initialize multiple clients to communicate with each server on demand. This ensures each component runs at their own frequency and avoids potential synchronization issues.
In each policy inference loop, the task script will:
- Query the latest camera images and the robot states
- Process the images and states and send to the policy server
- Wait for the policy server to return the next action trajectory
- Schedule the action trajectory on each robot controller
- robot-message-queue A light-weight and flexible Robot-centric Message Queue for Python applications based on ZeroMQ.
- Spawns an additional C++ thread on each server to handle communication so the client requests will not interrupt the server loop.
- Supports shared memory in C++ for high-res video streaming.
- Self-contained without additional dependencies (if you are suffering from the complicated ROS environment).
- robologger Light-weight and efficient logging library for robot learning applications.
- Best used with GPU accelerated video recording.
- Synchronizes multi-process logging in the background.
- teleop-utils A collection of teleoperation utilities (spacemouse, keyboard, mocap, iphone).
- robot-utils A collection of (hopefully) bug-free and frequently used utility functions for robot learning research.
During experiments, we might accidentally change some configs that leads to different behaviors and forgot the original configs. To ensure each episode is reproducible, we use hydra to compose configs in each component and aggregate them in the task script. The task script will then dump all the configs to <project_name>/<task_name>/<run_name>/episode_xxxxxx/metadata.zarr/.zattrs. (Please see the robologger output)
After all the setup hardware components above, we provide a checklist to run experiments. Except for the policy server, all other scripts should be run in the real-env conda environment and each in a different terminal. When switching checkpoints/experiments, the robot controller, spacemouse, and camera servers does not need to be restarted. Shortcut executables are installed in the real-env conda environment, use which xxx to find the underlying python script.
- Launch robot controllers:
ur5,wsg50(orarx5 <model>orarx5_bimanual <model>where<model>can beX5_iphumi,X5_umi,L5_iphumi,L5_umi; if not connected, please runsudo slcand -o -f -s8 /dev/arxcan0 can0 && sudo ifconfig can0 up(SLCAN) orsudo ip link set up can0 type can bitrate 1000000(candleLight) again.) - Launch spacemouse server:
spacemouse_server. - Launch camera servers:
iphone wrist(orwebcam,gopro 0). - Run the policy server in the
imitation-learning-policiescodebase, for example,cd ../imitation-learning-policiesconda activate imitationand thenshell_scripts/serve_policy_ckpt.sh iphumi_place_back_with_correction_diffusion_gated.ckptorshell_scripts/serve_policy_ckpt.sh data/checkpoints/real/umi_multi_diffusion_transformer_large.ckpt. - Run the task script:
iphumi_ur5 flip_and_place_backoriphumi_arx5 flip_and_place_backorumi_ur5 multi_taskorumi_arx5 multi_task. If everything is working, you should be able to teleop the robot with SpaceMouse. The task configs are stored inreal_env/configs/tasks/. If you are using a bimanual config, you can uselto switch the SpaceMouse to control the left arm and;for right arm. - To reset the robot, press
rin the task script terminal. - To continue policy control, press
cin the task script terminal. - (Does not have to be in the task script terminal) To stop policy control and mark success/failure, press
y/nwherever which window is on top; to stop policy control, presssthere will be a prompt to set success/failure. - To run a single trajectory with policy control, press
Cin the task script terminal. - Run
shell_scripts/kill_all_processes.shto kill all the processes after the experiment.
We welcome contributions! Feel free to open pull requests to add support for additional robots, camera, sensors, or other additions.
This repository is initially developed during research project Gated Memory Policy. If you find it useful, please cite our paper:
@misc{gao2026gatedmemorypolicy,
title = {Gated Memory Policy},
author = {Yihuai Gao and Jinyun Liu and Shuang Li and Shuran Song},
year = {2026},
eprint = {2604.18933},
archivePrefix = {arXiv},
primaryClass = {cs.RO},
url = {https://arxiv.org/abs/2604.18933},
}- Austin Patel contributed bimanual ARX support as part of Behavior Prompting Policy