Spisu treści:

Skaner laserowy Raspberry Pi: 9 kroków (ze zdjęciami)
Skaner laserowy Raspberry Pi: 9 kroków (ze zdjęciami)

Wideo: Skaner laserowy Raspberry Pi: 9 kroków (ze zdjęciami)

Wideo: Skaner laserowy Raspberry Pi: 9 kroków (ze zdjęciami)
Wideo: Kodi (LibreELEC) + Raspberry Pi4 czyli jak zbudować własne MediaPC, tanio, szybko i łatwo 2024, Lipiec
Anonim
Image
Image
Skaner laserowy Raspberry Pi
Skaner laserowy Raspberry Pi

Skaner laserowy to wbudowane urządzenie systemowe Raspberry Pi, które może digitalizować obiekty do plików siatki.obj w celu reprodukcji za pomocą drukowania 3D. Urządzenie robi to, wykorzystując laser liniowy i zintegrowany PiCam do wykonywania wizji komputerowej. Laser jest ustawiony pod kątem 45 stopni w stosunku do lasera i wyświetla jaskrawoczerwoną linię na jeden pionowy wycinek obiektu. Kamera wykrywa odległość plasterka od środka, aby uzyskać plasterek siatki. Obiekt jest wirowany na obrotowej tacy i proces jest powtarzany aż do zeskanowania całego obiektu. Wygenerowany plik.obj jest ostatecznie wysyłany do użytkownika pocztą elektroniczną, dzięki czemu system jest w pełni samodzielny i osadzony.

Ten instruktaż omówi sposób budowy urządzenia, niektóre wyniki i przyszłe kroki.

Krok 1: Inspiracja

Inspiracja
Inspiracja
Inspiracja
Inspiracja

Jako zapalony twórca od kilku lat zajmuję się drukowaniem 3D i modelowaniem bryłowym. Pracowałem z wieloma różnymi narzędziami do prototypowania, od routerów CNC przez wycinarki laserowe po drukarki 3D. Jednym z urządzeń, którego moja lokalna przestrzeń produkcyjna jeszcze nie kupiła, był skaner 3D – i mogę ci powiedzieć, dlaczego.

Tańsze (kilkaset dolarów) były zawodne, wymagały doskonałych warunków, a mimo to dawały dość marne rezultaty. Te drogie były… no cóż, drogie, sięgały nawet kilku tysięcy dolarów, przez co ich funkcja w wielu przypadkach nie była tego warta. Co więcej, częściej niż nie decyduję się na pomiary i zaprojektowanie modelu od podstaw, niż zajmuję się siatką powierzchni wygenerowaną ze skanu.

Z tego powodu chciałem zbudować niedrogi samodzielny skaner, aby zobaczyć, jak dobrze mogę zeskanować obiekt przy użyciu gotowych komponentów.

Po przeprowadzeniu pewnych badań zauważyłem, że wiele skanerów 3D wykorzystuje obrotową platformę, a następnie różne czujniki do pomiaru odległości od środka w celu zbudowania modelu obrotowego. Wiele z nich używało podwójnych kamer podobnych do tego z Kinect. W końcu natknąłem się na Yscanner, który jest skanerem o niskiej rozdzielczości wykorzystującym laser. Patrząc na prostotę i wykonalność, ta technika laserowa, w której laser jest przesunięty względem kamery w celu pomiaru odległości od środka, wyglądała na wyraźną ścieżkę do przodu.

Krok 2: Narzędzia i części

Części:

  • Raspberry Pi 35,00 zł
  • Kamera Raspberry Pi V2 30,00 zł
  • Diody LED, rezystory i przewody
  • Filament do druku 3D
  • Arkusze drewna 12x12x0,125
  • Sprzęt M3
  • Silnik krokowy - 14 USD
  • Laser liniowy - $8
  • Sterowniki silników krokowych LN298 - 2,65 USD
  • Przycisk metalowy - $5

Narzędzia:

  • Lutownica
  • Wycinarka laserowa
  • drukarka 3d
  • Śrubokręt
  • Szczypce

Krok 3: Projekt wysokiego poziomu

Projekt wysokiego poziomu
Projekt wysokiego poziomu
Projekt wysokiego poziomu
Projekt wysokiego poziomu

Centralnym elementem tego projektu jest laser liniowy, który rzutuje na pionowy przekrój obiektów. Ta projekcja może zostać uchwycona na pikamerze, skorygowana w perspektywie, a następnie przefiltrowana przed przetwarzaniem obrazu. W przetwarzaniu obrazu można zebrać odległość między każdym segmentem linii od środka obiektu. We współrzędnych radialnych obraz ten dałby zarówno składowe r, jak i z. Trzeci wymiar, Θ, jest następnie osiągany przez obrócenie obiektu do nowego wycinka. Ta koncepcja jest pokazana na pierwszym rysunku.

Aby wykonać opisane powyżej czynności, wykorzystałem Raspberry Pi jako naszą centralną jednostkę obliczeniową. Podłączyłem silnik krokowy i sterownik silnika do Pi, zasilany z zewnętrznego zasilacza 5 V i kontrolowany przez piny GPIO Pi. Laser liniowy został umieszczony na linii 3,3 V na Pi, a PiCam został podłączony do wejścia kamery na Pi. Na koniec zainstalowano prosty rozwijany przycisk i diodę LED stanu, aby wskazać użytkownikowi, w jakim stanie znajduje się system. Cały system jest podsumowany na schemacie blokowym systemu.

Od początku planowano umieścić elektronikę w laserowo wycinanym pudełku, które łączy się z rowkami teowymi i osprzętem M3. Elektronika byłaby ukryta przed wzrokiem w dolnej komorze, a pokrywa umożliwiałaby łatwy dostęp do umieszczania przedmiotów na obrotowej tacy. Ta pokrywa jest niezbędna, aby zminimalizować ilość światła przedostającego się do systemu, ponieważ to zewnętrzne światło może generować hałas podczas końcowego skanowania.

Krok 4: Sprzęt

Sprzęt komputerowy
Sprzęt komputerowy
Sprzęt komputerowy
Sprzęt komputerowy
Sprzęt komputerowy
Sprzęt komputerowy

Jak widać powyżej, zanim zacząłem cięcie laserowe lub drukowanie 3D, użyłem Autodesk Fusion 360 do wykonania szczegółowego modelu 3D naszego projektu. Ogólnie rzecz biorąc, urządzenie jest prostym pudełkiem z pokrywką z wyciętymi laserowo zawiasami. Urządzenie składa się z dwóch głównych warstw: łoża z elektroniką i łoża głównego, z otworami do prowadzenia przewodów pomiędzy tymi warstwami.

Większość naszych pudełek została wyprodukowana za pomocą wycinarki laserowej, a projekty zostały wyprodukowane w Fusion 360 i wycięte na wycinarce laserowej Epilog Zing 40 W. Nasze projekty są pokazane na powyższych rysunkach. Od lewego górnego rogu przesuwając się w prawo, elementy to łóżko główne, łóżko elektroniki, dwie części na pokrywę, część tylna, część przednia i dwie części boczne. W głównym łóżku znajdują się trzy główne wycięcia: jedno do montażu silnika krokowego, jedno do prowadzenia przewodów z lasera i jedno do prowadzenia szerokiego kabla PiCam. Łóżko ma otwory montażowe do mocowania Pi, płytki stykowej i sterownika silnika oraz większe wycięcie umożliwiające dostęp do silnika krokowego. Elementy pokrywy zatrzaskują się po prostu, tworząc trójkątny element widoczny powyżej, a zawias jest prostym wytłoczeniem, które ma szerokość średnicy otworu w deskach bocznych. Tylna część i jedna z bocznych części mają szczeliny z boku, dzięki czemu można łatwo uzyskać dostęp do portów Pi (HDMI, USB, Ethernet, Power). Przód jest prostym elementem, w którym ostatecznie zrobiłem otwory wiertarką ręczną, aby zamontować przycisk i diodę LED. Jak widać na wszystkich elementach, nasze części są utrzymywane razem przez osprzęt M3 za pomocą trójników i szczelin. Jest to metoda przytrzymywania ciętych laserowo elementów prostopadle i bezpiecznie. Żebra kawałków są wyrównane z rowkami innych kawałków, a wycięcie w kształcie litery T na krawędziach daje miejsce na wciśnięcie nakrętki M3 bez obracania. Pozwala nam to następnie użyć śruby M3 do zablokowania elementów razem z bardzo małą ilością miejsca na ruchy, bez konieczności pełnego trwałego montażu.

Zdecydowałem się wykonać większość naszych prac za pomocą wycinarki laserowej ze względu na jej szybkość i łatwość. Jednak nadal musiałem drukować w 3D niektóre elementy ze względu na ich geometrię 3D, która byłaby trudniejsza do wykonania na ploterze. Pierwszym elementem był uchwyt lasera liniowego. Ten element miał być zamontowany na głównym łóżku pod kątem 45 stopni od widoku kamery i mieć otwór tak, aby laser mógł być w nim ciasno dopasowany. Musiałem też stworzyć mocowanie silnika, ponieważ wał silnika był bardzo długi. Mocowanie tarciowe pasowało do wyciętych laserowo elementów i obniżyło płaszczyznę, do której przymocowano silnik, tak aby obrotowa platforma znajdowała się równo z głównym łóżkiem.

Krok 5: Elektronika

Elektronika
Elektronika

Okablowanie tego projektu było bardzo proste, ponieważ skaner 3D nie wymagał zbyt wielu urządzeń peryferyjnych. Do Pi należało podłączyć silnik, przycisk, diodę LED, laser i kamerę. Jak pokazano, upewniłem się, że rezystory zostały połączone szeregowo z każdym pinem, którego użyliśmy, aby chronić piny. Jeden pin GPIO był dedykowany do sterowania diodą statusu, która zapalała się, gdy urządzenie było gotowe do użycia i pulsowała z PWM, gdy urządzenie pracowało. Kolejny pin GPIO był podłączony do podciągniętego przycisku, rejestrując HIGH, gdy przycisk nie był wciśnięty, i LOW, gdy przycisk był wciśnięty. Na koniec poświęciłem cztery piny GPIO do napędzania silnika krokowego.

Ponieważ nasz silnik musiał poruszać się tylko w pewnym stopniu bez konieczności kontrolowania prędkości, zdecydowaliśmy się na prostszy sterownik silnika krokowego (L298N), który po prostu zwiększa linie sterujące, aby zasilać wejścia silnika. Aby dowiedzieć się, jak obsługiwać silniki krokowe na bardzo niskim poziomie, odwołaliśmy się zarówno do arkusza danych L298N, jak i biblioteki Arduino. Silniki krokowe mają rdzeń magnetyczny z wystającymi palcami o zmiennej polaryzacji. Cztery przewody są owinięte, aby sterować dwoma elektromagnesami, z których każdy zasila każdy przeciwny palec w silniku. Tym samym zmieniając biegunowość palców jesteśmy w stanie popchnąć stepper o jeden krok. Dzięki tej wiedzy na temat działania stepperów z poziomu sprzętu byliśmy w stanie znacznie łatwiej sterować stepperami. Zdecydowaliśmy się na zasilanie naszego silnika krokowego z zasilacza 5 V w laboratorium, a nie z Pi, ze względu na maksymalny pobór prądu wynoszący około 0,8 A, czyli więcej niż Pi może dostarczyć.

Krok 6: Oprogramowanie

Oprogramowanie
Oprogramowanie
Oprogramowanie
Oprogramowanie
Oprogramowanie
Oprogramowanie
Oprogramowanie
Oprogramowanie

Oprogramowanie do tego projektu można podzielić na cztery główne komponenty, które współdziałają ze sobą: przetwarzanie obrazu, sterowanie silnikiem, tworzenie siatki i funkcje osadzone.

Jako podsumowanie oprogramowania możemy spojrzeć na pierwszą cyfrę. Podczas uruchamiania systemu.bashrc automatycznie loguje się do Pi i zaczyna uruchamiać nasz kod Pythona. System zapala lampkę stanu, aby poinformować użytkownika, że został uruchomiony poprawnie i czeka na naciśnięcie przycisku. Użytkownik może następnie umieścić przedmiot do zeskanowania i zamknąć pokrywę. Po naciśnięciu przycisku dioda LED pulsuje, informując użytkownika, że urządzenie działa. Urządzenie będzie przełączać się w pętli między przetwarzaniem obrazu a sterowaniem silnikiem, aż do pełnego obrotu i zebrania wszystkich danych obiektu. Na koniec tworzona jest siatka, a plik jest wysyłany pocztą elektroniczną na wstępnie wybraną wiadomość e-mail. Powoduje to ponowne uruchomienie cyklu, a maszyna jest gotowa do wykonania kolejnego skanowania po naciśnięciu przycisku.

Przetwarzanie obrazu

Pierwszą zaimplementowaną rzeczą było przetworzenie przechwyconego obrazu w celu wydobycia informacji zapisanych w obrazie do postaci, która mogłaby zostać użyta do stworzenia tablicy punktów w przestrzeni. Aby to zrobić, zacząłem od zrobienia zdjęcia obiektu na platformie wraz z całym szumem tła wytwarzanym przez laser świecący na tył pudełka i rozpraszający się. Ten obraz miał dwa główne problemy w swojej surowej formie. Po pierwsze, obiekt był oglądany pod kątem z podniesioną perspektywą, a po drugie, w tle było dużo szumu. Pierwszą rzeczą, którą musiałem zrobić, to uwzględnić ten kąt widzenia, ponieważ użycie zdjęcia w takim stanie nie pozwoliłoby nam określić stałej wysokości obiektu. Jak widać na drugim rysunku, wysokość odwróconego kształtu „L” jest spójna; jednak ze względu na to, że jedna strona jest dłuższa od drugiej, wydają się mieć różne wysokości na krawędzi najbliżej widza.

Aby to naprawić, musiałem przekształcić obszar roboczy na obrazie w prostokąt z trapezoidalnego kształtu, w którym był poprzednio. Aby to zrobić, użyłem kodu dostarczonego przez ten link, który po podaniu obrazu i czterech punktów przycina obraz między czterema punktami i przekształca przycięty obraz, aby skompensować perspektywę. Ta transformacja wykorzystuje cztery punkty do utworzenia prostokąta zamiast kształtu typu trapez, jak widać na trzecim rysunku.

Kolejnym problemem, który wymagał rozwiązania, był szum tła w postaci światła zewnętrznego i odbijanie światła przez sam laser. W tym celu przefiltrowałem światło za pomocą funkcji inRange() OpenCV. Ustawiłem próg, aby na pewnym poziomie odbierać tylko czerwone światło. Aby uzyskać prawidłową wartość, zacząłem od łagodnego progu i zwiększałem poziom progu, aż jedynym odbieranym światłem było światło lasera na skanowanym obiekcie. Po uzyskaniu tego obrazu znalazłem najjaśniejszy piksel w każdym rzędzie uzyskać linię jednego piksela na wiersz, która graniczy z lewą skrajną stroną linii lasera. Każdy piksel był następnie konwertowany na wierzchołek w przestrzeni 3D i przechowywany w tablicy, jak opisano w sekcji tworzenia siatki. Wyniki tych kroków można zobaczyć na czwartym rysunku.

Kontrola silnika

Po pomyślnym przetworzeniu pojedynczego obrazu, aby uzyskać wycinek obiektu, musiałem być w stanie obrócić obiekt, aby zrobić nowe zdjęcie pod innym kątem. Aby to zrobić, sterowałem silnikiem krokowym pod platformą, na której znajduje się skanowany obiekt. Zbudowałem podstawę naszej funkcji krokowej, tworząc zmienną do śledzenia stanu silnika i mikrokroku, przełączając każde z czterech wejść silnika.

Tworzenie siatki Aby utworzyć siatkę ze wszystkich przetworzonych obrazów, najpierw musiałem przekonwertować każdy biały piksel w przetworzonym obrazie na wierzchołek w przestrzeni 3D. Ponieważ zbieram pojedyncze plastry obiektu o symetrii cylindrycznej, sensowne było rozpoczęcie zbierania współrzędnych cylindrycznych. Miało to sens, ponieważ wysokość obrazu może reprezentować oś z, odległość od środka stołu obrotowego może reprezentować oś R, a obrót silnika krokowego może reprezentować oś theta. Ponieważ jednak przechowywałem nasze dane we współrzędnych cylindrycznych, musiałem przekonwertować każdy z tych wierzchołków na współrzędne kartezjańskie.

Po utworzeniu tych wierzchołków były one przechowywane na liście, a wspomniana lista była przechowywana na innej liście, która zawierała listy wierzchołków utworzone dla każdego przechwyconego obrazu. Gdy wszystkie obrazy zostały przetworzone i przekonwertowane na wierzchołki, musiałem wybrać wierzchołki, które faktycznie chciałem przedstawić w końcowej siatce. Chciałem, aby uwzględniono górny i dolny wierzchołek, a następnie na podstawie rozdzielczości wybrałem równomiernie rozmieszczoną liczbę wierzchołków do użycia dla każdego obrazu. Ponieważ nie wszystkie listy wierzchołków miały tę samą długość, musiałem je wyrównać, znajdując listę z najmniejszą liczbą wierzchołków i usuwając wierzchołki ze wszystkich innych list, aż wszystkie były parzyste. Po utworzeniu list wierzchołków mogłem teraz utwórz siatkę. Zdecydowałem się sformatować naszą siatkę według standardu pliku.obj, ponieważ jest prosta i można ją wydrukować w 3D.

Wbudowana funkcja

Po tym, jak urządzenie było sprawne, dopracowałem je dodając pełną, wbudowaną funkcjonalność. Oznaczało to usunięcie klawiatury, myszy i monitora oraz bezprzewodowe przesłanie nam pliku.obj po zakończeniu przetwarzania. Na początek zmieniłem kod.bashrc, aby automatycznie logował się i uruchamiał główny program Pythona podczas uruchamiania. Dokonano tego za pomocą sudo raspi-config i wybierając „Console Autologin” oraz dodając wiersz „sudo python /home/pi/finalProject/FINAL.py” do /home/pi/.bashrc. dodano przycisk i diodę LED stanu dla wejścia i wyjścia użytkownika. Przycisk pozwalałby użytkownikowi powiedzieć urządzeniu, kiedy rozpocząć skanowanie, a dioda LED informowałaby użytkownika o stanie urządzenia. Jeśli dioda świeci, urządzenie jest gotowe do rozpoczęcia nowego skanowania. Jeśli dioda LED pulsuje, urządzenie aktualnie skanuje. Jeśli dioda LED jest biurowa, wystąpił błąd oprogramowania, wzywający do ponownego uruchomienia systemu. Na koniec umożliwiłem urządzeniu wysyłanie pliku.obj przez e-mail. Dokonano tego za pomocą bibliotek smtplib i e-mail. Ta możliwość wysyłania e-maili dała nam bardzo wygodny i bezprzewodowy sposób dostarczania wytworzonego pliku do użytkownika na wielu różnych platformach.

Krok 7: Integracja

Integracja
Integracja

Po wyprodukowaniu różnych części urządzenia, zmontowałem je razem. Powyższy rysunek przedstawia w kolejności:

(a) zmontowane pudełko na zewnątrz

(b) zmontowane pudełko wewnątrz z kamerą i laserem

(c) widok wnętrza łóżka elektroniki

(d) tył Pi z dostępem do portów Pi i wejścia silnika 5V

(e) przycisk z pierścieniem LED i lampką stanu z przodu urządzenia;

Krok 8: Wyniki

Wyniki
Wyniki
Wyniki
Wyniki
Wyniki
Wyniki
Wyniki
Wyniki

Laserowy skaner 3D potrafił skanować obiekty z przyzwoitą precyzją. Cechy obiektów są wyraźne i rozpoznawalne, a części można bardzo łatwo wydrukować w 3D za pomocą oprogramowania do cięcia, takiego jak Repetier. Powyższe rysunki pokazują kilka przykładowych skanów kawałka drewna i gumowej kaczuszki.

Jednym z naszych największych odkryć i sukcesów, które odkryłem podczas testów, była spójność urządzenia. Podczas wielu prób tego samego obiektu skaner był w stanie wygenerować plik.obj, który za każdym razem był bardzo podobny, nawet jeśli nieznacznie zmieniliśmy położenie obiektu. Jak widać na trzech oddzielnych skanach, wszystkie wyglądają bardzo podobnie, rejestrując te same szczegóły i taką samą ilość szczegółów. Ogólnie byłem pod wrażeniem spójności i solidności naszego systemu.

Jedną ze zmiennych, które naprawdę udało mi się dostroić, jest rozdzielczość skanów. Ponieważ w steperze jest 400 kroków, mogę wybrać, jak duży jest każdy ΔΘ, aby dyktować rozdzielczość kątową. Domyślnie mam rozdzielczość kątową ustawioną na 20 iteracji, co oznacza, że w każdej klatce silnik obraca się o 20 kroków (400/20 = 20). Wybrano to głównie ze względu na czas - wykonanie w ten sposób skanu zajmuje około 45 sekund. Jeśli jednak chcę uzyskać skan o znacznie wyższej jakości, mogę zwiększyć liczbę iteracji aż do 400. Daje to o wiele więcej punktów do skonstruowania modelu, co zapewnia znacznie bardziej szczegółowy skan. Oprócz rozdzielczości kątowej mogę również dostosować rozdzielczość pionową lub liczbę różnych punktów, które wybieram do sondowania wzdłuż wycinka laserowego. Dla podobnego zainteresowania czasem ustawiłem tę domyślną wartość na 20, ale mogę ją zwiększyć, aby uzyskać lepsze wyniki. Bawiąc się tymi parametrami rozdzielczości kątowej i przestrzennej, udało mi się skompilować wyniki różnych skanów poniżej na ostatnim rysunku. Każda etykieta jest sformatowana w taki sposób, że jest to rozdzielczość kątowa x rozdzielczość przestrzenna. Jak widać w domyślnych ustawieniach skanowania, funkcje kaczki są rozpoznawalne, ale nie są szczegółowe. Jednak w miarę zwiększania rozdzielczości zaczynają pojawiać się poszczególne, precyzyjne cechy, w tym oczy, dziób, ogon i skrzydła kaczki. Skanowanie obrazu o najwyższej rozdzielczości zajęło około 5 minut. Zobaczenie tak wysokiej możliwej do osiągnięcia rozdzielczości było bardzo dużym sukcesem.

Ograniczenia

Pomimo pomyślnych wyników projektu, nadal istnieje kilka ograniczeń w projektowaniu i wdrażaniu. Z użyciem lasera pojawia się wiele problemów z rozpraszaniem światła. Wiele obiektów, które próbowałem zeskanować, które były albo półprzezroczyste, błyszczące, albo bardzo ciemne, powodowało problemy z odbijaniem się światła od powierzchni. Gdyby obiekt był przezroczysty, światło zostałoby pochłonięte i rozproszone, powodując bardzo głośny odczyt plasterków. W błyszczących i ciemnych przedmiotach światło byłoby albo odbijane, albo pochłaniane do punktu, w którym trudno byłoby je uchwycić. Co więcej, ponieważ używam aparatu do uchwycenia cech obiektów, jego wykrywanie jest ograniczone przez linię widzenia, co oznacza, że wklęsłe obiekty i ostre kąty są często blokowane przez inne części obiektu. Jest to pokazane w naszym przykładzie gumowej kaczuszki, ponieważ ogon czasami traci swoją krzywiznę na skanie. Kamera może również wykrywać tylko struktury powierzchni, co oznacza, że nie można uchwycić otworów ani geometrii wewnętrznej. Jest to jednak powszechny problem, który występuje również w wielu innych rozwiązaniach do skanowania.

Następne kroki

Chociaż byłem zadowolony z wyników naszego projektu, było kilka rzeczy, które można było wdrożyć, aby go ulepszyć. Na początek, w obecnym stanie rozdzielczość skanowania można zmienić tylko poprzez zmianę zakodowanych na stałe zmiennych rozdzielczości w naszym kodzie. Aby projekt był bardziej osadzony, można dołączyć potencjometr rozdzielczości, aby użytkownik mógł zmieniać rozdzielczość bez konieczności podłączania monitora i klawiatury do skanera. Ponadto skaner tworzy obrazy, które czasami mogą wyglądać na postrzępione. Aby to naprawić, można zastosować techniki wygładzania siatki, aby wygładzić nierówności i ostre narożniki. Wreszcie odkryłem, że współrzędne pikseli nie skalują się dobrze do rzeczywistego świata. Utworzone przeze mnie siatki były od 6 do 7 razy większe niż rzeczywisty obiekt. W przyszłości korzystne byłoby zaimplementowanie sposobu skalowania siatek, aby były one bardziej dokładne do rzeczywistego rozmiaru obiektu.

Krok 9: Zasoby

Dołączyłem kod, pliki STL do druku oraz pliki DXF do wycięcia na całość projektu.

Konkurs Raspberry Pi 2020
Konkurs Raspberry Pi 2020
Konkurs Raspberry Pi 2020
Konkurs Raspberry Pi 2020

Pierwsza nagroda w konkursie Raspberry Pi 2020

Zalecana: