Android JNI编程 调用c语言卡尔曼滤波。。。
1、kalman.cpp
// // Created by xy on 2021/6/12. // #include "kalman.h" float Q = Q_DEFAULT; float R = R_DEFAULT; float x_last, p_last; void ResetValue(){ x_last = 0; p_last = 0; } void ProcessQset(float q){ Q = q; } void ProcessRset(float r){ R = r; } float KalmanFilter(float ResrcData) { // static float x_last; // static float p_last; float x_mid; float x_now; x_mid = x_last; float p_mid; float p_now; float kg; //x_last=x(k-1|k-1),x_mid=x(k|k-1) x_mid = x_last; //p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=噪声 p_mid = p_last + Q; //kg为kalman filter,R为噪声 kg = p_mid / (p_mid + R); //估计出的最优值 x_now = x_mid + kg * (ResrcData - x_mid); //最优值对应的covariance p_now = (1 - kg) * p_mid; //更新covariance值 p_last = p_now; //更新系统状态值 x_last = x_now; return x_now; }
2、kalman.h
// // Created by xy on 2021/6/12. // #ifndef PHMETER_KALMAN_H #define PHMETER_KALMAN_H #include "../common.h" /** * Q: ProcessNiose_Q * R: MeasureNoise_R * Q:过程噪声,Q增大,动态响应变快,收敛稳定性变坏 * R:测量噪声,R增大,动态响应变慢,收敛稳定性变好 */ #define Q_DEFAULT 0.01 #define R_DEFAULT 10 /** * 重置记录值 */ void ResetValue(); /** * 设置滤波参数Q * @param q */ void ProcessQset(float q); /** * 设置滤波参数R * @param r */ void ProcessRset(float r); /** * 卡尔曼滤波C语言实现 * @param ResrcData 输入 * @return float 返回:滤波后数据 */ float KalmanFilter(float ResrcData); #endif //PHMETER_KALMAN_H
3、common.h
// // Created by xy on 2021/6/12. // #ifndef PHMETER_COMMON_H #define PHMETER_COMMON_H #include <jni.h> #include <stdio.h> #include <string.h> #include <string> #include <Android/log.h> #include <Android/asset_manager.h> #include <Android/asset_manager_jni.h> #define TAG "api.linkzill.jni" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) #endif //PHMETER_COMMON_H
4、filter-lib.cpp
// // Created by Think on 2021/6/11. // #include "common.h" #include "filter/kalman.h" #include <iostream> extern "C" { JNIEXPORT void Java_api_linkzill_jni_FilterApiJNI_resetVal(JNIEnv *env){ ResetValue(); } JNIEXPORT void Java_api_linkzill_jni_FilterApiJNI_setQ(JNIEnv *env, jfloat q){ ProcessQset(q); } JNIEXPORT void Java_api_linkzill_jni_FilterApiJNI_setR(JNIEnv *env, jfloat r){ ProcessRset(r); } JNIEXPORT jfloat JNICALL Java_api_linkzill_jni_FilterApiJNI_kalmanFilter(JNIEnv *env, jfloat val){ return KalmanFilter(val); } }
5、FilterApiJNI
package api.linkzill.jni; /** * Author:Think * Time:2021/6/11 17:11 * Description:This is FilterApiJNI */ public class FilterApiJNI { static { // 加载。名字和。CMakeLists.txt 的名字一样 System.loadLibrary("filter-lib"); } public static native void resetVal(); public static native void setQ(float q); public static native void setR(float r); public static native float kalmanFilter(float val); }
6、CMakeLists.txt
#指定CMake构建本地库时所需的最小版本 cmake_minimum_required(VERSION 3.4.1) # 输出路径 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jni/${ANDROID_ABI}) # 配置加载native依赖 include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/) set(CMAKE_VERBOSE_MAKEFILE on) #native-lib #file(GLOB_RECURSE CPP_SRCS "src/main/cpp/*.cpp") set(GLOB_RECURSE_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp) add_library( filter-lib SHARED ${GLOB_RECURSE_DIR}/filter-lib.cpp ${GLOB_RECURSE_DIR}/filter/kalman.cpp) find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) target_link_libraries( # Specifies the target library. filter-lib # Links the target library to the log library # included in the NDK. ${log-lib} )
7、build.gradle配置
defaultConfig { minSdkVersion ext.android.minSdk targetSdkVersion ext.android.targetSdk versionCode project.ext.versionCode //版本号 versionName ext.android.versionName //版本名 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // 增加cmake控制属性 externalNativeBuild { cmake { // 指定编译架构 可省略 abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64' // cpp 编译时的额外选项 可省略 cppFlags "" } } } // 指定CMakeLists.txt路径 externalNativeBuild { cmake { // 在该文件种设置所要编写的c源码位置,以及编译后so文件的名字 path "CMakeLists.txt" // cmake版本 可以省略 version "3.10.2" } }
8、整体目录结构