Модальные g-коды и конец программы.

Обсуждение установки, настройки и использования LinuxCNC. Вопросы по Gкоду.
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Модальные g-коды и конец программы.

Сообщение Lexxa »

Коллеги, пошу вот какой момент прояснить.
Согласно ISO, ГОСТ и википедии ( :hehehe: ) комадны
M02 - конец программы без сброса модальных функций
М30 - конец программы со сбросом мобальных функций.

Фактически же М02 сбрасывает модальные функции аналогично М30.
Например, включив G55-57 и/или G95 и выполнив m02 они сбросятся на G94 и G54.

Кто знает как вылечить?

Проверял на 2.6.11 и 2.7.2
:bender:
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

Ответ на вопрос почему так, сидит в мануале, однако это не есть правильно
3. M2, M30 Program End

M2 - end the program. Pressing cycle start will start the program at the beginning of the file.
M30 - exchange pallet shuttles and end the program. Pressing cycle start will start the program at the beginning of the file.
Both of these commands have the following effects:
Change from Auto mode to MDI mode.
Origin offsets are set to the default (like G54).
Selected plane is set to XY plane (like G17).
Distance mode is set to absolute mode (like G90).
Feed rate mode is set to units per minute (like G94).
Feed and speed overrides are set to ON (like M48).
Cutter compensation is turned off (like G40).
The spindle is stopped (like M5).
The current motion mode is set to feed (like G1).
Coolant is turned off (like M9).
:bender:
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5183
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Serg »

Это полностью совпадает с тем, что написано в RS274/NGC, т.е. разницы между M2 и М30 нет.
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

Совпадать то оно совпадает. Однако, во-первых это не соответствует ни
ISO 6983-1:2009, ни ГОСТ 20999-83.
А во-вторых, это не удобно.
Как минимум абсурдно на токарном станке включать g17 по команде м2.
Да, менять режим ввода подачи и менять активную систему координат тоже смысла нет.
(для просмотра содержимого нажмите на ссылку)

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

4024 /****************************************************************************/
4025 
4026 /*! convert_stop
4027 
4028 Returned Value: int
4029    When an m2 or m30 (program_end) is encountered, this returns INTERP_EXIT.
4030    If the code is not m0, m1, m2, m30, or m60, this returns
4031    NCE_BUG_CODE_NOT_M0_M1_M2_M30_M60
4032    Otherwise, it returns INTERP_OK.
4033 
4034 Side effects:
4035    An m0, m1, m2, m30, or m60 in the block is executed.
4036 
4037    For m0, m1, and m60, this makes a function call to the PROGRAM_STOP
4038    canonical machining function (which stops program execution).
4039    In addition, m60 calls PALLET_SHUTTLE.
4040 
4041    For m2 and m30, this resets the machine and then calls PROGRAM_END.
4042    In addition, m30 calls PALLET_SHUTTLE.
4043 
4044 Called by: execute_block.
4045 
4046 This handles stopping or ending the program (m0, m1, m2, m30, m60)
4047 
4048 [NCMS] specifies how the following modes should be reset at m2 or
4049 m30. The descriptions are not collected in one place, so this list
4050 may be incomplete.
4051 
4052 G52 offsetting coordinate zero points [NCMS, page 10]
4053 G92 coordinate offset using tool position [NCMS, page 10]
4054 
4055 The following should have reset values, but no description of reset
4056 behavior could be found in [NCMS].
4057 G17, G18, G19 selected plane [NCMS, pages 14, 20]
4058 G90, G91 distance mode [NCMS, page 15]
4059 G93, G94 feed mode [NCMS, pages 35 - 37]
4060 M48, M49 overrides enabled, disabled [NCMS, pages 37 - 38]
4061 M3, M4, M5 spindle turning [NCMS, page 7]
4062 
4063 The following should be set to some value at machine start-up but
4064 not automatically reset by any of the stopping codes.
4065 1. G20, G21 length units [NCMS, page 15]. This is up to the installer.
4066 2. motion_control_mode. This is set in Interp::init but not reset here.
4067    Might add it here.
4068 
4069 The following resets have been added by calling the appropriate
4070 canonical machining command and/or by resetting interpreter
4071 settings. They occur on M2 or M30.
4072 
4073 1. origin offsets are set to the default (like G54)
4074 2. Selected plane is set to CANON_PLANE_XY (like G17) - SELECT_PLANE
4075 3. Distance mode is set to MODE_ABSOLUTE (like G90)   - no canonical call
4076 4. Feed mode is set to UNITS_PER_MINUTE (like G94)    - no canonical call
4077 5. Feed and speed overrides are set to true (like M48)  - ENABLE_FEED_OVERRIDE
4078                                                       - ENABLE_SPEED_OVERRIDE
4079 6. Cutter compensation is turned off (like G40)       - no canonical call
4080 7. The spindle is stopped (like M5)                   - STOP_SPINDLE_TURNING
4081 8. The motion mode is set to G_1 (like G1)            - no canonical call
4082 9. Coolant is turned off (like M9)                    - FLOOD_OFF & MIST_OFF
4083 
4084 */
4085 
4086 int Interp::convert_stop(block_pointer block,    //!< pointer to a block of RS274/NGC instructions
4087                         setup_pointer settings) //!< pointer to machine settings                 
4088 {
4089   int index;
4090   char *line;
4091   int length;
4092 
4093   double cx, cy, cz;
4094   comp_get_current(settings, &cx, &cy, &cz);
4095   CHP(move_endpoint_and_flush(settings, cx, cy));
4096   dequeue_canons(settings);
4097 
4098   if (block->m_modes[4] == 0) {
4099     PROGRAM_STOP();
4100   } else if (block->m_modes[4] == 60) {
4101     PALLET_SHUTTLE();
4102     PROGRAM_STOP();
4103   } else if (block->m_modes[4] == 1) {
4104     OPTIONAL_PROGRAM_STOP();
4105   } else if ((block->m_modes[4] == 2) || (block->m_modes[4] == 30)) {   /* reset stuff here */
4106 /*1*/
4107     settings->current_x += settings->origin_offset_x;
4108     settings->current_y += settings->origin_offset_y;
4109     settings->current_z += settings->origin_offset_z;
4110     settings->AA_current += settings->AA_origin_offset;
4111     settings->BB_current += settings->BB_origin_offset;
4112     settings->CC_current += settings->CC_origin_offset;
4113     settings->u_current += settings->u_origin_offset;
4114     settings->v_current += settings->v_origin_offset;
4115     settings->w_current += settings->w_origin_offset;
4116     rotate(&settings->current_x, &settings->current_y, settings->rotation_xy);
4117 
4118     settings->origin_index = 1;
4119     settings->parameters[5220] = 1.0;
4120     settings->origin_offset_x = USER_TO_PROGRAM_LEN(settings->parameters[5221]);
4121     settings->origin_offset_y = USER_TO_PROGRAM_LEN(settings->parameters[5222]);
4122     settings->origin_offset_z = USER_TO_PROGRAM_LEN(settings->parameters[5223]);
4123     settings->AA_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5224]);
4124     settings->BB_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5225]);
4125     settings->CC_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5226]);
4126     settings->u_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5227]);
4127     settings->v_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5228]);
4128     settings->w_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5229]);
4129     settings->rotation_xy = settings->parameters[5230];
4130 
4131     rotate(&settings->current_x, &settings->current_y, -settings->rotation_xy);
4132     settings->current_x -= settings->origin_offset_x;
4133     settings->current_y -= settings->origin_offset_y;
4134     settings->current_z -= settings->origin_offset_z;
4135     settings->AA_current -= settings->AA_origin_offset;
4136     settings->BB_current -= settings->BB_origin_offset;
4137     settings->CC_current -= settings->CC_origin_offset;
4138     settings->u_current -= settings->u_origin_offset;
4139     settings->v_current -= settings->v_origin_offset;
4140     settings->w_current -= settings->w_origin_offset;
4141 
4142     SET_G5X_OFFSET(settings->origin_index,
4143                    settings->origin_offset_x,
4144                    settings->origin_offset_y,
4145                    settings->origin_offset_z,
4146                    settings->AA_origin_offset,
4147                    settings->BB_origin_offset,
4148                    settings->CC_origin_offset,
4149                    settings->u_origin_offset,
4150                    settings->v_origin_offset,
4151                    settings->w_origin_offset);
4152     SET_XY_ROTATION(settings->rotation_xy);
4153 
4154 /*2*/ if (settings->plane != CANON_PLANE_XY) {
4155       SELECT_PLANE(CANON_PLANE_XY);
4156       settings->plane = CANON_PLANE_XY;
4157     }
4158 
4159 /*3*/
4160     settings->distance_mode = MODE_ABSOLUTE;
4161 
4162 /*4*/ settings->feed_mode = UNITS_PER_MINUTE;
4163     SET_FEED_MODE(0);
4164     settings->feed_rate = block->f_number;
4165     SET_FEED_RATE(0);
4166 
4167 /*5*/ if (!settings->feed_override) {
4168       ENABLE_FEED_OVERRIDE();
4169       settings->feed_override = true;
4170     }
4171     if (!settings->speed_override) {
4172       ENABLE_SPEED_OVERRIDE();
4173       settings->speed_override = true;
4174     }
4175 
4176 /*6*/
4177     settings->cutter_comp_side = false;
4178     settings->cutter_comp_firstmove = true;
4179 
4180 /*7*/ STOP_SPINDLE_TURNING();
4181     settings->spindle_turning = CANON_STOPPED;
4182 
4183     /* turn off FPR */
4184     SET_SPINDLE_MODE(0);
4185 
4186 /*8*/ settings->motion_mode = G_1;
4187 
4188 /*9*/ if (settings->mist) {
4189       MIST_OFF();
4190       settings->mist = false;
4191     }
4192     if (settings->flood) {
4193       FLOOD_OFF();
4194       settings->flood = false;
4195     }
4196 
4197     if (block->m_modes[4] == 30)
4198       PALLET_SHUTTLE();
4199     PROGRAM_END();
4200     if (_setup.percent_flag && _setup.file_pointer) {
4201       line = _setup.linetext;
4202       for (;;) {                /* check for ending percent sign and comment if missing */
4203         if (fgets(line, LINELEN, _setup.file_pointer) == NULL) {
4204           enqueue_COMMENT("interpreter: percent sign missing from end of file");
4205           break;
4206         }
4207         length = strlen(line);
4208         if (length == (LINELEN - 1)) {       // line is too long. need to finish reading the line
4209           for (; fgetc(_setup.file_pointer) != '\n';);
4210           continue;
4211         }
4212         for (index = (length - 1);      // index set on last char
4213              (index >= 0) && (isspace(line[index])); index--);
4214         if (line[index] == '%') // found line with % at end
4215         {
4216           for (index--; (index >= 0) && (isspace(line[index])); index--);
4217           if (index == -1)      // found line with only percent sign
4218             break;
4219         }
4220       }
4221     }
4222     unwind_call(INTERP_EXIT, __FILE__,__LINE__,__FUNCTION__);
4223     return INTERP_EXIT;
4224   } else
4225     ERS(NCE_BUG_CODE_NOT_M0_M1_M2_M30_M60);
4226   return INTERP_OK;
4227 }
4228 
:bender:
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5183
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Serg »

Почитал ГОСТ - не нашёл там разницы в работе М2 и М30...
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

Дело не в разнице м2 и м 30. Дело в действии "приведение в исходное состояние" у lcnc и ГОСТ.
:bender:
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

согласно действующему в РФ ГОСТ
М02 Указывает на завершение отработки управляющей программы и приводит к останову шпинделя, подачи и выключению охлаждения после выполнения всех команд в кадре. Используется для приведения в исходное состояние УЧПУ и (или) исходное положение исполнительных органов станка.

М30 Приводит к останову шпинделя, подачи и выключению охлаждения после выполнения всех команд в кадре. Используется для приведения в исходное состояние УЧПУ и (или) исходное положение исполнительных органов станка. Установка в положение УЧПУ включает в себя возврат к символу "Начало программы".

Исходное состояние УЧПУ.
Рекомендуется, чтобы при включении питания, а также после отработки функций М02 или М30 в УЧПУ автоматически устанавливались следующие подготовительные функции:
при позиционном и прямолинейном управлении: G00, G40, G80, G90, G94, и G-функция "Размеры в милиметрах"
при контурном управлении (кроме токарных станков): G01, G17, G40, G80, G90, G94, и G-функция "Размеры в милиметрах"
при контурном управлении для токарных станков: G01, G40, G90, G94, G97 и G-функция "Размеры в милиметрах".

LinuxCNC при отработке М02 и М30 не учитывает тип станка - токарный он или фрезерный и как следствие все причесывает под одну фрезеную гребенку и это баг.
Ихмо тот же косяк и с циклами сверления, ибо они просят G17.
Ну в самом деле, какой же G17 токарному станку.

А ГОСТ не указано, что G18 является плоскостью по умолчанию для токарного станка, однако это подразумевается
Однако, по ГОСТ полсе отработки М02 и М30 УЧПУ должно приводиться в исходное состояние, которое в LinuxCNC определяется как параметр ini-файла
RS274NGC_STARTUP_CODE.
И, если уж не по ГОСТ, тогда исходное состояние должно быть таким, которое указано в этом параметре. Поскольку это не так,то это баг.
:bender:
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5183
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Serg »

Тут есть несколько моментов:

1.
Lexxa писал(а):Рекомендуется, чтобы при включении питания, а также после отработки функций М02 или М30
"Рекомендуется" != "Должно быть", даже в ГОСТ'ах.

2.
Lexxa писал(а):однако это подразумевается
В ГОСТ'ах ничего не подразумевается. В ГОСТ'ах либо определено, либо нет.

3. ГОСТ'ы - вообще не указ для разработчиков LinuxCNC, просто по факту их рождения. :)
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
Сергей Саныч
Мастер
Сообщения: 9116
Зарегистрирован: 30 май 2012, 14:20
Репутация: 2858
Откуда: Тюмень
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Сергей Саныч »

В давние-давние времена, когда программы ЧПУ набивались на перфоленте, M30 отличалась от M2 тем, что по M30 перфолента перематывалась на начало (до знака %).
M02 End of program
....
M30 End of program & rewind
А когда программы стали храниться на дисках, надобность в перемотке отпала.
Чудес не бывает. Бывают фокусы.
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

UAVpilot писал(а):3. ГОСТ'ы - вообще не указ для разработчиков LinuxCNC, просто по факту их рождения.
и именно по этому на токарном станке устанавливается плоскость G17 после М2 и М30?
Выдержки из ГОСТа, я показал, чтоб было видно,что для фрезерного это даже в госте прописано, а для токарного - нет.
UAVpilot писал(а):"Рекомендуется" != "Должно быть"
Я знал, что ты прицепишься к этой фразе. Дело твое.
В википедии, которая естественно разработчикам LinuxCNC тоже не указ, сказано, что
M02 - конец без сброса модальных функций,
М30 - конец со сбросом модальных функций.
В документе RS274D, который весь исписан про М2 и М30 нет деталей вообще, кроме того что это конец программы.
Однако

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

This handles stopping or ending the program (m0, m1, m2, m30, m60)

[NCMS] specifies how the following modes should be reset at m2 or
m30. The descriptions are not collected in one place, so this list
may be incomplete.

G52 offsetting coordinate zero points [NCMS, page 10]
G92 coordinate offset using tool position [NCMS, page 10]

The following should have reset values, but no description of reset
behavior could be found in [NCMS].
G17, G18, G19 selected plane [NCMS, pages 14, 20]
G90, G91 distance mode [NCMS, page 15]
G93, G94 feed mode [NCMS, pages 35 - 37]
M48, M49 overrides enabled, disabled [NCMS, pages 37 - 38]
M3, M4, M5 spindle turning [NCMS, page 7]

The following should be set to some value at machine start-up but
not automatically reset by any of the stopping codes.
1. G20, G21 length units [NCMS, page 15]. This is up to the installer.
2. motion_control_mode. This is set in Interp::init but not reset here.
   Might add it here.

The following resets have been added by calling the appropriate
canonical machining command and/or by resetting interpreter
settings. They occur on M2 or M30.

1. origin offsets are set to the default (like G54)
2. Selected plane is set to CANON_PLANE_XY (like G17) - SELECT_PLANE
3. Distance mode is set to MODE_ABSOLUTE (like G90)   - no canonical call
4. Feed mode is set to UNITS_PER_MINUTE (like G94)    - no canonical call
5. Feed and speed overrides are set to true (like M48)  - ENABLE_FEED_OVERRIDE
                                                      - ENABLE_SPEED_OVERRIDE
6. Cutter compensation is turned off (like G40)       - no canonical call
7. The spindle is stopped (like M5)                   - STOP_SPINDLE_TURNING
8. The motion mode is set to G_1 (like G1)            - no canonical call
9. Coolant is turned off (like M9)                    - FLOOD_OFF & MIST_OFF

*/
Т.е. сделали, так как знали.
:bender:
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5183
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Serg »

Lexxa писал(а):Выдержки из ГОСТа, я показал, чтоб было видно,что для фрезерного это даже в госте прописано, а для токарного - нет.
Возможно ГОСТ устарел, возможно даже, что его разработчики не думали о токарных - они ведь тоже люди...
Lexxa писал(а):Я знал, что ты прицепишься к этой фразе. Дело твое.
А я-то тут при чём? :) Оно на то и рекомендация, что можно ей следовать, а можно и не следовать.
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

В общем вылечил я это правкой исходников:
в файл
src/emc/rs274ngc/interp_internal.hh
после

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

  int lazy_closing;                  // close has been called
  char wizard_root[PATH_MAX];
  int tool_change_at_g30;
  int tool_change_quill_up;
  int tool_change_with_spindle_on;
  int a_axis_wrapped;
  int b_axis_wrapped;
  int c_axis_wrapped;
вставляем

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

  int lathe_mode;
  int def_unit_per_rev;
в файл src/emc/rs274ngc/rs274ngc_pre.cc
после

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

  _setup.call_state = CS_NORMAL;
вставляем

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

  _setup.lathe_mode = 0; // mill
  _setup.def_unit_per_rev = 0; //G94
после

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

          inifile.Find(&_setup.feature_set, "FEATURES", "RS274NGC");
вставляем

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

          inifile.Find(&_setup.lathe_mode, "LATHE", "DISPLAY");
          inifile.Find(&_setup.def_unit_per_rev,"DEFAULT_G95","RS274NGC");
в файл src/emc/rs274ngc/interp_convert.cc
вместо функции
convert_stop (для просмотра содержимого нажмите на ссылку)

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

4024 /****************************************************************************/
4025 
4026 /*! convert_stop
4027 
4028 Returned Value: int
4029    When an m2 or m30 (program_end) is encountered, this returns INTERP_EXIT.
4030    If the code is not m0, m1, m2, m30, or m60, this returns
4031    NCE_BUG_CODE_NOT_M0_M1_M2_M30_M60
4032    Otherwise, it returns INTERP_OK.
4033 
4034 Side effects:
4035    An m0, m1, m2, m30, or m60 in the block is executed.
4036 
4037    For m0, m1, and m60, this makes a function call to the PROGRAM_STOP
4038    canonical machining function (which stops program execution).
4039    In addition, m60 calls PALLET_SHUTTLE.
4040 
4041    For m2 and m30, this resets the machine and then calls PROGRAM_END.
4042    In addition, m30 calls PALLET_SHUTTLE.
4043 
4044 Called by: execute_block.
4045 
4046 This handles stopping or ending the program (m0, m1, m2, m30, m60)
4047 
4048 [NCMS] specifies how the following modes should be reset at m2 or
4049 m30. The descriptions are not collected in one place, so this list
4050 may be incomplete.
4051 
4052 G52 offsetting coordinate zero points [NCMS, page 10]
4053 G92 coordinate offset using tool position [NCMS, page 10]
4054 
4055 The following should have reset values, but no description of reset
4056 behavior could be found in [NCMS].
4057 G17, G18, G19 selected plane [NCMS, pages 14, 20]
4058 G90, G91 distance mode [NCMS, page 15]
4059 G93, G94 feed mode [NCMS, pages 35 - 37]
4060 M48, M49 overrides enabled, disabled [NCMS, pages 37 - 38]
4061 M3, M4, M5 spindle turning [NCMS, page 7]
4062 
4063 The following should be set to some value at machine start-up but
4064 not automatically reset by any of the stopping codes.
4065 1. G20, G21 length units [NCMS, page 15]. This is up to the installer.
4066 2. motion_control_mode. This is set in Interp::init but not reset here.
4067    Might add it here.
4068 
4069 The following resets have been added by calling the appropriate
4070 canonical machining command and/or by resetting interpreter
4071 settings. They occur on M2 or M30.
4072 
4073 1. origin offsets are set to the default (like G54)
4074 2. Selected plane is set to CANON_PLANE_XY (like G17) - SELECT_PLANE
4075 3. Distance mode is set to MODE_ABSOLUTE (like G90)   - no canonical call
4076 4. Feed mode is set to UNITS_PER_MINUTE (like G94)    - no canonical call
4077 5. Feed and speed overrides are set to true (like M48)  - ENABLE_FEED_OVERRIDE
4078                                                       - ENABLE_SPEED_OVERRIDE
4079 6. Cutter compensation is turned off (like G40)       - no canonical call
4080 7. The spindle is stopped (like M5)                   - STOP_SPINDLE_TURNING
4081 8. The motion mode is set to G_1 (like G1)            - no canonical call
4082 9. Coolant is turned off (like M9)                    - FLOOD_OFF & MIST_OFF
4083 
4084 */
4085 
4086 int Interp::convert_stop(block_pointer block,    //!< pointer to a block of RS274/NGC instructions
4087                         setup_pointer settings) //!< pointer to machine settings                 
4088 {
4089   int index;
4090   char *line;
4091   int length;
4092 
4093   double cx, cy, cz;
4094   comp_get_current(settings, &cx, &cy, &cz);
4095   CHP(move_endpoint_and_flush(settings, cx, cy));
4096   dequeue_canons(settings);
4097 
4098   if (block->m_modes[4] == 0) {
4099     PROGRAM_STOP();
4100   } else if (block->m_modes[4] == 60) {
4101     PALLET_SHUTTLE();
4102     PROGRAM_STOP();
4103   } else if (block->m_modes[4] == 1) {
4104     OPTIONAL_PROGRAM_STOP();
4105   } else if ((block->m_modes[4] == 2) || (block->m_modes[4] == 30)) {   /* reset stuff here */
4106 /*1*/
4107     settings->current_x += settings->origin_offset_x;
4108     settings->current_y += settings->origin_offset_y;
4109     settings->current_z += settings->origin_offset_z;
4110     settings->AA_current += settings->AA_origin_offset;
4111     settings->BB_current += settings->BB_origin_offset;
4112     settings->CC_current += settings->CC_origin_offset;
4113     settings->u_current += settings->u_origin_offset;
4114     settings->v_current += settings->v_origin_offset;
4115     settings->w_current += settings->w_origin_offset;
4116     rotate(&settings->current_x, &settings->current_y, settings->rotation_xy);
4117 
4118     settings->origin_index = 1;
4119     settings->parameters[5220] = 1.0;
4120     settings->origin_offset_x = USER_TO_PROGRAM_LEN(settings->parameters[5221]);
4121     settings->origin_offset_y = USER_TO_PROGRAM_LEN(settings->parameters[5222]);
4122     settings->origin_offset_z = USER_TO_PROGRAM_LEN(settings->parameters[5223]);
4123     settings->AA_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5224]);
4124     settings->BB_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5225]);
4125     settings->CC_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5226]);
4126     settings->u_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5227]);
4127     settings->v_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5228]);
4128     settings->w_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5229]);
4129     settings->rotation_xy = settings->parameters[5230];
4130 
4131     rotate(&settings->current_x, &settings->current_y, -settings->rotation_xy);
4132     settings->current_x -= settings->origin_offset_x;
4133     settings->current_y -= settings->origin_offset_y;
4134     settings->current_z -= settings->origin_offset_z;
4135     settings->AA_current -= settings->AA_origin_offset;
4136     settings->BB_current -= settings->BB_origin_offset;
4137     settings->CC_current -= settings->CC_origin_offset;
4138     settings->u_current -= settings->u_origin_offset;
4139     settings->v_current -= settings->v_origin_offset;
4140     settings->w_current -= settings->w_origin_offset;
4141 
4142     SET_G5X_OFFSET(settings->origin_index,
4143                    settings->origin_offset_x,
4144                    settings->origin_offset_y,
4145                    settings->origin_offset_z,
4146                    settings->AA_origin_offset,
4147                    settings->BB_origin_offset,
4148                    settings->CC_origin_offset,
4149                    settings->u_origin_offset,
4150                    settings->v_origin_offset,
4151                    settings->w_origin_offset);
4152     SET_XY_ROTATION(settings->rotation_xy);
4153 
4154 /*2*/ if (settings->plane != CANON_PLANE_XY) {
4155       SELECT_PLANE(CANON_PLANE_XY);
4156       settings->plane = CANON_PLANE_XY;
4157     }
4158 
4159 /*3*/
4160     settings->distance_mode = MODE_ABSOLUTE;
4161 
4162 /*4*/ settings->feed_mode = UNITS_PER_MINUTE;
4163     SET_FEED_MODE(0);
4164     settings->feed_rate = block->f_number;
4165     SET_FEED_RATE(0);
4166 
4167 /*5*/ if (!settings->feed_override) {
4168       ENABLE_FEED_OVERRIDE();
4169       settings->feed_override = true;
4170     }
4171     if (!settings->speed_override) {
4172       ENABLE_SPEED_OVERRIDE();
4173       settings->speed_override = true;
4174     }
4175 
4176 /*6*/
4177     settings->cutter_comp_side = false;
4178     settings->cutter_comp_firstmove = true;
4179 
4180 /*7*/ STOP_SPINDLE_TURNING();
4181     settings->spindle_turning = CANON_STOPPED;
4182 
4183     /* turn off FPR */
4184     SET_SPINDLE_MODE(0);
4185 
4186 /*8*/ settings->motion_mode = G_1;
4187 
4188 /*9*/ if (settings->mist) {
4189       MIST_OFF();
4190       settings->mist = false;
4191     }
4192     if (settings->flood) {
4193       FLOOD_OFF();
4194       settings->flood = false;
4195     }
4196 
4197     if (block->m_modes[4] == 30)
4198       PALLET_SHUTTLE();
4199     PROGRAM_END();
4200     if (_setup.percent_flag && _setup.file_pointer) {
4201       line = _setup.linetext;
4202       for (;;) {                /* check for ending percent sign and comment if missing */
4203         if (fgets(line, LINELEN, _setup.file_pointer) == NULL) {
4204           enqueue_COMMENT("interpreter: percent sign missing from end of file");
4205           break;
4206         }
4207         length = strlen(line);
4208         if (length == (LINELEN - 1)) {       // line is too long. need to finish reading the line
4209           for (; fgetc(_setup.file_pointer) != '\n';);
4210           continue;
4211         }
4212         for (index = (length - 1);      // index set on last char
4213              (index >= 0) && (isspace(line[index])); index--);
4214         if (line[index] == '%') // found line with % at end
4215         {
4216           for (index--; (index >= 0) && (isspace(line[index])); index--);
4217           if (index == -1)      // found line with only percent sign
4218             break;
4219         }
4220       }
4221     }
4222     unwind_call(INTERP_EXIT, __FILE__,__LINE__,__FUNCTION__);
4223     return INTERP_EXIT;
4224   } else
4225     ERS(NCE_BUG_CODE_NOT_M0_M1_M2_M30_M60);
4226   return INTERP_OK;
4227 }
4228 
Вставляем свою
convert_stop (для просмотра содержимого нажмите на ссылку)

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

/****************************************************************************/

/*! convert_stop

Returned Value: int
   When an m2 or m30 (program_end) is encountered, this returns INTERP_EXIT.
   If the code is not m0, m1, m2, m30, or m60, this returns
   NCE_BUG_CODE_NOT_M0_M1_M2_M30_M60
   Otherwise, it returns INTERP_OK.

Side effects:
   An m0, m1, m2, m30, or m60 in the block is executed.

   For m0, m1, and m60, this makes a function call to the PROGRAM_STOP
   canonical machining function (which stops program execution).
   In addition, m60 calls PALLET_SHUTTLE.

   For m2 and m30, this resets the machine and then calls PROGRAM_END.
   In addition, m30 calls PALLET_SHUTTLE.

Called by: execute_block.

This handles stopping or ending the program (m0, m1, m2, m30, m60)

[NCMS] specifies how the following modes should be reset at m2 or
m30. The descriptions are not collected in one place, so this list
may be incomplete.

G52 offsetting coordinate zero points [NCMS, page 10]
G92 coordinate offset using tool position [NCMS, page 10]

The following should have reset values, but no description of reset
behavior could be found in [NCMS].
G17, G18, G19 selected plane [NCMS, pages 14, 20]
G90, G91 distance mode [NCMS, page 15]
G93, G94 feed mode [NCMS, pages 35 - 37]
M48, M49 overrides enabled, disabled [NCMS, pages 37 - 38]
M3, M4, M5 spindle turning [NCMS, page 7]

The following should be set to some value at machine start-up but
not automatically reset by any of the stopping codes.
1. G20, G21 length units [NCMS, page 15]. This is up to the installer.
2. motion_control_mode. This is set in Interp::init but not reset here.
   Might add it here.

The following resets have been added by calling the appropriate
canonical machining command and/or by resetting interpreter
settings. They occur on M2 or M30.

1. origin offsets are set to the default (like G54)
2. Selected plane is set to CANON_PLANE_XY (like G17) - SELECT_PLANE
3. Distance mode is set to MODE_ABSOLUTE (like G90)   - no canonical call
4. Feed mode is set to UNITS_PER_MINUTE (like G94)    - no canonical call
5. Feed and speed overrides are set to true (like M48)  - ENABLE_FEED_OVERRIDE
                                                      - ENABLE_SPEED_OVERRIDE
6. Cutter compensation is turned off (like G40)       - no canonical call
7. The spindle is stopped (like M5)                   - STOP_SPINDLE_TURNING
8. The motion mode is set to G_1 (like G1)            - no canonical call
9. Coolant is turned off (like M9)                    - FLOOD_OFF & MIST_OFF

*/

int Interp::convert_stop(block_pointer block,    //!< pointer to a block of RS274/NGC instructions
                        setup_pointer settings) //!< pointer to machine settings                 
{
  int index;
  char *line;
  int length;

  double cx, cy, cz;
  comp_get_current(settings, &cx, &cy, &cz);
  CHP(move_endpoint_and_flush(settings, cx, cy));
  dequeue_canons(settings);

  if (block->m_modes[4] == 0) {
    PROGRAM_STOP();
  } else if (block->m_modes[4] == 60) {
    PALLET_SHUTTLE();
    PROGRAM_STOP();
  } else if (block->m_modes[4] == 1) {
    OPTIONAL_PROGRAM_STOP();
  } else if ((block->m_modes[4] == 2) || (block->m_modes[4] == 30)) {   /* reset stuff here */
/*1*/
    if (block->m_modes[4] == 30) {
    settings->current_x += settings->origin_offset_x;
    settings->current_y += settings->origin_offset_y;
    settings->current_z += settings->origin_offset_z;
    settings->AA_current += settings->AA_origin_offset;
    settings->BB_current += settings->BB_origin_offset;
    settings->CC_current += settings->CC_origin_offset;
    settings->u_current += settings->u_origin_offset;
    settings->v_current += settings->v_origin_offset;
    settings->w_current += settings->w_origin_offset;
    rotate(&settings->current_x, &settings->current_y, settings->rotation_xy);
    settings->origin_index = 1;
    settings->parameters[5220] = 1.0;
    settings->origin_offset_x = USER_TO_PROGRAM_LEN(settings->parameters[5221]);
    settings->origin_offset_y = USER_TO_PROGRAM_LEN(settings->parameters[5222]);
    settings->origin_offset_z = USER_TO_PROGRAM_LEN(settings->parameters[5223]);
    settings->AA_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5224]);
    settings->BB_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5225]);
    settings->CC_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5226]);
    settings->u_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5227]);
    settings->v_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5228]);
    settings->w_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5229]);
    settings->rotation_xy = settings->parameters[5230];
    rotate(&settings->current_x, &settings->current_y, -settings->rotation_xy);
    settings->current_x -= settings->origin_offset_x;
    settings->current_y -= settings->origin_offset_y;
    settings->current_z -= settings->origin_offset_z;
    settings->AA_current -= settings->AA_origin_offset;
    settings->BB_current -= settings->BB_origin_offset;
    settings->CC_current -= settings->CC_origin_offset;
    settings->u_current -= settings->u_origin_offset;
    settings->v_current -= settings->v_origin_offset;
    settings->w_current -= settings->w_origin_offset;

    SET_G5X_OFFSET(settings->origin_index,
                   settings->origin_offset_x,
                   settings->origin_offset_y,
                   settings->origin_offset_z,
                   settings->AA_origin_offset,
                   settings->BB_origin_offset,
                   settings->CC_origin_offset,
                   settings->u_origin_offset,
                   settings->v_origin_offset,
                   settings->w_origin_offset);
    SET_XY_ROTATION(settings->rotation_xy);
    }

/*2*/
    if (settings->lathe_mode==1) {
        if (settings->plane != CANON_PLANE_XZ) {
          SELECT_PLANE(CANON_PLANE_XZ);
          settings->plane = CANON_PLANE_XZ;
        }
    }
    if (settings->lathe_mode==0) {
        if (settings->plane != CANON_PLANE_XY) {
          SELECT_PLANE(CANON_PLANE_XY);
          settings->plane = CANON_PLANE_XY;
        }
    }
/*3*/
    settings->distance_mode = MODE_ABSOLUTE;

/*4*/
    if (settings->def_unit_per_rev==1) {
        settings->feed_mode = UNITS_PER_REVOLUTION;
        SET_FEED_MODE(1);
        settings->feed_rate = block->f_number;
        SET_FEED_RATE(0);
    } else {
        settings->feed_mode = UNITS_PER_MINUTE;
        SET_FEED_MODE(0);
        settings->feed_rate = block->f_number;
        SET_FEED_RATE(0);
    }

/*5*/ if (!settings->feed_override) {
      ENABLE_FEED_OVERRIDE();
      settings->feed_override = true;
    }
    if (!settings->speed_override) {
      ENABLE_SPEED_OVERRIDE();
      settings->speed_override = true;
    }

/*6*/
    settings->cutter_comp_side = false;
    settings->cutter_comp_firstmove = true;

/*7*/ STOP_SPINDLE_TURNING();
    settings->spindle_turning = CANON_STOPPED;

    /* turn off FPR */
    SET_SPINDLE_MODE(0);

/*8*/ settings->motion_mode = G_1;

/*9*/ if (settings->mist) {
      MIST_OFF();
      settings->mist = false;
    }
    if (settings->flood) {
      FLOOD_OFF();
      settings->flood = false;
    }

    if (block->m_modes[4] == 30)
      PALLET_SHUTTLE();
    PROGRAM_END();
    if (_setup.percent_flag && _setup.file_pointer) {
      line = _setup.linetext;
      for (;;) {                /* check for ending percent sign and comment if missing */
        if (fgets(line, LINELEN, _setup.file_pointer) == NULL) {
          enqueue_COMMENT("interpreter: percent sign missing from end of file");
          break;
        }
        length = strlen(line);
        if (length == (LINELEN - 1)) {       // line is too long. need to finish reading the line
          for (; fgetc(_setup.file_pointer) != '\n';);
          continue;
        }
        for (index = (length - 1);      // index set on last char
             (index >= 0) && (isspace(line[index])); index--);
        if (line[index] == '%') // found line with % at end
        {
          for (index--; (index >= 0) && (isspace(line[index])); index--);
          if (index == -1)      // found line with only percent sign
            break;
        }
      }
    }
    unwind_call(INTERP_EXIT, __FILE__,__LINE__,__FUNCTION__);
    return INTERP_EXIT;
  } else
    ERS(NCE_BUG_CODE_NOT_M0_M1_M2_M30_M60);
  return INTERP_OK;
}
В итоге
1) если в ini-файле в секции [DYSPLAY] есть "LATHE = 1", то после выполнения M2 или М30 включится плоскость G17;
2) если отрабатыается команда M02, то ноль детали остается тем, что последний раз включался в MDI или программе, если M30, то переключается на G54;
3) если в секции [RS274NGC] есть "DEFAULT_G95 =1", то после M02 или M30 включится G95, если этого параметра нет или "DEFAULT_G95 =1", то будет все как и было раньше, т.е. включится G94.

Далее все как обычно:

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

make clean && ./configure --prefix=/usr --enable-simulator && make && make install
Неудобство в том, что при обновлении придется повторять операцию вновь.

Знатоки, как сделать патч?
:bender:
nkp
Мастер
Сообщения: 8340
Зарегистрирован: 28 ноя 2011, 00:25
Репутация: 1589
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение nkp »

Lexxa писал(а):Далее все как обычно:
после правок в исходиках всегда хватало просто:
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5183
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Serg »

Lexxa писал(а):Знатоки, как сделать патч?
утилитой diff.
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

nkp писал(а):после правок в исходиках всегда хватало просто:
просто make не копирует все в /usr...
:bender:
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5183
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Serg »

"make install" копирует.

Без "make clean && ./configure --prefix=/usr --enable-simulator" скомпилируется только то, что было изменено.
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

UAVpilot,
проясни плз конструкцию

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

int motion_mode;              // active G-code for motion
+

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

_setup.motion_mode = G_80;
+

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

int Interp::convert_cycle_zx(int motion, //!< a g-code between G_81 and G_89, a canned cycle
                            block_pointer block,        //!< pointer to a block of RS274 instructions      
                            setup_pointer settings)     //!< pointer to machine settings                   
{
 if (settings->motion_mode != motion) {
    CHKS((!block->y_flag),
        _readers[(int)'y']? NCE_Y_VALUE_UNSPECIFIED_IN_XZ_PLANE_CANNED_CYCLE: _("G18 canned cycle is not possible on a machine without Y axis"));
  }
}
Опять же токарный станок, никаких Y-ков, при команде
G90 G81 G98 X4 Z1.5 R2.8 F100
ругается на отсутствие Y.
upd:
Т.е. оно смотрит, что цикл в цикле не запущен, т.е. есть G80, а затем смотрит на
_readers[(int)'y']? - как это на русский язык перевести?

если так:

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

if LATHE != 1 {
        _readers[(int)'y']? NCE_Y_VALUE_UNSPECIFIED_IN_XZ_PLANE_CANNED_CYCLE: _("G18 canned cycle is not possible on a machine without Y axis"));
}
по идее он проглотит и не ругнется на отсутствие Y, не будет ли косяка при отработке цикла?
:bender:
Аватара пользователя
Serg
Мастер
Сообщения: 21923
Зарегистрирован: 17 апр 2012, 14:58
Репутация: 5183
Заслуга: c781c134843e0c1a3de9
Настоящее имя: Сергей
Откуда: Москва
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Serg »

Lexxa писал(а):int motion_mode;
Объявление переменной. Судя по дальнейшему использованию это объявление элемента структуры, просто ты показал не все объявление.
Lexxa писал(а):_setup.motion_mode = G_80;
структура _setup, элемент motion_mode, присваивание именованной константы (скорее всего).
Lexxa писал(а):ругается на отсутствие Y.
Всё правильно, G81 желает перемещаться в XY плане...
Lexxa писал(а):_readers[(int)'y']? - как это на русский язык перевести?
символ 'y' с приведением к типу int, т.е. код символа 'y'.

Рекоментую осилисть хотябы основы C, будет много проще...
Я не Христос, рыбу не раздаю, но могу научить, как сделать удочку...
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

Институтский курс вспоминаю)

С объявлением переменной это понятно.
Не ясно символ "_" перед setup.
UAVpilot писал(а):Всё правильно, G81 желает перемещаться в XY плане...
А вот и нет! Ибо конструкция

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

_readers[(int)'y']? бла бла бла
описана в функции
convert_cycle_zx (для просмотра содержимого нажмите на ссылку)

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

int Interp::convert_cycle_zx(int motion, //!< a g-code between G_81 and G_89, a canned cycle
                            block_pointer block,        //!< pointer to a block of RS274 instructions      
                            setup_pointer settings)     //!< pointer to machine settings                   
{
  double aa;
  double aa_increment=0.;
  double bb;
  double bb_increment=0.;
  double cc;
  double clear_cc;
  double i;
  double j;
  double k;
  double old_cc;
  double radius_increment = 0.;
  double theta_increment = 0.;
  CANON_PLANE plane;
  double r;
  int repeat;
  CANON_MOTION_MODE save_mode;
  double save_tolerance; //save current path-following tolerance, to restore it lateron
  double current_cc = settings->current_y;

  plane = CANON_PLANE_XZ;
  if (settings->motion_mode != motion) {
    CHKS((!block->y_flag),
        _readers[(int)'y']? NCE_Y_VALUE_UNSPECIFIED_IN_XZ_PLANE_CANNED_CYCLE: _("G18 canned cycle is not possible on a machine without Y axis"));
  }
  block->y_number =
    block->y_flag ? block->y_number : settings->cycle_cc;
  if(settings->cycle_il_flag) {
      old_cc = settings->cycle_il;
  } else {
      old_cc = settings->cycle_il = current_cc;
      settings->cycle_il_flag = true;
  }

  if (settings->distance_mode == MODE_ABSOLUTE) {
    aa_increment = 0.0;
    bb_increment = 0.0;
    r = block->r_number;
    cc = block->y_number;
    aa = block->z_flag ? block->z_number : settings->current_z;
    bb = block->x_flag ? block->x_number : settings->current_x;
  } else if (settings->distance_mode == MODE_INCREMENTAL) {
    if (block->z_flag) aa_increment = block->z_number;
    if (block->x_flag) bb_increment = block->x_number;
    r = (block->r_number + old_cc);
    cc = (r + block->y_number); /* [NCMS, page 98] */
    aa = settings->current_z;
    bb = settings->current_x;
  } else
    ERS(NCE_BUG_DISTANCE_MODE_NOT_G90_OR_G91);
  CHKS((r < cc), NCE_R_LESS_THAN_Y_IN_CYCLE_IN_XZ_PLANE);

  if (old_cc < r) {
    STRAIGHT_TRAVERSE(block->line_number, settings->current_x, r, settings->current_z,
                      settings->AA_current, settings->BB_current, settings->CC_current,
                      settings->u_current, settings->v_current, settings->w_current);
    old_cc = r;
    current_cc = old_cc;
  }
  clear_cc = (settings->retract_mode == R_PLANE) ? r : old_cc;

  save_mode = GET_EXTERNAL_MOTION_CONTROL_MODE();
  save_tolerance = GET_EXTERNAL_MOTION_CONTROL_TOLERANCE();
  if (save_mode != CANON_EXACT_PATH)
    SET_MOTION_CONTROL_MODE(CANON_EXACT_PATH, 0);

  switch (motion) {
  case G_81:
    CYCLE_MACRO(convert_cycle_g81(block, CANON_PLANE_XZ, aa, bb, clear_cc, cc))
      break;
  case G_82:
    CHKS(((settings->motion_mode != G_82) && (block->p_number == -1.0)),
        NCE_DWELL_TIME_P_WORD_MISSING_WITH_G82);
    block->p_number =
      block->p_number == -1.0 ? settings->cycle_p : block->p_number;
    CYCLE_MACRO(convert_cycle_g82(block, CANON_PLANE_XZ, aa, bb, clear_cc, cc,
                                  block->p_number))
      settings->cycle_p = block->p_number;
    break;
  case G_73:
    CHKS(((settings->motion_mode != G_73) && (block->q_number == -1.0)),
        NCE_Q_WORD_MISSING_WITH_G73);
    block->q_number =
      block->q_number == -1.0 ? settings->cycle_q : block->q_number;
    CYCLE_MACRO(convert_cycle_g73(block, CANON_PLANE_XZ, aa, bb, r, clear_cc, cc,
                                  block->q_number))
      settings->cycle_q = block->q_number;
    break;
  case G_83:
    CHKS(((settings->motion_mode != G_83) && (block->q_number == -1.0)),
        NCE_Q_WORD_MISSING_WITH_G83);
    block->q_number =
      block->q_number == -1.0 ? settings->cycle_q : block->q_number;
    CYCLE_MACRO(convert_cycle_g83(block, CANON_PLANE_XZ, aa, bb, r, clear_cc, cc,
                                  block->q_number))
      settings->cycle_q = block->q_number;
    break;
  case G_84:
    CYCLE_MACRO(convert_cycle_g84(block, CANON_PLANE_XZ, aa, bb, clear_cc, cc,
                                  settings->spindle_turning,
                                  settings->speed_feed_mode)) break;
  case G_85:
    CYCLE_MACRO(convert_cycle_g85(block, CANON_PLANE_XZ, aa, bb, r, clear_cc, cc))
      break;
  case G_86:
    CHKS(((settings->motion_mode != G_86) && (block->p_number == -1.0)),
        NCE_DWELL_TIME_P_WORD_MISSING_WITH_G86);
    block->p_number =
      block->p_number == -1.0 ? settings->cycle_p : block->p_number;
    CYCLE_MACRO(convert_cycle_g86(block, CANON_PLANE_XZ, aa, bb, clear_cc, cc,
                                  block->p_number,
                                  settings->spindle_turning)) settings->
      cycle_p = block->p_number;
    break;
  case G_87:
    if (settings->motion_mode != G_87) {
      CHKS((!block->i_flag), NCE_I_WORD_MISSING_WITH_G87);
      CHKS((!block->j_flag), NCE_J_WORD_MISSING_WITH_G87);
      CHKS((!block->k_flag), NCE_K_WORD_MISSING_WITH_G87);
    }
    i = block->i_flag ? block->i_number : settings->cycle_i;
    j = block->j_flag ? block->j_number : settings->cycle_j;
    k = block->k_flag ? block->k_number : settings->cycle_k;
    settings->cycle_i = i;
    settings->cycle_j = j;
    settings->cycle_k = k;
    if (settings->distance_mode == MODE_INCREMENTAL) {
      j = (cc + j);             /* j always absolute in function call below */
    }
    CYCLE_MACRO(convert_cycle_g87(block, CANON_PLANE_XZ, aa, (aa + k), bb,
                                  (bb + i), r, clear_cc, j, cc,
                                  settings->spindle_turning)) break;
  case G_88:
    CHKS(((settings->motion_mode != G_88) && (block->p_number == -1.0)),
        NCE_DWELL_TIME_P_WORD_MISSING_WITH_G88);
    block->p_number =
      block->p_number == -1.0 ? settings->cycle_p : block->p_number;
    CYCLE_MACRO(convert_cycle_g88(block, CANON_PLANE_XZ, aa, bb, cc,
                                  block->p_number,
                                  settings->spindle_turning)) settings->
      cycle_p = block->p_number;
    break;
  case G_89:
    CHKS(((settings->motion_mode != G_89) && (block->p_number == -1.0)),
        NCE_DWELL_TIME_P_WORD_MISSING_WITH_G89);
    block->p_number =
      block->p_number == -1.0 ? settings->cycle_p : block->p_number;
    CYCLE_MACRO(convert_cycle_g89(block, CANON_PLANE_XZ, aa, bb, clear_cc, cc,
                                  block->p_number))
      settings->cycle_p = block->p_number;
    break;
  default:
    ERS(NCE_BUG_FUNCTION_SHOULD_NOT_HAVE_BEEN_CALLED);
  }
  settings->current_z = aa;     /* CYCLE_MACRO updates aa and bb */
  settings->current_x = bb;
  settings->current_y = clear_cc;
  settings->cycle_cc = block->y_number;

  if (save_mode != CANON_EXACT_PATH)
    SET_MOTION_CONTROL_MODE(save_mode, save_tolerance);

  return INTERP_OK;
}
Кроме того в файле interp_cycles_cc есть функция convert_cycle_g81 в коментах к которой написано, что
/*! convert_cycle_g81

Returned Value: int (INTERP_OK)

Side effects: See below

Called by:
convert_cycle_xy
convert_cycle_yz
convert_cycle_zx

For the XY plane, this implements the following RS274/NGC cycle, which
is usually drilling:
1. Move the z-axis only at the current feed rate to the specified bottom_z.
2. Retract the z-axis at traverse rate to clear_z.

See [NCMS, page 99].

CYCLE_MACRO has positioned the tool at (x, y, r, a, b, c) when this starts.

For the XZ and YZ planes, this makes analogous motions.

*/
Которая используется все в той же функции convert_cycle_zx, которая и генерит ошибку про ось Y:

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

  switch (motion) {
  case G_81:
    CYCLE_MACRO(convert_cycle_g81(block, CANON_PLANE_XZ, aa, bb, clear_cc, cc))
      break;
  case G_82:
    CHKS(((settings->motion_mode != G_82) && (block->p_number == -1.0)),
        NCE_DWELL_TIME_P_WORD_MISSING_WITH_G82);
    block->p_number =
      block->p_number == -1.0 ? settings->cycle_p : block->p_number;
    CYCLE_MACRO(convert_cycle_g82(block, CANON_PLANE_XZ, aa, bb, clear_cc, cc,
                                  block->p_number))
      settings->cycle_p = block->p_number;
    break;
:bender:
Аватара пользователя
Lexxa
Мастер
Сообщения: 2703
Зарегистрирован: 16 дек 2011, 16:48
Репутация: 319
Настоящее имя: Алексей
Откуда: ryazan
Контактная информация:

Re: Модальные g-коды и конец программы.

Сообщение Lexxa »

Lexxa писал(а):Всё правильно, G81 желает перемещаться в XY плане...
Тут требуется вот какое разъяснение.
Цикл всерления работает во всех трех плоскостях: G17, G18 и G19.
Циклы G81 и иже с ними написаны так, что они требуют третью ось, опять же в концепции фрезерного станка, а именно
В плоскости
G17 (XY) цикл G81 считает, что ось шпинделя это Z
G18 (XZ) цикл G81 считает, что ось шпинделя это Y
G19 (YZ) цикл G81 считает, что ось шпинделя это X
Именно поэтому он и ругается на отсутствие оси Y у токарного станка.

Видится следующий путь решения:
если LATHE=1, то выполняем цикл сверления аналогичный циклу XY, но без смены плоскости.
Как это запрограммировать я пока не шарю, но постараюсь разобраться.
:bender:
Ответить

Вернуться в «LinuxCNC»