The VisAO Camera
framegrabber47.cpp
Go to the documentation of this file.
1 /************************************************************
2 * framegrabber47.cpp
3 *
4 * Author: Jared R. Males (jrmales@email.arizona.edu)
5 *
6 * Definitions for a class to manage the EDT PCI framegrabber for the CCD47.
7 *
8 * Developed as part of the Magellan Adaptive Optics system.
9 ************************************************************/
10 
11 /** \file framegrabber47.cpp
12  * \author Jared R. Males
13  * \brief Definitions for a class to manage the EDT PCI framegrabber for the CCD47.
14  *
15  *
16 */
17 
18 #include "framegrabber47.h"
19 
20 
21 namespace VisAO
22 {
23 
24 framegrabber47::framegrabber47(int argc, char **argv) throw (AOException) : framegrabber<short>(argc, argv)
25 {
26  init_framegrabber47();
27 }
28 
29 framegrabber47::framegrabber47(std::string name, const std::string &conffile) throw (AOException) : framegrabber<short>(name, conffile)
30 {
31  init_framegrabber47();
32 }
33 
34 void framegrabber47::init_framegrabber47()
35 {
36  edt_devname[128] = '\0';
37  channel = 0;
38  unit = 0;
39 
40  overruns = 0;
41 
42  last_timeouts = 0;
43 
44  recovering_timeout = FALSE;
45 
46  calc_dark = 0;
47 
48  //Set the number of buffers
49  try
50  {
51  num_bufs = (int)(ConfigDictionary())["num_bufs"];
52  }
53  catch(Config_File_Exception)
54  {
55  num_bufs = 4;
56  }
57  _logger->log(Logger::LOG_LEV_INFO, "Set number of DMA buffers used by EDT driver (num_bufs): %i", num_bufs);
58 
59 
60 
61  //Init the status board
63  if(create_statusboard(sizeof(basic_status_board)) != 0)
64  {
66  _logger->log(Logger::LOG_LEV_ERROR, "Could not create status board.");
67  }
68  else
69  {
71  strncpy(bsb->appname, MyFullName().c_str(), 25);
72  bsb->max_update_interval = pause_time;
73  }
74 
75 }
76 
77 
79 {
80  /*
81  * open the interface
82  *
83  * EDT_INTERFACE is defined in edtdef.h (included via edtinc.h)
84  *
85  * edt_parse_unit_channel and pdv_open_channel) are equivalent to
86  * edt_parse_unit and pdv_open except for the extra channel arg and
87  * would normally be 0 unless there's another camera (or simulator)
88  * on the second channel (camera link) or daisy-chained RCI (PCI FOI)
89  */
90  if (edt_devname[0])
91  {
92  unit = edt_parse_unit_channel(edt_devname, edt_devname, EDT_INTERFACE, &channel);
93  }
94  else
95  {
96  strcpy(edt_devname, EDT_INTERFACE);
97  }
98  //printf("%s %i % i\n", edt_devname, unit, channel);
99 
100  if ((pdv_p = pdv_open_channel(edt_devname, unit, channel)) == NULL)
101  {
102  logss.str("");
103  logss << "pdv_open_channel(" << edt_devname << unit << channel << ") failed.";
104  log_msg(Logger::LOG_LEV_ERROR, logss.str());
105  std::cerr << logss.str() << " (logged) \n";
106  return -1;
107  }
108 
109  /*
110  * get image size and name for display, save, printfs, etc.
111  */
112  width = pdv_get_width(pdv_p);
113  if(width > 1024) bias_width = width-1024;
114  else bias_width = 0;
115 
116  height = pdv_get_height(pdv_p);
117  if(height > 1024) bias_height = height-1024;
118  else bias_height = 0;
119 
120  depth = pdv_get_depth(pdv_p);
121  cameratype = pdv_get_cameratype(pdv_p);
122 
123  u_int edt_timestamp[2];
124  /*
125  * allocate buffers for optimal pdv ring buffer pipeline (reduce if
126  * memory is at a premium)
127  */
128  pdv_multibuf(pdv_p, num_bufs);
129 
130  logss.str("");
131  logss << "reading images from '" << cameratype << "' width " << width << " height " << height << " depth " << depth << ".";
132  log_msg(Logger::LOG_LEV_INFO, logss.str());
133  std::cerr << logss.str() << " (logged) \n";
134 
135  /*
136  * prestart the first image or images outside the loop to get the
137  * pipeline going. Start multiple images unless force_single set in
138  * config file, since some cameras (e.g. ones that need a gap between
139  * images or that take a serial command to start every image) don't
140  * tolerate queueing of multiple images
141  */
142 // if (pdv_p->dd_p->force_single)
143 // {
144 // pdv_start_image(pdv_p);
145 // RUNNING = 1;
146 // }
147 // else
148 // {
149  pdv_start_images(pdv_p, 0);// starts freerun (instead of using num_bufs);
150  RUNNING = num_bufs;
151 // }
152 
153 
154  logss.str("");
155  logss << "framegrabber running.";
156  log_msg(Logger::LOG_LEV_INFO, logss.str());
157  std::cerr << logss.str() << " (logged) \n";
158 
159  u_char **image_buff = pdv_buffer_addresses(pdv_p);
160  //int buffi = 0;
161  while(!STOP_FRAMEGRABBER && !TimeToDie)
162  {
163 
164  /*
165  * get the image and immediately start the next one (if not the last
166  * time through the loop). Processing (saving to a file in this case)
167  * can then occur in parallel with the next acquisition
168  */
169 
170 /* int loop_open_counter = 0;
171 
172  if(aosb) loop_open_counter == aosb->loop_open_counter;*/
173 
174  image_p = pdv_wait_image_timed(pdv_p, edt_timestamp);
175  //frameNo = edt_done_count(pdv_p);
176  gettimeofday(&tv, 0);
177  tv_dma.tv_sec = edt_timestamp[0];
178  tv_dma.tv_usec = edt_timestamp[1];
179 
180  //if(tv.tv_usec == last_usec) tv.tv_usec++;
181  //last_usec = tv.tv_usec;
182 // if(aosb && close_loop_save)
183 // {
184 // //Loop changed state during exposure - do not save.
185 // if(loop_open_counter != aosb->loop_open_counter || aosb->loop_on != 1) continue;
186 // }
187 
188  postGetImage();
189 
190  if ((overrun = (edt_reg_read(pdv_p, PDV_STAT) & PDV_OVERRUN))) ++overruns;
191 
192  if (!STOP_FRAMEGRABBER)
193  {
194  //pdv_start_image(pdv_p);
195 
196  timeouts = pdv_timeouts(pdv_p);
197  }
198  /*
199  * check for timeouts or data overruns -- timeouts occur when data
200  * is lost, camera isn't hooked up, etc, and application programs
201  * should always check for them. data overruns usually occur as a
202  * result of a timeout but should be checked for separately since
203  * ROI can sometimes mask timeouts
204  */
205  if (timeouts > last_timeouts)
206  {
207  /*
208  * pdv_timeout_cleanup helps recover gracefully after a timeout,
209  * particularly if multiple buffers were prestarted
210  */
211  pdv_timeout_restart(pdv_p, TRUE);
212  last_timeouts = timeouts;
213  recovering_timeout = TRUE;
214  logss.str("");
215  logss << "timeout.";
216  log_msg(Logger::LOG_LEV_ERROR, logss.str());
217  std::cerr << logss.str() << " (logged) \n";
218  }
219  else if (recovering_timeout)
220  {
221  pdv_timeout_restart(pdv_p, TRUE);
222  recovering_timeout = FALSE;
223  logss.str("");
224  logss << "....restarted....";
225  log_msg(Logger::LOG_LEV_ERROR, logss.str());
226  std::cerr << logss.str() << " (logged) \n";
227  }
228 
230 
231  if(calc_dark)
232  {
233  addto_dark();
234  }
235  send_ping();
236  }
237 
238 
239  logss.str("");
240  logss << frameNo << " images " << last_timeouts << " timeouts " << overruns << " overruns.";
241  log_msg(Logger::LOG_LEV_INFO, logss.str());
242  std::cerr << logss.str() << " (logged) \n";
243 
244  return stop_framegrabber();
245 }
246 
248 {
249  if(pdv_p) pdv_close(pdv_p);
250  pdv_p = 0;
251 
252  edt_devname[128] = '\0';
253  channel = 0;
254  unit = 0;
255 
256  overruns = 0;
257 
258  last_timeouts = 0;
259 
260  recovering_timeout = FALSE;
261 
262  RUNNING = 0;
263 
264  logss.str("");
265  logss << "framegrabber stopped.";
266  log_msg(Logger::LOG_LEV_INFO, logss.str());
267  std::cerr << logss.str() << " (logged) \n";
268 
269  return 0;
270 }
271 
272 } //namespace VisAO
273 
#define STATUS_framegrabber47
Shared memory key for the ccd47 framegrabber status board.
Definition: statusboard.h:43
int depth
Image bit depth.
Definition: framegrabber.h:96
void log_msg(int LogLevel, std::string lmsg)
Report an error. Also calls log_msg. Overloaded from VisAOApp_base.
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-...
virtual int stop_framegrabber()
Override this: framegrabber clean up.
int postGetImage()
Call this immediately after getting each frame. updates frameNo and saves the init file...
timeval tv_dma
Convenience variable for filling in the dma timestamp.
Definition: framegrabber.h:125
int height
Image height.
Definition: framegrabber.h:94
int frameNo
For use as a running tally of images captured.
Definition: framegrabber.h:98
std::ostringstream logss
Conveninence string stream for building log messages.
void * statusboard_shmemptr
The pointer to the shared memory block for the statusboard.
int bias_height
Height of bias stripe (if any)
Definition: framegrabber.h:95
Declarations for a class to manage the EDT PCI framegrabber for the CCD47.
key_t statusboard_shmemkey
The key used to lookup the shared memory.
int TimeToDie
Global set by SIGTERM.
double pause_time
Time to pause during application main loop.
Definition: VisAOApp_base.h:84
int STOP_FRAMEGRABBER
If true, framegrabber stops at top of next loop.
Definition: framegrabber.h:119
int create_statusboard(size_t sz)
Creates and attaches to the statusboard shared memory.
int send_ping()
Sends a ping to the waiting process (usuallly a framewriter).
u_char * image_p
Pointer to the current image data.
Definition: framegrabber.h:90
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
virtual int start_framegrabber()
Override this: it is where your framegrabber should do all its work. Check for !STOP_FRAMEGRABBER and...
int RUNNING
Status of framegrabber.
Definition: framegrabber.h:120