Hi, okay so we have a mecanum drivetrain and it was working totally fine before with WPILIB’s MecanumDrive class and the driveCartesian() method, but that was on the old command-based framework. We just migrated our code over to the new 2020 rewrite of the command-based framework (I know, we’re a bit late to the party). I think we did everything correctly and we are able to successfully build/deploy code, but now when we try to drive the robot doesn’t move and the Driverstation gives us this error: ERROR 1 MecanumDrive… Output not updated often enough. edu.wpilibj.MotorSafety.check(MotorSafety.java:96). Does anyone know what could be causing this error and how to remedy it? Any help would be greatly appreciated!
I know it wouldn’t necessarily solve the root of the problem, but would adding this line of code: “robotDrive.setSafetyEnabled(false);” at least stop it from spamming us with errors and allow us to drive? I think the problem is that this is a like a new feature in the new command-based framework. As far as actually solving the problem without just disabling the “safety” feature, I’m not sure how to do that but the robot was working fine before so
If you share your code (ideally a link to github or something), we’d be better able to help.
In short, that means you’re not feeding your MecanumDrive object often enough. Calling driveCartesian() should do that for you, but if you’re not using that for some commands, then you would need to call .feed() instead to silence that error.
But yes, disabling motor safety would also silence the error message, though generally it’s not recommended.
Okay, thanks for the helpful info! Here is our Drivetrain Subsystem: RapidReact/Drivetrain.java at New-Commands-Structure · team3042/RapidReact (github.com) and here is our default command for that subsystem: RapidReact/Drivetrain_MecanumDrive.java at New-Commands-Structure · team3042/RapidReact (github.com). What exactly does calling .feed() do? Is it any better than using robotDrive.setSafetyEnabled(false) to silence the error?
Hey, so we still seem to be having problems with this. Calling robotDrive.setSafetyEnabled(false); silences the warning message, but it doesn’t actually stop the safety feature from disabling the motors. How do we get around this error? Our code worked perfectly fine in the old command framework so I’m not sure why we’re having this issue. Some of our drivetrain commands work perfectly fine and others are plagued by this issue even though all of them constantly set power to the motors in execute() so I’m not really sure what the issue is, and why doesn’t robotDrive.setSafetyEnabled(false); actually disable the feature?
Teleop driving in teleopPeriodic() works fine but some of our autonomous commands are giving us this issue, like this one: RapidReact/Drivetrain_GyroStraight.java at main · team3042/RapidReact (github.com)
I couldn’t find any info here relating to the issue in question
Where in this code is it disabling the safety?
It’s not right now, we took that code out because it didn’t seem to do anything. It silenced the error message in the driverstation, but didn’t prevent the motors from being disabled
But when we had it, we did it in the constructor of the drivetrain subsystem
@jdaming We have a meeting tomorrow, I can give you more specific info if we come across the problem again, but basically it’s only been happening in our autonomous commands, teleop driving has been working fine
@jdaming Okay, yes, we are definitely still being plagued by this breaking issue. All of our teleop code works 100% fine, but any autonomous command that utilizes the drivetrain subsystem is rendered useless by this motorSafety feature. The main command we are trying to get working is this, which is supposed to drive a specified distance and correct for heading errors using the gyro. For reference, we are using a Mecanum Drivetrain, and here is the code for our Drivetrain subsystem. This command used to work with the old command-based framework, but no longer works now that we’ve switched over to the new 2020 rewrite of the framework. When the motorSafety feature is enabled it spams that error and the drivetrain doesn’t move, but when it’s disabled, weird things happen. For this command, for example, power is given to the motors, but they keep going forever and don’t stop when the encoders reach their goal. And we know all the encoders are working, we already checked that. Can you see anything in our code that would cause problems? Any help you can give would be greatly appreciated, we are pretty stuck on this issue.
Maybe this would be helpful for us: does anyone here have an example of their own team’s code that successfully completes a drivetrain command during autonomous mode? We are using a SendableChooser to choose our command in ShuffleBoard, does anyone here do it that way too and actually have it working? Seeing someone else’s code that works would probably help us out a lot
Are you sure your Drivetrain_GyroStraight command isn’t ending earlier than you expect? Note that as soon as it finishes, the command calls drivetrain.stop(), and then none of the drivetrain functions will get called after that point, which will result in the motor safety error.
The Drivetrain subsystem has a mix of methods that call individual motor set() calls (e.g. setPower) and MecanumDrive calls (e.g. driveCartesian). Pick one approach–having a MecanumDrive but bypassing it (e.g. not calling its functions, even if you call functions at the individual motor level) will trigger motor safety (as that is done at the MecanumDrive class level).
Okay, so when the motorSafety feature is disabled, the drivetrain just keeps driving forever, so the command isn’t even ending, or if it is then it’s not stopping the drivetrain like it should with stop(); With the motorSafety feature enabled, sometimes the command works and then we get the motorSafety error after it finishes, exactly as you described! But then the weird thing is that if we disable and enable to run the command, it doesn’t drive. The command literally works every other time which is super weird, do you know what would cause this to happen?
If the safety feature is disabled, the robot never stops. If the safety feature is enabled, it does stop successfully! But only every other time and I don’t get why. I also don’t get why having the safety feature disabled would cause the robot to drive forever. We just have so many questions right now and don’t know how to find the answers.
We actually tried this today, but to no avail. We removed all instances where we call stop() and instead called driveCartesian(0,0,0) but this didn’t seem to change anything
You’re resetting the encoders (in initialize) and then immediately reading them (in isFinished). I’m wondering if there might be latency between setPosition() and getPosition(). E.g. setPosition(0) doesn’t immediately get reflected in getPosition(), but might take a handful of ms to propagate to the motor controller and back.
Hm, interesting, that actually makes a lot of sense. How would we fix this issue? Maybe by resetting the encoders in end()?
That won’t help if you string commands together. The better approach is to never reset (at least at the motor controller level). Get the start value in initialize, save them to instance variables, then do subtraction in isFinished. Or do the equivalent of that in the drivetrain subsystem behind the resetEncoders() and getter methods.