Cancel individual objects on the build plate


  • administrators

    I've just completed an initial implementation of the M486 code that Marlin introduced recently. See https://reprap.org/wiki/G-code#M486:_Cancel_Object for the specification. I will be looking for volunteers to test this, in particular on machines with multiple tools, because tool changes that were omitted while skipping the process of printing the cancelled object may need to be executed later.

    The M486 code has the disadvantage that individual objects need to be labelled with M486 commands. AFAIK there are no slicers that do this yet, although some slicers can label objects using comments, and there are Python scripts to convert these labels into M486 commands. So I plan to supplement M486 with the following functionality:

    1. RRF will look for comments in the GCode file that identify the object being printed. It will maintain a directory linking the object number with the object name. The object name is normally the name of the STL file being printed; except that when using S3D you have to use a different process for each object if you want to distinguish between them, so the object label is the process name.

    2. RRF will also record the minimum and maximum X and Y coordinates where which extrusion has been seen for each object, to help with object identification.

    3. The "job" object of the object model shall be enhanced to include the object directory.

    4. This means it will be possible for DWC or another UI to query the object model, list the objects being printed along with their approximate XY centre coordinates, so that a user can select one. The UI would then issue a M486 command to cancel that object.

    Can anyone see a problem with this? I'm aiming it mainly at Duet 2, because more sophisticated approaches will be possible when running Duet 3 with attached SBC.



  • Having been messing with this today... it seems to work well and I think it's going to be really useful!

    In playing, I've noticed an interesting issue with gcode generated using PrusaSilcer so I thought I'd mention it in case it trips anyone else up. I have checked Simplify3D and it doesn't have the issue. Anyway...

    There seems to be a bug in the current version of PrusaSlicer (2.2.0) in that it puts the object labels in the wrong place. In some cases it's not an issue, but if you also use nozzle wipe and cancel an object things can get messy. Logically, a wipe & retract should be associated the end of a loop and a prime with the beginning of the next. However, if you slice 3 objects (for example) in PrusaSlicer here's a snip of what it produces:

    • finishes the last loop on object 1 for the current layer
    • --
    • labels the end of object 1 and the start of object 2
    • performs the wipe then retract for object 1
    • does the travel to object 2
    • primes for object 2
    • starts the first loop for object 2
    • finishes the last loop on object 2 for the current layer
    • --
    • labels the end of object 2 and the start of object 3
    • performs the wipe then retract for object 2
    • does the travel to object 3
    • primes for object 3
    • starts the first loop for object 3
    • finishes the last loop on object 3 for the current layer
    • --
    • etc...

    So the issue is that if you cancel an object, the wipe and retract positions get messed up and you end up with a birds nest above the cancelled object (or elsewhere depending on order). Here's an example output of what happens in this situation - in this case the top right object was cancelled first, then later the bottom left. To be clear that the mess here isn't a problem with the printer or RRF, it's because the slicer got its object labels in the wrong place.

    IMG_20200502_194007.jpg



  • @ChrisP That's good info. Thanks.

    How does Simplify3D handle multiple objects? It doesn't list ID or copy number right? Is it just the process label you are using or does it produce labels for objects when you have multiple models loaded? I guess I could slice something and check...



  • @bot said in Cancel individual objects on the build plate:

    @ChrisP That's good info. Thanks.

    How does Simplify3D handle multiple objects? It doesn't list ID or copy number right? Is it just the process label you are using or does it produce labels for objects when you have multiple models loaded? I guess I could slice something and check...

    Yeh sorry, I should have said I just used @dc42's suggestion to use an individual process for each object. It's not ideal, particularly if you have a large number of objects, but it works. I'm currently using a D3+SBC which as I reported in another thread earlier, doesn't parse labels quite right with PS so I didn't even try the file straight out of S3D. Instead, I used a find/replace in notepad++ to swap process labels for M486 commands and that seemed to work fine.

    The other thing that I did notice with this which may need looking at was that there were occasions where there was a significant pause where the duet was clearly skipping through the code to find the next object. This may cause issues with oozing, but hey, it's pretty neat so far and if we can rescue parts of long prints by cancelling parts, I'd still call that a big win!

    I though it was particularly neat that RRF tracks the x/y coordinates of each object too! Looking forward to seeing how this is all implemented into DWC!



  • For reference for other who might want to try this...

    As mentioned above, yesterday I tried printing files with multiple objects generated in both PrusaSlicer and Simplify3D using object labelling and individual processes respectively to identify the objects on the builds. I found that using un-modified gcode files on a D3+SBC setup failed to identify the objects Post-processing the files to find/replace the labels with M486 commands resulted in both files working as intended (other than PS putting the labels in the wrong place - but that's another issue).

    Today, I setup the system in standalone mode without the SBC and can confirm that both of the un-modified files work as intended.
    I'm currently using the latest firmware/software: 3.01-RC11 | DSF 2.1.3



  • Sorry in advance for what has developed into a long post.... hopefully someone will find it useful or it can be used to improve the object cancellation function.

    @bot I'd be interested to hear how you get on with this if you you try with Simplify. While the results (below) are infinitely cleaner than those from PrusaSlicer (my post above) as the object label comes after the retract, I have since discovered other issues - generally minor & none that prevented the print coming out as expected. In this image, as before, Object2 was cancelled first, then later Object1 was cancelled. The others were left to go to completion.
    IMG_20200503_155222.jpg

    So here are the other issues I found...

    1. Simplify still puts some travel moves relating to the previous object at the start of the current object, so if that previous object has been cancelled, unnecessary travel occurs. In the example gcode below there are 5 lines (line #46-50) of travel at the start of Object4 that relate to Object2 (which was cancelled), then the 6th line (#51) is the correct travel to the the start of Object4. See the orange and purple segments in plot below that shows the unnecessary travel.
      On checking later I discovered that these 5 moves were generated because the "Avoid crossing outline for travel movements" option is enabled. So Simplify isn't being sensible here as its treating these as part of the travel to Object4 rather than the travel required to exit the perimeter of the Object2.
      I don't think there a practical way for RRF to overcome this if "Avoid crossing outline for travel movements", but as the retract happens prior to the travel the only side effect is wasted time due to the unnecessary travel.

    2. Relating to the previous point, I'm seeing that despite there being a F9000 on the first of those travel moves (line #46 & the long part of orange line on the plot) at the beginning of Object4 (from X38.929,Y45.252 to X80.765,Y66.837), the head moves incredibly slowly - indeed, DWC shows that the feedrate is 10mm/s... ie. the F600 from the z-hop on the previous line.
      I then observe the remaining travel commands (lines #47-51 & the small parts of the orange line and the purple line on the plot) in that short sequence go at the full F9000. Its clear to see as it happens at every layer (and similarly on other cancelled objects). I've been looking at this for a while now and unfortunately I'm wondering whether there might be a bug in RRF where the feedrate isn't being updated in the correct place - @dc42? Or maybe there's something I'm not seeing here? Either way line #46 seems to move at F600, not F9000. I can print again and video if needed?

    3. I typically begin all my prints with a skirt. In Simplify3D, when there are multiple processes the skirt for all processes is generated by just one of them - the the bottom image. Since we're using separate processes to distinguish objects, for that one first object that generates the skirt the min & max XY positions that RRF calculates are incorrect as it will be using the bounding box of the skirt instead. After a quick check, the same is true for brims. I therefore wonder if it's feasible to make RRF look for the ; feature skirt comment and de-select whatever object RRF thinks is current? I think that would solve this issue.

    ; process Object1
    ; feature inner perimeter
    ; tool H0.150 W0.430
    --snip--
    G1 X39.198 Y52.512 E0.0078
    G1 X38.924 Y52.350 E0.0085
    G1 X38.794 Y52.260 E0.0042
    G1 X38.525 Y52.030 E0.0095
    G1 X38.340 Y51.840 E0.0071
    G1 X38.142 Y51.597 E0.0084
    G1 X37.798 Y51.060 E0.0171
    G1 X37.626 Y50.715 E0.0103
    G1 X37.479 Y50.360 E0.0103
    G1 X37.407 Y50.144 E0.0061
    G1 X37.312 Y49.859 F1080
    G1 X37.190 Y49.371 F1080
    G1 X37.103 Y48.914
    G1 X37.038 Y48.416
    G1 X37.001 Y47.909
    G1 X37.001 Y47.888
    ; feature infill
    ; tool H0.150 W0.452
    G1 X38.236 Y47.816 F9000
    G1 X41.993 Y47.816 E0.1058 F2160
    G1 X42.293 Y47.816 F2160
    G1 X40.293 Y47.816 E-2.7778 F2160
    G1 E-1.2222 F3000
    G1 Z2.899 F600
    G1 X38.338 Y46.274 F9000
    G1 Z2.599 F600
    G1 E4.0000 F3000
    G1 X39.779 Y43.780 E0.0811 F2160
    G1 X39.929 Y43.520 F2160
    G1 X38.929 Y45.252 E-2.7778 F2160
    G1 E-1.2222 F3000
    
    ; process Object2
    ; feature inner perimeter
    ; tool H0.150 W0.430
    --snip (cancelled object)--
    
    ; process Object4
    ; feature inner perimeter
    ; tool H0.150 W0.430
    G1 Z2.899 F600
    G1 X80.765 Y66.837 F9000
    G1 X80.733 Y66.820
    G1 X80.336 Y66.675
    G1 X80.007 Y66.610
    G1 X79.675 Y66.595
    G1 X79.081 Y51.759
    G1 Z2.599 F600
    G1 E4.0000 F3000
    G1 X78.944 Y51.686 E0.0042 F1620
    G1 X78.775 Y51.570 E0.0055
    G1 X78.541 Y51.366 E0.0083
    G1 X78.355 Y51.156 E0.0075
    G1 X78.203 Y50.953 E0.0068
    G1 X78.060 Y50.724 E0.0072
    G1 X77.960 Y50.536 E0.0057
    G1 X77.787 Y50.159 E0.0111
    G1 X77.710 Y49.957 E0.0058
    G1 X77.603 Y49.622 E0.0094
    G1 X77.524 Y49.322 E0.0083
    

    2020-05-03 (1).png
    2020-05-03.png



  • Excellent post. Thanks for tagging me I enjoyed the read.

    I am not actively experimenting with this, so I have no input myself. I'm actively watching it, though, as I've asked the developers of IceSL to include the necessary changes to allow printer profiles to label objects for cancellation.

    As for your skirt/brim problem with S3D. Let's not go too far catering to S3D's gcode. If they don't manage to get 5.0 out anytime soon, their company is as good as done. I'm very actively looking for ways to move away from S3D totally. We should demand slicers do things properly instead of bloating a codebase to cater to odd scenarios.

    In terms of that last point, cancelling an object on the first few layers is something I brought up in one of these threads as something that would be useful. At the same time, I realize that most use cases would have the cancellation come much farther along into the print, where ignoring or catering to the skirt/brim may not be necessary. However, does the x/y extent calculation when a skirt/brim is present interfere with proper cancellation behaviour?



  • @bot said in Cancel individual objects on the build plate:

    Excellent post. Thanks for tagging me I enjoyed the read.

    Thanks. Unfortunately it's drilled into me to be as complete as possible when documenting features or bugs, so I know I can sometime go on a bit. Glad it was of interest.

    As for your skirt/brim problem with S3D. Let's not go too far catering to S3D's gcode. If they don't manage to get 5.0 out anytime soon, their company is as good as done. I'm very actively looking for ways to move away from S3D totally. We should demand slicers do things properly instead of bloating a codebase to cater to odd scenarios.

    Indeed. I agree that catering too far for S3D's code (or any particular slicer) isn't the right way to go about producing the right output from an input that's fundamentally wrong. However, while like you, I'd love to move away from Simplify (probably to PrusaSlicer), unfortunately for what I use it for both at home and work there's still nothing that comes close to Simplify. Though I do agree that unless they get a new release out soon, they'll be dead.
    edit: it also has to be said that there is already some specific parsing for PS and S3D labels etc, so why not add the functionality to identify skirt/brims and logically separate them from the process tag?

    In terms of that last point, cancelling an object on the first few layers is something I brought up in one of these threads as something that would be useful. At the same time, I realize that most use cases would have the cancellation come much farther along into the print, where ignoring or catering to the skirt/brim may not be necessary. However, does the x/y extent calculation when a skirt/brim is present interfere with proper cancellation behaviour?

    Yes. Everything works as expect otherwise. My main reason for bringing this point up was because I imagine this data will be key to any UI that is made to make object cancellation user friendly. Or automated object cancellation through in-process monitoring.
    From my point of view, I was less interested in the aspect of cancelling a skirt or brim and more interested in ensuring the data that RRF generated was accurate 🙂



  • @ChrisP I wasn't thinking about the UI implications! Definitely warranted to cater to another S3D quirk in that case. As you say, we already cater to many slicers' quirks. Even now, I'm spending a lot of time ensuring that the gcode icesl generates can emulate S3D for visualization purposes and compatibility with firmware which expects such formatting.


  • administrators

    I've now modified the M486 command so that when it is used without parameters, it lists the objects that RRF knows about. There are new builds of RRF with this functionality at https://www.dropbox.com/sh/3azy1njy3ayjsbp/AACquxr2m00eV568RZg5QG5wa?dl=0.



  • Is it worth it to implement this? I think it is literally easier to make sure things stick to the bed than to label all the parts on the print bed individually, especially when they´re duplicates.



  • @NitroFreak There are a lot of things that can go wrong with a print as well as poor bed adhesion. Is this feature worth implementing? I guess that's a decision for each individual user to make. One could say the same about a lot of features. For example, one could argue that it's much better to build a bed that is flat, level and stays that way than it is use to use mesh bed compensation. Personally, that's the approach that I take but there are many more users who prefer to use firmware to compensate for "deficiencies" in hardware. So my take on it is that it's a good thing the features exist even though they may not be for me.



  • @NitroFreak said in Cancel individual objects on the build plate:

    Is it worth it to implement this? I think it is literally easier to make sure things stick to the bed than to label all the parts on the print bed individually, especially when they´re duplicates.

    Yup, in an ideal situation this feature shouldn't be needed, and on a most hobbyist-size systems theres almost no excuse if you're printing "standard" materials.
    Unfortunately if you're printing up to 1000 items in one hit, it only takes one part to fail (and as @deckingman mentioned, we're not necessarily rarely talking bed adhesion issues here) to potentially write off the whole lot. Similarly imagine a bed with just two parts using £200+ of material - I'd rather cancel one to save the other than scrap both. Printing with more exotic material can often increase the chance of failure - I'd have loved this feature back when I was printing PEEK!

    @deckingman said in Cancel individual objects on the build plate:

    For example, one could argue that it's much better to build a bed that is flat, level and stays that way than it is use to use mesh bed compensation. Personally, that's the approach that I take but there are many more users who prefer to use firmware to compensate for "deficiencies" in hardware.

    Indeed. Interesting example - I've no doubt that probing and mesh compensation works well for those that use it, but in the years I've been printing I've never had a need for it (auto-levelling is the first thing I turn off on a new UM3)... I guess the exception is delta calibration.



  • @dc42 said in Cancel individual objects on the build plate:

    I've now modified the M486 command so that when it is used without parameters, it lists the objects that RRF knows about. There are new builds of RRF with this functionality at https://www.dropbox.com/sh/3azy1njy3ayjsbp/AACquxr2m00eV568RZg5QG5wa?dl=0.

    Thanks, this works well! One very very minor thing is that it seems to put an extra space at the beginning of each line from line 2 onwards...
    2020-05-05.png


  • administrators

    @ChrisP, did you run M486 from DWC,.or some other way? There should be a leading space on every line, so that the lines still line up when there are 10 or more of them.



  • @dc42 Yes, I ran M486 from the console tab in DWC. I will try again now just to double check...



  • @dc42 From DWC...
    2020-05-05 (1).png

    It might also be useful to have M486 report what the current object is that's printing...


  • administrators

    @ChrisP said in Cancel individual objects on the build plate:

    It might also be useful to have M486 report what the current object is that's printing...

    Good idea! It's already available in the object model.

    EDIT: except that it might not always be entirely accurate, because the moves in the print queue lag the object tracking.



  • @dc42 said in Cancel individual objects on the build plate:

    @ChrisP said in Cancel individual objects on the build plate:

    It might also be useful to have M486 report what the current object is that's printing...

    Good idea! It's already available in the object model.

    EDIT: except that it might not always be entirely accurate, because the moves in the print queue lag the object tracking.

    Presumably though, the error will only be during travel moves and the first loop of an object then? So it would only be an issue if you happened to get unlucky at the point you queried or if the layer times for objects were particularly small...?

    What would eventually be nice to see is an Objects tab under the Status tab in DWC where the bed area is plotted using the the limit info from config, then bounding boxes of the objects are plotted over that with a list of all the known objects on the bed and the current one highlighted.... dreams of the future 😀


  • administrators

    @ChrisP said in Cancel individual objects on the build plate:

    What would eventually be nice to see is an Objects tab under the Status tab in DWC where the bed area is plotted using the the limit info from config, then bounding boxes of the objects are plotted over that with a list of all the known objects on the bed and the current one highlighted.... dreams of the future

    This is planned.



  • @dc42 any news? I had the possibility in RepetierServer to cancel a object. Was quite nice.

    fc21e60f-6715-43cb-8e77-1532ad762628-grafik.png


  • administrators

    This was waiting for the plugin interface in DWC. That interface has been implemented in DWC 3.2beta1. Now the plugin for object cancellation just needs to be written.



  • Just wanted to add that as the person that originally developed the octoprint plugin and did the initial work for Marlin, I really appreciate the systematic way this has been approached in RRF and documented in this thread. Well done. Now, to "standardize" where to put those object labels relative to wipes/retractions....


  • administrators

    @ppaukstelis thanks for the feedback. The model used for changing tools may also be useful here for slicer writers. i.e:

    gcode that happens before the object starts to be printed on that layer,
    gcode that happens after that layer of the object finishes being printed

    Than can the be tagged with ";Pre-ObjectX" and ";Post-ObjectX"

    Anything in between a "post-ObjectX and a "pre-ObjectY" is not object related (i.e its travel, or a tool change, or a prime etc).

    would that work?



  • I was thinking more in terms of what a slicer considers to be an object. Right now PrusaSlicer/SuperSlicer already have "; stop printing objectX" tags that can be used for termination as you suggest. But as of right now post-object wipes are not considered part of the object, they come after the stop printing comments. This wastes time and movement. Cura uses NONMESH object tags which work fine. However, it defines all supports as NONMESH and not as parts of objects, so you can never cancel the supports along with the individual object.


Log in to reply