00001 #include <boost/thread.hpp>
00002
00003 #include <ros/ros.h>
00004 #include <ros/time.h>
00005
00006 #include "uvc_cam/uvc_cam.h"
00007 #include "sensor_msgs/Image.h"
00008 #include "sensor_msgs/CompressedImage.h"
00009 #include "sensor_msgs/image_encodings.h"
00010 #include "sensor_msgs/CameraInfo.h"
00011 #include "camera_info_manager/camera_info_manager.h"
00012 #include "image_transport/image_transport.h"
00013
00014 #include "uvc_camera/camera.h"
00015
00016 using namespace sensor_msgs;
00017
00018 namespace uvc_camera {
00019
00020 Camera::Camera(ros::NodeHandle _comm_nh, ros::NodeHandle _param_nh) :
00021 node(_comm_nh), pnode(_param_nh), it(_comm_nh),
00022 info_mgr(_comm_nh, "camera"), cam(0) {
00023
00024
00025 width = 640;
00026 height = 480;
00027 fps = 10;
00028 skip_frames = 0;
00029 frames_to_skip = 0;
00030 device = "/dev/video0";
00031 frame = "camera";
00032 rotate = false;
00033 format = "rgb";
00034
00035
00036 std::string url, camera_name;
00037 pnode.getParam("camera_info_url", url);
00038 pnode.param<std::string>("camera_name", camera_name, "camera");
00039
00040 info_mgr.setCameraName(camera_name);
00041 info_mgr.loadCameraInfo(url);
00042
00043
00044 pnode.getParam("device", device);
00045
00046 pnode.getParam("fps", fps);
00047 pnode.getParam("skip_frames", skip_frames);
00048
00049 pnode.getParam("width", width);
00050 pnode.getParam("height", height);
00051
00052 pnode.getParam("frame_id", frame);
00053
00054 pnode.getParam("format", format);
00055
00056
00057 if (format != "jpeg")
00058 pub = it.advertise("image_raw", 1);
00059 else
00060 pubjpeg = node.advertise<CompressedImage>("image_raw/compressed", 1);
00061
00062 info_pub = node.advertise<CameraInfo>("camera_info", 1);
00063
00064
00065 uvc_cam::Cam::mode_t mode = uvc_cam::Cam::MODE_RGB;
00066 if (format == "jpeg")
00067 mode = uvc_cam::Cam::MODE_MJPG;
00068 cam = new uvc_cam::Cam(device.c_str(), mode, width, height, fps);
00069 cam->set_motion_thresholds(100, -1);
00070
00071 bool auto_focus;
00072 if (pnode.getParam("auto_focus", auto_focus)) {
00073 cam->set_v4l2_control(V4L2_CID_FOCUS_AUTO, auto_focus, "auto_focus");
00074 }
00075
00076 int focus_absolute;
00077 if (pnode.getParam("focus_absolute", focus_absolute)) {
00078 cam->set_v4l2_control(V4L2_CID_FOCUS_ABSOLUTE, focus_absolute, "focus_absolute");
00079 }
00080
00081 bool auto_exposure;
00082 if (pnode.getParam("auto_exposure", auto_exposure)) {
00083 int val;
00084 if (auto_exposure) {
00085 val = V4L2_EXPOSURE_AUTO;
00086 } else {
00087 val = V4L2_EXPOSURE_MANUAL;
00088 }
00089 cam->set_v4l2_control(V4L2_CID_EXPOSURE_AUTO, val, "auto_exposure");
00090 }
00091
00092 int exposure_auto_priority;
00093 if (pnode.getParam("exposure_auto_priority", exposure_auto_priority)) {
00094 cam->set_v4l2_control(V4L2_CID_EXPOSURE_AUTO_PRIORITY, exposure_auto_priority, "exposure_auto_priority");
00095 }
00096
00097 int exposure_absolute;
00098 if (pnode.getParam("exposure_absolute", exposure_absolute)) {
00099 cam->set_v4l2_control(V4L2_CID_EXPOSURE_ABSOLUTE, exposure_absolute, "exposure_absolute");
00100 }
00101
00102 int exposure;
00103 if (pnode.getParam("exposure", exposure)) {
00104 cam->set_v4l2_control(V4L2_CID_EXPOSURE, exposure, "exposure");
00105 }
00106
00107 int brightness;
00108 if (pnode.getParam("brightness", brightness)) {
00109 cam->set_v4l2_control(V4L2_CID_BRIGHTNESS, brightness, "brightness");
00110 }
00111
00112 int power_line_frequency;
00113 if (pnode.getParam("power_line_frequency", power_line_frequency)) {
00114 int val;
00115 if (power_line_frequency == 0) {
00116 val = V4L2_CID_POWER_LINE_FREQUENCY_DISABLED;
00117 } else if (power_line_frequency == 50) {
00118 val = V4L2_CID_POWER_LINE_FREQUENCY_50HZ;
00119 } else if (power_line_frequency == 60) {
00120 val = V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
00121 } else {
00122 printf("power_line_frequency=%d not supported. Using auto.\n", power_line_frequency);
00123 val = V4L2_CID_POWER_LINE_FREQUENCY_AUTO;
00124 }
00125 cam->set_v4l2_control(V4L2_CID_POWER_LINE_FREQUENCY, val, "power_line_frequency");
00126 }
00127
00128 int contrast;
00129 if (pnode.getParam("contrast", contrast)) {
00130 cam->set_v4l2_control(V4L2_CID_CONTRAST, contrast, "contrast");
00131 }
00132
00133 int saturation;
00134 if (pnode.getParam("saturation", saturation)) {
00135 cam->set_v4l2_control(V4L2_CID_SATURATION, saturation, "saturation");
00136 }
00137
00138 int hue;
00139 if (pnode.getParam("hue", hue)) {
00140 cam->set_v4l2_control(V4L2_CID_HUE, hue, "hue");
00141 }
00142
00143 bool auto_white_balance;
00144 if (pnode.getParam("auto_white_balance", auto_white_balance)) {
00145 cam->set_v4l2_control(V4L2_CID_AUTO_WHITE_BALANCE, auto_white_balance, "auto_white_balance");
00146 }
00147
00148 int white_balance_tmp;
00149 if (pnode.getParam("white_balance_temperature", white_balance_tmp)) {
00150 cam->set_v4l2_control(V4L2_CID_WHITE_BALANCE_TEMPERATURE, white_balance_tmp, "white_balance_temperature");
00151 }
00152
00153 int gamma;
00154 if (pnode.getParam("gamma", gamma)) {
00155 cam->set_v4l2_control(V4L2_CID_GAMMA, gamma, "gamma");
00156 }
00157
00158 int sharpness;
00159 if (pnode.getParam("sharpness", sharpness)) {
00160 cam->set_v4l2_control(V4L2_CID_SHARPNESS, sharpness, "sharpness");
00161 }
00162
00163 int backlight_comp;
00164 if (pnode.getParam("backlight_compensation", backlight_comp)) {
00165 cam->set_v4l2_control(V4L2_CID_BACKLIGHT_COMPENSATION, backlight_comp, "backlight_compensation");
00166 }
00167
00168 bool auto_gain;
00169 if (pnode.getParam("auto_gain", auto_gain)) {
00170 cam->set_v4l2_control(V4L2_CID_AUTOGAIN, auto_gain, "auto_gain");
00171 }
00172
00173 int gain;
00174 if (pnode.getParam("gain", gain)) {
00175 cam->set_v4l2_control(V4L2_CID_GAIN, gain, "gain");
00176 }
00177
00178 bool h_flip;
00179 if (pnode.getParam("horizontal_flip", h_flip)) {
00180 cam->set_v4l2_control(V4L2_CID_HFLIP, h_flip, "horizontal_flip");
00181 }
00182
00183 bool v_flip;
00184 if (pnode.getParam("vertical_flip", v_flip)) {
00185 cam->set_v4l2_control(V4L2_CID_VFLIP, v_flip, "vertical_flip");
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 ok = true;
00195 image_thread = boost::thread(boost::bind(&Camera::feedImages, this));
00196 }
00197
00198 void Camera::sendInfo(ImagePtr &image, ros::Time time) {
00199 CameraInfoPtr info(new CameraInfo(info_mgr.getCameraInfo()));
00200
00201
00202 if (info->K[0] != 0.0 &&
00203 (image->width != info->width
00204 || image->height != info->height)) {
00205 info.reset(new CameraInfo());
00206 }
00207
00208
00209 if (info->K[0] == 0.0) {
00210 info->width = image->width;
00211 info->height = image->height;
00212 }
00213
00214 info->header.stamp = time;
00215 info->header.frame_id = frame;
00216
00217 info_pub.publish(info);
00218 }
00219
00220 void Camera::sendInfoJpeg(ros::Time time) {
00221 CameraInfoPtr info(new CameraInfo(info_mgr.getCameraInfo()));
00222 info->header.stamp = time;
00223 info->header.frame_id = frame;
00224
00225 info_pub.publish(info);
00226 }
00227
00228 void Camera::feedImages() {
00229 unsigned int pair_id = 0;
00230 while (ok) {
00231 unsigned char *img_frame = NULL;
00232 uint32_t bytes_used;
00233
00234 ros::Time capture_time = ros::Time::now();
00235
00236 int idx = cam->grab(&img_frame, bytes_used);
00237
00238
00239
00240
00241
00242 if (skip_frames == 0 || frames_to_skip == 0) {
00243 if (img_frame && format != "jpeg") {
00244 ImagePtr image(new Image);
00245
00246 image->height = height;
00247 image->width = width;
00248 image->step = 3 * width;
00249 image->encoding = image_encodings::RGB8;
00250
00251 image->header.stamp = capture_time;
00252 image->header.seq = pair_id;
00253
00254 image->header.frame_id = frame;
00255
00256 image->data.resize(image->step * image->height);
00257
00258 memcpy(&image->data[0], img_frame, width*height * 3);
00259
00260 pub.publish(image);
00261
00262 sendInfo(image, capture_time);
00263
00264 ++pair_id;
00265 } else if (img_frame && format == "jpeg") {
00266 CompressedImagePtr image(new CompressedImage);
00267
00268 image->header.stamp = capture_time;
00269 image->header.seq = pair_id;
00270
00271 image->header.frame_id = frame;
00272
00273 image->data.resize(bytes_used);
00274
00275 memcpy(&image->data[0], img_frame, bytes_used);
00276
00277 pubjpeg.publish(image);
00278
00279 sendInfoJpeg(capture_time);
00280
00281 ++pair_id;
00282 }
00283
00284 frames_to_skip = skip_frames;
00285 } else {
00286 frames_to_skip--;
00287 }
00288
00289 if (img_frame) cam->release(idx);
00290 }
00291 }
00292
00293 Camera::~Camera() {
00294 ok = false;
00295 image_thread.join();
00296 if (cam) delete cam;
00297 }
00298
00299
00300 };
00301