ifw-fgf 2.0.0
 
Loading...
Searching...
No Matches
commAdapter.hpp
Go to the documentation of this file.
1
6
7#ifndef DCS_ANDOR_LIB_COM_ADPT_HPP_H_
8#define DCS_ANDOR_LIB_COM_ADPT_HPP_H_
9
10#include <stdint.h>
11#include <vector>
12#include <cstdint>
13#include <type_traits>
14#include "atcore.h"
15
16
26
27
28typedef std::unique_ptr<AT_U8[]> image_t;
29
30// Define a helper type trait to check if a type is in a list of types
31template<typename T, typename... Types>
32struct is_any_of;
33
34template<typename T>
35struct is_any_of<T> : std::false_type {};
36
37template<typename T, typename U, typename... Types>
38struct is_any_of<T, U, Types...> : std::conditional_t<std::is_same_v<T, U>, std::true_type, is_any_of<T, Types...>> {};
39
40
41namespace ifw::fgf::andor {
42
43class Config;
44
45
46const double CONNECT_TIMEOUT = 10.0;
47const double FRAME_REC_THR_SLEEP_TIME = 0.0005;
48const uint16_t MAX_NB_OF_RECEP_BUFFERS = 10;
49const uint16_t NB_OF_INPUT_BUFFERS = 5;
50const int32_t DEFAULT_PACKET_SIZE = 1500;
51const uint32_t STREAM_BYTES_PER_SECOND_MIN = 1000000;
52const uint32_t STREAM_BYTES_PER_SECOND_MAX = 248000000; // 12400000;
53const int TIMEOUTMS = 30000;
54const short RPC_SUCCESS = 0;
55const short RPC_ERROR = -1;
56const short FEATURE_ERROR = -5;
57const AT_64 ALIGNMENT = 16;
58constexpr const char* BALOR_TYPE = "Balor";
59constexpr const char* MARANA_TYPE = "Marana";
60constexpr const char* SIM_TYPE = "Andor SimCam";
61constexpr const char* CAMERA_INTERFACE = "CoaXPress";
64 BALOR = 1,
65 MARANA = 2,
66 SIM = 3
67};
68
69
70enum RpcError: short {
72};
73
75// struct RtmsNetworkConfig is in the publisher header, used transitively.
76
77
80
100 std::size_t operator()(const AndorCtrlEnumKey& key) const {
101 return std::visit([](auto&& arg) -> std::size_t {
102 return std::hash<std::underlying_type_t<std::decay_t<decltype(arg)>>>()(static_cast<std::underlying_type_t<std::decay_t<decltype(arg)>>>(arg));
103 }, key);
104 }
105 };
106
111
113 std::size_t operator()(const AndorStatEnumKey& key) const {
114 return std::visit([](auto&& arg) -> std::size_t {
115 return std::hash<std::underlying_type_t<std::decay_t<decltype(arg)>>>()(static_cast<std::underlying_type_t<std::decay_t<decltype(arg)>>>(arg));
116 }, key);
117 }
118 };
119
130public:
131
132 // Method that returns an error string given an error code
133 // Surprisingly, the Andor SDK does not have a function for this.
134 static std::string getErrorMessage(int errorCode) {
135 auto it = enumerated_errors.find(errorCode);
136 if (it != enumerated_errors.end()) {
137 return it->second;
138 }
139 return "Unknown error"; // Default for unknown error codes
140 }
141
142
151 CommAdapter(const RtmsNetworkConfig& rtms_cfg,
152 std::string_view config_filename = "",
153 bool compute_latency = false,
154 const PublisherThreadConfig& thread_cfg = PublisherThreadConfig());
155
159 virtual ~CommAdapter();
160
164 virtual void Initialise();
165
171 virtual void CheckConnection(bool& connected);
172
176 virtual void Connect();
177
181 virtual void Disconnect();
182
188 virtual bool IsConnected() const;
189
195 virtual void Read(ifw::fgf::common::VectorVariant& params) const override;
196
202 virtual void Read(ifw::fgf::common::PairVariant& param) const override;
203
209 virtual void Write(const ifw::fgf::common::VectorVariant& params) override;
210
216 virtual void Write(const ifw::fgf::common::PairVariant& param) override;
217
223 virtual short Start() override;
224
230 virtual short Stop() override;
231
237 virtual short Init();
238
239 virtual std::string GetLoggers();
240
241 virtual short SetLogLevel(std::string& level, std::string& logger);
242
248 virtual short Reset() override;
249
250
256 virtual short Setup() ;
257
258private:
259
263 virtual void Run();
264
268 virtual void Monitor();
269
273 void StartAcqThread();
274
278 void StartMonThread();
279
283 void StopAcqThread();
284
288 void StopMonThread();
289
295 short SetupAcquisition();
296
297
298 int SetupFeatures();
299 int ReadFeatures();
306 void SetSetupParam(ifw::fgf::andor::AndorCtrlEnumKey key, const ifw::fgf::common::Variant& value);
307
314 void GetStatusParam(ifw::fgf::andor::AndorStatEnumKey key, ifw::fgf::common::Variant& value) const;
315
316
317
321 void WaitForInitialisation();
322
326 void GetCameraInfo();
327
331 void GetCameraStatus();
332
336 void StartAcquisition();
337
343 void WaitForEmptyQueue(const int timeout_ms) const;
344
352 template<typename T>
353 typename std::enable_if<is_any_of<T, bool, int, double, long long>::value, int>::type
354 SetParam(const AT_WC* feature, T value);
355
363 template<typename T>
364 typename std::enable_if<is_any_of<T, bool, int, double, long long>::value, int>::type
365 GetParam(const AT_WC* feature, T& value);
366
367 template<typename T>
368 typename std::enable_if<is_any_of<T, std::string>::value, int>::type
369 GetParam(const AT_WC* feature, T& value);
377 template<typename T>
378 typename std::enable_if<is_any_of<T, const AT_WC*, const wchar_t*>::value, int>::type
379 SetParam(const AT_WC* feature, T value);
380
381 template<typename T>
382 typename std::enable_if<is_any_of<T, std::string_view>::value, int>::type
383 SetParam(const AT_WC* feature, T value);
384
396 int GetEnumParam(const AT_WC* feature, std::string& value);
397
398
399
400protected:
401
403 std::shared_ptr<ifw::fgf::common::RawImage> m_rawimage;
405 int m_img_bpp{0};
410
411private:
413 std::unique_ptr<RtmsLlnetioPublisher> m_publisher;
414
416 std::condition_variable m_acq_condvar;
417
419 std::condition_variable m_mon_condvar;
420
422 std::mutex m_mtx;
423
425 static std::atomic<bool> m_stopped ;
426 static std::atomic<bool> m_mon_stopped ;
427 bool m_acq_active{false};
428
432
434 std::thread m_acq_thread;
436 std::thread m_mon_thread;
437
438 fgf::common::CameraSetup m_cam_setup;
439 fgf::andor::CameraSetup m_andor_setup;
440 fgf::common::CameraStatus m_cam_status;
441 fgf::andor::CameraStatus m_andor_status;
442 log4cplus::Logger m_logger;
443
445 double m_mudpi_basetimestamp{0.0};
446
447 // Andor specific member attributes
448 std::vector<image_t> images;
449 int m_buffer_segments{1000};
450 int m_number_frames{1000};
451 unsigned char * m_image_buffer{nullptr};
452 unsigned char *m_image_data{nullptr};
453 unsigned char** m_acq_buffers;
454 unsigned char** m_aligned_buffers;
455 int m_cam_id{0};
456 int m_cam_handle{AT_HANDLE_UNINITIALISED};
457 unsigned int m_frame_counter{0};
458 AT_64 m_width, m_height;
459 AT_64 m_size_in_bytes;
460 AT_64 m_timestamp_clock_freq;
461 int m_buffer_size{0};
462
463 std::string m_config_filename{};
464 std::unique_ptr<fgf::andor::Config> m_config;
465
466 // Static maps for different error categories
467 static const std::map<int, std::string> enumerated_errors;
468
469
470};
471
472
473// Specialization for types using a custom type trait
474
475template<typename T>
476typename std::enable_if<is_any_of<T, bool, int, double, long long>::value, int>::type
477CommAdapter::SetParam(const AT_WC* feature, T value) {
478 int i_err = AT_SUCCESS;
479
480 size_t len = std::wcstombs(nullptr, feature, 0);
481 std::string command(len, '\0');
482 std::wcstombs(&command[0], feature, len);
483
484 const std::string msg = "Setting " + command + " to " + std::to_string(value) + " ...";
485 LOG4CPLUS_INFO(m_logger, msg);
486
487 if (std::is_same_v<T, AT_64>) {
488 LOG4CPLUS_DEBUG(m_logger, "long long type");
489 i_err = AT_SetInt(m_cam_handle, feature, value);
490 } else if (std::is_same_v<T, AT_BOOL>) {
491 LOG4CPLUS_DEBUG(m_logger, "SDK boolean type");
492 i_err = AT_SetBool(m_cam_handle, feature, value);
493 } else if (std::is_same_v<T, bool>) {
494 AT_BOOL bool_value = value ? AT_TRUE : AT_FALSE;
495 LOG4CPLUS_DEBUG(m_logger, "boolean type");
496 i_err = AT_SetBool(m_cam_handle, feature, bool_value);
497 } else if (std::is_same_v<T, double>) {
498 LOG4CPLUS_DEBUG(m_logger, "double type");
499 i_err = AT_SetFloat(m_cam_handle, feature, value);
500 }
501 if (i_err != AT_SUCCESS) {
502 const std::string msg = "Failure setting " + command + ", SDK error: " +
503 getErrorMessage(i_err);
504 LOG4CPLUS_ERROR(m_logger, msg);
505 m_andor_status.cmd_error_text = msg;
506 }
507 return i_err;
508}
509
510template<typename T>
511typename std::enable_if<is_any_of<T, bool, int, double, long long>::value, int>::type
512CommAdapter::GetParam(const AT_WC* feature, T& value) {
513 int i_err = AT_SUCCESS;
514
515 size_t len = std::wcstombs(nullptr, feature, 0);
516 std::string command(len, '\0');
517 std::wcstombs(&command[0], feature, len);
518
519 const std::string msg = "Getting " + command + "...";
520 LOG4CPLUS_INFO(m_logger, msg);
521
522 if (std::is_same_v<T, AT_64>) {
523 LOG4CPLUS_DEBUG(m_logger, "long long type");
524 AT_64 local_value;
525 i_err = AT_GetInt(m_cam_handle, feature, &local_value);
526 if (i_err == AT_SUCCESS) {
527 LOG4CPLUS_INFO(m_logger, "Read " << command << "=" << local_value);
528 value = static_cast<T>(local_value); // Assign to the output value
529 }
530 } else if (std::is_same_v<T, bool>) {
531 LOG4CPLUS_DEBUG(m_logger, "boolean type");
532 AT_BOOL local_value;
533 i_err = AT_GetBool(m_cam_handle, feature, &local_value);
534 if (i_err == AT_SUCCESS) {
535 LOG4CPLUS_INFO(m_logger, "Read " << command << "=" << local_value);
536 if (local_value == AT_TRUE) {
537 value = true;
538 } else {
539 value = false;
540 }
541 }
542 } else if (std::is_same_v<T, AT_BOOL>) {
543 LOG4CPLUS_DEBUG(m_logger, "boolean type");
544 AT_BOOL local_value;
545 i_err = AT_GetBool(m_cam_handle, feature, &local_value);
546 if (i_err == AT_SUCCESS) {
547 LOG4CPLUS_INFO(m_logger, "Read " << command << "=" << local_value);
548 value = static_cast<T>(local_value); // Assign to the output value
549 }
550 } else if (std::is_same_v<T, double>) {
551 LOG4CPLUS_DEBUG(m_logger, "double type");
552 double local_value;
553 i_err = AT_GetFloat(m_cam_handle, feature, &local_value);
554 if (i_err == AT_SUCCESS) {
555 LOG4CPLUS_INFO(m_logger, "Read " << command << "=" << local_value);
556 value = static_cast<T>(local_value); // Assign to the output value
557 }
558 }
559 if (i_err != AT_SUCCESS) {
560 const std::string msg = "Failure getting " + command + ", SDK error: " +
561 getErrorMessage(i_err);
562 LOG4CPLUS_ERROR(m_logger, msg);
563 m_andor_status.cmd_error_text = msg;
564 }
565 return i_err;
566}
567
568template<typename T>
569typename std::enable_if<is_any_of<T, std::string>::value, int>::type
570CommAdapter::GetParam(const AT_WC* feature, T& value) {
571 int i_err = AT_SUCCESS;
572
573 size_t len = std::wcstombs(nullptr, feature, 0);
574 std::string command(len, '\0');
575 std::wcstombs(&command[0], feature, len);
576
577 const std::string msg = "Getting " + command + "...";
578 LOG4CPLUS_INFO(m_logger, msg);
579
580 int length = 0;
581 i_err = AT_GetStringMaxLength(m_cam_handle,feature, &length);
582 if(AT_SUCCESS != i_err) {
583 LOG4CPLUS_ERROR(m_logger,"Problems getting maximum string length");
584 return i_err;
585 }
586
587 std::vector<AT_WC> string_value(static_cast<size_t>(length));
588 string_value.resize(static_cast<size_t>(length));
589 i_err = AT_GetString(m_cam_handle,feature,string_value.data(), static_cast<int>(string_value.size()));
590 if(i_err == AT_SUCCESS) {
591 std::string local_value;
592 local_value = std::string(string_value.begin(), string_value.end());
593 value = static_cast<T>(local_value); // Assign to the output value
594 LOG4CPLUS_INFO(m_logger, "Read " << command << "=" << value);
595
596 // Special case, the CameraName defines the camera type used to
597 // differentiate the two cameras.
598 if (feature == std::wstring(L"CameraName")) {
599 char szStr[32];
600 wcstombs(szStr, &string_value[0],string_value.size());
601 std::string camera_type{szStr};
602
603 if (camera_type == std::string(MARANA_TYPE)) {
604 m_cam_type = CameraType::MARANA;
605 LOG4CPLUS_INFO(m_logger,"Andor Marana ");
606 } else if (camera_type == std::string(BALOR_TYPE)) {
607 m_cam_type = CameraType::BALOR;
608 LOG4CPLUS_INFO(m_logger,"Andor Balor ");
609 } else if (camera_type == std::string(SIM_TYPE)) {
610 m_cam_type = CameraType::SIM;
611 LOG4CPLUS_INFO(m_logger,"Andor Sim Camera ");
612 } else {
613 LOG4CPLUS_ERROR(m_logger,"Wrong camera name ");
614 }
615 }
616 string_value.clear();
617 }
618
619
620 if (i_err != AT_SUCCESS) {
621 const std::string msg = "Failure getting " + command + ", SDK error: " +
622 getErrorMessage(i_err);
623 LOG4CPLUS_ERROR(m_logger, msg);
624 m_andor_status.cmd_error_text = msg;
625 }
626 return i_err;
627}
628
629// Specialization for const wchar_t* (or AT_WC*)
630template<typename T>
631typename std::enable_if<is_any_of<T, const AT_WC*, const wchar_t*>::value, int>::type
632CommAdapter::SetParam(const AT_WC* feature, T value) {
633
634 int i_err = AT_SUCCESS;
635
636 size_t len = std::wcstombs(nullptr, feature, 0);
637 std::string command(len, '\0');
638 std::wcstombs(&command[0], feature, len);
639
640 size_t lenval = std::wcstombs(nullptr, value, 0);
641 std::string strvalue(lenval, '\0');
642 std::wcstombs(&strvalue[0], value, lenval);
643
644 const std::string msg = "Setting " + command + " to " + strvalue + " ...";
645 LOG4CPLUS_INFO(m_logger, msg);
646
647 i_err = AT_SetEnumString(m_cam_handle, feature, value);
648 if (i_err != AT_SUCCESS) {
649 const std::string msg = "Failure setting " + command + ", SDK error: " +
650 getErrorMessage(i_err);
651 LOG4CPLUS_ERROR(m_logger, msg);
652 m_andor_status.cmd_error_text = msg;
653 }
654 return i_err;
655}
656
657// Specialization for const std::string
658template<typename T>
659typename std::enable_if<is_any_of<T, std::string_view>::value, int>::type
660CommAdapter::SetParam(const AT_WC* feature, T value) {
661
662 int i_err = AT_SUCCESS;
663
664 size_t len = value.length() + 1; // +1 for null terminator
665 std::vector<wchar_t> wstr_value(len);
666 std::mbstowcs(&wstr_value[0], value.data(), len);
667
668 len = std::wcstombs(nullptr, feature, 0);
669 std::string command(len, '\0');
670 std::wcstombs(&command[0], feature, len);
671
672
673
674 //const std::string msg = "Setting " + command + " to " + std::string(value.data()) + " ...";
675 LOG4CPLUS_INFO(m_logger, "Setting " << command << " to " << value << " ...");
676
677 i_err = AT_SetEnumString(m_cam_handle, feature, &wstr_value[0]);
678 if (i_err != AT_SUCCESS) {
679 const std::string msg = "Failure setting " + command + ", SDK error: " +
680 getErrorMessage(i_err);
681 LOG4CPLUS_ERROR(m_logger, msg);
682 m_andor_status.cmd_error_text = msg;
683 }
684 return i_err;
685}
686
687
688
689}
690
691#endif // DCS_ANDOR_LIB_COM_ADPT_HPP_H_
Frame Grabber Camera Base Class definitions.
std::unique_ptr< AT_U8[]> image_t
Definition commAdapter.hpp:28
CommAdapter(const RtmsNetworkConfig &rtms_cfg, std::string_view config_filename="", bool compute_latency=false, const PublisherThreadConfig &thread_cfg=PublisherThreadConfig())
Constructor for CommAdapter.
Definition commAdaptor.cpp:73
virtual short Stop() override
Stops the acquisition process.
Definition commAdaptor.cpp:739
int m_img_bpp
Bits per pixel of the current image.
Definition commAdapter.hpp:405
virtual void Initialise()
Initializes the communication adapter.
Definition commAdaptor.cpp:112
virtual short Start() override
Starts the acquisition process.
Definition commAdaptor.cpp:664
static std::string getErrorMessage(int errorCode)
Definition commAdapter.hpp:134
int m_img_height
Height of the current image.
Definition commAdapter.hpp:409
virtual ~CommAdapter()
Destructor for CommAdapter.
Definition commAdaptor.cpp:155
virtual void CheckConnection(bool &connected)
Checks if the connection to the camera is established.
Definition commAdaptor.cpp:186
std::shared_ptr< ifw::fgf::common::RawImage > m_rawimage
Pointer to latest received image.
Definition commAdapter.hpp:403
virtual void Read(ifw::fgf::common::VectorVariant &params) const override
Reads multiple parameters from the camera.
Definition commAdaptor.cpp:929
virtual short Reset() override
Resets the camera to its initial state.
Definition commAdaptor.cpp:801
virtual bool IsConnected() const
Checks if the adapter is currently connected to the camera.
Definition commAdaptor.cpp:192
virtual short Setup()
Download parameters to the camera.
Definition commAdaptor.cpp:914
virtual short SetLogLevel(std::string &level, std::string &logger)
Definition commAdaptor.cpp:787
virtual void Connect()
Establishes a connection to the camera.
Definition commAdaptor.cpp:198
virtual void Write(const ifw::fgf::common::VectorVariant &params) override
Writes multiple parameters to the camera.
Definition commAdaptor.cpp:972
virtual std::string GetLoggers()
Definition commAdaptor.cpp:773
virtual void Disconnect()
Disconnects from the camera.
Definition commAdaptor.cpp:224
virtual short Init()
Initializes the camera for acquisition.
Definition commAdaptor.cpp:764
int m_img_width
Width of the current image.
Definition commAdapter.hpp:407
Abstract base class for implementing FGF Communication Adapters.
Definition iCommAdapter.hpp:24
Frame Grabber Camera Base Class definitions.
Abstract base class for implementing FGF Communication Adapters.
Logging definitions.
Image class for handling images from the camera.
Definition commAdaptor.cpp:34
const uint32_t STREAM_BYTES_PER_SECOND_MAX
Definition commAdapter.hpp:52
const AT_64 ALIGNMENT
Definition commAdapter.hpp:57
const double FRAME_REC_THR_SLEEP_TIME
Definition commAdapter.hpp:47
const short RPC_ERROR
Definition commAdapter.hpp:55
constexpr const char * MARANA_TYPE
Definition commAdapter.hpp:59
const int TIMEOUTMS
Definition commAdapter.hpp:53
constexpr const char * BALOR_TYPE
Definition commAdapter.hpp:58
constexpr const char * SIM_TYPE
Definition commAdapter.hpp:60
RpcError
Definition commAdapter.hpp:70
@ PARAM_SETUP_ERROR
Definition commAdapter.hpp:71
std::variant< ifw::fgf::common::SetupParam::ParamEnum, ifw::fgf::andor::SetupParam::ParamEnum > AndorCtrlEnumKey
RTMS network configuration (defined in rtmsLlnetioPublisher.hpp)
Definition commAdapter.hpp:78
const uint16_t NB_OF_INPUT_BUFFERS
Definition commAdapter.hpp:49
const uint32_t STREAM_BYTES_PER_SECOND_MIN
Definition commAdapter.hpp:51
constexpr const char * CAMERA_INTERFACE
Definition commAdapter.hpp:61
const double CONNECT_TIMEOUT
Definition commAdapter.hpp:46
const int32_t DEFAULT_PACKET_SIZE
Definition commAdapter.hpp:50
const short FEATURE_ERROR
Definition commAdapter.hpp:56
const uint16_t MAX_NB_OF_RECEP_BUFFERS
Definition commAdapter.hpp:48
const short RPC_SUCCESS
Definition commAdapter.hpp:54
std::variant< ifw::fgf::common::StatusParam::StatusEnum, ifw::fgf::andor::StatusParam::StatusEnum, ifw::fgf::common::SetupParam::ParamEnum, ifw::fgf::andor::SetupParam::ParamEnum > AndorStatEnumKey
Definition commAdapter.hpp:107
CameraType
Definition commAdapter.hpp:62
@ UNKNOWN
Definition commAdapter.hpp:63
@ MARANA
Definition commAdapter.hpp:65
@ SIM
Definition commAdapter.hpp:66
@ BALOR
Definition commAdapter.hpp:64
std::variant< bool, int, unsigned int, short, double, std::string > Variant
Definition setupParam.hpp:21
std::vector< PairVariant > VectorVariant
Definition setupParam.hpp:24
std::pair< std::string, Variant > PairVariant
Definition setupParam.hpp:23
RTMS publisher thread for LLNETIO-based adapters.
A custom hash function for AndorStatEnumKey, which supports hashing of variant-like types (e....
Definition commAdapter.hpp:89
std::size_t operator()(const AndorCtrlEnumKey &key) const
Generates a hash value for the given AndorCtrlEnumKey.
Definition commAdapter.hpp:100
Definition commAdapter.hpp:112
std::size_t operator()(const AndorStatEnumKey &key) const
Definition commAdapter.hpp:113
Definition camAndor.hpp:14
Definition camAndor.hpp:28
Thread-level tuning for the publisher.
Definition rtmsLlnetioPublisher.hpp:51
RTMS network configuration (shared with CommAdapter).
Definition rtmsLlnetioPublisher.hpp:34
ParamEnum
Definition setupParam.hpp:37
StatusEnum
Definition statusParam.hpp:44
Structure to hold camera setup parameters.
Definition camBase.hpp:27
Structure to hold camera status parameters.
Definition camBase.hpp:43
ParamEnum
Definition setupParam.hpp:42
StatusEnum
Status ("stat" category) parameters enums.
Definition statusParam.hpp:42
Definition commAdapter.hpp:32