00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00021
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
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
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
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 {
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 {
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));
00141 pose=pose*OSGToTFconvention;
00142
00143 return 1;
00144
00145 }