mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-29 02:21:44 +00:00
[hal, wpilib] PWM Rewrite (#7845)
The HAL will only contain the output period and the raw microseconds. Higher level things such as SimDevice can handle everything else.
This commit is contained in:
@@ -27,21 +27,21 @@ class PWM : public wpi::Sendable, public wpi::SendableHelper<PWM> {
|
||||
public:
|
||||
friend class AddressableLED;
|
||||
/**
|
||||
* Represents the amount to multiply the minimum servo-pulse pwm period by.
|
||||
* Represents the output period in microseconds.
|
||||
*/
|
||||
enum PeriodMultiplier {
|
||||
enum OutputPeriod {
|
||||
/**
|
||||
* Don't skip pulses. PWM pulses occur every 5.05 ms
|
||||
* PWM pulses occur every 5 ms
|
||||
*/
|
||||
kPeriodMultiplier_1X = 1,
|
||||
kOutputPeriod_5Ms = 1,
|
||||
/**
|
||||
* Skip every other pulse. PWM pulses occur every 10.10 ms
|
||||
* PWM pulses occur every 10 ms
|
||||
*/
|
||||
kPeriodMultiplier_2X = 2,
|
||||
kOutputPeriod_10Ms = 2,
|
||||
/**
|
||||
* Skip three out of four pulses. PWM pulses occur every 20.20 ms
|
||||
* PWM pulses occur every 20 ms
|
||||
*/
|
||||
kPeriodMultiplier_4X = 4
|
||||
kOutputPeriod_20Ms = 4
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -74,7 +74,7 @@ class PWM : public wpi::Sendable, public wpi::SendableHelper<PWM> {
|
||||
*
|
||||
* @param time Microsecond PWM value.
|
||||
*/
|
||||
virtual void SetPulseTime(units::microsecond_t time);
|
||||
void SetPulseTime(units::microsecond_t time);
|
||||
|
||||
/**
|
||||
* Get the PWM pulse time directly from the hardware.
|
||||
@@ -83,122 +83,30 @@ class PWM : public wpi::Sendable, public wpi::SendableHelper<PWM> {
|
||||
*
|
||||
* @return Microsecond PWM control value.
|
||||
*/
|
||||
virtual units::microsecond_t GetPulseTime() const;
|
||||
|
||||
/**
|
||||
* Set the PWM value based on a position.
|
||||
*
|
||||
* This is intended to be used by servos.
|
||||
*
|
||||
* @pre SetBounds() called.
|
||||
*
|
||||
* @param pos The position to set the servo between 0.0 and 1.0.
|
||||
*/
|
||||
virtual void SetPosition(double pos);
|
||||
|
||||
/**
|
||||
* Get the PWM value in terms of a position.
|
||||
*
|
||||
* This is intended to be used by servos.
|
||||
*
|
||||
* @pre SetBounds() called.
|
||||
*
|
||||
* @return The position the servo is set to between 0.0 and 1.0.
|
||||
*/
|
||||
virtual double GetPosition() const;
|
||||
|
||||
/**
|
||||
* Set the PWM value based on a speed.
|
||||
*
|
||||
* This is intended to be used by motor controllers.
|
||||
*
|
||||
* @pre SetBounds() called.
|
||||
*
|
||||
* @param speed The speed to set the motor controller between -1.0 and 1.0.
|
||||
*/
|
||||
virtual void SetSpeed(double speed);
|
||||
|
||||
/**
|
||||
* Get the PWM value in terms of speed.
|
||||
*
|
||||
* This is intended to be used by motor controllers.
|
||||
*
|
||||
* @pre SetBounds() called.
|
||||
*
|
||||
* @return The most recently set speed between -1.0 and 1.0.
|
||||
*/
|
||||
virtual double GetSpeed() const;
|
||||
units::microsecond_t GetPulseTime() const;
|
||||
|
||||
/**
|
||||
* Temporarily disables the PWM output. The next set call will re-enable
|
||||
* the output.
|
||||
*/
|
||||
virtual void SetDisabled();
|
||||
void SetDisabled();
|
||||
|
||||
/**
|
||||
* Slow down the PWM signal for old devices.
|
||||
* Sets the PWM output period.
|
||||
*
|
||||
* @param mult The period multiplier to apply to this channel
|
||||
* @param mult The output period to apply to this channel
|
||||
*/
|
||||
void SetPeriodMultiplier(PeriodMultiplier mult);
|
||||
|
||||
/**
|
||||
* Latches PWM to zero.
|
||||
*/
|
||||
void SetZeroLatch();
|
||||
|
||||
/**
|
||||
* Optionally eliminate the deadband from a motor controller.
|
||||
*
|
||||
* @param eliminateDeadband If true, set the motor curve on the motor
|
||||
* controller to eliminate the deadband in the middle
|
||||
* of the range. Otherwise, keep the full range
|
||||
* without modifying any values.
|
||||
*/
|
||||
void EnableDeadbandElimination(bool eliminateDeadband);
|
||||
|
||||
/**
|
||||
* Set the bounds on the PWM pulse widths.
|
||||
*
|
||||
* This sets the bounds on the PWM values for a particular type of controller.
|
||||
* The values determine the upper and lower speeds as well as the deadband
|
||||
* bracket.
|
||||
*
|
||||
* @param max The max PWM pulse width in us
|
||||
* @param deadbandMax The high end of the deadband range pulse width in us
|
||||
* @param center The center (off) pulse width in us
|
||||
* @param deadbandMin The low end of the deadband pulse width in us
|
||||
* @param min The minimum pulse width in us
|
||||
*/
|
||||
void SetBounds(units::microsecond_t max, units::microsecond_t deadbandMax,
|
||||
units::microsecond_t center, units::microsecond_t deadbandMin,
|
||||
units::microsecond_t min);
|
||||
|
||||
/**
|
||||
* Get the bounds on the PWM values.
|
||||
*
|
||||
* This gets the bounds on the PWM values for a particular each type of
|
||||
* controller. The values determine the upper and lower speeds as well as the
|
||||
* deadband bracket.
|
||||
*
|
||||
* @param max The maximum pwm value
|
||||
* @param deadbandMax The high end of the deadband range
|
||||
* @param center The center speed (off)
|
||||
* @param deadbandMin The low end of the deadband range
|
||||
* @param min The minimum pwm value
|
||||
*/
|
||||
void GetBounds(units::microsecond_t* max, units::microsecond_t* deadbandMax,
|
||||
units::microsecond_t* center,
|
||||
units::microsecond_t* deadbandMin, units::microsecond_t* min);
|
||||
|
||||
/**
|
||||
* Sets the PWM output to be a continuous high signal while enabled.
|
||||
*
|
||||
*/
|
||||
void SetAlwaysHighMode();
|
||||
void SetOutputPeriod(OutputPeriod mult);
|
||||
|
||||
int GetChannel() const;
|
||||
|
||||
/**
|
||||
* Indicates this input is used by a simulated device.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
*/
|
||||
void SetSimDevice(HAL_SimDeviceHandle device);
|
||||
|
||||
protected:
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
|
||||
@@ -4,20 +4,27 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hal/SimDevice.h>
|
||||
#include <units/angle.h>
|
||||
|
||||
#include "frc/PWM.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
namespace sim {
|
||||
class ServoSim;
|
||||
} // namespace sim
|
||||
|
||||
/**
|
||||
* Standard hobby style servo.
|
||||
*
|
||||
* The range parameters default to the appropriate values for the Hitec HS-322HD
|
||||
* servo provided in the FIRST Kit of Parts in 2008.
|
||||
*/
|
||||
class Servo : public PWM {
|
||||
class Servo : public wpi::Sendable, public wpi::SendableHelper<Servo> {
|
||||
public:
|
||||
friend class frc::sim::ServoSim;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -42,13 +49,6 @@ class Servo : public PWM {
|
||||
*/
|
||||
void Set(double value);
|
||||
|
||||
/**
|
||||
* Set the servo to offline.
|
||||
*
|
||||
* Set the servo raw value to 0 (undriven)
|
||||
*/
|
||||
void SetOffline();
|
||||
|
||||
/**
|
||||
* Get the servo position.
|
||||
*
|
||||
@@ -86,30 +86,27 @@ class Servo : public PWM {
|
||||
*/
|
||||
double GetAngle() const;
|
||||
|
||||
/**
|
||||
* Get the maximum angle of the servo.
|
||||
*
|
||||
* @return The maximum angle of the servo in degrees.
|
||||
*/
|
||||
double GetMaxAngle() const;
|
||||
|
||||
/**
|
||||
* Get the minimum angle of the servo.
|
||||
*
|
||||
* @return The minimum angle of the servo in degrees.
|
||||
*/
|
||||
double GetMinAngle() const;
|
||||
int GetChannel() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
double GetServoAngleRange() const;
|
||||
static double GetServoAngleRange();
|
||||
units::microsecond_t GetFullRangeScaleFactor() const;
|
||||
|
||||
static constexpr double kMaxServoAngle = 180.;
|
||||
static constexpr double kMaxServoAngle = 180.0;
|
||||
static constexpr double kMinServoAngle = 0.0;
|
||||
|
||||
static constexpr units::millisecond_t kDefaultMaxServoPWM = 2.4_ms;
|
||||
static constexpr units::millisecond_t kDefaultMinServoPWM = 0.6_ms;
|
||||
|
||||
units::millisecond_t m_maxPwm = kDefaultMaxServoPWM;
|
||||
units::millisecond_t m_minPwm = kDefaultMinServoPWM;
|
||||
|
||||
hal::SimDevice m_simDevice;
|
||||
hal::SimDouble m_simPosition;
|
||||
|
||||
PWM m_pwm;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <hal/SimDevice.h>
|
||||
#include <units/voltage.h>
|
||||
#include <wpi/deprecated.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
@@ -133,11 +134,35 @@ class PWMMotorController : public MotorController,
|
||||
/// PWM instances for motor controller.
|
||||
PWM m_pwm;
|
||||
|
||||
void SetSpeed(double speed);
|
||||
double GetSpeed() const;
|
||||
|
||||
void SetBounds(units::microsecond_t maxPwm,
|
||||
units::microsecond_t deadbandMaxPwm,
|
||||
units::microsecond_t centerPwm,
|
||||
units::microsecond_t deadbandMinPwm,
|
||||
units::microsecond_t minPwm);
|
||||
|
||||
private:
|
||||
bool m_isInverted = false;
|
||||
std::vector<PWMMotorController*> m_nonowningFollowers;
|
||||
std::vector<std::unique_ptr<PWMMotorController>> m_owningFollowers;
|
||||
|
||||
hal::SimDevice m_simDevice;
|
||||
hal::SimDouble m_simSpeed;
|
||||
|
||||
bool m_eliminateDeadband{0};
|
||||
units::microsecond_t m_minPwm{0};
|
||||
units::microsecond_t m_deadbandMinPwm{0};
|
||||
units::microsecond_t m_centerPwm{0};
|
||||
units::microsecond_t m_deadbandMaxPwm{0};
|
||||
units::microsecond_t m_maxPwm{0};
|
||||
|
||||
units::microsecond_t GetMinPositivePwm() const;
|
||||
units::microsecond_t GetMaxNegativePwm() const;
|
||||
units::microsecond_t GetPositiveScaleFactor() const;
|
||||
units::microsecond_t GetNegativeScaleFactor() const;
|
||||
|
||||
PWM* GetPwm() { return &m_pwm; }
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hal/SimDevice.h>
|
||||
#include <units/length.h>
|
||||
|
||||
#include "frc/motorcontrol/PWMMotorController.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class PWMMotorController;
|
||||
|
||||
namespace sim {
|
||||
|
||||
class PWMMotorControllerSim {
|
||||
public:
|
||||
explicit PWMMotorControllerSim(const PWMMotorController& motorctrl);
|
||||
|
||||
explicit PWMMotorControllerSim(int channel);
|
||||
|
||||
double GetSpeed() const;
|
||||
|
||||
private:
|
||||
hal::SimDouble m_simSpeed;
|
||||
};
|
||||
} // namespace sim
|
||||
} // namespace frc
|
||||
@@ -27,13 +27,6 @@ class PWMSim {
|
||||
*/
|
||||
explicit PWMSim(const PWM& pwm);
|
||||
|
||||
/**
|
||||
* Constructs from a PWMMotorController object.
|
||||
*
|
||||
* @param motorctrl PWMMotorController to simulate
|
||||
*/
|
||||
explicit PWMSim(const PWMMotorController& motorctrl);
|
||||
|
||||
/**
|
||||
* Constructs from a PWM channel number.
|
||||
*
|
||||
@@ -91,56 +84,6 @@ class PWMSim {
|
||||
*/
|
||||
void SetPulseMicrosecond(int32_t microsecondPulseTime);
|
||||
|
||||
/**
|
||||
* Register a callback to be run when the PWM speed changes.
|
||||
*
|
||||
* @param callback the callback
|
||||
* @param initialNotify whether to run the callback with the initial value
|
||||
* @return the CallbackStore object associated with this callback
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::unique_ptr<CallbackStore> RegisterSpeedCallback(NotifyCallback callback,
|
||||
bool initialNotify);
|
||||
|
||||
/**
|
||||
* Get the PWM speed.
|
||||
*
|
||||
* @return the PWM speed (-1.0 to 1.0)
|
||||
*/
|
||||
double GetSpeed() const;
|
||||
|
||||
/**
|
||||
* Set the PWM speed.
|
||||
*
|
||||
* @param speed the PWM speed (-1.0 to 1.0)
|
||||
*/
|
||||
void SetSpeed(double speed);
|
||||
|
||||
/**
|
||||
* Register a callback to be run when the PWM position changes.
|
||||
*
|
||||
* @param callback the callback
|
||||
* @param initialNotify whether to run the callback with the initial value
|
||||
* @return the CallbackStore object associated with this callback
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::unique_ptr<CallbackStore> RegisterPositionCallback(
|
||||
NotifyCallback callback, bool initialNotify);
|
||||
|
||||
/**
|
||||
* Get the PWM position.
|
||||
*
|
||||
* @return the PWM position (0.0 to 1.0)
|
||||
*/
|
||||
double GetPosition() const;
|
||||
|
||||
/**
|
||||
* Set the PWM position.
|
||||
*
|
||||
* @param position the PWM position (0.0 to 1.0)
|
||||
*/
|
||||
void SetPosition(double position);
|
||||
|
||||
/**
|
||||
* Register a callback to be run when the PWM period scale changes.
|
||||
*
|
||||
@@ -149,7 +92,7 @@ class PWMSim {
|
||||
* @return the CallbackStore object associated with this callback
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::unique_ptr<CallbackStore> RegisterPeriodScaleCallback(
|
||||
std::unique_ptr<CallbackStore> RegisterOutputPeriodCallback(
|
||||
NotifyCallback callback, bool initialNotify);
|
||||
|
||||
/**
|
||||
@@ -157,39 +100,14 @@ class PWMSim {
|
||||
*
|
||||
* @return the PWM period scale
|
||||
*/
|
||||
int GetPeriodScale() const;
|
||||
int GetOutputPeriod() const;
|
||||
|
||||
/**
|
||||
* Set the PWM period scale.
|
||||
*
|
||||
* @param periodScale the PWM period scale
|
||||
* @param period the PWM period scale
|
||||
*/
|
||||
void SetPeriodScale(int periodScale);
|
||||
|
||||
/**
|
||||
* Register a callback to be run when the PWM zero latch state changes.
|
||||
*
|
||||
* @param callback the callback
|
||||
* @param initialNotify whether to run the callback with the initial state
|
||||
* @return the CallbackStore object associated with this callback
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::unique_ptr<CallbackStore> RegisterZeroLatchCallback(
|
||||
NotifyCallback callback, bool initialNotify);
|
||||
|
||||
/**
|
||||
* Check whether the PWM is zero latched.
|
||||
*
|
||||
* @return true if zero latched
|
||||
*/
|
||||
bool GetZeroLatch() const;
|
||||
|
||||
/**
|
||||
* Define whether the PWM has been zero latched.
|
||||
*
|
||||
* @param zeroLatch true to indicate zero latched
|
||||
*/
|
||||
void SetZeroLatch(bool zeroLatch);
|
||||
void SetOutputPeriod(int period);
|
||||
|
||||
/**
|
||||
* Reset all simulation data.
|
||||
|
||||
31
wpilibc/src/main/native/include/frc/simulation/ServoSim.h
Normal file
31
wpilibc/src/main/native/include/frc/simulation/ServoSim.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hal/SimDevice.h>
|
||||
#include <units/length.h>
|
||||
|
||||
#include "frc/Servo.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class Servo;
|
||||
|
||||
namespace sim {
|
||||
class ServoSim {
|
||||
public:
|
||||
explicit ServoSim(const Servo& servo);
|
||||
|
||||
explicit ServoSim(int channel);
|
||||
|
||||
double GetPosition() const;
|
||||
|
||||
double GetAngle() const;
|
||||
|
||||
private:
|
||||
hal::SimDouble m_simPosition;
|
||||
};
|
||||
} // namespace sim
|
||||
} // namespace frc
|
||||
Reference in New Issue
Block a user