ZED360 crashing and not showing skeletal data

Hi there

Attempting to setup two cameras with 360 fusion.

Two ZED2i with jetsons xavier JETSON_L4T=35.4.1 over the network with SDK 5.1.2 running 360 senders.
Receiver running ZED360 on win 11 SDK 5.1.2 CUDA 13.

Sometimes zed360 just crashes when trying to setup the room. Sometimes it does not and adds both cameras in one spot. See attached image. When in calibration it does not show any bodies detected or moving and calibration saves no data.

these are snippets of the code with parameters on the senders:

InitParameters init_parameters;
init_parameters.camera_resolution = sl::RESOLUTION::HD720;
init_parameters.camera_fps = 30;
init_parameters.depth_mode = sl::DEPTH_MODE::NEURAL_LIGHT;
init_parameters.coordinate_system = sl::COORDINATE_SYSTEM::RIGHT_HANDED_Y_UP;
init_parameters.sdk_verbose = 1;

PositionalTrackingParameters positional_tracking_parameters;
positional_tracking_parameters.set_as_static = true;

BodyTrackingParameters body_traking_parameters;
body_traking_parameters.enable_tracking = false;
body_traking_parameters.enable_body_fitting = false;
body_traking_parameters.body_format = sl::BODY_FORMAT::BODY_18;
body_traking_parameters.detection_model = BODY_TRACKING_MODEL::HUMAN_BODY_FAST;

BodyTrackingRuntimeParameters body_tracking_rt;
body_tracking_rt.detection_confidence_threshold = 40;
body_tracking_rt.skeleton_smoothing = 0.7;

CommunicationParameters configuration;
returned_state = zed.startPublishing(configuration);

grab is in the main loop

Both senders are adding receiver:
[RTPSession\] Adding Receiver with IP: 10.30.30.141 ID 187110364

Am I missing any crucial parameters on senders? Also is there a log or a way to see zed360 app log to see what is happening?

Last question does zed360 handle time sync of both jetsons or that has to be done as per your documentation Setting Up Multiple 3D Cameras - Stereolabs is this the missing bit in this chain?

Hi,

You should at least see the raw skeletons in 360 even if the calibration fails…

Can you first double check the senders are actually detecting someone? You can simply add a print in the main loop displaying the number of detections.

Your main loop should look like that :

    Bodies bodies;
    while (true) {
        // Grab images
        auto err = zed.grab();
        if (err == ERROR_CODE::SUCCESS) {
            // Retrieve Detected Human Bodies
            zed.retrieveBodies(bodies, body_tracker_parameters_rt);
            std::cout << "Nb of detections : " << bodies.body_list.size() << std::endl;
        } 
    }

Hi there,

I can confirm that senders are detecting and getting body count.

I have made two identical senders C++ and Python. From many tests, python senders do not crash ZED360, both adding the receiver. But all I can see is two cameras added to the ZED360 scene, no skeletons are showing, cameras are slightly moving around the scene.

C++ version senders are running, but when adding them in ZED360 sometimes only one sender gets added or second sender is added a second later and this is when ZED360 just crashes. C++ route is almost impossible to add senders. Python feel much more solid.

Also, what is important is to use configuration.set_for_local_network(port, ip) on each sender if this is not added ZED360 will never add senders and will always crash. Your sample code does not have this added.

Not sure what more can be debugged on my end. Can you please confirm that you can successfully setup this workflow from scratch on your end (2 jetsons via network with a PC receiver running ZED360) with latest SDK.

To add Jetsons running same SDK as PC 5.1.2 but Jetson’s CUDA is 11.4.315 as this is latest can run on Xaviers with Jetpack 5.1.2.

Thanks

Quick update.

Upgraded to SDK 5.2, on jetsons and PC running ZED360

ZED360 terminal outputs “WRONG BODY FORMAT”

I have tried all combinations on senders .18 .34 .38, also different combinations of BODY_TRACKING_MODEL

On ZED 360 all possible body model combinations.

Both Senders output Adding Receiver with IP: 10.30.20.141 ID 1551339472

This is ZED360 output:

Camera “{“input”:{“fusion”:{“configuration”:{“ip”:“10.30.20.95”,“port”:31950},“type”:“LOCAL_NETWORK”},“zed”:{“configuration”:“1”}},“world”:{“rotation”:[0.0,0.0,0.0],“translation”:[0.0,0.0,0.0]}}”
Camera “{“input”:{“fusion”:{“configuration”:{“ip”:“10.30.20.98”,“port”:31980},“type”:“LOCAL_NETWORK”},“zed”:{“configuration”:“2”}},“world”:{“rotation”:[0.0,0.0,0.0],“translation”:[0.0,0.0,0.0]}}”
Running the fusion for 2 devices.
INIT FUSION
START RUN FUSION
enableSK
ERROR : WRONG BODY FORMAT
STOP RUN FUSION

So still failing to get skeletons on ZED360, any clue to why this workflow not working for us?

This error appears when both senders are using different formats.
I doubt that’s what’s happening here, but can you double check this is not the case?

If not, I’ll try to reproduce your issue at the office.

Best,

Hi,

We have recently been experiencing the same issue. Based on the information shared in the thread Framerate issue when using the Fusion Network Workflow , we performed some tests on our side.

With the same setup, ZED360 reporting WRONG BODY FORMAT error when running with SDK 5.1 & 5.2, while SDK 5.0 works correctly.

Our project requires multi-camera Body Tracking and Object Detection. According to SDK 5.1 release notes, the fllowing feature was introduced:

Added support for object detection streaming from sl::Cameratosl::Fusion in the network configuration.

Additionally, based on the FPS issues discussed in the thread mentioned above, it seems we will likely need SDK5.1+ for our project.

So we would like to ask if there has been any update, fix or recommended workaround for this issue?

Here is some additional information about our setup:

We have two Zed Mini Box [JetPack: 6.1 (nvidia-jetpack 6.1+b123) L4T: 36.4.4 Ubuntu: 22.04] each having two Zed X connected.

Thanks

Hi, adding a third reproduction of this bug so it doesn’t look like a one-off. Same ERROR : WRONG BODY FORMAT in ZED360 as @Hedgehog and @ZavierL, with identical body formats on both senders.

Machine and camera setup

Two publisher hosts, each a ZED Box Orin NX running JetPack 6.0, on the same LAN as the receiver.

  • Publisher A: two ZED X One monos used as a virtual stereo rig. Using the new SDK for local virtual cam setup without streaming.
  • Publisher B: same rig type, same Python sender code.
  • Receiver: separate host on the same LAN, running ZED360 on Linux and, for cross-checking, a minimal Python sl.Fusion subscriber.

SDK version

ZED SDK 5.2.2 on both ZED Box Orin NX publishers and on the receiver host.

Sender-side code (publisher)

Identical Python on both boxes, only the serial / input type differs.

"""
Minimal headless body tracking sender for ZED Fusion.

This sender is designed to behave like a virtual sensor:
- it publishes raw body detections for Fusion over the local network,
- it keeps virtual stereo support for ZED X One left/right pairs,
- it keeps depth-related init settings from the existing headless sender,
- and uses body tracking/runtime parameters from the Fusion C++ reference.
"""

import argparse
import os
import signal

import pyzed.sl as sl


def _setup_virtual_stereo(init, left_serial, right_serial):
    stereo_serial = sl.generate_virtual_stereo_serial_number(left_serial, right_serial)
    if stereo_serial == 0:
        raise RuntimeError(
            "Failed to generate a virtual stereo serial number. "
            "Check that left/right serials are different and valid."
        )

    input_type = sl.InputType()
    if not hasattr(input_type, "set_virtual_stereo_from_serial_numbers"):
        raise RuntimeError(
            "This pyzed runtime does not support virtual stereo APIs on InputType. "
            "Please upgrade the installed ZED SDK Python package."
        )

    err = input_type.set_virtual_stereo_from_serial_numbers(left_serial, right_serial, stereo_serial)
    if err:
        raise RuntimeError(
            "set_virtual_stereo_from_serial_numbers failed for left={}, right={}, virtual={}".format(
                left_serial,
                right_serial,
                stereo_serial,
            )
        )

    init.input = input_type
    print(
        "[Sample] Using virtual stereo from ZED X One pair: left={}, right={}, virtual={}".format(
            left_serial,
            right_serial,
            stereo_serial,
        )
    )


def _parse_source_args(init, opt):
    if opt.leftsn is not None and opt.rightsn is not None:
        _setup_virtual_stereo(init, opt.leftsn, opt.rightsn)

    if len(opt.input_svo_file) > 0 and opt.input_svo_file.endswith((".svo", ".svo2")):
        init.set_from_svo_file(opt.input_svo_file)
        print("[Sample] Using SVO File input: {}".format(opt.input_svo_file))
    elif len(opt.ip_address) > 0:
        ip_str = opt.ip_address
        if ip_str.replace(":", "").replace(".", "").isdigit() and len(ip_str.split(".")) == 4 and len(ip_str.split(":")) == 2:
            init.set_from_stream(ip_str.split(":")[0], int(ip_str.split(":")[1]))
            print("[Sample] Using Stream input, IP : {}".format(ip_str))
        elif ip_str.replace(":", "").replace(".", "").isdigit() and len(ip_str.split(".")) == 4:
            init.set_from_stream(ip_str)
            print("[Sample] Using Stream input, IP : {}".format(ip_str))
        else:
            print("Invalid IP format. Using live stream")

    init.camera_resolution = sl.RESOLUTION.HD1080
    print("[Sample] Forcing Camera resolution HD1080")


def _is_jetson_platform():
    return os.path.exists("/etc/nv_tegra_release")


def main(opt):
    print("Running Body Tracking Fusion Sender (headless) ... Press Ctrl+C to quit")

    zed = sl.Camera()

    init_params = sl.InitParameters()
    init_params.camera_resolution = sl.RESOLUTION.HD1080
    init_params.camera_fps = 30
    init_params.coordinate_units = sl.UNIT.METER
    init_params.depth_mode = sl.DEPTH_MODE.NEURAL
    init_params.coordinate_system = sl.COORDINATE_SYSTEM.RIGHT_HANDED_Y_UP
    init_params.depth_maximum_distance = 15.0
    init_params.depth_minimum_distance = 1.5
    init_params.depth_stabilization = 40

    _parse_source_args(init_params, opt)

    err = zed.open(init_params)
    if err != sl.ERROR_CODE.SUCCESS:
        print("Camera open failed: {}".format(err))
        zed.close()
        return 1

    camera_info = zed.get_camera_information()
    actual_res = camera_info.camera_configuration.resolution
    if actual_res.width != 1920 or actual_res.height != 1080:
        print(
            "[Camera] ERROR: Forced HD1080 but SDK opened {}x{}. "
            "Stopping to avoid FOV mismatch.".format(actual_res.width, actual_res.height)
        )
        zed.close()
        return 1

    positional_tracking_parameters = sl.PositionalTrackingParameters()
    err = zed.enable_positional_tracking(positional_tracking_parameters)
    if err != sl.ERROR_CODE.SUCCESS:
        print("Positional tracking failed: {}".format(err))
        zed.close()
        return 1

    body_param = sl.BodyTrackingParameters()
    body_param.enable_tracking = False
    body_param.enable_body_fitting = False
    body_param.body_format = sl.BODY_FORMAT.BODY_18
    body_param.detection_model = sl.BODY_TRACKING_MODEL.HUMAN_BODY_ACCURATE

    err = zed.enable_body_tracking(body_param)
    if err != sl.ERROR_CODE.SUCCESS:
        print("Body tracking failed: {}".format(err))
        zed.disable_positional_tracking()
        zed.close()
        return 1

    body_runtime_param = sl.BodyTrackingRuntimeParameters()
    body_runtime_param.detection_confidence_threshold = 40
    body_runtime_param.skeleton_smoothing = 0.7

    communication_parameters = sl.CommunicationParameters()
    communication_parameters.set_for_local_network(30000)
    err = zed.start_publishing(communication_parameters)
    if err != sl.ERROR_CODE.SUCCESS:
        print("Fusion publishing start failed on port 30000: {}".format(err))
        zed.disable_body_tracking()
        zed.disable_positional_tracking()
        zed.close()
        return 1
    print("[Fusion] Publishing started on local network (port 30000)")

    running = True

    def signal_handler(_sig, _frame):
        nonlocal running
        running = False

    signal.signal(signal.SIGINT, signal_handler)

    bodies = sl.Bodies()
    frame_count = 0
    while running:
        if zed.grab() == sl.ERROR_CODE.SUCCESS:
            zed.retrieve_bodies(bodies, body_runtime_param)
            frame_count += 1
            if frame_count % 30 == 0:
                print("[Frame {:>6d}] Bodies detected: {}".format(frame_count, len(bodies.body_list)))
                print("Sample body skeleton keypoints (first body, if any):", bodies.body_list[0].keypoint if len(bodies.body_list) > 0 else "N/A")

    print("\nShutting down...")
    zed.disable_body_tracking()
    zed.disable_positional_tracking()
    zed.close()
    print("Done.")
    return 0


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--input_svo_file",
        type=str,
        help="Path to an .svo/.svo2 file to replay",
        default="",
    )
    parser.add_argument(
        "--ip_address",
        type=str,
        help="Stream source IP in format a.b.c.d:port or a.b.c.d",
        default="",
    )
    parser.add_argument(
        "--leftsn",
        type=int,
        help="Serial number of the left ZED X One camera",
        default=None,
    )
    parser.add_argument(
        "--rightsn",
        type=int,
        help="Serial number of the right ZED X One camera",
        default=None,
    )
    opt = parser.parse_args()

    has_svo = len(opt.input_svo_file) > 0
    has_ip = len(opt.ip_address) > 0
    has_stereo = opt.leftsn is not None or opt.rightsn is not None

    if sum([has_svo, has_ip, has_stereo]) > 1:
        print("Specify only one of: --input_svo_file, --ip_address, or --leftsn/--rightsn. Exit.")
        raise SystemExit(1)

    if (opt.leftsn is None) != (opt.rightsn is None):
        print("Both --leftsn and --rightsn must be specified together. Exit.")
        raise SystemExit(1)

    raise SystemExit(main(opt))

Extra evidence it is not a sender-side mismatch

We also wrote a minimal Python subscriber using sl.Fusion.subscribe + retrieve_bodies(bodies, rt, uuid) per camera. That subscriber does receive valid per-camera skeletons from both publishers, with synchronised timestamps and SENDER_ERROR_CODE.SUCCESS from get_sender_state.

Would appreciate any ETA or workaround for SDK 5.2.x, since downgrading to 5.0 seems to be not an option for our project (we need the virtual cams, 5.0.x ZED360 is also not compatible with 5.2 senders, based on our experiments). Happy to share full logs or run a reproducer on request.

Thanks.