Go to the documentation of this file.00001 #include "GeneralVirtualCamera.hpp"
00002
00003 namespace virtual_camera {
00004
00005
00006
00007
00008 GeneralVirtualCamera::GeneralVirtualCamera(const std::string & name,
00009 const VirtualCameraParametersPtr & params):
00010 realCameras(new std::list<RealCameraPtr>()) {
00011 this->name = name;
00012 this->composer = ImageComposerPtr(new InterpolatingImageComposer(this->realCameras));
00013 this->updateVirtualCameraParameters(params);
00014 this->seqId = 0;
00015 this->composerCacheFlag = true;
00016 this->updatePointCloudFlag = false;
00017 for (int i=0; i<5; i++) {
00018 this->Dci.push_back(0);
00019 }
00020 for (int i=0; i<9; i++) {
00021 Rci0[i] = Kci0[i] = Pci0[i] = 0;
00022 }
00023 Pci0[9] = Pci0[10] = Pci0[11] = 0;
00024 Rci[0] = 1; Rci[1] = 0; Rci[2] = 0;
00025 Rci[3] = 0; Rci[4] = 1; Rci[5] = 0;
00026 Rci[6] = 0; Rci[7] = 0; Rci[8] = 1;
00027 this->isValidCameraInfo = false;
00028 }
00029
00030 sensor_msgs::CameraInfoConstPtr GeneralVirtualCamera::getCameraInfo() {
00031 sensor_msgs::CameraInfoPtr camInfo(new sensor_msgs::CameraInfo());
00032 camInfo->header.stamp = ros::Time::now();
00033 camInfo->header.frame_id = this->name;
00034 camInfo->width = static_cast<uint32_t>(this->parameters->viewportWidth);
00035 camInfo->height = static_cast<uint32_t>(this->parameters->viewportHeight);
00036 camInfo->distortion_model = "plumb_bob";
00037 camInfo->D = this->Dci;
00038 camInfo->K = this->isValidCameraInfo ? this->Kci : this->Kci0;
00039 camInfo->R = this->isValidCameraInfo ? this->Rci : this->Rci0;
00040 camInfo->P = this->isValidCameraInfo ? this->Pci : this->Pci0;
00041 return camInfo;
00042 }
00043
00044
00045 sensor_msgs::ImageConstPtr GeneralVirtualCamera::generateImage() {
00046
00047 this->broadcast();
00048 this->updateCachesIfNeeded();
00049 cv_bridge::CvImagePtr image = this->createEmptyImage();
00050 this->composer->compose(image, this->parameters->encoding);
00051 return image->toImageMsg();
00052 }
00053
00054
00055 bool GeneralVirtualCamera::addRealCamera(const RealCameraPtr & realCamera) {
00056 std::list<RealCameraPtr>::iterator it = this->realCameras->begin();
00057 while (it != this->realCameras->end()){
00058 if ((*it) == realCamera) {
00059 return false;
00060 }
00061 ++it;
00062 }
00063 this->realCameras->push_back(realCamera);
00064 realCamera->setPointsCache(this->name, this->pointCloud);
00065 this->composerCacheFlag = true;
00066 return true;
00067 }
00068
00069
00070 bool GeneralVirtualCamera::removeRealCamera(const RealCameraPtr & realCamera) {
00071 ROS_ERROR("Remove camera is unsupported operation yet");
00072 return false;
00073 }
00074
00075
00076 void GeneralVirtualCamera::updateVirtualCameraParameters(
00077 const VirtualCameraParametersPtr & params) {
00078 this->parameters = params;
00079 this->updateExternalParameters(params);
00080 this->updateInternalParameters(params);
00081 }
00082
00083
00084 double GeneralVirtualCamera::getFrameRate() {
00085 return this->parameters->frameRate;
00086 }
00087
00088
00089 std::string GeneralVirtualCamera::getName() {
00090 return this->name;
00091 }
00092
00093
00094
00095
00096
00097 void GeneralVirtualCamera::updateExternalParameters(
00098 const VirtualCameraParametersPtr & params) {
00099 this->transform.setOrigin(tf::Vector3(params->posX, params->posY, params->posZ));
00100 double roll = angles::from_degrees(-params->tilt);
00101 double yaw = angles::from_degrees(params->pan);
00102 this->transform.setRotation(tf::createQuaternionFromRPY(roll, 0, yaw));
00103 }
00104
00105
00106 void GeneralVirtualCamera::updateInternalParameters(
00107 const VirtualCameraParametersPtr & params) {
00108 this->hFovRad = angles::from_degrees(params->horizontalFov);
00109 this->vFovRad = angles::from_degrees(params->verticalFov);
00110 this->composerCacheFlag = true;
00111 this->updateCameraModel(params->model);
00112 this->pointCloud = this->model->createPointCloud(this->parameters);
00113 this->updatePointCloudFlag = true;
00114 }
00115
00116
00117 void GeneralVirtualCamera::updateCameraModel(const std::string & identifier) {
00118 if (!(this->model) || identifier != this->model->getIndentifier()) {
00119 if (identifier == "cylindric") {
00120 this->model = CameraModelPtr(new BasicCylinderCameraModel());
00121 this->isValidCameraInfo = false;
00122 } else if (identifier == "spherical") {
00123 this->model = CameraModelPtr(new SphericalCameraModel());
00124 this->isValidCameraInfo = false;
00125 } else {
00126 this->model = CameraModelPtr(new PinholeCameraModel());
00127 this->isValidCameraInfo = true;
00128 }
00129 }
00130 }
00131
00132
00133
00134
00135 cv_bridge::CvImagePtr GeneralVirtualCamera::createEmptyImage() {
00136 cv_bridge::CvImagePtr image(new cv_bridge::CvImage());
00137 const int & width = this->parameters->viewportWidth;
00138 const int & height = this->parameters->viewportHeight;
00139 image->encoding = this->parameters->encoding;
00140 image->header.seq = this->seqId++;
00141 image->header.stamp = ros::Time::now();
00142 image->header.frame_id = this->name;
00143 if (this->parameters->encoding == "bgr8") {
00144 image->image = cv::Mat(height, width,
00145 CV_8UC3, cv::Scalar_<uchar>::all(0));
00146 }else if (this->parameters->encoding == "mono8") {
00147 image->image = cv::Mat(height, width,
00148 CV_8UC1, cv::Scalar_<uchar>::all(0));
00149 }
00150 return image;
00151 }
00152
00153
00154 void GeneralVirtualCamera::updateCachesIfNeeded() {
00155 std::list<RealCameraPtr>::iterator it = this->realCameras->begin();
00156 while (it != this->realCameras->end()) {
00157 if (this->updatePointCloudFlag) {
00158 (*it)->setPointsCache(this->name, this->pointCloud);
00159 }else if (!(*it)->validateCache()){
00160 this->composerCacheFlag = true;
00161 }
00162 ++it;
00163 }
00164 if (this->composerCacheFlag) {
00165 this->composer->refreshCache(this->parameters->viewportHeight,
00166 this->parameters->viewportWidth);
00167 this->composerCacheFlag = false;
00168 }
00169 this->updatePointCloudFlag = false;
00170 }
00171
00172
00173 void GeneralVirtualCamera::broadcast() {
00174 this->broadcaster.sendTransform(tf::StampedTransform(this->transform,
00175 ros::Time::now(), this->parameters->parentFrameId, this->name));
00176 }
00177
00178
00179 void GeneralVirtualCamera::updateCameraInfo() {
00180
00181 const int & width = this->parameters->viewportWidth;
00182 const int & height = this->parameters->viewportHeight;
00183 double fx = width/(2*std::tan(this->hFovRad/2));
00184 double fy = height/(2*std::tan(this->vFovRad/2));
00185 double px = (width+1)/2;
00186 double py = (height+1)/2;
00187 Kci[0] = fx; Kci[1] = 0; Kci[2] = px;
00188 Kci[3] = 0; Kci[4] = fy; Kci[5] = py;
00189 Kci[6] = 0; Kci[7] = 0; Kci[8] = 1;
00190 Pci[0] = fx; Pci[1] = 0; Pci[2] = px; Pci[3] = 0;
00191 Pci[4] = 0; Pci[5] = fy; Pci[6] = py; Pci[7] = 0;
00192 Pci[8] = 0; Pci[9] = 0; Pci[10] = 1; Pci[11] = 0;
00193
00194 }
00195
00196
00197
00198 }
00199
00200
00201