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
47using namespace fawkes;
48using namespace fawkes::openni;
49using namespace firevision;
50
51bool g_quit = false;
52bool g_pause = false;
53bool g_draw_image = true;
54bool g_draw_depth = false;
55bool g_draw_skeleton = true;
56RemoteBlackBoard * g_rbb;
57Camera * g_image_cam;
58Camera * g_depth_cam;
59Camera * g_label_cam;
60SkelGuiImageDrawer * g_image_drawer = NULL;
61SkelGuiDepthDrawer * g_depth_drawer = NULL;
62SkelGuiSkeletonDrawer *g_skeleton_drawer = NULL;
63
64UserMap g_users;
65HandMap g_hands;
66
67SkelIfObserver *g_obs;
68HandIfObserver *g_hands_obs;
69
70void
71clean_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
92void
93glut_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
128void
129glut_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
141void
142glut_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
167void
168glInit(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
188int
189main(int argc, char **argv)
190{
191 ArgumentParser argp(argc, argv, "hr:n::js");
192
193 Thread::init_main();
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}
Draw images from camera in texture.
Definition: depth_drawer.h:35
void toggle_show_labels()
Toggle label state.
Draw images from camera in texture.
Definition: image_drawer.h:33
Draw body skeleton using OpenGL.
Definition: skel_drawer.h:32
void draw()
Draw skeletons.
void toggle_print_state()
Toggle the printing state.
void draw()
Draw texture to screen.
Parse command line arguments.
Definition: argparser.h:64
Base class for exceptions in Fawkes.
Definition: exception.h:36
void print_trace() noexcept
Prints trace to stderr.
Definition: exception.cpp:601
Remote BlackBoard.
Definition: remote.h:50
virtual void close(Interface *interface)
Close interface.
Definition: remote.cpp:319
Hand interface observer.
void process_queue()
Process internal queue.
Skeleton interface observer.
void process_queue()
Process internal queue.
Camera interface for image aquiring devices in FireVision.
Definition: camera.h:33
virtual unsigned int pixel_height()=0
Height of image in pixels.
virtual unsigned int pixel_width()=0
Width of image in pixels.
virtual void open()=0
Open the camera.
virtual void start()=0
Start image transfer from the camera.
Network camera.
Definition: net.h:41
Shared memory camera.
Definition: shmem.h:36
Fawkes library namespace.