Skip to content

Commit 17512f6

Browse files
committed
add g2o
1 parent bd5c1e4 commit 17512f6

File tree

7 files changed

+1431
-0
lines changed

7 files changed

+1431
-0
lines changed
73.7 KB
Binary file not shown.

PathPlanning/DynamicWindowApproach/dwa.cpp

Lines changed: 494 additions & 0 deletions
Large diffs are not rendered by default.

g2o/em/a.out

2.63 MB
Binary file not shown.

g2o/em/com.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
g++ em-g2o.cpp -I /usr/include/eigen3/ `pkg-config --cflags --libs opencv` -lg2o_core -lg2o_stuff

g2o/em/em-g2o.cpp

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
#include <iostream>
2+
#include <g2o/core/base_vertex.h>
3+
#include <g2o/core/base_unary_edge.h>
4+
#include <g2o/core/block_solver.h>
5+
#include <g2o/core/optimization_algorithm_levenberg.h>
6+
#include <g2o/core/optimization_algorithm_gauss_newton.h>
7+
#include <g2o/core/optimization_algorithm_dogleg.h>
8+
#include <g2o/solvers/dense/linear_solver_dense.h>
9+
10+
#include <Eigen/Core>
11+
#include <Eigen/Dense>
12+
13+
#include <opencv2/core/core.hpp>
14+
#include <cmath>
15+
16+
using namespace std;
17+
using namespace Eigen;
18+
19+
20+
//顶点,即待优化变量,目标值
21+
class CurveFittingVertex: public g2o::BaseVertex<4,Vector4d>
22+
{
23+
public:
24+
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
25+
26+
CurveFittingVertex():BaseVertex<4,Vector4d>()
27+
{
28+
29+
}
30+
31+
virtual void setToOriginImpl()
32+
{
33+
_estimate << 0,0,0,0;
34+
}
35+
36+
virtual void oplusImpl(const double *update_) //更新顶点
37+
{
38+
Eigen::Map<const Vector4d> up(update_);
39+
_estimate += up;
40+
// cout<<"eee" <<_estimate<<endl;
41+
}
42+
43+
bool read(std::istream& is){}
44+
bool write(std::ostream& os) const{}
45+
46+
47+
};
48+
49+
//边,描述顶点之间的关系
50+
class CurveFittingEdge: public g2o::BaseUnaryEdge<1,double,CurveFittingVertex>
51+
{
52+
public:
53+
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
54+
55+
CurveFittingEdge():g2o::BaseUnaryEdge<1,double,CurveFittingVertex>(){}
56+
// 计算误差
57+
void computeError()
58+
{
59+
const CurveFittingVertex *v = static_cast<const CurveFittingVertex *>(_vertices[0]);
60+
const Vector4d abcd = v->estimate();
61+
double A = abcd[0],B = abcd[1],C = abcd[2],D = abcd[3];
62+
_error(0,0) = _measurement - (A*sin(B*_x)+C*cos(D*_x)); // 观测量减去估计量
63+
// cout << "cee "<<_error << endl;
64+
65+
}
66+
// 计算雅可比矩阵
67+
void linearizeOplus()
68+
{
69+
CurveFittingVertex *vi = static_cast<CurveFittingVertex *>(_vertices[0]);
70+
Vector4d abcd = vi->estimate();
71+
double A = abcd[0],B = abcd[1],C = abcd[2],D = abcd[3];
72+
// cout << " ddd" << endl;
73+
//误差项对待优化变量的Jacobian
74+
_jacobianOplusXi(0,0) = -sin(B*_x);
75+
_jacobianOplusXi(0,1) = -A*_x*cos(B*_x);
76+
_jacobianOplusXi(0,2) = -cos(D*_x);
77+
_jacobianOplusXi(0,3) = C*_x*sin(D*_x);
78+
79+
80+
}
81+
82+
bool read(istream &is){}
83+
bool write(ostream &os) const {}
84+
85+
public:
86+
double _x;
87+
};
88+
89+
int main(int argc, char**argv)
90+
{
91+
// double a = 5.0,b = 1.0,c = 10.0,d = 2.0;
92+
// int N = 100;
93+
94+
// double w_sigma = 2.0;
95+
96+
// cv::RNG rng;
97+
98+
// double abcd[4] = {0.0,0.0,0.0};
99+
100+
// vector<double> x_data,y_data;
101+
102+
// cout << "generate data" << endl;
103+
104+
// for (int i = 0; i < N; i++)
105+
// {
106+
// double x = rng.uniform(-10,10);
107+
// double y = a*sin(b*x)+c*cos(d*x)+rng.gaussian(w_sigma);
108+
// x_data.push_back(x);
109+
// y_data.push_back(y);
110+
111+
// // cout << x_data[i] << " ," << y_data[i] << endl;
112+
113+
// }
114+
115+
// // 每个误差项优化变量维度为 4,误差值维度为1
116+
// typedef g2o::BlockSolver<g2o::BlockSolverTraits<4,1>> Block;
117+
// // 线性方程求解器: 稠密的增量方程
118+
// Block::LinearSolverType* linearSolver = new g2o::LinearSolverDense<Block::PoseMatrixType>();
119+
120+
// // 矩阵块求解器
121+
// Block* solver_ptr = new Block(std::unique_ptr<Block::LinearSolverType>(linearSolver));
122+
123+
// // 梯度下降方法
124+
// // g2o::OptimizationAlgorithmLevenberg *solver = new g2o::OptimizationAlgorithmLevenberg(std::unique_ptr<Block>(solver_ptr));
125+
// g2o::OptimizationAlgorithmDogleg *solver = new g2o::OptimizationAlgorithmDogleg(std::unique_ptr<Block>(solver_ptr));
126+
127+
// g2o::SparseOptimizer optimizer;
128+
// optimizer.setAlgorithm(solver);
129+
// optimizer.setVerbose(true);
130+
131+
// CurveFittingVertex *v = new CurveFittingVertex();
132+
// // 初始值
133+
// v->setEstimate(Eigen::Vector4d(1.6,1.4,6.2,1.7));
134+
// v->setId(0);
135+
// v->setFixed(false);
136+
// optimizer.addVertex(v);//添加顶点
137+
138+
// for(int i=0;i< N;i++)
139+
// {
140+
// CurveFittingEdge *edge = new CurveFittingEdge();
141+
// edge->setId(i+1);
142+
// edge->setVertex(0,v);//设置连接的顶点
143+
// edge->setMeasurement(y_data[i]);
144+
145+
// //信息矩阵: 协方差矩阵之逆
146+
// edge->setInformation(Eigen::Matrix<double,1,1>::Identity()*1/(w_sigma*w_sigma));
147+
// edge->_x = x_data[i];
148+
// optimizer.addEdge(edge);
149+
150+
// }
151+
152+
// cout << "start optimization" << endl;
153+
154+
// chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
155+
// optimizer.initializeOptimization();
156+
// optimizer.optimize(100);
157+
158+
// chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
159+
160+
// chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1);
161+
// cout << " time_used: " << time_used.count() << " seconds" << endl;
162+
163+
// Eigen::Vector4d abcd_estimate = v->estimate();
164+
// cout << "estimated \n" << abcd_estimate << endl;
165+
166+
// return 0;
167+
168+
169+
double a = 5.0, b = 1.0, c = 10.0, d = 2.0; // 真实参数值
170+
int N = 100;
171+
double w_sigma = 0.2; // 噪声值Sigma
172+
cv::RNG rng; // 随机数产生器OpenCV
173+
double abcd[4] = {0, 0, 0, 0}; // 参数的估计值abc
174+
175+
vector<double> x_data, y_data;
176+
177+
cout << "generate random data" << endl;
178+
179+
for(int i = 0; i < N; i++)
180+
{
181+
//generate a random variable [-10 10]
182+
double x = rng.uniform(-10., 10.);
183+
double y = a * sin(b*x) + c * cos(d *x) + rng.gaussian(w_sigma);
184+
// double y = a * sin(b*x) + c * cos(d *x);
185+
x_data.push_back(x);
186+
y_data.push_back(y);
187+
188+
// cout << x_data[i] << " , " << y_data[i] << endl;
189+
}
190+
191+
// 构建图优化,先设定g2o
192+
// 矩阵块:每个误差项优化变量维度为4 ,误差值维度为1
193+
typedef g2o::BlockSolver< g2o::BlockSolverTraits<4, 1> > Block;
194+
// 线性方程求解器:稠密的增量方程
195+
// Block::LinearSolverType* linearSolver = new g2o::LinearSolverDense<Block::PoseMatrixType>();
196+
197+
typedef g2o::LinearSolverDense<Block::PoseMatrixType> MyLinearSolver;
198+
// Block* solver_ptr = new Block(linearSolver); // 矩阵块求解器
199+
200+
// // 梯度下降方法,从GN, LM, DogLeg 中选
201+
// g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg( solver_ptr );
202+
// g2o::OptimizationAlgorithmGaussNewton* solver = new g2o::OptimizationAlgorithmGaussNewton( solver_ptr );
203+
// g2o::OptimizationAlgorithmDogleg* solver = new g2o::OptimizationAlgorithmDogleg( solver_ptr );
204+
// 矩阵块求解器
205+
// Block* solver_ptr = new Block(std::make_unique<Block::LinearSolverType>(linearSolver));
206+
// g2o::OptimizationAlgorithmDogleg *solver = new g2o::OptimizationAlgorithmDogleg(std::unique_ptr<Block>(solver_ptr));
207+
g2o::SparseOptimizer optimizer; // 图模型
208+
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(g2o::make_unique<Block>(g2o::make_unique<MyLinearSolver>()));
209+
// g2o::OptimizationAlgorithmDogleg* solver = new g2o::OptimizationAlgorithmDogleg(g2o::make_unique<Block>(g2o::make_unique<MyLinearSolver>()));
210+
211+
optimizer.setAlgorithm( solver ); // 设置求解器
212+
optimizer.setVerbose(true); // 打开调试输出
213+
214+
// 往图中增加顶点
215+
CurveFittingVertex *v = new CurveFittingVertex();
216+
// 设置优化初始估计值
217+
v->setEstimate( Eigen::Vector4d(1.6, 1.4, 6.2, 1.7));
218+
v->setId(0);
219+
// v->setFixed(false);
220+
optimizer.addVertex(v);
221+
222+
// 往图中增加边
223+
for(int i = 0; i < N; i++)
224+
{
225+
CurveFittingEdge* edge = new CurveFittingEdge();
226+
edge->setId(i+1);
227+
edge->setVertex(0, v); // 设置连接的顶点
228+
edge->setMeasurement( y_data[i] ); // 观测数值
229+
230+
// 信息矩阵:协方差矩阵之逆
231+
edge->setInformation( Eigen::Matrix<double, 1, 1>::Identity() );
232+
233+
edge->_x = x_data[i];
234+
235+
optimizer.addEdge( edge );
236+
}
237+
238+
// 执行优化
239+
cout << "strat optimization" << endl;
240+
241+
chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
242+
243+
optimizer.initializeOptimization();
244+
optimizer.optimize(500);
245+
246+
chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
247+
248+
chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double> > (t2 - t1);
249+
cout << "solve time cost = " << time_used.count() << " seconds." << endl;
250+
251+
// 输出优化值
252+
Eigen::Vector4d abcd_estimate = v->estimate();
253+
cout << "estimated module: " << endl << abcd_estimate << endl;
254+
255+
return 0;
256+
257+
258+
}
259+
260+

0 commit comments

Comments
 (0)