00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <assert.h>
00005 #include <math.h>
00006 #include <sys/time.h>
00007 #include <unistd.h>
00008 #include <inttypes.h>
00009
00010 #include <pthread.h>
00011
00012 #include <zlib.h>
00013 #include <glib.h>
00014 #include <lcm/lcm.h>
00015 #include <libfreenect.h>
00016
00017 #include <lcmtypes/kinect_depth_msg_t.h>
00018 #include <lcmtypes/kinect_image_msg_t.h>
00019 #include <lcmtypes/kinect_frame_msg_t.h>
00020 #include <lcmtypes/kinect_cmd_msg_t.h>
00021 #include <lcmtypes/kinect_sensor_status_t.h>
00022
00023 #if USE_JPEG_UTILS_POD
00024 #include <jpeg-utils/jpeg-utils.h>
00025 #else
00026 #include "jpeg-utils-ijg.h"
00027 #endif
00028
00029 #include "timestamp.h"
00030 #include "pixels.h"
00031
00032 #define dbg(...) fprintf(stderr, __VA_ARGS__)
00033
00034 #define alpha 0.05 //decay rate for the moving average
00035 typedef struct _rate_t {
00036 double target_hz;
00037 double current_hz;
00038 int64_t last_tick;
00039 int64_t tick_count;
00040 } rate_t;
00041
00042 rate_t* rate_new(double target_hz);
00043
00044 void rate_destroy(rate_t* rate);
00045
00049 int rate_check(rate_t* rate);
00050
00051 typedef struct _state_t {
00052 GThread* freenect_thread;
00053 volatile int die;
00054
00055 freenect_context *f_ctx;
00056 freenect_device *f_dev;
00057 int freenect_angle;
00058 int freenect_led;
00059
00060 int8_t requested_image_format;
00061 int8_t current_image_format;
00062
00063 int8_t requested_depth_format;
00064 int8_t current_depth_format;
00065
00066 int8_t current_resolution;
00067
00068 uint8_t* image_data;
00069
00070 uint8_t* image_buf;
00071 int image_buf_size;
00072
00073 uint8_t* debayer_buf;
00074 int debayer_buf_size;
00075
00076 uint16_t* depth_unpack_buf;
00077 int depth_unpack_buf_size;
00078
00079 uint8_t* depth_compress_buf;
00080 int debayer_buf_stride;
00081 int depth_compress_buf_size;
00082
00083 freenect_raw_tilt_state* tilt_state;
00084 double accel_mks[3];
00085 double tilt_radians;
00086
00087 int8_t current_led;
00088 int8_t requested_led;
00089
00090 kinect_frame_msg_t msg;
00091 char* msg_channel;
00092
00093 int got_img;
00094 int got_depth;
00095
00096 int skip_img;
00097 int skip_depth;
00098 int throttle;
00099 timestamp_sync_state_t* clocksync;
00100
00101 rate_t* capture_rate;
00102 rate_t* report_rate;
00103
00104 uint8_t* jpeg_buf;
00105 int jpeg_buf_size;
00106
00107 int jpeg_quality;
00108
00109 int use_zlib;
00110
00111 lcm_t* lcm;
00112
00113 int64_t last_timestamp;
00114 int64_t last_depth_timestamp;
00115 int64_t last_img_timestamp;
00116
00117 pthread_t work_thread;
00118
00119 } state_t;
00120
00121 static void
00122 populate_status(state_t* state, kinect_frame_msg_t* msg, int64_t timestamp)
00123 {
00124 freenect_update_tilt_state(state->f_dev);
00125 state->tilt_state = freenect_get_tilt_state(state->f_dev);
00126
00127 double dx, dy, dz;
00128 freenect_get_mks_accel(state->tilt_state, &dx, &dy, &dz);
00129
00130 msg->timestamp = timestamp;
00131 msg->raw_accel[0] = state->tilt_state->accelerometer_x;
00132 msg->raw_accel[1] = state->tilt_state->accelerometer_y;
00133 msg->raw_accel[2] = state->tilt_state->accelerometer_z;
00134 msg->raw_tilt = state->tilt_state->tilt_angle;
00135
00136 msg->accel[0] = dx;
00137 msg->accel[1] = dy;
00138
00139
00140
00141
00142 msg->accel[2] = dz;
00143
00144 msg->tilt_radians = freenect_get_tilt_degs(state->tilt_state) * M_PI / 180;
00145
00146 msg->led_status = state->current_led;
00147
00148 switch (state->tilt_state->tilt_status) {
00149 case TILT_STATUS_STOPPED:
00150 msg->tilt_status = KINECT_FRAME_MSG_T_TILT_STATUS_STOPPED;
00151 break;
00152 case TILT_STATUS_LIMIT:
00153 msg->tilt_status = KINECT_FRAME_MSG_T_TILT_STATUS_LIMIT;
00154 break;
00155 case TILT_STATUS_MOVING:
00156 msg->tilt_status = KINECT_FRAME_MSG_T_TILT_STATUS_MOVING;
00157 break;
00158 }
00159 msg->tilt_status = state->tilt_state->tilt_status;
00160 }
00161
00162 rate_t* rate_new(double target_hz)
00163 {
00164 rate_t* rt = (rate_t *) calloc(1, sizeof(rate_t));
00165 rt->target_hz = target_hz;
00166 rt->tick_count = 0;
00167 return rt;
00168 }
00169
00170 void rate_destroy(rate_t* rate)
00171 {
00172 free(rate);
00173 }
00174
00175 int rate_check(rate_t* rate)
00176 {
00177
00178 int64_t c_utime = timestamp_now();
00179
00180
00181 int64_t dt = c_utime - rate->last_tick;
00182
00183 double p_framerate = alpha * (1.0 * 1e6 / dt) + (1 - alpha) * rate->current_hz;
00184 if (p_framerate > rate->target_hz) {
00185
00186 return 0;
00187 }
00188 else {
00189
00190 rate->current_hz = p_framerate;
00191 rate->last_tick = c_utime;
00192 rate->tick_count++;
00193 return 1;
00194 }
00195 }
00196
00197 static void
00198 set_image_depth_formats(state_t* state)
00199 {
00200 freenect_video_format vfmt;
00201 freenect_depth_format dfmt;
00202
00203 switch (state->requested_image_format) {
00204 case KINECT_IMAGE_MSG_T_VIDEO_RGB:
00205 case KINECT_IMAGE_MSG_T_VIDEO_BAYER:
00206 case KINECT_IMAGE_MSG_T_VIDEO_IR_8BIT:
00207 case KINECT_IMAGE_MSG_T_VIDEO_IR_10BIT:
00208 case KINECT_IMAGE_MSG_T_VIDEO_IR_10BIT_PACKED:
00209 case KINECT_IMAGE_MSG_T_VIDEO_YUV_RAW:
00210 {
00211 vfmt = state->requested_image_format;
00212 freenect_frame_mode md = freenect_find_video_mode(state->current_resolution, state->requested_image_format);
00213 state->msg.image.image_data_nbytes = md.bytes;
00214 }
00215 break;
00216 case KINECT_IMAGE_MSG_T_VIDEO_RGB_JPEG:
00217 vfmt = FREENECT_VIDEO_BAYER;
00218 break;
00219 default:
00220 vfmt = FREENECT_VIDEO_BAYER;
00221 fprintf(stderr, "Invalid image format requested: %d\n", state->requested_image_format);
00222 state->msg.image.image_data_nbytes = 0;
00223 break;
00224 }
00225
00226 switch (state->requested_depth_format) {
00227 case KINECT_DEPTH_MSG_T_DEPTH_11BIT:
00228 case KINECT_DEPTH_MSG_T_DEPTH_10BIT:
00229 case KINECT_DEPTH_MSG_T_DEPTH_11BIT_PACKED:
00230 case KINECT_DEPTH_MSG_T_DEPTH_10BIT_PACKED:
00231 case KINECT_DEPTH_MSG_T_DEPTH_REGISTERED:
00232 case KINECT_DEPTH_MSG_T_DEPTH_MM:
00233 dfmt = state->requested_depth_format;
00234 break;
00235 default:
00236 dfmt = FREENECT_DEPTH_11BIT_PACKED;
00237 fprintf(stderr, "Invalid depth format requested: %d\n", state->requested_depth_format);
00238 break;
00239 }
00240
00241 state->current_image_format = state->requested_image_format;
00242 state->msg.image.image_data_format = state->requested_image_format;
00243 state->current_depth_format = state->requested_depth_format;
00244 state->msg.depth.depth_data_format = state->requested_depth_format;
00245
00246 freenect_frame_mode vmode = freenect_find_video_mode(state->current_resolution, vfmt);
00247 freenect_frame_mode dmode = freenect_find_depth_mode(state->current_resolution, dfmt);
00248
00249 freenect_set_video_mode(state->f_dev, vmode);
00250 freenect_set_depth_mode(state->f_dev, dmode);
00251 }
00252
00253 void
00254 cmd_cb(const lcm_recv_buf_t *rbuf __attribute__((unused)),
00255 const char *channel __attribute__((unused)),
00256 const kinect_cmd_msg_t *msg,
00257 void *user)
00258 {
00259 state_t *self = (state_t *) user;
00260
00261 if (msg->command_type == KINECT_CMD_MSG_T_SET_TILT) {
00262 dbg("Received tilt command; Angle : %d\n", msg->tilt_degree);
00263 self->freenect_angle = msg->tilt_degree;
00264
00265 if (self->freenect_angle > 30)
00266 self->freenect_angle = 30;
00267 else if (self->freenect_angle < -20)
00268 self->freenect_angle = -20;
00269
00270
00271 freenect_set_tilt_degs(self->f_dev, self->freenect_angle);
00272 }
00273 else if (msg->command_type == KINECT_CMD_MSG_T_SET_LED) {
00274
00275 if (msg->led_status >= 0 && msg->led_status <= 6) {
00276
00277 freenect_set_led(self->f_dev, msg->led_status);
00278 }
00279 }
00280 else if (msg->command_type == KINECT_CMD_MSG_T_SET_DEPTH_DATA_FORMAT) {
00281
00282 if (msg->depth_data_format >= 0 && msg->depth_data_format < 4) {
00283 self->requested_depth_format = msg->depth_data_format;
00284 }
00285 }
00286 else if (msg->command_type == KINECT_CMD_MSG_T_SET_IMAGE_DATA_FORMAT) {
00287
00288 }
00289 }
00290
00291
00292 static inline void
00293 convert_packed_to_16bit(uint8_t *raw, uint16_t *frame, int vw, int len)
00294 {
00295 int mask = (1 << vw) - 1;
00296 uint32_t buffer = 0;
00297 int bitsIn = 0;
00298 while (len--) {
00299 while (bitsIn < vw) {
00300 buffer = (buffer << 8) | *(raw++);
00301 bitsIn += 8;
00302 }
00303 bitsIn -= vw;
00304 *(frame++) = (buffer >> bitsIn) & mask;
00305 }
00306 }
00307
00308 void
00309 depth_cb(freenect_device *dev, void *data, uint32_t timestamp)
00310 {
00311 state_t* state = (state_t*) freenect_get_user(dev);
00312 int64_t host_utime = timestamp_now();
00313 int64_t msg_utime = timestamp_sync(state->clocksync, timestamp, host_utime);
00314
00315 #if 0
00316 if(state->last_timestamp) {
00317 printf("D depth: %10.6f img : %10.6f last : %10.6f (%"PRId64")\n",
00318 (msg_utime - state->last_depth_timestamp) * 1e-6,
00319 (msg_utime - state->last_img_timestamp) * 1e-6,
00320 (msg_utime - state->last_timestamp) * 1e-6,
00321 msg_utime);
00322 }
00323 state->last_depth_timestamp = msg_utime;
00324 state->last_timestamp = msg_utime;
00325 #endif
00326
00327
00328
00329 if (!state->got_img)
00330 return;
00331 state->got_depth = 1;
00332
00333 if (state->skip_depth) {
00334 state->msg.depth.timestamp = 0;
00335 state->msg.depth.width = 0;
00336 state->msg.depth.height = 0;
00337 state->msg.depth.depth_data_nbytes = 0;
00338 state->msg.depth.depth_data_format = KINECT_DEPTH_MSG_T_DEPTH_NONE;
00339 state->msg.depth.compression = KINECT_DEPTH_MSG_T_COMPRESSION_NONE;
00340 state->msg.depth.uncompressed_size = 0;
00341 return;
00342 }
00343
00344 state->msg.depth.timestamp = msg_utime;
00345
00346 freenect_frame_mode md = freenect_find_depth_mode(state->current_resolution, state->current_depth_format);
00347 state->msg.depth.depth_data_nbytes = md.bytes;
00348 state->msg.depth.depth_data_format = state->current_depth_format;
00349 if (state->current_depth_format == KINECT_DEPTH_MSG_T_DEPTH_10BIT_PACKED
00350 || state->current_depth_format == KINECT_DEPTH_MSG_T_DEPTH_11BIT_PACKED) {
00351 assert(state->msg.depth.depth_data_nbytes <= state->depth_unpack_buf_size);
00352 convert_packed_to_16bit(data, state->depth_unpack_buf, md.data_bits_per_pixel, 640 * 480);
00353 }
00354 else {
00355 assert(state->msg.depth.depth_data_nbytes <= state->depth_unpack_buf_size);
00356 memcpy(state->depth_unpack_buf, data, state->msg.depth.depth_data_nbytes);
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 if (state->use_zlib) {
00386 int uncompressed_size = state->msg.depth.depth_data_nbytes;
00387 unsigned long compressed_size = state->depth_compress_buf_size;
00388 compress2(state->depth_compress_buf, &compressed_size, (void*) state->depth_unpack_buf, uncompressed_size,
00389 Z_BEST_SPEED);
00390 state->msg.depth.depth_data_nbytes = (int) compressed_size;
00391 state->msg.depth.compression = KINECT_DEPTH_MSG_T_COMPRESSION_ZLIB;
00392 state->msg.depth.uncompressed_size = uncompressed_size;
00393 }
00394 else {
00395 assert(state->msg.depth.depth_data_nbytes <= state->depth_compress_buf_size);
00396 memcpy(state->depth_compress_buf, state->depth_unpack_buf, state->msg.depth.depth_data_nbytes);
00397 state->msg.depth.compression = KINECT_DEPTH_MSG_T_COMPRESSION_NONE;
00398 state->msg.depth.uncompressed_size = state->msg.depth.depth_data_nbytes;
00399 }
00400 }
00401
00402 void
00403 image_cb(freenect_device *dev, void *data, uint32_t timestamp)
00404 {
00405 state_t* state = (state_t*) freenect_get_user(dev);
00406 int64_t host_utime = timestamp_now();
00407 int64_t msg_utime = timestamp_sync(state->clocksync, timestamp, host_utime);
00408
00409 #if 0
00410 if(state->last_timestamp) {
00411 printf(" I depth: %10.6f img : %10.6f last : %10.6f (%"PRId64")\n",
00412 (msg_utime - state->last_depth_timestamp) * 1e-6,
00413 (msg_utime - state->last_img_timestamp) * 1e-6,
00414 (msg_utime - state->last_timestamp) * 1e-6,
00415 msg_utime);
00416 }
00417 state->last_img_timestamp = msg_utime;
00418 state->last_timestamp = msg_utime;
00419 #endif
00420
00421 if (!rate_check(state->capture_rate)) {
00422 return;
00423 }
00424 state->got_img = 1;
00425
00426
00427 if (state->skip_img) {
00428 state->msg.image.timestamp = 0;
00429 state->msg.image.width = 0;
00430 state->msg.image.height = 0;
00431 state->msg.image.image_data_nbytes = 0;
00432 state->msg.image.image_data_format = KINECT_IMAGE_MSG_T_VIDEO_NONE;
00433 return;
00434 }
00435
00436 state->msg.image.timestamp = msg_utime;
00437
00438
00439 if (state->current_image_format == KINECT_IMAGE_MSG_T_VIDEO_BAYER ||
00440 state->current_image_format == KINECT_IMAGE_MSG_T_VIDEO_RGB_JPEG) {
00441
00442 cam_pixel_convert_bayer_to_8u_bgra(state->debayer_buf, state->debayer_buf_stride,
00443 640, 480, data, 640, CAM_PIXEL_FORMAT_BAYER_GRBG);
00444
00445
00446
00447 cam_pixel_convert_8u_bgra_to_8u_rgb((uint8_t*) data, 640 * 3, 640, 480,
00448 state->debayer_buf, state->debayer_buf_stride);
00449 state->msg.image.image_data_nbytes = 640 * 480 * 3;
00450 state->msg.image.image_data_format = KINECT_IMAGE_MSG_T_VIDEO_RGB;
00451 }
00452
00453
00454 if (state->current_image_format == KINECT_IMAGE_MSG_T_VIDEO_RGB_JPEG) {
00455 int compressed_size = state->image_buf_size;
00456 #if USE_JPEG_UTILS_POD
00457 int compression_status = jpeg_compress_8u_rgb (data, 640, 480, 640*3,
00458 state->image_buf, &compressed_size, state->jpeg_quality);
00459 #else
00460 int compression_status = jpegijg_compress_8u_rgb(data, 640, 480, 640 * 3,
00461 state->image_buf, &compressed_size, state->jpeg_quality);
00462 #endif
00463
00464 if (0 != compression_status) {
00465 fprintf(stderr, "JPEG compression failed...\n");
00466 }
00467 state->msg.image.image_data_nbytes = compressed_size;
00468 state->msg.image.image_data_format = KINECT_IMAGE_MSG_T_VIDEO_RGB_JPEG;
00469
00470 }
00471 else {
00472 assert(state->msg.image.image_data_nbytes <= state->image_buf_size);
00473 memcpy(state->image_buf, data, state->msg.image.image_data_nbytes);
00474 }
00475 }
00476
00477
00478
00479 static void *
00480 freenect_threadfunc(void *user_data)
00481 {
00482 printf("starting kinect thread...\n");
00483 state_t* state = (state_t*) user_data;
00484
00485 freenect_set_tilt_degs(state->f_dev, state->freenect_angle);
00486 freenect_set_led(state->f_dev, state->current_led);
00487 freenect_set_depth_callback(state->f_dev, depth_cb);
00488 freenect_set_video_callback(state->f_dev, image_cb);
00489 set_image_depth_formats(state);
00490 freenect_set_video_buffer(state->f_dev, state->image_data);
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 freenect_start_depth(state->f_dev);
00501 freenect_start_video(state->f_dev);
00502
00503 while (!state->die && freenect_process_events(state->f_ctx) >= 0) {
00504
00505
00506 if (state->got_img && state->got_depth) {
00507 populate_status(state, &state->msg, timestamp_now());
00508 kinect_frame_msg_t_publish(state->lcm, state->msg_channel, &state->msg);
00509
00510 state->got_img = 0;
00511 state->got_depth = 0;
00512 }
00513
00514 #if 0
00515
00516 if (state->requested_image_format != state->current_image_format) {
00517 dbg("Changing Image format\n");
00518 freenect_stop_video(state->f_dev);
00519 freenect_set_video_format(state->f_dev, state->requested_image_format);
00520 freenect_start_video(state->f_dev);
00521 state->current_image_format = state->requested_image_format;
00522 }
00523
00524
00525 if (state->requested_depth_format != state->current_depth_format) {
00526 dbg("Changing Depth format\n");
00527 freenect_stop_depth(state->f_dev);
00528 freenect_set_depth_format(state->f_dev, state->requested_depth_format);
00529 freenect_start_depth(state->f_dev);
00530 state->current_depth_format = state->requested_depth_format;
00531 }
00532 #endif
00533
00534 if (rate_check(state->report_rate)) {
00535 printf("Capture rate: %5.2fHz (%6"PRId64")\n", state->capture_rate->current_hz, state->capture_rate->tick_count);
00536 }
00537 }
00538
00539 printf("\nshutting down streams...\n");
00540
00541 freenect_stop_depth(state->f_dev);
00542 freenect_stop_video(state->f_dev);
00543
00544 freenect_close_device(state->f_dev);
00545 freenect_shutdown(state->f_ctx);
00546
00547 printf("-- done!\n");
00548 return NULL;
00549 }
00550
00551
00552 static void *status_thread(void *user)
00553 {
00554 state_t *self = (state_t*) user;
00555
00556 while(1){
00557 if(self->report_rate){
00558 kinect_sensor_status_t msg;
00559 msg.utime = timestamp_now();
00560 msg.sensor_name = "kinect";
00561 msg.rate = self->capture_rate->current_hz;
00562
00563 msg.type = KINECT_SENSOR_STATUS_T_KINECT;
00564
00565 kinect_sensor_status_t_publish(self->lcm, "SENSOR_STATUS_KINECT", &msg);
00566 }
00567 sleep(1);
00568 }
00569
00570 return 0;
00571 }
00572
00573 static void usage(const char* progname)
00574 {
00575 fprintf(stderr, "Usage: %s [options]\n"
00576 "\n"
00577 "Options:\n"
00578 " -r RATE Throttle publishing to RATE Hz.\n"
00579 " -d Depth mode\n"
00580 " -i Image mode\n"
00581 " -j JPEG-compress RGB images\n"
00582 " -q QUAL JPEG compression quality (0-100, default 94)\n"
00583 " -z ZLib compress depth images\n"
00584 " -l URL Specify LCM URL\n"
00585 " -h This help message\n"
00586 " -n dev Number of the device to open\n"
00587 " -c name LCM channel\n",
00588 g_path_get_basename(progname));
00589
00590 fprintf(stderr, "Image mode must be one of:\n"
00591 " VIDEO_RGB = 0\n"
00592 " VIDEO_BAYER = 1\n"
00593 " VIDEO_IR_8BIT = 2\n"
00594 " VIDEO_IR_10BIT = 3\n"
00595 " VIDEO_IR_10BIT_PACKED = 4\n"
00596 " VIDEO_YUV_RGB = 5\n"
00597 " VIDEO_YUV_RAW = 6\n"
00598 "\n"
00599 " VIDEO_DISABLED = -1\n"
00600 );
00601
00602 fprintf(stderr, "Depth mode must be one of:\n"
00603 " DEPTH_11BIT = 0\n"
00604 " DEPTH_10BIT = 1\n"
00605 " DEPTH_11BIT_PACKED = 2\n"
00606 " DEPTH_10BIT_PACKED = 3\n"
00607 " DEPTH_REGISTERED = 4\n"
00608 " DEPTH_MM = 5\n"
00609 "\n"
00610 " DEPTH_DISABLED =-1\n"
00611 );
00612 exit(1);
00613 }
00614
00615 int main(int argc, char **argv)
00616 {
00617 state_t *state = (state_t*) calloc(1, sizeof(state_t));
00618
00619 double target_rate = INFINITY;
00620
00621 state->skip_img = 0;
00622 state->skip_depth = 0;
00623 state->throttle = 0;
00624 state->capture_rate = NULL;
00625
00626 state->freenect_thread = NULL;
00627 state->die = 0;
00628
00629 state->f_ctx = NULL;
00630 state->f_dev = NULL;
00631 state->freenect_angle = 0;
00632 state->freenect_led = 0;
00633
00634 state->jpeg_quality = 94;
00635
00636
00637 state->requested_image_format = KINECT_IMAGE_MSG_T_VIDEO_BAYER;
00638 state->requested_depth_format = KINECT_DEPTH_MSG_T_DEPTH_11BIT;
00639 state->requested_led = LED_RED;
00640 state->current_image_format = state->requested_image_format;
00641 state->current_depth_format = state->requested_depth_format;
00642 state->current_led = state->requested_led;
00643 int user_device_number = 0;
00644 state->msg_channel = g_strdup("KINECT_FRAME");
00645
00646
00647 state->current_resolution = FREENECT_RESOLUTION_MEDIUM;
00648
00649 int c;
00650 char *lcm_url = NULL;
00651
00652 while ((c = getopt(argc, argv, "hd:i:r:jq:zl:n:c:")) >= 0) {
00653 switch (c) {
00654 case 'i':
00655 state->requested_image_format = atoi(optarg);
00656 break;
00657 case 'd':
00658 state->requested_depth_format = atoi(optarg);
00659 break;
00660 case 'j':
00661 state->requested_image_format = KINECT_IMAGE_MSG_T_VIDEO_RGB_JPEG;
00662 break;
00663 case 'q':
00664 state->jpeg_quality = atoi(optarg);
00665 if (state->jpeg_quality < 0 || state->jpeg_quality > 100)
00666 usage(argv[0]);
00667 break;
00668 case 'n':
00669 user_device_number = atoi(optarg);
00670 printf("attempting to open device %i\n", user_device_number);
00671 break;
00672 case 'z':
00673 state->use_zlib = 1;
00674 printf("ZLib compressing depth data\n");
00675 break;
00676 case 'r':
00677 target_rate = strtod(optarg, NULL);
00678 printf("Target Rate is : %.3f Hz\n", target_rate);
00679 state->throttle = 1;
00680 break;
00681 case 'l':
00682 lcm_url = strdup(optarg);
00683 printf("Using LCM URL \"%s\"\n", lcm_url);
00684 break;
00685 case 'c':
00686 g_free(state->msg_channel);
00687 state->msg_channel = g_strdup(optarg);
00688 printf("Output on LCM channel: %s\n", state->msg_channel);
00689 break;
00690 case 'h':
00691 case '?':
00692 usage(argv[0]);
00693 }
00694 }
00695
00696 const char * depthModeSting[] = {
00697 "DEPTH_11BIT",
00698 "DEPTH_10BIT",
00699 "DEPTH_11BIT_PACKED",
00700 "DEPTH_10BIT_PACKED",
00701 "DEPTH_REGISTERED",
00702 "DEPTH_MM",
00703 };
00704 switch (state->requested_depth_format) {
00705 case KINECT_DEPTH_MSG_T_DEPTH_11BIT:
00706 case KINECT_DEPTH_MSG_T_DEPTH_10BIT:
00707 case KINECT_DEPTH_MSG_T_DEPTH_11BIT_PACKED:
00708 case KINECT_DEPTH_MSG_T_DEPTH_10BIT_PACKED:
00709 case KINECT_DEPTH_MSG_T_DEPTH_REGISTERED:
00710 case KINECT_DEPTH_MSG_T_DEPTH_MM:
00711 dbg("Depth Mode is %s\n", depthModeSting[state->requested_depth_format]);
00712 break;
00713 case KINECT_DEPTH_MSG_T_DEPTH_NONE:
00714 case -1:
00715 dbg("Depth is disabled");
00716 state->requested_depth_format = KINECT_DEPTH_MSG_T_DEPTH_NONE;
00717 state->skip_depth = 1;
00718 break;
00719 default:
00720 dbg("Invalid depth format %d\n", state->requested_depth_format);
00721 usage(argv[0]);
00722 break;
00723 }
00724
00725 const char * imageModeSting[] = {
00726 "VIDEO_RGB",
00727 "VIDEO_BAYER",
00728 "VIDEO_IR_8BIT",
00729 "VIDEO_IR_10BIT",
00730 "VIDEO_IR_10BIT_PACKED",
00731 "VIDEO_YUV_RGB",
00732 "VIDEO_YUV_RAW",
00733 };
00734
00735 switch (state->requested_image_format) {
00736 case KINECT_IMAGE_MSG_T_VIDEO_RGB:
00737 case KINECT_IMAGE_MSG_T_VIDEO_BAYER:
00738 case KINECT_IMAGE_MSG_T_VIDEO_IR_8BIT:
00739 case KINECT_IMAGE_MSG_T_VIDEO_IR_10BIT:
00740 case KINECT_IMAGE_MSG_T_VIDEO_IR_10BIT_PACKED:
00741 case KINECT_IMAGE_MSG_T_VIDEO_YUV_RGB:
00742 case KINECT_IMAGE_MSG_T_VIDEO_YUV_RAW:
00743 dbg("Image Mode is %s\n", imageModeSting[state->requested_image_format]);
00744 break;
00745
00746 case KINECT_IMAGE_MSG_T_VIDEO_RGB_JPEG:
00747 dbg("Jpeg Compressing RGB images\n");
00748 break;
00749 case KINECT_IMAGE_MSG_T_VIDEO_NONE:
00750 case -1:
00751 dbg("Image is disabled");
00752 state->requested_image_format = KINECT_IMAGE_MSG_T_VIDEO_NONE;
00753 state->skip_img = 1;
00754 break;
00755 default:
00756 dbg("Invalid image format %d\n", state->requested_image_format);
00757 usage(argv[0]);
00758 break;
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 state->capture_rate = rate_new(target_rate);
00771
00772
00773
00774
00775 state->image_data = (uint8_t*) malloc(640 * 480 * 4);
00776
00777
00778 state->image_buf_size = 640 * 480 * 10;
00779 if (0 != posix_memalign((void**) &state->image_buf, 16, state->image_buf_size)) {
00780 fprintf(stderr, "Error allocating image buffer\n");
00781 return 1;
00782 }
00783 state->msg.image.image_data = state->image_buf;
00784 state->msg.image.width = 640;
00785 state->msg.image.height = 480;
00786
00787
00788 state->debayer_buf_size = 640 * 480 * 4;
00789 state->debayer_buf_stride = 640 * 4;
00790 if (0 != posix_memalign((void**) &state->debayer_buf, 16, state->debayer_buf_size)) {
00791 fprintf(stderr, "error allocating de-Bayer buffer\n");
00792 return 1;
00793 }
00794
00795
00796 state->depth_unpack_buf_size = 640 * 480 * sizeof(uint16_t);
00797 state->depth_unpack_buf = (uint16_t*) malloc(state->depth_unpack_buf_size);
00798
00799
00800 state->depth_compress_buf_size = 640 * 480 * sizeof(int16_t) * 4;
00801 state->depth_compress_buf = (uint8_t*) malloc(state->depth_compress_buf_size);
00802 state->msg.depth.depth_data = state->depth_compress_buf;
00803 state->msg.depth.width = 640;
00804 state->msg.depth.height = 480;
00805
00806 state->got_img = 0;
00807 state->got_depth = 0;
00808
00809 state->report_rate = rate_new(0.5);
00810
00811 state->last_timestamp = 0;
00812
00813
00814
00815 state->lcm = lcm_create(lcm_url);
00816
00817 if (!state->lcm) {
00818 fprintf(stderr, "Unable to initialize LCM\n");
00819 return 1;
00820 }
00821
00822
00823 if (freenect_init(&state->f_ctx, NULL) < 0) {
00824 printf("freenect_init() failed\n");
00825 return 1;
00826 }
00827
00828 freenect_set_log_level(state->f_ctx, FREENECT_LOG_INFO);
00829
00830 int num_devices = freenect_num_devices(state->f_ctx);
00831 printf("Number of devices found: %d\n", num_devices);
00832
00833 if (num_devices < 1)
00834 return 1;
00835
00836 if (freenect_open_device(state->f_ctx, &state->f_dev, user_device_number) < 0) {
00837 printf("Could not open device\n");
00838 return 1;
00839 }
00840
00841 freenect_set_user(state->f_dev, state);
00842
00843
00844
00845 state->clocksync = timestamp_sync_init(100000000, 0xFFFFFFFFLL, 1.001);
00846
00847 if (!g_thread_supported())
00848 g_thread_init(NULL);
00849
00850
00851 kinect_cmd_msg_t_subscribe(state->lcm, "KINECT_CMD", cmd_cb, state);
00852
00853 GError *thread_err = NULL;
00854 state->freenect_thread = g_thread_create(freenect_threadfunc, state, TRUE, &thread_err);
00855 if (thread_err) {
00856 fprintf(stderr, "Error creating thread: %s\n", thread_err->message);
00857 return 1;
00858 }
00859
00860 pthread_create(&state->work_thread, NULL, status_thread, state);
00861
00862 while (!state->die) {
00863 lcm_handle(state->lcm);
00864 }
00865
00866 timestamp_sync_free(state->clocksync);
00867 g_free(state->msg_channel);
00868 rate_destroy(state->capture_rate);
00869 free(state);
00870
00871 return 0;
00872 }