Exemple #1
0
/**
 * 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.
 */
AnalogInput::AnalogInput(uint32_t channel) {
    std::stringstream buf;
    buf << "Analog Input " << channel;
    Resource::CreateResourceObject(inputs, kAnalogInputs);

    if (!checkAnalogInputChannel(channel)) {
        wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
        return;
    }

    if (inputs->Allocate(channel, buf.str()) ==
            std::numeric_limits<uint32_t>::max()) {
        CloneError(*inputs);
        return;
    }

    m_channel = channel;

    void *port = getPort(channel);
    int32_t status = 0;
    m_port = initializeAnalogInputPort(port, &status);
    wpi_setErrorWithContext(status, getHALErrorMessage(status));

    LiveWindow::GetInstance()->AddSensor("AnalogInput", channel, this);
    HALReport(HALUsageReporting::kResourceType_AnalogChannel, channel);
}
/**
 * Initialize the Ultrasonic Sensor.
 * This is the common code that initializes the ultrasonic sensor given that there
 * are two digital I/O channels allocated. If the system was running in automatic mode (round robin)
 * when the new sensor is added, it is stopped, the sensor is added, then automatic mode is
 * restored.
 */
void Ultrasonic::Initialize()
{
	m_table = NULL;
	bool originalMode = m_automaticEnabled;
	if (m_semaphore == 0) m_semaphore = initializeSemaphore(SEMAPHORE_FULL);
	SetAutomaticMode(false); // kill task when adding a new sensor
	takeSemaphore(m_semaphore); // link this instance on the list
	{
		m_nextSensor = m_firstSensor;
		m_firstSensor = this;
	}
	giveSemaphore(m_semaphore);

	m_counter = new Counter(m_echoChannel); // set up counter for this sensor
	m_counter->SetMaxPeriod(1.0);
	m_counter->SetSemiPeriodMode(true);
	m_counter->Reset();
	m_enabled = true; // make it available for round robin scheduling
	SetAutomaticMode(originalMode);

	static int instances = 0;
	instances++;
	HALReport(HALUsageReporting::kResourceType_Ultrasonic, instances);
	LiveWindow::GetInstance()->AddSensor("Ultrasonic", m_echoChannel->GetChannel(), this);
}
Exemple #3
0
/**
 * Drive method for Mecanum wheeled robots.
 *
 * A method for driving with Mecanum wheeled robots. There are 4 wheels
 * on the robot, arranged so that the front and back wheels are toed in 45
 * degrees.
 * When looking at the wheels from the top, the roller axles should form an X
 * across the robot.
 *
 * @param magnitude The speed that the robot should drive in a given direction.
 *                  [-1.0..1.0]
 * @param direction The direction the robot should drive in degrees. The
 *                  direction and maginitute are independent of the rotation
 *                  rate.
 * @param rotation  The rate of rotation for the robot that is completely
 *                  independent of the magnitute or direction. [-1.0..1.0]
 */
void RobotDrive::MecanumDrive_Polar(float magnitude, float direction,
                                    float rotation) {
  static bool reported = false;
  if (!reported) {
    HALReport(HALUsageReporting::kResourceType_RobotDrive, GetNumMotors(),
              HALUsageReporting::kRobotDrive_MecanumPolar);
    reported = true;
  }

  // Normalized for full power along the Cartesian axes.
  magnitude = Limit(magnitude) * sqrt(2.0);
  // The rollers are at 45 degree angles.
  double dirInRad = (direction + 45.0) * 3.14159 / 180.0;
  double cosD = cos(dirInRad);
  double sinD = sin(dirInRad);

  double wheelSpeeds[kMaxNumberOfMotors];
  wheelSpeeds[kFrontLeftMotor] = sinD * magnitude + rotation;
  wheelSpeeds[kFrontRightMotor] = cosD * magnitude - rotation;
  wheelSpeeds[kRearLeftMotor] = cosD * magnitude + rotation;
  wheelSpeeds[kRearRightMotor] = sinD * magnitude - rotation;

  Normalize(wheelSpeeds);

  m_frontLeftMotor->Set(wheelSpeeds[kFrontLeftMotor] * m_maxOutput);
  m_frontRightMotor->Set(wheelSpeeds[kFrontRightMotor] * m_maxOutput);
  m_rearLeftMotor->Set(wheelSpeeds[kRearLeftMotor] * m_maxOutput);
  m_rearRightMotor->Set(wheelSpeeds[kRearRightMotor] * m_maxOutput);

  m_safetyHelper->Feed();
}
Exemple #4
0
/**
 * Drive method for Mecanum wheeled robots.
 *
 * A method for driving with Mecanum wheeled robots. There are 4 wheels
 * on the robot, arranged so that the front and back wheels are toed in 45
 * degrees.
 * When looking at the wheels from the top, the roller axles should form an X
 * across the robot.
 *
 * This is designed to be directly driven by joystick axes.
 *
 * @param x         The speed that the robot should drive in the X direction.
 *                  [-1.0..1.0]
 * @param y         The speed that the robot should drive in the Y direction.
 *                  This input is inverted to match the forward == -1.0 that
 *                  joysticks produce. [-1.0..1.0]
 * @param rotation  The rate of rotation for the robot that is completely
 *                  independent of the translation. [-1.0..1.0]
 * @param gyroAngle The current angle reading from the gyro.  Use this to
 *                  implement field-oriented controls.
 */
void RobotDrive::MecanumDrive_Cartesian(float x, float y, float rotation,
                                        float gyroAngle) {
  static bool reported = false;
  if (!reported) {
    HALReport(HALUsageReporting::kResourceType_RobotDrive, GetNumMotors(),
              HALUsageReporting::kRobotDrive_MecanumCartesian);
    reported = true;
  }

  double xIn = x;
  double yIn = y;
  // Negate y for the joystick.
  yIn = -yIn;
  // Compenstate for gyro angle.
  RotateVector(xIn, yIn, gyroAngle);

  double wheelSpeeds[kMaxNumberOfMotors];
  wheelSpeeds[kFrontLeftMotor] = xIn + yIn + rotation;
  wheelSpeeds[kFrontRightMotor] = -xIn + yIn - rotation;
  wheelSpeeds[kRearLeftMotor] = -xIn + yIn + rotation;
  wheelSpeeds[kRearRightMotor] = xIn + yIn - rotation;

  Normalize(wheelSpeeds);

  m_frontLeftMotor->Set(wheelSpeeds[kFrontLeftMotor] * m_maxOutput);
  m_frontRightMotor->Set(wheelSpeeds[kFrontRightMotor] * m_maxOutput);
  m_rearLeftMotor->Set(wheelSpeeds[kRearLeftMotor] * m_maxOutput);
  m_rearRightMotor->Set(wheelSpeeds[kRearRightMotor] * m_maxOutput);

  m_safetyHelper->Feed();
}
/**
 * Constructor.
 *
 * @param moduleNumber The CAN ID of the PCM the solenoid is attached to
 * @param channel The channel on the PCM to control (0..7).
 */
Solenoid::Solenoid(uint8_t moduleNumber, uint32_t channel)
    : SolenoidBase(moduleNumber), m_channel(channel) {
  std::stringstream buf;
  if (!CheckSolenoidModule(m_moduleNumber)) {
    buf << "Solenoid Module " << m_moduleNumber;
    wpi_setWPIErrorWithContext(ModuleIndexOutOfRange, buf.str());
    return;
  }
  if (!CheckSolenoidChannel(m_channel)) {
    buf << "Solenoid Module " << m_channel;
    wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
    return;
  }
  Resource::CreateResourceObject(m_allocated, m_maxModules * m_maxPorts);
  buf << "Solenoid " << m_channel << " (Module: " << m_moduleNumber << ")";
  if (m_allocated->Allocate(m_moduleNumber * kSolenoidChannels + m_channel,
                            buf.str()) ==
      std::numeric_limits<uint32_t>::max()) {
    CloneError(*m_allocated);
    return;
  }

#if FULL_WPILIB
  LiveWindow::GetInstance()->AddActuator("Solenoid", m_moduleNumber, m_channel,
                                         this);
#endif
  HALReport(HALUsageReporting::kResourceType_Solenoid, m_channel,
            m_moduleNumber);
}
Exemple #6
0
/**
 * Drive the motors at "outputMagnitude" and "curve".
 * Both outputMagnitude and curve are -1.0 to +1.0 values, where 0.0 represents
 * stopped and not turning. curve < 0 will turn left and curve > 0 will turn
 * right.
 *
 * The algorithm for steering provides a constant turn radius for any normal
 * speed range, both forward and backward. Increasing m_sensitivity causes
 * sharper turns for fixed values of curve.
 *
 * This function will most likely be used in an autonomous routine.
 *
 * @param outputMagnitude The speed setting for the outside wheel in a turn,
 *        forward or backwards, +1 to -1.
 * @param curve The rate of turn, constant for different forward speeds. Set
 *        curve < 0 for left turn or curve > 0 for right turn.
 * Set curve = e^(-r/w) to get a turn radius r for wheelbase w of your robot.
 * Conversely, turn radius r = -ln(curve)*w for a given value of curve and
 * wheelbase w.
 */
void RobotDrive::Drive(float outputMagnitude, float curve) {
  float leftOutput, rightOutput;
  static bool reported = false;
  if (!reported) {
    HALReport(HALUsageReporting::kResourceType_RobotDrive, GetNumMotors(),
              HALUsageReporting::kRobotDrive_ArcadeRatioCurve);
    reported = true;
  }

  if (curve < 0) {
    float value = log(-curve);
    float ratio = (value - m_sensitivity) / (value + m_sensitivity);
    if (ratio == 0) ratio = .0000000001;
    leftOutput = outputMagnitude / ratio;
    rightOutput = outputMagnitude;
  } else if (curve > 0) {
    float value = log(curve);
    float ratio = (value - m_sensitivity) / (value + m_sensitivity);
    if (ratio == 0) ratio = .0000000001;
    leftOutput = outputMagnitude;
    rightOutput = outputMagnitude / ratio;
  } else {
    leftOutput = outputMagnitude;
    rightOutput = outputMagnitude;
  }
  SetLeftRightMotorOutputs(leftOutput, rightOutput);
}
Exemple #7
0
/**
 * Fixup the sendMode so Set() serializes the correct demand value.
 * Also fills the modeSelecet in the control frame to disabled.
 * @param mode Control mode to ultimately enter once user calls Set().
 * @see Set()
 */
void CANTalon::ApplyControlMode(CANSpeedController::ControlMode mode) {
  m_controlMode = mode;
  HALReport(HALUsageReporting::kResourceType_CANTalonSRX, m_deviceNumber + 1,
            mode);
  switch (mode) {
    case kPercentVbus:
      m_sendMode = kThrottle;
      break;
    case kCurrent:
      m_sendMode = kCurrentMode;
      break;
    case kSpeed:
      m_sendMode = kSpeedMode;
      break;
    case kPosition:
      m_sendMode = kPositionMode;
      break;
    case kVoltage:
      m_sendMode = kVoltageMode;
      break;
    case kFollower:
      m_sendMode = kFollowerMode;
      break;
  }
  // Keep the talon disabled until Set() is called.
  CTR_Code status = m_impl->SetModeSelect((int)kDisabled);
  if (status != CTR_OKAY) {
    wpi_setErrorWithContext(status, getHALErrorMessage(status));
  }
}
Exemple #8
0
/**
 * Provide tank steering using the stored robot configuration.
 * This function lets you directly provide joystick values from any source.
 * @param leftValue The value of the left stick.
 * @param rightValue The value of the right stick.
 */
void RobotDrive::TankDrive(float leftValue, float rightValue,
                           bool squaredInputs) {
  static bool reported = false;
  if (!reported) {
    HALReport(HALUsageReporting::kResourceType_RobotDrive, GetNumMotors(),
              HALUsageReporting::kRobotDrive_Tank);
    reported = true;
  }

  // square the inputs (while preserving the sign) to increase fine control
  // while permitting full power
  leftValue = Limit(leftValue);
  rightValue = Limit(rightValue);
  if (squaredInputs) {
    if (leftValue >= 0.0) {
      leftValue = (leftValue * leftValue);
    } else {
      leftValue = -(leftValue * leftValue);
    }
    if (rightValue >= 0.0) {
      rightValue = (rightValue * rightValue);
    } else {
      rightValue = -(rightValue * rightValue);
    }
  }

  SetLeftRightMotorOutputs(leftValue, rightValue);
}
Exemple #9
0
/**
 * Initialize the gyro.  Calibration is handled by Calibrate().
 */
void AnalogGyro::InitGyro() {
    if (StatusIsFatal()) return;

    if (!m_analog->IsAccumulatorChannel()) {
        wpi_setWPIErrorWithContext(ParameterOutOfRange,
                                   " channel (must be accumulator channel)");
        m_analog = nullptr;
        return;
    }

    m_voltsPerDegreePerSecond = kDefaultVoltsPerDegreePerSecond;
    m_analog->SetAverageBits(kAverageBits);
    m_analog->SetOversampleBits(kOversampleBits);
    float sampleRate =
        kSamplesPerSecond * (1 << (kAverageBits + kOversampleBits));
    m_analog->SetSampleRate(sampleRate);
    Wait(0.1);

    SetDeadband(0.0f);

    SetPIDSourceType(PIDSourceType::kDisplacement);

    HALReport(HALUsageReporting::kResourceType_Gyro, m_analog->GetChannel());
    LiveWindow::GetInstance()->AddSensor("AnalogGyro", m_analog->GetChannel(), this);
}
Exemple #10
0
/**
 * Constructor for a VictorSP
 * @param channel The PWM channel that the VictorSP is attached to. 0-9 are
 * on-board, 10-19 are on the MXP port
 */
VictorSP::VictorSP(uint32_t channel) : SafePWM(channel) {
  SetBounds(2.004, 1.52, 1.50, 1.48, .997);
  SetPeriodMultiplier(kPeriodMultiplier_1X);
  SetRaw(m_centerPwm);
  SetZeroLatch();

  HALReport(HALUsageReporting::kResourceType_VictorSP, GetChannel());
  LiveWindow::GetInstance()->AddActuator("VictorSP", GetChannel(), this);
}
Exemple #11
0
/**
 * Common initialization code called by all constructors.
 *
 * InitServo() assigns defaults for the period multiplier for the servo PWM control signal, as
 * well as the minimum and maximum PWM values supported by the servo.
 */
void Servo::InitServo()
{
	m_table = NULL;
	SetBounds(kDefaultMaxServoPWM, 0.0, 0.0, 0.0, kDefaultMinServoPWM);
	SetPeriodMultiplier(kPeriodMultiplier_4X);

	LiveWindow::GetInstance()->AddActuator("Servo", GetChannel(), this);
	HALReport(HALUsageReporting::kResourceType_Servo, GetChannel());
}
Exemple #12
0
/**
 * Constructor for a Spark
 * @param channel The PWM channel that the Spark is attached to. 0-9 are
 * on-board, 10-19 are on the MXP port
 */
Spark::Spark(uint32_t channel) : PWMSpeedController(channel) {
  SetBounds(2.003, 1.55, 1.50, 1.46, .999);
  SetPeriodMultiplier(kPeriodMultiplier_1X);
  SetRaw(m_centerPwm);
  SetZeroLatch();

  HALReport(HALUsageReporting::kResourceType_RevSPARK, GetChannel());
  LiveWindow::GetInstance()->AddActuator("Spark", GetChannel(), this);
}
Exemple #13
0
/**
 * Constructor for a SD540
 * @param channel The PWM channel that the SD540 is attached to. 0-9 are
 * on-board, 10-19 are on the MXP port
 */
SD540::SD540(uint32_t channel) : SafePWM(channel) {
  SetBounds(2.05, 1.55, 1.50, 1.44, .94);
  SetPeriodMultiplier(kPeriodMultiplier_1X);
  SetRaw(m_centerPwm);
  SetZeroLatch();

  HALReport(HALUsageReporting::kResourceType_MindsensorsSD540, GetChannel());
  LiveWindow::GetInstance()->AddActuator("SD540", GetChannel(), this);
}
Exemple #14
0
/**
 * Common initialization code called by all constructors.
 *
 * Note that the Talon uses the following bounds for PWM values. These values should work reasonably well for
 * most controllers, but if users experience issues such as asymmetric behavior around
 * the deadband or inability to saturate the controller in either direction, calibration is recommended.
 * The calibration procedure can be found in the Talon User Manual available from CTRE.
 *
 *   2.037ms = full "forward"
 *   1.539ms = the "high end" of the deadband range
 *   1.513ms = center of the deadband range (off)
 *   1.487ms = the "low end" of the deadband range
 *   0.989ms = full "reverse"
 */
void Talon::InitTalon() {
	SetBounds(2.037, 1.539, 1.513, 1.487, .989);
	SetPeriodMultiplier(kPeriodMultiplier_1X);
	SetRaw(m_centerPwm);
	SetZeroLatch();

	HALReport(HALUsageReporting::kResourceType_Talon, GetChannel());
	LiveWindow::GetInstance()->AddActuator("Talon", GetChannel(), this);
}
/**
 * Constructor.
 *
 * @param port The I2C port the accelerometer is attached to
 * @param range The range (+ or -) that the accelerometer will measure.
 */
ADXL345_I2C::ADXL345_I2C(Port port, Range range) : I2C(port, kAddress) {
  // Turn on the measurements
  Write(kPowerCtlRegister, kPowerCtl_Measure);
  // Specify the data format to read
  SetRange(range);

  HALReport(HALUsageReporting::kResourceType_ADXL345,
            HALUsageReporting::kADXL345_I2C, 0);
  LiveWindow::GetInstance()->AddSensor("ADXL345_I2C", port, this);
}
DigitalGlitchFilter::DigitalGlitchFilter() {
  std::lock_guard<priority_mutex> sync(m_mutex);
  auto index =
      std::find(m_filterAllocated.begin(), m_filterAllocated.end(), false);
  wpi_assert(index != m_filterAllocated.end());

  m_channelIndex = std::distance(m_filterAllocated.begin(), index);
  *index = true;

  HALReport(HALUsageReporting::kResourceType_DigitalFilter, m_channelIndex);
}
/**
 * Initialize an analog trigger from a channel.
 */
void AnalogTrigger::InitTrigger(uint32_t channel)
{
	void* port = getPort(channel);
	int32_t status = 0;
	uint32_t index = 0;
	m_trigger = initializeAnalogTrigger(port, &index, &status);
	wpi_setErrorWithContext(status, getHALErrorMessage(status));
	m_index = index;

	HALReport(HALUsageReporting::kResourceType_AnalogTrigger, channel);
}
Exemple #18
0
Preferences::Preferences() {
  std::unique_lock<priority_recursive_mutex> sync(m_fileLock);
  m_readTask = Task("PreferencesReadTask", &Preferences::ReadTaskRun, this);

  /* The main thread initially blocks on the semaphore. The read task signals
   * the main thread to continue after it has locked the table mutex (so the
   * table will be fully populated when the main thread can finally access it).
   */
  m_fileOpStarted.take();

  HALReport(HALUsageReporting::kResourceType_Preferences, 0);
}
Exemple #19
0
/**
 * Construct an instance of a joystick.
 * The joystick index is the usb port on the drivers station.
 *
 * @param port The port on the driver station that the joystick is plugged into
 * (0-5).
 */
Joystick::Joystick(uint32_t port)
    : Joystick(port, kNumAxisTypes, kNumButtonTypes) {
  m_axes[kXAxis] = kDefaultXAxis;
  m_axes[kYAxis] = kDefaultYAxis;
  m_axes[kZAxis] = kDefaultZAxis;
  m_axes[kTwistAxis] = kDefaultTwistAxis;
  m_axes[kThrottleAxis] = kDefaultThrottleAxis;

  m_buttons[kTriggerButton] = kDefaultTriggerButton;
  m_buttons[kTopButton] = kDefaultTopButton;

  HALReport(HALUsageReporting::kResourceType_Joystick, port);
}
Exemple #20
0
/**
 * Arcade drive implements single stick driving.
 * This function lets you directly provide joystick values from any source.
 * @param moveValue The value to use for fowards/backwards
 * @param rotateValue The value to use for the rotate right/left
 * @param squaredInputs If set, increases the sensitivity at low speeds
 */
void RobotDrive::ArcadeDrive(float moveValue, float rotateValue,
                             bool squaredInputs) {
  static bool reported = false;
  if (!reported) {
    HALReport(HALUsageReporting::kResourceType_RobotDrive, GetNumMotors(),
              HALUsageReporting::kRobotDrive_ArcadeStandard);
    reported = true;
  }

  // local variables to hold the computed PWM values for the motors
  float leftMotorOutput;
  float rightMotorOutput;

  moveValue = Limit(moveValue);
  rotateValue = Limit(rotateValue);

  if (squaredInputs) {
    // square the inputs (while preserving the sign) to increase fine control
    // while permitting full power
    if (moveValue >= 0.0) {
      moveValue = (moveValue * moveValue);
    } else {
      moveValue = -(moveValue * moveValue);
    }
    if (rotateValue >= 0.0) {
      rotateValue = (rotateValue * rotateValue);
    } else {
      rotateValue = -(rotateValue * rotateValue);
    }
  }

  if (moveValue > 0.0) {
    if (rotateValue > 0.0) {
      leftMotorOutput = moveValue - rotateValue;
      rightMotorOutput = std::max(moveValue, rotateValue);
    } else {
      leftMotorOutput = std::max(moveValue, -rotateValue);
      rightMotorOutput = moveValue + rotateValue;
    }
  } else {
    if (rotateValue > 0.0) {
      leftMotorOutput = -std::max(-moveValue, rotateValue);
      rightMotorOutput = moveValue + rotateValue;
    } else {
      leftMotorOutput = moveValue - rotateValue;
      rightMotorOutput = -std::max(-moveValue, -rotateValue);
    }
  }
  SetLeftRightMotorOutputs(leftMotorOutput, rightMotorOutput);
}
Exemple #21
0
/**
 * Relay constructor given a channel.
 *
 * This code initializes the relay and reserves all resources that need to be
 * locked. Initially the relay is set to both lines at 0v.
 * @param channel The channel number (0-3).
 * @param direction The direction that the Relay object will control.
 */
Relay::Relay(uint32_t channel, Relay::Direction direction)
    : m_channel(channel), m_direction(direction) {
  std::stringstream buf;
  Resource::CreateResourceObject(relayChannels,
                                 dio_kNumSystems * kRelayChannels * 2);
  if (!SensorBase::CheckRelayChannel(m_channel)) {
    buf << "Relay Channel " << m_channel;
    wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
    return;
  }

  if (m_direction == kBothDirections || m_direction == kForwardOnly) {
    buf << "Forward Relay " << m_channel;
    if (relayChannels->Allocate(m_channel * 2, buf.str()) == ~0ul) {
      CloneError(*relayChannels);
      return;
    }

    HALReport(HALUsageReporting::kResourceType_Relay, m_channel);
  }
  if (m_direction == kBothDirections || m_direction == kReverseOnly) {
    buf << "Reverse Relay " << m_channel;
    if (relayChannels->Allocate(m_channel * 2 + 1, buf.str()) == ~0ul) {
      CloneError(*relayChannels);
      return;
    }

    HALReport(HALUsageReporting::kResourceType_Relay, m_channel + 128);
  }

  int32_t status = 0;
  setRelayForward(m_relay_ports[m_channel], false, &status);
  setRelayReverse(m_relay_ports[m_channel], false, &status);
  wpi_setErrorWithContext(status, getHALErrorMessage(status));

  LiveWindow::GetInstance().AddActuator("Relay", 1, m_channel, this);
}
Exemple #22
0
/**
 * Common initialization code for Encoders.
 * This code allocates resources for Encoders and is common to all constructors.
 *
 * The counter will start counting immediately.
 *
 * @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 Encoder::InitEncoder(bool reverseDirection, EncodingType encodingType)
{
	m_table = NULL;
	m_encodingType = encodingType;
	m_index = 0;
	switch (encodingType)
	{
		case k4X:
		{
			m_encodingScale = 4;
			if (m_aSource->StatusIsFatal())
			{
				CloneError(m_aSource);
				return;
			}
			if (m_bSource->StatusIsFatal())
			{
				CloneError(m_bSource);
				return;
			}
			int32_t status = 0;
			m_encoder =  initializeEncoder(m_aSource->GetModuleForRouting(), m_aSource->GetChannelForRouting(),
										   m_aSource->GetAnalogTriggerForRouting(),
										   m_bSource->GetModuleForRouting(), m_bSource->GetChannelForRouting(),
										   m_bSource->GetAnalogTriggerForRouting(),
										   reverseDirection, &m_index, &status);
			  wpi_setErrorWithContext(status, getHALErrorMessage(status));
			m_counter = NULL;
			SetMaxPeriod(.5);
			break;
		}
		case k1X:
		case k2X:
		{
			m_encodingScale = encodingType == k1X ? 1 : 2;
			m_counter = new Counter(m_encodingType, m_aSource, m_bSource, reverseDirection);
			m_index = m_counter->GetFPGAIndex();
			break;
		}
		default:
			wpi_setErrorWithContext(-1, "Invalid encodingType argument");
			break;
	}
	m_distancePerPulse = 1.0;
	m_pidSource = kDistance;

	HALReport(HALUsageReporting::kResourceType_Encoder, m_index, encodingType);
	LiveWindow::GetInstance()->AddSensor("Encoder", m_aSource->GetChannelForRouting(), this);
}
void DigitalGlitchFilter::DoAdd(DigitalSource* input, int requested_index) {
  // Some sources from Counters and Encoders are null.  By pushing the check
  // here, we catch the issue more generally.
  if (input) {
    int32_t status = 0;
    setFilterSelect(m_digital_ports[input->GetChannelForRouting()],
                    requested_index, &status);
    wpi_setErrorWithContext(status, getHALErrorMessage(status));

    // Validate that we set it correctly.
    int actual_index = getFilterSelect(
        m_digital_ports[input->GetChannelForRouting()], &status);
    wpi_assertEqual(actual_index, requested_index);

    HALReport(HALUsageReporting::kResourceType_DigitalInput,
              input->GetChannelForRouting());
  }
}
/**
 * Constructor for a Jaguar connected via PWM
 * @param channel The PWM channel that the Jaguar is attached to. 0-9 are
 * on-board, 10-19 are on the MXP port
 */
Jaguar::Jaguar(uint32_t channel) : PWMSpeedController(channel) {
  /**
   * Input profile defined by Luminary Micro.
   *
   * Full reverse ranges from 0.671325ms to 0.6972211ms
   * Proportional reverse ranges from 0.6972211ms to 1.4482078ms
   * Neutral ranges from 1.4482078ms to 1.5517922ms
   * Proportional forward ranges from 1.5517922ms to 2.3027789ms
   * Full forward ranges from 2.3027789ms to 2.328675ms
   */
  SetBounds(2.31, 1.55, 1.507, 1.454, .697);
  SetPeriodMultiplier(kPeriodMultiplier_1X);
  SetRaw(m_centerPwm);
  SetZeroLatch();

  HALReport(HALUsageReporting::kResourceType_Jaguar, GetChannel());
  LiveWindow::GetInstance()->AddActuator("Jaguar", GetChannel(), this);
}
/**
 * Internal common init function.
 */
void ADXL345_SPI::Init(Range range)
{
		m_spi = new SPI(m_port);
		m_spi->SetClockRate(500000);
		m_spi->SetMSBFirst();
		m_spi->SetSampleDataOnFalling();
		m_spi->SetClockActiveLow();
		m_spi->SetChipSelectActiveHigh();

		uint8_t commands[2];
		// Turn on the measurements
		commands[0] = kPowerCtlRegister;
		commands[1] = kPowerCtl_Measure;
		m_spi->Transaction(commands, commands, 2);

		SetRange(range);

		HALReport(HALUsageReporting::kResourceType_ADXL345, HALUsageReporting::kADXL345_SPI);
}
/**
 * Create an instance of a DigitalInput.
 * Creates a digital input given a channel. Common creation routine for all
 * constructors.
 */
void DigitalInput::InitDigitalInput(uint32_t channel)
{
	m_table = NULL;
	char buf[64];

	if (!CheckDigitalChannel(channel))
	{
		snprintf(buf, 64, "Digital Channel %d", channel);
		wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf);
		return;
	}
	m_channel = channel;

	int32_t status = 0;
	allocateDIO(m_digital_ports[channel], true, &status);
	wpi_setErrorWithContext(status, getHALErrorMessage(status));

	LiveWindow::GetInstance()->AddSensor("DigitalInput", channel, this);
	HALReport(HALUsageReporting::kResourceType_DigitalInput, channel);
}
Exemple #27
0
/**
 * Construct a TalonSRX connected via PWM
 * @param channel The PWM channel that the TalonSRX is attached to. 0-9 are
 * on-board, 10-19 are on the MXP port
 */
TalonSRX::TalonSRX(uint32_t channel) : SafePWM(channel) {
  /* Note that the TalonSRX uses the following bounds for PWM values. These
   * values should work reasonably well for most controllers, but if users
   * experience issues such as asymmetric behavior around the deadband or
   * inability to saturate the controller in either direction, calibration is
   * recommended. The calibration procedure can be found in the TalonSRX User
   * Manual available from Cross The Road Electronics.
   *   2.004ms = full "forward"
   *   1.52ms = the "high end" of the deadband range
   *   1.50ms = center of the deadband range (off)
   *   1.48ms = the "low end" of the deadband range
   *   0.997ms = full "reverse"
   */
  SetBounds(2.004, 1.52, 1.50, 1.48, .997);
  SetPeriodMultiplier(kPeriodMultiplier_1X);
  SetRaw(m_centerPwm);
  SetZeroLatch();

  HALReport(HALUsageReporting::kResourceType_TalonSRX, GetChannel());
  LiveWindow::GetInstance()->AddActuator("TalonSRX", GetChannel(), this);
}
Exemple #28
0
/**
 * Gyro constructor on the specified SPI port.
 *
 * @param port The SPI port the gyro is attached to.
 */
ADXRS450_Gyro::ADXRS450_Gyro(SPI::Port port) : m_spi(port) {
  m_spi.SetClockRate(3000000);
  m_spi.SetMSBFirst();
  m_spi.SetSampleDataOnRising();
  m_spi.SetClockActiveHigh();
  m_spi.SetChipSelectActiveLow();

  // Validate the part ID
  if ((ReadRegister(kPIDRegister) & 0xff00) != 0x5200) {
    DriverStation::ReportError("could not find ADXRS450 gyro");
    return;
  }

  m_spi.InitAccumulator(kSamplePeriod, 0x20000000u, 4, 0x0c000000u, 0x04000000u,
                        10u, 16u, true, true);

  Calibrate();

  HALReport(HALUsageReporting::kResourceType_ADXRS450, port);
  LiveWindow::GetInstance()->AddSensor("ADXRS450_Gyro", port, this);
}
Exemple #29
0
void PIDController::Initialize(float Kp, float Ki, float Kd, float Kf,
                               PIDSource* source, PIDOutput* output,
                               float period) {
  m_controlLoop = std::make_unique<Notifier>(&PIDController::Calculate, this);

  m_P = Kp;
  m_I = Ki;
  m_D = Kd;
  m_F = Kf;

  m_pidInput = source;
  m_pidOutput = output;
  m_period = period;

  m_controlLoop->StartPeriodic(m_period);
  m_setpointTimer.Start();

  static int32_t instances = 0;
  instances++;
  HALReport(HALUsageReporting::kResourceType_PIDController, instances);
}
Exemple #30
0
/**
 * 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
 */
PWM::PWM(uint32_t channel) {
  std::stringstream buf;

  if (!CheckPWMChannel(channel)) {
    buf << "PWM Channel " << channel;
    wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
    return;
  }

  int32_t status = 0;
  allocatePWMChannel(m_pwm_ports[channel], &status);
  wpi_setErrorWithContext(status, getHALErrorMessage(status));

  m_channel = channel;

  setPWM(m_pwm_ports[m_channel], kPwmDisabled, &status);
  wpi_setErrorWithContext(status, getHALErrorMessage(status));

  m_eliminateDeadband = false;

  HALReport(HALUsageReporting::kResourceType_PWM, channel);
}