MultibeamSensor.cpp
Go to the documentation of this file.
00001 /* 
00002  * Copyright (c) 2013 University of Jaume-I.
00003  * All rights reserved. This program and the accompanying materials
00004  * are made available under the terms of the GNU Public License v3.0
00005  * which accompanies this distribution, and is available at
00006  * http://www.gnu.org/licenses/gpl.html
00007  * 
00008  * Contributors:
00009  *     Mario Prats
00010  *     Javier Perez
00011  */
00012 
00013 #include <uwsim/MultibeamSensor.h>
00014 #include <osg/PositionAttitudeTransform>
00015 
00016 MultibeamSensor::MultibeamSensor(osg::Group *uwsim_root, std::string name, std::string parentName, osg::Node *trackNode, double initAngle,
00017                                  double finalAngle, double alpha, double range, unsigned int mask, int visible,unsigned int ARMask)
00018 {
00019 
00020   //Decide number of cameras to use -> using a single camera when the fov is greater than 160 an eyefish distortion appears,...
00021   // fov 180 doesn't work fov>180 is a completely mess. SO we use cameras until 120 fov and merge the result.
00022   nCams=(int)(finalAngle-initAngle)/120.00000001+1;
00023   camsFOV=(finalAngle-initAngle)/nCams;
00024   camPixels=camsFOV / alpha + 1;
00025   for(int i=0;i<nCams;i++)
00026   {
00027     osg::PositionAttitudeTransform * mTc= new osg::PositionAttitudeTransform;
00028     mTc->setPosition(osg::Vec3d(0,0,0));
00029     mTc->setAttitude(osg::Quat( (initAngle+camsFOV/2  + camsFOV*i)* M_PI /180.0 , osg::Vec3d(1,0,0)));
00030     trackNode->asTransform()->addChild(mTc);
00031     vcams.push_back(VirtualCamera(uwsim_root, name,parentName, mTc, camPixels, camsFOV, range));
00032   }
00033 
00034   this->numpixels = fabs(finalAngle - initAngle) / alpha + 1;
00035   this->range = range;
00036   this->initAngle = initAngle;
00037   this->finalAngle = finalAngle;
00038   this->angleIncr = alpha;
00039   this->name=name;
00040   this->trackNode = trackNode;
00041   parentLinkName=parentName;
00042   preCalcTable();
00043   for(int i=0;i<nCams;i++)
00044   {
00045     vcams[i].textureCamera->setCullMask(mask);
00046   }
00047 
00048   if (visible)
00049   {
00050     osg::ref_ptr<osg::Geometry> beam = osg::ref_ptr<osg::Geometry>(new osg::Geometry);
00051     osg::ref_ptr<osg::Vec3Array> points = new osg::Vec3Array;
00052     for(double initAux=initAngle;initAux<finalAngle;initAux+=angleIncr)
00053     {
00054       osg::Vec3d start(0, 0, 0);
00055       osg::Vec3d end(0, sin(initAux*3.14/180.0)*range, -cos(initAux*3.14/180.0)*range);
00056       points->push_back(start);
00057       points->push_back(end);
00058     }
00059     osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;
00060     color->push_back(osg::Vec4(0.0, 1.0, 0.0, 0.6));
00061     beam->setVertexArray(points.get());
00062     beam->setColorArray(color.get());
00063     beam->setColorBinding(osg::Geometry::BIND_OVERALL);
00064     beam->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, points->size()));
00065     geode = osg::ref_ptr<osg::Geode>(new osg::Geode());
00066     geode->addDrawable(beam.get());
00067     geode->setNodeMask(ARMask);
00068   }
00069   trackNode->asGroup()->addChild(geode);
00070 }
00071 
00072 void MultibeamSensor::preCalcTable()
00073 {
00074 
00075   int iCam=0;
00076   remapVector.resize(numpixels);
00077   int current = 0;
00078   double lastTheta = 0;
00079   double thetacenter;
00080   osg::Vec3d first, last, center;
00081   osg::Matrix *MVPW;
00082   for (int i = 0; i < numpixels; i++)
00083   {
00084     if(i>=camPixels*iCam)
00085     {
00086       //Create matrix to unproject camera points to real world
00087        MVPW = new osg::Matrix(
00088           vcams[iCam].textureCamera->getViewMatrix() * vcams[iCam].textureCamera->getProjectionMatrix()
00089           * vcams[iCam].textureCamera->getViewport()->computeWindowMatrix());
00090       MVPW->invert(*MVPW);
00091 
00092       //Get first last and center points from camera
00093       first = osg::Vec3d(0, 0, 1) * (*MVPW) ;
00094       last = osg::Vec3d(0, camPixels - 1, 1) * (*MVPW);
00095       center = osg::Vec3d(0, camPixels / 2, 1) * (*MVPW);
00096       thetacenter = acos((first * center) / (center.length() * first.length())) + camsFOV*iCam*M_PI/180;
00097       iCam++;
00098     }
00099 
00100     //Interpolate points
00101     osg::Vec3d point = osg::Vec3d(0, i%camPixels, 1) * (*MVPW);
00102 
00103     double theta = acos((first * point) / (first.length() * point.length())) + camsFOV*(iCam-1)*M_PI/180;
00104     while (theta >= angleIncr * current * M_PI/180 && current < numpixels)
00105     {
00106       if (theta == angleIncr * current*M_PI/180 )
00107       { //usually only first iteration as point has to be exactly the same
00108         remapVector[current].pixel1 = i;
00109         remapVector[current].weight1 = 0.50;
00110         remapVector[current].pixel2 = i;
00111         remapVector[current].weight2 = 0.50;
00112       }
00113       else
00114       { //Interpolate between this and last point
00115         double dist = fabs(theta - angleIncr * current*M_PI/180 ), prevdist = fabs(lastTheta - angleIncr * current*M_PI/180 );
00116         remapVector[current].pixel1 = i;
00117         remapVector[current].weight1 = prevdist / (dist + prevdist);
00118         remapVector[current].pixel2 = i - 1;
00119         remapVector[current].weight2 = dist / (dist + prevdist);
00120       }
00121       remapVector[current].distort = 1 / cos(fabs(theta - thetacenter));
00122       current++;
00123     }
00124     lastTheta = theta;
00125   }
00126 
00127 }
00128 
00129 int MultibeamSensor::getTFTransform(tf::Pose & pose, std::string & parent){
00130   parent=parentLinkName;
00131   pose.setOrigin(tf::Vector3(trackNode->asTransform()->asPositionAttitudeTransform()->getPosition().x(),
00132                         trackNode->asTransform()->asPositionAttitudeTransform()->getPosition().y(),
00133                         trackNode->asTransform()->asPositionAttitudeTransform()->getPosition().z()));
00134   pose.setRotation( tf::Quaternion(trackNode->asTransform()->asPositionAttitudeTransform()->getAttitude().x(),
00135                         trackNode->asTransform()->asPositionAttitudeTransform()->getAttitude().y(),
00136                         trackNode->asTransform()->asPositionAttitudeTransform()->getAttitude().z(),
00137                         trackNode->asTransform()->asPositionAttitudeTransform()->getAttitude().w()));
00138 
00139   tf::Pose OSGToTFconvention;
00140   OSGToTFconvention.setRotation(tf::Quaternion(tf::Vector3(0,1,0),M_PI/2));  //As we are using camera to simulate it, we need to rotate it
00141   pose=pose*OSGToTFconvention;
00142 
00143   return 1;
00144 
00145 }


uwsim
Author(s): Mario Prats , Javier Perez
autogenerated on Fri Aug 28 2015 13:28:58