Question: Dealing with reaction forces for swerve

Intro
While working on my current swerve project, I noticed a difficult problem, and figured I’d tap into community knowledge here to see what previous solutions have been.

Problem Statement:
Basically, when the drive wheel moves abruptly or with high acceleration, the centered drive gear induces a torque on the azimuth, turning the wheel to the side. Because my application here is a balancing robot, limiting accelerations isn’t really an option. These jerks are corrected pretty quickly by the azimuth controller, but in my application it’s not quickly enough. Here’s a little diagram:

Ideas
I have 2 motors running steering currently, and I think increasing their gear reduction there will be helpful. Setting the steering motors to brake mode once the forks reach the target angle (within some threshold) will also probably help; the problem is that that target angle changes constantly.

Have any of y’all encountered this problem when programming swerve? What solutions have you seen or implemented to keep wheel orientation accurate through different drive wheel accelerations? Any help or feedback is appreciated.

2 Likes

Are you saying that because the drive wheel is off center it causes the module to rotate which has to be fought against by the steering motors?

No maybe that wasn’t super clear. The drive wheel is centered, but abrupt drive motions are turning the forks.

1 Like

Am I correct in assuming this only happens when the direction of a wheel doesn’t match the overall direction of the robot and the forces on the wheel are then causing uncommanded changes to its steering angle?

We have wrestled with this same problem a bit (for a slightly different reason).

Over the past seasons, we have been increasing the steering speed in terms of module RPM. Basically, we are trying to reduce backlash more than trying to increase response speed but increasing the module speed by reducing gear ratio is good for both.

Our limit on the gear ratio (and therefore the number of stages of reduction) has always been controllability. In 2018 and 2019 we were running 150 RPM module speed with an RS550 (banebots) motor. We probably could have run faster, but we spent our time iterating other aspects of the designs instead.

Starting in 2020 we switched to the NEO550 we allowed us to run the steering control in the motor controller using the motor encoder itself for control rather than the absolute encoder. This allowed a much faster control loop without any jitter associated with the deadband due to geartrain backlash. We use the absolute encoder for the initial position, but then use the motor encoder for all control after that.

This allowed us to remove a stage from our steering gearset (we used a VP Lite for the steering reduction ahead of our final drive ratio). In 2020 and 2022 we had a total reduction from the NEO550 of 33.3:1 resulting in a theoretical free speed of the module of 330 RPM.

The other side of this coin is that we have reduced the steering torque available. This is where the math comes in.

If you look at our module, you can see that there is a VP gearbox between the drive motor and the bevel gear. When this motor applies a torque to drive the wheel, this torque will also try to spin the module due to the reaction torque at the 90 degree bevel gears. If the wheels were unable to turn (such as when you are in a pushing match) and the motor were at max stall torque, the reaction trying to spin the module would be the motor’s stall torque times the gear ratio of that gearing between the motor and the bevel. You should be able to calculate the motor reaction torque for your system pretty easily as it is is always the motor torque times the gear ratio of the gears before the bevel gear.

With our gearing, we run either 3:1 or 4:1 before the bevel and 2:1 after the bevel gear (in 2018 and 2019 we were running 3:1, but at the suggestion of another team we tried 4:1 this year to get better acceleration).

So, if you take the stall torque of our NEO motor @40A, times this gearing (we will take the worst case which is the 4:1), you get 2.92 ft-lb of torque trying to spin the module.

I believe that this is the highest load that the steering motor needs to react. This is also the reaction torque that you are showing in your diagram.

Taking the NEO 550 steering motor, you have 0.215 ft-lbs of stall torque available @30A. Apply the 33.3:1 ratio (10:1 in the VP gearbox and 100:30 in the final drive ratio) and you get 7.15 ft-lbs of torque available to resist the drive motor. This is 2.45 times the maximum torque from the drive motor described above. So, this gives us a decent factor of safety and ensures that we are not running the motor at excessive amperage at stall as we are resisting the torque of the drive motor. Taking the 30 Amps divided by 2.45, we get 12.25 Amps. REVs testing of the NEO550 says that it can sustain up to 20 amps continuously (over a minute) without failing, so 12 amps seems pretty safe.

So, my first question about your problem is, have you done the similar math to determine what sort of torque factor you have (stall torque divided by working torque to react the drive motor)?

If you have a decent margin there, then my second question would be have you measured how much backlash you have in your greartrain between the steering motor and the module azimuth. It could very well be that it is the backlash in the geartrain rather than the backdriving of the motor that are causing your issues.

Depending on which of these two issues is causing your problem, you should be able to fix it with some clever programming.

If you are backdriving your motor, then you can just drive the motor against the backdriving force. Since you have now done the math and you know how much torque will be applied to the steering motor, you can apply sufficient amperage to generate torque in the opposite direction to oppose the tendency for the module to rotate.

If you have too much backlash, then you would want to rotate the motor in one direction or the other to “consume” the deadband.

You can program these steering motor behaviors to occur at the same time that you are applying the drive torque before the steering inputs are calculated from the encoder.

2 Likes

So heh, the application here is a one-wheel self balancing robot; there isn’t really a relative direction to any other modules. Picture of the robot, to clarify:

The force I’m looking to mitigate is from internal torque from the module’s drive motor, not necessarily from the ground. Although this is worsened if the module is on the ground and motion is being resisted, because then the torque from the drive motor goes directly towards turning the forks.

I’ve not done any calculation to determine the net torque induced by the drive motor, and the associated holding torque requirement for steering. However, a quick gut check shows steering to be more than strong enough:

  • The drive motor input torque will be the torque (at some voltage) of the rev HD Hex motor multiplied by the 5:1 reduction (this would be if the wheel were not allowed to rotate, in practice it’ll probably be lower than this number).
    • Worth noting that ultraplanetary reductions aren’t exact integers, but I don’t wanna look up the exact reductions rn
  • The forks motor reaction torque will be the torque of 2 HD hex motors with 12:1 planetary reductions, and then an 82:18 reduction for the external ring gear.
    • Drive torque = 5 * t(rpm)
      • Where “t” is a linear function for motor torque at a given power
      • Roughly: t(rpm) = 3.69E-5nm * rpm + 0.072nm according to vex’s data
    • Steering torque = 2motors * 12 * (82/18) * t(rpm) = 109.3 * t(rpm)

So assuming motor power is equal, steering will always be able to counter drive. I think the issue I’m starting to see is that this steering motor holding power isn’t being applied when it needs to be.

Yeah I’d estimate it at about ±0.25 degrees, it’s really minimal. That’s measured between the turn gears and forks ring gear, though, so there may be more backlash coming from the ultraplanetary stages themselves.

I think the problem may be my control scheme actually. Currently the forks position is held with a proportional controller, which sets a pwm value for the brushed steering motors (rotational data comes from an absolute encoder). I think this doesn’t do a good job applying position-holding torque to the forks. Basically when the forks are at or near the target angle, very little power is applied to hold them in place. I think this is the problem, but I’m not sure how to solve it.

TL;DR - It can hold itself in place, it just isn’t trying to… so:
Does anyone have experience with “position hold” algorithms for brushed motors?
I know this is fairly easy to do with an odrive and brushless motors, I might have to research more thoroughly how that works.

1 Like

So it seems too simple* of a solution, but couldn’t you have something rotate in the opposite diection to create in opposing torque?

*probably requires additional design or redesign so not particularly simple in practice

I think this is doable; I’d love a happy little equilibrium. Calculating that power requirement is tricky, though, but motor testing data again comes in clutch. I have net torque as a function of rpm, so I can put rpm in terms of voltage to the brushed motors (a pwm signal of 0 to 255, or 0 to 12v).

I’ll write test code for this and see if it improves things. I may eventually be limited by the low-power controllability of the brushed motors and the long loop time on the microprocessor running the robot.

Still looking for more insights into position hold algorithms.

FWIW, we use brake mode on both steering and drive (without this on drive, the robot coasts more than the drivers like for it to). Brake mode really only comes in when a zero drive is being commanded, and it is helpful for steering in any case.

We also use trapezoidal PID (with I and D of zero). This has worked really well for us. The idea is the current and desired steering positions (and the current steering velocity) are used to plan out a desired position/velocity/acceleration over time, to reach the desired endpoint in the minimum amount of time, with a specified maximum acceleration and velocity. The P term can be large and is simply used to encourage the motor to track to the given plan.

1 Like

So, here is the reality - if the drive wheel is not on the ground then there only torque being applied by the drive motor is whatever is needed to overcome internal friction and inertia of the rotating bits - pretty small. If the drive wheel is on the ground, then the torque being applied by the drive motor is whatever is needed to produce the contact force between the wheel and the ground needed to accelerate the robot - much higher.

In my example, I used the maximum torque available (i.e. stall torque at 0 RPM) to calculate whether my steering motor could apply enough torque to the module to react that torque. But when the robot is accelerating, the drive motor can still apply up to the maximum torque available at that motor speed depending on amperage applied. If you know both motor speed and amperage, you should be able to calculate the drive motor torque using the curves provided by VEX.

So, this may be the bigger issue here. When the motors are trying to drive the robot and turn the module (wheel) the motor torques involved are reacted into the robot. Normally, for a multi-wheeled robot, these reaction forces are distributed into the other wheels and can pretty much be ignored. But with only one wheel touching the ground, there is nowhere else for these forces to be reacted to the ground. Therefore, the only thing that will counteract these reaction forces is the inertia of the robot itself (assuming that you don’t have some sort of gyro stabilization system that you are not showing us). So, when the robot tries to turn the module clockwise, the body of the robot is going to turn counter-clockwise by some amount. The amount that the body of the robot turns will be a function of the relative inertia of the body of the robot to the reaction forces. If the body of the robot has a decent amount of inertia, the resulting angle may be small enough to ignore in your control loop. But it may not. And if the body of the robot spins a few degrees while the module is rotating, that could be enough to throw off your calculations and make the robot unstable. You may need to account for this in your control loop tuning. It should be a predictable adjustment to the constants to account for this.

The inverted pendulum problem is fairly easy to solve in 2D (it is typically one of the example problems in control theory textbooks). Solving it in 3D is obviously trickier, especially if you want to include the case of near 0 forward velocity. If you have ever watched someone riding a unicycle, you know that they have a hard time balancing while stationary. Good luck. Sounds like a fun and ambitious project.

1 Like

For a one-wheeled self-balancing robot, it might make more sense to use a trackball-type setup…

(This uses a sphere that’s free to spin in any direction, with two rollers, set 90° apart, to impart motion to the sphere.)

EDIT: Either way, you’ll want to have a good IMU.

There are dozens of much more practical ways to make a one wheel balancing robot, monowheel swerve isn’t one of them.
This was one I’d never seen done before, and I wanted to try it because it was a crazy idea.

5 Likes

I’m very interested to learn more about this.

Yep, and this made it difficult to diagnose because the code worked on the testing stand, but the videos I took of the wheel while ground testing showed unexpected movements.

So the IMU measures tilt direction and angle relative to the robot, so “twist” shouldn’t affect this value. Provided the control loop runs quickly enough, it will always point the wheel towards where it’s falling (I have some additional vector math actually to account for fall directions about the central axis as well, but for the most part it’s just a ray away from the origin in the direction the robot is tilting).

So this is going to be the main driver of reaction torque, and it involves some inverted pendulum math I’m not really familiar with. If the robot is tilting at, say, 10 degrees and the drive motor applies some power, the reaction force will be different than at another angle. I think I need to do some research here.

trapezoidal PID

The links in the original post explain this reasonably well, but here’s a pretty solid explanation of the theory.

Here’s a link to our C++ code, in case this helps.

2 Likes

I thought of something new, and it’s a very simple mechanical solution.
Because the drive motor has so much less torque than the steering motors (by a factor of 20), I can just adjust the mechanical resistance in the azimuth bearing by tightening the bolts clamping the races together. If this is well tuned the drive motor won’t be able to turn the forks, but the turning motors easily will.
I’ll mess with this and see how it goes, definitely still interested in a control-based solution though.

You may not care where the wheel is pointing, as long as you can maintain balance. But, if you do want to be able to drive a path, you will have to deal with conservation of momentum around the steering axis – turning the wheel is going to also turn the whole robot, in the opposite direction.

And, if the robot starts to tip perpendicular to the direction of travel, you’ll have to do a quick steering correction to get the wheel into position to correct the balance – which could destabilize things and will almost certainly complicate them. It will be really great to see this all working, it will be a solid achievement to pull it off!

1 Like

Well, once you are moving, the 3D inverted pendulum problem gets much easier to control. If you start falling to one side of the direction you are moving in, you simply steer slightly toward that side and due to the speed that you are moving forward, the wheel moves under the pendulum. This is why bicycles are easier to steer and keep stable when you are moving than when you are stationary. Yes, I know there is also gyro stabilization going on, but from a control perspective, the amount of steering adjustment needed to keep the bike upright is much smaller when you have forward velocity that when you are stationary.

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.