3d scanner ro
TRANSCRIPT
Universitatea Valahia Târgovişte
Facultatea de Inginerie Electrică
Specializarea Automatică şi Informatică Industrială
PROIECT DE DIPLOMĂ
DIGITIZAREA AUTOMATĂ
A MODELELOR TRIDIMENSIONALE
Student: Banu Cosmin
Îndrumător: Conf. Dr. Ing. Dumitrache Cristian
Anul: 2006
1
CUPRINS
1. Prezentarea generală a conceptului de scanner 3D
1.1. Prezentarea temei proiectului
1.2. Principiul digitizării informaţiei analogice
1.3. Tipuri de scannere 3D (avantaje şi dezavantaje)
1.4. Domenii de interes şi utilizări
2. Algoritmul geometric pentru obţinerea modelului în trei dimensiuni
3. Descrierea componentelor hardware folosite
3.1. Folosirea modulului diodă laser pentru linia de scanare
3.2. Rotirea obiectului cu ajutorul motorului pas cu pas
3.3. Comandarea laserului şi motorului prin portul paralel
3.4. Utilizarea camerei video pentru obţinerea datelor de prelucrare
4. Montajul electric pentru controlarea laserului şi motorului
4.1. Protecţia portului paralel
4.2. Realizarea controlului motorului pas cu pas
4.3. Pornirea si oprirea laserului cu ajutorul portului paralel
4.4. Sursele de alimentare necesare funcţionării circuitelor şi motorului
4.5. Schema circuitului electric final
5. Aplicaţiile software folosite pentru dezvoltarea aplicaţiei principale
5.1. Despre mediul de programare Visual Studio 2005
5.2. Modele de programare software utilizate (OOP, DP)
5.3. Lista limbajelor de programare folosite (C#, C++/CLI, XAML)
5.4. Librăriile software utilizate
5.5. Schema bloc a aplicaţiei finale şi a librăriilor utilizate
6. Aplicaţia software de control a dispozitivelor şi prelucrare a datelor
6.1. Librării proprii create pentru a fi utilizate în aplicaţia principală
6.1.1. Clasa ParallelPort (foloseste inpout32.dll) realizează trimiterea de date
spre portul paralel
6.1.2. Clasa Laser abstractizeaza controlul laserului (oprirea si pornirea
acestuia)
6.1.3. Clasa Motor configurează şi controlează un motor pas cu pas
2
6.1.4. Clasa Camera înglobează caracteristicile video şi funcţionalitatea unei
camere web
6.1.5. Spaţiul ImageUtils realizează procesarea informaţiei video obţinute de la
camera web
6.1.5.1. Clasa Filters identifică diferenţele apărute de la o imagine la alta
6.1.5.2. Clasa Converters converteşte între cele două formate de imagine
6.1.5.3. Clasa Processors realizează identificarea liniei de scanare şi
transpunerea acesteia în spaţiul tridimensional
6.1.6. Clasa Model3D înglobează informaţia obiectului scanat
6.1.7. Clasa Model3DPreview realizează afişarea modelului
6.1.8. Clasa Transforms realizează transpunerea liniei de scanare din imagine
în format bidimensional şi în format tridimensional
6.2. Aplicaţia principală de configurare şi utilizare a scannerului
6.2.1. Setarea parametrilor pentru scanarea obiectelor
6.2.2. Controlarea scanării obiectului
6.2.3. Vizualizarea modelului scanat sub diferite forme (nor de puncte, linii de
scanare, mesh, suprafaţă)
6.2.4. Editarea norului de puncte obţinut
6.2.5. Salvarea, încărcarea şi publicarea modelului scanat
7. Concluzii asupra proiectului final
8. Sitografie
9. Alte resurse
10. Anexă cod sursă
3
1. Prezentarea generală a conceptului de scanner 3D
1.1. Prezentarea temei proiectului
Proiectul îşi propune realizarea unui scanner de obiecte tridimensionale, folosind un
modul diodă laser tip linie, un motor pas cu pas, si o camera web, conectate la un
calculator.
Scannerul este un scanner fără contact, activ, bazat pe metoda triangulaţiei. Obiectul
de scanat este asezat pe o masa rotativă, controlată de un motor pas cu pas. Motorul
este controlat la rândul lui prin portul paralel al unui calculator PC. Un modul laser
este folosit pentru a „desena” o linie roşie subţire pe obiect. Forma liniei (vazută din
alt unghi) este captată cu ajutorul unei camere web, conectata la portul USB al
calculatorului. În figura următoare este prezentată o schemă care arată cum sunt
poziţionate diferitele componente într-un caz real:
Fig. I-1. Elementele constituente ale dispozitivului de scanare
4
Laser
Camera
Masa rotativa
Obiect
Coordonatele camerei, laserului şi obiectului, precum şi orientarea acestora, sunt
cunoscute dinainte. La un anumit pas, sunt achiziţionate două imagini de la cameră:
una când laserul este stins, şi alta când este aprins. Prin compararea celor două
imagini, se poate determina linia laserului. În continuare trebuie stabilită poziţia în
spaţiul 3D a fiecărui punct de pe linie. Deoarece se cunoaşte poziţia şi geometria
camerei, precum şi pozitia laserului, se poate determina poziţia folosind algoritmul de
intersecţie al unei linii cu un plan (linia fiind raza ce porneşte din centrul vizual al
camerei şi trece prin respectivul punct roşu de pe linia de scanare; iar planul fiind cel
determinat de planul vertical de iluminare al laserului).
Aşadar linia roşie este convertită într-o serie de puncte în spaţiul 3D (care este o
aproximare digitala a liniei roşii ce iluminează obiectul). Rotind obiectul cu un anumit
pas unghiular, putem efectua operaţia din nou, şi obţinem astfel o nouă serie de puncte.
Dupa terminarea paşilor, seriile de puncte formează un nor de puncte. Acesta este de
fapt norul de puncte ce aproximează suprafaţa obiectului. În continuare, acesta poate fi
convertit din serii de puncte în linii, în mesh, sau în suprafaţă poligonală.
1.2. Principiul digitizării informaţiei analogice
Proiectul realizează digitizarea modelelor din lumea reală, şi transpunerea lor în spaţiul
3D, pe calculator. Termenul de digitizare este definit astfel: procesul de capturare a
caracteristicilor unei entităţi analogice sub forma unei colecţii de digiţi binari, folosind
un aparat pentru scanare. Digitizarea este o precondiţie pentru stocarea electronică,
cum ar fi stocarea magnetică, sau pe discuri optice.
Un exemplu des întâlnit de digitizare este scannerul de documente. Acesta transformă
documentul de scanat într-o imagine stocată pe calculator sub format binar.
Dezvoltând această idee, putem include aici şi eventuala procesare ulterioară a
imaginii obţinute, în scopul recunoaşterii caracterelor (OCR – Optical Character
Recognition, Recunoaşterea Optică a Caracterelor).
5
Un scanner 3D este un dispozitiv care analizează un obiect sau un mediu din lumea
reală, în scopul colectării de informaţie asupra formei şi chiar culorii acestuia.
Informaţiile colectate pot fi folosite apoi pentru construirea unor modele digitale
tridimensionale ce pot fi folosite într-o varietate de aplicaţii. Aceste dispozitive sunt
folosite extensiv în industrie, în realizarea de exemplu a filmelor şi jocurilor video.
Alte întrebuinţări cuprind proiectarea şi realizarea de protipuri, vizualizarea
computerizată, documentarea artifactelor culturale, etc.
1.2. Tipuri de scannere 3D (avantaje şi dezavantaje)
Există două tipuri de scannere 3D: cu contact, şi fără contact.
Scannerele cu contact testează obiectul prin atingere fizică. Un CMM (maşină de
măsurare a coordonatei) este un exemplu de scanner 3D cu contact. Este în principal
folosit în industria manufacturiera şi poate fi foarte precis. Dezavantajul CMM este
acela că necesită contactul cu obiectul de scanat. Aşadar, prin simpla scanare a
obiectului, acesta se poate modifica sau chiar deteriora. Acest fapt este foarte
important dacă este să luăm în considerare obiectele delicate sau foarte valoroase, cum
ar fi artifactele istorice. Un alt dezavantaj al CMM-urilor este acela ca sunt relativ
încete în comparaţie cu celelalte metode de scanare. Manevrarea fizică a braţului de
care este ataşat obiectul poate fi foarte înceată, iar cele mai rapide dispozitive nu pot
depăsi câteva sute de herţi. Spre deosebire, un scanner cu laser poate opera de la 10 la
500 kHz.
Scannerele fără contact pot fi împărţite mai departe în două categorii principale,
scannere active şi scannere pasive. Există o varietate de tehnologii în fiecare din aceste
categorii.
Scannerele active emit un tip de unde şi detectează reflecţia acesteia pentru a analiza
obiectul sau mediul. Tipuri posibile de unde cuprind razele luminoase, ultrasunetele
sau razele X. Scannerele cu timp-de-zbor folosesc lumina laser pentru probarea
6
obiectului. Din moment ce viteza luminii este cunoscută, poate fi folosit timpul-de-
zbor pentru a determina distanţa (timpul-de-zbor este măsurat ca diferenţa dintre
momentul emiterii pulsului laser, şi momentul în care acesta ajunge la detector).
Scannerele cu triangulare sunt tot un tip de scannere active care folosesc lumina laser
pentru a analiza obiectul. Spre deosebire de scannerele cu timp-de-zbor, cele cu
triangulare emit o rază laser pe subiect şi folosesc o cameră pentru detectarea poziţiei
punctului. În funcţie de distanţa până la obiect, punctul laser apare în poziţii diferite în
câmpul de vedere al camerei. Această tehnică se numeşte triangulare deoarece punctul
laser, camera şi modulul laser formează un triunghi. Lungimea unei laturi a
triunghiului, distanţa dintre cameră şi modulul laser, este cunoscută. Unghiul sub care
este poziţionat modulul laser este de asemenea cunoscut, la fel şi unghiul camerei. Cu
aceste trei date putem determina precis forma şi dimensiunea triunghiului, şi astfel
putem afla poziţia punctului laser. De obicei, în locul unui modul laser de tip punct,
este folosit un modul laser de tip linie (care emite o dungă laser).
Scannerele pasive nu emit nici o radiaţie, ci se bazează pe detectarea reflecţiei radiaţiei
ambientale. Majoritatea scannerelor de acest tip detectează lumina vizibilă, deoarece
este o radiaţie ambientală deja disponibilă. Alte tipuri de radiaţie, cum ar fi cea în
infraroşu, pot fi de asemenea folosite. Metodele pasive pot fi foarte ieftine, deoarece în
majoritatea cazurilor nu necesită dispozitive speciale. Sistemele stereoscopice de
obicei folosesc două camere video, aşezate una în apropierea celeilalte, şi analizând
aceeaşi scenă. Comparând diferenţele subtile dintre imaginile văzute de către fiecare
cameră, este posibilă determinarea distanţei până la fiecare punct din imagine. Această
metoda se bazează pe vederea stereoscopică a omului. Un alt tip de scannere pasive
sunt bazate pe metoda siluetei. Acestea folosesc contururile create de o secvenţă de
imagini luate în jurul unui obiect tridimensional care contrastează puternic cu fundalul.
Aceste siluete sunt extrudate şi intersectate pentru a forma o „păstaie” vizuală (eng:
visual hull) a obiectului. Folosind aceasta tehnică, unele tipuri de concavităţi ale
obiectului (cum ar fi interiorul unei vaze) nu sunt detectate.
Norii de puncte produşi de scannerele 3D nu sunt de obicei folosiţi în mod direct.
Majoritatea aplicaţiilor nu folosesc puncte de nori, ci folosesc modele 3D poligonale în
7
schimb. Procesul de convertire a unui nor de puncte într-un model poligonal 3D poartă
denumirea de reconstrucţie. Reconstrucţia constă în detectarea şi conectarea punctelor
adiacente cu scopul de a crea o suprafaţă continuă. În acest scop există mai mulţi
algoritmi.
1.4. Domenii de interes şi utilizări
Posibilitatea de scanare a obiectelor 3D deschide o serie de posibilităţi în diferite
domenii, cum ar fi cel manufacturier, arheologic, medical, şi chiar personal. În
domeniul manufacturier scannerele pot fi folosite pentru inspectarea suprafeţelor
produselor (pentru a ne asigura că obiectele produse se încadrează în standarde),
ingineria inversă (eng: reverse engineering), duplicarea obiectelor (producerea de
replici). În arheologie, scannerele pot fi folosite pentru a înregistra forma obiectelor, în
vederea stocării electronice, sau în scopul prelucrării ulterioare. De multe ori muzeele
sunt îngrijorate când sunt puse în situaţia de a expune obiecte fragile, cum ar fi oase de
dinozaur, vase din lut, sau ţesături, dar folosind scannerele 3D, acestea pot fi scanate şi
replicate, iar originalele sunt păstrate la loc sigur. În domeniul medical, se pot folosi
pentru scanarea formei corpului uman, sau a oaselor, pentru proteze dentare. De
exemplu putem scana forma unui os rupt, iar prin prelucrarea pe calculator, se poate
proiecta proteza. Este posibilă chiar generarea unui duplicat al osului, şi înlocuirea
porţiunii afectate cu un os artificial. În domeniul jocurilor pe calculator sau a filmelor,
scannerul poate fi folosit pentru digitizarea unor modele deja disponibile.
8
2. Algoritmul geometric pentru obţinerea modelului în trei
dimensiuni
Pentru a simplifica modul de explicare, se va considera transpunerea unui singur punct
din imaginea obţinută de camera web în spaţiul tridimensional. Datele necesare acestei
transformări sunt: poziţia punctului în imagine, unghiul de apertură al camerei (eng:
fov angle), aspectul imaginii (eng: aspect ratio), distanţa de la cameră până la centrul
de rotire al obiectului, unghiul făcut de laser cu direcţia camerei. În figura următoare
sunt prezentaţi parametrii necesari:
Fig. II-1. Parametrii geometrici necesari calculării poziţiei punctelor
unde:
dist – distanţa de la cameră până la centrul de rotire al obiectului
alfa – unghiul dintre direcţia laserului şi direcţia camerei
beta – unghiul camerei (fov angle)
wi – lăţimea imaginii
hi – înălţimea imaginii
wi/hi – aspectul imaginii (aspect ratio)
Fie punctul considerat P(xi, yi) în interiorul imaginii (0 xi < wi, 0 yi < hi).
Raportând fiecare coordonată la maximul ei, vom obţine valori între 0 şi 1 (x = xi / wi,
y = yi / hi). Considerând d distanţa din centrul camerei până la planul de vizualizare al
9
alfa beta
distwi
hi
camerei, putem determina în spatiul tridimensional lăţimea şi înălţimea imaginii (d –
ct.):
Fig. II-2. Parametrii geometrici ai camerei web
Aşadar, în planul camerei punctul din imagine are coordonatele S(xs, ys, zs), unde:
Punctul de centru al camerei are coordonatele C(0, 0, d). Considerând N normala la
planul vertical al laserului, punctul în spaţiu se va obţine astfel:
10
w
h
d
x
y
beta
S
C
3. Descrierea componentelor hardware folosite
3.1. Folosirea modulului diodă laser pentru linia de scanare
Laserul (acronim pentru “Light Amplification by Stimulated Emission of Radiation” –
“Lumină Amplificată prin Stimularea Emisiei de Radiaţie”) este o sursă optică ce
emite fotoni într-un fascicul coerent. Deşi cuvântul LASER provine de la o
prescurtare, el a fost inclus în diferite limbi ca un cuvânt separat (un acronim), de
aceea el se scrie cu litere mici. În limba engleză, s-a format şi verbul “to lase”,
însemnând “producerea de lumina coerentă prin emisie stimulată”.
Lumina laser este în mod obişnuit aproape-monocromatică, adică ea consistă dintr-o
singură lungime de undă sau culoare, şi este emisă într-un fascicul îngust. Este deci
foarte diferită de sursele de lumină obişnuite, cum ar fi becul cu incandescenţă, care
emite fotoni incoerenţi în aproape toate direcţiile, pe un spectru larg de lungimi de
undă.
Laserele variază în dimensiune de la diode laser microscopice (stânga) cu numeroase
aplicaţii, până la lasere cu neodim folosite în experimente fizice cu densitate mare de
energie (dreapta).
Fig. III-1. Stânga: diodă laser microscopică.
Dreapta: laser cu neodim, de putere foarte mare.
11
Componentele laserului
Fig. III-2. Principalele componente ale unui dispozitiv laser.
Unde:
1. mediu activ al laserului
2. energie de pompare
3. oglindă
4. oglindă partială
5. fascicul laser
Principiul de funcţionare
Se consideră o mulţime de atomi de sisteme cuantice care pentru simplificare, se
presupune că au doar două nivele de energie. Toţi atomii fiind identici, au aceeaşi
distanţă între cele două nivele de energie (DE). Se presupune de asemenea pentru
început că toţi atomii se găsesc în stare fundamentală. Inexistenţa atomilor pe starea
superioară face ca la o iradiere cu radiaţia de rezonanţă (perturbare) n=1/h*DE să se
petreacă numai tranziţii de jos în sus. Rezultă o absorbţie de energie, fasciculul ce
străbate această colectie de atomi va ieşi atenuat. Dacă s-ar reuşi aducerea tuturor (sau
cel puţin a majorităţii atomilor) pe nivelul superior, atunci radiaţia incidentă, de
frecvenţă de rezonanţă, ar determina tranziţii stimulate, de sus în jos. Rezultă astfel un
fascicul de radiaţie mai intens decat cel incident, obţinându-se astfel un fenomen de
amplificare a radiaţiei.
12
Problema cheie este deci realizarea situaţiei în care în starea superioară să se găsească
un număr mai mare de atomi decât în starea inferioară. Aceasta corespunde unei
situaţii de neechilibru şi deci nu poate să persiste decât dacă se consumă energie pentru
menţinerea ei. Procesul prin care se realizează această situaţie de neechilibru
(denumită şi inversiune de populaţie – inversiune a numărului de atomi, dintr-un
ansamblu de atomi identici, care se găsesc într-o stare determinată de energie) se
numeşte pompaj. Am putea compara procesul de pompaj cu procesul chimic dintr-o
pilă electrică, care menţine o stare de dezechilibru prin continua separare a purtătorilor
de sarcină electrică din interiorul ei.
Dezvoltând analogia, putem spune că menţinerea unei tensiuni constante la bornele
pilei se realizează doar dacă “viteza de separare” a purtătorilor din pilă este mai mare
ca viteza de revenire a lor prin circuitul exterior. La fel şi aici, procesul de pompare va
trebui sa fie mult mai intens decat cel de dezexcitare. Această condiţie se poate asigura
dacă unul dintre nivelele atomului (sau sistemului cuantic) este un nivel metastabil,
care în consecinţă determină o dezexcitare mai lentă (viaţa medie mai ridicată ca cea
normală).
Fig. III-3. Stânga: experiment folosind un laser (probabil argon). (armata SUA)
Dreapta: O demonstraţie cu laser HeNe.
(laboratorul Kastler-Brossel, Universitatea 6 Paris)
Siguranţa laserului - Clasificare
13
În Statele Unite ale Americii laserele sunt clasificate în funcţie de lungimea de undă şi
puterea maximă, în următoarele clase de siguranţă (clasificarea internaţională este
puţin diferită):
Clasa I – În mod obişnuit sigură; nu există posibilitatea afectării ochiului. Aceasta
poate fi datorită puterii mici (în care caz afectarea ochiului este imposibilă chiar şi
după ore de expunere), sau datorită unei carcase ce nu poate fi deschisă în timpul
operării normale fără ca laserul sa fie oprit automat, cum este cazul unităţilor CD.
Clasa II – Reflexul de a clipi al ochiului uman previne afectarea ochiului, atât timp cât
persoana nu priveşte fix în fasciculul laser în mod intenţionat. Puterea de ieşire este
până la 1mW. Aceasta clasă este pentru lumina vizibilă doar.
Clasa IIIa – Laserele din această clasă sunt în principal periculoase atunci când sunt
folosite în combinaţie cu instrumente optice care schimbă diametrul fasciculului.
Puteri de ieşire de la 1mW la 5mW. Această clasă cuprinde doar lasere cu lumina
vizibilă. Majoritatea laserelor “indicator” (eng: laser pointer) sunt incluse în aceasta
categorie.
Clasa IIIb – Poate dăuna dacă fasciculul pătrunde în ochi direct, sau dacă este reflectat
direct în ochi. Aceasta se aplică în general laserelor cu putere de ieşire între 5mW şi
500mW. Reflecţia difuză nu este considerată periculoasă iar laserul nu prezintă pericol
de incendiu.
Clasa IV – Foarte periculoasă; chiar şi reflectarea difuză indirectă a fasciculului poate
duce la afectarea ochiului sau pielii. Se aplică în general pentru lasere cu puteri de
ieşire mai mari de 500mW, sau lasere care produc pulsuri intense de lumină. Cu toate
că intensitatea fasciculului poate fi doar de câteva ori mai mare decât cea a soarelui
strălucitor, în momentul pătrunderii în ochi, fascicul poate fi focalizat într-un punct
foarte mic.
14
Puterile laser menţionate mai sus sunt valori tipice; clasificarea este de asemenea
dependentă de lungimea de undă, precum şi de modul de operare al laserului (puls sau
continuu). De asemenea, chiar şi un laser de putere mare poate fi atribuit unei clase
mici de siguranţă dacă este într-o carcasă, astfel încât radiaţia laser să nu o poată
părăsi, afectând vreo persoană.
Modulul laser folosit
Pentru aplicaţie s-a folosit un “modul de diodă laser generator de linie” (eng: line
generator laser diode module) obţinut de la Apinex Inc. Montreal, Canada.
Specificaţiile laserului sunt:
Fig. III-4. Laserul LML, procurat de la Apinex Inc.
Clasă: Semiconductor (clasa II sau IIIa)
Lungime de undă: 650nm
Putere de ieşire: 1mW
Circuit: Control Automat al Puterii
Sistem Optic: Lentile de plastic tratate anti-reflexie
Tensiune de operare: 3V curent continuu
Curent de operare: 35mA
15
Temperatură de operare: -10C până la +40C
Fascicul: Linie cu deschidere de 90
Material carcasă: Alamă
Lungime: 40mm
Diametru: 11,5mm
Lungimea firelor: 120mm
3.2. Rotirea obiectului cu ajutorul motorului pas cu pas
Introducere
Motoarele pas cu pas pot fi privite ca motoare electrice fără comutatoare. De obicei,
toate înfăşurările din motor fac parte din stator, iar rotorul este fie un magnet
permanent, fie, în cazul motoarelor cu reluctanţă variabilă, o piesă dinţată dintr-un
material magnetic moale. Toate comutaţiile trebuie manevrate extern de către
controlerul motorului, şi de obicei, motoarele şi controlerele sunt proiectate astfel încât
rotorul să poată fi ţinut în orice poziţie fixă, şi totodată sa poata fi rotit atât într-un
sens, cât şi în celălalt. Majoritatea motoarelor pas cu pas pot fi operate la frecvenţe
audio, permiţându-le să se rotească destul de rapid, iar cu un controler potrivit, pot să
fie pornite şi oprite cu acurateţe mare la poziţiile dorite.
Funcţionarea motorului pas cu pas
16
Fig. III-5. Cei 4 paşi ai secvenţei de rotire a unui motor pas cu pas.
Paşi:
1 – electromagnetul de sus (1) este pornit, atrăgând cei mai de sus patru dinţi ai
rotorului.
2 – electromagnetul de sus (1) este oprit, iar electromagnetul din dreapta (2) este
pornit, atrăgând cei mai apropiaţi 4 dinţi spre dreapta; aceasta rezultă într-o rotaţie cu
3,6.
3 – electromagnetul din dreapta (2) este oprit, iar electromagnetul de jos (3) este
pornit; are loc o altă rotaţie cu 3,6.
4 – electromagnetul de jos (3) este oprit, iar electromagnetul din stanga (4) este pornit;
se roteşte din nou cu 3,6.
Când electromagnetul de sus (1) este pornit din nou, dinţii rotorului se vor fi rotit cu o
poziţie de un dinte. Din moment ce avem 25 de dinţi pe rotor, vor fi necesari 100 de
paşi pentru o rotaţie completă.
Tipuri de motoare pas cu pas
Motoarele pas cu pas se găsesc în două varietăţi, cu magnet permanent şi cu reluctanţă
variabilă (mai există de asemenea şi motoare hibride, care sunt identice cu cele cu
magnet permanent din punctul de vedere al controlerului). În lipsa unei etichete pe
motor, le putem distinge prin senzaţia rotirii, când nu sunt alimentate. Motoarele cu
magnet permanent tind să “trepideze” când rotim axul cu mâna, în timp ce motoarele
17
cu reluctanţă variabilă au axul ce se roteşte aproape liber (deşi ar putea şi acestea sa
“trepideze” puţin, din cauza magnetizării reziduale din rotor). Putem de asemenea
distinge între cele două tipuri cu ajutorul unui ohmmetru. Motoarele cu reluctanţă
variabilă au de obicei trei înfăşurări, cu un fir comun, în timp ce motoarele cu magneţi
permanenţi au de obicei două înfăşurări independente, cu sau fără conexiune la centru.
Aceste tipuri de înfăşurări sunt folosite în motoarele cu magneţi permanenţi unipolari.
Motoarele pas cu pas au un domeniu larg al rezoluţiei unghiulare. Cele cu rezoluţie
mică de obicei se rotesc cu 90 la un pas, în timp ce motoarele cu magneţi permanenţi
de rezoluţie mare sunt de obicei capabile să se rotească cu 1,8 sau chiar 0,72 la un
pas. Folosind un controler potrivit, majoritatea motoarelor pas cu pas pot rula cu
jumătăţi de pasi (eng: half-stepping, spre deosebire de full-stepping), iar unele
controlere pot funcţiona mult mai fin, în modul micro-paşi (eng: micro-stepping).
Un fapt valabil pentru ambele tipuri de motoare, atât cele cu magneţi permanenţi, cât şi
cele cu reluctanţă variabilă, este acela că dacă doar o înfăşurare este alimentată, rotorul
(fără sa fie legat la vreo sarcină) se va poziţiona rapid sub un unghi fix, şi va menţine
acea poziţie până când cuplul aplicat asupra axului va depăşi cuplul de sprijin al
motorului, moment în care rotorul se va roti, încercând să se menţină fix la fiecare
punct de echilibru.
Motoare cu reluctanţă variabilă
Fig. III-6. Vedere schematică şi în secţiune a motorului.
18
În figură este reprezentat un motor cu reluctanţă variabilă, cu 3 înfăşurări, 4 fire (3
pentru fiecare înfăşurare, şi unul comun). În practică, firul comun este de obicei
conectat la sursă pozitivă, iar înfăşurările sunt alimentate secvenţial.
Motorul din figură are pasul de 30. Rotorul acestui motor are 4 dinţi iar statorul are 6
poli, fiecare bobină fiind înfăşurată în jurul a doi poli opuşi. Cu înfăşurarea 1
alimentată, dinţii rotorului sunt atraşi de polii acestei înfăşurări. Dacă curentul din
înfăşurarea 1 este oprit, şi alimentăm înfăşurarea 2, rotorul se va roti cu 30 în sensul
invers trigonometric, astfel încât ceilalti doi dinţi ai rotorului se aliniază cu polii
bobinei 2.
Pentru a roti acest motor continuu, se alimentează cele trei bobine secvenţial.
Presupunând logica pozitivă, unde 1 înseamnă alimentarea cu curent a unei bobine,
următoarea secvenţă de control va roti motorul în sens invers trigonometric 24 de paşi
(2 revoluţii):
Înfăşurarea 1: 1001001001001001001001001…
Înfăşurarea 2: 0100100100100100100100100…
Înfăşurarea 3: 0010010010010010010010010…
Motoare unipolare
Fig. III-7. Vedere schematică şi în secţiune a motorului.
Motoarele pas cu pas unipolare, atât cele cu magneţi permanenţi cât şi cele hibride, cu
5 sau 6 fire, sunt de regulă conectate ca în figură, cu o conexiune centrală pe fiecare
din cele două înfăşurări. În practică, conexiunile centrale ale înfăşurărilor sunt de
19
obicei conectate la sursa pozitivă, iar cele două terminaţii ale fiecărei înfăşurări sunt
conectate la masă alternativ pentru a inversa direcţia câmpului generat de acea
înfăşurare.
Motorul din figură este un motor cu pasul de 30, motor cu magnet permanent sau
motor hibrid, diferenţa între cele două tipuri de motoare fiind nerelevantă la acest nivel
de abstractizare. Înfăşurarea 1 este distribuită intre polul de sus şi cel de jos ale
statorului, iar înfăşurarea 2 este distribuită între polul din stânga şi cel din dreapta.
Rotorul este un magnet permanent cu 6 poli, 3 poli sud şi 3 poli nord, distribuiţi de-a
lungul circumferinţei sale.
După cum se vede din figură, curentul care trece de la conexiunea centrală a înfăşurarii
1 până la terminalul ‘a’ face ca polul de sus al statorului să fie un pol nord, iar polul de
jos al statorului sa fie un pol sud. Aşadar rotorul este atras în poziţia arătată. Dacă
alimentarea înfăşurării 1 este întreruptă şi înfăşurarea 2 este alimentată, rotorul se va
roti cu 30, adica un pas.
Pentru a roti rotorul continuu, se alimentează cele două înfăşurări secvenţial.
Presupunând logica pozitivă, unde 1 simbolizează alimentarea cu curent a unei
înfăşurări a motorului, următoarele două secvenţe de control vor roti rotorul în sens
invers trigonometric 24 de paşi, adica 2 revoluţii:
Înfăşurarea: 1a 1000100010001000100010001…
Înfăşurarea: 1b 0010001000100010001000100…
Înfăşurarea: 2a 0100010001000100010001000…
Înfăşurarea: 2b 0001000100010001000100010…
Înfăşurarea: 1a 1100110011001100110011001…
Înfăşurarea: 1b 0011001100110011001100110…
Înfăşurarea: 2a 0110011001100110011001100…
Înfăşurarea: 2b 1001100110011001100110011…
20
Se observă că cele două jumătăţi ale fiecărei înfăşurări nu sunt alimentate niciodată
simultan. Ambele secvenţe arătate mai sus vor roti un motor cu magnet permanent, cu
cate un pas. Secvenţa de sus alimentează doar o înfăşurare la fiecare moment; aşadar,
foloseşte mai puţină energie. Secvenţa de jos implică alimentarea ambelor înfăşurări la
fiecare moment, şi în general produce un cuplu mai mare de 1,4 ori decât prima
secvenţă, consumând totodată de două ori mai multă energie.
Poziţiile paşilor produşi de către cele două secvenţe anterioare nu sunt la fel; drept
consecinţă, combinând cele două secvenţe se obţine rotirea cu jumătăti de paşi (eng:
half-stepping), rotorul oprindu-se alternativ la poziţiile indicate de o secvenţă sau de
cealaltă. Secvenţa combinată arată astfel:
Înfăşurarea 1a: 11000001110000011100000111…
Înfăşurarea 1b: 00011100000111000001110000…
Înfăşurarea 2a: 01110000011100000111000001…
Înfăşurarea 2b: 00000111000001110000011100…
Motoare bipolare
Fig. III-8. Vedere schematică şi în secţiune a motorului.
Motoarele bipolare sunt construite cu exact acelaşi mecanism ca cel din motoarele
unipolare, dar cele două înfăşurări sunt conectate simplu, fără conexiuni centrale.
Aşadar, motorul în sine este mai simplu, dar circuitul de control al acestuia necesar
pentru a inversa polaritatea fiecărei perechi de poli a motorului este mai complex. În
figură se arată cum este realizat un astfel de motor, schema de conectare diferă, dar
vederea în secţiune este la fel cu cea a motoarelor unipolare.
21
Circuitul de control pentru un asemenea motor necesită o punte H pentru fiecare
înfăşurare (în esenţă, o punte H permite ca polaritatea alimentării fiecărei înfăşurări să
fie controlată independent). Secvenţele de control pentru rotirea unui astfel de motor
sunt arătate în continuare, folosind simbolurile + şi – pentru a indica polaritatea
fiecărei terminaţii a fiecărei înfăşurări:
Terminaţia 1a: +---+---+---+--- ++--++--++--++--
Terminaţia 1b: --+---+---+---+- --++--++--++--++
Terminaţia 2a: -+---+---+---+-- -++--++--++--++-
Terminaţia 2b: ---+---+---+---+ +--++--++--++--+
Se observă că aceste secvenţe sunt identice cu cele pentru un motor unipolar, la un
nivel abstract, deci mai sus de nivelul circuitelor de comutare a puntilor H, sistemele
de control ale celor două tipuri de motor poate fi identic.
Pentru a putea face distincţia între motorul bipolar cu magneţi permanenţi şi celelalte
motoare cu 4 fire, se măsoară rezistenţa între diferitele terminaţii. De menţionat este
faptul că unele motoare pas cu pas cu magneţi permanenţi au 4 înfăşurări
independente, organizate ca seturi de cate două. În cadrul fiecarui set, dacă cele două
înfăşurări sunt înseriate, atunci motorul poate fi folosit ca un motor bipolar de tensiune
mare. Dacă sunt montate în paralel, atunci motorul poate fi folosit ca un motor bipolar
de tensiune mică. Dacă sunt înseriate, cu conexiune centrală, atunci motorul poate fi
folosit ca un motor unipolar de tensiune mică.
Motoare bifilare
Aceste tipuri de motoare au geometria statorului şi rotorului identică cu cea a
motoarelor bipolare, în schimb înfăşurările fiecărei bobine sunt dublate, cele două fire
fiind dispuse în paralel. Drept rezultat, motorul are 8 fire, nu 4.
22
În practică, motoarele cu înfăşurări bifilare sunt de regulă folosite fie ca motoare
unipolare, fie ca motoare bipolare. În figură se arată cele două tipuri de conectare ale
înfăşurărilor unui astfel de motor.
Fig. III-9. Vedere schematică şi în secţiune a motorului.
Pentru a folosi un motor bifilar ca motor unipolar, cele două fire ale fiecarei înfăşurări
sunt conectate în serie, iar punctul de conectare este folosit drept conexiune la centru.
În figură, înfăşurarea 1 este conectată în acest mod.
Pentru a folosi un motor bifilar ca motor bipolar, cele două fire ale fiecarei înfăşurări
sunt conectate fie în paralel, fie în serie. Înfăşurarea 2 din figură arată o conexiune
paralelă; aceasta permite operarea la tensiune mică şi curent mare. Înfăşurarea 1 din
figură arată o conexiune serie; dacă punctul de conexiune la centru este ignorat,
aceasta permite operarea la tensiune mare şi curent mic, decât dacă înfăşurările ar fi
fost folosite în paralel.
Motorul pas cu pas folosit
Pentru aplicaţie s-a folosit un motor pas cu pas cu magnet permanent SPH-39AC-023,
produs de Tokyo Electric Co. Ltd., obţinut dintr-o unitate de discheţi magnetici veche.
În plus faţă de motorul pas cu pas, o unitate de discheţi de 5,25 inci include şi un
motor de curent continuu de 12V cu tahometru şi circuit de control al motorului, două
micro-comutatoare, şi o pereche ce include un led şi fotosenzorul corespunzător.
Motorul pas cu pas din unitate este un motor cu magnet permanent, unipolar, cu
conexiunile centrale unite către un singur fir. Acestea sunt specificaţiile lui:
23
Fig. III-10. Motorul pas cu pas folosit.
Tip: cu magnet permanent
Polaritate: unipolar
Rezoluţia pasului: 3,6
Paşi per revoluţie: 100
Tensiune: 12V curent continuu
Număr fire: 5
Rezistenţă: 150 per înfăşurare (4 x 75 ambele înfăşurări)
3.3. Comandarea laserului şi motorului prin portul paralel
Introducere
În lumea calculatoarelor, portul paralel este un tip de interfaţă fizică folosită împreună
cu un cablu pentru a conecta periferice separate dintr-un sistem de calcul. Prin portul
paralel, informaţia binară este transmisă în paralel: fiecare din biţii unei anumite
valoari este trimis simultan sub forma unui puls electric pe un fir separat, spre
deosebire de portul serial, care necesită ca fiecare din biţi să fie trimis în serie pe
acelaşi fir. Numărul de fire şi tipul de conector la un port paralel poate varia.
24
Fig. III-11. Portul paralel al unui laptop Compaq N150.
În majoritatea cazurilor, interfaţa USB a înlocuit portul paralel (la momentul scrierii
acestui document, marea parte a imprimantelor moderne sunt conectate prin portul
USB, şi de multe ori nici nu au nevoie de o conexiune pe portul paralel). Pe multe
calculatoare moderne, portul paralel este omis pentru a mai salva din costuri, şi este
considerat a fi un port învechit.
Aplicaţii
Portul paralel este de obicei folosit de microprocesoare pentru comunicarea cu
dispozitivele periferice. Cel mai întâlnit tip de port paralel este portul de imprimantă,
port bazat pe conector Centronics ce poate transfera 8 biţi deodată. Discurile dure
(eng: HDD disk drives) sunt de asemenea conectate prin porturi paralele speciale, cum
sunt cele folosite în tehnologiile SCSI şi ATA. Cu toate acestea, în vorbirea de zi cu zi,
portul paralel se referă de obicei la portul de imprimantă al calculatorului PC.
Portul paralel al unui calculator compatibil IBM/PC este, de departe, cel mai comun
port standard de calculator ce ofera tensiunile logice standard direct la seturile de pini.
Este foarte folosit de ingineri (şi amatori) drept un mijloc ieftin de realizare a
proiectelor de control prin calculator. Tensiunea logica standard, 5V curent continuu,
este inofensivă. Pe de alta parte, circuitul electric al portului paralel este în general
destul de fragil; pentru a nu îl deteriora, trebuie sa acordăm atenţia cuvenită.
Conectori
25
Portul paralel are de obicei minim 25 de pini, majoritatea fiind folosiţi, ceea ce rezultă
în cabluri groase. Aceste cabluri sunt de asemenea limitate în lungime la un maxim de
3 până la 8 metri, în funcţie de portul respectiv şi caracteristicile cablului. Deşi în
zilele noastre există mai multe standarde pentru portul paralel, acestea nu sunt
întotdeauna respectate (în special în cazul dispozitivelor mai vechi), ceea ce
îngreunează procurarea cablului şi aplicatiei software potrivite.
Porturile paralele au 4 tipuri de pini:
Pinii de date (P2–P9), de obicei 8, câteodată 16, şi uneori cu un pin în plus pentru
bitul de paritate. Pot fi atât unidirecţionale (de exemplu de la calculator la imprimantă)
cât şi bidirecţionale. Pentru a indica faptul că un bit are valoarea 1, este aplicată o
tensiune de 5V pinului respectiv. Lipsa unei tensiuni pe un pin semnifică valoarea 0.
Acesta este un mod simplu, dar eficient, de a transmite informaţie digitala pe un cablu
analog în timp real.
Pinii de control, folosiţi pentru a trimite semnale de control cum ar fi STROBE
pentru a indica faptul că datele de pe pinii de date sunt disponibili, şi R/W pentru a
specifica dacă porturile bidirecţionale citesc sau scriu date. Pinul STROBE (P1)
mentine un nivel al tensiunii între 2,8V şi 5V, dar scade sub 0,5V atunci când
calculatorul trimite un octet de date. Această scădere a voltajului anunţă imprimanta de
primirea datelor.
Pinii de stare, folosiţi pentru a trimite semnale ca BUSY pentru a indica faptul că
dispozitivul nu este gata să primească date şi ACK pentru confirmarea primirii reuşite
a simbolului. Pinul ACKNOWLEDGE (P10) trimite semnalul de la imprimanta la
calculator, şi este folosit pentru a confirma calculatorului primirea datelor. Pinul
BUSY (P11) semnalizează faptul că imprimanta este ocupată.
Pinii de masa, folosiţi pentru a completa circuitele de la ceilalţi pini.
Adresarea portului
Din câte se ştie, sistemele IBM/PC au fost cele care şi-au alocat primele două porturi
paralele conform configuraţiei din tabelul de mai jos:
26
Numele portului Numărul
întreruperii
Adresa de start I/O Adresa de sfârşit
I/O
LPT1 IRQ 7 0x378 0x37F
LPT2 IRQ 5 0x278 0x27F
Interfaţarea cu portul paralel
Portul de imprimantă paralel IBM/PC a avut la început un total de 12 ieşiri digitale şi 5
intrări digitale accesate prin intermediul a 3 porturi consecutive de 8 biţi din spaţiul de
adresare I/O al procesorului:
8 pini de iesire accesaţi prin intermediul portului DATA (D0–D7 ).
5 pini de intrare (unul inversat) accesaţi prin intermediul portului STATUS.
4 pini de ieşire (trei inversaţi) accesaţi prin intermediul portului CONTROL.
Restul de 8 pini sunt legaţi la masă.
Fig. III-12. Pinii portului paralel IBM-PC.
De-a lungul timpului, au fost introduse mai multe versiuni imbunătăţite ale
originalului:
Bi-direcţional (PS/2)
Portul Paralel Îmbunătăţit (EPP – Enhanced Parallel Port)
27
Portul Extins al Capabilităţilor (ECP – Extended Capability Port)
Astăzi, portul original este menţionat ca Portul Paralel Standard (SPP – Standard
Parallel Port).
Portul paralel folosit în aplicaţie
Portul paralel a fost folosit pentru controlarea prin calculator a motorului pas cu pas, şi
a laserului. Pentru controlul laserului (pornire şi oprire) a fost folosit un singur bit.
Pentru controlul motorului pas cu pas au fost folosite 4 fire, reprezentând cele 4
terminaţii ale bobinelor motorului. Modul de operare al motorului (cu pas întreg – full
stepping – sau cu jumatate de pas – half stepping) este controlat din program. Aşadar,
au fost de ajuns 6 fire pentru controlul laserului şi motorului. Tabelul următor arată
configuraţia pinilor:
Pinii conectorului DB25 Pinii de date
Motor pas cu pas P2–P5 D0 – D3
Laser P6 D4
Masă P18 –
3.4. Utilizarea camerei video pentru obţinerea datelor de
prelucrare
Pentru obţinerea fluxului de date video există multe opţiuni. Se poate folosi o cameră
video analogică în combinaţie cu o placă de captură video corespunzătoare. O altă
variantă este folosirea unei camere digitale controlabilă din calculator. Însă cea mai
ieftină modalitate o reprezintă utilizarea unei camere web, conectabilă la calculator
prin portul paralel. În cadrul acestui proiect a fost folosită o cameră web Logitech
QuickCam Pro 4000:
28
Fig. III-12. Camera web folosită: Logitech QuickCam Pro 4000.
Rezoluţie: 160x120, 320x240
Rezoluţie interpolată: 640x480, 1024x768
Interfaţă: USB 2.0
29
4. Montajul electric pentru controlarea laserului şi motorului
Partea electrică a proiectului are rolul de a controla prin portul paralel cele două
dispozitive: laserul şi motorul pas cu pas. Pentru a controla laserul este de ajuns un bit
al portului paralel (am ales bitul 4), iar pentru a controla motorul este nevoie de 4 biţi
(am ales biţii 0, 1, 2, 3).
4.1. Protecţia portului paralel
Deoarece portul paralel este foarte sensibil referitor la curentul ce poate fi folosit, vom
realiza optoizolarea portului folosind optocuploarele 4N35. Intern, un astfel de circuit
arată ca în figura următoare:
Fig. IV-1. Optocuplorul 4N35.
Un optocuplor (sau optoizolator) este un dispozitiv ce foloseşte o cale optică scurta de
transmitere a unui semnal între elementele unui circuit, menţinându-le în acelasi timp
izolate electric. Din moment ce se trece dintr-un semnal electric într-un semnal optic şi
înapoi într-un semnal electric, contactul electric de-a lungul transformărilor se pierde.
O implementare des întâlnită constă dintr-un led şi un senzor de lumină, separate în
aşa fel încât lumina să poată parcurge distanţa, dar curentul electric nu. Când un
semnal electric este aplicat la intrarea optocuplorului, ledul se aprinde, senzorul de
lumina se activează, şi un semnal electric corespunzător este generat la ieşire. Spre
deosebire de un transformator, optocuplorul permite lucrul în curent continuu şi de
obicei oferă protecţie mai bună în condiţii de supratensiune, astfel încât un circuit să
nu îl afecteze pe celălalt.
30
În cazul concret al optocuplorului 4N35, semnalul de intrare trebuie aplicat între pinii
1 şi 2. Pinul 1 va fi legat corespunzător la pinul de date al portului paralel, iar pinul 2
va fi legat la pinul de masă. Când bitul va fi setat prin program pe valoarea 1, între cei
doi pini vom avea o tensiune de 5V, ceea ce va face ca ledul sa lumineze. Lumina va
ajunge la fototranzistor, care va permite curentului sa treacă prin el, dinspre colector
către emitor.
Aplicaţia va folosi 5 optocuploare pentru protecţia portului paralel, câte unul pentru
fiecare fir de date folosit (patru pentru motorul pas cu pas, şi unul pentru laser).
4.2. Realizarea controlului motorului pas cu pas
În figura următoare este reprezentată configuraţia înfăşurărilor din interiorul
motorului:
Fig. IV-2. Înfăşurările motorului pas cu pas şi mufa de conectare.
Când conexiunea la centru a motorului este conectată la +12V şi un capăt al unei
înfăşurări este legat la masă, curentul ce va trece prin înfăşurare se va situa în jurul
valorii de 160mA:
31
Unităţile IBM originale foloseau o pereche de cipuri UDN3612N sau UDN5713. Vom
folosi însă circuitul integrat ULN2003 produs de către Allegro Microsystems, care este
probabil cel mai răspândit cirtuit de acest tip.
Circuitul ULN2003 este format de fapt dintr-o matrice de tranzistoare Darlington.
Tranzistorul Darlington este un dispozitiv semiconductor ce combină două tranzistoare
bipolare într-un singur dispozitiv astfel încât curentul amplificat de catre primul
tranzistor este amplificat mai departe de către al doilea tranzistor. Aceasta îi conferă un
factor de amplificare mare, şi foloseşte mai putin spaţiu decât dacă am folosi două
tranzistoare normale în aceeaşi configuraţie. Această configuraţie a fost inventată în
Laboratoarele Bell de către inginerul Sidney Darlington.
Fig. IV-3. Tranzistor Darlington.
Un circuit simplu pentru controlarea motorului prin portul paralel este prezentat în
figura următoare (au fost neglijate optocuploarele pentru protecţia portului paralel):
Fig. IV-4. Schema electrică de control al motorului prin portul paralel.
Este recomandat să se conecteze o dioda zener între sursa de alimentare şi VDD (pinul
9) de pe circuit, pentru a absorbi forţa electromagnetică inversă generată prin încetarea
câmpului magnetic atunci când înfăşurările motorului nu mai sunt alimentate.
32
ULN2003 se alimentează la o tensiune de 5V, spre deosebire de circuitele din aceeaşi
familie ULN2002 şi ULN2004 care se alimentează la 14–25V, respectiv 6–15V.
4.3. Pornirea si oprirea laserului cu ajutorul portului paralel
Laserul folosit nu prezintă probleme în controlare. Acesta este pornit şi oprit direct din
portul paralel (singurul circuit folosit este cel de optoizolare).
4.4. Sursele de alimentare necesare funcţionării circuitelor şi motorului
Este nevoie de două surse de tensiune, 12V şi 5V. Cei 12V sunt folosiţi pentru
alimentarea înfăşurărilor motorului, iar pentru circuitul integrat ULN2005 sunt folosiţi
5V. Ca sursă de tensiune de 12V este folosit un alimentator de telefon mobil (de la un
Alcatel) care se alimentează de la priza (230V curent alternativ, 50Hz). Pentru a obţine
5V, este folosit un circuit integrat regulator de tensiune LM7805. În figura următoare
este prezentat un astfel de circuit:
Fig. IV-5. Circuitul integrat LM7805.
Pentru realizarea sursei de tensiune este recomandată folosirea unui condensator de
220F, deoarece câteodată tensiunea de intrare poate avea un zgomot pronunţat, iar
folosirea condensatorului ajută la nivelarea zgomotului.
33
4.5. Schema circuitului electric final
Fig. IV-6. Schema sursei de tensiune de 5V.
Fig. IV-7. Schema de control al laserului.
Fig. IV-8. Schema de control al motorului pas cu pas.
Observaţie: Circuitul LM7805 este proiectat să accepte curent de maxim 1A (varianta
mai mică a lui, LM78L05 este capabila doar de 100mA), ceea ce este de ajuns pentru
alimentarea motorului şi laserului. Motorul consumă pe o fază 160mA, deci va
consuma maxim 320mA, în modul de operare cu jumatate de pas – half stepping.
Laserul consuma 35mA. În total rezultă un consum maxim de 355mA. La acest nivel
34
al curentului, LM7805 tinde sa se supraîncălzească, de aceea este necesară montarea
unui mic radiator pentru disiparea căldurii.
35
5. Aplicaţiile software folosite pentru dezvoltarea aplicaţiei
principale
5.1. Despre mediul de programare Visual Studio 2005
Visual Studio 2005 este un mediu integrat de dezvoltare produs de Microsoft. Cu
ajutorul acestuia programatorii pot realiza aplicaţii de birou, aplicaţii internet, situri şi
servicii web, care rulează pe platforma Windows (calculatoare PC, PDA-uri, telefoane
inteligente, etc). El include medii de dezvoltare pentru următoarele limbaje de
programare: Visual Basic (pentru limbajul Basic, varianta .NET), Visual C++ (pentru
limbajele C, C++, Managed Extensions of C++, şi noul C++/CLI), Visual C# (pentru
noul limbaj de programare C#, versiunea 2.0), Visual J#.
Microsoft a scos eticheta “.NET” din Visual Studio 2005 (la fel ca oricare alt produs al
cărui nume conţinea “.NET”), dar ţinta principală este cadrul de lucru .NET
Framework, cea mai recentă versiune fiind 2.0.
5.2. Modele de programare software utilizate (OOP, DP)
Din moment ce proiectul foloseşte mai multe limbaje de programare, este necesar să
menţionăm modelele de programare folosite de aceste limbaje, sau mai bine spus
paradigmele de programare. O paradigmă de programare furnizează (şi determină)
modul în care programatorul percepe execuţia programului. De exemplu, în
programarea orientată pe obiecte, programatorul se gândeşte la program ca la o
colecţie de obiecte ce interacţionează, în timp ce în programarea funcţională un
program poate fi perceput ca o secvenţă de evaluări de funcţii fără stare.
Multe modele de programare sunt bine cunoscute pentru tehnicile care le interzic, şi
mai puţin pentru cele pe care le pun la dispoziţie. De exemplu, programarea
funcţională pură interzice folosirea efectelor secundare (apelarea unei funcţii are ca
36
singur efect returnarea unei valori); programarea structurată interzice folosirea
instrucţiunilor de salt (eng: goto). Din aceasta cauză, modelele noi sunt deseori văzute
ca doctrinare sau prea rigide de către cei obişnuiţi cu stilurile mai vechi.
Relaţia între modelele de programare şi limbajele de programare poate fi complexă din
moment ce un limbaj poate suporta multiple modele. De exemplu, C++ este proiectat
să suporte elemente din programarea procedurală, din programarea bazată pe obiecte,
din programarea orientată pe obiecte şi din programarea generică. Cu toate acestea,
proiectanţii şi programatorii decid cum îşi vor dezvolta aplicaţia folosind acele
elemente ale modelelor. Cineva poate să scrie un program pur procedural folosind C+
+, altcineva poate să scrie un program orientat pur pe obiecte tot în C++, sau altcineva
poate folosi o combinaţie de elemente ale celor două paradigme.
OOP – Programarea Orientată Obiect
Ideea care stă la baza programării orientate obiect este aceea ca un program poate fi
văzut ca fiind format dintr-o mulţime de unităţi individuale, sau obiecte, care
acţionează unul asupra celuilalt, spre deosebire de aspectul tradiţional unde era văzut
ca o colecţie de funcţii, sau pur şi simplu de instrucţiuni, executate de calculator.
Fiecare obiect este capabil să primească mesaje, să proceseze date, şi să trimită mesaje
altor obiecte. Fiecare obiect poate fi văzut ca o mică maşină independentă, sau ca un
actor cu un rol distinct sau o responsabilitate distinctă.
Programarea orientată obiect este promovată ca prezentând o mai mare flexibilitate şi
mentenabilitate în programare, şi este foarte populară în ingineria software de scară
largă. Chiar mai mult, cei ce promovează OOP susţin că aceasta este mai uşor de
învăţat pentru cei noi în programarea calculatoarelor decât abordările mai vechi, şi că
OOP este deseori mai simplu de dezvoltat şi întreţinut, permintând o mai directă
analiză, programare şi înţelegere a situaţiilor şi procedurilor complexe, decât celelalte
metode de programare. Criticii însă dispută acest lucru, cel puţin pentru anumite
domenii (industriale).
37
DP – Programarea Declarativă
Există mai multe definiţii pentru programarea declarativă, care ajung să se suprapună.
Vom spune despre acest model de programare că se bazează pe următorul principiu:
un program este declarativ dacă descrie ce caracteristici are o anumită entitate, decât
cum se creează acea entitate sau ce poate face. Privind paradigmele comparativ, putem
spune pe scurt că programele imperative fac algoritmul explicit lăsând scopul implicit,
în timp ce programele declarative fac scopul explicit lăsând algoritmul implicit.
Într-un program declarativ se declară o structură de date care este procesată de către un
algoritm standard (pentru acel limbaj) producând rezultatul dorit. De exemplu, ăn
cazul unei pagini web, se declară cum va arăta pagina în HTML, iar algoritmul
browserului traduce această structură în pixeli pe ecran. De asemenea, un limbaj
declarativ, ca toate limbajele, are o sintaxă care descrie cum pot fi combinate
cuvintele, şi o semantică ce descrie care este corespondentul propoziţiilor în ieşirea
programului.
5.3. Lista limbajor de programare folosite (C#, C++/CLI, XAML)
Datorită complexităţii aplicaţiei finale, a fost necesară folosirea mai multor limbaje de
programare, fiecare cu avantajele şi dezavantajele lui.
C# (C Sharp)
C# este un limbaj OOP dezvoltat de către Microsoft ca parte a iniţiativei proprii .NET,
care a fost ulterior aprobat ca standard de către ECMA şi ISO. Sintaxa C# este
procedurală, orientată obiect, fiind bazată pe cea din C++, şi care include aspecte din
mai multe limbaje de programare (ies în evidenţă Delphi, Visual Basic şi Java),
punând accentul pe simplificare (mai puţine simboluri decât C++, mai puţine decoraţii
decât Java).
38
C# este, din unele perspective, limbajul de programare care reflectă cel mai direct
Infrastructura Comună a Limbajelor pe care se bazează (eng: CLI – Common
Language Infrastructure). A fost proiectat în mod special pentru a utiliza
caracteristicile şi avantajele puse la dispoziţie de către CLI.
Deşi este un limbaj nou, au trecut mai multe versiuni de la apariţia lui, cea curentă este
versiunea 2.0, fiind deja în lucru versiunea 3.0. De la o versiune la alta limbajul a
evoluat permanent, pastrând compatibilitatea cu versiunile anterioare (cu excepţia
librăriilor aferente cadrului de lucru, care au suferit mici modificări).
Specificaţia ECMA a C# detaliază un minim set de tipuri şi librării de clase pe care
compilatorul se asteaptă să le aibă la dispoziţie, şi care definesc cerinţele de bază.
Majoritatea implementărilor vin cu setul de librării extins.
C++/CLI
C++/CLI este noua specificaţie a limbajului menit sa înlocuiască varianta C++ cu
Extensii de Gestionare (end: Managed Extensions for C++). Fiind o varianta complet
revizuită pentru a simplifica mai vechea sintaxă a Managed C++, C++/CLI pune la
dispoziţie mult mai multă claritate în citirea codului. Ca şi Microsoft .NET sau C#, C+
+/CLI este standardizat de către ECMA. Este disponibil deocamdată doar în Visual C+
+ 2005.
C++/CLI este de fapt un limbaj de sine stătător (cu un nou set de cuvinte cheie, de
exemplu), spre deosebire de Managed C++ care era o extensie a C++ (şi folosea
cuvinte cheie nestandardizate, cum ar fi __gc sau __value). Din această cauză, există
mari schimbari ale sintaxei, legate în special de eliminarea identificatorilor ambigui şi
de adăugarea capabilităţilor specifice .NET.
Mai multe conflicte sintactice, cum ar fi multiplele versiuni ale operatorului new din
MC++ au fost separate: în C++/CLI, referinţele .NET sunt create cu noul cuvânt cheie
39
gcnew. De asemenea, C++ a introdus conceptul de generice (similare şabloanelor din
C++, dar destul de diferite).
În MC++, existau două tipuri diferite de pointeri: pointeri __nogc erau pointerii C++
normali, în timp ce pointerii __gc lucrau cu referinţele .NET. În C++/CLI singurul tip
de pointer este pointerul C++ normal, iar referinţele .NET sunt accesate prin
manipulatori (eng: handle), folosind noua sintaxa NumeClasa^ în loc de NumeClasa*.
Această nouă construcţie este în special de ajutor când avem de a face cu îmbinări de
cod gestionat şi cod nativ; este clar în acest caz care obiecte sunt administrate de către
colectorul automat de resturi al .NET (eng: automatic garbage collection), şi care
obiecte trebuie distruse manual în cod.
XAML (Extensible Application Markup Language)
XAML este limbajul descriptiv al interfeţei cu utilizatorul pentru Fundaţia de
Prezentare Windows (eng: WPF – Windows Presentation Foundation), care este unul
din pilonii interfeţei de programare pentru .NET Framework 3.0. XAML este un
limbaj de programare declarativ bazat pe XML (eXtensible Markup Language),
optimizat pentru a descrie interfeţe cu utilizatorul bogate vizual, cum sunt cele create
cu Macromedia Flash.
Codul XAML este compilat într-un format BAML (Binary xAML), care este mai
departe introdus ca resursă în ansamblul aplicaţiei generat de compilator. La execuţie,
codul BAML este procesat şi transformat în reprezentarea vizuală a interfeţei.
Elementele XAML corespund unor instanţe de obiecte ale CLR (Common Language
Runtime). Atributele lor corespund legăturilor WPF, proprietăţilor CLR şi
evenimentelor obiectelor respective.
5.4. Librăriile software utilizate
40
Pentru realizarea proiectului a fost necesară folosirea mai multor librării dedicate unor
segmente specifice. S-a încercat folosirea unor tehnologii cât mai noi, avansate. La
momentul dezvoltării aplicaţiei, librariile pentru interfaţa grafică se află încă în stadiul
de beta, ultima versiune fiind cea pentru WinFX Beta 2 (de curând redenumit ca .NET
Framework 3.0).
.NET Framework (v2.0)
Cadrul de lucru Microsoft .NET Framework este o componenta a sistemului de
operare Microsoft Windows. Pune la dispozitie un set mare de cod pentru soluţii la
cele mai comune cerinţe ale programelor, şi gestionează execuţia programelor scrise
special pentru acesta. El este un produs cheie al Microsoft, şi este menit sa fie folosit
de către majoritatea aplicaţiilor noi create pentru platforma Windows.
Setul de cod formează librăria de clase a .NET Framework şi acoperă o arie mare a
nevoilor de programare din diferite domenii, cum ar fi interfaţa cu utilizatorul, accesul
la date, criptografie, algoritmi numerici, şi comunicaţiile prin retea. Funcţiile librăriei
de clase sunt folosite de către programatori, care le combină în propriul cod pentru a
realiza aplicaţii.
Programele scrise pentru .NET Framework sunt executate într-un mediu software care
gestionează cerinţele la rulare ale programului. Acest mediu de rulare, care este
deasemenea parte a .NET Framework, este cunoscut sub denumirea de CLR (eng:
Common Language Runtime). CLR creează aparenţa unei maşini virtuale pentru
aplicaţie, astfel încât programatorii să nu mai trebuiască să ia în considerare
capabilităţile specifice ale procesorului care va executa aplicaţia. El dispune de
asemenea de servicii importante cum ar fi garanţii de securitate, gestionarea memoriei
şi tratarea excepţiilor. Conceptul de maşină virtuală a fost împrumutat de la Java cu al
său JVM (Java Virtual Machine).
41
Librăria de clase şi CLR-ul formează împreună .NET Framework. Acesta are ca scop
simplificarea dezvoltării de aplicaţii pe calculator şi reducerea vulnerabilităţii
aplicaţiilor şi calculatoarelor.
WPF (Windows Presentation Foundation)
WPF (nume de cod Avalon) este subsistemul grafic al Microsoft Windows. Va fi
inclus în Vista, următoarea versiune a Windows. Poate fi folosit şi pe Windows XP
SP2 ca parte a .NET Framework 3.0. Dispune de un model consistent pentru
dezvoltarea aplicaţiilor, indiferent dacă sunt instalate pe sistem sau sunt rulate dintr-un
browser web. Îmbunătăţeşte de asemenea controlul, proiectarea şi dezvoltarea
aspectelor vizuale ale programelor Windows. WPF are ca scop unificarea mai multor
tipuri de servicii pentru aplicaţii: interfaţa cu utilizatorul, desene 2D şi 3D, documente
fixe şi adaptive, grafică vectorială, grafică matriceală, animaţii, legături de date, audio
şi video.
Din punct de vedere al serviciilor grafice, WPF rutează toate elementele grafice prin
Direct3D (interfaţă de programare pentru accesul la accelerarea hardware 3D a plăcilor
video). Aceasta permite ca sarcinile grafice sa fie procesate de către procesorul GPU
(Graphical Processing Unit) al plăcii video şi nu de către procesorul CPU, care poate
executa alte sarcini mai importante în acest timp. Subsistemul grafic este bazat pe
grafică vectorială, care îmbunătăţeşte aspectul diferitelor elemente grafice când acestea
sunt mărite sau micşorate. Astfel, WPF arată mai bine pe monitoarele de rezoluţie
mare, iar cu creşterea numărului de pixeli pe inch, grafica arată mai bine, şi nu mai
mică. De asemenea, este posibilă integrarea de conţinut 3D în interfeţele obişnuite.
DirectShow
DirectShow (nume de cod Quartz) este o interfaţă de programare a aplicaţiilor produsă
de Microsoft pentru ca programatorii să efectueze diferite operaţii cu fişierele media.
Fiind bazat pe COM, DirectShow oferă o interfaţă comună pentru diferitele limbaje de
programare.
42
Este extensibil, bazat pe filtre, în sensul că programatorul creează un graf de filtre,
adaugă câteva filtre la graf (chiar şi filtre proprii), le poate conecta (sau poate lăsa
sistemul să le conecteze), şi apoi interpretează (eng: render) un fişier, URL sau o
cameră video. În timpul procesului de interpretare, graful de filtre caută în registrul
sistemului de operare filtre înregistrate, şi completează graful în funcţie de filtrele
găsite. Apoi conectează filtrele, iar din acest moment, la cererea utilizatorului, poate
controla afişarea conţinutului media.
Fig. V-1. Graf de filtre pentru redarea unui fişier MP3. Graful este creat în GraphEdit.
Fiecare filtru reprezintă o etapă în procesarea datelor (care pot avea ca sursă un fişier,
o cameră, sau date provenite de la ieşirea altui filtru). Fiecare filtru are un număr de
pini care reprezintă puncte de conexiune către alte filtre. Pinii pot fi de intrare sau de
ieşire. În funcţie de filtru, datele sunt consumate de la un pin de intrare, procesate, şi
apoi returnate la un pin de ieşire.
Majoritatea filtrelor sunt dezvoltate folosind un set de clase C++ din DirectShow,
numite Clasele de Baza DirectShow. Acestea gestionează marea parte a creării
filtrelor, a înregistrării acestora şi a logicii conectării filtrelor.
Direct3D
Direct3D este o tehnologie Microsoft, parte a DirectX. Este disponibilă doar pe
sistemele de operare Windows, şi este folosită pentru afişarea de conţinut 3D în
aplicaţii unde performanţele sunt importante, cum ar fi jocurile video. Pentru obţinerea
acestor performanţe, Direct3D accesează funcţiile de accelerare hardware 3D ale plăcii
video. Versiunea folosită în următorul sistem de operare, Windows Vista, este cea cu
numărul 10, şi reprezintă un salt important faţă de versiunea precedentă, introducând o
suită de concepte noi (de exemplu virtualizarea memoriei).
43
Microsoft pune la dispoziţie şi o versiune pentru limbajele conforme CLI, într-o
librărie numită Managed DirectX. Aşadar C# poate fi folosit pentru a crea aplicaţii în
Direct3D.
5.5. Schema bloc a aplicaţiei finale şi a librăriilor utilizate
Legenda:
Fig. V-2. Schema bloc a aplicaţiei finale şi a librăriilor utilizate.
44
Librării proprii implementate în cod
Librării disponibile pentru dezvoltare
6. Aplicaţia software de control a dispozitivelor si prelucrare a
datelor
Pentru dezvoltarea aplicaţiei principale, din cauza complexităţii ridicate, s-a avut în
vedere o abordare cât mai modularizată (organizată pe clase şi librării), care permite
împărţirea problemei principale în subprobleme, şi rezolvarea acestora în unităţi mai
mici. De asemenea, identificarea eventualelor probleme şi găsirea soluţiilor
corespunzătoare devine mai uşoară.
Lucrul cu Visual Studio 2005 este bazat pe conceptul de soluţii şi proiecte. Soluţia
reprezintă o organizare a tuturor proiectelor pentru o problema dată (în cazul nostru,
dezvoltarea programului de scanare 3D). Un proiect este format din totalitatea
fişierelor necesare pentru rezolvarea unei subprobleme.
Soluţia principală a proiectului conţine mai multe tipuri de proiecte: proiectul
aplicaţiei principale, proiectele librăriilor si proiectele aplicaţiilor de test. În acest
document vom descrie doar primele două tipuri de proiecte (aplicatiile de test au fost
dezvoltate pentru a verifica buna funcţionare a librăriilor).
45
Fig. VI-1. Schema aplicaţiei de scanare şi proiectele ce alcătuiesc soluţia.
6.1. Librării proprii create pentru a fi utilizate în aplicaţia principală
6.1.1. Clasa ParallelPort (foloseste inpout32.dll) realizează trimiterea de date spre
portul paralel
ParallelPort
Această clasă permite accesarea portului paralel pentru controlarea motorului pas cu
pas şi a laserului. Din cauză că versiunile de Windows bazate pe NT (în care este
inclus şi Windows XP) impun restricţii de acces la anumite funcţii cum sunt IN şi
46
OUT, a fost necesară folosirea unei librării externe care face ca accesul la portul
paralel să se producă uniform pe toate sistemele de operare Windows (98, NT, 2000 şi
XP).
Librăria folosită se numeşte InpOut32.dll, şi pune la dispozitie două funcţii pentru
scrierea şi citirea portului paralel:
C++/CLI
void _stdcall Out32(short PortAddress, short data);short _stdcall Inp32(short PortAddress);
Clasa ParallelPort înglobează această funcţionalitate într-o librărie accesibilă pentru
limbajele compatibile CLI (cum este C#). Pentru a îmbunătăţi funcţionalitatea oferită,
am introdus o variabila de stare (short mState) a portului paralel, ceea ce ne permite să
creăm următoarele funcţii:
C++/CLI
static void OutputData(Byte data);static void OutputDataBits(Byte data, Byte mask);
static void OutputSet(Byte bitmask);static void OutputReset(Byte bitmask);static void OutputToggle(Byte bitmask);
Funcţia OutputData pur şi simplu setează portul paralel pe valoarea transmisă. Funcţia
OutputDataBits face acelaşi lucru, dar foloseşte o mască pentru a lăsa doar anumiţi biţi
să fie setaţi. Următoarele trei funcţii operează pe măşti de biţi, pentru setarea (trecerea
pe valoarea 1), resetarea (trecerea pe valoarea 0), şi alternarea/negarea (trecerea din 0
în 1 sau invers) biţilor specificaţi.
De asemenea, clasa ParallelPort este protejată pentru accesul de pe multiple fire de
execuţie prin folosirea clasei .NET System.Threading.Monitor (monitorizează porţiuni
de cod pentru ca accesul să fie individual asupra datelor).
C++/CLI
Monitor::Enter(ParallelPort::typeid);try{
// seteaza datele}finally
47
{Monitor::Exit(ParallelPort::typeid);
}
Deşi clasa în sine nu creează threaduri, monitorizarea a fost introdusa deoarece alte
clase (cum este clasa Motor) vor folosi mai multe fire de execuţie.
6.1.2. Clasa Laser abstractizeaza controlul laserului (oprirea si pornirea acestuia)
Laser
Clasa Laser reprezintă modulul laser, şi este simplă în funcţionalitate, permiţând
pornirea şi oprirea laserului. Membrii clasei sunt:
C#
private int? mBitLaser;private bool mTurnedOn;
public int? BitLaser {…}public bool TurnedOn {…}
public void Dispose() {…}private void Dispose(bool disposing) {…}
Primele două linii reprezintă câmpurile private ale clasei, mBitLaser şi mTurnedOn.
Ele reprezintă starea laserului la un moment dat. Iniţial laserul este oprit, iar linia de
date corespunzătoare lui nu se cunoaşte (este setată pe null). De observat faptul că este
folosit un tip special de variabila (int?) care de fapt reprezintă o valoare întreaga ce
poate fi nulă (Nullable<int>).
Următoarele două linii reprezintă proprietăţile clasei, accesibile public. Pentru
utilizare, întâi trebuie setat care este bitul de laser, prin intermediul proprietăţii
BitLaser, iar apoi se poate controla pornirea şi oprirea lui modificând valoarea
proprietăţii TurnedOn.
După utilizare, este recomandat să se apeleze funcţia Dispose pentru a opri laserul
automat. Dacă funcţia nu este apelata manual, ea va fi oricum apelată automat de către
48
colectorul automat de resturi (eng: automatic garbage collector), de obicei la
terminarea programului (dar nu neapărat).
6.1.3. Clasa Motor configurează şi controlează un motor pas cu pas
Motor
Clasa Motor este destul de complexă în comparaţie cu clasa Laser. Pentru modul de
operare s-a optat pentru folosirea rulării cu jumătăţi de pas (half-stepping):
Pas Faza 4 Faza 3 Faza 2 Faza 1 Codul secventei
0 0 0 0 1 0x01
1 0 0 1 1 0x03
2 0 0 1 0 0x02
3 0 1 1 0 0x06
4 0 1 0 0 0x04
5 1 1 0 0 0x0C
6 1 0 0 0 0x08
7 1 0 0 1 0x09
Deci secvenţele din ultima coloană sunt cele care trebuie urmate de sus în jos pentru
rotirea într-un sens a rotorului, pentru rotirea în sens invers, secvenţele se iau de jos în
sus.
C#
// 4-phase half-stepping modeprivate static readonly byte[] mSequences =
{ 0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09, 0x00 };private static readonly double mStepModeReduction = 2.0;private static readonly int mNumSeq = mSequences.Length - 1;private int mSeqIndex = mSequences.Length - 1;
Caracteristicile motorului (rezolutie, sistem reductor, viteza de rulare) sunt specificate
prin următorii parametri (accesibili prin proprietatile Resolution, Reduction, MinSpeed
şi MaxSpeed, sau prin funcţiile SetParameters şi GetParameters):
49
C#
// motor specificationsprivate double? mResolution; // angle resolution (degrees)private double? mReduction; // angle reduction (1:reduction)private double? mMinSpeed; // minimum rotation speed (rpm)private double? mMaxSpeed; // maximum rotation speed (rpm)
public double? Resolution {…}public double? Reduction {…}public double? MinSpeed {…}public double? MaxSpeed {…}
public void SetParameters(double? resolution,double? reduction,double? minspeed,double? Maxspeed
) {…}
public void GetParameters(out double? resolution,out double? reduction,out double? minspeed,out double? Maxspeed
) {…}
Liniile de date prin care se face comanda motorului pas cu pas pe portul paralel sunt
specificate prin următorii parametri (accesibili prin proprietăţile BitPhase1, BitPhase2,
BitPhase3 şi BitPhase4, sau prin funcţiile SetBits şi GetBits):
C#
// the data lines bits in clockwise order of the motor coilsprivate int? mBitPhase1;private int? mBitPhase2;private int? mBitPhase3;private int? mBitPhase4;
public int? BitPhase1 {…}public int? BitPhase2 {…}public int? BitPhase3 {…}public int? BitPhase4 {…}
public void SetBits(int? bitphase1,int? bitphase2,int? bitphase3,int? bitphase4
) {…}
public void GetBits(out int? bitphase1,out int? bitphase2,out int? bitphase3,out int? bitphase4
) {…}
50
În momentul lucrului cu motorul, acesta poate fi controlat prin proprietăţile Speed şi
Angle, având la bază o suită de câmpuri private, necesare stabilirii unghiului curent,
unghiului dorit şi vitezei de rotire. Pentru a opera corect în interfeţele grafice utilizator,
este folosită execuţia pe un fir separat pentru rotirea motorului.
C#
// calculated motor parametersprivate double? mReferenceAngle;private int? mAngleTicks;private double? mAngleStep;private double? mSpeed;private int? mDeltaTime;
// impulses threadThread mThread;double? mTargetAngle;
public double? Speed {…}public double? Angle {…}
Parametrii secundari (cei nedisponibili direct prin intermediul proprietatilor) sunt
calculaţi în funcţia ComputeSecondaryParameters. Pentru a afla dacă motorul este
gata de operare, în funcţie de setările efectuate, accesăm proprietatea Ready (poate fi
doar citită).
C#
private void ComputeSecondaryParameters(){
if (mSpeed < mMinSpeed) mSpeed = mMinSpeed;if (mSpeed > mMaxSpeed) mSpeed = mMaxSpeed;
mAngleStep = mResolution / (mReduction * mStepModeReduction);mDeltaTime = (int?)((mAngleStep / 360.0) * (60000.0 / mSpeed));
}
public bool Ready {…}
Firul de execuţie care reglează unghiul rotorului prin trimiterea de impulsuri
corespunzătoare secvenţelor de rotire rulează funcţia AngleThread şi este pornit şi
oprit cu ajutorul funcţiilor StopMotorThread şi StartMotorThread. Pentru
sincronizarea firului de execuţie al motorului cu cel al interfeţei grafice, apelăm funcţia
WaitForAngleReached, care utilizează clasa ManualResetEvent din spaţiul de nume
System.Threading (este un tip simplificat de semafor).
C#
// 'angle reached' signaling
51
ManualResetEvent mMotorStopped = new ManualResetEvent(true);
private void AngleThread() {…}private void StopMotorThread() {…}private void StopMotorThread(){…}private void StopMotorThread(){…}
public void WaitForAngleReached(){…}
O etapă importantă în obţinerea controlului asupra motorului este determinarea
fazelor. Pentru aceasta a fost creată o aplicaţie de test care trece prin toate
configuraţiile posibile (pe 4 biti, folosind formula permutărilor, avem 4! = 24
variante), menţinând timp de 3 secunde fiecare din configuraţii. Dintre acestea 24, 8
variante rotesc motorul corect (4 într-un sens, 4 în celălalt sens). Dacă nu s-ar fi folosit
o aplicaţie de detectare a ordinii fazelor, tot ar fi fost posibil (destul de uşor) să găsim
o configuraţie corectă (8/24 = 33% configuratii corecte).
La fel ca în cazul laserului, după terminarea lucrului cu motorul, este recomandat să se
apeleze funcţia Dispose pentru a opri firul de execuţie care roteşte motorul, şi a reseta
bitii folosiţi ai portului paralel.
6.1.4. Clasa Camera înglobează caracteristicile video şi funcţionalitatea unei
camere web
Camera
Pentru implementarea acestei clase a fost folosit limbajul C++/CLI, deoarece era
necesară interacţiunea cu librăriile DirectShow, şi înglobarea funcţiilor oferite într-o
formă accesibilă din C# (la fel ca în cazul clasei ParallelPort).
Această clasă înglobează funcţionalitatea unei camere web de care avem nevoie pentru
acest proiect. La iniţializarea statică a clasei, sunt detectate toate dispozitivele video de
pe calculator care sunt camere web. La fiecare din aceste dispozitive sunt colectate atat
descrierea dispozitivului (un şir de caractere unic, identificabil în sistem), cât şi
numele acestuia (afişat utilizatorului). Acestea pot fi folosite pentru a permite
52
utilizatorului să selecteze între diferitele camere disponibile în sistem. Colecţia este
oferită prin proprietatea Devices (care acceseaza câmpul mDevices), completată la
iniţializare de constructorul static al clasei.
C++/CLI
// list of devices found on the systemstatic initonly ReadOnlyCollection<CameraDescription^>^ mDevices;
// list of available devices on the systemstatic property ReadOnlyCollection<CameraDescription^>^ Devices {…}
Pentru utilizarea camerei, s-a renunţat la metoda tradiţională de creare a unui obiect
prin constructor (acesta a fost declarat protected, deci nu poate fi apelat decât din
interiorul clasei), şi s-a abordat stilul fabrică (eng: factory pattern), care ofera o funcţie
membru a clasei ce crează obiecte de tipul clasei respective. Aceasta este în cazul
nostru funcţia CreateCamera.
C++/CLI
protected:// the hidden constructor, used by the factory function
CreateCamera()Camera(IMoniker *pMoniker, CameraDescription^ description);
public:// factory function to create camera objectsstatic Camera^ CreateCamera(int index);
În momentul creării unui obiect de tip cameră, este generat intern graful de filtre
DirectShow ce va fi folosit, precum şi creatorul grafului de captură (eng: capture graph
builder). Acesta din urmă se va ocupa de conectarea optimă a filtrelor rămase
neconectate. Apoi sunt adăugate filtrele preliminare, cum ar fi filtrul sursa al camerei
şi filtrul convertor de culoare. Mai departe sunt obţinute interfetele de control al
semnalului video, cea de control al camerei şi cea de control al fluxului de date. Aceste
interfeţe ne vor da posibilitatea să ajustăm diferitele proprietăţi oferite de cameră.
C++/CLI
// the directshow interfacesIGraphBuilder *mpGraph;ICaptureGraphBuilder2 *mpCapture;
// the four filters that are added to the graph and linkedIBaseFilter *mpSrcFilter;IBaseFilter *mpSmartTee;IBaseFilter *mpColor;IBaseFilter *mpVmrFilter;
53
// video signal settingsIAMVideoProcAmp *mpVidProcAmp;// camera settingsIAMCameraControl *mpCamControl;// resolution controlIAMStreamConfig *mpStreamConfig;
Proprietăţile camerei care pot fi setate sunt împărţite în trei categorii: proprietăţile
semnalului video (Brightness, Contrast, Hue, Saturation, Sharpness, Gamma,
ColorEnable, WhiteBalance, BacklightCompensation şi Gain), proprietăţile de control
al camerei (Pan, Tilt, Roll, Zoom, Exposure, Iris, Focus) şi proprietăţile fluxului de
date (Resolution). Rezoluţia poate fi setată în funcţie de colecţia de rezoluţii
Resolutions suportate de către cameră.
C++/CLI
public:
property CameraProperty^ Brightness {…}property CameraProperty^ Contrast {…}property CameraProperty^ Hue {…}property CameraProperty^ Saturation {…}property CameraProperty^ Sharpness {…}property CameraProperty^ Gamma {…}property CameraProperty^ ColorEnable {…}property CameraProperty^ WhiteBalance {…}property CameraProperty^ BacklightCompensation {…}property CameraProperty^ Gain {…}
property CameraProperty^ Pan {…}property CameraProperty^ Tilt {…}property CameraProperty^ Roll {…}property CameraProperty^ Zoom {…}property CameraProperty^ Exposure {…}property CameraProperty^ Iris {…}property CameraProperty^ Focus {…}
property CameraResolution Resolution {…}property ReadOnlyCollection<CameraResolution>^ Resolutions {…}
Pentru a porni camera, este necesar întâi să o ataşăm. Previzualizarea poate fi ataşată
fie într-o fereastră Windows Forms, fie la o textură 3D în Direct3D (cu ajutorul
funcţiilor PreviewWFAttach şi PreviewD3DAttach). La momentul implementării clasei
nu este posibilă ataşarea într-o interfaţă WPF, deoarece nivelul la care este necesară
intervenţia nu este disponibil public în API-ul WPF. Pentru a putea totuşi previzualiza
camera şi în interfeţele din WPF, în aplicaţia principală s-a folosit tehnologia
Crossbow de la Microsoft care permite înglobarea de ferestre şi controale Windows
54
Forms în WPF, şi invers. Ataşarea camerei presupune completarea grafului de filtre cu
filtrul VMR9, capabil să afişeze conţinut video în ferestre WIN32 sau în texturi video
Direct3D. Pentru afişarea în Direct3D a fost necesară crearea unui filtru special (clasa
CameraAP). De asemenea utilizatorul trebuie să specifice care sunt dreptunghiurile
sursă (de la semnalul video al camerei) şi destinaţie (spre zona din fereastra/textura de
afişare). Odată ataşată previzualizarea, aceasta poate fi controlată cu ajutorul
următoarelor funcţii: PreviewPlay, PreviewPause şi PreviewStop.
C++/CLI
private:
// utility function to destroy the graphvoid TearDownGraph();// utility function to build the graphvoid AssembleGraph();//utility function to disconnect all pins connected to a base filtervoid DisconnectAllPins(IBaseFilter *pFilter);
protected private:
// VMR interfacesIVMRFilterConfig9 *mpConfig;// windowless modeIVMRWindowlessControl9 *mpVMRwc9;// renderless modeIVMRSurfaceAllocatorNotify9 *mpVMRsan9;
// Windows Forms attach
// the control to which the preview is attachedControl^ mWFControl;// the display area and video area preview settingsSystem::Drawing::Rectangle^ mWFDisplayArea;System::Drawing::Rectangle^ mWFVideoArea;
// Direct3D Device attach
// the device to which the preview is attachedDevice^ mD3DDevice;// custom allocator/presenterCameraAP* mpCameraAP;// the texture rectangle to which the preview is renderedRectangleF mD3DTextureRect;
public:
// 'preview' functionsvoid PreviewWFAttach(Control^ wfcontrol);void PreviewD3DAttach(Device^ d3ddevice);void PreviewDetach();void PreviewStop();void PreviewPause();void PreviewPlay();
55
Pentru a face o poză cu camera apelăm funcţia TakePicture. Deoarece modul în care
operează VMR9 este fie fără fereastră proprie (eng: windowless), adică în Windows
Forms, fie fără randare (eng: renderless), adică în Direct3D, funcţia TakePicture va
întoarce rezultatul uneia din funcţiile TakePictureWindowless sau
TakePictureRenderless.
C++/CLI
private:
// utility function to take picture while in windowless modeBitmap^ TakePictureWindowless();// utility function to take picture while in renderless modeBitmap^ TakePictureRenderless();
public:
// take a pictureBitmap^ TakePicture();
Şi în cazul clasei Camera, după încetarea lucrului cu dispozitivul, este recomandată
apelarea funcţiei Dispose pentru a elibera resursele.
6.1.5. Spaţiul ImageUtils realizează procesarea informaţiei video obţinute de la
camera web
ImageUtils.Filters, ImageUtils.Converters, ImageUtils.Processors
Spaţiul de nume ImageUtils conţine câteva clase care se ocupă cu procesarea
informaţiilor provenite de la camera web. Funcţiile din aceste clase sunt statice, deci
nu este necesară crearea unei instanţe a claselor respective pentru accesarea
funcţionalităţii acestora.
6.1.5.1. Clasa Filters identifică diferenţele apărute de la o imagine la alta
Filters
56
Clasa Filters conţine două funcţii de determinare a modificărilor apărute în fluxul
video, de la o imagine la alta. Sunt implementaţi doi algoritmi, DiffFilter şi
MotionDiffFilter. În aplicaţia principală este folosită doar funcţia DiffFilter.
C++/CLI
public ref class Filters{public:
static Bitmap^ DiffFilter(Bitmap^ before, Bitmap^ after);static Bitmap^ MotionDiffFilter(Bitmap^ before, Bitmap^ after);
};
Cele două funcţii primesc ca parametri două obiecte de tip Bitmap şi întorc un nou
obiect de acelaşi tip. Algoritmul funcţiei DiffFilter face diferenţa pentru fiecare
componentă a culorii (roşu, verde, albastru) între imaginea after şi cea before (D = A –
B). Algoritmul funcţiei MotionDiffFilter este puţin diferit. Acesta calculează întâi o
valoare medie a celor trei componente de culoare din ambele imagini, şi apoi face
diferenţa. Dacă valoarea obţinută este pozitivă, este reglată intensitatea componentei
roşu din imaginea finală. Dacă este negativă, este reglată intensitatea componentei
albastru. Componenta verde este setată la valoare maximă.
57
Fig. VI-2. Imaginea iniţială (before), imaginea finală (after),
imaginea obţinută cu DiffFilter, şi imaginea obţinută cu MotionDiffFilter.
6.1.5.2. Clasa Converters converteşte între cele două formate de imagine
Converters
Clasa pune la dispoziţie o singură funcţie, care realizează conversia între cele două
tipuri de obiecte imagine folosite: clasa Bitmap (din spaţiul de nume System.Drawing)
şi clasa BitmapSource (din spaţiul de nume System.Windows.Media.Imaging, folosită
în WPF). Conversia este necesară pentru a putea afişa imagina obţinută de la webcam
în interfaţa aplicaţiei creată în WPF.
C++/CLI
public ref class Converters{public:
static BitmapSource^ ConvertBitmap(Bitmap^ bitmap);};
6.1.5.3. Clasa Processors realizează identificarea liniei de scanare şi transpunerea
acesteia în spaţiul tridimensional
Processors
58
Operaţia de transpunere a liniei laserului din imagine într-o curbă în spaţiul 3D este
efectuată în două etape. Clasa Processors pune la dispoziţie funcţia pentru efectuarea
primei etape: transformarea liniei din imagine într-o linie de scanare în spaţiul 2D al
imaginii (parametrizarea liniei de scanare). Aceasta este efectuată de către funcţia
GetScanLine2DFromImage. Cea de-a doua funcţie este folosită pentru obţinerea unei
reprezentări pe ecran a parametrizării liniei.
C++/CLI
public ref class Processors{public:
static ScanLine2D^ GetScanLine2DFromImage(Bitmap^ redline, int threshold);
static Bitmap^ DrawScanLine2DtoImage(int width, int height, ScanLine2D^ scanline, Color bg, Color fg);
};
Mai jos este arătată imaginea liniei laser pe un obiect (stânga) şi reprezentarea
parametrizării ei (dreapta).
Fig. VI-3. Imaginea liniei laser identificată, şi parametrizarea acesteia.
6.1.6. Clasa Model3D înglobează informaţia obiectului scanat
Model3D
Această clasă realizează înglobarea tuturor informaţiilor scanate, şi nu numai.
Informaţia scanată este structurată într-o listă de linii de scanare (List<Scanline3D>).
Iniţial, modelul nu conţine nici o linie. Pe măsura ce este realizată scanarea obiectului,
59
sunt adăugate noi linii de scanare cu ajutorul funcţiei AddScanline(). La finalul
scanării trebuie setată proprietatea FullScan (dacă modelul a fost scanat prin rotire
completă), şi apoi apelată funcţia SetScanComplete(), care marchează sfârşitul
scanării.
C#
List<ScanLine3D> mScanLines;public void AddScanLine(ScanLine3D scanline) {…}SetScanComplete(){…}public bool FullScan { get {…} set {…} }
Liniile de scanare sunt prelucrate pentru a putea fi afişate pe ecran în cele patru
variante: puncte, linii, mesh şi suprafaţă. Funcţiile care se ocupă de acest lucru sunt
Update3DContent*(). Pentru implementarea micului editor din aplicaţie, sunt folosite
funcţii ca: SelectPoints(), SelectAllPoints(), InvertSelectedPoints(),
SmoothSelectedPoints(), DeleteSelectedPoints(), etc.
C#
private void Update3DContentPoints() {…}private void Update3DContentLines() {…}private void Update3DContentWireframe() {…}private void Update3DContentSurface() {…}private void Update3DContentAll() {…}
public void SelectPoints(Rectangle selrect) {…}public void DeSelectPoints(Rectangle selrect) {…}public void SmoothSelectedPoints(){…}public void DeleteSelectedPoints(){…}
De afişarea pe ecran se ocupă funcţiile Render*(). Pentru ca acestea să funcţioneze,
modelului îi trebuie ataşată o instanţă de tip Model3DPreview, care este de fapt un
control ce foloseşte Direct3D şi primeşte instrucţiuni de afişare din partea modelului.
Acest control este setat cu ajutorul funcţiei SetPreview().
C#
Model3DPreview mPreview;public void SetPreview(Model3DPreview preview) {…}public void RenderPoints() {…}public void RenderLines() {…}public void RenderWireframe() {…}public void RenderSurface() {…}
De asemenea pentru realizarea stocării şi încărcării modelelor, sunt folosite o serie de
funcţii ce lucrează în formatul XML. Pentru salvarea şi încarcarea fişierelor de tip
60
.model sunt folosite funcţiile GetModelXml() şi LoadFromXml(). Pentru salvarea
modelului în format X3D sunt folosite funcţiile Get*X3D(). Fişierul de descriere al
modelului (pentru crearea galeriei de modele de pe serverul web) este creat cu ajutorul
funcţiei GetPublishXml().
C#
public XmlDocument GetModelXml(){…}public void SaveAsXml(string filename) {…}public static Model3D LoadFromXml(string filename) {…}public XmlDocument GetPublishXml(){…}public XmlDocument GetPointsX3D(){…}public XmlDocument GetLinesX3D(){…}public XmlDocument GetWireframeX3D(){…}public XmlDocument GetSurfaceX3D(){…}
6.1.7. Clasa Model3DPreview realizează afişarea modelului
Pentru afişarea modelului este folosită componenta Direct3D a DirectX, varianta
gestionata (Managed DirectX). Pentru a putea fi folosit, trebuie iniţial setat modelul
ce va fi afişat, prin intermediul proprietăţii Model. Modul de vizualizare şi control al
camerei foloseşte coordonate sferice (două unghiuri, pe orizontala şi verticală, şi
distanţa până la obiect).
C#
// the D3D deviceprivate Device mDevice;
// camera parameters - sphericalprivate float mAlpha;private float mBeta;private float mDist;
// modelprivate Model3D mModel;public Model3D Model { get {…} set {…} }
6.1.8. Clasa Transforms realizează transpunerea liniei de scanare din imagine în
format bidimensional şi în format tridimensional
În cadrul algoritmului de obţinere a formei liniei de iluminare în spaţiul 3D s-a discutat
doar despre prima etapă, cea de parametrizare a imaginii ce conţine linia roşie a
61
laserului. Cea de-a doua etapă este de fapt cea mai importantă etapă din algoritmul de
triangulare, şi anume aceea de transformare a liniei de scanare din spaţiul 2D al
camerei, în cel 3D. Funcţia care face acest lucru este ScanLine2DToScanLine3D().
C#
public static ScanLine3D ScanLine2DToScanLine3D(// scanlineScanLine2D scanline,// camera geometrydouble fovangle, double aspectratio,// scene geometrydouble distance, double laserangle, double motorangle) {…}
6.2. Aplicaţia principală de configurare şi utilizare a scannerului
Dispozitivul de scanare în sine (format din motorul pas cu pas, modulul diodă laser,
circuitul de control şi camera web) este coordonat de aplicaţia de scanare Object
Scanner. Aceasta se foloseşte de toate librăriile discutate până acum pentru
determinarea formei obiectului, vizualizarea acestuia în diferite moduri şi stocarea
modelului.
Iniţial, la pornire, aplicaţia va prezenta următoarea interfaţă:
62
Fig. VI-4. Interfaţa principala a aplicaţiei de scanare.
Pentru a începe lucrul cu aplicaţia de scanare, iniţial trebuie setaţi parametrii de rulare.
Aceştia pot fi configuraţi accesând cele 5 butoane din partea superioară a interfeţei:
Laser Setup, Motor Setup, Camera Setup, Camera Geometry, Position Geometry şi
Scan Job Parameters.
După configurarea parametrilor, poate fi pornită scanarea obiectului. Butoanele de
control a scanării obiectului sunt: Start, Pause, Stop şi Reset. Atât în timpul scanării,
cât şi după terminarea acesteia, modelul poate fi vizualizat în partea din stânga a
interfeţei, la Object Preview. Pe toată durata scanării, în Camera Preview este afişat
fluxul video venit de la camera web, iar în dreapta interfeţei, la Processing Preview
pot fi analizate imaginile procesate de cameră, şi rezultatele parametrizării liniei de
scanare curente.
După terminarea scanării, modelul poate fi inserat în lista de obiecte scanate. Această
listă este controlată cu ajutorul butoanelor Grab, Preview, Rename, Remove. De
63
asemenea, modelele din această listă pot fi salvate şi încărcate de pe spaţiul local de
stocare (discul dur) folosind butoanele Save şi Load. Pentru publicarea modelului pe
un server FTP, se foloseşte butonul Publish.
6.2.1. Setarea parametrilor pentru scanarea obiectelor
Laser Setup
La apăsarea butonului Laser Setup, va apărea fereastra de setare şi testare a laserului.
Pentru oprirea şi pornirea laserului este necesară o singura linie de date a portului
paralel. Cele două butoane servesc pentru testarea funcţionării corecte a laserului.
Fig. VI-5. Configurarea parametrilor laserului.
Motor Setup
Fereastra de configurare şi testare a motorului pas cu pas este mai complexă. Se pot
seta cei 4 biţi ai portului paralel ce vor fi folosiţi, precum şi ordinea acestora (ordinea
fazelor poate fi descoperită destul de repede prin încercări, existând 24 de configuraţii
posibile, dintre care 8 rotesc motorul corect într-un sens sau în celalalt). Următorul
parametru ce trebuie setat este rezoluţia motorului, în acest caz 3,6. Parametrul gear
reduction este util în cazul folosirii angrenajelor de reducere a rezoluţiei, în lipsa
acestora parametrul trebuind setat la 1,0. Următorii parametri sunt legaţi de viteza de
rotire a motorului şi nu prezintă importanţă deosebită. Pentru testarea configuraţiei
sunt puse la dispoziţie 5 butoane (rotire continuu stânga, rotire pas stânga, stop, rotire
pas dreapta, rotire continuu dreapta).
64
Fig. VI-6. Configurarea parametrilor motorului.
Camera Setup
Setarea camerei consta în alegerea camerei ce va fi folosită (în caz că sunt disponibile
mai multe în sistem), a rezoluţiei acesteia, şi configurarea parametrilor de imagine:
Brightness, Contrast, Gamma, Gain, Exposure, Sharpness. Pentru a vedea calitatea
imaginii şi în cazul folosirii laserului, acesta poate fi pornit şi oprit prin apăsarea
butonului Toggle Laser.
Fig. VI-7. Configurarea parametrilor camerei.
65
Camera Geometry
Geometria camerei se referă la câmpul vizual al acesteia. Trebuie configurat unghiul
fov (eng: field of view), şi aspectul imaginii (adica raportul dintre lăţimea imaginii, şi
înălţimea acesteia).
Fig. VI-8. Configurarea geometriei camerei.
Position Geometry
Parametrii geometriei de poziţie descriu aşezarea celor 3 componente ale scannerului
în scenă (camera, motor, laser).
Fig. VI-9. Configurarea parametrilor geometrici de poziţie.
Scan Job Parameters
Aceşti parametri se referă la modul de scanare al obiectului. Start Angle şi Stop Angle
determină procentul din suprafaţa obiectului, care va fi scanat. În cazul de faţă rotirea
se efectuează cu 360, deci scanarea va fi completă. Parametrul Ticks Per Step indică
numărul de paşi cu care se va roti motorul pentru fiecare linie scanată.
66
Fig. VI-10. Configurarea parametrilor de scanare.
6.2.2. Controlarea scanării obiectului
Scanarea obiectului poate fi controlată prin intermediul butoanelor Start, Pause, Stop şi
Reset.
Fig. VI-11. Butoanele de control a procesului de scanare.
Butonul Start porneşte procesul de scanare a obiectului. Dacă se doreşte întreruperea
pe moment a scanării, se foloseşte butonul Pause. Pentru a relua scanarea din locul de
unde a fost întreruptă, se apasă din nou butonul Pause, sau butonul Start. Scanarea va
continua până la epuizarea tuturor paşilor de scanare. Dacă se doreşte finalizarea
prematură a scanării, poate fi folosit butonul Stop. Acesta întrerupe complet scanarea,
fără a pierde informaţiile deja culese. Butonul Reset este folosit pentru a reiniţializa
spaţiul de lucru, şi a porni o nouă scanare (nu poate fi începută o nouă scanare fără
apăsarea butonului Reset).
6.2.3. Vizualizarea modelului scanat sub diferite forme (nor de puncte, linii de
scanare, mesh, suprafaţă)
Modelul scanat poate fi vizualizat în fereastra Object Preview atât după terminarea
scanării, cât şi în timpul acesteia. În timpul scanării, ultima linie de scanare adăugată
67
va fi reprezentată cu roşu. Modelul poate fi analizat prin rotire, folosind butonul stânga
al mausului.
Fig. VI-12. Diferite moduri de vizualizare a obiectului scanat.
6.2.4. Editarea norului de puncte obţinut
Norul de puncte obţinut poate fi editat rapid pentru înlăturarea unor artifacturi, cum ar
fi platforma de rotire ce apare în cazul unei scanări normale. Selectarea punctelor se
face cu ajutorul butonului stânga al mausului, ţinând apăsată tasta Control. Pentru
deselectare, se foloseşte combinaţia de taste Control-Alt. Pentru ştergerea punctelor se
apasă tasta Delete. Există şi o opţiune de netezire a liniilor de scanare, ce poate fi
efectuată asupra punctelor selectate folosind combinaţia de taste Control-M. Toate
aceste funcţii de editare se regăsesc şi în cadrul meniului contextual al controlului, ce
poate fi accesat apăsând butonul dreapta al mausului.
68
Fig. VI-13. Editarea modelului scanat.
6.2.5. Mijloace de stocare a modelului scanat
Modelul scanat poate fi stocat şi încărcat atât local, pe discul dur, folosind formatul
propriu .model, cât şi publicat pe un server FTP, putându-se crea astfel o galerie cu
modelele scanate.
Fereastra de publicare pe serverul FTP este numită Ftp Publish. Este necesară
specificarea adresei serverului de FTP, a numelui sub care va fi stocat modelul,
precum şi a numelui de utilizator şi a parolei de acces.
Fig. VI-5. Publicarea modelului pe internet.
În urma operaţiei de publicare, pe serverul FTP vor fi stocate cinci fişiere: descrierea
modelului în format XML, şi cele patru moduri de vizualizare (nor de puncte, linii de
69
scanare, mesh şi suprafaţă) în format X3D. Folosind un plugin pentru deschiderea
fişierelor X3D, modelul poate fi vizualizat direct în browser.
Fig. VI-5. Vizualizarea modelului in cadrul galeriei online.
70
7. Concluzii
Proiectul de faţă reuşeşte, fără a folosi echipamente sofisticate, să realizeze un
dispozitiv de scanare a obiectelor 3D în vederea digitizării formei acestora. Trebuie
avute în vedere mai multe aspecte care influenţează calitatea informaţiei obţinute:
rezoluţia mică a camerei web, rezoluţia mică a motorului pas cu pas, considerente
legate de metoda de scanare folosită, algoritmul implementat de generare a
suprafeţelor.
Rezoluţia camerei web
Camera folosită dispune de o rezoluţie mică, 320x240, suficientă pentru scopuri
demonstrative, dar innacceptabilă în cazul unui produs comercial. Folosind o cameră
digitală de rezoluţie mare (de la 1MP în sus), se va obţine o formă mult mai detaliată a
fiecărei linii de scanare (de exemplu, la rezoluţia de 1024x768 se poate obţine un
maxim de 1024 de puncte pentru fiecare linie de scanare).
Rezoluţia motorului pas cu pas
Motorul folosit în acest proiect are o rezoluţie de 3,6, ceea ce înseamna 100 de linii de
scanare la o scanare completă a obiectului. Folosind un motor de rezoluţie mai mare
(1,8; 0,9; 0,72; etc.), sau un sistem reductor (angrenaje formate din roţi dinţate
dispuse special), se poate mări numărul de linii de scanare obţinute. De exemplu, dacă
s-ar fi folosit un sistem reductor cu un factor de reducere de 3,0, motorul s-ar fi rotit cu
1,2 la fiecare pas, deci s-ar obţine 300 linii de scanare. Există spre comercializare
astfel de motoare, dotate direct din fabrică cu sistem reductor, cum ar fi motorul
LSG35 produs de Hurst Manufacturing Inc. Sistemul reductor poate atinge un factor
de 300 (LSG35012E98P), ceea ce înseamnă o rezoluţie de 0,1 la fiecare pas (3600
linii de scanare la o scanare completă).
Considerente legate de metoda de scanare folosită
71
Din cauza faptului că laserul ce luminează obiectul este aşezat sub un anumit unghi
faţă de direcţia de vizualizare a camerei, obiectul nu este scanat complet. În anumite
poziţii, camera nu poate vedea complet linia trasată de laser (aceasta se întâmplă în
special când se ajunge la colţurile obiectului). Pentru a reduce din acest handicap, ar
trebui folosit un unghi al laserului cât mai mic. Aceasta rezultă într-o scanare aproape
completa a obiectului (desigur în cazul unui unghi de 0, scanarea este completă).
Unghiurile mici însa afectează calitatea curbei detectate, de aceea la unghiuri mici se
poate observa un zgomot pronunţat al liniilor de scanare (în cazul unghiului de 0,
forma liniei nu poate fi detectată). Un unghi mai mare asigură o bună detectare a
formei liniei laserului. De aceea trebuie realizat un compromis între aria de scanare a
obiectului şi calitatea scanării obţinute. Un unghi potrivit este cel de 30.
Algoritmul implementat de generare a suprafeţelor
În cazul aplicaţiei de faţă, pentru demonstraţie, suprafaţa este generată pornind de la
liniile de scanare, folosind un algoritm propriu. Însa într-un caz real aplicaţia de
scanare nu va fi cea care va genera din norul de puncte suprafaţa corespunzătoare.
Pentru acest scop exista aplicaţii de grafică speciale, care folosesc algoritmi avansaţi
de generare a suprafeţei (procesul poartă denumirea de “reconstruire a suprafeţei”, iar
algoritmii sunt de obicei bazaţi pe diagrame Voronoi şi triangulaţii Delaunay).
72
Bibliografie:
[1] Scanner cu laser 3D (data consultării: Noiembrie 2005)
http://www.muellerr.ch/engineering/laserscanner/
[2] Despre scannerele 3D (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/3D_scanner
[3] Module de lasere generatoare de linii LML (data consultării: Februarie 2006)
http://www.apinex.com/ret2/lmlan.html
[4] Laser (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/Laser
[5] Motorul pas cu pas (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/Stepper_motor
[6] Despre motoarele pas cu pas (data consultării: Martie 2006)
http://www.cs.uiowa.edu/~jones/step/index.html
[7] Portul paralel (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/Parallel_port
[8] Cum funcţioneaza portul paralel (data consultării: Mai 2006)
http://computer.howstuffworks.com/parallel-port.htm
[9] Ieşirea pe portul paralel (data consultării: Martie 2006)
http://www.epanorama.net/circuits/parallel_output.html
[10] Controlul motorului pas cu pas prin portul paralel (data consultării: Martie 2006)
http://www.doc.ic.ac.uk/~ih/doc/stepper/control2/connect.html
73
[11] Un exemplu de control al motorului pas cu pas (data consultării: Martie 2006)
http://www.electronics-lab.com/projects/pc/006/index.html
[12] Programarea Orientata Obiect (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/Object_oriented_programming
[13] Programarea Declarativa (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/Declarative_programming
[14] C# (C Sharp) (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/C_sharp
[15] C++/CLI (C++ / Common Language Infrastructure) (data consultării: Aprilie
2006)
http://en.wikipedia.org/wiki/C%2B%2B/CLI
[16] XAML (eXtensible Application Markup Language) (data consultării: Aprilie
2006)
http://en.wikipedia.org/wiki/XAML
[17] .NET Framework (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/.net_framework
[18] Windows Presentation Foundation (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/Windows_Presentation_Foundation
[19] DirectShow (data consultării: Aprilie 2006)
http://en.wikipedia.org/wiki/DirectShow
[20] Formatul X3D (data consultării: Iunie 2006)
http://www.web3d.org/x3d/specifications/
74
[21] Geometry compendium (data consultării: Iunie 2006)
http://astronomy.swin.edu.au/~pbourke/geometry/
75
Alte resurse:
Forumuri de discutii MSDN
http://forums.microsoft.com/MSDN/
Grupuri de discutii Google:
http://groups.google.com/
microsoft.public.win32.programmer.directx.managed
microsoft.public.win32.programmer.directx.video
microsoft.public.windows.developer.winfx.avalon
Documentatie pentru diverse API-uri folosite
http://www.msdn.com
Exemple de aplicatii
http://www.codeproject.com
76