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
00144 Noise noise1 = Information(dpNoise);
00145
00146 MatrixXd ssNoise = 10000. * eye(6);
00147
00148
00149
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 ) {
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
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 ) {
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
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
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
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 }