diff --git a/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/CANTalon/src/Robot.cpp b/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/CANTalon/src/Robot.cpp
index e175af4460..2794e7beef 100644
--- a/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/CANTalon/src/Robot.cpp
+++ b/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/CANTalon/src/Robot.cpp
@@ -1,35 +1,37 @@
#include "WPILib.h"
/**
- * This is a quick sample program to show how to use the new Talon SRX over CAN.
- * As of the time of this writing (11/20/14), the only mode supported on the SRX is the
- * straight-up throttle (status info, such as current and temperature should work).
+ * This sample shows how to use the new CANTalon to just run a motor in a basic
+ * throttle mode, in the same manner as you might control a traditional PWM
+ * controlled motor.
*
*/
class Robot : public SampleRobot {
CANTalon m_motor;
- // update every 0.005 seconds/5 milliseconds.
- double kUpdatePeriod = 0.005;
+ Joystick m_stick;
+
+ // update every 0.01 seconds/10 milliseconds.
+ // The talon only receives control packets every 10ms.
+ double kUpdatePeriod = 0.010;
public:
Robot()
- : m_motor(1) // Initialize the Talon as device 1. Use the roboRIO web
+ : m_motor(1), // Initialize the Talon as device 1. Use the roboRIO web
// interface to change the device number on the talons.
+ m_stick(0)
{}
/**
* Runs the motor from the output of a Joystick.
*/
void OperatorControl() {
- m_motor.EnableControl();
while (IsOperatorControl() && IsEnabled()) {
// Takes a number from -1.0 (full reverse) to +1.0 (full forwards).
- m_motor.Set(0.5);
+ m_motor.Set(m_stick.GetY());
- Wait(kUpdatePeriod); // Wait 5ms for the next update.
+ Wait(kUpdatePeriod); // Wait a bit so that the loop doesn't lock everything up.
}
- m_motor.Set(0.0);
}
};
diff --git a/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/CANTalonPID/src/Robot.cpp b/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/CANTalonPID/src/Robot.cpp
new file mode 100644
index 0000000000..837f392764
--- /dev/null
+++ b/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/CANTalonPID/src/Robot.cpp
@@ -0,0 +1,63 @@
+#include "WPILib.h"
+
+/**
+ * This is a quick sample program to show how to use the new Talon SRX over CAN.
+ * This particular sample demonstrates running a basic PID control loop with an
+ * analog potentiometer.
+ *
+ */
+class Robot : public SampleRobot {
+ CANTalon m_motor;
+
+public:
+ Robot()
+ : m_motor(1) // Initialize the Talon as device 1. Use the roboRIO web
+ // interface to change the device number on the m_motors.
+ {
+ // This sets the mode of the m_motor. The options are:
+ // kPercentVbus: basic throttle; no closed-loop.
+ // kCurrent: Runs the motor with the specified current if possible.
+ // kSpeed: Runs a PID control loop to keep the motor going at a constant
+ // speed using the specified sensor.
+ // kPosition: Runs a PID control loop to move the motor to a specified move
+ // the motor to a specified sensor position.
+ // kVoltage: Runs the m_motor at a constant voltage, if possible.
+ // kFollower: The m_motor will run at the same throttle as the specified other talon.
+ m_motor.SetControlMode(CANSpeedController::kPosition);
+ // This command allows you to specify which feedback device to use when doing
+ // closed-loop control. The options are:
+ // AnalogPot: Basic analog potentiometer
+ // QuadEncoder: Quadrature Encoder
+ // AnalogEncoder: Analog Encoder
+ // EncRising: Counts the rising edges of the QuadA pin (allows use of a
+ // non-quadrature encoder)
+ // EncFalling: Same as EncRising, but counts on falling edges.
+ m_motor.SetFeedbackDevice(CANTalon::AnalogPot);
+ // This sets the basic P, I , and D values (F, Izone, and rampRate can also
+ // be set, but are ignored here).
+ // These must all be positive floating point numbers (SetSensorDirection will
+ // multiply the sensor values by negative one in case your sensor is flipped
+ // relative to your motor).
+ // These values are in units of throttle / sensor_units where throttle ranges
+ // from -1023 to +1023 and sensor units are from 0 - 1023 for analog
+ // potentiometers, encoder ticks for encoders, and position / 10ms for
+ // speeds.
+ m_motor.SetPID(1.0, 0.0, 0.0);
+ }
+
+ /**
+ * Runs the motor from the output of a Joystick.
+ */
+ void OperatorControl() {
+ while (IsOperatorControl() && IsEnabled()) {
+ // In closed loop mode, this sets the goal in the units mentioned above.
+ // Since we are using an analog potentiometer, this will try to go to
+ // the middle of the potentiometer range.
+ m_motor.Set(512);
+
+ Wait(5.0);
+ }
+ }
+};
+
+START_ROBOT_CLASS(Robot);
diff --git a/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/examples.xml b/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/examples.xml
index dc2cface62..61b8c8b1b7 100644
--- a/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/examples.xml
+++ b/eclipse-plugins/edu.wpi.first.wpilib.plugins.cpp/resources/templates/examples/examples.xml
@@ -145,6 +145,23 @@
+
+ CAN Talon SRX PID
+ Quick demo of running the SRX with a PID loop.
+
+ Robot and Motor
+ Digital
+ Actuators
+ Complete List
+
+
+ src
+
+
+
+
+
+
Relay
Demonstrate controlling a Relay from Joystick buttons.
diff --git a/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/CANTalon/src/org/usfirst/frc/team190/robot/Robot.java b/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/CANTalon/src/org/usfirst/frc/team190/robot/Robot.java
index 48af9802d1..3d4dbb1145 100755
--- a/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/CANTalon/src/org/usfirst/frc/team190/robot/Robot.java
+++ b/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/CANTalon/src/org/usfirst/frc/team190/robot/Robot.java
@@ -8,31 +8,29 @@ import edu.wpi.first.wpilibj.Timer;
/**
* This is a short sample program demonstrating how to use the basic throttle
- * mode of the new CAN Talon. As of when this was made, the basic throttle mode
- * is all that is supported.
+ * mode of the new CAN Talon.
*/
public class Robot extends SampleRobot {
CANTalon motor;
- private final double k_updatePeriod = 0.005; // update every 0.005 seconds/5 milliseconds (200Hz)
-
public Robot() {
motor = new CANTalon(1); // Initialize the CanTalonSRX on device 1.
}
/**
- * Runs the motor from a joystick.
+ * Runs the motor.
*/
public void operatorControl() {
- motor.enableControl();
while (isOperatorControl() && isEnabled()) {
// Set the motor's output to half power.
// This takes a number from -1 (100% speed in reverse) to +1 (100% speed
// going forward)
motor.set(0.5);
- Timer.delay(k_updatePeriod); // wait 5ms to the next update
+ Timer.delay(0.01); // Note that the CANTalon only receives updates every
+ // 10ms, so updating more quickly would not gain you
+ // anything.
}
motor.disable();
}
diff --git a/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/CANTalonPID/src/org/usfirst/frc/team190/robot/Robot.java b/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/CANTalonPID/src/org/usfirst/frc/team190/robot/Robot.java
new file mode 100755
index 0000000000..090e1d8226
--- /dev/null
+++ b/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/CANTalonPID/src/org/usfirst/frc/team190/robot/Robot.java
@@ -0,0 +1,62 @@
+package $package;
+
+
+import edu.wpi.first.wpilibj.SpeedController;
+import edu.wpi.first.wpilibj.CANTalon;
+import edu.wpi.first.wpilibj.SampleRobot;
+import edu.wpi.first.wpilibj.Timer;
+
+/**
+ * This is a short sample program demonstrating how to use the Talon SRX over
+ * CAN to run a closed-loop PID controller with an analog potentiometer.
+ */
+public class Robot extends SampleRobot {
+
+ CANTalon motor;
+
+ public Robot() {
+ motor = new CANTalon(1); // Initialize the CanTalonSRX on device 1.
+
+ // This sets the mode of the m_motor. The options are:
+ // PercentVbus: basic throttle; no closed-loop.
+ // Current: Runs the motor with the specified current if possible.
+ // Speed: Runs a PID control loop to keep the motor going at a constant
+ // speed using the specified sensor.
+ // Position: Runs a PID control loop to move the motor to a specified move
+ // the motor to a specified sensor position.
+ // Voltage: Runs the m_motor at a constant voltage, if possible.
+ // Follower: The m_motor will run at the same throttle as the specified
+ // other talon.
+ motor.changeControlMode(CANTalon.ControlMode.Position);
+ // This command allows you to specify which feedback device to use when doing
+ // closed-loop control. The options are:
+ // AnalogPot: Basic analog potentiometer
+ // QuadEncoder: Quadrature Encoder
+ // AnalogEncoder: Analog Encoder
+ // EncRising: Counts the rising edges of the QuadA pin (allows use of a
+ // non-quadrature encoder)
+ // EncFalling: Same as EncRising, but counts on falling edges.
+ motor.setFeedbackDevice(CANTalon.FeedbackDevice.AnalogPot);
+ // This sets the basic P, I , and D values (F, Izone, and rampRate can also
+ // be set, but are ignored here).
+ // These must all be positive floating point numbers (reverseSensor will
+ // multiply the sensor values by negative one in case your sensor is flipped
+ // relative to your motor).
+ // These values are in units of throttle / sensor_units where throttle ranges
+ // from -1023 to +1023 and sensor units are from 0 - 1023 for analog
+ // potentiometers, encoder ticks for encoders, and position / 10ms for
+ // speeds.
+ motor.setPID(1.0, 0.0, 0.0);
+ }
+
+ public void operatorControl() {
+ while (isOperatorControl() && isEnabled()) {
+ // In closed loop mode, this sets the goal in the units mentioned above.
+ // Since we are using an analog potentiometer, this will try to go to
+ // the middle of the potentiometer range.
+ motor.set(512);
+
+ Timer.delay(5.0);
+ }
+ }
+}
diff --git a/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/examples.xml b/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/examples.xml
index b0bd47120b..483fa383b0 100755
--- a/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/examples.xml
+++ b/eclipse-plugins/edu.wpi.first.wpilib.plugins.java/resources/templates/examples/examples.xml
@@ -171,6 +171,23 @@
+
+ CAN Talon SRX PID
+ Demonstrate running a Talon SRX with PID Closed Loop control.
+
+ Actuators
+ Complete List
+ Robot and Motor
+
+
+ src/$package-dir
+
+
+
+
+
+
CommandBased Robot
diff --git a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/CANTalon.java b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/CANTalon.java
index 6fb46ad2b5..d67588ce0e 100644
--- a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/CANTalon.java
+++ b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/CANTalon.java
@@ -75,7 +75,8 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
}
@Override
- public void pidWrite(double output) {
+ public void pidWrite(double output)
+ {
if (getControlMode() == ControlMode.PercentVbus) {
set(output);
}
@@ -342,6 +343,12 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_controlEnabled = false;
}
+ /**
+ * Get the current proportional constant.
+ *
+ * @returns double proportional constant for current profile.
+ * @throws IllegalStateException if not in Position of Speed mode.
+ */
public double getP() {
if(!(m_controlMode.equals(ControlMode.Position) || m_controlMode.equals(ControlMode.Speed))) {
throw new IllegalStateException("PID mode only applies in Position and Speed modes.");
@@ -353,6 +360,9 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
else
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_P);
+ // Briefly wait for new values from the Talon.
+ Timer.delay(1);
+
long pp = CanTalonJNI.new_doublep();
m_impl.GetPgain(m_profile, new SWIGTYPE_p_double(pp, true));
return CanTalonJNI.doublep_value(pp);
@@ -369,6 +379,9 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
else
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_I);
+ // Briefly wait for new values from the Talon.
+ Timer.delay(1);
+
long ip = CanTalonJNI.new_doublep();
m_impl.GetIgain(m_profile, new SWIGTYPE_p_double(ip, true));
return CanTalonJNI.doublep_value(ip);
@@ -385,6 +398,9 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
else
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_D);
+ // Briefly wait for new values from the Talon.
+ Timer.delay(1);
+
long dp = CanTalonJNI.new_doublep();
m_impl.GetDgain(m_profile, new SWIGTYPE_p_double(dp, true));
return CanTalonJNI.doublep_value(dp);
@@ -401,6 +417,9 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
else
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_F);
+ // Briefly wait for new values from the Talon.
+ Timer.delay(1);
+
long fp = CanTalonJNI.new_doublep();
m_impl.GetFgain(m_profile, new SWIGTYPE_p_double(fp, true));
return CanTalonJNI.doublep_value(fp);
@@ -417,6 +436,9 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
else
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_IZone);
+ // Briefly wait for new values from the Talon.
+ Timer.delay(1);
+
long fp = CanTalonJNI.new_intp();
m_impl.GetIzone(m_profile, new SWIGTYPE_p_int(fp, true));
return CanTalonJNI.intp_value(fp);
@@ -433,34 +455,97 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
else
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_CloseLoopRampRate);
+ // Briefly wait for new values from the Talon.
+ Timer.delay(1);
+
long fp = CanTalonJNI.new_intp();
m_impl.GetCloseLoopRampRate(m_profile, new SWIGTYPE_p_int(fp, true));
return CanTalonJNI.intp_value(fp);
}
+ /**
+ * Set the proportional value of the currently selected profile.
+ *
+ * @param p Proportional constant for the currently selected PID profile.
+ * @see setProfile For selecting a certain profile.
+ */
public void setP(double p) {
m_impl.SetPgain(m_profile, p);
}
+ /**
+ * Set the integration constant of the currently selected profile.
+ *
+ * @param i Integration constant for the currently selected PID profile.
+ * @see setProfile For selecting a certain profile.
+ */
public void setI(double i) {
m_impl.SetIgain(m_profile, i);
}
+ /**
+ * Set the derivative constant of the currently selected profile.
+ *
+ * @param d Derivative constant for the currently selected PID profile.
+ * @see setProfile For selecting a certain profile.
+ */
public void setD(double d) {
m_impl.SetDgain(m_profile, d);
}
+ /**
+ * Set the feedforward value of the currently selected profile.
+ *
+ * @param f Feedforward constant for the currently selected PID profile.
+ * @see setProfile For selecting a certain profile.
+ */
public void setF(double f) {
m_impl.SetFgain(m_profile, f);
}
+ /**
+ * Set the integration zone of the current Closed Loop profile.
+ *
+ * Whenever the error is larger than the izone value, the accumulated
+ * integration error is cleared so that high errors aren't racked up when at
+ * high errors.
+ * An izone value of 0 means no difference from a standard PIDF loop.
+ *
+ * @param izone Width of the integration zone.
+ * @see setProfile For selecting a certain profile.
+ */
public void setIZone(int izone) {
m_impl.SetIzone(m_profile, izone);
}
- public void setRampRate(int rampRate) {
- m_impl.SetCloseLoopRampRate(m_profile, rampRate);
+ /**
+ * Set the closed loop ramp rate for the current profile.
+ *
+ * Limits the rate at which the throttle will change.
+ * Only affects position and speed closed loop modes.
+ *
+ * @param rampRate Maximum change in voltage, in volts / sec.
+ * @see setProfile For selecting a certain profile.
+ */
+ public void setCloseLoopRampRate(double rampRate) {
+ // CanTalonSRX takes units of Throttle (0 - 1023) / 10ms.
+ int rate = (int) (rampRate * 1023.0 / 12.0 * 100.0);
+ m_impl.SetCloseLoopRampRate(m_profile, rate);
+ }
+
+ /**
+ * Set the voltage ramp rate for the current profile.
+ *
+ * Limits the rate at which the throttle will change.
+ * Affects all modes.
+ *
+ * @param rampRate Maximum change in voltage, in volts / sec.
+ */
+ public void setVoltageRampRate(double rampRate) {
+ // CanTalonSRX takes units of Throttle (0 - 1023) / 10ms.
+ int rate = (int) (rampRate * 1023.0 / 12.0 * 100.0);
+ m_impl.SetRampThrottle(rate);
}
/**
@@ -479,7 +564,8 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* on hand in the talon. In order to switch profiles without recalling setPID,
* you must call setProfile().
*/
- public void setPID(double p, double i, double d, double f, int izone, int ramprate, int profile) {
+ public void setPID(double p, double i, double d, double f, int izone, int ramprate, int profile)
+ {
if (profile != 0 && profile != 1)
throw new IllegalArgumentException("Talon PID profile must be 0 or 1.");
m_profile = profile;
@@ -489,7 +575,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
setD(d);
setF(f);
setIZone(izone);
- setRampRate(ramprate);
+ setCloseLoopRampRate(ramprate);
}
public void setPID(double p, double i, double d) {
setPID(p, i, d, 0, 0, 0, m_profile);
@@ -499,7 +585,8 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* Select which closed loop profile to use, and uses whatever PIDF gains and
* the such that are already there.
*/
- public void setProfile(int profile) {
+ public void setProfile(int profile)
+ {
if (profile != 0 && profile != 1)
throw new IllegalArgumentException("Talon PID profile must be 0 or 1.");
m_profile = profile;