Hi! We are trying to create some auto mode code but we keep getting a “WARNING: wpilib.motorsafety : Robot Drive… Output not updating often enough”. We are using a string of elif statements with the auto counter to avoid using for loops and while loops.
if self.auto_loop_counter<=25:
self.non_existant_motor.set(-.5)
self.sol.set(True)
self.auto_loop_counter+=1
elif self.auto_loop_counter <= 100 and self.auto_loop_counter>25:
self.robot_drive.drive(-0.5, 0) # Drive forwards at half speed
self.auto_loop_counter += 1
self.sol.set(False)
self.non_existant_motor.set(0)
else:
self.robot_drive.drive(0, 0)
We have many more elifs then that but that is the basic framework of our code. Any help will be greatly appreciated!
Robot drive not updated often enough is an error you’ll receive when your code isn’t executing in a short enough amount of time. Don’t quote me on it, but I think you’ll receive the error if your code doesn’t send a control message to the robot every 100ms.
Why are you trying to avoid for and while loops?
The code that prints this error is in motorsafety.py and looks like this
def check(self):
"""Check if this motor has exceeded its timeout.
This method is called periodically to determine if this motor has
exceeded its timeout value. If it has, the stop method is called,
and the motor is shut down until its value is updated again.
"""
if not self.safetyEnabled or RobotState.isDisabled() or RobotState.isTest():
return
if self.safetyStopTime < Timer.getFPGATimestamp():
logger.warn("%s... Output not updated often enough." %
self.getDescription())
self.stopMotor()
It looks like SafePWM (the base class for Victor and Talon) inherits this class. So, basically, if you don’t call .set() on your motor controller object periodically it will assume your code has run away from you and stop that particular motor. The default timeout is 0.1 seconds.
Your auto code is only calling robot_drive.drive in some parts of the if structure. Therefore, the set method on those speed controllers isn’t being called, hence this message printing.
You can fix this by:
- Disabling motor safety by calling setSafetyEnabled on the motor object
- Calling set on each motor in each iteration. I suggest something like the following:
non_e_motor_out = 0
drive_out = (0,0)
if self.auto_loop_counter<=25:
non_e_motor_out = -.5 #
self.sol.set(True)
self.auto_loop_counter+=1
elif self.auto_loop_counter <= 100 and self.auto_loop_counter>25:
drive_out = (-0.5, 0) # Drive forwards at half speed
self.auto_loop_counter += 1
self.sol.set(False)
self.non_existant_motor.set(0)
self.robot_drive.drive(drive_out[0], drive_out[1])
self.non_existant_motor.set(non_e_motor_out)
Thanks to both of you and I will try out that code as soon as I can!
Hopefully you run your code through the simulator… right?
Definitely make sure you run your autonomous through the simulator, it’ll show things like that and you can fix them there before putting it on the robot.
Additionally, don’t forget that there’s a really simple autonomous framework you can use in python. Check it out: http://robotpy-wpilib-utilities.readthedocs.org/en/latest/robotpy_ext.autonomous.html#module-robotpy_ext.autonomous.stateful_autonomous
Also, I just uploaded a sample of the autonomous framework, if you want to play with it. Very simple to use, and a great way to manage simple state machines for autonomous mode.
https://github.com/robotpy/robotpy-wpilib-utilities/tree/master/samples