00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
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;
00375
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