Android平台使用Ceres Solver


在Android平台上使用Ceres求解器,官方教程不明確,且編譯過程遇到了很多問題。

環境

Ubuntu 18.04

源代碼

https://github.com/Great-Keith/ceres-android

准備工作

Eigen 3.3.7(最新):在編譯Ceres的時候需要使用。

NDK r20(最新):NDK r14b版本無法使用,建議使用高於14的版本。

Ceres 1.14.0(最新)已經附帶在倉庫中。

[NOTE] Ceres其他依賴項按照官方教程進行配置,建議先檢驗Linux系統下是否能夠安裝成功。

# 官方安裝指導 http://ceres-solver.org/installation.html

# CMake
sudo apt-get install cmake
# google-glog + gflags
sudo apt-get install libgoogle-glog-dev
# BLAS & LAPACK
sudo apt-get install libatlas-base-dev
# Eigen3
sudo apt-get install libeigen3-dev
# SuiteSparse and CXSparse (optional)
# - If you want to build Ceres as a *static* library (the default)
#   you can use the SuiteSparse package in the main Ubuntu package
#   repository:
sudo apt-get install libsuitesparse-dev
# - However, if you want to build Ceres as a *shared* library, you must
#   add the following PPA:
sudo add-apt-repository ppa:bzindovic/suitesparse-bugfix-1319687
sudo apt-get update
sudo apt-get install libsuitesparse-dev

mkdir ceres-bin
cd ceres-bin
cmake ../ceres-solver-1.14.0
make -j3
make test
# Optionally install Ceres, it can also be exported using CMake which
# allows Ceres to be used without requiring installation, see the documentation
# for the EXPORT_BUILD_DIR option for more information.
make install

Android Studio 3.4.1:需要配置CMake, LLDB, ndk(在SDK Tools中點擊安裝)

官方Android指南

來源一:官方網站

原文

下載版本高於r9dAndroid NDK版本,在jni目錄下使用ndk-build進行編譯,你會得到libceres.a

解釋

具體使用方法:

cd ceres-solver-1.14.0/jni
EIGEN_PATH=/path/to/eigen/header ndk-build

隨后libceres.a便會出現在ceres-solver-1.14.0/obj/local/${ABI}目錄下。

${ABI}的值通過修改Application.mk中的APP_ABI := arm64-v8a一行,可.以換armeabi-7va, x86_64等等。

至於動態庫(*.so)的生成,根據網上的一些教程進行修改Android.mkApplication.mk,都無法正常編譯,官方GitHub里的issue中對於這些報錯,建議使用CMake進行編譯。

[NOTE] 如果從GitHub上clone的版本是不帶jni目錄的,只能使用CMake進行編譯。

來源二:代碼內的文檔

原文

編譯需要使用NDK r15或者更高版本。

需要使用CMake尋找NDK當中的toolchain來替換本身的自帶toolchain。假設你已經設置了變量$NDK_DIR,你可以使用如下命令編譯:

cmake \
-DCMAKE_TOOLCHAIN_FILE=\
    $NDK_DIR/build/cmake/android.toolchain.cmake \
-DEIGEN_INCLUDE_DIR=/path/to/eigen/header \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_STL=c++_shared \
-DANDROID_NATIVE_API_LEVEL=android-24 \
-DBUILD_SHARED_LIBS=ON \
-DMINIGLOG=ON \
<PATH_TO_CERES_SOURCE>

你可以為各種安卓STL或ABI進行編譯,但是最推薦使用c++_shared STL和armeabi-v7a(對於32位機)或arm64-v8a(對於64位機) ABI。許多API的版本都可以進行支持,但是推薦使用你安卓項目所支持的最高版本。

對於你的安卓項目和Ceres二進制文件,你需要使用相同的API版本和STL進行編譯。

編譯完成之后,你會得到一份libceres.so的庫,你可以在編譯的腳本中通過使用PREBUILT_SHARED_LIBRARY將它鏈接到你的安卓項目當中。

如果你正在編譯Ceres的例子,想要驗證你的庫能否使,你需要將他們和libceres.so放在安卓設備上一個可執行的公共目錄下(比如/data/local/tmp),並且確保NDK的STL也在同一個目錄下。

需要注意的是,所有的求解器或者其他被你包含在項目中的共享依賴項,都需要出現在你安卓的編譯配置和你的測試目錄當中。

解釋

最好采用CMake編譯這種方法,后面解釋如何修改這個命令。

編譯命令

參考資料:https://github.com/qiu-yongheng/cerestest

根據官方材料和參考資料得出如下命令:

rm -rf CMake*

/path/to/sdk/cmake/[version]/bin/cmake \
-DCMAKE_TOOLCHAIN_FILE=/path/to/sdk/ndk-bundle/build/cmake/android.toolchain.cmake \
-DEIGEN_INCLUDE_DIR=/path/to/eigen/header \
-DANDROID_ABI=[ABI]] \
-DANDROID_STL=[c++_shared | c++_static] \
-DANDROID_NATIVE_API_LEVEL=android-24 \
-DBUILD_SHARED_LIBS=ON \
-DMINIGLOG=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-s" \
-DCMAKE_C_FLAGS=-std=c99 -Os -fvisibility=hidden \
/path/to/ceres

make clean
make
make install

執行如上命令后,首先會遇到如下錯誤:undefined reference to '__android_log_write'

解決方法:打開[ceres]/internal/ceres/minglog/glog/logging.h,搜索__android_log_write,將帶有這個函數的幾行注釋掉。

重新編譯,最后會報錯誤:'libc++_shared.so' no found

解決方法:這個錯誤無關緊要,可以看到當前目錄下的lib目錄已經生成了我們想要的庫文件。從ndk-bundle中復制我們所需要的該文件到安卓項目中即可,該文件目錄可能是ndk-bundle/sources/cxx-stl/llvm-libc++/libs/[ABI]。無需繼續進行編譯。

[NOTE] /path/to/eigen/header這個地址,不能使用安裝eigen時候放置到的比如/usr/include地址,否則編譯的時候會出現沖突,應該直接使用下載解壓后的位置。

[NOTE] 每次cmake后,重新編譯需要提前先刪除當前目錄下的CMakeFiles, CMakeCache等中間文件,否則CMake的配置不會發生改變。

測試結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM