snark
dc1394.h
1 // This file is part of snark, a generic and flexible library
2 // for robotics research.
3 //
4 // Copyright (C) 2011 The University of Sydney
5 //
6 // snark is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // snark is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 // for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with snark. If not, see <http://www.gnu.org/licenses/>.
18 
19 #ifndef SNARK_SENSORS_DC1394_H_
20 #define SNARK_SENSORS_DC1394_H_
21 
22 #include <boost/date_time/posix_time/posix_time.hpp>
23 #include <boost/optional.hpp>
24 #include <dc1394/dc1394.h>
25 
26 #include <opencv2/core/core.hpp>
27 #include <opencv2/core/core_c.h>
28 #include <comma/io/select.h>
29 #include <comma/visiting/traits.h>
30 #include <snark/sensors/dc1394/types.h>
31 
32 namespace snark { namespace camera {
33 
35 class dc1394
36 {
37 public:
38  struct config
39  {
40  enum output_type{ RGB, BGR, Raw };
41  config();
42  int type() const;
43 
44  output_type output;
45  dc1394video_mode_t video_mode;
46  dc1394operation_mode_t operation_mode;
47  dc1394speed_t iso_speed;
48  // TODO framerate is not used in format7, as the way to set the framerate is different.
49  // see http://damien.douxchamps.net/ieee1394/libdc1394/v2.x/faq/#How_do_I_set_the_frame_rate
50  dc1394framerate_t frame_rate;
51  unsigned int relative_shutter;
52  unsigned int relative_gain;
53  float shutter; // 0 means do not change
54  float gain;
55  uint64_t guid;
56  };
57 
58 // DC1394_FEATURE_SHUTTER,
59 // DC1394_FEATURE_GAIN,
60 
61  dc1394( const config& config = config(), unsigned int format7_width = 0, unsigned int format7_height = 0, unsigned int format7_size = 8160, unsigned int exposure = 0 );
62  ~dc1394();
63 
64  const cv::Mat& read();
65  boost::posix_time::ptime time() const { return m_time; }
66  bool poll();
67  static void list_cameras();
68 
69 private:
70  void init_camera();
71  void setup_camera();
72  void setup_camera_format7();
73  void set_exposure( float shutter, float gain );
74  void set_exposure( unsigned int shutter, unsigned int gain );
75 
76  config m_config;
77  dc1394camera_t* m_camera;
78  dc1394video_frame_t* m_frame;
79  dc1394video_frame_t m_output_frame;
80  cv::Mat m_image;
81  const boost::posix_time::ptime m_epoch;
82  boost::posix_time::ptime m_time;
83  int m_fd;
84  comma::io::select m_select;
85  boost::posix_time::time_duration m_frame_duration;
86  unsigned int m_width;
87  unsigned int m_height;
88  unsigned int m_format7_width;
89  unsigned int m_format7_height;
90  unsigned int m_format7_size;
91  boost::optional< unsigned int > m_auto_exposure;
92  boost::optional< unsigned int > m_adjusted_exposure;
93  boost::posix_time::ptime m_last_shutter_update;
94 
95 };
96 
97 } } // namespace snark { namespace camera {
98 
99 namespace comma { namespace visiting {
100 
101 template <> struct traits< snark::camera::dc1394::config >
102 {
103  template < typename Key, class Visitor >
104  static void visit( const Key&, snark::camera::dc1394::config& c, Visitor& v )
105  {
106  std::string outputType;
107  v.apply( "output-type", outputType );
108  if( outputType == "RGB" || outputType == "rgb" )
109  {
110  c.output = snark::camera::dc1394::config::RGB;
111  }
112  else if( outputType == "BGR" || outputType == "brg" )
113  {
114  c.output = snark::camera::dc1394::config::BGR;
115  }
116  else
117  {
118  c.output = snark::camera::dc1394::config::Raw;
119  }
120 
121  std::string video_mode;
122  std::string operation_mode;
123  std::string iso_speed;
124  std::string frame_rate;
125  v.apply( "video-mode", video_mode );
126  v.apply( "operation-mode", operation_mode );
127  v.apply( "iso-speed", iso_speed );
128  v.apply( "frame-rate", frame_rate );
129 
130  c.video_mode = snark::camera::video_mode_from_string( video_mode );
131  c.operation_mode = snark::camera::operation_mode_from_string( operation_mode );
132  c.iso_speed = snark::camera::iso_speed_from_string( iso_speed );
133  c.frame_rate = snark::camera::frame_rate_from_string( frame_rate );
134 
135  v.apply( "relative-shutter", c.relative_shutter );
136  v.apply( "relative-gain", c.relative_gain );
137  v.apply( "shutter", c.shutter );
138  v.apply( "gain", c.gain );
139  v.apply( "guid", c.guid );
140  }
141 
142  template < typename Key, class Visitor >
143  static void visit( const Key&, const snark::camera::dc1394::config& c, Visitor& v )
144  {
145  std::string outputType;
146  if( c.output == snark::camera::dc1394::config::RGB )
147  {
148  outputType = "RGB";
149  }
150  else if( c.output == snark::camera::dc1394::config::BGR )
151  {
152  outputType = "BGR";
153  }
154  else
155  {
156  outputType = "Raw";
157  }
158  v.apply( "output-type", outputType );
159 
160  std::string video_mode = snark::camera::video_mode_to_string( c.video_mode );
161  std::string operation_mode = snark::camera::operation_mode_to_string( c.operation_mode );
162  std::string iso_speed = snark::camera::iso_speed_to_string( c.iso_speed );
163  std::string frame_rate = snark::camera::frame_rate_to_string( c.frame_rate );
164 
165  v.apply( "video-mode", video_mode );
166  v.apply( "operation-mode", operation_mode );
167  v.apply( "iso-speed", iso_speed );
168  v.apply( "frame-rate", frame_rate );
169  v.apply( "relative-shutter", c.relative_shutter );
170  v.apply( "relative-gain", c.relative_gain );
171  v.apply( "shutter", c.shutter );
172  v.apply( "gain", c.gain );
173  v.apply( "guid", c.guid );
174  }
175 };
176 
177 } }
178 
179 #endif // SNARK_SENSORS_DC1394_H_