Rysowanie elementu z kodu maszyny CNC

Rysowanie elementu z kodu maszyny CNC

Wątek przeniesiony 2017-09-09 16:25 z Java przez flowCRANE.

LO
  • Rejestracja:ponad 11 lat
  • Ostatnio:około 3 lata
  • Postów:11
0

Próbuję zrobić program który w tekście np (G01 X100.0 Z50.0) wyszukuje X i cyfrę i Z i cyfrę po to żeby wydobyć cyfry które potem posłużą do rysowania w canvas. Mam problem w poniższym kodzie który może jest nie fachowo napisany bo jestem początkującym, z przypadkiem kiedy pętla natrafia na linię gdzie NIE MA X i Z i jak zrobić żeby program przeskoczył do następnej linii i jeśli jest tylko jedna X lub Z to program ma pozostawić wartość tej której NIE MA z poprzedniej linii. Obecnie brak Z lub X powoduje błąd. Może ktoś już się zajmował tym zadaniem, może moje podejście do tego zadania jest błędne to proszę o jakieś rady jak do tego najlepiej podejść.

Kopiuj
procedure TForm1.lb711Click(Sender: TObject);
var
  liczbax, liczbaz: double;
  I, xx, zz, x2, z2: integer;
 // g:extended;
  text: string;
  Z, X: string;
begin
   form9.image1.Picture:= nil;
   form9.image1.Canvas.Pen.Style :=psDashDot;
   form9.image1.Canvas.MoveTo(500, 0);
   form9.image1.Canvas.lineTo(500, 600);// rysuje oś X
   form9.image1.Canvas.MoveTo(0, 400);
   form9.image1.Canvas.lineTo(1000, 400);// rysuje oś Z
    form9.image1.Canvas.Pen.Width :=2;
   form9.image1.Canvas.Pen.Style :=pssolid;
  // showmessage(inttostr((ActiveMDIChild as TForm2).syndt1.Lines.Count));
  form9.Show;

  form9.image1.Canvas.MoveTo(180, 150);// poczatek malowania linii
  //Z := '';
  for I := 0 to (ActiveMDIChild as TForm2).syndt1.Lines.Count -1 do
  begin

    text := (ActiveMDIChild as TForm2).syndt1.Lines[I]; // pobranie zawartości linii

    if length(TEXT) <> 0 then
    begin
      try
        Z := TRegEx.Match(text, 'Z[+-]?[0-9]+(\.[0-9]+)').Value; //pobranie z tekstu np Z100.6
        X := TRegEx.Match(text, 'X[+-]?[0-9]+(\.[0-9]+)').Value;


        delete(Z, 1, 1);// wymazanie z z pobranego tekstu np (Z100.0)pozostaje 100.0
        delete(X, 1, 1);
      except
	//on E: ERegularExpressionError do begin
		// Syntax error in the regular expression }
      end;

      x := stringreplace((x), '.', ',', [rfreplaceall, rfignorecase]);//zmiana kropki na przecinek
        showmessage(x);
      liczbax := strtofloat(x);
      xx := round(liczbax*100); //likwidacja liczb po przecinku z ich przesunieciem o dwa miejsca 


      z := stringreplace((z), '.', ',', [rfreplaceall, rfignorecase]);
      liczbaz := strtofloat(z);
      zz := round(liczbaz*100);

      form9.image1.Canvas.LineTo(xx, zz);
    end;
  end;
end;
edytowany 1x, ostatnio: flowCRANE
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
0
loza napisał(a):

Próbuję zrobić program który w tekście np (G01 X100.0 Z50.0) wyszukuje X i cyfrę i Z i cyfrę po to żeby wydobyć cyfry które potem posłużą do rysowania w canvas.

Nie cyfrę, a liczbę rzeczywistą – nazywaj rzeczy po imieniu.

[…] z przypadkiem kiedy pętla natrafia na linię gdzie NIE MA X i Z i jak zrobić żeby program przeskoczył do następnej linii i jeśli jest tylko jedna X lub Z to program ma pozostawić wartość tej której NIE MA z poprzedniej linii.

Strasznie niezgrabnie to tłumaczysz. Myślę że chodzi o to, że wartości X i Z mogą być zapisane w jednej lub w dwóch liniach, a algorytm ma działać prawidłowo dla obu przypadków. Racja?


Najpierw powinieneś pobrać linię tekstu. Następnie taką linię należy poddać walidacji – sprawdzić które wartości znajdują się w niej i zwrócić stan do głównego kodu. Jeśli w bieżącej linii którejś współrzędnej brakuje, to powinieneś pobrać kolejną linię i w niej poszukać brakujących danych.

Potrzebujesz metody, która pobierze w parametrze ciąg znaków linii i zwróci informację o tym, które współrzędne się w niej znajdują. Przyda się też osobna metoda, która umożliwi ekstrakcję współrzędnej z zadanej linii. Możesz to załatwić regexem, dlatego że jeśli ten nie znajdzie dopasowania to zapewne zwróci pusty ciąg znaków – i to jest informacja o braku zadanej współrzędnej.


Jeśli mowa o Twoim kodzie – bajzel w nim straszny i wymaga podzielenia na mniejsze fragmenty. Blok try except przy operacjach na regexach jest zbędny – przecież masz je hardkodowane, więc chyba potrafisz określić ich bezbłędność?

Kolejna rzecz to zmiana znaków w ciągu, za pomocą StringReplace. Używasz w niej flagi rfIgnoreCase, co jest zbędne, bo znaki które zamieniasz, nie posiadają wielkiej i małej postaci. Tę flagę używa się do liter, nie znaków interpunkcyjnych. Zamiast wymieniać separator na inny, równie dobrze możesz skorzystać z uniwersalnej pseudoprocedury Val, które obsługuje kropkę jako separator.

Ostatnia rzecz to nazwy formularzy i kontrolek – form9, image1 i syndt1 to nie są dobre identyfikatory, bo absolutnie nic nie mówią o przeznaczeniu tych obiektów. Tak więc nadaj konkretne nazwy wszystkim kontrolkom, a praca z kodem stanie się łatwiejsza.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
LO
  • Rejestracja:ponad 11 lat
  • Ostatnio:około 3 lata
  • Postów:11
0

Dziękuję bardzo za rady na pewno z nich skorzystam i przepraszam za ten kod na pewno masz racje w tym ze to totalny bajzel, ale na błędach się człowiek uczy. Pracuję na obrabiarkach numerycznych sterowanie Fanuc i próbuję ułatwić sobie pracę aby z programu do obrabiarki wydobyć wartości współrzędnych X i Z i za pomocą canvas zobaczyć proces obróbki. Jak na mnie jest to trudne zadanie bo dopiero zaczynam przygodę z delphi.

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
0

Łatwiej by było, gdybyś podał przykładową zawartość kontrolki syndt1 – wtedy mógłbym coś podłubać u siebie i mieć pewność, że rozwiązanie będzie działać prawidłowo.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
LO
  • Rejestracja:ponad 11 lat
  • Ostatnio:około 3 lata
  • Postów:11
0

Podam typowy program do cnc bo to on będzie w kontrolce synedt1

Kopiuj
:0049(SHEAR SCREW M18X1.5) 
N10(ISS A/C-P=20.0)
N20G00G21G40G99
N30G50S2700
N40G10P0Z-40.0 
N50T1212(STOP) 
N60G00X10.0Z10.0 
N70G200Z-20.0R0.4
N80G00X150.0Z160.0M01
N90T0303(PCLNR 0.8)
N100G00G96S220F0.05M13 
N110X21.0Z0.2
N120G01X-1.0 
N130G00X20.5Z1.0 
N140G71U1.5R1.0
N150G71P160Q210U0.2W0.1F0.1
N160G00X14.0 
N170G01Z0.1
N180G01X15.298A135.0F0.01
N190G01Z-19.999F0.05 
N200G01X17.8A135.0 
N210G01Z-32.0
N220G00X150.0Z160.0M01 
N230T0909(MTJNR 0.4) 
N240G00G96S300F0.05M13 
N250X20.5Z0.0
N260G01X-1.5 
N270G00X20.5Z0.5 
N280G70P160Q210
N290G00X150.0Z150.0M01 
N300T0505(1.17MM P/OFF)
N310G00G97X15.5Z-15.0S700F0.03M13
N320G01X13.26
N330G00X15.4 
N340G00Z-13.8
N350G01X12.7 
N360G00X15.4 
N370G00Z-13.77 
N380G01X13.26
N390G00X15.4 
N395G01Z-13.57X15.3F0.01 
N400G03X14.9Z-13.77R0.2
N410G01X13.26
N420G02X12.66Z-14.07R0.3 
N430G01Z-14.7S400F0.04 
N431G00X15.4 
N432G00Z-15.2X15.3 
N433G02X14.9Z-15.0R0.2F0.01
N434G01X13.26
N435G03X12.66Z-14.7R0.3
N436G00X17.0 
N440G00X150.0Z150.0M01 
N450T1111(2MM PART OFF)
N455G00G96X20.0Z-31.0S300F0.05M13
N460G01X15.0F0.05
N470G00X18.0 
N480G00Z-29.5
N490G01Z-31.0A225
N500G00X20.0 
N510G00X150.0Z150.0M01 
N520T0707(M18X1.5) 
N530G00G97X18.5Z-18.0S500M13 
N540G76P020060Q100R0.05
N550G76X16.5Z-30.0P750Q100F1.5 
N560G00X150.0Z150.0M01 
N570T1111(2MM P/OFF) 
N580G00G96Z-29.5X20.0S300F0.05M13
N582G01X18.0 
N584G01Z-31.0A225M70 
N590G01X5.0
N600G01G97S300X0.0 
N610G00X25.0M74
N620X100.0Z160.0M01
N630M05
N640M09
N650M99

Jak można zauważyć są linie które są tylko komentarzem i linie w których występuje X i Z lub samo X. To tak jak ruch po osi współrzędnych. Są też specjalne funkcje które jak np G76 do obróbki gwintów która w sobie zawiera z kilkanaście linii i aby to wyrysować to trzeba będzie stworzyć osobny podprogram do rozpisania go ale to w dalszej części.

edytowany 1x, ostatnio: flowCRANE
abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:7 miesięcy
  • Postów:6610
1

nudziło mnie się :p

Kopiuj
unit MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, SynEdit,
  SynMemo;

type
  TfrmMain = class(TForm)
    mmoProgram: TSynMemo;
    pbDrawBox: TPaintBox;
    pnlButtons: TPanel;
    btnDraw: TButton;
    procedure FormCreate(Sender: TObject);
    procedure pbDrawBoxPaint(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure btnDrawClick(Sender: TObject);
  private
    FBuffer: TBitmap;
    procedure ClearBuffer;
    procedure DrawCNC;
    procedure ValFromStr(const str, find: string; var Val: Double);
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.btnDrawClick(Sender: TObject);
begin
  ClearBuffer;
  DrawCNC;
end;

procedure TfrmMain.ClearBuffer;
const
  GridSize = 20;
var
  i: Integer;
begin
  with FBuffer, Canvas do
  begin
    //wypełnienie na biało
    Brush.Color := clWhite;
    Brush.Style := bsSolid;
    FillRect(Rect(0, 0, Width, Height));
    //obrys dookoła
    Pen.Style := psSolid;
    Pen.Color := clBlack;
    Pen.Width := 1;
    Rectangle(1, 1, Width - 2, Height - 2);
    //oś X
    MoveTo(1, Height div 2);
    LineTo(Width - 2, Height div 2);
    //oś Y
    MoveTo(Width div 2, 1);
    LineTo(Width div 2, Height - 2);
    //siatka
    Pen.Style := psDot;
    pen.Color := clSilver;
    for i := 1 to Height div GridSize * 2 do
    begin
      //siatka linie poziome
      MoveTo(1, Height div 2 - i * GridSize);
      LineTo(Width - 2, Height div 2 - i * GridSize);
      MoveTo(1, Height div 2 + i * GridSize);
      LineTo(Width - 2, Height div 2 + i * GridSize);
      //siatka linie pionowe
      MoveTo(Width div 2 - i * GridSize, 1);
      LineTo(Width div 2 - i * GridSize, Height - 2);
      MoveTo(Width div 2 + i * GridSize, 1);
      LineTo(Width div 2 + i * GridSize, Height - 2);
    end;
  end;
end;

procedure TfrmMain.DrawCNC;
var
  X, Z: Double;
  dX, dY: Integer;
  i: Integer;
  s: string;
begin
  with FBuffer, Canvas do
  begin
    Pen.Color := clBlue;
    Pen.Style := psSolid;
    dX := Width div 2;
    dy := Height div 2;
    X := dX;
    Z := dY;

    MoveTo(Round(X), Round(Z));
    for s in mmoProgram.Lines do
    begin
      ValFromStr(s, 'X', X);
      ValFromStr(s, 'Z', Z);
      LineTo(Round(X) + dX, Round(Z) + dY);
    end;
  end;
  pbDrawBox.Refresh;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FBuffer := TBitmap.Create;
  FBuffer.Width := pbDrawBox.ClientWidth;
  FBuffer.Height := pbDrawBox.Height;

  ClearBuffer;
end;

procedure TfrmMain.FormResize(Sender: TObject);
begin
  FBuffer.Width := pbDrawBox.ClientWidth;
  FBuffer.Height := pbDrawBox.Height;

  ClearBuffer;
end;

procedure TfrmMain.ValFromStr(const str, find: string; var Val: Double);
var
  b, e, i: Integer;
begin
  b := Pos(find, str);
  if b > 0 then
  begin
    Inc(b);
    e := b;
    while str[e] in ['0'..'9', '.', '-'] do
      Inc(e);
    Val := StrToFloat(StringReplace(Copy(str, b, e- b), '.', FormatSettings.DecimalSeparator, [rfReplaceAll]));
  end;
end;

procedure TfrmMain.pbDrawBoxPaint(Sender: TObject);
begin
  pbDrawBox.Canvas.Draw(0, 0, FBuffer);
end;

end.

(https://4programmers.net/Forum/Download/16610)4p1.png

Cały projekt w załączniku


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
LO
  • Rejestracja:ponad 11 lat
  • Ostatnio:około 3 lata
  • Postów:11
0

Dziękuję bardzo, program widzę zrobiony fachowo, ja bym tego nigdy nie zrobił. Wszystko jest ok tylko troche w złym miejscu rysuje pionowa oś to oś X, pozioma to oś Z, z tym że -Z powinno rysować od środka na lewo i w górnej części.

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:3 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
0

To tylko przykład – nie wiemy przecież jak chcesz aby to wyglądało (no, teraz wiemy).

Jak coś jest w złym miejscu rysowane to dodaj sobie offsety, a jak po złej stronie osi to zmień znak współrzędnej.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
0

W Lazarus-ie jest biblioteka fpvectorial http://wiki.lazarus.freepascal.org/fpvectorial
umożliwiająca zapis i odczyt i rysowanie plików w formacie G-Code.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)