00001
00002
00003
00004
00005
00006
00007
00008 #include "hogman_minimal/graph_optimizer_hogman/graph_optimizer3d_chol.h"
00009 #include <sstream>
00010
00011 #include "hogman_wrapper.h"
00012 #include "structs.h"
00013 #include "utils.h"
00014 #include "geometry_msgs/Pose.h"
00015 #include "articulation_models/utils.h"
00016
00017 using namespace AISNavigation;
00018 using namespace geometry_msgs;
00019 using namespace articulation_models;
00020
00021 void add_vertex(GraphOptimizer3D* optimizer, int id, btTransform pose) {
00022 Vector6 p;
00023 double roll, pitch, yaw;
00024 MAT_to_RPY(pose.getBasis(), roll, pitch, yaw);
00025 p[0] = pose.getOrigin().x();
00026 p[1] = pose.getOrigin().y();
00027 p[2] = pose.getOrigin().z();
00028 p[3] = roll;
00029 p[4] = pitch;
00030 p[5] = yaw;
00031 Transformation3 t = Transformation3::fromVector(p);
00032 Matrix6 identity = Matrix6::eye(1.0);
00033 GraphOptimizer3D::Vertex* v = optimizer->addVertex(id, t, identity);
00034 if (!v) {
00035 cerr << "adding vertex id=" << id << "failed" << endl;
00036 }
00037 }
00038
00039 void add_edge(GraphOptimizer3D* optimizer, int id1, int id2, btTransform pose,
00040 double sigma_position, double sigma_orientation) {
00041 Vector6 p;
00042 double roll, pitch, yaw;
00043 MAT_to_RPY(pose.getBasis(), roll, pitch, yaw);
00044 p[0] = pose.getOrigin().x();
00045 p[1] = pose.getOrigin().y();
00046 p[2] = pose.getOrigin().z();
00047 p[3] = roll;
00048 p[4] = pitch;
00049 p[5] = yaw;
00050
00051 Matrix6 m = Matrix6::eye(1.0);
00052 double ip = 1 / SQR(sigma_position);
00053 double io = 1 / SQR(sigma_orientation);
00054 m[0][0] = ip;
00055 m[1][1] = ip;
00056 m[2][2] = ip;
00057 m[3][3] = io;
00058 m[4][4] = io;
00059 m[5][5] = io;
00060 GraphOptimizer3D::Vertex* v1 = optimizer->vertex(id1);
00061 GraphOptimizer3D::Vertex* v2 = optimizer->vertex(id2);
00062 if (!v1) {
00063 cerr << "adding edge, id1=" << id1 << " not found" << endl;
00064 }
00065 if (!v2) {
00066 cerr << "adding edge, id2=" << id2 << " not found" << endl;
00067 }
00068 Transformation3 t = Transformation3::fromVector(p);
00069 GraphOptimizer3D::Edge* e = optimizer->addEdge(v1, v2, t, m);
00070 if (!e) {
00071 cerr << "adding edge failed" << endl;
00072 }
00073 }
00074
00075 PoseMap hogman_solver(KinematicGraphType &graph, PoseIndex &poseIndex,
00076 PoseMap &observed, PoseMap &predictedEmpty, double sigma_position, double sigma_orientation,
00077 double timestamp) {
00078 bool visualize = false;
00079 bool verbose = false;
00080 bool guess = 0;
00081 int iterations = 10;
00082
00083 GraphOptimizer3D* optimizer = new CholOptimizer3D();
00084
00085 optimizer->verbose() = verbose;
00086 optimizer->visualizeToStdout() = visualize;
00087 optimizer->guessOnEdges() = guess;
00088
00089 optimizer->clear();
00090
00091
00092 btTransform root = poseToTransform(observed.begin()->second);
00093
00094 int n=1000;
00095
00096
00097 for (PoseMap::iterator it = predictedEmpty.begin(); it != predictedEmpty.end(); it++) {
00098 btTransform m = poseToTransform(it->second);
00099 add_vertex(optimizer, it->first, root.inverseTimes(m));
00100 }
00101
00102
00103 for (PoseMap::iterator it = observed.begin(); it != observed.end(); it++) {
00104 btTransform m = poseToTransform(it->second);
00105 add_vertex(optimizer, it->first + n, root.inverseTimes(m));
00106 }
00107
00108 for (KinematicGraphType::iterator it = graph.begin(); it != graph.end(); it++) {
00109 int idx = poseIndex[it->first.first][it->first.second][timestamp];
00110 Pose& pose_pred = it->second->model.track.pose_projected[idx];
00111
00112 ROS_ASSERT(!(isnan(pose_pred.position.x) || isnan(pose_pred.position.y) || isnan(pose_pred.position.z) ||
00113 isnan(pose_pred.orientation.x) || isnan(pose_pred.orientation.y) || isnan(pose_pred.orientation.z)|| isnan(pose_pred.orientation.w)));
00114 add_edge(optimizer, it->first.first, it->first.second, poseToTransform(
00115 pose_pred), sigma_position, sigma_orientation);
00116 }
00117
00118
00119 for (PoseMap::iterator it = observed.begin(); it != observed.end(); it++) {
00120 if (it == observed.begin())
00121 it++;
00122
00123 btTransform m = poseToTransform(observed.begin()->second).inverseTimes(
00124 poseToTransform(it->second));
00125 add_edge(optimizer, observed.begin()->first + n,
00126 it->first + n, m, sigma_position / 100,
00127 sigma_orientation / 100);
00128 }
00129
00130
00131 for (PoseMap::iterator it = observed.begin(); it != observed.end(); it++) {
00132
00133 btTransform m = btTransform::getIdentity();
00134 add_edge(optimizer, it->first, it->first + n, m,
00135 sigma_position * 100, sigma_orientation * 100);
00136 }
00137
00138 optimizer->initialize(0);
00139 optimizer->optimize(iterations, false);
00140
00141 PoseMap predictedMarkers;
00142 GraphOptimizer3D::VertexIDMap &vertices = optimizer->vertices();
00143 for (PoseMap::iterator it = predictedEmpty.begin(); it
00144 != predictedEmpty.end(); it++) {
00145 const PoseGraph3D::Vertex* v;
00146 v= reinterpret_cast<const PoseGraph3D::Vertex*>(vertices[it->first]);
00147 if (v == 0) {
00148 cerr << "VERTEX not found!!" << endl;
00149 }
00150 Transformation3 t = v->transformation;
00151 Vector6 p = t.toVector();
00152 btTransform d = btTransform(RPY_to_MAT(p[3], p[4], p[5]), btVector3(
00153 p[0], p[1], p[2]));
00154 predictedMarkers[it->first] = transformToPose(root * d);
00155 }
00156
00157 const PoseGraph3D::Vertex* v = reinterpret_cast<const PoseGraph3D::Vertex*>(vertices[observed.begin()->first + n]);
00158 Transformation3 t = v->transformation;
00159 Vector6 p = t.toVector();
00160 btTransform d = btTransform(RPY_to_MAT(p[3], p[4], p[5]), btVector3(p[0],
00161 p[1], p[2]));
00162 for (PoseMap::iterator it = predictedMarkers.begin(); it
00163 != predictedMarkers.end(); it++) {
00164
00165 it->second = transformToPose(root * d.inverseTimes(root.inverseTimes(
00166 poseToTransform(it->second))));
00167 }
00168
00169 delete optimizer;
00170
00171 return predictedMarkers;
00172 }
00173