The VisAO Camera
framegrabber.h
Go to the documentation of this file.
1 /************************************************************
2 * framegrabber.h
3 *
4 * Author: Jared R. Males (jrmales@email.arizona.edu)
5 *
6 * Declarations and definitions for a template class to manage a generic framegrabber.
7 *
8 * Developed as part of the Magellan Adaptive Optics system.
9 ************************************************************/
10 
11 /** \file framegrabber.h
12  * \author Jared R. Males
13  * \brief Declarations and definitions for a template class to manage a generic framegrabber.
14  *
15  *
16 */
17 
18 #ifndef __framegrabber_h__
19 #define __framegrabber_h__
20 
21 #include "VisAOApp_standalone.h"
22 #include "visaoimutils.h"
23 #include "../lib/sharedim_stack.h"
24 
25 namespace VisAO
26 {
27 
28 ///The basic VisAO framegrabber.
29 /** This class provides a framework for a framegrabber which writes to a sharedim_stack.
30  * You need to provide, at a minimum overloaded members start_framegrabber and stop_framegrabber.
31  * Has local, script, and auto fifos. Is intended to be normally controlled in auto mode by the camera controller.
32  * When a frame is ready, it (optionally) issues a ping to a frame writer process and a frame server process.
33  * These pings are frame-ready notifications. The difference between the writer and the server is that the writer
34  * also manages saving (number and skipping), whereas the server only receives pings.
35  *
36  * In addition to the \ref VisAOApp_standalone config file options, has:
37  * - <b>num_sharedim</b> <tt>int</tt> [200] - the number of shared images to build into the stack
38  * - <b>max_imsize</b> <tt>int</tt> [1024x1024] - the maximum possible size of an image
39  * - <b>shmem_key</b> <tt>int</tt> [DATA_framegrabber47] - the shared memory key of the image data circular buffer
40  * - <b>dark_shmem_key</b> <tt>int</tt> [0] - the shared memory key of the dark image data circular buffer
41  * - <b>writer_ping_path</b> <tt>string</tt> - the path to the frame writer ping fifo, relative to VISAO_ROOT
42  * - <b>writer_ping_name</b> <tt>string</tt> - the name of the frame writer ping. If not set then writer ping is
43  * disabled
44  * - <b>server_ping_path</b> <tt>string</tt>- the path to the frame server ping fifo, relative to VISAO_ROOT
45  * - <b>server_ping_name</b> <tt>string</tt>- the name of the frame server ping. If not set then server ping is
46  * disabled
47  * - <b>init_save_interval</b> <tt>int</tt> [200] - how often, in frames, to save the frame number to the init
48  * file
49  *
50  * See \ref VisAOApp_standalone for command line arguments. There are no additional command line arguments for
51  * a basic framegrabber, though derived clases may add them.
52  *
53  * Commands:
54  * - <b>start</b> starts the framegrabber, returns 1
55  * - <b>stop</b> stops the framegrabber, returns 0
56  * - <b>running?</b> returns 1 if running, 0 if not
57  * - <b>save n</b> enable pings for n images
58  * - <b>save -1</b> enable pings indefinitely
59  * - <b>save 0</b> disable pings for frame writer
60  * - <b>savedark n</b> saves n dark images, and also updates the realtime dark
61  * - <b>skip n</b> when pings enabled, skip n frames between pings
62  * - <b>save?</b> status of pings for frame writer (returns value of save)
63  * - <b>skip?</b> returns the number of images being skipped
64  * - <b>dark n</b> calculates a new realtime dark image (average) from the next n frames
65  * - <b>serve 1</b> enable pings for the frame server
66  * - <b>serve 0</b> disable pings for the frame server
67  * - <b>serve?</b> status of pings for frame server
68  * - <b>state?</b> returns a string of the form "A,B,C,D,E,F" where the fields indicate:
69  * - A is the one letter control mode (N,R,L,S,or A)
70  * - B is the running state, 1 or 0
71  * - C is the status of saving, 0, n, or -1
72  * - D is the status of skipping, 0..n
73  * - E is the number of saves remaining
74  * - F is the status of the server ping
75  *
76  *
77  */
78 template <class dataT> class framegrabber : public VisAOApp_standalone
79 {
80  public:
81  framegrabber(int argc, char **argv) throw (AOException);
82  framegrabber(std::string, const std::string &conffile) throw (AOException);
83 
84  ~framegrabber();
85 
86  protected:
87  ///Processes the config file
88  void Create();
89 
90  u_char *image_p; ///< Pointer to the current image data.
91 
92  int width; ///<Image width
93  int bias_width; ///<Width of bias stripe (if any)
94  int height; ///<Image height
95  int bias_height; ///<Height of bias stripe (if any)
96  int depth; ///<Image bit depth
97 
98  int frameNo; ///<For use as a running tally of images captured
99 
100  sharedim_stack<dataT> sis; ///< The shared memory ring buffer for image storage
101  sharedim<dataT> * sim; ///< Pointer to a shared memory image
102 
103  int shmem_key; ///< The key for the shared memory
104  int dark_shmem_key; ///< The key for the darks shared memory
105  int num_sharedim; ///< The number of shared images available in the buffer
106  size_t max_imsize; ///<The maximum size (x*y) of images that will be put in this buffer.
107 
108  int hasWriterPing; ///<If true, open fifo for pinging the framewriter
109  int writerPingEnabled; ///<Send pings on frame ready when true
110  int writerPingChan; ///<The fifo channel for the writer pings
111  int saves_remaining; ///<Number pings left to issue
112  int num_skip; ///<The number of frames to skip between pings
113  int skips_remaining; ///<Skips remaining
114 
115  int hasServerPing; ///<If true, open fifo for pinging the frame server
116  int serverPingEnabled; ///<Send pings on frame ready when true
117  int serverPingChan; ///<The fifo channel for the writer pings
118 
119  int STOP_FRAMEGRABBER;///<If true, framegrabber stops at top of next loop.
120  int RUNNING; ///<Status of framegrabber
121 
122  int sh_i; ///<Convenience variable for loops
123  int sh_j; ///<Convenience variable for loops
124  timeval tv; ///<Convenience variable for filling in the frame time in the image header
125  timeval tv_dma; ///<Convenience variable for filling in the dma timestamp
126 
127  //Calculating darks
128  sharedim_stack<dataT> dark_sis; ///< The shared memory ring buffer for image storage
129  sharedim<dataT> * dark_sim; ///< Pointer to a shared memory image
130  std::vector<dataT> dark_temp; ///<Temporary data storage for dark calculations
131 
132  int calc_dark;
133 
134  int addto_dark();
135 
136  int no_darks_added;
137 
138 
139  public:
140  virtual int Run(); ///<Main loop, normally won't need to be overridden
141 
142  virtual int start_framegrabber(); ///<Override this: it is where your framegrabber should do all its work. Check for !STOP_FRAMEGRABBER and !TimeToDie
143  virtual int stop_framegrabber(); ///<Override this: framegrabber clean up.
144 
145  int postGetImage(); ///< Call this immediately after getting each frame. updates frameNo and saves the init file
146 
147  ///Sends a ping to the waiting process (usuallly a framewriter).
148  /**Contains the logic for number of saves and skipping frames.
149  *Should be called after one of the copyto functions completes.
150  *\retval 0 on success
151  *\retval -1 on failure
152  */
153  int send_ping();
154 
155  ///Copies the image data to shared memory, as shorts
156  int copyto_sharedim_short(unsigned char * im);
157 
158  ///Copies the image data to shared memory, as shorts, rotated by 90 degrees
159  int copyto_sharedim_short_rotated(unsigned char * im);
160 
161  ///Copies the image to data to shared memory, as shorts, rotated by 90 degrees, with DALSA 2 channel de-interleaving
162  int copyto_sharedim_short_deintlv_rotated(unsigned char * im);
163 
164  std::string local_command(std::string com);
165  std::string script_command(std::string com);
166  std::string auto_command(std::string com, char *seqmsg);
167  std::string common_command(std::string com, int cmode);
168 
169  protected:
170  ///Save the initialization data to disk
171  int save_init();
172 
173  int init_save_interval;
174 
175  ///Delete the initialization file
176  int delete_init();
177 };
178 
179 
180 template <class dataT> framegrabber<dataT>::framegrabber(int argc, char **argv) throw (AOException) : VisAOApp_standalone(argc, argv)
181 {
182  Create();
183 }
184 
185 template <class dataT> framegrabber<dataT>::framegrabber(std::string name, const std::string &conffile) throw (AOException) : VisAOApp_standalone(name, conffile)
186 {
187  Create();
188 }
189 
190 template <class dataT> framegrabber<dataT>::~framegrabber()
191 {
192  save_init();
193 }
194 
195 template <class dataT> void framegrabber<dataT>::Create()
196 {
197  //Set the number of images in the shared image buffer
198  try
199  {
200  num_sharedim = (int)(ConfigDictionary())["num_sharedim"];
201  }
202  catch(Config_File_Exception)
203  {
204  num_sharedim = 200;
205  }
206  _logger->log(Logger::LOG_LEV_INFO, "Set number of images in the shared image buffer (num_sharedim): %i", num_sharedim);
207 
208  try
209  {
210  max_imsize = (int)(ConfigDictionary())["max_imsize"];
211  }
212  catch(Config_File_Exception)
213  {
214  max_imsize = 1024*1024;
215  }
216  _logger->log(Logger::LOG_LEV_INFO, "Set the maximum image size to (max_imsize): %i", max_imsize);
217 
218  try
219  {
220  shmem_key = (int)(ConfigDictionary())["shmem_key"];
221  }
222  catch(Config_File_Exception)
223  {
224  shmem_key = DATA_framegrabber47;
225  }
226  _logger->log(Logger::LOG_LEV_INFO, "Set the shared memory key (shmem_key): %i", shmem_key);
227 
228  try
229  {
230  dark_shmem_key = (int)(ConfigDictionary())["dark_shmem_key"];
231  }
232  catch(Config_File_Exception)
233  {
234  dark_shmem_key = 0;
235  }
236  _logger->log(Logger::LOG_LEV_INFO, "Set the shared memory key (dark_shmem_key): %i", shmem_key);
237 
238 
239  std::string wPingPath, wPingName;
240  //Set the writer ping fifo base path
241  try
242  {
243  wPingPath = (std::string)(ConfigDictionary())["writer_ping_path"];
244  }
245  catch(Config_File_Exception)
246  {
247  wPingPath = "fifos";
248  }
249 
250  try
251  {
252  wPingName = (std::string)(ConfigDictionary())["writer_ping_name"];
253  hasWriterPing = 1;
254  }
255  catch(Config_File_Exception)
256  {
257  hasWriterPing = 0;
258  }
259 
260  std::string sPingPath, sPingName;
261  //Set the server ping fifo base path
262  try
263  {
264  sPingPath = (std::string)(ConfigDictionary())["server_ping_path"];
265  hasServerPing = 1;
266  }
267  catch(Config_File_Exception)
268  {
269  hasServerPing = 0;
270  }
271 
272  try
273  {
274  sPingName = (std::string)(ConfigDictionary())["server_ping_name"];
275  hasServerPing = 1;
276  }
277  catch(Config_File_Exception)
278  {
279  hasServerPing = 0;
280  }
281 
282  //set up the fifos
283  setup_fifo_list(3+hasWriterPing + hasServerPing);
284  setup_baseApp(0, 1, 1, 1, false);
285 
286  std::string tmppath;
287  std::string visao_root = getenv("VISAO_ROOT");
288 
289  int nPings = 0;
290  if(hasWriterPing)
291  {
292  tmppath = visao_root + "/" + wPingPath + "/" + wPingName;
293 
294  writerPingChan = nPings;
295 
296  //get the pingfifoXX
297  set_fifo_list_channel(&fl, writerPingChan, RWBUFF_SZ, std::string(tmppath+"_out").c_str(),std::string(tmppath+"_in").c_str(), 0, 0);
298  _logger->log(Logger::LOG_LEV_INFO, "Set writer ping: %s", tmppath.c_str());
299  nPings++;
300  }
301 
302  serverPingEnabled = 0;
303  if(hasServerPing)
304  {
305  tmppath = visao_root + "/" + sPingPath + "/" + sPingName;
306 
307  serverPingChan = nPings;
308 
309  //get the pingfifoXX
310  set_fifo_list_channel(&fl, serverPingChan, RWBUFF_SZ, std::string(tmppath+"_out").c_str(),std::string(tmppath+"_in").c_str(), 0, 0);
311  _logger->log(Logger::LOG_LEV_INFO, "Set server ping", tmppath.c_str());
312 
313  nPings++;
314  serverPingEnabled = 1;
315  }
316 
317  try
318  {
319  init_save_interval = (int)(ConfigDictionary())["init_save_interval"];
320  }
321  catch(Config_File_Exception)
322  {
323  init_save_interval = 100;
324  }
325  _logger->log(Logger::LOG_LEV_INFO, "Set interval to save init info to disk (init_save_interval): %i", init_save_interval);
326 
327 
328  if(init_vars)
329  {
330  try
331  {
332  frameNo = (*init_vars)["frameNo"];
333  }
334  catch(Config_File_Exception)
335  {
336  frameNo = 0;
337  }
338  }
339 
340  //Init darks shared memory buffer
341  int num_darks = 1;
342 
343  if(dark_shmem_key)
344  {
345  if(dark_sis.create_shm(dark_shmem_key, num_sharedim, sizeof(sharedim_stack_header) + num_darks*sizeof(intptr_t) + (num_darks)*(sizeof(sharedim<dataT>) + max_imsize*sizeof(dataT))) != 0)
346  {
347  ERROR_REPORT("Error attaching to shared memory for dark frame.");
348 
349  exit(0);
350  }
351  dark_sis.header->save_sequence = 0;
352  dark_sim = dark_sis.set_next_image(1024, 1024);
353  dark_temp.resize(1024*1024);
354  dark_sis.enable_next_image();
355 
356  for(sh_i=0; sh_i<1024; sh_i++)
357  {
358  for(sh_j=0; sh_j<1024; sh_j++)
359  {
360  dark_sim->imdata[sh_i*1024+sh_j] = 0.;
361  }
362  }
363  }//if(dark_shmem_key)
364 
365  writerPingEnabled = 0;
366 
367  num_skip = 0;
368 
369  STOP_FRAMEGRABBER = 1;
370  RUNNING = 0;
371 
372  bias_width = 0;
373  bias_height = 0;
374 
375 }
376 
377 template <class dataT> int framegrabber<dataT>::Run()
378 {
379  if(sis.create_shm(shmem_key, num_sharedim, sizeof(sharedim_stack_header) + num_sharedim*sizeof(intptr_t) + (num_sharedim)*(sizeof(sharedim<dataT>) + max_imsize*sizeof(dataT))) != 0)
380  {
381  ERROR_REPORT("Error attaching to shared memory.");
382  return -1;
383  }
384 
385  sis.header->save_sequence = 0;
386 
387  //Install the main thread handler
388  if(install_sig_mainthread_catcher() != 0)
389  {
390  ERROR_REPORT("Error installing main thread catcher.");
391  return -1;
392  }
393 
394  signal(SIGIO, SIG_IGN);
395 
396  //Startup the I/O signal handling thread
397  if(start_signal_catcher() != 0)
398  {
399  ERROR_REPORT("Error starting signal catching thread.");
400  return -1;
401  }
402 
403  //Now Block all I/O signals in this thread.
404  if(block_sigio() != 0)
405  {
406  ERROR_REPORT("Error starting signal catching thread.");
407  return -1;
408  }
409 
410  LOG_INFO("starting up . . .");
411 
412 
413  while(!TimeToDie)
414  {
415  pthread_mutex_lock(&signal_mutex);
416  pthread_cond_wait(&signal_cond, &signal_mutex);
417  pthread_mutex_unlock(&signal_mutex);
418 
419  if(!STOP_FRAMEGRABBER) start_framegrabber();
420  }
421 
422  pthread_join(signal_thread, 0);
423 
424  return 0;
425 
426 }
427 
428 template <class dataT> int framegrabber<dataT>::start_framegrabber()
429 {
430  return 0;
431 }
432 
433 template <class dataT> int framegrabber<dataT>::stop_framegrabber()
434 {
435  return 0;
436 }
437 
438 template <class dataT> int framegrabber<dataT>::postGetImage()
439 {
440  frameNo++;
441 
442  if((frameNo % init_save_interval) == 0) save_init();
443 
444  return 0;
445 }
446 
447 template <class dataT> int framegrabber<dataT>::send_ping()
448 {
449  //issue pings to notify waiting processes that the data is ready.
450  if(writerPingEnabled)
451  {
452  if(skips_remaining <= 0)
453  {
454  skips_remaining = num_skip;
455  write_fifo_channel(writerPingChan, "1", 2, 0);
456  if(saves_remaining > 0) saves_remaining--;
457  if(saves_remaining == 0)
458  {
459  writerPingEnabled = 0;
460  std::cout << '\a' << std::endl; //Beep to say saving done.
461  }
462  }
463  else
464  {
465  if(skips_remaining == 1)
466  {
467  sis.header->save_sequence++;
468  write_fifo_channel(writerPingChan, "1", 2, 0); //On first ping after new sequence, no image is saved.
469  }
470  skips_remaining--;
471  }
472  }
473 
474  if(serverPingEnabled)
475  {
476  write_fifo_channel(serverPingChan, "1", 2, 0);
477  }
478 
479  return 0;
480 }
481 
482 template <class dataT> int framegrabber<dataT>::copyto_sharedim_short(unsigned char * im)
483 {
484  sim = sis.set_next_image(width, height);
485  sim->depth = depth;
486  sim->frameNo = frameNo;
487  sim->saved = 0;
488 
489  if(sim > 0)
490  {
491  for(sh_i=0; sh_i<width; sh_i++)
492  {
493  for(sh_j=0; sh_j<height; sh_j++)
494  {
495  sim->imdata[sh_i*width+sh_j] = (short) ((short *)im)[sh_i*width+sh_j];
496  }
497  }
498  sim->frame_time = tv;
499  sim->frame_time_dma = tv_dma;
500  sis.enable_next_image();
501  }
502 
503  return 0;
504 }
505 
506 template <class dataT> int framegrabber<dataT>::copyto_sharedim_short_rotated(unsigned char * im)
507 {
508  sim = sis.set_next_image(width, height);
509  sim->depth = depth;
510  sim->frameNo = frameNo;
511  sim->saved = 0;
512 
513  if(sim > 0)
514  {
515  for(sh_i=0; sh_i<width; sh_i++)
516  {
517  for(sh_j=0; sh_j<height; sh_j++)
518  {
519  sim->imdata[sh_i*width+sh_j] = (short) ((short *)im)[sh_j*width+sh_i];
520  }
521  }
522  sim->frame_time = tv;
523  sim->frame_time_dma = tv_dma;
524  sis.enable_next_image();
525  }
526 
527  return 0;
528 }
529 
530 template <class dataT> int framegrabber<dataT>::copyto_sharedim_short_deintlv_rotated(unsigned char * im)
531 {
532  sim = sis.set_next_image(height, width);
533  sim->depth = depth;
534  sim->frameNo = frameNo;
535  sim->saved = 0;
536 
537  if(sim > 0)
538  {
539  int sh_k = 0;
540 
541  for(sh_i=0; sh_i<(height-bias_height); sh_i+=2, sh_k++)
542  {
543  /*for(sh_j=0; sh_j<(height-bias_height); sh_j+=1)
544  * {
545  * sim->imdata[sh_k*(width-bias_width)+sh_j] = (short) ((short *)im)[sh_j*(width-bias_width)+sh_i];
546  }*/
547  for(sh_j=(width-bias_width)-1; sh_j>=0; sh_j-=1)
548  {
549  sim->imdata[sh_k*(height-bias_height)+sh_j] = (short) ((short *)im)[sh_j*(height-bias_height)+sh_i];
550  }
551  }
552 
553  sh_k = (height-bias_height)-1;
554  for(sh_i=1; sh_i<(height-bias_height); sh_i+=2, sh_k--)
555  {
556  /*for(sh_j=0; sh_j< (height-bias_height); sh_j+=1)
557  * {
558  * sim->imdata[sh_k*(width-bias_width)+sh_j] = (short) ((short *)im)[sh_j*(width-bias_width)+sh_i];
559  }*/
560  for(sh_j=(width-bias_width)-1; sh_j>= 0; sh_j-=1)
561  {
562  sim->imdata[sh_k*(height-bias_height)+sh_j] = (short) ((short *)im)[sh_j*(height-bias_height)+sh_i];
563  }
564  }
565  sim->frame_time = tv;
566  sim->frame_time_dma = tv_dma;
567  sis.enable_next_image();
568  }
569  return 0;
570 }
571 
572 template <class dataT> int framegrabber<dataT>::addto_dark()
573 {
574  if(!dark_shmem_key) return 0;
575 
576  if(no_darks_added == 0)
577  {
578  dark_sim->depth = depth;
579  dark_sim->nx = width;
580  dark_sim->ny = height;
581  for(sh_i=0; sh_i<width; sh_i++)
582  {
583  for(sh_j=0; sh_j<height; sh_j++)
584  {
585  dark_temp[sh_i*width+sh_j] =0;
586  }
587  }
588  std::cout << dark_sim->imdata << std::endl;
589  }
590 
591  if(no_darks_added < calc_dark)
592  {
593  if(sim > 0)
594  {
595  for(sh_i=0; sh_i<width; sh_i++)
596  {
597  for(sh_j=0; sh_j<height; sh_j++)
598  {
599  dark_temp[sh_i*width+sh_j] += sim->imdata[sh_i*width+sh_j];
600  }
601  }
602  }
603  no_darks_added++;
604  }
605  else
606  {
607  for(sh_i=0; sh_i<width; sh_i++)
608  {
609  for(sh_j=0; sh_j<height; sh_j++)
610  {
611  dark_sim->imdata[sh_i*width+sh_j] = (int) ((double)dark_temp[sh_i*width+sh_j])/((double) no_darks_added);
612  //std::cout << dark_sim->imdata[sh_i*width+sh_j] << " ";
613  }
614  }
615  //std::cout << "\n";
616  calc_dark = 0;
617  no_darks_added = 0;
618  }
619 }
620 
621 template <class dataT> std::string framegrabber<dataT>::local_command(std::string com)
622 {
623  std::string resp;
624  _logger->log(Logger::LOG_LEV_TRACE, "Received local command: %s.", com.c_str());
625  resp = common_command(com, CMODE_LOCAL);
626  if(resp == "") resp = "UNKOWN COMMAND\n";
627  _logger->log(Logger::LOG_LEV_TRACE, "Response to local command: %s.", resp.c_str());
628  return resp;
629 }
630 
631 template <class dataT> std::string framegrabber<dataT>::script_command(std::string com)
632 {
633  std::string resp;
634  std::cout << "In script command" << std::endl;
635  _logger->log(Logger::LOG_LEV_TRACE, "Received script command: %s.", com.c_str());
636  resp = common_command(com, CMODE_SCRIPT);
637  if(resp == "") resp = "UNKOWN COMMAND\n";
638  _logger->log(Logger::LOG_LEV_TRACE, "Response to script command: %s.", resp.c_str());
639  return resp;
640 }
641 
642 template <class dataT> std::string framegrabber<dataT>::auto_command(std::string com, char *seqmsg __attribute__((unused)))
643 {
644  std::string resp;
645  _logger->log(Logger::LOG_LEV_TRACE, "Received auto command: %s.", com.c_str());
646  resp = common_command(com, CMODE_AUTO);
647 
648  if(resp == "") resp = post_auto_command(com);
649  _logger->log(Logger::LOG_LEV_TRACE, "Response to auto command: %s.", resp.c_str());
650  return resp;
651 }
652 
653 template <class dataT> std::string framegrabber<dataT>::common_command(std::string com, int cmode)
654 {
655  char rstr[50];
656 
657  cmode = cmode;
658 
659  if(com == "start")
660  {
661  if(cmode == control_mode)
662  {
663  STOP_FRAMEGRABBER = 0;
664 
665  return "0\n";
666  }
667  else return control_mode_response();
668  }
669 
670  if(com == "stop")
671  {
672  if(cmode == control_mode)
673  {
674  STOP_FRAMEGRABBER = 1;
675  pthread_kill(main_thread, SIG_MAINTHREAD);
676  writerPingEnabled = 0;
677  saves_remaining = 0;
678  }
679  else return control_mode_response();
680 
681  return "0\n";
682  }
683 
684  if(com == "running?")
685  {
686  if(RUNNING) return "1\n";
687  else return "0\n";
688  }
689 
690  if(com == "save?")
691  {
692  if(writerPingEnabled ) return "1\n";
693  else return "0\n";
694  }
695 
696  if(com == "serve?")
697  {
698  if(serverPingEnabled ) return "1\n";
699  else return "0\n";
700  }
701 
702  if(com == "remaining?")
703  {
704  snprintf(rstr, 50, "%i\n", saves_remaining);
705  return rstr;
706  }
707 
708  if(com == "skip?")
709  {
710  snprintf(rstr, 50, "%i\n", num_skip);
711  return rstr;
712  }
713 
714  if(com.substr(0,4) == "skip")
715  {
716  if(cmode == control_mode)
717  {
718  int nskip = atoi(com.substr(5, com.length()-5).c_str());
719 
720  if(nskip > 0) num_skip = nskip;
721  else num_skip = 0;
722  return "0\n";
723  }
724  else return control_mode_response();
725  }
726 
727  if(com.substr(0,8) == "savedark")
728  {
729  if(cmode == control_mode)
730  {
731  int nsav = atoi(com.substr(9, com.length()-9).c_str());
732  std::cout << nsav << "\n";
733  if(nsav != 0 && !writerPingEnabled)
734  {
735  writerPingEnabled = 1;
736  sis.header->save_sequence++;
737  saves_remaining = nsav; //don't know why yet, but framewriter skips first ping.
738  skips_remaining = 0; //save first one, then start skipping.
739 
740  calc_dark = nsav;
741  no_darks_added = 0;
742 
743  }
744 
745  if(nsav == 0)
746  {
747  calc_dark = 0;
748  writerPingEnabled = 0;
749  saves_remaining = 0;
750  }
751 
752  return "0\n";
753  }
754  else return control_mode_response();
755  }
756 
757  if(com.substr(0,4) == "save")
758  {
759  if(cmode == control_mode)
760  {
761  int nsav = atoi(com.substr(5, com.length()-5).c_str());
762 
763  if(nsav != 0 && !writerPingEnabled)
764  {
765  writerPingEnabled = 1;
766  sis.header->save_sequence++;
767  if(nsav > 0) saves_remaining = nsav; //don't know why yet, but framewriter skips first ping.
768  else saves_remaining = -1;
769  skips_remaining = 0; //save first one, then start skipping.
770  }
771 
772  if(nsav == 0)
773  {
774  writerPingEnabled = 0;
775  saves_remaining = 0;
776  }
777 
778  return "0\n";
779  }
780  else return control_mode_response();
781  }
782 
783 
784 
785  if(com.substr(0,4) == "dark")
786  {
787  if(cmode == control_mode)
788  {
789  int ndrk = atoi(com.substr(5, com.length()-5).c_str());
790 
791  if(ndrk > 0)
792  {
793  calc_dark = ndrk;
794  no_darks_added = 0;
795  }
796  else calc_dark = 0;
797  return "0\n";
798  }
799  else return control_mode_response();
800  }
801 
802  if(com.substr(0,5) == "serve")
803  {
804  if(cmode == control_mode)
805  {
806  int nsav = atoi(com.substr(5, com.length()-5).c_str());
807 
808  if(nsav != 0)
809  {
810  serverPingEnabled = 1;
811  if(writerPingEnabled == 0) sis.header->save_sequence++; //don't scram the writer
812  }
813 
814  if(nsav == 0)
815  {
816  serverPingEnabled = 0;
817  }
818 
819  return "0\n";
820  }
821  else return control_mode_response();
822  }
823 
824  if(com == "state?")
825  {
826  snprintf(rstr, 50, "%c,%i,%i,%i,%i,%i\n", control_mode_response()[0], RUNNING, writerPingEnabled, num_skip, saves_remaining-1, serverPingEnabled);
827  return rstr;
828  }
829 
830  return "";
831 };
832 
833 
834 template <class dataT> int framegrabber<dataT>::save_init()
835 {
836  std::ofstream of;
837 
838  of.open((std::string(getenv("VISAO_ROOT")) + "/" + init_file).c_str());
839 
840  of.precision(10);
841  of << "frameNo int " << frameNo << "\n";
842 
843  of.close();
844 
845  return 0;
846 }
847 
848 template <class dataT> int framegrabber<dataT>::delete_init()
849 {
850  remove((std::string(getenv("VISAO_ROOT")) + "/" + init_file).c_str());
851 
852  return 0;
853 }
854 
855 
856 } //namespace VisAO
857 
858 
859 #endif //__framegrabber_h__
sharedim_stack< dataT > dark_sis
The shared memory ring buffer for image storage.
Definition: framegrabber.h:128
int depth
Image bit depth.
Definition: framegrabber.h:96
int copyto_sharedim_short_deintlv_rotated(unsigned char *im)
Copies the image to data to shared memory, as shorts, rotated by 90 degrees, with DALSA 2 channel de-...
Definition: framegrabber.h:530
int write_fifo_channel(fifo_channel *fc, const char *com, int comlen)
Write data to the output channel.
Definition: fifoutils.c:194
int postGetImage()
Call this immediately after getting each frame. updates frameNo and saves the init file...
Definition: framegrabber.h:438
int setup_fifo_list(fifo_list *fl, int nch)
Setup a fifo_list.
Definition: fifoutils.c:354
virtual int stop_framegrabber()
Override this: framegrabber clean up.
Definition: framegrabber.h:433
sharedim< dataT > * dark_sim
Pointer to a shared memory image.
Definition: framegrabber.h:129
timeval tv_dma
Convenience variable for filling in the dma timestamp.
Definition: framegrabber.h:125
sharedim_stack< dataT > sis
The shared memory ring buffer for image storage.
Definition: framegrabber.h:100
int writerPingChan
The fifo channel for the writer pings.
Definition: framegrabber.h:110
int height
Image height.
Definition: framegrabber.h:94
int copyto_sharedim_short_rotated(unsigned char *im)
Copies the image data to shared memory, as shorts, rotated by 90 degrees.
Definition: framegrabber.h:506
The standalone VisAO application, does not interface with the AO Supervisor.
int dark_shmem_key
The key for the darks shared memory.
Definition: framegrabber.h:104
int serverPingChan
The fifo channel for the writer pings.
Definition: framegrabber.h:117
int delete_init()
Delete the initialization file.
Definition: framegrabber.h:848
int saves_remaining
Number pings left to issue.
Definition: framegrabber.h:111
int frameNo
For use as a running tally of images captured.
Definition: framegrabber.h:98
std::vector< dataT > dark_temp
Temporary data storage for dark calculations.
Definition: framegrabber.h:130
int bias_height
Height of bias stripe (if any)
Definition: framegrabber.h:95
std::string local_command(std::string com)
Called by __local_command after control state logic.
Definition: framegrabber.h:621
int width
Image width.
Definition: framegrabber.h:92
Declarations for the standalone VisAO application.
int sh_j
Convenience variable for loops.
Definition: framegrabber.h:123
int save_init()
Save the initialization data to disk.
Definition: framegrabber.h:834
sharedim< dataT > * sim
Pointer to a shared memory image.
Definition: framegrabber.h:101
int shmem_key
The key for the shared memory.
Definition: framegrabber.h:103
int num_skip
The number of frames to skip between pings.
Definition: framegrabber.h:112
int hasServerPing
If true, open fifo for pinging the frame server.
Definition: framegrabber.h:115
int skips_remaining
Skips remaining.
Definition: framegrabber.h:113
Convenience structure for the stack header.
int writerPingEnabled
Send pings on frame ready when true.
Definition: framegrabber.h:109
int hasWriterPing
If true, open fifo for pinging the framewriter.
Definition: framegrabber.h:108
int TimeToDie
Global set by SIGTERM.
int num_sharedim
The number of shared images available in the buffer.
Definition: framegrabber.h:105
virtual int Run()
Main loop, normally won't need to be overridden.
Definition: framegrabber.h:377
int serverPingEnabled
Send pings on frame ready when true.
Definition: framegrabber.h:116
std::string script_command(std::string com)
Called by __script_command after control state logic.
Definition: framegrabber.h:631
int STOP_FRAMEGRABBER
If true, framegrabber stops at top of next loop.
Definition: framegrabber.h:119
void Create()
Processes the config file.
Definition: framegrabber.h:195
#define DATA_framegrabber47
Shared memory key for ccd47 data.
Definition: statusboard.h:26
int send_ping()
Sends a ping to the waiting process (usuallly a framewriter).
Definition: framegrabber.h:447
The basic VisAO framegrabber.
Definition: framegrabber.h:78
int sh_i
Convenience variable for loops.
Definition: framegrabber.h:122
u_char * image_p
Pointer to the current image data.
Definition: framegrabber.h:90
std::string auto_command(std::string com, char *seqmsg)
Processing for auto commands - to be overriden.
Definition: framegrabber.h:642
virtual int start_framegrabber()
Override this: it is where your framegrabber should do all its work. Check for !STOP_FRAMEGRABBER and...
Definition: framegrabber.h:428
The namespace of VisAO software.
int bias_width
Width of bias stripe (if any)
Definition: framegrabber.h:93
timeval tv
Convenience variable for filling in the frame time in the image header.
Definition: framegrabber.h:124
size_t max_imsize
The maximum size (x*y) of images that will be put in this buffer.
Definition: framegrabber.h:106
Declarations for various image utility functions.
#define RWBUFF_SZ
The size of the i/o buffer.
Definition: fifoutils.h:43
int copyto_sharedim_short(unsigned char *im)
Copies the image data to shared memory, as shorts.
Definition: framegrabber.h:482
int set_fifo_list_channel(fifo_list *fl, int nch, int buffsz, const char *fin, const char *fout, int(*inp_hand)(fifo_channel *), void *adata)
Set the details of one channel in the list.
Definition: fifoutils.c:373
int RUNNING
Status of framegrabber.
Definition: framegrabber.h:120