From 7867e906e9bd5a104010c150ead568bf8b507957 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 1 Dec 2017 00:43:11 -0800 Subject: [PATCH] NidecBrushless: Have disable() call PWM.setDisabled(). (#763) This provides a way to stop motor operation even if the DIO is disconnected. Also change Set() to enable the PWM instead of having the constructor do it. Provide an explicit Enable() call to re-enable after Disable() is called. This is different from the other motor controllers (which automatically re-enable when Set() is called) due to the dual-wiring of this motor controller. Motor safety results in disabling the motor only until the next Set() call. --- .../src/main/native/cpp/NidecBrushless.cpp | 34 ++++++++++++++----- .../src/main/native/include/NidecBrushless.h | 4 +++ .../edu/wpi/first/wpilibj/NidecBrushless.java | 27 ++++++++++++--- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/wpilibc/src/main/native/cpp/NidecBrushless.cpp b/wpilibc/src/main/native/cpp/NidecBrushless.cpp index bd9ce72ecd..e81bfe4395 100644 --- a/wpilibc/src/main/native/cpp/NidecBrushless.cpp +++ b/wpilibc/src/main/native/cpp/NidecBrushless.cpp @@ -30,9 +30,6 @@ NidecBrushless::NidecBrushless(int pwmChannel, int dioChannel) m_dio.SetPWMRate(15625); m_dio.EnablePWM(0.5); - // the pwm enables the controller - m_pwm.SetRaw(0xffff); - LiveWindow::GetInstance()->AddActuator("Nidec Brushless", pwmChannel, this); HAL_Report(HALUsageReporting::kResourceType_NidecBrushless, pwmChannel); } @@ -46,8 +43,11 @@ NidecBrushless::NidecBrushless(int pwmChannel, int dioChannel) * @param speed The speed value between -1.0 and 1.0 to set. */ void NidecBrushless::Set(double speed) { - m_speed = speed; - m_dio.UpdateDutyCycle(0.5 + 0.5 * (m_isInverted ? -speed : speed)); + if (!m_disabled) { + m_speed = speed; + m_dio.UpdateDutyCycle(0.5 + 0.5 * (m_isInverted ? -speed : speed)); + m_pwm.SetRaw(0xffff); + } m_safetyHelper.Feed(); } @@ -97,9 +97,13 @@ bool NidecBrushless::IsAlive() const { return m_safetyHelper.IsAlive(); } /** * Stop the motor. This is called by the MotorSafetyHelper object when it has a - * timeout for this PWM and needs to stop it from running. + * timeout for this PWM and needs to stop it from running. Calling Set() will + * re-enable the motor. */ -void NidecBrushless::StopMotor() { Disable(); } +void NidecBrushless::StopMotor() { + m_dio.UpdateDutyCycle(0.5); + m_pwm.SetDisabled(); +} /** * Check if motor safety is enabled. @@ -118,7 +122,21 @@ void NidecBrushless::GetDescription(llvm::raw_ostream& desc) const { desc << "Nidec " << GetChannel(); } -void NidecBrushless::Disable() { m_dio.UpdateDutyCycle(0.5); } +/** + * Disable the motor. The Enable() function must be called to re-enable + * the motor. + */ +void NidecBrushless::Disable() { + m_disabled = true; + m_dio.UpdateDutyCycle(0.5); + m_pwm.SetDisabled(); +} + +/** + * Re-enable the motor after Disable() has been called. The Set() + * function must be called to set a new motor speed. + */ +void NidecBrushless::Enable() { m_disabled = false; } /** * Gets the channel number associated with the object. diff --git a/wpilibc/src/main/native/include/NidecBrushless.h b/wpilibc/src/main/native/include/NidecBrushless.h index b6dcd82242..9a80da5a70 100644 --- a/wpilibc/src/main/native/include/NidecBrushless.h +++ b/wpilibc/src/main/native/include/NidecBrushless.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include @@ -38,6 +39,8 @@ class NidecBrushless : public SpeedController, void Disable() override; void StopMotor() override; + void Enable(); + // PIDOutput interface void PIDWrite(double output) override; @@ -63,6 +66,7 @@ class NidecBrushless : public SpeedController, private: MotorSafetyHelper m_safetyHelper; bool m_isInverted = false; + std::atomic_bool m_disabled{false}; DigitalOutput m_dio; PWM m_pwm; double m_speed = 0.0; diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/NidecBrushless.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/NidecBrushless.java index 98980b1330..405ca014b7 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/NidecBrushless.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/NidecBrushless.java @@ -24,6 +24,7 @@ public class NidecBrushless implements SpeedController, MotorSafety, LiveWindowS private DigitalOutput m_dio; private PWM m_pwm; private volatile double m_speed = 0.0; + private volatile boolean m_disabled = false; /** * Constructor. @@ -45,7 +46,6 @@ public class NidecBrushless implements SpeedController, MotorSafety, LiveWindowS // the pwm enables the controller m_pwm = new PWM(pwmChannel); - m_pwm.setRaw(0xffff); LiveWindow.addActuator("Nidec Brushless", pwmChannel, this); HAL.report(tResourceType.kResourceType_NidecBrushless, pwmChannel); @@ -61,8 +61,11 @@ public class NidecBrushless implements SpeedController, MotorSafety, LiveWindowS */ @Override public void set(double speed) { - m_speed = speed; - m_dio.updateDutyCycle(0.5 + 0.5 * (m_isInverted ? -speed : speed)); + if (!m_disabled) { + m_speed = speed; + m_dio.updateDutyCycle(0.5 + 0.5 * (m_isInverted ? -speed : speed)); + m_pwm.setRaw(0xffff); + } m_safetyHelper.feed(); } @@ -129,10 +132,12 @@ public class NidecBrushless implements SpeedController, MotorSafety, LiveWindowS /** * Stop the motor. This is called by the MotorSafetyHelper object * when it has a timeout for this PWM and needs to stop it from running. + * Calling set() will re-enable the motor. */ @Override public void stopMotor() { - disable(); + m_dio.updateDutyCycle(0.5); + m_pwm.setDisabled(); } /** @@ -155,9 +160,23 @@ public class NidecBrushless implements SpeedController, MotorSafety, LiveWindowS return "Nidec " + getChannel(); } + /** + * Disable the motor. The enable() function must be called to re-enable + * the motor. + */ @Override public void disable() { + m_disabled = true; m_dio.updateDutyCycle(0.5); + m_pwm.setDisabled(); + } + + /** + * Re-enable the motor after disable() has been called. The set() + * function must be called to set a new motor speed. + */ + public void enable() { + m_disabled = false; } /**