diff --git a/README.md b/README.md index 6ca3562..ef06379 100644 --- a/README.md +++ b/README.md @@ -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 @@ -49,7 +49,7 @@ 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. @@ -57,34 +57,26 @@ URLab communicates with external systems over ZMQ. The companion package [**urla - **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. diff --git a/Source/URLab/Private/MuJoCo/Components/Geometry/MjGeom.cpp b/Source/URLab/Private/MuJoCo/Components/Geometry/MjGeom.cpp index 0d49e34..c8b05cb 100644 --- a/Source/URLab/Private/MuJoCo/Components/Geometry/MjGeom.cpp +++ b/Source/URLab/Private/MuJoCo/Components/Geometry/MjGeom.cpp @@ -196,7 +196,8 @@ 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 }; @@ -204,13 +205,14 @@ void UMjGeom::ImportFromXml(const FXmlNode* Node, const FMjCompilerSettings& Com } 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)); } diff --git a/Source/URLabEditor/Private/Tests/MjBindingTest.cpp b/Source/URLabEditor/Private/Tests/MjBindingTest.cpp index 871db76..152ba89 100644 --- a/Source/URLabEditor/Private/Tests/MjBindingTest.cpp +++ b/Source/URLabEditor/Private/Tests/MjBindingTest.cpp @@ -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 diff --git a/docs/getting_started.md b/docs/getting_started.md index ed2a15f..78f5c4a 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -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). @@ -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: @@ -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 @@ -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.