Mountain Bike Reviews Forum banner

Programmatically optimize shim stacks

1 reading
18K views 59 replies 15 participants last post by  jsma09  
#1 ·
I'm getting more interested in damper tuning, which naturally led me to the ReStackor software. While it represents an amazing body of work, the interface feels a bit flipped on its head to me as a newcomer. As it stands, you manually manipulate the shims in a stack and it plots shaft velocity by kgf, and a whole slew of other information. You are left to guess and check, though the checking is quantitative, as opposed to a butt dyno.

I'd rather define the force response curve I'm interested, or be able to say something like, "I want 25% more kgf at shaft velocity X," and then it spits out the stack that meets your needs. I think this is possible when you pair the models developed by the ReStackor author with machine learning optimization tools. You define the search space of shim count, thickness, and position, and let the algorithms mull it over. The barrier for entry to this is pretty low these days with tools such as hyperopt.

Before you can get to the optimization steps, we need tools to programmatically interface with ReStackor. I've written a function in R that takes as input a data frame of shim widths and thicknesses, then runs ReStackor based on these values, and finally saves the output to a location of your choosing. Even if I fail at pairing it with an optimization strategy, these tools could be useful for rapidly analyzing several stacks at a time.

Image
 
#3 ·
I like where you are going.

But I thought you needed to model the pistons with port size, shape, etc before ReStackor spit out any accurate information. Even the basic Charger pistons are not just pucks with some holes in them.

Is there an mtb piston library for ReStakor?
These are things that, for our purposes, must be measured empirically, and that you provide to Restackor, but would remain unchanged when testing shim stacks. The script I linked earlier updates the Restackor.xls with this information here. In this example it only updates 2 parameters, but you can populate all the piston properties, or anything you want to alter from the ReStackor defaults, but wish to remain static during stack optimization. To update this information you supply: piston parameter value, and the correspond row and column in the .xls file, in that order. Honestly, I haven't investigated these piston parameters myself, but have plans to measure them for the charger 2.1, unless somebody has these on hand and can supply them?

Finally, I would point out that optimal piston parameters are also something that could be explored with these tools.
 
#4 ·
Nice work. Huge amount of setup to make it accurate though and goal-seeking algorithms require you to accurately define the goal. Which is the hardest part of all.

Because ultimately if you can fully define the goal then you have solved the problem already.
 
#5 ·
Thanks, I think the near term objective would be to target a few linear damping profiles differing in force/velocity slope. This in my mind is the lowest bar, but we'll see. You could come up with a library and folks could choose how much force the want to max out at.

One thing to check is if variation in the piston/port parameters influences all stacks in the same way. That would be nice, as the stacks might still be relevant relative to one another if you don't have accurate measurements of the piston. My suspicion is that assumption won't hold.
 
#7 ·
This is a real nice thought. Of course Dougal raises the big picture issue!
I think there are two fundamental questions that must be answered to achieve suspension bliss:
1) What damper response do you like?.. the elusive goal Dougal mentions.
2) How do you achieve it?

I think Restackor helps to answer both questions. In the context of Charger 2.1, we know that we need more damping, but how much more? Restackor can help you get quantitative, but if you want to test 50% more damping across the board, or at a specific range of shaft velocity values, how long are you going to sit in front of an Excel spreadsheet to get there?

This is how I'm trying to hasten the process. With this interface you can get there more quickly, which in its present form can enable thousands of shim stack trials in a short among of time, and it will spit out the stack producing the best fit to your target line. On my machine running the Restackor executable requires maybe 2 seconds, so in an hours worth of time I could explore 1800 candidate stacks in an hour on a single core. If I set it to run overnight with a 28-core machine, I could run a ~ million trials. Brute force grid search might be a viable option, given the trivial compute costs.

However, if the goal is to use that optimiser library thing then why not write the whole ReStackor interfacer code in python?
Yes, Python makes sense if you are going to use Hyperopt or Optuna. The fact is that in my day job, I am a data poor ecologist and my colleagues are afraid of methods developed after 1999. So, I'm saddled with the linear modeling paradigms most days, and R shines for this task, as well as data viz and reporting with markdown docs. I use Python for a handful of ML tools primarily, but the process is a little slower for me using purely Python, because I'm not as familiar with what libraries are out there. For example, XLConnect package in R allows you to edit xls docs in place without destroying them (a key requirement here without having to get invasive in the Restackor code); is there a Python analog?

Currently, I'm just trying to get a prototype going to see if further investment is worthwhile, and I can do this quicker in R. And, as mentioned earlier, I think brute force grid-search or random search could pan out, and R and Python are equally suited for this task.

Speaking of defining the hyperparameter space, I'm thinking of something like this:

Face shim count: 1 to 10 (face shim widths are fixed, and damper dependent)
Face shim thickness: 0.1, 0.15, 0.2
Additional stack count: 0 to 10
Additional stack thickness: 0.1, 0.15, 0.2
Additional stack starting width: 9 to (Face width - 1)
Additional stack ending width: 9 to (Face width - 1)
Additional stack profile: concave, convex, linear (alternatively, could just have shim width step-down increments)
Clamp shim width: 4 to 18 (less sure of sensible range)
Clamp shim thickness: 0.1, 0.15, 0.2, 0.4
 
#8 ·
I think it can be an extremely useful tool when you have a defined piston geometry, know the damping goals and need to know what configurations your available shim kits can do.

You'll need to be able to carefully setup limit rules for available shim sizes etc.
 
#9 ·
As much as I like optimization tools like this in design/analysis somewhere, this might be a lost cause. As mentioned above, once you can accurately describe what "correct" is, building a system to support that performance is pretty well documented, especially in ReStackor threads elsewhere. Getting a picture of that "correct" setting requires something more personal/tangible, and preferably on-site high-speed camera work. Also, once you have a profile for the forces that you want to achieve, you have to go through some practicalities of building the system, like durability considerations, stack height considerations, etc etc. Then there's the whole pressure balance issue and making sure your stationary valve is doing it's job in conjunction, and in proportion, with the moving valve. My gut feel on it is that those are fine-touch iterative parameters that would likely be garbage in some way if generated by some linear regression code.
 
#11 ·
#16 ·
I've been chipping away at this and learned a lot. Turns out modifying the Excel file was not the way, but instead you need to edit the Stack.in text file. I've gathered the last remaining estimates for the port dimensions and other damper properties for the Charger 2.1, and have put them up on a Google sheet here. If you see anything weird about those numbers, let me know. One of the functions I've written pulls data from that sheet, and we could populate it with other dampers if you'd like to contribute to the project.

I set up an experiment with the stock Charger stack and an example candidate stack. Results below. About ready to run a much larger set of trials and look forward to sharing what I find!

Image

Presuming you have Restackor Pro, you can reproduce these results here. I'll have docs up for the library of functions I'm writing, but take a peak at the code here.
 

Attachments

#17 ·
I have the first batch of results, exploring ~2.6k stack configurations for a Charger 2.1 Ultimate base valve. All of these are single stage at this point. I don't expect outcomes to be a surprise to those in the know, but this was more of a data-driven, self-teaching tool to understand how this stuff works.

I varied shim count (2 to 12), final shim width (10:18), stack profile (flat, concave, convex, and more nuanced variations), and clamp width. I did not explore thicknesses, shims are all 0.1 mm and the clamp is 0.4. I tried messing with clamp thickness early on, but this tended to make ReStackor grumpy when varying from stock dimensions. Here are some of the outcomes with clicker at 9 clicks out/middle:
Image


Stacks start to show there true colors after 2 m/sec. The more insane force values correspond to the large clamp widths (especially beyond 12mm):

Image


I was curious how the shape of a stack (flat, concave, or convex) interacted with shim count. I generated various stack profiles with the shaping parameter of the Weibull distribution, which reduced the search space versus other options. Not a whole lot going on, but a few interesting things occur as you add shims (just looking at an 8mm wide clamp):
Image

You are stuck with a digressive curve for stacks of 5 shims or less (among single stage options). Something magical happens at 6 shims, where a more tapered stack gives you a more linear force response beyond 3m/sec. Beyond 6 shims all configurations become comparatively linear. I'm currently running a tapered stack with 7 shims, and like it a lot with LSC dial set to 12 clicks out (sitting at 210 riding weight). Probably will bump it down to six shims in the near future.

Next steps will be to develop an interface to filter through these. You could set max shim count, or include/exclude based on available shim dimensions on hand. Finally, I'm thinking up ways to draw a desired profile and find a stack that matches it from the database.

Here is how I did all of this. The code is for running it on Unix systems with wine, but if you want to run it on Windows, just comment out lines 3:5. Here is the code for the plots.

Thanks to Dougal for sharing some of the damper geometries!
 
#18 ·
Nice work. As you can see, things get out of hand quickly with the wrong tune. I think 5-6m/s is a safe cutoff for an MTB fork. But look at the progression between that and the ~1m/s that other tuners seem to think is all that matters!
 
#21 ·
I was curious what influence HSC preload had on the stack I'm running. Up front caveats: I'm using the stock LSC needle geometry provided by ReStackor and not sure of the correspondence between HSC clicks and preload. I ran preload values at 0 to 8, however, at 2mm intervals. Anyone know the true rate at which clicks increase preload?

It's really interesting to see how much of an effect LSC clicks have on higher shaft velocities. Kind of feels like a misnomer after studying these.
Image

Image
 
#23 ·
Getting closer to the dream of "drawing" a curve and finding the stack that matches it. You specify a set of points you want to hit (red dots below) and the functions finds the top n stacks that are closest from a database of stacks as demonstrated here. The fit part is pretty challenging, and there is room to improve the definition of this. But for lack of something better I've been using MAPE.

Many fit metrics prioritize errors of high values over low ones (mean squared error, etc.), but the force generated from small bumps is as important as that of big ones, IMO, so MAPE for the time being.

Another thing-I wasn't able to find as many linear options with single-stage stacks, and I've been exploring the two-stage realm (more on this in 40 hours; I'm through 3k of 27k two-stage stacks). Here are the current top three outcomes from a target of 2 kgf at 1.25 m/s, that increases ~linearly to 20 kgf at 6 m/s with clickers in the middle:
Image


Weird how squirrely stack 3 gets. I don't think I'm going to be able to hit the 1.25 m/s target without opening the LSC a click or so. This might be softer than most people want anyway.
 
#24 ·
I think doing “peak force matching” would give you a target in a more reasonable range. This is discussed in reStackor application example of compression damping.

Damper force is maximized in the initial portion of the stroke, and spring force is maximized at the deepest point with zero shaft speed thus zero damping force. Let’s say bike+rider+gear = 90kg, and the static seated fork sag is 20% with 40/60 weight distribution.

The fork bottom out spring force = 90 /20% *0.4 = 180kgf at your max shaft speed, say 6m/s. As a sanity check, a linear stack will give us 30kgf @ 1m/s. Based on the dyno plots in Tuesday Tune 32 Steve put out for Fox 38 and VVC GRIP2, this is between the gen1 GRIP2 and RC2 maximum damping force at 1m/s.

This method scales with rider weight, and the aggressiveness of rider would influence the static seated sag percentage.
 
#25 ·
That makes sense to me, however what I’m shooting for right now does not include damping effects of the midvalve. All dyno plot results reflect both systems, base and mid, in concert, where what I’ve been representing is a model of the base valve in isolation. At best it allows for comparison of one stack with another. This might not be suitable for a suspension shop, but for a hobbyist, it might still have some use. What I find surprising is that the Voraprung Grip 2 dyno data are reporting two orders of magnitude more kgf for values below 1 m/s velocities versus the Restackor data I’m getting. Two different dampers, but shouldn’t they be in the same ballpark? Seems very unlikely that the midvalve would be making up the difference.

Given how little variation I’m seeing from stack to stack at low velocities, I’m guessing I cocked up measurements of bleed port diameter. Or maybe the stock needle geometry is not a good enough estimate.
 
#26 ·
Thanks for explaining mid valve is not modeled here. However, pressure drop over mid valve is actually limited by the pressure drop over base valve and the IFP/Bladder pressure build up, otherwise cavitation will happen. Mid valve can only provide a fixed damping curve down to the point base valve is too soft causing cavitation.

Assuming “pressure balanced” base-valve and mid-valve, the damping force ratio between them is proportional to the sweep area and shaft area. I don’t know the mid-valve geometry, but let me use the base valve geometry as an example. 17.4mm valve diameter with 10mm shaft diameter gives us a ratio of (17.4^2-10^2)/10^2 ~ 2. So mid-valve force is bounded to be less than 2x base valve, assuming it’s tuned to avoid cavitation.

Perfectly linear stack with a specific force-speed target may not be in the solution space defined by the existing valve geometry. That’s why most mod kit goes beyond shims. Closing the bypass completely will definitely deviating from a linear shim, but may get you closer to the force-speed target.

Your modeled force is similar to the VVC GRIP2 in Steve’s video, and matches with Dougal’s general comment that both RS and Fox dampers are similarly and strangely weak nowadays.

I am just a fellow MTBer relaying info already explained on restackor website. I read enough to feel confident participating in such discussion, but decided to just trust Steve and ride my Fractive tuned 34 without spending time modeling the damper. It’s great to see your effort here.
 
#27 ·
I still don't understand the interaction between base and mid valve and will need to read over the ReStackor docs more closely. I assumed the forces from both valves were additive, but your post has me doubting this. So, bottom line, I'm not currently able to achieve the peak force matching you described, because I don't have the capacity to account for mid-valve contributions. I still think there is value though in comparing the relative forces generated from two or more base-valve stacks, and this is what most of the hobbyist here appear to be doing. The fact that ReStackor has you pick one valve at a time for which to model force values suggests that this is also done at the professional level.

In addition to mid-valve related mysteries, I notice that the Y-axis in the 38 Tuesday Tune is N, not kgf. That helps my y-axis problem a little. I wonder if it is the case that the free bleed circuit is closed for the max force value? I've been running simulations with the clicker in the middle, but it occurs to me that if you are trying to display the maximum forces for a given velocity, you would want no free bleed.
 
#28 ·
I assumed the forces from both valves were additive
Pretty sure they are but the stiffness of the mid valve is limited by the stiffness of the base valve. Consider the limiting case where the mid valve is actually a solid piston and you can see that it must cavitate on compression or not move at all. If the mid valve is sufficiently more stiff than the base valve then the pressure between the base valve and mid valve will not open the mid valve and again you have cavitation.

So you can infer some information about your abstract mid valve from your base valve model.

I think that's how it works anyway.
 
#29 · (Edited)
I have no idea what you're doing, but I do know that I'd love a program or app where you could put in some values of the stock setup, tell it your weight, desired ride characteristics, and have it tell you the general ballpark of a stack to achieve it.

I know that'll never supplant a professional tuner's work, but for easy to crack dampers (lack Manitou) it might allow more garage geeks to get closer to their ideal tune without sending off the fork.
 
#30 ·
Let me try to address some confusion I caused.

1. Yes, they are additive, but only till cavitation happens (which should never happen in a well designed/tuned damper). Strange things happen when there is cavitation. Solid piston is a good mental picture as mentioned earlier.

2. Mid valve cavitation or not highly depends on the base valve, so it has to be analyzed after base valve is settle.

3. The mid valve sweep area/ rod area ratio gives you the upper bound of force mid-valve can generate without cavitation, so take this into consideration when you choose your base valve target force-speed.

4. Practically, most MTBer wants some on-the-fly tunability, which is only possible through the base valve. Thus, mid valve has to properly function under the softest possible base valve setting considering both preload and bleed. This severely limits how much force mid valve could provide unless user is willing to completely avoid some extremely open bleed setting. If you want tunability, most damping force should come from the base valve with a check valve behaving mid valve.

5. A moto tuner can ask the rider to never touch the clicker after it’s set, tune the base valve first with the proper ratio in mind, then proceed to tune the mid valve. Once done, cavitation should be checked across the whole shaft speed range to confirm the earlier base valve choice is proper.

6. I think reStackor doesn’t model the initial acceleration part of the shaft speed, and just start the numerical iteration with “impact velocity” to progress through the whole stroke. The “bump velocity” section actually has details on this but seems not used in the SW package. This is an important part to understand Dougal’s comment “harsh but no support”. I suspect the harshness comes from cavitation at low shaft speed during acceleration, and no support because the peak total damping force is too weak.

What is “harsh” doesn’t have a widely accepted objective description yet. However, all charger damper seems having the same mid valve from 1.0 to 2.1, but the base valve progressively gets weaker and weaker. RS engineer is not following the engineering principle I described here based on restackor documents.
 
#31 ·
Thanks, @upsha that is helpful.

I circled back and remeasured all the ports, didn't find anything egregiously off, but did make some changes, and it'll be interesting to see to what extent it alters my results.

Just some initial impressions: it’s still hard to achieve force values above 20 kgf at high velocities (6m/s) with 0.1 shims only. This is true even with stacks that are 10 shims deep. Increasing the clamp to 12mm can get you up into the low 40s. I think the sensible thing though is to add 0.15 shims to the stack. This really expands the search space, however.

Looking at the moto forums, folks seem to suggest that for equivalent force values, 0.15 shims have a qualitatively different feel than 0.1s. Is this real and true for non-face shims? I wonder if adding the thick shims at the clamp end of the stack would minimize qualitative changes. This would also make the search space smaller, because you could focus on, eg, just the final and second to last shim.
 
#34 ·
I fell off my bike and hit my head last week and then my wife and toddler woke up with COVID on Monday. So forced couch time currently.

In other COVID news, I can't find 10x0.3 clamp shims anywhere stateside. Anybody have a source?
That's a bit rough.
 
#35 ·
@Dougal, thanks for the tip to try closing off the LSC. It took me a while to understand, but I have some data to back up this approach now. You give up adjustability, but can get exactly the curve you want. So much free bleed, otherwise. Couldn't you fix this with a new hollow base-valve bolt with skinnier ID?

I also have been really frustrated with the way this damper applies HSC preload. I've measured the HSC adjuster to offer a range of 6mm, ~1.5 mm per click. However, for a given click the absolute amount of preload applied varies with the height and shape of the stack, causing headaches. I'm pretty sure that under no conditions will four clicks out apply preload, and even three clicks out may offer none if the stack is tall and tapered. Regardless, I've given up on accounting for this, and will only consider 0 preload from here on out as a basis of comparison. I can't recall who, but someone in the Charger 2 modification thread mentioned adding in a backer shim behind the clamp shim so that the spring applies the same amount of preload no matter the stack configuration. Maybe that is a good approach to make the HSC adjuster more predictable?

Anyway, I've been exploring two and one stage configurations, and including thicker shims. I've also found that the key to unlocking higher kgf values is burly clamp shims, 10+ mm seem to offer the most versatility. Maybe this effectively reduces the area of the ports?

Maybe it will feel like sh!t, but it's fairly straightforward to reveal truly linear force curves now. Before too long I'll have the database ready. I'll put up a PDF with target ending forces at 1 kgf increments. Each target will have a couple of stack options for achieving the same goal. Here's an example:

Image
 

Attachments

#36 ·
I've got a medium sized database of shim stacks up in a basic app here. You can filter through them based upon the forces they end up at at 6 m/s. You can also adjust the LSC setting while maintaining a given target max force to get more linear or progressive responses.

Image

I'm finding I like three or four clicks out on my current stack to take the edge off a bit.
 
#37 ·
I've got a medium sized database of shim stacks up in a basic app here. You can filter through them based upon the forces they end up at at 6 m/s. You can also adjust the LSC setting while maintaining a given target max force to get more linear or progressive responses.
Wow, thank you for this huge job! And your app could me even more useful if you will add target shaft velocity and target force delta adjustments instead of hard-coded ones.
 
#38 · (Edited)
Wow, quiet the thread here. Good job on the software side.

It's been a while since I looked at restackor, doesn't it have a tab for combining the impact of the mid valve? Seemed like you calculated the base valve, then loaded the results into the mid valve section and recalculated again?

From what Dougal has stated, this will have a massive impact on higher shaft speeds. Would be interested to see if Restackor agrees.

From what it seems though, most of what you feel on a bike as far as impact on handling happens at <2m/s. Not sure targeting a peak force at 6m/s is an ideal target.