CGR Localization
 All Classes Namespaces Files Functions Variables Macros Pages
kinect_main.cpp
Go to the documentation of this file.
1 //========================================================================
2 // This software is free: you can redistribute it and/or modify
3 // it under the terms of the GNU Lesser General Public License Version 3,
4 // as published by the Free Software Foundation.
5 //
6 // This software is distributed in the hope that it will be useful,
7 // but WITHOUT ANY WARRANTY; without even the implied warranty of
8 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 // GNU Lesser General Public License for more details.
10 //
11 // You should have received a copy of the GNU Lesser General Public License
12 // Version 3 in the file COPYING that came with this distribution.
13 // If not, see <http://www.gnu.org/licenses/>.
14 //========================================================================
20 //========================================================================
21 
22 #include <limits.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <iostream>
26 #include <stdio.h>
27 
28 #include "terminal_utils.h"
29 #include "proghelp.h"
30 #include "sys/time.h"
31 #include <ros/ros.h>
32 #include "timer.h"
33 #include <vector>
34 
35 #include "popt_pp.h"
36 #include <libusb.h>
37 #include "libfreenect.h"
38 #include <pthread.h>
39 #include <math.h>
40 #include "sensor_msgs/Image.h"
41 #include "sensor_msgs/image_encodings.h"
42 #include "plane_filtering.h"
43 #include "configreader.h"
44 #include "geometry.h"
45 
46 using namespace std;
47 
48 bool run = true;
49 
50 ros::NodeHandle *n;
51 KinectRawDepthCam kinectDepthCam;
52 
53 sensor_msgs::Image rawDepthImgMsg;
54 sensor_msgs::Image depthImgMsg;
55 sensor_msgs::Image rgbImgMsg;
56 
57 //ROS publisher
58 ros::Publisher rgbImagePublisher;
59 ros::Publisher depthImagePublisher;
60 ros::Publisher processedDepthImagePublisher;
61 
62 //Run modes
63 bool captureReady = false;
64 bool runColor = false;
65 int debugLevel = -1;
66 
67 //Device data
68 int kinectDeviceNumber = 0;
69 
70 //Kinect pose
71 vector3f kinectLoc;
72 float xRot, yRot, zRot;
73 
74 void rgb_cb(freenect_device *dev, freenect_pixel *rgb, uint32_t timestamp);
75 
76 WatchFiles watch_files;
77 ConfigReader config("./");
78 
79 void LoadParameters()
80 {
81  if(!config.readFiles()){
82  printf("Failed to read config\n");
83  exit(1);
84  }
85 
86  ConfigReader::SubTree c(config,"KinectParameters");
87 
88  unsigned int maxDepthVal=1024;
89  bool error = false;
90  error = error || !c.getReal("f",kinectDepthCam.f);
91  error = error || !c.getReal("fovH",kinectDepthCam.fovH);
92  error = error || !c.getReal("fovV",kinectDepthCam.fovV);
93  error = error || !c.getInt("width",kinectDepthCam.width);
94  error = error || !c.getInt("height",kinectDepthCam.height);
95  error = error || !c.getUInt("maxDepthVal",maxDepthVal);
96  kinectDepthCam.maxDepthVal = maxDepthVal;
97 
98  float xRot, yRot, zRot;
99  error = error || !c.getVec3f("loc",kinectLoc);
100  error = error || !c.getReal("xRot",xRot);
101  error = error || !c.getReal("yRot",yRot);
102  error = error || !c.getReal("zRot",zRot);
103 
104  if(error){
105  printf("Error Loading Kinect Parameters!\n");
106  exit(2);
107  }
108 }
109 
110 void InitMsgs()
111 {
112  rgbImgMsg.header.seq = 0;
113  rgbImgMsg.header.frame_id = "kinect";
114  rgbImgMsg.height = 480;
115  rgbImgMsg.width = 640;
116  rgbImgMsg.encoding = sensor_msgs::image_encodings::RGB8;
117  rgbImgMsg.is_bigendian = 0;
118  rgbImgMsg.step = 640*3;
119  rgbImgMsg.data.resize(640*480*3);
120 
121  rawDepthImgMsg.header.seq = 0;
122  rawDepthImgMsg.header.frame_id = "kinect";
123  rawDepthImgMsg.height = 480;
124  rawDepthImgMsg.width = 640;
125  rawDepthImgMsg.encoding = sensor_msgs::image_encodings::MONO16;
126  rawDepthImgMsg.is_bigendian = 0;
127  rawDepthImgMsg.step = 640*2;
128  rawDepthImgMsg.data.resize(640*480*2);
129 
130  depthImgMsg.header.seq = 0;
131  depthImgMsg.header.frame_id = "kinect";
132  depthImgMsg.height = 480;
133  depthImgMsg.width = 640;
134  depthImgMsg.encoding = sensor_msgs::image_encodings::MONO8;
135  depthImgMsg.is_bigendian = 0;
136  depthImgMsg.step = 640;
137  depthImgMsg.data.resize(640*480);
138 
139 }
140 
141 void rgbMsgCallback(const sensor_msgs::ImageConstPtr& msg)
142 {
143  static const bool debug = false;
144  if(debug) printf("Kinect RGB message received, t=%f\n",msg->header.stamp.toSec());
145  rgb_cb(NULL, (freenect_pixel*) msg->data.data(), 0);
146 }
147 
148 void PublishProcessedDepth(freenect_depth *depth)
149 {
150  static const double MaxDepth = 4.0;
151  depthImgMsg.header.seq++;
152  depthImgMsg.header.stamp = ros::Time::now();
153  double val;
154  for(int i=0; i<640*480; i++){
155  val = bound(1.0/(-0.00307110156*double(depth[i])+3.3309495)/MaxDepth,0.0,1.0);
156  depthImgMsg.data[i] = floor(255.0*val);
157  }
158  processedDepthImagePublisher.publish(depthImgMsg);
159 }
160 
161 void depth_cb(freenect_device *dev, freenect_depth *depth, uint32_t timestamp)
162 {
163  if(!captureReady)
164  return;
165 
166  uint8_t* ptrDest = rawDepthImgMsg.data.data();
167  memcpy(ptrDest, depth, FREENECT_DEPTH_SIZE);
168 
169  if(debugLevel>0)
170  PublishProcessedDepth(depth);
171 
172  rawDepthImgMsg.header.seq++;
173  rawDepthImgMsg.header.stamp = ros::Time::now();
174  depthImagePublisher.publish(rawDepthImgMsg);
175 }
176 
177 void rgb_cb(freenect_device *dev, freenect_pixel *rgb, uint32_t timestamp)
178 {
179  if(!captureReady)
180  return;
181 
182  uint8_t* ptrDest = rgbImgMsg.data.data();
183  memcpy(ptrDest, rgb, FREENECT_RGB_SIZE);
184  rgbImgMsg.header.seq++;
185  rgbImgMsg.header.stamp = ros::Time::now();
186  rgbImagePublisher.publish(rgbImgMsg);
187 }
188 
189 int kinect_main()
190 {
191  freenect_context *f_ctx;
192  freenect_device *f_dev;
193 
194  if (freenect_init(&f_ctx, NULL) < 0) {
195  printf("freenect_init() failed\n");
196  return 1;
197  }
198 
199  int nr_devices = freenect_num_devices (f_ctx);
200  if(debugLevel>=0) printf ("Number of devices found: %d\n", nr_devices);
201 
202  if (nr_devices < 1){
203  printf("No Kinect connected!\n");
204  return 1;
205  }
206 
207  if (freenect_open_device(f_ctx, &f_dev, kinectDeviceNumber) < 0) {
208  printf("Could not open device\n");
209  return 1;
210  }
211 
212  freenect_set_led(f_dev,LED_GREEN);
213  freenect_set_depth_callback(f_dev, depth_cb);
214 
215  freenect_set_rgb_callback(f_dev, rgb_cb);
216  freenect_set_rgb_format(f_dev, FREENECT_FORMAT_RGB);
217  freenect_set_depth_format(f_dev, FREENECT_FORMAT_11_BIT);
218 
219  if(debugLevel>=0) printf("Starting depth capture... "); fflush(stdout);
220  freenect_start_depth(f_dev);
221  if(debugLevel>=0) printf("Ready.\n"); fflush(stdout);
222 
223 
224  if(runColor){
225  if(debugLevel>=0) printf("Starting RGB capture... "); fflush(stdout);
226  freenect_start_rgb(f_dev);
227  if(debugLevel>=0) printf("Ready.\n"); fflush(stdout);
228  }
229 
230  captureReady = true;
231 
232  while(run && freenect_process_events(f_ctx) >= 0 && ros::ok()){
233 
234  if(watch_files.getEvents() != 0){
235  printf("Reloading parameters.\n");
236  LoadParameters();
237  watch_files.clearEvents();
238  }
239  Sleep(0.01);
240  }
241 
242  //freenect_stop_depth(f_dev);
243  //freenect_stop_rgb(f_dev);
244 
245  if(debugLevel>=0) printf("done!\n");
246  freenect_set_led(f_dev,LED_BLINK_GREEN);
247 
248  return 0;
249 }
250 
251 int main(int argc, char **argv) {
252 
253  ColourTerminal(TerminalUtils::TERMINAL_COL_WHITE,TerminalUtils::TERMINAL_COL_BLACK,TerminalUtils::TERMINAL_ATTR_BRIGHT);
254  printf("\nKinect module\n\n");
255  ResetTerminal();
256 
257  // option table
258  static struct poptOption options[] = {
259  { "debug" , 'd', POPT_ARG_INT , &debugLevel, 0, "Debug Level" , "NUM" },
260  { "device-num" , 'n', POPT_ARG_INT , &kinectDeviceNumber ,0, "Kinect device number" , "NUM" },
261  { "color" , 'c', POPT_ARG_NONE , &runColor ,0, "Run Color Camera" , "NONE"},
262 
263  POPT_AUTOHELP
264  { NULL, 0, 0, NULL, 0, NULL, NULL }
265  };
266  // parse options
267  POpt popt(NULL,argc,(const char**)argv,options,0);
268  int c;
269  while((c = popt.getNextOpt()) >= 0){
270  }
271 
272  config.init(watch_files);
273  config.addFile("config/kinect_parameters.cfg");
274  LoadParameters();
275  InitMsgs();
276 
277  ros::init(argc, argv, "Kinect_Module", ros::init_options::NoSigintHandler);
278  n = new ros::NodeHandle();
279  rgbImagePublisher = n->advertise<sensor_msgs::Image>("Kinect/RGB", 1);
280  depthImagePublisher = n->advertise<sensor_msgs::Image>("Kinect/Depth", 1);
281  processedDepthImagePublisher = n->advertise<sensor_msgs::Image>("Kinect/ProcessedDepth", 1);
282 
283  // main program initialization
284  InitHandleStop(&run);
285 
286  return kinect_main();
287 
288  if(debugLevel>=0) printf("Closing.\n");
289 
290  return(0);
291 }
Subroutines to spice up stdout.
float f
focal point
Definition: popt_pp.h:6
uint16_t maxDepthVal
Maximum valid depth value.
Raw Kinect Depth Camera to process raw depth images from libfreenect.
Interface to PlaneFiltering class, to perform plane filtering of 3D point clouds from depth images...