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/image_encodings.h"
00009 #include "sensor_msgs/CameraInfo.h"
00010 #include "camera_info_manager/camera_info_manager.h"
00011 #include "image_transport/image_transport.h"
00012
00013 #include "uvc_camera/stereocamera.h"
00014
00015 using namespace sensor_msgs;
00016
00017
00018 static inline void rotate(unsigned char *dst_chr, unsigned char *src_chr, int pixels) {
00019 struct pixel_t {
00020 unsigned char r, g, b;
00021 };
00022
00023 struct pixel_t *src = (pixel_t *) src_chr;
00024 struct pixel_t *dst = &(((pixel_t *) dst_chr)[pixels - 1]);
00025
00026 for (int i = pixels; i != 0; --i) {
00027 *dst = *src;
00028 src++;
00029 dst--;
00030 }
00031 }
00032
00033 namespace uvc_camera {
00034
00035 StereoCamera::StereoCamera(ros::NodeHandle comm_nh, ros::NodeHandle param_nh) :
00036 node(comm_nh), pnode(param_nh), it(comm_nh),
00037 left_info_mgr(ros::NodeHandle(comm_nh, "left"), "left_camera"),
00038 right_info_mgr(ros::NodeHandle(comm_nh, "right"), "right_camera") {
00039
00040
00041 width = 640;
00042 height = 480;
00043 fps = 10;
00044 skip_frames = 0;
00045 frames_to_skip = 0;
00046 left_device = "/dev/video0";
00047 right_device = "/dev/video1";
00048 frame = "camera";
00049 rotate_left = false;
00050 rotate_right = false;
00051
00052
00053 std::string left_url, right_url;
00054
00055 pnode.getParam("left/camera_info_url", left_url);
00056 pnode.getParam("right/camera_info_url", right_url);
00057
00058 left_info_mgr.loadCameraInfo(left_url);
00059 right_info_mgr.loadCameraInfo(right_url);
00060
00061
00062 pnode.getParam("left/device", left_device);
00063 pnode.getParam("right/device", right_device);
00064
00065 pnode.getParam("fps", fps);
00066 pnode.getParam("skip_frames", skip_frames);
00067
00068 pnode.getParam("left/rotate", rotate_left);
00069 pnode.getParam("right/rotate", rotate_right);
00070
00071 pnode.getParam("width", width);
00072 pnode.getParam("height", height);
00073
00074 pnode.getParam("frame_id", frame);
00075
00076
00077 left_pub = it.advertise("left/image_raw", 1);
00078 right_pub = it.advertise("right/image_raw", 1);
00079
00080 left_info_pub = node.advertise<CameraInfo>("left/camera_info", 1);
00081 right_info_pub = node.advertise<CameraInfo>("right/camera_info", 1);
00082
00083
00084 cam_left =
00085 new uvc_cam::Cam(left_device.c_str(), uvc_cam::Cam::MODE_RGB,
00086 width, height, fps);
00087 cam_left->set_motion_thresholds(100, -1);
00088 cam_right =
00089 new uvc_cam::Cam(right_device.c_str(), uvc_cam::Cam::MODE_RGB,
00090 width, height, fps);
00091 cam_right->set_motion_thresholds(100, -1);
00092
00093
00094 ok = true;
00095 image_thread = boost::thread(boost::bind(&StereoCamera::feedImages, this));
00096 }
00097
00098 void StereoCamera::sendInfo(ros::Time time) {
00099 CameraInfoPtr info_left(new CameraInfo(left_info_mgr.getCameraInfo()));
00100 CameraInfoPtr info_right(new CameraInfo(right_info_mgr.getCameraInfo()));
00101
00102 info_left->header.stamp = time;
00103 info_right->header.stamp = time;
00104 info_left->header.frame_id = frame;
00105 info_right->header.frame_id = frame;
00106
00107 left_info_pub.publish(info_left);
00108 right_info_pub.publish(info_right);
00109 }
00110
00111
00112 void StereoCamera::feedImages() {
00113 unsigned int pair_id = 0;
00114 while (ok) {
00115 unsigned char *frame_left = NULL, *frame_right = NULL;
00116 uint32_t bytes_used_left, bytes_used_right;
00117
00118 ros::Time capture_time = ros::Time::now();
00119
00120 int left_idx = cam_left->grab(&frame_left, bytes_used_left);
00121 int right_idx = cam_right->grab(&frame_right, bytes_used_right);
00122
00123
00124
00125
00126
00127
00128 if (skip_frames == 0 || frames_to_skip == 0) {
00129 if (frame_left && frame_right) {
00130 ImagePtr image_left(new Image);
00131 ImagePtr image_right(new Image);
00132
00133 image_left->height = height;
00134 image_left->width = width;
00135 image_left->step = 3 * width;
00136 image_left->encoding = image_encodings::RGB8;
00137 image_left->header.stamp = capture_time;
00138 image_left->header.seq = pair_id;
00139
00140 image_right->height = height;
00141 image_right->width = width;
00142 image_right->step = 3 * width;
00143 image_right->encoding = image_encodings::RGB8;
00144 image_right->header.stamp = capture_time;
00145 image_right->header.seq = pair_id;
00146
00147 image_left->header.frame_id = frame;
00148 image_right->header.frame_id = frame;
00149
00150 image_left->data.resize(image_left->step * image_left->height);
00151 image_right->data.resize(image_right->step * image_right->height);
00152
00153 if (rotate_left)
00154 rotate(&image_left->data[0], frame_left, width * height);
00155 else
00156 memcpy(&image_left->data[0], frame_left, width * height * 3);
00157
00158 if (rotate_right)
00159 rotate(&image_right->data[0], frame_right, width * height);
00160 else
00161 memcpy(&image_right->data[0], frame_right, width * height * 3);
00162
00163 left_pub.publish(image_left);
00164 right_pub.publish(image_right);
00165
00166 sendInfo(capture_time);
00167
00168 ++pair_id;
00169 }
00170
00171 frames_to_skip = skip_frames;
00172 } else {
00173 frames_to_skip--;
00174 }
00175
00176 if (frame_left)
00177 cam_left->release(left_idx);
00178 if (frame_right)
00179 cam_right->release(right_idx);
00180 }
00181 }
00182
00183 StereoCamera::~StereoCamera() {
00184 ok = false;
00185 image_thread.join();
00186 if (cam_left)
00187 delete cam_left;
00188 if (cam_right)
00189 delete cam_right;
00190 }
00191
00192 };