siemens / ros-sharp

ROS# is a set of open source software libraries and tools in C# for communicating with ROS from .NET applications, in particular Unity3D
Apache License 2.0
945 stars 364 forks source link

XmlException UrdfImporter #411

Closed rprb93 closed 2 years ago

rprb93 commented 2 years ago

I found a bug!

Here is my bug description: I'm trying to import a URDF from ROS to my Unity workspace, but an XMLExecption happen. When I start the plugin, on the ROS side I saw a WebSocket client connecting. After, an error happened in the Unity terminal reporting:

XmlException: Data at the root level is invalid. Line 1, position 1.

System.Xml.XmlTextReaderImpl.Throw (System.Exception e) (at <1d98d70bb7d8453b80c25aa561fdecd1>:0) System.Xml.XmlTextReaderImpl.Throw (System.String res, System.String arg) (at <1d98d70bb7d8453b80c25aa561fdecd1>:0) System.Xml.XmlTextReaderImpl.Throw (System.String res) (at <1d98d70bb7d8453b80c25aa561fdecd1>:0) System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace () (at <1d98d70bb7d8453b80c25aa561fdecd1>:0) System.Xml.XmlTextReaderImpl.ParseDocumentContent () (at <1d98d70bb7d8453b80c25aa561fdecd1>:0) System.Xml.XmlTextReaderImpl.Read () (at <1d98d70bb7d8453b80c25aa561fdecd1>:0) System.Xml.Linq.XDocument.Load (System.Xml.XmlReader reader, System.Xml.Linq.LoadOptions options) (at <a9ef27d60e3144519c0741b6584ba229>:0) System.Xml.Linq.XDocument.Parse (System.String text, System.Xml.Linq.LoadOptions options) (at <a9ef27d60e3144519c0741b6584ba229>:0) System.Xml.Linq.XDocument.Parse (System.String text) (at <a9ef27d60e3144519c0741b6584ba229>:0) RosSharp.RosBridgeClient.UrdfTransfer.UrdfTransferFromRos.ImportResourceFiles (System.String fileContents) (at <0f423d031f3c48f18d807ebe4816015c>:0) RosSharp.RosBridgeClient.UrdfTransfer.UrdfTransferFromRos+<>c__DisplayClass7_0.<ReceiveRobotDescription>b__0 () (at <0f423d031f3c48f18d807ebe4816015c>:0) System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) (at <437ba245d8404784b9fbab9b439ac908>:0) System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) (at <437ba245d8404784b9fbab9b439ac908>:0) System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) (at <437ba245d8404784b9fbab9b439ac908>:0) System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) (at <437ba245d8404784b9fbab9b439ac908>:0) System.Threading.ThreadHelper.ThreadStart () (at <437ba245d8404784b9fbab9b439ac908>:0) UnityEngine.<>c:<RegisterUECatcher>b__0_0(Object, UnhandledExceptionEventArgs) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Scripting/UnhandledExceptionHandler.bindings.cs:46)

Screenshot 2021-11-09 at 15 35 16

I already try downgrading the ROS# version and the Unity version and didn't solve the problem. Some help? The system already worked in times.

MartinBischoff commented 2 years ago

Hi @rprb93 ,

please let me know if this answer resolves your problem: https://stackoverflow.com/a/27743515

I'm thinking about adding the suggested check to the beginning of the XML import:

string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xml.StartsWith(_byteOrderMarkUtf8))
{
    xml = xml.Remove(0, _byteOrderMarkUtf8.Length);
}
rprb93 commented 2 years ago

Hi @MartinBischoff ,

I saw this suggestion, but I don't know where I need to put these codes.

MartinBischoff commented 2 years ago

Hi @rprb93 the responsible class UrdfTransferFromRos is already mentioned in your error message above. I' suggest to put the code in FormatTextFileContents(). In this method the received file contents is already treated with various fixes before it is actually saved in WriteTextFile().

rprb93 commented 2 years ago

Is it normal Libraries folder are not in Unity Assets? The FormatTextFileContents() are only in Libraries folder.

MartinBischoff commented 2 years ago

Yes. This has been addressed in multiple issues already. Also see README.md As URDF Import is independent of Unity, we put it in the Library VS solution.

rprb93 commented 2 years ago

Nothing changed with the modification.

I put the code in FormatTextFileContents(), resulting in:

private static string FormatTextFileContents(string fileContents)
{
    string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
    if (fileContents.StartsWith(_byteOrderMarkUtf8))
    {
        fileContents = fileContents.Remove(0, _byteOrderMarkUtf8.Length);
    }

    // remove enclosing quotations if existent:
    if (fileContents.Substring(0, 1) == "\"" && fileContents.Substring(fileContents.Length - 1, 1) == "\"")
        fileContents = fileContents.Substring(1, fileContents.Length - 2);

    // replace \" quotation sign by actual quotation:
    fileContents = fileContents.Replace("\\\"", "\"");

    // replace \n newline sign by actual new line:
    return fileContents.Replace("\\n", Environment.NewLine);
}

Compiled without errors and copied the RosBridgeClient.dll to ...\Unity3D\Assets\RosSharp\Plugins\.

rprb93 commented 2 years ago

I solve the problem. It was my mistake in URDF Parameter. The URDF Parameter name need matches in publish launch (ROS side) and in the URDF Transfer plugin (Unity Side).