[記憶] Tslib Manual Calibrate On Android

 

http://xxw8393.blog.163.com/blog/static/37256834200988102647150/

Tslib Manual Calibrate On Android

Java&Android 2009-09-08 10:26:47 閱讀783 評論2 字號:

                       Tslib Manual Calibrate On Android
                                     --by ON

CE
1.android 的座標轉換處理
This implementation is a linear transformation using 7 parameters
(a, b, c, d, e, f and s) to transform the device coordinates (Xd, Yd)
into screen coordinates (Xs, Ys) using the following equations:
s*Xs = a*Xd + b*Yd + c
s*Ys = d*Xd + e*Yd + f
Xs,Ys:LCD 座標(也就是所謂的絕對座標)
Xd,Yd:觸摸屏座標
在編譯好了的 ANDROID 根文件系統的 system/etc/pointercal 這個文件
內,存放着 7 個數,
這 7 個數就是對應上面公式的 a,b,c,d,e,f,s
比如我原來的:
+----+-----+--------+------+--+--------+----+
  a | b |           c     |d      |e | f       |s |
+----+-----+--------+------+--+--------+----+
|-411|37818|-3636780|-51325|39|47065584|6553|
+----+-----+--------+------+--+--------+----+
2.tslib 庫的移植
首先下載到一份 tslib 的代碼,我用的是 tslib011.tar.gz(該包由
luzhuwei 同學友情贊助)。
將 tslib 解壓到 external/下
要將一份代碼編譯到 android 裏面去 其實沒什麼其他工作 主要就是那
個 Android.mk 文件的編寫。網上找找 自己改改也就出來了。我的
Android.mk 文件內容如下:
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
TSLIB_PLUGINDIR := /system/lib/ts/plugins
LOCAL_SRC_FILES := /
      src/ts_attach.c /
      src/ts_close.c /
      src/ts_config.c /
      src/ts_error.c /
      src/ts_fd.c /
      src/ts_load_module.c /
      src/ts_open.c /
      src/ts_parse_vars.c /
      src/ts_read.c /
      src/ts_read_raw.c /
      src/ts_read_raw_module.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/ /
                 /usr/include/
LOCAL_SHARED_LIBRARIES := libdl
LOCAL_MODULE := libts
include $(BUILD_SHARED_LIBRARY)
#
# plugin: input-raw
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := plugins/input-raw.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/
LOCAL_SHARED_LIBRARIES := libdl /
                 libts
LOCAL_MODULE := ts/plugins/input-raw
include $(BUILD_SHARED_LIBRARY)
#
# plugin: pthres
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := plugins/pthres.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/
LOCAL_SHARED_LIBRARIES := libdl /
                 libts
LOCAL_MODULE := ts/plugins/pthres
include $(BUILD_SHARED_LIBRARY)
#
# plugin: linear
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := plugins/linear.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/
LOCAL_SHARED_LIBRARIES := libdl /
                 libts
LOCAL_MODULE := ts/plugins/linear
include $(BUILD_SHARED_LIBRARY)
#
# plugin: dejitter
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := plugins/dejitter.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/
LOCAL_SHARED_LIBRARIES := libdl /
                   libts
LOCAL_MODULE := ts/plugins/dejitter
include $(BUILD_SHARED_LIBRARY)
#
# plugin: variance
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := plugins/variance.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/
LOCAL_SHARED_LIBRARIES := libdl /
                   libts
LOCAL_MODULE := ts/plugins/variance
include $(BUILD_SHARED_LIBRARY)
#
# ts_calibrate
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := tests/testutils.c /
      tests/fbutils.c /
      tests/font_8x8.c /
      tests/ts_calibrate.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/ /
                  tests/ts_calibrate.h /
                  /usr/include/
LOCAL_SHARED_LIBRARIES := libdl /
                    libts
LOCAL_MODULE := ts_calibrate
include $(BUILD_EXECUTABLE)
#
# ts_test
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := tests/testutils.c /
      tests/fbutils.c /
      tests/font_8x8.c /
      tests/ts_test.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/ /
                  /usr/include/
LOCAL_SHARED_LIBRARIES := libdl /
                    libts
LOCAL_MODULE := ts_test
include $(BUILD_EXECUTABLE)
#
# ts_print
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := tests/testutils.c /
      tests/fbutils.c /
      tests/font_8x8.c /
      tests/ts_print.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/ /
                  /usr/include/
LOCAL_SHARED_LIBRARIES := libdl /
                    libts
LOCAL_MODULE := ts_print
include $(BUILD_EXECUTABLE)
#
# ts_print_raw
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := tests/testutils.c /
      tests/fbutils.c /
      tests/font_8x8.c /
      tests/ts_print_raw.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/ /
                  /usr/include/
LOCAL_SHARED_LIBRARIES := libdl /
                     libts
LOCAL_MODULE := ts_print_raw
include $(BUILD_EXECUTABLE)
#
# ts_harvest
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := tests/testutils.c /
       tests/fbutils.c /
       tests/font_8x8.c /
       tests/ts_harvest.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/ /
                   /usr/include/
LOCAL_SHARED_LIBRARIES := libdl /
                     libts
LOCAL_MODULE := ts_harvest
include $(BUILD_EXECUTABLE)
我真不願意粘帖上面的這個文件...太大 不過方便後人拷貝。
這裏要注意是我們需要修改一下 tslib 的幾個相關文件,因爲 android
裏的部分設備文件位置比較特殊。還有就是 tslib 裏的部分變量他是
定義在 Makefile 裏的 我們要把它定義到我們的文件中去。
首先 fb0 的位置變了: tests/fbutils.c
static char *defaultfbdevice = "/dev/fb0";
 static char *defaultfbdevice = "/dev/graphics/fb0";
其次 plugins 的目錄變了 src/ts_load_module.c
     #define PLUGIN_DIR "/system/lib/ts/plugins/"
最後 config 文件的位置變了 src/ts_config.c
     #define TS_CONF "/system/etc/ts.conf"
最後的最後不得不提到我們的配置文件 ts.conf。其他都不要動 但是
必須將它的 module_raw input 註釋出來。並且 因爲我們的 input 模塊
編譯出來之後我們命名爲 input-raw 了 所以這裏得改成
 module_raw input-raw
下面就是編譯了。發現錯誤就手工拷貝一下編出來的庫到需要它在的
目錄。
3. ts_calibrate 生成 pointercal
這裏要首先不啓動 android,然後進命令行手工啓動 ts_calibrate 程序。
然後在屏幕上校驗,完成後會生成一個正確的 pointercal 文件。
4.Android 讀取校驗文件 pointercal
如果要讓我們的 android 被校驗 那莪沒我們就要按上面的公式 將
android 讀取座標部分替換掉。
“system/etc/pointercal”這個文件是被 java 程序讀取使用的,文件目錄:
f rameworks/base/services/java/com/android/server/InputDevice.java
看了一下這個文件的代碼 發現要被修改的座標爲
             if (device.absX != null) {
                 //xxw added
                 if (device.tInfo != null){
                    scaledX = (device.tInfo.x1 * x + device.tInfo.y1 * y +
device.tInfo.z1)/ device.tInfo.s;
                    Log.i("XXW","x: "+x);
                    Log.i("XXW","trans x: "+scaledX);
                }
                else//end
                    scaledX = ((scaledX-device.absX.minValue)
                          / device.absX.range) * w;
            }
            if (device.absY != null) {
                //xxw added
                if (device.tInfo != null){
                    scaledY = (device.tInfo.x2 * x + device.tInfo.y2 * y +
device.tInfo.z2) / device.tInfo.s;
                    Log.i("XXW","y: "+y);
                    Log.i("XXW","trans y: "+scaledY);
                }
                else //end
                scaledY = ((scaledY-device.absY.minValue)
                          / device.absY.range) * h;
            }
對照上面的公式其實很容易理解 在註釋 xxw 和 end 之間的代碼就是
我修改的代碼。其中的 device.tInfo 是我定義的一個結構,這個結構
是用來讀取 pointercal 文件裏的 7 個數字得到的對應的值,具體結構
如下:
  static class TransformInfo {
     float x1;
     float y1;
     float z1;
     float x2;
     float y2;
     float z2;
     float s;
 };
讀取文件的代碼 我放在 InputDevice 的構造函數裏:
 //xxw added
 TransformInfo t = null;
 try {Log.i("XXW","InputDevice! try");
 FileInputStream is = new FileInputStream(CALIBRATION_FILE);
 byte[] mBuffer = new byte[64];
 int len = is.read(mBuffer);
 is.close();
 if (len > 0) {Log.i("XXW","InputDevice! len>0");
    int i;
    for (i = 0 ; i < len ; i++) {
 if (mBuffer[i] == '/n' || mBuffer[i] == 0) {
 break;
 }
    }
    len = i;
   }Log.i("XXW","InputDevice! len"+len);
   StringTokenizer st = new StringTokenizer( new String(mBuffer, 0, 0,
len));
   t = new TransformInfo ();
   t.x1 = Integer.parseInt( st.nextToken() ); Log.i("XXW", "t.x1"+t.x1);
   t.y1 = Integer.parseInt( st.nextToken() );Log.i("XXW", "t.y1"+t.y1);
   t.z1 = Integer.parseInt( st.nextToken() );Log.i("XXW", "t.z1"+t.z1);
   t.x2 = Integer.parseInt( st.nextToken() );Log.i("XXW", "t.x2"+t.x2);
   t.y2 = Integer.parseInt( st.nextToken() );Log.i("XXW", "t.y2"+t.y2);
   t.z2 = Integer.parseInt( st.nextToken() );Log.i("XXW", "t.z2"+t.z2);
   t.s = Integer.parseInt( st.nextToken() );Log.i("XXW", "t.s"+t.s);
   } catch (java.io.FileNotFoundException e) {Log.i("XXW",
"FileNotFound!");
   } catch (java.io.IOException e) {Log.i("XXW", "IOException");
   }
   tInfo = t;
  Log.i("XXW","InputDevice end!");
   }
其中 static final String CALIBRATION_FILE = "/etc/pointercal";
這個時候點擊一下屏幕看看是不是準確就知道是不是成功了。這裏要
注意的是因爲是在 InputDevice 裏讀取的文件 所以當我們中途替換了
pointercal 文件的時候 android 並不會再去讀取這個文件。所以當我們
用 ts_calibrate 程序生成 pointercal 文件之後需要重啓一下。同樣 當我
們修改或者刪除了那個文件 我們也是需要重啓的。所以這個文檔 的
名字叫手工校驗。
PS:
如何自動化?
如何用 android 應用程序校驗而不是命令行?
如何不需要重啓也能實現?
請聽下回分解。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章