#pragma once #include #include #include #include // The few calls of InfraTec's IRBGRAB SDK (libirbgrab, v4) that the thermal // camera needs, declared here rather than taken from the SDK's own headers: // the SDK is licensed per tower and may not be copied into this repository or // a build image. Everything below was established against the installed SDK // (4.3.44) and a TarisIR mini - see TarisIR-Integration.md in the workspace. // // The library is loaded at run time (dlopen), so the program builds and its // tests run on machines that have never seen the SDK; a tower without it // simply has no thermal camera. namespace fgc::irbgrab { using Handle = size_t; // the SDK's handles are pointer-sized integers using Ret = uint32_t; // Return codes: a type in the top bits, a code below. inline constexpr Ret kTypeOk = 0x10000000; inline constexpr Ret kTypeStatus = 0x20000000; inline constexpr Ret kTypeErr = 0x80000000; inline constexpr Ret kSuccess = kTypeOk | 0x01; inline constexpr Ret kErrNotSupported = kTypeErr | 0x02; inline constexpr Ret kErrNotFound = kTypeErr | 0x03; // Means both "NUC in progress" and "invalid licence". With the licence // installed correctly it was never seen in testing, so when it piles up the // licence is the first suspect. inline constexpr Ret kErrNucOrLicence = 0x80000017; inline bool ok(Ret r) { return r == kSuccess; } // Fixed text buffers the SDK fills. inline constexpr int kCharBuffer = 1024; // What dev_getdata hands out. enum MemObject : int32_t { kMemBitmap32 = 1, kMemIrDigitFrame = 2, // uint16 counts: what is archived kMemTemperatures = 3, // float32 Kelvin: the counts through the LUT, nothing more }; // Parameter ids (dev_getparam / dev_setparam). namespace param { inline constexpr uint32_t kCalibMaxFrameRate = 117; inline constexpr uint32_t kCalibChangeInProgress = 118; inline constexpr uint32_t kCalibCount = 119; inline constexpr uint32_t kCalibActive = 120; inline constexpr uint32_t kCalibName = 121; inline constexpr uint32_t kPollingEnable = 184; // getdata without a callback inline constexpr uint32_t kSearchString = 202; inline constexpr uint32_t kCameraName = 203; inline constexpr uint32_t kCameraSerialNum = 211; inline constexpr uint32_t kCameraTempHousing = 217; // Kelvin inline constexpr uint32_t kFramerateHz = 240; inline constexpr uint32_t kFrameWidth = 294; inline constexpr uint32_t kFrameHeight = 295; // Non-uniformity correction, done in the camera with its own shutter. inline constexpr uint32_t kNucActive = 410; // R bool: correction applied inline constexpr uint32_t kNucPerform = 411; // W Int2 {mode, flags}: run one now inline constexpr uint32_t kNucInProgress = 412; // R bool inline constexpr uint32_t kNucInterval = 415; // R/W s between automatic ones, 0 = off } // namespace param // kNucPerform's mode (Int2::value1); value2 takes flags, 0 for none. inline constexpr int32_t kNucMode1Point = 2; #pragma pack(push, 1) struct String { char* text; int32_t len; }; struct IdxString { int32_t index; String value; }; struct IdxInt32 { int32_t index; int32_t value; }; struct Int2 { int32_t value1; int32_t value2; }; // Per-frame information (mem_getinfo). struct_size must be set before the call. struct MemInfo { int32_t struct_size; int32_t triggered; double timestamp_ms; // since the grab started int64_t image_num; int32_t missed_packets; }; #pragma pack(pop) // Data type tokens: base type | extension | size of what the pointer points at. inline constexpr uint32_t kBaseInt32 = 0x40000000; inline constexpr uint32_t kBaseInt64 = 0x50000000; inline constexpr uint32_t kBaseFloat32 = 0xA0000000; inline constexpr uint32_t kBaseString = 0xF0000000; inline constexpr uint32_t kExIndex = 0x01000000; inline constexpr uint32_t kExArray2 = 0x02020000; // a pair inline constexpr uint32_t kTypeInt32 = kBaseInt32 | sizeof(int32_t); inline constexpr uint32_t kTypeInt64 = kBaseInt64 | sizeof(int64_t); inline constexpr uint32_t kTypeSingle = kBaseFloat32 | sizeof(float); inline constexpr uint32_t kTypeString = kBaseString | sizeof(String); inline constexpr uint32_t kTypeIdxString = kExIndex | kBaseString | sizeof(IdxString); inline constexpr uint32_t kTypeIdxInt32 = kExIndex | kBaseInt32 | sizeof(IdxInt32); inline constexpr uint32_t kType2Int32 = kExArray2 | kBaseInt32 | sizeof(Int2); // The entry points, as function pointers so a test can stand in for the SDK. struct Api { Ret (*dll_init)() = nullptr; void (*dll_uninit)() = nullptr; Ret (*dll_version)(char* buf, int len) = nullptr; Ret (*dll_devicetypenames)(char* buf, int len) = nullptr; // ';'-separated Ret (*dev_create)(Handle* dev, int32_t type, char* ini) = nullptr; Ret (*dev_free)(Handle* dev) = nullptr; Ret (*dev_search)(Handle dev, int32_t* count) = nullptr; Ret (*dev_connect)(Handle dev, char* search) = nullptr; Ret (*dev_disconnect)(Handle dev) = nullptr; Ret (*dev_startgrab)(Handle dev, int32_t stream) = nullptr; Ret (*dev_stopgrab)(Handle dev, int32_t stream) = nullptr; Ret (*dev_getparam)(Handle dev, uint32_t what, void* data, uint32_t type) = nullptr; Ret (*dev_setparam)(Handle dev, uint32_t what, void* data, uint32_t type) = nullptr; Ret (*dev_getdata)(Handle dev, int32_t what, Handle* mem) = nullptr; Ret (*mem_free)(Handle* mem) = nullptr; Ret (*mem_getdimension)(Handle mem, uint32_t* w, uint32_t* h, uint32_t* type) = nullptr; Ret (*mem_getdataptr)(Handle mem, Handle* data, int32_t* bytes) = nullptr; Ret (*mem_getinfo)(Handle mem, void* info) = nullptr; // The counts-to-Kelvin table (65536 floats) for the given emissivity, // transmission, environment and path temperature. Ret (*mem_getdvlut)(Handle mem, void* lut, float eps, float tau, float t_env, float t_path) = nullptr; }; // Load the SDK. RTLD_GLOBAL, because the camera plugins it loads in dll_init() // resolve their symbols against it; without it no device type registers. The // library stays loaded for the life of the process. nullptr, with `error` set, // if the library or one of its entry points is missing. std::shared_ptr load(const std::string& library, std::string& error); // "0x80000017 (NUC in progress or invalid licence)", for logs. std::string describe(Ret r); } // namespace fgc::irbgrab