kliment / Printrun

Pronterface, Pronsole, and Printcore - Pure Python 3d printing host software
GNU General Public License v3.0
2.38k stars 996 forks source link

Feature Request - Resume Print #383

Open RenaeMacLeod opened 11 years ago

RenaeMacLeod commented 11 years ago

I have run into an issue of a number of very long prints failing because of a print head jam. some of these 1/2 day or longer prints were 95% done which resulted in a lot of wasted plastic. Alternatively, I also envision a long print running out of filament or for whatever reason having to power down the printer during a long print. Ideally I would like to be able to resume a print by moving the print head to the last position it was in when it was properly printing. This is clearly an advanced feature and my hope is that it might be simple to implement.

I'm not sure if it's possible to read the coordinates of the print head so here are two options...

  1. Safely home the print head and then move the print head to the exact position you want to start from. Resume the print and Printrun then finds that position in the GCode and resumes from that line.
  2. Safely home the print head and then move the print head to the exact position you want to start from, keeping track of the distance you have moved it. Resume the print and Printrun asks you what position the head is in and then finds that position in the GCode and resumes from that line.
iXce commented 11 years ago

Hm, isn't this feature already there ? The "recover" button is meant to do that, and there's already a @pause command which is meant to handle such situations too (not sure how it works though)

RenaeMacLeod commented 11 years ago

Seeing that button is what made my mind think of this. My understanding after reading about it is that the recover button is to resolve the issue of the printer printing really slowly after un-pausing it. My thought is for recovering from something catastrophic such as a computer crash, jammed filament while the printer is not being monitored (such as overnight), or moving the printer from an event to the office or vice versa.

I have had 1 crash but mostly I have had failed prints while I sleep (I print a lot of large objects which can take from 12 to 24 hours) that were caused by a number of issues such as bad filament joins hidden in the spool or filament simply jamming in the extruder gear. I come down to see the printer stopped, or even still 'printing', many centimeters above the object.

iXce commented 11 years ago

Hm okai, I've reread the code a little bit. The Recover button is to recover after a hard disconnect from the printer (that is, you had to hit the disconnect & connect buttons to talk to the printer again). Right now the Pause feature is already doing some smart things (that were broken until 51e261805 because of some other changes I had made), which are probably what you want. When you hit the "Pause" button, the current status of the printer is stored. When you then "resume" the print, this status is restored : the print head should go back to the absolute position it was in, and the extruder status and feedrates are restored so that the print can safely continue. So no matter what you have done it between (jogging, extruding...), as long as the printer can physically come back to the same position by itself (if it hasn't lost steps or if you can rehome it to reset to the same absolute 0) the print you are resuming should continue.

Now I feel that the core of your request would be to tell Printrun "the print failed when the head was in position X/Y/Z, find wherever this was in the GCode and start over from there. While this sounds possible, it might not be a trivial thing in practice. To which resolution can you reposition the head ? (I imagine that if you're discovering the print failed at some point when you wake up, you won't be able to backtrack by yourself to the gcode line where this failed, and thus won't have the 10^-3 position the gcode specified) Also, if there are several gcode commands stopping a this point, which should be chosen ?

cdaringe commented 11 years ago

Renae: I agree with iXce. I understand your problem statement--I too have experienced this. I've actually gone as far as repositioning my head as you've described, setting absolute coords via GCODE, then deleting my .gcode file's line 1 thru line ##,### and simply hitting 'print' after setting the temp. It worked pretty dang well! It was a mendelMax plate for a friend. However, it was clearly imperfect and had showed an obvious jog.

The ability to repeatably reposition a head after a failure I believe is so difficult that it may not warrant SW dev activity.

RenaeMacLeod commented 11 years ago

Is the info stored when you press pause accessible? Maybe I can use that as a work-around. I print toys for my kids and pieces to fix broken things around the house. Some of these objects can get large and as you all know a failed print is just wasted plastic. With that being said this is certainly not a high priority by any means, just a thought to reduce the waste where possible.

iXce commented 11 years ago

Yeah, you can inspect by typing e.g. !self.pauseX (or Y, Z, E, F, Relative)

iXce commented 10 years ago

Hmm, so is there anything practical we could do about this ?

cdaringe commented 10 years ago

I suppose that an interactive script could: _Parse the GCODE (from mem or freshly loaded) Go to the max Z, prompt the user if this is the layer to resume on :_if not, drop X many layers (either user specified, or default to 1) :iterate until the desired layer height is found Have the user select the resume line on the GCODE vector map Enable the user to move the head away, resume heating and prime the extruder *Execute

It'd be a project, that's for sure. I'm skeptical if @kliment would permit it to be merged to master anyway.

drf5n commented 10 years ago

Are self.pause{X|Y|Z|E|F|Relative} values accessible through [variable] expansion?

iXce commented 10 years ago

Hmm, there's no such variable expansion for the moment. You can however get them using !print self... and use them, but indeed variable expansion would probably be very useful for this.

ohhmm commented 8 years ago

My thought, its only need to pause print on disconnect instead of stopping it.

nieknooijens commented 7 years ago

Same here, I plugged my laptop into the same power strip as my printer causing a brown-out, the printer still retained it's calibration values but because of the power dip my serial port got redirected to /dev/ttyUSB1, resulting in a disconnect from pronterface.

hexane360 commented 7 years ago

!self.pauseX (/Y/Z/E/Relative) isn't defined for me after I pause: AttributeError: 'PronterWindow' object has no attribute 'pauseX'

Has this hook changed?

In the meantime, I'm just using !print self.current_pos to give similar functionality.

hurzl commented 5 years ago

When you hit the "Pause" button, the current status of the printer is stored. When you then "resume" the print, this status is restored : the print head should go back to the absolute position it was in, and the extruder status and feedrates are restored so that the print can safely continue. So no matter what you have done it between (jogging, extruding...), as long as the printer can physically come back to the same position by itself (if it hasn't lost steps or if you can rehome it to reset to the same absolute 0) the print you are resuming should continue.

So it should be possible to continue after a "Reset Printer" which I need when the printer panicked because the bed temp sensor failed?

andreaskielkopf commented 3 years ago

I do have the same Problem. My Printer did quit a few Jobs after 8 or 9 hours. Then i found some tips (https://www.instructables.com/continue-failed-3d-print/) resuming the Print. I did:

The Print was resumed at the beginnig of the interrupted Layer, and the Part was rescued

Because i had to do this several times successfull i now wrote a smal bash script. But it would be a lot easier if this was included in pronterface. ` Schreibtisch cat /home/andreas/bin/restPrint.sh

!/usr/bin/zsh

_

_ Entferne die schon gedruckten Layer aus einer GCODE-Datei um den Druck fortsetzen zu können

_ @copyright Andreas Kielkopf 2021 given under GPL v3

LAYER=$2 CALIBRATE_Z="G28 Z"

if [[ -z $1 ]] then me=${0##*/} echo echo "Usage: $me filename layer" echo " $me cube.gcode 123" echo " filename is the file whose printing was interrupted" echo " layer is the layer to continue with" echo echo " or: $me filename" echo " $me cube.gcode" echo " show the last Layer in this file" exit fi

DIR="$(dirname $1)" EXT=".gcode" NAME="$(basename $1 $EXT)" SOURCE="$DIR/$NAME$EXT" LAYER=$2

_ Gibt es die Datei ?

[[ ! -e "$SOURCE" ]] && echo "file $SOURCE not found" && exit -2

if [[ -z $2 ]] then egrep -n 'Layer [0-9]*$' "$SOURCE" |tail -n 1 exit fi

_ Gibt es den Layer ?

egrep -n "Layer $2\$" "$SOURCE" || { echo "there is no Layer $2";exit -3 }

_ kommt er genau 2 x vor ?

ANZAHL=$(egrep -c "Layer $2\$" "$SOURCE") [[ $ANZAHL != 2 ]] && echo "we expect 2 lines with 'Layer $2', but there are $ANZAHL" && exit -4

_ Ermittle die Zeilenummer

ZEILE=$(egrep -B1 -n -m1 "Layer $2\$" "$SOURCE") ZEILE1=${ZEILE%%-*} echo "layer $LAYER starts at line $ZEILE1" TOLAYER=$(tail -n "+$ZEILE1" "$SOURCE" |head -n 12|egrep -m1 'G[01] Z') tail -n "+$ZEILE1" "$SOURCE" |head -n 12 echo echo "Command for Z-Layer is: $TOLAYER" echo ZIEL="$DIR/$NAME"_rest"$EXT"

echo "Copy INIT into $ZIEL" echo "(hotend and bed temperature and other stuff)" echo "inserting Calibration of X and Y into $ZIEL" echo { echo "; Try to resume interrupted 3d-print" echo "; (c)2021 by Andreas Kielkopf given to you under GPL v3" echo

dont copy FAN xxx or Motor OFF

head -n 500 "$SOURCE" |egrep '^M[0-9]{1,3}' |egrep -v 'M106|M107|M84'
echo
echo "G21 ; set to mm"
echo "G91 ; add 1mm to Z"
echo "G0 Z1"
echo "G90"
echo "G28 X Y ; calibrate X,Y"
echo "$CALIBRATE_Z ; calibrate Z"
echo "$TOLAYER ; set to Layer $LAYER"
echo "G91 ; add 1mm to Z"
echo "G0 Z1"
echo "G92 E0 ; set E to 0"
echo "G90 ; set absolute positioning "
echo "M83 ; set E to relative Mode"
echo
echo "; Now the rest of the interrupted print"
echo "; *************************************"
echo
tail -n "+$ZEILE1" "$SOURCE"

} > "$ZIEL"

echo echo " *" echo "DONT FORGET !" echo echo "Please clean the hotend manualy" echo "Please extrude some PLA to test the hotend" echo echo "After that you can load $ZIEL into pronterface and start your print"
`

This may be not "perfect", but it saved me from throwing away some of my prints and trying them again from the beginning. One of these prints was interrupted 2 times and was saved this way :-)

volconst commented 3 years ago

@kliment do you mind adding this script to the repository? Did not test it, but like the idea.

andreaskielkopf commented 3 years ago

@kliment do you mind adding this script to the repository? Did not test it, but like the idea.

This script was written by me. I do use it regularly because my printer likes to stop printing ;-( I hereby grant you and all interested users the right to use and distribute this small script under the GPL v3. Feel free to add it to the repository.

Andreas Kielkopf P.S. There may be an other even nicer possibility. Today i noticed that it is possible to scroll back in "print-time" by using ctrl-mouse-wheel. If only it would be possible to:

  1. scroll back (with ctrl-mouse-wheel) to the point where the print stopped (this is often visible because of changing features in one or another layer)
  2. select wehter you would like to calibrate xy, or xyz, or nothing
  3. restart the printing from this selected point in the file with a keyboard-shortcut
volconst commented 3 years ago

@andreaskielkopf , I have also thought about this. Do you know that if you double click on the 3D view, another window opens with a slider for the layers. I think this window can accommodate a button 'Print from here'. Or maybe a checkbox to move the extruder Z position together with the slider. Continuing print from the last visible layer could be possible with a macro and a custom button. Unfortunately reality is a bit more complex - the print may need to be continued from some intermediate point in the layer.

andreaskielkopf commented 3 years ago

I will test this slider when i do my next print :-) In theory it is necessary to resume at the exact position where the print stopped. But in reality this is very different.

  1. Most time i have better results when i restart a complete level. Often the PLA-feed did not stop suddenly, but decreased within some time, and then stopped completely.
  2. Sometimes it is even better to start one level below the point where the print stopped. The PLA there might be under 80% of the specified volume. The hotend does then reheat this layer and presses some additional PLA into it. The excess goes into the inside of the object (or will give a fine line on the outside). the bonding to the already existing print then is very good.
  3. If you find an print broken after a few hours, the print has cooled down to room-temperature. It has decreased the height a little. So it may be necessary to start even 2 or 3 layers below to get a good bonding

So i think it would be sufficient to be able to start on the start of a selected level.

What i do need is the possibility to clean the hotend, and sometimes to calibrate XY or XYZ because i did touch the hotend to clean it. It also would be very nice, if it would be possible to print the first (connecting) layer in slow motion. This would help to reheat the upper layer of the existing print by the hotend.

Is it possible to connect the layer-slider to Z-position of the hotend? This would allow to try to find the right layer by probing. (you can't measure it by hand. I just guess most of the time or try to probe with Z movements until it touches the print. Sometimes i do have to use my script several times to find the right layer)

I do appreciate your work. this program is amazing

andreaskielkopf commented 3 years ago

I did test the 3D-View. But the numbering of Layers seems to differ a lot. After printing the first layer of a print the 3D-View said "Layer 7" and my Script said "Layer 0" which is also wrong. The right Value would have been "Layer 1" My Script tries to extract Layer-Info from Prusa-Gcode (i will have to correct it because the numbering is wrong by 1 or 2

volconst commented 3 years ago

I do appreciate your work. this program is amazing

Thanks, I am a recent contributor.

I did test the 3D-View. But the numbering of Layers seems to differ a lot.

Are you using the rc8? It contains layer counting changes. The layer counting does not try (too hard) to be the same as the comments in the gcode, since they depend on the slicer and thus can contradict to each other or be absent. Slicers have layer/model information that is richer than what is serialized as gcode, so we can't compete (closely follow) with them. I will post here a macro that will start a print from the slider selected layer. This should mitigate layer numbering differences and provide spectacular possibilities to crash your printer head in the object :D As the layer numbering is fluid, one should use for reference the Z value.

volconst commented 3 years ago

@andreaskielkopf , please post feedback in PR #1197