fwt_software/include/fgc/IrbgrabApi.h

149 lines
6.8 KiB
C++

#pragma once
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
// 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<const Api> 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