Interpretacja poleceń "I" oraz "J"

Rozmowy dotyczące oprogramowania sterującego maszynami CNC i sterowników CNC obrabiarek numerycznych

Autor tematu
baxter12
Sympatyk forum poziom 2 (min. 50)
Sympatyk forum poziom 2 (min. 50)
Posty w temacie: 4
Posty: 57
Rejestracja: 04 lut 2013, 17:03
Lokalizacja: Poznan

Interpretacja poleceń "I" oraz "J"

#1

Post napisał: baxter12 » 23 sie 2013, 13:48

Zapragnąłem i ja mieć plotter, a ponieważ lezy mi Arduino, postanowiłem zbudować maszynkę w oparciu o te platformę. Rozwiazania które wujek google podsunął, nie zadowalały mnie, w zw. z tym postanowiłem sam napisać kod który pozwoli sterować maszyna.
Zaznaczam że całą pracę obliczeniowa wykonuje Arduino. Komputer przesyła G-code, po wykonaniu jednej linii, Arduino prosi o nastepna, rozpoznaje i interpretuje odebrane komendy i parametry, tnie, i znów prosi o następną linie kodu.
Biezące położenie freza jest podawane na LCD.

Aby wypróbować poprawność napisanego kodu, złożyłem sobie maszynkę na początek, za 200 zł. Takie g. na początek, silniki krokowe znalazłem na śmietniku, zawiasy od szuflad za 20 zł, trzy sterowniki l293, i kilka tranzystorów, pręt gwintowany M6 z Castoramy i trzy długie nakretki. Wyswietlacz LCD za 17zł.
I Pare tygodni dłubania i składania, na początek wystarczy, aby się z technika zapoznać. A w planach juz następna maszynka.
Link do kilku zdjęć:
http://www.rcclub.eu/view...w=unread#unread


A teraz problem:
Program poprawnie odczytuje i interpretuje kody G00, G01, oraz parametry X, Y, Z, . Poprawnie rozlicza kroki, aby wykreślić linię krzywą (tzn. Linię prostą prowadzona pod kątem).
Potrafi się zpozycjonować w punkcie X0 Y0.

Poniżej fragment kodu "rozliczającego" linię. chodzi o to co ile kroków X trzeba zrobic krok Y, aby prosta była maksymalnie prosta. Publikuję z dumą bo zajęło mi tydzień wymyślenie sposobu obliczania...

//Gdy X lub Y = "0" Jeżeli posów w którejś osi jest równy "0"
if (STEP_X == 0){x = 0 ; Jeżeli posów w kierunku x jest 0
if (STEP_Y > 0) { for ( x == 1 ; x <= STEP_Y ; x++ ){StepperY.step(1); }}
if (STEP_Y < 0) { for ( x == -1 ; x >= STEP_Y ; x--){StepperY.step(-1); }}
STEP_Y = 0;}jeżeli posów w kierunku Y jest 0
if (STEP_Y == 0){x = 0 ;
if (STEP_X > 0) { for ( x == 1 ; x <= STEP_X ; x++ ){StepperX.step(1); }}
if (STEP_X < 0) { for ( x == -1 ; x >= STEP_X ; x--){StepperX.step(-1); }}
STEP_X = 0;}
// Pierwsza cwiartka ukł. współrzędnych, w linii zamieniam wszystkie wartości na większe od zera
if (STEP_X > 0 && STEP_Y > 0){STEP_X = abs(STEP_X); STEP_Y = abs(STEP_Y);
Jeżeli X=Y wtedy jedziemy na skos :)
if (STEP_X == STEP_Y){ x = 0 ; for ( x == 0; x <= STEP_X ; x++){ StepperX.step(1);StepperY.step(1);}}
A poniże główny algorytm rozliczjacy kroki:
if (STEP_X > STEP_Y){
A_1 = STEP_X / STEP_Y ;
float A = STEP_X / STEP_Y ;
if (A_1 < A) { A_1 = A_1 + 1 ; }
r = STEP_Y - (STEP_X/A_1);
if ( r > 0){ A_2 = STEP_X / r ;
r = STEP_Y - (STEP_X/A_1) - (STEP_X/A_2) ;}
if ( r > 0){
A_3 = STEP_X / r ;
}
a = A_1 ;b = A_2 ; c = A_3;
//Wycinanie
x = 0;
for (x == 1; x <= STEP_X ; x++){ StepperX.step(1);

if (x == a ){ StepperY.step(1); a = a + A_1; }
if (x == b ){ StepperY.step(1); b = b + A_2; }
if (x == c ){ StepperY.step(1); c = c + A_3; }
}

Nie brałem pod uwage, bo sądziłem że bez tego się obędzie, poleceń "J" i "I". Jednak okazało się niemożliwe, lub bardzo trudne obejscie tego problemu.
Prosze więc o pomoc w znalezieniu algorytmu, obliczającego kolejne punkty na łuku. Bynajmniej podpowiedź jakąś, od której strony to "ugryźć".
Wiadomo że maszyna będzie musiała odczytać polecenia G02 i G03, aby ustalić w którą stronę porusza się narzędzie.
Kody:
I to odległość w osi X środka okręgu od punktu początkowego
J to odległość w osi Y środka okregu od punktu początkowego
Punkt końcowy podany jest w linii, razem z kodami I i J.
Punkt początkowy linie wcześniej.



Awatar użytkownika

grg12
ELITA FORUM (min. 1000)
ELITA FORUM (min. 1000)
Posty w temacie: 3
Posty: 1670
Rejestracja: 03 sty 2007, 14:27
Lokalizacja: Wiedeń

#2

Post napisał: grg12 » 23 sie 2013, 14:59



Autor tematu
baxter12
Sympatyk forum poziom 2 (min. 50)
Sympatyk forum poziom 2 (min. 50)
Posty w temacie: 4
Posty: 57
Rejestracja: 04 lut 2013, 17:03
Lokalizacja: Poznan

#3

Post napisał: baxter12 » 23 sie 2013, 15:44

To nie to.
Potrzebuje wzór na obliczenie współrzednych kolejnego punktu, i teraz albo co np 1 stopień (przy większych elementach np co 0.1 stopnia), albo w dłuższej osi (X.Y) co 0.1mm..
Algorytm rozwiazania problemu wyglada w/g mnie mniej wiecej tak:
1. Czy krecimy w prawo, czy w lewo. I skok do podprogramu
2. Czy
X>0 Y>0
X>0 Y<0
X<0 Y>0
X<0 Y<0
X=0 Y<0
X=0 Y>0
X>0 Y=0
X<0 Y=0
3. I teraz zaleznie od metody.
a. Kątami.
Szukamy kąt poczatkowy i końcowy, i jedziemy co 1 czy 0.1 stopnia.
b. wymiarem, sprawdzam kóra długość łuku jest wieksza, w osi X czy Y. I jedziemy od pozycji wyjsciowej, do końcowej co np 0.1mm i obliczamy dla kazdego punktu drugi parametr. Tniemy oczywiście linię łamaną zamiast łuku, ale to chyba jest nieuniknione.

Aha, zapomniałem napisać że mój program liczy z dokładnością do 6 miejsca po przecinku.

Awatar użytkownika

grg12
ELITA FORUM (min. 1000)
ELITA FORUM (min. 1000)
Posty w temacie: 3
Posty: 1670
Rejestracja: 03 sty 2007, 14:27
Lokalizacja: Wiedeń

#4

Post napisał: grg12 » 23 sie 2013, 17:14

Liczenie kolejnych punktów z kąta jest banalne - środek koła X0,Y0, promień koła R
X=X0+cos(alpha)*R, Y=Y0+sin(alpha)*R. Problem w tym że albo trzeba liczyć funkcje trygonometryczne (czasochłonne) albo zrobić sobie tablice (zajmują dużo miejsca). Potrzebujesz też funkcji atan do policzenia kąta początkowego, do tego wszystkiego musisz jakoś sprawdzać czy już dotarłeś do końca żeby nie "przestrzelić" - kupa obliczeń/
A algorytmem Bresenhama możesz "rysować" dużo mniejszym kosztem.
Zamiast wyliczać kolejne położenia i łączyć je linią łamaną bierzesz aktualną pozycje i liczysz w która stronę zrobić krok - masz wszystkiego 8 możliwości ruchu ((x++,y),(x++,y++),(x,y++),(x--,y++),(x--,y),(x--,y--),(x,y--) i (x++,y--)) z których 6 eliminujesz na podstawie informacji w której ćwiartce koła jesteś i w którą stronę jedziesz, potem z pozostałych dwóch wybierasz tą która cie utrzyma bliżej obwodu koła, robisz krok, sprawdzasz czy już dotarłeś do końca łuku i zaczynasz od początku.


Autor tematu
baxter12
Sympatyk forum poziom 2 (min. 50)
Sympatyk forum poziom 2 (min. 50)
Posty w temacie: 4
Posty: 57
Rejestracja: 04 lut 2013, 17:03
Lokalizacja: Poznan

#5

Post napisał: baxter12 » 23 sie 2013, 21:03

A jak ustale która z tych dwóch jest bliżej koła?
Bo
pierwsza część jak najbardziej rozumiem.

Awatar użytkownika

grg12
ELITA FORUM (min. 1000)
ELITA FORUM (min. 1000)
Posty w temacie: 3
Posty: 1670
Rejestracja: 03 sty 2007, 14:27
Lokalizacja: Wiedeń

#6

Post napisał: grg12 » 24 sie 2013, 08:52

Metoda naiwna to policzyć kwadrat odległość od środka koła i porównać z kwadratem promienia (kwadraty żeby uniknąć liczenia pierwiastka). Zakładając że środek koła jest w X0,Y0 a badane położenia Xi,Yi liczysz
dx=Xi-X0;
dy=Yi-Y0;
dd=dx*dx+dy*dy; (Pitagoras się kłania)
porównujesz z R^2 - np.
R2=R*R;
dr=abs(dd-R2);
następnie wybierasz ruch który da najmniejszą wartość dr. Tylko nie próbuj czasem liczyś dr dla wszystkich 8 kierunków bo może się okazać że skieruje cię "do tyłu" :) (z informacji w której ćwiartce koła jesteś i kierunku ruchu powinieneś wydedukować dwa możliwe kierunki ruchu).
Ale naprawdę warto zapoznać się z algorytmem Bresenhama bo pozwala on zrobić potrzebne porównania znacznie mniejszym kosztem. Nie wiem którego modelu Arduino używasz ale jeśli nie jest to jakaś 32 bitowa rakieta to żeby uzyskać sensowną częstotliwość kroków będziesz musiał pisać bardzo oszczędny (w sensie cykli procesora) kod.


Autor tematu
baxter12
Sympatyk forum poziom 2 (min. 50)
Sympatyk forum poziom 2 (min. 50)
Posty w temacie: 4
Posty: 57
Rejestracja: 04 lut 2013, 17:03
Lokalizacja: Poznan

#7

Post napisał: baxter12 » 24 sie 2013, 09:46

Dziękuje. teraz jest to jasne. Faktycznie sporo mniej liczenia.
A Arduino mam Uno.

ODPOWIEDZ Poprzedni tematNastępny temat

Wróć do „Ogólne Dyskusje na Temat Systemów Sterowania CNC”