Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
V
vision
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
mobile_robotics
wolf_projects
wolf_lib
plugins
vision
Commits
61617f8c
Commit
61617f8c
authored
3 years ago
by
Mederic Fourmy
Browse files
Options
Downloads
Patches
Plain Diff
[skip-ci] Implement new triangulation
parent
8cd162f0
No related branches found
Branches containing commit
No related tags found
1 merge request
!38
Draft: Resolve "Improve visual odometry"
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/vision/processor/processor_visual_odometry.h
+4
-1
4 additions, 1 deletion
include/vision/processor/processor_visual_odometry.h
src/processor/processor_visual_odometry.cpp
+101
-3
101 additions, 3 deletions
src/processor/processor_visual_odometry.cpp
with
105 additions
and
4 deletions
include/vision/processor/processor_visual_odometry.h
+
4
−
1
View file @
61617f8c
...
...
@@ -258,12 +258,15 @@ class ProcessorVisualOdometry : public ProcessorTracker
/**
* \brief Emplace a landmark corresponding to a track and initialize it with triangulation.
* \param _feature_ptr a pointer to the feature used to create the new landmark
* \param _track_kf track with only features associated to keyframes that maye be used for initialisation
* \return a pointer to the created landmark. If null, the triangulation failed due to low parallax
*
* Implementation: try to triangulate a new landmark based on previous frames estimates.
* Apply a numerical test to asses if parallax is enough.
*/
LandmarkBasePtr
emplaceLandmarkTriangulation
(
FeatureBasePtr
_feature_ptr
);
LandmarkBasePtr
emplaceLandmarkTriangulation
(
FeatureBasePtr
_feature_ptr
,
Track
_track_kf
);
Eigen
::
Isometry3d
getTcw
(
TimeStamp
_ts
)
const
;
/** \brief Advance the incoming Capture to become the last.
*
...
...
This diff is collapsed.
Click to expand it.
src/processor/processor_visual_odometry.cpp
+
101
−
3
View file @
61617f8c
...
...
@@ -25,6 +25,8 @@
#include
"vision/processor/processor_visual_odometry.h"
#include
<opencv2/imgproc.hpp>
#include
<opencv2/calib3d.hpp>
#include
<opencv2/core/eigen.hpp>
#include
<chrono>
#include
<ctime>
...
...
@@ -345,11 +347,19 @@ void ProcessorVisualOdometry::establishFactors()
else
if
(
track_matrix_
.
trackSize
(
feat
->
trackId
())
>=
params_visual_odometry_
->
min_track_length_for_landmark
)
{
WOLF_INFO
(
" NEW valid track
\\
o/"
)
LandmarkBasePtr
lmk
=
emplaceLandmarkNaive
(
feat_pi
);
lmk
->
setId
(
feat_pi
->
trackId
());
Track
track_kf
=
track_matrix_
.
trackAtKeyframes
(
feat
->
trackId
());
LandmarkBasePtr
lmk
=
emplaceLandmarkTriangulation
(
feat_pi
,
track_kf
);
if
(
lmk
==
nullptr
){
continue
;
}
// Add factors from all KFs of this track to the new lmk
Track
track_kf
=
track_matrix_
.
trackAtKeyframes
(
feat
->
trackId
());
WOLF_INFO
(
"
\n\n
HEY"
)
WOLF_INFO
(
feat_pi
->
getFrame
()
->
getStateVector
().
transpose
())
WOLF_INFO
(
lmk
->
getStateVector
().
transpose
())
WOLF_INFO
(
getSensor
()
->
getStateVector
().
transpose
())
for
(
auto
feat_kf
:
track_kf
)
{
LandmarkHpPtr
lmk_hp
=
std
::
dynamic_pointer_cast
<
LandmarkHp
>
(
lmk
);
...
...
@@ -364,6 +374,76 @@ void ProcessorVisualOdometry::establishFactors()
return
;
}
LandmarkBasePtr
ProcessorVisualOdometry
::
emplaceLandmarkTriangulation
(
FeatureBasePtr
_feat
,
Track
_track_kf
)
{
// at least 2 KF needed to triangulate
if
(
_track_kf
.
size
()
<
2
)
{
return
nullptr
;
}
// heuristic: use oldest feature/KF to triangulate with respect to current time
FeaturePointImagePtr
feat_pi1
=
std
::
static_pointer_cast
<
FeaturePointImage
>
(
_track_kf
.
begin
()
->
second
);
// Feature at current time
FeaturePointImagePtr
feat_pi2
=
std
::
static_pointer_cast
<
FeaturePointImage
>
(
_feat
);
cv
::
Vec2d
pix1
,
pix2
;
// WOLF_INFO("TOTO")
cv
::
eigen2cv
(
feat_pi1
->
getMeasurement
(),
pix1
);
cv
::
eigen2cv
(
feat_pi2
->
getMeasurement
(),
pix2
);
// WOLF_INFO(pix1, pix2)
// create 3x4 projection matrices [K|0] * Tcw
Matrix4d
Tcw1
=
getTcw
(
feat_pi1
->
getCapture
()
->
getTimeStamp
()).
matrix
();
Matrix4d
Tcw2
=
getTcw
(
feat_pi2
->
getCapture
()
->
getTimeStamp
()).
matrix
();
Eigen
::
Matrix
<
double
,
3
,
4
>
P1
=
sen_cam_
->
getProjectionMatrix
()
*
Tcw1
;
Eigen
::
Matrix
<
double
,
3
,
4
>
P2
=
sen_cam_
->
getProjectionMatrix
()
*
Tcw2
;
cv
::
Mat
P1_cv
,
P2_cv
;
cv
::
eigen2cv
(
P1
,
P1_cv
);
cv
::
eigen2cv
(
P2
,
P2_cv
);
// WOLF_INFO(P1)
// WOLF_INFO(P1_cv)
// perform triangulation of one landmark
cv
::
Vec4d
ptcv_w
;
// output: homogeneous landmark point expressed in world frame
cv
::
triangulatePoints
(
P1_cv
,
P2_cv
,
pix1
,
pix2
,
ptcv_w
);
// WOLF_INFO("YAY: ", ptcv_w)
/////////////////////////////////////////////////////////
// check that triangulation was done with enough parallax
/////////////////////////////////////////////////////////
bool
triangulation_is_a_success
=
true
;
// Not implemented yet
if
(
!
triangulation_is_a_success
)
{
return
nullptr
;
}
// normalize to make equivalent to a unit quaternion
Eigen
::
Vector4d
pt_c
;
cv
::
cv2eigen
(
ptcv_w
,
pt_c
);
// HACK: to avoid "nans" in residal, set Z = 1
pt_c
(
2
)
=
1
*
pt_c
(
3
);
// Normilization necessary since homogeneous point stateblock is supposed to be unitary
pt_c
.
normalize
();
WOLF_INFO
(
"New lmk: "
,
pt_c
.
transpose
())
auto
lmk_hp_ptr
=
LandmarkBase
::
emplace
<
LandmarkHp
>
(
getProblem
()
->
getMap
(),
pt_c
,
feat_pi2
->
getKeyPoint
().
getDescriptor
());
// Set all IDs equal to track ID
size_t
track_id
=
_feat
->
trackId
();
lmk_hp_ptr
->
setId
(
track_id
);
_feat
->
setLandmarkId
(
track_id
);
return
lmk_hp_ptr
;
}
LandmarkBasePtr
ProcessorVisualOdometry
::
emplaceLandmarkNaive
(
FeatureBasePtr
_feat
)
{
// Taken from processor_bundle_adjustment
...
...
@@ -410,6 +490,24 @@ LandmarkBasePtr ProcessorVisualOdometry::emplaceLandmarkNaive(FeatureBasePtr _fe
}
Eigen
::
Isometry3d
ProcessorVisualOdometry
::
getTcw
(
TimeStamp
_ts
)
const
{
// get robot position and orientation at capture's timestamp
const
auto
&
state
=
getProblem
()
->
getState
(
_ts
,
"PO"
);
const
auto
&
pos
=
state
.
at
(
'P'
);
const
auto
&
ori
=
state
.
at
(
'O'
);
// compute world-to-camera transform
Eigen
::
Isometry3d
T_w_r
=
Translation3d
(
pos
)
*
Quaterniond
(
ori
.
data
());
Eigen
::
Isometry3d
T_r_c
=
Translation3d
(
getSensor
()
->
getP
()
->
getState
())
*
Quaterniond
(
getSensor
()
->
getP
()
->
getState
().
data
());
// invert transform to camera-to-world and return
return
(
T_w_r
*
T_r_c
).
inverse
();
}
void
ProcessorVisualOdometry
::
postProcess
()
{
// Delete tracks with no keyframes
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment