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