DynExp
Highly flexible laboratory automation for dynamically changing experiments.
HardwareAdapterPVCam.h
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
9 #pragma once
10 
11 #include "stdafx.h"
12 #include "HardwareAdapter.h"
13 #include "../MetaInstruments/Camera.h"
14 
15 #undef DEPRECATED
17 {
18  #include "../include/PVCam/master.h"
19  #include "../include/PVCam/pvcam.h"
20 }
21 
22 namespace DynExpHardware
23 {
25 
27  {
28  public:
29  PVCamException(std::string Description, const int ErrorCode, const Util::ErrorType Type = Util::ErrorType::Error,
30  const std::source_location Location = std::source_location::current()) noexcept
31  : Exception(std::move(Description), Type, ErrorCode, Location)
32  {}
33  };
34 
36  {
37  public:
39  virtual ~PVCamHardwareAdapterParams() = default;
40 
41  virtual const char* GetParamClassTag() const noexcept override { return "PVCamHardwareAdapterParams"; }
42 
43  Param<TextList> CameraName = { *this, {}, "CameraName", "Camera name",
44  "Name of the PVCam camera to connect with" };
45 
46  private:
47  void ConfigureParamsImpl(dispatch_tag<HardwareAdapterParamsBase>) override final;
49  };
50 
52  {
53  public:
56 
58  virtual ~PVCamHardwareAdapterConfigurator() = default;
59 
60  private:
61  virtual DynExp::ParamsBasePtrType MakeParams(DynExp::ItemIDType ID, const DynExp::DynExpCore& Core) const override { return DynExp::MakeParams<PVCamHardwareAdapterConfigurator>(ID, Core); }
62  };
63 
65  {
74  {
75  private:
76  PVCamInitializer() = default;
78 
79  public:
80  static void Init() { GetInstance(true); }
81  static auto GetIsInitialized() noexcept { return GetInstance().IsInitialized.load(); }
82 
83  // Synchronizes every call to PVCam library from anywhere.
84  static [[nodiscard]] LockType Lock(const std::chrono::milliseconds Timeout = std::chrono::milliseconds(100));
85 
86  private:
87  // Does not throw if MayInit = false.
88  static PVCamInitializer& GetInstance(bool MayInit = false);
89 
90  std::atomic<bool> IsInitialized = false;
91  };
92 
93  public:
96 
97  using TimeType = std::chrono::milliseconds;
98 
99  constexpr static auto Name() noexcept { return "PVCam"; }
100  constexpr static auto Category() noexcept { return "Image Capturing"; }
101  constexpr static auto BytesPerPixel() noexcept { return 2; }
102  static auto Enumerate();
103 
105  virtual ~PVCamHardwareAdapter();
106 
107  virtual std::string GetName() const override { return Name(); }
108  virtual std::string GetCategory() const override { return Category(); }
109 
110  bool IsOpened() const noexcept { return PVCamHandleValid; }
111  auto GetCameraState() const noexcept { return CameraState.load(); }
112  decltype(PVCamSyms::rgn_type::s2) GetImageWidth() const;
113  decltype(PVCamSyms::rgn_type::p2) GetImageHeight() const;
115  auto GetBitDepth() const noexcept { return BitDepth.load(); }
116  auto GetColorMode() const noexcept { return ColorMode.load(); }
117 
120  TimeType GetExposureTime() const;
121  float GetFPS() const;
122 
123  // GetCurrentImage() returns an object move-constructed from the internal data. Subsequent calls to
124  // GetCurrentImage() will return an empty image until a new one has been captured. GetCurrentImageCopy()
125  // instead copies the image first and returns the copy which is more expensive.
128 
129  void SetCameraMode(size_t ID) const;
130  void SetExposureTime(TimeType Time) const;
131 
132  void CaptureSingle() const;
133  void StartCapturing() const;
134  void StopCapturing() const;
135 
136  private:
138  using PVCamEnumType = std::pair<PVCamSyms::int32, std::string>;
139  using PVCamEnumVectorType = std::vector<PVCamEnumType>;
140 
142  {
144  {
145  GainOptionType(PVCamSyms::int16 GainIndex, PVCamSyms::int16 BitDepth)
147 
148  PVCamSyms::int16 GainIndex;
149  PVCamSyms::int16 BitDepth;
150  };
151 
154 
156  PVCamSyms::int16 SpeedIndex;
158  std::vector<GainOptionType> Gains;
159  };
160 
161  static void PV_DECL NewFrameCallback(PVCamSyms::FRAME_INFO* FrameInfo, void* PVCamHardwareAdapterPtr);
162 
163  void Init();
164 
165  void ResetImpl(dispatch_tag<HardwareAdapterBase>) override final;
167 
168  void EnsureReadyStateChild() override final;
169  bool IsReadyChild() const override final;
170  bool IsConnectedChild() const noexcept override final;
171 
172  // Not thread-safe, must be called from function calling AcquireLock().
173  void CheckError(const PVCamSyms::rs_bool Result, bool OnlyLog = false, const std::source_location Location = std::source_location::current()) const;
174 
175  void OpenUnsafe();
176  void CloseUnsafe();
177 
178  void ReserveMemory(const PVCamSyms::uns32 BytesRequired) const;
179  PVCamEnumVectorType ReadPVCamEnumUnsafe(PVCamSyms::uns32 ParamID, std::string ParamName);
180  void SetupSpeedTableUnsafe();
181  void SetCameraModeUnsafe(size_t ID) const;
182  void StartCapturingUnsafe() const;
183  void StopCapturingUnsafe() const;
184  void ReadMinMaxExposureTimeUnsafe() const;
185  void ReadExposureTimeUnsafe() const;
186  void NewFrame(PVCamSyms::FRAME_INFO* FrameInfo) noexcept;
187 
188  static constexpr unsigned int NumFramesInBuffer = 2;
189 
190  mutable std::atomic<CameraStateType> CameraState;
191 
192  std::string CameraName;
197  float CurrentFPS;
198  PVCamSyms::rgn_type Region;
199  mutable std::atomic<PVCamSyms::int16> BitDepth;
200  std::atomic<PVCamSyms::PL_COLOR_MODES> ColorMode;
201 
202  // PVCam library might write to ImageData at any time while capturing except when it calls
203  // callback function NewFrameCallback(). So copy ImageData to CopiedImageData in that function.
204  mutable Util::BlobDataType ImageData;
205  mutable Util::BlobDataType CopiedImageData;
206 
207  std::atomic<bool> PVCamHandleValid;
208  PVCamSyms::int16 PVCamHandle;
209  };
210 }
Implementation of DynExp hardware adapter objects.
PVCamException(std::string Description, const int ErrorCode, const Util::ErrorType Type=Util::ErrorType::Error, const std::source_location Location=std::source_location::current()) noexcept
virtual DynExp::ParamsBasePtrType MakeParams(DynExp::ItemIDType ID, const DynExp::DynExpCore &Core) const override
Override to make derived classes call DynExp::MakeParams with the correct configurator type derived f...
virtual const char * GetParamClassTag() const noexcept override
This function is intended to be overridden once in each derived class returning the name of the respe...
void ConfigureParamsImpl(dispatch_tag< HardwareAdapterParamsBase >) override final
virtual void ConfigureParamsImpl(dispatch_tag< PVCamHardwareAdapterParams >)
PVCamHardwareAdapterParams(DynExp::ItemIDType ID, const DynExp::DynExpCore &Core)
Only one instance of this class is allowed for synchronizing calls to the PVCam library from any PVCa...
static LockType Lock(const std::chrono::milliseconds Timeout=std::chrono::milliseconds(100))
static PVCamInitializer & GetInstance(bool MayInit=false)
constexpr static auto BytesPerPixel() noexcept
static constexpr unsigned int NumFramesInBuffer
virtual std::string GetName() const override
Returns the name of this Object type.
virtual void ResetImpl(dispatch_tag< PVCamHardwareAdapter >)
void ReserveMemory(const PVCamSyms::uns32 BytesRequired) const
virtual std::string GetCategory() const override
Returns the category of this Object type.
PVCamHardwareAdapter(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
bool IsConnectedChild() const noexcept override final
Determines the connection status of the hardware interface.
decltype(PVCamSyms::rgn_type::p2) GetImageHeight() const
Util::BlobDataType GetCurrentImage() const
std::vector< PVCamReadoutOptionType > CameraSpeedTable
PVCamEnumVectorType ReadPVCamEnumUnsafe(PVCamSyms::uns32 ParamID, std::string ParamName)
decltype(PVCamSyms::rgn_type::s2) GetImageWidth() const
void ResetImpl(dispatch_tag< HardwareAdapterBase >) override final
constexpr static auto Category() noexcept
static void PV_DECL NewFrameCallback(PVCamSyms::FRAME_INFO *FrameInfo, void *PVCamHardwareAdapterPtr)
Util::BlobDataType GetCurrentImageCopy() const
std::vector< PVCamEnumType > PVCamEnumVectorType
void NewFrame(PVCamSyms::FRAME_INFO *FrameInfo) noexcept
bool IsReadyChild() const override final
Returns wheter this Object instance is ready (e.g. it is running or connected to a hardware device) a...
std::atomic< PVCamSyms::PL_COLOR_MODES > ColorMode
void EnsureReadyStateChild() override final
Ensures that this Object instance is ready by possibly starting its worker thread or by opening conne...
void CheckError(const PVCamSyms::rs_bool Result, bool OnlyLog=false, const std::source_location Location=std::source_location::current()) const
constexpr static auto Name() noexcept
std::atomic< CameraStateType > CameraState
DynExpInstr::CameraData::CameraModesType GetCameraModes() const
std::atomic< PVCamSyms::int16 > BitDepth
std::pair< PVCamSyms::int32, std::string > PVCamEnumType
CapturingStateType
Type indicating whether the camera is currently capturing images.
Definition: Camera.h:106
std::vector< std::string > CameraModesType
List type containing strings of modes the camera can operate in.
Definition: Camera.h:100
DynExp's core class acts as the interface between the user interface and DynExp's internal data like ...
Definition: DynExpCore.h:127
Defines the base class for a hardware adapter object. Hardware adapters describe interfaces/connectio...
Configurator class for HardwareAdapterBase.
Parameter class for HardwareAdapterBase.
HardwareAdapterParamsBase(ItemIDType ID, const DynExpCore &Core)
Constructs the parameters for a HardwareAdapterBase instance.
const std::thread::id OwnerThreadID
Thread id of the thread which has constructed (and owns) this Object instance.
Definition: Object.h:2302
const ParamsBasePtrType Params
Pointer to the parameter class instance belonging to this Object instance.
Definition: Object.h:2303
Refer to ParamsBase::dispatch_tag.
Definition: Object.h:2018
const ItemIDType ID
ID of the Object this parameter class instance belongs to.
Definition: Object.h:1779
const DynExpCore & Core
Reference to DynExp's core.
Definition: Object.h:1780
Tag for function dispatching mechanism within this class used when derived classes are not intended t...
Definition: Object.h:349
Data type which manages a binary large object. The reserved memory is freed upon destruction.
Definition: Util.h:517
DynExp exceptions are derived from this class. It contains basic information about the cause of the e...
Definition: Exception.h:51
Exception(std::string Description, const ErrorType Type=ErrorType::Error, const int ErrorCode=-1, const std::source_location Location=std::source_location::current()) noexcept
Constructs an exception. Constructor is noexcept, although std::runtime_error() might throw std::bad_...
Definition: Exception.cpp:8
const ErrorType Type
DynExp error type from Util::ErrorType
Definition: Exception.h:105
const int ErrorCode
DynExp error code from DynExpErrorCodes::DynExpErrorCodes
Definition: Exception.h:106
Interface to allow synchronizing the access to derived classes between different threads by providing...
Definition: Util.h:56
std::unique_lock< MutexType > LockType
Definition: Util.h:66
DynExp's hardware namespace contains the implementation of DynExp hardware adapters which extend DynE...
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition: Object.h:1807
size_t ItemIDType
ID type of objects/items managed by DynExp.
DynExp's Util namespace contains commonly used functions and templates as well as extensions to Qt an...
Definition: circularbuf.cpp:7
ErrorType
DynExp's error types
Definition: Exception.h:15
Accumulates include statements to provide a precompiled header.
GainOptionType(PVCamSyms::int16 GainIndex, PVCamSyms::int16 BitDepth)
PVCamReadoutOptionType(PVCamEnumType Port, PVCamSyms::int16 SpeedIndex, float ReadoutFrequency)