G code interpreter ends too early

Moderators: TomKerekes, dynomotion

Post Reply
Juanjo-Lasing
Posts: 25
Joined: Wed Sep 04, 2019 11:56 am

G code interpreter ends too early

Post by Juanjo-Lasing » Thu Mar 05, 2020 7:56 am

Hello everyone,

I am programing an application in .NET with visual studio where I use the G-Code interpreter. We have various cameras in different positions and the axis move to this positions to make different actions. When we need to execute a G-Code, first the motors move the axis to a particular position. When the movement finish, we make zero with all the axis and then we call the interpreter to run a G-Code. When the interpreter has finished, we return to the new zero and then we move back to the original position. All this process works fine except for the return to the original position. For some reason, the movement finish before the axis reach the position.
I am using the example SimpleGCodeWPF as reference.

Debugging the code, I can tell that the Interpreter_InterpreterCompleted event is sent before the G-Code is really completed and the variable ExecutionInProgress changes before it ends. I am waiting until the variable ExecutionInProgresss is false and then make the return movement but, since ExecutionInProgress changes to false before the interpreter finish, the return routine starts too early. Of course, until the G-Code ends the return movement doesn’t start, but it seems like that doesn’t matter and it start to count movement too early and that is why the motion isn’t enough to reach the destination. I tried this routine but without running G-Code and works fine.

This is a simplified code:

Code: Select all

 
private void RunGCode() 
{
KM.SetUserData(70,1); //this will be equal to zero when the movement ends.
KM.ExecuteProgram(1, CFileMovement1, false); //move to the a concrete position, then put persistUserData[70] = 0
while (KM.GetUserData(70) == 1) ; //wait until the movement ends
 
KM.ExecuteProgram(1, CFileZero, false); //make zero with all the axis
 
ExecutionInProgress = true;
KM.CoordMotion.Abort();
KM.CoordMotion.ClearAbort();
 
KM.CoordMotion.Interpreter.InitializeInterpreter();
            
KM.CoordMotion.Interpreter.Interpret(GCodeFile.Text);  // Execute the G-Code
 
while(ExectionInProgress) ; //ExecutionInProgress
//Thread.Sleep(5000);
 
KM.SetUserData(70,1); //this will be equal to zero when the movement ends.
KM.ExecuteProgram(1, CFileMovement2, false); //move to the a original position, then put persistUserData[70] = 0
while (KM.GetUserData(70) == 1) ; //wait until the movement ends
}

Of course, I have this in the code too:

Code: Select all

static void KM_ErrorUpdated(string message)
{
MessageBox.Show(message);
}
 
static void Interpreter_InterpreterCompleted(int status, int lineno, int sequence_number, string err)
{
if (status !=0 && status != 1005)  MessageBox.Show(err);  //status 1005 = successful halt
ExecutionInProgress = false;
}
 
private void AddHandlers() //I call this when Initialize the application
{
//Set the callback for Errors
KM.ErrorReceived += new KMotion_dotNet.KMErrorHandler(KM_ErrorUpdated);
 
//Set the Interpreter's callbacks
KM.CoordMotion.Interpreter.InterpreterCompleted += 
new KMotion_dotNet.KM_Interpreter.KM_GCodeInterpreterCompleteHandler(Interpreter_InterpreterCompleted);
}
A example of G-Code could be something like this:

Code: Select all

F60 
#1 = 0 
#2 = 0 
#3 = 2

M98 P1 L[#3]
G0 X0 Y0 Z0 
M2 

O1 
G0 X-0.1833 Y-0.5564 Z[#1*#2]
G1 X0.0196 Y-0.5564
G1 X0.0196 Y-0.8116
G1 X-0.1833 Y-0.8116
G1 X-0.1833 Y-0.5564
G1 X-0.1833 Y-0.8116
G1 X0.0196 Y-0.8116
G1 X0.0196 Y-0.7916
G1 X-0.1833 Y-0.7916
G1 X-0.1833 Y-0.7716
G1 X0.0196 Y-0.7716
G1 X0.0196 Y-0.7516
G1 X-0.1833 Y-0.7516
G1 X-0.1833 Y-0.7316
G1 X0.0196 Y-0.7316
G1 X0.0196 Y-0.7116
G1 X-0.1833 Y-0.7116
G1 X-0.1833 Y-0.6916
G1 X0.0196 Y-0.6916
G1 X0.0196 Y-0.6716
G1 X-0.1833 Y-0.6716
G1 X-0.1833 Y-0.6516
G1 X0.0196 Y-0.6516
G1 X0.0196 Y-0.6316
G1 X-0.1833 Y-0.6316
G1 X-0.1833 Y-0.6116
G1 X0.0196 Y-0.6116
G1 X0.0196 Y-0.5916
G1 X-0.1833 Y-0.5916
G1 X-0.1833 Y-0.5716
G1 X0.0196 Y-0.5716

G0 X-0.1833 Y-0.8116
G1 X-0.1833 Y-0.8116
G1 X-0.1833 Y-0.5564
G1 X-0.1633 Y-0.5564
G1 X-0.1633 Y-0.8116
G1 X-0.1433 Y-0.8116
G1 X-0.1433 Y-0.5564
G1 X-0.1233 Y-0.5564
G1 X-0.1233 Y-0.8116
G1 X-0.1033 Y-0.8116
G1 X-0.1033 Y-0.5564
G1 X-0.0833 Y-0.5564
G1 X-0.0833 Y-0.8116
G1 X-0.0633 Y-0.8116
G1 X-0.0633 Y-0.5564
G1 X-0.0433 Y-0.5564
G1 X-0.0433 Y-0.8116
G1 X-0.0233 Y-0.8116
G1 X-0.0233 Y-0.5564
G1 X-0.0033 Y-0.5564
G1 X-0.0033 Y-0.8116
#2 = [#2 + 1] 
M99 
This is a rectangle filled with a small pitch, repeated 2 times moving Z axis between each time.

If I wait enough time before executing the return movement (with Thread.Sleep(5000)) this works fine, but this isn’t a solution at all because the G-Code will be different each time (and probably bigger). I need to be sure that the G-Code has truly finished before return to the original position.
Any idea of how can I solve this?

Thank you.

User avatar
TomKerekes
Posts: 2529
Joined: Mon Dec 04, 2017 1:49 am

Re: G code interpreter ends too early

Post by TomKerekes » Fri Mar 06, 2020 3:37 pm

Hi Juan,

I don't see anything wrong with your code and I replicate the issue testing with SimpleGCodeWPF.

What Version of KMotion are you using?

You might try debugging inside the C++ library.


After the GCode Interpreter finishes the file, DoExecuteComplete should be called which should then call ExecutionStop, but only if there are no errors:

Code: Select all

int CGCodeInterpreter::DoExecuteComplete()
{
    if (!CoordMotion->GetAbort() && !CoordMotion->GetHalt() && CoordMotion->ExecutionStop())
.
.
.

Then ExecutionStop should call WaitForSegmentsFinished as shown below which should not return until all motion is completed. Then the callback to your callback should occur. Set a breakpoint at WaitForSegmentsFinished and verify if it is being called.

Code: Select all

int CCoordMotion::ExecutionStop()
{
    // commit any segments waiting to potentially be combined
    if (CommitPendingSegments(false)) return 1;

    if (m_Abort) return 1;

    if (!m_Halt)
        if (FlushSegments()) return 1;

    int result = WaitForSegmentsFinished();

#ifdef DEBUG_DOWNLOAD
    CloseDiag();
#endif

    return result;
}
Regards,

Tom Kerekes
Dynomotion, Inc.

Juanjo-Lasing
Posts: 25
Joined: Wed Sep 04, 2019 11:56 am

Re: G code interpreter ends too early

Post by Juanjo-Lasing » Mon Mar 09, 2020 7:40 am

Hi Tom,

I tested the process and found that I changed the ExecutionInProcess variable in another part of the code myself. I fixed it and now it's working.

Anyway, what I don't understand is why, while a GCode is running and I try to move the axes at the same time, the movement "counts" even if the system doesn't respond until the GCode is finished. I assumed it would be ignored or would moved at the same time as the GCode is running.

Anyway, I was able to find the problem and I fixed it, which is the important thing.

Thank you for your time Tom.

User avatar
TomKerekes
Posts: 2529
Joined: Mon Dec 04, 2017 1:49 am

Re: G code interpreter ends too early

Post by TomKerekes » Mon Mar 09, 2020 6:43 pm

Hi Juan,
what I don't understand is why, while a GCode is running and I try to move the axes at the same time, the movement "counts" even if the system doesn't respond until the GCode is finished. I assumed it would be ignored or would moved at the same time as the GCode is running.
Commanding a Coordinated Trajectory and an Independent Trajectory at the same time will cause indeterminate results as the axis can't be two places at the same time. Probably the last commanded will prevail and depend on open loop or closed loop what will happen.
Regards,

Tom Kerekes
Dynomotion, Inc.

Post Reply