Over the past few years there have been a few discussions here about DifferentialDrive... Output not updated often enough errors
. Sometimes they are the result of programming mistakes; sometimes they seem more fundamental.
For example consider the following situation. I want to run a driving command that drives until a specific condition is achieved (for example, reaching the end of a trajectory). Simultaneously I want to aim a turret. The time taken for both of these commands is unknown. I have a default command for the DifferentialDrive subsystem that causes it to stop in the absence of operator joystick input; and MotorSafety is enabled on the DifferentialDrive subsystem.
Let’s name a few things:
NormalDriving
– the default drivebase Command; never finishes; feeds 0 to motors in absence of driver input.
DriveTrajectory
– a Command that drives the trajectory; finishes when the end of the trajectory is reached; requires drivebase
AimTurret
– the Command that aims the turret; finishes when the turret is aimed; requires turret
PCG
- ParallelCommandGroup, SCG
- SequentialCommandGroup, PRG
- ParallelRaceGroup
How do I do DriveTrajectory
and AimTurret
simultaneously? I put them in a parallel command group, right?
doBothCommand1 = new PCG(DriveTrajectory, AimTurret).
doBothCommand1
is a command that requires the turret and the drivebase and ends when both commands’ finish conditions have been met. Unfortunately, it is also a command that leaves the drivebase watchdog unfed if the DriveTrajectory
command ends before the AimTurret
command does: because doBothCommand1
is the scheduled command for the drivebase until AimTurret
finishes, DriveNormal
(the drivebase’s default command) does not get scheduled on the Drivebase. And so, a DifferentialDrive... Output not updated often enough
error occurs. If I were to enable MotorSafety for the turret subsystem, it would pretty much be guaranteed that I would get Output not updated often enough
for one subsystem or the other whenever I ran doBothCommand1
.
So how can this be avoided (assuming I’m not willing to disable MotorSafety for the drivebase)? I apparently need to put a NormalDriving
command after the DriveTrajectory
. So let’s consider
doBothCommand2 = new PCG(new SCG(DriveTrajectory, DriveNormal), AimTurret)
doBothCommand2
doesn’t cause an Output not updated often enough
error; but it also doesn’t work – since DriveNormal
never finishes, the parallel command group never finishes.
How about
doBothCommand3 = new SCG(new PRG(DriveTrajectory, AimTurret), new PRG(DriveNormal, AimTurret))
That works if AimTurret
takes longer than DriveTrajectory
, but does not work if DriveTrajectory
takes longer (driving is interrupted before reaching the destination).
So, am I missing something obvious from the (new) Command framework that would let me solve this problem? And if not, what additional/different functionality could be made part of the Command framework to provide a solution for this, I believe fairly common, use case? And what if MotorSafety is enabled on the turret as well. (And as I said above, I don’t consider turning off MotorSafety a solution).
For now, tolerating the errors seems to be the best approach. When the MotorSafety reports the error it also turns off the motors which is exactly what is required. It’s just that it shouldn’t be a reported error in this case.