I am looking to add a super simple autonomous to a new team. So I created something like:
public void driveTime(double time, double speed) {
m_talonsrxleft.set(speed);
m_talonsrxright.set(speed);
new WaitCommand(time);
m_talonsrxleft.set(0);
m_talonsrxright.set(0);
}
And I call it with code like:
new InstantCommand(() -> m_robotDrive.driveTime(3, .25), m_robotDrive)
It however does nothing. They don’t have a differential drive so I wouldn’t expect to need to feed the motor safety. It seems to me that the default command that is using the joysticks to control the drive is interrupting this but I can’t understand why? What can I do to keep the default command from interrupting this if that is indeed the problem?
Default commands will never interrupt another command. They will, however, fight other commands for motors if you bypass the resource management system and have multiple commands accessing the same motors. The solution to this is to correctly declare command requirements.
Oh, I had thought you were calling that method in your autonomous routine directly.
The method you’ve written will not work; instantiating a command is not the same as scheduling a command. You need to write a command group. I suggest reading through the command-based documentation.
To create small reusable snippets (as it seems you’re trying to do), the best way we’ve found is to create a function that returns a new Command as specified. Something like this is helpful:
public Command driveTime(double speed, double time){
return
new RunCommand(() -> {m_talonsrxleft.set(speed); m_talonsrxright.set(speed);})
.withTimeout(time)
.andThen(new InstantCommand(() -> {m_talonsrxleft.set(speed); m_talonsrxright.set(speed);}))
;
}
Since this builds a new command sequence which drives forward (while continously updating the motors), times out at the specific time, then stops the motors. You can then use it directly in an auto by going to RobotContainer and putting this in getAutonomousCommand as shown here:
public Command getAutonomousCommand() {
return driveTime(3, 025) ;
}
Because driveTime(time,speed) returns a new Command instance, you can use it anywhere you would want a command, including in CommandGroups.
Regarding motor safety, as I understand it_all_ motors will time out and stop when not updated. This can be disabled in unofficial play using some specific functions, but such functions are not allowed in official matches, and you’ll just see a robot fail in unexpected ways.
I am fairly certain this is not true. From what I have heard the safety is purely a “feature” of differential drive and can be disabled at will. Am I wrong?
You very well could be correct on this, as we’ve never explicitly tested or relied on this behavior. Our team’s policy is to actively set all motors per loop, even if it’s just to 0. Motor Safety stuff also could be something from days of yore when we drove all motors via PWM that no longer applies to the off-board controllers.
The MotorSafety feature runs per motor, but objects such as DifferentialDrive update all the MotorSafety objects for each of its motors when either feed() is called, or some other drive method which calls feed() is called. Only motors which have not been feed will be stopped when they expire. If there is some other instance of DifferentialDrive or WPI_TalonSRX (which implements the MotorSafety), those will not be affected unless they also have timed out.
Regarding official/unofficial match behavior, there are no restrictions on what you can do in a match vs out of a match regarding software. You are allowed to turn the Motor Safety features off during match gameplay.
The only difference between official and unofficial matches, is that you will have the FMS connected to your DriverStation (not robot) which will provide extra match information and, of course, enable/disable & switch modes.
FMS has nothing to do with motor safety. You can enable it or disable it till your hearts content.
MotorSafety is a feature of the WPILib SpeedController class. It is disabled by default on all WPILib pure speed controllers but enabled on DifferentialDrive. However, different vendors have the ability to enable it by default on their libraries.