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