I am working with c++ for Titan motor controller. And there is a small problem with ParallelCommandGroup. In fact this function should work in parallel, so it shoul work with motors like that. But for our code it makes problems

llegal use of Command: Multiple commands in a parallel group cannot require the same subsystems  AddCommands [ParallelCommandGroup.cpp:79]

You can’t reuse command instances. Create new objects for each instead.

Also, when asking for code help, please share your code as well (ideally as a link to github or similar)

This message means that you have more than one command object that is trying to simultaneously control the same hardware subsystem.

For example, if you have a command that expects to control your drivetrain, it will have a statement that “requires” the drivetrain subsystem object. This indicates to the runtime that the command expects to have exclusive control over the subsystem while it is running.

If you try to execute parallel Commands, no two of them can be trying to require the same subsystem, or else they would be attempting to have exclusive control over the same subsystem at the same time.

If the Commands are capable of sharing the subsystem then they should not require it. If they need to have exclusive control of the subsystem then you cannot execute the commands in parallel.

If you post a link to your code, people here can offer more specific advice.

This code works of course but for parallel motors when I add 2 motors in it it may works only one motor. But we all know that parallelcommandgroup should work in this situation but it does not work. Here is a code!

#include “commands/Multiple.h”
#include “commands/robotCommands/MotorPid0.h”
#include “commands/robotCommands/MotorPid1.h”
#include “commands/robotCommands/MotorPid2.h”
#include “commands/robotCommands/DriveServo.h”
#include <frc2/command/WaitCommand.h>
#include <frc2/command/ParallelRaceGroup.h>
#include <frc2/command/ParallelCommandGroup.h>

Multiple::Multiple(DriveTrain* driveTrain)
{
AddCommands
(
//MotorPid0(driveTrain, 1000, 10).WithTimeout(5.0_s), //Drive forward 1M

    // frc2::ParallelCommandGroup{ //Run the next commands in parrallel
    //      MotorPid1(driveTrain, 1000, 10),   //Drive forward 1M
    //      MotorPid2(driveTrain, 1000, 10),
    //      },

    // frc2::WaitCommand(3.0_s),  //Wait 3 seconds

    frc2::ParallelCommandGroup{ //Run the next commands in parrallel
         MotorPid2(driveTrain, 1000, 10).WithTimeout(3.0_s),
         MotorPid1(driveTrain, 1000, 10).WithTimeout(4.0_s)
      }
);

}

The problem is likely to be in the implementation of your MotorPid1 and MotorPid2 command definitions. I suspect that both commands are requiring your drivetrain even though each command is only controlling half of it.

You probably need to restructure these operations, and perhaps combine them into a single command?

If you want the two control operations to happen one after the other, you should be using a SequentialCommandGroup instead of the ParallelCommandGroup.

Our error is not in sequence. We need to run two motors in parallel. This means we need to be able to command each motor separately. For example, we need to be able to turn the first motor to the right and the second motor to the left, and this movement should be in parallel, not in series.

I can add that this written code works only in separately, it only reads the first line of code in parallelcommandgroup, it cannot read the second line.

Understood. The issue I believe you are having (but I can’t be sure without seeing more of your code) is that both of your commands are telling the runtime that they need to have exclusive control over the entire drivetrain - including the other motor.

Think of “requires” like checking out a library book. If your MotorPid1 Command tells the runtime that it “requires” the drivetrain, then no other command is allowed to also require the drivetrain at the same time. Your robot code is warning you that two commands are claiming exclusive control over the same set of motors.

You either need to combine the control of both sides of your drivetrain into a single command, or you need to split your drivetrain subsystem into two separate subsystems (one for each side) and then only “require” one half in each command.

2 Likes

Adding to this, commands shouldnt care (or even know about) specific motors. Let the subsystem worry about that.

To use a rough example, your drivetrain can know that youre using SparkMax controllers (or TalonSRX, or TalonFX, etc), but your command should simply tell your subsystem to drive in a given direction/speed. Your subsystem can then choose how to apply that to the motors (could be via PID setpoints, direct fractional values, etc)

3 Likes

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.