mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-05 03:21:42 +00:00
SCRIPT Move cc files
This commit is contained in:
committed by
Peter Johnson
parent
10b4a0c971
commit
7ca1be9bae
@@ -0,0 +1,160 @@
|
||||
// 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 <networktables/NTSendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/I2C.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* ADXL345 Accelerometer on I2C.
|
||||
*
|
||||
* This class allows access to a Analog Devices ADXL345 3-axis accelerometer on
|
||||
* an I2C bus. This class assumes the default (not alternate) sensor address of
|
||||
* 0x1D (7-bit address).
|
||||
*/
|
||||
class ADXL345_I2C : public nt::NTSendable,
|
||||
public wpi::SendableHelper<ADXL345_I2C> {
|
||||
public:
|
||||
/**
|
||||
* Accelerometer range.
|
||||
*/
|
||||
enum Range {
|
||||
/// 2 Gs max.
|
||||
kRange_2G = 0,
|
||||
/// 4 Gs max.
|
||||
kRange_4G = 1,
|
||||
/// 8 Gs max.
|
||||
kRange_8G = 2,
|
||||
/// 16 Gs max.
|
||||
kRange_16G = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Accelerometer axes.
|
||||
*/
|
||||
enum Axes {
|
||||
/// X axis.
|
||||
kAxis_X = 0x00,
|
||||
/// Y axis.
|
||||
kAxis_Y = 0x02,
|
||||
/// Z axis.
|
||||
kAxis_Z = 0x04
|
||||
};
|
||||
|
||||
/**
|
||||
* Container type for accelerations from all axes.
|
||||
*/
|
||||
struct AllAxes {
|
||||
/// Acceleration along the X axis in g-forces.
|
||||
double XAxis = 0.0;
|
||||
/// Acceleration along the Y axis in g-forces.
|
||||
double YAxis = 0.0;
|
||||
/// Acceleration along the Z axis in g-forces.
|
||||
double ZAxis = 0.0;
|
||||
};
|
||||
|
||||
/// Default I2C device address.
|
||||
static constexpr int kAddress = 0x1D;
|
||||
|
||||
/**
|
||||
* Constructs the ADXL345 Accelerometer over I2C.
|
||||
*
|
||||
* @param port The I2C port the accelerometer is attached to
|
||||
* @param range The range (+ or -) that the accelerometer will measure
|
||||
* @param deviceAddress The I2C address of the accelerometer (0x1D or 0x53)
|
||||
*/
|
||||
explicit ADXL345_I2C(I2C::Port port, Range range = kRange_2G,
|
||||
int deviceAddress = kAddress);
|
||||
~ADXL345_I2C() override = default;
|
||||
|
||||
ADXL345_I2C(ADXL345_I2C&&) = default;
|
||||
ADXL345_I2C& operator=(ADXL345_I2C&&) = default;
|
||||
|
||||
I2C::Port GetI2CPort() const;
|
||||
int GetI2CDeviceAddress() const;
|
||||
|
||||
/**
|
||||
* Set the measuring range of the accelerometer.
|
||||
*
|
||||
* @param range The maximum acceleration, positive or negative, that the
|
||||
* accelerometer will measure.
|
||||
*/
|
||||
void SetRange(Range range);
|
||||
|
||||
/**
|
||||
* Returns the acceleration along the X axis in g-forces.
|
||||
*
|
||||
* @return The acceleration along the X axis in g-forces.
|
||||
*/
|
||||
double GetX();
|
||||
|
||||
/**
|
||||
* Returns the acceleration along the Y axis in g-forces.
|
||||
*
|
||||
* @return The acceleration along the Y axis in g-forces.
|
||||
*/
|
||||
double GetY();
|
||||
|
||||
/**
|
||||
* Returns the acceleration along the Z axis in g-forces.
|
||||
*
|
||||
* @return The acceleration along the Z axis in g-forces.
|
||||
*/
|
||||
double GetZ();
|
||||
|
||||
/**
|
||||
* Get the acceleration of one axis in Gs.
|
||||
*
|
||||
* @param axis The axis to read from.
|
||||
* @return Acceleration of the ADXL345 in Gs.
|
||||
*/
|
||||
virtual double GetAcceleration(Axes axis);
|
||||
|
||||
/**
|
||||
* Get the acceleration of all axes in Gs.
|
||||
*
|
||||
* @return An object containing the acceleration measured on each axis of the
|
||||
* ADXL345 in Gs.
|
||||
*/
|
||||
virtual AllAxes GetAccelerations();
|
||||
|
||||
void InitSendable(nt::NTSendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
I2C m_i2c;
|
||||
|
||||
hal::SimDevice m_simDevice;
|
||||
hal::SimEnum m_simRange;
|
||||
hal::SimDouble m_simX;
|
||||
hal::SimDouble m_simY;
|
||||
hal::SimDouble m_simZ;
|
||||
|
||||
static constexpr int kPowerCtlRegister = 0x2D;
|
||||
static constexpr int kDataFormatRegister = 0x31;
|
||||
static constexpr int kDataRegister = 0x32;
|
||||
static constexpr double kGsPerLSB = 0.00390625;
|
||||
|
||||
enum PowerCtlFields {
|
||||
kPowerCtl_Link = 0x20,
|
||||
kPowerCtl_AutoSleep = 0x10,
|
||||
kPowerCtl_Measure = 0x08,
|
||||
kPowerCtl_Sleep = 0x04
|
||||
};
|
||||
|
||||
enum DataFormatFields {
|
||||
kDataFormat_SelfTest = 0x80,
|
||||
kDataFormat_SPI = 0x40,
|
||||
kDataFormat_IntInvert = 0x20,
|
||||
kDataFormat_FullRes = 0x08,
|
||||
kDataFormat_Justify = 0x04
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,106 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/AnalogInput.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Handle operation of an analog accelerometer.
|
||||
*
|
||||
* The accelerometer reads acceleration directly through the sensor. Many
|
||||
* sensors have multiple axis and can be treated as multiple devices. Each is
|
||||
* calibrated by finding the center value over a period of time.
|
||||
*/
|
||||
class AnalogAccelerometer : public wpi::Sendable,
|
||||
public wpi::SendableHelper<AnalogAccelerometer> {
|
||||
public:
|
||||
/**
|
||||
* Create a new instance of an accelerometer.
|
||||
*
|
||||
* The constructor allocates desired analog input.
|
||||
*
|
||||
* @param channel The channel number for the analog input the accelerometer is
|
||||
* connected to
|
||||
*/
|
||||
explicit AnalogAccelerometer(int channel);
|
||||
|
||||
/**
|
||||
* Create a new instance of Accelerometer from an existing AnalogInput.
|
||||
*
|
||||
* Make a new instance of accelerometer given an AnalogInput. This is
|
||||
* particularly useful if the port is going to be read as an analog channel as
|
||||
* well as through the Accelerometer class.
|
||||
*
|
||||
* @param channel The existing AnalogInput object for the analog input the
|
||||
* accelerometer is connected to
|
||||
*/
|
||||
explicit AnalogAccelerometer(AnalogInput* channel);
|
||||
|
||||
/**
|
||||
* Create a new instance of Accelerometer from an existing AnalogInput.
|
||||
*
|
||||
* Make a new instance of accelerometer given an AnalogInput. This is
|
||||
* particularly useful if the port is going to be read as an analog channel as
|
||||
* well as through the Accelerometer class.
|
||||
*
|
||||
* @param channel The existing AnalogInput object for the analog input the
|
||||
* accelerometer is connected to
|
||||
*/
|
||||
explicit AnalogAccelerometer(std::shared_ptr<AnalogInput> channel);
|
||||
|
||||
~AnalogAccelerometer() override = default;
|
||||
|
||||
AnalogAccelerometer(AnalogAccelerometer&&) = default;
|
||||
AnalogAccelerometer& operator=(AnalogAccelerometer&&) = default;
|
||||
|
||||
/**
|
||||
* Return the acceleration in Gs.
|
||||
*
|
||||
* The acceleration is returned units of Gs.
|
||||
*
|
||||
* @return The current acceleration of the sensor in Gs.
|
||||
*/
|
||||
double GetAcceleration() const;
|
||||
|
||||
/**
|
||||
* Set the accelerometer sensitivity.
|
||||
*
|
||||
* This sets the sensitivity of the accelerometer used for calculating the
|
||||
* acceleration. The sensitivity varies by accelerometer model.
|
||||
*
|
||||
* @param sensitivity The sensitivity of accelerometer in Volts per G.
|
||||
*/
|
||||
void SetSensitivity(double sensitivity);
|
||||
|
||||
/**
|
||||
* Set the voltage that corresponds to 0 G.
|
||||
*
|
||||
* The zero G voltage varies by accelerometer model.
|
||||
*
|
||||
* @param zero The zero G voltage.
|
||||
*/
|
||||
void SetZero(double zero);
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Common function for initializing the accelerometer.
|
||||
*/
|
||||
void InitAccelerometer();
|
||||
|
||||
std::shared_ptr<AnalogInput> m_analogInput;
|
||||
double m_voltsPerG = 1.0;
|
||||
double m_zeroGVoltage = 2.5;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
159
wpilibc/src/main/native/include/wpi/hardware/bus/CAN.hpp
Normal file
159
wpilibc/src/main/native/include/wpi/hardware/bus/CAN.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
// 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 <stdint.h>
|
||||
|
||||
#include <hal/CANAPI.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* High level class for interfacing with CAN devices conforming to
|
||||
* the standard CAN spec.
|
||||
*
|
||||
* No packets that can be sent gets blocked by the RoboRIO, so all methods
|
||||
* work identically in all robot modes.
|
||||
*
|
||||
* All methods are thread save, however the buffer objects passed in
|
||||
* by the user need to not be modified for the duration of their calls.
|
||||
*/
|
||||
class CAN {
|
||||
public:
|
||||
/**
|
||||
* Create a new CAN communication interface with the specific device ID.
|
||||
* This uses the team manufacturer and device types.
|
||||
* The device ID is 6 bits (0-63)
|
||||
*
|
||||
* @param busId The bus id
|
||||
* @param deviceId The device id
|
||||
*/
|
||||
CAN(int busId, int deviceId);
|
||||
|
||||
/**
|
||||
* Create a new CAN communication interface with a specific device ID,
|
||||
* manufacturer and device type. The device ID is 6 bits, the
|
||||
* manufacturer is 8 bits, and the device type is 5 bits.
|
||||
*
|
||||
* @param busId The bus id
|
||||
* @param deviceId The device ID
|
||||
* @param deviceManufacturer The device manufacturer
|
||||
* @param deviceType The device type
|
||||
*/
|
||||
CAN(int busId, int deviceId, int deviceManufacturer, int deviceType);
|
||||
|
||||
CAN(CAN&&) = default;
|
||||
CAN& operator=(CAN&&) = default;
|
||||
|
||||
/**
|
||||
* Write a packet to the CAN device with a specific ID. This ID is 10 bits.
|
||||
*
|
||||
* @param apiId The API ID to write.
|
||||
* @param message the CAN message.
|
||||
*/
|
||||
void WritePacket(int apiId, const HAL_CANMessage& message);
|
||||
|
||||
/**
|
||||
* Write a repeating packet to the CAN device with a specific ID. This ID is
|
||||
* 10 bits. The RoboRIO will automatically repeat the packet at the specified
|
||||
* interval
|
||||
*
|
||||
* @param apiId The API ID to write.
|
||||
* @param message the CAN message.
|
||||
* @param repeatMs The period to repeat the packet at.
|
||||
*/
|
||||
void WritePacketRepeating(int apiId, const HAL_CANMessage& message,
|
||||
int repeatMs);
|
||||
|
||||
/**
|
||||
* Write an RTR frame to the CAN device with a specific ID. This ID is 10
|
||||
* bits. The length by spec must match what is returned by the responding
|
||||
* device
|
||||
*
|
||||
* @param apiId The API ID to write.
|
||||
* @param message the CAN message.
|
||||
*/
|
||||
void WriteRTRFrame(int apiId, const HAL_CANMessage& message);
|
||||
|
||||
/**
|
||||
* Write a packet to the CAN device with a specific ID. This ID is 10 bits.
|
||||
*
|
||||
* @param apiId The API ID to write.
|
||||
* @param message the CAN message.
|
||||
*/
|
||||
int WritePacketNoError(int apiId, const HAL_CANMessage& message);
|
||||
|
||||
/**
|
||||
* Write a repeating packet to the CAN device with a specific ID. This ID is
|
||||
* 10 bits. The RoboRIO will automatically repeat the packet at the specified
|
||||
* interval
|
||||
*
|
||||
* @param apiId The API ID to write.
|
||||
* @param message the CAN message.
|
||||
* @param repeatMs The period to repeat the packet at.
|
||||
*/
|
||||
int WritePacketRepeatingNoError(int apiId, const HAL_CANMessage& message,
|
||||
int repeatMs);
|
||||
|
||||
/**
|
||||
* Write an RTR frame to the CAN device with a specific ID. This ID is 10
|
||||
* bits. The length by spec must match what is returned by the responding
|
||||
* device
|
||||
*
|
||||
* @param apiId The API ID to write.
|
||||
* @param message the CAN message.
|
||||
*/
|
||||
int WriteRTRFrameNoError(int apiId, const HAL_CANMessage& message);
|
||||
|
||||
/**
|
||||
* Stop a repeating packet with a specific ID. This ID is 10 bits.
|
||||
*
|
||||
* @param apiId The API ID to stop repeating
|
||||
*/
|
||||
void StopPacketRepeating(int apiId);
|
||||
|
||||
/**
|
||||
* Read a new CAN packet. This will only return properly once per packet
|
||||
* received. Multiple calls without receiving another packet will return
|
||||
* false.
|
||||
*
|
||||
* @param apiId The API ID to read.
|
||||
* @param data Storage for the received data.
|
||||
* @return True if the data is valid, otherwise false.
|
||||
*/
|
||||
bool ReadPacketNew(int apiId, HAL_CANReceiveMessage* data);
|
||||
|
||||
/**
|
||||
* Read a CAN packet. The will continuously return the last packet received,
|
||||
* without accounting for packet age.
|
||||
*
|
||||
* @param apiId The API ID to read.
|
||||
* @param data Storage for the received data.
|
||||
* @return True if the data is valid, otherwise false.
|
||||
*/
|
||||
bool ReadPacketLatest(int apiId, HAL_CANReceiveMessage* data);
|
||||
|
||||
/**
|
||||
* Read a CAN packet. The will return the last packet received until the
|
||||
* packet is older then the requested timeout. Then it will return false.
|
||||
*
|
||||
* @param apiId The API ID to read.
|
||||
* @param timeoutMs The timeout time for the packet
|
||||
* @param data Storage for the received data.
|
||||
* @return True if the data is valid, otherwise false.
|
||||
*/
|
||||
bool ReadPacketTimeout(int apiId, int timeoutMs, HAL_CANReceiveMessage* data);
|
||||
|
||||
/// Team manufacturer.
|
||||
static constexpr HAL_CANManufacturer kTeamManufacturer = HAL_CAN_Man_kTeamUse;
|
||||
|
||||
/// Team device type.
|
||||
static constexpr HAL_CANDeviceType kTeamDeviceType =
|
||||
HAL_CAN_Dev_kMiscellaneous;
|
||||
|
||||
private:
|
||||
hal::Handle<HAL_CANHandle, HAL_CleanCAN> m_handle;
|
||||
};
|
||||
} // namespace frc
|
||||
160
wpilibc/src/main/native/include/wpi/hardware/bus/I2C.hpp
Normal file
160
wpilibc/src/main/native/include/wpi/hardware/bus/I2C.hpp
Normal file
@@ -0,0 +1,160 @@
|
||||
// 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 <stdint.h>
|
||||
|
||||
#include <hal/I2C.h>
|
||||
#include <hal/I2CTypes.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* I2C bus interface class.
|
||||
*
|
||||
* This class is intended to be used by sensor (and other I2C device) drivers.
|
||||
* It probably should not be used directly.
|
||||
*/
|
||||
class I2C {
|
||||
public:
|
||||
/**
|
||||
* I2C connection ports.
|
||||
*/
|
||||
enum Port {
|
||||
/// I2C Port 0.
|
||||
kPort0 = 0,
|
||||
/// I2C Port 1.
|
||||
kPort1
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param port The I2C port to which the device is connected.
|
||||
* @param deviceAddress The address of the device on the I2C bus.
|
||||
*/
|
||||
I2C(Port port, int deviceAddress);
|
||||
|
||||
I2C(I2C&&) = default;
|
||||
I2C& operator=(I2C&&) = default;
|
||||
|
||||
/**
|
||||
* Returns I2C port.
|
||||
*
|
||||
* @return I2C port.
|
||||
*/
|
||||
Port GetPort() const;
|
||||
|
||||
/**
|
||||
* Returns I2C device address.
|
||||
*
|
||||
* @return I2C device address.
|
||||
*/
|
||||
int GetDeviceAddress() const;
|
||||
|
||||
/**
|
||||
* Generic transaction.
|
||||
*
|
||||
* This is a lower-level interface to the I2C hardware giving you more control
|
||||
* over each transaction. If you intend to write multiple bytes in the same
|
||||
* transaction and do not plan to receive anything back, use writeBulk()
|
||||
* instead. Calling this with a receiveSize of 0 will result in an error.
|
||||
*
|
||||
* @param dataToSend Buffer of data to send as part of the transaction.
|
||||
* @param sendSize Number of bytes to send as part of the transaction.
|
||||
* @param dataReceived Buffer to read data into.
|
||||
* @param receiveSize Number of bytes to read from the device.
|
||||
* @return Transfer Aborted... false for success, true for aborted.
|
||||
*/
|
||||
bool Transaction(uint8_t* dataToSend, int sendSize, uint8_t* dataReceived,
|
||||
int receiveSize);
|
||||
|
||||
/**
|
||||
* Attempt to address a device on the I2C bus.
|
||||
*
|
||||
* This allows you to figure out if there is a device on the I2C bus that
|
||||
* responds to the address specified in the constructor.
|
||||
*
|
||||
* @return Transfer Aborted... false for success, true for aborted.
|
||||
*/
|
||||
bool AddressOnly();
|
||||
|
||||
/**
|
||||
* Execute a write transaction with the device.
|
||||
*
|
||||
* Write a single byte to a register on a device and wait until the
|
||||
* transaction is complete.
|
||||
*
|
||||
* @param registerAddress The address of the register on the device to be
|
||||
* written.
|
||||
* @param data The byte to write to the register on the device.
|
||||
* @return Transfer Aborted... false for success, true for aborted.
|
||||
*/
|
||||
bool Write(int registerAddress, uint8_t data);
|
||||
|
||||
/**
|
||||
* Execute a bulk write transaction with the device.
|
||||
*
|
||||
* Write multiple bytes to a device and wait until the
|
||||
* transaction is complete.
|
||||
*
|
||||
* @param data The data to write to the register on the device.
|
||||
* @param count The number of bytes to be written.
|
||||
* @return Transfer Aborted... false for success, true for aborted.
|
||||
*/
|
||||
bool WriteBulk(uint8_t* data, int count);
|
||||
|
||||
/**
|
||||
* Execute a read transaction with the device.
|
||||
*
|
||||
* Read bytes from a device.
|
||||
* Most I2C devices will auto-increment the register pointer internally
|
||||
* allowing you to read consecutive registers on a device in a single
|
||||
* transaction.
|
||||
*
|
||||
* @param registerAddress The register to read first in the transaction.
|
||||
* @param count The number of bytes to read in the transaction.
|
||||
* @param data A pointer to the array of bytes to store the data
|
||||
* read from the device.
|
||||
* @return Transfer Aborted... false for success, true for aborted.
|
||||
*/
|
||||
bool Read(int registerAddress, int count, uint8_t* data);
|
||||
|
||||
/**
|
||||
* Execute a read only transaction with the device.
|
||||
*
|
||||
* Read bytes from a device. This method does not write any data to prompt the
|
||||
* device.
|
||||
*
|
||||
* @param buffer A pointer to the array of bytes to store the data read from
|
||||
* the device.
|
||||
* @param count The number of bytes to read in the transaction.
|
||||
* @return Transfer Aborted... false for success, true for aborted.
|
||||
*/
|
||||
bool ReadOnly(int count, uint8_t* buffer);
|
||||
|
||||
/**
|
||||
* Verify that a device's registers contain expected values.
|
||||
*
|
||||
* Most devices will have a set of registers that contain a known value that
|
||||
* can be used to identify them. This allows an I2C device driver to easily
|
||||
* verify that the device contains the expected value.
|
||||
*
|
||||
* @pre The device must support and be configured to use register
|
||||
* auto-increment.
|
||||
*
|
||||
* @param registerAddress The base register to start reading from the device.
|
||||
* @param count The size of the field to be verified.
|
||||
* @param expected A buffer containing the values expected from the
|
||||
* device.
|
||||
*/
|
||||
bool VerifySensor(int registerAddress, int count, const uint8_t* expected);
|
||||
|
||||
private:
|
||||
hal::Handle<HAL_I2CPort, HAL_CloseI2C, HAL_I2C_kInvalid> m_port;
|
||||
int m_deviceAddress;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
260
wpilibc/src/main/native/include/wpi/hardware/bus/SerialPort.hpp
Normal file
260
wpilibc/src/main/native/include/wpi/hardware/bus/SerialPort.hpp
Normal file
@@ -0,0 +1,260 @@
|
||||
// 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 <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <hal/SerialPort.h>
|
||||
#include <hal/Types.h>
|
||||
#include <units/time.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Driver for the RS-232 serial port on the roboRIO.
|
||||
*
|
||||
* The current implementation uses the VISA formatted I/O mode. This means that
|
||||
* all traffic goes through the formatted buffers. This allows the intermingled
|
||||
* use of Printf(), Scanf(), and the raw buffer accessors Read() and Write().
|
||||
*
|
||||
* More information can be found in the NI-VISA User Manual here:
|
||||
* http://www.ni.com/pdf/manuals/370423a.pdf
|
||||
* and the NI-VISA Programmer's Reference Manual here:
|
||||
* http://www.ni.com/pdf/manuals/370132c.pdf
|
||||
*/
|
||||
class SerialPort {
|
||||
public:
|
||||
/**
|
||||
* Serial port.
|
||||
*/
|
||||
enum Port {
|
||||
/// Onboard serial port on the roboRIO.
|
||||
kOnboard = 0,
|
||||
/// MXP (roboRIO MXP) serial port.
|
||||
kMXP = 1,
|
||||
/// USB serial port (same as kUSB1).
|
||||
kUSB = 2,
|
||||
/// USB serial port 1.
|
||||
kUSB1 = 2,
|
||||
/// USB serial port 2.
|
||||
kUSB2 = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the parity to use for serial communications.
|
||||
*/
|
||||
enum Parity {
|
||||
/// No parity.
|
||||
kParity_None = 0,
|
||||
/// Odd parity.
|
||||
kParity_Odd = 1,
|
||||
/// Even parity.
|
||||
kParity_Even = 2,
|
||||
/// Parity bit always on.
|
||||
kParity_Mark = 3,
|
||||
/// Parity bit always off.
|
||||
kParity_Space = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the number of stop bits to use for Serial Communication.
|
||||
*/
|
||||
enum StopBits {
|
||||
/// One stop bit.
|
||||
kStopBits_One = 10,
|
||||
/// One and a half stop bits.
|
||||
kStopBits_OnePointFive = 15,
|
||||
/// Two stop bits.
|
||||
kStopBits_Two = 20
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents what type of flow control to use for serial communication.
|
||||
*/
|
||||
enum FlowControl {
|
||||
/// No flow control.
|
||||
kFlowControl_None = 0,
|
||||
/// XON/XOFF flow control.
|
||||
kFlowControl_XonXoff = 1,
|
||||
/// RTS/CTS flow control.
|
||||
kFlowControl_RtsCts = 2,
|
||||
/// DTS/DSR flow control.
|
||||
kFlowControl_DtrDsr = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents which type of buffer mode to use when writing to a serial port.
|
||||
*/
|
||||
enum WriteBufferMode {
|
||||
/// Flush the buffer on each access.
|
||||
kFlushOnAccess = 1,
|
||||
/// Flush the buffer when it is full.
|
||||
kFlushWhenFull = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an instance of a Serial Port class.
|
||||
*
|
||||
* @param baudRate The baud rate to configure the serial port.
|
||||
* @param port The physical port to use
|
||||
* @param dataBits The number of data bits per transfer. Valid values are
|
||||
* between 5 and 8 bits.
|
||||
* @param parity Select the type of parity checking to use.
|
||||
* @param stopBits The number of stop bits to use as defined by the enum
|
||||
* StopBits.
|
||||
*/
|
||||
explicit SerialPort(int baudRate, Port port = kOnboard, int dataBits = 8,
|
||||
Parity parity = kParity_None,
|
||||
StopBits stopBits = kStopBits_One);
|
||||
|
||||
/**
|
||||
* Create an instance of a Serial Port class.
|
||||
*
|
||||
* Prefer to use the constructor that doesn't take a port name, but in some
|
||||
* cases the automatic detection might not work correctly.
|
||||
*
|
||||
* @param baudRate The baud rate to configure the serial port.
|
||||
* @param port The physical port to use
|
||||
* @param portName The direct port name to use
|
||||
* @param dataBits The number of data bits per transfer. Valid values are
|
||||
* between 5 and 8 bits.
|
||||
* @param parity Select the type of parity checking to use.
|
||||
* @param stopBits The number of stop bits to use as defined by the enum
|
||||
* StopBits.
|
||||
*/
|
||||
SerialPort(int baudRate, std::string_view portName, Port port = kOnboard,
|
||||
int dataBits = 8, Parity parity = kParity_None,
|
||||
StopBits stopBits = kStopBits_One);
|
||||
|
||||
SerialPort(SerialPort&& rhs) = default;
|
||||
SerialPort& operator=(SerialPort&& rhs) = default;
|
||||
|
||||
/**
|
||||
* Set the type of flow control to enable on this port.
|
||||
*
|
||||
* By default, flow control is disabled.
|
||||
*/
|
||||
void SetFlowControl(FlowControl flowControl);
|
||||
|
||||
/**
|
||||
* Enable termination and specify the termination character.
|
||||
*
|
||||
* Termination is currently only implemented for receive.
|
||||
* When the the terminator is received, the Read() or Scanf() will return
|
||||
* fewer bytes than requested, stopping after the terminator.
|
||||
*
|
||||
* @param terminator The character to use for termination.
|
||||
*/
|
||||
void EnableTermination(char terminator = '\n');
|
||||
|
||||
/**
|
||||
* Disable termination behavior.
|
||||
*/
|
||||
void DisableTermination();
|
||||
|
||||
/**
|
||||
* Get the number of bytes currently available to read from the serial port.
|
||||
*
|
||||
* @return The number of bytes available to read
|
||||
*/
|
||||
int GetBytesReceived();
|
||||
|
||||
/**
|
||||
* Read raw bytes out of the buffer.
|
||||
*
|
||||
* @param buffer Pointer to the buffer to store the bytes in.
|
||||
* @param count The maximum number of bytes to read.
|
||||
* @return The number of bytes actually read into the buffer.
|
||||
*/
|
||||
int Read(char* buffer, int count);
|
||||
|
||||
/**
|
||||
* Write raw bytes to the buffer.
|
||||
*
|
||||
* @param buffer Pointer to the buffer to read the bytes from.
|
||||
* @param count The maximum number of bytes to write.
|
||||
* @return The number of bytes actually written into the port.
|
||||
*/
|
||||
int Write(const char* buffer, int count);
|
||||
|
||||
/**
|
||||
* Write raw bytes to the buffer.
|
||||
*
|
||||
* Use Write({data, len}) to get a buffer that is shorter than the length of
|
||||
* the string.
|
||||
*
|
||||
* @param buffer the buffer to read the bytes from.
|
||||
* @return The number of bytes actually written into the port.
|
||||
*/
|
||||
int Write(std::string_view buffer);
|
||||
|
||||
/**
|
||||
* Configure the timeout of the serial port.
|
||||
*
|
||||
* This defines the timeout for transactions with the hardware.
|
||||
* It will affect reads and very large writes.
|
||||
*
|
||||
* @param timeout The time to wait for I/O.
|
||||
*/
|
||||
void SetTimeout(units::second_t timeout);
|
||||
|
||||
/**
|
||||
* Specify the size of the input buffer.
|
||||
*
|
||||
* Specify the amount of data that can be stored before data
|
||||
* from the device is returned to Read or Scanf. If you want
|
||||
* data that is received to be returned immediately, set this to 1.
|
||||
*
|
||||
* It the buffer is not filled before the read timeout expires, all
|
||||
* data that has been received so far will be returned.
|
||||
*
|
||||
* @param size The read buffer size.
|
||||
*/
|
||||
void SetReadBufferSize(int size);
|
||||
|
||||
/**
|
||||
* Specify the size of the output buffer.
|
||||
*
|
||||
* Specify the amount of data that can be stored before being
|
||||
* transmitted to the device.
|
||||
*
|
||||
* @param size The write buffer size.
|
||||
*/
|
||||
void SetWriteBufferSize(int size);
|
||||
|
||||
/**
|
||||
* Specify the flushing behavior of the output buffer.
|
||||
*
|
||||
* When set to kFlushOnAccess, data is synchronously written to the serial
|
||||
* port after each call to either Printf() or Write().
|
||||
*
|
||||
* When set to kFlushWhenFull, data will only be written to the serial port
|
||||
* when the buffer is full or when Flush() is called.
|
||||
*
|
||||
* @param mode The write buffer mode.
|
||||
*/
|
||||
void SetWriteBufferMode(WriteBufferMode mode);
|
||||
|
||||
/**
|
||||
* Force the output buffer to be written to the port.
|
||||
*
|
||||
* This is used when SetWriteBufferMode() is set to kFlushWhenFull to force a
|
||||
* flush before the buffer is full.
|
||||
*/
|
||||
void Flush();
|
||||
|
||||
/**
|
||||
* Reset the serial port driver to a known state.
|
||||
*
|
||||
* Empty the transmit and receive buffers in the device and formatted I/O.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
hal::Handle<HAL_SerialPortHandle, HAL_CloseSerial> m_portHandle;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,204 @@
|
||||
// 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 <stdint.h>
|
||||
|
||||
#include <hal/AnalogInput.h>
|
||||
#include <hal/Types.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Analog input class.
|
||||
*
|
||||
* Connected to each analog channel is an averaging and oversampling engine.
|
||||
* This engine accumulates the specified ( by SetAverageBits() and
|
||||
* SetOversampleBits() ) number of samples before returning a new value. This is
|
||||
* not a sliding window average. The only difference between the oversampled
|
||||
* samples and the averaged samples is that the oversampled samples are simply
|
||||
* accumulated effectively increasing the resolution, while the averaged samples
|
||||
* are divided by the number of samples to retain the resolution, but get more
|
||||
* stable values.
|
||||
*/
|
||||
class AnalogInput : public wpi::Sendable,
|
||||
public wpi::SendableHelper<AnalogInput> {
|
||||
public:
|
||||
/**
|
||||
* Construct an analog input.
|
||||
*
|
||||
* @param channel The channel number on the roboRIO to represent. 0-3 are
|
||||
* on-board 4-7 are on the MXP port.
|
||||
*/
|
||||
explicit AnalogInput(int channel);
|
||||
|
||||
AnalogInput(AnalogInput&&) = default;
|
||||
AnalogInput& operator=(AnalogInput&&) = default;
|
||||
|
||||
~AnalogInput() override = default;
|
||||
|
||||
/**
|
||||
* Get a sample straight from this channel.
|
||||
*
|
||||
* The sample is a 12-bit value representing the 0V to 3.3V range of the A/D
|
||||
* converter in the module. The units are in A/D converter codes. Use
|
||||
* GetVoltage() to get the analog value in calibrated units.
|
||||
*
|
||||
* @return A sample straight from this channel.
|
||||
*/
|
||||
int GetValue() const;
|
||||
|
||||
/**
|
||||
* Get a sample from the output of the oversample and average engine for this
|
||||
* channel.
|
||||
*
|
||||
* The sample is 12-bit + the bits configured in SetOversampleBits().
|
||||
* The value configured in SetAverageBits() will cause this value to be
|
||||
* averaged 2**bits number of samples.
|
||||
*
|
||||
* This is not a sliding window. The sample will not change until
|
||||
* 2**(OversampleBits + AverageBits) samples have been acquired from the
|
||||
* module on this channel.
|
||||
*
|
||||
* Use GetAverageVoltage() to get the analog value in calibrated units.
|
||||
*
|
||||
* @return A sample from the oversample and average engine for this channel.
|
||||
*/
|
||||
int GetAverageValue() const;
|
||||
|
||||
/**
|
||||
* Get a scaled sample straight from this channel.
|
||||
*
|
||||
* The value is scaled to units of Volts using the calibrated scaling data
|
||||
* from GetLSBWeight() and GetOffset().
|
||||
*
|
||||
* @return A scaled sample straight from this channel.
|
||||
*/
|
||||
double GetVoltage() const;
|
||||
|
||||
/**
|
||||
* Get a scaled sample from the output of the oversample and average engine
|
||||
* for this channel.
|
||||
*
|
||||
* The value is scaled to units of Volts using the calibrated scaling data
|
||||
* from GetLSBWeight() and GetOffset().
|
||||
*
|
||||
* Using oversampling will cause this value to be higher resolution, but it
|
||||
* will update more slowly.
|
||||
*
|
||||
* Using averaging will cause this value to be more stable, but it will update
|
||||
* more slowly.
|
||||
*
|
||||
* @return A scaled sample from the output of the oversample and average
|
||||
* engine for this channel.
|
||||
*/
|
||||
double GetAverageVoltage() const;
|
||||
|
||||
/**
|
||||
* Get the channel number.
|
||||
*
|
||||
* @return The channel number.
|
||||
*/
|
||||
int GetChannel() const;
|
||||
|
||||
/**
|
||||
* Set the number of averaging bits.
|
||||
*
|
||||
* This sets the number of averaging bits. The actual number of averaged
|
||||
* samples is 2^bits.
|
||||
*
|
||||
* Use averaging to improve the stability of your measurement at the expense
|
||||
* of sampling rate. The averaging is done automatically in the FPGA.
|
||||
*
|
||||
* @param bits Number of bits of averaging.
|
||||
*/
|
||||
void SetAverageBits(int bits);
|
||||
|
||||
/**
|
||||
* Get the number of averaging bits previously configured.
|
||||
*
|
||||
* This gets the number of averaging bits from the FPGA. The actual number of
|
||||
* averaged samples is 2^bits. The averaging is done automatically in the
|
||||
* FPGA.
|
||||
*
|
||||
* @return Number of bits of averaging previously configured.
|
||||
*/
|
||||
int GetAverageBits() const;
|
||||
|
||||
/**
|
||||
* Set the number of oversample bits.
|
||||
*
|
||||
* This sets the number of oversample bits. The actual number of oversampled
|
||||
* values is 2^bits. Use oversampling to improve the resolution of your
|
||||
* measurements at the expense of sampling rate. The oversampling is done
|
||||
* automatically in the FPGA.
|
||||
*
|
||||
* @param bits Number of bits of oversampling.
|
||||
*/
|
||||
void SetOversampleBits(int bits);
|
||||
|
||||
/**
|
||||
* Get the number of oversample bits previously configured.
|
||||
*
|
||||
* This gets the number of oversample bits from the FPGA. The actual number of
|
||||
* oversampled values is 2^bits. The oversampling is done automatically in the
|
||||
* FPGA.
|
||||
*
|
||||
* @return Number of bits of oversampling previously configured.
|
||||
*/
|
||||
int GetOversampleBits() const;
|
||||
|
||||
/**
|
||||
* Get the factory scaling least significant bit weight constant.
|
||||
*
|
||||
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
|
||||
*
|
||||
* @return Least significant bit weight.
|
||||
*/
|
||||
int GetLSBWeight() const;
|
||||
|
||||
/**
|
||||
* Get the factory scaling offset constant.
|
||||
*
|
||||
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
|
||||
*
|
||||
* @return Offset constant.
|
||||
*/
|
||||
int GetOffset() const;
|
||||
|
||||
/**
|
||||
* Set the sample rate per channel for all analog channels.
|
||||
*
|
||||
* The maximum rate is 500kS/s divided by the number of channels in use.
|
||||
* This is 62500 samples/s per channel.
|
||||
*
|
||||
* @param samplesPerSecond The number of samples per second.
|
||||
*/
|
||||
static void SetSampleRate(double samplesPerSecond);
|
||||
|
||||
/**
|
||||
* Get the current sample rate for all channels
|
||||
*
|
||||
* @return Sample rate.
|
||||
*/
|
||||
static double GetSampleRate();
|
||||
|
||||
/**
|
||||
* Indicates this input is used by a simulated device.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
*/
|
||||
void SetSimDevice(HAL_SimDeviceHandle device);
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
int m_channel;
|
||||
hal::Handle<HAL_AnalogInputHandle, HAL_FreeAnalogInputPort> m_port;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,38 @@
|
||||
// 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 <units/time.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Interface for counting the number of ticks on a digital input channel.
|
||||
*
|
||||
* Encoders, Gear tooth sensors, and counters should all subclass this so it can
|
||||
* be used to build more advanced classes for control and driving.
|
||||
*
|
||||
* All counters will immediately start counting - Reset() them if you need them
|
||||
* to be zeroed before use.
|
||||
*/
|
||||
class CounterBase {
|
||||
public:
|
||||
enum EncodingType { k1X, k2X, k4X };
|
||||
|
||||
CounterBase() = default;
|
||||
virtual ~CounterBase() = default;
|
||||
|
||||
CounterBase(CounterBase&&) = default;
|
||||
CounterBase& operator=(CounterBase&&) = default;
|
||||
|
||||
virtual int Get() const = 0;
|
||||
virtual void Reset() = 0;
|
||||
virtual units::second_t GetPeriod() const = 0;
|
||||
virtual void SetMaxPeriod(units::second_t maxPeriod) = 0;
|
||||
virtual bool GetStopped() const = 0;
|
||||
virtual bool GetDirection() const = 0;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,65 @@
|
||||
// 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/DIO.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Class to read a digital input.
|
||||
*
|
||||
* This class will read digital inputs and return the current value on the
|
||||
* channel. Other devices such as encoders, gear tooth sensors, etc. that are
|
||||
* implemented elsewhere will automatically allocate digital inputs and outputs
|
||||
* as required. This class is only for devices like switches etc. that aren't
|
||||
* implemented anywhere else.
|
||||
*/
|
||||
class DigitalInput : public wpi::Sendable,
|
||||
public wpi::SendableHelper<DigitalInput> {
|
||||
public:
|
||||
/**
|
||||
* Create an instance of a Digital Input class.
|
||||
*
|
||||
* Creates a digital input given a channel.
|
||||
*
|
||||
* @param channel The DIO channel 0-9 are on-board, 10-25 are on the MXP port
|
||||
*/
|
||||
explicit DigitalInput(int channel);
|
||||
|
||||
DigitalInput(DigitalInput&&) = default;
|
||||
DigitalInput& operator=(DigitalInput&&) = default;
|
||||
|
||||
~DigitalInput() override = default;
|
||||
|
||||
/**
|
||||
* Get the value from a digital input channel.
|
||||
*
|
||||
* Retrieve the value of a single digital input channel from the FPGA.
|
||||
*/
|
||||
bool Get() const;
|
||||
|
||||
/**
|
||||
* @return The GPIO channel number that this object represents.
|
||||
*/
|
||||
int GetChannel() const;
|
||||
|
||||
/**
|
||||
* Indicates this input is used by a simulated device.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
*/
|
||||
void SetSimDevice(HAL_SimDeviceHandle device);
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
int m_channel;
|
||||
hal::Handle<HAL_DigitalHandle, HAL_FreeDIOPort> m_handle;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,150 @@
|
||||
// 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/DIO.h>
|
||||
#include <hal/Types.h>
|
||||
#include <units/time.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Class to write to digital outputs.
|
||||
*
|
||||
* Write values to the digital output channels. Other devices implemented
|
||||
* elsewhere will allocate channels automatically so for those devices it
|
||||
* shouldn't be done here.
|
||||
*/
|
||||
class DigitalOutput : public wpi::Sendable,
|
||||
public wpi::SendableHelper<DigitalOutput> {
|
||||
public:
|
||||
/**
|
||||
* Create an instance of a digital output.
|
||||
*
|
||||
* Create a digital output given a channel.
|
||||
*
|
||||
* @param channel The digital channel 0-9 are on-board, 10-25 are on the MXP
|
||||
* port
|
||||
*/
|
||||
explicit DigitalOutput(int channel);
|
||||
|
||||
DigitalOutput(DigitalOutput&&) = default;
|
||||
DigitalOutput& operator=(DigitalOutput&&) = default;
|
||||
|
||||
~DigitalOutput() override;
|
||||
|
||||
/**
|
||||
* Set the value of a digital output.
|
||||
*
|
||||
* Set the value of a digital output to either one (true) or zero (false).
|
||||
*
|
||||
* @param value 1 (true) for high, 0 (false) for disabled
|
||||
*/
|
||||
void Set(bool value);
|
||||
|
||||
/**
|
||||
* Gets the value being output from the Digital Output.
|
||||
*
|
||||
* @return the state of the digital output.
|
||||
*/
|
||||
bool Get() const;
|
||||
|
||||
/**
|
||||
* @return The GPIO channel number that this object represents.
|
||||
*/
|
||||
int GetChannel() const;
|
||||
|
||||
/**
|
||||
* Output a single pulse on the digital output line.
|
||||
*
|
||||
* Send a single pulse on the digital output line where the pulse duration is
|
||||
* specified in seconds. Maximum of 65535 microseconds.
|
||||
*
|
||||
* @param pulseLength The pulse length in seconds
|
||||
*/
|
||||
void Pulse(units::second_t pulseLength);
|
||||
|
||||
/**
|
||||
* Determine if the pulse is still going.
|
||||
*
|
||||
* Determine if a previously started pulse is still going.
|
||||
*/
|
||||
bool IsPulsing() const;
|
||||
|
||||
/**
|
||||
* Change the PWM frequency of the PWM output on a Digital Output line.
|
||||
*
|
||||
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is
|
||||
* logarithmic.
|
||||
*
|
||||
* There is only one PWM frequency for all digital channels.
|
||||
*
|
||||
* @param rate The frequency to output all digital output PWM signals.
|
||||
*/
|
||||
void SetPWMRate(double rate);
|
||||
|
||||
/**
|
||||
* Enable a PWM PPS (Pulse Per Second) Output on this line.
|
||||
*
|
||||
* Allocate one of the 6 DO PWM generator resources from this module.
|
||||
*
|
||||
* Supply the duty-cycle to output.
|
||||
*
|
||||
* The resolution of the duty cycle is 8-bit.
|
||||
*
|
||||
* @param dutyCycle The duty-cycle to start generating. [0..1]
|
||||
*/
|
||||
void EnablePPS(double dutyCycle);
|
||||
|
||||
/**
|
||||
* Enable a PWM Output on this line.
|
||||
*
|
||||
* Allocate one of the 6 DO PWM generator resources from this module.
|
||||
*
|
||||
* Supply the initial duty-cycle to output so as to avoid a glitch when first
|
||||
* starting.
|
||||
*
|
||||
* The resolution of the duty cycle is 8-bit for low frequencies (1kHz or
|
||||
* less) but is reduced the higher the frequency of the PWM signal is.
|
||||
*
|
||||
* @param initialDutyCycle The duty-cycle to start generating. [0..1]
|
||||
*/
|
||||
void EnablePWM(double initialDutyCycle);
|
||||
|
||||
/**
|
||||
* Change this line from a PWM output back to a static Digital Output line.
|
||||
*
|
||||
* Free up one of the 6 DO PWM generator resources that were in use.
|
||||
*/
|
||||
void DisablePWM();
|
||||
|
||||
/**
|
||||
* Change the duty-cycle that is being generated on the line.
|
||||
*
|
||||
* The resolution of the duty cycle is 8-bit for low frequencies (1kHz or
|
||||
* less) but is reduced the higher the frequency of the PWM signal is.
|
||||
*
|
||||
* @param dutyCycle The duty-cycle to change to. [0..1]
|
||||
*/
|
||||
void UpdateDutyCycle(double dutyCycle);
|
||||
|
||||
/**
|
||||
* Indicates this output is used by a simulated device.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
*/
|
||||
void SetSimDevice(HAL_SimDeviceHandle device);
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
int m_channel;
|
||||
hal::Handle<HAL_DigitalHandle, HAL_FreeDIOPort> m_handle;
|
||||
hal::Handle<HAL_DigitalPWMHandle> m_pwmGenerator;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
118
wpilibc/src/main/native/include/wpi/hardware/discrete/PWM.hpp
Normal file
118
wpilibc/src/main/native/include/wpi/hardware/discrete/PWM.hpp
Normal file
@@ -0,0 +1,118 @@
|
||||
// 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 <stdint.h>
|
||||
|
||||
#include <hal/PWM.h>
|
||||
#include <hal/Types.h>
|
||||
#include <units/time.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
namespace frc {
|
||||
class AddressableLED;
|
||||
|
||||
/**
|
||||
* Class implements the PWM generation in the FPGA.
|
||||
*
|
||||
* The values supplied as arguments for PWM outputs range from -1.0 to 1.0. They
|
||||
* are mapped to the microseconds to keep the pulse high, with a range of 0
|
||||
* (off) to 4096. Changes are immediately sent to the FPGA, and the update
|
||||
* occurs at the next FPGA cycle (5.05ms). There is no delay.
|
||||
*/
|
||||
class PWM : public wpi::Sendable, public wpi::SendableHelper<PWM> {
|
||||
public:
|
||||
friend class AddressableLED;
|
||||
/**
|
||||
* Represents the output period in microseconds.
|
||||
*/
|
||||
enum OutputPeriod {
|
||||
/**
|
||||
* PWM pulses occur every 5 ms
|
||||
*/
|
||||
kOutputPeriod_5Ms = 1,
|
||||
/**
|
||||
* PWM pulses occur every 10 ms
|
||||
*/
|
||||
kOutputPeriod_10Ms = 2,
|
||||
/**
|
||||
* PWM pulses occur every 20 ms
|
||||
*/
|
||||
kOutputPeriod_20Ms = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocate a PWM given a channel number.
|
||||
*
|
||||
* Checks channel value range and allocates the appropriate channel.
|
||||
* The allocation is only done to help users ensure that they don't double
|
||||
* assign channels.
|
||||
*
|
||||
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the
|
||||
* MXP port
|
||||
* @param registerSendable If true, adds this instance to SendableRegistry
|
||||
*/
|
||||
explicit PWM(int channel, bool registerSendable = true);
|
||||
|
||||
PWM(PWM&&) = default;
|
||||
PWM& operator=(PWM&&) = default;
|
||||
|
||||
/**
|
||||
* Free the PWM channel.
|
||||
*
|
||||
* Free the resource associated with the PWM channel and set the value to 0.
|
||||
*/
|
||||
~PWM() override;
|
||||
|
||||
/**
|
||||
* Set the PWM pulse time directly to the hardware.
|
||||
*
|
||||
* Write a microsecond value to a PWM channel.
|
||||
*
|
||||
* @param time Microsecond PWM value.
|
||||
*/
|
||||
void SetPulseTime(units::microsecond_t time);
|
||||
|
||||
/**
|
||||
* Get the PWM pulse time directly from the hardware.
|
||||
*
|
||||
* Read a microsecond value from a PWM channel.
|
||||
*
|
||||
* @return Microsecond PWM control value.
|
||||
*/
|
||||
units::microsecond_t GetPulseTime() const;
|
||||
|
||||
/**
|
||||
* Temporarily disables the PWM output. The next set call will re-enable
|
||||
* the output.
|
||||
*/
|
||||
void SetDisabled();
|
||||
|
||||
/**
|
||||
* Sets the PWM output period.
|
||||
*
|
||||
* @param mult The output period to apply to this channel
|
||||
*/
|
||||
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;
|
||||
|
||||
private:
|
||||
int m_channel;
|
||||
hal::Handle<HAL_DigitalHandle, HAL_FreePWMPort> m_handle;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
131
wpilibc/src/main/native/include/wpi/hardware/imu/OnboardIMU.hpp
Normal file
131
wpilibc/src/main/native/include/wpi/hardware/imu/OnboardIMU.hpp
Normal file
@@ -0,0 +1,131 @@
|
||||
// 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 <frc/geometry/Quaternion.h>
|
||||
#include <frc/geometry/Rotation2d.h>
|
||||
#include <frc/geometry/Rotation3d.h>
|
||||
|
||||
#include <units/acceleration.h>
|
||||
#include <units/angle.h>
|
||||
#include <units/angular_velocity.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* SystemCore onboard IMU
|
||||
*/
|
||||
class OnboardIMU {
|
||||
public:
|
||||
/**
|
||||
* A mount orientation of SystemCore
|
||||
*/
|
||||
enum MountOrientation {
|
||||
/** Flat (mounted parallel to the ground). */
|
||||
kFlat,
|
||||
/** Landscape (vertically mounted with long edge of SystemCore parallel to
|
||||
the ground). */
|
||||
kLandscape,
|
||||
/** Portrait (vertically mounted with the short edge of SystemCore parallel
|
||||
to the ground). */
|
||||
kPortrait
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a handle to the SystemCore onboard IMU.
|
||||
* @param mountOrientation the mount orientation of SystemCore to determine
|
||||
* yaw.
|
||||
*/
|
||||
explicit OnboardIMU(MountOrientation mountOrientation);
|
||||
|
||||
/**
|
||||
* Get the yaw value
|
||||
* @return yaw value
|
||||
*/
|
||||
units::radian_t GetYaw();
|
||||
|
||||
/**
|
||||
* Reset the current yaw value to 0. Future reads of the yaw value will be
|
||||
* relative to the current orientation.
|
||||
*/
|
||||
void ResetYaw();
|
||||
|
||||
/**
|
||||
* Get the yaw as a Rotation2d.
|
||||
* @return yaw
|
||||
*/
|
||||
Rotation2d GetRotation2d();
|
||||
|
||||
/**
|
||||
* Get the 3D orientation as a Rotation3d.
|
||||
* @return 3D orientation
|
||||
*/
|
||||
Rotation3d GetRotation3d();
|
||||
|
||||
/**
|
||||
* Get the 3D orientation as a Quaternion.
|
||||
* @return 3D orientation
|
||||
*/
|
||||
Quaternion GetQuaternion();
|
||||
|
||||
/**
|
||||
* Get the angle about the X axis of the IMU.
|
||||
* @return angle about the X axis
|
||||
*/
|
||||
units::radian_t GetAngleX();
|
||||
|
||||
/**
|
||||
* Get the angle about the Y axis of the IMU.
|
||||
* @return angle about the Y axis
|
||||
*/
|
||||
units::radian_t GetAngleY();
|
||||
|
||||
/**
|
||||
* Get the angle about the Z axis of the IMU.
|
||||
* @return angle about the Z axis
|
||||
*/
|
||||
units::radian_t GetAngleZ();
|
||||
|
||||
/**
|
||||
* Get the angular rate about the X axis of the IMU.
|
||||
* @return angular rate about the X axis
|
||||
*/
|
||||
units::radians_per_second_t GetGyroRateX();
|
||||
|
||||
/**
|
||||
* Get the angular rate about the Y axis of the IMU.
|
||||
* @return angular rate about the Y axis
|
||||
*/
|
||||
units::radians_per_second_t GetGyroRateY();
|
||||
|
||||
/**
|
||||
* Get the angular rate about the Z axis of the IMU.
|
||||
* @return angular rate about the Z axis
|
||||
*/
|
||||
units::radians_per_second_t GetGyroRateZ();
|
||||
|
||||
/**
|
||||
* Get the acceleration along the X axis of the IMU.
|
||||
* @return acceleration along the X axis
|
||||
*/
|
||||
units::meters_per_second_squared_t GetAccelX();
|
||||
|
||||
/**
|
||||
* Get the acceleration along the Z axis of the IMU.
|
||||
* @return acceleration along the Z axis
|
||||
*/
|
||||
units::meters_per_second_squared_t GetAccelY();
|
||||
|
||||
/**
|
||||
* Get the acceleration along the Z axis of the IMU.
|
||||
* @return acceleration along the Z axis
|
||||
*/
|
||||
units::meters_per_second_squared_t GetAccelZ();
|
||||
|
||||
private:
|
||||
units::radian_t GetYawNoOffset();
|
||||
MountOrientation m_mountOrientation;
|
||||
units::radian_t m_yawOffset{0};
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,186 @@
|
||||
// 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 <initializer_list>
|
||||
#include <span>
|
||||
|
||||
#include <hal/AddressableLED.h>
|
||||
#include <hal/AddressableLEDTypes.h>
|
||||
#include <hal/Types.h>
|
||||
#include <units/time.h>
|
||||
|
||||
#include "util/Color.h"
|
||||
#include "util/Color8Bit.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* A class for driving addressable LEDs, such as WS2812B, WS2815, and NeoPixels.
|
||||
*
|
||||
* Some LEDs use a different color order than the default GRB. The color order
|
||||
* is configurable using SetColorOrder().
|
||||
*
|
||||
* Up to 1024 LEDs may be controlled in total across all AddressableLED
|
||||
* instances. A single global buffer is used for all instances. The start
|
||||
* position used for LED data for the output is set via SetStart() and the
|
||||
* length of the strip is set via SetLength(). Both of these default to zero, so
|
||||
* multiple instances will access the same pixel data unless SetStart() is
|
||||
* called to adjust the starting point.
|
||||
*/
|
||||
class AddressableLED {
|
||||
public:
|
||||
/**
|
||||
* Order that color data is sent over the wire.
|
||||
*/
|
||||
enum ColorOrder {
|
||||
kRGB = HAL_ALED_RGB, ///< RGB order
|
||||
kRBG = HAL_ALED_RBG, ///< RBG order
|
||||
kBGR = HAL_ALED_BGR, ///< BGR order
|
||||
kBRG = HAL_ALED_BRG, ///< BRG order
|
||||
kGBR = HAL_ALED_GBR, ///< GBR order
|
||||
kGRB = HAL_ALED_GRB ///< GRB order. This is the default order.
|
||||
};
|
||||
|
||||
class LEDData : public HAL_AddressableLEDData {
|
||||
public:
|
||||
LEDData() : LEDData(0, 0, 0) {}
|
||||
LEDData(int _r, int _g, int _b) {
|
||||
r = _r;
|
||||
g = _g;
|
||||
b = _b;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper method to set all values of the LED.
|
||||
*
|
||||
* @param r the r value [0-255]
|
||||
* @param g the g value [0-255]
|
||||
* @param b the b value [0-255]
|
||||
*/
|
||||
void SetRGB(int r, int g, int b) {
|
||||
this->r = r;
|
||||
this->g = g;
|
||||
this->b = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper method to set all values of the LED.
|
||||
*
|
||||
* @param h the h value [0-180]
|
||||
* @param s the s value [0-255]
|
||||
* @param v the v value [0-255]
|
||||
*/
|
||||
void SetHSV(int h, int s, int v);
|
||||
|
||||
/*
|
||||
* Sets a specific LED in the buffer.
|
||||
*
|
||||
* @param color The color of the LED
|
||||
*/
|
||||
void SetLED(const Color& color) {
|
||||
this->r = color.red * 255;
|
||||
this->g = color.green * 255;
|
||||
this->b = color.blue * 255;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets a specific LED in the buffer.
|
||||
*
|
||||
* @param color The color of the LED
|
||||
*/
|
||||
void SetLED(const Color8Bit& color) {
|
||||
this->r = color.red;
|
||||
this->g = color.green;
|
||||
this->b = color.blue;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new driver for a specific channel.
|
||||
*
|
||||
* @param channel the output channel to use
|
||||
*/
|
||||
explicit AddressableLED(int channel);
|
||||
|
||||
AddressableLED(AddressableLED&&) = default;
|
||||
AddressableLED& operator=(AddressableLED&&) = default;
|
||||
|
||||
/**
|
||||
* Gets the channel for this addressable LED.
|
||||
*
|
||||
* @return channel
|
||||
*/
|
||||
int GetChannel() const { return m_channel; }
|
||||
|
||||
/**
|
||||
* Sets the color order for this AddressableLED. The default order is GRB.
|
||||
*
|
||||
* This will take effect on the next call to SetData().
|
||||
*
|
||||
* @param order the color order
|
||||
*/
|
||||
void SetColorOrder(ColorOrder order);
|
||||
|
||||
/**
|
||||
* Sets the display start of the LED strip in the global buffer.
|
||||
*
|
||||
* @param start the strip start, in LEDs
|
||||
*/
|
||||
void SetStart(int start);
|
||||
|
||||
/**
|
||||
* Gets the display start of the LED strip in the global buffer.
|
||||
*
|
||||
* @return the strip start, in LEDs
|
||||
*/
|
||||
int GetStart() const { return m_start; }
|
||||
|
||||
/**
|
||||
* Sets the length of the LED strip.
|
||||
*
|
||||
* @param length the strip length, in LEDs
|
||||
*/
|
||||
void SetLength(int length);
|
||||
|
||||
/**
|
||||
* Sets the LED output data. This will write to the global buffer starting at
|
||||
* the location set by SetStart() and up to the length set by SetLength().
|
||||
*
|
||||
* @param ledData the buffer to write
|
||||
*/
|
||||
void SetData(std::span<const LEDData> ledData);
|
||||
|
||||
/**
|
||||
* Sets the LED output data. This will write to the global buffer starting at
|
||||
* the location set by SetStart() and up to the length set by SetLength().
|
||||
*
|
||||
* @param ledData the buffer to write
|
||||
*/
|
||||
void SetData(std::initializer_list<LEDData> ledData);
|
||||
|
||||
/**
|
||||
* Sets the LED output data at an arbitrary location in the global buffer.
|
||||
*
|
||||
* @param start the start location, in LEDs
|
||||
* @param colorOrder the color order
|
||||
* @param ledData the buffer to write
|
||||
*/
|
||||
static void SetGlobalData(int start, ColorOrder colorOrder,
|
||||
std::span<const LEDData> ledData);
|
||||
|
||||
private:
|
||||
hal::Handle<HAL_AddressableLEDHandle, HAL_FreeAddressableLED> m_handle;
|
||||
int m_channel;
|
||||
int m_start{0};
|
||||
int m_length{0};
|
||||
ColorOrder m_colorOrder{kGRB};
|
||||
};
|
||||
|
||||
constexpr auto format_as(AddressableLED::ColorOrder order) {
|
||||
return static_cast<int32_t>(order);
|
||||
}
|
||||
|
||||
} // namespace frc
|
||||
404
wpilibc/src/main/native/include/wpi/hardware/led/LEDPattern.hpp
Normal file
404
wpilibc/src/main/native/include/wpi/hardware/led/LEDPattern.hpp
Normal file
@@ -0,0 +1,404 @@
|
||||
// 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 <functional>
|
||||
#include <span>
|
||||
#include <utility>
|
||||
|
||||
#include <units/frequency.h>
|
||||
#include <units/length.h>
|
||||
#include <units/time.h>
|
||||
#include <units/velocity.h>
|
||||
|
||||
#include "frc/AddressableLED.h"
|
||||
#include "util/Color.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class LEDPattern {
|
||||
public:
|
||||
/**
|
||||
* A wrapper around a length and an arbitrary reader function that accepts an
|
||||
* LED index and returns data for the LED at that index. This configuration
|
||||
* allows us to abstract over different container types without templating.
|
||||
*/
|
||||
class LEDReader {
|
||||
public:
|
||||
LEDReader(std::function<frc::AddressableLED::LEDData(int)> impl,
|
||||
size_t size)
|
||||
: m_impl{std::move(impl)}, m_size{size} {}
|
||||
|
||||
frc::AddressableLED::LEDData operator[](size_t index) const {
|
||||
return m_impl(index);
|
||||
}
|
||||
|
||||
size_t size() const { return m_size; }
|
||||
|
||||
private:
|
||||
std::function<frc::AddressableLED::LEDData(int)> m_impl;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
explicit LEDPattern(std::function<void(frc::LEDPattern::LEDReader,
|
||||
std::function<void(int, frc::Color)>)>
|
||||
impl);
|
||||
|
||||
void ApplyTo(LEDReader reader,
|
||||
std::function<void(int, frc::Color)> writer) const;
|
||||
|
||||
/**
|
||||
* Writes the pattern to an LED buffer. Dynamic animations should be called
|
||||
* periodically (such as with a command or with a periodic method) to refresh
|
||||
* the buffer over time.
|
||||
*
|
||||
* This method is intentionally designed to use separate objects for reading
|
||||
* and writing data. By splitting them up, we can easily modify the behavior
|
||||
* of some base pattern to make it scroll, blink, or breathe by intercepting
|
||||
* the data writes to transform their behavior to whatever we like.
|
||||
*
|
||||
* @param data the current data of the LED strip
|
||||
* @param writer data writer for setting new LED colors on the LED strip
|
||||
*/
|
||||
void ApplyTo(std::span<frc::AddressableLED::LEDData> data,
|
||||
std::function<void(int, frc::Color)> writer) const;
|
||||
|
||||
/**
|
||||
* Writes the pattern to an LED buffer. Dynamic animations should be called
|
||||
* periodically (such as with a command or with a periodic method) to refresh
|
||||
* the buffer over time.
|
||||
*
|
||||
* This method is intentionally designed to use separate objects for reading
|
||||
* and writing data. By splitting them up, we can easily modify the behavior
|
||||
* of some base pattern to make it scroll, blink, or breathe by intercepting
|
||||
* the data writes to transform their behavior to whatever we like.
|
||||
*
|
||||
* @param data the current data of the LED strip
|
||||
*/
|
||||
void ApplyTo(std::span<frc::AddressableLED::LEDData> data) const;
|
||||
|
||||
/**
|
||||
* Creates a pattern with remapped indices.
|
||||
*
|
||||
* @param indexMapper the index mapper
|
||||
* @return the mapped pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern MapIndex(std::function<size_t(size_t, size_t)> indexMapper);
|
||||
|
||||
/**
|
||||
* Creates a pattern that displays this one in reverse. Scrolling patterns
|
||||
* will scroll in the opposite direction (but at the same speed). It will
|
||||
* treat the end of an LED strip as the start, and the start of the strip as
|
||||
* the end. This can be useful for making ping-pong patterns that travel from
|
||||
* one end of an LED strip to the other, then reverse direction and move back
|
||||
* to the start. This can also be useful when working with LED strips
|
||||
* connected in a serpentine pattern (where the start of one strip is
|
||||
* connected to the end of the previous one).
|
||||
*
|
||||
* @return the reverse pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern Reversed();
|
||||
|
||||
/**
|
||||
* Creates a pattern that displays this one, but offset by a certain number of
|
||||
* LEDs. The offset pattern will wrap around, if necessary.
|
||||
*
|
||||
* @param offset how many LEDs to offset by
|
||||
* @return the offset pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern OffsetBy(int offset);
|
||||
|
||||
/**
|
||||
* Creates a pattern that plays this one scrolling up the buffer. The velocity
|
||||
* controls how fast the pattern returns back to its original position, and is
|
||||
* in terms of the length of the LED strip; scrolling across a segment that is
|
||||
* 10 LEDs long will travel twice as fast as on a segment that's only 5 LEDs
|
||||
* long (assuming equal LED density on both segments).
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern ScrollAtRelativeSpeed(units::hertz_t velocity);
|
||||
|
||||
/**
|
||||
* Creates a pattern that plays this one scrolling up an LED strip. A negative
|
||||
* velocity makes the pattern play in reverse.
|
||||
*
|
||||
* <p>For example, scrolling a pattern at 4 inches per second along an LED
|
||||
* strip with 60 LEDs per meter:
|
||||
*
|
||||
* <pre>
|
||||
* // LEDs per meter, a known value taken from the spec sheet of our
|
||||
* particular LED strip units::meter_t LED_SPACING = units::meter_t{1 /60.0};
|
||||
*
|
||||
* frc::LEDPattern rainbow = frc::LEDPattern::Rainbow();
|
||||
* frc::LEDPattern scrollingRainbow =
|
||||
* rainbow.ScrollAtAbsoluteSpeed(units::feet_per_second_t{1 / 3.0},
|
||||
* LED_SPACING);
|
||||
* </pre>
|
||||
*
|
||||
* <p>Note that this pattern will scroll <i>faster</i> if applied to a less
|
||||
* dense LED strip (such as 30 LEDs per meter), or <i>slower</i> if applied to
|
||||
* a denser LED strip (such as 120 or 144 LEDs per meter).
|
||||
*
|
||||
* @param velocity how fast the pattern should move along a physical LED strip
|
||||
* @param ledSpacing the distance between adjacent LEDs on the physical LED
|
||||
* strip
|
||||
* @return the scrolling pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern ScrollAtAbsoluteSpeed(units::meters_per_second_t velocity,
|
||||
units::meter_t ledSpacing);
|
||||
|
||||
/**
|
||||
* Creates a pattern that switches between playing this pattern and turning
|
||||
* the entire LED strip off.
|
||||
*
|
||||
* @param onTime how long the pattern should play for, per cycle
|
||||
* @param offTime how long the pattern should be turned off for, per cycle
|
||||
* @return the blinking pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern Blink(units::second_t onTime, units::second_t offTime);
|
||||
|
||||
/**
|
||||
* Like {@link LEDPattern::Blink(units::second_t)}, but where the
|
||||
* "off" time is exactly equal to the "on" time.
|
||||
*
|
||||
* @param onTime how long the pattern should play for (and be turned off for),
|
||||
* per cycle
|
||||
* @return the blinking pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern Blink(units::second_t onTime);
|
||||
|
||||
/**
|
||||
* Creates a pattern that blinks this one on and off in sync with a true/false
|
||||
* signal. The pattern will play while the signal outputs {@code true}, and
|
||||
* will turn off while the signal outputs
|
||||
* {@code false}.
|
||||
*
|
||||
* @param signal the signal to synchronize with
|
||||
* @return the blinking pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern SynchronizedBlink(std::function<bool()> signal);
|
||||
|
||||
/**
|
||||
* Creates a pattern that brightens and dims this one over time. Brightness
|
||||
* follows a sinusoidal pattern.
|
||||
*
|
||||
* @param period how fast the breathing pattern should complete a single cycle
|
||||
* @return the breathing pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern Breathe(units::second_t period);
|
||||
|
||||
/**
|
||||
* Creates a pattern that plays this pattern overlaid on another. Anywhere
|
||||
* this pattern sets an LED to off (or {@link frc::Color::kBlack}), the base
|
||||
* pattern will be displayed instead.
|
||||
*
|
||||
* @param base the base pattern to overlay on top of
|
||||
* @return the combined overlay pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern OverlayOn(const LEDPattern& base);
|
||||
|
||||
/**
|
||||
* Creates a pattern that displays outputs as a combination of this pattern
|
||||
* and another. Color values are calculated as the average color of both
|
||||
* patterns; if both patterns set the same LED to the same color, then it is
|
||||
* set to that color, but if one pattern sets to one color and the other
|
||||
* pattern sets it to off, then it will show the color of the first pattern
|
||||
* but at approximately half brightness. This is different from {@link
|
||||
* LEDPattern::OverlayOn(const LEDPattern&)}, which will show the base pattern
|
||||
* at full brightness if the overlay is set to off at that position.
|
||||
*
|
||||
* @param other the pattern to blend with
|
||||
* @return the blended pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern Blend(const LEDPattern& other);
|
||||
|
||||
/**
|
||||
* Similar to {@link LEDPattern::Blend(const LEDPattern&)}, but performs a
|
||||
* bitwise mask on each color channel rather than averaging the colors for
|
||||
* each LED. This can be helpful for displaying only a portion of the base
|
||||
* pattern by applying a mask that sets the desired area to white, and all
|
||||
* other areas to black. However, it can also be used to display only certain
|
||||
* color channels or hues; for example, masking with {@code
|
||||
* LEDPattern.color(Color.kRed)} will turn off the green and blue channels on
|
||||
* the output pattern, leaving only the red LEDs to be illuminated.
|
||||
*
|
||||
* @param mask the mask to apply
|
||||
* @return the masked pattern
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern Mask(const LEDPattern& mask);
|
||||
|
||||
/**
|
||||
* Creates a pattern that plays this one, but at a different brightness.
|
||||
* Brightness multipliers are applied per-channel in the RGB space; no HSL or
|
||||
* HSV conversions are applied. Multipliers are also uncapped, which may
|
||||
* result in the original colors washing out and appearing less saturated or
|
||||
* even just a bright white.
|
||||
*
|
||||
* <p>This method is predominantly intended for dimming LEDs to avoid
|
||||
* painfully bright or distracting patterns from playing (apologies to the
|
||||
* 2024 NE Greater Boston field staff).
|
||||
*
|
||||
* <p>For example, dimming can be done simply by adding a call to
|
||||
* `atBrightness` at the end of a pattern:
|
||||
*
|
||||
* <pre>
|
||||
* // Solid red, but at 50% brightness
|
||||
* frc::LEDPattern::Solid(frc::Color::kRed).AtBrightness(0.5);
|
||||
*
|
||||
* // Solid white, but at only 10% (i.e. ~0.5V)
|
||||
* frc::LEDPattern::Solid(frc:Color::kWhite).AtBrightness(0.1);
|
||||
* </pre>
|
||||
*
|
||||
* @param relativeBrightness the multiplier to apply to all channels to modify
|
||||
* brightness
|
||||
* @return the input pattern, displayed at
|
||||
*/
|
||||
[[nodiscard]]
|
||||
LEDPattern AtBrightness(double relativeBrightness);
|
||||
|
||||
/** A pattern that turns off all LEDs. */
|
||||
static LEDPattern Off();
|
||||
|
||||
/**
|
||||
* Creates a pattern that displays a single static color along the entire
|
||||
* length of the LED strip.
|
||||
*
|
||||
* @param color the color to display
|
||||
* @return the pattern
|
||||
*/
|
||||
static LEDPattern Solid(const Color color);
|
||||
|
||||
/**
|
||||
* Creates a pattern that works as a mask layer for {@link
|
||||
* LEDPattern::Mask(const LEDPattern&)} that illuminates only the portion of
|
||||
* the LED strip corresponding with some progress. The mask pattern will start
|
||||
* from the base and set LEDs to white at a proportion equal to the progress
|
||||
* returned by the function. Some usages for this could be for displaying
|
||||
* progress of a flywheel to its target velocity, progress of a complex
|
||||
* autonomous sequence, or the height of an elevator.
|
||||
*
|
||||
* <p>For example, creating a mask for displaying a red-to-blue gradient,
|
||||
* starting from the red end, based on where an elevator is in its range of
|
||||
* travel.
|
||||
*
|
||||
* <pre>
|
||||
* frc::LEDPattern basePattern =
|
||||
* frc::LEDPattern::Gradient(frc::Color::kRed, frc::Color::kBlue);
|
||||
* frc::LEDPattern progressPattern =
|
||||
* basePattern.Mask(frc::LEDPattern::ProgressMaskLayer([&]() {
|
||||
* return elevator.GetHeight() / elevator.MaxHeight();
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param progressFunction the function to call to determine the progress.
|
||||
* This should return values in the range [0, 1]; any values outside that
|
||||
* range will be clamped.
|
||||
* @return the mask pattern
|
||||
*/
|
||||
static LEDPattern ProgressMaskLayer(std::function<double()> progressFunction);
|
||||
|
||||
/**
|
||||
* Display a set of colors in steps across the length of the LED strip. No
|
||||
* interpolation is done between colors. Colors are specified by the first LED
|
||||
* on the strip to show that color. The last color in the map will be
|
||||
* displayed all the way to the end of the strip. LEDs positioned before the
|
||||
* first specified step will be turned off (you can think of this as if
|
||||
* there's a 0 -> black step by default).
|
||||
*
|
||||
* @param steps a map of progress to the color to start displaying at that
|
||||
* position along the LED strip
|
||||
* @return a motionless step pattern
|
||||
*/
|
||||
static LEDPattern Steps(std::span<const std::pair<double, Color>> steps);
|
||||
|
||||
/**
|
||||
* Display a set of colors in steps across the length of the LED strip. No
|
||||
* interpolation is done between colors. Colors are specified by the first LED
|
||||
* on the strip to show that color. The last color in the map will be
|
||||
* displayed all the way to the end of the strip. LEDs positioned before the
|
||||
* first specified step will be turned off (you can think of this as if
|
||||
* there's a 0 -> black step by default).
|
||||
*
|
||||
* @param steps a map of progress to the color to start displaying at that
|
||||
* position along the LED strip
|
||||
* @return a motionless step pattern
|
||||
*/
|
||||
static LEDPattern Steps(
|
||||
std::initializer_list<std::pair<double, Color>> steps);
|
||||
|
||||
/** Types of gradients. */
|
||||
enum GradientType {
|
||||
/**
|
||||
* A continuous gradient, where the gradient wraps around to allow for
|
||||
* seamless scrolling effects.
|
||||
*/
|
||||
kContinuous,
|
||||
/**
|
||||
* A discontinuous gradient, where the first pixel is set to the first color
|
||||
* of the gradient and the final pixel is set to the last color of the
|
||||
* gradient. There is no wrapping effect, so scrolling effects will display
|
||||
* an obvious seam.
|
||||
*/
|
||||
kDiscontinuous
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a pattern that displays a non-animated gradient of colors across
|
||||
* the entire length of the LED strip. Colors are evenly distributed along the
|
||||
* full length of the LED strip. The gradient type is configured with the
|
||||
* {@code type} parameter, allowing the gradient to be either continuous (no
|
||||
* seams, good for scrolling effects) or discontinuous (a clear seam is
|
||||
* visible, but the gradient applies to the full length of the LED strip
|
||||
* without needing to use some space for wrapping).
|
||||
*
|
||||
* @param type the type of gradient (continuous or discontinuous)
|
||||
* @param colors the colors to display in the gradient
|
||||
* @return a motionless gradient pattern
|
||||
*/
|
||||
static LEDPattern Gradient(GradientType type, std::span<const Color> colors);
|
||||
|
||||
/**
|
||||
* Creates a pattern that displays a non-animated gradient of colors across
|
||||
* the entire length of the LED strip. Colors are evenly distributed along the
|
||||
* full length of the LED strip. The gradient type is configured with the
|
||||
* {@code type} parameter, allowing the gradient to be either continuous (no
|
||||
* seams, good for scrolling effects) or discontinuous (a clear seam is
|
||||
* visible, but the gradient applies to the full length of the LED strip
|
||||
* without needing to use some space for wrapping).
|
||||
*
|
||||
* @param type the type of gradient (continuous or discontinuous)
|
||||
* @param colors the colors to display in the gradient
|
||||
* @return a motionless gradient pattern
|
||||
*/
|
||||
static LEDPattern Gradient(GradientType type,
|
||||
std::initializer_list<Color> colors);
|
||||
|
||||
/**
|
||||
* Creates an LED pattern that displays a rainbow across the color wheel. The
|
||||
* rainbow pattern will stretch across the entire length of the LED strip.
|
||||
*
|
||||
* @param saturation the saturation of the HSV colors, in [0, 255]
|
||||
* @param value the value of the HSV colors, in [0, 255]
|
||||
* @return the rainbow pattern
|
||||
*/
|
||||
static LEDPattern Rainbow(int saturation, int value);
|
||||
|
||||
private:
|
||||
std::function<void(frc::LEDPattern::LEDReader,
|
||||
std::function<void(int, frc::Color)>)>
|
||||
m_impl;
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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 <units/voltage.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Interface for motor controlling devices.
|
||||
*/
|
||||
class MotorController {
|
||||
public:
|
||||
virtual ~MotorController() = default;
|
||||
|
||||
/**
|
||||
* Common interface for setting the speed of a motor controller.
|
||||
*
|
||||
* @param speed The speed to set. Value should be between -1.0 and 1.0.
|
||||
*/
|
||||
virtual void Set(double speed) = 0;
|
||||
|
||||
/**
|
||||
* Sets the voltage output of the MotorController. Compensates for
|
||||
* the current bus voltage to ensure that the desired voltage is output even
|
||||
* if the battery voltage is below 12V - highly useful when the voltage
|
||||
* outputs are "meaningful" (e.g. they come from a feedforward calculation).
|
||||
*
|
||||
* <p>NOTE: This function *must* be called regularly in order for voltage
|
||||
* compensation to work properly - unlike the ordinary set function, it is not
|
||||
* "set it and forget it."
|
||||
*
|
||||
* @param output The voltage to output.
|
||||
*/
|
||||
virtual void SetVoltage(units::volt_t output);
|
||||
|
||||
/**
|
||||
* Common interface for getting the current set speed of a motor controller.
|
||||
*
|
||||
* @return The current set speed. Value is between -1.0 and 1.0.
|
||||
*/
|
||||
virtual double Get() const = 0;
|
||||
|
||||
/**
|
||||
* Common interface for inverting direction of a motor controller.
|
||||
*
|
||||
* @param isInverted The state of inversion, true is inverted.
|
||||
*/
|
||||
virtual void SetInverted(bool isInverted) = 0;
|
||||
|
||||
/**
|
||||
* Common interface for returning the inversion state of a motor controller.
|
||||
*
|
||||
* @return isInverted The state of inversion, true is inverted.
|
||||
*/
|
||||
virtual bool GetInverted() const = 0;
|
||||
|
||||
/**
|
||||
* Common interface for disabling a motor.
|
||||
*/
|
||||
virtual void Disable() = 0;
|
||||
|
||||
/**
|
||||
* Common interface to stop the motor until Set is called again.
|
||||
*/
|
||||
virtual void StopMotor() = 0;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,75 @@
|
||||
// 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 <functional>
|
||||
#include <vector>
|
||||
|
||||
#include <wpi/deprecated.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/motorcontrol/MotorController.h"
|
||||
|
||||
WPI_IGNORE_DEPRECATED
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Allows multiple MotorController objects to be linked together.
|
||||
*/
|
||||
class [[deprecated(
|
||||
"Use PWMMotorController::AddFollower() or if using CAN motor controllers,"
|
||||
"use their method of following.")]] MotorControllerGroup
|
||||
: public wpi::Sendable,
|
||||
public MotorController,
|
||||
public wpi::SendableHelper<MotorControllerGroup> {
|
||||
public:
|
||||
/**
|
||||
* Create a new MotorControllerGroup with the provided MotorControllers.
|
||||
*
|
||||
* @tparam MotorControllers The MotorController types.
|
||||
* @param motorController The first MotorController to add
|
||||
* @param motorControllers The MotorControllers to add
|
||||
*/
|
||||
template <class... MotorControllers>
|
||||
explicit MotorControllerGroup(MotorController& motorController,
|
||||
MotorControllers&... motorControllers)
|
||||
: m_motorControllers(std::vector<std::reference_wrapper<MotorController>>{
|
||||
motorController, motorControllers...}) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MotorControllerGroup with the provided MotorControllers.
|
||||
*
|
||||
* @param motorControllers The MotorControllers to add.
|
||||
*/
|
||||
explicit MotorControllerGroup(
|
||||
std::vector<std::reference_wrapper<MotorController>>&& motorControllers);
|
||||
|
||||
MotorControllerGroup(MotorControllerGroup&&) = default;
|
||||
MotorControllerGroup& operator=(MotorControllerGroup&&) = default;
|
||||
|
||||
void Set(double speed) override;
|
||||
void SetVoltage(units::volt_t output) override;
|
||||
double Get() const override;
|
||||
void SetInverted(bool isInverted) override;
|
||||
bool GetInverted() const override;
|
||||
void Disable() override;
|
||||
void StopMotor() override;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
bool m_isInverted = false;
|
||||
std::vector<std::reference_wrapper<MotorController>> m_motorControllers;
|
||||
|
||||
void Initialize();
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
|
||||
WPI_UNIGNORE_DEPRECATED
|
||||
@@ -0,0 +1,123 @@
|
||||
// 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 <string>
|
||||
|
||||
#include <units/time.h>
|
||||
#include <wpi/mutex.h>
|
||||
|
||||
#include "frc/Timer.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* The Motor Safety feature acts as a watchdog timer for an individual motor. It
|
||||
* operates by maintaining a timer that tracks how long it has been since the
|
||||
* feed() method has been called for that actuator. Code in the Driver Station
|
||||
* class initiates a comparison of these timers to the timeout values for any
|
||||
* actuator with safety enabled every 5 received packets (100ms nominal).
|
||||
*
|
||||
* The subclass should call Feed() whenever the motor value is updated.
|
||||
*/
|
||||
class MotorSafety {
|
||||
public:
|
||||
MotorSafety();
|
||||
virtual ~MotorSafety();
|
||||
|
||||
MotorSafety(MotorSafety&& rhs);
|
||||
MotorSafety& operator=(MotorSafety&& rhs);
|
||||
|
||||
/**
|
||||
* Feed the motor safety object.
|
||||
*
|
||||
* Resets the timer on this object that is used to do the timeouts.
|
||||
*/
|
||||
void Feed();
|
||||
|
||||
/**
|
||||
* Set the expiration time for the corresponding motor safety object.
|
||||
*
|
||||
* @param expirationTime The timeout value.
|
||||
*/
|
||||
void SetExpiration(units::second_t expirationTime);
|
||||
|
||||
/**
|
||||
* Retrieve the timeout value for the corresponding motor safety object.
|
||||
*
|
||||
* @return the timeout value.
|
||||
*/
|
||||
units::second_t GetExpiration() const;
|
||||
|
||||
/**
|
||||
* Determine if the motor is still operating or has timed out.
|
||||
*
|
||||
* @return true if the motor is still operating normally and hasn't timed out.
|
||||
*/
|
||||
bool IsAlive() const;
|
||||
|
||||
/**
|
||||
* Enable/disable motor safety for this device.
|
||||
*
|
||||
* Turn on and off the motor safety option for this PWM object.
|
||||
*
|
||||
* @param enabled True if motor safety is enforced for this object.
|
||||
*/
|
||||
void SetSafetyEnabled(bool enabled);
|
||||
|
||||
/**
|
||||
* Return the state of the motor safety enabled flag.
|
||||
*
|
||||
* Return if the motor safety is currently enabled for this device.
|
||||
*
|
||||
* @return True if motor safety is enforced for this device.
|
||||
*/
|
||||
bool IsSafetyEnabled() const;
|
||||
|
||||
/**
|
||||
* Check if this motor has exceeded its timeout.
|
||||
*
|
||||
* This method is called periodically to determine if this motor has exceeded
|
||||
* its timeout value. If it has, the stop method is called, and the motor is
|
||||
* shut down until its value is updated again.
|
||||
*/
|
||||
void Check();
|
||||
|
||||
/**
|
||||
* Check the motors to see if any have timed out.
|
||||
*
|
||||
* This static method is called periodically to poll all the motors and stop
|
||||
* any that have timed out.
|
||||
*/
|
||||
static void CheckMotors();
|
||||
|
||||
/**
|
||||
* Called to stop the motor when the timeout expires.
|
||||
*/
|
||||
virtual void StopMotor() = 0;
|
||||
|
||||
/**
|
||||
* Returns a description to print when an error occurs.
|
||||
*
|
||||
* @return Description to print when an error occurs.
|
||||
*/
|
||||
virtual std::string GetDescription() const = 0;
|
||||
|
||||
private:
|
||||
static constexpr auto kDefaultSafetyExpiration = 100_ms;
|
||||
|
||||
// The expiration time for this object
|
||||
units::second_t m_expiration = kDefaultSafetyExpiration;
|
||||
|
||||
// True if motor safety is enabled for this motor
|
||||
bool m_enabled = false;
|
||||
|
||||
// The FPGA clock value when the motor has expired
|
||||
units::second_t m_stopTime = Timer::GetFPGATimestamp();
|
||||
|
||||
mutable wpi::mutex m_thisMutex;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,171 @@
|
||||
// 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 <concepts>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <hal/SimDevice.h>
|
||||
#include <units/voltage.h>
|
||||
#include <wpi/deprecated.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/MotorSafety.h"
|
||||
#include "frc/PWM.h"
|
||||
#include "frc/motorcontrol/MotorController.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
WPI_IGNORE_DEPRECATED
|
||||
|
||||
/**
|
||||
* Common base class for all PWM Motor Controllers.
|
||||
*/
|
||||
class PWMMotorController : public MotorController,
|
||||
public MotorSafety,
|
||||
public wpi::Sendable,
|
||||
public wpi::SendableHelper<PWMMotorController> {
|
||||
public:
|
||||
PWMMotorController(PWMMotorController&&) = default;
|
||||
PWMMotorController& operator=(PWMMotorController&&) = default;
|
||||
|
||||
/**
|
||||
* Set the PWM value.
|
||||
*
|
||||
* The PWM value is set using a range of -1.0 to 1.0, appropriately scaling
|
||||
* the value for the FPGA.
|
||||
*
|
||||
* @param value The speed value between -1.0 and 1.0 to set.
|
||||
*/
|
||||
void Set(double value) override;
|
||||
|
||||
/**
|
||||
* Sets the voltage output of the PWMMotorController. Compensates for
|
||||
* the current bus voltage to ensure that the desired voltage is output even
|
||||
* if the battery voltage is below 12V - highly useful when the voltage
|
||||
* outputs are "meaningful" (e.g. they come from a feedforward calculation).
|
||||
*
|
||||
* <p>NOTE: This function *must* be called regularly in order for voltage
|
||||
* compensation to work properly - unlike the ordinary set function, it is not
|
||||
* "set it and forget it."
|
||||
*
|
||||
* @param output The voltage to output.
|
||||
*/
|
||||
void SetVoltage(units::volt_t output) override;
|
||||
|
||||
/**
|
||||
* Get the recently set value of the PWM. This value is affected by the
|
||||
* inversion property. If you want the value that is sent directly to the
|
||||
* MotorController, use PWM::GetSpeed() instead.
|
||||
*
|
||||
* @return The most recently set value for the PWM between -1.0 and 1.0.
|
||||
*/
|
||||
double Get() const override;
|
||||
|
||||
/**
|
||||
* Gets the voltage output of the motor controller, nominally between -12 V
|
||||
* and 12 V.
|
||||
*
|
||||
* @return The voltage of the motor controller, nominally between -12 V and 12
|
||||
* V.
|
||||
*/
|
||||
virtual units::volt_t GetVoltage() const;
|
||||
|
||||
void SetInverted(bool isInverted) override;
|
||||
|
||||
bool GetInverted() const override;
|
||||
|
||||
void Disable() override;
|
||||
|
||||
// MotorSafety interface
|
||||
void StopMotor() override;
|
||||
std::string GetDescription() const override;
|
||||
|
||||
int GetChannel() const;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Make the given PWM motor controller follow the output of this one.
|
||||
*
|
||||
* @param follower The motor controller follower.
|
||||
*/
|
||||
void AddFollower(PWMMotorController& follower);
|
||||
|
||||
/**
|
||||
* Make the given PWM motor controller follow the output of this one.
|
||||
*
|
||||
* @param follower The motor controller follower.
|
||||
*/
|
||||
template <std::derived_from<PWMMotorController> T>
|
||||
void AddFollower(T&& follower) {
|
||||
m_owningFollowers.emplace_back(
|
||||
std::make_unique<std::decay_t<T>>(std::forward<T>(follower)));
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor for a PWM Motor %Controller connected via PWM.
|
||||
*
|
||||
* @param name Name to use for SendableRegistry
|
||||
* @param channel The PWM channel that the controller is attached to. 0-9 are
|
||||
* on-board, 10-19 are on the MXP port
|
||||
*/
|
||||
PWMMotorController(std::string_view name, int channel);
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
/// 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; }
|
||||
};
|
||||
|
||||
WPI_UNIGNORE_DEPRECATED
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,183 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/Types.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/CompressorConfigType.h"
|
||||
#include "frc/PneumaticsBase.h"
|
||||
#include "frc/PneumaticsModuleType.h"
|
||||
#include "frc/SensorUtil.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Class for operating a compressor connected to a pneumatics module.
|
||||
*
|
||||
* The module will automatically run in closed loop mode by default whenever a
|
||||
* Solenoid object is created. For most cases, a Compressor object does not need
|
||||
* to be instantiated or used in a robot program. This class is only required in
|
||||
* cases where the robot program needs a more detailed status of the compressor
|
||||
* or to enable/disable closed loop control.
|
||||
*
|
||||
* Note: you cannot operate the compressor directly from this class as doing so
|
||||
* would circumvent the safety provided by using the pressure switch and closed
|
||||
* loop control. You can only turn off closed loop control, thereby stopping
|
||||
* the compressor from operating.
|
||||
*/
|
||||
class Compressor : public wpi::Sendable,
|
||||
public wpi::SendableHelper<Compressor> {
|
||||
public:
|
||||
/**
|
||||
* Constructs a compressor for a specified module and type.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param module The module ID to use.
|
||||
* @param moduleType The module type to use.
|
||||
*/
|
||||
Compressor(int busId, int module, PneumaticsModuleType moduleType);
|
||||
|
||||
/**
|
||||
* Constructs a compressor for a default module and specified type.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param moduleType The module type to use.
|
||||
*/
|
||||
Compressor(int busId, PneumaticsModuleType moduleType);
|
||||
|
||||
~Compressor() override;
|
||||
|
||||
Compressor(const Compressor&) = delete;
|
||||
Compressor& operator=(const Compressor&) = delete;
|
||||
|
||||
Compressor(Compressor&&) = default;
|
||||
Compressor& operator=(Compressor&&) = default;
|
||||
|
||||
/**
|
||||
* Returns whether the compressor is active or not.
|
||||
*
|
||||
* @return true if the compressor is on - otherwise false.
|
||||
*/
|
||||
bool IsEnabled() const;
|
||||
|
||||
/**
|
||||
* Returns the state of the pressure switch.
|
||||
*
|
||||
* @return True if pressure switch indicates that the system is not full,
|
||||
* otherwise false.
|
||||
*/
|
||||
bool GetPressureSwitchValue() const;
|
||||
|
||||
/**
|
||||
* Get the current drawn by the compressor.
|
||||
*
|
||||
* @return Current drawn by the compressor.
|
||||
*/
|
||||
units::ampere_t GetCurrent() const;
|
||||
|
||||
/**
|
||||
* If supported by the device, returns the analog input voltage (on channel
|
||||
* 0).
|
||||
*
|
||||
* This function is only supported by the REV PH. On CTRE PCM, this will
|
||||
* return 0.
|
||||
*
|
||||
* @return The analog input voltage, in volts.
|
||||
*/
|
||||
units::volt_t GetAnalogVoltage() const;
|
||||
|
||||
/**
|
||||
* If supported by the device, returns the pressure read by the analog
|
||||
* pressure sensor (on channel 0).
|
||||
*
|
||||
* This function is only supported by the REV PH with the REV Analog Pressure
|
||||
* Sensor. On CTRE PCM, this will return 0.
|
||||
*
|
||||
* @return The pressure read by the analog pressure sensor.
|
||||
*/
|
||||
units::pounds_per_square_inch_t GetPressure() const;
|
||||
|
||||
/**
|
||||
* Disable the compressor.
|
||||
*/
|
||||
void Disable();
|
||||
|
||||
/**
|
||||
* Enables the compressor in digital mode using the digital pressure switch.
|
||||
* The compressor will turn on when the pressure switch indicates that the
|
||||
* system is not full, and will turn off when the pressure switch indicates
|
||||
* that the system is full.
|
||||
*/
|
||||
void EnableDigital();
|
||||
|
||||
/**
|
||||
* If supported by the device, enables the compressor in analog mode. This
|
||||
* mode uses an analog pressure sensor connected to analog channel 0 to cycle
|
||||
* the compressor. The compressor will turn on when the pressure drops below
|
||||
* {@code minPressure} and will turn off when the pressure reaches {@code
|
||||
* maxPressure}. This mode is only supported by the REV PH with the REV Analog
|
||||
* Pressure Sensor connected to analog channel 0.
|
||||
*
|
||||
* On CTRE PCM, this will enable digital control.
|
||||
*
|
||||
* @param minPressure The minimum pressure. The compressor will turn on when
|
||||
* the pressure drops below this value.
|
||||
* @param maxPressure The maximum pressure. The compressor will turn off when
|
||||
* the pressure reaches this value.
|
||||
*/
|
||||
void EnableAnalog(units::pounds_per_square_inch_t minPressure,
|
||||
units::pounds_per_square_inch_t maxPressure);
|
||||
|
||||
/**
|
||||
* If supported by the device, enables the compressor in hybrid mode. This
|
||||
* mode uses both a digital pressure switch and an analog pressure sensor
|
||||
* connected to analog channel 0 to cycle the compressor. This mode is only
|
||||
* supported by the REV PH with the REV Analog Pressure Sensor connected to
|
||||
* analog channel 0.
|
||||
*
|
||||
* The compressor will turn on when \a both:
|
||||
*
|
||||
* - The digital pressure switch indicates the system is not full AND
|
||||
* - The analog pressure sensor indicates that the pressure in the system
|
||||
* is below the specified minimum pressure.
|
||||
*
|
||||
* The compressor will turn off when \a either:
|
||||
*
|
||||
* - The digital pressure switch is disconnected or indicates that the system
|
||||
* is full OR
|
||||
* - The pressure detected by the analog sensor is greater than the specified
|
||||
* maximum pressure.
|
||||
*
|
||||
* On CTRE PCM, this will enable digital control.
|
||||
*
|
||||
* @param minPressure The minimum pressure. The compressor will turn on
|
||||
* when the pressure drops below this value and the pressure switch indicates
|
||||
* that the system is not full.
|
||||
* @param maxPressure The maximum pressure. The compressor will turn
|
||||
* off when the pressure reaches this value or the pressure switch is
|
||||
* disconnected or indicates that the system is full.
|
||||
*/
|
||||
void EnableHybrid(units::pounds_per_square_inch_t minPressure,
|
||||
units::pounds_per_square_inch_t maxPressure);
|
||||
|
||||
/**
|
||||
* Returns the active compressor configuration.
|
||||
*
|
||||
* @return The active compressor configuration.
|
||||
*/
|
||||
CompressorConfigType GetConfigType() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<PneumaticsBase> m_module;
|
||||
PneumaticsModuleType m_moduleType;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,22 @@
|
||||
// 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
|
||||
|
||||
namespace frc {
|
||||
/**
|
||||
* Compressor config type.
|
||||
*/
|
||||
enum class CompressorConfigType {
|
||||
/// Disabled.
|
||||
Disabled = 0,
|
||||
/// Digital.
|
||||
Digital = 1,
|
||||
/// Analog.
|
||||
Analog = 2,
|
||||
/// Hybrid.
|
||||
Hybrid = 3
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,140 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/Types.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/PneumaticsBase.h"
|
||||
#include "frc/PneumaticsModuleType.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* DoubleSolenoid class for running 2 channels of high voltage Digital Output
|
||||
* on a pneumatics module.
|
||||
*
|
||||
* The DoubleSolenoid class is typically used for pneumatics solenoids that
|
||||
* have two positions controlled by two separate channels.
|
||||
*/
|
||||
class DoubleSolenoid : public wpi::Sendable,
|
||||
public wpi::SendableHelper<DoubleSolenoid> {
|
||||
public:
|
||||
/**
|
||||
* Possible values for a DoubleSolenoid.
|
||||
*/
|
||||
enum Value {
|
||||
/// Off position.
|
||||
kOff,
|
||||
/// Forward position.
|
||||
kForward,
|
||||
/// Reverse position.
|
||||
kReverse
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a double solenoid for a specified module of a specific module
|
||||
* type.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param module The module of the solenoid module to use.
|
||||
* @param moduleType The module type to use.
|
||||
* @param forwardChannel The forward channel on the module to control.
|
||||
* @param reverseChannel The reverse channel on the module to control.
|
||||
*/
|
||||
DoubleSolenoid(int busId, int module, PneumaticsModuleType moduleType,
|
||||
int forwardChannel, int reverseChannel);
|
||||
|
||||
/**
|
||||
* Constructs a double solenoid for a default module of a specific module
|
||||
* type.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param moduleType The module type to use.
|
||||
* @param forwardChannel The forward channel on the module to control.
|
||||
* @param reverseChannel The reverse channel on the module to control.
|
||||
*/
|
||||
DoubleSolenoid(int busId, PneumaticsModuleType moduleType, int forwardChannel,
|
||||
int reverseChannel);
|
||||
|
||||
~DoubleSolenoid() override;
|
||||
|
||||
DoubleSolenoid(DoubleSolenoid&&) = default;
|
||||
DoubleSolenoid& operator=(DoubleSolenoid&&) = default;
|
||||
|
||||
/**
|
||||
* Set the value of a solenoid.
|
||||
*
|
||||
* @param value The value to set (Off, Forward or Reverse)
|
||||
*/
|
||||
void Set(Value value);
|
||||
|
||||
/**
|
||||
* Read the current value of the solenoid.
|
||||
*
|
||||
* @return The current value of the solenoid.
|
||||
*/
|
||||
Value Get() const;
|
||||
|
||||
/**
|
||||
* Toggle the value of the solenoid.
|
||||
*
|
||||
* If the solenoid is set to forward, it'll be set to reverse. If the solenoid
|
||||
* is set to reverse, it'll be set to forward. If the solenoid is set to off,
|
||||
* nothing happens.
|
||||
*/
|
||||
void Toggle();
|
||||
|
||||
/**
|
||||
* Get the forward channel.
|
||||
*
|
||||
* @return the forward channel.
|
||||
*/
|
||||
int GetFwdChannel() const;
|
||||
|
||||
/**
|
||||
* Get the reverse channel.
|
||||
*
|
||||
* @return the reverse channel.
|
||||
*/
|
||||
int GetRevChannel() const;
|
||||
|
||||
/**
|
||||
* Check if the forward solenoid is Disabled.
|
||||
*
|
||||
* If a solenoid is shorted, it is added to the DisabledList and disabled
|
||||
* until power cycle, or until faults are cleared.
|
||||
*
|
||||
* @see ClearAllStickyFaults()
|
||||
* @return If solenoid is disabled due to short.
|
||||
*/
|
||||
bool IsFwdSolenoidDisabled() const;
|
||||
|
||||
/**
|
||||
* Check if the reverse solenoid is Disabled.
|
||||
*
|
||||
* If a solenoid is shorted, it is added to the DisabledList and disabled
|
||||
* until power cycle, or until faults are cleared.
|
||||
*
|
||||
* @see ClearAllStickyFaults()
|
||||
* @return If solenoid is disabled due to short.
|
||||
*/
|
||||
bool IsRevSolenoidDisabled() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<PneumaticsBase> m_module;
|
||||
int m_forwardChannel; // The forward channel on the module to control.
|
||||
int m_reverseChannel; // The reverse channel on the module to control.
|
||||
int m_forwardMask; // The mask for the forward channel.
|
||||
int m_reverseMask; // The mask for the reverse channel.
|
||||
int m_mask;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,317 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/Types.h>
|
||||
#include <units/pressure.h>
|
||||
#include <wpi/DenseMap.h>
|
||||
#include <wpi/mutex.h>
|
||||
|
||||
#include "PneumaticsBase.h"
|
||||
|
||||
namespace frc {
|
||||
/** Module class for controlling a REV Robotics Pneumatic Hub. */
|
||||
class PneumaticHub : public PneumaticsBase {
|
||||
public:
|
||||
/**
|
||||
* Constructs a PneumaticHub with the default ID (1).
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
*/
|
||||
explicit PneumaticHub(int busId);
|
||||
|
||||
/**
|
||||
* Constructs a PneumaticHub.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param module module number to construct
|
||||
*/
|
||||
PneumaticHub(int busId, int module);
|
||||
|
||||
~PneumaticHub() override = default;
|
||||
|
||||
bool GetCompressor() const override;
|
||||
|
||||
/**
|
||||
* Disables the compressor. The compressor will not turn on until
|
||||
* EnableCompressorDigital(), EnableCompressorAnalog(), or
|
||||
* EnableCompressorHybrid() are called.
|
||||
*/
|
||||
void DisableCompressor() override;
|
||||
|
||||
void EnableCompressorDigital() override;
|
||||
|
||||
/**
|
||||
* Enables the compressor in analog mode. This mode uses an analog pressure
|
||||
* sensor connected to analog channel 0 to cycle the compressor. The
|
||||
* compressor will turn on when the pressure drops below {@code minPressure}
|
||||
* and will turn off when the pressure reaches {@code maxPressure}.
|
||||
*
|
||||
* @param minPressure The minimum pressure. The compressor will turn on when
|
||||
* the pressure drops below this value. Range 0 - 120 PSI.
|
||||
* @param maxPressure The maximum pressure. The compressor will turn off when
|
||||
* the pressure reaches this value. Range 0 - 120 PSI. Must be larger then
|
||||
* minPressure.
|
||||
*/
|
||||
void EnableCompressorAnalog(
|
||||
units::pounds_per_square_inch_t minPressure,
|
||||
units::pounds_per_square_inch_t maxPressure) override;
|
||||
|
||||
/**
|
||||
* Enables the compressor in hybrid mode. This mode uses both a digital
|
||||
* pressure switch and an analog pressure sensor connected to analog channel 0
|
||||
* to cycle the compressor.
|
||||
*
|
||||
* The compressor will turn on when \a both:
|
||||
*
|
||||
* - The digital pressure switch indicates the system is not full AND
|
||||
* - The analog pressure sensor indicates that the pressure in the system is
|
||||
* below the specified minimum pressure.
|
||||
*
|
||||
* The compressor will turn off when \a either:
|
||||
*
|
||||
* - The digital pressure switch is disconnected or indicates that the system
|
||||
* is full OR
|
||||
* - The pressure detected by the analog sensor is greater than the specified
|
||||
* maximum pressure.
|
||||
*
|
||||
* @param minPressure The minimum pressure. The compressor will turn on when
|
||||
* the pressure drops below this value and the pressure switch indicates that
|
||||
* the system is not full. Range 0 - 120 PSI.
|
||||
* @param maxPressure The maximum pressure. The compressor will turn off when
|
||||
* the pressure reaches this value or the pressure switch is disconnected or
|
||||
* indicates that the system is full. Range 0 - 120 PSI. Must be larger then
|
||||
* minPressure.
|
||||
*/
|
||||
void EnableCompressorHybrid(
|
||||
units::pounds_per_square_inch_t minPressure,
|
||||
units::pounds_per_square_inch_t maxPressure) override;
|
||||
|
||||
CompressorConfigType GetCompressorConfigType() const override;
|
||||
|
||||
bool GetPressureSwitch() const override;
|
||||
|
||||
units::ampere_t GetCompressorCurrent() const override;
|
||||
|
||||
void SetSolenoids(int mask, int values) override;
|
||||
|
||||
int GetSolenoids() const override;
|
||||
|
||||
int GetModuleNumber() const override;
|
||||
|
||||
int GetSolenoidDisabledList() const override;
|
||||
|
||||
void FireOneShot(int index) override;
|
||||
|
||||
void SetOneShotDuration(int index, units::second_t duration) override;
|
||||
|
||||
bool CheckSolenoidChannel(int channel) const override;
|
||||
|
||||
int CheckAndReserveSolenoids(int mask) override;
|
||||
|
||||
void UnreserveSolenoids(int mask) override;
|
||||
|
||||
bool ReserveCompressor() override;
|
||||
|
||||
void UnreserveCompressor() override;
|
||||
|
||||
Solenoid MakeSolenoid(int channel) override;
|
||||
DoubleSolenoid MakeDoubleSolenoid(int forwardChannel,
|
||||
int reverseChannel) override;
|
||||
Compressor MakeCompressor() override;
|
||||
|
||||
void ReportUsage(std::string_view device, std::string_view data) override;
|
||||
|
||||
/** Version and device data received from a REV PH. */
|
||||
struct Version {
|
||||
/** The firmware major version. */
|
||||
uint32_t FirmwareMajor;
|
||||
/** The firmware minor version. */
|
||||
uint32_t FirmwareMinor;
|
||||
/** The firmware fix version. */
|
||||
uint32_t FirmwareFix;
|
||||
/** The hardware minor version. */
|
||||
uint32_t HardwareMinor;
|
||||
/** The hardware major version. */
|
||||
uint32_t HardwareMajor;
|
||||
/** The device's unique ID. */
|
||||
uint32_t UniqueId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the hardware and firmware versions of this device.
|
||||
*
|
||||
* @return The hardware and firmware versions.
|
||||
*/
|
||||
Version GetVersion() const;
|
||||
|
||||
/**
|
||||
* Faults for a REV PH. These faults are only active while the condition is
|
||||
* active.
|
||||
*/
|
||||
struct Faults {
|
||||
/** Fault on channel 0. */
|
||||
uint32_t Channel0Fault : 1;
|
||||
/** Fault on channel 1. */
|
||||
uint32_t Channel1Fault : 1;
|
||||
/** Fault on channel 2. */
|
||||
uint32_t Channel2Fault : 1;
|
||||
/** Fault on channel 3. */
|
||||
uint32_t Channel3Fault : 1;
|
||||
/** Fault on channel 4. */
|
||||
uint32_t Channel4Fault : 1;
|
||||
/** Fault on channel 5. */
|
||||
uint32_t Channel5Fault : 1;
|
||||
/** Fault on channel 6. */
|
||||
uint32_t Channel6Fault : 1;
|
||||
/** Fault on channel 7. */
|
||||
uint32_t Channel7Fault : 1;
|
||||
/** Fault on channel 8. */
|
||||
uint32_t Channel8Fault : 1;
|
||||
/** Fault on channel 9. */
|
||||
uint32_t Channel9Fault : 1;
|
||||
/** Fault on channel 10. */
|
||||
uint32_t Channel10Fault : 1;
|
||||
/** Fault on channel 11. */
|
||||
uint32_t Channel11Fault : 1;
|
||||
/** Fault on channel 12. */
|
||||
uint32_t Channel12Fault : 1;
|
||||
/** Fault on channel 13. */
|
||||
uint32_t Channel13Fault : 1;
|
||||
/** Fault on channel 14. */
|
||||
uint32_t Channel14Fault : 1;
|
||||
/** Fault on channel 15. */
|
||||
uint32_t Channel15Fault : 1;
|
||||
/** An overcurrent event occurred on the compressor output. */
|
||||
uint32_t CompressorOverCurrent : 1;
|
||||
/** The compressor output has an open circuit. */
|
||||
uint32_t CompressorOpen : 1;
|
||||
/** An overcurrent event occurred on a solenoid output. */
|
||||
uint32_t SolenoidOverCurrent : 1;
|
||||
/** The input voltage is below the minimum voltage. */
|
||||
uint32_t Brownout : 1;
|
||||
/** A warning was raised by the device's CAN controller. */
|
||||
uint32_t CanWarning : 1;
|
||||
/** The hardware on the device has malfunctioned. */
|
||||
uint32_t HardwareFault : 1;
|
||||
|
||||
/**
|
||||
* Gets whether there is a fault at the specified channel.
|
||||
* @param channel Channel to check for faults.
|
||||
* @return True if a a fault exists at the channel, otherwise false.
|
||||
* @throws A ChannelIndexOutOfRange error if the provided channel is outside
|
||||
* of the range supported by the hardware.
|
||||
*/
|
||||
bool GetChannelFault(int channel) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the faults currently active on this device.
|
||||
*
|
||||
* @return The faults.
|
||||
*/
|
||||
Faults GetFaults() const;
|
||||
|
||||
/**
|
||||
* Sticky faults for a REV PH. These faults will remain active until they
|
||||
* are reset by the user.
|
||||
*/
|
||||
struct StickyFaults {
|
||||
/** An overcurrent event occurred on the compressor output. */
|
||||
uint32_t CompressorOverCurrent : 1;
|
||||
/** The compressor output has an open circuit. */
|
||||
uint32_t CompressorOpen : 1;
|
||||
/** An overcurrent event occurred on a solenoid output. */
|
||||
uint32_t SolenoidOverCurrent : 1;
|
||||
/** The input voltage is below the minimum voltage. */
|
||||
uint32_t Brownout : 1;
|
||||
/** A warning was raised by the device's CAN controller. */
|
||||
uint32_t CanWarning : 1;
|
||||
/** The device's CAN controller experienced a "Bus Off" event. */
|
||||
uint32_t CanBusOff : 1;
|
||||
/** The hardware on the device has malfunctioned. */
|
||||
uint32_t HardwareFault : 1;
|
||||
/** The firmware on the device has malfunctioned. */
|
||||
uint32_t FirmwareFault : 1;
|
||||
/** The device has rebooted. */
|
||||
uint32_t HasReset : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the sticky faults currently active on this device.
|
||||
*
|
||||
* @return The sticky faults.
|
||||
*/
|
||||
StickyFaults GetStickyFaults() const;
|
||||
|
||||
/** Clears the sticky faults. */
|
||||
void ClearStickyFaults();
|
||||
|
||||
/**
|
||||
* Returns the current input voltage for this device.
|
||||
*
|
||||
* @return The input voltage.
|
||||
*/
|
||||
units::volt_t GetInputVoltage() const;
|
||||
|
||||
/**
|
||||
* Returns the current voltage of the regulated 5v supply.
|
||||
*
|
||||
* @return The current voltage of the 5v supply.
|
||||
*/
|
||||
units::volt_t Get5VRegulatedVoltage() const;
|
||||
|
||||
/**
|
||||
* Returns the total current drawn by all solenoids.
|
||||
*
|
||||
* @return Total current drawn by all solenoids.
|
||||
*/
|
||||
units::ampere_t GetSolenoidsTotalCurrent() const;
|
||||
|
||||
/**
|
||||
* Returns the current voltage of the solenoid power supply.
|
||||
*
|
||||
* @return The current voltage of the solenoid power supply.
|
||||
*/
|
||||
units::volt_t GetSolenoidsVoltage() const;
|
||||
|
||||
/**
|
||||
* Returns the raw voltage of the specified analog input channel.
|
||||
*
|
||||
* @param channel The analog input channel to read voltage from.
|
||||
* @return The voltage of the specified analog input channel.
|
||||
*/
|
||||
units::volt_t GetAnalogVoltage(int channel) const override;
|
||||
|
||||
/**
|
||||
* Returns the pressure read by an analog pressure sensor on the specified
|
||||
* analog input channel.
|
||||
*
|
||||
* @param channel The analog input channel to read pressure from.
|
||||
* @return The pressure read by an analog pressure sensor on the specified
|
||||
* analog input channel.
|
||||
*/
|
||||
units::pounds_per_square_inch_t GetPressure(int channel) const override;
|
||||
|
||||
private:
|
||||
class DataStore;
|
||||
friend class DataStore;
|
||||
friend class PneumaticsBase;
|
||||
PneumaticHub(int busId, HAL_REVPHHandle handle, int module);
|
||||
|
||||
static std::shared_ptr<PneumaticsBase> GetForModule(int busId, int module);
|
||||
|
||||
std::shared_ptr<DataStore> m_dataStore;
|
||||
HAL_REVPHHandle m_handle;
|
||||
int m_module;
|
||||
|
||||
static wpi::mutex m_handleLock;
|
||||
static std::unique_ptr<wpi::DenseMap<int, std::weak_ptr<DataStore>>[]>
|
||||
m_handleMaps;
|
||||
static std::weak_ptr<DataStore>& GetDataStore(int busId, int module);
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,286 @@
|
||||
// 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 <memory>
|
||||
#include <string_view>
|
||||
|
||||
#include <units/current.h>
|
||||
#include <units/pressure.h>
|
||||
#include <units/time.h>
|
||||
#include <units/voltage.h>
|
||||
|
||||
#include "frc/CompressorConfigType.h"
|
||||
#include "frc/PneumaticsModuleType.h"
|
||||
|
||||
namespace frc {
|
||||
class Solenoid;
|
||||
class DoubleSolenoid;
|
||||
class Compressor;
|
||||
|
||||
/**
|
||||
* Base class for pneumatics devices.
|
||||
*/
|
||||
class PneumaticsBase {
|
||||
public:
|
||||
virtual ~PneumaticsBase() = default;
|
||||
|
||||
/**
|
||||
* Returns whether the compressor is active or not.
|
||||
*
|
||||
* @return True if the compressor is on - otherwise false.
|
||||
*/
|
||||
virtual bool GetCompressor() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the state of the pressure switch.
|
||||
*
|
||||
* @return True if pressure switch indicates that the system is full,
|
||||
* otherwise false.
|
||||
*/
|
||||
virtual bool GetPressureSwitch() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the current drawn by the compressor.
|
||||
*
|
||||
* @return The current drawn by the compressor.
|
||||
*/
|
||||
virtual units::ampere_t GetCompressorCurrent() const = 0;
|
||||
|
||||
/** Disables the compressor. */
|
||||
virtual void DisableCompressor() = 0;
|
||||
|
||||
/**
|
||||
* Enables the compressor in digital mode using the digital pressure switch.
|
||||
* The compressor will turn on when the pressure switch indicates that the
|
||||
* system is not full, and will turn off when the pressure switch indicates
|
||||
* that the system is full.
|
||||
*/
|
||||
virtual void EnableCompressorDigital() = 0;
|
||||
|
||||
/**
|
||||
* If supported by the device, enables the compressor in analog mode. This
|
||||
* mode uses an analog pressure sensor connected to analog channel 0 to cycle
|
||||
* the compressor. The compressor will turn on when the pressure drops below
|
||||
* {@code minPressure} and will turn off when the pressure reaches {@code
|
||||
* maxPressure}. This mode is only supported by the REV PH with the REV Analog
|
||||
* Pressure Sensor connected to analog channel 0.
|
||||
*
|
||||
* On CTRE PCM, this will enable digital control.
|
||||
*
|
||||
* @param minPressure The minimum pressure. The compressor will turn on
|
||||
* when the pressure drops below this value.
|
||||
* @param maxPressure The maximum pressure. The compressor will turn
|
||||
* off when the pressure reaches this value.
|
||||
*/
|
||||
virtual void EnableCompressorAnalog(
|
||||
units::pounds_per_square_inch_t minPressure,
|
||||
units::pounds_per_square_inch_t maxPressure) = 0;
|
||||
|
||||
/**
|
||||
* If supported by the device, enables the compressor in hybrid mode. This
|
||||
* mode uses both a digital pressure switch and an analog pressure sensor
|
||||
* connected to analog channel 0 to cycle the compressor. This mode is only
|
||||
* supported by the REV PH with the REV Analog Pressure Sensor connected to
|
||||
* analog channel 0.
|
||||
*
|
||||
* The compressor will turn on when \a both:
|
||||
*
|
||||
* - The digital pressure switch indicates the system is not full AND
|
||||
* - The analog pressure sensor indicates that the pressure in the system
|
||||
* is below the specified minimum pressure.
|
||||
*
|
||||
* The compressor will turn off when \a either:
|
||||
*
|
||||
* - The digital pressure switch is disconnected or indicates that the system
|
||||
* is full OR
|
||||
* - The pressure detected by the analog sensor is greater than the specified
|
||||
* maximum pressure.
|
||||
*
|
||||
* On CTRE PCM, this will enable digital control.
|
||||
*
|
||||
* @param minPressure The minimum pressure. The compressor will turn on
|
||||
* when the pressure drops below this value and the pressure switch indicates
|
||||
* that the system is not full.
|
||||
* @param maxPressure The maximum pressure. The compressor will turn
|
||||
* off when the pressure reaches this value or the pressure switch is
|
||||
* disconnected or indicates that the system is full.
|
||||
*/
|
||||
virtual void EnableCompressorHybrid(
|
||||
units::pounds_per_square_inch_t minPressure,
|
||||
units::pounds_per_square_inch_t maxPressure) = 0;
|
||||
|
||||
/**
|
||||
* Returns the active compressor configuration.
|
||||
*
|
||||
* @return The active compressor configuration.
|
||||
*/
|
||||
virtual CompressorConfigType GetCompressorConfigType() const = 0;
|
||||
|
||||
/**
|
||||
* Sets solenoids on a pneumatics module.
|
||||
*
|
||||
* @param mask Bitmask indicating which solenoids to set. The LSB represents
|
||||
* solenoid 0.
|
||||
* @param values Bitmask indicating the desired states of the solenoids. The
|
||||
* LSB represents solenoid 0.
|
||||
*/
|
||||
virtual void SetSolenoids(int mask, int values) = 0;
|
||||
|
||||
/**
|
||||
* Gets a bitmask of solenoid values.
|
||||
*
|
||||
* @return Bitmask containing the state of the solenoids. The LSB represents
|
||||
* solenoid 0.
|
||||
*/
|
||||
virtual int GetSolenoids() const = 0;
|
||||
|
||||
/**
|
||||
* Get module number for this module.
|
||||
*
|
||||
* @return module number
|
||||
*/
|
||||
virtual int GetModuleNumber() const = 0;
|
||||
|
||||
/**
|
||||
* Get a bitmask of disabled solenoids.
|
||||
*
|
||||
* @return Bitmask indicating disabled solenoids. The LSB represents solenoid
|
||||
* 0.
|
||||
*/
|
||||
virtual int GetSolenoidDisabledList() const = 0;
|
||||
|
||||
/**
|
||||
* Fire a single solenoid shot.
|
||||
*
|
||||
* @param index solenoid index
|
||||
*/
|
||||
virtual void FireOneShot(int index) = 0;
|
||||
|
||||
/**
|
||||
* Set the duration for a single solenoid shot.
|
||||
*
|
||||
* @param index solenoid index
|
||||
* @param duration shot duration
|
||||
*/
|
||||
virtual void SetOneShotDuration(int index, units::second_t duration) = 0;
|
||||
|
||||
/**
|
||||
* Check if a solenoid channel is valid.
|
||||
*
|
||||
* @param channel Channel to check
|
||||
* @return True if channel exists
|
||||
*/
|
||||
virtual bool CheckSolenoidChannel(int channel) const = 0;
|
||||
|
||||
/**
|
||||
* Check to see if the solenoids marked in the bitmask can be reserved, and if
|
||||
* so, reserve them.
|
||||
*
|
||||
* @param mask The bitmask of solenoids to reserve. The LSB represents
|
||||
* solenoid 0.
|
||||
* @return 0 if successful; mask of solenoids that couldn't be allocated
|
||||
* otherwise
|
||||
*/
|
||||
virtual int CheckAndReserveSolenoids(int mask) = 0;
|
||||
|
||||
/**
|
||||
* Unreserve the solenoids marked in the bitmask.
|
||||
*
|
||||
* @param mask The bitmask of solenoids to unreserve. The LSB represents
|
||||
* solenoid 0.
|
||||
*/
|
||||
virtual void UnreserveSolenoids(int mask) = 0;
|
||||
|
||||
/**
|
||||
* Reserve the compressor.
|
||||
*
|
||||
* @return true if successful; false if compressor already reserved
|
||||
*/
|
||||
virtual bool ReserveCompressor() = 0;
|
||||
|
||||
/**
|
||||
* Unreserve the compressor.
|
||||
*/
|
||||
virtual void UnreserveCompressor() = 0;
|
||||
|
||||
/**
|
||||
* If supported by the device, returns the raw voltage of the specified analog
|
||||
* input channel.
|
||||
*
|
||||
* This function is only supported by the REV PH. On CTRE PCM, this will
|
||||
* return 0.
|
||||
*
|
||||
* @param channel The analog input channel to read voltage from.
|
||||
* @return The voltage of the specified analog input channel.
|
||||
*/
|
||||
virtual units::volt_t GetAnalogVoltage(int channel) const = 0;
|
||||
|
||||
/**
|
||||
* If supported by the device, returns the pressure read by an analog
|
||||
* pressure sensor on the specified analog input channel.
|
||||
*
|
||||
* This function is only supported by the REV PH. On CTRE PCM, this will
|
||||
* return 0.
|
||||
*
|
||||
* @param channel The analog input channel to read pressure from.
|
||||
* @return The pressure read by an analog pressure sensor on the
|
||||
* specified analog input channel.
|
||||
*/
|
||||
virtual units::pounds_per_square_inch_t GetPressure(int channel) const = 0;
|
||||
|
||||
/**
|
||||
* Create a solenoid object for the specified channel.
|
||||
*
|
||||
* @param channel solenoid channel
|
||||
* @return Solenoid object
|
||||
*/
|
||||
virtual Solenoid MakeSolenoid(int channel) = 0;
|
||||
|
||||
/**
|
||||
* Create a double solenoid object for the specified channels.
|
||||
*
|
||||
* @param forwardChannel solenoid channel for forward
|
||||
* @param reverseChannel solenoid channel for reverse
|
||||
* @return DoubleSolenoid object
|
||||
*/
|
||||
virtual DoubleSolenoid MakeDoubleSolenoid(int forwardChannel,
|
||||
int reverseChannel) = 0;
|
||||
|
||||
/**
|
||||
* Create a compressor object.
|
||||
*
|
||||
* @return Compressor object
|
||||
*/
|
||||
virtual Compressor MakeCompressor() = 0;
|
||||
|
||||
/**
|
||||
* Report usage.
|
||||
*
|
||||
* @param device device and channel as appropriate
|
||||
* @param data arbitrary usage data
|
||||
*/
|
||||
virtual void ReportUsage(std::string_view device, std::string_view data) = 0;
|
||||
|
||||
/**
|
||||
* For internal use to get a module for a specific type.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param module module number
|
||||
* @param moduleType module type
|
||||
* @return module
|
||||
*/
|
||||
static std::shared_ptr<PneumaticsBase> GetForType(
|
||||
int busId, int module, PneumaticsModuleType moduleType);
|
||||
|
||||
/**
|
||||
* For internal use to get the default for a specific type.
|
||||
*
|
||||
* @param moduleType module type
|
||||
* @return module default
|
||||
*/
|
||||
static int GetDefaultForType(PneumaticsModuleType moduleType);
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,217 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/Types.h>
|
||||
#include <wpi/DenseMap.h>
|
||||
#include <wpi/mutex.h>
|
||||
|
||||
#include "PneumaticsBase.h"
|
||||
|
||||
namespace frc {
|
||||
/** Module class for controlling a Cross The Road Electronics Pneumatics Control
|
||||
* Module. */
|
||||
class PneumaticsControlModule : public PneumaticsBase {
|
||||
public:
|
||||
/**
|
||||
* Constructs a PneumaticsControlModule with the default ID (0).
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
*/
|
||||
explicit PneumaticsControlModule(int busId);
|
||||
|
||||
/**
|
||||
* Constructs a PneumaticsControlModule.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param module module number to construct
|
||||
*/
|
||||
PneumaticsControlModule(int busId, int module);
|
||||
|
||||
~PneumaticsControlModule() override = default;
|
||||
|
||||
bool GetCompressor() const override;
|
||||
|
||||
/**
|
||||
* Disables the compressor. The compressor will not turn on until
|
||||
* EnableCompressorDigital() is called.
|
||||
*/
|
||||
void DisableCompressor() override;
|
||||
|
||||
void EnableCompressorDigital() override;
|
||||
|
||||
/**
|
||||
* Enables the compressor in digital mode. Analog mode is unsupported by the
|
||||
* CTRE PCM.
|
||||
*
|
||||
* @param minPressure Unsupported.
|
||||
* @param maxPressure Unsupported.
|
||||
* @see EnableCompressorDigital()
|
||||
*/
|
||||
void EnableCompressorAnalog(
|
||||
units::pounds_per_square_inch_t minPressure,
|
||||
units::pounds_per_square_inch_t maxPressure) override;
|
||||
|
||||
/**
|
||||
* Enables the compressor in digital mode. Hybrid mode is unsupported by the
|
||||
* CTRE PCM.
|
||||
*
|
||||
* @param minPressure Unsupported.
|
||||
* @param maxPressure Unsupported.
|
||||
* @see EnableCompressorDigital()
|
||||
*/
|
||||
void EnableCompressorHybrid(
|
||||
units::pounds_per_square_inch_t minPressure,
|
||||
units::pounds_per_square_inch_t maxPressure) override;
|
||||
|
||||
CompressorConfigType GetCompressorConfigType() const override;
|
||||
|
||||
bool GetPressureSwitch() const override;
|
||||
|
||||
units::ampere_t GetCompressorCurrent() const override;
|
||||
|
||||
/**
|
||||
* Return whether the compressor current is currently too high.
|
||||
*
|
||||
* @return True if the compressor current is too high, otherwise false.
|
||||
* @see GetCompressorCurrentTooHighStickyFault()
|
||||
*/
|
||||
bool GetCompressorCurrentTooHighFault() const;
|
||||
|
||||
/**
|
||||
* Returns whether the compressor current has been too high since sticky
|
||||
* faults were last cleared. This fault is persistent and can be cleared by
|
||||
* ClearAllStickyFaults()
|
||||
*
|
||||
* @return True if the compressor current has been too high since sticky
|
||||
* faults were last cleared.
|
||||
* @see GetCompressorCurrentTooHighFault()
|
||||
*/
|
||||
bool GetCompressorCurrentTooHighStickyFault() const;
|
||||
|
||||
/**
|
||||
* Returns whether the compressor is currently shorted.
|
||||
*
|
||||
* @return True if the compressor is currently shorted, otherwise false.
|
||||
* @see GetCompressorShortedStickyFault()
|
||||
*/
|
||||
bool GetCompressorShortedFault() const;
|
||||
|
||||
/**
|
||||
* Returns whether the compressor has been shorted since sticky faults were
|
||||
* last cleared. This fault is persistent and can be cleared by
|
||||
* ClearAllStickyFaults()
|
||||
*
|
||||
* @return True if the compressor has been shorted since sticky faults were
|
||||
* last cleared, otherwise false.
|
||||
* @see GetCompressorShortedFault()
|
||||
*/
|
||||
bool GetCompressorShortedStickyFault() const;
|
||||
|
||||
/**
|
||||
* Returns whether the compressor is currently disconnected.
|
||||
*
|
||||
* @return True if compressor is currently disconnected, otherwise false.
|
||||
* @see GetCompressorNotConnectedStickyFault()
|
||||
*/
|
||||
bool GetCompressorNotConnectedFault() const;
|
||||
|
||||
/**
|
||||
* Returns whether the compressor has been disconnected since sticky faults
|
||||
* were last cleared. This fault is persistent and can be cleared by
|
||||
* ClearAllStickyFaults()
|
||||
*
|
||||
* @return True if the compressor has been disconnected since sticky faults
|
||||
* were last cleared, otherwise false.
|
||||
* @see GetCompressorNotConnectedFault()
|
||||
*/
|
||||
bool GetCompressorNotConnectedStickyFault() const;
|
||||
|
||||
/**
|
||||
* Returns whether the solenoid is currently reporting a voltage fault.
|
||||
*
|
||||
* @return True if solenoid is reporting a fault, otherwise false.
|
||||
* @see GetSolenoidVoltageStickyFault()
|
||||
*/
|
||||
bool GetSolenoidVoltageFault() const;
|
||||
|
||||
/**
|
||||
* Returns whether the solenoid has reported a voltage fault since sticky
|
||||
* faults were last cleared. This fault is persistent and can be cleared by
|
||||
* ClearAllStickyFaults()
|
||||
*
|
||||
* @return True if solenoid is reporting a fault, otherwise false.
|
||||
* @see GetSolenoidVoltageFault()
|
||||
*/
|
||||
bool GetSolenoidVoltageStickyFault() const;
|
||||
|
||||
/** Clears all sticky faults on this device. */
|
||||
void ClearAllStickyFaults();
|
||||
|
||||
void SetSolenoids(int mask, int values) override;
|
||||
|
||||
int GetSolenoids() const override;
|
||||
|
||||
int GetModuleNumber() const override;
|
||||
|
||||
int GetSolenoidDisabledList() const override;
|
||||
|
||||
void FireOneShot(int index) override;
|
||||
|
||||
void SetOneShotDuration(int index, units::second_t duration) override;
|
||||
|
||||
bool CheckSolenoidChannel(int channel) const override;
|
||||
|
||||
int CheckAndReserveSolenoids(int mask) override;
|
||||
|
||||
void UnreserveSolenoids(int mask) override;
|
||||
|
||||
bool ReserveCompressor() override;
|
||||
|
||||
void UnreserveCompressor() override;
|
||||
|
||||
/**
|
||||
* Unsupported by the CTRE PCM.
|
||||
*
|
||||
* @param channel Unsupported.
|
||||
* @return 0
|
||||
*/
|
||||
units::volt_t GetAnalogVoltage(int channel) const override;
|
||||
|
||||
/**
|
||||
* Unsupported by the CTRE PCM.
|
||||
*
|
||||
* @param channel Unsupported.
|
||||
* @return 0
|
||||
*/
|
||||
units::pounds_per_square_inch_t GetPressure(int channel) const override;
|
||||
|
||||
Solenoid MakeSolenoid(int channel) override;
|
||||
DoubleSolenoid MakeDoubleSolenoid(int forwardChannel,
|
||||
int reverseChannel) override;
|
||||
Compressor MakeCompressor() override;
|
||||
|
||||
void ReportUsage(std::string_view device, std::string_view data) override;
|
||||
|
||||
private:
|
||||
class DataStore;
|
||||
friend class DataStore;
|
||||
friend class PneumaticsBase;
|
||||
PneumaticsControlModule(int busId, HAL_CTREPCMHandle handle, int module);
|
||||
|
||||
static std::shared_ptr<PneumaticsBase> GetForModule(int busId, int module);
|
||||
|
||||
std::shared_ptr<DataStore> m_dataStore;
|
||||
HAL_CTREPCMHandle m_handle;
|
||||
int m_module;
|
||||
|
||||
static wpi::mutex m_handleLock;
|
||||
static std::unique_ptr<wpi::DenseMap<int, std::weak_ptr<DataStore>>[]>
|
||||
m_handleMaps;
|
||||
static std::weak_ptr<DataStore>& GetDataStore(int busId, int module);
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,17 @@
|
||||
// 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
|
||||
|
||||
namespace frc {
|
||||
/**
|
||||
* Pneumatics module type.
|
||||
*/
|
||||
enum class PneumaticsModuleType {
|
||||
/// CTRE PCM.
|
||||
CTREPCM,
|
||||
/// REV PH.
|
||||
REVPH
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,122 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/Types.h>
|
||||
#include <units/time.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/PneumaticsBase.h"
|
||||
#include "frc/PneumaticsModuleType.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Solenoid class for running high voltage Digital Output on a pneumatics
|
||||
* module.
|
||||
*
|
||||
* The Solenoid class is typically used for pneumatics solenoids, but could be
|
||||
* used for any device within the current spec of the module.
|
||||
*/
|
||||
class Solenoid : public wpi::Sendable, public wpi::SendableHelper<Solenoid> {
|
||||
public:
|
||||
/**
|
||||
* Constructs a solenoid for a specified module and type.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param module The module ID to use.
|
||||
* @param moduleType The module type to use.
|
||||
* @param channel The channel the solenoid is on.
|
||||
*/
|
||||
Solenoid(int busId, int module, PneumaticsModuleType moduleType, int channel);
|
||||
|
||||
/**
|
||||
* Constructs a solenoid for a default module and specified type.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param moduleType The module type to use.
|
||||
* @param channel The channel the solenoid is on.
|
||||
*/
|
||||
Solenoid(int busId, PneumaticsModuleType moduleType, int channel);
|
||||
|
||||
~Solenoid() override;
|
||||
|
||||
Solenoid(Solenoid&&) = default;
|
||||
Solenoid& operator=(Solenoid&&) = default;
|
||||
|
||||
/**
|
||||
* Set the value of a solenoid.
|
||||
*
|
||||
* @param on Turn the solenoid output off or on.
|
||||
*/
|
||||
void Set(bool on);
|
||||
|
||||
/**
|
||||
* Read the current value of the solenoid.
|
||||
*
|
||||
* @return The current value of the solenoid.
|
||||
*/
|
||||
bool Get() const;
|
||||
|
||||
/**
|
||||
* Toggle the value of the solenoid.
|
||||
*
|
||||
* If the solenoid is set to on, it'll be turned off. If the solenoid is set
|
||||
* to off, it'll be turned on.
|
||||
*/
|
||||
void Toggle();
|
||||
|
||||
/**
|
||||
* Get the channel this solenoid is connected to.
|
||||
*/
|
||||
int GetChannel() const;
|
||||
|
||||
/**
|
||||
* Check if solenoid is Disabled.
|
||||
*
|
||||
* If a solenoid is shorted, it is added to the DisabledList and
|
||||
* disabled until power cycle, or until faults are cleared.
|
||||
*
|
||||
* @see ClearAllPCMStickyFaults()
|
||||
*
|
||||
* @return If solenoid is disabled due to short.
|
||||
*/
|
||||
bool IsDisabled() const;
|
||||
|
||||
/**
|
||||
* Set the pulse duration in the pneumatics module. This is used in
|
||||
* conjunction with the startPulse method to allow the pneumatics module to
|
||||
* control the timing of a pulse.
|
||||
*
|
||||
* On the PCM, the timing can be controlled in 0.01 second increments, with a
|
||||
* maximum of 2.55 seconds. On the PH, the timing can be controlled in 0.001
|
||||
* second increments, with a maximum of 65.534 seconds.
|
||||
*
|
||||
* @param duration The duration of the pulse.
|
||||
*
|
||||
* @see startPulse()
|
||||
*/
|
||||
void SetPulseDuration(units::second_t duration);
|
||||
|
||||
/**
|
||||
* %Trigger the pneumatics module to generate a pulse of the duration set in
|
||||
* setPulseDuration.
|
||||
*
|
||||
* @see setPulseDuration()
|
||||
*/
|
||||
void StartPulse();
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<PneumaticsBase> m_module;
|
||||
int m_mask;
|
||||
int m_channel;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,353 @@
|
||||
// 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 <vector>
|
||||
|
||||
#include <hal/PowerDistribution.h>
|
||||
#include <hal/Types.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Class for getting voltage, current, temperature, power and energy from the
|
||||
* CTRE Power Distribution Panel (PDP) or REV Power Distribution Hub (PDH).
|
||||
*/
|
||||
class PowerDistribution : public wpi::Sendable,
|
||||
public wpi::SendableHelper<PowerDistribution> {
|
||||
public:
|
||||
/// Default module number.
|
||||
static constexpr int kDefaultModule = -1;
|
||||
|
||||
/**
|
||||
* Power distribution module type.
|
||||
*/
|
||||
enum class ModuleType {
|
||||
/// CTRE (Cross The Road Electronics) CTRE Power Distribution Panel (PDP).
|
||||
kCTRE = 1,
|
||||
/// REV Power Distribution Hub (PDH).
|
||||
kRev = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a PowerDistribution object.
|
||||
*
|
||||
* Detects the connected PDP/PDH using the default CAN ID (0 for CTRE and 1
|
||||
* for REV).
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
*/
|
||||
explicit PowerDistribution(int busId);
|
||||
|
||||
/**
|
||||
* Constructs a PowerDistribution object.
|
||||
*
|
||||
* @param busId The bus ID.
|
||||
* @param module The CAN ID of the PDP/PDH
|
||||
* @param moduleType The type of module
|
||||
*/
|
||||
PowerDistribution(int busId, int module, ModuleType moduleType);
|
||||
|
||||
PowerDistribution(PowerDistribution&&) = default;
|
||||
PowerDistribution& operator=(PowerDistribution&&) = default;
|
||||
|
||||
~PowerDistribution() override = default;
|
||||
|
||||
/**
|
||||
* Gets the number of channels for this power distribution object.
|
||||
*
|
||||
* @return Number of output channels (16 for PDP, 24 for PDH).
|
||||
*/
|
||||
int GetNumChannels() const;
|
||||
|
||||
/**
|
||||
* Query the input voltage of the PDP/PDH.
|
||||
*
|
||||
* @return The input voltage in volts
|
||||
*/
|
||||
double GetVoltage() const;
|
||||
|
||||
/**
|
||||
* Query the temperature of the PDP.
|
||||
*
|
||||
* Not supported on the Rev PDH and returns 0.
|
||||
*
|
||||
*
|
||||
* @return The temperature in degrees Celsius
|
||||
*/
|
||||
double GetTemperature() const;
|
||||
|
||||
/**
|
||||
* Query the current of a single channel of the PDP/PDH.
|
||||
*
|
||||
* @param channel the channel to query (0-15 for PDP, 0-23 for PDH)
|
||||
* @return The current of the channel in Amperes
|
||||
*/
|
||||
double GetCurrent(int channel) const;
|
||||
|
||||
/**
|
||||
* Query all currents of the PDP.
|
||||
*
|
||||
* @return The current of each channel in Amperes
|
||||
*/
|
||||
std::vector<double> GetAllCurrents() const;
|
||||
|
||||
/**
|
||||
* Query the total current of all monitored PDP/PDH channels.
|
||||
*
|
||||
* @return The total current drawn from all channels in Amperes
|
||||
*/
|
||||
double GetTotalCurrent() const;
|
||||
|
||||
/**
|
||||
* Query the total power drawn from all monitored PDP channels.
|
||||
*
|
||||
* Not supported on the Rev PDH and returns 0.
|
||||
*
|
||||
* @return The total power drawn in Watts
|
||||
*/
|
||||
double GetTotalPower() const;
|
||||
|
||||
/**
|
||||
* Query the total energy drawn from the monitored PDP channels.
|
||||
*
|
||||
* Not supported on the Rev PDH and returns 0.
|
||||
*
|
||||
* @return The total energy drawn in Joules
|
||||
*/
|
||||
double GetTotalEnergy() const;
|
||||
|
||||
/**
|
||||
* Reset the total energy drawn from the PDP.
|
||||
*
|
||||
* Not supported on the Rev PDH and does nothing.
|
||||
*
|
||||
* @see PowerDistribution#GetTotalEnergy
|
||||
*/
|
||||
void ResetTotalEnergy();
|
||||
|
||||
/**
|
||||
* Remove all of the fault flags on the PDP/PDH.
|
||||
*/
|
||||
void ClearStickyFaults();
|
||||
|
||||
/**
|
||||
* Gets module number (CAN ID).
|
||||
*/
|
||||
int GetModule() const;
|
||||
|
||||
/**
|
||||
* Gets module type.
|
||||
*/
|
||||
ModuleType GetType() const;
|
||||
|
||||
/**
|
||||
* Gets whether the PDH switchable channel is turned on or off. Returns false
|
||||
* with the CTRE PDP.
|
||||
*
|
||||
* @return The output state of the PDH switchable channel
|
||||
*/
|
||||
bool GetSwitchableChannel() const;
|
||||
|
||||
/**
|
||||
* Sets the PDH switchable channel on or off. Does nothing with the CTRE PDP.
|
||||
*
|
||||
* @param enabled Whether to turn the PDH switchable channel on or off
|
||||
*/
|
||||
void SetSwitchableChannel(bool enabled);
|
||||
|
||||
/** Version and device data received from a PowerDistribution device */
|
||||
struct Version {
|
||||
/** Firmware major version number. */
|
||||
uint32_t FirmwareMajor;
|
||||
/** Firmware minor version number. */
|
||||
uint32_t FirmwareMinor;
|
||||
/** Firmware fix version number. */
|
||||
uint32_t FirmwareFix;
|
||||
/** Hardware minor version number. */
|
||||
uint32_t HardwareMinor;
|
||||
/** Hardware major version number. */
|
||||
uint32_t HardwareMajor;
|
||||
/** Unique ID. */
|
||||
uint32_t UniqueId;
|
||||
};
|
||||
|
||||
Version GetVersion() const;
|
||||
|
||||
/**
|
||||
* Faults for a PowerDistribution device. These faults are only active while
|
||||
* the condition is active.
|
||||
*/
|
||||
struct Faults {
|
||||
/** Breaker fault on channel 0. */
|
||||
uint32_t Channel0BreakerFault : 1;
|
||||
/** Breaker fault on channel 1. */
|
||||
uint32_t Channel1BreakerFault : 1;
|
||||
/** Breaker fault on channel 2. */
|
||||
uint32_t Channel2BreakerFault : 1;
|
||||
/** Breaker fault on channel 3. */
|
||||
uint32_t Channel3BreakerFault : 1;
|
||||
/** Breaker fault on channel 4. */
|
||||
uint32_t Channel4BreakerFault : 1;
|
||||
/** Breaker fault on channel 5. */
|
||||
uint32_t Channel5BreakerFault : 1;
|
||||
/** Breaker fault on channel 6. */
|
||||
uint32_t Channel6BreakerFault : 1;
|
||||
/** Breaker fault on channel 7. */
|
||||
uint32_t Channel7BreakerFault : 1;
|
||||
/** Breaker fault on channel 8. */
|
||||
uint32_t Channel8BreakerFault : 1;
|
||||
/** Breaker fault on channel 9. */
|
||||
uint32_t Channel9BreakerFault : 1;
|
||||
/** Breaker fault on channel 10. */
|
||||
uint32_t Channel10BreakerFault : 1;
|
||||
/** Breaker fault on channel 12. */
|
||||
uint32_t Channel11BreakerFault : 1;
|
||||
/** Breaker fault on channel 13. */
|
||||
uint32_t Channel12BreakerFault : 1;
|
||||
/** Breaker fault on channel 14. */
|
||||
uint32_t Channel13BreakerFault : 1;
|
||||
/** Breaker fault on channel 15. */
|
||||
uint32_t Channel14BreakerFault : 1;
|
||||
/** Breaker fault on channel 16. */
|
||||
uint32_t Channel15BreakerFault : 1;
|
||||
/** Breaker fault on channel 17. */
|
||||
uint32_t Channel16BreakerFault : 1;
|
||||
/** Breaker fault on channel 18. */
|
||||
uint32_t Channel17BreakerFault : 1;
|
||||
/** Breaker fault on channel 19. */
|
||||
uint32_t Channel18BreakerFault : 1;
|
||||
/** Breaker fault on channel 20. */
|
||||
uint32_t Channel19BreakerFault : 1;
|
||||
/** Breaker fault on channel 21. */
|
||||
uint32_t Channel20BreakerFault : 1;
|
||||
/** Breaker fault on channel 22. */
|
||||
uint32_t Channel21BreakerFault : 1;
|
||||
/** Breaker fault on channel 23. */
|
||||
uint32_t Channel22BreakerFault : 1;
|
||||
/** Breaker fault on channel 24. */
|
||||
uint32_t Channel23BreakerFault : 1;
|
||||
/** The input voltage is below the minimum voltage. */
|
||||
uint32_t Brownout : 1;
|
||||
/** A warning was raised by the device's CAN controller. */
|
||||
uint32_t CanWarning : 1;
|
||||
/** The hardware on the device has malfunctioned. */
|
||||
uint32_t HardwareFault : 1;
|
||||
|
||||
/**
|
||||
* Gets whether there is a breaker fault at a specified channel.
|
||||
* @param channel Channel to check for faults.
|
||||
* @return If there is a breaker fault.
|
||||
* @throws A ChannelIndexOutOfRange error if the given int is outside of the
|
||||
* range supported by the hardware.
|
||||
*/
|
||||
bool GetBreakerFault(int channel) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the power distribution faults.
|
||||
*
|
||||
* On a CTRE PDP, this will return an object with no faults active.
|
||||
*
|
||||
* @return The power distribution faults.
|
||||
*/
|
||||
Faults GetFaults() const;
|
||||
|
||||
/**
|
||||
* Sticky faults for a PowerDistribution device. These faults will remain
|
||||
* active until they are reset by the user.
|
||||
*/
|
||||
struct StickyFaults {
|
||||
/** Breaker fault on channel 0. */
|
||||
uint32_t Channel0BreakerFault : 1;
|
||||
/** Breaker fault on channel 1. */
|
||||
uint32_t Channel1BreakerFault : 1;
|
||||
/** Breaker fault on channel 2. */
|
||||
uint32_t Channel2BreakerFault : 1;
|
||||
/** Breaker fault on channel 3. */
|
||||
uint32_t Channel3BreakerFault : 1;
|
||||
/** Breaker fault on channel 4. */
|
||||
uint32_t Channel4BreakerFault : 1;
|
||||
/** Breaker fault on channel 5. */
|
||||
uint32_t Channel5BreakerFault : 1;
|
||||
/** Breaker fault on channel 6. */
|
||||
uint32_t Channel6BreakerFault : 1;
|
||||
/** Breaker fault on channel 7. */
|
||||
uint32_t Channel7BreakerFault : 1;
|
||||
/** Breaker fault on channel 8. */
|
||||
uint32_t Channel8BreakerFault : 1;
|
||||
/** Breaker fault on channel 9. */
|
||||
uint32_t Channel9BreakerFault : 1;
|
||||
/** Breaker fault on channel 10. */
|
||||
uint32_t Channel10BreakerFault : 1;
|
||||
/** Breaker fault on channel 12. */
|
||||
uint32_t Channel11BreakerFault : 1;
|
||||
/** Breaker fault on channel 13. */
|
||||
uint32_t Channel12BreakerFault : 1;
|
||||
/** Breaker fault on channel 14. */
|
||||
uint32_t Channel13BreakerFault : 1;
|
||||
/** Breaker fault on channel 15. */
|
||||
uint32_t Channel14BreakerFault : 1;
|
||||
/** Breaker fault on channel 16. */
|
||||
uint32_t Channel15BreakerFault : 1;
|
||||
/** Breaker fault on channel 17. */
|
||||
uint32_t Channel16BreakerFault : 1;
|
||||
/** Breaker fault on channel 18. */
|
||||
uint32_t Channel17BreakerFault : 1;
|
||||
/** Breaker fault on channel 19. */
|
||||
uint32_t Channel18BreakerFault : 1;
|
||||
/** Breaker fault on channel 20. */
|
||||
uint32_t Channel19BreakerFault : 1;
|
||||
/** Breaker fault on channel 21. */
|
||||
uint32_t Channel20BreakerFault : 1;
|
||||
/** Breaker fault on channel 22. */
|
||||
uint32_t Channel21BreakerFault : 1;
|
||||
/** Breaker fault on channel 23. */
|
||||
uint32_t Channel22BreakerFault : 1;
|
||||
/** Breaker fault on channel 24. */
|
||||
uint32_t Channel23BreakerFault : 1;
|
||||
/** The input voltage is below the minimum voltage. */
|
||||
uint32_t Brownout : 1;
|
||||
/** A warning was raised by the device's CAN controller. */
|
||||
uint32_t CanWarning : 1;
|
||||
/** The device's CAN controller experienced a "Bus Off" event. */
|
||||
uint32_t CanBusOff : 1;
|
||||
/** The hardware on the device has malfunctioned. */
|
||||
uint32_t HardwareFault : 1;
|
||||
/** The firmware on the device has malfunctioned. */
|
||||
uint32_t FirmwareFault : 1;
|
||||
/** The device has rebooted. */
|
||||
uint32_t HasReset : 1;
|
||||
|
||||
/**
|
||||
* Gets whether there is a sticky breaker fault at the specified channel.
|
||||
* @param channel Index to check for sticky faults.
|
||||
* @return True if there is a sticky breaker fault at the channel, otherwise
|
||||
* false.
|
||||
* @throws A ChannelIndexOutOfRange error if the provided channel is outside
|
||||
* of the range supported by the hardware.
|
||||
*/
|
||||
bool GetBreakerFault(int channel) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the power distribution sticky faults.
|
||||
*
|
||||
* On a CTRE PDP, this will return an object with no faults active.
|
||||
*
|
||||
* @return The power distribution sticky faults.
|
||||
*/
|
||||
StickyFaults GetStickyFaults() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
hal::Handle<HAL_PowerDistributionHandle, HAL_CleanPowerDistribution> m_handle;
|
||||
int m_module;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
100
wpilibc/src/main/native/include/wpi/hardware/range/SharpIR.hpp
Normal file
100
wpilibc/src/main/native/include/wpi/hardware/range/SharpIR.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
// 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 <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/AnalogInput.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class SharpIR : public wpi::Sendable, public wpi::SendableHelper<SharpIR> {
|
||||
public:
|
||||
/**
|
||||
* Sharp GP2Y0A02YK0F is an analog IR sensor capable of measuring
|
||||
* distances from 20cm to 150cm.
|
||||
*
|
||||
* @param channel Analog input channel the sensor is connected to
|
||||
*
|
||||
* @return sensor object
|
||||
*/
|
||||
static SharpIR GP2Y0A02YK0F(int channel);
|
||||
|
||||
/**
|
||||
* Sharp GP2Y0A21YK0F is an analog IR sensor capable of measuring
|
||||
* distances from 10cm to 80cm.
|
||||
*
|
||||
* @param channel Analog input channel the sensor is connected to
|
||||
*
|
||||
* @return sensor object
|
||||
*/
|
||||
static SharpIR GP2Y0A21YK0F(int channel);
|
||||
|
||||
/**
|
||||
* Sharp GP2Y0A41SK0F is an analog IR sensor capable of measuring
|
||||
* distances from 4cm to 30cm.
|
||||
*
|
||||
* @param channel Analog input channel the sensor is connected to
|
||||
*
|
||||
* @return sensor object
|
||||
*/
|
||||
static SharpIR GP2Y0A41SK0F(int channel);
|
||||
|
||||
/**
|
||||
* Sharp GP2Y0A51SK0F is an analog IR sensor capable of measuring
|
||||
* distances from 2cm to 15cm.
|
||||
*
|
||||
* @param channel Analog input channel the sensor is connected to
|
||||
*
|
||||
* @return sensor object
|
||||
*/
|
||||
static SharpIR GP2Y0A51SK0F(int channel);
|
||||
|
||||
/**
|
||||
* Manually construct a SharpIR object. The distance is computed using this
|
||||
* formula: A*v ^ B. Prefer to use one of the static factories to create this
|
||||
* device instead.
|
||||
*
|
||||
* @param channel Analog input channel the sensor is connected to
|
||||
* @param a Constant A
|
||||
* @param b Constant B
|
||||
* @param min Minimum distance to report
|
||||
* @param max Maximum distance to report
|
||||
*/
|
||||
SharpIR(int channel, double a, double b, units::meter_t min,
|
||||
units::meter_t max);
|
||||
|
||||
/**
|
||||
* Get the analog input channel number.
|
||||
*
|
||||
* @return analog input channel
|
||||
*/
|
||||
int GetChannel() const;
|
||||
|
||||
/**
|
||||
* Get the range from the distance sensor.
|
||||
*
|
||||
* @return range of the target returned by the sensor
|
||||
*/
|
||||
units::meter_t GetRange() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
AnalogInput m_sensor;
|
||||
|
||||
hal::SimDevice m_simDevice;
|
||||
hal::SimDouble m_simRange;
|
||||
|
||||
double m_A;
|
||||
double m_B;
|
||||
units::meter_t m_min;
|
||||
units::meter_t m_max;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,150 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/SimDevice.h>
|
||||
#include <hal/Types.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
namespace frc {
|
||||
class AnalogInput;
|
||||
|
||||
/**
|
||||
* Class for supporting continuous analog encoders, such as the US Digital MA3.
|
||||
*/
|
||||
class AnalogEncoder : public wpi::Sendable,
|
||||
public wpi::SendableHelper<AnalogEncoder> {
|
||||
public:
|
||||
/**
|
||||
* Construct a new AnalogEncoder attached to a specific AnalogIn channel.
|
||||
*
|
||||
* <p>This has a fullRange of 1 and an expectedZero of 0.
|
||||
*
|
||||
* @param channel the analog input channel to attach to
|
||||
*/
|
||||
explicit AnalogEncoder(int channel);
|
||||
|
||||
/**
|
||||
* Construct a new AnalogEncoder attached to a specific AnalogInput.
|
||||
*
|
||||
* <p>This has a fullRange of 1 and an expectedZero of 0.
|
||||
*
|
||||
* @param analogInput the analog input to attach to
|
||||
*/
|
||||
explicit AnalogEncoder(AnalogInput& analogInput);
|
||||
|
||||
/**
|
||||
* Construct a new AnalogEncoder attached to a specific AnalogInput.
|
||||
*
|
||||
* <p>This has a fullRange of 1 and an expectedZero of 0.
|
||||
*
|
||||
* @param analogInput the analog input to attach to
|
||||
*/
|
||||
explicit AnalogEncoder(AnalogInput* analogInput);
|
||||
|
||||
/**
|
||||
* Construct a new AnalogEncoder attached to a specific AnalogInput.
|
||||
*
|
||||
* <p>This has a fullRange of 1 and an expectedZero of 0.
|
||||
*
|
||||
* @param analogInput the analog input to attach to
|
||||
*/
|
||||
explicit AnalogEncoder(std::shared_ptr<AnalogInput> analogInput);
|
||||
|
||||
/**
|
||||
* Construct a new AnalogEncoder attached to a specific AnalogIn channel.
|
||||
*
|
||||
* @param channel the analog input channel to attach to
|
||||
* @param fullRange the value to report at maximum travel
|
||||
* @param expectedZero the reading where you would expect a 0 from get()
|
||||
*/
|
||||
AnalogEncoder(int channel, double fullRange, double expectedZero);
|
||||
|
||||
/**
|
||||
* Construct a new AnalogEncoder attached to a specific AnalogInput.
|
||||
*
|
||||
* @param analogInput the analog input to attach to
|
||||
* @param fullRange the value to report at maximum travel
|
||||
* @param expectedZero the reading where you would expect a 0 from get()
|
||||
*/
|
||||
AnalogEncoder(AnalogInput& analogInput, double fullRange,
|
||||
double expectedZero);
|
||||
|
||||
/**
|
||||
* Construct a new AnalogEncoder attached to a specific AnalogInput.
|
||||
*
|
||||
* @param analogInput the analog input to attach to
|
||||
* @param fullRange the value to report at maximum travel
|
||||
* @param expectedZero the reading where you would expect a 0 from get()
|
||||
*/
|
||||
AnalogEncoder(AnalogInput* analogInput, double fullRange,
|
||||
double expectedZero);
|
||||
|
||||
/**
|
||||
* Construct a new AnalogEncoder attached to a specific AnalogInput.
|
||||
*
|
||||
* @param analogInput the analog input to attach to
|
||||
* @param fullRange the value to report at maximum travel
|
||||
* @param expectedZero the reading where you would expect a 0 from get()
|
||||
*/
|
||||
AnalogEncoder(std::shared_ptr<AnalogInput> analogInput, double fullRange,
|
||||
double expectedZero);
|
||||
|
||||
~AnalogEncoder() override;
|
||||
|
||||
AnalogEncoder(AnalogEncoder&&) = default;
|
||||
AnalogEncoder& operator=(AnalogEncoder&&) = default;
|
||||
|
||||
/**
|
||||
* Get the encoder value.
|
||||
*
|
||||
* @return the encoder value scaled by the full range input
|
||||
*/
|
||||
double Get() const;
|
||||
|
||||
/**
|
||||
* Set the encoder voltage percentage range. Analog sensors are not always
|
||||
* fully stable at the end of their travel ranges. Shrinking this range down
|
||||
* can help mitigate issues with that.
|
||||
*
|
||||
* @param min minimum voltage percentage (0-1 range)
|
||||
* @param max maximum voltage percentage (0-1 range)
|
||||
*/
|
||||
void SetVoltagePercentageRange(double min, double max);
|
||||
|
||||
/**
|
||||
* Set if this encoder is inverted.
|
||||
*
|
||||
* @param inverted true to invert the encoder, false otherwise
|
||||
*/
|
||||
void SetInverted(bool inverted);
|
||||
|
||||
/**
|
||||
* Get the channel number.
|
||||
*
|
||||
* @return The channel number.
|
||||
*/
|
||||
int GetChannel() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
void Init(double fullRange, double expectedZero);
|
||||
double MapSensorRange(double pos) const;
|
||||
|
||||
std::shared_ptr<AnalogInput> m_analogInput;
|
||||
double m_fullRange;
|
||||
double m_expectedZero;
|
||||
double m_sensorMin{0.0};
|
||||
double m_sensorMax{1.0};
|
||||
bool m_isInverted{false};
|
||||
|
||||
hal::SimDevice m_simDevice;
|
||||
hal::SimDouble m_simPosition;
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,112 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/AnalogInput.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* Class for reading analog potentiometers. Analog potentiometers read in an
|
||||
* analog voltage that corresponds to a position. The position is in whichever
|
||||
* units you choose, by way of the scaling and offset constants passed to the
|
||||
* constructor.
|
||||
*/
|
||||
class AnalogPotentiometer : public wpi::Sendable,
|
||||
public wpi::SendableHelper<AnalogPotentiometer> {
|
||||
public:
|
||||
/**
|
||||
* Construct an Analog Potentiometer object from a channel number.
|
||||
*
|
||||
* Use the fullRange and offset values so that the output produces meaningful
|
||||
* values. I.E: you have a 270 degree potentiometer and you want the output to
|
||||
* be degrees with the halfway point as 0 degrees. The fullRange value is
|
||||
* 270.0 degrees and the offset is -135.0 since the halfway point after
|
||||
* scaling is 135 degrees.
|
||||
*
|
||||
* This will calculate the result from the fullRange times the fraction of the
|
||||
* supply voltage, plus the offset.
|
||||
*
|
||||
* @param channel The Analog Input channel number on the roboRIO the
|
||||
* potentiometer is plugged into. 0-3 are on-board and 4-7
|
||||
* are on the MXP port.
|
||||
* @param fullRange The value (in desired units) representing the full
|
||||
* 0-3.3V range of the input.
|
||||
* @param offset The value (in desired units) representing the
|
||||
* angular output at 0V.
|
||||
*/
|
||||
explicit AnalogPotentiometer(int channel, double fullRange = 1.0,
|
||||
double offset = 0.0);
|
||||
|
||||
/**
|
||||
* Construct an Analog Potentiometer object from an existing Analog Input
|
||||
* pointer.
|
||||
*
|
||||
* Use the fullRange and offset values so that the output produces meaningful
|
||||
* values. I.E: you have a 270 degree potentiometer and you want the output to
|
||||
* be degrees with the halfway point as 0 degrees. The fullRange value is
|
||||
* 270.0 degrees and the offset is -135.0 since the halfway point after
|
||||
* scaling is 135 degrees.
|
||||
*
|
||||
* This will calculate the result from the fullRange times the fraction of the
|
||||
* supply voltage, plus the offset.
|
||||
*
|
||||
* @param input The existing Analog Input pointer
|
||||
* @param fullRange The value (in desired units) representing the full
|
||||
* 0-3.3V range of the input.
|
||||
* @param offset The value (in desired units) representing the
|
||||
* angular output at 0V.
|
||||
*/
|
||||
explicit AnalogPotentiometer(AnalogInput* input, double fullRange = 1.0,
|
||||
double offset = 0.0);
|
||||
|
||||
/**
|
||||
* Construct an Analog Potentiometer object from an existing Analog Input
|
||||
* pointer.
|
||||
*
|
||||
* Use the fullRange and offset values so that the output produces meaningful
|
||||
* values. I.E: you have a 270 degree potentiometer and you want the output to
|
||||
* be degrees with the halfway point as 0 degrees. The fullRange value is
|
||||
* 270.0 degrees and the offset is -135.0 since the halfway point after
|
||||
* scaling is 135 degrees.
|
||||
*
|
||||
* This will calculate the result from the fullRange times the fraction of the
|
||||
* supply voltage, plus the offset.
|
||||
*
|
||||
* @param input The existing Analog Input pointer
|
||||
* @param fullRange The value (in desired units) representing the full
|
||||
* 0-3.3V range of the input.
|
||||
* @param offset The value (in desired units) representing the
|
||||
* angular output at 0V.
|
||||
*/
|
||||
explicit AnalogPotentiometer(std::shared_ptr<AnalogInput> input,
|
||||
double fullRange = 1.0, double offset = 0.0);
|
||||
|
||||
~AnalogPotentiometer() override = default;
|
||||
|
||||
AnalogPotentiometer(AnalogPotentiometer&&) = default;
|
||||
AnalogPotentiometer& operator=(AnalogPotentiometer&&) = default;
|
||||
|
||||
/**
|
||||
* Get the current reading of the potentiometer.
|
||||
*
|
||||
* @return The current position of the potentiometer (in the units used for
|
||||
* fullRange and offset).
|
||||
*/
|
||||
double Get() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<AnalogInput> m_analog_input;
|
||||
double m_fullRange, m_offset;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,79 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/DutyCycle.h>
|
||||
#include <hal/Types.h>
|
||||
#include <units/frequency.h>
|
||||
#include <units/time.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
namespace frc {
|
||||
/**
|
||||
* Class to read a duty cycle PWM input.
|
||||
*
|
||||
* <p>PWM input signals are specified with a frequency and a ratio of high to
|
||||
* low in that frequency. These can be attached to any SmartIO.
|
||||
*
|
||||
*/
|
||||
class DutyCycle : public wpi::Sendable, public wpi::SendableHelper<DutyCycle> {
|
||||
public:
|
||||
/**
|
||||
* Constructs a DutyCycle input from a smartio channel.
|
||||
*
|
||||
* @param source The channel to use.
|
||||
*/
|
||||
explicit DutyCycle(int source);
|
||||
|
||||
DutyCycle(DutyCycle&&) = default;
|
||||
DutyCycle& operator=(DutyCycle&&) = default;
|
||||
|
||||
/**
|
||||
* Close the DutyCycle and free all resources.
|
||||
*/
|
||||
~DutyCycle() override = default;
|
||||
|
||||
/**
|
||||
* Get the frequency of the duty cycle signal.
|
||||
*
|
||||
* @return frequency
|
||||
*/
|
||||
units::hertz_t GetFrequency() const;
|
||||
|
||||
/**
|
||||
* Get the output ratio of the duty cycle signal.
|
||||
*
|
||||
* <p> 0 means always low, 1 means always high.
|
||||
*
|
||||
* @return output ratio between 0 and 1
|
||||
*/
|
||||
double GetOutput() const;
|
||||
|
||||
/**
|
||||
* Get the raw high time of the duty cycle signal.
|
||||
*
|
||||
* @return high time of last pulse
|
||||
*/
|
||||
units::second_t GetHighTime() const;
|
||||
|
||||
/**
|
||||
* Get the channel of the source.
|
||||
*
|
||||
* @return the source channel
|
||||
*/
|
||||
int GetSourceChannel() const;
|
||||
|
||||
protected:
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
void InitDutyCycle();
|
||||
int m_channel;
|
||||
hal::Handle<HAL_DutyCycleHandle, HAL_FreeDutyCycle> m_handle;
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,199 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/SimDevice.h>
|
||||
#include <hal/Types.h>
|
||||
#include <units/frequency.h>
|
||||
#include <units/time.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
namespace frc {
|
||||
class DutyCycle;
|
||||
|
||||
/**
|
||||
* Class for supporting duty cycle/PWM encoders, such as the US Digital MA3 with
|
||||
* PWM Output, the CTRE Mag Encoder, the Rev Hex Encoder, and the AM Mag
|
||||
* Encoder.
|
||||
*/
|
||||
class DutyCycleEncoder : public wpi::Sendable,
|
||||
public wpi::SendableHelper<DutyCycleEncoder> {
|
||||
public:
|
||||
/**
|
||||
* Construct a new DutyCycleEncoder on a specific channel.
|
||||
*
|
||||
* <p>This has a fullRange of 1 and an expectedZero of 0.
|
||||
*
|
||||
* @param channel the channel to attach to
|
||||
*/
|
||||
explicit DutyCycleEncoder(int channel);
|
||||
|
||||
/**
|
||||
* Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
|
||||
*
|
||||
* <p>This has a fullRange of 1 and an expectedZero of 0.
|
||||
*
|
||||
* @param dutyCycle the duty cycle to attach to
|
||||
*/
|
||||
explicit DutyCycleEncoder(DutyCycle& dutyCycle);
|
||||
|
||||
/**
|
||||
* Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
|
||||
*
|
||||
* <p>This has a fullRange of 1 and an expectedZero of 0.
|
||||
*
|
||||
* @param dutyCycle the duty cycle to attach to
|
||||
*/
|
||||
explicit DutyCycleEncoder(DutyCycle* dutyCycle);
|
||||
|
||||
/**
|
||||
* Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
|
||||
*
|
||||
* <p>This has a fullRange of 1 and an expectedZero of 0.
|
||||
*
|
||||
* @param dutyCycle the duty cycle to attach to
|
||||
*/
|
||||
explicit DutyCycleEncoder(std::shared_ptr<DutyCycle> dutyCycle);
|
||||
|
||||
/**
|
||||
* Construct a new DutyCycleEncoder on a specific channel.
|
||||
*
|
||||
* @param channel the channel to attach to
|
||||
* @param fullRange the value to report at maximum travel
|
||||
* @param expectedZero the reading where you would expect a 0 from get()
|
||||
*/
|
||||
DutyCycleEncoder(int channel, double fullRange, double expectedZero);
|
||||
|
||||
/**
|
||||
* Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
|
||||
*
|
||||
* @param dutyCycle the duty cycle to attach to
|
||||
* @param fullRange the value to report at maximum travel
|
||||
* @param expectedZero the reading where you would expect a 0 from get()
|
||||
*/
|
||||
DutyCycleEncoder(DutyCycle& dutyCycle, double fullRange, double expectedZero);
|
||||
|
||||
/**
|
||||
* Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
|
||||
*
|
||||
* @param dutyCycle the duty cycle to attach to
|
||||
* @param fullRange the value to report at maximum travel
|
||||
* @param expectedZero the reading where you would expect a 0 from get()
|
||||
*/
|
||||
DutyCycleEncoder(DutyCycle* dutyCycle, double fullRange, double expectedZero);
|
||||
|
||||
/**
|
||||
* Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
|
||||
*
|
||||
* @param dutyCycle the duty cycle to attach to
|
||||
* @param fullRange the value to report at maximum travel
|
||||
* @param expectedZero the reading where you would expect a 0 from get()
|
||||
*/
|
||||
DutyCycleEncoder(std::shared_ptr<DutyCycle> dutyCycle, double fullRange,
|
||||
double expectedZero);
|
||||
|
||||
~DutyCycleEncoder() override = default;
|
||||
|
||||
DutyCycleEncoder(DutyCycleEncoder&&) = default;
|
||||
DutyCycleEncoder& operator=(DutyCycleEncoder&&) = default;
|
||||
|
||||
/**
|
||||
* Get the frequency of the duty cycle signal from the encoder.
|
||||
*
|
||||
* @return duty cycle frequency
|
||||
*/
|
||||
units::hertz_t GetFrequency() const;
|
||||
|
||||
/**
|
||||
* Get if the sensor is connected
|
||||
*
|
||||
* This uses the duty cycle frequency to determine if the sensor is connected.
|
||||
* By default, a value of 100 Hz is used as the threshold, and this value can
|
||||
* be changed with SetConnectedFrequencyThreshold.
|
||||
*
|
||||
* @return true if the sensor is connected
|
||||
*/
|
||||
bool IsConnected() const;
|
||||
|
||||
/**
|
||||
* Change the frequency threshold for detecting connection used by
|
||||
* IsConnected.
|
||||
*
|
||||
* @param frequency the minimum frequency.
|
||||
*/
|
||||
void SetConnectedFrequencyThreshold(units::hertz_t frequency);
|
||||
|
||||
/**
|
||||
* Get the encoder value.
|
||||
*
|
||||
* @return the encoder value scaled by the full range input
|
||||
*/
|
||||
double Get() const;
|
||||
|
||||
/**
|
||||
* Set the encoder duty cycle range. As the encoder needs to maintain a duty
|
||||
* cycle, the duty cycle cannot go all the way to 0% or all the way to 100%.
|
||||
* For example, an encoder with a 4096 us period might have a minimum duty
|
||||
* cycle of 1 us / 4096 us and a maximum duty cycle of 4095 / 4096 us. Setting
|
||||
* the range will result in an encoder duty cycle less than or equal to the
|
||||
* minimum being output as 0 rotation, the duty cycle greater than or equal to
|
||||
* the maximum being output as 1 rotation, and values in between linearly
|
||||
* scaled from 0 to 1.
|
||||
*
|
||||
* @param min minimum duty cycle (0-1 range)
|
||||
* @param max maximum duty cycle (0-1 range)
|
||||
*/
|
||||
void SetDutyCycleRange(double min, double max);
|
||||
|
||||
/**
|
||||
* Sets the assumed frequency of the connected device.
|
||||
*
|
||||
* <p>By default, the DutyCycle engine has to compute the frequency of the
|
||||
* input signal. This can result in both delayed readings and jumpy readings.
|
||||
* To solve this, you can pass the expected frequency of the sensor to this
|
||||
* function. This will use that frequency to compute the DutyCycle percentage,
|
||||
* rather than the computed frequency.
|
||||
*
|
||||
* @param frequency the assumed frequency of the sensor
|
||||
*/
|
||||
void SetAssumedFrequency(units::hertz_t frequency);
|
||||
|
||||
/**
|
||||
* Set if this encoder is inverted.
|
||||
*
|
||||
* @param inverted true to invert the encoder, false otherwise
|
||||
*/
|
||||
void SetInverted(bool inverted);
|
||||
|
||||
/**
|
||||
* Get the channel of the source.
|
||||
*
|
||||
* @return the source channel
|
||||
*/
|
||||
int GetSourceChannel() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
void Init(double fullRange, double expectedZero);
|
||||
double MapSensorRange(double pos) const;
|
||||
|
||||
std::shared_ptr<DutyCycle> m_dutyCycle;
|
||||
units::hertz_t m_frequencyThreshold = {100_Hz};
|
||||
double m_fullRange;
|
||||
double m_expectedZero;
|
||||
units::second_t m_period{0_s};
|
||||
double m_sensorMin{0.0};
|
||||
double m_sensorMax{1.0};
|
||||
bool m_isInverted{false};
|
||||
|
||||
hal::SimDevice m_simDevice;
|
||||
hal::SimDouble m_simPosition;
|
||||
hal::SimBoolean m_simIsConnected;
|
||||
};
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,283 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include <hal/Encoder.h>
|
||||
#include <hal/Types.h>
|
||||
#include <wpi/sendable/Sendable.h>
|
||||
#include <wpi/sendable/SendableHelper.h>
|
||||
|
||||
#include "frc/CounterBase.h"
|
||||
|
||||
namespace frc {
|
||||
/**
|
||||
* Class to read quad encoders.
|
||||
*
|
||||
* Quadrature encoders are devices that count shaft rotation and can sense
|
||||
* direction. The output of the QuadEncoder class is an integer that can count
|
||||
* either up or down, and can go negative for reverse direction counting. When
|
||||
* creating QuadEncoders, a direction is supplied that changes the sense of the
|
||||
* output to make code more readable if the encoder is mounted such that forward
|
||||
* movement generates negative values. Quadrature encoders have two digital
|
||||
* outputs, an A Channel and a B Channel that are out of phase with each other
|
||||
* to allow the FPGA to do direction sensing.
|
||||
*
|
||||
* All encoders will immediately start counting - Reset() them if you need them
|
||||
* to be zeroed before use.
|
||||
*/
|
||||
class Encoder : public CounterBase,
|
||||
public wpi::Sendable,
|
||||
public wpi::SendableHelper<Encoder> {
|
||||
public:
|
||||
/**
|
||||
* Encoder constructor.
|
||||
*
|
||||
* Construct a Encoder given a and b channels.
|
||||
*
|
||||
* The counter will start counting immediately.
|
||||
*
|
||||
* @param aChannel The a channel DIO channel. 0-9 are on-board, 10-25
|
||||
* are on the MXP port
|
||||
* @param bChannel The b channel DIO channel. 0-9 are on-board, 10-25
|
||||
* are on the MXP port
|
||||
* @param reverseDirection represents the orientation of the encoder and
|
||||
* inverts the output values if necessary so forward
|
||||
* represents positive values.
|
||||
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
|
||||
* decoding. If 4X is selected, then an encoder FPGA
|
||||
* object is used and the returned counts will be 4x
|
||||
* the encoder spec'd value since all rising and
|
||||
* falling edges are counted. If 1X or 2X are selected
|
||||
* then a counter object will be used and the returned
|
||||
* value will either exactly match the spec'd count or
|
||||
* be double (2x) the spec'd count.
|
||||
*/
|
||||
Encoder(int aChannel, int bChannel, bool reverseDirection = false,
|
||||
EncodingType encodingType = k4X);
|
||||
|
||||
Encoder(Encoder&&) = default;
|
||||
Encoder& operator=(Encoder&&) = default;
|
||||
|
||||
~Encoder() override = default;
|
||||
|
||||
// CounterBase interface
|
||||
/**
|
||||
* Gets the current count.
|
||||
*
|
||||
* Returns the current count on the Encoder. This method compensates for the
|
||||
* decoding type.
|
||||
*
|
||||
* @return Current count from the Encoder adjusted for the 1x, 2x, or 4x scale
|
||||
* factor.
|
||||
*/
|
||||
int Get() const override;
|
||||
|
||||
/**
|
||||
* Reset the Encoder distance to zero.
|
||||
*
|
||||
* Resets the current count to zero on the encoder.
|
||||
*/
|
||||
void Reset() override;
|
||||
|
||||
/**
|
||||
* Returns the period of the most recent pulse.
|
||||
*
|
||||
* Returns the period of the most recent Encoder pulse in seconds. This method
|
||||
* compensates for the decoding type.
|
||||
*
|
||||
* Warning: This returns unscaled periods. Use GetRate() for rates that are
|
||||
* scaled using the value from SetDistancePerPulse().
|
||||
*
|
||||
* @return Period in seconds of the most recent pulse.
|
||||
* @deprecated Use getRate() in favor of this method.
|
||||
*/
|
||||
[[deprecated("Use GetRate() in favor of this method")]]
|
||||
units::second_t GetPeriod() const override;
|
||||
|
||||
/**
|
||||
* Sets the maximum period for stopped detection.
|
||||
*
|
||||
* Sets the value that represents the maximum period of the Encoder before it
|
||||
* will assume that the attached device is stopped. This timeout allows users
|
||||
* to determine if the wheels or other shaft has stopped rotating.
|
||||
* This method compensates for the decoding type.
|
||||
*
|
||||
* @param maxPeriod The maximum time between rising and falling edges before
|
||||
* the FPGA will report the device stopped. This is expressed
|
||||
* in seconds.
|
||||
* @deprecated Use SetMinRate() in favor of this method. This takes unscaled
|
||||
* periods and SetMinRate() scales using value from
|
||||
* SetDistancePerPulse().
|
||||
*/
|
||||
[[deprecated(
|
||||
"Use SetMinRate() in favor of this method. This takes unscaled periods "
|
||||
"and SetMinRate() scales using value from SetDistancePerPulse().")]]
|
||||
void SetMaxPeriod(units::second_t maxPeriod) override;
|
||||
|
||||
/**
|
||||
* Determine if the encoder is stopped.
|
||||
*
|
||||
* Using the MaxPeriod value, a boolean is returned that is true if the
|
||||
* encoder is considered stopped and false if it is still moving. A stopped
|
||||
* encoder is one where the most recent pulse width exceeds the MaxPeriod.
|
||||
*
|
||||
* @return True if the encoder is considered stopped.
|
||||
*/
|
||||
bool GetStopped() const override;
|
||||
|
||||
/**
|
||||
* The last direction the encoder value changed.
|
||||
*
|
||||
* @return The last direction the encoder value changed.
|
||||
*/
|
||||
bool GetDirection() const override;
|
||||
|
||||
/**
|
||||
* Gets the raw value from the encoder.
|
||||
*
|
||||
* The raw value is the actual count unscaled by the 1x, 2x, or 4x scale
|
||||
* factor.
|
||||
*
|
||||
* @return Current raw count from the encoder
|
||||
*/
|
||||
int GetRaw() const;
|
||||
|
||||
/**
|
||||
* The encoding scale factor 1x, 2x, or 4x, per the requested encodingType.
|
||||
*
|
||||
* Used to divide raw edge counts down to spec'd counts.
|
||||
*/
|
||||
int GetEncodingScale() const;
|
||||
|
||||
/**
|
||||
* Get the distance the robot has driven since the last reset.
|
||||
*
|
||||
* @return The distance driven since the last reset as scaled by the value
|
||||
* from SetDistancePerPulse().
|
||||
*/
|
||||
double GetDistance() const;
|
||||
|
||||
/**
|
||||
* Get the current rate of the encoder.
|
||||
*
|
||||
* Units are distance per second as scaled by the value from
|
||||
* SetDistancePerPulse().
|
||||
*
|
||||
* @return The current rate of the encoder.
|
||||
*/
|
||||
double GetRate() const;
|
||||
|
||||
/**
|
||||
* Set the minimum rate of the device before the hardware reports it stopped.
|
||||
*
|
||||
* @param minRate The minimum rate. The units are in distance per second as
|
||||
* scaled by the value from SetDistancePerPulse().
|
||||
*/
|
||||
void SetMinRate(double minRate);
|
||||
|
||||
/**
|
||||
* Set the distance per pulse for this encoder.
|
||||
*
|
||||
* This sets the multiplier used to determine the distance driven based on the
|
||||
* count value from the encoder.
|
||||
*
|
||||
* Do not include the decoding type in this scale. The library already
|
||||
* compensates for the decoding type.
|
||||
*
|
||||
* Set this value based on the encoder's rated Pulses per Revolution and
|
||||
* factor in gearing reductions following the encoder shaft.
|
||||
*
|
||||
* This distance can be in any units you like, linear or angular.
|
||||
*
|
||||
* @param distancePerPulse The scale factor that will be used to convert
|
||||
* pulses to useful units.
|
||||
*/
|
||||
void SetDistancePerPulse(double distancePerPulse);
|
||||
|
||||
/**
|
||||
* Get the distance per pulse for this encoder.
|
||||
*
|
||||
* @return The scale factor that will be used to convert pulses to useful
|
||||
* units.
|
||||
*/
|
||||
double GetDistancePerPulse() const;
|
||||
|
||||
/**
|
||||
* Set the direction sensing for this encoder.
|
||||
*
|
||||
* This sets the direction sensing on the encoder so that it could count in
|
||||
* the correct software direction regardless of the mounting.
|
||||
*
|
||||
* @param reverseDirection true if the encoder direction should be reversed
|
||||
*/
|
||||
void SetReverseDirection(bool reverseDirection);
|
||||
|
||||
/**
|
||||
* Set the Samples to Average which specifies the number of samples of the
|
||||
* timer to average when calculating the period.
|
||||
*
|
||||
* Perform averaging to account for mechanical imperfections or as
|
||||
* oversampling to increase resolution.
|
||||
*
|
||||
* @param samplesToAverage The number of samples to average from 1 to 127.
|
||||
*/
|
||||
void SetSamplesToAverage(int samplesToAverage);
|
||||
|
||||
/**
|
||||
* Get the Samples to Average which specifies the number of samples of the
|
||||
* timer to average when calculating the period.
|
||||
*
|
||||
* Perform averaging to account for mechanical imperfections or as
|
||||
* oversampling to increase resolution.
|
||||
*
|
||||
* @return The number of samples being averaged (from 1 to 127)
|
||||
*/
|
||||
int GetSamplesToAverage() const;
|
||||
|
||||
/**
|
||||
* Indicates this encoder is used by a simulated device.
|
||||
*
|
||||
* @param device simulated device handle
|
||||
*/
|
||||
void SetSimDevice(HAL_SimDeviceHandle device);
|
||||
|
||||
int GetFPGAIndex() const;
|
||||
|
||||
void InitSendable(wpi::SendableBuilder& builder) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Common initialization code for Encoders.
|
||||
*
|
||||
* This code allocates resources for Encoders and is common to all
|
||||
* constructors. The counter will start counting immediately.
|
||||
* @param aChannel The a channel.
|
||||
* @param bChannel The b channel.
|
||||
* @param reverseDirection If true, counts down instead of up (this is all
|
||||
* relative)
|
||||
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
|
||||
* decoding. If 4X is selected, then an encoder FPGA
|
||||
* object is used and the returned counts will be 4x
|
||||
* the encoder spec'd value since all rising and
|
||||
* falling edges are counted. If 1X or 2X are selected
|
||||
* then a counter object will be used and the returned
|
||||
* value will either exactly match the spec'd count or
|
||||
* be double (2x) the spec'd count.
|
||||
*/
|
||||
void InitEncoder(int aChannel, int bChannel, bool reverseDirection,
|
||||
EncodingType encodingType);
|
||||
|
||||
/**
|
||||
* The scale needed to convert a raw counter value into a number of encoder
|
||||
* pulses.
|
||||
*/
|
||||
double DecodingScaleFactor() const;
|
||||
|
||||
hal::Handle<HAL_EncoderHandle, HAL_FreeEncoder> m_encoder;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
Reference in New Issue
Block a user