g2o
types_six_dof_expmap.cpp
Go to the documentation of this file.
1 // g2o - General Graph Optimization
2 // Copyright (C) 2011 H. Strasdat
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include "types_six_dof_expmap.h"
28 
29 #include "g2o/core/factory.h"
30 #include "g2o/stuff/macros.h"
31 
32 namespace g2o {
33 
34 using namespace std;
35 using namespace Eigen;
36 
38 G2O_REGISTER_TYPE(VERTEX_SE3:EXPMAP, VertexSE3Expmap);
39 G2O_REGISTER_TYPE(EDGE_SE3:EXPMAP, EdgeSE3Expmap);
40 G2O_REGISTER_TYPE(EDGE_PROJECT_XYZ2UV:EXPMAP, EdgeProjectXYZ2UV);
41 G2O_REGISTER_TYPE(EDGE_PROJECT_XYZ2UVU:EXPMAP, EdgeProjectXYZ2UVU);
42 G2O_REGISTER_TYPE(PARAMS_CAMERAPARAMETERS, CameraParameters);
43 
46  : focal_length(1.),
47  principle_point(Vector2D(0., 0.)),
48  baseline(0.5) {
49 }
50 
52  Vector2D res;
53  res(0) = v(0)/v(2);
54  res(1) = v(1)/v(2);
55  return res;
56 }
57 
59  Vector3D res;
60  res(0) = v(0);
61  res(1) = v(1);
62  res(2) = 1;
63  return res;
64 }
65 
66 inline Vector3D invert_depth(const Vector3D & x){
67  return unproject2d(x.head<2>())/x[2];
68 }
69 
70 Vector2D CameraParameters::cam_map(const Vector3D & trans_xyz) const {
71  Vector2D proj = project2d(trans_xyz);
72  Vector2D res;
73  res[0] = proj[0]*focal_length + principle_point[0];
74  res[1] = proj[1]*focal_length + principle_point[1];
75  return res;
76 }
77 
79  Vector2D uv_left = cam_map(trans_xyz);
80  double proj_x_right = (trans_xyz[0]-baseline)/trans_xyz[2];
81  double u_right = proj_x_right*focal_length + principle_point[0];
82  return Vector3D(uv_left[0],uv_left[1],u_right);
83 }
84 
85 
87 }
88 
89 bool VertexSE3Expmap::read(std::istream& is) {
90  Vector7d est;
91  for (int i=0; i<7; i++)
92  is >> est[i];
93  SE3Quat cam2world;
94  cam2world.fromVector(est);
95  setEstimate(cam2world.inverse());
96  return true;
97 }
98 
99 bool VertexSE3Expmap::write(std::ostream& os) const {
100  SE3Quat cam2world(estimate().inverse());
101  for (int i=0; i<7; i++)
102  os << cam2world[i] << " ";
103  return os.good();
104 }
105 
108 }
109 
110 bool EdgeSE3Expmap::read(std::istream& is) {
111  Vector7d meas;
112  for (int i=0; i<7; i++)
113  is >> meas[i];
114  SE3Quat cam2world;
115  cam2world.fromVector(meas);
116  setMeasurement(cam2world.inverse());
117  //TODO: Convert information matrix!!
118  for (int i=0; i<6; i++)
119  for (int j=i; j<6; j++) {
120  is >> information()(i,j);
121  if (i!=j)
122  information()(j,i)=information()(i,j);
123  }
124  return true;
125 }
126 
127 bool EdgeSE3Expmap::write(std::ostream& os) const {
128  SE3Quat cam2world(measurement().inverse());
129  for (int i=0; i<7; i++)
130  os << cam2world[i] << " ";
131  for (int i=0; i<6; i++)
132  for (int j=i; j<6; j++){
133  os << " " << information()(i,j);
134  }
135  return os.good();
136 }
137 
139  _cam = 0;
140  resizeParameters(1);
142 }
143 
144 bool EdgeProjectPSI2UV::write(std::ostream& os) const {
145  os << _cam->id() << " ";
146  for (int i=0; i<2; i++){
147  os << measurement()[i] << " ";
148  }
149 
150  for (int i=0; i<2; i++)
151  for (int j=i; j<2; j++){
152  os << " " << information()(i,j);
153  }
154  return os.good();
155 }
156 
157 bool EdgeProjectPSI2UV::read(std::istream& is) {
158  int paramId;
159  is >> paramId;
160  setParameterId(0, paramId);
161 
162  for (int i=0; i<2; i++){
163  is >> _measurement[i];
164  }
165  for (int i=0; i<2; i++)
166  for (int j=i; j<2; j++) {
167  is >> information()(i,j);
168  if (i!=j)
169  information()(j,i)=information()(i,j);
170  }
171  return true;
172 }
173 
175  const VertexSBAPointXYZ * psi = static_cast<const VertexSBAPointXYZ*>(_vertices[0]);
176  const VertexSE3Expmap * T_p_from_world = static_cast<const VertexSE3Expmap*>(_vertices[1]);
177  const VertexSE3Expmap * T_anchor_from_world = static_cast<const VertexSE3Expmap*>(_vertices[2]);
178  const CameraParameters * cam = static_cast<const CameraParameters *>(parameter(0));
179 
180  Vector2D obs(_measurement);
181  _error = obs - cam->cam_map(T_p_from_world->estimate()
182  *T_anchor_from_world->estimate().inverse()
183  *invert_depth(psi->estimate()));
184 }
185 
186 inline Matrix<double,2,3,Eigen::ColMajor> d_proj_d_y(const double & f, const Vector3D & xyz){
187  double z_sq = xyz[2]*xyz[2];
188  Matrix<double,2,3,Eigen::ColMajor> J;
189  J << f/xyz[2], 0, -(f*xyz[0])/z_sq,
190  0, f/xyz[2], -(f*xyz[1])/z_sq;
191  return J;
192 }
193 
194 inline Matrix<double,3,6,Eigen::ColMajor> d_expy_d_y(const Vector3D & y){
195  Matrix<double,3,6,Eigen::ColMajor> J;
196  J.topLeftCorner<3,3>() = -skew(y);
197  J.bottomRightCorner<3,3>().setIdentity();
198 
199  return J;
200 }
201 
202 inline Matrix3D d_Tinvpsi_d_psi(const SE3Quat & T, const Vector3D & psi){
203  Matrix3D R = T.rotation().toRotationMatrix();
204  Vector3D x = invert_depth(psi);
205  Vector3D r1 = R.col(0);
206  Vector3D r2 = R.col(1);
207  Matrix3D J;
208  J.col(0) = r1;
209  J.col(1) = r2;
210  J.col(2) = -R*x;
211  J*=1./psi.z();
212  return J;
213 }
214 
216  VertexSBAPointXYZ* vpoint = static_cast<VertexSBAPointXYZ*>(_vertices[0]);
217  Vector3D psi_a = vpoint->estimate();
218  VertexSE3Expmap * vpose = static_cast<VertexSE3Expmap *>(_vertices[1]);
219  SE3Quat T_cw = vpose->estimate();
220  VertexSE3Expmap * vanchor = static_cast<VertexSE3Expmap *>(_vertices[2]);
221  const CameraParameters * cam
222  = static_cast<const CameraParameters *>(parameter(0));
223 
224  SE3Quat A_aw = vanchor->estimate();
225  SE3Quat T_ca = T_cw*A_aw.inverse();
226  Vector3D x_a = invert_depth(psi_a);
227  Vector3D y = T_ca*x_a;
228  Matrix<double,2,3,Eigen::ColMajor> Jcam
229  = d_proj_d_y(cam->focal_length, y);
230  _jacobianOplus[0] = -Jcam*d_Tinvpsi_d_psi(T_ca, psi_a);
231  _jacobianOplus[1] = -Jcam*d_expy_d_y(y);
232  _jacobianOplus[2] = Jcam*T_ca.rotation().toRotationMatrix()*d_expy_d_y(x_a);
233 }
234 
235 
236 
238 {
239  _cam = 0;
240  resizeParameters(1);
242 }
243 
244 bool EdgeProjectXYZ2UV::read(std::istream& is){
245  int paramId;
246  is >> paramId;
247  setParameterId(0, paramId);
248 
249  for (int i=0; i<2; i++){
250  is >> _measurement[i];
251  }
252  for (int i=0; i<2; i++)
253  for (int j=i; j<2; j++) {
254  is >> information()(i,j);
255  if (i!=j)
256  information()(j,i)=information()(i,j);
257  }
258  return true;
259 }
260 
261 bool EdgeProjectXYZ2UV::write(std::ostream& os) const {
262  os << _cam->id() << " ";
263  for (int i=0; i<2; i++){
264  os << measurement()[i] << " ";
265  }
266 
267  for (int i=0; i<2; i++)
268  for (int j=i; j<2; j++){
269  os << " " << information()(i,j);
270  }
271  return os.good();
272 }
273 
275  VertexSE3Expmap * vi = static_cast<VertexSE3Expmap *>(_vertices[0]);
276  SE3Quat Ti(vi->estimate());
277 
278  VertexSE3Expmap * vj = static_cast<VertexSE3Expmap *>(_vertices[1]);
279  SE3Quat Tj(vj->estimate());
280 
281  const SE3Quat & Tij = _measurement;
282  SE3Quat invTij = Tij.inverse();
283 
284  SE3Quat invTj_Tij = Tj.inverse()*Tij;
285  SE3Quat infTi_invTij = Ti.inverse()*invTij;
286 
287  _jacobianOplusXi = invTj_Tij.adj();
288  _jacobianOplusXj = -infTi_invTij.adj();
289 }
290 
292  VertexSE3Expmap * vj = static_cast<VertexSE3Expmap *>(_vertices[1]);
293  SE3Quat T(vj->estimate());
294  VertexSBAPointXYZ* vi = static_cast<VertexSBAPointXYZ*>(_vertices[0]);
295  Vector3D xyz = vi->estimate();
296  Vector3D xyz_trans = T.map(xyz);
297 
298  double x = xyz_trans[0];
299  double y = xyz_trans[1];
300  double z = xyz_trans[2];
301  double z_2 = z*z;
302 
303  const CameraParameters * cam = static_cast<const CameraParameters *>(parameter(0));
304 
305  Matrix<double,2,3,Eigen::ColMajor> tmp;
306  tmp(0,0) = cam->focal_length;
307  tmp(0,1) = 0;
308  tmp(0,2) = -x/z*cam->focal_length;
309 
310  tmp(1,0) = 0;
311  tmp(1,1) = cam->focal_length;
312  tmp(1,2) = -y/z*cam->focal_length;
313 
314  _jacobianOplusXi = -1./z * tmp * T.rotation().toRotationMatrix();
315 
316  _jacobianOplusXj(0,0) = x*y/z_2 *cam->focal_length;
317  _jacobianOplusXj(0,1) = -(1+(x*x/z_2)) *cam->focal_length;
318  _jacobianOplusXj(0,2) = y/z *cam->focal_length;
319  _jacobianOplusXj(0,3) = -1./z *cam->focal_length;
320  _jacobianOplusXj(0,4) = 0;
321  _jacobianOplusXj(0,5) = x/z_2 *cam->focal_length;
322 
323  _jacobianOplusXj(1,0) = (1+y*y/z_2) *cam->focal_length;
324  _jacobianOplusXj(1,1) = -x*y/z_2 *cam->focal_length;
325  _jacobianOplusXj(1,2) = -x/z *cam->focal_length;
326  _jacobianOplusXj(1,3) = 0;
327  _jacobianOplusXj(1,4) = -1./z *cam->focal_length;
328  _jacobianOplusXj(1,5) = y/z_2 *cam->focal_length;
329 }
330 
331 bool EdgeProjectXYZ2UVU::read(std::istream& is){
332  for (int i=0; i<3; i++){
333  is >> _measurement[i];
334  }
335  for (int i=0; i<3; i++)
336  for (int j=i; j<3; j++) {
337  is >> information()(i,j);
338  if (i!=j)
339  information()(j,i)=information()(i,j);
340  }
341  return true;
342 }
343 
344 bool EdgeProjectXYZ2UVU::write(std::ostream& os) const {
345  for (int i=0; i<3; i++){
346  os << measurement()[i] << " ";
347  }
348 
349  for (int i=0; i<3; i++)
350  for (int j=i; j<3; j++){
351  os << " " << information()(i,j);
352  }
353  return os.good();
354 }
355 
356 } // end namespace
Eigen::Matrix< double, 2, 1, Eigen::ColMajor > Vector2D
Definition: eigen_types.h:45
bool installParameter(ParameterType *&p, size_t argNo, int paramId=-1)
G2O_REGISTER_TYPE(VERTEX_TAG, VertexTag)
Vector2D cam_map(const Vector3D &trans_xyz) const
Eigen::Matrix< double, 3, 1, Eigen::ColMajor > Vector3D
Definition: eigen_types.h:46
bool write(std::ostream &os) const
write the vertex to a stream
bool read(std::istream &is)
read the vertex from a stream, i.e., the internal state of the vertex
Templatized BaseVertex.
Definition: base_vertex.h:50
virtual void setMeasurement(const Measurement &m)
Definition: base_edge.h:76
Eigen::Matrix< double, 7, 1 > Vector7d
Definition: sim3.h:35
Eigen::Matrix< double, 6, 6, Eigen::ColMajor > adj() const
Definition: se3quat.h:256
SE3Quat inverse() const
Definition: se3quat.h:120
Point vertex, XYZ.
Definition: types_sba.h:137
EIGEN_MAKE_ALIGNED_OPERATOR_NEW VertexSE3Expmap()
SE3 Vertex parameterized internally with a transformation matrix and externally with its exponential ...
bool write(std::ostream &os) const
write the vertex to a stream
bool setParameterId(int argNum, int paramId)
Vector3D invert_depth(const Vector3D &x)
virtual bool write(std::ostream &os) const
write the vertex to a stream
bool read(std::istream &is)
read the vertex from a stream, i.e., the internal state of the vertex
bool read(std::istream &is)
read the vertex from a stream, i.e., the internal state of the vertex
int id() const
Definition: parameter.h:45
Matrix3D d_Tinvpsi_d_psi(const SE3Quat &T, const Vector3D &psi)
Vector3D stereocam_uvu_map(const Vector3D &trans_xyz) const
void fromVector(const Vector7d &v)
Definition: se3quat.h:147
const Eigen::Quaterniond & rotation() const
Definition: se3quat.h:97
Eigen::Matrix< double, 3, 3, Eigen::ColMajor > Matrix3D
Definition: eigen_types.h:61
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
Definition: base_vertex.h:101
const Parameter * parameter(int argNo) const
Vector3D unproject2d(const Vector2D &v)
Matrix< double, 3, 6, Eigen::ColMajor > d_expy_d_y(const Vector3D &y)
void resizeParameters(size_t newSize)
EIGEN_STRONG_INLINE const InformationType & information() const
information matrix of the constraint
Definition: base_edge.h:67
G2O_REGISTER_TYPE_GROUP(data)
const EstimateType & estimate() const
return the current estimate of the vertex
Definition: base_vertex.h:99
bool write(std::ostream &os) const
write the vertex to a stream
Matrix< double, 2, 3, Eigen::ColMajor > d_proj_d_y(const double &f, const Vector3D &xyz)
virtual bool read(std::istream &is)
read the vertex from a stream, i.e., the internal state of the vertex
G2O_TYPES_SLAM3D_API Matrix3D skew(const Vector3D &v)
Definition: se3_ops.h:28
EIGEN_STRONG_INLINE const Measurement & measurement() const
accessor functions for the measurement represented by the edge
Definition: base_edge.h:75
bool read(std::istream &is)
read the vertex from a stream, i.e., the internal state of the vertex
bool write(std::ostream &os) const
write the vertex to a stream
Vector2D project2d(const Vector3D &v)
VertexContainer _vertices
Definition: hyper_graph.h:202