Trying to understand FusionConfiguration

Hello!

I am trying to understand data contained in FusionConfiguration that is created from the ReadConfigurationFile method. My setup is two cameras ZED2 calibrated with ZED360 app with the 4.1 SDK.
When I check data from script or debug, they don’t seem consistent compared to the json file.

multiSetupZed4_1.json (1.1 KB)

var multiCamConfig = Config.ConfigDirectory + Config.MULTI_CAMERA_FILENAME;
var fusion = new Fusion();
fusion.ReadConfigurationFile(new StringBuilder(multiCamConfig), COORDINATE_SYSTEM.LEFT_HANDED_Y_UP, UNIT.METER, ref configurations, ref nbCameras);

The content of configurations is an array of 20 elements where the three first are:
firstThree

and the seventeen others are:
seventeenOthers

I think there is a problem with the FusionConfiguration class that has an enum INPUT_TYPE inputType attribute but is supposed to have a struct InputType inputType that contain this enum instead.

Hey @VR_Neo,

Thank you for the report, that’s a good catch. We’ll update it soon.

In the meantime, you can fix it on your side from the sources, the building instructions are on the repo.
You should only have to change INPUT_TYPE to InputType here: zed-csharp-api/Stereolabs.zed/src/ZEDCommon.cs at 80fc742a9c17973778167afeb7d6e17d3938f95e · stereolabs/zed-csharp-api · GitHub

Hello!

Fixing InputType is not enought to make Fusion working, I had to do a lot of minor changes in both C and C# wrapper.
One other important fix is in ZEDFusion.RetrieveBodies method that transmit bodies as ref instead of IntPtr compared to ZEDCamera.RetrieveBodies otherwise there is a Marshall error.

        /// <summary>
        /// retrieves the body data, can be the fused data (default), or the raw data provided by a specific sender
        /// </summary>
        /// <param name="bodies"></param>
        /// <param name="rtparams"></param>
        /// <param name="uuid"></param>
        /// <returns></returns>
        public FUSION_ERROR_CODE RetrieveBodies(ref Bodies bodies, ref BodyTrackingFusionRuntimeParameters rtparams, CameraIdentifier uuid)
        {
            //(Changed by VR) original method is commented, new is based on ZedCamera.RetrieveBodies
            //return dllz_fusion_retrieve_bodies(ref bodies, ref rtparams, uuid);
            
            IntPtr p = Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf<sl.Bodies>());
            sl.FUSION_ERROR_CODE err = dllz_fusion_retrieve_bodies(p, ref rtparams, uuid);

            if (p != IntPtr.Zero)
            {
                bodies = (sl.Bodies)Marshal.PtrToStructure(p, typeof(sl.Bodies));
                Marshal.FreeHGlobal(p);
                return err;
            }
            else
            {
                Marshal.FreeHGlobal(p);
                return sl.FUSION_ERROR_CODE.FAILURE;
            }
        }

I still have a bad result using Fusion.ReadConfigurationFile method but I achieved a functional Multicamera body-tracking by parsing the ZED360 by myself to generate the required FusionConfiguration[ ].

Hello @JPlou,
I’ve faced the same problem.
I’ve managed to parse the json in order to create the right FusionConfiguration[] object.
However I get an error on the line:

FUSION_ERROR_CODE state = fusion.Subscribe(ref uuid, jsonConfigFilename, ref configurations[i].position, ref configurations[i].rotation);

the state value is INVALID_IP_ADDRESS even though I have two zed2 connected via USB on the same pc and the json config “type” is set to “USB_SERIAL” on both cameras.
It seems that I cannot pass the FusionConfiguration[] object to the fusion.Subscribe method, but only the path to the json config filename.

Here’s my json calibration (sorry I cannot upload files):

{
    "21772418": {
        "input": {
            "fusion": {
                "type": "INTRA_PROCESS"
            },
            "zed": {
                "configuration": "21772418",
                "type": "USB_SERIAL"
            }
        },
        "world": {
            "rotation": [
                0.0,
                0.0,
                0.0
            ],
            "translation": [
                0.0,
                -0.6605420112609863,
                0.0
            ]
        }
    },
    "26675215": {
        "input": {
            "fusion": {
                "type": "INTRA_PROCESS"
            },
            "zed": {
                "configuration": "26675215",
                "type": "USB_SERIAL"
            }
        },
        "world": {
            "rotation": [
                0.00506022060289979,
                1.0849298238754272,
                -0.03133285418152809
            ],
            "translation": [
                -0.9777283072471619,
                -0.5663315653800964,
                0.7421109676361084
            ]
        }
    }
}

Hi @JPlou ,
any news about the fix of this issue in the next release?

Hi,

I wanted to let you know that I’m currently working on it, fixing the Fusion API as well as implementing a sample similar to the one available in C++ (and python).

Hi Benjamin!

That’s good news !

My Rider IDE alert me of allocated memory issues in SOH when I’am using fusion.RetrieveBodies method.

This happens using ref or my own IntPtr management as above.
On Windows it provocs my program to crash after few minutes because of “ucrtbase.dll, version 10.0.19041.3636”.

Thanks for the info, I’ll pay attention to that.

I have a question for you as you are an active user of our CSharp wrapper.

I’m considering updating the wrapper to (most likely) .net8.
I’m not an expert but it does not seem to require a lot of changes. Is it something that you (or any other user) might be interested in?
Do you think dropping the support of the current version for .net8 is doable or should we keep both versions?

Thank you for your feedback.

Hi Benjamin,

I don’t know for .net8 because I am using .Net6 (on Jetson with Ubuntu 20.04 and Windows 10 X64) on my project. Anyway having .Net* instead of .NetFramework sounds better to ease wrapper deployment on both platforms.

I can notice that I have built C# wrapper for Windows X64 in .NetFramework4.8 and only difference was to add a constructor to RegionOfInterestParameters in ZEDCommons.cs - line 605. On Jetson I am using mcs compiler.

Ok I’ll consider it then and see if I can fit this task in my backlog for 4.2.

I was thinking about .net 8 because it seems the support for .net6 will end very (.NET and .NET Core official support policy).

Hi @here,

I can finally share an updated version of the csharp wrapper with a working Fusion API (as well as a sample for body tracking fusion).

For now, both the sample and the package are available here : body-tracking-fusion/csharp at master · Bvallon-sl/body-tracking-fusion · GitHub

Note this requires the ZED SDK 4.1.4 that just came out yesterday to work.
The sample is not completely finished, some features available in cpp are not implemented yet.

To use a local Nuget package, please follow the step described in this link : c# - Getting local Nuget Package into Visual Studio Solution - Stack Overflow

Let me know if you find any additional bug or API issues.

Best regards,
Benjamin Vallon

Hi Benjamin!

I don’t see anything about Fusion on Releases notes of downloading SDK page. As you said that we need to upgrade SDK, do you know if there is any change that can impact captation or memory management when retrieving data?

I just updated the nuget package on my repo.
You should not need to use the latest version now.

Actually, if you downloaded the latest SDK Version yesterday, you might want to resintall it again, we just published a hotfix. Sorry for the inconvenience.

You are right, there is no change regarding the Fusion module in this patch, it will perform the same.