Broken ZED SDK 4.2.5 for IMU data logging

Hi,

I am currently using an NVIDIA Jetson Orin AGX running Jetpack 5.1.2 (CUDA version 11.4) with two ZED-X One cameras. When I executed the example code you provided from this tutorial using SDK version 4.2.5, I noticed that no IMU data was recorded. However, after switching to SDK version 4.2.1, the IMU data was successfully logged in the console.

Unfortunately, I need to continue using SDK version 4.2.5 because the command ZED_Media_Server --cli /path/to/my/configuration/file works properly with this version, whereas it does not work with SDK version 4.2.1.

Could you please advise which SDK version supports both IMU data recording and the ZED_Media_Server --cli /path/to/my/configuration/file command? It is quite frustrating and a little bit annoying that not all functionalities are available in the latest SDK version.

Thanks for your quick reply.

Can you provide more information? Is it not recorded in an SVO file or not streamed by the ZED Media Server?

I guess it is not streamed by the ZED_Media_Server. What I did is:

  1. Starting streaming by executing ZED_Media_Server --cli /path/my/configuration
  2. Using the example code you provided to log the IMU data.

Then I found no IMU data was recorded. But if I switch to ZED SDK version 4.2.1, after starting data streaming (in this case, I must use the GUI to manually configure the virtual camera and start streaming by clicking the button), I can use the SAME code to log the IMU data.

How do you connect to the ZED_Media_Server stream?
Do you use the address127.0.0.1?
If that’s the case, can you use instead the local IP address of the device obtained with hostname -I and let me know if it works in this case?

Yes, I used the address 127.0.0.1. Tomorrow I will try it and let you know since currently I am not in my office. Thanks for your quick support again.

@Myzhar , I tried the local IP address returned by hostname -I. It didn’t work either. Any solutions about it?

The error messages are like:

[2025-02-27 09:01:55 UTC][ZED][INFO] Logging level INFO
[2025-02-27 09:01:55 UTC][ZED][INFO] Logging level INFO
[2025-02-27 09:01:55 UTC][ZED][INFO] Logging level INFO
[Streaming] Warning : receiving port 34000 is not available (already used)... switching to port 34002. Retrying...
[Streaming] No backward compatibility required.
[Streaming] Warning: Corrupted frame chunk received (recv: 196 / expect 16016)  from ip : 134.61.67.50 at ts 1740646916124(ms)
Opening in BLOCKING MODE 
NvMMLiteOpen : Block : BlockType = 279 
NvMMLiteBlockCreate : Block : BlockType = 279 
[2025-02-27 09:01:56 UTC][ZED][INFO] [Init]  Depth mode: NONE
[2025-02-27 09:01:56 UTC][ZED][INFO] [Init]  Serial Number: S/N 102246514
[2025-02-27 09:01:57 UTC][ZED][WARNING] [Init]  Self-calibration failed. Point the camera towards a more textured and brighter area. Avoid objects closer than 1 meter (Error code: 0x01) 
Camera Model: Virtual ZED-X
Serial Number: 102246514
Camera Firmware: 1523
Sensors Firmware: 0

The code snippet is like:

def main():
    # Create a Camera object
    zed = sl.Camera()

    init_params = sl.InitParameters()
    # init_params.set_from_stream("127.0.0.1", 34000)
    init_params.set_from_stream("134.61.67.50", 34000)
    init_params.depth_mode = sl.DEPTH_MODE.NONE

    # Open the camera
    err = zed.open(init_params)
    if err != sl.ERROR_CODE.SUCCESS :
        print(repr(err))
        zed.close()
        exit(1)

    # Get camera information sensors_data
    info = zed.get_camera_information()

    cam_model = info.camera_model
    if cam_model == sl.MODEL.ZED :
        print("This tutorial only supports ZED-M and ZED2 camera models, ZED does not have additional sensors")
        exit(1)

    # Display camera information (model,S/N, fw version)
    print("Camera Model: " + str(cam_model))
    print("Serial Number: " + str(info.serial_number))
    print("Camera Firmware: " + str(info.camera_configuration.firmware_version))
    print("Sensors Firmware: " + str(info.sensors_configuration.firmware_version))

    # # Display sensors parameters (imu,barometer,magnetometer)
    # printSensorParameters(info.sensors_configuration.accelerometer_parameters) # accelerometer configuration
    # printSensorParameters(info.sensors_configuration.gyroscope_parameters) # gyroscope configuration
    # printSensorParameters(info.sensors_configuration.magnetometer_parameters) # magnetometer configuration
    # printSensorParameters(info.sensors_configuration.barometer_parameters) # barometer configuration
    
    # Used to store the sensors timestamp to know if the sensors_data is a new one or not
    ts_handler = TimestampHandler()

    # Get Sensor Data for 5 seconds
    sensors_data = sl.SensorsData()
    # print(zed.get_sensors_data(sensors_data, sl.TIME_REFERENCE.CURRENT))
    # print(sensors_data.get_imu_data().get_pose().get_orientation().get())
    time_0 = time.time() 
    while time.time()-time_0 < 1 :
        # retrieve the current sensors sensors_data
        # Depending on your Camera model or its firmware, differents sensors are presents.
        # They do not run at the same rate: Therefore, to do not miss samples we iterate as fast as we can and compare timestamp to know when a sensors_data is a new one
        # NOTE: There is no need to acquire images with grab() function. Sensors sensors_data are running in a separated internal capture thread.
        if zed.get_sensors_data(sensors_data, sl.TIME_REFERENCE.CURRENT) == sl.ERROR_CODE.SUCCESS :
            # Check if the data has been updated since the last time
            # IMU is the sensor with the highest rate
            if ts_handler.is_new(sensors_data.get_imu_data()):

                print(" - IMU:")
                # Filtered orientation quaternion
                quaternion = sensors_data.get_imu_data().get_pose().get_orientation().get()
                print(" \t Orientation: [ Ox: {0}, Oy: {1}, Oz {2}, Ow: {3} ]".format(quaternion[0], quaternion[1], quaternion[2], quaternion[3]))
                
                # linear acceleration
                linear_acceleration = sensors_data.get_imu_data().get_linear_acceleration()
                print(" \t Acceleration: [ {0} {1} {2} ] [m/sec^2]".format(linear_acceleration[0], linear_acceleration[1], linear_acceleration[2]))

                # angular velocities
                angular_velocity = sensors_data.get_imu_data().get_angular_velocity()
                print(" \t Angular Velocities: [ {0} {1} {2} ] [deg/sec]".format(angular_velocity[0], angular_velocity[1], angular_velocity[2]))

                # Check if Magnetometer data has been updated (not the same frequency than IMU)
                if ts_handler.is_new(sensors_data.get_magnetometer_data()):
                    magnetic_field_calibrated = sensors_data.get_magnetometer_data().get_magnetic_field_calibrated()
                    print(" - Magnetometer\n \t Magnetic Field: [ {0} {1} {2} ] [uT]".format(magnetic_field_calibrated[0], magnetic_field_calibrated[1], magnetic_field_calibrated[2]))
                
                # Check if Barometer data has been updated 
                if ts_handler.is_new(sensors_data.get_barometer_data()):
                    magnetic_field_calibrated = sensors_data.get_barometer_data().pressure
                    print(" - Barometer\n \t Atmospheric pressure: {0} [hPa]".format(sensors_data.get_barometer_data().pressure))


    zed.close()
    return 0

I’m trying to replicate the problem

@Myzhar Additionally, I have also found another issue about saving images from the streaming. I used the code snippet below.

i = 0
    image_left = sl.Mat()
    runtime_parameters = sl.RuntimeParameters()
    while i < 5:
        # Grab an image, a RuntimeParameters object must be given to grab()
        if zed.grab(runtime_parameters) == sl.ERROR_CODE.SUCCESS:
            # A new image is available if grab() returns SUCCESS
            zed.retrieve_image(image_left, sl.VIEW.LEFT)
            timestamp = zed.get_timestamp(sl.TIME_REFERENCE.IMAGE).get_nanoseconds()
            image_left.write("{}/{}ZED.png".format(str(folder_path / "left"), timestamp))

            i = i + 1
    zed.close()

The resolution of saved image is correct, but it is just enlarged part of the real image.



I have tested this functionality for both SDK 4.2.1 and 4.2.5. Same wrong results. How can I solve this issue.

This is probably a bad camera calibration problem.
Please try to recalibrate the virtual stereo rig

I replicated the issue and reported it to the SDK Team.
It will be fixed soon.
Meanwhile, I can only advise you to downgrade to v4.2.1.

@Myzhar , I have tried to recalibrate the virtual stereo rig and verified the calibration using the program you provided under this link https://github.com/stereolabs/zedx-one-capture/tree/main/stereo_calibration. Therefore the calibration should be correct. Although it becomes better, I assume that it is still not correct.

Below is the screenshot of the GUI ZED_Media_Server.


The saved left and right images from the data streaming:

It seems that both images are cropped and then enlarged. I guess both saved images are not the original images but the after the distortion correction. Is my guess correct? However, in the OpenCV library, after distortion correction, although the image size stay unchanged, some areas will be black. However, for the saved images, valid areas are kind of enlarged which is not optimal/correct anymore for my application. Are there any ways to get the original images?

ZED Media Server displays the unrectified image, but your sample code gets the rectified images. That is why you have a difference in FoV.

To get the same image, use sl.VIEW.LEFT_UNRECTIFIED instead of sl.VIEW.LEFT

1 Like

Anythings new about this issue? When could it be fixed so that IMU data can be accessed. Since in my case, if I downgraded to v4.2.1, the software ZED_Media_Server can’t be executed with ``–cliflag. In my usecase, the NVIDIA Jetson works in headless mode which requires running the software with–cli` flag in the background.