bundleAdjust.cpp
Go to the documentation of this file.
00001 #include <math.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <ros/ros.h>
00005 
00006 #include <nav_msgs/Odometry.h>
00007 
00008 #include <tf/transform_datatypes.h>
00009 #include <tf/transform_listener.h>
00010 #include <tf/transform_broadcaster.h>
00011 
00012 #include "isam/isam.h"
00013 #include "isam/slam_depthmono.h"
00014 #include "isam/robust.h"
00015 
00016 #include "cameraParameters.h"
00017 #include "pointDefinition.h"
00018 
00019 using namespace std;
00020 using namespace isam;
00021 using namespace Eigen;
00022 
00023 const double PI = 3.1415926;
00024 
00025 const int keyframeNum = 5;
00026 pcl::PointCloud<DepthPoint>::Ptr depthPoints[keyframeNum];
00027 pcl::PointCloud<DepthPoint>::Ptr depthPointsStacked(new pcl::PointCloud<DepthPoint>());
00028 
00029 double depthPointsTime;
00030 bool newKeyframe = false;
00031 
00032 float rollRec, pitchRec, yawRec;
00033 float txRec, tyRec, tzRec;
00034 
00035 float transformBefBA[6] = {0};
00036 float transformAftBA[6] = {0};
00037 
00038 double robust_cost_function(double d) {
00039   return cost_pseudo_huber(d, .5);
00040 }
00041 
00042 void transformAssociateToBA()
00043 {
00044   float txDiff = txRec - transformBefBA[3];
00045   float tyDiff = tyRec - transformBefBA[4];
00046   float tzDiff = tzRec - transformBefBA[5];
00047 
00048   float x1 = cos(yawRec) * txDiff - sin(yawRec) * tzDiff;
00049   float y1 = tyDiff;
00050   float z1 = sin(yawRec) * txDiff + cos(yawRec) * tzDiff;
00051 
00052   float x2 = x1;
00053   float y2 = cos(pitchRec) * y1 + sin(pitchRec) * z1;
00054   float z2 = -sin(pitchRec) * y1 + cos(pitchRec) * z1;
00055 
00056   txDiff = cos(rollRec) * x2 + sin(rollRec) * y2;
00057   tyDiff = -sin(rollRec) * x2 + cos(rollRec) * y2;
00058   tzDiff = z2;
00059 
00060   pitchRec += transformAftBA[0] - transformBefBA[0];
00061   yawRec += transformAftBA[1] - transformBefBA[1];
00062   rollRec += transformAftBA[2] - transformBefBA[2];
00063 
00064   x1 = cos(rollRec) * txDiff - sin(rollRec) * tyDiff;
00065   y1 = sin(rollRec) * txDiff + cos(rollRec) * tyDiff;
00066   z1 = tzDiff;
00067 
00068   x2 = x1;
00069   y2 = cos(pitchRec) * y1 - sin(pitchRec) * z1;
00070   z2 = sin(pitchRec) * y1 + cos(pitchRec) * z1;
00071 
00072   txDiff = cos(yawRec) * x2 + sin(yawRec) * z2;
00073   tyDiff = y2;
00074   tzDiff = -sin(yawRec) * x2 + cos(yawRec) * z2;
00075 
00076   txRec = transformAftBA[3] + txDiff;
00077   tyRec = transformAftBA[4] + tyDiff;
00078   tzRec = transformAftBA[5] + tzDiff;
00079 }
00080 
00081 void depthPointsHandler(const sensor_msgs::PointCloud2ConstPtr& depthPoints2)
00082 {
00083   depthPointsTime = depthPoints2->header.stamp.toSec();
00084 
00085   depthPointsStacked->clear();
00086   pcl::fromROSMsg(*depthPoints2, *depthPointsStacked);
00087   int depthPointsStackedNum = depthPointsStacked->points.size();
00088 
00089   for (int i = 0; i < keyframeNum; i++) {
00090     depthPoints[i]->clear();
00091   }
00092 
00093   int keyframeCount = -1;
00094   for (int i = 0; i < depthPointsStackedNum; i++) {
00095     if (depthPointsStacked->points[i].ind == -2) {
00096       keyframeCount++;
00097     }
00098 
00099     if (keyframeCount >= 0 && keyframeCount < keyframeNum) {
00100       depthPoints[keyframeCount]->push_back(depthPointsStacked->points[i]);
00101     }
00102   }
00103 
00104   bool enoughPoints = true;
00105   for (int i = 0; i < keyframeNum; i++) {
00106     if (depthPoints[i]->points.size() < 10) {
00107       enoughPoints = false;
00108     }
00109   }
00110 
00111   if (enoughPoints) {
00112     newKeyframe = true;
00113   }
00114 }
00115 
00116 int main(int argc, char** argv)
00117 {
00118   ros::init(argc, argv, "bundleAdjust");
00119   ros::NodeHandle nh;
00120 
00121   for (int i = 0; i < keyframeNum; i++) {
00122     pcl::PointCloud<DepthPoint>::Ptr depthPointsTemp(new pcl::PointCloud<DepthPoint>());
00123     depthPoints[i] = depthPointsTemp;
00124   }
00125 
00126   ros::Subscriber depthPointsSub = nh.subscribe<sensor_msgs::PointCloud2>
00127                                    ("/depth_points_stacked", 1, depthPointsHandler);
00128 
00129   ros::Publisher odomBefBAPub = nh.advertise<nav_msgs::Odometry> ("/bef_ba_to_init", 1);
00130 
00131   ros::Publisher odomAftBAPub = nh.advertise<nav_msgs::Odometry> ("/aft_ba_to_init", 1);
00132 
00133   tf::TransformBroadcaster tfBroadcaster;
00134 
00135   Vector2d pp(0, 0);
00136   DepthmonoCamera camera(1, pp);
00137 
00138   MatrixXd mpNoise = eye(3);
00139   mpNoise(2, 2) = 0.001;
00140   Noise noise0 = Information(mpNoise);
00141 
00142   MatrixXd dpNoise = eye(3);
00143   //dpNoise(2, 2) = 1.;
00144   Noise noise1 = Information(dpNoise);
00145 
00146   MatrixXd ssNoise = 10000. * eye(6);
00147   //ssNoise(3, 3) = 100;
00148   //ssNoise(4, 4) = 100;
00149   //ssNoise(5, 5) = 100;
00150   Noise noise2 = Information(ssNoise);
00151 
00152   MatrixXd psNoise = 10000. * eye(6);
00153   psNoise(3, 3) = 100;
00154   psNoise(4, 4) = 100;
00155   psNoise(5, 5) = 100;
00156   Noise noise3 = Information(psNoise);
00157 
00158   bool status = ros::ok();
00159   while (status) {
00160     ros::spinOnce();
00161 
00162     if (newKeyframe) {
00163       newKeyframe = false;
00164 
00165       Slam ba;
00166 
00167       vector<Pose3d_Node*> poses;
00168       Pose3d_Node* pose0 = new Pose3d_Node();
00169       poses.push_back(pose0);
00170       ba.add_node(pose0);
00171 
00172       rollRec = depthPoints[0]->points[0].depth;
00173       pitchRec = depthPoints[0]->points[0].u;
00174       yawRec = depthPoints[0]->points[0].v;
00175       txRec = depthPoints[0]->points[1].u;
00176       tyRec = depthPoints[0]->points[1].v;
00177       tzRec = depthPoints[0]->points[1].depth;
00178 
00179       transformAssociateToBA();
00180 
00181       Pose3d_Factor* poseFactors0 = new Pose3d_Factor(pose0, 
00182                                     Pose3d(tzRec, txRec, tyRec, yawRec, pitchRec, rollRec), noise2);
00183       ba.add_factor(poseFactors0);
00184 
00185       rollRec = depthPoints[0]->points[0].depth;
00186       pitchRec = depthPoints[0]->points[0].u;
00187       yawRec = depthPoints[0]->points[0].v;
00188       txRec = depthPoints[0]->points[1].u;
00189       tyRec = depthPoints[0]->points[1].v;
00190       tzRec = depthPoints[0]->points[1].depth;
00191 
00192       vector<Pose3d_Pose3d_Factor*> posePoseFactors;
00193       for (int i = 1; i < keyframeNum; i++) {
00194         Pose3d_Node* posen = new Pose3d_Node();
00195         poses.push_back(posen);
00196         ba.add_node(posen);
00197 
00198         float roll = depthPoints[i]->points[0].depth;
00199         float pitch = depthPoints[i]->points[0].u;
00200         float yaw = depthPoints[i]->points[0].v;
00201         float tx = depthPoints[i]->points[1].u;
00202         float ty = depthPoints[i]->points[1].v;
00203         float tz = depthPoints[i]->points[1].depth;
00204 
00205         float txDiff = tx - txRec;
00206         float tyDiff = ty - tyRec;
00207         float tzDiff = tz - tzRec;
00208 
00209         float x1 = cos(yawRec) * txDiff - sin(yawRec) * tzDiff;
00210         float y1 = tyDiff;
00211         float z1 = sin(yawRec) * txDiff + cos(yawRec) * tzDiff;
00212 
00213         float x2 = x1;
00214         float y2 = cos(pitchRec) * y1 + sin(pitchRec) * z1;
00215         float z2 = -sin(pitchRec) * y1 + cos(pitchRec) * z1;
00216 
00217         txDiff = cos(rollRec) * x2 + sin(rollRec) * y2;
00218         tyDiff = -sin(rollRec) * x2 + cos(rollRec) * y2;
00219         tzDiff = z2;
00220 
00221         Pose3d_Pose3d_Factor* poseposeFactorn = new Pose3d_Pose3d_Factor
00222                                                 (poses[i - 1], posen, Pose3d(tzDiff, txDiff, tyDiff, 
00223                                                 yaw - yawRec, pitch - pitchRec, roll - rollRec), noise3);
00224         posePoseFactors.push_back(poseposeFactorn);
00225         ba.add_factor(poseposeFactorn);
00226 
00227         rollRec = roll; pitchRec = pitch; yawRec = yaw;
00228         txRec = tx; tyRec = ty; tzRec = tz;
00229       }
00230 
00231       vector<Point3d_Node*> points;
00232       std::vector<int> pointsInd;
00233       vector<Depthmono_Factor*> depthmonoFactors;
00234       for (int i = 0; i < keyframeNum; i++) {
00235         pcl::PointCloud<DepthPoint>::Ptr dpPointer = depthPoints[i];
00236         int kfptNum = dpPointer->points.size();
00237         int ptRecNum = points.size();
00238 
00239         if (i == 0) {
00240           pcl::PointCloud<DepthPoint>::Ptr dpPointerNext = depthPoints[i + 1];
00241           int kfptNumNext = dpPointerNext->points.size();
00242 
00243           int ptCountNext = 2;
00244           for (int j = 2; j < kfptNum; j++) {
00245             bool ptFound = false;
00246             for (; ptCountNext < kfptNumNext; ptCountNext++) {
00247               if (dpPointerNext->points[ptCountNext].ind == dpPointer->points[j].ind) {
00248                 ptFound = true;
00249               }
00250               if (dpPointerNext->points[ptCountNext].ind >= dpPointer->points[j].ind) {
00251                 break;
00252               }
00253             }
00254 
00255             if (ptFound && dpPointer->points[j].label == 1) {
00256               Point3d_Node* pointn = new Point3d_Node();
00257               points.push_back(pointn);
00258               pointsInd.push_back(dpPointer->points[j].ind);
00259               ba.add_node(pointn);
00260 
00261               Depthmono_Factor* depthmonoFactorn = new Depthmono_Factor(poses[i], pointn, &camera,
00262                                                    DepthmonoMeasurement(dpPointer->points[j].u,
00263                                                    dpPointer->points[j].v, dpPointer->points[j].depth),
00264                                                    noise1);
00265               depthmonoFactors.push_back(depthmonoFactorn);
00266               ba.add_factor(depthmonoFactorn);
00267             }
00268           }
00269         } else if (i == keyframeNum - 1) {
00270           pcl::PointCloud<DepthPoint>::Ptr dpPointerLast = depthPoints[i - 1];
00271           int kfptNumLast = dpPointerLast->points.size();
00272 
00273           int ptCountLast = 2;
00274           int ptRecCount = 0;
00275           for (int j = 2; j < kfptNum; j++) {
00276             bool ptFound = false;
00277             for (; ptCountLast < kfptNumLast; ptCountLast++) {
00278               if (dpPointerLast->points[ptCountLast].ind == dpPointer->points[j].ind) {
00279                 ptFound = true;
00280               }
00281               if (dpPointerLast->points[ptCountLast].ind >= dpPointer->points[j].ind) {
00282                 break;
00283               }
00284             }
00285 
00286             if (ptFound /*&& dpPointer->points[j].label == 1*/) {
00287               bool prFound = false;
00288               for (; ptRecCount < ptRecNum; ptRecCount++) {
00289                 if (pointsInd[ptRecCount] == dpPointer->points[j].ind) {
00290                   prFound = true;
00291                 }
00292                 if (pointsInd[ptRecCount] >= dpPointer->points[j].ind) {
00293                   break;
00294                 }
00295               }
00296 
00297               Point3d_Node* pointn;
00298               Depthmono_Factor* depthmonoFactorn;
00299               if (prFound) {
00300                 pointn = points[ptRecCount];
00301 
00302                 depthmonoFactorn = new Depthmono_Factor(poses[i], pointn, &camera,
00303                                    DepthmonoMeasurement(dpPointer->points[j].u,
00304                                    dpPointer->points[j].v, dpPointer->points[j].depth), noise0);
00305                 //continue;
00306               } else {
00307                 pointn = new Point3d_Node();
00308                 points.push_back(pointn);
00309                 pointsInd.push_back(dpPointer->points[j].ind);
00310                 ba.add_node(pointn);
00311 
00312                 depthmonoFactorn = new Depthmono_Factor(poses[i], pointn, &camera,
00313                                    DepthmonoMeasurement(dpPointer->points[j].u,
00314                                    dpPointer->points[j].v, dpPointer->points[j].depth), noise1);
00315               }
00316 
00317               depthmonoFactors.push_back(depthmonoFactorn);
00318               ba.add_factor(depthmonoFactorn);
00319             }
00320           }
00321         } else {
00322           pcl::PointCloud<DepthPoint>::Ptr dpPointerNext = depthPoints[i + 1];
00323           pcl::PointCloud<DepthPoint>::Ptr dpPointerLast = depthPoints[i - 1];
00324           int kfptNumNext = dpPointerNext->points.size();
00325           int kfptNumLast = dpPointerLast->points.size();
00326 
00327           int ptCountNext = 2;
00328           int ptCountLast = 2;
00329           int ptRecCount = 0;
00330           for (int j = 2; j < kfptNum; j++) {
00331             bool ptFound = false;
00332             for (; ptCountNext < kfptNumNext; ptCountNext++) {
00333               if (dpPointerNext->points[ptCountNext].ind == dpPointer->points[j].ind) {
00334                 ptFound = true;
00335               }
00336               if (dpPointerNext->points[ptCountNext].ind >= dpPointer->points[j].ind) {
00337                 break;
00338               }
00339             }
00340 
00341             if (!ptFound) {
00342               for (; ptCountLast < kfptNumLast; ptCountLast++) {
00343                 if (dpPointerLast->points[ptCountLast].ind == dpPointer->points[j].ind) {
00344                   ptFound = true;
00345                 }
00346                 if (dpPointerLast->points[ptCountLast].ind >= dpPointer->points[j].ind) {
00347                   break;
00348                 }
00349               }
00350             }
00351 
00352             if (ptFound /*&& dpPointer->points[j].label == 1*/) {
00353               bool prFound = false;
00354               for (; ptRecCount < ptRecNum; ptRecCount++) {
00355                 if (pointsInd[ptRecCount] == dpPointer->points[j].ind) {
00356                   prFound = true;
00357                 }
00358                 if (pointsInd[ptRecCount] >= dpPointer->points[j].ind) {
00359                     break;
00360                 }
00361               }
00362 
00363               Point3d_Node* pointn;
00364               Depthmono_Factor* depthmonoFactorn;
00365               if (prFound) {
00366                 pointn = points[ptRecCount];
00367 
00368                 depthmonoFactorn = new Depthmono_Factor(poses[i], pointn, &camera,
00369                                    DepthmonoMeasurement(dpPointer->points[j].u,
00370                                    dpPointer->points[j].v, dpPointer->points[j].depth), noise0);
00371                 //continue;
00372               } else {
00373                 pointn = new Point3d_Node();
00374                 points.push_back(pointn);
00375                 pointsInd.push_back(dpPointer->points[j].ind);
00376                 ba.add_node(pointn);
00377 
00378                 depthmonoFactorn = new Depthmono_Factor(poses[i], pointn, &camera,
00379                                    DepthmonoMeasurement(dpPointer->points[j].u,
00380                                    dpPointer->points[j].v, dpPointer->points[j].depth), noise1);
00381               }
00382 
00383               depthmonoFactors.push_back(depthmonoFactorn);
00384               ba.add_factor(depthmonoFactorn);
00385             }
00386           }
00387         }
00388       }
00389 
00390       Properties prop = ba.properties();
00391       prop.method = DOG_LEG;
00392       ba.set_properties(prop);
00393       //ba.set_cost_function(robust_cost_function);
00394       ba.batch_optimization();
00395 
00396       transformBefBA[0] = depthPoints[keyframeNum - 1]->points[0].u;
00397       transformBefBA[1] = depthPoints[keyframeNum - 1]->points[0].v;
00398       transformBefBA[2] = depthPoints[keyframeNum - 1]->points[0].depth;
00399       transformBefBA[3] = depthPoints[keyframeNum - 1]->points[1].u;
00400       transformBefBA[4] = depthPoints[keyframeNum - 1]->points[1].v;
00401       transformBefBA[5] = depthPoints[keyframeNum - 1]->points[1].depth;
00402 
00403       transformAftBA[0] = poses[keyframeNum - 1]->value().pitch();
00404       transformAftBA[1] = poses[keyframeNum - 1]->value().yaw();
00405       transformAftBA[2] = poses[keyframeNum - 1]->value().roll();
00406       transformAftBA[3] = poses[keyframeNum - 1]->value().y();
00407       transformAftBA[4] = poses[keyframeNum - 1]->value().z();
00408       transformAftBA[5] = poses[keyframeNum - 1]->value().x();
00409 
00410       transformAftBA[0] = (1 - 0.5) * transformAftBA[0] + 0.5 * transformBefBA[0];
00411       //transformAftBA[1] = (1 - 0.1) * transformAftBA[1] + 0.1 * transformBefBA[1];
00412       transformAftBA[2] = (1 - 0.5) * transformAftBA[2] + 0.5 * transformBefBA[2];
00413 
00414       int posesNum = poses.size();
00415       for (int i = 1; i < posesNum; i++) {
00416         delete poses[i];
00417       }
00418       poses.clear();
00419 
00420       delete poseFactors0;
00421 
00422       int posePoseFactorsNum = posePoseFactors.size();
00423       for (int i = 1; i < posePoseFactorsNum; i++) {
00424         delete posePoseFactors[i];
00425       }
00426       posePoseFactors.clear();
00427 
00428       int pointsNum = points.size();
00429       for (int i = 1; i < pointsNum; i++) {
00430         delete points[i];
00431       }
00432       points.clear();
00433 
00434       int depthmonoFactorsNum = depthmonoFactors.size();
00435       for (int i = 1; i < depthmonoFactorsNum; i++) {
00436         delete depthmonoFactors[i];
00437       }
00438       depthmonoFactors.clear();
00439 
00440       geometry_msgs::Quaternion geoQuat = tf::createQuaternionMsgFromRollPitchYaw
00441                                 (transformBefBA[2], -transformBefBA[0], -transformBefBA[1]);
00442 
00443       nav_msgs::Odometry odomBefBA;
00444       odomBefBA.header.frame_id = "/camera_init";
00445       odomBefBA.child_frame_id = "/bef_ba";
00446       odomBefBA.header.stamp = ros::Time().fromSec(depthPointsTime);
00447       odomBefBA.pose.pose.orientation.x = -geoQuat.y;
00448       odomBefBA.pose.pose.orientation.y = -geoQuat.z;
00449       odomBefBA.pose.pose.orientation.z = geoQuat.x;
00450       odomBefBA.pose.pose.orientation.w = geoQuat.w;
00451       odomBefBA.pose.pose.position.x = transformBefBA[3];
00452       odomBefBA.pose.pose.position.y = transformBefBA[4];
00453       odomBefBA.pose.pose.position.z = transformBefBA[5];
00454       odomBefBAPub.publish(odomBefBA);
00455 
00456       geoQuat = tf::createQuaternionMsgFromRollPitchYaw
00457                 (transformAftBA[2], -transformAftBA[0], -transformAftBA[1]);
00458 
00459       nav_msgs::Odometry odomAftBA;
00460       odomAftBA.header.frame_id = "/camera_init";
00461       odomAftBA.child_frame_id = "/aft_ba";
00462       odomAftBA.header.stamp = ros::Time().fromSec(depthPointsTime);
00463       odomAftBA.pose.pose.orientation.x = -geoQuat.y;
00464       odomAftBA.pose.pose.orientation.y = -geoQuat.z;
00465       odomAftBA.pose.pose.orientation.z = geoQuat.x;
00466       odomAftBA.pose.pose.orientation.w = geoQuat.w;
00467       odomAftBA.pose.pose.position.x = transformAftBA[3];
00468       odomAftBA.pose.pose.position.y = transformAftBA[4];
00469       odomAftBA.pose.pose.position.z = transformAftBA[5];
00470       odomAftBAPub.publish(odomAftBA);
00471 
00472       tf::StampedTransform tfAftBA;
00473       tfAftBA.frame_id_ = "/camera_init";
00474       tfAftBA.child_frame_id_ = "/aft_ba";
00475       tfAftBA.stamp_ = ros::Time().fromSec(depthPointsTime);
00476       tfAftBA.setRotation(tf::Quaternion(-geoQuat.y, -geoQuat.z, geoQuat.x, geoQuat.w));
00477       tfAftBA.setOrigin(tf::Vector3(transformAftBA[3], 
00478                             transformAftBA[4], transformAftBA[5]));
00479       tfBroadcaster.sendTransform(tfAftBA);
00480     }
00481 
00482     status = ros::ok();
00483     cvWaitKey(10);
00484   }
00485 
00486   return 0;
00487 }


demo_rgbd
Author(s): Ji Zhang
autogenerated on Mon Jan 6 2014 11:16:08