00001 #include "shape_tracker/ShapeTracker.h"
00002
00003 #include <pcl_conversions/pcl_conversions.h>
00004
00005 #include <shape_reconstruction/RangeImagePlanar.hpp>
00006
00007
00008 #include "pcl_ros/point_cloud.h"
00009
00010 #include "pcl/filters/approximate_voxel_grid.h"
00011
00012 #include "opencv2/imgproc/imgproc.hpp"
00013
00014 using namespace omip;
00015
00016 #define BB_FILTER_BEFORE_ICP
00017
00018
00019 void Image8u2IndicesOfOrganizedPC(const cv::Mat& image_8u, pcl::PointIndices::Ptr indices_ptr)
00020 {
00021 indices_ptr->indices.clear();
00022 for(int j=0; j<image_8u.rows; j++)
00023 {
00024 for(int i=0; i<image_8u.cols; i++)
00025 {
00026 if(image_8u.at<uchar>(j,i))
00027 {
00028 indices_ptr->indices.push_back(j*image_8u.cols + i);
00029 }
00030 }
00031 }
00032 }
00033
00034
00035 void IndicesOfOrganizedPC2Image8u(pcl::PointIndices::Ptr indices_ptr, cv::Mat& image_8u)
00036 {
00037 for(int k=0; k<indices_ptr->indices.size(); k++)
00038 {
00039 image_8u.at<uchar>(std::floor(indices_ptr->indices[k]/640), indices_ptr->indices[k]%640) = 255;
00040 }
00041 }
00042
00043 ShapeTracker::ShapeTracker(omip::RB_id_t rb_id)
00044 : _rb_id(rb_id),
00045 _new_model(false),
00046 _current_dm(480, 640, CV_32FC1),
00047 _segment_of_current(480,640,CV_8U),
00048 _segment_of_current_dilated(480,640,CV_8U)
00049 {
00050
00051 _rb_model.reset(new pcl::PointCloud<pcl::PointXYZ >());
00052
00053 _icp.setMaxCorrespondenceDistance(1);
00054 _icp.setEuclideanFitnessEpsilon(1e-6);
00055 _icp.setMaximumIterations(1000);
00056 _icp.setTransformationEpsilon(0.0);
00057
00058 std::stringstream pub_topic_name;
00059 pub_topic_name << "/shape_tracker/segment_rb" << this->_rb_id;
00060 _segment_pub = _nh.advertise<pcl::PointCloud<pcl::PointXYZ> >(pub_topic_name.str(), 1);
00061
00062 int dilation_type = cv::MORPH_RECT;
00063 int dilation_size = 2;
00064 _dilation_element = cv::getStructuringElement( dilation_type,
00065 cv::Size( 2*dilation_size + 1, 2*dilation_size+1 ),
00066 cv::Point( dilation_size, dilation_size ) );
00067
00068 #ifdef USE_LIBPOINTMATCHER_ICP
00069 _icp_lpm = new PM::ICP();
00070
00071 PointMatcherSupport::Parametrizable::Parameters params;
00072 std::string name;
00073
00074 name = "MaxPointCountDataPointsFilter";
00075 params["maxCount"] = "1000";
00076 PM::DataPointsFilter* maxCount_read =
00077 PM::get().DataPointsFilterRegistrar.create(name, params);
00078 params.clear();
00079
00080 name = "BoundingBoxDataPointsFilter";
00081 params["xMin"] = "-inf";
00082 params["xMax"] = "inf";
00083 params["yMin"] = "-inf";
00084 params["yMax"] = "inf";
00085 params["zMin"] = "-inf";
00086 params["zMax"] = "inf";
00087 params["removeInside"] = "0";
00088 PM::DataPointsFilter* bb_read =
00089 PM::get().DataPointsFilterRegistrar.create(name, params);
00090 params.clear();
00091
00092
00093 name = "KDTreeMatcher";
00094 params["knn"] = "1";
00095 params["epsilon"] = "0";
00096 params["maxDist"] = "0.02";
00097 params["searchType"] = "1";
00098 PM::Matcher* kdtree =
00099 PM::get().MatcherRegistrar.create(name, params);
00100 params.clear();
00101
00102
00103 name = "TrimmedDistOutlierFilter";
00104 params["ratio"] = "0.75";
00105 PM::OutlierFilter* trim =
00106 PM::get().OutlierFilterRegistrar.create(name, params);
00107 params.clear();
00108
00109
00110 name = "PointToPointErrorMinimizer";
00111 PM::ErrorMinimizer* pointToPoint =
00112 PM::get().ErrorMinimizerRegistrar.create(name);
00113
00114
00115 name = "CounterTransformationChecker";
00116 params["maxIterationCount"] = "10";
00117 PM::TransformationChecker* maxIter =
00118 PM::get().TransformationCheckerRegistrar.create(name, params);
00119 params.clear();
00120
00121 name = "DifferentialTransformationChecker";
00122 params["minDiffRotErr"] = "0.01";
00123 params["minDiffTransErr"] = "0.01";
00124 params["smoothLength"] = "1";
00125 PM::TransformationChecker* diff =
00126 PM::get().TransformationCheckerRegistrar.create(name, params);
00127 params.clear();
00128
00129
00130 PM::Inspector* nullInspect =
00131 PM::get().InspectorRegistrar.create("NullInspector");
00132
00133
00134 PM::Transformation* rigidTrans =
00135 PM::get().TransformationRegistrar.create("RigidTransformation");
00136
00137
00138 _icp_lpm->readingDataPointsFilters.push_back(maxCount_read);
00139 _icp_lpm->referenceDataPointsFilters.push_back(bb_read);
00140 _icp_lpm->referenceDataPointsFilters.push_back(maxCount_read);
00141 _icp_lpm->matcher.reset(kdtree);
00142 _icp_lpm->outlierFilters.push_back(trim);
00143 _icp_lpm->errorMinimizer.reset(pointToPoint);
00144 _icp_lpm->transformationCheckers.push_back(maxIter);
00145 _icp_lpm->transformationCheckers.push_back(diff);
00146 _icp_lpm->inspector.reset(nullInspect);
00147 _icp_lpm->transformations.push_back(rigidTrans);
00148 #endif
00149 }
00150
00151 ShapeTracker::ShapeTracker(const ShapeTracker &sr)
00152 {
00153 ROS_ERROR_STREAM_NAMED("ShapeTracker.ShapeTracker", "Do not use this copy constructor! It is not complete!");
00154
00155 this->_rb_id = sr._rb_id;
00156 this->_rb_model = sr._rb_model;
00157 }
00158
00159 ShapeTracker::~ShapeTracker()
00160 {
00161 }
00162
00163 void ShapeTracker::setCameraInfo(const sensor_msgs::CameraInfo& camera_info)
00164 {
00165 this->_ci = sensor_msgs::CameraInfo(camera_info);
00166 }
00167
00168 void OrganizedPC2DepthMap2(const pcl::PointCloud<pcl::PointXYZ >::Ptr organized_pc, cv::Mat& depth_map_mat)
00169 {
00170 float* data_ptr = (float*)depth_map_mat.data;
00171 size_t elem_step = depth_map_mat.step / sizeof(float);
00172
00173 for(int v=0; v< organized_pc->height; v++)
00174 {
00175 for(int u=0; u< organized_pc->width; u++)
00176 {
00177 if(pcl::isFinite(organized_pc->points[v*organized_pc->width + u]))
00178 data_ptr[v*elem_step + u] = organized_pc->points[v*organized_pc->width + u].z;
00179 else
00180 data_ptr[v*elem_step + u] = nanf("");
00181 }
00182 }
00183 }
00184
00185
00186 void ShapeTracker::step(const sensor_msgs::PointCloud2ConstPtr &pc_msg,
00187 const omip_msgs::RigidBodyPoseAndVelMsg& tracked_rbm,
00188 omip_msgs::ShapeTrackerState& st_state)
00189 {
00190 if(this->_rb_model->points.size() != 0)
00191 {
00192 ros::WallTime t1 = ros::WallTime::now();
00193
00194
00195 Eigen::Twistd pose_twist2;
00196 ROSTwist2EigenTwist(tracked_rbm.pose_wc.twist, pose_twist2);
00197 Eigen::Matrix4d pose_matrix;
00198 Twist2TransformMatrix(pose_twist2, pose_matrix);
00199
00200
00201
00202 pcl::PointCloud<pcl::PointXYZ >::Ptr rb_model_current_pose(new pcl::PointCloud<pcl::PointXYZ >);
00203 pcl::transformPointCloud<pcl::PointXYZ>(*this->_rb_model, *rb_model_current_pose, pose_matrix.cast<float>());
00204 pcl::PointXYZ min_pt;
00205 pcl::PointXYZ max_pt;
00206 pcl::getMinMax3D<pcl::PointXYZ>(*rb_model_current_pose, min_pt, max_pt);
00207 double safety_margin = 0.01;
00208 _icp_lpm->referenceDataPointsFilters.at(0)->parameters["xMin"] = min_pt.x - safety_margin;
00209 _icp_lpm->referenceDataPointsFilters.at(0)->parameters["xMax"] = max_pt.x + safety_margin;
00210 _icp_lpm->referenceDataPointsFilters.at(0)->parameters["yMin"] = min_pt.y - safety_margin;
00211 _icp_lpm->referenceDataPointsFilters.at(0)->parameters["yMax"] = max_pt.y + safety_margin;
00212 _icp_lpm->referenceDataPointsFilters.at(0)->parameters["zMin"] = min_pt.z - safety_margin;
00213 _icp_lpm->referenceDataPointsFilters.at(0)->parameters["zMax"] = max_pt.z + safety_margin;
00214
00215 sensor_msgs::PointCloud2 model_now;
00216 pcl::toROSMsg(*rb_model_current_pose, model_now);
00217 model_now.header.frame_id = "/camera_rgb_optical_frame";
00218 this->_segment_pub.publish(model_now);
00219
00220 ros::WallTime t4 = ros::WallTime::now();
00221
00222 ros::WallTime t5 = ros::WallTime::now();
00223
00224 bool lpm_converged = true;
00225
00226
00227 boost::shared_ptr<DP> current_segment_of_pc_extended_lpm(new DP(PointMatcher_ros::rosMsgToPointMatcherCloud<float>(*pc_msg)));
00228
00229 ros::WallTime t6 = ros::WallTime::now();
00230
00231
00232 PM::TransformationParameters T;
00233 try{
00234 std::cout << pose_matrix << std::endl;
00235
00236 T = _icp_lpm->operator()(*_rb_model_lpm, *current_segment_of_pc_extended_lpm, pose_matrix.cast<float>());
00237 std::cout << T << std::endl;
00238 }catch(...)
00239 {
00240 ROS_ERROR_STREAM("[RB" << this->_rb_id << "] Libmatchpoint ICP did not converge!");
00241 lpm_converged = false;
00242 st_state.fitness_score = 1;
00243 }
00244
00245 ros::WallTime t7 = ros::WallTime::now();
00246
00247 ROS_INFO_STREAM_NAMED("ShapeReconstruction._RemoveInconsistentPointsFromRBModel",
00248 "[RB" << this->_rb_id << " Estimated LPM ICP refinement: " << std::endl << T);
00249
00250 ROS_INFO_STREAM_NAMED("ShapeReconstruction.step",
00251 "t4 - t1: " << t4 - t1 );
00252 ROS_INFO_STREAM_NAMED("ShapeReconstruction.step",
00253 "t5 - t4: " << t5 - t4 );
00254 ROS_INFO_STREAM_NAMED("ShapeReconstruction.step",
00255 "t6 - t5: " << t6 - t5 );
00256 ROS_INFO_STREAM_NAMED("ShapeReconstruction.step",
00257 "t7 - t6: " << t7 - t6 );
00258
00259
00260 if(lpm_converged)
00261 {
00262 Eigen::Twistd compound_twist;
00263 TransformMatrix2Twist( T.cast<double>(), compound_twist);
00264
00265 EigenTwist2GeometryMsgsTwist(compound_twist, st_state.pose_wc.twist);
00266
00267 st_state.rb_id = this->_rb_id;
00268
00269 st_state.fitness_score = 0;
00270
00271 for (unsigned int i = 0; i < 6; i++)
00272 {
00273 for (unsigned int j = 0; j < 6; j++)
00274 {
00275 st_state.pose_wc.covariance[6 * i + j] = this->_icp_lpm->errorMinimizer->getCovariance()(i, j);
00276 }
00277 }
00278
00279
00280
00281 st_state.number_of_points_of_model = this->_icp_lpm->getPrefilteredReadingPtsCount();
00282 std::cout << this->_icp_lpm->getPrefilteredReadingPtsCount() << std::endl;
00283
00284 st_state.number_of_points_of_current_pc = this->_icp_lpm->getPrefilteredReferencePtsCount();
00285 std::cout << this->_icp_lpm->getPrefilteredReferencePtsCount() << std::endl;
00286
00287 }else{
00288 st_state.pose_wc.twist = tracked_rbm.pose_wc.twist;
00289 st_state.number_of_points_of_model = 0;
00290 st_state.number_of_points_of_current_pc =0;
00291 }
00292
00293 ROS_WARN_STREAM("Before refinement: \t" << tracked_rbm.pose_wc.twist.linear.x << " " <<
00294 tracked_rbm.pose_wc.twist.linear.y << " " <<
00295 tracked_rbm.pose_wc.twist.linear.z << " " <<
00296 tracked_rbm.pose_wc.twist.angular.x << " " <<
00297 tracked_rbm.pose_wc.twist.angular.y << " " <<
00298 tracked_rbm.pose_wc.twist.angular.z );
00299
00300 ROS_WARN_STREAM("After refinement: \t" <<st_state.pose_wc.twist.linear.x << " " <<
00301 st_state.pose_wc.twist.linear.y << " " <<
00302 st_state.pose_wc.twist.linear.z << " " <<
00303 st_state.pose_wc.twist.angular.x << " " <<
00304 st_state.pose_wc.twist.angular.y << " " <<
00305 st_state.pose_wc.twist.angular.z );
00306
00307 st_state.probabilistic_value = 1.0;
00308 }else{
00309 st_state.pose_wc.twist = tracked_rbm.pose_wc.twist;
00310 ROS_WARN_STREAM("Model is empty! Same twist as the input: " << st_state.pose_wc.twist.linear.x << " " <<
00311 st_state.pose_wc.twist.linear.y << " " <<
00312 st_state.pose_wc.twist.linear.z << " " <<
00313 st_state.pose_wc.twist.angular.x << " " <<
00314 st_state.pose_wc.twist.angular.y << " " <<
00315 st_state.pose_wc.twist.angular.z );
00316
00317 st_state.rb_id = this->_rb_id;
00318 st_state.fitness_score = std::numeric_limits<float>::infinity();
00319
00320 st_state.probabilistic_value = 1.0;
00321
00322 st_state.number_of_points_of_model = 0;
00323 st_state.number_of_points_of_current_pc = 0;
00324 }
00325 }
00326
00327 void ShapeTracker::setShapeModel(const sensor_msgs::PointCloud2& model)
00328 {
00329
00330 pcl::fromROSMsg(model, *this->_rb_model);
00331
00332
00333 sensor_msgs::PointCloud2 rb_model_ros;
00334 pcl::toROSMsg(*this->_rb_model, rb_model_ros);
00335 _rb_model_lpm.reset(new DP(PointMatcher_ros::rosMsgToPointMatcherCloud<float>(rb_model_ros)));
00336 }
00337
00338 void ShapeTracker::_RemoveInconsistentPointsFromRBModel(pcl::PointCloud<pcl::PointXYZ >::Ptr model_current_pose,
00339 pcl::PointCloud<pcl::PointXYZ >::Ptr current_pc,
00340 pcl::PointCloud<pcl::PointXYZ >::Ptr& rb_segment,
00341 pcl::PointCloud<pcl::PointXYZ >::Ptr& current_pc_extended_segment)
00342 {
00343
00344 OrganizedPC2DepthMap2(current_pc, this->_current_dm);
00345
00346 pcl::PointIndicesPtr indices_to_remove(new pcl::PointIndices);
00347
00348
00349
00350 pcl::PointIndicesPtr indices_matching_in_current(new pcl::PointIndices);
00351
00352
00353 pcl::PointIndicesPtr indices_matching_in_model(new pcl::PointIndices);
00354
00355
00356
00357 _FindInconsistentPoints(model_current_pose,
00358 this->_current_dm,
00359 indices_to_remove,
00360 indices_matching_in_model,
00361 indices_matching_in_current
00362 );
00363
00364 ROS_INFO_STREAM_NAMED("ShapeReconstruction._RemoveInconsistentPointsFromRBModel",
00365 "Matched points in current point cloud: " << indices_matching_in_current->indices.size());
00366 ROS_INFO_STREAM_NAMED("ShapeReconstruction._RemoveInconsistentPointsFromRBModel",
00367 "Matched points in model: " << indices_matching_in_model->indices.size());
00368
00369
00370 this->_segment_of_current.setTo(0);
00371 IndicesOfOrganizedPC2Image8u(indices_matching_in_current, this->_segment_of_current);
00372
00373
00374 cv::dilate(this->_segment_of_current, this->_segment_of_current_dilated, this->_dilation_element);
00375
00376
00377 pcl::PointIndicesPtr indices_matching_in_current_extended(new pcl::PointIndices);
00378 Image8u2IndicesOfOrganizedPC(this->_segment_of_current_dilated, indices_matching_in_current_extended);
00379
00380 ROS_INFO_STREAM_NAMED("ShapeReconstruction._RemoveInconsistentPointsFromRBModel",
00381 "Matched points in current point cloud extended: " << indices_matching_in_current_extended->indices.size());
00382
00383
00384 _extractor.setNegative(false);
00385 _extractor.setInputCloud(model_current_pose);
00386 _extractor.setIndices(indices_matching_in_model);
00387 _extractor.setKeepOrganized(false);
00388 _extractor.filter(*rb_segment);
00389
00390
00391 _extractor.setInputCloud(current_pc);
00392 _extractor.setIndices(indices_matching_in_current_extended);
00393 _extractor.setKeepOrganized(false);
00394 _extractor.filter(*current_pc_extended_segment);
00395 }
00396
00397 void ShapeTracker::_FindInconsistentPoints(const pcl::PointCloud<pcl::PointXYZ >::Ptr& pc_source,
00398 const cv::Mat & dm_true,
00399 pcl::PointIndicesPtr& indices_to_remove,
00400 pcl::PointIndicesPtr& indices_matching_in_true,
00401 pcl::PointIndicesPtr& indices_matching_in_dm,
00402 const double min_depth_error)
00403 {
00404 indices_to_remove->indices.clear();
00405
00406 using ::shape_reconstruction::RangeImagePlanar;
00407 RangeImagePlanar::Ptr dm_source_rip(new RangeImagePlanar);
00408
00409 Eigen::Affine3f sensor_pose;
00410 sensor_pose.matrix() = Eigen::Matrix4f::Identity();
00411 pcl::RangeImagePlanar::CoordinateFrame coordinate_frame = pcl::RangeImagePlanar::CAMERA_FRAME;
00412
00413 int width = dm_true.cols, height = dm_true.rows;
00414 dm_source_rip->matchPointCloudAndImage (*pc_source,
00415 width,
00416 height,
00417 this->_ci.P[2],
00418 this->_ci.P[6],
00419 this->_ci.P[0],
00420 this->_ci.P[5],
00421 sensor_pose,
00422 coordinate_frame,
00423 dm_true,
00424 min_depth_error,
00425 indices_matching_in_true,
00426 indices_matching_in_dm,
00427 indices_to_remove
00428 );
00429
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 void calculate_ICP_COV(pcl::PointCloud<pcl::PointXYZ>& data_pi, pcl::PointCloud<pcl::PointXYZ>& model_qi, Eigen::Matrix4f& transform, Eigen::MatrixXd& ICP_COV)
00441 {
00442
00443 double Tx = transform(0,3);
00444 double Ty = transform(1,3);
00445 double Tz = transform(2,3);
00446 double roll = atan2f(transform(2,1), transform(2,2));
00447 double pitch = asinf(-transform(2,0));
00448 double yaw = atan2f(transform(1,0), transform(0,0));
00449
00450 double x, y, z, a, b, c;
00451 x = Tx; y = Ty; z = Tz;
00452 a = yaw; b = pitch; c = roll;
00453
00454
00455 std::cout << "\nPrinting out [x, y, z, a, b, c] = " <<x<<" "<<y<<" "<<z<<" "<<a<<" "<<b<<" "<<c<<std::endl;
00456
00457
00458 Eigen::MatrixXd d2J_dX2(6,6);
00459 d2J_dX2 = Eigen::MatrixXd::Zero(6,6);
00460
00461
00462 for (size_t s = 0; s < data_pi.points.size(); ++s )
00463 {
00464 double pix = data_pi.points[s].x;
00465 double piy = data_pi.points[s].y;
00466 double piz = data_pi.points[s].z;
00467 double qix = model_qi.points[s].x;
00468 double qiy = model_qi.points[s].y;
00469 double qiz = model_qi.points[s].z;
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 double d2J_dx2, d2J_dydx, d2J_dzdx, d2J_dadx, d2J_dbdx, d2J_dcdx,
00491 d2J_dxdy, d2J_dy2, d2J_dzdy, d2J_dady, d2J_dbdy, d2J_dcdy,
00492 d2J_dxdz, d2J_dydz, d2J_dz2, d2J_dadz, d2J_dbdz, d2J_dcdz,
00493 d2J_dxda, d2J_dyda, d2J_dzda, d2J_da2, d2J_dbda, d2J_dcda,
00494 d2J_dxdb, d2J_dydb, d2J_dzdb, d2J_dadb, d2J_db2, d2J_dcdb,
00495 d2J_dxdc, d2J_dydc, d2J_dzdc, d2J_dadc, d2J_dbdc, d2J_dc2;
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 d2J_dx2 = 2;
00506
00507 d2J_dy2 = 2;
00508
00509 d2J_dz2 = 2;
00510
00511 d2J_dydx = 0;
00512
00513 d2J_dxdy = 0;
00514
00515 d2J_dzdx = 0;
00516
00517 d2J_dxdz = 0;
00518
00519 d2J_dydz = 0;
00520
00521 d2J_dzdy = 0;
00522
00523 d2J_da2 = (piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + pix*cos(a)*cos(b))*(2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b)) - (2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*pix*cos(b)*sin(a))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) + (piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a))*(2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*pix*cos(b)*sin(a)) - (2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b));
00524
00525 d2J_db2 = (pix*cos(b) + piz*cos(c)*sin(b) + piy*sin(b)*sin(c))*(2*pix*cos(b) + 2*piz*cos(c)*sin(b) + 2*piy*sin(b)*sin(c)) - (2*piz*cos(b)*cos(c) - 2*pix*sin(b) + 2*piy*cos(b)*sin(c))*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c)) - (2*pix*cos(a)*cos(b) + 2*piz*cos(a)*cos(c)*sin(b) + 2*piy*cos(a)*sin(b)*sin(c))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) + (piz*cos(a)*cos(b)*cos(c) - pix*cos(a)*sin(b) + piy*cos(a)*cos(b)*sin(c))*(2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c)) - (2*pix*cos(b)*sin(a) + 2*piz*cos(c)*sin(a)*sin(b) + 2*piy*sin(a)*sin(b)*sin(c))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) + (piz*cos(b)*cos(c)*sin(a) - pix*sin(a)*sin(b) + piy*cos(b)*sin(a)*sin(c))*(2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c));
00526
00527 d2J_dc2 = (piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)))*(2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c))) + (piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)))*(2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c))) - (2*piz*cos(b)*cos(c) + 2*piy*cos(b)*sin(c))*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c)) + (2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) - 2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) + (piy*cos(b)*cos(c) - piz*cos(b)*sin(c))*(2*piy*cos(b)*cos(c) - 2*piz*cos(b)*sin(c)) - (2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a));
00528
00529 d2J_dxda = 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) - 2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*pix*cos(b)*sin(a);
00530
00531 d2J_dadx = 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) - 2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*pix*cos(b)*sin(a);
00532
00533 d2J_dyda = 2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b);
00534
00535 d2J_dady = 2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b);
00536
00537 d2J_dzda = 0;
00538
00539 d2J_dadz = 0;
00540
00541 d2J_dxdb = 2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c);
00542
00543 d2J_dbdx = 2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c);
00544
00545 d2J_dydb = 2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c);
00546
00547 d2J_dbdy = 2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c);
00548
00549 d2J_dzdb = - 2*pix*cos(b) - 2*piz*cos(c)*sin(b) - 2*piy*sin(b)*sin(c);
00550
00551 d2J_dbdz = - 2*pix*cos(b) - 2*piz*cos(c)*sin(b) - 2*piy*sin(b)*sin(c);
00552
00553 d2J_dxdc = 2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c));
00554
00555 d2J_dcdx = 2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c));
00556
00557 d2J_dydc = - 2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) - 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c));
00558
00559 d2J_dcdy = - 2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) - 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c));
00560
00561 d2J_dzdc = 2*piy*cos(b)*cos(c) - 2*piz*cos(b)*sin(c);
00562
00563 d2J_dcdz = 2*piy*cos(b)*cos(c) - 2*piz*cos(b)*sin(c);
00564
00565 d2J_dadb = (2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c))*(piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + pix*cos(a)*cos(b)) - (2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c))*(piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) + (2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) - (2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b));
00566
00567 d2J_dbda = (piz*cos(b)*cos(c)*sin(a) - pix*sin(a)*sin(b) + piy*cos(b)*sin(a)*sin(c))*(2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b)) - (piz*cos(a)*cos(b)*cos(c) - pix*cos(a)*sin(b) + piy*cos(a)*cos(b)*sin(c))*(2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*pix*cos(b)*sin(a)) + (2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) - (2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b));
00568
00569 d2J_dbdc = (2*piy*cos(a)*cos(b)*cos(c) - 2*piz*cos(a)*cos(b)*sin(c))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) + (2*piy*cos(b)*cos(c)*sin(a) - 2*piz*cos(b)*sin(a)*sin(c))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) - (2*piy*cos(b)*cos(c) - 2*piz*cos(b)*sin(c))*(pix*cos(b) + piz*cos(c)*sin(b) + piy*sin(b)*sin(c)) - (2*piy*cos(c)*sin(b) - 2*piz*sin(b)*sin(c))*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c)) + (2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)))*(piz*cos(a)*cos(b)*cos(c) - pix*cos(a)*sin(b) + piy*cos(a)*cos(b)*sin(c)) - (2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)))*(piz*cos(b)*cos(c)*sin(a) - pix*sin(a)*sin(b) + piy*cos(b)*sin(a)*sin(c));
00570
00571 d2J_dcdb = (2*piy*cos(a)*cos(b)*cos(c) - 2*piz*cos(a)*cos(b)*sin(c))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) + (2*piy*cos(b)*cos(c)*sin(a) - 2*piz*cos(b)*sin(a)*sin(c))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) - (piy*cos(b)*cos(c) - piz*cos(b)*sin(c))*(2*pix*cos(b) + 2*piz*cos(c)*sin(b) + 2*piy*sin(b)*sin(c)) - (2*piy*cos(c)*sin(b) - 2*piz*sin(b)*sin(c))*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c)) + (piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)))*(2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c)) - (piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)))*(2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c));
00572
00573 d2J_dcda = (2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) - (piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)))*(2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*pix*cos(b)*sin(a)) - (piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)))*(2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b)) + (2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a));
00574
00575 d2J_dadc = (2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) - (2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)))*(piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) - (2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)))*(piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + pix*cos(a)*cos(b)) + (2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a));
00576
00577 Eigen::MatrixXd d2J_dX2_temp(6,6);
00578
00579 d2J_dX2_temp << d2J_dx2, d2J_dydx, d2J_dzdx, d2J_dadx, d2J_dbdx, d2J_dzdx,
00580 d2J_dxdy, d2J_dy2, d2J_dzdy, d2J_dady, d2J_dbdy, d2J_dcdy,
00581 d2J_dxdz, d2J_dydz, d2J_dz2, d2J_dadz, d2J_dbdz, d2J_dcdz,
00582 d2J_dxda, d2J_dyda, d2J_dzda, d2J_da2, d2J_dbda, d2J_dcda,
00583 d2J_dxdb, d2J_dydb, d2J_dzdb, d2J_dadb, d2J_db2, d2J_dcdb,
00584 d2J_dxdc, d2J_dydc, d2J_dzdc, d2J_dadc, d2J_dbdc, d2J_dc2;
00585
00586 d2J_dX2 = d2J_dX2 + d2J_dX2_temp;
00587
00588 }
00589
00590 std::cout << "\n**************\n Successfully Computed d2J_dX2 \n**************\n" << std::endl;
00591
00592
00593
00594
00595 int n = data_pi.points.size();
00596
00597 if (n > 200) n = 200;
00598
00599 std::cout << "\nNumber of Correspondences used for ICP's covariance estimation = " << n << std::endl;
00600
00601 Eigen::MatrixXd d2J_dZdX(6,6*n);
00602
00603 for (int k = 0; k < n ; ++k)
00604 {
00605
00606 double pix = data_pi.points[k].x;
00607 double piy = data_pi.points[k].y;
00608 double piz = data_pi.points[k].z;
00609 double qix = model_qi.points[k].x;
00610 double qiy = model_qi.points[k].y;
00611 double qiz = model_qi.points[k].z;
00612
00613 Eigen::MatrixXd d2J_dZdX_temp(6,6);
00614
00615
00616 double d2J_dpix_dx, d2J_dpiy_dx, d2J_dpiz_dx, d2J_dqix_dx, d2J_dqiy_dx, d2J_dqiz_dx,
00617 d2J_dpix_dy, d2J_dpiy_dy, d2J_dpiz_dy, d2J_dqix_dy, d2J_dqiy_dy, d2J_dqiz_dy,
00618 d2J_dpix_dz, d2J_dpiy_dz, d2J_dpiz_dz, d2J_dqix_dz, d2J_dqiy_dz, d2J_dqiz_dz,
00619 d2J_dpix_da, d2J_dpiy_da, d2J_dpiz_da, d2J_dqix_da, d2J_dqiy_da, d2J_dqiz_da,
00620 d2J_dpix_db, d2J_dpiy_db, d2J_dpiz_db, d2J_dqix_db, d2J_dqiy_db, d2J_dqiz_db,
00621 d2J_dpix_dc, d2J_dpiy_dc, d2J_dpiz_dc, d2J_dqix_dc, d2J_dqiy_dc, d2J_dqiz_dc;
00622
00623 d2J_dpix_dx = 2*cos(a)*cos(b);
00624
00625 d2J_dpix_dy = 2*cos(b)*sin(a);
00626
00627 d2J_dpix_dz = -2*sin(b);
00628
00629 d2J_dpix_da = cos(b)*sin(a)*(2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b)) - cos(a)*cos(b)*(2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*pix*cos(b)*sin(a)) - 2*cos(b)*sin(a)*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) + 2*cos(a)*cos(b)*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a));
00630
00631 d2J_dpix_db = sin(b)*(2*pix*cos(b) + 2*piz*cos(c)*sin(b) + 2*piy*sin(b)*sin(c)) - 2*cos(b)*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c)) + cos(a)*cos(b)*(2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c)) - 2*sin(a)*sin(b)*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) + cos(b)*sin(a)*(2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c)) - 2*cos(a)*sin(b)*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b));
00632
00633 d2J_dpix_dc = cos(a)*cos(b)*(2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c))) - sin(b)*(2*piy*cos(b)*cos(c) - 2*piz*cos(b)*sin(c)) - cos(b)*sin(a)*(2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)));
00634
00635 d2J_dpiy_dx = 2*cos(a)*sin(b)*sin(c) - 2*cos(c)*sin(a);
00636
00637 d2J_dpiy_dy = 2*cos(a)*cos(c) + 2*sin(a)*sin(b)*sin(c);
00638
00639 d2J_dpiy_dz = 2*cos(b)*sin(c);
00640
00641 d2J_dpiy_da = (cos(a)*cos(c) + sin(a)*sin(b)*sin(c))*(2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b)) + (cos(c)*sin(a) - cos(a)*sin(b)*sin(c))*(2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*pix*cos(b)*sin(a)) - (2*cos(a)*cos(c) + 2*sin(a)*sin(b)*sin(c))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) - (2*cos(c)*sin(a) - 2*cos(a)*sin(b)*sin(c))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a));
00642
00643 d2J_dpiy_db = (cos(a)*cos(c) + sin(a)*sin(b)*sin(c))*(2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c)) - (cos(c)*sin(a) - cos(a)*sin(b)*sin(c))*(2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c)) - 2*sin(b)*sin(c)*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c)) - cos(b)*sin(c)*(2*pix*cos(b) + 2*piz*cos(c)*sin(b) + 2*piy*sin(b)*sin(c)) + 2*cos(a)*cos(b)*sin(c)*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) + 2*cos(b)*sin(a)*sin(c)*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a));
00644
00645 d2J_dpiy_dc = (2*sin(a)*sin(c) + 2*cos(a)*cos(c)*sin(b))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) - (2*cos(a)*sin(c) - 2*cos(c)*sin(a)*sin(b))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) - (cos(a)*cos(c) + sin(a)*sin(b)*sin(c))*(2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c))) - (cos(c)*sin(a) - cos(a)*sin(b)*sin(c))*(2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c))) + 2*cos(b)*cos(c)*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c)) + cos(b)*sin(c)*(2*piy*cos(b)*cos(c) - 2*piz*cos(b)*sin(c));
00646
00647 d2J_dpiz_dx = 2*sin(a)*sin(c) + 2*cos(a)*cos(c)*sin(b);
00648
00649 d2J_dpiz_dy = 2*cos(c)*sin(a)*sin(b) - 2*cos(a)*sin(c);
00650
00651 d2J_dpiz_dz = 2*cos(b)*cos(c);
00652
00653 d2J_dpiz_da = (2*cos(a)*sin(c) - 2*cos(c)*sin(a)*sin(b))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) - (sin(a)*sin(c) + cos(a)*cos(c)*sin(b))*(2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*pix*cos(b)*sin(a)) - (cos(a)*sin(c) - cos(c)*sin(a)*sin(b))*(2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + 2*pix*cos(a)*cos(b)) + (2*sin(a)*sin(c) + 2*cos(a)*cos(c)*sin(b))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a));
00654
00655 d2J_dpiz_db = (sin(a)*sin(c) + cos(a)*cos(c)*sin(b))*(2*piz*cos(a)*cos(b)*cos(c) - 2*pix*cos(a)*sin(b) + 2*piy*cos(a)*cos(b)*sin(c)) - (cos(a)*sin(c) - cos(c)*sin(a)*sin(b))*(2*piz*cos(b)*cos(c)*sin(a) - 2*pix*sin(a)*sin(b) + 2*piy*cos(b)*sin(a)*sin(c)) - 2*cos(c)*sin(b)*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c)) - cos(b)*cos(c)*(2*pix*cos(b) + 2*piz*cos(c)*sin(b) + 2*piy*sin(b)*sin(c)) + 2*cos(a)*cos(b)*cos(c)*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) + 2*cos(b)*cos(c)*sin(a)*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a));
00656
00657 d2J_dpiz_dc = (2*cos(c)*sin(a) - 2*cos(a)*sin(b)*sin(c))*(x - qix - piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) + piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + pix*cos(a)*cos(b)) - (2*cos(a)*cos(c) + 2*sin(a)*sin(b)*sin(c))*(y - qiy + piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + pix*cos(b)*sin(a)) + (sin(a)*sin(c) + cos(a)*cos(c)*sin(b))*(2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) + 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c))) + (cos(a)*sin(c) - cos(c)*sin(a)*sin(b))*(2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c))) + cos(b)*cos(c)*(2*piy*cos(b)*cos(c) - 2*piz*cos(b)*sin(c)) - 2*cos(b)*sin(c)*(z - qiz - pix*sin(b) + piz*cos(b)*cos(c) + piy*cos(b)*sin(c));
00658
00659 d2J_dqix_dx = -2;
00660
00661 d2J_dqix_dy = 0;
00662
00663 d2J_dqix_dz = 0;
00664
00665 d2J_dqix_da = 2*piy*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c)) - 2*piz*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*pix*cos(b)*sin(a);
00666
00667 d2J_dqix_db = 2*pix*cos(a)*sin(b) - 2*piz*cos(a)*cos(b)*cos(c) - 2*piy*cos(a)*cos(b)*sin(c);
00668
00669 d2J_dqix_dc = - 2*piy*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*piz*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c));
00670
00671 d2J_dqiy_dx = 0;
00672
00673 d2J_dqiy_dy = -2;
00674
00675 d2J_dqiy_dz = 0;
00676
00677 d2J_dqiy_da = 2*piy*(cos(c)*sin(a) - cos(a)*sin(b)*sin(c)) - 2*piz*(sin(a)*sin(c) + cos(a)*cos(c)*sin(b)) - 2*pix*cos(a)*cos(b);
00678
00679 d2J_dqiy_db = 2*pix*sin(a)*sin(b) - 2*piz*cos(b)*cos(c)*sin(a) - 2*piy*cos(b)*sin(a)*sin(c);
00680
00681 d2J_dqiy_dc = 2*piy*(cos(a)*sin(c) - cos(c)*sin(a)*sin(b)) + 2*piz*(cos(a)*cos(c) + sin(a)*sin(b)*sin(c));
00682
00683 d2J_dqiz_dx = 0;
00684
00685 d2J_dqiz_dy = 0;
00686
00687 d2J_dqiz_dz = -2;
00688
00689 d2J_dqiz_da = 0;
00690
00691 d2J_dqiz_db = 2*pix*cos(b) + 2*piz*cos(c)*sin(b) + 2*piy*sin(b)*sin(c);
00692
00693 d2J_dqiz_dc = 2*piz*cos(b)*sin(c) - 2*piy*cos(b)*cos(c);
00694
00695 d2J_dZdX_temp << d2J_dpix_dx, d2J_dpiy_dx, d2J_dpiz_dx, d2J_dqix_dx, d2J_dqiy_dx, d2J_dqiz_dx,
00696 d2J_dpix_dy, d2J_dpiy_dy, d2J_dpiz_dy, d2J_dqix_dy, d2J_dqiy_dy, d2J_dqiz_dy,
00697 d2J_dpix_dz, d2J_dpiy_dz, d2J_dpiz_dz, d2J_dqix_dz, d2J_dqiy_dz, d2J_dqiz_dz,
00698 d2J_dpix_da, d2J_dpiy_da, d2J_dpiz_da, d2J_dqix_da, d2J_dqiy_da, d2J_dqiz_da,
00699 d2J_dpix_db, d2J_dpiy_db, d2J_dpiz_db, d2J_dqix_db, d2J_dqiy_db, d2J_dqiz_db,
00700 d2J_dpix_dc, d2J_dpiy_dc, d2J_dpiz_dc, d2J_dqix_dc, d2J_dqiy_dc, d2J_dqiz_dc;
00701
00702
00703 d2J_dZdX.block<6,6>(0,6*k) = d2J_dZdX_temp;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712 Eigen::MatrixXd cov_z(6*n,6*n);
00713 cov_z = 0.01 * Eigen::MatrixXd::Identity(6*n,6*n);
00714
00715 ICP_COV = d2J_dX2.inverse() * d2J_dZdX * cov_z * d2J_dZdX.transpose() * d2J_dX2.inverse();
00716
00717 std::cout << "\n\n********************** \n\n" << "ICP_COV = \n" << ICP_COV <<"\n*******************\n\n"<< std::endl;
00718
00719 std::cout << "\nSuccessfully Computed the ICP's Covariance !!!\n" << std::endl;
00720 }