MotionMagic - Hardware PID turning

And that’s exactly what we’re doing. The Software PID with PIDController works just fine, with both NavX or Pidgeon. But we want to offload all that work to the motor controller.
And also as was indicated, because of the “different scrub”, precision turning without IMU PID proved to be impossible. It depended on the surface too much. The angle discrepancy in our tank drive on carpet vs tiles was close to 20 degrees.

Thanks for the code link! So, in your case you’re doing


rather than

ControlMode.MotionMagic ? That should work for simple turns, and I can try it.

MotionMagic certainly performs better (and looks nicer), but I always start with position since it has less parameters to tune.

We will try it!

My approach to this - let’s figure out dozens of parameters required for proper configuration. Once done, the actual start of the PID is just two lines - one zeros the sensor, and the second sets the target sensor position. The rest works like Magic :slight_smile:

Question - What’s the functional difference between the two? I mean - MotionMagic can accommodate max speeds and acceleration. But if we do not care, what does the Position not do in comparison to MotionMagic?

Look at the CTRE documentation page. They explain that Motion Magic uses a trapezoidal velocity curve, while regular position PID is just… PID.

1 Like

In short, Position control will immediately command the mechanism to the set point. It will race to the set point, and only slow as it approaches the target. MotionMagic is a motion profile that will accelerate the mechanism, cruise at the max speed (if there is time), and then decelerate to the setpoint. The whole motion is planned and also error-corrected throughout, so you usually get more accurate results in addition to smoother motion.

The WPILib docs give a nice description of how motion profiles are an improvement over position control.

CTRE’s Motion Magic actually uses an S-curve, but you can get trapezoidal behavior by setting the curve strength to 0. It’s not really explained in the main document section, but it’s in this blog entry.

EDIT: I take that back, it actually is explained pretty well in the main document section. I was looking at the MotionMagic detail section, but the overview has a lot more background.

1 Like

Have you gone through this section of the docs?

That section is for auxiliary closed-loop, which is a second PID loop. I don’t think that applies here.

1 Like

From the link in prior post: “As an example, we will use a differential drive train with 2 encoders on each side and a pigeon.” This sound a lot like the question originally posed.

The idea (as I understand it, I have not used this feature) is that one side is A+B and the other A-B. Here, A is the forward/reverse control and B is the turning control. With motion magic, one could control either position or velocity. Given that you asked about turning 45 degrees, the former case would apply. If you are only turning, you would have A be zero (hold forward/reverse position). In this case, you would use an IMU to drive a motion planned B.

This is correct, but the later case would not apply. This is why auxiliary closed-loop is not appropriate here. Auxiliary closed-loop would be for when you want two loops to work together.

The OP is asking only how to rotate the robot in place (spin) using a pigeon. When spinning, encoder readings are not used. In fact, as the OP mentioned, using the encoders while spinning is highly dependent on traction.

Motion magic is only for position control. It does control velocity throughout the motion profile, but the set point can only be a position.

1 Like

As I said, I have not used these features, nor do I have access to a device to test these days. The OP asked about using motion magic with a Pigeon IMU to perform a turn.

This is somewhat similar to this CTRE example: MotionMagic_AuxStraightPigeon. It does have some differences as well.

The MotionMagic_TalonFX_AuxStraightPigeon example demonstrates the Talon auxiliary and
remote features to perform complex closed loops. This example has the robot performing
Motion Magic with an auxiliary closed loop on Pigeon Yaw to keep the robot straight.

One thing that’s very nice is if you can set the motor controller up once and then not have to change the config parameters, since doing this on the fly can be expensive. Plus, you then have to decide which set of parameters to save (and worry about what happens if the motor controller reboots). This argues for using a complex control mode, plus this is what the OP was asking for, as I read the question.

The above example is pretty nice – it allows one to control both forward/back and simultaneously control turning, while using motion magic. It also allows the control to run on the motor controller (as requested by OP) and to be based on the IMU input. So, the goal here would be to build on this to get to the desired end state, with motion control plus turning.

I think we actually agree on most of this, but I got a little loose with the terminology – here’s what I had in mind for motion magic velocity control:

Motion Magic in firmware >= 4.17 (Talon SRX and Victor SPX) now supports an S-Curve parameter, allowing you to create a continuous velocity profile. [See here.]

So, the idea here is to build on the example, or replicate it in some sense, but to bring in actual turning (as opposed to holding a zero turn) and to get motion magic into the forward/back control. Without direct experience or something to try things out on, this is about as far as I can take this. But, it might provide a starting point, if even only to search for a closer example or to experiment.

There is no need to use the auxiliary loop here.

The Talon has 2 control loops running on it at once: Primary and Auxiliary PID. These are Loop Index 0 and Loop Index 1 respectively. They can each load sensors from any valid source and use any of the 4 PID slots to determine their constants. Many of the older Talon examples use the Aux loop to allow for common tank drive tasks, like driving to an encoder distance (primary loop) while keeping the robot straight (auxiliary loop).

The OP just wants to rotate in place. This can be done purely on the primary loop, as there is only a need for one feedback device. The auxiliary loop does not need to be used here. Once position PID works, the same constants can be copied to Motion Magic and the velocity/acceleration determined via testing for the feedforward.

The CTRE docs explain this pretty well.

1 Like

I didn’t think they only wanted to rotate in place, but this was me filing in what I might do I suppose and extending the question to cover driving while turning or following a path.

Maybe it helps to lay out what is possible, but hopefully just going through the discussion has helped to clarify things. For me, the terminology was an issue, so apologies for muddying things.

If it were me doing this, I’d probably pick one or two top teams who have released code, see what they are doing, understand this, and go from there. I’ll guess at least some of these do use the aux stuff. But I agree that this isn’t needed to just turn in place.

CTRE devices persist settings between reboots. You may be thinking of the REV Spark Max, which resets to the last parameters that were burned to flash.

Some settings persist, and some don’t. Which is which is defined in the CTRE documentation. I’m a big fan of running reset to factory defaults on robot init, before writing all the settings from scratch. Saves the hassle of dealing with a random persistent setting (like limit switch NO/NC) especially when getting spares from other teams.

1 Like

I agree 100%! The settings are all under source control this way. This also makes it easy to swap a device. You just need to set the CAN ID. You don’t need to worry about fiddling with settings in Phoenix Tuner.

As a matter of update - I wanted to thank you for sharing the code.

We indeed were able to adopt the code with ControlMode.Position, and it indeed worked properly with less than half-degree tolerance.

That would make our stringed-trajectory routine much easier and less demanding on Rio.

Do you have something similar that uses ControlMode.MotionMagic as well? Ultimately we’re looking for full trajectory driving from Pose1 to Pose2 where each pose includes coordinates and direction. We have done it some years ago with Ramsete, but that was before the New Command Robot, so we need to retrofit that code. Besides, we really would like to utilize MotionProfile instead if at all possible.

Thanks again.

Why? Individual motion profiling of each side of a differential drive hasn’t been a best-practice since, like, 2018. You should use a control algorithm that actually converges to the desired pose.

1 Like

We have CAN saturation and Rio CPU usage concerns. Granted, once we moved vision to Limelight and PhotonVision (including driver cameras), and implemented MotionMagic for some of the items, some of these concerns are lessened. However, I still like the idea of the Hardware PID whenever possible. We also did not try the Rio2 yet. Since it’s a little faster, we may have lesser CPU usage concerns as well.
Ultimately we want to have all the capabilities proven and tested - hardware and software PID, hardware and software-driven trajectories etc. That would allow us to choose whatever fits the task best for the competition.