00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <cams/bumblebee2.h>
00025
00026 #include <cams/cam_exceptions.h>
00027 #include <core/exception.h>
00028 #include <fvutils/system/camargp.h>
00029 #include <fvutils/color/conversions.h>
00030
00031
00032 #include <stdlib.h>
00033 #include <unistd.h>
00034 #include <string>
00035 #include <endian.h>
00036
00037 #include <utils/math/angle.h>
00038
00039 #include <cstdio>
00040
00041 #include <dc1394/utils.h>
00042 #include <dc1394/register.h>
00043 #include <dc1394/conversions.h>
00044
00045 using namespace fawkes;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 const unsigned int Bumblebee2Camera::ORIGINAL = 0;
00081
00082
00083 const unsigned int Bumblebee2Camera::DEINTERLACED = 1;
00084
00085
00086 const unsigned int Bumblebee2Camera::RGB_IMAGE = 2;
00087
00088
00089
00090
00091 #define PGR_BAYER_TILE_MAPPING_REGISTER (0x1040)
00092
00093
00094 #define PGR_REG_CONFIG_LENGTH (0x1FFC)
00095
00096
00097 #define PGR_REG_CONFIG_DATA (0x2000)
00098
00099
00100 #define PGR_REG_UNIT_DIRECTORY_OFFSET (0x0424)
00101
00102
00103 #define PGR_REG_IMAGE_DATA_FORMAT (0x1048)
00104
00105 #define PTG_Y16_Data_Format_PGR_specific (0xFFFFFFFE)
00106
00107
00108 #define PGR_REG_SERIAL_NUMBER (0x1F20)
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 Bumblebee2Camera::Bumblebee2Camera(const CameraArgumentParser *cap)
00122 : FirewireCamera(DC1394_FRAMERATE_30,
00123 DC1394_VIDEO_MODE_FORMAT7_3,
00124 DC1394_ISO_SPEED_400,
00125 8)
00126 {
00127
00128
00129 _model = strdup(cap->cam_id().c_str());
00130
00131 _format7_coding = DC1394_COLOR_CODING_RAW16;
00132 _format7_width = 640;
00133 _format7_height = 480;
00134 _format7_startx = _format7_starty = 0;
00135
00136 if ( cap->has("nbufs") ) {
00137 _num_buffers = atoi(cap->get("nbufs").c_str());
00138 }
00139 if ( cap->has("width") ) {
00140 _format7_width = atoi(cap->get("width").c_str());
00141 }
00142 if ( cap->has("height") ) {
00143 _format7_height = atoi(cap->get("height").c_str());
00144 }
00145 if ( cap->has("startx") ) {
00146 _format7_startx = atoi(cap->get("startx").c_str());
00147 }
00148 if ( cap->has("starty") ) {
00149 _format7_starty = atoi(cap->get("starty").c_str());
00150 }
00151 if ( cap->has("focus") ) {
00152 parse_set_focus(cap->get("focus").c_str());
00153 }
00154 if ( cap->has("white_balance") ) {
00155 parse_set_white_balance(cap->get("white_balance").c_str());
00156 }
00157 if ( cap->has("shutter") ) {
00158 parse_set_shutter(cap->get("shutter").c_str());
00159 }
00160
00161 __buffer_deinterlaced = NULL;
00162 __buffer_rgb = NULL;
00163 }
00164
00165
00166
00167 Bumblebee2Camera::~Bumblebee2Camera()
00168 {
00169 if (__buffer_deinterlaced != NULL) free(__buffer_deinterlaced);
00170 if (__buffer_rgb != NULL) free(__buffer_rgb);
00171 }
00172
00173
00174
00175
00176
00177 uint32_t
00178 Bumblebee2Camera::serial_no() const
00179 {
00180 if ( ! _opened ) throw Exception("Camera not opened");
00181
00182 uint32_t value = 0;
00183 dc1394error_t err = dc1394_get_control_register( _camera, PGR_REG_SERIAL_NUMBER, &value );
00184 if ( err != DC1394_SUCCESS ) {
00185 throw Exception("Bumblebee2::serial_no: dc1394_get_control_register(PGR_REG_SERIAL_NUMBER) failed\n");
00186 }
00187 return value;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 bool
00202 Bumblebee2Camera::verify_guid(uint64_t ver_guid) const
00203 {
00204 if ( ! _opened ) throw Exception("Camera not opened");
00205
00206 uint64_t tguid = ver_guid;
00207 tguid >>= 32;
00208 tguid &= 0xFFFFFFFF;
00209 if ( tguid == 0xFFFFFFFF ) {
00210
00211 ver_guid &= 0xFFFFFFFF;
00212 return (serial_no() == ver_guid);
00213 } else {
00214 return (guid() == ver_guid);
00215 }
00216 }
00217
00218
00219 void
00220 Bumblebee2Camera::print_info()
00221 {
00222 FirewireCamera::print_info();
00223
00224 printf("Serial: %u\n", serial_no());
00225 #if __WORDSIZE == 64
00226 printf("GUID: 0x%016lx\n", guid());
00227 #else
00228 printf("GUID: 0x%016llx\n", guid());
00229 #endif
00230 }
00231
00232 void
00233 Bumblebee2Camera::open()
00234 {
00235 try {
00236 FirewireCamera::open();
00237 } catch (Exception &e) {
00238 throw;
00239 }
00240
00241 if ( ! _opened ) {
00242 throw Exception("Bumblebee2Camera::open: FirewireCamera::open dit not suceed");
00243 }
00244
00245 __buffer_deinterlaced = (unsigned char *)malloc(pixel_width() * pixel_height() * 2);
00246 __buffer_rgb = malloc_buffer(RGB, pixel_width(), pixel_height() * 2);
00247 __buffer = NULL;
00248
00249 #if __BYTE_ORDER == __LITTLE_ENDIAN
00250 dc1394error_t err;
00251 uint32_t value;
00252 typedef struct {
00253 uint32_t presence : 1;
00254 uint32_t reserved1 : 21;
00255 uint32_t mirror : 1;
00256 uint32_t bayer_mono : 1;
00257 uint32_t reserved2 : 7;
00258 uint32_t data_format: 1;
00259 } idf_t;
00260 err = dc1394_get_control_register( _camera, PGR_REG_IMAGE_DATA_FORMAT, &value );
00261 if ( err != DC1394_SUCCESS ) {
00262 throw Exception("Bumblebee2::open: dc1394_get_control_register(PGR_REG_DATA_FORMAT) failed\n");
00263 }
00264 idf_t *i = (idf_t *)(void *)&value;
00265 value &= PTG_Y16_Data_Format_PGR_specific;
00266 i->data_format = 0;
00267 err = dc1394_set_control_register( _camera, PGR_REG_IMAGE_DATA_FORMAT, value );
00268 if ( err != DC1394_SUCCESS ) {
00269 throw Exception("Bumblebee2::open: Setting PGR-specific mode on little-endian system failed\n");
00270 }
00271 #endif
00272
00273 get_bayer_tile();
00274 }
00275
00276
00277 void
00278 Bumblebee2Camera::close()
00279 {
00280 if ( _opened ) {
00281 FirewireCamera::close();
00282 if (__buffer_deinterlaced != NULL) {
00283 free(__buffer_deinterlaced);
00284 __buffer_deinterlaced = NULL;
00285 }
00286 if (__buffer_rgb != NULL) {
00287 free(__buffer_rgb);
00288 __buffer_rgb = NULL;
00289 }
00290 }
00291 }
00292
00293 void
00294 Bumblebee2Camera::capture()
00295 {
00296 try {
00297 FirewireCamera::capture();
00298 } catch (CaptureException &e) {
00299 e.append("Bumblebee2Camera::capture: failed to retrieve image");
00300 if ( ORIGINAL == __image_num ) __buffer = NULL;
00301 throw;
00302 }
00303 if ( ORIGINAL == __image_num ) {
00304 __buffer = _frame->image;
00305 }
00306 }
00307
00308
00309 unsigned char *
00310 Bumblebee2Camera::buffer()
00311 {
00312 return __buffer;
00313 }
00314
00315
00316 void
00317 Bumblebee2Camera::set_image_number(unsigned int image_num)
00318 {
00319 __image_num = image_num;
00320 switch ( image_num ) {
00321 case DEINTERLACED: __buffer = __buffer_deinterlaced; break;
00322 case RGB_IMAGE: __buffer = __buffer_rgb; break;
00323 default: __buffer = NULL; break;
00324 }
00325 }
00326
00327
00328
00329
00330
00331 bool
00332 Bumblebee2Camera::is_bumblebee2()
00333 {
00334 if ( ! _opened ) throw CameraNotOpenedException();
00335
00336 return( strncmp( _camera->model, "Bumblebee2", strlen("Bumblebee2") ) == 0);
00337 }
00338
00339
00340
00341 void
00342 Bumblebee2Camera::deinterlace_stereo()
00343 {
00344 dc1394_deinterlace_stereo( _frame->image, __buffer_deinterlaced,
00345 pixel_width(), 2 * pixel_height() );
00346 }
00347
00348
00349
00350
00351
00352
00353
00354 void
00355 Bumblebee2Camera::decode_bayer()
00356 {
00357 dc1394_bayer_decoding_8bit( __buffer_deinterlaced, __buffer_rgb,
00358 pixel_width(), 2 * pixel_height(),
00359 __bayer_pattern, DC1394_BAYER_METHOD_NEAREST );
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 void
00374 Bumblebee2Camera::deinterlace_stereo(unsigned char *raw16, unsigned char *deinterlaced,
00375 unsigned int width, unsigned int height)
00376 {
00377 dc1394_deinterlace_stereo( raw16, deinterlaced, width, 2 * height );
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 void
00397 Bumblebee2Camera::decode_bayer(unsigned char *deinterlaced, unsigned char *rgb,
00398 unsigned int width, unsigned int height,
00399 bayer_pattern_t bayer_pattern)
00400 {
00401 dc1394color_filter_t dc_bayer_pattern;
00402
00403 switch (bayer_pattern) {
00404 default:
00405 case BAYER_PATTERN_YYYY:
00406 dc_bayer_pattern = (dc1394color_filter_t) 0;
00407 break;
00408 case BAYER_PATTERN_RGGB:
00409 dc_bayer_pattern = DC1394_COLOR_FILTER_RGGB;
00410 break;
00411 case BAYER_PATTERN_GBRG:
00412 dc_bayer_pattern = DC1394_COLOR_FILTER_GBRG;
00413 break;
00414 case BAYER_PATTERN_GRBG:
00415 dc_bayer_pattern = DC1394_COLOR_FILTER_GRBG;
00416 break;
00417 case BAYER_PATTERN_BGGR:
00418 dc_bayer_pattern = DC1394_COLOR_FILTER_BGGR;
00419 break;
00420 }
00421
00422 dc1394_bayer_decoding_8bit( deinterlaced, rgb, width, 2 * height,
00423 dc_bayer_pattern, DC1394_BAYER_METHOD_NEAREST );
00424 }
00425
00426
00427
00428
00429
00430
00431 void
00432 Bumblebee2Camera::get_bayer_tile()
00433 {
00434 uint32_t value;
00435 if (dc1394_get_control_register( _camera, PGR_BAYER_TILE_MAPPING_REGISTER, &value) != DC1394_SUCCESS ) {
00436 throw Exception("Could not query bayer tile register");
00437 }
00438
00439
00440 switch (value) {
00441 default:
00442 case 0x59595959:
00443
00444 __bayer_pattern = (dc1394color_filter_t) 0;
00445 break;
00446 case 0x52474742:
00447 __bayer_pattern = DC1394_COLOR_FILTER_RGGB;
00448 break;
00449 case 0x47425247:
00450 __bayer_pattern = DC1394_COLOR_FILTER_GBRG;
00451 break;
00452 case 0x47524247:
00453 __bayer_pattern = DC1394_COLOR_FILTER_GRBG;
00454 break;
00455 case 0x42474752:
00456 __bayer_pattern = DC1394_COLOR_FILTER_BGGR;
00457 break;
00458 }
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 void
00470 Bumblebee2Camera::write_triclops_config_from_camera_to_file(const char *filename)
00471 {
00472 dc1394error_t err;
00473 uint32_t value;
00474
00475 err = dc1394_get_control_register( _camera, PGR_REG_CONFIG_LENGTH, &value );
00476 if ( err != DC1394_SUCCESS ) {
00477 throw Exception("dc1394_get_control_register(PGR_REG_CONFIG_LENGTH) failed\n");
00478 }
00479
00480
00481 unsigned long file_size_bytes = value;
00482 if( file_size_bytes == 0 ) {
00483 throw Exception("File size == 0!\n" );
00484 }
00485
00486 FILE* file = fopen( filename, "w" );
00487 if ( !file ) {
00488 throw Exception("Can't open temporary file\n" );
00489 }
00490
00491
00492
00493 for( unsigned long offset = 0 ; offset < file_size_bytes; offset += 4 ) {
00494 err = dc1394_get_control_register( _camera,
00495 PGR_REG_CONFIG_DATA + offset,
00496 &value );
00497
00498 if( err != DC1394_SUCCESS ) {
00499 Exception e("Failed to get control register");
00500 e.append("Can't get control register 0x%x\n",
00501 (int) (PGR_REG_CONFIG_DATA+offset) );
00502 fclose( file );
00503 throw e;
00504 }
00505
00506 for( int i = 24; i >= 0; i -= 8 ) {
00507 fputc( ( (value>>i) & 0xFF ), file );
00508 }
00509 }
00510 fclose( file );
00511 }
00512