Calibrazione touch screen

A scuola abbiamo le LIM, e ho verificato che collegandole con il portatile il touch screen è nativamente supportato da Fedora (uso Gnome), e che potrei usare kolourpaint per scrivere sulla LIM quando spiego.
Solo che, quando tocco lo schermo, la scritta compare più a destra rispetto alla posizione del pennarello virtuale, e quindi ho bisogno di calibrare la LIM.
Ho installato e avviato xinput_calibrator, ma compare solo il punto in alto a sinistra dove cliccare, mentre una scritta è parzialmente oscurata dalla fine del monitor a destra.
Risultato: non ho modo di cliccare sugli altri punti, e quindi xinput_calibrator esce senza appurare la posizione della LIM.

Ho l’impressione che, mentre ho istruito Gnome a usare i 2 monitor come duplicati (in altre parole, sulla LIM compare esattamente quanto vedo sullo schermo del monitor del portatile), xinput_calibrator creda di trovarsi di fronte un monitor diviso in 2, di cui solo la parte sinistra mi è visibile.

C’è un modo per effettuare con successo la calibrazione?

Non sono sicuro di aver compreso a pieno. Provo comunque a risponderti: proverei ad utilizzare prima un solo schermo, oppure a premere comunque sullo schermo in fase di calibrazione, in modo da generare un file di calibrazione e poi a modificare manualmente i parametri…
Magari xinput_calibrator ha qualche opzione specifica per il tuo caso.

Come faccio ad usare un solo schermo? Al portatile non posso mica staccare il monitor, mentre la LIM è collegata al portatile tramite la porta VGA (se la stacco, non ho più nulla da calibrare).
I monitor sono settati, dentro Gnome, su “Duplicato” anziché “Affiancato”: quindi vedo l’intera Scrivania su entrambi (con “Affiancato” vedrei sulla LIM la parte destra della Scrivania, e sul monitor del portatile la parte sinistra).
Ma xinput_calibrator mi mostra solo la metà sinistra, impedendomi di cliccare sul secondo punto, che, presumo, esce dallo schermo.

Puoi disabilitare l’uscita video interna al portatile via kernel Linux tramite opzione al boot (è un trucco utile quando vengono riconosciuti monitor inesistenti o rotti) :
http://doc.fedoraonline.it/Utente:FrancescoFrassinelli/Sandbox#Disabilitare_una_uscita_video

Ho trovato http://askubuntu.com/questions/253395/touchscreen-calibration-with-dual-monitors-nvidia-and-xinput, e mi riservo di verificare se può servire.
Nel frattempo ho modificato lo script che mi hai linkato, modificandolo in

do $f =~ $REGEX ]] && echo ${BASH_REMATCH[1]} || true done)); echo "Video outputs:"; i=1; for output in ${OUTPUTS@]}; do echo "$i) $output " $(cat $DIR/$output/{status,enabled}); let i++; done | column -t; read -p "Select video output [1-${#OUTPUTS[@]}]: " id; $id -ge 1 && $id -le ${#OUTPUTS@]} ]] || exit 1; let id--; ${OUTPUTS$id]} =~ $REGEX ]] || exit 1; cat /etc/sysconfig/grub | sed -r 's/(GRUB_CMDLINE_LINUX=)"(.*)"/\1"\2 video='${BASH_REMATCH[2]}':d"/')
per non scrivere permanentemente i files di grub.
Praticamente leggo a schermo il contenuto che dovrebbe avere la riga GRUB_CMDLINE_LINUX di /etc/sysconfig/grub, mi segno il parametro, e lo aggiungo a mano al boot.
La cosa ha funzionato, in quanto il monitor del portatile, da un certo punto del boot in poi, è diventato nero, e l’immagine mostrata da xinput_calibrator, finalmente, era completa.
Clicco sul primo punto, clicco sul secondo, clicco sul terzo… tutto bene, ma quando clicco sul quarto dice sempre misclick e ricomincia daccapo. Probabilmente l’immagine non è esattamente in piano.

Risultato: sono un po’ più avanti rispetto a prima, ma ancora non sono riuscito a calibrare il touch screen.

Sono riuscito ad avere da xinput_calibrator i parametri con l’opzione “–misclick=0”:

[code]DEBUG: Adding click 0 (X=180, Y=85)
DEBUG: Adding click 1 (X=904, Y=81)
DEBUG: Adding click 2 (X=187, Y=642)
DEBUG: Adding click 3 (X=927, Y=643)

–> Making the calibration permanent <–
DEBUG: Found that ‘SMART Technologies Inc. SMART Interactive Whiteboard Controller (SB6)’ is a sysfs name.
copy the policy below into ‘/etc/hal/fdi/policy/touchscreen.fdi’

3935
66399
-875
62782
[/code]

Ho provato a seguire l’indicazione, ma ovviamente viene ignorata (hal non esiste più non ricordo da che versione di Fedora).

Per caso, hai provato a vedere se Wayland si comporta meglio di Xorg?

No, non ho provato Wayland. Ma il problema mi sembra più che altro in che modo “spiegare” al driver che gestisce il mouse che quando clicco in (x,y) deve interpretarlo come (x+Δx;y+Δy).
Tra l’altro ho provato ieri a dare, come dice http://askubuntu.com/questions/253395/touchscreen-calibration-with-dual-monitors-nvidia-and-xinput,

$ xrandr --output <non-touch-output> --off

per disconnettere (non so se è il termine giusto) il monitor del portatile prima di eseguire xinput_calibrator (è molto più comodo che riavviare e aggiungere un parametro al kernel).
A parte il fatto che l’opzione “–on” indicata nel link non sembra esistere, e che quindi non saprei riconnettere il monitor quando finisco di usare la LIM, in questo modo riesco a cliccare i quattro punti mostrati da xinput_calibrator (l’immagine è distribuita correttamente solo sulla LIM), e alla fine mi compare un messaggio che dice più o meno “per rendere permanente questi valori ecc. ecc.”. Questo mi farebbe pensare che siano stati corretti per la sessione corrente, solo che riaprendo subito (e dallo stesso terminale) kolourpaint non cambia nulla. La scritta è spostata rispetto al click, esattamente come prima. E il suggerimento per rendere permanente l’opzione non sembra funzionare (e come potrebbe, visto che hal è dismesso da un po’?)

Calibrando con il seguente comando, dovrebbero esserti restituite delle coordinate per la calibrazione, o sbaglio?

$ xinput_calibrator --output-type xinput

Perché potremmo poi cercare di “aggiustarle” (aggiungendo il Δ di cui parlavi) e applicarle in modo che resistano per tutta la sessione (potremmo aggiungere i comandi per xinput direttamente in “/etc/gdm/Init/Default”, per esempio).

Vediamo anche come viene riconosciuta la lavagna in questione:

$ xrandr
$ xinput --list

$ xrandr Screen 0: minimum 320 x 200, current 1024 x 768, maximum 8192 x 8192 LVDS connected primary 1024x768+0+0 (normal left inverted right x axis y axis) 382mm x 214mm 1600x900 60.00 + 1440x900 59.89 1280x854 59.89 1280x800 59.81 1280x720 59.86 1152x768 59.78 1024x768 60.04* 60.00 59.92 960x720 60.00 928x696 60.05 896x672 60.01 800x600 60.00 60.32 59.86 56.25 848x480 59.66 700x525 59.98 720x480 59.71 640x512 60.02 640x480 60.00 59.94 59.38 512x384 60.00 400x300 60.32 56.34 320x240 60.05 VGA-0 connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm 1024x768 60.00* 800x600 60.32 56.25 848x480 60.00 640x480 59.94 HDMI-0 disconnected (normal left inverted right x axis y axis)
Dove VGA-0 è l’uscita dove collego la LIM, e LVDS quella del monitor del portatile.

$ xinput_calibrator --list Device "SMART Technologies Inc. SMART Interactive Whiteboard Controller (SB6)" id=16
(la LIM)

$ xinput --list ⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ Logitech USB Optical Mouse id=10 [slave pointer (2)] ⎜ ↳ SynPS/2 Synaptics TouchPad id=13 [slave pointer (2)] ⎜ ↳ SMART Technologies Inc. SMART Interactive Whiteboard Controller (SB6) id=16 [slave pointer (2)] ⎣ Virtual core keyboard id=3 [master keyboard (2)] ↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)] ↳ Power Button id=6 [slave keyboard (3)] ↳ Video Bus id=7 [slave keyboard (3)] ↳ Power Button id=8 [slave keyboard (3)] ↳ Sleep Button id=9 [slave keyboard (3)] ↳ HP Webcam id=11 [slave keyboard (3)] ↳ AT Translated Set 2 keyboard id=12 [slave keyboard (3)] ↳ HP WMI hotkeys id=14 [slave keyboard (3)] ↳ ENE eHome Infrared Remote Receiver id=15 [slave keyboard (3)]

E, per finire, dopo aver dato

$ xrandr --output LVDS --off

per disattivare il monitor del portatile,

[code]$ xinput_calibrator --output-type xinput -v --misclick 0
DEBUG: XInputExtension version is 2.3
DEBUG: Skipping virtual master devices and devices without axis valuators.
DEBUG: Skipping device ‘Virtual core XTEST pointer’ id=4, does not report Absolute events.
DEBUG: Skipping device ‘Logitech USB Optical Mouse’ id=10, does not report Absolute events.
DEBUG: Skipping device ‘SynPS/2 Synaptics TouchPad’ id=13, does not report Absolute events.
DEBUG: Selected device: SMART Technologies Inc. SMART Interactive Whiteboard Controller (SB6)
DEBUG: Not usbtouchscreen calibrator: Not a usbtouchscreen device
DEBUG: Not evdev calibrator: Evdev: invalid “Evdev Axis Calibration” property format
Calibrating standard Xorg driver “SMART Technologies Inc. SMART Interactive Whiteboard Controller (SB6)”
current calibration values: min_x=0, max_x=65535 and min_y=0, max_y=65535
If these values are estimated wrong, either supply it manually with the --precalib option, or run the ‘get_precalib.sh’ script to automatically get it (through HAL).
DEBUG: Adding click 0 (X=353, Y=85)
DEBUG: Adding click 1 (X=933, Y=83)
DEBUG: Adding click 2 (X=361, Y=650)
DEBUG: Adding click 3 (X=956, Y=646)

–> Making the calibration permanent <–
ERROR: XorgPrint Calibrator does not support the supplied --output-type
Error: unable to apply or save configuration values[/code]

Edit: aggiungo che alla pagina https://www.freedesktop.org/wiki/Software/xinput_calibrator/ viene segnalata come ultima versione di xinput_calibrator la 0.7.5, disponibile per… Fedora 13 (leggasi: TREDICI!) e altre distribuzioni dell’epoca.
Al momento ho la versione 0.7.5 installata dai repository:

$ rpm -qa xinput_calibrator xinput_calibrator-0.7.5-13.fc24.x86_64
Funzionerà ancora un programma che è rimasto alla stessa versione che si usava con Fedora 13, con tutti i cambiamenti intervenuti nel frattempo??? Non mi stupisce che cerchi di usare hal!

Condivido i tuoi dubbi a riguardo i xinput_calibrator… Per questo mi chiedevo se con il più moderno Wayland la situazione fosse migliore.

Diamo un’occhiata anche a questo, se possibile:

$ xinput list-props "SMART Technologies Inc. SMART Interactive Whiteboard Controller (SB6)"

Se il programma che gestisce la calibrazione è tanto vecchio da non funzionare con xorg, ho forti dubbi che possa funzionare con Wayland.
In ogni caso, consultando la https://wiki.archlinux.org/index.php/Calibrating_Touchscreen#Using_nVidia.27s_TwinView (che è sempre ben fatta), e procedendo a tentoni, ho quasi risolto con

$ xinput set-prop "SMART Technologies Inc. SMART Interactive Whiteboard Controller (SB6)" --type=float "Coordinate Transformation Matrix" 1.0 0.0 -0.05 0.0 1.0 0.01 0.0 0.0 1.0

Non è perfetto, ma va molto meglio. Bisognerebbe aggiustare i parametri -0.05 (touch_area_x_offset / total_width) e 0.01 (touch_area_y_offset / total_height), e non sarebbe una cattiva idea scrivere un programma che funzioni, ma già si comincia a ragionare.

Ottimo. Non credo si possa fare di meglio.

No, xinput_calibrator non credo funzioni con Wayland (così come xrandr e altri componenti del “mondo Xorg”). Forse però la LIM funzionerebbe meglio già nativamente, senza bisogno di intervenire con settaggi particolari.

Si può, si può… ma datemi ancora qualche giorno…

La Lim funziona benissimo già ora nativamente; solo che il proiettore manda l’immagine non esattamente sullo schermo touch screen; per questo va calibrata (bisogna spiegare al driver che se sente un click in (x;y) io volevo darlo, a causa dell’immagine che vedo, in (x’;y’).
L’ho detto… datemi qualche giorno.

Ora ho bisogno di aiuto.

Da https://wiki.ubuntu.com/X/InputCoordinateTransformation link leggo che

[code]Using the Coordinate Transformation Matrix

By default, the CTM for every input device in X is the identity matrix. As an example, lets say you touch a touchscreen at point (400, 197) on the screen:

⎡ 1 0 0 ⎤ ⎡ 400 ⎤ ⎡ 400 ⎤
⎜ 0 1 0 ⎥ · ⎜ 197 ⎥ = ⎜ 197 ⎥
⎣ 0 0 1 ⎦ ⎣ 1 ⎦ ⎣ 1 ⎦[/code]

Quindi la regola per ottenere le nuove coordinate (x’;y’) dalle vecchie (x;y) dovrebbe essere la seguente:

⎡ c₁₁ c₁₂ c₁₃ ⎤ ⎡ x ⎤ ⎡ x' ⎤ ⎜ c₂₁ c₂₂ c₂₃ ⎥ · ⎜ y ⎥ = ⎜ y' ⎥ ⎣ c₃₁ c₃₂ c₃₃ ⎦ ⎣ 1 ⎦ ⎣ 1 ⎦

Applicando la regola di moltiplicazione tra matrici, si ottiene che

x'=c₁₁x+c₁₂y+c₁₃ y'=c₂₁x+c₂₂y+c₂₃ 1=c₃₁x+c₃₂y+c₃₃

In particolare, poiché consultando la https://wiki.archlinux.org/index.php/Calibrating_Touchscreen#Calculate_the_Coordinate_Transformation_Matrix si vede che la matrice di trasformazione delle coordinate è

⎡ c₀ 0 c₁ ⎤ ⎜ 0 c₂ c₃ ⎥ ⎣ 0 0 1 ⎦
si ottiene

⎡ c₀ 0 c₁ ⎤ ⎡ x ⎤ ⎡ x' ⎤ ⎜ 0 c₂ c₃ ⎥ · ⎜ y ⎥ = ⎜ y' ⎥ ⎣ 0 0 1 ⎦ ⎣ 1 ⎦ ⎣ 1 ⎦
e quindi

x'=c₀x+c₁ y'=c₂y+c₃

Poiché, nel mio caso, ho rilevato i valori

code -> (179;84.4)
(896;96) -> (877.5;77.6)
(128;672) -> (186;648.4)
(896;672) -> (920.5;654.7)[/code]
segue che, prendendo i valori medi,

x∈[128;896] -> x'∈[182.5;899] y∈[96;672] -> y'∈[81;651.6]
Poiché

x'₂=c₀x₂+c₁ x'₁=c₀x₁+c₁
si ottiene, sottraendo membro a membro,

x'₂-x'₁=c₀(x₂-x₁)

da cui

Ovvero, nel mio caso,

c₀=(899-182.5)/(896-128)≈0.933

Analogamente,

che, nel mio caso, diventa

c₂=(651.6-81)/(672-96)≈0.991

Forse fino a qui siamo a posto.

Ora, per calcolare c₁, ricordiamo che

x'₁=c₀x₁+c₁

e quindi

che, nel mio caso, diventa

c₁=182.5-0.933·128≈63.1

Analogamente,

che, nel mio caso, diventa

c₃=81-0.991·96≈-14.1

E già qui ho ottenuto una stranezza: la guida di Archlinux dice che

[quote=Archlinux]Now, calculate these as accurate as possible:

c₀ = touch_area_width / total_width
c₂ = touch_area_height / total_height
c₁ = touch_area_x_offset / total_width
c₃ = touch_area_y_offset / total_height[/quote]

Quindi secondo la guida di Archlinux c₁ dovrebbe essere l’offset della x diviso la larghezza dello schermo, mentre io ho ricavato c₁ come semplice offset della x (discorso analogo vale per c₃).
Visto il concetto espresso dal primo link (il wiki di Ubuntu), mi fiderei di più dei calcoli fatti moltiplicando le matrici (da cui ho ricavato le mie formule) che della guida di Archlinux (per quanto sia, solitamente, ben fatta).
Solo che la guida di Archlinux dice anche che, per applicare la matrice, bisogna eseguire il comando

xinput set-prop "Device Name" --type=float "Coordinate Transformation Matrix" c₀ 0 c₁ 0 c₂ c₃ 0 0 1

Quindi in teoria dovrei dare

xinput set-prop "Device Name" --type=float "Coordinate Transformation Matrix" 0.933 0 63.1 0 63.1 -14.1 0 0 1

Tuttavia, se provo ad eseguire il comando (in realtà oggi non ho applicato il comando, ma l’ho fatto applicare ad un programma in python che ho scritto, usando nuovi click che ho dimenticato di segnare, ma che non dovrebbero differire sostanzialmente da quelli indicati qui), il cursore sparisce dallo schermo e non riesco più ad usare il touch screen (per l’esattezza, vedo i menù in alto a destra che si aprono anche se il cursore dovrebbe stare al centro dello schermo).

Dove sbaglio?

Credo di aver risolto il problema delle formule. Innanzitutto avevo invertito il ruolo di (x;y) con quello di (x’;y’), e poi avevo sbagliato a dar credito al link di Ubuntu, anziché a quello di Archlinux (potrò mai essere perdonato? :reddy:).

Supponiamo di inserire due cerchietti alle posizioni (x₁;y₁) e (x₂;y₂). Noi clicchiamo sui cerchietti, ma, a causa dello sfasamento tra lo schermo touch screen e il proiettore che ci invia l’immagine, il click viene rilevato rispettivamente alle posizioni (x’₁;y’₁) e (x’₂;y’₂).

Il sistema corregge la posizione del click utilizzando la regola seguente:

⎡ c₀ 0 c₁ ⎤ ⎡ x'/width ⎤ ⎡ x/width ⎤ ⎜ 0 c₂ c₃ ⎥ · ⎜ y'/height ⎥ = ⎜ y/height ⎥ ⎣ 0 0 1 ⎦ ⎣ 1 ⎦ ⎣ 1 ⎦
Dove width e height danno, in pixel, larghezza e altezza della risoluzione dello schermo.

In altre parole, i valori della seconda e terza matrice devono essere compresi tra 0 e 1: per esempio, 0.5 indicherà un valore a metà dello schermo. Non è possibile inserire 400 o 197.

Quindi le formule corrette sono le seguenti:

c₀=(x₂-x₁)/(x'₂-x'₁) c₁=(x₁-c₀*x'₁)/width c₂=(y₂-y₁)/(y'₂-y'₁) c₃=(y₁-c₂*y'₁)/height

Ora sono a buon punto nella scrittura di un programma in python3 (e Gtk 3) per calibrare la LIM, ma mi rimangono due piccoli problemi da risolvere.

  1. Come distinguere, dall’output di un comando, i dispositivi calibrabili da quelli come mouse e affini? xinput_calibrator rileva (giustamente) solo i primi, mentre l’output di “xinput --list” include i dispositivi di puntamento come mouse e touchpad.

  2. La https://wiki.archlinux.org/index.php/Calibrating_Touchscreen#Do_it_automatically_via_a_udev_rule dice che, per rendere permanente la matrice di trasformazione delle coordinate, bisogna scrivere un file 99-*.rules in /etc/udev/rules.d con il seguente contenuto:

[quote=https://wiki.archlinux.org/index.php/Calibrating_Touchscreen#Do_it_automatically_via_a_udev_rule]ENV{ID_VENDOR_ID}==“2149”,ENV{ID_MODEL_ID}==“2703”,ENV{WL_OUTPUT}=“DVI1”,ENV{LIBINPUT_CALIBRATION_MATRIX}=“1 0 0 0 1 0”

Substitute your own touchscreen’s vendor ID, model ID, the xrandr output name, and the calibration matrix that you calculated above. This is based on the assumption that you are using the libinput driver for your touchscreen.[/quote]
Ora, vendor ID e model ID li posso ricavare automaticamente con

$ xinput list-props $id

(nel mio caso $id è 16); ma il nome dato in output da xrandr (quello che devo sostituire a “DVI1”) posso dedurlo in automatico da uno script conoscendo id e nome del touch screen (nel mio caso 16 e “SMART Technologies Inc. SMART Interactive Whiteboard Controller (SB6)”, o devo necessariamente chiedere all’utente di sceglierlo?

Sospetto la seconda, ma aspetto conferme.

N.B. Se qualcuno ne ha la possibilità, potrebbe testare l’rpm che trovate alla pagina http://www.mathhelp.eu/software/calibratetouchscreen/calibratetouchscreeninstall.html?
A me sembra che funzioni (tranne il rendere permanente la matrice, visto che non l’ho ancora implementato), ma l’ho potuto testare solo su una LIM, per il momento.