Skip to content

RESET STATE IF NOT USE IN REMAP #4715

Open

Description

@soundlike

While using version 2.9.0-pre0 with the Remap configuration, I encountered a BUG—I am not sure if it still exists in subsequent versions.

If no coordinate system (G54, etc.) is specified in the Abort.ngc remap file, and I issue a G55 command in MDI mode, LinuxCNC correctly retains G55 upon the next restart.

If LinuxCNC is currently using G55 and I trigger an abort, it remains on G55, which is also correct.

However, if I am in automatic mode and start a machining program that contains an error, LinuxCNC defaults to G54.

I have observed the same behavior regarding plane selection (G17, etc.).

In my view, when using remap, the only G or M functions that should be executed—whether during an abort or in other similar situations—are those explicitly defined within the Abort.ngc file.

Activity

  1. soundlike commented on Oct 28, 2026

    @soundlike
    Author

    Good morning at all.
    I have check the patch, but it not can compile on 2.9.0-pre0, the emcTaskStateRestore(); not is declared.

    Can resolve in another fix on 2.9.0-pre0 ?

  2. BsAtHome commented on Oct 28, 2026

    @BsAtHome
    Contributor

    Are you sure you are using "2.9.0-pre0"? That is ancient and a non-stable old target.
    The latest master tag is 2.10.0-pre2 and there are a lot of changes from that tag up to HEAD.
    The latest 2.9 series release is at 2.9.10.

  3. andypugh commented on Oct 28, 2026

    @andypugh
    Collaborator

    What is in the abort.ngc file?
    Note that M2 (And G30) revert to G54.

  4. soundlike commented on Oct 28, 2026

    @soundlike
    Author

    Hi. Abort.ngc , is file remapped in ini file: ON_ABORT_COMMAND = o abort call.
    In onabort file i have -
    G40
    G80
    G90

    NON have origin (G54 to G59.3)

    After star Lcnc, command in MDI G55 and work with G55 active.
    If execute Abort procedure, the Lcnc have again G55 and this is good
    if restart Lcnc the Lcnc have G55 running and this is good
    if read M30 and M2 Lcnc reload G17 and G54
    if start Nc program in automatic and have example limit on program, Lcnc reload G17 G54, but it now are writet in abort file.
    How are in code this automatic reset, i want fix manual this part the code , because i use for now 2.9.0-pre0

    Thanks for support

  5. grandixximo commented on Oct 29, 2026

    @grandixximo
    Contributor

    The fix in #4727 needs the state tags that arrived in 2.9.0-pre1, so it cannot build on 2.9.0-pre0. For 2.9.0-pre0, make these changes in src/emc/task and rebuild.

    If you do this manually, the + are just there to show the lines you need to be adding to your file, the +++ just shows you file path @@ are the line numbers. Otherwise copy and save in a file like fix.patch and apply with patch -p0 -l < fix.patch but I'm not sure that will work as the line numbers may be different.

    --- src/emc/task/emctask.cc
    +++ src/emc/task/emctask.cc
    @@ -173,8 +173,26 @@ int emcTaskHalt()
         return 0;
     }
     
    +// The modes a program starts in.  The interpreter reads ahead of motion,
    +// often as far as the M2 that resets them, so a program that is aborted
    +// gets them back (issue #4715).
    +static int run_g_codes[ACTIVE_G_CODES];
    +static int run_g_codes_valid = 0;
    +
    +void emcTaskSaveRunModes()
    +{
    +    interp.active_g_codes(run_g_codes);
    +    run_g_codes_valid = 1;
    +}
    +
     int emcTaskAbort()
     {
    +    // only an abort of a running program restores the modes it started in
    +    if (emcStatus->task.mode != EMC_TASK_MODE_AUTO ||
    +	emcStatus->task.interpState == EMC_TASK_INTERP_IDLE) {
    +	run_g_codes_valid = 0;
    +    }
    +
         emcMotionAbort();
     
         // clear out the pending command
    @@ -714,6 +732,23 @@ int emcTaskUpdate(EMC_TASK_STAT * stat)
         return 0;
     }
     
    +// put back the plane, distance mode, feed mode and coordinate system the
    +// aborted program started in: the ones M2 resets
    +void emcTaskRestoreRunModes()
    +{
    +    char cmd[LINELEN];
    +
    +    if (!run_g_codes_valid)
    +	return;
    +    run_g_codes_valid = 0;
    +    snprintf(cmd, sizeof(cmd), "G%.1f G%.1f G%.1f G%.1f",
    +	     run_g_codes[3] / 10.0, run_g_codes[6] / 10.0,
    +	     run_g_codes[7] / 10.0, run_g_codes[8] / 10.0);
    +    int status = interp.execute(cmd);
    +    if (status > INTERP_MIN_ERROR)
    +	print_interp_error(status);
    +}
    +
     int emcAbortCleanup(int reason, const char *message)
     {
         int status = interp.on_abort(reason,message);
    --- src/emc/task/emctaskmain.cc
    +++ src/emc/task/emctaskmain.cc
    @@ -2093,6 +2093,7 @@ static int emcTaskIssueCommand(NMLmsg * cmd)
             emcIoAbort(EMC_ABORT_TASK_ABORT);
         for (int s = 0; s < emcStatus->motion.traj.spindles; s++) emcSpindleAbort(s);
     	mdi_execute_abort();
    +	emcTaskRestoreRunModes();
     	emcAbortCleanup(EMC_ABORT_TASK_ABORT);
     	retval = 0;
     	break;
    @@ -2281,6 +2282,7 @@ static int emcTaskIssueCommand(NMLmsg * cmd)
     	}
     	run_msg = (EMC_TASK_PLAN_RUN *) cmd;
     	programStartLine = run_msg->line;
    +	emcTaskSaveRunModes();
     	emcStatus->task.interpState = EMC_TASK_INTERP_READING;
     	emcStatus->task.task_paused = 0;
     	retval = 0;
    @@ -2552,6 +2554,7 @@ static int emcTaskExecute(void)
     	// clear out pending command
     	emcTaskCommand = 0;
     	interp_list.clear();
    +	emcTaskRestoreRunModes();
     	emcAbortCleanup(EMC_ABORT_TASK_EXEC_ERROR);
             emcStatus->task.currentLine = 0;
     
    @@ -3488,6 +3491,7 @@ int main(int argc, char *argv[])
     	    interp_list.clear();
     	    emcStatus->task.currentLine = 0;
     
    +	    emcTaskRestoreRunModes();
     	    emcAbortCleanup(EMC_ABORT_MOTION_OR_IO_RCS_ERROR);
     
     	    // clear out the interpreter state
    --- src/emc/task/task.hh
    +++ src/emc/task/task.hh
    @@ -31,6 +31,8 @@ int all_homed(void);
     int emcTaskInit();
     int emcTaskHalt();
     int emcTaskAbort();
    +void emcTaskSaveRunModes();
    +void emcTaskRestoreRunModes();
     int emcTaskSetMode(int mode);
     int emcTaskSetState(int state);
     int emcTaskPlanInit();

    I could not build 2.9.0-pre0 here, so I checked that the changed files compile and tested the same change on current 2.9 in a simulator: a soft limit error and Abort in the middle of a program keep G55 G18, and a program that ends with M2 still goes to G54 G17.

  6. grandixximo commented on Oct 31, 2026

    @grandixximo
    Contributor

    @soundlike did that fix it?

  7. soundlike commented on Oct 31, 2026

    @soundlike
    Author

    HI Grandixximo, i have apply , the patch , but the problem is the same .
    We don't use M70, M71, M72,M73, i thing this patch is for this use.

    I recall seeing a section in some code file—marked with a "3rd step" comment—where default G-code values ​​are set; this part of the code resets G-code states, even when using iocontrol instead of iocontrolv2. However, I don’t remember which file contained this, and I’m unable to find it now.

    Thanks for support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions