Dynamic input shaper

After reading through the docs of a klipper fork pertaining to input shaping, and how resonances can be different depending on toolhead position, I got this idea. Adapt the shaper depending on toolhead position.

the main thing is how and when to call it. There are a few options.

  1. every so often with a macro timer. the only issue is this might not be fast enough for some printers, as macro timers only go to 1 sec minimun I think.
  2. every G0/G1 command, this may require overriding G0/G1 as well as checking the position it’s going to, and if it’s relative or absolute.
  3. via a postscript. Might be the easiest as it’s in the Gcode but also will need to be configured per printer, so some start print args are needed.

the only limitation is that it’ll likely only work on CoreXY style, cartesian beddroppers, and Delta kinematics, Cartesian bedslingers, Deltesian, and CoreXZ will likely need something more complex as the bed mass changes.

Delta can likely be separated into 3 zones on the bed for the shaper to change, all at 120 degree intervals near the pillars of the printer, while the other 2 can be separated into a minimum of 4 zones for the bed. While I don’t think this will help with ender 5 sized printers that much unless it’s on something very rickety, larger ones like the 500mm RatRig, Z9V5Max, or Tronxy Veho series might benefit better due to the sheer size of the machine, Deltas have this problem moreso than coreXY machines according to the docs.

I’ll touch on bedslingers tomorrow, it’s 1Am at the time of writing and I’m out of my usual timezone for MRRF

scratch the sleeping part, apparently Jet Lag sets in quickly for me.

Bedslingers will probably need to be adjusted depending on the mass of the bed + mass of the print, or the current frequencies of the Y axis.

so option 1 would require quite a bit of calibration. First you need the resonance and shaper for the bed without anything on it. Then you need to print something on the bed e.g. A 25mm PLA box from prusa slicer, then do the y measurement again, then weigh the cube.

in one example scenario, say the Y axis needs the EI shaper @ 45hz (Ha), without any print on the bed. Then after printing a 25mm cube it changes to 40hz (Hb). We would need to take the weight of the print (g), 5g in this case. and do the following. (Math below)

(Hb - Ha) / g

Which in our case = 1g/hz. I’m aware it’s an extreme example but simple math scales to complex stuff.

more realistically it’d be at least 250-500g before anything noticeable occurs on an ender more than likely, but on printers like the CR-M4, it’d be obvious a bit quicker potentially.

This could also be done with something with a known mass, but it’d need to be stuck to the bed somehow.

the other option would be an ADXL or MPU4020 attached to the Y axis, then adjusting the frequencies from that

an idea would be a “real time” use of the sensor (mpu6050, adxl345), but I have no idea if it’s possible!

the main concern of a printer is its rigidity, the more rigid it will be, the less resonance there will be (finally, the more the rigidity and the mass increase, the lower the resonance frequency will be, the reason for the large industrial cnc which weighs more than 3 tonnes, in addition to the need for dynamic rigidity due to the cutting force, of course, but the principle is the same for parasitic resonances)

therefore a “rigid” printer will be more suitable to have a single resonance setting with the adxl345, the axis guides must also be without backlash, the belts must be as rigid as possible (steel wire reinforced belt) and the structure of the printer must not deform by just pressing on a corner! , you will have better results :slight_smile:

in theory a perfectly rigid printer does not need “input shaping”, but in theory of course :slight_smile:

One challenge with this is that updating the shaper parameters flushes the step generation with toolhead.flush_step_generation(). This can lead to issues when executed frequently every few moves. This can possibly be avoided by setting a fixed step generation window for the lowest expected frequency.

I don’t know for sure not sure about other kinematics, but on cartesian printers it makes little sense to update the shaper parameters depending on the position.
It would definitely be useful on bed slingers as the increasing moving mass can be computed from the position of the E axis. However, this method will only work reliably for prints with a low height-to-width ratio. In the case of tall and thin prints, the mass of the printed object will contribute to its own vibration mode instead of reducing the bed’s vibration frequency.

Minor detail: The frequency scales inversely with the square root of the mass. If the mass is quadrupled, the frequency is halved.
The linear relation would look like 1 / freq² = a * linear_density * E_position + b, where b/a is the inferred mass of the bed + rotor inertia. The linear_density parameter allows to fit the model with one filament and reuse it with filaments of various densities.

Theoretically yes. The print movements contain enough discontinuities to cover a wide range of frequencies, so it should be possible to extract the changes of resonant frequencies in real-time. However it seems quite difficult to do in practice. A frequency domain method will have a large time lag, increasing with the frequency resolution (uncertainty principle). A better method could be analyzing the zero-crossings of the residual vibrations during cruising. I’m just thinking out loud, I could be missing some well-known techniques that allows to do this. In any case, this will likely require some kind of non-linear filtering to integrate the information in real-time, which is notoriously difficult to implement.

If there is indeed value in adapting the sharper frequencies based on the XY position, it would be simpler and more effective to map and calibrate the resonance on a grid and then interpolate from it while printing.

yes a “default” grid like the mesh somehow would be much simpler

in real time I don’t know, that would require computing power for that, on 2 axes, at a high frequency and of course a PID filter, the implementation would probably require an extra cpu just for, I don’t know if an rpi4 could manage a fast double pid at the same time (or if this is simply implantable on the rpi in another process which only returns the “shaper” value in real time and which klipper takes into account in its own calculation, j I have developed servo pid applications, you already need a good fast µC to read the data in real time without lag + the calculations, an stm32F103 might not be enough, the fact remains that you would have to “lay” a well-made code for :slight_smile: and that klipper agrees to receive the calculated values in real time!

I’d have to test it. I plan on writing it into a macro for now, there’s a reason why I opted for just 4 zones, but larger printers will need more areas calculated.

I have 2 possibilities planned out. One would be to detect when a G0/G1 move brings the toolhead into a new zone, but as printers are easily reaching 600mm/s for printing it may have to be a near real-time check. Another option would be via a postscript, but this would require running the g-code through a path simulation.

in either case the rundown is that you would need to run the input shaper tests in different spots on he build plate, and on printers like the 2.4 potentially at different Z heights as well. and depending on where the tool head will move you adjust the input shaper accordingly. This might be more doable on Z than x and y unless you’re doing nonplaner slicing.

I don’t have a Delta printer to do the Delta version, and I’d be running in circles doing it for my SV04 as I would have 2 toolheads to contend with. I’m also at MRRF at current so I can’t really begin dev work yet.

yes but delta style printers have varying resonances depending on tool head position apparently from reading the docs on input shaping.

There’s also the issue of what I can only describe as the ‘skyscraper effect’ with printers like deltas or those who move the gantry on the Z like the 2.4 as a moving mass gets higher from the point of gravity, usually the floor it’'ll shake the structure more, this is the main reason you have counterweights hanging from the top of tall skyscrapers, as the force pushing it around, usually wind, is more pronounced towards the top than the bottom. it’s possible moving the bed down on particularly tall printers, such as the extended Z height VEHO’s can affect the shaper as well. Though I’m not well-versed in this sort of physics to see if it’d be significant enough.

@Piezo

I have yet to test it but it seems some preliminary tests are needed before we consider this. Particularly from those who have large-size printers as I’d imagine ringing would be more pronounced in those printers.

The first test would be to run the input shaper near the 4 corners of a coreXY or ender 5 style printer, and near the 3 pillars of a delta.

2nd one would be to run the test at varying Z heights on a delta and 2.4 style printer, as well as with the bed in different spots on the z axis of standard CoreXY and ender 5 style printers.

3rd would probably have to run the 4 corners/3 pillars test at varying z heights, as it’s possible moving a heavy mass lower down affects the frequencies, but by how much remains to be seen.

my printer has 490*300mm of useful stroke (and 450mm of Z, but that doesn’t matter here) my structure is in profile 2020, and reinforced, it doesn’t move easily, I’m in core XY and the beam main is aluminum and is 550mm long, kevlar belt, I made the “shaping” adjustment in the center up to 150hz, I could do the test on several places to see if there is a noticeable difference!

please do, I’m an MRRF right now so I can’t test this on my printers till Tuesday. It’s possible it’ll be more noticeable in delta printers.

I do have one printer on top of another, Z9V5 on top of Voron Trident, so it’s possible that will affect things. s it might prove useful in a print farm senario

my printer is working at the moment, and I have some urgent piece to finish, normally by Sunday I think I could do the test :slight_smile:

yeah looks like I’m not the first one with this idea. But like mixing hotends until recently, an implementation has never been documented. I’d like to try @dmbutyugin 's input smoother and custom input shaper branches with this but I’m not home till Monday or Tuesday. interpolation might be a bit much though for the processor, which is why I went for the… I guess I can call it a 3d mesh approach.

yes the idea must have been thought of by others, that said it seems the simplest to me, although in practice each 1/10mm can change the value of the resonance (distance, flexion, mass, inertia ratio, etc. very variable) but I suppose this should be sufficient for machines with gantries under 1kg (±600gr in most cases for the entire moving mass)

to reduce the impact, and reduce the need for a “sensor”, it is necessary to reduce the moving mass as much as possible and improve the rigidity of the assembly

otherwise I didn’t know how to do the tests today, too hot in the lab (more than 40°, it’s a veranda…) so I didn’t know how to do anything this weekend :confused:

@nathan22211, yeah, feel free to experiment with this, it would be interesting if you get your idea running. My couple of cents:

  • As already mentioned in the thread above, the input shaper configuration command essentially runs toolhead.flush_step_generation(). This is because you can only change an input shaper when the toolhead is either not moving, or when it is cruising at constant velocity far away from any corners. Otherwise, change of an input shaper will result in an instant change of a ‘commanded’ (after input shaping) toolhead location, which Klipper current step generator cannot handle, and you’ll get stepcompress errors. The latter (crusing far from corners) is difficult to ensure, and in general isn’t always possible to have (e.g. if the model is small and consists of very small moves). Thus SET_INPUT_SHAPER instead flushes the step generation, which also makes the toolhead to stop. I imagine if you want to adjust the input shapers in real time, you’d not want that, as otherwise you’ll get zits on the model where toolhead stopped. So, you’ll somehow need to figure out the dynamic change of the input shaper, which isn’t easy to achieve.
  • Just for completeness, what you can do right now (and it is kind of what’s recommended ATM), is to run a resonance test in multiple points where you expect the input shaping to be different, and then feed the resonance data files for different points for the same axis into the shaper calibration script. Then it will hopefully select the input shaper that’ll work well in all those points. Yes, it’ll probably won’t be MZV or ZV at that rate, probably EI, 2HUMP_EI or even 3HUMP_EI, but then it may work well for the whole print volume without any adjustments needed.

yeah, but no documentation on your custom_shaper branch doesn’t help, I’m not used to sifting through code to find relevant calls for something like Klipper’s config files or crafttweaker’s zenscript

Interesting attitude and wording.
You dig into work-in-progress and / or beta stuff and / or stuff that could completely change anytime or even be abandoned and demand proper documentation?

I’m looking forward to seeing your well laid out and documented development work.

yeah considering I’m not that great at explaining stuff to my grandma, I’m autistic and live with her, probably shouldn’t have remarked that, but then again programming isn’t something I do often.

I’ll have to look at the developer and macro docs for stuff to see if getting this to work is doable, I tend to try to use macros where I can but I feel like this would warrant an extras extension

As @dmbutyugin has pointed out and as far as my understanding goes:

  • The SET_INPUT_SHAPER command is the only command that can be used within a macro, but will cause the tool-head to stop. This makes it unsuited for changing during printing. It is more aimed, e.g. at IDEX printers, where one head needs to stop anyway before the second one continues.
  • The “magic” of input shaping happens deep in the path generation and step compression logic of Klipper, which inarguably is the most critical and complex area of the whole program.

Well I did some tests after managing to get a macro working to do it.


This is with it on every G0/G1 command. It actually caused a massive slowdown in the print, so not ideal.

This is with a macro timer, it seemed to be at my usual print speeds for my reborn 2 but Mainsail was showing 60mm/s on avg but it did jump to the triple digits, could just be the size of the model as well though.

note I stopped both early so I can save this spool for my lack table.

The areas where the model wasn’t well defined are a bit bumpy but I suspect that’s because 1, I don’t have PA tuned for this printer, 2, I was using the ZV shaper to test it so it’s really sensitive, and 3, from looking at the scurve PA branch topic in development, input shaper/smoother can affect pressure advance

@dmbutyugin could use your help here… is it possible to set the X and Y shaper types separately via the SET_INPUT_SHAPER command? I’m trying to calibrate this system for my reborn 2 but I have a different shaper type for Y than X in one spot

Yeah, you should be able to specify

SET_INPUT_SHAPER SHAPER_TYPE_X=... SHAPER_FREQ_X=... SHAPER_TYPE_Y=... SHAPER_FREQ_Y=...

(or SMOOTHER_FREQ_X and SMOOTHER_FREQ_Y for smoothers if you use those).