FormerLurker / Octolapse

Stabilized timelapses for Octoprint
GNU Affero General Public License v3.0
637 stars 99 forks source link

Trigger Position Restrictions #40

Closed FormerLurker closed 6 years ago

FormerLurker commented 6 years ago

Add a feature to restrict snapshot positions to certain areas for each trigger. The fences can be either rectangular or circular. Not sure if this would be useful for Gcode Triggers, but I'll put it there anyway to be consistent.

The user should be able to add as many position restrictions as they want. If a snapshot would normally trigger, but the axes are not in the proper place, the trigger will be put into a waiting state until a movement puts it inside one of these 'fences'.

A good bonus feature would be to add another drop down to each restriction that says something like 'allow' and 'prevent'.

This is in-process

FormerLurker commented 6 years ago

This has been implemented, including the newly added 'forbidden' and 'required' types. I have written some tests, and have had success in the virtual printer, but have not fully tested all possibilities on an actual printer. Here are the scenarios for each of the three triggers (timer, gcode, layer/height):

One required position - snapshots can only trigger within the provided shape (circle and rect)

Multiple required positions - snapshots can only trigger within the provided shapes (circle and rect)

One forbidden position - snapshots can only trigger outside of the provided shape (circle and rect)

Multiple forbidden positions - snapshots can only trigger outside of the provided shapes (circle and rect)

Mixed forbidden/required positions - snapshots cannot trigger inside of any forbidden positions. If not in a forbidden position, the snapshot can only trigger inside one of the required shapes (circle and rect).

I'm changing this to 'Needs Testing'

adam6806 commented 6 years ago

I'll give this a test on my mk3.

cabbey commented 6 years ago

This is more a note for when these get documented, something I've learned from experimenting with it.

If the bounding box is too small and the move command passes THROUGH it, without stopping IN IT, then the trigger will not fire.

As an example: say you have a model that is a square, centered on 100,100, with a side of 100, and say it is rotating clockwise as it goes up, 1/4th turn every 10 layers. So every 10 layers up it will have spun back to effectively the same position, the "top" and "bottom" lines will be at 50 and 150. Assume for the sake of simplicity that you are printing hollow, just the outer shell. (in other words, pretend it is vase mode, without the complicated height changes.)

Now, say you set a restriction box from 95,100 to 105,500. So it is 10 wide and stretches from the "center" of the square up through the top, well past any maximum that the square will rotate through. That box is connected to a layer change restriction, and all other restrictions in terms of extruder, axis, etc are disabled.... you are PURELY looking for the print head passing through the box, once per layer.

If that box is rendered with four moves, from corner to corner to corner to corner... it will not trigger on the first layer. Nor the second, third or (probably) fourth. The fifth layer (cube is now 1/2 way rotated, is a diamond with top/bottom points on the 100 line) will trigger a snapshot, as the top point is within the bounding box. Sixth (probably), Seventh, eighth, ninth and tenth layers will not capture either.

(I say probably on the 4th and 6th layers purely because I've not done the trig to figure out if they would land a corner in the capture box.)

On the other hand, if that box is rendered with 80 moves, each 5 long turning every 20, then you WILL capture an image on every frame, as at least one movement command will end/begin within the capture box on every layer. (If this isn't clear, let me know and I'll draw up some pictures.)

Edit to add, you can see the skipped captures in this octolapse: https://cabbey.smugmug.com/Fun/3D-Printing/i-2Lk75Sh/A every time the top of the print jumps way more than 0.2mm per frame... yeah, that's when the lines that made up the vase mode print were longer than the 2mm wide restriction box I had configured for this print.)

FormerLurker commented 6 years ago

I anticipated this scenario, but haven't thought too much about documentation. Maybe I should start that. It is still a cool video.

I was thinking that it would be possible to intercept and add another GCode between any extrusion line that enters the restriction. Not easy, but possible. I'll think about this.

FormerLurker commented 6 years ago

Hey, I'm going to close this out now in favor of issue #76 - Test Trigger Position Restrictions.

Also, I added the intersection detection! It's super Beta right now, but it's pretty neat. Now Octolapse will detect intersections and break the current GCode up into two smaller units so that you're guaranteed to hit the position restriction!

Lastly, what do you think about me moving the restrictions outside of the layer/timer/gcode trigger section so they are all in one place? I'm having a hard time coming up with a reason to have alternative restrictions for the different types of triggers.

cabbey commented 6 years ago

Heh, that solution sounds exactly like what I was thinking of doing! Only concern with the split up is the accuracies of FP math needed to do it... the line may not end up quite as straight or extruded quite as well as it should have if the math isn't super accurate.

I've been thinking about the restrictions change you propose. I think it makes sense. When it comes to snapshots you have a set of events that can trigger a snapshot (layer change, timer, code sensed) and you have a set of positional restrictions, either positive or negative that those triggers need to respect. I think it makes a lot of sense to split them up into separate profiles.

FormerLurker commented 6 years ago

Oh, it's accurate enough. Way past the accuracy of the printer. I tested it with a thin wall test (20mm high, 21.5mm width and depth with a single edge) rotated 45 degrees, and it worked perfectly. I even did a print with absolute E movements and it worked too! There were marks on the print where it moved to take a snapshot, but it was impressively small (I'll post a pic later).

I was able to test with the circular and the rectangular restrictions. Also, I moved the restriction settings out of the individual trigger sections and into the advanced settings at the very bottom. I figured why in the world would anyone want to treat the timer/gcode trigger differently than the layer trigger! It greatly simplifies testing.

Lastly I further improved the extruder calculations. There were some rounding issues in general (not just with position restrictions). This has been basically eliminated down to 5 decimals. There were also some problems switching back and forth from absolute to relative extrusion which I have fixed, among other various improvements. I've been getting GREAT quality recently, especially when using the new position restrictions. Depending on your print, you might be able to make a timelapse with 0 quality impact except a tiny dot on the very top layer! I could add a max-height feature to eliminate that too :)

I'm psyched about this feature. Just have to make it easier to configure. I can't tell you how many times I've messed up just a little bit configuring the restriction. I might add a 'Center' button or something else to assist. I thought about adding an HTML5 canvas that you could click, but I'm not sure the accuracy is high enough. It might be good enough for most cases, however. I might also add a profile for the default prusa MMU wipe tower location. Let me know what you think.

cabbey commented 6 years ago

NICE! I'm going to have to get it back up and running when I can get un-burried from work.

I hear ya on the complexity of setting it up... that's been a real thorn in my side, several prints I've blown the math and put the restriction block in the wrong space. That's what lead to the WBN feature request I filed this morning.

A default profile for where slice3r PE and Prusa Control put the purge block is probably a great place to start. I'd also suggest a default profile for vase mode. Can we get some variables in the positional notation and equations support? :) I'd love to set the box's X1 and X2 as something like "=(width / 2) - 10", "=(width / 2) + 10", then set the Y1 and Y2 to something like "=(depth / 2)" and "=depth". (of course that only works when origin is in the corner.. if origin is centered it's a lot easier.)

Possibly just an html canvas to visualize the plate and where the restrictions are. No need to use it as an input source. If you could get the gcode visualization overlaid on it... even better. :)

On Wed, Mar 21, 2018 at 10:06 AM, FormerLurker notifications@github.com wrote:

Oh, it's accurate enough. Way past the accuracy of the printer. I tested it with a thin wall test (20mm high, 21.5mm width and depth with a single edge) rotated 45 degrees, and it worked perfectly. I even did a print with absolute E movements and it worked too! There were marks on the print where it moved to take a snapshot, but it was impressively small (I'll post a pic later).

I was able to test with the circular and the rectangular restrictions. Also, I moved the restriction settings out of the individual trigger sections and into the advanced settings at the very bottom. I figured why in the world would anyone want to treat the timer/gcode trigger differently than the layer trigger! It greatly simplifies testing.

Lastly I further improved the extruder calculations. There were some rounding issues in general (not just with position restrictions). This has been basically eliminated down to 5 decimals. There were also some problems switching back and forth from absolute to relative extrusion which I have fixed, among other various improvements. I've been getting GREAT quality recently, especially when using the new position restrictions. Depending on your print, you might be able to make a timelapse with 0 quality impact except a tiny dot on the very top layer! I could add a max-height feature to eliminate that too :)

I'm psyched about this feature. Just have to make it easier to configure. I can't tell you how many times I've messed up just a little bit configuring the restriction. I might add a 'Center' button or something else to assist. I thought about adding an HTML5 canvas that you could click, but I'm not sure the accuracy is high enough. It might be good enough for most cases, however. I might also add a profile for the default prusa MMU wipe tower location. Let me know what you think.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/FormerLurker/Octolapse/issues/40#issuecomment-375020404, or mute the thread https://github.com/notifications/unsubscribe-auth/AAf3o30ui8sZ4jSbVGzEqsec0Ve75o6eks5tgoilgaJpZM4SUFYl .

FormerLurker commented 6 years ago

Good idea about the canvas as just an indicator. I already have some javascript for plotting the current X,Y position (unimplemented, but it's there).

Also, that's an interesting idea about the definition of a rectangle. The variables would be difficult to validate, but maybe it's possible. What about some different ways to enter a rectangle? Maybe a width, height and a center point? Maybe both options (two coordinates or a center, length and width)? I'm trying to imagine what the UI would look like for that.

Oh, I thought I'd also mention I'm getting the git wiki filled in. It's a grueling process, but hopefully it will help some folks. I realized I didn't know exactly how some functions behaved until i tried to put it down on paper!

I hope you dig yourself out from under your pile of work! Good luck there!

cabbey commented 6 years ago

I don't see much value to a width/length/center for a rectangle... the current x1,x2,y1,y2 formula is perfectly functional, and fairly common.

I have a couple ideas on how to do formulas. It's not actually too bad to manage as long as we can keep the list of values contained to a sane number. I've written similar code in the past, I can go plug something together and send up a PR.

I saw the wiki show up the other day... writing docs can be far harder than writing code some days. But as you noted, it's not at all uncommon to be half way through trying to explain it in user friendly terms that you realize you don't actually understand how the heck the code you built works!

I've gotta say, you're moving impressively fast on this project.