techlab:projekte:inhouse:tabletap

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
techlab:projekte:inhouse:tabletap [2022/01/19 10:39] – [Input] ivotechlab:projekte:inhouse:tabletap [2022/01/19 11:06] (current) ivo
Line 1: Line 1:
 +====== Tabletap ======
 +  * 3 (oder mehr) Kontaktmikrophone (Piezo) werden auf einem Tisch montiert. Damit soll gemessen werden, wann ein Finger den auf den Tisch tippt. Aus den Laufzeitdifferenzen des Schalls soll die Position bestimmt werden.
 +  * Dazu braucht es erst einmal eine gute Verstärkerschaltung. Erste gute Ergebnisse wurden mit folgender Schaltung erhalten: http://davidhoulding.blogspot.com/2014/02/high-sensitivity-vibration-sensor-using.html {{:techlab:projekte:inhouse:pasted:20220118-173944.png}}
 +  * Video vom Test der Schaltung: https://t.co/bWnQNcHFeu
 +  * Um die Laufzeiten möglichst genau zu messen, verwenden wir Interrupts auf dem ESP32. Ein POC findet sich hier: https://github.com/techlabksbg/tabletap
 +
 +
 +===== Mathematik dahinter =====
 +Der Zeitpunkt, zu dem der Tisch berührt wurde ist nicht bekannt. Es somit nur die Laufzeitdifferenzen zu den einzelnen Mikrophonen bekannt. Kennt man nur zwei Mikrophone (und die Schallgeschwindigkeit), liegt der Berührungspunkt auf einem Hyperbelast.
 +
 +Es sind also Hyperbeln in allgemeiner Lage zu schneiden, was zu potenziell 4 Schnittpunkten führen kann, also Gleichungen 4. Grades.
 +
 +==== Input ====
 +Gegeben:
 +  * Positionen F1, F2, F3 als (x,y)-Koordinaten
 +  * Zeitstempel t1, t2, t3 wann das Signal angekommen ist.
 +
 +Gesucht:
 +  * Position P, wo die Berührung stattgefunden hat. Oder t0, wann die Berührung stattgefunden hat.
 +
 +Annahmen:
 +  * t1<t2 und t1<t3. D.h. F1 hat als erstes die Berührung registriert.
 +  * Schallgeschwindigkeit v bekannt. Es kann also direkt mit den Abstandsdifferenzen gearbeitet werden:
 +  * ¯PF2¯PF1=d2=t2ttv und ¯PF3¯PF1=d3.
 +
 +Ansätze:
 +  * Schnitt zweier Hyperbeläste in «allgemeiner» Lage, wobei jeweils ein Brennpunkt gemeinsam ist. In GeoGebra sieht es so aus, als gäbe es für spitzwinklige Dreiecke F1F2F3 nur genau eine Lösung, für stumpfwinkle aber 2. 
 +  * Affine Transformation einer Hyperbel auf die Form y=1x, die andere in allgemeiner Form schreiben, einsetzen, Polynom 4. Grades lösen (z.B. mit Newton-Verfahren).
 +  * P schätzen, iterativ verbessern (funktioniert ungefähr, Konvergenz ist langsam, speziell wenn P nahe ein einem Fi liegt.
 +  * Abstände in Funktion von t0 schreiben, nummerisch auflösen.
 +
 +
 +=== r=¯PF1 bestimmen ===
 +Sei s=¯F1F2.
 +
 +Sei fx=1sF1F2 und fy der um +90 gedrehte fx.
 +
 +Sei nun OP=OF1+afx+hfy. Dann gilt:
 +r2a2=(r+d2)2(sa)2
 +
 +Daraus folgt
 +a=s22d2rd222s
 +und
 +$$
 +h^2 = r^2-a^2 = r^2-{{\left(s^2-2\,d_{2}\,r-d_{2}^2\right)^2}\over{4\,s^2}} = -{{s^2}\over{4}}-{{d_{2}^2\,r^2}\over{s^2}}-{{d_{2}^3\,r}\over{s^2
 + }}-{{d_{2}^4}\over{4\,s^2}}+r^2+d_{2}\,r+{{d_{2}^2}\over{2}}
 +$$
 +Das ist Polynom 2.Grades in r mit den Koeffizienten (aufsteigende Potenzen von r):
 +<code txt>
 +[-((s-d_2)^2*(s+d_2)^2)/(4*s^2),(d_2*(s-d_2)*(s+d_2))/s^2,((s-d_2)*(s+d_2))/s^2]
 +</code>
 +
 +Seien (x,y) die Koordinaten von F3 im System (F1,fx,fy).
 +
 +Es gitl ¯PF3=r+d3:
 +
 +$$\left(y-\sqrt{r^2-{{\left(s^2-2\,d_{2}\,r-d_{2}^2\right)^2}\over{4
 + \,s^2}}}\right)^2+\left(x-{\it as}\right)^2=r+d_{3}
 +$$
 +
 +$$y^2-2\,\sqrt{-{{s^2}\over{4}}-{{d_{2}^2\,r^2}\over{s^2}}-{{d_{2}^3
 + \,r}\over{s^2}}-{{d_{2}^4}\over{4\,s^2}}+r^2+d_{2}\,r+{{d_{2}^2
 + }\over{2}}}\,y+x^2-2\,{\it as}\,x-{{s^2}\over{4}}-{{d_{2}^2\,r^2
 + }\over{s^2}}-{{d_{2}^3\,r}\over{s^2}}-{{d_{2}^4}\over{4\,s^2}}+r^2+
 + d_{2}\,r-r-d_{3}+{{d_{2}^2}\over{2}}+{\it as}^2=0$$
 +
 +Wurzel isolieren, quadrieren, alles auf eine Seite, mit 16s4 erweitert liefert folgendes Polynom vierten Grades in r:
 +
 +<code maxima>
 +eq: r^2-a^2 = (r+d_2)^2-(s-a)^2;
 +ar:rhs(solve(eq, a)[1]);
 +h2: r^2-ar^2;
 +string(create_list(factor(coeff(expand(h2),r,i)),i,0,2));
 +eq2: (x-ar)^2+(y-sqrt(h2))^2 = r+d_3;
 +expand(eq2)-rhs(eq2);
 +string(expand(eq2)-rhs(eq2));
 +eq3:expand(eq2)-rhs(eq2);
 +string(eq3);
 +eq4:eq3+2*sqrt((-s^2/4)-(d_2^2*r^2)/s^2-(d_2^3*r)/s^2-d_2^4/(4*s^2)+r^2+d_2\
 +*r+d_2^2/2)*y;
 +eq5: expand(lhs(eq4)^2) = expand(rhs(eq4)^2);
 +eq6: eq5-rhs(eq5);
 +create_list(factor(coeff(lhs(eq6),r,i))*s^4*16,i,0,4);
 +</code>
 +
 +
 +=== Weiter buddeln ===
 +$$h^2 = -{{\left(s-d_{2}\right)\,\left(s+d_{2}\right)\,\left(s-2\,r-d_{2}
 + \right)\,\left(s+2\,r+d_{2}\right)}\over{4\,s^2}}$$
 +
 +Die Gleichung erst mal h geschrieben:
 +
 +(yh)2+(xa)2=r+d3
 +
 +h isoliert:
 +
 +y2+x22axr+h2d3+a2=2hy
 +
 +quadriert:
 +
 +(y2+x22axr+h2d3+a2)2=4h2y2
 +
 +Alles nach links, Faktorisieren, Freude haben (und dann wieder nicht, weil wieder h drin vorkommt):
 +
 +$$\left(y^2-2\,h\,y+x^2-2\,a\,x-r+h^2-d_{3}+a^2\right)\,\left(y^2+2\,
 + h\,y+x^2-2\,a\,x-r+h^2-d_{3}+a^2\right)=0$$
 +
 +Man kommt schlussendlich wieder auf das gleiche Polynom wie vorher:
 +
 +<code txt>
 +[(s^2*y^4+2*s^2*x^2*y^2-2*s^3*x*y^2+2*d_2^2*s*x*y^2+s^4*y^2-2*d_3*s^2*\
 +y^2-2*d_2^2*s^2*y^2+d_2^4*y^2+s^2*x^4-2*s^3*x^3+2*d_2^2*s*x^3+s^4*x^2-2*d_3*s^\
 +2*x^2-2*d_2^2*s^2*x^2+d_2^4*x^2+2*d_3*s^3*x-2*d_2^2*d_3*s*x+d_3^2*s^2)/s^2,(2*\
 +(2*d_2*s*x*y^2-2*d_2*s^2*y^2-s^2*y^2+2*d_2^3*y^2+2*d_2*s*x^3-2*d_2*s^2*x^2-s^2\
 +*x^2+2*d_2^3*x^2+s^3*x-2*d_2*d_3*s*x-d_2^2*s*x+d_3*s^2))/s^2,-(2*s^2*y^2-4*d_2\
 +^2*y^2-2*s^2*x^2-4*d_2^2*x^2+2*s^3*x-2*d_2^2*s*x+4*d_2*s*x+2*d_3*s^2-s^2)/s^2,\
 +(2*(2*d_2*x-s))/s,1]
 +</code>
 +
 +<code maxima>
 +eq10: (x-a)^2+(y-h)^2=r+d_3;
 +eq11:expand(eq10)-rhs(eq10)+2*h*y;
 +eq12:eq11^2;
 +h2: factor(expand(r^2 - ar^2));
 +eq13:expand(eq12-rhs(eq12)), h^2=h2;
 +string(%);
 +eq14: eq13, a=ar;
 +eq15:factor(eq14*s^2);
 +create_list(factor(coeff(expand(lhs(eq14)),r,i)),i,0,4);
 +</code>