예제 #1
0
/**
 * Get the value of the axis on a joystick.
 * This depends on the mapping of the joystick connected to the specified port.
 *
 * @param stick The joystick to read.
 * @param axis The analog axis value to read from the joystick.
 * @return The value of the axis on the joystick.
 */
float DriverStation::GetStickAxis(uint32_t stick, uint32_t axis)
{
	if (stick >= kJoystickPorts)
	{
		wpi_setWPIError(BadJoystickIndex);
		return 0;
	}

	if (axis >= m_joystickAxes[stick].count)
	{
		if (axis >= kMaxJoystickAxes)
			wpi_setWPIError(BadJoystickAxis);
		else
			ReportJoystickUnpluggedError("WARNING: Joystick Axis missing, check if all controllers are plugged in\n");
		return 0.0f;
	}

	int8_t value = m_joystickAxes[stick].axes[axis];

	if(value < 0)
	{
		return value / 128.0f;
	}
	else
	{
		return value / 127.0f;
	}
}
예제 #2
0
/**
 * Constructor.
 * 
 * @param moduleNumber The digital module that the sensor is plugged into (1 or 2).
 */
HiTechnicColorSensor::HiTechnicColorSensor(UINT8 moduleNumber)
	: m_i2c (NULL)
{
	m_table = NULL;
	DigitalModule *module = DigitalModule::GetInstance(moduleNumber);
	m_mode = kActive;
	
	if (module)
	{
		m_i2c = module->GetI2C(kAddress);
	
		// Verify Sensor
		const UINT8 kExpectedManufacturer[] = "HiTechnc";
		const UINT8 kExpectedSensorType[] = "ColorPD ";
		if ( ! m_i2c->VerifySensor(kManufacturerBaseRegister, kManufacturerSize, kExpectedManufacturer) )
		{
			wpi_setWPIError(CompassManufacturerError);
			return;
		}
		if ( ! m_i2c->VerifySensor(kSensorTypeBaseRegister, kSensorTypeSize, kExpectedSensorType) )
		{
			wpi_setWPIError(CompassTypeError);
		}
		
		nUsageReporting::report(nUsageReporting::kResourceType_HiTechnicColorSensor, moduleNumber - 1);
	}
}
예제 #3
0
/**
 * Free an allocated resource.
 * After a resource is no longer needed, for example a destructor is called for
 * a channel assignment
 * class, Free will release the resource value so it can be reused somewhere
 * else in the program.
 */
void Resource::Free(uint32_t index) {
  std::unique_lock<priority_recursive_mutex> sync(m_allocateLock);
  if (index == std::numeric_limits<uint32_t>::max()) return;
  if (index >= m_isAllocated.size()) {
    wpi_setWPIError(NotAllocated);
    return;
  }
  if (!m_isAllocated[index]) {
    wpi_setWPIError(NotAllocated);
    return;
  }
  m_isAllocated[index] = false;
}
예제 #4
0
/**
 * Set the relay state.
 *
 * Valid values depend on which directions of the relay are controlled by the
 * object.
 *
 * When set to kBothDirections, the relay can be any of the four states:
 * 0v-0v, 0v-12v, 12v-0v, 12v-12v
 *
 * When set to kForwardOnly or kReverseOnly, you can specify the constant for
 * the direction or you can simply specify kOff and kOn.  Using only kOff and
 * kOn is recommended.
 *
 * @param value The state to set the relay.
 */
void Relay::Set(Relay::Value value) {
  if (StatusIsFatal()) return;

  int32_t status = 0;

  switch (value) {
    case kOff:
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        HAL_SetRelay(m_forwardHandle, false, &status);
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        HAL_SetRelay(m_reverseHandle, false, &status);
      }
      break;
    case kOn:
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        HAL_SetRelay(m_forwardHandle, true, &status);
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        HAL_SetRelay(m_reverseHandle, true, &status);
      }
      break;
    case kForward:
      if (m_direction == kReverseOnly) {
        wpi_setWPIError(IncompatibleMode);
        break;
      }
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        HAL_SetRelay(m_forwardHandle, true, &status);
      }
      if (m_direction == kBothDirections) {
        HAL_SetRelay(m_reverseHandle, false, &status);
      }
      break;
    case kReverse:
      if (m_direction == kForwardOnly) {
        wpi_setWPIError(IncompatibleMode);
        break;
      }
      if (m_direction == kBothDirections) {
        HAL_SetRelay(m_forwardHandle, false, &status);
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        HAL_SetRelay(m_reverseHandle, true, &status);
      }
      break;
  }

  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
예제 #5
0
/**
 * Set the relay state.
 *
 * Valid values depend on which directions of the relay are controlled by the
 * object.
 *
 * When set to kBothDirections, the relay can be any of the four states:
 * 	 0v-0v, 0v-12v, 12v-0v, 12v-12v
 *
 * When set to kForwardOnly or kReverseOnly, you can specify the constant for
 * the
 * 	 direction or you can simply specify kOff and kOn.  Using only kOff and
 * kOn is
 * 	 recommended.
 *
 * @param value The state to set the relay.
 */
void Relay::Set(Relay::Value value) {
  if (StatusIsFatal()) return;

  int32_t status = 0;

  switch (value) {
    case kOff:
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        setRelayForward(m_relay_ports[m_channel], false, &status);
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        setRelayReverse(m_relay_ports[m_channel], false, &status);
      }
      break;
    case kOn:
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        setRelayForward(m_relay_ports[m_channel], true, &status);
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        setRelayReverse(m_relay_ports[m_channel], true, &status);
      }
      break;
    case kForward:
      if (m_direction == kReverseOnly) {
        wpi_setWPIError(IncompatibleMode);
        break;
      }
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        setRelayForward(m_relay_ports[m_channel], true, &status);
      }
      if (m_direction == kBothDirections) {
        setRelayReverse(m_relay_ports[m_channel], false, &status);
      }
      break;
    case kReverse:
      if (m_direction == kForwardOnly) {
        wpi_setWPIError(IncompatibleMode);
        break;
      }
      if (m_direction == kBothDirections) {
        setRelayForward(m_relay_ports[m_channel], false, &status);
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        setRelayReverse(m_relay_ports[m_channel], true, &status);
      }
      break;
  }

  wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
예제 #6
0
/**
 * Validate that the data being packed will fit in the buffer.
 */
bool Dashboard::ValidateAdd(INT32 size)
{
	if ((m_packPtr - m_localBuffer) + size > kMaxDashboardDataSize)
	{
		wpi_setWPIError(DashboardDataOverflow);
		return false;
	}
	// Make sure printf is not being used at the same time.
	if (m_localPrintBuffer[0] != 0)
	{
		wpi_setWPIError(DashboardDataCollision);
		return false;
	}
	return true;
}
예제 #7
0
/**
 * Returns a boolean indicating if the controller is an xbox controller.
 *
 * @param stick The joystick port number
 * @return A boolean that is true if the controller is an xbox controller.
 */
bool DriverStation::GetJoystickIsXbox(uint32_t stick) const {
  if (stick >= kJoystickPorts) {
    wpi_setWPIError(BadJoystickIndex);
    return false;
  }
  return (bool)m_joystickDescriptor[stick].isXbox;
}
예제 #8
0
/**
 * Set the sample rate on the module.
 * 
 * This is a global setting for the module and effects all channels.
 * 
 * @param samplesPerSecond The number of samples per channel per second.
 */
void AnalogModule::SetSampleRate(float samplesPerSecond)
{
	// TODO: This will change when variable size scan lists are implemented.
	// TODO: Need float comparison with epsilon.
	//wpi_assert(!sampleRateSet || GetSampleRate() == samplesPerSecond);
	m_sampleRateSet = true;

	// Compute the convert rate
	UINT32 ticksPerSample = (UINT32)((float)kTimebase / samplesPerSecond);
	UINT32 ticksPerConversion = ticksPerSample / GetNumChannelsToActivate();
	// ticksPerConversion must be at least 80
	if (ticksPerConversion < 80)
	{
		wpi_setWPIError(SampleRateTooHigh);
		ticksPerConversion = 80;
	}

	// Atomically set the scan size and the convert rate so that the sample rate is constant
	tAI::tConfig config;
	config.ScanSize = GetNumChannelsToActivate();
	config.ConvertRate = ticksPerConversion;
	tRioStatusCode localStatus = NiFpga_Status_Success;
	m_module->writeConfig(config, &localStatus);
	wpi_setError(localStatus);

	// Indicate that the scan size has been commited to hardware.
	SetNumChannelsToActivate(0);
}
예제 #9
0
/**
 * Returns the name of the joystick at the given port
 *
 * @param stick The joystick port number
 * @return The name of the joystick at the given port
 */
std::string DriverStation::GetJoystickName(uint32_t stick) const {
  if (stick >= kJoystickPorts) {
    wpi_setWPIError(BadJoystickIndex);
  }
  std::string retVal(m_joystickDescriptor[stick].name);
  return retVal;
}
예제 #10
0
/**
 * Start the task that is responsible for sending images to the PC.
 */
int PCVideoServer::StartServerTask()
{
	if (StatusIsFatal())
	{
		return -1;
	}
	int id = 0;
	m_stopServer = false;
	// Check for prior copy of running task
	int oldId = taskNameToId((char*)m_serverTask.GetName());
	if(oldId != ERROR)
	{
		// TODO: Report error. You are in a bad state.
		taskDelete(oldId);
	}

	// spawn video server task
	// this is done to ensure that the task is spawned with the
	// floating point context save parameter.
	bool started = m_serverTask.Start((int)this);

	id = m_serverTask.GetID();

	if (!started)
	{
		wpi_setWPIError(TaskError);
		return id;
	}
	taskDelay(1);
	return id;
}
예제 #11
0
/**
 * Indicate that the packing is complete and commit the buffer to the DriverStation.
 * 
 * The packing of the dashboard packet is complete.
 * If you are not using the packed dashboard data, you can call Finalize() to commit the Printf() buffer and the error string buffer.
 * In effect, you are packing an empty structure.
 * Prepares a packet to go to the dashboard...
 * @return The total size of the data packed into the userData field of the status packet.
 */
INT32 Dashboard::Finalize()
{
	if (!m_complexTypeStack.empty())
	{
		wpi_setWPIError(MismatchedComplexTypeClose);
		return 0;
	}

	static bool reported = false;
	if (!reported)
	{
		nUsageReporting::report(nUsageReporting::kResourceType_Dashboard, 0);
		reported = true;
	}

	Synchronized sync(m_statusDataSemaphore);

	// Sequence number
	DriverStation::GetInstance()->IncrementUpdateNumber();

	// Packed Dashboard Data
	m_userStatusDataSize = m_packPtr - m_localBuffer;
	memcpy(m_userStatusData, m_localBuffer, m_userStatusDataSize);
	m_packPtr = m_localBuffer;

	return m_userStatusDataSize;
}
예제 #12
0
/**
 * Returns the types of Axes on a given joystick port
 *
 * @param stick The joystick port number and the target axis
 * @return What type of axis the axis is reporting to be
 */
int DriverStation::GetJoystickAxisType(uint32_t stick, uint8_t axis) const {
  if (stick >= kJoystickPorts) {
    wpi_setWPIError(BadJoystickIndex);
    return -1;
  }
  return m_joystickDescriptor[stick].axisTypes[axis];
}
예제 #13
0
/**
 * Returns the type of joystick at a given port
 *
 * @param stick The joystick port number
 * @return The HID type of joystick at the given port
 */
int DriverStation::GetJoystickType(uint32_t stick) const {
  if (stick >= kJoystickPorts) {
    wpi_setWPIError(BadJoystickIndex);
    return -1;
  }
  return (int)m_joystickDescriptor[stick].type;
}
예제 #14
0
/**
 * Free an allocated resource.
 * After a resource is no longer needed, for example a destructor is called for a channel assignment
 * class, Free will release the resource value so it can be reused somewhere else in the program.
 */
void Resource::Free(uint32_t index)
{
	Synchronized sync(m_allocateLock);
	if (index == ~0ul) return;
	if (index >= m_size)
	{
		wpi_setWPIError(NotAllocated);
		return;
	}
	if (!m_isAllocated[index])
	{
		wpi_setWPIError(NotAllocated);
		return;
	}
	m_isAllocated[index] = false;
}
예제 #15
0
/**
 * Convert a voltage to a raw value for a specified channel.
 * 
 * This process depends on the calibration of each channel, so the channel
 * must be specified.
 * 
 * @todo This assumes raw values.  Oversampling not supported as is.
 * 
 * @param channel The channel to convert for.
 * @param voltage The voltage to convert.
 * @return The raw value for the channel.
 */
INT32 AnalogModule::VoltsToValue(INT32 channel, float voltage)
{
	if (voltage > 10.0)
	{
		voltage = 10.0;
		wpi_setWPIError(VoltageOutOfRange);
	}
	if (voltage < -10.0)
	{
		voltage = -10.0;
		wpi_setWPIError(VoltageOutOfRange);
	}
	UINT32 LSBWeight = GetLSBWeight(channel);
	INT32 offset = GetOffset(channel);
	INT32 value = (INT32) ((voltage + offset * 1.0e-9) / (LSBWeight * 1.0e-9));
	return value;
}
예제 #16
0
/**
 * Provide tank steering using the stored robot configuration.
 * Drive the robot using two joystick inputs. The Y-axis will be selected from
 * each Joystick object.
 * @param leftStick The joystick to control the left side of the robot.
 * @param rightStick The joystick to control the right side of the robot.
 */
void RobotDrive::TankDrive(GenericHID *leftStick, GenericHID *rightStick,
                           bool squaredInputs) {
  if (leftStick == nullptr || rightStick == nullptr) {
    wpi_setWPIError(NullParameter);
    return;
  }
  TankDrive(leftStick->GetY(), rightStick->GetY(), squaredInputs);
}
예제 #17
0
/**
 * 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
 */
AnalogAccelerometer::AnalogAccelerometer(AnalogInput* channel)
    : m_analogInput(channel, NullDeleter<AnalogInput>()) {
  if (channel == nullptr) {
    wpi_setWPIError(NullParameter);
  } else {
    InitAccelerometer();
  }
}
예제 #18
0
/**
 * Convert a voltage to a raw value for a specified channel.
 * 
 * This process depends on the calibration of each channel, so the channel
 * must be specified.
 * 
 * @todo This assumes raw values.  Oversampling not supported as is.
 * 
 * @param channel The channel to convert for.
 * @param voltage The voltage to convert.
 * @return The raw value for the channel.
 */
int32_t AnalogModule::VoltsToValue(int32_t channel, float voltage)
{
	if (voltage > 10.0)
	{
		voltage = 10.0;
		wpi_setWPIError(VoltageOutOfRange);
	}
	if (voltage < -10.0)
	{
		voltage = -10.0;
		wpi_setWPIError(VoltageOutOfRange);
	}
	uint32_t LSBWeight = GetLSBWeight(channel);
	int32_t offset = GetOffset(channel);
	int32_t value = (int32_t) ((voltage + offset * 1.0e-9) / (LSBWeight * 1.0e-9));
	return value;
}
예제 #19
0
/**
 * Get the state of a POV on the joystick.
 *
 * @return the angle of the POV in degrees, or -1 if the POV is not pressed.
 */
int DriverStation::GetStickPOV(uint32_t stick, uint32_t pov) {
  if (stick >= kJoystickPorts) {
    wpi_setWPIError(BadJoystickIndex);
    return -1;
  }

  if (pov >= m_joystickPOVs[stick].count) {
    if (pov >= kMaxJoystickPOVs)
      wpi_setWPIError(BadJoystickAxis);
    else
      ReportJoystickUnpluggedWarning(
          "Joystick POV missing, check if all controllers are plugged in");
    return -1;
  }

  return m_joystickPOVs[stick].povs[pov];
}
예제 #20
0
/**
 * 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
 */
AnalogAccelerometer::AnalogAccelerometer(std::shared_ptr<AnalogInput> channel)
    : m_analogInput(channel) {
  if (channel == nullptr) {
    wpi_setWPIError(NullParameter);
  } else {
    InitAccelerometer();
  }
}
예제 #21
0
/**
 * The state of the buttons on the joystick.
 *
 * @param stick The joystick to read.
 * @return The state of the buttons on the joystick.
 */
uint32_t DriverStation::GetStickButtons(uint32_t stick) const {
  if (stick >= kJoystickPorts) {
    wpi_setWPIError(BadJoystickIndex);
    return 0;
  }

  return m_joystickButtons[stick].buttons;
}
예제 #22
0
/**
 * Set the relay state.
 *
 * Valid values depend on which directions of the relay are controlled by the
 * object.
 *
 * When set to kBothDirections, the relay can be any of the four states:
 *    0v-0v, 0v-12v, 12v-0v, 12v-12v
 *
 * When set to kForwardOnly or kReverseOnly, you can specify the constant for
 * the direction or you can simply specify kOff and kOn.  Using only kOff and
 * kOn is recommended.
 *
 * @param value The state to set the relay.
 */
void Relay::Set(Relay::Value value) {
  switch (value) {
    case kOff:
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        go_pos = false;
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        go_neg = false;
      }
      break;
    case kOn:
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        go_pos = true;
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        go_neg = true;
      }
      break;
    case kForward:
      if (m_direction == kReverseOnly) {
        wpi_setWPIError(IncompatibleMode);
        break;
      }
      if (m_direction == kBothDirections || m_direction == kForwardOnly) {
        go_pos = true;
      }
      if (m_direction == kBothDirections) {
        go_neg = false;
      }
      break;
    case kReverse:
      if (m_direction == kForwardOnly) {
        wpi_setWPIError(IncompatibleMode);
        break;
      }
      if (m_direction == kBothDirections) {
        go_pos = false;
      }
      if (m_direction == kBothDirections || m_direction == kReverseOnly) {
        go_neg = true;
      }
      break;
  }
  impl->Set((go_pos ? 1 : 0) + (go_neg ? -1 : 0));
}
예제 #23
0
/**
 * Enables or disables automatically turning the compressor on when the
 * pressure is low.
 * @param on Set to true to enable closed loop control of the compressor. False
 * to disable.
 */
void Compressor::SetClosedLoopControl(bool on) {
  int32_t status = 0;

  setClosedLoopControl(m_pcm_pointer, on, &status);

  if (status) {
    wpi_setWPIError(Timeout);
  }
}
예제 #24
0
/**
 * Clear ALL sticky faults inside PCM that Compressor is wired to.
 *
 * If a sticky fault is set, then it will be persistently cleared.  Compressor
 * drive
 * 		maybe momentarily disable while flags are being cleared. Care
 * should be
 * 		taken to not call this too frequently, otherwise normal
 * compressor
 * 		functionality may be prevented.
 *
 * If no sticky faults are set then this call will have no effect.
 */
void Compressor::ClearAllPCMStickyFaults() {
  int32_t status = 0;

  clearAllPCMStickyFaults(m_pcm_pointer, &status);

  if (status) {
    wpi_setWPIError(Timeout);
  }
}
예제 #25
0
Encoder::Encoder(std::shared_ptr<DigitalSource> aSource,
                 std::shared_ptr<DigitalSource> bSource, bool reverseDirection,
                 EncodingType encodingType)
    : m_aSource(aSource), m_bSource(bSource) {
  if (m_aSource == nullptr || m_bSource == nullptr)
    wpi_setWPIError(NullParameter);
  else
    InitEncoder(reverseDirection, encodingType);
}
예제 #26
0
/**
 * Encoder constructor.
 *
 * Construct a Encoder given a and b channels as digital inputs. This is used in
 * the case where the digital inputs are shared. The Encoder class will not
 * allocate the digital inputs and assume that they already are counted.
 *
 * The counter will start counting immediately.
 *
 * @param aSource          The source that should be used for the a channel.
 * @param bSource          the source that should be used for the b channel.
 * @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::Encoder(DigitalSource* aSource, DigitalSource* bSource,
                 bool reverseDirection, EncodingType encodingType)
    : m_aSource(aSource, NullDeleter<DigitalSource>()),
      m_bSource(bSource, NullDeleter<DigitalSource>()) {
  if (m_aSource == nullptr || m_bSource == nullptr)
    wpi_setWPIError(NullParameter);
  else
    InitEncoder(reverseDirection, encodingType);
}
예제 #27
0
/**
 * Gyro constructor with a precreated AnalogInput object.
 * Use this constructor when the analog channel needs to be shared.
 * This object will not clean up the AnalogInput object when using this
 * constructor
 * @param channel A pointer to the AnalogInput object that the gyro is
 * connected to.
 */
AnalogGyro::AnalogGyro(std::shared_ptr<AnalogInput> channel)
    : m_analog(channel) {
    if (channel == nullptr) {
        wpi_setWPIError(NullParameter);
    } else {
        InitGyro();
        Calibrate();
    }
}
예제 #28
0
파일: RobotDrive.cpp 프로젝트: 0xacf/wpilib
/*
 * Invert a motor direction.
 * This is used when a motor should run in the opposite direction as the drive
 * code would normally run it. Motors that are direct drive would be inverted, the
 * Drive code assumes that the motors are geared with one reversal.
 * @param motor The motor index to invert.
 * @param isInverted True if the motor should be inverted when operated.
 */
void RobotDrive::SetInvertedMotor(MotorType motor, bool isInverted)
{
	if (motor < 0 || motor > 3)
	{
		wpi_setWPIError(InvalidMotorIndex);
		return;
	}
	m_invertedMotors[motor] = isInverted ? -1 : 1;
}
예제 #29
0
/**
 * Returns the number of buttons on a given joystick port
 *
 * @param stick The joystick port number
 * @return The number of buttons on the indicated joystick
 */
int DriverStation::GetStickButtonCount(uint32_t stick) const {
  if (stick >= kJoystickPorts) {
    wpi_setWPIError(BadJoystickIndex);
    return 0;
  }
  HALJoystickButtons joystickButtons;
  HALGetJoystickButtons(stick, &joystickButtons);
  return joystickButtons.count;
}
예제 #30
0
/**
 * Indicate the end of a cluster packed into the dashboard data structure.
 * 
 * After packing data into the cluster, call FinalizeCluster().
 * Every call to AddCluster() must have a matching call to FinalizeCluster().
 */
void Dashboard::FinalizeCluster()
{
	if (m_complexTypeStack.top() != kCluster)
	{
		wpi_setWPIError(MismatchedComplexTypeClose);
		return;
	}
	m_complexTypeStack.pop();
	AddedElement(kOther);
}