Skip to content

Commit 3a8b0bb

Browse files
committed
added node regularization to non changing worlds and fixed the viz issue. although non changing worlds reg seem to solve the problem it adds some computational budget. can fiddle around with that
1 parent 782b3fe commit 3a8b0bb

3 files changed

Lines changed: 66 additions & 33 deletions

File tree

src/PoseGraphSLAM.cpp

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,16 +1361,16 @@ bool PoseGraphSLAM::saveAsJSON(const string base_path)
13611361
#define __reinit_loopedge_cout( msg ) ;
13621362

13631363

1364-
// #define __reint_gueses_short_info(msg) msg;
1365-
#define __reint_gueses_short_info(msg) ;
1364+
#define __reint_gueses_short_info(msg) msg;
1365+
// #define __reint_gueses_short_info(msg) ;
13661366

13671367

13681368
// Print info on node regularization. I use node regularization to set
13691369
// the start of each worlds as constant. You can tune this as need be.
13701370
// The reason I do not use ceres::SetParameterBlockConstant() is that it cannot be
13711371
// set to not constant which hinders when the initial guess moves.
1372-
// #define __reint_node_regularization_info( msg ) msg;
1373-
#define __reint_node_regularization_info( msg ) ;
1372+
#define __reint_node_regularization_info( msg ) msg;
1373+
// #define __reint_node_regularization_info( msg ) ;
13741374

13751375

13761376
// Print Ceres Brief Report and other info on solving
@@ -1410,7 +1410,8 @@ void PoseGraphSLAM::reinit_ceres_problem_onnewloopedge_optimize6DOF()
14101410
// robust_norm = new ceres::CauchyLoss(1.0);
14111411
robust_norm = new ceres::HuberLoss(0.1);
14121412

1413-
std::map< int , std::tuple<int,int> > changes_to_setid_on_set_union; // key:= worldID, value:= (prev setID of this world, new setID of this world).
1413+
//==> key:= worldID, value:= (prev setID of this world, new setID of this world).
1414+
std::map< int , std::tuple<int,int> > changes_to_setid_on_set_union;
14141415
vector<ceres::ResidualBlockId> regularization_terms_list;
14151416

14161417

@@ -1421,10 +1422,15 @@ void PoseGraphSLAM::reinit_ceres_problem_onnewloopedge_optimize6DOF()
14211422
int loopedge_len = manager->getEdgeLen();
14221423

14231424
___trigger_header(
1424-
cout << "---\n";
1425-
cout << "node_len=" << node_len << "\tloopedge_len=" << loopedge_len << "\t\t";
1426-
cout << "prev_node_len=" << prev_node_len << "\tprev_loopedge_len=" << prev_loopedge_len << endl;
1427-
cout << "\tso total_new_loopedges=" << loopedge_len - prev_loopedge_len << endl;
1425+
// cout << "---\n";
1426+
// cout << "node_len=" << node_len << "\tloopedge_len=" << loopedge_len << "\t\t";
1427+
// cout << "prev_node_len=" << prev_node_len << "\tprev_loopedge_len=" << prev_loopedge_len << endl;
1428+
// cout << "\tso total_new_loopedges=" << loopedge_len - prev_loopedge_len << endl;
1429+
1430+
cout << "---";
1431+
cout << "node_len=(" << prev_node_len << " to " << node_len << ")\t";
1432+
cout << "loopedge_len=(" << prev_loopedge_len << " to " << prev_loopedge_len << ")\t";
1433+
cout << endl;
14281434
)
14291435

14301436
//--- If no new loop edges sleep again!
@@ -1841,14 +1847,15 @@ void PoseGraphSLAM::reinit_ceres_problem_onnewloopedge_optimize6DOF()
18411847

18421848

18431849
}
1844-
changes_to_setid_on_set_union.clear(); //< this is important to clear. When the setID changes (upon union_sets), this map is filled in to indicate the changes. The node initialization uses this to selectively reinitialize old node.
1850+
18451851
___trigger_header( cout << "\n[ETA initial_guesses] done in milli-secs=" << eta.toc_milli() << " node_len="<< node_len << endl; )
18461852

18471853

18481854
//-----------------------------
18491855
// -5- Mark nodes as constant. Possibly also need to mark starts of each worlds as constants. Can also try setting each sets 1st node as constant.
18501856
//------------------------------
18511857
#if 1
1858+
eta.tic();
18521859
for( int v=0 ; v<regularization_terms_list.size() ; v++ ) {
18531860
reint_problem.RemoveResidualBlock( regularization_terms_list[v] );
18541861
__reint_node_regularization_info( cout << "Remove " << v << " th regularization term\n"; )
@@ -1868,10 +1875,10 @@ void PoseGraphSLAM::reinit_ceres_problem_onnewloopedge_optimize6DOF()
18681875
// continue;
18691876
int ww_setid = manager->getWorldsConstPtr()->find_setID_of_world_i(ww);
18701877
int ww_start = manager->nodeidx_of_world_i_started( ww );
1871-
__reint_node_regularization_info( cout << TermColor::CYAN() << "&&&&&&&&&&&&world#" << ww << " is in setID=" << ww_setid << " with ww_start=" << ww_start << TermColor::RESET() << endl; )
1872-
if( (ww_setid >= 0 && ww_setid==ww) ) {
1873-
1874-
1878+
int ww_end = manager->nodeidx_of_world_i_ended( ww );
1879+
__reint_node_regularization_info( cout << TermColor::CYAN() << "&&&&&&&&&&&&world#" << ww << " is in setID=" << ww_setid << " with ww_start=" << ww_start << " ww_end=" << ww_end << TermColor::RESET() << endl; )
1880+
if( (ww_setid >= 0 && ww_setid==ww) )
1881+
{
18751882
__reint_node_regularization_info( cout << "Mark node#" << ww_start << " as constant. \n"; )
18761883
reg_debug_info += "Mark node#" + to_string(ww_start) + " as constant \n";
18771884

@@ -1880,28 +1887,49 @@ void PoseGraphSLAM::reinit_ceres_problem_onnewloopedge_optimize6DOF()
18801887

18811888
// Matrix4d ww_start_pose = manager->getNodePose(ww_start);
18821889
// Functionally similar to marking it as constant
1890+
double regularization_weight = log( 1+ww_end - ww_start )/2.;
1891+
1892+
for( int s=0; s<2 ; s++ )
18831893
{
1884-
Matrix4d ww_start_pose = this->getNodePose(ww_start);
1885-
__reint_node_regularization_info( cout << "ww_start_pose : " << PoseManipUtils::prettyprintMatrix4d( ww_start_pose ) << endl; )
1886-
ceres::CostFunction * regularixa_cost = NodePoseRegularization::Create( ww_start_pose, 1.3 );
1887-
ceres::ResidualBlockId resi_id = reint_problem.AddResidualBlock( regularixa_cost, NULL, get_raw_ptr_to_opt_variable_q(ww_start), get_raw_ptr_to_opt_variable_t(ww_start) );
1894+
__reint_node_regularization_info( cout << "s="<< s << " "; )
1895+
Matrix4d ww_start_pose = this->getNodePose(ww_start+s);
1896+
__reint_node_regularization_info( cout << "regularization_weight=" << regularization_weight << " ww_start_pose : " << PoseManipUtils::prettyprintMatrix4d( ww_start_pose ) << endl; )
1897+
ceres::CostFunction * regularixa_cost = NodePoseRegularization::Create( ww_start_pose, regularization_weight );
1898+
ceres::ResidualBlockId resi_id = reint_problem.AddResidualBlock( regularixa_cost, NULL, get_raw_ptr_to_opt_variable_q(ww_start+s), get_raw_ptr_to_opt_variable_t(ww_start+s) );
18881899
regularization_terms_list.push_back( resi_id );
18891900
}
18901901

18911902

18921903

1893-
18941904
}
18951905
else {
18961906
__reint_node_regularization_info( cout << "skip\n"; )
18971907
}
1908+
1909+
1910+
// check if this world is in change set aka `changes_to_setid_on_set_union`. Add regularization if not in changeset
1911+
if( changes_to_setid_on_set_union.count( ww ) > 0 ) {
1912+
__reint_node_regularization_info( cout << "World#" << ww << " is in `changes_to_setid_on_set_union`. This indicates it was changed.So no regularization needed\n"; )
1913+
}
1914+
else {
1915+
if( ww == manager->n_worlds()-1 ) // dont add regularization for current world
1916+
continue;
1917+
__reint_node_regularization_info( cout << "Add regularization to each node of world#" << ww << endl; )
1918+
for( int q=ww_start ; q<=ww_end ; q++ ) {
1919+
Matrix4d ww_start_pose = this->getNodePose(q);
1920+
ceres::CostFunction * regularixa_cost = NodePoseRegularization::Create( ww_start_pose, 1.0 );
1921+
ceres::ResidualBlockId resi_id = reint_problem.AddResidualBlock( regularixa_cost, NULL, get_raw_ptr_to_opt_variable_q(q), get_raw_ptr_to_opt_variable_t(q) );
1922+
regularization_terms_list.push_back( resi_id );
1923+
}
1924+
}
1925+
18981926
}
1899-
___trigger_header( cout << "Total elements in `regularization_terms_list` = " << regularization_terms_list.size() << endl; )
1927+
___trigger_header( cout << "\n[ETA Total elements in `regularization_terms_list` = " << regularization_terms_list.size() << " done in milli-secs=" << eta.toc_milli() << " node_len="<< node_len << endl; )
19001928
___trigger_header( cout << "Debug Info: " << reg_debug_info << "Done with debug info\n"; )
19011929
#endif
19021930

19031931

1904-
1932+
changes_to_setid_on_set_union.clear(); //< this is important to clear. When the setID changes (upon union_sets), this map is filled in to indicate the changes. The node initialization uses this to selectively reinitialize old node.
19051933

19061934
//-----------------------
19071935
//-6- ceres::Solve()

src/PoseGraphSLAM.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ class SixDOFError
277277
class NodePoseRegularization
278278
{
279279
public:
280-
NodePoseRegularization( const Matrix4d _nodepose, const double _weight = 1.0 ) : nodepose( _nodepose ), weight( _weight )
280+
NodePoseRegularization( const Matrix4d _nodepose, const double _weight ) : nodepose( _nodepose ), weight( _weight )
281281
{
282282

283283
}

src/keyframe_pose_graph_slam_node.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ void periodic_publish_odoms( const NodeDataManager * manager, const VizPoseGraph
7373
{
7474
cout << "Start `periodic_publish`\n";
7575
ros::Rate loop_rate(15);
76-
double offset_x = 30., offset_y=0., offset_z=0.;
77-
// double offset_x = 0., offset_y=0., offset_z=0.;
76+
// double offset_x = 30., offset_y=0., offset_z=0.;
77+
double offset_x = 0., offset_y=0., offset_z=0.;
7878

7979
map<int, vector<Matrix4d> > jmb;
8080
bool published_axis = false;
@@ -108,7 +108,7 @@ void periodic_publish_odoms( const NodeDataManager * manager, const VizPoseGraph
108108

109109
// Publish all the odometries (unregistered) and also plot the loop edges.
110110
// make the follow to 1 if you need this.
111-
#if 0
111+
#if 1
112112
for( auto it=jmb.begin() ; it!=jmb.end() ; it++ ) {
113113
string ns = "odom-world#"+to_string( it->first );
114114

@@ -130,12 +130,12 @@ void periodic_publish_odoms( const NodeDataManager * manager, const VizPoseGraph
130130
// }
131131

132132
}
133-
viz->publishLastNEdges( -1 );
133+
// viz->publishLastNEdges( -1 );
134134
#endif
135135

136136

137137

138-
#if 1// only publish the latest odometry. Set this to zero if you dont need this.
138+
#if 0// only publish the latest odometry. Set this to zero if you dont need this.
139139
int to_publish_key = -1; //lets the largest key value
140140
for( auto it=jmb.begin() ; it!=jmb.end() ; it++ ) {
141141

@@ -428,12 +428,17 @@ void opt_traj_publisher_colored_by_world( const NodeDataManager * manager, const
428428
if( ____solvedUntil == 0 ) {
429429
w_TM_i = manager->getNodePose( i );
430430
} else {
431-
if( world_id >= 0 && ____solvedUntil_worldid == world_id )
432-
last_idx = ____solvedUntil;
433-
else if( world_id >=0 && ____solvedUntil_worldid != world_id )
434-
w_TM_i = manager->getNodePose( i );
435-
else
436-
last_idx = ____solvedUntil;
431+
if( world_id >= 0 && ____solvedUntil_worldid == world_id ) {
432+
last_idx = ____solvedUntil;}
433+
else if( world_id >=0 && ____solvedUntil_worldid != world_id ) {
434+
w_TM_i = manager->getNodePose( i );}
435+
else if( world_id < 0 ) {
436+
// last_idx = ____solvedUntil;
437+
last_idx = manager->nodeidx_of_world_i_ended( -world_id - 1 );
438+
} else {
439+
cout << "opt_traj_publisher_colored_by_world impossivle";
440+
exit(2);
441+
}
437442

438443
}
439444

0 commit comments

Comments
 (0)