Program Listing for File DeviceBase.hpp

Return to documentation for file (include/depthai/device/DeviceBase.hpp)

#pragma once

// std
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <vector>

// project
#include "depthai/common/CameraBoardSocket.hpp"
#include "depthai/common/CameraFeatures.hpp"
#include "depthai/common/UsbSpeed.hpp"
#include "depthai/device/CalibrationHandler.hpp"
#include "depthai/device/DeviceGate.hpp"
#include "depthai/device/Version.hpp"
#include "depthai/openvino/OpenVINO.hpp"
#include "depthai/pipeline/PipelineSchema.hpp"
#include "depthai/utility/Pimpl.hpp"
#include "depthai/utility/ProfilingData.hpp"
#include "depthai/xlink/XLinkConnection.hpp"
#include "depthai/xlink/XLinkStream.hpp"

// shared
#include "depthai/common/ChipTemperature.hpp"
#include "depthai/common/ConnectionInterface.hpp"
#include "depthai/common/CpuUsage.hpp"
#include "depthai/common/MemoryInfo.hpp"
#include "depthai/common/StereoPair.hpp"
#include "depthai/device/BoardConfig.hpp"
#include "depthai/device/CrashDump.hpp"
#include "depthai/log/LogLevel.hpp"
#include "depthai/log/LogMessage.hpp"

namespace dai {

// Forward declare Pipeline
class Pipeline;
class PipelineImpl;
class DeviceBase {
    friend class PipelineImpl;  // Needed for reconnections

   public:
    // constants

    static constexpr std::chrono::seconds DEFAULT_SEARCH_TIME{10};
    static constexpr float DEFAULT_SYSTEM_INFORMATION_LOGGING_RATE_HZ{1.0f};
    static constexpr UsbSpeed DEFAULT_USB_SPEED{UsbSpeed::SUPER};
    static constexpr std::chrono::milliseconds DEFAULT_TIMESYNC_PERIOD{5000};
    static constexpr int DEFAULT_TIMESYNC_NUM_SAMPLES{10};
    static constexpr bool DEFAULT_TIMESYNC_RANDOM{true};

    // Structures

    struct Config {
        OpenVINO::Version version = OpenVINO::VERSION_UNIVERSAL;
        BoardConfig board;
        bool nonExclusiveMode = false;
        std::optional<LogLevel> outputLogLevel;
        std::optional<LogLevel> logLevel;
    };

    // static API

    static std::chrono::milliseconds getDefaultSearchTime();

    static std::tuple<bool, DeviceInfo> getAnyAvailableDevice(std::chrono::milliseconds timeout);

    static std::tuple<bool, DeviceInfo> getAnyAvailableDevice();

    static std::tuple<bool, DeviceInfo> getAnyAvailableDevice(std::chrono::milliseconds timeout, std::function<void()> cb);

    static std::tuple<bool, DeviceInfo> getFirstAvailableDevice(bool skipInvalidDevice = true);

    static std::tuple<bool, DeviceInfo> getDeviceById(std::string deviceId);

    static std::vector<DeviceInfo> getAllAvailableDevices();

    static std::vector<DeviceInfo> getAllConnectedDevices();

    static std::vector<std::uint8_t> getEmbeddedDeviceBinary(bool usb2Mode, OpenVINO::Version version = OpenVINO::VERSION_UNIVERSAL);

    static std::vector<std::uint8_t> getEmbeddedDeviceBinary(Config config);

    static ProfilingData getGlobalProfilingData();

    DeviceBase();

    DeviceBase(UsbSpeed maxUsbSpeed);

    DeviceBase(const DeviceInfo& devInfo, UsbSpeed maxUsbSpeed);

    DeviceBase(const DeviceInfo& devInfo, const std::filesystem::path& pathToCmd);

    explicit DeviceBase(Config config);

    DeviceBase(Config config, const DeviceInfo& devInfo);

    explicit DeviceBase(const DeviceInfo& devInfo);

    DeviceBase(std::string nameOrDeviceId);

    DeviceBase(std::string nameOrDeviceId, UsbSpeed maxUsbSpeed);

    DeviceBase(Config config, UsbSpeed maxUsbSpeed);

    DeviceBase(Config config, const std::filesystem::path& pathToCmd);

    DeviceBase(Config config, const DeviceInfo& devInfo, UsbSpeed maxUsbSpeed);

    DeviceBase(Config config, const DeviceInfo& devInfo, const std::filesystem::path& pathToCmd, bool dumpOnly = false);

    virtual ~DeviceBase();

    std::optional<Version> getBootloaderVersion();

    bool isPipelineRunning();

    bool startPipeline(const Pipeline& pipeline);

    void setLogLevel(LogLevel level);

    void setNodeLogLevel(int64_t id, LogLevel level);

    LogLevel getLogLevel();

    LogLevel getNodeLogLevel(int64_t id);

    void setXLinkChunkSize(int sizeBytes);

    int getXLinkChunkSize();

    DeviceInfo getDeviceInfo() const;

    std::string getDeviceName();

    std::string getProductName();

    [[deprecated("Use getDeviceId() instead")]] std::string getMxId();

    std::string getDeviceId();

    void setLogOutputLevel(LogLevel level);

    LogLevel getLogOutputLevel();

    bool setIrLaserDotProjectorIntensity(float intensity, int mask = -1);

    bool setIrFloodLightIntensity(float intensity, int mask = -1);

    std::vector<std::tuple<std::string, int, int>> getIrDrivers();

    dai::CrashDump getCrashDump(bool clearCrashDump = true);

    bool hasCrashDump();

    ProfilingData getProfilingData();

    int addLogCallback(std::function<void(LogMessage)> callback);

    bool removeLogCallback(int callbackId);

    void setSystemInformationLoggingRate(float rateHz);

    float getSystemInformationLoggingRate();

    std::vector<CameraBoardSocket> getConnectedCameras();

    std::vector<ConnectionInterface> getConnectionInterfaces();

    std::vector<CameraFeatures> getConnectedCameraFeatures();

    std::vector<StereoPair> getStereoPairs();

    std::vector<StereoPair> getAvailableStereoPairs();

    std::unordered_map<CameraBoardSocket, std::string> getCameraSensorNames();

    std::string getConnectedIMU();

    dai::Version getIMUFirmwareVersion();

    dai::Version getEmbeddedIMUFirmwareVersion();

    bool startIMUFirmwareUpdate(bool forceUpdate = false);

    std::tuple<bool, float> getIMUFirmwareUpdateStatus();

    MemoryInfo getDdrMemoryUsage();

    MemoryInfo getCmxMemoryUsage();

    MemoryInfo getLeonCssHeapUsage();

    MemoryInfo getLeonMssHeapUsage();

    ChipTemperature getChipTemperature();

    CpuUsage getLeonCssCpuUsage();

    CpuUsage getLeonMssCpuUsage();

    int64_t getProcessMemoryUsage();

    bool isEepromAvailable();

    bool tryFlashCalibration(CalibrationHandler calibrationDataHandler);

    void flashCalibration(CalibrationHandler calibrationDataHandler);

    void setCalibration(CalibrationHandler calibrationDataHandler);

    CalibrationHandler getCalibration();

    CalibrationHandler readCalibration();

    CalibrationHandler readCalibration2();

    CalibrationHandler readCalibrationOrDefault();

    void factoryResetCalibration();

    void flashFactoryCalibration(CalibrationHandler calibrationHandler);

    void flashEepromClear();

    void flashFactoryEepromClear();

    CalibrationHandler readFactoryCalibration();

    CalibrationHandler readFactoryCalibrationOrDefault();

    std::vector<std::uint8_t> readCalibrationRaw();

    std::vector<std::uint8_t> readFactoryCalibrationRaw();

    UsbSpeed getUsbSpeed();

    void setTimesync(std::chrono::milliseconds period, int numSamples, bool random);

    void setTimesync(bool enable);

    void close();

    bool isClosed() const;

    void crashDevice();

    std::shared_ptr<XLinkConnection> getConnection() {
        return connection;
    }

    std::shared_ptr<const XLinkConnection> getConnection() const {
        return connection;
    }
    enum class ReconnectionStatus { RECONNECTED, RECONNECTING, RECONNECT_FAILED };
    void setMaxReconnectionAttempts(int maxAttempts, std::function<void(ReconnectionStatus)> callBack = nullptr);

   protected:
    std::shared_ptr<XLinkConnection> connection;

    void tryStartPipeline(const Pipeline& pipeline);

    virtual bool startPipelineImpl(const Pipeline& pipeline);

    virtual void closeImpl();

   protected:
    // protected functions
    void init();
    void init(const std::filesystem::path& pathToCmd);
    void init(UsbSpeed maxUsbSpeed);
    void init(UsbSpeed maxUsbSpeed, const std::filesystem::path& pathToMvcmd);
    void init(const Pipeline& pipeline);
    void init(const Pipeline& pipeline, UsbSpeed maxUsbSpeed);
    void init(const Pipeline& pipeline, const std::filesystem::path& pathToCmd);
    void init(const Pipeline& pipeline, const DeviceInfo& devInfo);
    void init(const Pipeline& pipeline, const DeviceInfo& devInfo, bool usb2Mode);
    void init(const Pipeline& pipeline, const DeviceInfo& devInfo, UsbSpeed maxUsbSpeed);
    void init(const Pipeline& pipeline, const DeviceInfo& devInfo, const std::filesystem::path& pathToCmd);
    void init(const Pipeline& pipeline, UsbSpeed maxUsbSpeed, const std::filesystem::path& pathToMvcmd);
    void init(Config config, UsbSpeed maxUsbSpeed, const std::filesystem::path& pathToMvcmd);
    void init(Config config, UsbSpeed maxUsbSpeed);
    void init(Config config, const std::filesystem::path& pathToCmd);
    void init(Config config, const DeviceInfo& devInfo, UsbSpeed maxUsbSpeed);
    void init(Config config, const DeviceInfo& devInfo, const std::filesystem::path& pathToCmd);

   private:
    // private functions
    void init2(Config cfg, const std::filesystem::path& pathToMvcmd, bool hasPipeline, bool reconnect = false);
    void tryGetDevice();
    struct PrevInfo {
        DeviceInfo deviceInfo;
        Config cfg;
        std::filesystem::path pathToMvcmd;
        bool hasPipeline;
    };
    void monitorCallback(std::chrono::milliseconds watchdogTimeout, PrevInfo prev);
    DeviceInfo deviceInfo = {};
    std::optional<Version> bootloaderVersion;

    // Log callback
    int uniqueCallbackId = 0;
    std::mutex logCallbackMapMtx;
    std::unordered_map<int, std::function<void(LogMessage)>> logCallbackMap;

    // Watchdog thread
    std::thread watchdogThread;
    std::atomic<bool> watchdogRunning{true};
    std::condition_variable watchdogCondVar;
    std::mutex watchdogMtx;

    // Timesync thread
    std::thread timesyncThread;
    std::atomic<bool> timesyncRunning{true};

    // Logging thread
    std::thread loggingThread;
    std::atomic<bool> loggingRunning{true};

    // Profiling thread
    std::thread profilingThread;
    std::atomic<bool> profilingRunning{true};

    // Monitor thread
    std::thread monitorThread;
    std::mutex lastWatchdogPingTimeMtx;
    std::chrono::steady_clock::time_point lastWatchdogPingTime;

    // RPC stream
    std::unique_ptr<XLinkStream> rpcStream;

    // DeviceGate connection
    std::unique_ptr<DeviceGate> gate;

    // closed
    mutable std::mutex closedMtx;
    bool closed{false};

    // pimpl
    class Impl;
    Pimpl<Impl> pimpl;

    // Device config
    Config config;

    std::filesystem::path firmwarePath;
    bool dumpOnly = false;

    // Started pipeline
    std::optional<PipelineSchema> pipelineSchema;

    // Reconnection attempts and pointer to reset connections
    int maxReconnectionAttempts = 1;
    std::weak_ptr<PipelineImpl> pipelinePtr;
    bool isClosing = false;  // if true, don't attempt to reconnect
    std::function<void(ReconnectionStatus)> reconnectionCallback = nullptr;
};
}  // namespace dai