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.hal.FRCNetComm.tResourceType; 008import edu.wpi.first.hal.HAL; 009import edu.wpi.first.util.sendable.Sendable; 010import edu.wpi.first.util.sendable.SendableBuilder; 011import edu.wpi.first.util.sendable.SendableRegistry; 012import edu.wpi.first.wpilibj.DigitalOutput; 013import edu.wpi.first.wpilibj.MotorSafety; 014import edu.wpi.first.wpilibj.PWM; 015 016/** Nidec Brushless Motor. */ 017@SuppressWarnings("removal") 018public class NidecBrushless extends MotorSafety 019 implements MotorController, Sendable, AutoCloseable { 020 private boolean m_isInverted; 021 private final DigitalOutput m_dio; 022 private final PWM m_pwm; 023 private volatile double m_speed; 024 private volatile boolean m_disabled; 025 026 /** 027 * Constructor. 028 * 029 * @param pwmChannel The PWM channel that the Nidec Brushless controller is attached to. 0-9 are 030 * on-board, 10-19 are on the MXP port 031 * @param dioChannel The DIO channel that the Nidec Brushless controller is attached to. 0-9 are 032 * on-board, 10-25 are on the MXP port 033 */ 034 @SuppressWarnings("this-escape") 035 public NidecBrushless(final int pwmChannel, final int dioChannel) { 036 setSafetyEnabled(false); 037 038 // the dio controls the output (in PWM mode) 039 m_dio = new DigitalOutput(dioChannel); 040 SendableRegistry.addChild(this, m_dio); 041 m_dio.setPWMRate(15625); 042 m_dio.enablePWM(0.5); 043 044 // the pwm enables the controller 045 m_pwm = new PWM(pwmChannel); 046 SendableRegistry.addChild(this, m_pwm); 047 048 HAL.report(tResourceType.kResourceType_NidecBrushless, pwmChannel + 1); 049 SendableRegistry.addLW(this, "Nidec Brushless", pwmChannel); 050 } 051 052 @Override 053 public void close() { 054 SendableRegistry.remove(this); 055 m_dio.close(); 056 m_pwm.close(); 057 } 058 059 /** 060 * Set the PWM value. 061 * 062 * <p>The PWM value is set using a range of -1.0 to 1.0, appropriately scaling the value for the 063 * FPGA. 064 * 065 * @param speed The speed value between -1.0 and 1.0 to set. 066 */ 067 @Override 068 public void set(double speed) { 069 if (!m_disabled) { 070 m_speed = speed; 071 m_dio.updateDutyCycle(0.5 + 0.5 * (m_isInverted ? -speed : speed)); 072 m_pwm.setAlwaysHighMode(); 073 } 074 075 feed(); 076 } 077 078 /** 079 * Get the recently set value of the PWM. 080 * 081 * @return The most recently set value for the PWM between -1.0 and 1.0. 082 */ 083 @Override 084 public double get() { 085 return m_speed; 086 } 087 088 @Override 089 public void setInverted(boolean isInverted) { 090 m_isInverted = isInverted; 091 } 092 093 @Override 094 public boolean getInverted() { 095 return m_isInverted; 096 } 097 098 /** 099 * Stop the motor. This is called by the MotorSafety object when it has a timeout for this PWM and 100 * needs to stop it from running. Calling set() will re-enable the motor. 101 */ 102 @Override 103 public void stopMotor() { 104 m_dio.updateDutyCycle(0.5); 105 m_pwm.setDisabled(); 106 } 107 108 @Override 109 public String getDescription() { 110 return "Nidec " + getChannel(); 111 } 112 113 /** Disable the motor. The enable() function must be called to re-enable the motor. */ 114 @Override 115 public void disable() { 116 m_disabled = true; 117 m_dio.updateDutyCycle(0.5); 118 m_pwm.setDisabled(); 119 } 120 121 /** 122 * Re-enable the motor after disable() has been called. The set() function must be called to set a 123 * new motor speed. 124 */ 125 public void enable() { 126 m_disabled = false; 127 } 128 129 /** 130 * Gets the channel number associated with the object. 131 * 132 * @return The channel number. 133 */ 134 public int getChannel() { 135 return m_pwm.getChannel(); 136 } 137 138 @Override 139 public void initSendable(SendableBuilder builder) { 140 builder.setSmartDashboardType("Nidec Brushless"); 141 builder.setActuator(true); 142 builder.setSafeState(this::stopMotor); 143 builder.addDoubleProperty("Value", this::get, this::set); 144 } 145}