fakenect.c
Go to the documentation of this file.
1 /*
2  * This file is part of the OpenKinect Project. http://www.openkinect.org
3  *
4  * Copyright (c) 2010 Brandyn White (bwhite@dappervision.com)
5  *
6  * This code is licensed to you under the terms of the Apache License, version
7  * 2.0, or, at your option, the terms of the GNU General Public License,
8  * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
9  * or the following URLs:
10  * http://www.apache.org/licenses/LICENSE-2.0
11  * http://www.gnu.org/licenses/gpl-2.0.txt
12  *
13  * If you redistribute this file in source form, modified or unmodified, you
14  * may:
15  * 1) Leave this header intact and distribute it under the same terms,
16  * accompanying it with the APACHE20 and GPL20 files, or
17  * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
18  * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
19  * In all cases you must keep the copyright notice intact and include a copy
20  * of the CONTRIB file.
21  *
22  * Binary distributions must follow the binary distribution requirements of
23  * either License.
24  */
25 
26 #include "libfreenect.h"
27 #include "platform.h"
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <math.h>
32 #include <unistd.h>
33 #include <assert.h>
34 
35 #define GRAVITY 9.80665
36 
37 // The dev and ctx are just faked with these numbers
38 
43 static char *input_path = NULL;
44 static FILE *index_fp = NULL;
46 static int already_warned = 0;
47 static double playback_prev_time = 0.;
48 static double record_prev_time = 0.;
49 static void *depth_buffer = NULL;
50 static void *rgb_buffer = NULL;
51 static int depth_running = 0;
52 static int rgb_running = 0;
53 static void *user_ptr = NULL;
54 
55 static char *one_line(FILE *fp)
56 {
57  int c;
58  int pos = 0;
59  char *out = NULL;
60  for (c = fgetc(fp); !(c == '\n' || c == EOF); c = fgetc(fp))
61  {
62  out = realloc(out, pos + 1);
63  out[pos++] = c;
64  }
65  if (out) {
66  out = realloc(out, pos + 1);
67  out[pos] = '\0';
68  }
69  return out;
70 }
71 
72 static int get_data_size(FILE *fp)
73 {
74  int orig = ftell(fp);
75  fseek(fp, 0L, SEEK_END);
76  int out = ftell(fp);
77  fseek(fp, orig, SEEK_SET);
78  return out;
79 }
80 
81 static int parse_line(char *type, double *cur_time, unsigned int *timestamp, unsigned int *data_size, char **data)
82 {
83  char *line = one_line(index_fp);
84  if (!line) {
85  printf("Warning: No more lines in [%s]\n", input_path);
86  return -1;
87  }
88  int file_path_size = strlen(input_path) + strlen(line) + 50;
89  char *file_path = malloc(file_path_size);
90  snprintf(file_path, file_path_size, "%s/%s", input_path, line);
91  // Open file
92  FILE *cur_fp = fopen(file_path, "rb");
93  if (!cur_fp) {
94  printf("Error: Cannot open file [%s]\n", file_path);
95  exit(1);
96  }
97  // Parse data from file name
98  int ret = 0;
99  *data_size = get_data_size(cur_fp);
100  sscanf(line, "%c-%lf-%u-%*s", type, cur_time, timestamp);
101  *data = malloc(*data_size);
102  if (fread(*data, *data_size, 1, cur_fp) != 1) {
103  printf("Error: Couldn't read entire file.\n");
104  ret = -1;
105  }
106  fclose(cur_fp);
107  free(line);
108  free(file_path);
109  return ret;
110 }
111 
112 static void open_index()
113 {
114  input_path = getenv("FAKENECT_PATH");
115  if (!input_path) {
116  printf("Error: Environmental variable FAKENECT_PATH is not set. Set it to a path that was created using the 'record' utility.\n");
117  exit(1);
118  }
119  int index_path_size = strlen(input_path) + 50;
120  char *index_path = malloc(index_path_size);
121  snprintf(index_path, index_path_size, "%s/INDEX.txt", input_path);
122  index_fp = fopen(index_path, "rb");
123  if (!index_fp) {
124  printf("Error: Cannot open file [%s]\n", index_path);
125  exit(1);
126  }
127  free(index_path);
128 }
129 
130 static char *skip_line(char *str)
131 {
132  char *out = strchr(str, '\n');
133  if (!out) {
134  printf("Error: PGM/PPM has incorrect formatting, expected a header on one line followed by a newline\n");
135  exit(1);
136  }
137  return out + 1;
138 }
139 
141 {
142  /* This is where the magic happens. We read 1 update from the index
143  per call, so this needs to be called in a loop like usual. If the
144  index line is a Depth/RGB image the provided callback is called. If
145  the index line is accelerometer data, then it is used to update our
146  internal state. If you query for the accelerometer data you get the
147  last sensor reading that we have. The time delays are compensated as
148  best as we can to match those from the original data and current run
149  conditions (e.g., if it takes longer to run this code then we wait less).
150  */
151  if (!index_fp)
152  open_index();
153  char type;
154  double record_cur_time;
155  unsigned int timestamp, data_size;
156  char *data = NULL;
157  if (parse_line(&type, &record_cur_time, &timestamp, &data_size, &data))
158  return -1;
159  // Sleep an amount that compensates for the original and current delays
160  // playback_ is w.r.t. the current time
161  // record_ is w.r.t. the original time period during the recording
162  if (record_prev_time != 0. && playback_prev_time != 0.)
163  sleep_highres((record_cur_time - record_prev_time) - (get_time() - playback_prev_time));
164  record_prev_time = record_cur_time;
165  switch (type) {
166  case 'd':
167  if (cur_depth_cb && depth_running) {
168  void *cur_depth = skip_line(data);
169  if (depth_buffer) {
171  cur_depth = depth_buffer;
172  }
173  cur_depth_cb(fake_dev, cur_depth, timestamp);
174  }
175  break;
176  case 'r':
177  if (cur_rgb_cb && rgb_running) {
178  void *cur_rgb = skip_line(data);
179  if (rgb_buffer) {
181  cur_rgb = rgb_buffer;
182  }
183  cur_rgb_cb(fake_dev, cur_rgb, timestamp);
184  }
185  break;
186  case 'a':
187  if (data_size == sizeof(state)) {
188  memcpy(&state, data, sizeof(state));
189  } else if (!already_warned) {
190  already_warned = 1;
191  printf("\n\nWarning: Accelerometer data has an unexpected"
192  " size [%u] instead of [%u]. The acceleration "
193  "and tilt data will be substituted for dummy "
194  "values. This data was probably made with an "
195  "older version of record (the upstream interface "
196  "changed).\n\n",
197  data_size, (unsigned int)sizeof state);
198  }
199  break;
200  }
201  free(data);
203  return 0;
204 }
205 
207 {
208  return freenect_process_events(ctx);
209 }
210 
212 {
213  // NOTE: This is duped from tilt.c, this is the only function we need from there
214  return ((double)state->tilt_angle) / 2.;
215 }
216 
218 {
219  return &state;
220 }
221 
223 {
224  return state->tilt_status;
225 }
226 
227 void freenect_get_mks_accel(freenect_raw_tilt_state *state, double* x, double* y, double* z)
228 {
229  //the documentation for the accelerometer (http://www.kionix.com/Product%20Sheets/KXSD9%20Product%20Brief.pdf)
230  //states there are 819 counts/g
231  *x = (double)state->accelerometer_x/FREENECT_COUNTS_PER_G*GRAVITY;
232  *y = (double)state->accelerometer_y/FREENECT_COUNTS_PER_G*GRAVITY;
233  *z = (double)state->accelerometer_z/FREENECT_COUNTS_PER_G*GRAVITY;
234 }
235 
237 {
238  cur_depth_cb = cb;
239 }
240 
242 {
243  cur_rgb_cb = cb;
244 }
245 
247 {
248  // Always say it was successful but continue to pass through the
249  // underlying data. Would be better to check for conflict.
250  return 0;
251 }
252 
254 {
255  // Always say it was successful but continue to pass through the
256  // underlying data. Would be better to check for conflict.
257  return 0;
258 }
259 
261  assert(FREENECT_RESOLUTION_MEDIUM == res);
262  assert(FREENECT_VIDEO_RGB == fmt);
263  // NOTE: This will leave uninitialized values if new fields are added.
264  // To update this line run the "record" program, look at the top output
265  freenect_frame_mode out = {256, 1, {0}, 921600, 640, 480, 24, 0, 30, 1};
266  return out;
267 }
268 
270 {
271  return 1;
272 }
273 
275 {
277 }
278 
280 {
281  return freenect_get_video_mode(0);
282 }
283 
285  assert(FREENECT_RESOLUTION_MEDIUM == res);
286  assert(FREENECT_DEPTH_11BIT == fmt);
287  // NOTE: This will leave uninitialized values if new fields are added.
288  // To update this line run the "record" program, look at the top output
289  freenect_frame_mode out = {256, 1, {0}, 614400, 640, 480, 11, 5, 30, 1};
290  return out;
291 }
292 
294 {
295  return 1;
296 }
297 
299 {
301 }
302 
304 {
305  return freenect_get_depth_mode(0);
306 }
307 
309 {
310  // Always 1 device
311  return 1;
312 }
313 
315 {
316  // Set it to some number to allow for NULL checks
317  *dev = fake_dev;
318  return 0;
319 }
320 
322 {
323  *dev = fake_dev;
324  return 0;
325 }
326 
328 {
329  *ctx = fake_ctx;
330  return 0;
331 }
332 
334 {
336 }
337 
339  // Ideally, we'd actually check for MOTOR and CAMERA and AUDIO, but for now
340  // we just ignore them and provide all captured data.
341 }
342 
344 {
345  depth_buffer = buf;
346  return 0;
347 }
348 
350 {
351  rgb_buffer = buf;
352  return 0;
353 }
354 
355 void freenect_set_user(freenect_device *dev, void *user)
356 {
357  user_ptr = user;
358 }
359 
361 {
362  return user_ptr;
363 }
364 
366 {
367  depth_running = 1;
368  return 0;
369 }
370 
372 {
373  rgb_running = 1;
374  return 0;
375 }
376 
378 {
379  depth_running = 0;
380  return 0;
381 }
382 
384 {
385  rgb_running = 0;
386  return 0;
387 }
388 
390 {
391  assert(fmt == FREENECT_VIDEO_RGB);
392  return 0;
393 }
395 {
396  assert(fmt == FREENECT_DEPTH_11BIT);
397  return 0;
398 }
399 
403 {
404  return 0;
405 }
407 {
408  return 0;
409 }
411 {
412  return 0;
413 }
415 {
416  return 0;
417 }
419 {
420  return 0;
421 }
void freenect_set_video_callback(freenect_device *dev, freenect_video_cb cb)
Definition: fakenect.c:241
freenect_frame_mode freenect_get_depth_mode(int mode_num)
Definition: fakenect.c:298
static FILE * index_fp
Definition: fakenect.c:44
void freenect_select_subdevices(freenect_context *ctx, freenect_device_flags subdevs)
Definition: fakenect.c:338
static double record_prev_time
Definition: fakenect.c:48
void freenect_get_mks_accel(freenect_raw_tilt_state *state, double *x, double *y, double *z)
Definition: fakenect.c:227
void freenect_set_log_callback(freenect_context *ctx, freenect_log_cb cb)
Definition: fakenect.c:400
void sleep_highres(double tm)
Definition: platform.h:61
int freenect_stop_video(freenect_device *dev)
Definition: fakenect.c:383
freenect_video_format
Definition: libfreenect.h:86
int freenect_open_device_by_camera_serial(freenect_context *ctx, freenect_device **dev, const char *camera_serial)
Definition: fakenect.c:321
static void * depth_buffer
Definition: fakenect.c:49
freenect_frame_mode freenect_get_video_mode(int mode_num)
Definition: fakenect.c:274
static int parse_line(char *type, double *cur_time, unsigned int *timestamp, unsigned int *data_size, char **data)
Definition: fakenect.c:81
static double playback_prev_time
Definition: fakenect.c:47
void freenect_usb_context
Definition: libfreenect.h:182
int freenect_num_devices(freenect_context *ctx)
Definition: fakenect.c:308
freenect_tilt_status_code tilt_status
Definition: libfreenect.h:172
int freenect_start_depth(freenect_device *dev)
Definition: fakenect.c:365
static freenect_context * fake_ctx
Definition: fakenect.c:40
int freenect_set_led(freenect_device *dev, freenect_led_options option)
Definition: fakenect.c:414
int freenect_set_video_buffer(freenect_device *dev, void *buf)
Definition: fakenect.c:349
int freenect_shutdown(freenect_context *ctx)
Definition: fakenect.c:402
void(* freenect_depth_cb)(freenect_device *dev, void *depth, uint32_t timestamp)
Typedef for depth image received event callbacks.
Definition: libfreenect.h:385
#define FREENECT_COUNTS_PER_G
Definition: libfreenect.h:42
freenect_depth_format
Definition: libfreenect.h:99
int freenect_set_video_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:246
int freenect_set_tilt_degs(freenect_device *dev, double angle)
Definition: fakenect.c:410
int freenect_process_events_timeout(freenect_context *ctx, struct timeval *timeout)
Definition: fakenect.c:206
static int depth_running
Definition: fakenect.c:51
void freenect_set_depth_callback(freenect_device *dev, freenect_depth_cb cb)
Definition: fakenect.c:236
freenect_loglevel
Enumeration of message logging levels.
Definition: libfreenect.h:200
void freenect_set_log_level(freenect_context *ctx, freenect_loglevel level)
Definition: fakenect.c:401
int freenect_start_video(freenect_device *dev)
Definition: fakenect.c:371
double freenect_get_tilt_degs(freenect_raw_tilt_state *state)
Definition: fakenect.c:211
freenect_tilt_status_code freenect_get_tilt_status(freenect_raw_tilt_state *state)
Definition: fakenect.c:222
freenect_frame_mode freenect_find_video_mode(freenect_resolution res, freenect_video_format fmt)
Definition: fakenect.c:260
static freenect_device * fake_dev
Definition: fakenect.c:39
static int rgb_running
Definition: fakenect.c:52
int freenect_set_video_format(freenect_device *dev, freenect_video_format fmt)
Definition: fakenect.c:389
freenect_frame_mode freenect_get_current_depth_mode(freenect_device *dev)
Definition: fakenect.c:303
void * freenect_get_user(freenect_device *dev)
Definition: fakenect.c:360
freenect_frame_mode freenect_find_depth_mode(freenect_resolution res, freenect_depth_format fmt)
Definition: fakenect.c:284
freenect_led_options
Definition: libfreenect.h:148
#define GRAVITY
Definition: fakenect.c:35
static char * skip_line(char *str)
Definition: fakenect.c:130
static void * user_ptr
Definition: fakenect.c:53
freenect_raw_tilt_state * freenect_get_tilt_state(freenect_device *dev)
Definition: fakenect.c:217
static char * input_path
Definition: fakenect.c:43
static freenect_depth_cb cur_depth_cb
Definition: fakenect.c:41
int freenect_update_tilt_state(freenect_device *dev)
Definition: fakenect.c:418
void(* freenect_log_cb)(freenect_context *dev, freenect_loglevel level, const char *msg)
Typedef for logging callback functions.
Definition: libfreenect.h:232
int freenect_get_video_mode_count()
Definition: fakenect.c:269
int freenect_close_device(freenect_device *dev)
Definition: fakenect.c:406
int freenect_set_depth_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:253
freenect_frame_mode freenect_get_current_video_mode(freenect_device *dev)
Definition: fakenect.c:279
int freenect_open_device(freenect_context *ctx, freenect_device **dev, int index)
Definition: fakenect.c:314
int freenect_get_depth_mode_count()
Definition: fakenect.c:293
freenect_resolution
Definition: libfreenect.h:77
double get_time()
Definition: platform.h:39
static int get_data_size(FILE *fp)
Definition: fakenect.c:72
static freenect_video_cb cur_rgb_cb
Definition: fakenect.c:42
int freenect_supported_subdevices(void)
Definition: fakenect.c:333
static void open_index()
Definition: fakenect.c:112
static freenect_context * ctx
Data from the tilt motor and accelerometer.
Definition: libfreenect.h:167
static freenect_raw_tilt_state state
Definition: fakenect.c:45
freenect_device_flags
Definition: libfreenect.h:58
int freenect_stop_depth(freenect_device *dev)
Definition: fakenect.c:377
static int already_warned
Definition: fakenect.c:46
void(* freenect_video_cb)(freenect_device *dev, void *video, uint32_t timestamp)
Typedef for video image received event callbacks.
Definition: libfreenect.h:387
freenect_tilt_status_code
Enumeration of tilt motor status.
Definition: libfreenect.h:160
static char * one_line(FILE *fp)
Definition: fakenect.c:55
int freenect_process_events(freenect_context *ctx)
Definition: fakenect.c:140
int freenect_set_depth_format(freenect_device *dev, freenect_depth_format fmt)
Definition: fakenect.c:394
int freenect_set_depth_buffer(freenect_device *dev, void *buf)
Definition: fakenect.c:343
void freenect_set_user(freenect_device *dev, void *user)
Definition: fakenect.c:355
static void * rgb_buffer
Definition: fakenect.c:50
int freenect_init(freenect_context **ctx, freenect_usb_context *usb_ctx)
Definition: fakenect.c:327


libfreenect
Author(s): Hector Martin, Josh Blake, Kyle Machulis, OpenKinect community
autogenerated on Mon Jun 10 2019 13:46:42