Go to the documentation of this file.00001 #include "VirtualCameraNodelet.hpp"
00002
00003 namespace virtual_camera {
00004
00005 VirtualCameraParametersPtr VirtualCameraNodelet::handleStartupParameters() {
00006 ros::NodeHandle & nh = this->getPrivateNodeHandle();
00007 VirtualCameraParametersPtr ret(new VirtualCameraParameters());
00008 nh.getParam("approxDistance", ret->approxDistance);
00009 nh.getParam("viewportWidth", ret->viewportWidth);
00010 nh.getParam("viewportHeight", ret->viewportHeight);
00011 nh.getParam("horizontalFov", ret->horizontalFov);
00012 nh.getParam("verticalFov", ret->verticalFov);
00013 nh.getParam("frameRate", ret->frameRate);
00014 nh.getParam("posX", ret->posX);
00015 nh.getParam("posY", ret->posY);
00016 nh.getParam("posZ", ret->posZ);
00017 nh.getParam("pan", ret->pan);
00018 nh.getParam("tilt", ret->tilt);
00019 nh.getParam("parentFrameId", ret->parentFrameId);
00020 nh.getParam("encoding", ret->encoding);
00021 nh.getParam("model", ret->model);
00022 nh.getParam("synchronize", ret->synchronize);
00023 this->synchronizer = RealCameraSynchronizerPtr(
00024 new RealCameraSynchronizer(ret->synchronize,
00025 this->imageSyncMutex));
00026 NODELET_INFO("Parameters successfully loaded.");
00027 return ret;
00028 }
00029
00030
00031 void VirtualCameraNodelet::handleNewCameraParams(
00032 const VirtualCameraParametersPtr & params) {
00033 this->synchronizer->setSynchronization(params->synchronize);
00034 this->camera->updateVirtualCameraParameters(params);
00035 }
00036
00037
00038 void VirtualCameraNodelet::addRealCamerasFromParams() {
00039 ros::NodeHandle & nh = this->getPrivateNodeHandle();
00040 int i = 1;
00041 std::string iS = boost::lexical_cast<std::string>(i);
00042 while (nh.hasParam("realCameraTopic" + iS)) {
00043 AddRealCameraPtr nCam(new AddRealCamera());
00044 nh.getParam("realCameraTopic" + iS, nCam->topic);
00045 nh.param<std::string>("realCameraFrame" + iS, nCam->frameId, "");
00046 this->newCameraCallback(nCam);
00047 ++i;
00048 iS = boost::lexical_cast<std::string>(i);
00049 }
00050 }
00051
00052
00053 void VirtualCameraNodelet::registerCamerasFromWaitList() {
00054 std::list<RealCameraPtr>::iterator it = this->addWaitList.begin();
00055 while (it != this->addWaitList.end()) {
00056 bool can = this->transformListener->canTransform((*it)->getName(),
00057 this->camera->getName(), ros::Time(0));
00058 if (can && (*it)->isReady()) {
00059 this->camera->addRealCamera(*it);
00060 ROS_INFO_STREAM((*it)->getName() << " - camera ready and added.");
00061 this->addWaitList.erase(it++);
00062 }else {
00063 ROS_INFO_STREAM((*it)->getName() << " - camera not ready yet.");
00064 ++it;
00065 }
00066 }
00067 }
00068
00069
00070 std::string VirtualCameraNodelet::getNameFromTopic(const std::string & topic) {
00071 int start = topic.length()-1;
00072 for (; start >= 0; --start){
00073 if (topic[start] == '/') break;
00074 }
00075 return topic.substr(start+1, topic.length()-(start+1));
00076 }
00077
00078
00079 void VirtualCameraNodelet::loop(const ros::TimerEvent& event) {
00080 static double lastRate = camera->getFrameRate();
00081 static image_transport::Publisher pub = this->it->advertise(
00082 this->name + "/image", 1);
00083 if (lastRate != camera->getFrameRate()){
00084 lastRate = camera->getFrameRate();
00085 this->timer.setPeriod(ros::Duration(1/lastRate));
00086 }
00087 this->registerCamerasFromWaitList();
00088 this->cameraInfoPublisher.publish(this->camera->getCameraInfo());
00089 boost::mutex::scoped_lock(*(this->imageSyncMutex));
00090 pub.publish(camera->generateImage());
00091 }
00092
00093
00094 void VirtualCameraNodelet::newCameraCallback(AddRealCameraConstPtr cam) {
00095 NODELET_INFO("Adding new camera");
00096 std::string frameId;
00097 if(cam->frameId != "") {
00098 frameId = cam->frameId;
00099 }else {
00100 frameId = this->getNameFromTopic(cam->topic);
00101 }
00102 ROS_INFO_STREAM("DEBUG: " << this->nh.resolveName(cam->topic + "/camera_info"));
00103 RealCameraPtr nCam(new RealMonoCamera(frameId, this->transformListener));
00104 this->realCamInfoSubs.push_back(
00105 this->nh.subscribe(this->nh.resolveName(cam->topic + "/camera_info"),
00106 1, &RealCamera::setCameraInfo, nCam));
00107 this->synchronizer->addCamera(this->nh.resolveName(cam->topic + "/image"),
00108 nCam, this->it);
00109 this->addWaitList.push_back(nCam);
00110 }
00111
00112
00113 void VirtualCameraNodelet::onInit() {
00114 NODELET_INFO("Initialization ahead");
00115 this->nh = this->getNodeHandle();
00116 this->imageSyncMutex = MutexPtr(new boost::mutex());
00117 this->it = boost::shared_ptr<image_transport::ImageTransport>(
00118 new image_transport::ImageTransport(nh));
00119 this->getPrivateNodeHandle().getParam("name", this->name);
00120 this->transformListener = boost::shared_ptr<tf::TransformListener>(new tf::TransformListener());
00121 this->camera = VirtualCameraPtr(new GeneralVirtualCamera(this->name,
00122 this->handleStartupParameters()));
00123 this->cameraInfoPublisher = nh.advertise<sensor_msgs::CameraInfo>(
00124 nh.resolveName(this->name + "/camera_info"), 1000);
00125 this->virtCamParamsSubscriber = nh.subscribe(
00126 nh.resolveName(this->name + "/input_params"),
00127 1, &VirtualCameraNodelet::handleNewCameraParams, this);
00128 this->addCameraSubscriber = nh.subscribe(
00129 nh.resolveName(this->name + "/add_camera"),
00130 1000, &VirtualCameraNodelet::newCameraCallback, this);
00131 timer = nh.createTimer(ros::Rate(this->camera->getFrameRate()),
00132 &VirtualCameraNodelet::loop, this, false);
00133
00134 this->addRealCamerasFromParams();
00135 NODELET_INFO("Successful start");
00136 }
00137
00138
00139 }