Fawkes API  Fawkes Development Version
retriever_thread.cpp
1 
2 /***************************************************************************
3  * retriever_thread.cpp - FireVision Retriever Thread
4  *
5  * Created: Tue Jun 26 17:39:11 2007
6  * Copyright 2006-2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "retriever_thread.h"
24 
25 #include <fvcams/camera.h>
26 #include <fvutils/ipc/shm_image.h>
27 #include <utils/time/tracker.h>
28 #include <fvutils/writers/seq_writer.h>
29 #include <fvutils/writers/jpeg.h>
30 #include <fvmodels/color/lookuptable.h>
31 
32 #include <cstring>
33 #include <cstdlib>
34 
35 using namespace fawkes;
36 using namespace firevision;
37 
38 /** @class FvRetrieverThread "retriever_thread.h"
39  * FireVision retriever thread.
40  * This implements the functionality of the FvRetrieverPlugin.
41  * @author Tim Niemueller
42  */
43 
44 /** Constructor.
45  * @param camera_string camera argument string for camera to open
46  * @param cfg_name ID used to form thread name (FvRetrieverThread_[ID]) and shared
47  * memory image segment ID (retriever_[ID]).
48  * @param cfg_prefix configuration prefix path
49  */
50 FvRetrieverThread::FvRetrieverThread(std::string camera_string,
51  std::string cfg_name, std::string cfg_prefix)
52  : Thread("FvRetrieverThread", Thread::OPMODE_WAITFORWAKEUP),
53  VisionAspect(VisionAspect::CYCLIC)
54 {
55  cfg_name_ = cfg_name;
56  cfg_prefix_ = cfg_prefix;
57  camera_string_ = camera_string;
58  set_name("FvRetrieverThread_%s", cfg_name_.c_str());
59  seq_writer = NULL;
60 }
61 
62 
63 /** Destructor. */
65 {
66 }
67 
68 
69 void
71 {
72  colorspace_t cspace = YUV422_PLANAR;
73  std::string cspace_str = colorspace_to_string(cspace);
74  try {
75  cspace_str = config->get_string((cfg_prefix_ + "colorspace").c_str());
76  cspace = colorspace_by_name(cspace_str.c_str());
77  } catch (Exception &e) {} // ignored, use default
78  if (cspace == CS_UNKNOWN) {
79  throw Exception("Unknown colorspace '%s' configured", cspace_str.c_str());
80  }
81 
82  try {
83  logger->log_debug(name(), "Registering for camera '%s' (colorspace %s)",
84  camera_string_.c_str(), colorspace_to_string(cspace));
85  cam = vision_master->register_for_camera(camera_string_.c_str(), this, cspace);
86  } catch (Exception &e) {
87  e.append("FvRetrieverThread::init() failed");
88  throw;
89  }
90  try {
91  char *imgbufname;
92  if ( asprintf(&imgbufname, "retriever_%s", cfg_name_.c_str()) == -1 ) {
93  throw Exception("Cannot allocate buffer name");
94  }
95  shm = new SharedMemoryImageBuffer(imgbufname, cam->colorspace(),
96  cam->pixel_width(), cam->pixel_height());
97 
98  free(imgbufname);
99  if ( ! shm->is_valid() ) {
100  throw Exception("Shared memory segment not valid");
101  }
102  } catch (Exception &e) {
103  delete cam;
104  cam = NULL;
105  throw;
106  }
107 
108  try {
109  std::string frame_id = config->get_string((cfg_prefix_ + "frame").c_str());
110  shm->set_frame_id(frame_id.c_str());
111  } catch (Exception &e) {/* ignored, not critical */}
112 
113  seq_writer = NULL;
114  try {
115  if ( config->get_bool("/firevision/retriever/save_images") ) {
116  logger->log_info(name(), "Writing images to disk");
117  Writer* writer = new JpegWriter();
118  seq_writer = new SeqWriter(writer);
119  std::string save_path;
120  try {
121  save_path = config->get_string("/firevision/retriever/save_path");
122  } catch (Exception &e) {
123  save_path = ("recorded_images");
124  logger->log_info(name(), "No save path specified. Using './%s'", save_path.c_str());
125  }
126  seq_writer->set_path( save_path.c_str() );
127  seq_writer->set_dimensions( cam->pixel_width(), cam->pixel_height() );
128  seq_writer->set_colorspace( cam->colorspace() );
129  }
130  } catch (Exception &e) {
131  // ignored, not critical
132  }
133 
134  __tt = NULL;
135  try {
136  if ( config->get_bool("/firevision/retriever/use_time_tracker") ) {
137  __tt = new TimeTracker();
138  __ttc_capture = __tt->add_class("Capture");
139  __ttc_memcpy = __tt->add_class("Memcpy");
140  __ttc_dispose = __tt->add_class("Dispose");
141  __loop_count = 0;
142  }
143  } catch (Exception &e) {
144  // ignored, not critical
145  }
146 
147  __cm = new ColorModelLookupTable(1, "retriever-colormap", true);
148  YuvColormap *ycm = __cm->get_colormap();
149  for (unsigned int u = 100; u < 150; ++u) {
150  for (unsigned int v = 100; v < 150; ++v) {
151  ycm->set(128, u, v, C_ORANGE);
152  }
153  }
154 
155  __cam_has_timestamp_support = true;
156  try {
157  fawkes::Time *t = cam->capture_time();
158  if (t->is_zero()) {
159  throw NotImplementedException("");
160  }
161  cap_time_ = NULL;
162  }
163  catch (NotImplementedException &e)
164  {
165  __cam_has_timestamp_support = false;
166  cap_time_ = new Time(clock);
167  }
168 }
169 
170 
171 void
173 {
174  logger->log_debug(name(), "Unregistering from vision master");
176  delete cam;
177  delete shm;
178  delete seq_writer;
179  delete __tt;
180  delete __cm;
181  delete cap_time_;
182 }
183 
184 
185 /** Thread loop. */
186 void
188 {
189  if (__tt) {
190  // use time tracker
191  __tt->ping_start(__ttc_capture);
192  cam->capture();
193  __tt->ping_end(__ttc_capture);
194  __tt->ping_start(__ttc_memcpy);
195  shm->lock_for_write();
196  memcpy(shm->buffer(), cam->buffer(), cam->buffer_size()-1);
197  shm->unlock();
198  __tt->ping_end(__ttc_memcpy);
199  if (__cam_has_timestamp_support) shm->set_capture_time(cam->capture_time());
200  __tt->ping_start(__ttc_dispose);
201  cam->dispose_buffer();
202  __tt->ping_end(__ttc_dispose);
203  if ( (++__loop_count % 200) == 0 ) {
204  // output results every 200 loops
205  __tt->print_to_stdout();
206  }
207  } else {
208  // no time tracker
209  cam->capture();
210  shm->lock_for_write();
211  memcpy(shm->buffer(), cam->buffer(), cam->buffer_size());
212  shm->unlock();
213  if (__cam_has_timestamp_support) {
214  shm->set_capture_time(cam->capture_time());
215  } else {
216  cap_time_->stamp();
217  shm->set_capture_time(cap_time_);
218  }
219  cam->dispose_buffer();
220  }
221 
222  if (seq_writer) {
223  seq_writer->write( shm->buffer() );
224  }
225 }
virtual unsigned int buffer_size()=0
Size of buffer.
void ping_start(unsigned int cls)
Start of given class task.
Definition: tracker.cpp:228
virtual void init()
Initialize the thread.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
void lock_for_write()
Lock shared memory segment for writing.
Definition: shm.cpp:918
Fawkes library namespace.
Interface to write images.
Definition: writer.h:34
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
firevision::VisionMaster * vision_master
Vision master.
Definition: vision.h:53
virtual ~FvRetrieverThread()
Destructor.
Called method has not been implemented.
Definition: software.h:107
virtual unsigned int pixel_width()=0
Width of image in pixels.
A class for handling time.
Definition: time.h:91
Color model based on a lookup table.
Definition: lookuptable.h:37
FvRetrieverThread(std::string camera_string, std::string cfg_name, std::string cfg_prefix)
Constructor.
Thread class encapsulation of pthreads.
Definition: thread.h:42
virtual colorspace_t colorspace()=0
Colorspace of returned image.
YUV Colormap.
Definition: yuvcm.h:39
Logger * logger
This is the Logger member used to access the logger.
Definition: logging.h:44
YuvColormap * get_colormap() const
Get colormap.
bool is_valid() const
Check validity of shared memory segment.
Definition: shm.cpp:766
virtual void unregister_thread(fawkes::Thread *thread)=0
Unregister a thread.
unsigned char * buffer() const
Get image buffer.
Definition: shm_image.cpp:235
Clock * clock
By means of this member access to the clock is given.
Definition: clock.h:45
void set_colorspace(colorspace_t cspace)
Set the colorspace of the image.
Definition: seq_writer.cpp:107
Writes a sequence of images to disk.
Definition: seq_writer.h:36
void set_name(const char *format,...)
Set name of thread.
Definition: thread.cpp:761
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual void capture()=0
Capture an image.
virtual fawkes::Time * capture_time()
Get the Time of the last successfully captured image.
Definition: camera.cpp:141
Thread aspect to use in FireVision apps.
Definition: vision.h:35
JPEG file writer.
Definition: jpeg.h:36
void set_frame_id(const char *frame_id)
Set frame ID.
Definition: shm_image.cpp:153
virtual void set(unsigned int y, unsigned int u, unsigned int v, color_t c)
Set color class for given YUV value.
Definition: yuvcm.cpp:182
unsigned int add_class(std::string name)
Add a new class.
Definition: tracker.cpp:156
Shared memory image buffer.
Definition: shm_image.h:181
Time tracking utility.
Definition: tracker.h:38
bool is_zero() const
Check if time is zero.
Definition: time.h:116
const char * name() const
Get name of thread.
Definition: thread.h:95
void set_dimensions(unsigned int width, unsigned int height)
Set the image dimensions.
Definition: seq_writer.cpp:99
void ping_end(unsigned int cls)
End of given class task.
Definition: tracker.cpp:254
void print_to_stdout()
Print results to stdout.
Definition: tracker.cpp:317
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
virtual unsigned char * buffer()=0
Get access to current image buffer.
virtual unsigned int pixel_height()=0
Height of image in pixels.
Time & stamp()
Set this time to the current time.
Definition: time.cpp:783
void write(unsigned char *buffer)
Write a single image to disk.
Definition: seq_writer.cpp:116
void set_path(const char *img_path)
Set the path to where the images are stored.
Definition: seq_writer.cpp:77
virtual void loop()
Thread loop.
virtual Camera * register_for_camera(const char *camera_string, fawkes::Thread *thread, colorspace_t cspace=YUV422_PLANAR)=0
Register thread for camera.
Configuration * config
This is the Configuration member used to access the configuration.
Definition: configurable.h:44
virtual void finalize()
Finalize the thread.
void set_capture_time(fawkes::Time *time)
Set the capture time.
Definition: shm_image.cpp:205
void unlock()
Unlock memory.
Definition: shm.cpp:985
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
virtual void dispose_buffer()=0
Dispose current buffer.