FtcRobotController
FtcRobotController copied to clipboard
STOP_AND_RESET_ENCODER often doesn't stop motors
tl;dr: Switching a DcMotorEx into STOP_AND_RESET_ENCODER mode doesn't always stop the motor -- the motor continues to receive power. Here's the bottom-line image of the issue at work, where a motor is in STOP_AND_RESET_ENCODER mode but the motor is drawing nearly 7 amps as it has reached its mechanical limit of travel and is stalled:
This issue was first identified and has been discussed at https://ftc-community.firstinspires.org/t/stop-and-reset-encoder-sometimes-doesnt-stop-motor/922 , along with some potential workarounds. I've also made a YouTube video that demonstrates the problem at https://youtu.be/rkFPpIvgoFs .
The bottom line so far seems to be that executing .setMode(STOP_AND_RESET_ENCODER) within 470ms (0.47s) of switching a motor to RUN_USING_ENCODER or RUN_TO_POSITION will reset the encoder value but will continue powering the motor according to the previous mode. A simple program demonstrating this behavior is attached as TRunMode.java.txt . I can also provide additional video demonstration if desired.
This incorrect/undocumented behavior seems to have been the "silent killer" for many of our team's burnt-out (literally) motors and degraded batteries over the past several seasons, as motors ended up in stall conditions for long periods of time when the program indicated they should be idle/depowered.
The Javadocs (https://javadoc.io/doc/org.firstinspires.ftc/RobotCore/latest/com/qualcomm/robotcore/hardware/DcMotor.html) claim that a side effect of STOP_AND_RESET_ENCODER is that power is removed from the motor. There's a blurb mentioning that some motor controllers will "automatically transition to a different mode after the reset" but if this is occurring, it's happening silently -- i.e. .getMode() still reports STOP_AND_RESET_ENCODER even as it continues sending power to the motor. It would also surprise me if the REV controllers are part of the category of "automatically transitioning controllers", but perhaps they are the reason for the additional blurb in the Javadocs.
At the least, the fact that STOP_AND_RESET_ENCODER doesn't actually remove power to a motor in some circumstances should be mentioned in the documentation. As our team has now discovered, mechanisms using limit switches and having mechanical limits on travel can easily find the motors placed in a stall condition because the STOP_AND_RESET_ENCODER didn't actually remove power as expected/documented.
Ideally the mode would be fixed so that the 0.4sec delay isn't needed and STOP_AND_RESET_ENCODER always does what it claims.
If the REV controllers are in the class of controller that automatically transitions to another mode after resetting the encoder, then the .getMode() method should reflect the results of that transition.
Another improvement might be to provide a .resetEncoder() API method that doesn't change the mode of the DcMotor at all -- a lot of beginner-level programming could be greatly simplified if this feature were available. The most common example is switching between RUN_USING_ENCODER and RUN_TO_POSITION for manual and "automatic preset" positioning of hardware mechanisms. Yes, a work around for this is for programmers to maintain their own "zero offset" variable in code, but this adds some level of complexity to coding and a rich source of bugs/edge cases to consider, which is more challenging for newer programmers and coaches. Setting a zero-point without changing the run state really feels like it's a fundamental operation that should be made more available in the API.
I'm glad to provide more details as needed, either in this issue ticket or on the community forum thread. Thanks for reading.