Open Kai-X-Org opened 1 year ago
using System.Collections; using System.IO; using System.IO.Compression; using UnityEngine; using Unity.Robotics.UrdfImporter; using UnityEngine.Networking; using Unity.Robotics.UrdfImporter.Control; using TMPro;
public class UrdfRuntimeLoader : MonoBehaviour { public TextMeshPro DebugText; public string zipUrl = ""; // URL to download the zip file public string localZipFileName = "urdf_ue5.zip"; // Name of the local zip file public string urdfFileName = "ur5e.urdf"; // Name of the URDF file inside the zip public bool setImmovableLink = true; public bool useVHACD = false; public bool showProgress = false; public bool clearOnLoad = true;
private GameObject currentRobot = null;
private bool isLoading = false;
private IEnumerator LoadUrdf()
{
isLoading = true;
string localZipPath = Path.Combine(Application.persistentDataPath, localZipFileName);
UnityWebRequest zipRequest = UnityWebRequest.Get(zipUrl);
zipRequest.downloadHandler = new DownloadHandlerFile(localZipPath);
yield return zipRequest.SendWebRequest();
if (zipRequest.result != UnityWebRequest.Result.Success)
{
Debug.LogError("Failed to download zip file: " + zipRequest.error);
isLoading = false;
yield break;
}
string extractPath = Path.Combine(Application.persistentDataPath, "ExtractedURDF");
if (Directory.Exists(extractPath))
{
Directory.Delete(extractPath, true); // Clear any existing extracted content
}
Directory.CreateDirectory(extractPath);
ZipFile.ExtractToDirectory(localZipPath, extractPath);
Debug.Log("Extracted to: " + extractPath);
string urdfFilePath = Path.Combine(extractPath + "/URDF ur5e", urdfFileName);
if (!File.Exists(urdfFilePath))
{
Debug.LogError("URDF file not found in the extracted content!");
isLoading = false;
yield break;
}
if (clearOnLoad && currentRobot != null)
{
currentRobot.SetActive(false);
Destroy(currentRobot);
}
yield return null;
ImportSettings settings = new ImportSettings
{
chosenAxis = ImportSettings.axisType.yAxis,
convexMethod = useVHACD ? ImportSettings.convexDecomposer.vHACD : ImportSettings.convexDecomposer.unity,
};
GameObject robotObject = null;
try
{
DebugText.text = $"Loading URDF from: {urdfFilePath}";
robotObject = UrdfRobotExtensions.CreateRuntime(urdfFilePath, settings);
DebugText.text = "12 - Robot creation completed";
}
catch (System.Exception ex)
{
Debug.LogError("Error during URDF creation: " + ex.Message);
//DebugText.text = "Error during URDF creation: " + ex.Message;
isLoading = false;
yield break;
}
if (robotObject != null && robotObject.transform != null)
{
robotObject.transform.SetParent(transform);
SetControllerParameters(robotObject);
Debug.Log("Successfully Loaded URDF: " + robotObject.name);
}
currentRobot = robotObject;
isLoading = false;
}
void SetControllerParameters(GameObject robot)
{
robot.GetComponent<UrdfRobot>().SetRigidbodiesUseGravity();
if (robot.TryGetComponent<Controller>(out Controller controller))
{
controller.stiffness = 10000;
controller.damping = 100;
controller.forceLimit = 10;
controller.speed = 30;
controller.acceleration = 10;
controller.enabled = true;
}
if (setImmovableLink)
{
Transform baseNode = robot.transform.GetChild(robot.transform.childCount - 1);
if (baseNode)
{
ArticulationBody baseNodeAB = baseNode.GetComponent<ArticulationBody>();
if (baseNodeAB == null)
{
baseNodeAB = baseNode.gameObject.AddComponent<ArticulationBody>();
}
baseNodeAB.immovable = true;
}
else
{
Debug.LogWarning($"The specified immovable link was not found in the robot hierarchy.");
}
}
}
public void LoadModel()
{
StartCoroutine(LoadUrdf());
}
}
I am using this script and it works in the editor to download and load the URDF models at runtime. Hope this helps
Does the current importer support importing urdf with code? i.e. is there a function I can call in a script that can just import the urdf? I am currently working on interfacing Unity to a Python-based scenario description language and would like to be able to rapidly spawn/delete robots across scenes directly from code without the user having to touch the editor. Thank you so much!