5456|2

468

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

android 电阻单点触摸屏校准 [复制链接]

今天做了android下触摸屏的校准,注意触摸屏可能有不一样,我们目前是用的是单点的电阻是触摸屏,android 平台是 2.1

下面来说下触摸屏的校准


client 采集数据:计算校对系数,写入文件 /data/etc/xxxx  通过propty来设置状态   InputDevice.java 根据propty 来读取校对的系数来校对数据。

校对数据模型采用    M=ax+by+k1;  N=cx+dy+k2,其中 M,N为经校对系数计算后的准确的触摸屏位置。

那么我们要做的是通过数据采集来计算a,b,k1,c,d,k2,对于每一维的坐标,都是三个系数,因此我们采集三个有效的数据点。成而得到


M1=ax1+by1+k1 ; N1=cx1+dy1+k2

M2=ax2+by2+k1 ; N2=cx2+dy2+k2

M3=ax2+by2+k1 ; N3=cx2+dy2+k2,其中(M1,N1),(M2,N2),(M3,N3),是你校对的标准数据,我的代码里取

做上角(32,32),右上脚(SCREEN_WIDTH-32,32),右下脚(32,SCREEN_HEIGHT-32),

(x1,y1),(x2,y2),(x3,y3)分别是获取的没校准前的 触摸屏的数据。


那么可以解得a,b,k1,c,d,k2,让后将这6个数据写入到/data/et/xxx文件中。

然后InputDevice.java读取propty的状态来决定是否使用校对系数.。

当触摸屏设置完后就会设置为done

当InputDevie 发现propty为done的时候读取校对系数建立校对模型。


有触摸屏传来的数据(x,y),那么由公式,X准=ax+by+k1; Y准=cx+dy+k2; 试验验证准有效


代码分析:

界面代码 TouchCalibration.java,它很简单,一个全屏的activty

模型M的取值范围

    int xList[] = {
            32, UI_SCREEN_WIDTH - 32, 32, UI_SCREEN_WIDTH - 32, UI_SCREEN_WIDTH / 2
        };


模型N的取值范围

  int yList[] = {
            32, 32, UI_SCREEN_HEIGHT - 32, UI_SCREEN_HEIGHT - 32, UI_SCREEN_HEIGHT / 2
        };


为五个参考点的坐标,其实只用了3个点,哈哈(还没搞明白五个点的数学模型,如果有知道的,希望能不吝赐教)

重载 onTouchEvent的接口,然后活去取三个点的实际触摸到的坐标

x1,y1,x2,y2,x3,y3,而这个准确的位置分别对应了xList[0],yList[0],xList[1],yList[1],xList[2],yList[2],

取道数据后,用Calibrate.java来计算出 a,b,k1,c,d,k2,三个未知数三个一次方程求解,

主要函数在perform_calibration 中



a=((y3-y2)*(M2-M1)-(M3-M2)*(y2-y1))/((y3-y2)*(x2-x1)-(y2-y1)*(x3-x2))

其它的可以自己计算出来,

float M1,M2,M3,N1,N2,N3;
    float a,b,k1,c,d,k2;
    float x1,y1,x2,y2,x3,y3;
    float mul,div;
    float scaling = (float)65536.0;

    M1=cal.xfb[0];
    N1=cal.yfb[0];
    M2=cal.xfb[1];
    N2=cal.yfb[1];
    M3=cal.xfb[2];
    N3=cal.yfb[2];

    x1=cal.x[0];
    y1=cal.y[0];
    x2=cal.x[1];
    y2=cal.y[1];
    x3=cal.x[2];
    y3=cal.y[2];
   
    div=((y3-y2)*(x2-x1)-(y2-y1)*(x3-x2));
    mul=((y3-y2)*(M2-M1)-(M3-M2)*(y2-y1));
    a=mul/div;
    div=((x3-x2)*(y2-y1)-(x2-x1)*(y3-y2));
    mul=(x3-x2)*(M2-M1)-(x2-x1)*(M3-M2);
    b=mul/div;
    k1=M1-a*x1-b*y1;
   
    div=((y3-y2)*(x2-x1)-(y2-y1)*(x3-x2));
    mul=((y3-y2)*(N2-N1)-(N3-N2)*(y2-y1));
    c=mul/div;
    div=((x3-x2)*(y2-y1)-(x2-x1)*(y3-y2));
    mul=(x3-x2)*(N2-N1)-(x2-x1)*(N3-N2);
    d=mul/div;
    k2=N1-c*x1-d*y1;
    Log.d("[hd debug]",a+":"+b+":"+k1+":"+c+":"+d+":"+k2+":");
    cal.a[0]=(int)(a*scaling);
    cal.a[1]=(int)(b*scaling);
    cal.a[2]=(int)(k1*scaling);
    cal.a[3]=(int)(c*scaling);
    cal.a[4]=(int)(d*scaling);
    cal.a[5]=(int)(k2*scaling);
    cal.a[6]=(int)(scaling);
        return true;

然后将三计算出来的值写入文件/data/etc/pointercal中,并设置ts.config.calibrate propty为done,

ts.config.calibrate propty是InputDevice.java,与触摸校对程序的通讯标志。


InputDevice.java 中修改你的generateAbsMotion函数,据说android 2.1支持多点触摸,我们用电阻式,所以没有去追究。

(我没有看懂)InputDevice.java代码,修改generateAbsMotion只能满足我的项目的需求,请仔细思考这里。


    String prop = SystemProperties.get("ts.config.calibrate", "noset");
            if (prop.equalsIgnoreCase("start")){
                    Log.d("XXW prop", prop);
                    Log.d("XXW", "prop.equalsIgnoreCase start");
                    device.tInfo = null;
            }else if (prop.equalsIgnoreCase("done")){
                    Log.d("XXW prop", prop);
                    Log.d("XXW", "prop.equalsIgnoreCase done");
                    readCalibrate();
            device.tInfo=tInfo;
                    SystemProperties.set("ts.config.calibrate", "end");
            }else{
                    Log.d("XXW prop", prop);
                    Log.d("XXW", "prop.equalsIgnoreCase else");
        }

这里根据propty设置是否采用校验系数,

如果采用的话,那么就使用隐射模型:

if (absX != null) {
                    if (device.tInfo != null){
                        reportData[j + MotionEvent.SAMPLE_X] = (device.tInfo.x1 * x + device.tInfo.y1 * y + device.tInfo.z1);
                    }
                }
                if (absY != null) {
                    if (device.tInfo != null){
                        reportData[j + MotionEvent.SAMPLE_Y] = (device.tInfo.x2 * x + device.tInfo.y2 * y + device.tInfo.z2);
                    }
                }

来计算出新的坐标,

代码将在我的资源里给出,有心趣的同学自己实现,没有兴趣的同学花点分,去下载资源源码也是可以的。


原文地址 http://blog.csdn.net/voidinit/article/details/5808357
此帖出自Linux开发论坛

最新回复

这个电阻屏幕的校准算法是很麻烦的,这个比电容屏幕麻烦多了,除非你自己写,但不知道网上是否有参考,如果没有就悲剧了。  详情 回复 发表于 2013-6-17 16:17
点赞 关注
个人签名

回复
举报

468

帖子

0

TA的资源

纯净的硅(高级)

沙发
 
这个文章还是比较有趣的。
此帖出自Linux开发论坛
 
个人签名
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

板凳
 

这个电阻屏幕的校准算法是很麻烦的,这个比电容屏幕麻烦多了,除非你自己写,但不知道网上是否有参考,如果没有就悲剧了。
此帖出自Linux开发论坛
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表