Fawkes API  Fawkes Development Version
main.cpp
1 
2 /***************************************************************************
3  * main.cpp - Skeleton Visualization GUI: main program
4  *
5  * Created: Wed Mar 02 11:15:53 2011
6  * Copyright 2006-2011 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 "depth_drawer.h"
24 #include "image_drawer.h"
25 #include "skel_drawer.h"
26 
27 #include <GL/glut.h>
28 #include <blackboard/interface_observer.h>
29 #include <blackboard/remote.h>
30 #include <core/threading/mutex.h>
31 #include <core/threading/thread.h>
32 #include <fvcams/net.h>
33 #include <fvcams/shmem.h>
34 #include <plugins/openni/utils/hand_if_observer.h>
35 #include <plugins/openni/utils/skel_if_observer.h>
36 #include <utils/system/argparser.h>
37 
38 #include <cstdio>
39 #include <cstring>
40 #include <map>
41 #include <queue>
42 #include <string>
43 
44 #define GL_WIN_SIZE_X 640
45 #define GL_WIN_SIZE_Y 480
46 
47 using namespace fawkes;
48 using namespace fawkes::openni;
49 using namespace firevision;
50 
51 bool g_quit = false;
52 bool g_pause = false;
53 bool g_draw_image = true;
54 bool g_draw_depth = false;
55 bool g_draw_skeleton = true;
56 RemoteBlackBoard * g_rbb;
57 Camera * g_image_cam;
58 Camera * g_depth_cam;
59 Camera * g_label_cam;
60 SkelGuiImageDrawer * g_image_drawer = NULL;
61 SkelGuiDepthDrawer * g_depth_drawer = NULL;
62 SkelGuiSkeletonDrawer *g_skeleton_drawer = NULL;
63 
64 UserMap g_users;
65 HandMap g_hands;
66 
67 SkelIfObserver *g_obs;
68 HandIfObserver *g_hands_obs;
69 
70 void
71 clean_exit()
72 {
73  delete g_obs;
74  delete g_hands_obs;
75  for (UserMap::iterator i = g_users.begin(); i != g_users.end(); ++i) {
76  g_rbb->close(i->second.skel_if);
77  g_rbb->close(i->second.proj_if);
78  }
79  delete g_rbb;
80 
81  delete g_image_cam;
82  delete g_depth_cam;
83  delete g_label_cam;
84  delete g_image_drawer;
85  delete g_depth_drawer;
86  delete g_skeleton_drawer;
87 
88  exit(1);
89 }
90 
91 // this function is called each frame
92 void
93 glut_display(void)
94 {
95  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
96 
97  // Setup the OpenGL viewpoint
98  glMatrixMode(GL_PROJECTION);
99  glPushMatrix();
100  glLoadIdentity();
101 
102  glOrtho(0, GL_WIN_SIZE_X, GL_WIN_SIZE_Y, 0, -1.0, 1.0);
103 
104  if (g_draw_image && g_image_drawer)
105  g_image_drawer->draw();
106  if (g_draw_depth && g_depth_drawer)
107  g_depth_drawer->draw();
108 
109  if (!g_users.empty() || !g_hands.empty()) {
110  if (!g_pause) {
111  for (UserMap::iterator i = g_users.begin(); i != g_users.end(); ++i) {
112  i->second.skel_if->read();
113  i->second.proj_if->read();
114  }
115  for (HandMap::iterator i = g_hands.begin(); i != g_hands.end(); ++i) {
116  i->second.hand_if->read();
117  }
118  }
119 
120  // Process the data
121  if (g_draw_skeleton)
122  g_skeleton_drawer->draw();
123  }
124 
125  glutSwapBuffers();
126 }
127 
128 void
129 glut_idle()
130 {
131  if (g_quit)
132  clean_exit();
133 
134  g_obs->process_queue();
135  g_hands_obs->process_queue();
136 
137  // Display the frame
138  glutPostRedisplay();
139 }
140 
141 void
142 glut_keyboard(unsigned char key, int x, int y)
143 {
144  switch (key) {
145  case 27:
146  case 'q': clean_exit();
147  case 'i':
148  g_draw_image = !g_draw_image;
149  if (g_draw_image)
150  g_draw_depth = false;
151  break;
152  case 'd':
153  g_draw_depth = !g_draw_depth;
154  if (g_draw_depth)
155  g_draw_image = false;
156  break;
157  case 's': g_draw_skeleton = !g_draw_skeleton; break;
158  case 'l': g_skeleton_drawer->toggle_print_state(); break;
159  case 'L':
160  if (g_depth_drawer)
161  g_depth_drawer->toggle_show_labels();
162  break;
163  case 'p': g_pause = !g_pause; break;
164  }
165 }
166 
167 void
168 glInit(int *pargc, char **argv)
169 {
170  glutInit(pargc, argv);
171  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
172  glutInitWindowSize(GL_WIN_SIZE_X, GL_WIN_SIZE_Y);
173  glutCreateWindow("Fawkes Skeleton GUI");
174  //glutFullScreen();
175  glutSetCursor(GLUT_CURSOR_NONE);
176 
177  glutKeyboardFunc(glut_keyboard);
178  glutDisplayFunc(glut_display);
179  glutIdleFunc(glut_idle);
180 
181  glDisable(GL_DEPTH_TEST);
182  glEnable(GL_TEXTURE_2D);
183 
184  glEnableClientState(GL_VERTEX_ARRAY);
185  glDisableClientState(GL_COLOR_ARRAY);
186 }
187 
188 int
189 main(int argc, char **argv)
190 {
191  ArgumentParser argp(argc, argv, "hr:n::js");
192 
194  glInit(&argc, argv);
195 
196  std::string host = "localhost";
197  unsigned short int port = 1910;
198  if (argp.has_arg("r")) {
199  argp.parse_hostport("r", host, port);
200  }
201 
202  std::string fvhost = host;
203  unsigned short int fvport = 2208;
204  if (argp.has_arg("n")) {
205  argp.parse_hostport("n", fvhost, fvport);
206  }
207 
208  printf("Connecting to %s:%u\n", host.c_str(), port);
209  try {
210  g_rbb = new RemoteBlackBoard(host.c_str(), port);
211  } catch (Exception &e) {
212  e.print_trace();
213  exit(-1);
214  }
215  g_obs = new SkelIfObserver(g_rbb, g_users);
216  g_hands_obs = new HandIfObserver(g_rbb, g_hands);
217 
218  g_image_cam = NULL;
219  g_depth_cam = NULL;
220  g_label_cam = NULL;
221  g_image_drawer = NULL;
222 
223  if (argp.has_arg("n") || argp.has_arg("s")) {
224  if (argp.has_arg("n")) {
225  g_image_cam = new NetworkCamera(fvhost.c_str(), fvport, "openni-image", argp.has_arg("j"));
226  g_depth_cam = new NetworkCamera(fvhost.c_str(), fvport, "openni-depth");
227  g_label_cam = new NetworkCamera(fvhost.c_str(), fvport, "openni-labels");
228  } else {
229  g_image_cam = new SharedMemoryCamera("openni-image");
230  g_depth_cam = new SharedMemoryCamera("openni-depth");
231  try {
232  g_label_cam = new SharedMemoryCamera("openni-labels");
233  g_label_cam->open();
234  g_label_cam->start();
235  if ((g_label_cam->pixel_width() != GL_WIN_SIZE_X)
236  || (g_label_cam->pixel_height() != GL_WIN_SIZE_Y)) {
237  delete g_label_cam;
238  g_label_cam = NULL;
239  throw Exception("Invalid label cam");
240  }
241  } catch (Exception &e) {
242  printf("Cannot open label cam, user tracker not running? "
243  "Disabling labels.\n");
244  }
245  }
246  g_image_cam->open();
247  g_image_cam->start();
248  g_depth_cam->open();
249  g_depth_cam->start();
250  if (g_label_cam) {
251  g_label_cam->open();
252  g_label_cam->start();
253  }
254 
255  if ((g_image_cam->pixel_width() != GL_WIN_SIZE_X)
256  || (g_image_cam->pixel_height() != GL_WIN_SIZE_Y)
257  || (g_depth_cam->pixel_width() != GL_WIN_SIZE_X)
258  || (g_depth_cam->pixel_height() != GL_WIN_SIZE_Y)) {
259  printf("Image size different from window size, closing camera");
260  delete g_image_cam;
261  delete g_depth_cam;
262  g_image_cam = g_depth_cam = NULL;
263  }
264 
265  g_image_drawer = new SkelGuiImageDrawer(g_image_cam);
266  g_depth_drawer = new SkelGuiDepthDrawer(g_depth_cam, g_label_cam, 10000);
267  }
268 
269  g_skeleton_drawer = new SkelGuiSkeletonDrawer(g_users, g_hands);
270 
271  glutMainLoop();
272 }
void toggle_print_state()
Toggle the printing state.
Draw body skeleton using OpenGL.
Definition: skel_drawer.h:31
Camera interface for image aquiring devices in FireVision.
Definition: camera.h:32
void draw()
Draw skeletons.
Draw images from camera in texture.
Definition: depth_drawer.h:34
Fawkes library namespace.
void toggle_show_labels()
Toggle label state.
void process_queue()
Process internal queue.
virtual unsigned int pixel_width()=0
Width of image in pixels.
Parse command line arguments.
Definition: argparser.h:63
static void init_main()
Initialize Thread wrapper instance for main thread.
Definition: thread.cpp:1276
void process_queue()
Process internal queue.
virtual void close(Interface *interface)
Close interface.
Definition: remote.cpp:319
Skeleton interface observer.
Base class for exceptions in Fawkes.
Definition: exception.h:35
void draw()
Draw texture to screen.
Shared memory camera.
Definition: shmem.h:35
Hand interface observer.
virtual void open()=0
Open the camera.
Draw images from camera in texture.
Definition: image_drawer.h:32
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:601
Remote BlackBoard.
Definition: remote.h:48
virtual unsigned int pixel_height()=0
Height of image in pixels.
virtual void start()=0
Start image transfer from the camera.
Network camera.
Definition: net.h:40