Environment

  • Operating System: Win 10
  • Android Studio: Version 4.2
  • SDK: API 26: Android 8.0(Oreo)
  • Requirement: C++ 14 compiler & cmake & Eigen3

g2o的运行需要Eigen3,导入步骤详见在安卓项目中引入Eigen3库

Introduction

g2o is an open-source C++ framework for optimizing graph-based nonlinear error functions. g2o has been designed to be easily extensible to a wide range of problems and a new problem typically can be specified in a few lines of code. The current implementation provides solutions to several variants of SLAM and BA

A wide range of problems in robotics as well as in computer-vision involve the minimization of a non-linear error function that can be represented as a graph. Typical instances are simultaneous localization and mapping (SLAM) or bundle adjustment (BA). The overall goal in these problems is to find the configuration of parameters or state variables that maximally explain a set of measurements affected by Gaussian noise. g2o is an open-source C++ framework for such nonlinear least squares problems. g2o has been designed to be easily extensible to a wide range of problems and a new problem typically can be specified in a few lines of code. The current implementation provides solutions to several variants of SLAM and BA. g2o offers a performance comparable to implementations of state-of-the-art approaches for the specific problems

g2o是一个开源的C++框架,用于优化基于图形的非线性误差函数。g2o被设计成易于扩展到广泛的问题,通常只需几行代码就可以指定一个新问题。目前的实现为SLAM和BA的几个变体提供了解决方案

机器人学和计算机视觉中的许多问题都涉及到非线性误差函数的最小化,这些误差函数可以表示为一个图形。典型的例子是同步定位和制图(SLAM)或捆绑调整(BA)。这些问题的总体目标是找到参数或状态变量的配置,以最大限度地解释受高斯噪声影响的一组测量值。g2o是一个用于此类非线性最小二乘法问题的开源C++框架。g2o被设计为易于扩展到广泛的问题,通常只需几行代码就可以指定一个新问题。目前的实现为SLAM和BA的几个变体提供了解决方案。g2o的性能可与最先进的具体问题的实现相媲美

Step1

创建以Native C++为模板的安卓项目

  1. 打开Android Studio点击创建项目

1

  1. 选择Native C++模板并点击Next

2

  1. 填写相应字段后点击Next

3

  1. 选择C++版本并点击Finish创建项目
  • 这里我选择的是标准C++ 14

4

Step2

下载g2o包并导入到项目中

  1. 官网下载g2o包并解压到本地

5

  1. 将下载的g2o包下的g2o文件夹复制到安卓项目中

6

Step3

通过CMakeLists.txt引入g2o

  1. 打开CMakeLists.txt文件

7

  1. 添加如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
####### Eigen3 #######

INCLUDE_DIRECTORIES(Eigen)

####### ###### #######

####### g2o #######

INCLUDE_DIRECTORIES(g2o)
INCLUDE_DIRECTORIES(../cpp)

INCLUDE_DIRECTORIES(g2o/core)
INCLUDE_DIRECTORIES(g2o/types)
INCLUDE_DIRECTORIES(g2o/stuff)
INCLUDE_DIRECTORIES(g2o/solvers)

AUX_SOURCE_DIRECTORY(g2o/core g2oCore)
AUX_SOURCE_DIRECTORY(g2o/solvers g2oSolvers)
AUX_SOURCE_DIRECTORY(g2o/stuff g2oStuff)
AUX_SOURCE_DIRECTORY(g2o/types g2oTypes)

add_library( # Sets the name of the library.
g2o

# Sets the library as a shared library.
SHARED

# Provides a relative path to your source file(s).
${g2oCore} ${g2oSolvers} ${g2oStuff} ${g2oTypes} )

####### ### #######

Step4

适当修改g2o源码?

由于每个人每台计算机的环境不同,配置不同,路径不同,就造成引入时会出现不同的问题

例如#include<tr1/unordered_map>C++ 11以后要写成#include<unordered_map>

g2o库中需要config.h文件,且引用了大量的头文件,这些需要自己去配置

例如在ORB-SLAM2中,调用了第三方库g2o,并对其内容进行了修改以及删除了不必要的文件

可参考实际情况,根据具体需要对源码进行相应的修改

Step5

编码测试

  1. /g2o/core路径下创建g2oTest.cpp文件,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <jni.h>
#include <string>
#include <Eigen/Dense>
#include "core/factory.h"

using namespace std;
using namespace g2o;

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_androidstudiog2o_MainActivity_g2oTest(
JNIEnv* env,
jobject) {
string g2oTestString="g2o";
g2o::Factory;
return env->NewStringUTF(g2oTestString.c_str());
}
  1. 修改MainActivity.java的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.example.androidstudiog2o;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.example.androidstudiog2o.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
System.loadLibrary("g2o");
}

private ActivityMainBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

// Example of a call to a native method
TextView tv = binding.sampleText;
tv.setText(stringFromJNI());

// g2o
tv.setText(g2oTest());

}

/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
public native String g2oTest();
}
  1. 运行查看结果
  • MainActivity.java中原本将tv中的文本置为stringFromJNI()函数的返回值
  • 修改后应为我们自己编写的函数的结果,即g2o

8

导入成功!