ATR Torque Offset Proportional to ERPM

My first attempt to contributing - it started by trying to figure out my Amps to Accel/Decel Ratios from a log in Python, but then I realized there’s a distinct relationship between the Torque Offset needed and Speed:

Which kind of makes sense, average torque at standstill is 0 and at speed you’re pulling more Amps. I used linear regression to find coefficients for atr_filtered_current and erpm. Intercept was relatively small, so I constrained it to 0. Essentialy, instead of multiplying by SIGN(d->erpm), we can use d->erpm itself:

float torque_adjusted = d->atr_filtered_current - 0.00022 * d->erpm * accel_factor;
expected_acc = torque_adjusted / accel_factor;

I’m assuming heavier riders need bigger Torque Offset, so that’s where the top accel_factor comes from. It can be rearranged a bit, but by storing the torque_adjusted first, it can be used as input in the Classic Torque Tilt as well (no need to raise nose at fast speeds).

The value of roughly 0.00022 is what I got from the regression, but since accel_factor is taken into account, I’m hoping it should be more or less the same for all riders if they tune that.

This is where the fun begins!

By some miracle (Im0rtality’s vesc_toolchain) I’ve been able to test it and to my surprise it worked! Less over-reacting, bonks and drops felt really good, and overall it was mostly a pleasant experience.

There was however one weird moment, where on a messed up sidewalk it sort of jerked. I think. (probably wheel locked for a moment > different ERPM > different Torque Offset > different setpoint?). I’m guessing it might need to rely more strongly on some filtering or accurate wheelslip detection in some edge cases.

Still though, pretty excited. But I know placebo is a thing, would anyone be willing to try it at their own risk? Here’s a pre-compiled .vescpkg:

Or if anyone could send me some representative VESC Tool ride logs for analysis, that would be much appreciated as well. And please tell me if it’s a completely wrong and flawed approach! What do you think?


v03 on Google Drive (link above) now uses strongly filtered ERPM instead of raw. It’s so buttery, I don’t think I can go back to stock Float. Feels almost as if ATR was disabled, but it still does its thing. For reference, I’m a light rider who uses strong ATR strengths up to 1.5. However, still be cautious when testing it.

UPDATE - I’m happy with the ATR change, but Torque Tilt might need a little more work.

Using the “speed adjusted” Amps works really well for flat ground, but on some hills there are instances where it feels a bit nose-dippy. Adjusting TT settings can help, but there might be a better solution. Spoiler - measured acceleration? Here’s some theoretical exploration.

Different way to calculate Torque Tilt?

Basically, we want to first estimate current, at which accel_diff is the same and acceleration is 0. Then use those Amps as a baseline for TT calculation. In other words “Given hill gradient, at what Amps would this speed stay constant?” Initially I just wanted to add another offset to fulfil those requirements:

float amp_offset_speed = 0.00022f * mot->erpm_smooth * accel_factor;
float amp_offset_atr = atr->accel_diff * accel_factor;
float amps_adjusted = mot->atr_filtered_current - amp_offset_speed - amp_offset_atr;

But interestingly, if you write it as expected acceleration, substitute accel_diff and rearrange some terms, it’s exactly the same as measured acceleration. In retrospect, of course it is - “real” acceleration is sort of what I wanted the modified TT to respond to anyway.

There are a few issues though:

  • when wheel locks, you wouldn’t get a strong forward response
  • when wheel slips, you would get a response too strong (until wheelslip gets detected)
  • ERPM acceleration might be overall less reliable than current?

Possible solutions:

  • simply clamping the acceleration (like ATR does) should help
  • perhaps strongly filtered acceleration (to further smooth out wheel slips) would work just fine
  • new value could be introduced to mix between the current-based and accel-based approach. Or even crazier, having TT and Accel. Tilt (if it ends up working)

Has anyone already tried using ERPM acceleration to drive Torque Tilt?

I really want to test this but I’m having trouble compiling again. I don’t know if it’s a good idea, it does make some sense to me - I don’t want TT to interfere with setpoint when simply riding at a constant speed (I’d say that’s ATRs job), but at the same time maybe it would defeat the purpose of the original TT? It wouldn’t really be torque based anymore. To be continued, might be a completely dead end…

Additional random thoughts

  • currently, wheelslip detection is based on acceleration, if it used accel_diff instead, it could get tighter to the “normal traction” values. Lets say fabsf(d->atr.accel_diff) > 5 instead of fabsf(d->motor.acceleration) > 15. Or even better, it could be a smooth factor (wheelslip “probability”) that is used to sort of mix between normal behavior and winding down.
  • some values like acceleration (and therefore Amps to Accel Ratio) depend on loop hertz. Doesn’t really matter but it would be nice to make things controller agnostic. A simple yet elegant way to transition could be to use “per ms” instead of “per loop”. That would lead to only a minimal change in tune for most people but could make things easier in the future?
  • often, asymmetric parameters are switched based on some boolean, like motor->braking or not. Perhaps having a continuous input and then blending the 2 sides based on some sigmoid function could work slightly better at standstill.
  • converting between Amps and accel. is possible (Amps to Accel Ratio), so theoretically, the same “units” could be used for both ATR and TT. That way, their strength values would be quite similar actually (just a coincidence though).
  • there is a discrepancy between ATR and TT thresholds. Degrees are intuitive, but when strength is changed by user, so is the starting point. TT and its Start Current Threshold doesn’t have this problem because it’s applied before multiplying by strength. And again, since Amps and accel. are convertible, both could use Amps as a unit for example. But even if both used degrees, at least it would be more consistent I guess.
  • ramping step size for a smoother ride overall - I think this deserves its own post, I’ll share my findings soon.

Thanks for reading, I know this post is all over the place… But I think some of these things are worth exploring. And to all the people that made these features possible in the first place (thanks!) - please don’t take it as criticism, I just enjoy thinking about alternative ways to do things.