Generally, when using the command-based framework, you instantiate things like speed controllers in the owning subsystem, so that they can be kept hidden from other subsystems. This makes it easier to reason about the subsystem, because you know that all of the logic impacting the motor is in front of you in one file.
3081 commonly creates a special SensorSubsystem that is the owner of nearly all of the sensors on the robot. SensorSubsystem has methods on it that allow other subsystems and commands to read sensor values. For example, suppose your elevator has a limit switch when your traveler is at the lowest desired position.
In the SensorSubsystem, you'd say something like (note C++ here, not Java):
Code:
this->elevatorLowLimit = new DigitalInput(ELEVATOR_LIMIT_LOW);
and have a method like this:
Code:
bool SensorSubsystem::IsElevatorAtLowLimit() {
return this->towerLowLimit->Get();
}
Then code in other subsystems/commands would say:
Code:
if (sensorSubsystem->IsElevatorAtLowLimit() {
// turn off motor, or whatever
}