001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj.motorcontrol; 006 007import edu.wpi.first.util.sendable.Sendable; 008import edu.wpi.first.util.sendable.SendableBuilder; 009import edu.wpi.first.util.sendable.SendableRegistry; 010import java.util.Arrays; 011 012/** 013 * Allows multiple {@link MotorController} objects to be linked together. 014 * 015 * @deprecated Use {@link PWMMotorController#addFollower(PWMMotorController)} or if using CAN motor 016 * controllers, use their method of following. 017 */ 018@SuppressWarnings("removal") 019@Deprecated(forRemoval = true, since = "2024") 020public class MotorControllerGroup implements MotorController, Sendable, AutoCloseable { 021 private boolean m_isInverted; 022 private final MotorController[] m_motorControllers; 023 private static int instances; 024 025 /** 026 * Create a new MotorControllerGroup with the provided MotorControllers. 027 * 028 * @param motorController The first MotorController to add 029 * @param motorControllers The MotorControllers to add 030 */ 031 @SuppressWarnings("this-escape") 032 public MotorControllerGroup( 033 MotorController motorController, MotorController... motorControllers) { 034 m_motorControllers = new MotorController[motorControllers.length + 1]; 035 m_motorControllers[0] = motorController; 036 System.arraycopy(motorControllers, 0, m_motorControllers, 1, motorControllers.length); 037 init(); 038 } 039 040 /** 041 * Create a new MotorControllerGroup with the provided MotorControllers. 042 * 043 * @param motorControllers The MotorControllers to add. 044 */ 045 @SuppressWarnings("this-escape") 046 public MotorControllerGroup(MotorController[] motorControllers) { 047 m_motorControllers = Arrays.copyOf(motorControllers, motorControllers.length); 048 init(); 049 } 050 051 private void init() { 052 for (MotorController controller : m_motorControllers) { 053 SendableRegistry.addChild(this, controller); 054 } 055 instances++; 056 SendableRegistry.addLW(this, "MotorControllerGroup", instances); 057 } 058 059 @Override 060 public void close() { 061 SendableRegistry.remove(this); 062 } 063 064 @Override 065 public void set(double speed) { 066 for (MotorController motorController : m_motorControllers) { 067 motorController.set(m_isInverted ? -speed : speed); 068 } 069 } 070 071 @Override 072 public void setVoltage(double outputVolts) { 073 for (MotorController motorController : m_motorControllers) { 074 motorController.setVoltage(m_isInverted ? -outputVolts : outputVolts); 075 } 076 } 077 078 @Override 079 public double get() { 080 if (m_motorControllers.length > 0) { 081 return m_motorControllers[0].get() * (m_isInverted ? -1 : 1); 082 } 083 return 0.0; 084 } 085 086 @Override 087 public void setInverted(boolean isInverted) { 088 m_isInverted = isInverted; 089 } 090 091 @Override 092 public boolean getInverted() { 093 return m_isInverted; 094 } 095 096 @Override 097 public void disable() { 098 for (MotorController motorController : m_motorControllers) { 099 motorController.disable(); 100 } 101 } 102 103 @Override 104 public void stopMotor() { 105 for (MotorController motorController : m_motorControllers) { 106 motorController.stopMotor(); 107 } 108 } 109 110 @Override 111 public void initSendable(SendableBuilder builder) { 112 builder.setSmartDashboardType("Motor Controller"); 113 builder.setActuator(true); 114 builder.setSafeState(this::stopMotor); 115 builder.addDoubleProperty("Value", this::get, this::set); 116 } 117}