Compare commits

...

12 Commits

Author SHA1 Message Date
Peter Johnson
8801568325 DriverStation::GetJoystickName(): Make work for stick>0.
Change-Id: I1c62742cf8b80c81d21c2198f966c8151a758a01
2016-01-15 10:45:20 -08:00
Brad Miller (WPI)
6adf4c48cd Merge "Fix HALGetJoystickDescriptor()." 2016-01-15 08:44:03 -08:00
Brad Miller (WPI)
026c427a2b Merge "Fixed Simulation C++ API" 2016-01-15 08:43:31 -08:00
Peter_Mitrano
63878d8ab7 Fixed Simulation C++ API
Fixed API in the following classes:
 - RobotDrive
 - AnalogGyro

moved some files from Athena the shared that are independant of platform
Renamed Gyro to AnalogGyro
added smart pointer constructors to RobotDrive

Change-Id: If8a1bde5aed77fd60869d1993c302dd519bc8848
2016-01-15 11:26:16 -05:00
Peter Johnson
83f902f2f6 Fix HALGetJoystickDescriptor().
This reverts the previous commit instead fixing it at the root
HALGetJoystickDescriptor function, which also fixes use of that function
by the C++ DriverStation class.

Change-Id: I1f203a015d8f10d119c61635def2822bf124754c
2016-01-14 21:49:50 -08:00
Thad House
f79ed1ab44 Artf4800: Fixes HALGetJoystick*** Segfault
The HALGetJoystick*** methods were not initializing the descriptor
variable properly. This was causing a SegFault if joysticks were moved
around while one of these methods were running.

Change-Id: If804c7ea724b10381765068e4d6fad75fad69ecb
2016-01-14 11:19:51 -08:00
Brad Miller (WPI)
bf89762e82 Merge "fix sim_ds launch script" 2016-01-13 10:19:40 -08:00
Brad Miller (WPI)
bd1e091629 Merge "Added build dir specification for sim javadoc to not overwrite athena javadoc" 2016-01-13 10:17:15 -08:00
Fredric Silberberg
2662a7ab0d Initialized the m_sensors variable to fix artf4798.
Change-Id: Iab7b76c0e36b3a8e5ab764f7dcd6772a2058bd0f
2016-01-12 16:27:34 -05:00
Fredric Silberberg
713d54fd2f Added build dir specification for sim javadoc to not overwrite athena javadoc
Change-Id: Idcc1303628134dd37c6c178b0bd66cfe2d24f928
2016-01-11 22:26:25 -05:00
Peter_Mitrano
75a07fc3e4 fix sim_ds launch script
It seems the tilde character doesn't always resolve to the home
directory

Change-Id: I69ecbab266901b271a16ce81b60a8bf7873f8a20
2016-01-08 01:31:01 -05:00
Peter Johnson
6b740e87b3 Fix C++ PIDController SetToleranceBuffer and OnTarget locking.
Also implement OnTarget fix in simulation PIDController.

Change-Id: Ic4b452759f80aa769a721f22cb6e732c2a9a213a
2016-01-07 20:55:10 -08:00
14 changed files with 129 additions and 170 deletions

View File

@@ -37,6 +37,12 @@ int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons)
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc)
{
desc->isXbox = 0;
desc->type = -1;
desc->name[0] = '\0';
desc->axisCount = 0;
desc->buttonCount = 0;
desc->povCount = 0;
return FRC_NetworkCommunication_getJoystickDesc(joystickNum, &desc->isXbox, &desc->type, (char *)(&desc->name),
&desc->axisCount, (uint8_t *)&desc->axisTypes, &desc->buttonCount, &desc->povCount);
}

View File

@@ -1 +1 @@
java -Djava.library.path=~/wpilib/simulation/lib -jar ~/wpilib/simulation/jar/SimDS-all.jar
java -Djava.library.path=${HOME}/wpilib/simulation/lib -jar ~/wpilib/simulation/jar/SimDS-all.jar

View File

@@ -159,7 +159,7 @@ std::string DriverStation::GetJoystickName(uint32_t stick) const {
if (stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
}
std::string retVal(m_joystickDescriptor[0].name);
std::string retVal(m_joystickDescriptor[stick].name);
return retVal;
}

View File

@@ -469,6 +469,7 @@ void PIDController::SetAbsoluteTolerance(float absTolerance) {
* @param bufLength Number of previous cycles to average. Defaults to 1.
*/
void PIDController::SetToleranceBuffer(unsigned bufLength) {
std::lock_guard<priority_recursive_mutex> sync(m_mutex);
m_bufLength = bufLength;
// Cut the buffer down to size if needed.
@@ -489,10 +490,9 @@ void PIDController::SetToleranceBuffer(unsigned bufLength) {
* This will return false until at least one input value has been computed.
*/
bool PIDController::OnTarget() const {
std::lock_guard<priority_recursive_mutex> sync(m_mutex);
if (m_buf.size() == 0) return false;
double error = GetAvgError();
std::lock_guard<priority_recursive_mutex> sync(m_mutex);
switch (m_toleranceType) {
case kPercentTolerance:
return fabs(error) < m_tolerance / 100 * (m_maximumInput - m_minimumInput);

View File

@@ -25,6 +25,7 @@ constexpr double Ultrasonic::kSpeedOfSoundInchesPerSec;
Task Ultrasonic::m_task;
// automatic round robin mode
std::atomic<bool> Ultrasonic::m_automaticEnabled{false};
std::set<Ultrasonic*> Ultrasonic::m_sensors;
/**
* Background task that goes through the list of ultrasonic sensors and pings

View File

@@ -7,9 +7,7 @@
#pragma once
#include "SensorBase.h"
#include "PIDSource.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "GyroBase.h"
#include "simulation/SimGyro.h"
#include <memory>
@@ -19,7 +17,7 @@ class AnalogModule;
/**
* Use a rate gyro to return the robots heading relative to a starting position.
* The Gyro class tracks the robots heading based on the starting position. As the robot
* The AnalogGyro class tracks the robots heading based on the starting position. As the robot
* rotates the new heading is computed by integrating the rate of rotation returned
* by the sensor. When the class is instantiated, it does a short calibration routine
* where it samples the gyro while at rest to determine the default offset. This is
@@ -27,7 +25,7 @@ class AnalogModule;
* with a channel that is assigned one of the Analog accumulators from the FPGA. See
* AnalogInput for the current accumulator assignments.
*/
class Gyro : public SensorBase, public PIDSource, public LiveWindowSendable
class AnalogGyro : public GyroBase
{
public:
static const uint32_t kOversampleBits;
@@ -36,25 +34,15 @@ public:
static const float kCalibrationSampleTime;
static const float kDefaultVoltsPerDegreePerSecond;
explicit Gyro(uint32_t channel);
virtual ~Gyro() = default;
virtual float GetAngle() const;
virtual double GetRate() const;
virtual void Reset();
// PIDSource interface
void SetPIDSourceType(PIDSourceType pidSource) override;
double PIDGet() override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<ITable> subTable) override;
std::shared_ptr<ITable> GetTable() const override;
explicit AnalogGyro(uint32_t channel);
virtual ~AnalogGyro() = default;
float GetAngle() const;
void Calibrate() override;
double GetRate() const;
void Reset();
private:
void InitGyro(int channel);
void InitAnalogGyro(int channel);
SimGyro* impl;

View File

@@ -9,6 +9,7 @@
#include "ErrorBase.h"
#include <stdlib.h>
#include <memory>
#include "MotorSafety.h"
#include "MotorSafetyHelper.h"
@@ -39,11 +40,17 @@ public:
uint32_t frontRightMotorChannel, uint32_t rearRightMotorChannel);
RobotDrive(SpeedController *leftMotor, SpeedController *rightMotor);
RobotDrive(SpeedController &leftMotor, SpeedController &rightMotor);
RobotDrive(std::shared_ptr<SpeedController> leftMotor,
std::shared_ptr<SpeedController> rightMotor);
RobotDrive(SpeedController *frontLeftMotor, SpeedController *rearLeftMotor,
SpeedController *frontRightMotor, SpeedController *rearRightMotor);
RobotDrive(SpeedController &frontLeftMotor, SpeedController &rearLeftMotor,
SpeedController &frontRightMotor, SpeedController &rearRightMotor);
virtual ~RobotDrive();
RobotDrive(std::shared_ptr<SpeedController> frontLeftMotor,
std::shared_ptr<SpeedController> rearLeftMotor,
std::shared_ptr<SpeedController> frontRightMotor,
std::shared_ptr<SpeedController> rearRightMotor);
virtual ~RobotDrive() = default;
RobotDrive(const RobotDrive&) = delete;
RobotDrive& operator=(const RobotDrive&) = delete;
@@ -91,10 +98,10 @@ protected:
float m_sensitivity = 0.5;
double m_maxOutput = 1.0;
bool m_deleteSpeedControllers;
SpeedController *m_frontLeftMotor = nullptr;
SpeedController *m_frontRightMotor = nullptr;
SpeedController *m_rearLeftMotor = nullptr;
SpeedController *m_rearRightMotor = nullptr;
std::shared_ptr<SpeedController> m_frontLeftMotor;
std::shared_ptr<SpeedController> m_frontRightMotor;
std::shared_ptr<SpeedController> m_rearLeftMotor;
std::shared_ptr<SpeedController> m_rearRightMotor;
// FIXME: MotorSafetyHelper *m_safetyHelper;
private:

View File

@@ -47,7 +47,7 @@
#include "Counter.h"
#include "DigitalInput.h"
#include "Encoder.h"
#include "Gyro.h"
#include "AnalogGyro.h"
#include "GenericHID.h"
#include "Joystick.h"
#include "PIDController.h"

View File

@@ -5,16 +5,16 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include "Gyro.h"
#include "AnalogGyro.h"
#include "Timer.h"
#include "WPIErrors.h"
#include "LiveWindow/LiveWindow.h"
const uint32_t Gyro::kOversampleBits = 10;
const uint32_t Gyro::kAverageBits = 0;
const float Gyro::kSamplesPerSecond = 50.0;
const float Gyro::kCalibrationSampleTime = 5.0;
const float Gyro::kDefaultVoltsPerDegreePerSecond = 0.007;
const uint32_t AnalogGyro::kOversampleBits = 10;
const uint32_t AnalogGyro::kAverageBits = 0;
const float AnalogGyro::kSamplesPerSecond = 50.0;
const float AnalogGyro::kCalibrationSampleTime = 5.0;
const float AnalogGyro::kDefaultVoltsPerDegreePerSecond = 0.007;
/**
* Initialize the gyro.
@@ -24,7 +24,7 @@ const float Gyro::kDefaultVoltsPerDegreePerSecond = 0.007;
* in progress, this is typically done when the robot is first turned on while it's sitting at
* rest before the competition starts.
*/
void Gyro::InitGyro(int channel)
void AnalogGyro::InitAnalogGyro(int channel)
{
SetPIDSourceType(PIDSourceType::kDisplacement);
@@ -32,17 +32,17 @@ void Gyro::InitGyro(int channel)
int n = sprintf(buffer, "analog/%d", channel);
impl = new SimGyro(buffer);
LiveWindow::GetInstance()->AddSensor("Gyro", channel, this);
LiveWindow::GetInstance()->AddSensor("AnalogGyro", channel, this);
}
/**
* Gyro constructor with only a channel..
* AnalogGyro constructor with only a channel..
*
* @param channel The analog channel the gyro is connected to.
*/
Gyro::Gyro(uint32_t channel)
AnalogGyro::AnalogGyro(uint32_t channel)
{
InitGyro(channel);
InitAnalogGyro(channel);
}
/**
@@ -50,11 +50,15 @@ Gyro::Gyro(uint32_t channel)
* Resets the gyro to a heading of zero. This can be used if there is significant
* drift in the gyro and it needs to be recalibrated after it has been running.
*/
void Gyro::Reset()
void AnalogGyro::Reset()
{
impl->Reset();
}
void AnalogGyro::Calibrate(){
Reset();
}
/**
* Return the actual angle in degrees that the robot is currently facing.
*
@@ -66,7 +70,7 @@ void Gyro::Reset()
* @return the current heading of the robot in degrees. This heading is based on integration
* of the returned rate from the gyro.
*/
float Gyro::GetAngle() const
float AnalogGyro::GetAngle() const
{
return impl->GetAngle();
}
@@ -79,56 +83,7 @@ float Gyro::GetAngle() const
*
* @return the current rate in degrees per second
*/
double Gyro::GetRate() const
double AnalogGyro::GetRate() const
{
return impl->GetVelocity();
}
void Gyro::SetPIDSourceType(PIDSourceType pidSource)
{
m_pidSource = pidSource;
}
/**
* Get the angle in degrees for the PIDSource base object.
*
* @return The angle in degrees.
*/
double Gyro::PIDGet()
{
switch(GetPIDSourceType()){
case PIDSourceType::kRate:
return GetRate();
case PIDSourceType::kDisplacement:
return GetAngle();
default:
return 0;
}
}
void Gyro::UpdateTable() {
if (m_table != nullptr) {
m_table->PutNumber("Value", GetAngle());
}
}
void Gyro::StartLiveWindowMode() {
}
void Gyro::StopLiveWindowMode() {
}
std::string Gyro::GetSmartDashboardType() const {
return "Gyro";
}
void Gyro::InitTable(std::shared_ptr<ITable> subTable) {
m_table = subTable;
UpdateTable();
}
std::shared_ptr<ITable> Gyro::GetTable() const {
return m_table;
}

View File

@@ -500,6 +500,7 @@ void PIDController::SetAbsoluteTolerance(float absTolerance)
* @param bufLength Number of previous cycles to average. Defaults to 1.
*/
void PIDController::SetToleranceBuffer(unsigned bufLength) {
std::lock_guard<priority_recursive_mutex> lock(m_mutex);
m_bufLength = bufLength;
// Cut the buffer down to size if needed.
@@ -518,9 +519,9 @@ void PIDController::SetToleranceBuffer(unsigned bufLength) {
*/
bool PIDController::OnTarget() const
{
double error = GetError();
std::lock_guard<priority_recursive_mutex> sync(m_mutex);
if (m_buf.size() == 0) return false;
double error = GetError();
switch (m_toleranceType) {
case kPercentTolerance:
return fabs(error) < m_tolerance / 100 * (m_maximumInput - m_minimumInput);

View File

@@ -6,11 +6,10 @@
/*----------------------------------------------------------------------------*/
#include "RobotDrive.h"
//#include "CANJaguar.h"
#include "GenericHID.h"
#include "Joystick.h"
#include "Jaguar.h"
#include "Talon.h"
#include "Utility.h"
#include "WPIErrors.h"
#include <math.h>
@@ -20,6 +19,10 @@
const int32_t RobotDrive::kMaxNumberOfMotors;
static auto make_shared_nodelete(SpeedController *ptr) {
return std::shared_ptr<SpeedController>(ptr, NullDeleter<SpeedController>());
}
/*
* Driving functions
* These functions provide an interface to multiple motors that is used for C programming
@@ -40,15 +43,16 @@ void RobotDrive::InitRobotDrive() {
/** Constructor for RobotDrive with 2 motors specified with channel numbers.
* Set up parameters for a two wheel drive system where the
* left and right motor pwm channels are specified in the call.
* This call assumes Jaguars for controlling the motors.
* This call assumes Talosn for controlling the motors.
* @param leftMotorChannel The PWM channel number that drives the left motor.
* @param rightMotorChannel The PWM channel number that drives the right motor.
*/
RobotDrive::RobotDrive(uint32_t leftMotorChannel, uint32_t rightMotorChannel)
{
InitRobotDrive();
m_rearLeftMotor = new Jaguar(leftMotorChannel);
m_rearRightMotor = new Jaguar(rightMotorChannel);
m_rearLeftMotor = std::make_shared<Talon>(leftMotorChannel);
m_rearRightMotor = std::make_shared<Talon>(rightMotorChannel);
for (int32_t i=0; i < kMaxNumberOfMotors; i++)
{
m_invertedMotors[i] = 1;
@@ -61,7 +65,7 @@ RobotDrive::RobotDrive(uint32_t leftMotorChannel, uint32_t rightMotorChannel)
* Constructor for RobotDrive with 4 motors specified with channel numbers.
* Set up parameters for a four wheel drive system where all four motor
* pwm channels are specified in the call.
* This call assumes Jaguars for controlling the motors.
* This call assumes Talons for controlling the motors.
* @param frontLeftMotor Front left motor channel number
* @param rearLeftMotor Rear Left motor channel number
* @param frontRightMotor Front right motor channel number
@@ -71,10 +75,10 @@ RobotDrive::RobotDrive(uint32_t frontLeftMotor, uint32_t rearLeftMotor,
uint32_t frontRightMotor, uint32_t rearRightMotor)
{
InitRobotDrive();
m_rearLeftMotor = new Jaguar(rearLeftMotor);
m_rearRightMotor = new Jaguar(rearRightMotor);
m_frontLeftMotor = new Jaguar(frontLeftMotor);
m_frontRightMotor = new Jaguar(frontRightMotor);
m_rearLeftMotor = std::make_shared<Talon>(rearLeftMotor);
m_rearRightMotor = std::make_shared<Talon>(rearRightMotor);
m_frontLeftMotor = std::make_shared<Talon>(frontLeftMotor);
m_frontRightMotor = std::make_shared<Talon>(frontRightMotor);
for (int32_t i=0; i < kMaxNumberOfMotors; i++)
{
m_invertedMotors[i] = 1;
@@ -91,34 +95,36 @@ RobotDrive::RobotDrive(uint32_t frontLeftMotor, uint32_t rearLeftMotor,
* @param leftMotor The left SpeedController object used to drive the robot.
* @param rightMotor the right SpeedController object used to drive the robot.
*/
RobotDrive::RobotDrive(SpeedController *leftMotor, SpeedController *rightMotor)
{
RobotDrive::RobotDrive(SpeedController *leftMotor,
SpeedController *rightMotor) {
InitRobotDrive();
if (leftMotor == nullptr || rightMotor == nullptr)
{
if (leftMotor == nullptr || rightMotor == nullptr) {
wpi_setWPIError(NullParameter);
m_rearLeftMotor = m_rearRightMotor = nullptr;
return;
}
m_rearLeftMotor = leftMotor;
m_rearRightMotor = rightMotor;
for (int32_t i=0; i < kMaxNumberOfMotors; i++)
{
m_invertedMotors[i] = 1;
}
m_deleteSpeedControllers = false;
m_rearLeftMotor = make_shared_nodelete(leftMotor);
m_rearRightMotor = make_shared_nodelete(rightMotor);
}
RobotDrive::RobotDrive(SpeedController &leftMotor, SpeedController &rightMotor)
{
//TODO: Change to rvalue references & move syntax.
RobotDrive::RobotDrive(SpeedController &leftMotor,
SpeedController &rightMotor) {
InitRobotDrive();
m_rearLeftMotor = &leftMotor;
m_rearRightMotor = &rightMotor;
for (int32_t i=0; i < kMaxNumberOfMotors; i++)
{
m_invertedMotors[i] = 1;
m_rearLeftMotor = make_shared_nodelete(&leftMotor);
m_rearRightMotor = make_shared_nodelete(&rightMotor);
}
RobotDrive::RobotDrive(std::shared_ptr<SpeedController> leftMotor,
std::shared_ptr<SpeedController> rightMotor) {
InitRobotDrive();
if (leftMotor == nullptr || rightMotor == nullptr) {
wpi_setWPIError(NullParameter);
m_rearLeftMotor = m_rearRightMotor = nullptr;
return;
}
m_deleteSpeedControllers = false;
m_rearLeftMotor = leftMotor;
m_rearRightMotor = rightMotor;
}
/**
@@ -129,12 +135,40 @@ RobotDrive::RobotDrive(SpeedController &leftMotor, SpeedController &rightMotor)
* @param rearRightMotor The back right SpeedController object used to drive the robot.
* @param frontRightMotor The front right SpeedController object used to drive the robot.
*/
RobotDrive::RobotDrive(SpeedController *frontLeftMotor, SpeedController *rearLeftMotor,
SpeedController *frontRightMotor, SpeedController *rearRightMotor)
{
RobotDrive::RobotDrive(SpeedController *frontLeftMotor,
SpeedController *rearLeftMotor,
SpeedController *frontRightMotor,
SpeedController *rearRightMotor) {
InitRobotDrive();
if (frontLeftMotor == nullptr || rearLeftMotor == nullptr || frontRightMotor == nullptr || rearRightMotor == nullptr)
{
if (frontLeftMotor == nullptr || rearLeftMotor == nullptr ||
frontRightMotor == nullptr || rearRightMotor == nullptr) {
wpi_setWPIError(NullParameter);
return;
}
m_frontLeftMotor = make_shared_nodelete(frontLeftMotor);
m_rearLeftMotor = make_shared_nodelete(rearLeftMotor);
m_frontRightMotor = make_shared_nodelete(frontRightMotor);
m_rearRightMotor = make_shared_nodelete(rearRightMotor);
}
RobotDrive::RobotDrive(SpeedController &frontLeftMotor,
SpeedController &rearLeftMotor,
SpeedController &frontRightMotor,
SpeedController &rearRightMotor) {
InitRobotDrive();
m_frontLeftMotor = make_shared_nodelete(&frontLeftMotor);
m_rearLeftMotor = make_shared_nodelete(&rearLeftMotor);
m_frontRightMotor = make_shared_nodelete(&frontRightMotor);
m_rearRightMotor = make_shared_nodelete(&rearRightMotor);
}
RobotDrive::RobotDrive(std::shared_ptr<SpeedController> frontLeftMotor,
std::shared_ptr<SpeedController> rearLeftMotor,
std::shared_ptr<SpeedController> frontRightMotor,
std::shared_ptr<SpeedController> rearRightMotor) {
InitRobotDrive();
if (frontLeftMotor == nullptr || rearLeftMotor == nullptr ||
frontRightMotor == nullptr || rearRightMotor == nullptr) {
wpi_setWPIError(NullParameter);
return;
}
@@ -142,42 +176,6 @@ RobotDrive::RobotDrive(SpeedController *frontLeftMotor, SpeedController *rearLef
m_rearLeftMotor = rearLeftMotor;
m_frontRightMotor = frontRightMotor;
m_rearRightMotor = rearRightMotor;
for (int32_t i=0; i < kMaxNumberOfMotors; i++)
{
m_invertedMotors[i] = 1;
}
m_deleteSpeedControllers = false;
}
RobotDrive::RobotDrive(SpeedController &frontLeftMotor, SpeedController &rearLeftMotor,
SpeedController &frontRightMotor, SpeedController &rearRightMotor)
{
InitRobotDrive();
m_frontLeftMotor = &frontLeftMotor;
m_rearLeftMotor = &rearLeftMotor;
m_frontRightMotor = &frontRightMotor;
m_rearRightMotor = &rearRightMotor;
for (int32_t i=0; i < kMaxNumberOfMotors; i++)
{
m_invertedMotors[i] = 1;
}
m_deleteSpeedControllers = false;
}
/**
* RobotDrive destructor.
* Deletes motor objects that were not passed in and created internally only.
**/
RobotDrive::~RobotDrive()
{
if (m_deleteSpeedControllers)
{
delete m_frontLeftMotor;
delete m_rearLeftMotor;
delete m_frontRightMotor;
delete m_rearRightMotor;
}
// FIXME: delete m_safetyHelper;
}
/**

View File

@@ -42,6 +42,7 @@ task wpilibjSimJavadoc(type: Javadoc) {
description = 'Generates javadoc for the simulation components'
group = 'WPILib'
source sourceSets.sim.allJava, sourceSets.shared.allJava
destinationDir = file("$buildDir/docs/java-simulation")
classpath = files([sourceSets.sim.compileClasspath, sourceSets.shared.compileClasspath])
}
@@ -56,12 +57,14 @@ task wpilibjSimJavadocJar(type: Jar, dependsOn: wpilibjSimJavadoc) {
publishing {
publications {
wpilibjSim(MavenPublication) {
artifact wpilibjSimJar
artifact wpilibjSimJar {
classifier = 'simulation'
}
artifact(wpilibjSimSources) {
classifier = "sources"
classifier = 'sources-simulation'
}
artifact(wpilibjSimJavadocJar) {
classifier "javadoc"
classifier 'javadoc-simulation'
}
groupId 'edu.wpi.first.wpilibj'