> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.stereolabs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.stereolabs.com/_mcp/server.

# Tutorial - Retrieving Sensors Data

This tutorial shows how to retrieve onboard sensor data from ZED 3D cameras: IMU (accelerometer and gyroscope) data on any camera with an integrated IMU (ZED 2/2i, ZED Mini, ZED X family), plus barometer and magnetometer data on ZED 2/2i. The sample loops and retrieves 800 sensor data samples, printing the updated values in the console.

## Getting Started

* First, download the latest version of the [ZED SDK](https://www.stereolabs.com/developers/).
* Download the [Sensor Data](https://github.com/stereolabs/zed-sdk/tree/master/tutorials/tutorial%207%20-%20sensor%20data) sample code in C, C++, Python or C#.

## Code Overview

### Open the camera

As in previous tutorials, we create, configure and open the ZED 3D camera. Since we do not need depth information in this tutorial, we can disable depth capture using `DEPTH_MODE::NONE`.

**`C++`**

```cpp C++
// Create a ZED camera object
Camera zed;

// Set configuration parameters
InitParameters init_parameters;
// No depth computation required here
init_parameters.depth_mode = DEPTH_MODE::NONE;

// Open the camera
ERROR_CODE err = zed.open(init_parameters);
if (err != ERROR_CODE::SUCCESS) {
    cout << "Error " << err << ", exit program.\n";
    return -1;
}
```

**`Python`**

```python Python
# Create a ZED camera object
zed = sl.Camera()

# Set configuration parameters
init_params = sl.InitParameters()
# No depth computation is required here
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)
```

**`C#`**

```csharp C#
// Create a ZED camera object
Camera zed = new Camera(0);

// Set configuration parameters
InitParameters init_params = new InitParameters();
// No depth computation required here
init_params.depthMode = DEPTH_MODE.NONE;

// Open the camera
ERROR_CODE err = zed.Open(ref init_params);
if (err != ERROR_CODE.SUCCESS)
    Environment.Exit(-1);
```

### Capture Sensor Data

The data from the different sensors are accessible with the `SensorsData` class. To retrieve sensor data, use `getSensorsData()` as shown below.

**`C++`**

```cpp C++
SensorsData sensors_data;
while(zed.grab() == ERROR_CODE::SUCCESS){
    zed.getSensorsData(sensors_data, TIME_REFERENCE::CURRENT);
}
```

**`Python`**

```python Python
sensors_data = sl.SensorsData()
while zed.grab() == sl.ERROR_CODE.SUCCESS:
    zed.get_sensors_data(sensors_data, sl.TIME_REFERENCE.CURRENT)
```

**`C#`**

```csharp C#
SensorsData sensors_data = new SensorsData();
RuntimeParameters runtimeParameters = new RuntimeParameters();
while(zed.Grab(ref runtimeParameters) == ERROR_CODE.SUCCESS){
    zed.GetSensorsData(ref sensors_data, TIME_REFERENCE.CURRENT);
}
```

Here we use `TIME_REFERENCE::CURRENT` to extract the most recent data available for each sensor. We can also extract sensor data that was captured at the same time or close to the camera's latest image using `TIME_REFERENCE::IMAGE`.

For more information on reference time, see the [Time Synchronization](/docs/development/zed-sdk/modules/sensors/time-synchronization/) section.

### Update Sensor Data

Since the sensors on the 3D camera have different sampling rates, their data is not updated at the same frequency. To know if a given sensor data has been updated, we compare timestamps that are used as unique identifiers. If they are the same, then the sensor data has not been updated.

In this tutorial, we use a basic class `TimestampHandler` to store timestamps and check for data updates.

**`C++`**

```cpp C++
TimestampHandler ts;
if (ts.isNew(sensors_data.imu)) {
    // sensors_data.imu contains new data
}
```

**`Python`**

```python Python
ts_handler = TimestampHandler()
if ts_handler.is_new(sensors_data.get_imu_data()):
    # sensors_data.get_imu_data() contains new data
    pass
```

**`C#`**

```csharp C#
ulong last_imu_timestamp = 0;
ulong last_magnetometer_timestamp = 0;
ulong last_barometer_timestamp = 0;

if (sensors_data.imu.timestamp > last_imu_timestamp){
    // sensors_data.imu contains new data
    last_imu_timestamp = sensors_data.imu.timestamp;
}
```

If new data is available, we display it in the console:

**`C++`**

```cpp C++
// Check if IMU data has been updated
if (ts.isNew(sensors_data.imu)) {
    cout << "IMU Orientation: {" << sensors_data.imu.pose.getOrientation() << "}";
    cout << "IMU Linear Acceleration: {" << sensors_data.imu.linear_acceleration << "} [m/sec^2]";
    cout << "IMU Angular Velocity: {" << sensors_data.imu.angular_velocity << "} [deg/sec]";
}

// Check if Magnetometer data has been updated
if (ts.isNew(sensors_data.magnetometer)) {
    cout << " Magnetometer Magnetic Field: {" << sensors_data.magnetometer.magnetic_field_calibrated << "} [uT]";
}

// Check if Barometer data has been updated
if (ts.isNew(sensors_data.barometer)) {
    cout << " Barometer Atmospheric pressure:" << sensors_data.barometer.pressure << " [hPa]";
}
```

**`Python`**

```python Python
# Check if IMU data has been updated
if ts_handler.is_new(sensors_data.get_imu_data()):
    quaternion = sensors_data.get_imu_data().get_pose().get_orientation().get()
    print("IMU Orientation: {}".format(quaternion))
    linear_acceleration = sensors_data.get_imu_data().get_linear_acceleration()
    print("IMU Acceleration: {} [m/sec^2]".format(linear_acceleration))
    angular_velocity = sensors_data.get_imu_data().get_angular_velocity()
    print("IMU Angular Velocity: {} [deg/sec]".format(angular_velocity))

# Check if Magnetometer data has been updated
if ts_handler.is_new(sensors_data.get_magnetometer_data()):
    magnetic_field_calibrated = sensors_data.get_magnetometer_data().get_magnetic_field_calibrated()
    print("Magnetometer Magnetic Field: {} [uT]".format(magnetic_field_calibrated))

# Check if Barometer data has been updated 
if ts_handler.is_new(sensors_data.get_barometer_data()):
    pressure = sensors_data.get_barometer_data().pressure
    print("Barometer Atmospheric pressure: {} [hPa]".format(pressure))
```

**`C#`**

```csharp C#
// Check if IMU data has been updated
if (sensors_data.imu.timestamp > last_imu_timestamp){
    Console.WriteLine("IMU Orientation : " + sensors_data.imu.fusedOrientation);
    Console.WriteLine("IMU Linear Acceleration : " + sensors_data.imu.linearAcceleration + " [m/sec^2]");
    Console.WriteLine("IMU Angular Velocity : " + sensors_data.imu.angularVelocity + " [deg/sec]");
    last_imu_timestamp = sensors_data.imu.timestamp;
}
// Check if Magnetometer data has been updated
if (sensors_data.magnetometer.timestamp > last_magnetometer_timestamp){
    Console.WriteLine("Magnetometer Magnetic field : " + sensors_data.magnetometer.magneticField + " [uT]");
    last_magnetometer_timestamp = sensors_data.magnetometer.timestamp;
}
// Check if Barometer data has been updated
if (sensors_data.barometer.timestamp > last_barometer_timestamp){
    Console.WriteLine("Barometer Atmospheric pressure : " + sensors_data.barometer.pressure + " [hPa]");
    last_barometer_timestamp = sensors_data.barometer.timestamp;
}
```

You do not need to check sensor availability based on your 3D camera model. If a sensor is not available on your camera, its data will contain `NAN` values and its timestamp will be `0`.

### Close the camera

Once sensor data has been extracted, don't forget to close the camera before exiting the program.

**`C++`**

```cpp C++
// Close the camera
zed.close();
```

**`Python`**

```python Python
# Close the camera
zed.close()
```

**`C#`**

```csharp C#
// Close the camera
zed.Close();
```