Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

K40 engraving position does not match cut #577

Closed
andyschmidt opened this issue May 8, 2020 · 20 comments
Closed

K40 engraving position does not match cut #577

andyschmidt opened this issue May 8, 2020 · 20 comments

Comments

@andyschmidt
Copy link

Hi,

I'm using a K40 (M2). I made a template with Inkscape containing engraving and cutting areas.
When running the job, the position of engraving and cutting areas don't match. They are shifted about 1cm in X and Y.

Any idea?

@t-oster
Copy link
Owner

t-oster commented May 8, 2020

can you upload a simple example input file and driver output?

@andyschmidt
Copy link
Author

Here we go ... but where can I get the driver output?
visicut-test.zip

@t-oster
Copy link
Owner

t-oster commented May 8, 2020

File -> Export Lasercode

@andyschmidt
Copy link
Author

Note: I did this without active cutter
visicut-test.lcode.zip

@mgmax
Copy link
Collaborator

mgmax commented May 10, 2020

@tatarize could you please have a look?

@andyschmidt
Copy link
Author

Here a short update. I made some more research on this and it stated out that it's not a problem of engraving. It's a problem of order. So, here's my example:
We just started visicut <- this is important
And we have an SVG with 3 Layers.
I open it in VisiCut and select "Layer Engrave" -> execute 'engrave'
Then I select "Layer Inner" -> execute 'cut'
Last I select "Layer Outer" -> execute 'cut'

It's always the first job which is misaligned. All following jobs are done with the same position/alignment. So it seems that only the first initialization of the K40 starting position is wrong.
I attached all files. I also made Laser Code files for each step. Hope this helps
sample-files.zip

@tatarize
Copy link

  • (Any initial position is considered to be 0,0 and may not be)
  • Layer Engrave
  • Home
  • Layer Inner
  • Home
  • Layer Outer
  • Home

Given the update, that might be right. Visicut didn't have any jogging or positioning controls or realtime command systems. It's one of the reasons I coded up MeerK40t since I could add such things. The visicut system would work really well for protocols like Moshiboard, and GCode systems without any realtime controls.

Designwise, I didn't want to move the laser head when it wasn't needed since I tracked the exact expected position within the driver itself at all times. But, this left an issue that between jobs it wouldn't know where the laser head was actually located. If I left the laser head at (500,1000) and the it sent the next job as a different event it would think it was at 0,0, and would be off by half and inch and an inch respectively.

I solved this by homing after each job. In the lcode file the command "IPP" at the end tells it to home the machine. Visicut seemed pretty geared towards sending all the data to the device and be done with that device. So saving the driver state wasn't an option.

The issue of homing is that the first engrave operation is assumed to be 0,0 and you might have the head moved, either manually or from something else. MeerK40t for example just stops exactly where it finished and stays there, or goes to the next part exactly from that location. Whisperer returns to the upper left hand corner of the part completed (or tries, it's actually off by 2 mils after a raster). The homing only serves to fixed things between objects.

In theory, I could make the driver home the device, draw the part where visicut tells me it is, then make the driver home the device again when done.

  • Home
  • Layer Engrave
  • Home
  • Home
  • Layer Inner
  • Home
  • Home
  • Layer Outer
  • Home

Would look a lot weird, but would ensure whatever the first job is, it started correctly at (0,0).

@tatarize
Copy link

That said, looking at this rastering code I might consider taking another swing at it. I've since mapped out the better way to do it, based on LaserDrw's methods and analysis of the hardware. You can save the state of the stepper direction forward/back toggle on the x-stepper and y-stepper chips and the state of the last executed direction to skip some of these superfluous mode switches. The end result is you get rasters that don't underbuffer nearly as easily. The underbuffer causes a stutter in the machine. Since its constantly just streaming the data at the machine which uses 128 bytes of local buffer, and can burn through those ~4 packets pretty quickly if it's doing some commands like a bunch of turn laser off, move by 1, turn laser on, move by 1, running at a fast speed it can finish all those commands very quickly, and be forced to decelerate. Good command efficiency lets you shove like 50% more commands in there.

Though Scorch took a shot at duplicating that and messed up the states and produced a faulty version of Whisperer.

@andyschmidt
Copy link
Author

From my point of view, homing the laser before and after each job would be a good workaround. Although it would be better, if visicut would be able to provide "realtime" commands, such as positioning or "homing" and also "cancel" a job would be usefull.

@tatarize
Copy link

tatarize commented May 11, 2020

Yeah, that lack of cancel is annoying too. But, since Visicut is made for send it to the laser like operations, and do no monitoring of the job or control of the job. It loses a bunch of stuff. Like there's a realtime pause command for the M2 board. In MeerK40t when you hit escape it launches an adjustments window but also, instantly pauses the job in progress. GRBL also has something similar. But, with the way Visicut's front end is setup, I can't even just suspend packet sending because there's no hook for that. It's only like 4 packets ahead, If I stop sending packets it stops in a couple seconds.

One of my current side projects within MeerK40t is to get Lightburn working through it. So it sits there pretending to be grbl server, I am doing the same thing for RDWorks and pretending to be a ruida device and... I just realized that would also let you run lightburn through MeerK40t. One of my tests on GRBL is to make Visicut control MeerK40t to laser on the M2 by pretending to be a GRBL device. Even with that, since there's no controls inside Visicut you can't do anything fancy with that.

It's like pause, resume, home, unlock rail, lock rail, jog right, jog left, jog top, jog bottom, cancel jog, ±1% / ±10% power, ±1% / ±10% speed, ±1% / ±10% rapid, reset speed to default, and reset power to default. GRBL has some minor other things like mist coolant that's far more for regular CNC stuff. And you can do other things like firing the laser without it moving, but those aren't thing you need realtime commands to do. And most of them will also be able to give status reports. But, the only real status capabilities given to the Visicut driver authors is send some data through the progress listener.

@andyschmidt
Copy link
Author

I really like the visicut gui. Also the best feature is to execute jobs by layers. But there are still too many features missing. I just installed Meerk40t and opened my test file, but I stumbled over the selection of cut/engrave paths. Seems like I have to spend a bit more time on that. But it looks quite powerfull.

@tatarize
Copy link

Yeah, feel free to raise any issues you have with it on the github over there. I too like the visicut gui, for the most part. Visicut's sort of raster everything or engrave everything things are actually pretty nice. Currently MeerK40t is a bit cumbersome in that respect and sort of relies on color-strokes to build out the operations and lets you drag and drop things between them though sometimes has things weirdly too difficult. https://www.youtube.com/watch?v=ikTlH5z2U-0

Good UI is kinda hard to do, especially if you balance it against getting a bunch of weird crazy powerful features in there.

@mgmax
Copy link
Collaborator

mgmax commented May 11, 2020

Regarding "cancel job": I already explained here how this could be implemented in VisiCut. No evil magic involved, just Thread.interrupt() and a button. #399 (comment)

@tatarize
Copy link

In Java the thread interrupt doesn't perform a kill operation directly. You actually just mark the thread as interrupted and the threads themselves have to check if they've been interrupted. It's perfectly doable, but it seems like a real time command channel is more appropriate and kinda less hacky. And could be added to the drivers without needing any of them to actually implement them. And maybe ask for some more information. My driver and the grbl device will, for example, know where the laser head is currently located (or rather where it will be in like 3 seconds in my driver's example), also Ruida has this capability. And other lasers unlock rails like the M2 Nano and Moshiboards. Though with Moshiboards, it uses the same command to unlock the rail also stops the current job in progress so any driver would need to keep pinging for status reports and not allow rail unlocking if not in idle mode.

With GRBL and Moshiboards the entire program might have been written to memory by the time you hit stop, the thread will be finished. But, it sends a command to pause the feed as it's sending. The M2 also has a pause command but since it's really only like 4 packets ahead of the laser you can wait for the buffer to just stop.

@t-oster
Copy link
Owner

t-oster commented May 12, 2020

Maybe we should identify all mechanisms we want for realtime-control (cancel, get current position, unlock rail etc or more general) and then add a new interface which a driver can provide or not. Then VisiCut can have a new Tab with UI for those realtime controls which is only activated when the driver supports it.
But we should start collecting use-cases first.
And we should start a separate issue because this here is clearly a bug report and has nothing to do with visicut's forcus on fire-and-forget jobs instead of being a job-monitoring realtime controller and operator.

However I think at least a cancel method makes sense, so feel free to open a new issue with constructive ideas on how to integrate more control without adding too much complexity.

And as a sidenote: When I created VisiCut there was as far as I know a law which prevented lasercutters from starting a job without physically pressing a button on the device, which is why it was focused on a job based model, leaving controlling to the device itself.

@tatarize
Copy link

There's not that many of them. In fact I've tried to map them out for some work in MeerK40t. A lot of them are covered in GRBL since it's pretty popular and open. And largely has mapped out what people want and given it to them. It's not just the realtime commands but other commands that may fall in sequence that are reasonable laser commands like home. You wouldn't really force a homing sequence while it's processing which is kinda what's needed for realtime. Skip the queue and do that now. But, such mechanisms are clearly needed for pause and resume.

https://github.com/gnea/grbl/wiki/Grbl-v1.1-Commands


Jogging. Basically all lasers have jogging, usually done through moves. This also permits a lot of different alternative command sequences like tracing the job by moving the laser around the outer part of the job, or performing tests.

  • GRBL: this is sent with the whole $J= prefix and is non-mode shifting move codes. $J=X(pos) Y(pos), with a lot of optional gcode flags.
  • M2 Nano: this is sent with some basic commands inside rapid mode. Usually with a I(RLTB)(distance)S1P.
  • Ruida: this is sent as a single UDP packet with the right command prefix something like "d900027f7f7f3170" and the weird 7 bit encoding (unswizzled)
  • Moshiboard: this is send via USB with a complete program packet, in absolute value of the desired end position. 79:13:27:01:00:00:C5:00:00:00:5D:00:00:00:00:0D:25:25:25:25:2D:2D:00:00:00. Where the control codes, 79, C5, 5D, 0D, 25, 2D can vary among the 16 different swizzled forms.

Jogging cancel

  • GRBL also has a realtime reset command for the jogging. This seems to be to stop a fairly continuous motion. ctrl-x sent at anytime, reacts instantly.
  • M2 Nano can issue a soft reset to purge the buffer. Can be sent at most times will purge react instantly.
  • Ruida: I dunno any way to stop a move in process.
  • Moshiboard: could call Stop since the jogs are small programs.

Home

  • GRBL: accepts a $H command and there are a couple G-codes that can do this.
  • M2 Nano: Performs homing when sent "PP" in any single packet. Usually IPP.
  • Ruida: sends a command: d82c
  • Moshiboard: Homing on a moshi is a command that says go to the absolute poisition of 0,0

Unlock Rail

  • GRBL: M18 unlocks and disables the steppers.
  • M2 Nano: Triggered by IDS2P or any command with a S2 value.
  • Ruida: I dunno.
  • Moshiboard: A7 and anything in the command values: '08', '11', '48', '13', '18', '31', '58', '33', '0c', '19', '4c', '1b', '1c', '39', '5c', or '3b'. which is the same thing as stop. During idle this unlocks rail, and while running a programs stops that program. Likely both.

Linger Laser Fire. Sometimes a thing, always scary. This would be used to punch through a board to start with or test fire the laser.

  • GRBL: there is some way to linger the laser in a spot.
  • M2 Nano: IDS1P.
  • Ruida: I dunno if this is possible.
  • Moshiboard: everything is written in these program things and sent A6 and there's nothing for leaving the laser on. Since the control flags cover laser-on/laser-off and a destination.

Soft reset. Halts and resets board without power cycle.

  • GRBL. Explicit and realtime. ctrl-x soft resets the board. Halts the program, throws an alarm.
  • M2 Nano. Sending I will soft reset, must be accompanied by also halting the flow of packets on the driver side.
  • Ruida, again I dunno.
  • Moshiboard: Sends USB command A7xx where xx is '08', '11', '48', '13', '18', '31', '58', '33', '0c', '19', '4c', '1b', '1c', '39', '5c', or '3b'.

Pause/Resume

  • GRBL: Takes realtime commands ! for feed hold. And ~ for resume.
  • M2 Nano: Takes realtime command "P" which pauses. Also "P" which resumes. These must be in different packets.
  • Ruida:
  • Moshiboard:

Information requests.

  • GRBL: '?' status report. This provides information on machine state and current position and some modal information.
  • M2 Nano: Sends the CH341x chip a status request which provides information about CRC errors, low power, mode completion, and business.
  • Ruida: Ruida sends for a lot of information is specific requests DA00xxxx and the requested information index. And the machine responds DA01xxxx. These things include job count, current position in X, Y, Z and U. The min and max power settings, the current set speed, the previous work time, get frame, and a lot more.
  • Moshiboard: Requests are sent via usb with ACxx which is the requested amount of bytes this then advances until it's read this data and then it know the Moshiboard version. It also sends status requests like the M2 Nano since it also uses a CH341x chip. This information contains error information and state information. So idle and working state information.

Speed/Power/Rapid overrides.

  • GRBL: These are explicit in GRBL. It does ±1% or ±10% for speed, power, or rapid movements.
  • M2 Nano: Since the entire file isn't sent on the fly overrides will just involve changing the state of something producing in the information on the fly. If this is a pre-defined egv file that wouldn't be possible. But, it's pretty easy to just tell it to move at a different speed. Though these could take a few seconds to kick in.
  • Ruida: I dunno. There's some buttons for cut scale and go scale.
  • Moshiboard: All moshi commands are a precompiled program, changing speed while running is doubtful and moshidraw has no option for that.

Misc.

  • GRBL: Safety Door, Spindle Stop, Flood Coolant, Mist Coolant. -- Mostly triggers some weird stuff like forcing a safety door alarm, and using coolant for regular non-laser projects or triggering those particular switches on the board that might be reused for other things.
  • M2 Nano: --
  • Ruida: --
  • Moshiboard: --

That should be it for out of sequence non-program mode commands. Basically anything you wouldn't find saved in a file of laser code.

@tatarize
Copy link

GRBL and Ruida also have settings stored internally for a bunch of stuff like speed, and power. GRBL has a bunch of $ commands that can be triggered and changed. ( https://github.com/gnea/grbl/wiki/Grbl-v1.1-Configuration ). While not realtime they are feedback information out of the regular send a bunch of gcode data to a pipe. M2 Nano cannot store any information. The Moshiboard clearly does have an EEPROM hooked up but I have no clue why. Got through a lot of the reverse engineering there but don't have all that stuff sorted.

@t-oster
Copy link
Owner

t-oster commented May 12, 2020

Thanks for this detailed answer, but as already said, please open a new issue/pr and let's focus on the reported bug here.
Is it possible for the driver to just start with homing on job start in order to fix this?

@tatarize
Copy link

Having a think on it, the better solution here, regardless that I tracked the x and y position, is to, rather than home at all, tell the system to return to (0,0) or where the system thinks (0,0) should be.

This would provide a superior solution since it wouldn't introduce what can be slop (pretty small) after a home operation. And would be quite similar to the way Whisperer works. Namely you start and end at the exact same position, always. Then if you have things set correctly, it will return back to the home position perfectly fine. But, if you moved your laserhead you'll end up to where-ever you put your laserhead initially.

It's not going to double-home between jobs. But, can let you move your laserhead and run projects without incurring any serious troubles. Since rather than relative to the real home position for the all jobs after the first, it'll be relative to the start position for all jobs.

t-oster pushed a commit to t-oster/LibLaserCut that referenced this issue May 13, 2020
* t-oster/VisiCut#577 Return 0,0, not Home

Correction for t-oster/VisiCut#577 rather than home returning to true 0,0 we return simply absolute move to 0,0 so if we began this operation at an adjusted position, we maintain that adjustment rather than lose it for subsequent operations.
@tatarize
Copy link

Tested the merged update. Performs exactly as expected and desired. This is a closable issue.

@mgmax mgmax closed this as completed May 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants