Совместная разработка системы ЧПУ.

Mach, популярные и не очень CAD, CAM. Обсуждение и разработка программ для управления станками.
AAN
Мастер
Сообщения: 284
Зарегистрирован: 14 апр 2015, 10:28
Репутация: 35
Настоящее имя: Антон
Откуда: Томск
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение AAN »

sidor094 писал(а): А где её взять на пк? ИСА сейчас не используется,а остальные требуют как минимум плис для реализации.Кроме того ,если использовать не ибм пс компьютер,так там вообще непонятно что будет.
Ну да, современные ПК всё дальше уходят от систем реального времени и реального мира ) Поэтому лучше реализовываться через клоны малинки, у неё GPIO предостаточно для паралельной шины, а вычислительных мощностей для интерполятора и прочего реалтайма. Современные непромышленные ПК это в любом случае про красивости и виртуальности, с шершавой действительностью они должны взаимодействовать через толмача.
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

Между удалёнными устройствами, практически, всегда используется последовательная шина данных. Пакет в 80 байт по таким шинам будет пролетать со свистом. Современные Ethernet'ы, USB, SPI, UART справятся за миллисекунду и меньше. Планировщик (+ управляющий компонент) может готовить данные пакета гораздо дольше.

Выше упоминалось, что можно для каких-то значений использовать не 32 бита, а меньше. Конечно, можно. Но группировка по 32 бита (4 байта) делает разбор/правку данных быстрее и проще на любой платформе. Даже JavaScript сможет быстро разобрать/изменить бинарник, сгруппированный по 32 бита (при помощи ArrayBuffer и Uint32Array). На С/С++ работа с данными по 32 бита вообще песня. Можно бегать по бинарнику пакета с помощью указателей (*/&) безо всяких структур (typedef/struct).
vtgmfg
Мастер
Сообщения: 1438
Зарегистрирован: 23 июн 2022, 14:13
Репутация: 53
Настоящее имя: Максим
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение vtgmfg »

MX_Master писал(а): Между удалёнными устройствами, практически, всегда используется последовательная шина данных. Пакет в 80 байт по таким шинам будет пролетать со свистом. Современные Ethernet'ы, USB, SPI, UART справятся за миллисекунду и меньше. Планировщик (+ управляющий компонент) может готовить данные пакета гораздо дольше.
в параллельных синхронных шинах с расстоянием начинает проявляться проблема "перекоса". причем эту проблему можно "увидеть" рассматривая материнские платы. Поэтому синхронные шины и не используют между удаленными устройствами в современном мире. ну клавиатуру с мышью разве что подключить.
асинхронные последовательные для связи между МК и ПК конечно... откуда тут SPI нарисовался.. это вот на одной плате между МК данными обмениваться годно или тупыми регистрами порты расширять да и то аккуратно.
да на что-то коммуникационное кроме USB как рассчитывать на современном ИБМ ПК? Ноутбук,нетбук,планшет..
Расчитывать на малинки /апельсинки и прочие микрописИ? Я бы их первыми отмел
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

Надо упомянуть и про беспроводную связь. GUI может крутится на удалённом ноуте/планшете/телефоне. На которых основной вид связи - это Wi-Fi.

Малинки вполне могут крутить всю систему на себе, отдав работу с сигналами микроконтроллеру. Глупо отбрасывать минипк в сторону, просто, потому что они чем-то не угодили.
vtgmfg
Мастер
Сообщения: 1438
Зарегистрирован: 23 июн 2022, 14:13
Репутация: 53
Настоящее имя: Максим
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение vtgmfg »

MX_Master писал(а): Надо упомянуть и про беспроводную связь. GUI может крутится на удалённом ноуте/планшете/телефоне. На которых основной вид связи - это Wi-Fi.
почему бы и нет
MX_Master писал(а): Глупо отбрасывать минипк в сторону, просто, потому что они чем-то не угодили.
ну usb то там есть - так что если хочется микропк в макрогараже - почему бы и нет. а вот закладываться на какую то специфику не стал бы. на какую то повышенную надежность - тоже.
Аватара пользователя
Mamont
Мастер
Сообщения: 1953
Зарегистрирован: 10 дек 2015, 12:21
Репутация: 382
Настоящее имя: Виталий
Откуда: РБ Минск
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение Mamont »

Wifi нет. Качество передачи зависит от количества абонентов в зоне видимости. Придут к станку поглазеть 5 10 рабочих со всключенными вайфаями на телефонах и связь начнет лагать. По крайней мере я это ощущаю в обед по отваливанию связи . Это рабочие приходят в столовку .

Usb очень осторожно. Лучше кабелем 10 15см до платы. И от нее гальванически/оптически развязанные сигналы пойдут на драйвера и прочие исполнительные устройства.
vtgmfg
Мастер
Сообщения: 1438
Зарегистрирован: 23 июн 2022, 14:13
Репутация: 53
Настоящее имя: Максим
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение vtgmfg »

Mamont писал(а): Придут к станку поглазеть 5 10 рабочих со всключенными вайфаями на телефонах и связь начнет лагать.
такие проблемы со связью решаются организационно))
Без особой необходимости беспроводную связь конечно не стоит применять
Mamont писал(а): Usb очень осторожно.
а какие варианты? ну можно usb конвертер на RS422/485 - если такие страшные ужасные помехи и сотни метров дистанция.. а опторазвязка то зачем?
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

Изобразил на досуге универсальный сканер строк G кода. После разбора каждой строки, получаем удобную структуру данных (~400 байт), которую легко использовать для дальнейших расчётов где-то в планировщике или других местах. Замечания приветствуются ;)

Функционал на данный момент:
  • Ищутся G коды от 0 до 99 (Gnn), включая подкоды (Gnn.s, до 8 подкодов)
  • Ищутся М коды от 0 до 199 (Мnnn), включая подкоды (Мnnn.s, до 8 подкодов)
  • Ищутся другие коды (NXYZFIJKTSHDPQRLEABCUVWO) с одиночным значением (float)
  • Комментарии вида "( ... )" и "; ..." игнорируются
  • Код универсален и работает на любой платформе
  • О-коды не обрабатываются
  • Параметры (#xxx) не обрабатываются
  • Расчёты ([...]) не производятся

Исходники в онлайн компиляторе - https://onlinegdb.com/x89-EBZ_nN.
Нажать Run (F9) для запуска.
В нижнем окошке смотреть результаты разбора строк.

Все файлы одним архивом:
parse-g-code-text (2).zip
(2.89 КБ) 74 скачивания

main.c - тест

Код: Выделить всё

#include <stdio.h>
#include <string.h>

#include "text_parser.h"
#include "gcode_parser.h"





#define TEXT_TEST_1 \
  "G21 G40 G17.1 G90\n" \
  "(comment) G4 P0.5\n" \
  "G04 X0.120 P7 I12.4 \r\n" \
  "illegal line\n" \
  "n0001 M3S 6000 \r\n" \
  "(G2/G3) G002 X0.2 Y0.4 I1.1 J2.2 ;R1.5 (P1) \n" \
  "N2 G00\tX+0   Y-0.0 F200.0\n" \
  "\n" \
  "G1 X+.01(cmnt1)Y+10.123 (cmnt2) ; Z -10\r\n" \
  "\tX 100Y-100.000 (Z100\n" \
  "M002 ; G0 X0 Y0"




int main() {
  char *gcode_text = TEXT_TEST_1;
  char *text = gcode_text;
  char *line;
  int line_size;
  int line_num = 0;
  int full_line_size;
  gcode_line_data_t data;

  printf("text size = %lu bytes\n\n", strlen(text));

  while ( text && *text && (line = text_get_line(text, &line_size, &full_line_size)) ) {
    // print line
    printf("`");
    text_print_line(line);
    printf("` (%i bytes, #%i)\n", line_size, line_num++);
    // parse line for gcodes
    memset((char *)&data, 0, sizeof data);
    if ( gcode_parse_line(line, &data) ) gcode_line_data_print(&data);
    // go to next line    
    text += full_line_size;
  }

  return 0;
}

gcode_parser.h

Код: Выделить всё

#ifndef GCODE_PARSER_H
#define GCODE_PARSER_H

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>




#define GCODE_DEBUG_PRINT       1
#define GCODE_TIME_BENCHMARK    1

#define GCODE_WORDS_SEARCH_S    "NGXYZFIJKMTSHDPQRLEABCUVWO" \
                                "ngxyzfijkmtshdpqrleabcuvwo" \
                                "(;\r\n"

#define GCODE_COMMENT1_START_C  '('
#define GCODE_COMMENT1_END_C    ')'
#define GCODE_COMMENT2_START_C  ';'
#define GCODE_RETURN_C          '\r'
#define GCODE_NEWLINE_C         '\n'
#define GCODE_G_CNT             100
#define GCODE_M_CNT             200




typedef struct {
  uint32_t found; // found gcode words mask
  uint8_t G[GCODE_G_CNT]; // found G codes masks
  uint8_t M[GCODE_M_CNT]; // found M codes masks
  // found other codes values (NXYZFIJKTSHDPQRLEABCUVWO)
  float N; float X; float Y; float Z; float F; float I; float J; float K; 
  float T; float S; float H; float D; float P; float Q; float R; float L; 
  float E; float A; float B; float C; float U; float V; float W; float O;
} gcode_line_data_t;




//inline
int gcode_parse_line(char *line, gcode_line_data_t *data) {
  char *fc;
  char c;
  float f;
  int code;
  int words_found = 0;
  #if GCODE_TIME_BENCHMARK
    clock_t begin;
    clock_t end;
    double time_spent;
    static double time_spent_total = 0;
  #endif

  #if GCODE_TIME_BENCHMARK
    begin = clock();
  #endif

  #define d (*data)

  // search for gcode word chars
  while ( line && *line && (fc = strpbrk(line, GCODE_WORDS_SEARCH_S)) ) {
    // parse ';' comments and '\r','\n' chars
    if ( *fc == GCODE_COMMENT2_START_C || 
         *fc == GCODE_RETURN_C ||
         *fc == GCODE_NEWLINE_C ) break;
    // parse "(...)" comments
    if ( *fc == GCODE_COMMENT1_START_C ) {
      fc = strchr(fc, GCODE_COMMENT1_END_C);
      if ( !fc ) break;
      line = fc + 1;
      continue;
    }
    // goto next char
    line = fc+1;
    // get gcode pair values (char+float)
    if ( sscanf(fc, "%c%f", &c, &f) < 2 || c != *fc ) continue;
    // gcode name to uppercase
    if ( c >= 'a' && c <= 'z' ) c = 'A' + (c-'a');
    // parse g code values
    if ( c == 'G' ) { // G codes
      code = (int)(10 * f);
      if ( code >= 0 && code < (GCODE_G_CNT*10) ) {
        d.found |= 1 << (c-'A');
        d.G[code/10] |= 1 << (code%10);
        words_found++;
      }
    } else if ( c == 'M' ) { // M codes
      code = (int)(10 * f);
      if ( code >= 0 && code < (GCODE_M_CNT*10) ) {
        d.found |= 1 << (c-'A');
        d.M[code/10] |= 1 << (code%10);
        words_found++;
      }
    } else { // other codes - NXYZFIJKTSHDPQRLEABCUVWO
      d.found |= 1 << (c-'A'); 
      words_found++;
      switch (c) {
        case 'N': d.N = f; break;
        case 'X': d.X = f; break;
        case 'Y': d.Y = f; break;
        case 'Z': d.Z = f; break;
        case 'F': d.F = f; break;
        case 'I': d.I = f; break;
        case 'J': d.J = f; break;
        case 'K': d.K = f; break;
        case 'T': d.T = f; break;
        case 'S': d.S = f; break;
        case 'H': d.H = f; break;
        case 'D': d.D = f; break;
        case 'P': d.P = f; break;
        case 'Q': d.Q = f; break;
        case 'R': d.R = f; break;
        case 'L': d.L = f; break;
        case 'E': d.E = f; break;
        case 'A': d.A = f; break;
        case 'B': d.B = f; break;
        case 'C': d.C = f; break;
        case 'U': d.U = f; break;
        case 'V': d.V = f; break;
        case 'W': d.W = f; break;
        case 'O': d.O = f; break;
      }
    }
  }
  
  #undef d

  gcode_parse_end:

  #if GCODE_TIME_BENCHMARK
    end = clock();
    time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    time_spent_total += time_spent;
    #if GCODE_DEBUG_PRINT >= 1
      printf("  %f seconds (this line), %f seconds (all lines)\n", 
             time_spent, time_spent_total);
    #endif
  #endif
  
  #if GCODE_DEBUG_PRINT >= 1
    printf("  %i gcode words found\n", words_found);
  #endif

  return words_found;
}




//inline
int gcode_line_data_print(gcode_line_data_t *data) {
  int c;
  int sc;

  if ( !data ) return -1;

  #define d (*data)

  if ( !d.found ) return 0;

  // print G codes
  if ( d.found & (1<<('G'-'A')) ) {
    for ( c = 0; c < GCODE_G_CNT; c++ ) {
      if ( !d.G[c] ) continue;
      if ( d.G[c] == 1 ) { printf("  G%i\n", c); continue; }
      for ( sc = 0; sc < 8; sc++ ) {
        if ( d.G[c] & (1<<sc) ) printf("  G%i.%i\n", c, sc);
      }
    }
  }

  // print M codes
  if ( d.found & (1<<('M'-'A')) ) {
    for ( c = 0; c < GCODE_M_CNT; c++ ) {
      if ( !d.M[c] ) continue;
      if ( d.M[c] == 1 ) { printf("  M%i\n", c); continue; }
      for ( sc = 0; sc < 8; sc++ ) {
        if ( d.M[c] & (1<<sc) ) printf("  M%i.%i\n", c, sc);
      }
    }
  }

  // print other codes
  if ( d.found & (1<<('N'-'A')) ) printf("  N%f\n", d.N);
  if ( d.found & (1<<('X'-'A')) ) printf("  X%f\n", d.X);
  if ( d.found & (1<<('Y'-'A')) ) printf("  Y%f\n", d.Y);
  if ( d.found & (1<<('Z'-'A')) ) printf("  Z%f\n", d.Z);
  if ( d.found & (1<<('F'-'A')) ) printf("  F%f\n", d.F);
  if ( d.found & (1<<('I'-'A')) ) printf("  I%f\n", d.I);
  if ( d.found & (1<<('J'-'A')) ) printf("  J%f\n", d.J);
  if ( d.found & (1<<('K'-'A')) ) printf("  K%f\n", d.K);
  if ( d.found & (1<<('T'-'A')) ) printf("  T%f\n", d.T);
  if ( d.found & (1<<('S'-'A')) ) printf("  S%f\n", d.S);
  if ( d.found & (1<<('H'-'A')) ) printf("  H%f\n", d.H);
  if ( d.found & (1<<('D'-'A')) ) printf("  D%f\n", d.D);
  if ( d.found & (1<<('P'-'A')) ) printf("  P%f\n", d.P);
  if ( d.found & (1<<('Q'-'A')) ) printf("  Q%f\n", d.Q);
  if ( d.found & (1<<('R'-'A')) ) printf("  R%f\n", d.R);
  if ( d.found & (1<<('L'-'A')) ) printf("  L%f\n", d.L);
  if ( d.found & (1<<('E'-'A')) ) printf("  E%f\n", d.E);
  if ( d.found & (1<<('A'-'A')) ) printf("  A%f\n", d.A);
  if ( d.found & (1<<('B'-'A')) ) printf("  B%f\n", d.B);
  if ( d.found & (1<<('C'-'A')) ) printf("  C%f\n", d.C);
  if ( d.found & (1<<('U'-'A')) ) printf("  U%f\n", d.U);
  if ( d.found & (1<<('V'-'A')) ) printf("  V%f\n", d.V);
  if ( d.found & (1<<('W'-'A')) ) printf("  W%f\n", d.W);
  if ( d.found & (1<<('O'-'A')) ) printf("  O%f\n", d.O);

  #undef d
  
  return 0;
}




#endif

text_parser.h

Код: Выделить всё

#ifndef TEXT_PARSER_H
#define TEXT_PARSER_H

#include <stdio.h>
#include <string.h>




#define TEXT_RETURN_C           '\r'
#define TEXT_NEWLINE_C          '\n'
#define TEXT_NEWLINE_PATTERN_S  "\r\n"
#define TEXT_LINE_MAX_SIZE      256




//inline
char *text_get_line(char *text, int *line_size, int *full_line_size) {
  char *new_line;

  if ( !text || !*text ) goto line_not_found; 

  new_line = strpbrk(text, TEXT_NEWLINE_PATTERN_S);
  if ( !new_line ) new_line = memchr(text, 0, TEXT_LINE_MAX_SIZE);
  if ( !new_line ) goto line_not_found;

  *line_size = (int) (new_line - text);
  *full_line_size = *line_size + strspn(new_line, TEXT_NEWLINE_PATTERN_S);
  return text;

  line_not_found:
  *line_size = 0; 
  *full_line_size = 0; 
  return NULL; 
}




//inline
int text_print_line(char *line) {
  int i;
  if ( !line || !(*line) ) return 0;
  for ( i = 0; 
        line[i] && line[i] != TEXT_RETURN_C && line[i] != TEXT_NEWLINE_C; 
        i++ ) printf("%c", line[i]);
  return i;
}



#endif
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

Попробовал добавить в сканер разбор параметров и переменных (#nnn / #<xxx>). Стандартными функциями из stdio.h/string.h получается довольно сложно. Если позже добавить ещё и разбор выражений с расчётами ([...]) получится офигенно громоздкий код.

Походу, надо переходить на регулярные выражения (regex). Сделал сейчас пару тестов на скорость. Regex работает довольно быстро при условии, что сами выражения для поиска скомпилированы заранее.
AAN
Мастер
Сообщения: 284
Зарегистрирован: 14 апр 2015, 10:28
Репутация: 35
Настоящее имя: Антон
Откуда: Томск
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение AAN »

Для парсера лучше Python применять, как и для других высокоуровневых задач...
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

AAN писал(а): 24 дек 2022, 04:41 Для парсера лучше Python применять, как и для других высокоуровневых задач...
Разработчики LinuxCNC, долго не думая, так и поступили. И теперь их вычислительный монстр может работать только на очень быстрых процессорах с жёсткой привязкой к цельному питону и его версии. Специально посмотрел. Вызывать из модуля на С++ функции на питоне - это какое-то программистское позорище. Из пушки по воробьям. И слабые микроконтроллеры при таком подходе сразу отпадают. Им ещё остальные модули надо обработать, а тут разбор текста все ресурсы съел :)
AAN
Мастер
Сообщения: 284
Зарегистрирован: 14 апр 2015, 10:28
Репутация: 35
Настоящее имя: Антон
Откуда: Томск
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение AAN »

Во-первых, всё равно придётся делать связку ПК+МК, где персоналка будет тянуть интерфейс, проверки всякие, эмуляторы и полупереваривать G-код.
Во-вторых, синтаксический анализ (парсинг) делается один раз и на "холодной" ЧПУ.
С такими исходными условиями Питон кроет Си, как бык овцу и по трудоёмкости написания кода, и по трудоёмкости его поддержки. Я впрочем, не настаиваю, можете переоценивать свои силы, будет ещё один сырой или куцый проект.
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

AAN писал(а): 24 дек 2022, 10:56 Во-первых, всё равно придётся делать связку ПК+МК, где персоналка будет тянуть интерфейс, проверки всякие, эмуляторы и полупереваривать G-код.
Во-вторых, синтаксический анализ (парсинг) делается один раз и на "холодной" ЧПУ.
С такими исходными условиями Питон кроет Си, как бык овцу и по трудоёмкости написания кода, и по трудоёмкости его поддержки. Я впрочем, не настаиваю, можете переоценивать свои силы, будет ещё один сырой или куцый проект.
Сразу видно, человек не знает как работает большинство популярных ЧПУ систем. Давайте без лишних разговоров сразу к примерам.

GRBL/Marlin/Smoothieware/... - вся ЧПУ работает внутри микроконтроллера. G код на лету разбирает сам контроллер. Вариант с ПК нужен только для удобства юзера. Но ПК в любой момент может быть заменён на мини экранчик с кнопками. G код при этом на лету читается с SD карты и разбирается тоже на лету. Никакого полного разбора файла с G кодом заранее нет.

Mach3/LinuxCNC/... - т.к. системы задумывались для работы на ПК, перед запуском файла с G кодом, одноразово сравниваются софт лимиты с позициями осей из файла. Далее разбор файла выполняется на лету, используя небольшой буфер для предпросмотра траектории и расчётов. Никакого полного разбора файла с G кодом заранее ЧПУ система не делает.

Оно и понятно, разбирать и конвертировать весь файл целиком - бесполезная трата времени и ресурсов. Особенно, для микроконтроллеров. Единственная польза данного процесса будет только при визуализации траектории. Но, зачастую, визуализаторы работают отдельно и не имеют прямого отношения к выполнению G кода ЧПУ системой. А вот результаты работы визуализатора при разборе больших файлов, думаю, каждый уже видел. По этой причине, народ предпочитает отключать полную визуализацию больших файлов. Потому что их мощный современный ПК начинает жутко тормозить. И далеко не последнюю роль в этих тормозах играет именно Python. Потому что его используют не только для разбора всего файла, но и для визуализации. Целые виртуальные миры люди создают на С/С++ в играх и работает это всё без тормозов. А тут, понимаешь ли, обычные линии визуализатор на питоне не может вывести на экран.

Сразу вспоминаются случаи, когда народ тянул в проект Raspberry Pi только, чтобы мигать светодиодами :hehehe:
sidor094
Мастер
Сообщения: 826
Зарегистрирован: 20 фев 2014, 09:13
Репутация: 81
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение sidor094 »

А что делать потом , с разобранным кодом?Опять разбирать?
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

sidor094 писал(а): 24 дек 2022, 19:43 А что делать потом , с разобранным кодом?Опять разбирать?
Когда в строке все данные найдены и разложены по переменным, дальнейшая работа (проверки, добавка в очередь, предпросмотр планировщика) с данными упрощается и ускоряется в десятки раз. Для мега простых ЧПУ систем это может и не пригодится. Но если система будет посложнее, с переменными, O-кодами и прочей логикой прямо в G коде, выигрыш в скорости от предварительного разбора строки будет очевиден. Особенно, если всё это будет крутится на микроконтроллере.
sidor094
Мастер
Сообщения: 826
Зарегистрирован: 20 фев 2014, 09:13
Репутация: 81
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение sidor094 »

MX_Master писал(а): выигрыш в скорости от предварительного разбора строки будет очевиден.
Не понятно ,в чем выигрыш от предварительного развора.Разве сразу действие по результату разбора не быстрее?Потом ,в чем смысл float?Разве работа с целыми числами не быстрее?Причем при расчете движения все равно нужен переход к целым.Или не так?
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

Чтобы перейти к дальнейшим действиям, надо разобрать всю строку. К примеру, если поставить код G91 в конце строки, а значения XYZ в начале, то трактовка позиций осей координально изменится только к концу строки. И мы не можем начать добавлять новые позиции осей в очередь, пока не будем полностью уверены.

В формате float, потому что так указано в стандарте G кода. Если системе для дальнейшего расчёта нужны целые числа, конвертируем (int) (1000.0 * float) и вперёд.
Аватара пользователя
hmnijp
Мастер
Сообщения: 1698
Зарегистрирован: 20 авг 2017, 15:02
Репутация: 516
Настоящее имя: Константин
Откуда: Ульяновск
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение hmnijp »

MX_Master писал(а): одноразово сравниваются софт лимиты с позициями осей из файла
а подпрограммы и всякие трансформации координат когда проверяются?
MX_Master писал(а): Оно и понятно, разбирать и конвертировать весь файл целиком - бесполезная трата времени и ресурсов
На сколько помню - mycnc может начинать выполнять ещё до полной загрузки кода. В uccnc есть вариант с полным предпросмотром(вся уп загружается в память - да это требует кучу оперативной), или только по факту остановка будет когда до буфера дойдет косячная строка, и она не отрисовывает с учетом множествненных wcs, но множественные подпрограммы со смещениями отрисует все. Всё это важно на больших файлах - с одной стороны предпросмотр очень долгий, с другой без него нельзя проверить все ошибки заранее - и будет обидно, если через несколько часов работы всё внезапно остановится, когда узнаешь что какой-то переход за лимит вышел либо у g2/g3 конец не сходится - а такое иногда встречается. Так же из-за компенсации диаметра может получится невозможная для выполнения строка.
Линуксснс тоже всё целиком в память грузит, и раскрывает подпрограммы, на сколько помню.
sidor094
Мастер
Сообщения: 826
Зарегистрирован: 20 фев 2014, 09:13
Репутация: 81
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение sidor094 »

MX_Master писал(а): К примеру, если поставить код G91 в конце строки, а значения XYZ в начале, то трактовка позиций осей координально изменится только к концу строки.
Да у меня вначале идет работа со всей строкой,а потом выполняется действие.Но тип действия содержится в памяти и меняется во непосредственно во время просмотра строки.Команды типа g90-g91 выполняются непосредственно во время просмотра строки.А команды g0,g1,g2,g3,g31,g33 выполняются после просмотра всей строки,но они переключают тип действия непосредственно при просмотре строки и оно сохраняется вплоть до поступления команды на изменение типа действия.Это дает возможность в команде вводить только координаты ,и не вводить повторно g0,g1,g2,g3,g31,g33 если они были установлены в предидущих строках.Все команды условных переходов ,команды считывания и устновки входных и выходных портов изменение работы корректоров на радиус и длину инструмента и.т.д ждут очистки буфера и окончания выполнения последней команды прямо во время обработки строки.
MX_Master писал(а): В формате float, потому что так указано в стандарте G кода. Если системе для дальнейшего расчёта нужны целые числа, конвертируем (int) (1000.0 * float) и вперёд.
Не слышал о таком стандарте.Но у меня float используется только для работы с ячейками памяти типа #xxx=xxx или когда требуются вычисления например g1 x(#1000 +17) но и здесь как только это происходит прямо внутри строки и сразу переводится в signed int.В остальных же случаях переводы из одного типа к другому только замедляют работу.
Аватара пользователя
MX_Master
Мастер
Сообщения: 7465
Зарегистрирован: 27 июн 2015, 19:45
Репутация: 3088
Настоящее имя: Михаил
Откуда: Алматы
Контактная информация:

Re: Совместная разработка системы ЧПУ.

Сообщение MX_Master »

Я всего лишь сделал универсальный сканер строк G кода, который не противоречит аналогичному подходу в других системах. И по сути является обычным десериализатором текстовых данных. Что делать с готовым массивом данных на выходе - это задача для других компонентов. Unix way.

ЗЫ в данный момент пробую улучшить разбор с помощью регулярных выражений (PCRE2). Хочу добавить разбор и замену числовых/именованных параметров. Потом сравню скорость разбора с оригиналом на стандартных функциях (stdio.h, string.h).
Ответить

Вернуться в «Windows / Mach»