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