JNI实现数据传输,App实现三点校准算法

xiaoxiao2021-02-28  103

校准逻辑

1、单片机上报原始数据; 2、JNI实现数据传输; 3、App实现校准,计算OK的参数写到单片机上。        解释一下:为什么在应用层去实现校准?因为,计算参数的的时候有坑呢,有可能会出现计算时数据溢出,导致计算操作不准确,在App上定义一个Long就搞定了,在底层实现还需要实现结构封装,好麻烦!,其实就是偷懒了!当然有其他目的需要保密的话,最好还是NDK里面实现吧!

JNI层

JNI层实现简单的读写功能,或者就是数据传输的通道而已。在这还是附上之前《 jni数组使用及将C的char数组传递给Java》的代码: /********************************************************************************** *====返回串口接收的数据 */ jcharArray Java_com_example_serialcal_PwtsingleClass_ReturnSerialData( JNIEnv* env ){ LOGE("UPON : INTO FUNCTION [--Java_com_example_serialcal_PwtsingleClass_ReturnSerialData()--]\n"); LOGE("UPON :[--Java_com_example_serialcal_PwtsingleClass_ReturnSerialData()--]---%d\n",fd); int i; char bufTemp[BUF_SIZE]; read_send_to_java(fd,bufTemp);//在文件描述符fd读取BUF_SIZE个数据到bufTemp,bufTemp按照协议定义好,长度为BUF_SIZE LOGE("UPON : bufTemp=%s\n",bufTemp); LOGE("UPON : bufTemp=0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", bufTemp[0],bufTemp[1],bufTemp[2],bufTemp[3],bufTemp[4],bufTemp[5],bufTemp[6],bufTemp[7],bufTemp[8],bufTemp[9]); jcharArray array = (*env)->NewCharArray(env,BUF_SIZE);//定义数据变量 if(array == NULL){ LOGE("UPON : NewCharArray error.\n"); return; } jchar *pArray ; pArray = (jchar*)calloc(BUF_SIZE, sizeof(jchar));//开辟jchar类型内存空间 if(pArray == NULL){ LOGE("UPON : calloc error.\n"); return; } //copy buffer to jchar array for(i = 0; i < BUF_SIZE; i++) { *(pArray + i) = bufTemp[i];//复制bufTemp数据元素到pArray内存空间 } //LOGE("UPON: =============%s\n",pArray); (*env)->SetCharArrayRegion(env,array,0,BUF_SIZE,pArray);//复制pArray的jchar数据元素到jcharArray return array; }

App实现三点校准:

           原理: //|-----------------------------------------------------------------------------------------------------------------------\ //|----------------------------------\ 三点 |-->| K = (X1 - X3)(Y2 - Y3) - (X2 - X3)(Y1 - Y3) |Author: UPON | //| || U || XL1 = AX1+BY1+C | 校 |-->| A = ((XL1 - XL3)(Y2 - Y3) - (XL2 - XL3)(Y1 - Y3))/K |QQ:3075583493 | //| || P || XL2 = AX2+BY2+C | 准 |-->| B = ((X1 - X3)(XL2 - XL3) - (XL1 - XL3)(X2 - X3))/K |-----------------| //| \\ // XL3 = AX3+BY3+C |=======\|-->| C = (Y1(X3XL2 - X2XL3) + Y2(X1XL3 - X3XL1) + Y3(X2XL1 - X1XL2))/K | //| // \\ YL1 = DX1+EY1+F |=======/|-->| D = ((YL1 - YL3)(Y2 - Y3) - (YL2 - YL3)(Y1 - Y3))/K | //| || O || YL2 = DX2+EY2+F | 算 |-->| E = ((X1 - X3)(YL2 - YL3) - (YL1 - YL3)(X2 - X3))/K | //| || N || YL3 = DX3+EY3+F | 法 |-->| F = (Y1(X3YL2 - X2YL3) + Y2(X1YL3 - X3YL1) + Y3(X2YL1 - X1YL2))/K | //|----------------------------------/ |==>|校准之后的坐标为:x=(Xl - B*y - C)/A y=(Yl - D*Xl + C*D - F)/(E - D*B) | //|=======================================================================================================================/    JAVA实现: public long X1,X2,X3; //触摸屏X坐标 public long Y1,Y2,Y3; //触摸屏Y坐标 public long XL1,XL2,XL3; //显示器XL坐标 public long YL1,YL2,YL3; //显示器YL坐标 public long K,A,B,C,D,E,F; //校准算法需要计算的校准参数 public double Temp_K,Temp_A,Temp_B,Temp_C,Temp_D,Temp_E,Temp_F;//校准算法需要计算的校准参数的中间变量 int Scale=10000;//根据需要将需要处理的数据放大10000倍,Scale为缩放因子 private void doCal(){//校准计算 flag = false; K = (X1 - X3)*(Y2 - Y3)-(X2 - X3)*(Y1 - Y3); Temp_A = (double)((XL1 - XL3)*(Y2 - Y3)-(XL2 - XL3)*(Y1 - Y3))/(double)K; A = (long)(Temp_A*10000); Temp_B = (double)((X1 - X3)*(XL2 - XL3) - (XL1 - XL3)*(X2 - X3))/(double)K; B = (long)(Temp_B*10000); C = (Y1*(X3*XL2 - X2*XL3) + Y2*(X1*XL3 - X3*XL1) + Y3*(X2*XL1 - X1*XL2))/K; Temp_D = (double)((YL1 - YL3)*(Y2 - Y3) - (YL2 - YL3)*(Y1 - Y3))/(double)K; D = (long)(Temp_D*10000); Temp_E = (double)((X1 - X3)*(YL2 - YL3) - (YL1 - YL3)*(X2 - X3))/(double)K; E = (long)(Temp_E*10000); F = (Y1*(X3*YL2 - X2*YL3) + Y2*(X1*YL3 - X3*YL1) + Y3*(X2*YL1 - X1*YL2))/K; //Toast.makeText(getApplicationContext(), "K的值"+K+"A的值"+A+"B的值"+B+"C的值"+C+"D的值"+D+"E的值"+E+"F的值"+F, Toast.LENGTH_LONG).show(); DrawCalCircle.drawText(screen_w/5, screen_h/4+500, "K="+K+" A="+A+" B="+B+" C="+C+" D="+D+" E="+E+" F="+F ,15); } 最后将校准好的参数,按照与单片机定义好的协议,写到单片机中,这样就实现了校准功能。
转载请注明原文地址: https://www.6miu.com/read-81471.html

最新回复(0)