winder / Universal-G-Code-Sender

A cross-platform G-Code sender for GRBL, Smoothieware, TinyG and G2core.
http://winder.github.io/ugs_website/
GNU General Public License v3.0
1.89k stars 764 forks source link

Shortcut for jogging get stuck #1494

Closed breiler closed 1 year ago

breiler commented 3 years ago

Describe the bug When pressing and holding the keyboard shortcut for jogging it will enter a sort of continuous jogging. Depending on how many commands that have been enqueued it will continue to jog even after releasing the buttons. If we then press stop it will cancel the sent commands but if we still have commands in the GRBL receive buffer these will now be processed and the jog will continue.

To reproduce Steps to reproduce the behavior:

  1. Press and hold the shortcut for jogging
  2. Release the key shortcut
  3. Press stop to cancel the movement
  4. The machine will stop but then start jogging again

Expected behavior The preferred behaviour would be to stop the machine if releasing the shortcut. This is however not possible as the shortcut framework only sends keypressed-events. For this we would need press and release events.

We do however expect that the stop button should stop all jogging commands.

Version UGS Platform 2.0.7

Hardware GRBL 1.1+

Operating system (please complete the following information): N/A

Additional context Discussion here: https://groups.google.com/g/universal-gcode-sender/c/aqrSTgfBSsA

risototh commented 3 years ago

Something similar happened to me few times, except that, that I used the on screen button with mouse. When I released the mouse button, it stopped, and then started jogging again (unfortunately the Z axis down :D ). I thought, that I made something wrong, so I didn't reported it. Sorry...

BTW, Mac OS 10.16

Smoghog commented 3 years ago

I have this same problem. Using the jog movement buttons in the GUI with the mouse stops as soon as I release the mouse button, but trying to jog with a keyboard or gamepad piles up the commands in the queue and keeps the machine moving long after the button is released.

Voxar commented 3 years ago

Same issues here. Happens a lot if I hold the onscreen button for more than 1 second. It slows down momentarily when releasing the jog button but then runs away. I’m running it on a raspberry pi 3.

breiler commented 3 years ago

@Voxar this should not happen if you press the GUI buttons, only the keyboard shortcuts. What version of UGS are you running?

TrevorTighe commented 3 years ago

This behaviour has been seen before. See this thread in gnea/GRBL issue 'Jog cancellation (0x85) not working [Solved]' It seams GRBL has a bug where when the serial buffer is full and a 'cancelling file transfer' command is sent, and while a jog is still being processed, and before the OK comes back from the last jog command. It seams that if UGS waits for the 'ok' from the last jog command before sending the cancel transfer command is sent then everything works as it should. Apparently the UGS sends jog commands every 100ms when in continuous jog mode, so maybe the timing is not exact and GRBL takes longer to send the ok because jog commands are being sent faster than being carried out by GRBL. One user has modified their UGS code to wait an extra 6ms before sending the cancel transfer command and this seams to work. This maybe all that is needed?

The continuous jog function is very useful, so ignoring the problem is not a good solution. UGS can avoid the GRBL bug by waiting for the 'ok' before sending the cancel transfer command. But how long should it wait? Maybe modify the jog command distance to be shorter than that calculated for the 100ms period, then the GRBL command buffer would not fill up during continuous jogging. But then the feed rate will vary while jogging because GRBL will start to decel due to expecting to stop at the end of the current jog command. This change in feed rate may sound strange, but it least it won't run on uncontrollably when you instruct it to stop!

Sorry I do not have the skills to make these changes to UGS code, so all I can do is comment and hopefully suggest possible solutions. To those who spend their time developing UGS (and GRBL), I thank you. I hope this comment helps to resolve this issue.

breiler commented 3 years ago

@TrevorTighe the continuous jogging feature implemented in UGS should take care of the timing waiting for the last command to be processed until it sends a "jog cancel" command. As I understand it, the jog cancel in GRBL will safely decelerate any motion to a stop so there is no need to alter the feed rate from UGS.

If anyone is curious its implemented here: https://github.com/winder/Universal-G-Code-Sender/blob/master/ugs-core/src/com/willwinder/universalgcodesender/utils/ContinuousJogWorker.java

But the continuous jogging feature only works when using a GUI buttons or a gamepad. I know that there was some problems with this implementation in earlier versions but should have been taken care of. If anyone still have this problem when using GUI buttons or gamepad you are welcome to issue a new bug report.

This issue highlights the problem with keyboard shortcuts. The shortcuts can't use the ContinuousJogWorker because the triggering of shortcuts doesn't issue both KEY_DOWN and KEY_UP events. It only issues KEY_PRESSED-events with an interval defined by the OS. So there is no way UGS could know when it should issue a jog cancel when using shortcuts.

The shortcuts will keep issuing jog commands as long as the user holds the shortcut so this bug is likely originated from the issue with the serial buffer being filled and hasn't been processed by GRBL as you mentioned. And the solution is maybe that the jog service should check if there is room in the controller planner before issuing new jog commands.

TrevorTighe commented 3 years ago

I have just done some more experiments. The re start jog problem happens when I have the jog feed rate in the UGS jog screen set much higher than the max allowable feed rate of the axis. So UGS sends jog steps that are greater than what GRBL is capable of in the 100ms time period. So the GRBL plan buffer is filling up due to UGS assuming the axis is travelling at the requested rate.

The only solution for UGS is to make sure it waits for the 'ok' from the last jog before sending the cancel transfer. But this period maybe a lot longer than 100ms if the axis is travelling a lot slower than what UGS thinks it is.

In GRBL I have my X axis max feed rate set to 6000 mm/min and the Y axis set to 2500 mm/min. This is because the Y axis is much bigger and heavier than the X axis. The Z axis of most machines is mechanically different as well. So different max feed rates would be common. To get full speed from my X axis I have the UGS jog rate set to 6000 mm/min. So my Y axis usually suffers from the run away jog problem.

sergei66666 commented 1 year ago

I ran into this problem while testing.

What do you think, maybe as a solution we can start a timer and send STOP if there were no events from the keyboard for more than X ms? For example, if there were no events for more than 50 ms, then we send STOP.

breiler commented 1 year ago

@sergei66666 what should happen if I execute the shortcut once with a jog to increment of 100 mm? Should that be aborted as well?

sergei66666 commented 1 year ago

I'm just getting started with CNC. But if I understand correctly, then the control panels (pendant) stop moving when we stop turning the encoder. It would probably be correct (from a security point of view) to consider keyboard control as a pendant. As soon as we release the buttons on the keyboard, the movement immediately stops.

But there will definitely be people who think it's not right. For them, add a setting that will allow them to work insecurely (run the last command to the end).

But here it is worth considering one nuance. Now the program works as follows: a person pressed a combination of keys, held it for a while, several commands were sent to move (each 100 mm). Even in an unsafe case, all commands should be canceled, with the exception of the very first one. If this cannot be done, then when releasing the buttons on the keyboard, we must always stop the movement. Otherwise, it may lead to collision with obstacles.

Alternatively, you can change the behavior of the program so that the next move command is sent only after the previous one has completed. I do not know for other firmware, but grblHal sends the current status (Jog, Idle and others). This will help determine the end of the current command and send the next one.

Forgive me if I described my thoughts too confusingly.

breiler commented 1 year ago

@sergei66666 thanks for your input. But as I have pointed out several times in this issue report, we don't get an event for when the key is released. That is a limitation of the shortcut framework we are using. We would need to duct tape our own key event listener on top of the existing shortcut listener consuming any shortcut key combination used for jogging.

Your second option is far more easier to implement and would mitigate the acute problem.

sergei66666 commented 1 year ago

Yes, I read your posts about the imperfection of the framework's event system. I am not an expert in Java, but I think that there will be no changes in the framework in the next few years. But in my subjective opinion, by default, the movement should always stop when we release the keys on the keyboard. This will help save a lot of cutting tool :) That is why in the post above I suggested a crutch in the form of a timer that will help fix this problem.

breiler commented 1 year ago

This should be fixed as of #2163