API
 
Loading...
Searching...
No Matches
nnReconstructor.hpp
Go to the documentation of this file.
1/** \file nnReconstructor.hpp
2 * \brief The MagAO-X generic ImageStreamIO stream integrator
3 *
4 * \ingroup app_files
5 */
6
7#ifndef nnReconstructor_hpp
8#define nnReconstructor_hpp
9
10#include <NvInfer.h>
11#include <cuda_fp16.h>
12#include <cuda_runtime_api.h>
13#include <iostream>
14#include <fstream>
15#include <vector>
16#include <limits>
17
18#include <mx/improc/eigenCube.hpp>
19#include <mx/improc/eigenImage.hpp>
20
21#include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
22#include "../../magaox_git_version.h"
23
24using namespace nvinfer1;
25
26// Logger for TensorRT info/warning/errors
27class Logger : public ILogger {
28 void log(Severity severity, const char* msg) noexcept override {
29 if (severity <= Severity::kWARNING) {
30 std::cout << msg << std::endl;
31 }
32 }
33};
34
35// #define MAGAOX_CURRENT_SHA1 0
36// #define MAGAOX_REPO_MODIFIED 0
37
38void halfToFloatArray(float* dst, const half* src, size_t num_elements) {
39 for (size_t i = 0; i < num_elements; ++i) {
40 dst[i] = __half2float(src[i]);
41 }
42}
43
44void floatToHalfArray(half* dst, const float* src, size_t num_elements) {
45 for (size_t i = 0; i < num_elements; ++i) {
46 dst[i] = __float2half(src[i]); // Convert each float to half-precision
47 }
48}
49
50
51namespace MagAOX
52{
53namespace app
54{
55
56class nnReconstructor : public MagAOXApp<true>, public dev::shmimMonitor<nnReconstructor>, public dev::frameGrabber<nnReconstructor>, public dev::telemeter<nnReconstructor>
57{
58 // Give the test harness access.
60
62
63 // The base shmimMonitor type
65
67
69
70 friend class dev::telemeter<nnReconstructor>;
71
73
74 /// Floating point type in which to do all calculations.
75 typedef float realT;
76
77 public:
78 /** \name app::dev Configurations
79 *@{
80 */
81
82 /// This framegrabber can't be flipped
83 static constexpr bool c_frameGrabber_flippable = false;
84
85 ///@}
86
87 protected:
88 /** \name Configurable Parameters
89 *@{
90 */
91 std::string dataDirs; // Location where the data (onnx file, engine, WFS reference) is stored
92 std::string engineName; // Name of the engine
93 std::string engineDirs; // Name of the engine
94 bool rebuildEngine {false}; // If true, it will rebuild the engine and save it at engineName
95
96 std::string m_fpsSource{ "camwfs" }; /**< Device name for getting fps of the loop.
97 This device must have *.fps.current. Default is camwfs*/
98
99 ///@}
100
101 Logger logger; // The tensorRT logger
102 std::vector<char> engineData; // for loading the engine file.
103
104 IRuntime* runtime {nullptr};
105 ICudaEngine* engine {nullptr};
107 int inputC {0};
108 int inputH {0};
109 int inputW {0};
110 int inputSize {0};
111 int input2Size {4};
113 int zeroPad { 2 };
114
115 float* d_input {nullptr};
116 float* d_input2 {nullptr};
117 float* d_output {nullptr};
118 bool use_fp16 = false;
119 bool explicit_tt = false;
120
121 float imageNorm; // Normalization constant for the image intensities
122 float modalNorm; // Normalization constant for the modal coefficients
123
124 int m_pupPix; // Number of pixels in the pupil used for the Neural Network
125 int pup_offset1_x; // Horizontal offset to the first set of pupils
126 int pup_offset1_y; // Vertical offset to the first set of pupils
127 int pup_offset2_x; // Horizontal offset to the second set of pupils
128 int pup_offset2_y; // Horizontal offset to the second set of pupils
130
131 int Npup{ 4 }; // Number of pupils
132
134
135 half *modeval_half{ nullptr };
136
137 float *pp_image{ nullptr };
138 float *pup_Is{ nullptr };
139 half *pp_image_half{ nullptr };
140 half *pup_Is_half{ nullptr };
141
142 size_t m_pwfsWidth{ 0 }; ///< The width of the image
143 size_t m_pwfsHeight{ 0 }; ///< The height of the image.
144
145 uint8_t m_pwfsDataType{ 0 }; ///< The ImageStreamIO type code.
146 size_t m_pwfsTypeSize{ 0 }; ///< The size of the type, in bytes.
147
148 float m_fps{ 0 }; ///< Current FPS from the FPS source.
149
150 sem_t m_smSemaphore{ 0 }; ///< Semaphore used to synchronize the fg thread and the dm command thread.
151
152 bool m_updated{ false }; ///< Flag indicating that the mode vals have been updated
153
154
155 public:
156 /// Default c'tor.
158
159 /// D'tor, declared and defined for noexcept.
163
164 virtual void setupConfig();
165
166 /// Implementation of loadConfig logic, separated for testing.
167 /** This is called by loadConfig().
168 */
169 int loadConfigImpl(
170 mx::app::appConfigurator &_config /**< [in] an application configuration
171 from which to load values*/
172 );
173
174 virtual void loadConfig();
175
176 /// Startup function
177 /**
178 *
179 */
180 virtual int appStartup();
181
182 /// Implementation of the FSM for nnReconstructor.
183 /**
184 * \returns 0 on no critical error
185 * \returns -1 on an error requiring shutdown
186 */
187 virtual int appLogic();
188
189 /// Shutdown the app.
190 /**
191 *
192 */
193 virtual int appShutdown();
194
195 // Custom functions
196 //int send_to_shmim();
197
198 void load_engine(const std::string filename);
203
204 // void build_engine(){};
205
206 protected:
207 int allocate( const dev::shmimT &dummy /**< [in] tag to differentiate shmimMonitor parents.*/ );
208
209 int processImage( void *curr_src, ///< [in] pointer to start of current frame.
210 const dev::shmimT &dummy ///< [in] tag to differentiate shmimMonitor parents.
211 );
212
213
214 /** \name frameGrabber Interface
215 * @{
216 */
217
218 /// Configure the output stream for acquistion.
219 /** Tests if stream exists and is expected size. Creates it if needed.
220 * will set m_width, m_height, and m_dataType.
221 */
223
224 /// Gets the frames-per-second readout rate
225 /** Used for the latency statistics
226 */
227 float fps();
228
229 /// Start acquisition.
230 /** A no-op in this class.
231 */
232 int startAcquisition();
233
234 /// Acquire data.
235 /** Here just waits on the semaphore.
236 */
238
239 /// Loads the modevals into the stream
240 int loadImageIntoStream(void * dest);
241
242 ///Take any actions needed to reconfigure the system. Called if m_reconfig is set to true.
243 int reconfig();
244
245 ///@}
246
247 /** \name INDI interface
248 * @{
249 */
250
251 pcf::IndiProperty m_indiP_fpsSource;
253
254 pcf::IndiProperty m_indiP_fps;
255
256 ///@}
257
258 /** \name Telemeter Interface
259 * @{
260 */
261
262 int checkRecordTimes();
263
264 int recordTelem( const telem_fgtimings * );
265
266 ///@}
267};
268
269void nnReconstructor::load_engine(const std::string filename) {
270
271 std::ifstream file(filename, std::ios::binary);
272 if (!file) {
273 std::cout << "Error opening " << filename << std::endl;
274 }
275
276 file.seekg(0, std::ios::end);
277
278 engineData = std::vector<char>(file.tellg());
279 file.seekg(0, std::ios::beg);
280 file.read(engineData.data(), engineData.size());
281
282}
283
285
286 // Create the runtime and deserialize the engine
288 if (!runtime) {
289 std::cout << "Failed to createInferRuntime\n";
290 }
291
292 engine = runtime->deserializeCudaEngine(engineData.data(), engineData.size());
293 if (!engine) {
294 std::cout << "Failed to deserialize CUDA engine.\n";
295 } else {
296 std::cout << "Deserialized CUDA engine.\n";
297 }
298
299 context = engine->createExecutionContext();
300
301
302 int numIOTensors = engine->getNbIOTensors();
303 std::cout << "Number of IO Tensors: " << numIOTensors << std::endl;
304
305
306 auto inputName = engine->getIOTensorName(0);
307 auto outputName = engine->getIOTensorName(1);
308 std::cout << "Tensor IO names: " << inputName << ", " << outputName << std::endl;
309
310
311 const auto inputDims = engine->getTensorShape(inputName);
312 const auto outputDims = engine->getTensorShape(outputName);
313 inputC = inputDims.d[1];
314 inputH = inputDims.d[2];
315 inputW = inputDims.d[3];
317
318 outputSize = outputDims.d[1];
319 std::cout << "Tensor input dimensions: " << inputC << "x" << inputH << "x" << inputW << std::endl;
320 std::cout << "Tensor output dimensions: " << outputSize << std::endl;
321
322}
323
325
326 // Allocate device memory for input and output
327 if (use_fp16) {
328 // Allocate FP16 memory
329 cudaMalloc((void**)&d_input, inputSize * sizeof(half));
330 if (explicit_tt) {
331 cudaMalloc((void**)&d_input2, input2Size * sizeof(half));
332 }
333 cudaMalloc((void**)&d_output, outputSize * sizeof(half));
334 } else {
335 // Allocate FP32 memory
336 cudaMalloc((void**)&d_input, inputSize * sizeof(float));
337 if (explicit_tt) {
338 cudaMalloc((void**)&d_input2, input2Size * sizeof(float));
339 }
340 cudaMalloc((void**)&d_output, outputSize * sizeof(float));
341 }
342
343 //cudaMalloc((void**)&d_input, inputSize * sizeof(float));
344 //cudaMalloc((void**)&d_output, outputSize * sizeof(float));
345
346}
347
357
359 if(context)
360 delete context;
361 if(engine)
362 delete engine;
363 if(runtime)
364 delete runtime;
365};
366
367inline nnReconstructor::nnReconstructor() : MagAOXApp( MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED )
368{
369 return;
370}
371
373{
374 std::cout << "setupConfig()" << std::endl;
375
379
380 config.add( "parameters.dataDirs",
381 "",
382 "parameters.dataDirs",
383 argType::Required,
384 "parameters",
385 "dataDirs",
386 false,
387 "string",
388 "The path to the directory with the onnx model." );
389
390 config.add( "parameters.engineDirs",
391 "",
392 "parameters.engineDirs",
393 argType::Required,
394 "parameters",
395 "engineDirs",
396 false,
397 "string",
398 "The path to the directory with the TRT engine." );
399
400 config.add( "parameters.engineName",
401 "",
402 "parameters.engineName",
403 argType::Required,
404 "parameters",
405 "engineName",
406 false,
407 "string",
408 "Name of the TRT engine." );
409
410 config.add( "parameters.rebuildEngine",
411 "",
412 "parameters.rebuildEngine",
413 argType::Required,
414 "parameters",
415 "rebuildEngine",
416 false,
417 "bool",
418 "If true the engine will be rebuild." );
419
420 config.add( "parameters.imageNorm",
421 "",
422 "parameters.imageNorm",
423 argType::Required,
424 "parameters",
425 "imageNorm",
426 false,
427 "float",
428 "Normalization term for the preprocessed images." );
429
430 config.add( "parameters.modalNorm",
431 "",
432 "parameters.modalNorm",
433 argType::Required,
434 "parameters",
435 "modalNorm",
436 false,
437 "float",
438 "Normalization term for the modal coefficients." );
439
440 config.add( "parameters.use_fp16",
441 "",
442 "parameters.use_fp16",
443 argType::Required,
444 "parameters",
445 "use_fp16",
446 false,
447 "bool",
448 "If true the half precision mode will be used." );
449
450 config.add( "parameters.explicit_tt",
451 "",
452 "parameters.explicit_tt",
453 argType::Required,
454 "parameters",
455 "explicit_tt",
456 false,
457 "bool",
458 "If true the model will additionally give the pupil intensities as input to the NN." );
459
460 config.add( "parameters.m_pupPix",
461 "",
462 "parameters.m_pupPix",
463 argType::Required,
464 "parameters",
465 "m_pupPix",
466 false,
467 "int",
468 "Number of pixels across a PWFS pupil." );
469
470 config.add( "parameters.pup_offset1_x",
471 "",
472 "parameters.pup_offset1_x",
473 argType::Required,
474 "parameters",
475 "pup_offset1_x",
476 false,
477 "int",
478 "Horizontal offset to the top left of the closest set op PWFS pupils." );
479
480 config.add( "parameters.pup_offset1_y",
481 "",
482 "parameters.pup_offset1_y",
483 argType::Required,
484 "parameters",
485 "pup_offset1_y",
486 false,
487 "int",
488 "Vertical offset to the top left of the closest set op PWFS pupils." );
489
490 config.add( "parameters.pup_offset2_x",
491 "",
492 "parameters.pup_offset2_x",
493 argType::Required,
494 "parameters",
495 "pup_offset2_x",
496 false,
497 "int",
498 "Horizontal offset to the top left of the furthest set op PWFS pupils." );
499
500 config.add( "parameters.pup_offset2_y",
501 "",
502 "parameters.pup_offset2_y",
503 argType::Required,
504 "parameters",
505 "pup_offset2_y",
506 false,
507 "int",
508 "Vertical offset to the top left of the furthest set op PWFS pupils." );
509
510}
511
512inline int nnReconstructor::loadConfigImpl( mx::app::appConfigurator &_config )
513{
514 std::cout << "loadConfigImpl()" << std::endl;
515
517
520
521 _config( dataDirs, "parameters.dataDirs" );
522 _config( engineDirs, "parameters.engineDirs" );
523 _config( engineName, "parameters.engineName" );
524 _config( rebuildEngine, "parameters.rebuildEngine" );
525 _config( imageNorm, "parameters.imageNorm" );
526 _config( modalNorm, "parameters.modalNorm" );
527 _config( use_fp16, "parameters.use_fp16" );
528 _config( explicit_tt, "parameters.explicit_tt" );
529
530 _config( m_pupPix, "parameters.m_pupPix" );
531 _config( pup_offset1_x, "parameters.pup_offset1_x" );
532 _config( pup_offset1_y, "parameters.pup_offset1_y" );
533 _config( pup_offset2_x, "parameters.pup_offset2_x" );
534 _config( pup_offset2_y, "parameters.pup_offset2_y" );
535
536 _config( m_fpsSource, "recon.fpsSource" );
537
539
540 if( true )
541 {
542 std::cout << "Debug configuration loading: " << std::endl;
543 std::cout << "dataDirs: " << dataDirs << std::endl;
544 std::cout << "engineDirs: " << engineDirs << std::endl;
545 std::cout << "engineName: " << engineName << std::endl;
546 std::cout << "rebuildEngine: " << rebuildEngine << std::endl;
547 std::cout << "imageNorm: " << imageNorm << std::endl;
548 std::cout << "modalNorm: " << modalNorm << std::endl;
549 std::cout << "use_fp16: " << use_fp16 << std::endl;
550 std::cout << "explicit_tt: " << explicit_tt << std::endl;
551 std::cout << "modeval Channel: " << frameGrabberT::m_shmimName << std::endl;
552
553 std::cout << "m_pupPix: " << m_pupPix << std::endl;
554 std::cout << "pup_offset1_x: " << pup_offset1_x << std::endl;
555 std::cout << "pup_offset1_y: " << pup_offset1_y << std::endl;
556 std::cout << "pup_offset2_x: " << pup_offset2_x << std::endl;
557 std::cout << "pup_offset2_y: " << pup_offset2_y << std::endl;
558 }
559
560 return 0;
561}
562
564{
565 loadConfigImpl( config );
566}
567
569{
570
571 REG_INDI_SETPROP( m_indiP_fpsSource, m_fpsSource, std::string( "fps" ) );
572
574 m_indiP_fps.add( pcf::IndiElement( "current" ) );
576 {
577 log<software_error>( { "" } );
578 return -1;
579 }
580
581 if( sem_init( &m_smSemaphore, 0, 0 ) < 0 )
582 {
583 log<software_critical>( { errno, "Initializing S.M. semaphore" } );
584 return -1;
585 }
586
587 std::string full_filepath = engineDirs + "/" + engineName;
588 std::cout << "file: " << full_filepath << std::endl;
589
593
594 //Do this after everything is configured so we can check sizes propertly
596
598
600
602 return 0;
603}
604
606{
608
610
612
613 std::unique_lock<std::mutex> lock( m_indiMutex );
614
616
618
619
620 return 0;
621}
622
624{
626
628
630
631 if( pp_image )
632 {
633 delete[] pp_image;
634 }
635 if( pp_image_half )
636 {
637 delete[] pp_image_half;
638 }
639 if( pup_Is )
640 {
641 delete[] pup_Is;
642 }
643 if( pup_Is_half)
644 {
645 delete[] pup_Is_half;
646 }
647
648 if( modeval_half )
649 {
650 delete[] modeval_half;
651 }
652
655
656 return 0;
657}
658
659inline int nnReconstructor::allocate( const dev::shmimT &dummy )
660{
661 std::cout << "allocate()" << std::endl;
662 static_cast<void>( dummy ); // be unused
663
664 // Wavefront sensor setup
667 std::cout << "Width: " << m_pwfsWidth << " Height: " << m_pwfsHeight << std::endl;
668
670 std::cout << "Pixels: " << pixels_per_quadrant << std::endl;
671 pp_image = new float[Npup * pixels_per_quadrant];
672 pup_Is = new float[4];
673 //modeval = new float[outputSize];
674 modeval.resize(outputSize, 1);
675
676 memset( pp_image, 0, sizeof( float ) * Npup * pixels_per_quadrant );
677 if (explicit_tt){
678 memset( pup_Is, 0, sizeof( float) * 4);
679 }
680 //memset( modeval, 0, sizeof( float) * outputSize);
681 modeval.setZero();
682
683 if (use_fp16){
686 pup_Is_half = new half[4];
687 memset( pp_image_half, 0, sizeof( half ) * Npup * pixels_per_quadrant );
688 if (explicit_tt){
689 memset( pup_Is_half, 0, sizeof( half ) * 4);
690 }
691 memset( modeval_half, 0, sizeof( half) * outputSize);
692 }
693
694 return 0;
695}
696
697inline int nnReconstructor::processImage( void *curr_src, const dev::shmimT &dummy )
698{
699 static_cast<void>( dummy ); // be unused
700
701 //record arrival time as the atime
703 {
704 m_shutdown = true;
705 return log<software_critical,-1>( { errno, "clock_gettime" } );
706 }
707
708 // aol_imwfs2 is reference and dark subtracted and is power normalized.
709
710 Eigen::Map<eigenImage<float>> pwfsIm(reinterpret_cast<float*>(curr_src), m_pwfsHeight, m_pwfsWidth);
711
712 // Split up the four pupils for the Neural Network.
713 int ki = 0;
714
715
716 for( int col_i = -zeroPad; col_i < (m_pupPix - zeroPad); ++col_i )
717 {
718 for( int row_i = -zeroPad; row_i < (m_pupPix - zeroPad); ++row_i )
719 {
720 if ((col_i < 0) or (col_i >= (m_pupPix - 2*zeroPad)) or (row_i < 0) or (row_i >= (m_pupPix - 2*zeroPad))){
721 pp_image[ki] = 0;
725 }
726 else {
731 }
732 ++ki;
733 }
734 }
735
736 // Copy input data to device
737 if (use_fp16){
740 if (explicit_tt){
743 }
744 }
745 else {
747 if (explicit_tt){
749
750 }
751 }
752
753
754 // Run inference
755 if (explicit_tt){
756 void* buffers[] = {d_input, d_input2, d_output};
757 context->executeV2(buffers);
758 }
759 else {
760 void* buffers[] = {d_input, d_output};
761 context->executeV2(buffers);
762 }
763
764 // Copy output data back to host
765 if (use_fp16){
768 }
769 else {
771 }
772
773 // Send modal coefficients to the correct stream
774 m_updated = true;
775
776 // trigger framegrabber
777 if( sem_post( &m_smSemaphore ) < 0 )
778 {
779 log<software_critical>( { errno, 0, "Error posting to semaphore" } );
780 return -1;
781 }
782
783 return 0;
784}
785
787{
788 static bool logged = false;
789
790 int rv = openShmim();
791 if(rv != 0)
792 {
793 return rv;
794 }
795
798 {
799 if( !logged )
800 {
801 log<text_log>( std::format( "{} is wrong size ({}x{}) or type ({})",
807 logged = true;
808 }
809 return 1;
810 }
811
812
813 logged = false;
814
815 return 0;
816}
817
819{
820 return m_fps;
821}
822
824{
825 return 0;
826}
827
829{
830 timespec ts;
831
832 errno = 0;
833 if( clock_gettime( CLOCK_REALTIME, &ts ) < 0 )
834 {
835 log<software_critical>( { errno, "clock_gettime" } );
836 return -1;
837 }
838
839 ts.tv_sec += 1;
840
841 if( sem_timedwait( &m_smSemaphore, &ts ) == 0 )
842 {
843 if( m_updated )
844 {
845 return 0;
846 }
847 else
848 {
849 return 1;
850 }
851 }
852 else
853 {
854 return 1;
855 }
856}
857
859{
861
862 m_updated = false;
863
864 return 0;
865}
866
868{
869 return 0;
870}
871
872INDI_SETCALLBACK_DEFN( nnReconstructor, m_indiP_fpsSource )( const pcf::IndiProperty &ipRecv )
873{
874 INDI_VALIDATE_CALLBACK_PROPS( m_indiP_fpsSource, ipRecv );
875
876 if( ipRecv.find( "current" ) != true ) // this isn't valid
877 {
878 return -1;
879 }
880
881 std::lock_guard<std::mutex> guard( m_indiMutex );
882
883 realT fps = ipRecv["current"].get<float>();
884
885 if( fps != m_fps )
886 {
887 m_fps = fps;
888 updateIfChanged( m_indiP_fps, "current", m_fps );
889 }
890
891 return 0;
892}
893
898
900{
901 return recordFGTimings( true );
902}
903
904} // namespace app
905} // namespace MagAOX
906
907#endif // nnReconstructor_hpp
void log(Severity severity, const char *msg) noexcept override
The base-class for XWCTk applications.
stateCodes::stateCodeT state()
Get the current state code.
int m_shutdown
Flag to signal it's time to shutdown. When not 0, the main loop exits.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
int createROIndiNumber(pcf::IndiProperty &prop, const std::string &propName, const std::string &propLabel="", const std::string &propGroup="")
Create a ReadOnly INDI Number property.
int registerIndiPropertyReadOnly(pcf::IndiProperty &prop)
Register an INDI property which is read only.
std::mutex m_indiMutex
Mutex for locking INDI communications.
timespec m_currImageTimestamp
The timestamp of the current image.
uint32_t m_width
The width of the image, once deinterlaced etc.
bool m_ownShmim
Flag controlling if the shmim is owned. If true it will be destroyed as needed.
size_t m_typeSize
The size of the type, in bytes. Result of sizeof.
uint8_t m_dataType
The ImageStreamIO type code.
uint32_t m_height
The height of the image, once deinterlaced etc.
uint32_t m_width
The width of the images in the stream.
uint32_t m_height
The height of the images in the stream.
int acquireAndCheckValid()
Acquire data.
float m_fps
Current FPS from the FPS source.
static constexpr bool c_frameGrabber_flippable
This framegrabber can't be flipped.
sem_t m_smSemaphore
Semaphore used to synchronize the fg thread and the dm command thread.
float realT
Floating point type in which to do all calculations.
int loadImageIntoStream(void *dest)
Loads the modevals into the stream.
dev::telemeter< nnReconstructor > telemeterT
size_t m_pwfsWidth
The width of the image.
virtual int appShutdown()
Shutdown the app.
size_t m_pwfsHeight
The height of the image.
int reconfig()
Take any actions needed to reconfigure the system. Called if m_reconfig is set to true.
int configureAcquisition()
Configure the output stream for acquistion.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
int recordTelem(const telem_fgtimings *)
int allocate(const dev::shmimT &dummy)
INDI_SETCALLBACK_DECL(nnReconstructor, m_indiP_fpsSource)
dev::frameGrabber< nnReconstructor > frameGrabberT
uint8_t m_pwfsDataType
The ImageStreamIO type code.
virtual int appStartup()
Startup function.
virtual int appLogic()
Implementation of the FSM for nnReconstructor.
void load_engine(const std::string filename)
int processImage(void *curr_src, const dev::shmimT &dummy)
size_t m_pwfsTypeSize
The size of the type, in bytes.
bool m_updated
Flag indicating that the mode vals have been updated.
float fps()
Gets the frames-per-second readout rate.
~nnReconstructor() noexcept
D'tor, declared and defined for noexcept.
int startAcquisition()
Start acquisition.
dev::shmimMonitor< nnReconstructor > shmimMonitorT
#define FRAMEGRABBER_SETUP_CONFIG(cfig)
Call frameGrabberT::setupConfig with error checking for frameGrabber.
#define FRAMEGRABBER_APP_LOGIC
Call frameGrabberT::appLogic with error checking for frameGrabber.
#define FRAMEGRABBER_APP_SHUTDOWN
Call frameGrabberT::appShutdown with error checking for frameGrabber.
#define FRAMEGRABBER_UPDATE_INDI
Call frameGrabberT::updateINDI with error checking for frameGrabber.
#define FRAMEGRABBER_LOAD_CONFIG(cfig)
Call frameGrabberT::loadConfig with error checking for frameGrabber.
#define FRAMEGRABBER_APP_STARTUP
Call frameGrabberT::appStartup with error checking for frameGrabber.
#define INDI_SETCALLBACK_DEFN(class, prop)
Define the callback for a set property request.
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, using the standard callback name.
@ OPERATING
The device is operating, other than homing.
#define INDI_VALIDATE_CALLBACK_PROPS(prop1, prop2)
Standard check for matching INDI properties in a callback.
const pcf::IndiProperty & ipRecv
updateIfChanged(m_indiP_angle, "target", m_angle)
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition dm.hpp:19
static constexpr logPrioT LOG_INFO
Informational. The info log level is the lowest level recorded during normal operations.
void halfToFloatArray(float *dst, const half *src, size_t num_elements)
void floatToHalfArray(half *dst, const float *src, size_t num_elements)
#define SHMIMMONITOR_APP_SHUTDOWN
Call shmimMonitorT::appShutdown with error checking for shmimMonitor.
#define SHMIMMONITOR_APP_LOGIC
Call shmimMonitorT::appLogic with error checking for shmimMonitor.
#define SHMIMMONITOR_APP_STARTUP
Call shmimMonitorT::appStartup with error checking for shmimMonitor.
#define SHMIMMONITOR_LOAD_CONFIG(cfig)
Call shmimMonitorT::loadConfig with error checking for shmimMonitor.
#define SHMIMMONITOR_UPDATE_INDI
Call shmimMonitorT::updateINDI with error checking for shmimMonitor.
#define SHMIMMONITOR_SETUP_CONFIG(cfig)
Call shmimMonitorT::setupConfig with error checking for shmimMonitor.
A device base class which saves telemetry.
Definition telemeter.hpp:75
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
Software CRITICAL log entry.
Log entry recording framegrabber timings.
#define TELEMETER_APP_LOGIC
Call telemeter::appLogic with error checking.
#define TELEMETER_LOAD_CONFIG(cfig)
Call telemeter::loadConfig with error checking.
#define TELEMETER_APP_STARTUP
Call telemeter::appStartup with error checking.
#define TELEMETER_SETUP_CONFIG(cfig)
Call telemeter::setupConfig with error checking.
#define TELEMETER_APP_SHUTDOWN
Call telemeter::appShutdown with error checking.