SegmentPrototype.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009 by Ulrich Friedrich Klank <klank@in.tum.de>
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 3 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 
00019 #include "SegmentPrototype.h"
00020 #include "XMLTag.h"
00021 
00022 
00023 #define XML_ATTRIBUTE_RELFRAME   "RelFrame"
00024 #define XML_ATTRIBUTE_PARALLEL "ParallelSearch"
00025 #define XML_ATTRIBUTE_COVX       "CovX"
00026 #define XML_ATTRIBUTE_COVY       "CovY"
00027 #define XML_ATTRIBUTE_COVZ       "CovZ"
00028 
00029 using namespace cop;
00030 
00031 
00032 SegmentPrototype::SegmentPrototype() :
00033   m_relFrame("/base_link"),
00034   m_relPoseOfRefFrame(NULL),
00035   m_covRotX(0.2),
00036   m_covRotY(0.2),
00037   m_covRotZ(0.8),
00038   m_parallel(true)
00039 
00040 {
00041 }
00042 
00043 
00044 
00045 
00046 
00047 SegmentPrototype::SegmentPrototype(std::string sensor_frame, const sensor_msgs::PointCloud& pcd, std::string classname, ObjectID_t id, ObjectID_t class_id) :
00048     Descriptor(new Class(classname, class_id)),
00049     m_relFrame("/base_link"),
00050     m_relPoseOfRefFrame(NULL),
00051     m_covRotX(0.2),
00052     m_covRotY(0.2),
00053     m_covRotZ(0.8),
00054     m_parallel(true)
00055 {
00056   double meanx = 0.0, meany = 0.0,  meanz = 0.0;
00057   double  cov[9];
00058   memset(cov, 0, sizeof(*cov)*9);
00059 
00060   m_ID = id;
00061   UpdateRefFrame();
00062   RelPose* p_sensor_frame = RelPoseFactory::GetRelPose(sensor_frame);
00063   if(p_sensor_frame == NULL)
00064     throw "Sensor frame is invalid";
00065   for(size_t i = 0; i < pcd.points.size(); i++)
00066   {
00067     meanx += pcd.points[i].x;
00068     meany += pcd.points[i].y;
00069     meanz += pcd.points[i].z;
00070 
00071     for(int j = 0; j < 3; j++)
00072     {
00073       for(int k = 0; k < 3; k++)
00074       {
00075         double tmp = 0.0;
00076         switch(j)
00077         {
00078           case 0:
00079             tmp = pcd.points[i].x;
00080             break;
00081           case 1:
00082             tmp = pcd.points[i].y;
00083             break;
00084           case 2:
00085             tmp = pcd.points[i].z;
00086             break;
00087         }
00088         switch(k)
00089         {
00090           case 0:
00091             tmp *= pcd.points[i].x;
00092             break;
00093           case 1:
00094             tmp *= pcd.points[i].y;
00095             break;
00096           case 2:
00097             tmp *= pcd.points[i].z;
00098             break;
00099         }
00100         cov[j*3+k] += tmp;
00101       }
00102     }
00103   }
00104   Matrix m = IdentityMatrix(4);
00105   Matrix covm(6,6);
00106   for(int j = 0; j < 6; j++)
00107   {
00108      for(int k = 0; k < 6; k++)
00109      {
00110        covm.element(j,k) = 0.0;
00111      }
00112   }
00113 
00114   m.element(0,3) = meanx / pcd.points.size();
00115   m.element(1,3) = meany / pcd.points.size();
00116   m.element(2,3) = meanz / pcd.points.size();
00117   covm.element(0,0) = cov[0] / pcd.points.size();
00118   covm.element(0,1) = cov[1] / pcd.points.size();
00119   covm.element(0,2) = cov[2] / pcd.points.size();
00120   covm.element(1,0) = cov[3] / pcd.points.size();
00121   covm.element(1,1) = cov[4] / pcd.points.size();
00122   covm.element(1,2) = cov[5] / pcd.points.size();
00123   covm.element(2,0) = cov[6] / pcd.points.size();
00124   covm.element(2,1) = cov[7] / pcd.points.size();
00125   covm.element(2,2) = cov[8] / pcd.points.size();
00126 
00127   RelPose *pose = RelPoseFactory::FRelPose(ID_WORLD, m, covm);
00128 
00129   SetLastMatchedImage(NULL, pose);
00130 
00131   SetPointCloud(pose->m_uniqueID, pcd, p_sensor_frame->m_uniqueID);
00132 
00133 }
00134 
00135 
00136 
00137 void SegmentPrototype::SetData(XMLTag* tag)
00138 {
00139   Descriptor::SetData(tag);
00140   m_relFrame =   tag->GetProperty(XML_ATTRIBUTE_RELFRAME, m_relFrame);
00141   m_parallel =   tag->GetPropertyInt(XML_ATTRIBUTE_PARALLEL, 0) == 0;
00142   UpdateRefFrame();
00143   m_covRotX =    tag->GetPropertyDouble(XML_ATTRIBUTE_COVX, m_covRotX);
00144   m_covRotY =    tag->GetPropertyDouble(XML_ATTRIBUTE_COVY, m_covRotY);
00145   m_covRotZ =    tag->GetPropertyDouble(XML_ATTRIBUTE_COVZ, m_covRotZ);
00146 
00147   RelPose* pose = GetLastMatchedPose();
00148   std::string filename = tag->GetProperty(XML_ATTRIBUTE_FILENAME, "");
00149 
00150   if(filename.length() > 0)
00151   {
00152     sensor_msgs::PointCloud pcd;
00153     FILE* file = fopen(filename.c_str(), "r");
00154     if (file==NULL)
00155     {
00156       ROS_ERROR("Could not read message from file (filename: %s in Class %s)\n", filename.c_str(), GetNodeName().c_str());
00157       throw("Error reading class");
00158     }
00159 
00160     // obtain file size:
00161     fseek (file, 0 , SEEK_END);
00162     long lSize = ftell (file);
00163     rewind (file);
00164     uint8_t*  buffer = new uint8_t[lSize];
00165     if (buffer == NULL)
00166     {
00167       ROS_ERROR("Could not read message from file (filename: %s in Class %s)\n", filename.c_str(), GetNodeName().c_str());
00168       throw("Error reading class");
00169     }
00170 
00171     // copy the file into the buffer:
00172     long result = fread (buffer,1,lSize,file);
00173     if (result != lSize)
00174     {
00175       ROS_ERROR("Could not read message from file (filename: %s in Class %s)\n", filename.c_str(), GetNodeName().c_str());
00176       delete buffer;
00177       throw("Error reading class");
00178     }
00179     pcd.deserialize(buffer);
00180 
00181     if(pose == NULL)
00182     {
00183       Matrix m = IdentityMatrix(4);
00184       Matrix cov = IdentityMatrix(6);
00185       double  cov33[9];
00186       for(unsigned int t = 0; t < 9; t++)
00187         cov33[t] = 0;
00188        for(unsigned int k = 0; k < pcd.points.size (); k++)
00189        {
00190          geometry_msgs::Point32 p = pcd.points[k];
00191          cov33[0] += p.x*p.x;
00192          cov33[1] += p.y*p.x;
00193          cov33[2] += p.z*p.x;
00194          cov33[3] += p.x*p.y;
00195          cov33[4] += p.y*p.y;
00196          cov33[5] += p.z*p.y;
00197          cov33[6] += p.x*p.z;
00198          cov33[7] += p.y*p.z;
00199          cov33[8] += p.z*p.z;
00200        }
00201        for(unsigned int t = 0; t < 9; t++)
00202        {
00203          cov.element(t/3, (t%3)) =   cov33[t] / pcd.points.size ();
00204          if(cov33[t] <= 0.0)
00205             cov33[t] = 0.000000001;
00206        }
00207       cov.element(3,3) = m_covRotX;
00208       cov.element(4,4) = m_covRotY;
00209       cov.element(5,5) = m_covRotZ;
00210 
00211       pose = RelPoseFactory::FRelPose(ID_WORLD, m, cov);
00212       SetLastMatchedImage(NULL, pose);
00213     }
00214 
00215     m_mapPCD[pose->m_uniqueID] = pcd;
00216     fclose (file);
00217     delete buffer;
00218   }
00219 }
00220 
00221 LocatedObjectID_t SegmentPrototype::GetFrameId()
00222 {
00223   UpdateRefFrame();
00224   return m_frameID;
00225 }
00226 
00227  LocatedObjectID_t SegmentPrototype::GetSensorFrameId(const LocatedObjectID_t &id)
00228  {
00229    if(m_sensorFrameID.find(id) != m_sensorFrameID.end())
00230      return m_sensorFrameID[id];
00231    else
00232   {
00233     printf("No entry for %ld in SegmentPrototype::GetSensorFrameId\n", id);
00234      return ID_WORLD;
00235    }
00236  }
00237 
00238 void SegmentPrototype::UpdateRefFrame()
00239 {
00240   RelPose* temp = m_relPoseOfRefFrame;
00241   m_relPoseOfRefFrame  = RelPoseFactory::GetRelPose(m_relFrame);
00242   if(temp  != NULL)
00243   {
00244     RelPoseFactory::FreeRelPose(&temp );
00245   }
00246   m_frameID = m_relPoseOfRefFrame->m_uniqueID;
00247 }
00248 
00249 SegmentPrototype::~SegmentPrototype(void)
00250 {
00251   RelPoseFactory::FreeRelPose(&m_relPoseOfRefFrame);
00252 }
00253 
00254 
00255 void SegmentPrototype::SaveTo(XMLTag* tag)
00256 {
00257   Descriptor::SaveTo(tag);
00258 
00259   if(GetLastMatchedPose() != NULL)
00260   {
00261     const RelPose* pose2 = GetLastMatchedPose();
00262     std::map<LocatedObjectID_t, sensor_msgs::PointCloud>::const_iterator test = m_mapPCD.find(pose2->m_uniqueID);
00263     if(test != m_mapPCD.end())
00264     {
00265       std::ostringstream os;
00266       os << "pcd_"  << m_ID << ".pcd";
00267       std::string filename = os.str();
00268       uint32_t length = (*test).second.serializationLength();
00269       uint8_t* write_pointer = new uint8_t[length];
00270       uint8_t seq = 0, *outp;
00271       outp = (*test).second.serialize(write_pointer, seq);
00272       FILE* file = fopen(filename.c_str(), "w");
00273       if(file != NULL)
00274       {
00275         fwrite(write_pointer, 1, length, file);
00276         tag->AddProperty(XML_ATTRIBUTE_FILENAME, filename);
00277         fclose(file);
00278       }
00279       else
00280       {
00281         ROS_ERROR("Could not write message to file (filename: %s in Class %s)\n", filename.c_str(), GetNodeName().c_str());
00282       }
00283       delete write_pointer;
00284       tag->AddProperty(XML_ATTRIBUTE_FILENAME, os.str());
00285      }
00286   }
00287   tag->AddProperty(XML_ATTRIBUTE_RELFRAME, m_relFrame);
00288   tag->AddProperty(XML_ATTRIBUTE_PARALLEL, m_parallel);
00289   tag->AddProperty(XML_ATTRIBUTE_COVX, m_covRotX);
00290   tag->AddProperty(XML_ATTRIBUTE_COVY, m_covRotY);
00291   tag->AddProperty(XML_ATTRIBUTE_COVZ, m_covRotZ);
00292 }
00293 
00294 
00295 void SegmentPrototype::Show(RelPose* pose, Sensor* camin)
00296 {
00297   printf("in SegmentPrototype::Show(RelPose* pose, Sensor* camin)\n");
00298   if(camin != NULL && pose != NULL && camin->GetRelPose() != NULL)
00299   {
00300     Matrix m = pose->GetMatrix(camin->GetRelPose()->m_uniqueID);
00301     printf("Pose %ld in %ld\n", pose->m_uniqueID, camin->GetRelPose()->m_uniqueID);
00302     cout << m;
00303     double row, column;
00304     camin->ProjectPoint3DToSensor(m.element(0, 3), m.element(1,3), m.element(2,3), row, column);
00305 
00306     printf("projected to %f, %f\n", row, column);
00307   }
00308   if(camin != NULL && pose != NULL)
00309   {
00310     RelPose* pose2;
00311     LocatedObjectID_t id = pose->m_uniqueID;
00312     LocatedObjectID_t parent = pose->m_parentID;
00313     if(GetLastMatchedPose() != NULL && GetLastMatchedPose()->m_uniqueID != id)
00314     {
00315       id = GetLastMatchedPose()->m_uniqueID;
00316       Matrix m = pose->GetMatrix(id);
00317       Matrix cov = pose->GetCovariance(id);
00318       pose2 = RelPoseFactory::FRelPose(GetLastMatchedPose()->m_parentID, m , cov);
00319       parent = pose2->m_uniqueID;
00320     }
00321     if(m_mapPCD.find(id) != m_mapPCD.end())
00322     {
00323      std::vector<double> x,y,z;
00324      sensor_msgs::PointCloud pcd = cloud_trans(pose->m_uniqueID, ID_WORLD, m_mapPCD[id]);
00325      for (size_t index = 0; index < pcd.points.size(); index++)
00326      {
00327         x.push_back(pcd.points[index].x);
00328         y.push_back(pcd.points[index].y);
00329         z.push_back(pcd.points[index].z);
00330       }
00331       camin->Publish3DData(x,y,z);
00332     }
00333     if(GetLastMatchedPose() != NULL && GetLastMatchedPose()->m_uniqueID != id)
00334     {
00335       RelPoseFactory::FreeRelPose(&pose2);
00336     }
00337 
00338   }
00339 }
00340 
00341 Elem* SegmentPrototype::Duplicate(bool bStaticCopy)
00342 {
00343   SegmentPrototype* new_obj = (SegmentPrototype*)Descriptor::Duplicate(bStaticCopy);
00345   new_obj->m_mapPCD = m_mapPCD;
00346   new_obj->m_sensorFrameID = m_sensorFrameID;
00348   new_obj->m_class = m_class;
00349   new_obj->m_imgLastMatchReading = m_imgLastMatchReading;
00350   new_obj->m_poseLastMatchReading = m_poseLastMatchReading;
00351   new_obj->m_qualityMeasure = m_qualityMeasure;
00352   return new_obj;
00353 }
00354 
00355 void SegmentPrototype::PropagatePose(RelPose* pose)
00356 {
00357   if(m_mapPCD.find(pose->m_uniqueID) != m_mapPCD.end())
00358   {
00359     m_poseLastMatchReading = pose;
00360   }
00361 }
00362 
00363 bool SegmentPrototype::GetShape(GeometricShape &objectShape) const
00364 {
00365   if(objectShape.type > 1)
00366   {
00367     printf("Shape already set\n");
00368     return false;
00369   }
00370   if(m_poseLastMatchReading == NULL)
00371   {
00372     printf("No pose\n");
00373   }
00374   objectShape.type = 4;/*undefined PCD;*/
00375   /*Matrix cov = m_poseLastMatchReading->GetCovarianceMatrix();*/
00376   LocatedObjectID_t id;
00377   LocatedObjectID_t parent;
00378   if(GetLastMatchedPose() != NULL)
00379   {
00380     const RelPose* pose2 = GetLastMatchedPose();
00381     id = pose2->m_uniqueID;
00382     parent = pose2->m_parentID;
00383     std::map<LocatedObjectID_t, sensor_msgs::PointCloud>::const_iterator test = m_mapPCD.find(id);
00384     if(test != m_mapPCD.end())
00385     {
00386       std::vector<double> x,y,z;
00387 
00388       sensor_msgs::PointCloud pcd = cloud_trans(id, ID_WORLD, (*test).second);
00389       for(size_t i = 0;i < pcd.points.size(); i++)
00390       {
00391         cop::PointShape p;
00392         p.x = pcd.points[i].x;
00393         p.y = pcd.points[i].y;
00394         p.z = pcd.points[i].z;
00395         objectShape.vertices.push_back(p);
00396       }
00397     }
00398   }
00399   return true;
00400 }
00401 
00402 
00403 
00404 sensor_msgs::PointCloud cop::cloud_trans (LocatedObjectID_t swissranger_jlo_id, LocatedObjectID_t ptu_base_jlo_id,  const sensor_msgs::PointCloud& cloud_in)
00405 {
00406    RelPose* pose = RelPoseFactory::GetRelPose(swissranger_jlo_id, ptu_base_jlo_id);
00407    sensor_msgs::PointCloud cloud_in_trans;
00408    if(pose == NULL)
00409    {
00410      printf("Strange Fallback solution\n");
00411       RelPose* pose1 = RelPoseFactory::GetRelPose("/sr4");
00412       RelPose* pose2 = RelPoseFactory::GetRelPose("/base_link");
00413       if(pose1 && pose2)
00414       {
00415         pose = RelPoseFactory::GetRelPose(pose1->m_uniqueID, pose2->m_uniqueID);
00416         RelPoseFactory::FreeRelPose(&pose1);
00417         RelPoseFactory::FreeRelPose(&pose2);
00418       }
00419       if(pose == NULL)
00420        throw "Cloud trans not possible: Location not clear";
00421    }
00422    Matrix m = pose->GetMatrix(0);
00423    cout << "Matrix in cloud_trans: ("<< pose->m_uniqueID << " -> "<< pose->m_parentID << " )  (asked"<< swissranger_jlo_id << "-> "<< ptu_base_jlo_id << ")\n" << m << "\n";
00424    RelPoseFactory::FreeRelPose(&pose);
00425 
00426    Matrix m_tmp = m;
00427    cloud_in_trans.points.clear();
00428    if(cloud_in.points.size() == 0 || cloud_in.points.size() > 1000000000)
00429       throw "Error in pointcloud, failed check 0 =< num_points < 1000000000";
00430    for(size_t i = 0; i < cloud_in.points.size(); i++)
00431    {
00432      ColumnVector v(4);
00433      v <<  cloud_in.points[i].x <<  cloud_in.points[i].y <<  cloud_in.points[i].z << 1;
00434      ColumnVector a = m_tmp*v;
00435      geometry_msgs::Point32 pt;
00436      pt.x = a.element(0);
00437      pt.y = a.element(1);
00438      pt.z = a.element(2);
00439      cloud_in_trans.points.push_back(pt);
00440    }
00441    cloud_in_trans.channels.clear();
00442    for(size_t channels = 0 ; channels < cloud_in.channels.size(); channels++)
00443    {
00444 
00445      cloud_in_trans.channels.push_back(sensor_msgs::ChannelFloat32());
00446      cloud_in_trans.channels[channels].name = cloud_in.channels[channels].name;
00447      for(size_t points = 0; points < cloud_in.channels[channels].values.size(); points++)
00448      {
00449        cloud_in_trans.channels[channels].values.push_back(
00450        cloud_in.channels[channels].values[points]);
00451      }
00452    }
00453    return cloud_in_trans;
00454 }
00455 
00456 
00457 void SegmentPrototype::SetPointCloud(const LocatedObjectID_t &id, const sensor_msgs::PointCloud &cloud_in, const LocatedObjectID_t &sensor_id)
00458 {
00459   sensor_msgs::PointCloud cloud_in_trans;
00460   RelPose* pose = RelPoseFactory::FRelPose(id);
00461   Matrix m_in = pose->GetMatrix(0);
00462   Matrix m = m_in.i();
00463 
00464   for(size_t i = 0; i < cloud_in.points.size(); i++)
00465   {
00466     ColumnVector v(4);
00467     v <<  cloud_in.points[i].x <<  cloud_in.points[i].y <<  cloud_in.points[i].z << 1;
00468     ColumnVector a = m*v;
00469     geometry_msgs::Point32 pt;
00470     pt.x = a.element(0);
00471     pt.y = a.element(1);
00472     pt.z = a.element(2);
00473     cloud_in_trans.points.push_back(pt);
00474   }
00475   m_mapPCD[id] = cloud_in_trans;
00476   m_sensorFrameID[id] = sensor_id;
00477   RelPoseFactory::FreeRelPose(&pose);
00478 }
00479 
00480 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


cop_sr4_plugins
Author(s): U. Klank
autogenerated on Thu May 23 2013 09:52:16