Release version 0.6.0 of Debug Visualisation viewRelease version 0.6.0 of Debug Visualisation view
After many hours of work we finally managed to release a new version of the Debug Visualisation project! This release is a complete rewrite of the previous version (0.5.X), and now it is built upon the JFace API and other standard eclipse technologies instead of different custom hackings. We expect improved stability and maintainability from the new techniques, which means that we can implement more advanced features in the plugin.
Currently, the new version does not include all functionality what the old version did, but we’re sure we will manage to reach it soon. For more information about this release, please refer to the release announcement.
Érdekes problémákba ütközik az ember, ha eclipse környékén fejleszt. Ezek nagyrészét ugyan már megoldották, de a megoldást külön művészet megtalálni a tengernyi dokumentációban. Mindenesetre legalább dokumentálták. A probléma, amiben pár napja az örömömet leltem, az az, hogy hogyan lehet egy nézet által kiválasztott elemeket átadni egy másik nézetnek, ami természetesen hasonló modell felett dolgozik. Konkrétan a Debug Visualisation projektem által definiált nézetet akartam összekötni a Variables View-vel és vice-versa.
Érdekes problémákba ütközik az ember, ha eclipse környékén fejleszt. Ezek nagyrészét ugyan már megoldották, de a megoldást külön művészet megtalálni a tengernyi dokumentációban. Mindenesetre legalább dokumentálták. A probléma, amiben pár napja az örömömet leltem, az az, hogy hogyan lehet egy nézet által kiválasztott elemeket átadni egy másik nézetnek, ami természetesen hasonló modell felett dolgozik. Konkrétan a Debug Visualisation projektem által definiált nézetet akartam összekötni a Variables View-vel és vice-versa.
Pár óra keresgélés és javadoc olvasgatás után rábukkantam a megoldásra: Minden view-t tartalmazó IWorkbenchPartSite lehetőséget biztosít egy ISelectionProvider regisztrálására, amely interfészt ad kiválasztási információk kinyerésére és átadására, továbbá listener-ek regisztrálására. A másik, csatlakoztatni kívánt view által megadott ISelectionProvider-nek az általunk generált kiválasztási eseményeket át lehet adni, illetve figyelni lehet az általa generált ilyen eseményeket.
A problémát csak az okoz, hogy egy adott view által generált és elfogadott kiválasztandó elemek az adott view modelljéből kerül ki, tehát ugyanezen modell elemeit kell neki átadni. Ha az általunk írt view más modellen, vagy ugyanazon modell felett máshogy definiálja a kiválasztást, akkor a kiválasztást konvertálni kell a modellek között. Ez természetesen csak akkor oldható meg, ha egyáltalán értelmezhető a közös kiválasztás.
Mindehhez persze az első lépés az, hogy megtaláljuk a csatlakoztatni kivánt view-t, amit az azonosítójának ismeretében tehetünk meg a következő módon:
ahol a [cci_java]viewID[/cci_java] helyére a keresett view szöveges azonosítóját kell megadni. A Variables View azonosítóját az org.eclipse.debug.ui plugin egy [cci_java]IDebugUIConstants[/cci_java] nevű publikus interfész elérhetővé teszi.
Mint az eclipse esetében általában erre problémára is egy jól kitalált megoldás létezik, ami megfelelően egyszerű ahhoz, hogy a módszer ismeretében könnyű legyen implementálni, a nehézséget csak a módszer megtalálása jelenti.
Aki fejlesztett már Eclipse PDE felett, az talán találkozott a lehetőséggel, hogy egy extension point tulajdonság típusa lehet “resource” is. Ez annyit tesz, hogy a kiterjesztésben megadhatunk egy, a plugin-nel csomagolt fájlt. De a másik oldalon, az extension point beolvasásakor hogyan is olvassuk ezt be? Hiszen fogalmunk sincs honnan jött, melyik plugin adja az extension-t, és hol keressük a fájlt. A megoldás nem triviális, és kell egy kis kutatást végezni, hogy rájöjjünk. Én ezt megtettem, és igyekszem közérthető formában továbbadni.
Aki fejlesztett már Eclipse PDE felett, az talán találkozott a lehetőséggel, hogy egy extension point tulajdonság típusa lehet “resource” is. Ez annyit tesz, hogy a kiterjesztésben megadhatunk egy, a plugin-nel csomagolt fájlt. De a másik oldalon, az extension point beolvasásakor hogyan is olvassuk ezt be? Hiszen fogalmunk sincs honnan jött, melyik plugin adja az extension-t, és hol keressük a fájlt. A megoldás nem triviális, és kell egy kis kutatást végezni, hogy rájöjjünk. Én ezt megtettem, és igyekszem közérthető formában továbbadni.
A probléma, kicsit formálisabban: adott egy extension point, melyen egyik attributúma resource típusú. Mikor egy plugin extension-t csatol ehhez a ponthoz, az adott attríbutúmnak úgy ad értéket, hogy a programozó kiválaszt egy fájlt, amit a pluginnel együtt csomagolva ad. Az extension point-ot adó plugin pedig az ilyen módon regisztrált fájlokat szeretné beolvasni.
Amikor beolvassuk ezt az értéket az extension-ből, a fájl relatív elérési útvonalát kapjuk meg a plugin csomagjában. Első feladatunk tehát, megtalálni a plugin csomagot ([[http://www.osgi.org/javadoc/r4v41/org/osgi/framework/Bundle.html|Bundle]]), ahonnan az extension jött, hiszen abban kell keresni a fájlt is. Ha megvan a csomag, kérhetünk tőle egy URL-t a fájlhoz. A kapott URL azonban nem szokványos, “bundleresource:” előtaggal rendelkezik. Korábban létezett egy asLocalUrl() függvény, ami az ilyen jellegű URL-t hivatott átalakítani abszolút “file:” URL-é. Azonban ez a függvény a 3.2-es verzióban @Deprecated megjegyzést kapott, tehát ez nem a megfelelő mód a megnyitásra. Szerencsére azonban az ilyen URL-ekhez implementálták az URL.openStream() metódust, ami nyit egy megfelelő adatfolyamot a számunkra. Kicsit egyszerűsítve a kód valahogy így néz ki:
//Listázzuk az extension point-hoz csatolt extension-öket:
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint point = registry.getExtensionPoint("ExtensionPointID");
for (IExtension extension : point.getExtensions()){
//Így kell lekérni az extension-t adó plugin csomagot:
Bundle bundle = Platform.getBundle(extension.getNamespaceIdentifier());
for (IConfigurationElement element : extension.getConfigurationElements()){
//A csomagon belüli relatív elérési út:
String path = element.getAtribute("resourceAttrib");
URL url = bundle.getResource(path);
InputStream is = url.openStream();
//...Olvasás...
}
}
Aki figyelemmel kisérte a nem rég [[Debug vizualizáció Eclipse-hez|bejelentett]] projektet, az már tudhat róla, hogy pár hónapja működik egy eclipse update site a honlapon. Az említett projekt [[http://code.google.com/p/debugvisualisation/|honlapján]] egy ideje már bejelentettük a létezését, de az itteni kihirdetés idő és kedv hiányában késett egy kicsit.
Tehát a lényeg: az eclipse menüben Help/Software Updates../Available Software/Add Site..: http://eclipse.cubussapiens.hu
Aki figyelemmel kisérte a nem rég [[Debug vizualizáció Eclipse-hez|bejelentett]] projektet, az már tudhat róla, hogy pár hónapja működik egy eclipse update site a honlapon. Az említett projekt [[http://code.google.com/p/debugvisualisation/|honlapján]] egy ideje már bejelentettük a létezését, de az itteni kihirdetés idő és kedv hiányában késett egy kicsit.
Tehát a lényeg: az eclipse menüben Help/Software Updates../Available Software/Add Site..: http://eclipse.cubussapiens.hu
Jelenleg egyetlen feature található rajta, de ahogy az időnk engedi, ez a kör bővülhet. Addig is használjátok egészséggel ezt az egyet, és nyugodtan küldjetek hibajelzést/kivánságot a projekt oldalára.
Végre hosszú idő után előkerült a PICkit a fiókból. Az [intlink id=”559″ type=”post”]el%u0151z%u0151 PIC[/intlink]-es próbálkozásom után most egy kicsit bonyolultabb probléma megoldására vállalkoztam. Konkrétan arra, hogy a kütyü képes legyen érzékelni valakinek a jelenlétét. Erre a leggyakrabban alkalmazott módszer infravörös fényt vetít a vizsgált térrész felé, és méri a visszaverődött fény mennyiségét. Minél több fény verődik vissza, annál közelebb van a tárgy, amiről visszaverődött. Az elmélet egyszerű, és mint azt a továbbiakban olvashatjátok, a gyakorlat se sokkal bonyolultabb.
Az első probléma ami felmerült, az a jelentős háttérzaj kérdése. Az infravörös tartományban a nap és a legtöbb mesterséges fényforrás is sugároz, ráadásul sokkal erősebben, mint egy ilyen alkalmazásban szóba jöhető infra-led. A háttérzaj és az infra-led jelét szétválasztani csak úgy lehet, ha modulált jelet sugározunk a térbe, és ezt a modulált jelet keressük a mért értékekben is. Léteznek olyan infra-vevők, melyek hardveresen támogatják a modulált jel érzékelését (pl. TSOP), de hasonló alkatrészt tucatnyi boltot körbejárva sem találtam (ha tud valaki olyan boltot, ahol vásárolható ilyen, kérem írjon). Ilyen célezköz hiányában a modulációt szoftveresen oldottam meg.
A szoftveres moduláció miatt a hardver rendkívül egyszerű lett, a következő alkatrészekre volt szükségem:
Pic16F690
1db infra led
1db fotodióda
1db npn tranzisztor
4db 1kOhm ellenállás
2db vörös led (egy a bekapcsolt állapotot jelzi – folyton világít, egy pedig a végeredményt adja meg, hogy érzékel-e jelenlétet az eszköz)
A munkát minimalizálandó felhasználtam a programozóhoz adott próbapanelt, amin beépített ledek állnak rendelkezésre, ezeket felhasználtam az állapotjelzések számára, így csak a fotódiódát és az infraledet kell hozzákötni, ami egy breadboard segítségével könnyedén kivitelezhető. Az infra-ledet a PIC rc0 kimenete fogja meghajtani, egy ellenállással bekötve ez a rész készen van. A kimenetet jelző led az rc1, a power-led az rc2-re van kötve hasonló módon. A fotódiódát a tranzisztorral erősítve kötjük a beépített A/D konverter bemenetére, hogy erősebb jelet kapjunk, ezzel megnövelve az érzékelés felbontását. A további félreértések rövidre zárásához felraktam egy kapcsolási rajzot:
A szoftver ezzel a következő módon tud együttműködni: az alapötlet az, hogy kikapcsolt infra-leddel lemérjük a bejövő fény mennyiségét, majd bekapcsoljuk az infrát, és újra mérünk. A bekapcsolt illetve kikapcsolt infra-led melletti mérések különbsége adja meg az infra-led által leadott és visszavert fény mennyiségét. Ha ez a különbség több iteráció után is meghaladja a küszöbértéket, akkor a kimeneten jelezzük az érzékelt jelenlétet. Azaz két paraméter a küszöbérték (mekkora különbséget várunk el kikapcsolt és bekapcsolt infra-led melletti mérések között), és a kitartás (hány iteráción át kell tartani ezt a különbséget).
És íme, a kód. A dolog nehézségét jelzi, hogy a legtöbb időt két érték összehasonlítása vette el. A kódban szereplő makrót a Microchip MPasm leírásából vettem, én egy kétszer olyan hosszú megoldást csináltam elötte.
;presence detector code.
;assumed peripheres:
; infra-led on RC0
; photo-diode connected to AN0
; detected proximity output on RC1
; power led on RC2
;
;we measure input on photo diode, while infra-led is turned off.
;then we measure again with turned on infra-led.
;if the infra-ray is reflected from anything, the second measurement
;should return a higher value
cblock 0x20
offmeasure ;stores measurement without infra led
onmeasure ;stores measurement with infra led
output ;output bits
waitcount ;wait count
surecount ;make sure that something is there and not moves
endc
OUT_ILED EQU H’0000′ ;bit for infra led
OUT_RES EQU H’0001′ ;bit for output
OUT_POWER EQU H’0002′ ;power led
THRESHOLD EQU H’0002′ ;threshold for measurment gain
SURENESS EQU H’000C’ ;number of measurements before we’re sure in the result
;======================================================
; compare file to constant and jump if file
; >= constant.
;======================================================
cfl_jge macro file, con, jump_to
movlw con & 0xff
subwf file, w
btfsc STATUS, C
goto jump_to
endm
;===============================================
;==============MAIN PROGRAM=====================
;===============================================
org 0
Init:
;set variables to zero
movlw 0x00
movwf output
movwf onmeasure
movwf offmeasure
;set powerled on
bsf output,OUT_POWER
;initialize devices
SELECT_BANK1
movlw 0xFF
movwf TRISA ; Make PortA all input
clrf TRISC ; Make PortC all output
movlw 0x10 ; A2D Clock Fosc/8
movwf ADCON1
SELECT_BANK2
movlw 0xFF ; we want all Port A pins Analoge
movwf ANSEL
SELECT_BANK0
movlw 0x01
movwf ADCON0 ; configure A2D for Channel 0 (RA0), Left justified, and turn on the A2D module
Loop:
MEASURE ;measure with light off
SWITCH_ILED ;turn light on
REFRESH_OUTPUT
call SubWait ;wait a bit
MEASURE ;measure with light on
SWITCH_ILED ;turn light off
call DecideOutput ;decide output
REFRESH_OUTPUT
call SubWait ;wait a bit
goto Loop
;===========================================
;===========Subroutine for long wait========
;===========================================
SubWait:
movlw 0xFF
movwf waitcount
StartWait:
WAIT 100
decfsz waitcount,F
goto StartWait
return
;===============================================
;=====PROGRAM END===============================
;===============================================
end
A kütyüt felprogramoztam, a perifériákat megépítettem, és pár iteratív hibajavítás/paraméterfinomítás után eljutottam arra az állapotra, amit elégségesnek neveztem a koncepció működésének a bizonyítására.
A fenti köntörfalas megfogalmazás nem költői önkifejezés, és nem is véletlen. Az eszköz működik, de épp hogy. A környezet által kifejtett fényerő fehérzajként adódik a rendszerhez, és csak magas “kitartás” és “küszöbérték” paraméter mellett lehet kiszűrni a téves jelzéseket. Ennek az az eredménye, hogy kb. két másodperc után jelzi ha 5cm-nél közelebb teszem a kezemet az infra-led+fotódióda pároshoz. 10cm-nél már bizonytalan a mérés, és akkor is előfordul egy-egy téves jelzés, ha nincs semmi a közelben.
Ezen problémák orvoslására több ötletem is van, egy részük azonnal megoldódna, ha találnék egy rendes infra adó-vevőt. Persze ötleteket, javaslatokat, hasonló problémákban szerzett tapasztalatokat szívesen fogadok.