Skip to content

Commit

Permalink
Better m6 macros (#1425)
Browse files Browse the repository at this point in the history
* WIP - Still borken

* WIP

Testing new ideas.

* Update GCode.cpp

* Fix alarm race and unhomed glitch

* M2 and M30 return from macros

* Handle % file delimiters

* Update GCode.cpp

---------

Co-authored-by: Mitch Bradley <[email protected]>
  • Loading branch information
bdring and MitchBradley authored Jan 19, 2025
1 parent 21da0b2 commit 597a4e9
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 29 deletions.
4 changes: 3 additions & 1 deletion FluidNC/src/Channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ class Channel : public Stream {

UTF8 _utf8;

bool _ended = false;
bool _ended = false;
bool _percent = false;

protected:
bool _active = true;
Expand Down Expand Up @@ -180,6 +181,7 @@ class Channel : public Stream {
void push(const std::string& s) { push(reinterpret_cast<const uint8_t*>(s.c_str()), s.length()); }

void end() { _ended = true; }
void percent() { _percent = true; }

// Pin extender functions
virtual void out(const char* s, const char* tag);
Expand Down
27 changes: 17 additions & 10 deletions FluidNC/src/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,13 @@ void collapseGCode(char* line) {
*outPtr = '\0';
return;
case '%':
// TODO: Install '%' feature
// Program start-end percent sign NOT SUPPORTED.
// NOTE: This may be installed to distinguish between program running vs manual input,
// where, during a program, the system auto-cycle start will continue to execute
// everything until the next '%' sign. This will help fix resuming issues with certain
// functions that empty the planner buffer to execute its task on-time.
// Per https://linuxcnc.org/docs/html/gcode/overview.html#gcode:file-requirements
// % only applies to "job" channels like files and macros, not to serial channels
// where the sequence of lines is potentially never-ending. A sender that handles
// files on the host system could apply the % semantics.
if (Job::active()) {
Job::channel()->percent();
}
break;
case '\r':
// In case one sneaks in
Expand Down Expand Up @@ -1613,6 +1614,7 @@ Error gc_execute_line(char* line) {
bool stopped_spindle = false; // was spindle stopped via the change
bool new_spindle = false; // was the spindle changed
protocol_buffer_synchronize(); // wait for motion in buffer to finish

Spindles::Spindle::switchSpindle(
gc_state.selected_tool, Spindles::SpindleFactory::objects(), spindle, stopped_spindle, new_spindle);
if (stopped_spindle) {
Expand All @@ -1621,13 +1623,19 @@ Error gc_execute_line(char* line) {
if (new_spindle) {
gc_state.spindle_speed = 0.0;
}
log_info("Sel:" << gc_state.selected_tool << " Cur:" << gc_state.current_tool);
spindle->tool_change(gc_state.selected_tool, false, false);
gc_state.current_tool = gc_state.selected_tool;
report_ovr_counter = 0; // Set to report change immediately
if (spindle->_atc_name == "" && spindle->_m6_macro.get().empty()) { // if neither of these exist we need to set the value here
gc_state.current_tool = gc_state.selected_tool;
}
report_ovr_counter = 0; // Set to report change immediately
gc_ovr_changed();
}
}
if (gc_block.modal.set_tool_number == SetToolNumber::Enable) {
if (gc_block.modal.set_tool_number == SetToolNumber::Enable) { // M61
if (gc_block.values.q < 0) {
FAIL(Error::NegativeValue); // https://linuxcnc.org/docs/2.8/html/gcode/m-code.html#mcode:m61
}
gc_state.selected_tool = gc_block.values.q;
bool stopped_spindle = false; // was spindle stopped via the change
bool new_spindle = false; // was the spindle changed
Expand Down Expand Up @@ -1894,7 +1902,6 @@ Error gc_execute_line(char* line) {

if (Job::active()) {
Job::channel()->end();
break;
}
// Upon program complete, only a subset of g-codes reset to certain defaults, according to
// LinuxCNC's program end descriptions and testing. Only modal groups [G-code 1,2,3,5,7,12]
Expand Down
14 changes: 14 additions & 0 deletions FluidNC/src/InputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Error InputFile::readLine(char* line, int maxlen) {
}
if (c == '\n') {
++_line_number;
if (len == 0) {
++_blank_lines;
}
break;
}
line[len++] = c;
Expand Down Expand Up @@ -62,6 +65,17 @@ Error InputFile::pollLine(char* line) {
if (_pending_error != Error::Ok) {
return _pending_error;
}
if (_percent) {
_percent = false;
// If the first non-blank line in the file is a % line, it denotes start-of-file.
// Otherwise a % line causes the rest of the file to be skipped, per
// https://linuxcnc.org/docs/html/gcode/overview.html#gcode:file-requirements
// The line with % is not blank, so if it is the first non-blank line
// _line_number will be one more than _blank_lines
if (_line_number != (_blank_lines + 1)) {
_ended = true;
}
}
if (_ended) {
end_message();
return Error::Eof;
Expand Down
2 changes: 2 additions & 0 deletions FluidNC/src/InputFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class InputFile : public FileStream {
Error _pending_error = Error::Ok;
void end_message();

size_t _blank_lines = 0;

public:
// fsname is the default file system on which the file is located, in case the path does not specify
// path is the full path to the file
Expand Down
6 changes: 4 additions & 2 deletions FluidNC/src/Machine/Homing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace Machine {

uint32_t Homing::_runs;

AxisMask Homing::_unhomed_axes; // Bitmap of axes whose position is unknown
AxisMask Homing::_unhomed_axes = 0; // Bitmap of axes whose position is unknown

bool Homing::axis_is_homed(size_t axis) {
return bitnum_is_false(_unhomed_axes, axis);
Expand All @@ -55,7 +55,9 @@ namespace Machine {
set_bitnum(_unhomed_axes, axis);
}
void Homing::set_all_axes_unhomed() {
_unhomed_axes = Machine::Axes::homingMask;
if (config->_start->_mustHome) {
_unhomed_axes = Machine::Axes::homingMask;
}
}
void Homing::set_all_axes_homed() {
_unhomed_axes = 0;
Expand Down
27 changes: 25 additions & 2 deletions FluidNC/src/Machine/Macros.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ Error MacroChannel::readLine(char* line, int maxlen) {
}
line[len] = '\0';
++_line_number;
if (len == 0) {
++_blank_lines;
}

return len ? Error::Ok : Error::Eof;
}

Expand All @@ -117,6 +121,11 @@ void MacroChannel::ack(Error status) {

MacroChannel::MacroChannel(Macro* macro) : Channel(macro->name(), false), _macro(macro) {}

void MacroChannel::end_message() {
_progress += name();
_progress += ": Sent";
}

Error MacroChannel::pollLine(char* line) {
// Macros only execute as proper jobs so we should not be polling one with a null line
if (!line) {
Expand All @@ -125,6 +134,21 @@ Error MacroChannel::pollLine(char* line) {
if (_pending_error != Error::Ok) {
return _pending_error;
}
if (_percent) {
_percent = false;
// If the first non-blank line in the macro is a % line, it denotes start-of-file.
// Otherwise a % line causes the rest of the macro to be skipped, per
// https://linuxcnc.org/docs/html/gcode/overview.html#gcode:file-requirements
// The line with % is not blank, so if it is the first non-blank line
// _line_number will be one more than _blank_lines
if (_line_number != _blank_lines + 1) {
_ended = true;
}
}
if (_ended) {
end_message();
return Error::Eof;
}
switch (auto err = readLine(line, Channel::maxLine)) {
case Error::Ok: {
log_debug("Macro line: " << line);
Expand All @@ -136,8 +160,7 @@ Error MacroChannel::pollLine(char* line) {
}
return Error::Ok;
case Error::Eof:
_progress = name();
_progress += ": Sent";
end_message();
return Error::Eof;
default:
log_error("Macro readLine failed");
Expand Down
2 changes: 2 additions & 0 deletions FluidNC/src/Machine/Macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ namespace Machine {
private:
Error _pending_error = Error::Ok;
size_t _position = 0;
size_t _blank_lines = 0;

Macro* _macro;

Error readLine(char* line, int maxlen);
void end_message();

public:
Error pollLine(char* line) override;
Expand Down
18 changes: 11 additions & 7 deletions FluidNC/src/Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void polling_loop(void* unused) {
// channels to see if one has a line ready.
activeChannel = pollChannels(activeLine);
} else {
if (state_is(State::Alarm) || state_is(State::ConfigAlarm)) {
if (state_is(State::Alarm) || state_is(State::ConfigAlarm) || state_is(State::Critical)) {
log_debug("Unwinding from Alarm");
Job::abort();
unwind_cause = nullptr;
Expand Down Expand Up @@ -449,9 +449,8 @@ static void protocol_do_start() {
send_alarm(ExecAlarm::Init);
return;
}
Homing::set_all_axes_homed();
if (config->_start->_mustHome && Machine::Axes::homingMask) {
Homing::set_all_axes_unhomed();
Homing::set_all_axes_unhomed();
if (Homing::unhomed_axes()) {
// If there is an axis with homing configured, enter Alarm state on startup
send_alarm(ExecAlarm::Unhomed);
} else {
Expand All @@ -465,20 +464,25 @@ static void protocol_do_alarm(void* alarmVoid) {
if (spindle->_off_on_alarm) {
spindle->stop();
}
alarm_msg(lastAlarm);
// It is important to do set_state() before alarm_msg() because the
// latter can cause a task switch that can introduce a race condition
// whereby polling_loop() does not see the state change.
if (lastAlarm == ExecAlarm::HardLimit || lastAlarm == ExecAlarm::HardStop) {
set_state(State::Critical); // Set system alarm state
report_error_message(Message::CriticalEvent);
protocol_disable_steppers();
Homing::set_all_axes_unhomed();
set_state(State::Critical); // Set system alarm state
alarm_msg(lastAlarm);
report_error_message(Message::CriticalEvent);
return;
}
if (lastAlarm == ExecAlarm::SoftLimit) {
set_state(State::Critical); // Set system alarm state
alarm_msg(lastAlarm);
report_error_message(Message::CriticalEvent);
return;
}
set_state(State::Alarm);
alarm_msg(lastAlarm);
}

static void protocol_start_holding() {
Expand Down
12 changes: 5 additions & 7 deletions FluidNC/src/Spindles/Spindle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ namespace Spindles {
spindle->stop(); // stop the current spindle
stop_spindle = true; // used to stop the next spindle
}
if (candidate != spindle) {
spindle = candidate;
new_spindle = true;
if (candidate != spindle) { // we are changing spindles
gc_state.selected_tool = new_tool;
spindle = candidate;
new_spindle = true;
log_info("Changed to spindle:" << spindle->name());
}
} else {
Expand Down Expand Up @@ -134,22 +135,19 @@ namespace Spindles {
return _atc->tool_change(tool_number, pre_select, set_tool);
}
if (!_m6_macro.get().empty()) {
log_info(_name << " spindle changed to tool:" << tool_number << " using m6_macro");
if (pre_select) {
return true;
}
_last_tool = tool_number;
if (set_tool) {
return true;
}

//if (tool_number != _last_tool) {
log_info(_name << " spindle run macro: " << _m6_macro.get());
_m6_macro.run(nullptr);
_last_tool = tool_number;
return true;
//}
}

return true;
}

Expand Down

0 comments on commit 597a4e9

Please sign in to comment.