API
streamCircBuff.hpp
Go to the documentation of this file.
1 /** \file streamCircBuff.hpp
2  * \brief The MagAO-X streamCircBuff app header file
3  *
4  * \ingroup streamCircBuff_files
5  */
6 
7 #ifndef streamCircBuff_hpp
8 #define streamCircBuff_hpp
9 
10 
11 #include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
12 #include "../../magaox_git_version.h"
13 
14 /** \defgroup streamCircBuff
15  * \brief An application to keep a circular buffer of a stream
16  *
17  * <a href="../handbook/operating/software/apps/streamCircBuff.html">Application Documentation</a>
18  *
19  * \ingroup apps
20  *
21  */
22 
23 /** \defgroup streamCircBuff_files
24  * \ingroup streamCircBuff
25  */
26 
27 namespace MagAOX
28 {
29 namespace app
30 {
31 
32 /// Class for application to keep a circular buffer of a stream and publish it to another stream
33 /**
34  * \ingroup streamCircBuff
35  */
36 class streamCircBuff : public MagAOXApp<true>, public dev::shmimMonitor<streamCircBuff>, public dev::frameGrabber<streamCircBuff>, public dev::telemeter<streamCircBuff>
37 {
38  friend class dev::shmimMonitor<streamCircBuff>;
39  friend class dev::frameGrabber<streamCircBuff>;
40  friend class dev::telemeter<streamCircBuff>;
41 
42 public:
43 
44  /** \name app::dev Configurations
45  *@{
46  */
47 
48  static constexpr bool c_frameGrabber_flippable = false; ///< app:dev config to tell framegrabber these images can not be flipped
49 
50  ///@}
51 
52  typedef float realT;
53 
54  /// The base shmimMonitor type
56 
57  /// The base frameGrabber type
59 
60  /// The telemeter type
62 
63 
64 protected:
65 
66  /** \name Configurable Parameters
67  *@{
68  */
69 
70 
71 
72  ///@}
73 
74  char * m_currSrc;
75 
76  sem_t m_smSemaphore {0}; ///< Semaphore used to synchronize the fg thread and the sm thread.
77 
78 public:
79  /// Default c'tor.
81 
82  /// D'tor, declared and defined for noexcept.
83  ~streamCircBuff() noexcept
84  {}
85 
86  virtual void setupConfig();
87 
88  /// Implementation of loadConfig logic, separated for testing.
89  /** This is called by loadConfig().
90  */
91  int loadConfigImpl( mx::app::appConfigurator & _config /**< [in] an application configuration from which to load values*/);
92 
93  virtual void loadConfig();
94 
95  /// Startup function
96  /**
97  *
98  */
99  virtual int appStartup();
100 
101  /// Implementation of the FSM for streamCircBuff.
102  /**
103  * \returns 0 on no critical error
104  * \returns -1 on an error requiring shutdown
105  */
106  virtual int appLogic();
107 
108  /// Shutdown the app.
109  /**
110  *
111  */
112  virtual int appShutdown();
113 
114 
115 protected:
116 
117  //shmimMonitor Interface
118  int allocate( const dev::shmimT & dummy /**< [in] tag to differentiate shmimMonitor parents.*/);
119 
121 
122  int processImage( void * curr_src, ///< [in] pointer to start of current frame.
123  const dev::shmimT & dummy ///< [in] tag to differentiate shmimMonitor parents.
124  );
125 
126  /** \name dev::frameGrabber interface
127  *
128  * @{
129  */
130 
131  /// Implementation of the framegrabber configureAcquisition interface
132  /**
133  * \returns 0 on success
134  * \returns -1 on error
135  */
136  int configureAcquisition();
137 
138  /// Implementation of the framegrabber fps interface
139  /**
140  * \todo this needs to infer the stream fps and return it
141  */
142  float fps()
143  {
144  return 1.0;
145  }
146 
147  /// Implementation of the framegrabber startAcquisition interface
148  /**
149  * \returns 0 on success
150  * \returns -1 on error
151  */
152  int startAcquisition();
153 
154  /// Implementation of the framegrabber acquireAndCheckValid interface
155  /**
156  * \returns 0 on success
157  * \returns -1 on error
158  */
159  int acquireAndCheckValid();
160 
161  /// Implementation of the framegrabber loadImageIntoStream interface
162  /**
163  * \returns 0 on success
164  * \returns -1 on error
165  */
166  int loadImageIntoStream( void * dest /**< [in] */);
167 
168  /// Implementation of the framegrabber reconfig interface
169  /**
170  * \returns 0 on success
171  * \returns -1 on error
172  */
173  int reconfig();
174 
175  /** \name Telemeter Interface
176  *
177  * @{
178  */
179  int checkRecordTimes();
180 
181  int recordTelem( const telem_fgtimings * );
182 
183  ///@}
184 
185 };
186 
187 streamCircBuff::streamCircBuff() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
188 {
189 
190  return;
191 }
192 
194 {
197  telemeterT::setupConfig(config);
198 
199 }
200 
201 int streamCircBuff::loadConfigImpl( mx::app::appConfigurator & _config )
202 {
203  shmimMonitorT::loadConfig(_config);
204  frameGrabberT::loadConfig(_config);
205  telemeterT::loadConfig(config);
206 
207  return 0;
208 }
209 
211 {
212  loadConfigImpl(config);
213 }
214 
216 {
217  if(sem_init(&m_smSemaphore, 0,0) < 0)
218  {
219  log<software_critical>({__FILE__, __LINE__, errno,0, "Initializing S.M. semaphore"});
220  return -1;
221  }
222 
223  if(shmimMonitorT::appStartup() < 0)
224  {
225  return log<software_error,-1>({__FILE__, __LINE__});
226  }
227 
228  if(frameGrabberT::appStartup() < 0)
229  {
230  return log<software_error,-1>({__FILE__, __LINE__});
231  }
232 
233  if(telemeterT::appStartup() < 0)
234  {
235  return log<software_error,-1>({__FILE__, __LINE__});
236  }
237 
239 
240  return 0;
241 }
242 
244 {
245  if( shmimMonitorT::appLogic() < 0)
246  {
247  return log<software_error,-1>({__FILE__,__LINE__});
248  }
249 
250  if( frameGrabberT::appLogic() < 0)
251  {
252  return log<software_error,-1>({__FILE__,__LINE__});
253  }
254 
255  if( telemeterT::appLogic() < 0)
256  {
257  return log<software_error,-1>({__FILE__,__LINE__});
258  }
259 
260  std::unique_lock<std::mutex> lock(m_indiMutex);
261 
262  if(shmimMonitorT::updateINDI() < 0)
263  {
264  log<software_error>({__FILE__, __LINE__});
265  }
266 
267  if(frameGrabberT::updateINDI() < 0)
268  {
269  log<software_error>({__FILE__, __LINE__});
270  }
271 
272  return 0;
273 }
274 
276 {
280 
281  return 0;
282 }
283 
285 {
286  static_cast<void>(dummy);
287 
288  //we don't actually do anything here -- just a pass through to f.g.
289  return 0;
290 }
291 
292 int streamCircBuff::processImage( void * curr_src,
293  const dev::shmimT & dummy
294  )
295 {
296  static_cast<void>(dummy);
297 
298  m_currSrc = static_cast<char *>(curr_src);
299 
300  //Now tell the f.g. to get going
301  if(sem_post(&m_smSemaphore) < 0)
302  {
303  log<software_critical>({__FILE__, __LINE__, errno, 0, "Error posting to semaphore"});
304  return -1;
305  }
306 
307  return 0;
308 }
309 
310 inline
312 {
313  std::unique_lock<std::mutex> lock(m_indiMutex);
314 
315  ///\todo potential but verrrrry unlikely bug: shmimMonitorT could change these before allocate sets the lock above. Should use a local set of w/h instead.
317  {
318  //This means we haven't connected to the stream to accumulate. so wait.
319  lock.unlock(); //don't hold the lock for a whole second.
320  sleep(1);
321  return -1;
322  }
323 
327 
328  return 0;
329 }
330 
332 {
333  return 0;
334 }
335 
337 {
338  timespec ts;
339 
340  if(clock_gettime(CLOCK_REALTIME, &ts) < 0)
341  {
342  log<software_critical>({__FILE__,__LINE__,errno,0,"clock_gettime"});
343  return -1;
344  }
345 
346  ts.tv_sec += 1;
347 
348  if(sem_timedwait(&m_smSemaphore, &ts) == 0)
349  {
350  clock_gettime(CLOCK_REALTIME, &m_currImageTimestamp);
351  return 0;
352  }
353  else
354  {
355  return 1;
356  }
357 }
358 
360 {
362  return 0;
363 }
364 
366 {
367  return 0;
368 }
369 
371 {
373 }
374 
375 inline
377 {
378  return recordFGTimings(true);
379 }
380 
381 
382 } //namespace app
383 } //namespace MagAOX
384 
385 #endif //streamCircBuff_hpp
The base-class for MagAO-X applications.
Definition: MagAOXApp.hpp:75
stateCodes::stateCodeT state()
Get the current state code.
Definition: MagAOXApp.hpp:2082
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
Definition: MagAOXApp.hpp:1590
std::mutex m_indiMutex
Mutex for locking INDI communications.
Definition: MagAOXApp.hpp:540
timespec m_currImageTimestamp
The timestamp of the current image.
uint32_t m_width
The width of the image, once deinterlaced etc.
int appShutdown()
Shuts down the framegrabber thread.
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
size_t m_typeSize
The size of the type, in bytes. Result of sizeof.
int updateINDI()
Update the INDI properties for this device controller.
uint8_t m_dataType
The ImageStreamIO type code.
int appLogic()
Checks the framegrabber thread.
uint32_t m_height
The height of the image, once deinterlaced etc.
uint32_t m_width
The width of the images in the stream.
int updateINDI()
Update the INDI properties for this device controller.
int appLogic()
Checks the shmimMonitor thread.
uint32_t m_height
The height of the images in the stream.
int appShutdown()
Shuts down the shmimMonitor thread.
uint8_t m_dataType
The ImageStreamIO type code.
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
Class for application to keep a circular buffer of a stream and publish it to another stream.
~streamCircBuff() noexcept
D'tor, declared and defined for noexcept.
dev::frameGrabber< streamCircBuff > frameGrabberT
The base frameGrabber type.
dev::shmimMonitor< streamCircBuff > shmimMonitorT
The base shmimMonitor type.
static constexpr bool c_frameGrabber_flippable
app:dev config to tell framegrabber these images can not be flipped
int acquireAndCheckValid()
Implementation of the framegrabber acquireAndCheckValid interface.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
virtual int appLogic()
Implementation of the FSM for streamCircBuff.
int allocate(const dev::shmimT &dummy)
int processImage(void *curr_src, const dev::shmimT &dummy)
int loadImageIntoStream(void *dest)
Implementation of the framegrabber loadImageIntoStream interface.
dev::telemeter< streamCircBuff > telemeterT
The telemeter type.
int recordTelem(const telem_fgtimings *)
virtual int appShutdown()
Shutdown the app.
int configureAcquisition()
Implementation of the framegrabber configureAcquisition interface.
sem_t m_smSemaphore
Semaphore used to synchronize the fg thread and the sm thread.
int reconfig()
Implementation of the framegrabber reconfig interface.
int startAcquisition()
Implementation of the framegrabber startAcquisition interface.
virtual int appStartup()
Startup function.
float fps()
Implementation of the framegrabber fps interface.
@ OPERATING
The device is operating, other than homing.
Definition: stateCodes.hpp:50
Definition: dm.hpp:24
A device which saves telemetry.
Definition: telemeter.hpp:52
int appShutdown()
Perform telemeter application shutdown.
Definition: telemeter.hpp:259
int loadConfig(appConfigurator &config)
Load the device section from an application configurator.
Definition: telemeter.hpp:208
int appLogic()
Perform telemeter application logic.
Definition: telemeter.hpp:253
int setupConfig(appConfigurator &config)
Setup an application configurator for the device section.
Definition: telemeter.hpp:195
int appStartup()
Starts the telemetry log thread.
Definition: telemeter.hpp:226
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
Definition: telemeter.hpp:266
Software ERR log entry.
Log entry recording framegrabber timings.