Motion Magic position puzzler

We have code to turn a turntable using a Falcon. We control it both with percent output and with motionmagic. The code is here:

and here:
Automatons-2023/ at Big-Mac · HP-Robotics/Automatons-2023 · GitHub

The logic is that we run the turntable at a constant speed. We use an IR sensor to look for the cone; if we find the two edges, we stop and command a ‘softer’ move to an offset set point. Softer because an abrupt stop often leaves the cone in variable positions. The ‘softer’ move is a motion magic move at a reduced velocity and acceleration. (Side note, this is not actually the ideal solution, because the motion profile starts slow and ramps up, so we get abrupt movement anyway, but it is what we had time for).

And this works. It works in the lab. It works on the practice field. It’s slick. But sometimes, just sometimes, usually after a relatively long running session, we get a novel behavior. After the cone stops in the correct position, the turntable will start spinning slowly clockwise.

Critically, that is not at any of the speeds we normally command. It is perhaps at the intended velocity of the motion magic command. Now, our position control is a not especially well tuned PID, so I had the theory that if we exited motion magic with a last I driven command, maybe that would go on forever. But my understanding is that motion magic will seek to hold the destination point after the move, so that doesn’t add up. My only other hypothesis is that sometimes GetSelectedSensorPosition() will return 0, or will ‘wrap’ such that our commanded move is actually taking us back to 0, instead of just using an offset. That is, if we spin a motor for a long time, can we get into a state where commanding a move to GetSelectedSensorPosition() + 1500 will go to an unexpected point?

It is the case that once the problem starts happening, it is quite consistent and happens every time.

At any rate, I find it to be an interesting puzzler so I thought I’d share and see if anyone else has any clue bats.

I would be really curious to see a self-test of that motor when its in that failure state… If you need a quick solution you could add some logic to set the motor to 0 velocity once it’s at its setpoint just to ensure it doesn’t try and go somewhere.

Well, the issue is that we can’t easily create the failure state. I think we’ve got a number of paths to ‘fixing’ it (including getting rid of the motion magic in favor of a soft slowdown). But I’m a curious type; I really want to know what’s happening.

I hate stuff that’s hard to reproduce. When you get in that failure state using tuner to self test the motor and plot relevant fields should shine light on it I hope.

While I’m not quite sure of what’s going on, I do know that MotionMagic can cause some funky results when stuff changes outside of it (typically while robot is disabled) that can cause it to ignore its motion profiling.

Is there a reason you are using a non-zero kI term on the turntable PID (i.e. was it failing to reach its target without it)? Most of the time, a simple P or PD controller is more than enough to produce consistent motion, especially with motion magic, so that may be the culprit.

Another thing that could happen is that the offset is getting repeatedly applied (i.e. motor is always targeting 1500 ticks ahead of its current position) because the command is not being properly terminated. This lines up with your symptoms of a.) constant rotation in the given direction at a speed consistent with your motion magic limits and b.) inability to terminate the behavior once it starts. You could use a timeout on the command to see if this is the source.

Thanks for listening :-).

The mechanism came together late and had some binding spots; the kI helps us overcome the flaws in the mechanism. In an ideal world, we wouldn’t need it (and we’d also use velocity control instead of % output control, but that’s a different issue).

That’s a good theory. But the method that sets the motor is guarded by a boolean, and I really can’t see how it would get called more than once. But I’d also expect it to consistently fail in that fashion if that was the bug, rather than only every blue moon.