Spark Max 1.40 and Smart Motion?

Hello,

I am trying to debug why my smart motion control loop on the 1.40 firmware is acting strangely. Is anyone else experiences a regression issue with this version (I’m upgrading from 1.1.9)?

I am trying to determine if it is a code error on my part (whether or not something has changed with the release that I am not aware of with regards to how smart motion works), or whether or not the update has a regression issue (which is probably not the case…).

Some background information: It is an elevator with two motors. I have set the arbitrary ff to the percent output required to hold the elevator. As it approaches a setpoint that I have, it is almost like it never reaches the deceleration period of the trapezoid, then last-minute tries to correct, like a lag spike almost. Then, it overshoots massively and eventually oscillates near the target setpoint. I am only really using f (setFF in code) right now on the PID controller (tested by running at different speeds then measuring velocity). I am using unit conversions to inches. Setpoints are negative since the way the elevator was wired up. Things I have considered:

  • I gain somehow that causes it to overshoot? I set it to zero though
  • Velocity/position conversion is causing problems?
  • Maybe negative setpoints don’t work well?
  • Loop overruns on the RIO, but this shouldn’t affect control loop on spark?
  • Closed-loop ramping set accidentally? I also set to zero
  • Firmware regression?
  • Output range set improperly, but I set it to -1 to 1
  • setReference is called every update. I thought this was okay?
  • Closed-loop error is set to zero
  • Arb feed-forward is set wrong?
  • Parameter mismatch between slave and master?

For now, I am writing a separate code in a new project that has only spark commands. This could maybe affirm the loop overrun problems? Main code sits at 90% CPU usage and has some garbage spikes.

Any help/insight is appreciated,

  • Quintin

Here is an example of how the velocity goes:

And here is the output:

It seems to skipp the deceleration phase entirely. Not sure why.

Can you also plot the position?

Can you share the PIDF constants you are using for the velocity loop?

There are no known regressions in Smart Motion in the latest firmware.

This is a new run. Position and Velocity (the set point was -10 inches):

Output (40 A seems high?)

Constants:

P: 0
I: 0
D: 0
F: 0.015
A: 12 m/s^2
V: 12 m/s
Arbitrary FF : -0.04 (percent out)

Here is output too:

I have no issues with the Spark Max firmware 1.4 with the Rev Robotics Spark motor controller. It works well for neo motor testing, I am having trouble with the smart current control, which I set at 30Amps but as when it reverses from 50% forward to 50% backward it will draw over 57.4 Amps from my power supply, tripping the breaker.

I’m pretty sure the issue is either my PIDF config or the way I set up the controller in code. It’s possible my F gain could be too big on the controller. I do not think that the spark max firmware is bugged, as I tested on multiple versions.

The way I got it was by running the motor at various percent outputs. Then, I would take the percent output minus the arbitrary feed-forward percent, and divide it by the max velocity reached. That is how I obtained an average value of around 0.015.

However, I think the overshooting may be caused by too high of an F gain. I had trouble reaching the target max velocity with a lower one however.

The problem currently is that it overshoots, it does not go into the deceleration period fast enough, then when it does, it is for too long. Maybe a smaller F gain will help this and a more aggressive P? I will try soon.

Also, it seems like the get current call to the spark is incorrect? I checked the driver station logs and there was no output as high as what I saw in the graph from the PDP.

Okay. So after isolating a lot of variables, I have come to the conclusion that the issue is the position and velocity conversions. When they are not set, the control loop works as expected, it slows down before the target. However, as soon as I convert all the PIDF constants, set points, target velocities and accelerations to my converted units (inches & inch/s), the behavior changes. It is almost like it does not enter the deceleration phase early enough, and when it does, it is for too long. I can see if I can get a graph of it soon.

From a code perspective, it may be a precision issue with doubles? I am not sure.

Hey, thank you for helping. See above for what I discovered ^^^

Maybe it is an issue with the specific setup of our robot? I am not sure. But when I used raw encoder units, it became a lot smoother.

Are you using raw encoder units or are you using velocity and position unit conversion?

As for current, I noticed that the sparks report current that seems a little too high when cross-referenced with the PDP.

There should not be any reason for this if you are just converting all the units, as the unit conversion is just that, a simple conversion. Can you post all of the constants (before and after).

Regarding your comment about the current measurement, note that the current measurement in the PDP logs is the input current to the motor, but the SPARK MAX is measuring the output current (actual current through the motor windings). You can read more about the difference between these two here: Neo motors pulling only 5 Amps when stalled?

Hey, thank you for the clarification about the current and the link.

Here are configs (I and D are zero):

Before:

{
    "ff": 0.031,
    "f": 0.00022,
    "p": 0.00005,
    "a": 5200,
    "v": 4000
}

After:

{
        "ff": 0.0310,
        "f": 0.0181,
        "p": 0.00412,
        "a": 63,
        "v": 58
}

Position conversion: 1.3720253714818562
Velocity conversion: 0.012147491593880535

Voltage compensation set to 12. Allowable closed loop error set to zero. No soft limits.

Also, I just noticed that you work for REV robotics. Sweet. I really like the Neos - brake mode and power are so much better compared to brushed!

Also, is the S curve feature functional? Or does it use the same as trapezoid for now?