Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
[![arXiv](https://img.shields.io/badge/arXiv-2504.14135-b31b1b.svg)](https://arxiv.org/abs/2504.14135)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
[![MuJoCo](https://img.shields.io/badge/MuJoCo-3.7+-green.svg)](https://github.com/google-deepmind/mujoco)
[![Unreal Engine](https://img.shields.io/badge/Unreal_Engine-5.4+-black.svg)](https://www.unrealengine.com)
[![Unreal Engine](https://img.shields.io/badge/Unreal_Engine-5.7+-black.svg)](https://www.unrealengine.com)

# URLab -- MuJoCo Physics in Unreal Engine

Expand Down Expand Up @@ -49,42 +49,34 @@ URLab communicates with external systems over ZMQ. The companion package [**urla

## Requirements

- **Unreal Engine 5.4+**
- **Unreal Engine 5.7+**
- **Windows** (Win64). Linux is experimental.
- **MuJoCo 3.7+** -- bundled in `third_party/`, built from source.
- **Visual Studio 2022** or compatible C++ toolchain.
- **CMake 3.24+** -- for building third-party libraries.
- **Python 3.11+** -- optional, for `urlab_bridge` policies.
- **[uv](https://github.com/astral-sh/uv)** -- optional, for Python dependency management.

## Quick Start (Installation)
## Installation

> **⚠️ Critical:** This is a C++ plugin. You **must** be using a C++ project. If your project is Blueprints-only, add a dummy C++ class via *Tools > New C++ Class* before starting.

### 1. Setup Folders
### 1. Clone the Plugin
Clone this repo into your project's `Plugins` folder:
```bash
cd "YourProject/Plugins"
git clone [https://github.com/URLab-Sim/UnrealRoboticsLab.git](https://github.com/URLab-Sim/UnrealRoboticsLab.git)
git clone https://github.com/URLab-Sim/UnrealRoboticsLab.git
```

### 2. Build Dependencies
Navigate to the plugin's `third_party` folder and run the build script to fetch and compile MuJoCo and ZMQ:
Navigate to the plugin's `third_party` folder and run the build script to fetch and compile MuJoCo, CoACD, and ZMQ:
```powershell
cd UnrealRoboticsLab/third_party
.\build_all.ps1
```
*(If this script fails with a **Stack Overflow** error, see [Troubleshooting](#-troubleshooting) below).*

### 3. Register Module (Don't skip!)
You must tell Unreal to link your project against the plugin. Open your project's `.Build.cs` file (e.g., `Source/MyProject/MyProject.Build.cs`) and add `"UnrealRoboticsLab"`:
```csharp
PublicDependencyModuleNames.AddRange(new string[] {
"Core", "CoreUObject", "Engine", "InputCore", "UnrealRoboticsLab"
});
```
*(If this script fails with a **Stack Overflow** error, see [Troubleshooting](#troubleshooting) below).*

### 4. Compile & Launch
### 3. Compile & Launch
1. Right-click your `.uproject` and select **Generate Visual Studio project files**.
2. Build the solution in VS2022/Rider and launch the Editor.
3. **Important:** In the Content Browser, go to **Settings (Gear Icon)** and check **"Show Plugin Content"** to see the UI and assets.
Expand Down
10 changes: 6 additions & 4 deletions Source/URLab/Private/MuJoCo/Components/Geometry/MjGeom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,21 +196,23 @@ void UMjGeom::ImportFromXml(const FXmlNode* Node, const FMjCompilerSettings& Com
else
{
FString PosStr = Node->GetAttribute(TEXT("pos"));
if ((bOverride_Pos = !PosStr.IsEmpty()))
bOverride_Pos = !PosStr.IsEmpty();
if (bOverride_Pos)
{
FVector MjPos = MjXmlUtils::ParseVector(PosStr);
double p[3] = { (double)MjPos.X, (double)MjPos.Y, (double)MjPos.Z };
SetRelativeLocation(MjUtils::MjToUEPosition(p));
}
else
{
SetRelativeLocation(FVector::Zero());
SetRelativeLocation(FVector::ZeroVector);
bOverride_Pos = false;
}

// Orientation (quat, axisangle, euler, xyaxes, zaxis — priority order)
double MjQuat[4];
if ((bOverride_Quat = MjOrientationUtils::OrientationToMjQuat(Node, CompilerSettings, MjQuat)))
bOverride_Quat = MjOrientationUtils::OrientationToMjQuat(Node, CompilerSettings, MjQuat);
if (bOverride_Quat)
{
SetRelativeRotation(MjUtils::MjToUERotation(MjQuat));
}
Expand Down
1 change: 1 addition & 0 deletions Source/URLabEditor/Private/Tests/MjBindingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "MuJoCo/Components/Geometry/MjGeom.h"
#include "MuJoCo/Components/Joints/MjJoint.h"
#include "MuJoCo/Core/AMjManager.h"
#include "MuJoCo/Core/MjPhysicsEngine.h"
#include "MuJoCo/Core/MjArticulation.h"

// Define a test with flags to run in Editor
Expand Down
36 changes: 22 additions & 14 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Prerequisites

* **Unreal Engine 5.4+**
* **Unreal Engine 5.7+** — The C++ plugin code and third-party libraries should compile on earlier UE5 versions, but the bundled `.uasset` files (UI widgets, materials, input mappings) were serialized in 5.7 and are not backwards compatible. The core simulation will still work on older versions but the dashboard UI and some editor features will be missing. If there is demand for older version support, we can look into providing compatible assets.
* **Windows 10/11**
* **C++ Project:** This plugin contains source code and cannot be used in a Blueprints-only project.
* **Visual Studio 2022 / 2025** (with "Game development with C++" workload).
Expand All @@ -13,7 +13,7 @@
1. **Clone the Plugin:** Navigate to your project's `Plugins/` directory and clone the repository:
```bash
cd "YourProject/Plugins"
git clone [https://github.com/URLab-Sim/UnrealRoboticsLab.git](https://github.com/URLab-Sim/UnrealRoboticsLab.git)
git clone https://github.com/URLab-Sim/UnrealRoboticsLab.git
```

2. **Build Third-Party Dependencies:** Before opening the engine, you must fetch and build the MuJoCo dependencies. Open **PowerShell** and run:
Expand All @@ -23,21 +23,17 @@ cd UnrealRoboticsLab/third_party
```
*(If you encounter a compiler stack overflow error here, see the [Troubleshooting](#troubleshooting) section below).*

3. **Register the Module:** Open your host project's `.Build.cs` file (e.g., `Source/YourProject/YourProject.Build.cs`) and add `"UnrealRoboticsLab"` to your `PublicDependencyModuleNames`:
```csharp
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UnrealRoboticsLab" });
```

4. **Compile:** Right-click your `.uproject` file, select **Generate Visual Studio project files**, then open the solution and **Build** your project in your IDE.
3. **Compile:** Right-click your `.uproject` file, select **Generate Visual Studio project files**, then open the solution and **Build** your project in your IDE.

5. **Show Assets:** In the Unreal Content Browser, click the **Settings** (gear icon) and check **Show Plugin Content**. This is required to see the UI widgets and plugin assets.
4. **Show Assets:** In the Unreal Content Browser, click the **Settings** (gear icon) and check **Show Plugin Content**. This is required to see the UI widgets and plugin assets.

6. **(Optional) Python Bridge:** Set up the bridge for external control:
```bash
cd UnrealRoboticsLab/urlab_bridge
pip install uv
uv sync
5. **(Optional) C++ Integration:** If you want to use URLab types directly in your own C++ code (e.g., `#include "MuJoCo/Core/AMjManager.h"`, casting to `AMjArticulation*`), add `"URLab"` to your project's `.Build.cs`:
```csharp
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "URLab" });
```
This is **not required** if you only use the plugin through the editor, Blueprints, or ZMQ.

6. **(Optional) Python Bridge:** The companion [urlab_bridge](https://github.com/URLab-Sim/urlab_bridge) package provides Python middleware for external control, RL policy deployment, and ROS 2 bridging. See its README for setup instructions.

## Import Your First Robot

Expand Down Expand Up @@ -121,6 +117,18 @@ The UI is context-sensitive and requires specific conditions:
* In the `MjManager` settings, verify `bAutoCreateSimulateWidget` is enabled.
* Ensure you have followed the **"Show Assets"** step in the Installation guide to make the UI widgets visible to the engine.

### Older UE Versions: Content Assets Won't Load
The bundled `.uasset` files (UI widgets, materials, input mappings) were saved in UE 5.7 and won't load in earlier versions. The C++ plugin code compiles and the core simulation runs, but the dashboard UI and some editor features will be missing.

We strongly recommend upgrading to UE 5.7 as that is the only version we test and support. If that is not possible and you have UE 5.7 installed alongside your older version, you can recreate the assets by copy-pasting their contents:
1. Open the plugin project in **UE 5.7** and open the widget/material/input asset you need.
2. Select all nodes in the editor graph (Ctrl+A) and copy (Ctrl+C).
3. In your **older UE version**, create a new asset of the same type (e.g., a Widget Blueprint parented to `MjSimulateWidget`).
4. Paste (Ctrl+V) — the nodes and hierarchy transfer across versions.
5. Save the new asset. It is now compatible with your engine version.

This works for UMG widget Blueprints, material graphs, and input mapping assets.

### Simulation: Robot is Static
* **Control Source:** Check if the **Control Source** on the `MjManager` or `MjArticulation` is set to **UI**. If set to **ZMQ**, UI sliders will be ignored.
* **Physics State:** Ensure the `MjManager` is not paused and that the robot is not set to `Static` in its component settings.