mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-05 03:21:42 +00:00
Compare commits
71 Commits
jenkins-re
...
jenkins-re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff2ea1287d | ||
|
|
b41690b387 | ||
|
|
ce8e65d41e | ||
|
|
66622b43e7 | ||
|
|
568b842c73 | ||
|
|
4d142cdafa | ||
|
|
2ae8f40a58 | ||
|
|
4833316571 | ||
|
|
16f9db30a9 | ||
|
|
e092742f40 | ||
|
|
4f6fa2482b | ||
|
|
52408e2658 | ||
|
|
d986ffac81 | ||
|
|
bc3c5447e7 | ||
|
|
b125e6b40a | ||
|
|
88a043bda4 | ||
|
|
c57d01af94 | ||
|
|
6abde412c1 | ||
|
|
5e6cd0bf9e | ||
|
|
ec03c3068d | ||
|
|
45f3b76103 | ||
|
|
dac04cb4a2 | ||
|
|
7d026be264 | ||
|
|
5893d28f39 | ||
|
|
cd01945908 | ||
|
|
ea610eb302 | ||
|
|
d04476bb2f | ||
|
|
2bb0a32c15 | ||
|
|
cdbe80315f | ||
|
|
517e708fd8 | ||
|
|
70825be690 | ||
|
|
43532198c7 | ||
|
|
4da9ebe1fd | ||
|
|
9479793e1d | ||
|
|
20e9f499b0 | ||
|
|
3d897cef58 | ||
|
|
fa229f2b13 | ||
|
|
b1056cf6d7 | ||
|
|
8e707169a1 | ||
|
|
47961c8b13 | ||
|
|
b59f4141c4 | ||
|
|
d62d82b28b | ||
|
|
a9d30c0389 | ||
|
|
6e0c84d942 | ||
|
|
bb8ea17acf | ||
|
|
c683e24aa9 | ||
|
|
7b371f6d7c | ||
|
|
f6de7bc961 | ||
|
|
c00d9f1523 | ||
|
|
6ec2d262c8 | ||
|
|
3c8b31608c | ||
|
|
29f36b0eac | ||
|
|
486885e8bf | ||
|
|
020d97580a | ||
|
|
28a41e4ac2 | ||
|
|
f590cda8f9 | ||
|
|
c98f54dbbc | ||
|
|
81840b2c49 | ||
|
|
78ccb48fd3 | ||
|
|
b9913d3e12 | ||
|
|
56430ccd7c | ||
|
|
d412584f16 | ||
|
|
364a3afad4 | ||
|
|
97456f40f7 | ||
|
|
7e5ed03d28 | ||
|
|
14a1e6ae8e | ||
|
|
529f5b773f | ||
|
|
91c70daf5b | ||
|
|
e86312cd6f | ||
|
|
d7a9794080 | ||
|
|
6234fe06f5 |
@@ -92,6 +92,13 @@
|
||||
<outputDirectory>${tools-zip}</outputDirectory>
|
||||
<destFileName>OutlineViewer.jar</destFileName>
|
||||
</artifactItem>
|
||||
<artifactItem>
|
||||
<groupId>edu.wpi.first.wpilib</groupId>
|
||||
<artifactId>java-installer</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<outputDirectory>${tools-zip}</outputDirectory>
|
||||
<destFileName>java-installer.jar</destFileName>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
|
||||
<overWriteReleases>false</overWriteReleases>
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package edu.wpi.first.wpilib.plugins.core.actions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.ui.IWorkbenchWindow;
|
||||
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
|
||||
|
||||
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
|
||||
|
||||
/**
|
||||
* Our sample action implements workbench action delegate.
|
||||
* The action proxy will be created by the workbench and
|
||||
* shown in the UI. When the user tries to use the action,
|
||||
* this delegate will be created and execution will be
|
||||
* delegated to it.
|
||||
* @see IWorkbenchWindowActionDelegate
|
||||
*/
|
||||
public class RunSimulationSmartDashboardAction implements IWorkbenchWindowActionDelegate {
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public RunSimulationSmartDashboardAction() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The action has been activated. The argument of the
|
||||
* method represents the 'real' action sitting
|
||||
* in the workbench UI.
|
||||
* @see IWorkbenchWindowActionDelegate#run
|
||||
*/
|
||||
public void run(IAction action) {
|
||||
File dir = new File(WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"tools");
|
||||
File[] files = dir.listFiles(new FilenameFilter() {
|
||||
@Override public boolean accept(File dir, String name) {
|
||||
return name.startsWith("SmartDashboard") && name.endsWith(".jar");
|
||||
}
|
||||
});
|
||||
if (files == null || files.length < 1) return;
|
||||
String[] cmd = {"java", "-jar", files[0].getAbsolutePath(), "-ip", "localhost"};
|
||||
try {
|
||||
DebugPlugin.exec(cmd, new File(System.getProperty("user.home")));
|
||||
} catch (CoreException e) {
|
||||
WPILibCore.logError("Error running SmartDashboard.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selection in the workbench has been changed. We
|
||||
* can change the state of the 'real' action here
|
||||
* if we want, but this can only happen after
|
||||
* the delegate has been created.
|
||||
* @see IWorkbenchWindowActionDelegate#selectionChanged
|
||||
*/
|
||||
public void selectionChanged(IAction action, ISelection selection) {
|
||||
}
|
||||
|
||||
/**
|
||||
* We can use this method to dispose of any system
|
||||
* resources we previously allocated.
|
||||
* @see IWorkbenchWindowActionDelegate#dispose
|
||||
*/
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
/**
|
||||
* We will cache window object in order to
|
||||
* be able to provide parent shell for the message dialog.
|
||||
* @see IWorkbenchWindowActionDelegate#init
|
||||
*/
|
||||
public void init(IWorkbenchWindow window) {
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,6 @@ import java.io.OutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
@@ -17,6 +15,7 @@ import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.jface.dialogs.MessageDialog;
|
||||
|
||||
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
|
||||
|
||||
@@ -117,7 +116,7 @@ public abstract class AbstractInstaller {
|
||||
protected void install() throws InstallException {
|
||||
if(installLocation.exists()) {
|
||||
if(!removeFileHandler(installLocation, true)) {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
MessageDialog.openError(null, "Error",
|
||||
String.format("Could not update the old wpilib folder.%n"
|
||||
+ "Please close any WPILib tools and restart Eclipse."));
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@ import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.jface.dialogs.MessageDialog;
|
||||
|
||||
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
|
||||
|
||||
@@ -21,8 +20,8 @@ public class SimulationNotification {
|
||||
|
||||
public static void showUnsupported() {
|
||||
String title = "Simulation Unsupported";
|
||||
String message = SIMULATION_UNSUPPORTED_MSG;
|
||||
JOptionPane.showMessageDialog(null, message, title, JOptionPane.OK_OPTION);
|
||||
String message = SIMULATION_UNSUPPORTED_MSG;
|
||||
MessageDialog.openError(null, title, message);
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI(URL));
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Arrays;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
@@ -48,4 +49,8 @@ public class ProjectComboField {
|
||||
combo.addModifyListener(modifyListener);
|
||||
}
|
||||
|
||||
public void addSelectionListener(SelectionListener selectionListener) {
|
||||
combo.addSelectionListener(selectionListener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
<listOptionValue builtIn="false" value="${WPILIB}/cpp/current/sim/include"/>
|
||||
<listOptionValue builtIn="false" value="/usr/include"/>
|
||||
<listOptionValue builtIn="false" value="/usr/include/gazebo-3.1"/>
|
||||
<listOptionValue builtIn="false" value="/usr/include/sdformat-2.0"/>
|
||||
<listOptionValue builtIn="false" value="/usr/include/sdformat-2.2"/>
|
||||
</option>
|
||||
<option id="gnu.cpp.compiler.option.optimization.level.1648211502" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.option.debugging.level.937474733" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
|
||||
@@ -23,7 +23,8 @@ private:
|
||||
|
||||
void AutonomousInit()
|
||||
{
|
||||
autonomousCommand->Start();
|
||||
if (autonomousCommand != NULL)
|
||||
autonomousCommand->Start();
|
||||
}
|
||||
|
||||
void AutonomousPeriodic()
|
||||
@@ -37,7 +38,8 @@ private:
|
||||
// teleop starts running. If you want the autonomous to
|
||||
// continue until interrupted by another command, remove
|
||||
// this line or comment it out.
|
||||
autonomousCommand->Cancel();
|
||||
if (autonomousCommand != NULL)
|
||||
autonomousCommand->Cancel();
|
||||
}
|
||||
|
||||
void TeleopPeriodic()
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "WPILib.h"
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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
|
||||
// interface to change the device number on the talons.
|
||||
m_stick(0)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Runs the motor from the output of a Joystick.
|
||||
*/
|
||||
void OperatorControl() {
|
||||
while (IsOperatorControl() && IsEnabled()) {
|
||||
// Takes a number from -1.0 (full reverse) to +1.0 (full forwards).
|
||||
m_motor.Set(m_stick.GetY());
|
||||
|
||||
Wait(kUpdatePeriod); // Wait a bit so that the loop doesn't lock everything up.
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
START_ROBOT_CLASS(Robot);
|
||||
@@ -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);
|
||||
@@ -128,6 +128,40 @@
|
||||
</files>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<name>CAN Talon SRX</name>
|
||||
<description>Quick demo of running the SRX at a given throttle value.</description>
|
||||
<tags>
|
||||
<tag>Robot and Motor</tag>
|
||||
<tag>Digital</tag>
|
||||
<tag>Actuators</tag>
|
||||
<tag>Complete List</tag>
|
||||
</tags>
|
||||
<packages>
|
||||
<package>src</package>
|
||||
</packages>
|
||||
<files>
|
||||
<file source="examples/CANTalon/src/Robot.cpp" destination="src/Robot.cpp"></file>
|
||||
</files>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<name>CAN Talon SRX PID</name>
|
||||
<description>Quick demo of running the SRX with a PID loop.</description>
|
||||
<tags>
|
||||
<tag>Robot and Motor</tag>
|
||||
<tag>Digital</tag>
|
||||
<tag>Actuators</tag>
|
||||
<tag>Complete List</tag>
|
||||
</tags>
|
||||
<packages>
|
||||
<package>src</package>
|
||||
</packages>
|
||||
<files>
|
||||
<file source="examples/CANTalonPID/src/Robot.cpp" destination="src/Robot.cpp"></file>
|
||||
</files>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<name>Relay</name>
|
||||
<description>Demonstrate controlling a Relay from Joystick buttons.</description>
|
||||
@@ -264,7 +298,7 @@
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<name>Getting Started</name>
|
||||
<name>Intermediate vision</name>
|
||||
<description>An example program that acquires images from an attached USB camera and adds some
|
||||
annotation to the image as you might do for showing operators the result of some image
|
||||
recognition, and sends it to the dashboard for display.
|
||||
|
||||
@@ -43,8 +43,8 @@ public class RSEUtils {
|
||||
RSECorePlugin.getTheCoreRegistry().getSystemTypeById("org.eclipse.rse.systemtype.ssh");
|
||||
host = registry.createHost(profile.getName(), systemType, connectionName, hostName,
|
||||
"The remote target for debugging the robot for team "+teamNumber+".");
|
||||
host.setDefaultUserId("admin");
|
||||
SystemSignonInformation info = new SystemSignonInformation(hostName, "admin",
|
||||
host.setDefaultUserId("lvuser");
|
||||
SystemSignonInformation info = new SystemSignonInformation(hostName, "lvuser",
|
||||
"", systemType);
|
||||
PasswordPersistenceManager.getInstance().add(info, true, false);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Deployment information
|
||||
username=admin
|
||||
username=lvuser
|
||||
password=
|
||||
deploy.dir=/home/lvuser
|
||||
deploy.kill.command=/usr/local/frc/bin/frcKillRobot.sh -t -r
|
||||
@@ -8,7 +8,7 @@ command.dir=/home/lvuser/
|
||||
# Libraries to use
|
||||
wpilib=${user.home}/wpilib/cpp/${cpp-version}
|
||||
wpilib.lib=${wpilib}/lib
|
||||
roboRIOAllowedImages=18
|
||||
roboRIOAllowedImages=20
|
||||
|
||||
# Ant support
|
||||
wpilib.ant.dir=${wpilib}/ant
|
||||
|
||||
@@ -19,21 +19,37 @@
|
||||
<!-- Targets -->
|
||||
|
||||
<target name="get-target-ip">
|
||||
<property name="ant.enable.asserts" value="true"/>
|
||||
<property name="target" value="roboRIO-${team-number}.local" />
|
||||
<echo>Trying Target: ${target}</echo>
|
||||
<if>
|
||||
<isreachable host="${target}"/>
|
||||
<isreachable host="${target}" timeout="5"/>
|
||||
<then>
|
||||
<echo>roboRIO found via mDNS</echo>
|
||||
</then>
|
||||
<else>
|
||||
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
|
||||
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
|
||||
<property name="target" value="10.${ip-upper}.${ip.lower}.2"/>
|
||||
<echo>roboRIO not found via mDNS, falling back to static address of ${target}</echo>
|
||||
<assert name="roboRIOFound" message="roboRIO not found, please check that the roboRIO is connected, imaged and that the team number is set properly in Eclipse">
|
||||
<isreachable host="${target}"/>
|
||||
</assert>
|
||||
<var name="target" unset="true"/>
|
||||
<echo> roboRIO not found via mDNS, falling back to static USB</echo>
|
||||
<property name="target" value="172.22.11.2"/>
|
||||
<if>
|
||||
<isreachable host="${target}" timeout="5"/>
|
||||
<then>
|
||||
<echo>roboRIO found via static USB</echo>
|
||||
</then>
|
||||
<else>
|
||||
<var name="target" unset="true"/>
|
||||
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
|
||||
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
|
||||
<property name="target" value="10.${ip.upper}.${ip.lower}.2"/>
|
||||
<echo>roboRIO not found via USB, falling back to static address of ${target}</echo>
|
||||
<assert name="roboRIOFound" message="roboRIO not found, please check that the roboRIO is connected, imaged and that the team number is set properly in Eclipse">
|
||||
<bool>
|
||||
<isreachable host="${target}" timeout="5"/>
|
||||
</bool>
|
||||
</assert>
|
||||
<echo>roboRIO found via Ethernet static</echo>
|
||||
</else>
|
||||
</if>
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
@@ -93,7 +109,7 @@
|
||||
|
||||
<target name="dependencies" depends="get-target-ip">
|
||||
<property name="ant.enable.asserts" value="true"/>
|
||||
<post to="http://${target}/nisysapi/server" logfile="sysProps.xml" verbose="false" encoding="UTF-16LE">
|
||||
<post to="http://${target}/nisysapi/server" logfile="sysProps.xml" verbose="false" encoding="UTF-16LE" append="false">
|
||||
<prop name="Function" value="GetPropertiesOfItem"/>
|
||||
<prop name="Plugins" value="nisyscfg"/>
|
||||
<prop name="Items" value="system"/>
|
||||
@@ -105,5 +121,6 @@
|
||||
<contains string="${roboRIOAllowedImages}" substring="${roboRIOImage}"/>
|
||||
</bool>
|
||||
</assert>
|
||||
<echo>roboRIO image version validated</echo>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
@@ -38,7 +38,7 @@ public class Robot extends IterativeRobot {
|
||||
|
||||
public void autonomousInit() {
|
||||
// schedule the autonomous command (example)
|
||||
autonomousCommand.start();
|
||||
if (autonomousCommand != null) autonomousCommand.start();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +53,15 @@ public class Robot extends IterativeRobot {
|
||||
// teleop starts running. If you want the autonomous to
|
||||
// continue until interrupted by another command, remove
|
||||
// this line or comment it out.
|
||||
autonomousCommand.cancel();
|
||||
if (autonomousCommand != null) autonomousCommand.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the disabled button is hit.
|
||||
* You can use it to reset subsystems before shutting down.
|
||||
*/
|
||||
public void disabledInit(){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
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 basic throttle
|
||||
* mode of the new CAN Talon.
|
||||
*/
|
||||
public class Robot extends SampleRobot {
|
||||
|
||||
CANTalon motor;
|
||||
|
||||
public Robot() {
|
||||
motor = new CANTalon(1); // Initialize the CanTalonSRX on device 1.
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the motor.
|
||||
*/
|
||||
public void operatorControl() {
|
||||
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(0.01); // Note that the CANTalon only receives updates every
|
||||
// 10ms, so updating more quickly would not gain you
|
||||
// anything.
|
||||
}
|
||||
motor.disable();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,6 +154,40 @@
|
||||
</files>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<name>CAN Talon SRX</name>
|
||||
<description>Demonstrate running a Talon SRX with the basic throttle mode.</description>
|
||||
<tags>
|
||||
<tag>Actuators</tag>
|
||||
<tag>Complete List</tag>
|
||||
<tag>Robot and Motor</tag>
|
||||
</tags>
|
||||
<packages>
|
||||
<package>src/$package-dir</package>
|
||||
</packages>
|
||||
<files>
|
||||
<file source="examples/CANTalon/src/org/usfirst/frc/team190/robot/Robot.java"
|
||||
destination="src/$package-dir/Robot.java"></file>
|
||||
</files>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<name>CAN Talon SRX PID</name>
|
||||
<description>Demonstrate running a Talon SRX with PID Closed Loop control.</description>
|
||||
<tags>
|
||||
<tag>Actuators</tag>
|
||||
<tag>Complete List</tag>
|
||||
<tag>Robot and Motor</tag>
|
||||
</tags>
|
||||
<packages>
|
||||
<package>src/$package-dir</package>
|
||||
</packages>
|
||||
<files>
|
||||
<file source="examples/CANTalonPID/src/org/usfirst/frc/team190/robot/Robot.java"
|
||||
destination="src/$package-dir/Robot.java"></file>
|
||||
</files>
|
||||
</example>
|
||||
|
||||
|
||||
<tagDescription>
|
||||
<name>CommandBased Robot</name>
|
||||
|
||||
@@ -2,6 +2,7 @@ package edu.wpi.first.wpilib.plugins.java.launching;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
@@ -15,8 +16,6 @@ import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationType;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.debug.core.ILaunchManager;
|
||||
import org.eclipse.debug.core.IStreamListener;
|
||||
import org.eclipse.debug.core.model.IStreamMonitor;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.debug.ui.ILaunchShortcut;
|
||||
import org.eclipse.jdt.core.IJavaElement;
|
||||
@@ -37,13 +36,13 @@ import edu.wpi.first.wpilib.plugins.java.WPILibJavaPlugin;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public abstract class JavaLaunchShortcut implements ILaunchShortcut {
|
||||
private static final int DEBUG_ATTACH_ATTEMPTS = 20;
|
||||
private static final int DEBUG_ATTACH_RETRY_DELAY_SEC = 2;
|
||||
|
||||
//Class constants - used to delineate types for launch shortcuts
|
||||
public static final String DEPLOY_TYPE = "edu.wpi.first.wpilib.plugins.core.deploy";
|
||||
private static final String ANT_SERVER_THREAD_NAME = "Ant Build Server Connection";
|
||||
|
||||
// NOTE: This string must be changed if the port is changed.
|
||||
private static final String DEBUG_START_TEXT = "Listening for transport dt_socket at address: 8348";
|
||||
|
||||
private static ILaunch lastDeploy = null;
|
||||
|
||||
/**
|
||||
@@ -155,11 +154,9 @@ public abstract class JavaLaunchShortcut implements ILaunchShortcut {
|
||||
lastDeploy = AntLauncher.runAntFile(new File (activeProj.getLocation().toOSString() + File.separator + "build.xml"), targets, null, mode);
|
||||
|
||||
if((mode.equals(ILaunchManager.DEBUG_MODE))&&(getLaunchType().equals(DEPLOY_TYPE))) {
|
||||
ILaunchConfigurationWorkingCopy config;
|
||||
try {
|
||||
config = getRemoteDebugConfig(activeProj);
|
||||
startDebugConfig(config, lastDeploy);
|
||||
} catch (CoreException e) {
|
||||
startDebugConfig(getRemoteDebugConfig(activeProj));
|
||||
} catch (CoreException | InterruptedException e) {
|
||||
WPILibJavaPlugin.logError("Debug attach failed", e);
|
||||
}
|
||||
}
|
||||
@@ -190,20 +187,28 @@ public abstract class JavaLaunchShortcut implements ILaunchShortcut {
|
||||
return WPILibCore.getDefault().getTargetIP(proj);
|
||||
}
|
||||
|
||||
private void startDebugConfig(final ILaunchConfigurationWorkingCopy config, ILaunch deploy) throws CoreException {
|
||||
IStreamListener listener = new IStreamListener() {
|
||||
@Override
|
||||
public void streamAppended(String text, IStreamMonitor monitor) {
|
||||
if (text.contains(DEBUG_START_TEXT)) {
|
||||
try {
|
||||
config.launch(ILaunchManager.DEBUG_MODE, null);
|
||||
} catch (CoreException e) {
|
||||
WPILibJavaPlugin.logError("Error starting debug config..", e);
|
||||
}
|
||||
monitor.removeListener(this);
|
||||
private void startDebugConfig(final ILaunchConfigurationWorkingCopy config)
|
||||
throws CoreException, InterruptedException {
|
||||
int remainingAttempts = DEBUG_ATTACH_ATTEMPTS;
|
||||
|
||||
// Retry until success or rethrow of exception on failure
|
||||
while (true) {
|
||||
try {
|
||||
WPILibJavaPlugin.logInfo("Attemping to attach debugger...");
|
||||
config.launch(ILaunchManager.DEBUG_MODE, null);
|
||||
WPILibJavaPlugin.logInfo("Debugger attached.");
|
||||
break;
|
||||
} catch (CoreException e) {
|
||||
if (--remainingAttempts > 0) {
|
||||
String errorMsg = MessageFormat.format("Unable to attach debugger. "
|
||||
+ "{0} attempts remain - waiting {1} second(s) before retrying...",
|
||||
remainingAttempts, DEBUG_ATTACH_RETRY_DELAY_SEC);
|
||||
WPILibJavaPlugin.logError(errorMsg, null);
|
||||
Thread.sleep(DEBUG_ATTACH_RETRY_DELAY_SEC * 1000);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
deploy.getProcesses()[0].getStreamsProxy().getOutputStreamMonitor().addListener(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.wizard.WizardPage;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
@@ -76,6 +78,15 @@ public class FileTemplateWizardMainPage extends WizardPage {
|
||||
});
|
||||
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
projectsCombo.setLayoutData(gd);
|
||||
projectsCombo.addSelectionListener(new SelectionListener() {
|
||||
public void widgetSelected(SelectionEvent e){
|
||||
if (project == null){
|
||||
project = projectsCombo.getProject();
|
||||
}
|
||||
packageText.setText(getDefaultPackage());
|
||||
}
|
||||
public void widgetDefaultSelected(SelectionEvent e){}
|
||||
});
|
||||
projectsCombo.addModifyListener(new ModifyListener() {
|
||||
public void modifyText(ModifyEvent e) {
|
||||
dialogChanged();
|
||||
@@ -116,6 +127,7 @@ public class FileTemplateWizardMainPage extends WizardPage {
|
||||
*/
|
||||
|
||||
private void initialize() {
|
||||
WPILibJavaPlugin.logInfo("initialize");
|
||||
projectsCombo.setProject(project);
|
||||
packageText.setText(getDefaultPackage());
|
||||
}
|
||||
@@ -130,7 +142,7 @@ public class FileTemplateWizardMainPage extends WizardPage {
|
||||
|
||||
// Update the default package if necessary
|
||||
if (project == null || !project.equals(projectsCombo.getProject())) {
|
||||
String oldDefault = getDefaultPackage();
|
||||
String oldDefault = getDefaultPackage();
|
||||
project = projectsCombo.getProject();
|
||||
if (packageString.equals(oldDefault)) {
|
||||
packageText.setText(getDefaultPackage());
|
||||
@@ -200,4 +212,4 @@ public class FileTemplateWizardMainPage extends WizardPage {
|
||||
if (defaultPackage != null) return defaultPackage;
|
||||
else return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
# Deployment information
|
||||
username=admin
|
||||
username=lvuser
|
||||
password=
|
||||
deploy.dir=/home/lvuser
|
||||
deploy.kill.command=. /etc/profile.d/natinst-path.sh; /usr/local/frc/bin/frcKillRobot.sh -t -r
|
||||
@@ -20,7 +20,7 @@ networktables.sources=${wpilib.lib}/NetworkTables-sources.jar
|
||||
#jnaerator.jar=${wpilib.lib}/jnaerator-runtime.jar
|
||||
#classpath=${wpilib.jar}:${networktables.jar}:${jna.jar}:${jnaerator.jar}
|
||||
classpath=${wpilib.jar}:${networktables.jar}
|
||||
roboRIOAllowedImages=18
|
||||
roboRIOAllowedImages=20
|
||||
|
||||
# Ant support
|
||||
wpilib.ant.dir=${wpilib}/ant
|
||||
|
||||
@@ -19,21 +19,37 @@
|
||||
<!-- Targets -->
|
||||
|
||||
<target name="get-target-ip">
|
||||
<property name="ant.enable.asserts" value="true"/>
|
||||
<property name="target" value="roboRIO-${team-number}.local" />
|
||||
<echo>Trying Target: ${target}</echo>
|
||||
<if>
|
||||
<isreachable host="${target}"/>
|
||||
<isreachable host="${target}" timeout="5"/>
|
||||
<then>
|
||||
<echo>roboRIO found via mDNS</echo>
|
||||
</then>
|
||||
<else>
|
||||
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
|
||||
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
|
||||
<property name="target" value="10.${ip-upper}.${ip.lower}.2"/>
|
||||
<echo>roboRIO not found via mDNS, falling back to static address of ${target}</echo>
|
||||
<assert name="roboRIOFound" message="roboRIO not found, please check that the roboRIO is connected, imaged and that the team number is set properly in Eclipse">
|
||||
<isreachable host="${target}"/>
|
||||
</assert>
|
||||
<var name="target" unset="true"/>
|
||||
<echo> roboRIO not found via mDNS, falling back to static USB</echo>
|
||||
<property name="target" value="172.22.11.2"/>
|
||||
<if>
|
||||
<isreachable host="${target}" timeout="5"/>
|
||||
<then>
|
||||
<echo>roboRIO found via static USB</echo>
|
||||
</then>
|
||||
<else>
|
||||
<var name="target" unset="true"/>
|
||||
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
|
||||
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
|
||||
<property name="target" value="10.${ip.upper}.${ip.lower}.2"/>
|
||||
<echo>roboRIO not found via USB, falling back to static address of ${target}</echo>
|
||||
<assert name="roboRIOFound" message="roboRIO not found, please check that the roboRIO is connected, imaged and that the team number is set properly in Eclipse">
|
||||
<bool>
|
||||
<isreachable host="${target}" timeout="5"/>
|
||||
</bool>
|
||||
</assert>
|
||||
<echo>roboRIO found via Ethernet static</echo>
|
||||
</else>
|
||||
</if>
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
@@ -192,7 +208,7 @@
|
||||
|
||||
<target name="dependencies" depends="get-target-ip">
|
||||
<property name="ant.enable.asserts" value="true"/>
|
||||
<post to="http://${target}/nisysapi/server" logfile="sysProps.xml" verbose="false" encoding="UTF-16LE">
|
||||
<post to="http://${target}/nisysapi/server" logfile="sysProps.xml" verbose="false" encoding="UTF-16LE" append="false">
|
||||
<prop name="Function" value="GetPropertiesOfItem"/>
|
||||
<prop name="Plugins" value="nisyscfg"/>
|
||||
<prop name="Items" value="system"/>
|
||||
@@ -204,6 +220,7 @@
|
||||
<contains string="${roboRIOAllowedImages}" substring="${roboRIOImage}"/>
|
||||
</bool>
|
||||
</assert>
|
||||
<echo>roboRIO image version validated</echo>
|
||||
<echo>Checking for JRE. If this fails install the JRE using these instructions: http://wpilib.screenstepslive.com/s/4485/m/13809/l/243933-installing-java-8-on-the-roborio-java-only</echo>
|
||||
<sshexec host="${target}"
|
||||
username="${username}"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/usr/local/frc/JRE/bin/java -jar /home/lvuser/FRCUserProgram.jar
|
||||
/usr/local/frc/bin/netconsole-host /usr/local/frc/JRE/bin/java -jar /home/lvuser/FRCUserProgram.jar
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/usr/local/frc/JRE/bin/java -XX:+UsePerfData -agentlib:jdwp=transport=dt_socket,address=8348,server=y,suspend=y -jar /home/lvuser/FRCUserProgram.jar
|
||||
/usr/local/frc/bin/netconsole-host /usr/local/frc/JRE/bin/java -XX:+UsePerfData -agentlib:jdwp=transport=dt_socket,address=8348,server=y,suspend=y -jar /home/lvuser/FRCUserProgram.jar
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "Accelerometer.hpp"
|
||||
#include "Analog.hpp"
|
||||
#include "CAN.hpp"
|
||||
#include "Compressor.hpp"
|
||||
#include "Digital.hpp"
|
||||
#include "Solenoid.hpp"
|
||||
@@ -178,7 +177,20 @@ struct HALJoystickPOVs {
|
||||
int16_t povs[kMaxJoystickPOVs];
|
||||
};
|
||||
|
||||
typedef uint32_t HALJoystickButtons;
|
||||
struct HALJoystickButtons {
|
||||
uint32_t buttons;
|
||||
uint8_t count;
|
||||
};
|
||||
|
||||
struct HALJoystickDescriptor {
|
||||
uint8_t isXbox;
|
||||
uint8_t type;
|
||||
char name[256];
|
||||
uint8_t axisCount;
|
||||
uint8_t axisTypes;
|
||||
uint8_t buttonCount;
|
||||
uint8_t povCount;
|
||||
};
|
||||
|
||||
inline float intToFloat(int value)
|
||||
{
|
||||
@@ -213,7 +225,10 @@ extern "C"
|
||||
int HALGetAllianceStation(enum HALAllianceStationID *allianceStation);
|
||||
int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes *axes);
|
||||
int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs);
|
||||
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons, uint8_t *count);
|
||||
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons);
|
||||
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc);
|
||||
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble);
|
||||
int HALGetMatchTime(float *matchTime);
|
||||
|
||||
void HALSetNewDataSem(pthread_cond_t *);
|
||||
|
||||
|
||||
@@ -11,4 +11,9 @@ extern "C"
|
||||
double getPDPTemperature(int32_t *status);
|
||||
double getPDPVoltage(int32_t *status);
|
||||
double getPDPChannelCurrent(uint8_t channel, int32_t *status);
|
||||
double getPDPTotalCurrent(int32_t *status);
|
||||
double getPDPTotalPower(int32_t *status);
|
||||
double getPDPTotalEnergy(int32_t *status);
|
||||
void resetPDPTotalEnergy(int32_t *status);
|
||||
void clearPDPStickyFaults(int32_t *status);
|
||||
}
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
#include "HAL/CAN.hpp"
|
||||
#include <map>
|
||||
|
||||
struct CANMessage
|
||||
{
|
||||
uint8_t data[8];
|
||||
};
|
||||
|
||||
static std::map<uint32_t, CANMessage> outgoingMessages;
|
||||
static std::map<uint32_t, CANMessage> incomingMessages;
|
||||
|
||||
static const uint32_t kFullMessageIDMask = 0x1fffffff;
|
||||
|
||||
/**
|
||||
* Gets the data from the outgoing hashmap and calls
|
||||
* CANSessionMux...sendMessage.
|
||||
*/
|
||||
void canTxSend(uint32_t arbID, uint8_t length, int32_t period)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
int32_t status;
|
||||
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(
|
||||
arbID, message.data, length, period, &status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time an single byte field changes in a message.data,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackInt8(uint32_t arbID, uint8_t offset, uint8_t value)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
message.data[offset] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time a short integer field changes in a message.data,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
*(uint16_t *)(message.data + offset) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time a long integer field changes in a message.data,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
*(uint32_t *)(message.data + offset) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time an 8.8 fixed point field changes in a message,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value)
|
||||
{
|
||||
int16_t raw = value * 255.0;
|
||||
|
||||
canTxPackInt16(arbID, offset, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time a 16.16 fixed point field changes in a message,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value)
|
||||
{
|
||||
int32_t raw = value * 65535.0;
|
||||
|
||||
canTxPackInt32(arbID, offset, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
uint8_t canTxUnpackInt8(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
return message.data[offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
return *reinterpret_cast<uint16_t *>(message.data + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
return *reinterpret_cast<uint32_t *>(message.data + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
double canTxUnpackFXP16(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
int16_t raw = canTxUnpackInt16(arbID, offset);
|
||||
|
||||
return raw / 255.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
double canTxUnpackFXP32(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
int32_t raw = canTxUnpackInt32(arbID, offset);
|
||||
|
||||
return raw / 65535.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data from CANSessionMux (if it's available) and put it in the incoming
|
||||
* hashmap.
|
||||
*
|
||||
* @return true if there's new data. Otherwise, the last received value should
|
||||
* still be in the hashmap.
|
||||
*/
|
||||
bool canRxReceive(uint32_t arbID)
|
||||
{
|
||||
CANMessage &message = incomingMessages[arbID];
|
||||
|
||||
uint8_t length;
|
||||
uint32_t timestamp;
|
||||
int32_t status;
|
||||
|
||||
FRC_NetworkCommunication_CANSessionMux_receiveMessage(
|
||||
&arbID, kFullMessageIDMask, message.data, &length, ×tamp, &status);
|
||||
|
||||
return status != ERR_CANSessionMux_MessageNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
uint8_t canRxUnpackInt8(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = incomingMessages[arbID];
|
||||
|
||||
return message.data[offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = incomingMessages[arbID];
|
||||
|
||||
return *reinterpret_cast<uint16_t *>(message.data + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = incomingMessages[arbID];
|
||||
|
||||
return *reinterpret_cast<uint32_t *>(message.data + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
double canRxUnpackFXP16(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
int16_t raw = canRxUnpackInt16(arbID, offset);
|
||||
|
||||
return raw / 255.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
double canRxUnpackFXP32(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
int32_t raw = canRxUnpackInt32(arbID, offset);
|
||||
|
||||
return raw / 65535.0;
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "NetworkCommunication/FRCComm.h"
|
||||
#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "NetworkCommunication/LoadOut.h"
|
||||
#include "NetworkCommunication/CANSessionMux.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
@@ -201,9 +202,25 @@ int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs)
|
||||
return FRC_NetworkCommunication_getJoystickPOVs(joystickNum, (JoystickPOV_t*) povs, kMaxJoystickPOVs);
|
||||
}
|
||||
|
||||
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons, uint8_t *count)
|
||||
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons)
|
||||
{
|
||||
return FRC_NetworkCommunication_getJoystickButtons(joystickNum, buttons, count);
|
||||
return FRC_NetworkCommunication_getJoystickButtons(joystickNum, &buttons->buttons, &buttons->count);
|
||||
}
|
||||
|
||||
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc)
|
||||
{
|
||||
return FRC_NetworkCommunication_getJoystickDesc(joystickNum, &desc->isXbox, &desc->type, (char *)(&desc->name),
|
||||
&desc->axisCount, &desc->axisTypes, &desc->buttonCount, &desc->povCount);
|
||||
}
|
||||
|
||||
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble)
|
||||
{
|
||||
return FRC_NetworkCommunication_setJoystickOutputs(joystickNum, outputs, leftRumble, rightRumble);
|
||||
}
|
||||
|
||||
int HALGetMatchTime(float *matchTime)
|
||||
{
|
||||
return FRC_NetworkCommunication_getMatchTime(matchTime);
|
||||
}
|
||||
|
||||
void HALSetNewDataSem(pthread_cond_t * param)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define WARN_CANSessionMux_NoToken 44087
|
||||
#define ERR_CANSessionMux_NotAllowed -44088
|
||||
#define ERR_CANSessionMux_NotInitialized -44089
|
||||
#define ERR_CANSessionMux_SessionOverrun 44050
|
||||
|
||||
struct tCANStreamMessage{
|
||||
uint32_t messageID;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#endif
|
||||
|
||||
#define ERR_FRCSystem_NetCommNotResponding -44049
|
||||
#define ERR_FRCSystem_NoDSConnection -44018
|
||||
|
||||
enum AllianceStationID_t {
|
||||
kAllianceStationID_red1,
|
||||
@@ -43,6 +44,13 @@ enum AllianceStationID_t {
|
||||
kAllianceStationID_blue3,
|
||||
};
|
||||
|
||||
enum MatchType_t {
|
||||
kMatchType_none,
|
||||
kMatchType_practice,
|
||||
kMatchType_qualification,
|
||||
kMatchType_elimination,
|
||||
};
|
||||
|
||||
struct ControlWord_t {
|
||||
#ifndef __vxworks
|
||||
uint32_t enabled : 1;
|
||||
|
||||
@@ -26,3 +26,36 @@ double getPDPChannelCurrent(uint8_t channel, int32_t *status) {
|
||||
return current;
|
||||
}
|
||||
|
||||
double getPDPTotalCurrent(int32_t *status) {
|
||||
double current;
|
||||
|
||||
*status = pdp.GetTotalCurrent(current);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
double getPDPTotalPower(int32_t *status) {
|
||||
double power;
|
||||
|
||||
*status = pdp.GetTotalPower(power);
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
double getPDPTotalEnergy(int32_t *status) {
|
||||
double energy;
|
||||
|
||||
*status = pdp.GetTotalEnergy(energy);
|
||||
|
||||
return energy;
|
||||
}
|
||||
|
||||
void resetPDPTotalEnergy(int32_t *status) {
|
||||
*status = pdp.ResetEnergy();
|
||||
}
|
||||
|
||||
void clearPDPStickyFaults(int32_t *status) {
|
||||
*status = pdp.ClearStickyFaults();
|
||||
}
|
||||
|
||||
|
||||
|
||||
992
hal/lib/Athena/ctre/CanTalonSRX.cpp
Normal file
992
hal/lib/Athena/ctre/CanTalonSRX.cpp
Normal file
@@ -0,0 +1,992 @@
|
||||
/**
|
||||
* @brief CAN TALON SRX driver.
|
||||
*
|
||||
* The TALON SRX is designed to instrument all runtime signals periodically. The default periods are chosen to support 16 TALONs
|
||||
* with 10ms update rate for control (throttle or setpoint). However these can be overridden with SetStatusFrameRate. @see SetStatusFrameRate
|
||||
* The getters for these unsolicited signals are auto generated at the bottom of this module.
|
||||
*
|
||||
* Likewise most control signals are sent periodically using the fire-and-forget CAN API.
|
||||
* The setters for these unsolicited signals are auto generated at the bottom of this module.
|
||||
*
|
||||
* Signals that are not available in an unsolicited fashion are the Close Loop gains.
|
||||
* For teams that have a single profile for their TALON close loop they can use either the webpage to configure their TALONs once
|
||||
* or set the PIDF,Izone,CloseLoopRampRate,etc... once in the robot application. These parameters are saved to flash so once they are
|
||||
* loaded in the TALON, they will persist through power cycles and mode changes.
|
||||
*
|
||||
* For teams that have one or two profiles to switch between, they can use the same strategy since there are two slots to choose from
|
||||
* and the ProfileSlotSelect is periodically sent in the 10 ms control frame.
|
||||
*
|
||||
* For teams that require changing gains frequently, they can use the soliciting API to get and set those parameters. Most likely
|
||||
* they will only need to set them in a periodic fashion as a function of what motion the application is attempting.
|
||||
* If this API is used, be mindful of the CAN utilization reported in the driver station.
|
||||
*
|
||||
* Encoder position is measured in encoder edges. Every edge is counted (similar to roboRIO 4X mode).
|
||||
* Analog position is 10 bits, meaning 1024 ticks per rotation (0V => 3.3V).
|
||||
* Use SetFeedbackDeviceSelect to select which sensor type you need. Once you do that you can use GetSensorPosition()
|
||||
* and GetSensorVelocity(). These signals are updated on CANBus every 20ms (by default).
|
||||
* If a relative sensor is selected, you can zero (or change the current value) using SetSensorPosition.
|
||||
*
|
||||
* Analog Input and quadrature position (and velocity) are also explicitly reported in GetEncPosition, GetEncVel, GetAnalogInWithOv, GetAnalogInVel.
|
||||
* These signals are available all the time, regardless of what sensor is selected at a rate of 100ms. This allows easy instrumentation
|
||||
* for "in the pits" checking of all sensors regardless of modeselect. The 100ms rate is overridable for teams who want to acquire sensor
|
||||
* data for processing, not just instrumentation. Or just select the sensor using SetFeedbackDeviceSelect to get it at 20ms.
|
||||
*
|
||||
* Velocity is in position ticks / 100ms.
|
||||
*
|
||||
* All output units are in respect to duty cycle (throttle) which is -1023(full reverse) to +1023 (full forward).
|
||||
* This includes demand (which specifies duty cycle when in duty cycle mode) and rampRamp, which is in throttle units per 10ms (if nonzero).
|
||||
*
|
||||
* Pos and velocity close loops are calc'd as
|
||||
* err = target - posOrVel.
|
||||
* iErr += err;
|
||||
* if( (IZone!=0) and abs(err) > IZone)
|
||||
* ClearIaccum()
|
||||
* output = P X err + I X iErr + D X dErr + F X target
|
||||
* dErr = err - lastErr
|
||||
* P, I,and D gains are always positive. F can be negative.
|
||||
* Motor direction can be reversed using SetRevMotDuringCloseLoopEn if sensor and motor are out of phase.
|
||||
* Similarly feedback sensor can also be reversed (multiplied by -1) if you prefer the sensor to be inverted.
|
||||
*
|
||||
* P gain is specified in throttle per error tick. For example, a value of 102 is ~9.9% (which is 102/1023) throttle per 1
|
||||
* ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
|
||||
*
|
||||
* I gain is specified in throttle per integrated error. For example, a value of 10 equates to ~0.99% (which is 10/1023)
|
||||
* for each accumulated ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
|
||||
* Close loop and integral accumulator runs every 1ms.
|
||||
*
|
||||
* D gain is specified in throttle per derivative error. For example a value of 102 equates to ~9.9% (which is 102/1023)
|
||||
* per change of 1 unit (ADC or encoder) per ms.
|
||||
*
|
||||
* I Zone is specified in the same units as sensor position (ADC units or quadrature edges). If pos/vel error is outside of
|
||||
* this value, the integrated error will auto-clear...
|
||||
* if( (IZone!=0) and abs(err) > IZone)
|
||||
* ClearIaccum()
|
||||
* ...this is very useful in preventing integral windup and is highly recommended if using full PID to keep stability low.
|
||||
*
|
||||
* CloseLoopRampRate ramps the target of the close loop. The units are in position per 1ms. Set to zero to disable ramping.
|
||||
* So a value of 10 means allow the target input of the close loop to approach the user's demand by 10 units (ADC or encoder edges)
|
||||
* per 1ms.
|
||||
*
|
||||
* auto generated using spreadsheet and WpiClassGen.csproj
|
||||
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
|
||||
*/
|
||||
#include "CanTalonSRX.h"
|
||||
#include "NetworkCommunication/CANSessionMux.h" //CAN Comm
|
||||
#include <string.h> // memset
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
#define STATUS_1 0x02041400
|
||||
#define STATUS_2 0x02041440
|
||||
#define STATUS_3 0x02041480
|
||||
#define STATUS_4 0x020414C0
|
||||
#define STATUS_5 0x02041500
|
||||
#define STATUS_6 0x02041540
|
||||
#define STATUS_7 0x02041580
|
||||
|
||||
#define CONTROL_1 0x02040000
|
||||
#define CONTROL_2 0x02040040
|
||||
#define CONTROL_3 0x02040080
|
||||
|
||||
#define EXPECTED_RESPONSE_TIMEOUT_MS (200)
|
||||
#define GET_STATUS1() CtreCanNode::recMsg<TALON_Status_1_General_10ms_t > rx = GetRx<TALON_Status_1_General_10ms_t>(STATUS_1 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS2() CtreCanNode::recMsg<TALON_Status_2_Feedback_20ms_t > rx = GetRx<TALON_Status_2_Feedback_20ms_t>(STATUS_2 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS3() CtreCanNode::recMsg<TALON_Status_3_Enc_100ms_t > rx = GetRx<TALON_Status_3_Enc_100ms_t>(STATUS_3 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS4() CtreCanNode::recMsg<TALON_Status_4_AinTempVbat_100ms_t> rx = GetRx<TALON_Status_4_AinTempVbat_100ms_t>(STATUS_4 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS5() CtreCanNode::recMsg<TALON_Status_5_Startup_OneShot_t > rx = GetRx<TALON_Status_5_Startup_OneShot_t>(STATUS_5 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS6() CtreCanNode::recMsg<TALON_Status_6_Eol_t > rx = GetRx<TALON_Status_6_Eol_t>(STATUS_6 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS7() CtreCanNode::recMsg<TALON_Status_7_Debug_200ms_t > rx = GetRx<TALON_Status_7_Debug_200ms_t>(STATUS_7 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
|
||||
#define PARAM_REQUEST 0x02041800
|
||||
#define PARAM_RESPONSE 0x02041840
|
||||
#define PARAM_SET 0x02041880
|
||||
|
||||
const int kParamArbIdValue = PARAM_RESPONSE;
|
||||
const int kParamArbIdMask = 0xFFFFFFFF;
|
||||
|
||||
const double FLOAT_TO_FXP = (double)0x400000;
|
||||
const double FXP_TO_FLOAT = 0.0000002384185791015625;
|
||||
|
||||
/* encoder/decoders */
|
||||
/** control */
|
||||
typedef struct _TALON_Control_1_General_10ms_t {
|
||||
unsigned TokenH:8;
|
||||
unsigned TokenL:8;
|
||||
unsigned DemandH:8;
|
||||
unsigned DemandM:8;
|
||||
unsigned DemandL:8;
|
||||
unsigned ProfileSlotSelect:1;
|
||||
unsigned FeedbackDeviceSelect:4;
|
||||
unsigned OverrideLimitSwitchEn:3;
|
||||
unsigned RevFeedbackSensor:1;
|
||||
unsigned RevMotDuringCloseLoopEn:1;
|
||||
unsigned OverrideBrakeType:2;
|
||||
unsigned ModeSelect:4;
|
||||
unsigned RampThrottle:8;
|
||||
} TALON_Control_1_General_10ms_t ;
|
||||
typedef struct _TALON_Control_2_Rates_OneShot_t {
|
||||
unsigned Status1Ms:8;
|
||||
unsigned Status2Ms:8;
|
||||
unsigned Status3Ms:8;
|
||||
unsigned Status4Ms:8;
|
||||
} TALON_Control_2_Rates_OneShot_t ;
|
||||
typedef struct _TALON_Control_3_ClearFlags_OneShot_t {
|
||||
unsigned ZeroFeedbackSensor:1;
|
||||
unsigned ClearStickyFaults:1;
|
||||
} TALON_Control_3_ClearFlags_OneShot_t ;
|
||||
|
||||
/** status */
|
||||
typedef struct _TALON_Status_1_General_10ms_t {
|
||||
unsigned CloseLoopErrH:8;
|
||||
unsigned CloseLoopErrM:8;
|
||||
unsigned CloseLoopErrL:8;
|
||||
unsigned AppliedThrottle_h3:3;
|
||||
unsigned Fault_RevSoftLim:1;
|
||||
unsigned Fault_ForSoftLim:1;
|
||||
unsigned TokLocked:1;
|
||||
unsigned LimitSwitchClosedRev:1;
|
||||
unsigned LimitSwitchClosedFor:1;
|
||||
unsigned AppliedThrottle_l8:8;
|
||||
unsigned ModeSelect_h1:1;
|
||||
unsigned FeedbackDeviceSelect:4;
|
||||
unsigned LimitSwitchEn:3;
|
||||
unsigned Fault_HardwareFailure:1;
|
||||
unsigned Fault_RevLim:1;
|
||||
unsigned Fault_ForLim:1;
|
||||
unsigned Fault_UnderVoltage:1;
|
||||
unsigned Fault_OverTemp:1;
|
||||
unsigned ModeSelect_b3:3;
|
||||
unsigned TokenSeed:8;
|
||||
} TALON_Status_1_General_10ms_t ;
|
||||
typedef struct _TALON_Status_2_Feedback_20ms_t {
|
||||
unsigned SensorPositionH:8;
|
||||
unsigned SensorPositionM:8;
|
||||
unsigned SensorPositionL:8;
|
||||
unsigned SensorVelocityH:8;
|
||||
unsigned SensorVelocityL:8;
|
||||
unsigned Current_h8:8;
|
||||
unsigned StckyFault_RevSoftLim:1;
|
||||
unsigned StckyFault_ForSoftLim:1;
|
||||
unsigned StckyFault_RevLim:1;
|
||||
unsigned StckyFault_ForLim:1;
|
||||
unsigned StckyFault_UnderVoltage:1;
|
||||
unsigned StckyFault_OverTemp:1;
|
||||
unsigned Current_l2:2;
|
||||
unsigned reserved:6;
|
||||
unsigned ProfileSlotSelect:1;
|
||||
unsigned BrakeIsEnabled:1;
|
||||
} TALON_Status_2_Feedback_20ms_t ;
|
||||
typedef struct _TALON_Status_3_Enc_100ms_t {
|
||||
unsigned EncPositionH:8;
|
||||
unsigned EncPositionM:8;
|
||||
unsigned EncPositionL:8;
|
||||
unsigned EncVelH:8;
|
||||
unsigned EncVelL:8;
|
||||
unsigned EncIndexRiseEventsH:8;
|
||||
unsigned EncIndexRiseEventsL:8;
|
||||
unsigned reserved:5;
|
||||
unsigned QuadIdxpin:1;
|
||||
unsigned QuadBpin:1;
|
||||
unsigned QuadApin:1;
|
||||
} TALON_Status_3_Enc_100ms_t ;
|
||||
typedef struct _TALON_Status_4_AinTempVbat_100ms_t {
|
||||
unsigned AnalogInWithOvH:8;
|
||||
unsigned AnalogInWithOvM:8;
|
||||
unsigned AnalogInWithOvL:8;
|
||||
unsigned AnalogInVelH:8;
|
||||
unsigned AnalogInVelL:8;
|
||||
unsigned Temp:8;
|
||||
unsigned BatteryV:8;
|
||||
unsigned reserved:8;
|
||||
} TALON_Status_4_AinTempVbat_100ms_t ;
|
||||
typedef struct _TALON_Status_5_Startup_OneShot_t {
|
||||
unsigned ResetCountH:8;
|
||||
unsigned ResetCountL:8;
|
||||
unsigned ResetFlagsH:8;
|
||||
unsigned ResetFlagsL:8;
|
||||
unsigned FirmVersH:8;
|
||||
unsigned FirmVersL:8;
|
||||
} TALON_Status_5_Startup_OneShot_t ;
|
||||
typedef struct _TALON_Status_6_Eol_t {
|
||||
unsigned currentAdcUncal_h2:2;
|
||||
unsigned reserved1:5;
|
||||
unsigned SpiCsPin_GadgeteerPin6:1;
|
||||
unsigned currentAdcUncal_l8:8;
|
||||
unsigned tempAdcUncal_h2:2;
|
||||
unsigned reserved2:6;
|
||||
unsigned tempAdcUncal_l8:8;
|
||||
unsigned vbatAdcUncal_h2:2;
|
||||
unsigned reserved3:6;
|
||||
unsigned vbatAdcUncal_l8:8;
|
||||
unsigned analogAdcUncal_h2:2;
|
||||
unsigned reserved4:6;
|
||||
unsigned analogAdcUncal_l8:8;
|
||||
} TALON_Status_6_Eol_t ;
|
||||
typedef struct _TALON_Status_7_Debug_200ms_t {
|
||||
unsigned TokenizationFails_h8:8;
|
||||
unsigned TokenizationFails_l8:8;
|
||||
unsigned LastFailedToken_h8:8;
|
||||
unsigned LastFailedToken_l8:8;
|
||||
unsigned TokenizationSucceses_h8:8;
|
||||
unsigned TokenizationSucceses_l8:8;
|
||||
} TALON_Status_7_Debug_200ms_t ;
|
||||
typedef struct _TALON_Param_Request_t {
|
||||
unsigned ParamEnum:8;
|
||||
} TALON_Param_Request_t ;
|
||||
typedef struct _TALON_Param_Response_t {
|
||||
unsigned ParamEnum:8;
|
||||
unsigned ParamValueL:8;
|
||||
unsigned ParamValueML:8;
|
||||
unsigned ParamValueMH:8;
|
||||
unsigned ParamValueH:8;
|
||||
} TALON_Param_Response_t ;
|
||||
|
||||
|
||||
CanTalonSRX::CanTalonSRX(int deviceNumber,int controlPeriodMs): CtreCanNode(deviceNumber), _can_h(0), _can_stat(0)
|
||||
{
|
||||
RegisterRx(STATUS_1 | (UINT8)deviceNumber );
|
||||
RegisterRx(STATUS_2 | (UINT8)deviceNumber );
|
||||
RegisterRx(STATUS_3 | (UINT8)deviceNumber );
|
||||
RegisterRx(STATUS_4 | (UINT8)deviceNumber );
|
||||
RegisterRx(STATUS_5 | (UINT8)deviceNumber );
|
||||
RegisterRx(STATUS_6 | (UINT8)deviceNumber );
|
||||
RegisterRx(STATUS_7 | (UINT8)deviceNumber );
|
||||
RegisterTx(CONTROL_1 | (UINT8)deviceNumber, (UINT8)controlPeriodMs);
|
||||
/* default our frame rate table to what firmware defaults to. */
|
||||
_statusRateMs[0] = 10; /* TALON_Status_1_General_10ms_t */
|
||||
_statusRateMs[1] = 20; /* TALON_Status_2_Feedback_20ms_t */
|
||||
_statusRateMs[2] = 100; /* TALON_Status_3_Enc_100ms_t */
|
||||
_statusRateMs[3] = 100; /* TALON_Status_4_AinTempVbat_100ms_t */
|
||||
/* the only default param that is nonzero is limit switch.
|
||||
* Default to using the flash settings. */
|
||||
SetOverrideLimitSwitchEn(kLimitSwitchOverride_UseDefaultsFromFlash);
|
||||
}
|
||||
/* CanTalonSRX D'tor
|
||||
*/
|
||||
CanTalonSRX::~CanTalonSRX()
|
||||
{
|
||||
if(_can_h){
|
||||
FRC_NetworkCommunication_CANSessionMux_closeStreamSession(_can_h);
|
||||
_can_h = 0;
|
||||
}
|
||||
}
|
||||
void CanTalonSRX::OpenSessionIfNeedBe()
|
||||
{
|
||||
_can_stat = 0;
|
||||
if (_can_h == 0) {
|
||||
/* bit30 - bit8 must match $000002XX. Top bit is not masked to get remote frames */
|
||||
FRC_NetworkCommunication_CANSessionMux_openStreamSession(&_can_h,kParamArbIdValue | GetDeviceNumber(), kParamArbIdMask, kMsgCapacity, &_can_stat);
|
||||
if (_can_stat == 0) {
|
||||
/* success */
|
||||
} else {
|
||||
/* something went wrong, try again later */
|
||||
_can_h = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CanTalonSRX::ProcessStreamMessages()
|
||||
{
|
||||
if(0 == _can_h)
|
||||
OpenSessionIfNeedBe();
|
||||
/* process receive messages */
|
||||
uint32_t i;
|
||||
uint32_t messagesToRead = sizeof(_msgBuff) / sizeof(_msgBuff[0]);
|
||||
uint32_t messagesRead = 0;
|
||||
/* read out latest bunch of messages */
|
||||
_can_stat = 0;
|
||||
if (_can_h){
|
||||
FRC_NetworkCommunication_CANSessionMux_readStreamSession(_can_h,_msgBuff, messagesToRead, &messagesRead, &_can_stat);
|
||||
}
|
||||
/* loop thru each message of interest */
|
||||
for (i = 0; i < messagesRead; ++i) {
|
||||
tCANStreamMessage * msg = _msgBuff + i;
|
||||
if(msg->messageID == (PARAM_RESPONSE | GetDeviceNumber()) ){
|
||||
TALON_Param_Response_t * paramResp = (TALON_Param_Response_t*)msg->data;
|
||||
/* decode value */
|
||||
int32_t val = paramResp->ParamValueH;
|
||||
val <<= 8;
|
||||
val |= paramResp->ParamValueMH;
|
||||
val <<= 8;
|
||||
val |= paramResp->ParamValueML;
|
||||
val <<= 8;
|
||||
val |= paramResp->ParamValueL;
|
||||
/* save latest signal */
|
||||
_sigs[paramResp->ParamEnum] = val;
|
||||
}else{
|
||||
int brkpthere = 42;
|
||||
++brkpthere;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CanTalonSRX::Set(double value)
|
||||
{
|
||||
if(value > 1)
|
||||
value = 1;
|
||||
else if(value < -1)
|
||||
value = -1;
|
||||
SetDemand(1023*value); /* must be within [-1023,1023] */
|
||||
}
|
||||
/*---------------------setters and getters that use the param request/response-------------*/
|
||||
/**
|
||||
* Send a one shot frame to set an arbitrary signal.
|
||||
* Most signals are in the control frame so avoid using this API unless you have to.
|
||||
* Use this api for...
|
||||
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
|
||||
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
|
||||
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
|
||||
*/
|
||||
CTR_Code CanTalonSRX::SetParamRaw(unsigned paramEnum, int rawBits)
|
||||
{
|
||||
/* caller is using param API. Open session if it hasn'T been done. */
|
||||
if(0 == _can_h)
|
||||
OpenSessionIfNeedBe();
|
||||
TALON_Param_Response_t frame;
|
||||
memset(&frame,0,sizeof(frame));
|
||||
frame.ParamEnum = paramEnum;
|
||||
frame.ParamValueH = rawBits >> 0x18;
|
||||
frame.ParamValueMH = rawBits >> 0x10;
|
||||
frame.ParamValueML = rawBits >> 0x08;
|
||||
frame.ParamValueL = rawBits;
|
||||
int32_t status = 0;
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(PARAM_SET | GetDeviceNumber(), (const uint8_t*)&frame, 5, 0, &status);
|
||||
if(status)
|
||||
return CTR_TxFailed;
|
||||
return CTR_OKAY;
|
||||
}
|
||||
/**
|
||||
* Checks cached CAN frames and updating solicited signals.
|
||||
*/
|
||||
CTR_Code CanTalonSRX::GetParamResponseRaw(unsigned paramEnum, int & rawBits)
|
||||
{
|
||||
CTR_Code retval = CTR_OKAY;
|
||||
/* process received param events. We don't expect many since this API is not used often. */
|
||||
ProcessStreamMessages();
|
||||
/* grab the solicited signal value */
|
||||
sigs_t::iterator i = _sigs.find(paramEnum);
|
||||
if(i == _sigs.end()){
|
||||
retval = CTR_SigNotUpdated;
|
||||
}else{
|
||||
rawBits = i->second;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
/**
|
||||
* Asks TALON to immedietely respond with signal value. This API is only used for signals that are not sent periodically.
|
||||
* This can be useful for reading params that rarely change like Limit Switch settings and PIDF values.
|
||||
* @param param to request.
|
||||
*/
|
||||
CTR_Code CanTalonSRX::RequestParam(param_t paramEnum)
|
||||
{
|
||||
/* process received param events. We don't expect many since this API is not used often. */
|
||||
ProcessStreamMessages();
|
||||
TALON_Param_Request_t frame;
|
||||
memset(&frame,0,sizeof(frame));
|
||||
frame.ParamEnum = paramEnum;
|
||||
int32_t status = 0;
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(PARAM_REQUEST | GetDeviceNumber(), (const uint8_t*)&frame, 1, 0, &status);
|
||||
if(status)
|
||||
return CTR_TxFailed;
|
||||
return CTR_OKAY;
|
||||
}
|
||||
|
||||
CTR_Code CanTalonSRX::SetParam(param_t paramEnum, double value)
|
||||
{
|
||||
int32_t rawbits = 0;
|
||||
switch(paramEnum){
|
||||
case eProfileParamSlot0_P:/* unsigned 10.22 fixed pt value */
|
||||
case eProfileParamSlot0_I:
|
||||
case eProfileParamSlot0_D:
|
||||
case eProfileParamSlot1_P:
|
||||
case eProfileParamSlot1_I:
|
||||
case eProfileParamSlot1_D:
|
||||
{
|
||||
uint32_t urawbits;
|
||||
value = std::min(value,1023.0); /* bounds check doubles that are outside u10.22 */
|
||||
value = std::max(value,0.0);
|
||||
urawbits = value * FLOAT_TO_FXP; /* perform unsign arithmetic */
|
||||
rawbits = urawbits; /* copy bits over. SetParamRaw just stuffs into CAN frame with no sense of signedness */
|
||||
} break;
|
||||
case eProfileParamSlot1_F: /* signed 10.22 fixed pt value */
|
||||
case eProfileParamSlot0_F:
|
||||
value = std::min(value, 512.0); /* bounds check doubles that are outside s10.22 */
|
||||
value = std::max(value,-512.0);
|
||||
rawbits = value * FLOAT_TO_FXP;
|
||||
break;
|
||||
default: /* everything else is integral */
|
||||
rawbits = (int32_t)value;
|
||||
break;
|
||||
}
|
||||
return SetParamRaw(paramEnum,rawbits);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetParamResponse(param_t paramEnum, double & value)
|
||||
{
|
||||
int32_t rawbits = 0;
|
||||
CTR_Code retval = GetParamResponseRaw(paramEnum,rawbits);
|
||||
switch(paramEnum){
|
||||
case eProfileParamSlot0_P:/* 10.22 fixed pt value */
|
||||
case eProfileParamSlot0_I:
|
||||
case eProfileParamSlot0_D:
|
||||
case eProfileParamSlot0_F:
|
||||
case eProfileParamSlot1_P:
|
||||
case eProfileParamSlot1_I:
|
||||
case eProfileParamSlot1_D:
|
||||
case eProfileParamSlot1_F:
|
||||
case eCurrent:
|
||||
case eTemp:
|
||||
case eBatteryV:
|
||||
value = ((double)rawbits) * FXP_TO_FLOAT;
|
||||
break;
|
||||
default: /* everything else is integral */
|
||||
value = (double)rawbits;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetParamResponseInt32(param_t paramEnum, int & value)
|
||||
{
|
||||
double dvalue = 0;
|
||||
CTR_Code retval = GetParamResponse(paramEnum, dvalue);
|
||||
value = (int32_t)dvalue;
|
||||
return retval;
|
||||
}
|
||||
/*----- getters and setters that use param request/response. These signals are backed up in flash and will survive a power cycle. ---------*/
|
||||
/*----- If your application requires changing these values consider using both slots and switch between slot0 <=> slot1. ------------------*/
|
||||
/*----- If your application requires changing these signals frequently then it makes sense to leverage this API. --------------------------*/
|
||||
/*----- Getters don't block, so it may require several calls to get the latest value. --------------------------*/
|
||||
CTR_Code CanTalonSRX::SetPgain(unsigned slotIdx,double gain)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return SetParam(eProfileParamSlot0_P, gain);
|
||||
return SetParam(eProfileParamSlot1_P, gain);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetIgain(unsigned slotIdx,double gain)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return SetParam(eProfileParamSlot0_I, gain);
|
||||
return SetParam(eProfileParamSlot1_I, gain);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetDgain(unsigned slotIdx,double gain)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return SetParam(eProfileParamSlot0_D, gain);
|
||||
return SetParam(eProfileParamSlot1_D, gain);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetFgain(unsigned slotIdx,double gain)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return SetParam(eProfileParamSlot0_F, gain);
|
||||
return SetParam(eProfileParamSlot1_F, gain);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetIzone(unsigned slotIdx,int zone)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return SetParam(eProfileParamSlot0_IZone, zone);
|
||||
return SetParam(eProfileParamSlot1_IZone, zone);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetCloseLoopRampRate(unsigned slotIdx,int closeLoopRampRate)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return SetParam(eProfileParamSlot0_CloseLoopRampRate, closeLoopRampRate);
|
||||
return SetParam(eProfileParamSlot1_CloseLoopRampRate, closeLoopRampRate);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetPgain(unsigned slotIdx,double & gain)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return GetParamResponse(eProfileParamSlot0_P, gain);
|
||||
return GetParamResponse(eProfileParamSlot1_P, gain);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetIgain(unsigned slotIdx,double & gain)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return GetParamResponse(eProfileParamSlot0_I, gain);
|
||||
return GetParamResponse(eProfileParamSlot1_I, gain);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetDgain(unsigned slotIdx,double & gain)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return GetParamResponse(eProfileParamSlot0_D, gain);
|
||||
return GetParamResponse(eProfileParamSlot1_D, gain);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFgain(unsigned slotIdx,double & gain)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return GetParamResponse(eProfileParamSlot0_F, gain);
|
||||
return GetParamResponse(eProfileParamSlot1_F, gain);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetIzone(unsigned slotIdx,int & zone)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return GetParamResponseInt32(eProfileParamSlot0_IZone, zone);
|
||||
return GetParamResponseInt32(eProfileParamSlot1_IZone, zone);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetCloseLoopRampRate(unsigned slotIdx,int & closeLoopRampRate)
|
||||
{
|
||||
if(slotIdx == 0)
|
||||
return GetParamResponseInt32(eProfileParamSlot0_CloseLoopRampRate, closeLoopRampRate);
|
||||
return GetParamResponseInt32(eProfileParamSlot1_CloseLoopRampRate, closeLoopRampRate);
|
||||
}
|
||||
|
||||
CTR_Code CanTalonSRX::SetSensorPosition(int pos)
|
||||
{
|
||||
return SetParam(eSensorPosition, pos);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetForwardSoftLimit(int forwardLimit)
|
||||
{
|
||||
return SetParam(eProfileParamSoftLimitForThreshold, forwardLimit);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetReverseSoftLimit(int reverseLimit)
|
||||
{
|
||||
return SetParam(eProfileParamSoftLimitRevThreshold, reverseLimit);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetForwardSoftEnable(int enable)
|
||||
{
|
||||
return SetParam(eProfileParamSoftLimitForEnable, enable);
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetReverseSoftEnable(int enable)
|
||||
{
|
||||
return SetParam(eProfileParamSoftLimitRevEnable, enable);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetForwardSoftLimit(int & forwardLimit)
|
||||
{
|
||||
return GetParamResponseInt32(eProfileParamSoftLimitForThreshold, forwardLimit);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetReverseSoftLimit(int & reverseLimit)
|
||||
{
|
||||
return GetParamResponseInt32(eProfileParamSoftLimitRevThreshold, reverseLimit);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetForwardSoftEnable(int & enable)
|
||||
{
|
||||
return GetParamResponseInt32(eProfileParamSoftLimitForEnable, enable);
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetReverseSoftEnable(int & enable)
|
||||
{
|
||||
return GetParamResponseInt32(eProfileParamSoftLimitRevEnable, enable);
|
||||
}
|
||||
/**
|
||||
* Change the periodMs of a TALON's status frame. See kStatusFrame_* enums for what's available.
|
||||
*/
|
||||
CTR_Code CanTalonSRX::SetStatusFrameRate(unsigned frameEnum, unsigned periodMs)
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint8_t period = (uint8_t)periodMs;
|
||||
/* tweak just the status messsage rate the caller cares about */
|
||||
switch(frameEnum){
|
||||
case kStatusFrame_General:
|
||||
_statusRateMs[0] = period;
|
||||
break;
|
||||
case kStatusFrame_Feedback:
|
||||
_statusRateMs[1] = period;
|
||||
break;
|
||||
case kStatusFrame_Encoder:
|
||||
_statusRateMs[2] = period;
|
||||
break;
|
||||
case kStatusFrame_AnalogTempVbat:
|
||||
_statusRateMs[3] = period;
|
||||
break;
|
||||
}
|
||||
/* build our request frame */
|
||||
TALON_Control_2_Rates_OneShot_t frame;
|
||||
memset(&frame,0,sizeof(frame));
|
||||
frame.Status1Ms = _statusRateMs[0];
|
||||
frame.Status2Ms = _statusRateMs[1];
|
||||
frame.Status3Ms = _statusRateMs[2];
|
||||
frame.Status4Ms = _statusRateMs[3];
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_2 | GetDeviceNumber(), (const uint8_t*)&frame, sizeof(frame), 0, &status);
|
||||
if(status)
|
||||
return CTR_TxFailed;
|
||||
return CTR_OKAY;
|
||||
}
|
||||
/**
|
||||
* Clear all sticky faults in TALON.
|
||||
*/
|
||||
CTR_Code CanTalonSRX::ClearStickyFaults()
|
||||
{
|
||||
int32_t status = 0;
|
||||
/* build request frame */
|
||||
TALON_Control_3_ClearFlags_OneShot_t frame;
|
||||
memset(&frame,0,sizeof(frame));
|
||||
frame.ClearStickyFaults = 1;
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_3 | GetDeviceNumber(), (const uint8_t*)&frame, sizeof(frame), 0, &status);
|
||||
if(status)
|
||||
return CTR_TxFailed;
|
||||
return CTR_OKAY;
|
||||
}
|
||||
/*------------------------ auto generated. This API is optimal since it uses the fire-and-forget CAN interface ----------------------*/
|
||||
/*------------------------ These signals should cover the majority of all use cases. ----------------------------------*/
|
||||
CTR_Code CanTalonSRX::GetFault_OverTemp(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_OverTemp;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_UnderVoltage(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_UnderVoltage;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_ForLim(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_ForLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_RevLim(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_RevLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_HardwareFailure(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_HardwareFailure;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_ForSoftLim(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_ForSoftLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_RevSoftLim(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_RevSoftLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_OverTemp(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_OverTemp;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_UnderVoltage(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_UnderVoltage;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_ForLim(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_ForLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_RevLim(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_RevLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_ForSoftLim(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_ForSoftLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_RevSoftLim(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_RevSoftLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetAppliedThrottle(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
int32_t raw = 0;
|
||||
raw |= rx->AppliedThrottle_h3;
|
||||
raw <<= 8;
|
||||
raw |= rx->AppliedThrottle_l8;
|
||||
raw <<= (32-11); /* sign extend */
|
||||
raw >>= (32-11); /* sign extend */
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetCloseLoopErr(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
int32_t raw = 0;
|
||||
raw |= rx->CloseLoopErrH;
|
||||
raw <<= 8;
|
||||
raw |= rx->CloseLoopErrM;
|
||||
raw <<= 8;
|
||||
raw |= rx->CloseLoopErrL;
|
||||
raw <<= (32-24); /* sign extend */
|
||||
raw >>= (32-24); /* sign extend */
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFeedbackDeviceSelect(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->FeedbackDeviceSelect;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetModeSelect(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->ModeSelect_h1;
|
||||
raw <<= 3;
|
||||
raw |= rx->ModeSelect_b3;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetLimitSwitchEn(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->LimitSwitchEn;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetLimitSwitchClosedFor(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->LimitSwitchClosedFor;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetLimitSwitchClosedRev(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->LimitSwitchClosedRev;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetSensorPosition(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
int32_t raw = 0;
|
||||
raw |= rx->SensorPositionH;
|
||||
raw <<= 8;
|
||||
raw |= rx->SensorPositionM;
|
||||
raw <<= 8;
|
||||
raw |= rx->SensorPositionL;
|
||||
raw <<= (32-24); /* sign extend */
|
||||
raw >>= (32-24); /* sign extend */
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetSensorVelocity(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
int32_t raw = 0;
|
||||
raw |= rx->SensorVelocityH;
|
||||
raw <<= 8;
|
||||
raw |= rx->SensorVelocityL;
|
||||
raw <<= (32-16); /* sign extend */
|
||||
raw >>= (32-16); /* sign extend */
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetCurrent(double ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->Current_h8;
|
||||
raw <<= 2;
|
||||
raw |= rx->Current_l2;
|
||||
param = (double)raw * 0.125 + 0;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetBrakeIsEnabled(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->BrakeIsEnabled;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetEncPosition(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
int32_t raw = 0;
|
||||
raw |= rx->EncPositionH;
|
||||
raw <<= 8;
|
||||
raw |= rx->EncPositionM;
|
||||
raw <<= 8;
|
||||
raw |= rx->EncPositionL;
|
||||
raw <<= (32-24); /* sign extend */
|
||||
raw >>= (32-24); /* sign extend */
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetEncVel(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
int32_t raw = 0;
|
||||
raw |= rx->EncVelH;
|
||||
raw <<= 8;
|
||||
raw |= rx->EncVelL;
|
||||
raw <<= (32-16); /* sign extend */
|
||||
raw >>= (32-16); /* sign extend */
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetEncIndexRiseEvents(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->EncIndexRiseEventsH;
|
||||
raw <<= 8;
|
||||
raw |= rx->EncIndexRiseEventsL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetQuadApin(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
param = rx->QuadApin;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetQuadBpin(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
param = rx->QuadBpin;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetQuadIdxpin(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
param = rx->QuadIdxpin;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetAnalogInWithOv(int ¶m)
|
||||
{
|
||||
GET_STATUS4();
|
||||
int32_t raw = 0;
|
||||
raw |= rx->AnalogInWithOvH;
|
||||
raw <<= 8;
|
||||
raw |= rx->AnalogInWithOvM;
|
||||
raw <<= 8;
|
||||
raw |= rx->AnalogInWithOvL;
|
||||
raw <<= (32-24); /* sign extend */
|
||||
raw >>= (32-24); /* sign extend */
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetAnalogInVel(int ¶m)
|
||||
{
|
||||
GET_STATUS4();
|
||||
int32_t raw = 0;
|
||||
raw |= rx->AnalogInVelH;
|
||||
raw <<= 8;
|
||||
raw |= rx->AnalogInVelL;
|
||||
param = (int)raw;
|
||||
raw <<= (32-16); /* sign extend */
|
||||
raw >>= (32-16); /* sign extend */
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetTemp(double ¶m)
|
||||
{
|
||||
GET_STATUS4();
|
||||
uint32_t raw = rx->Temp;
|
||||
param = (double)raw * 0.6451612903 + -50;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetBatteryV(double ¶m)
|
||||
{
|
||||
GET_STATUS4();
|
||||
uint32_t raw = rx->BatteryV;
|
||||
param = (double)raw * 0.05 + 4;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetResetCount(int ¶m)
|
||||
{
|
||||
GET_STATUS5();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->ResetCountH;
|
||||
raw <<= 8;
|
||||
raw |= rx->ResetCountL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetResetFlags(int ¶m)
|
||||
{
|
||||
GET_STATUS5();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->ResetFlagsH;
|
||||
raw <<= 8;
|
||||
raw |= rx->ResetFlagsL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFirmVers(int ¶m)
|
||||
{
|
||||
GET_STATUS5();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->FirmVersH;
|
||||
raw <<= 8;
|
||||
raw |= rx->FirmVersL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetDemand(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->DemandH = param>>16;
|
||||
toFill->DemandM = param>>8;
|
||||
toFill->DemandL = param>>0;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetOverrideLimitSwitchEn(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->OverrideLimitSwitchEn = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetFeedbackDeviceSelect(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->FeedbackDeviceSelect = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetRevMotDuringCloseLoopEn(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->RevMotDuringCloseLoopEn = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetOverrideBrakeType(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->OverrideBrakeType = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetModeSelect(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->ModeSelect = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetProfileSlotSelect(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->ProfileSlotSelect = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetRampThrottle(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->RampThrottle = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetRevFeedbackSensor(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->RevFeedbackSensor = param ? 1 : 0;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
316
hal/lib/Athena/ctre/CanTalonSRX.h
Normal file
316
hal/lib/Athena/ctre/CanTalonSRX.h
Normal file
@@ -0,0 +1,316 @@
|
||||
/**
|
||||
* @brief CAN TALON SRX driver.
|
||||
*
|
||||
* The TALON SRX is designed to instrument all runtime signals periodically. The default periods are chosen to support 16 TALONs
|
||||
* with 10ms update rate for control (throttle or setpoint). However these can be overridden with SetStatusFrameRate. @see SetStatusFrameRate
|
||||
* The getters for these unsolicited signals are auto generated at the bottom of this module.
|
||||
*
|
||||
* Likewise most control signals are sent periodically using the fire-and-forget CAN API.
|
||||
* The setters for these unsolicited signals are auto generated at the bottom of this module.
|
||||
*
|
||||
* Signals that are not available in an unsolicited fashion are the Close Loop gains.
|
||||
* For teams that have a single profile for their TALON close loop they can use either the webpage to configure their TALONs once
|
||||
* or set the PIDF,Izone,CloseLoopRampRate,etc... once in the robot application. These parameters are saved to flash so once they are
|
||||
* loaded in the TALON, they will persist through power cycles and mode changes.
|
||||
*
|
||||
* For teams that have one or two profiles to switch between, they can use the same strategy since there are two slots to choose from
|
||||
* and the ProfileSlotSelect is periodically sent in the 10 ms control frame.
|
||||
*
|
||||
* For teams that require changing gains frequently, they can use the soliciting API to get and set those parameters. Most likely
|
||||
* they will only need to set them in a periodic fashion as a function of what motion the application is attempting.
|
||||
* If this API is used, be mindful of the CAN utilization reported in the driver station.
|
||||
*
|
||||
* Encoder position is measured in encoder edges. Every edge is counted (similar to roboRIO 4X mode).
|
||||
* Analog position is 10 bits, meaning 1024 ticks per rotation (0V => 3.3V).
|
||||
* Use SetFeedbackDeviceSelect to select which sensor type you need. Once you do that you can use GetSensorPosition()
|
||||
* and GetSensorVelocity(). These signals are updated on CANBus every 20ms (by default).
|
||||
* If a relative sensor is selected, you can zero (or change the current value) using SetSensorPosition.
|
||||
*
|
||||
* Analog Input and quadrature position (and velocity) are also explicitly reported in GetEncPosition, GetEncVel, GetAnalogInWithOv, GetAnalogInVel.
|
||||
* These signals are available all the time, regardless of what sensor is selected at a rate of 100ms. This allows easy instrumentation
|
||||
* for "in the pits" checking of all sensors regardless of modeselect. The 100ms rate is overridable for teams who want to acquire sensor
|
||||
* data for processing, not just instrumentation. Or just select the sensor using SetFeedbackDeviceSelect to get it at 20ms.
|
||||
*
|
||||
* Velocity is in position ticks / 100ms.
|
||||
*
|
||||
* All output units are in respect to duty cycle (throttle) which is -1023(full reverse) to +1023 (full forward).
|
||||
* This includes demand (which specifies duty cycle when in duty cycle mode) and rampRamp, which is in throttle units per 10ms (if nonzero).
|
||||
*
|
||||
* Pos and velocity close loops are calc'd as
|
||||
* err = target - posOrVel.
|
||||
* iErr += err;
|
||||
* if( (IZone!=0) and abs(err) > IZone)
|
||||
* ClearIaccum()
|
||||
* output = P X err + I X iErr + D X dErr + F X target
|
||||
* dErr = err - lastErr
|
||||
* P, I,and D gains are always positive. F can be negative.
|
||||
* Motor direction can be reversed using SetRevMotDuringCloseLoopEn if sensor and motor are out of phase.
|
||||
* Similarly feedback sensor can also be reversed (multiplied by -1) if you prefer the sensor to be inverted.
|
||||
*
|
||||
* P gain is specified in throttle per error tick. For example, a value of 102 is ~9.9% (which is 102/1023) throttle per 1
|
||||
* ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
|
||||
*
|
||||
* I gain is specified in throttle per integrated error. For example, a value of 10 equates to ~0.99% (which is 10/1023)
|
||||
* for each accumulated ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
|
||||
* Close loop and integral accumulator runs every 1ms.
|
||||
*
|
||||
* D gain is specified in throttle per derivative error. For example a value of 102 equates to ~9.9% (which is 102/1023)
|
||||
* per change of 1 unit (ADC or encoder) per ms.
|
||||
*
|
||||
* I Zone is specified in the same units as sensor position (ADC units or quadrature edges). If pos/vel error is outside of
|
||||
* this value, the integrated error will auto-clear...
|
||||
* if( (IZone!=0) and abs(err) > IZone)
|
||||
* ClearIaccum()
|
||||
* ...this is very useful in preventing integral windup and is highly recommended if using full PID to keep stability low.
|
||||
*
|
||||
* CloseLoopRampRate ramps the target of the close loop. The units are in position per 1ms. Set to zero to disable ramping.
|
||||
* So a value of 10 means allow the target input of the close loop to approach the user's demand by 10 units (ADC or encoder edges)
|
||||
* per 1ms.
|
||||
*
|
||||
* auto generated using spreadsheet and WpiClassGen.csproj
|
||||
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
|
||||
*/
|
||||
#ifndef CanTalonSRX_H_
|
||||
#define CanTalonSRX_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include "CtreCanNode.h"
|
||||
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
#include <map>
|
||||
class CanTalonSRX : public CtreCanNode
|
||||
{
|
||||
private:
|
||||
|
||||
/** just in case user wants to modify periods of certain status frames.
|
||||
* Default the vars to match the firmware default. */
|
||||
uint32_t _statusRateMs[4];
|
||||
//---------------------- Vars for opening a CAN stream if caller needs signals that require soliciting */
|
||||
uint32_t _can_h; //!< Session handle for catching response params.
|
||||
int32_t _can_stat; //!< Session handle status.
|
||||
struct tCANStreamMessage _msgBuff[20];
|
||||
static int const kMsgCapacity = 20;
|
||||
typedef std::map<uint32_t, uint32_t> sigs_t;
|
||||
sigs_t _sigs; //!< Catches signal updates that are solicited. Expect this to be very few.
|
||||
void OpenSessionIfNeedBe();
|
||||
void ProcessStreamMessages();
|
||||
/**
|
||||
* Send a one shot frame to set an arbitrary signal.
|
||||
* Most signals are in the control frame so avoid using this API unless you have to.
|
||||
* Use this api for...
|
||||
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
|
||||
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
|
||||
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
|
||||
*/
|
||||
CTR_Code SetParamRaw(uint32_t paramEnum, int32_t rawBits);
|
||||
/**
|
||||
* Checks cached CAN frames and updating solicited signals.
|
||||
*/
|
||||
CTR_Code GetParamResponseRaw(uint32_t paramEnum, int32_t & rawBits);
|
||||
public:
|
||||
static const int kDefaultControlPeriodMs = 10; //!< default control update rate is 10ms.
|
||||
CanTalonSRX(int deviceNumber = 0,int controlPeriodMs = kDefaultControlPeriodMs);
|
||||
~CanTalonSRX();
|
||||
void Set(double value);
|
||||
/* mode select enumerations */
|
||||
static const int kMode_DutyCycle = 0; //!< Demand is 11bit signed duty cycle [-1023,1023].
|
||||
static const int kMode_PositionCloseLoop = 1; //!< Position PIDF.
|
||||
static const int kMode_VelocityCloseLoop = 2; //!< Velocity PIDF.
|
||||
static const int kMode_CurrentCloseLoop = 3; //!< Current close loop - not done.
|
||||
static const int kMode_VoltCompen = 4; //!< Voltage Compensation Mode - not done. Demand is fixed pt target 8.8 volts.
|
||||
static const int kMode_SlaveFollower = 5; //!< Demand is the 6 bit Device ID of the 'master' TALON SRX.
|
||||
static const int kMode_NoDrive = 15; //!< Zero the output (honors brake/coast) regardless of demand. Might be useful if we need to change modes but can't atomically change all the signals we want in between.
|
||||
/* limit switch enumerations */
|
||||
static const int kLimitSwitchOverride_UseDefaultsFromFlash = 1;
|
||||
static const int kLimitSwitchOverride_DisableFwd_DisableRev = 4;
|
||||
static const int kLimitSwitchOverride_DisableFwd_EnableRev = 5;
|
||||
static const int kLimitSwitchOverride_EnableFwd_DisableRev = 6;
|
||||
static const int kLimitSwitchOverride_EnableFwd_EnableRev = 7;
|
||||
/* brake override enumerations */
|
||||
static const int kBrakeOverride_UseDefaultsFromFlash = 0;
|
||||
static const int kBrakeOverride_OverrideCoast = 1;
|
||||
static const int kBrakeOverride_OverrideBrake = 2;
|
||||
/* feedback device enumerations */
|
||||
static const int kFeedbackDev_DigitalQuadEnc=0;
|
||||
static const int kFeedbackDev_AnalogPot=2;
|
||||
static const int kFeedbackDev_AnalogEncoder=3;
|
||||
static const int kFeedbackDev_CountEveryRisingEdge=4;
|
||||
static const int kFeedbackDev_CountEveryFallingEdge=5;
|
||||
static const int kFeedbackDev_PosIsPulseWidth=8;
|
||||
/* ProfileSlotSelect enumerations*/
|
||||
static const int kProfileSlotSelect_Slot0 = 0;
|
||||
static const int kProfileSlotSelect_Slot1 = 1;
|
||||
/* status frame rate types */
|
||||
static const int kStatusFrame_General = 0;
|
||||
static const int kStatusFrame_Feedback = 1;
|
||||
static const int kStatusFrame_Encoder = 2;
|
||||
static const int kStatusFrame_AnalogTempVbat = 3;
|
||||
/**
|
||||
* Signal enumeration for generic signal access.
|
||||
* Although every signal is enumerated, only use this for traffic that must be solicited.
|
||||
* Use the auto generated getters/setters at bottom of this header as much as possible.
|
||||
*/
|
||||
typedef enum _param_t{
|
||||
eProfileParamSlot0_P=1,
|
||||
eProfileParamSlot0_I=2,
|
||||
eProfileParamSlot0_D=3,
|
||||
eProfileParamSlot0_F=4,
|
||||
eProfileParamSlot0_IZone=5,
|
||||
eProfileParamSlot0_CloseLoopRampRate=6,
|
||||
eProfileParamSlot1_P=11,
|
||||
eProfileParamSlot1_I=12,
|
||||
eProfileParamSlot1_D=13,
|
||||
eProfileParamSlot1_F=14,
|
||||
eProfileParamSlot1_IZone=15,
|
||||
eProfileParamSlot1_CloseLoopRampRate=16,
|
||||
eProfileParamSoftLimitForThreshold=21,
|
||||
eProfileParamSoftLimitRevThreshold=22,
|
||||
eProfileParamSoftLimitForEnable=23,
|
||||
eProfileParamSoftLimitRevEnable=24,
|
||||
eOnBoot_BrakeMode=31,
|
||||
eOnBoot_LimitSwitch_Forward_NormallyClosed=32,
|
||||
eOnBoot_LimitSwitch_Reverse_NormallyClosed=33,
|
||||
eOnBoot_LimitSwitch_Forward_Disable=34,
|
||||
eOnBoot_LimitSwitch_Reverse_Disable=35,
|
||||
eFault_OverTemp=41,
|
||||
eFault_UnderVoltage=42,
|
||||
eFault_ForLim=43,
|
||||
eFault_RevLim=44,
|
||||
eFault_HardwareFailure=45,
|
||||
eFault_ForSoftLim=46,
|
||||
eFault_RevSoftLim=47,
|
||||
eStckyFault_OverTemp=48,
|
||||
eStckyFault_UnderVoltage=49,
|
||||
eStckyFault_ForLim=50,
|
||||
eStckyFault_RevLim=51,
|
||||
eStckyFault_ForSoftLim=52,
|
||||
eStckyFault_RevSoftLim=53,
|
||||
eAppliedThrottle=61,
|
||||
eCloseLoopErr=62,
|
||||
eFeedbackDeviceSelect=63,
|
||||
eRevMotDuringCloseLoopEn=64,
|
||||
eModeSelect=65,
|
||||
eProfileSlotSelect=66,
|
||||
eRampThrottle=67,
|
||||
eRevFeedbackSensor=68,
|
||||
eLimitSwitchEn=69,
|
||||
eLimitSwitchClosedFor=70,
|
||||
eLimitSwitchClosedRev=71,
|
||||
eSensorPosition=73,
|
||||
eSensorVelocity=74,
|
||||
eCurrent=75,
|
||||
eBrakeIsEnabled=76,
|
||||
eEncPosition=77,
|
||||
eEncVel=78,
|
||||
eEncIndexRiseEvents=79,
|
||||
eQuadApin=80,
|
||||
eQuadBpin=81,
|
||||
eQuadIdxpin=82,
|
||||
eAnalogInWithOv=83,
|
||||
eAnalogInVel=84,
|
||||
eTemp=85,
|
||||
eBatteryV=86,
|
||||
eResetCount=87,
|
||||
eResetFlags=88,
|
||||
eFirmVers=89,
|
||||
eSettingsChanged=90,
|
||||
}param_t;
|
||||
/*---------------------setters and getters that use the solicated param request/response-------------*//**
|
||||
* Send a one shot frame to set an arbitrary signal.
|
||||
* Most signals are in the control frame so avoid using this API unless you have to.
|
||||
* Use this api for...
|
||||
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
|
||||
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
|
||||
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
|
||||
*/
|
||||
CTR_Code SetParam(param_t paramEnum, double value);
|
||||
/**
|
||||
* Asks TALON to immedietely respond with signal value. This API is only used for signals that are not sent periodically.
|
||||
* This can be useful for reading params that rarely change like Limit Switch settings and PIDF values.
|
||||
* @param param to request.
|
||||
*/
|
||||
CTR_Code RequestParam(param_t paramEnum);
|
||||
CTR_Code GetParamResponse(param_t paramEnum, double & value);
|
||||
CTR_Code GetParamResponseInt32(param_t paramEnum, int & value);
|
||||
/*----- getters and setters that use param request/response. These signals are backed up in flash and will survive a power cycle. ---------*/
|
||||
/*----- If your application requires changing these values consider using both slots and switch between slot0 <=> slot1. ------------------*/
|
||||
/*----- If your application requires changing these signals frequently then it makes sense to leverage this API. --------------------------*/
|
||||
/*----- Getters don't block, so it may require several calls to get the latest value. --------------------------*/
|
||||
CTR_Code SetPgain(unsigned slotIdx,double gain);
|
||||
CTR_Code SetIgain(unsigned slotIdx,double gain);
|
||||
CTR_Code SetDgain(unsigned slotIdx,double gain);
|
||||
CTR_Code SetFgain(unsigned slotIdx,double gain);
|
||||
CTR_Code SetIzone(unsigned slotIdx,int zone);
|
||||
CTR_Code SetCloseLoopRampRate(unsigned slotIdx,int closeLoopRampRate);
|
||||
CTR_Code SetSensorPosition(int pos);
|
||||
CTR_Code SetForwardSoftLimit(int forwardLimit);
|
||||
CTR_Code SetReverseSoftLimit(int reverseLimit);
|
||||
CTR_Code SetForwardSoftEnable(int enable);
|
||||
CTR_Code SetReverseSoftEnable(int enable);
|
||||
CTR_Code GetPgain(unsigned slotIdx,double & gain);
|
||||
CTR_Code GetIgain(unsigned slotIdx,double & gain);
|
||||
CTR_Code GetDgain(unsigned slotIdx,double & gain);
|
||||
CTR_Code GetFgain(unsigned slotIdx,double & gain);
|
||||
CTR_Code GetIzone(unsigned slotIdx,int & zone);
|
||||
CTR_Code GetCloseLoopRampRate(unsigned slotIdx,int & closeLoopRampRate);
|
||||
CTR_Code GetForwardSoftLimit(int & forwardLimit);
|
||||
CTR_Code GetReverseSoftLimit(int & reverseLimit);
|
||||
CTR_Code GetForwardSoftEnable(int & enable);
|
||||
CTR_Code GetReverseSoftEnable(int & enable);
|
||||
/**
|
||||
* Change the periodMs of a TALON's status frame. See kStatusFrame_* enums for what's available.
|
||||
*/
|
||||
CTR_Code SetStatusFrameRate(unsigned frameEnum, unsigned periodMs);
|
||||
/**
|
||||
* Clear all sticky faults in TALON.
|
||||
*/
|
||||
CTR_Code ClearStickyFaults();
|
||||
/*------------------------ auto generated. This API is optimal since it uses the fire-and-forget CAN interface ----------------------*/
|
||||
/*------------------------ These signals should cover the majority of all use cases. ----------------------------------*/
|
||||
CTR_Code GetFault_OverTemp(int ¶m);
|
||||
CTR_Code GetFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetFault_ForLim(int ¶m);
|
||||
CTR_Code GetFault_RevLim(int ¶m);
|
||||
CTR_Code GetFault_HardwareFailure(int ¶m);
|
||||
CTR_Code GetFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_OverTemp(int ¶m);
|
||||
CTR_Code GetStckyFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetStckyFault_ForLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevLim(int ¶m);
|
||||
CTR_Code GetStckyFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetAppliedThrottle(int ¶m);
|
||||
CTR_Code GetCloseLoopErr(int ¶m);
|
||||
CTR_Code GetFeedbackDeviceSelect(int ¶m);
|
||||
CTR_Code GetModeSelect(int ¶m);
|
||||
CTR_Code GetLimitSwitchEn(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedFor(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedRev(int ¶m);
|
||||
CTR_Code GetSensorPosition(int ¶m);
|
||||
CTR_Code GetSensorVelocity(int ¶m);
|
||||
CTR_Code GetCurrent(double ¶m);
|
||||
CTR_Code GetBrakeIsEnabled(int ¶m);
|
||||
CTR_Code GetEncPosition(int ¶m);
|
||||
CTR_Code GetEncVel(int ¶m);
|
||||
CTR_Code GetEncIndexRiseEvents(int ¶m);
|
||||
CTR_Code GetQuadApin(int ¶m);
|
||||
CTR_Code GetQuadBpin(int ¶m);
|
||||
CTR_Code GetQuadIdxpin(int ¶m);
|
||||
CTR_Code GetAnalogInWithOv(int ¶m);
|
||||
CTR_Code GetAnalogInVel(int ¶m);
|
||||
CTR_Code GetTemp(double ¶m);
|
||||
CTR_Code GetBatteryV(double ¶m);
|
||||
CTR_Code GetResetCount(int ¶m);
|
||||
CTR_Code GetResetFlags(int ¶m);
|
||||
CTR_Code GetFirmVers(int ¶m);
|
||||
CTR_Code SetDemand(int param);
|
||||
CTR_Code SetOverrideLimitSwitchEn(int param);
|
||||
CTR_Code SetFeedbackDeviceSelect(int param);
|
||||
CTR_Code SetRevMotDuringCloseLoopEn(int param);
|
||||
CTR_Code SetOverrideBrakeType(int param);
|
||||
CTR_Code SetModeSelect(int param);
|
||||
CTR_Code SetProfileSlotSelect(int param);
|
||||
CTR_Code SetRampThrottle(int param);
|
||||
CTR_Code SetRevFeedbackSensor(int param);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,98 +1,101 @@
|
||||
#include "CtreCanNode.h"
|
||||
#include "NetworkCommunication/CANSessionMux.h"
|
||||
#include <string.h> // memset
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
static const UINT32 kFullMessageIDMask = 0x1fffffff;
|
||||
|
||||
CtreCanNode::CtreCanNode(UINT8 deviceNumber)
|
||||
{
|
||||
_deviceNumber = deviceNumber;
|
||||
}
|
||||
CtreCanNode::~CtreCanNode()
|
||||
{
|
||||
}
|
||||
void CtreCanNode::RegisterRx(uint32_t arbId)
|
||||
{
|
||||
/* no need to do anything, we just use new API to poll last received message */
|
||||
}
|
||||
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
txJob_t job;
|
||||
job.arbId = arbId;
|
||||
job.periodMs = periodMs;
|
||||
_txJobs[arbId] = job;
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
|
||||
job.toSend,
|
||||
8,
|
||||
job.periodMs,
|
||||
&status);
|
||||
}
|
||||
timespec diff(const timespec & start, const timespec & end)
|
||||
{
|
||||
timespec temp;
|
||||
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||
} else {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
|
||||
{
|
||||
CTR_Code retval = CTR_OKAY;
|
||||
int32_t status = 0;
|
||||
uint8_t len = 0;
|
||||
uint32_t timeStamp;
|
||||
/* cap timeout at 999ms */
|
||||
if(timeoutMs > 999)
|
||||
timeoutMs = 999;
|
||||
FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
|
||||
if(status == 0){
|
||||
/* fresh update */
|
||||
rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
|
||||
clock_gettime(2,&r.time); /* fill in time */
|
||||
memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
|
||||
}else{
|
||||
/* did not get the message */
|
||||
rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
|
||||
if(i == _rxRxEvents.end()){
|
||||
/* we've never gotten this mesage */
|
||||
retval = CTR_RxTimeout;
|
||||
/* fill caller's buffer with zeros */
|
||||
memset(dataBytes,0,8);
|
||||
}else{
|
||||
/* we've gotten this message before but not recently */
|
||||
memcpy(dataBytes,i->second.bytes,8);
|
||||
/* get the time now */
|
||||
struct timespec temp;
|
||||
clock_gettime(2,&temp); /* get now */
|
||||
/* how long has it been? */
|
||||
temp = diff(i->second.time,temp); /* temp = now - last */
|
||||
if(temp.tv_sec > 0){
|
||||
retval = CTR_RxTimeout;
|
||||
}else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){
|
||||
retval = CTR_RxTimeout;
|
||||
}else {
|
||||
/* our last update was recent enough */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void CtreCanNode::FlushTx(uint32_t arbId)
|
||||
{
|
||||
int32_t status = 0;
|
||||
txJobs_t::iterator iter = _txJobs.find(arbId);
|
||||
if(iter != _txJobs.end())
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
|
||||
iter->second.toSend,
|
||||
8,
|
||||
iter->second.periodMs,
|
||||
&status);
|
||||
}
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
|
||||
#include "CtreCanNode.h"
|
||||
#include "NetworkCommunication/CANSessionMux.h"
|
||||
#include <string.h> // memset
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
static const UINT32 kFullMessageIDMask = 0x1fffffff;
|
||||
|
||||
CtreCanNode::CtreCanNode(UINT8 deviceNumber)
|
||||
{
|
||||
_deviceNumber = deviceNumber;
|
||||
}
|
||||
CtreCanNode::~CtreCanNode()
|
||||
{
|
||||
}
|
||||
void CtreCanNode::RegisterRx(uint32_t arbId)
|
||||
{
|
||||
/* no need to do anything, we just use new API to poll last received message */
|
||||
}
|
||||
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
txJob_t job = {0};
|
||||
job.arbId = arbId;
|
||||
job.periodMs = periodMs;
|
||||
_txJobs[arbId] = job;
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
|
||||
job.toSend,
|
||||
8,
|
||||
job.periodMs,
|
||||
&status);
|
||||
}
|
||||
timespec diff(const timespec & start, const timespec & end)
|
||||
{
|
||||
timespec temp;
|
||||
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||
} else {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
|
||||
{
|
||||
CTR_Code retval = CTR_OKAY;
|
||||
int32_t status = 0;
|
||||
uint8_t len = 0;
|
||||
uint32_t timeStamp;
|
||||
/* cap timeout at 999ms */
|
||||
if(timeoutMs > 999)
|
||||
timeoutMs = 999;
|
||||
FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
|
||||
if(status == 0){
|
||||
/* fresh update */
|
||||
rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
|
||||
clock_gettime(2,&r.time); /* fill in time */
|
||||
memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
|
||||
}else{
|
||||
/* did not get the message */
|
||||
rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
|
||||
if(i == _rxRxEvents.end()){
|
||||
/* we've never gotten this mesage */
|
||||
retval = CTR_RxTimeout;
|
||||
/* fill caller's buffer with zeros */
|
||||
memset(dataBytes,0,8);
|
||||
}else{
|
||||
/* we've gotten this message before but not recently */
|
||||
memcpy(dataBytes,i->second.bytes,8);
|
||||
/* get the time now */
|
||||
struct timespec temp;
|
||||
clock_gettime(2,&temp); /* get now */
|
||||
/* how long has it been? */
|
||||
temp = diff(i->second.time,temp); /* temp = now - last */
|
||||
if(temp.tv_sec > 0){
|
||||
retval = CTR_RxTimeout;
|
||||
}else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){
|
||||
retval = CTR_RxTimeout;
|
||||
}else {
|
||||
/* our last update was recent enough */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void CtreCanNode::FlushTx(uint32_t arbId)
|
||||
{
|
||||
int32_t status = 0;
|
||||
txJobs_t::iterator iter = _txJobs.find(arbId);
|
||||
if(iter != _txJobs.end())
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
|
||||
iter->second.toSend,
|
||||
8,
|
||||
iter->second.periodMs,
|
||||
&status);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,121 +1,116 @@
|
||||
#ifndef CtreCanNode_H_
|
||||
#define CtreCanNode_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include "NetworkCommunication/CANSessionMux.h" //CAN Comm
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <string.h> // memcpy
|
||||
#include <sys/time.h>
|
||||
class CtreCanNode
|
||||
{
|
||||
public:
|
||||
CtreCanNode(UINT8 deviceNumber);
|
||||
~CtreCanNode();
|
||||
|
||||
UINT8 GetDeviceNumber()
|
||||
{
|
||||
return _deviceNumber;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
template <typename T> class txTask{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
T * toSend;
|
||||
T * operator -> ()
|
||||
{
|
||||
return toSend;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *toSend;
|
||||
}
|
||||
bool IsEmpty()
|
||||
{
|
||||
if(toSend == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template <typename T> class recMsg{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t bytes[8];
|
||||
CTR_Code err;
|
||||
T * operator -> ()
|
||||
{
|
||||
return (T *)bytes;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *(T *)bytes;
|
||||
}
|
||||
};
|
||||
UINT8 _deviceNumber;
|
||||
void RegisterRx(uint32_t arbId);
|
||||
void RegisterTx(uint32_t arbId, uint32_t periodMs);
|
||||
|
||||
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
|
||||
void FlushTx(uint32_t arbId);
|
||||
|
||||
template<typename T> txTask<T> GetTx(uint32_t arbId)
|
||||
{
|
||||
txTask<T> retval = {0};
|
||||
txJobs_t::iterator i = _txJobs.find(arbId);
|
||||
if(i != _txJobs.end()){
|
||||
retval.arbId = i->second.arbId;
|
||||
retval.toSend = (T*)i->second.toSend;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
template<class T> void FlushTx(T & par)
|
||||
{
|
||||
FlushTx(par.arbId);
|
||||
}
|
||||
|
||||
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
|
||||
{
|
||||
recMsg<T> retval;
|
||||
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class txJob_t {
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t toSend[8];
|
||||
uint32_t periodMs;
|
||||
txJob_t() : arbId(0),periodMs(0)
|
||||
{
|
||||
for(unsigned i=0;i<sizeof(toSend);++i)
|
||||
toSend[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class rxEvent_t{
|
||||
public:
|
||||
uint8_t bytes[8];
|
||||
struct timespec time;
|
||||
rxEvent_t()
|
||||
{
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
bytes[4] = 0;
|
||||
bytes[5] = 0;
|
||||
bytes[6] = 0;
|
||||
bytes[7] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint32_t,txJob_t> txJobs_t;
|
||||
txJobs_t _txJobs;
|
||||
|
||||
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
|
||||
rxRxEvents_t _rxRxEvents;
|
||||
};
|
||||
#endif
|
||||
#ifndef CtreCanNode_H_
|
||||
#define CtreCanNode_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <string.h> // memcpy
|
||||
#include <sys/time.h>
|
||||
class CtreCanNode
|
||||
{
|
||||
public:
|
||||
CtreCanNode(UINT8 deviceNumber);
|
||||
~CtreCanNode();
|
||||
|
||||
UINT8 GetDeviceNumber()
|
||||
{
|
||||
return _deviceNumber;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
template <typename T> class txTask{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
T * toSend;
|
||||
T * operator -> ()
|
||||
{
|
||||
return toSend;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *toSend;
|
||||
}
|
||||
bool IsEmpty()
|
||||
{
|
||||
if(toSend == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template <typename T> class recMsg{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t bytes[8];
|
||||
CTR_Code err;
|
||||
T * operator -> ()
|
||||
{
|
||||
return (T *)bytes;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *(T *)bytes;
|
||||
}
|
||||
};
|
||||
UINT8 _deviceNumber;
|
||||
void RegisterRx(uint32_t arbId);
|
||||
void RegisterTx(uint32_t arbId, uint32_t periodMs);
|
||||
|
||||
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
|
||||
void FlushTx(uint32_t arbId);
|
||||
|
||||
template<typename T> txTask<T> GetTx(uint32_t arbId)
|
||||
{
|
||||
txTask<T> retval = {0, nullptr};
|
||||
txJobs_t::iterator i = _txJobs.find(arbId);
|
||||
if(i != _txJobs.end()){
|
||||
retval.arbId = i->second.arbId;
|
||||
retval.toSend = (T*)i->second.toSend;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
template<class T> void FlushTx(T & par)
|
||||
{
|
||||
FlushTx(par.arbId);
|
||||
}
|
||||
|
||||
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
|
||||
{
|
||||
recMsg<T> retval;
|
||||
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class txJob_t {
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t toSend[8];
|
||||
uint32_t periodMs;
|
||||
};
|
||||
|
||||
class rxEvent_t{
|
||||
public:
|
||||
uint8_t bytes[8];
|
||||
struct timespec time;
|
||||
rxEvent_t()
|
||||
{
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
bytes[4] = 0;
|
||||
bytes[5] = 0;
|
||||
bytes[6] = 0;
|
||||
bytes[7] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint32_t,txJob_t> txJobs_t;
|
||||
txJobs_t _txJobs;
|
||||
|
||||
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
|
||||
rxRxEvents_t _rxRxEvents;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
#define STATUS_1 0x8041400
|
||||
#define STATUS_2 0x8041440
|
||||
#define STATUS_3 0x8041480
|
||||
#define STATUS_ENERGY 0x8041740
|
||||
|
||||
#define CONTROL_1 0x08041C00 /* PDP_Control_ClearStats */
|
||||
|
||||
#define EXPECTED_RESPONSE_TIMEOUT_MS (50)
|
||||
#define GET_STATUS1() CtreCanNode::recMsg<PdpStatus1_t> rx = GetRx<PdpStatus1_t>(STATUS_1,EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS2() CtreCanNode::recMsg<PdpStatus2_t> rx = GetRx<PdpStatus2_t>(STATUS_2,EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS3() CtreCanNode::recMsg<PdpStatus3_t> rx = GetRx<PdpStatus3_t>(STATUS_3,EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS_ENERGY() CtreCanNode::recMsg<PDP_Status_Energy_t> rx = GetRx<PDP_Status_Energy_t>(STATUS_ENERGY,EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
|
||||
/* encoder/decoders */
|
||||
typedef struct _PdpStatus1_t{
|
||||
@@ -56,6 +60,18 @@ typedef struct _PdpStatus3_t{
|
||||
unsigned busVoltage:8;
|
||||
unsigned temp:8;
|
||||
}PdpStatus3_t;
|
||||
typedef struct _PDP_Status_Energy_t {
|
||||
unsigned TmeasMs_likelywillbe20ms_:8;
|
||||
unsigned TotalCurrent_125mAperunit_h8:8;
|
||||
unsigned Power_125mWperunit_h4:4;
|
||||
unsigned TotalCurrent_125mAperunit_l4:4;
|
||||
unsigned Power_125mWperunit_m8:8;
|
||||
unsigned Energy_125mWPerUnitXTmeas_h4:4;
|
||||
unsigned Power_125mWperunit_l4:4;
|
||||
unsigned Energy_125mWPerUnitXTmeas_mh8:8;
|
||||
unsigned Energy_125mWPerUnitXTmeas_ml8:8;
|
||||
unsigned Energy_125mWPerUnitXTmeas_l8:8;
|
||||
} PDP_Status_Energy_t ;
|
||||
|
||||
PDP::PDP(UINT8 deviceNumber): CtreCanNode(deviceNumber)
|
||||
{
|
||||
@@ -128,6 +144,68 @@ CTR_Code PDP::GetTemperature(double &tempC)
|
||||
tempC = (double)raw * 1.03250836957542 - 67.8564500484966;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code PDP::GetTotalCurrent(double ¤tAmps)
|
||||
{
|
||||
GET_STATUS_ENERGY();
|
||||
uint32_t raw;
|
||||
raw = rx->TotalCurrent_125mAperunit_h8;
|
||||
raw <<= 4;
|
||||
raw |= rx->TotalCurrent_125mAperunit_l4;
|
||||
currentAmps = 0.125 * raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code PDP::GetTotalPower(double &powerWatts)
|
||||
{
|
||||
GET_STATUS_ENERGY();
|
||||
uint32_t raw;
|
||||
raw = rx->Power_125mWperunit_h4;
|
||||
raw <<= 8;
|
||||
raw |= rx->Power_125mWperunit_m8;
|
||||
raw <<= 4;
|
||||
raw |= rx->Power_125mWperunit_l4;
|
||||
powerWatts = 0.125 * raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code PDP::GetTotalEnergy(double &energyJoules)
|
||||
{
|
||||
GET_STATUS_ENERGY();
|
||||
uint32_t raw;
|
||||
raw = rx->Energy_125mWPerUnitXTmeas_h4;
|
||||
raw <<= 8;
|
||||
raw |= rx->Energy_125mWPerUnitXTmeas_mh8;
|
||||
raw <<= 8;
|
||||
raw |= rx->Energy_125mWPerUnitXTmeas_ml8;
|
||||
raw <<= 8;
|
||||
raw |= rx->Energy_125mWPerUnitXTmeas_l8;
|
||||
energyJoules = 0.125 * raw; /* mW integrated every TmeasMs */
|
||||
energyJoules *= rx->TmeasMs_likelywillbe20ms_; /* multiplied by TmeasMs = joules */
|
||||
return rx.err;
|
||||
}
|
||||
/* Clear sticky faults.
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
*/
|
||||
CTR_Code PDP::ClearStickyFaults()
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint8_t pdpControl[] = { 0x80 }; /* only bit set is ClearStickyFaults */
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_1 | GetDeviceNumber(), pdpControl, sizeof(pdpControl), 0, &status);
|
||||
if(status)
|
||||
return CTR_TxFailed;
|
||||
return CTR_OKAY;
|
||||
}
|
||||
|
||||
/* Reset Energy Signals
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
*/
|
||||
CTR_Code PDP::ResetEnergy()
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint8_t pdpControl[] = { 0x40 }; /* only bit set is ResetEnergy */
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_1 | GetDeviceNumber(), pdpControl, sizeof(pdpControl), 0, &status);
|
||||
if(status)
|
||||
return CTR_TxFailed;
|
||||
return CTR_OKAY;
|
||||
}
|
||||
//------------------ C interface --------------------------------------------//
|
||||
extern "C" {
|
||||
void * c_PDP_Init(void)
|
||||
|
||||
@@ -38,6 +38,19 @@ public:
|
||||
* @Param - status - Temperature of PDP in Centigrade / Celcius (C)
|
||||
*/
|
||||
CTR_Code GetTemperature(double &status);
|
||||
|
||||
CTR_Code GetTotalCurrent(double ¤tAmps);
|
||||
CTR_Code GetTotalPower(double &powerWatts);
|
||||
CTR_Code GetTotalEnergy(double &energyJoules);
|
||||
/* Clear sticky faults.
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
*/
|
||||
CTR_Code ClearStickyFaults();
|
||||
|
||||
/* Reset Energy Signals
|
||||
* @Return - CTR_Code - Error code (if any)
|
||||
*/
|
||||
CTR_Code ResetEnergy();
|
||||
private:
|
||||
uint64_t ReadCurrents(uint8_t api);
|
||||
};
|
||||
|
||||
@@ -38,23 +38,13 @@ typedef unsigned int UINT;
|
||||
typedef unsigned long ULONG;
|
||||
|
||||
typedef enum {
|
||||
CTR_OKAY, //No Error - Function executed as expected
|
||||
CTR_RxTimeout, /*
|
||||
* Receive Timeout
|
||||
*
|
||||
* No module-specific CAN frames have been received in
|
||||
* the last 50ms. Function returns the latest received data
|
||||
* but may be STALE DATA.
|
||||
*/
|
||||
CTR_TxTimeout, /*
|
||||
* Transmission Timeout
|
||||
*
|
||||
* No module-specific CAN frames were transmitted in
|
||||
* the last 50ms. Parameters passed in by the user are loaded
|
||||
* for next transmission but have not sent.
|
||||
*/
|
||||
CTR_InvalidParamValue,
|
||||
CTR_UnexpectedArbId,
|
||||
CTR_OKAY, //!< No Error - Function executed as expected
|
||||
CTR_RxTimeout, //!< CAN frame has not been received within specified period of time.
|
||||
CTR_TxTimeout, //!< Not used.
|
||||
CTR_InvalidParamValue, //!< Caller passed an invalid param
|
||||
CTR_UnexpectedArbId, //!< Specified CAN Id is invalid.
|
||||
CTR_TxFailed, //!< Could not transmit the CAN frame.
|
||||
CTR_SigNotUpdated, //!< Have not received an value response for signal.
|
||||
}CTR_Code;
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
.PHONY : all build copy-plugins clean docs clean-docs
|
||||
|
||||
all: build copy-plugins
|
||||
@@ -20,15 +25,15 @@ build:
|
||||
|
||||
copy-plugins:
|
||||
mkdir -p plugins
|
||||
cp msgs/build/libgz_msgs.so plugins
|
||||
cp dc_motor/build/libgz_dc_motor.so plugins
|
||||
cp pneumatic_piston/build/libgz_pneumatic_piston.so plugins
|
||||
cp potentiometer/build/libgz_potentiometer.so plugins
|
||||
cp rangefinder/build/libgz_rangefinder.so plugins
|
||||
cp encoder/build/libgz_encoder.so plugins
|
||||
cp gyro/build/libgz_gyro.so plugins
|
||||
cp limit_switch/build/libgz_limit_switch.so plugins
|
||||
cp clock/build/libgz_clock.so plugins
|
||||
cp msgs/build/libgz_msgs$(ext) plugins
|
||||
cp dc_motor/build/libgz_dc_motor$(ext) plugins
|
||||
cp pneumatic_piston/build/libgz_pneumatic_piston$(ext) plugins
|
||||
cp potentiometer/build/libgz_potentiometer$(ext) plugins
|
||||
cp rangefinder/build/libgz_rangefinder$(ext) plugins
|
||||
cp encoder/build/libgz_encoder$(ext) plugins
|
||||
cp gyro/build/libgz_gyro$(ext) plugins
|
||||
cp limit_switch/build/libgz_limit_switch$(ext) plugins
|
||||
cp clock/build/libgz_clock$(ext) plugins
|
||||
|
||||
clean: clean-docs
|
||||
cd msgs && make clean
|
||||
|
||||
@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(gazebo REQUIRED)
|
||||
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp)
|
||||
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
|
||||
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_clock.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_clock$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(gazebo REQUIRED)
|
||||
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp)
|
||||
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
|
||||
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_dc_motor.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_dc_motor$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(gazebo REQUIRED)
|
||||
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp)
|
||||
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
|
||||
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_encoder.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_encoder$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(gazebo REQUIRED)
|
||||
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp)
|
||||
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
|
||||
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_gyro.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_gyro$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(gazebo REQUIRED)
|
||||
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp)
|
||||
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
|
||||
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_limit_switch.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_limit_switch$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_msgs.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_msgs$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(gazebo REQUIRED)
|
||||
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp)
|
||||
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
|
||||
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_pneumatic_piston.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_pneumatic_piston$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(gazebo REQUIRED)
|
||||
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp)
|
||||
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
|
||||
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_potentiometer.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_potentiometer$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(gazebo REQUIRED)
|
||||
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES src/*.cpp)
|
||||
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||
|
||||
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
|
||||
plugin.dir = $(lib.dir)/frcsim/plugins
|
||||
build.dir = build
|
||||
|
||||
ext = .so
|
||||
ifeq ($(shell uname), Darwin)
|
||||
ext = .dylib
|
||||
endif
|
||||
|
||||
all:
|
||||
mkdir -p $(build.dir)
|
||||
cd ${build.dir} && cmake .. && make
|
||||
@@ -12,4 +17,4 @@ clean:
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_rangefinder.so $(DESTDIR)$(plugin.dir)
|
||||
install $(build.dir)/libgz_rangefinder$(ext) $(DESTDIR)$(plugin.dir)
|
||||
|
||||
@@ -5,38 +5,41 @@
|
||||
|
||||
/**
|
||||
* Class for reading analog potentiometers. Analog potentiometers read
|
||||
* in an analog voltage that corresponds to a position. Usually the
|
||||
* position is either degrees or meters. However, if no conversion is
|
||||
* given it remains volts.
|
||||
* 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.
|
||||
*
|
||||
* @author Alex Henning
|
||||
* @author Colby Skeggs (rail voltage)
|
||||
*/
|
||||
class AnalogPotentiometer : public Potentiometer, public LiveWindowSendable {
|
||||
public:
|
||||
/**
|
||||
* AnalogPotentiometer constructor.
|
||||
*
|
||||
* Use the scaling and offset values so that the output produces
|
||||
* 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 scale value is 270.0(degrees)/5.0(volts) and the
|
||||
* offset is -135.0 since the halfway point after scaling is 135
|
||||
* degrees.
|
||||
* 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 channel this potentiometer is plugged into.
|
||||
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
|
||||
* @param fullRange The scaling to multiply the voltage by to get a meaningful unit.
|
||||
* @param offset The offset to add to the scaled value for controlling the zero value
|
||||
*/
|
||||
explicit AnalogPotentiometer(int channel, double scale = 1.0, double offset = 0.0);
|
||||
explicit AnalogPotentiometer(int channel, double fullRange = 1.0, double offset = 0.0);
|
||||
|
||||
explicit AnalogPotentiometer(AnalogInput *input, double scale = 1.0, double offset = 0.0);
|
||||
explicit AnalogPotentiometer(AnalogInput *input, double fullRange = 1.0, double offset = 0.0);
|
||||
|
||||
explicit AnalogPotentiometer(AnalogInput &input, double scale = 1.0, double offset = 0.0);
|
||||
explicit AnalogPotentiometer(AnalogInput &input, double fullRange = 1.0, double offset = 0.0);
|
||||
|
||||
virtual ~AnalogPotentiometer();
|
||||
|
||||
/**
|
||||
* Get the current reading of the potentiomere.
|
||||
* Get the current reading of the potentiomer.
|
||||
*
|
||||
* @return The current position of the potentiometer.
|
||||
*/
|
||||
@@ -70,7 +73,7 @@ public:
|
||||
virtual void StopLiveWindowMode() {}
|
||||
|
||||
private:
|
||||
double m_scale, m_offset;
|
||||
double m_fullRange, m_offset;
|
||||
AnalogInput* m_analog_input;
|
||||
ITable* m_table;
|
||||
bool m_init_analog_input;
|
||||
@@ -78,5 +81,5 @@ private:
|
||||
/**
|
||||
* Common initialization code called by all constructors.
|
||||
*/
|
||||
void initPot(AnalogInput *input, double scale, double offset);
|
||||
void initPot(AnalogInput *input, double fullRange, double offset);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "Resource.h"
|
||||
#include "MotorSafetyHelper.h"
|
||||
#include "PIDOutput.h"
|
||||
#include "SpeedController.h"
|
||||
#include "CANSpeedController.h"
|
||||
#include "HAL/Semaphore.hpp"
|
||||
#include "HAL/HAL.hpp"
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
@@ -20,10 +20,10 @@
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* Luminary Micro Jaguar Speed Control
|
||||
* Luminary Micro / Vex Robotics Jaguar Speed Control
|
||||
*/
|
||||
class CANJaguar : public MotorSafety,
|
||||
public SpeedController,
|
||||
public CANSpeedController,
|
||||
public ErrorBase,
|
||||
public LiveWindowSendable,
|
||||
public ITableListener
|
||||
@@ -41,40 +41,11 @@ public:
|
||||
/** Sets a potentiometer as the position reference only. <br> Passed as the "tag" when setting the control mode. */
|
||||
static const struct PotentiometerStruct {} Potentiometer;
|
||||
|
||||
typedef enum {kPercentVbus, kCurrent, kSpeed, kPosition, kVoltage} ControlMode;
|
||||
typedef enum {kCurrentFault = 1, kTemperatureFault = 2, kBusVoltageFault = 4, kGateDriverFault = 8} Faults;
|
||||
typedef enum {kForwardLimit = 1, kReverseLimit = 2} Limits;
|
||||
typedef enum {
|
||||
kNeutralMode_Jumper = 0, /** Use the NeutralMode that is set by the jumper wire on the CAN device */
|
||||
kNeutralMode_Brake = 1, /** Stop the motor's rotation by applying a force. */
|
||||
kNeutralMode_Coast = 2 /** Do not attempt to stop the motor. Instead allow it to coast to a stop without applying resistance. */
|
||||
} NeutralMode;
|
||||
typedef enum {
|
||||
/**
|
||||
* Disables the soft position limits and only uses the limit switches to limit rotation.
|
||||
* @see CANJaguar#GetForwardLimitOK()
|
||||
* @see CANJaguar#GetReverseLimitOK()
|
||||
*
|
||||
*/
|
||||
kLimitMode_SwitchInputsOnly = 0,
|
||||
/**
|
||||
* Enables the soft position limits on the Jaguar.
|
||||
* These will be used in addition to the limit switches. This does not disable the behavior
|
||||
* of the limit switch input.
|
||||
* @see CANJaguar#ConfigSoftPositionLimits(double, double)
|
||||
*/
|
||||
kLimitMode_SoftPositionLimits = 1
|
||||
} LimitMode;
|
||||
|
||||
explicit CANJaguar(uint8_t deviceNumber);
|
||||
virtual ~CANJaguar();
|
||||
|
||||
uint8_t getDeviceNumber() const;
|
||||
|
||||
// SpeedController interface
|
||||
virtual float Get();
|
||||
virtual void Set(float value, uint8_t syncGroup=0);
|
||||
virtual void Disable();
|
||||
uint8_t GetHardwareVersion();
|
||||
|
||||
// PIDOutput interface
|
||||
virtual void PIDWrite(float output);
|
||||
@@ -104,39 +75,42 @@ public:
|
||||
void SetVoltageMode(QuadEncoderStruct, uint16_t codesPerRev);
|
||||
void SetVoltageMode(PotentiometerStruct);
|
||||
|
||||
// Other Accessors
|
||||
void SetP(double p);
|
||||
void SetI(double i);
|
||||
void SetD(double d);
|
||||
void SetPID(double p, double i, double d);
|
||||
double GetP();
|
||||
double GetI();
|
||||
double GetD();
|
||||
float GetBusVoltage();
|
||||
float GetOutputVoltage();
|
||||
float GetOutputCurrent();
|
||||
float GetTemperature();
|
||||
double GetPosition();
|
||||
double GetSpeed();
|
||||
bool GetForwardLimitOK();
|
||||
bool GetReverseLimitOK();
|
||||
uint16_t GetFaults();
|
||||
void SetVoltageRampRate(double rampRate);
|
||||
virtual uint32_t GetFirmwareVersion();
|
||||
uint8_t GetHardwareVersion();
|
||||
void ConfigNeutralMode(NeutralMode mode);
|
||||
void ConfigEncoderCodesPerRev(uint16_t codesPerRev);
|
||||
void ConfigPotentiometerTurns(uint16_t turns);
|
||||
void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition);
|
||||
void DisableSoftPositionLimits();
|
||||
void ConfigLimitMode(LimitMode mode);
|
||||
void ConfigForwardLimit(double forwardLimitPosition);
|
||||
void ConfigReverseLimit(double reverseLimitPosition);
|
||||
void ConfigMaxOutputVoltage(double voltage);
|
||||
void ConfigFaultTime(float faultTime);
|
||||
ControlMode GetControlMode();
|
||||
// CANSpeedController interface
|
||||
virtual float Get() override;
|
||||
virtual void Set(float value, uint8_t syncGroup=0) override;
|
||||
virtual void Disable() override;
|
||||
virtual void SetP(double p) override;
|
||||
virtual void SetI(double i) override;
|
||||
virtual void SetD(double d) override;
|
||||
virtual void SetPID(double p, double i, double d) override;
|
||||
virtual double GetP() override;
|
||||
virtual double GetI() override;
|
||||
virtual double GetD() override;
|
||||
virtual float GetBusVoltage() override;
|
||||
virtual float GetOutputVoltage() override;
|
||||
virtual float GetOutputCurrent() override;
|
||||
virtual float GetTemperature() override;
|
||||
virtual double GetPosition() override;
|
||||
virtual double GetSpeed() override;
|
||||
virtual bool GetForwardLimitOK() override;
|
||||
virtual bool GetReverseLimitOK() override;
|
||||
virtual uint16_t GetFaults() override;
|
||||
virtual void SetVoltageRampRate(double rampRate) override;
|
||||
virtual uint32_t GetFirmwareVersion() override;
|
||||
virtual void ConfigNeutralMode(NeutralMode mode) override;
|
||||
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) override;
|
||||
virtual void ConfigPotentiometerTurns(uint16_t turns) override;
|
||||
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) override;
|
||||
virtual void DisableSoftPositionLimits() override;
|
||||
virtual void ConfigLimitMode(LimitMode mode) override;
|
||||
virtual void ConfigForwardLimit(double forwardLimitPosition) override;
|
||||
virtual void ConfigReverseLimit(double reverseLimitPosition) override;
|
||||
virtual void ConfigMaxOutputVoltage(double voltage) override;
|
||||
virtual void ConfigFaultTime(float faultTime) override;
|
||||
virtual void SetControlMode(ControlMode mode);
|
||||
virtual ControlMode GetControlMode();
|
||||
|
||||
static void UpdateSyncGroup(uint8_t syncGroup);
|
||||
static void UpdateSyncGroup(uint8_t syncGroup);
|
||||
|
||||
void SetExpiration(float timeout);
|
||||
float GetExpiration();
|
||||
@@ -149,9 +123,6 @@ public:
|
||||
|
||||
protected:
|
||||
// Control mode helpers
|
||||
|
||||
void ChangeControlMode(ControlMode controlMode);
|
||||
|
||||
void SetSpeedReference(uint8_t reference);
|
||||
uint8_t GetSpeedReference();
|
||||
|
||||
|
||||
94
wpilibc/wpilibC++Devices/include/CANSpeedController.h
Normal file
94
wpilibc/wpilibC++Devices/include/CANSpeedController.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2014. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "SpeedController.h"
|
||||
|
||||
/**
|
||||
* Interface for "smart" CAN-based speed controllers.
|
||||
* @see CANJaguar
|
||||
* @see CANTalon
|
||||
*/
|
||||
class CANSpeedController : public SpeedController
|
||||
{
|
||||
public:
|
||||
enum ControlMode {
|
||||
kPercentVbus=0,
|
||||
kCurrent=1,
|
||||
kSpeed=2,
|
||||
kPosition=3,
|
||||
kVoltage=4,
|
||||
kFollower=5 // Not supported in Jaguar.
|
||||
};
|
||||
|
||||
enum Faults {
|
||||
kCurrentFault = 1,
|
||||
kTemperatureFault = 2,
|
||||
kBusVoltageFault = 4,
|
||||
kGateDriverFault = 8,
|
||||
/* SRX extensions */
|
||||
kFwdLimitSwitch = 0x10,
|
||||
kRevLimitSwitch = 0x20,
|
||||
kFwdSoftLimit = 0x40,
|
||||
kRevSoftLimit = 0x80,
|
||||
};
|
||||
|
||||
enum Limits {
|
||||
kForwardLimit = 1,
|
||||
kReverseLimit = 2
|
||||
};
|
||||
|
||||
enum NeutralMode {
|
||||
/** Use the NeutralMode that is set by the jumper wire on the CAN device */
|
||||
kNeutralMode_Jumper = 0,
|
||||
/** Stop the motor's rotation by applying a force. */
|
||||
kNeutralMode_Brake = 1,
|
||||
/** Do not attempt to stop the motor. Instead allow it to coast to a stop without applying resistance. */
|
||||
kNeutralMode_Coast = 2
|
||||
};
|
||||
|
||||
enum LimitMode {
|
||||
/** Only use switches for limits */
|
||||
kLimitMode_SwitchInputsOnly = 0,
|
||||
/** Use both switches and soft limits */
|
||||
kLimitMode_SoftPositionLimits = 1
|
||||
};
|
||||
|
||||
virtual float Get() = 0;
|
||||
virtual void Set(float value, uint8_t syncGroup=0) = 0;
|
||||
virtual void Disable() = 0;
|
||||
virtual void SetP(double p) = 0;
|
||||
virtual void SetI(double i) = 0;
|
||||
virtual void SetD(double d) = 0;
|
||||
virtual void SetPID(double p, double i, double d) = 0;
|
||||
virtual double GetP() = 0;
|
||||
virtual double GetI() = 0;
|
||||
virtual double GetD() = 0;
|
||||
virtual float GetBusVoltage() = 0;
|
||||
virtual float GetOutputVoltage() = 0;
|
||||
virtual float GetOutputCurrent() = 0;
|
||||
virtual float GetTemperature() = 0;
|
||||
virtual double GetPosition() = 0;
|
||||
virtual double GetSpeed() = 0;
|
||||
virtual bool GetForwardLimitOK() = 0;
|
||||
virtual bool GetReverseLimitOK() = 0;
|
||||
virtual uint16_t GetFaults() = 0;
|
||||
virtual void SetVoltageRampRate(double rampRate) = 0;
|
||||
virtual uint32_t GetFirmwareVersion() = 0;
|
||||
virtual void ConfigNeutralMode(NeutralMode mode) = 0;
|
||||
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) = 0;
|
||||
virtual void ConfigPotentiometerTurns(uint16_t turns) = 0;
|
||||
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) = 0;
|
||||
virtual void DisableSoftPositionLimits() = 0;
|
||||
virtual void ConfigLimitMode(LimitMode mode) = 0;
|
||||
virtual void ConfigForwardLimit(double forwardLimitPosition) = 0;
|
||||
virtual void ConfigReverseLimit(double reverseLimitPosition) = 0;
|
||||
virtual void ConfigMaxOutputVoltage(double voltage) = 0;
|
||||
virtual void ConfigFaultTime(float faultTime) = 0;
|
||||
// Hold off on interface until we figure out ControlMode enums.
|
||||
// virtual void SetControlMode(ControlMode mode) = 0;
|
||||
// virtual ControlMode GetControlMode() = 0;
|
||||
};
|
||||
122
wpilibc/wpilibC++Devices/include/CANTalon.h
Normal file
122
wpilibc/wpilibC++Devices/include/CANTalon.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2014. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "SafePWM.h"
|
||||
#include "CANSpeedController.h"
|
||||
#include "PIDOutput.h"
|
||||
#include "MotorSafetyHelper.h"
|
||||
|
||||
class CanTalonSRX;
|
||||
|
||||
/**
|
||||
* CTRE Talon SRX Speed Controller with CAN Control
|
||||
*/
|
||||
class CANTalon : public MotorSafety,
|
||||
public CANSpeedController,
|
||||
public ErrorBase
|
||||
{
|
||||
public:
|
||||
enum FeedbackDevice {
|
||||
QuadEncoder=0,
|
||||
AnalogPot=2,
|
||||
AnalogEncoder=3,
|
||||
EncRising=4,
|
||||
EncFalling=5
|
||||
};
|
||||
explicit CANTalon(int deviceNumber);
|
||||
virtual ~CANTalon();
|
||||
|
||||
// PIDController interface
|
||||
virtual void PIDWrite(float output) override;
|
||||
|
||||
// MotorSafety interface
|
||||
virtual void SetExpiration(float timeout) override;
|
||||
virtual float GetExpiration() override;
|
||||
virtual bool IsAlive() override;
|
||||
virtual void StopMotor() override;
|
||||
virtual void SetSafetyEnabled(bool enabled) override;
|
||||
virtual bool IsSafetyEnabled() override;
|
||||
virtual void GetDescription(char *desc) override;
|
||||
|
||||
// CANSpeedController interface
|
||||
virtual float Get() override;
|
||||
virtual void Set(float value, uint8_t syncGroup=0) override;
|
||||
virtual void Disable() override;
|
||||
virtual void EnableControl();
|
||||
virtual void SetP(double p) override;
|
||||
virtual void SetI(double i) override;
|
||||
virtual void SetD(double d) override;
|
||||
void SetF(double f);
|
||||
virtual void SetPID(double p, double i, double d) override;
|
||||
void SetPID(double p, double i, double d, double f);
|
||||
virtual double GetP() override;
|
||||
virtual double GetI() override;
|
||||
virtual double GetD() override;
|
||||
double GetF();
|
||||
virtual float GetBusVoltage() override;
|
||||
virtual float GetOutputVoltage() override;
|
||||
virtual float GetOutputCurrent() override;
|
||||
virtual float GetTemperature() override;
|
||||
void SetPosition(double pos);
|
||||
virtual double GetPosition() override;
|
||||
virtual double GetSpeed() override;
|
||||
virtual int GetClosedLoopError();
|
||||
virtual int GetAnalogIn();
|
||||
virtual int GetAnalogInVel();
|
||||
virtual int GetEncPosition();
|
||||
virtual int GetEncVel();
|
||||
int GetPinStateQuadA();
|
||||
int GetPinStateQuadB();
|
||||
int GetPinStateQuadIdx();
|
||||
int IsFwdLimitSwitchClosed();
|
||||
int IsRevLimitSwitchClosed();
|
||||
int GetNumberOfQuadIdxRises();
|
||||
void SetNumberOfQuadIdxRises(int rises);
|
||||
virtual bool GetForwardLimitOK() override;
|
||||
virtual bool GetReverseLimitOK() override;
|
||||
virtual uint16_t GetFaults() override;
|
||||
uint16_t GetStickyFaults();
|
||||
void ClearStickyFaults();
|
||||
virtual void SetVoltageRampRate(double rampRate) override;
|
||||
virtual uint32_t GetFirmwareVersion() override;
|
||||
virtual void ConfigNeutralMode(NeutralMode mode) override;
|
||||
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) override;
|
||||
virtual void ConfigPotentiometerTurns(uint16_t turns) override;
|
||||
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) override;
|
||||
virtual void DisableSoftPositionLimits() override;
|
||||
virtual void ConfigLimitMode(LimitMode mode) override;
|
||||
virtual void ConfigForwardLimit(double forwardLimitPosition) override;
|
||||
virtual void ConfigReverseLimit(double reverseLimitPosition) override;
|
||||
virtual void ConfigMaxOutputVoltage(double voltage) override;
|
||||
virtual void ConfigFaultTime(float faultTime) override;
|
||||
virtual void SetControlMode(ControlMode mode);
|
||||
void SetFeedbackDevice(FeedbackDevice device);
|
||||
virtual ControlMode GetControlMode();
|
||||
void SetSensorDirection(bool reverseSensor);
|
||||
void SetCloseLoopRampRate(double rampRate);
|
||||
void SelectProfileSlot(int slotIdx);
|
||||
double GetIzone();
|
||||
private:
|
||||
// Values for various modes as is sent in the CAN packets for the Talon.
|
||||
enum TalonControlMode {
|
||||
kThrottle=0,
|
||||
kFollowerMode=5,
|
||||
kVoltageMode=4,
|
||||
kPositionMode=1,
|
||||
kSpeedMode=2,
|
||||
kCurrentMode=3,
|
||||
kDisabled=15
|
||||
};
|
||||
|
||||
int m_deviceNumber;
|
||||
CanTalonSRX *m_impl;
|
||||
MotorSafetyHelper *m_safetyHelper;
|
||||
int m_profile; // Profile from CANTalon to use. Set to zero until we can actually test this.
|
||||
|
||||
bool m_controlEnabled;
|
||||
ControlMode m_controlMode;
|
||||
};
|
||||
@@ -34,7 +34,11 @@ public:
|
||||
|
||||
float GetStickAxis(uint32_t stick, uint32_t axis);
|
||||
int GetStickPOV(uint32_t stick, uint32_t pov);
|
||||
short GetStickButtons(uint32_t stick);
|
||||
bool GetStickButton(uint32_t stick, uint8_t button);
|
||||
|
||||
int GetStickAxisCount(uint32_t stick);
|
||||
int GetStickPOVCount(uint32_t stick);
|
||||
int GetStickButtonCount(uint32_t stick);
|
||||
|
||||
bool IsEnabled();
|
||||
bool IsDisabled();
|
||||
@@ -53,11 +57,6 @@ public:
|
||||
double GetMatchTime();
|
||||
float GetBatteryVoltage();
|
||||
|
||||
MUTEX_ID GetUserStatusDataSem()
|
||||
{
|
||||
return m_statusDataSemaphore;
|
||||
}
|
||||
|
||||
/** Only to be used to tell the Driver Station what code you claim to be executing
|
||||
* for diagnostic purposes only
|
||||
* @param entering If true, starting disabled code; if false, leaving disabled code */
|
||||
@@ -90,31 +89,21 @@ public:
|
||||
protected:
|
||||
DriverStation();
|
||||
|
||||
void GetData();
|
||||
void SetData();
|
||||
|
||||
private:
|
||||
static void InitTask(DriverStation *ds);
|
||||
static DriverStation *m_instance;
|
||||
|
||||
void ReportJoystickUnpluggedError(std::string message);
|
||||
void Run();
|
||||
|
||||
HALControlWord m_controlWord;
|
||||
HALAllianceStationID m_allianceStationID;
|
||||
HALJoystickAxes m_joystickAxes[kJoystickPorts];
|
||||
HALJoystickPOVs m_joystickPOVs[kJoystickPorts];
|
||||
HALJoystickButtons m_joystickButtons[kJoystickPorts];
|
||||
|
||||
MUTEX_ID m_statusDataSemaphore;
|
||||
Task m_task;
|
||||
SEMAPHORE_ID m_newControlData;
|
||||
MULTIWAIT_ID m_packetDataAvailableMultiWait;
|
||||
MUTEX_ID m_packetDataAvailableMutex;
|
||||
MULTIWAIT_ID m_waitForDataSem;
|
||||
MUTEX_ID m_waitForDataMutex;
|
||||
double m_approxMatchTimeOffset;
|
||||
bool m_userInDisabled;
|
||||
bool m_userInAutonomous;
|
||||
bool m_userInTeleop;
|
||||
bool m_userInTest;
|
||||
double m_nextMessageTime;
|
||||
};
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
void SetDeadband(float volts);
|
||||
void SetPIDSourceParameter(PIDSourceParameter pidSource);
|
||||
virtual void Reset();
|
||||
void InitGyro();
|
||||
|
||||
// PIDSource interface
|
||||
double PIDGet();
|
||||
@@ -51,10 +52,10 @@ public:
|
||||
void InitTable(ITable *subTable);
|
||||
ITable * GetTable();
|
||||
|
||||
private:
|
||||
void InitGyro();
|
||||
|
||||
protected:
|
||||
AnalogInput *m_analog;
|
||||
|
||||
private:
|
||||
float m_voltsPerDegreePerSecond;
|
||||
float m_offset;
|
||||
bool m_channelAllocated;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "PIDOutput.h"
|
||||
|
||||
/**
|
||||
* Luminary Micro Jaguar Speed Control
|
||||
* Luminary Micro / Vex Robotics Jaguar Speed Controller with PWM control
|
||||
*/
|
||||
class Jaguar : public SafePWM, public SpeedController
|
||||
{
|
||||
|
||||
@@ -37,6 +37,10 @@ public:
|
||||
{
|
||||
kTriggerButton, kTopButton, kNumButtonTypes
|
||||
} ButtonType;
|
||||
typedef enum
|
||||
{
|
||||
kLeftRumble, kRightRumble
|
||||
} RumbleType;
|
||||
|
||||
explicit Joystick(uint32_t port);
|
||||
Joystick(uint32_t port, uint32_t numAxisTypes, uint32_t numButtonTypes);
|
||||
@@ -65,6 +69,14 @@ public:
|
||||
virtual float GetDirectionRadians();
|
||||
virtual float GetDirectionDegrees();
|
||||
|
||||
int GetAxisCount();
|
||||
int GetButtonCount();
|
||||
int GetPOVCount();
|
||||
|
||||
void SetRumble(RumbleType type, float value);
|
||||
void SetOutput(uint8_t outputNumber, bool value);
|
||||
void SetOutputs(uint32_t value);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Joystick);
|
||||
void InitJoystick(uint32_t numAxisTypes, uint32_t numButtonTypes);
|
||||
@@ -73,6 +85,9 @@ private:
|
||||
uint32_t m_port;
|
||||
uint32_t *m_axes;
|
||||
uint32_t *m_buttons;
|
||||
uint32_t m_outputs;
|
||||
uint16_t m_leftRumble;
|
||||
uint16_t m_rightRumble;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,11 @@ class PowerDistributionPanel : public SensorBase {
|
||||
double GetVoltage();
|
||||
double GetTemperature();
|
||||
double GetCurrent(uint8_t channel);
|
||||
double GetTotalCurrent();
|
||||
double GetTotalPower();
|
||||
double GetTotalEnergy();
|
||||
void ResetTotalEnergy();
|
||||
void ClearStickyFaults();
|
||||
};
|
||||
|
||||
#endif /* __WPILIB_POWER_DISTRIBUTION_PANEL_H__ */
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "PIDOutput.h"
|
||||
|
||||
/**
|
||||
* CTRE Talon Speed Controller
|
||||
* Cross the Road Electronics (CTRE) Talon and Talon SR Speed Controller
|
||||
*/
|
||||
class Talon : public SafePWM, public SpeedController
|
||||
{
|
||||
|
||||
18
wpilibc/wpilibC++Devices/include/TalonSRX.h
Normal file
18
wpilibc/wpilibC++Devices/include/TalonSRX.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "Talon.h"
|
||||
|
||||
/**
|
||||
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control
|
||||
* @see CANTalon for CAN control
|
||||
*/
|
||||
class TalonSRX: public Talon {
|
||||
public:
|
||||
explicit TalonSRX(uint32_t channel);
|
||||
virtual ~TalonSRX();
|
||||
};
|
||||
@@ -10,7 +10,10 @@
|
||||
#include "PIDOutput.h"
|
||||
|
||||
/**
|
||||
* IFI Victor Speed Controller
|
||||
* Vex Robotics Victor 888 Speed Controller
|
||||
*
|
||||
* The Vex Robotics Victor 884 Speed Controller can also be used with this
|
||||
* class but may need to be calibrated per the Victor 884 user manual.
|
||||
*/
|
||||
class Victor : public SafePWM, public SpeedController
|
||||
{
|
||||
|
||||
17
wpilibc/wpilibC++Devices/include/VictorSP.h
Normal file
17
wpilibc/wpilibC++Devices/include/VictorSP.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
|
||||
#include "Talon.h"
|
||||
|
||||
/**
|
||||
* Vex Robotics Victor SP Speed Controller
|
||||
*/
|
||||
class VictorSP: public Talon {
|
||||
public:
|
||||
explicit VictorSP(uint32_t channel);
|
||||
virtual ~VictorSP();
|
||||
};
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Buttons/NetworkButton.h"
|
||||
#include "CameraServer.h"
|
||||
#include "CANJaguar.h"
|
||||
#include "CANTalon.h"
|
||||
#include "Commands/Command.h"
|
||||
#include "Commands/CommandGroup.h"
|
||||
#include "Commands/PIDCommand.h"
|
||||
@@ -77,10 +78,12 @@
|
||||
#include "SPI.h"
|
||||
#include "HAL/cpp/Synchronized.hpp"
|
||||
#include "Talon.h"
|
||||
#include "TalonSRX.h"
|
||||
#include "Task.h"
|
||||
#include "Timer.h"
|
||||
#include "Ultrasonic.h"
|
||||
#include "Utility.h"
|
||||
#include "Victor.h"
|
||||
#include "VictorSP.h"
|
||||
// XXX: #include "Vision/AxisCamera.h"
|
||||
#include "WPIErrors.h"
|
||||
|
||||
316
wpilibc/wpilibC++Devices/include/ctre/CanTalonSRX.h
Normal file
316
wpilibc/wpilibC++Devices/include/ctre/CanTalonSRX.h
Normal file
@@ -0,0 +1,316 @@
|
||||
/**
|
||||
* @brief CAN TALON SRX driver.
|
||||
*
|
||||
* The TALON SRX is designed to instrument all runtime signals periodically. The default periods are chosen to support 16 TALONs
|
||||
* with 10ms update rate for control (throttle or setpoint). However these can be overridden with SetStatusFrameRate. @see SetStatusFrameRate
|
||||
* The getters for these unsolicited signals are auto generated at the bottom of this module.
|
||||
*
|
||||
* Likewise most control signals are sent periodically using the fire-and-forget CAN API.
|
||||
* The setters for these unsolicited signals are auto generated at the bottom of this module.
|
||||
*
|
||||
* Signals that are not available in an unsolicited fashion are the Close Loop gains.
|
||||
* For teams that have a single profile for their TALON close loop they can use either the webpage to configure their TALONs once
|
||||
* or set the PIDF,Izone,CloseLoopRampRate,etc... once in the robot application. These parameters are saved to flash so once they are
|
||||
* loaded in the TALON, they will persist through power cycles and mode changes.
|
||||
*
|
||||
* For teams that have one or two profiles to switch between, they can use the same strategy since there are two slots to choose from
|
||||
* and the ProfileSlotSelect is periodically sent in the 10 ms control frame.
|
||||
*
|
||||
* For teams that require changing gains frequently, they can use the soliciting API to get and set those parameters. Most likely
|
||||
* they will only need to set them in a periodic fashion as a function of what motion the application is attempting.
|
||||
* If this API is used, be mindful of the CAN utilization reported in the driver station.
|
||||
*
|
||||
* Encoder position is measured in encoder edges. Every edge is counted (similar to roboRIO 4X mode).
|
||||
* Analog position is 10 bits, meaning 1024 ticks per rotation (0V => 3.3V).
|
||||
* Use SetFeedbackDeviceSelect to select which sensor type you need. Once you do that you can use GetSensorPosition()
|
||||
* and GetSensorVelocity(). These signals are updated on CANBus every 20ms (by default).
|
||||
* If a relative sensor is selected, you can zero (or change the current value) using SetSensorPosition.
|
||||
*
|
||||
* Analog Input and quadrature position (and velocity) are also explicitly reported in GetEncPosition, GetEncVel, GetAnalogInWithOv, GetAnalogInVel.
|
||||
* These signals are available all the time, regardless of what sensor is selected at a rate of 100ms. This allows easy instrumentation
|
||||
* for "in the pits" checking of all sensors regardless of modeselect. The 100ms rate is overridable for teams who want to acquire sensor
|
||||
* data for processing, not just instrumentation. Or just select the sensor using SetFeedbackDeviceSelect to get it at 20ms.
|
||||
*
|
||||
* Velocity is in position ticks / 100ms.
|
||||
*
|
||||
* All output units are in respect to duty cycle (throttle) which is -1023(full reverse) to +1023 (full forward).
|
||||
* This includes demand (which specifies duty cycle when in duty cycle mode) and rampRamp, which is in throttle units per 10ms (if nonzero).
|
||||
*
|
||||
* Pos and velocity close loops are calc'd as
|
||||
* err = target - posOrVel.
|
||||
* iErr += err;
|
||||
* if( (IZone!=0) and abs(err) > IZone)
|
||||
* ClearIaccum()
|
||||
* output = P X err + I X iErr + D X dErr + F X target
|
||||
* dErr = err - lastErr
|
||||
* P, I,and D gains are always positive. F can be negative.
|
||||
* Motor direction can be reversed using SetRevMotDuringCloseLoopEn if sensor and motor are out of phase.
|
||||
* Similarly feedback sensor can also be reversed (multiplied by -1) if you prefer the sensor to be inverted.
|
||||
*
|
||||
* P gain is specified in throttle per error tick. For example, a value of 102 is ~9.9% (which is 102/1023) throttle per 1
|
||||
* ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
|
||||
*
|
||||
* I gain is specified in throttle per integrated error. For example, a value of 10 equates to ~0.99% (which is 10/1023)
|
||||
* for each accumulated ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
|
||||
* Close loop and integral accumulator runs every 1ms.
|
||||
*
|
||||
* D gain is specified in throttle per derivative error. For example a value of 102 equates to ~9.9% (which is 102/1023)
|
||||
* per change of 1 unit (ADC or encoder) per ms.
|
||||
*
|
||||
* I Zone is specified in the same units as sensor position (ADC units or quadrature edges). If pos/vel error is outside of
|
||||
* this value, the integrated error will auto-clear...
|
||||
* if( (IZone!=0) and abs(err) > IZone)
|
||||
* ClearIaccum()
|
||||
* ...this is very useful in preventing integral windup and is highly recommended if using full PID to keep stability low.
|
||||
*
|
||||
* CloseLoopRampRate ramps the target of the close loop. The units are in position per 1ms. Set to zero to disable ramping.
|
||||
* So a value of 10 means allow the target input of the close loop to approach the user's demand by 10 units (ADC or encoder edges)
|
||||
* per 1ms.
|
||||
*
|
||||
* auto generated using spreadsheet and WpiClassGen.csproj
|
||||
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
|
||||
*/
|
||||
#ifndef CanTalonSRX_H_
|
||||
#define CanTalonSRX_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include "CtreCanNode.h"
|
||||
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
#include <map>
|
||||
class CanTalonSRX : public CtreCanNode
|
||||
{
|
||||
private:
|
||||
|
||||
/** just in case user wants to modify periods of certain status frames.
|
||||
* Default the vars to match the firmware default. */
|
||||
uint32_t _statusRateMs[4];
|
||||
//---------------------- Vars for opening a CAN stream if caller needs signals that require soliciting */
|
||||
uint32_t _can_h; //!< Session handle for catching response params.
|
||||
int32_t _can_stat; //!< Session handle status.
|
||||
struct tCANStreamMessage _msgBuff[20];
|
||||
static int const kMsgCapacity = 20;
|
||||
typedef std::map<uint32_t, uint32_t> sigs_t;
|
||||
sigs_t _sigs; //!< Catches signal updates that are solicited. Expect this to be very few.
|
||||
void OpenSessionIfNeedBe();
|
||||
void ProcessStreamMessages();
|
||||
/**
|
||||
* Send a one shot frame to set an arbitrary signal.
|
||||
* Most signals are in the control frame so avoid using this API unless you have to.
|
||||
* Use this api for...
|
||||
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
|
||||
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
|
||||
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
|
||||
*/
|
||||
CTR_Code SetParamRaw(uint32_t paramEnum, int32_t rawBits);
|
||||
/**
|
||||
* Checks cached CAN frames and updating solicited signals.
|
||||
*/
|
||||
CTR_Code GetParamResponseRaw(uint32_t paramEnum, int32_t & rawBits);
|
||||
public:
|
||||
static const int kDefaultControlPeriodMs = 10; //!< default control update rate is 10ms.
|
||||
CanTalonSRX(int deviceNumber = 0,int controlPeriodMs = kDefaultControlPeriodMs);
|
||||
~CanTalonSRX();
|
||||
void Set(double value);
|
||||
/* mode select enumerations */
|
||||
static const int kMode_DutyCycle = 0; //!< Demand is 11bit signed duty cycle [-1023,1023].
|
||||
static const int kMode_PositionCloseLoop = 1; //!< Position PIDF.
|
||||
static const int kMode_VelocityCloseLoop = 2; //!< Velocity PIDF.
|
||||
static const int kMode_CurrentCloseLoop = 3; //!< Current close loop - not done.
|
||||
static const int kMode_VoltCompen = 4; //!< Voltage Compensation Mode - not done. Demand is fixed pt target 8.8 volts.
|
||||
static const int kMode_SlaveFollower = 5; //!< Demand is the 6 bit Device ID of the 'master' TALON SRX.
|
||||
static const int kMode_NoDrive = 15; //!< Zero the output (honors brake/coast) regardless of demand. Might be useful if we need to change modes but can't atomically change all the signals we want in between.
|
||||
/* limit switch enumerations */
|
||||
static const int kLimitSwitchOverride_UseDefaultsFromFlash = 1;
|
||||
static const int kLimitSwitchOverride_DisableFwd_DisableRev = 4;
|
||||
static const int kLimitSwitchOverride_DisableFwd_EnableRev = 5;
|
||||
static const int kLimitSwitchOverride_EnableFwd_DisableRev = 6;
|
||||
static const int kLimitSwitchOverride_EnableFwd_EnableRev = 7;
|
||||
/* brake override enumerations */
|
||||
static const int kBrakeOverride_UseDefaultsFromFlash = 0;
|
||||
static const int kBrakeOverride_OverrideCoast = 1;
|
||||
static const int kBrakeOverride_OverrideBrake = 2;
|
||||
/* feedback device enumerations */
|
||||
static const int kFeedbackDev_DigitalQuadEnc=0;
|
||||
static const int kFeedbackDev_AnalogPot=2;
|
||||
static const int kFeedbackDev_AnalogEncoder=3;
|
||||
static const int kFeedbackDev_CountEveryRisingEdge=4;
|
||||
static const int kFeedbackDev_CountEveryFallingEdge=5;
|
||||
static const int kFeedbackDev_PosIsPulseWidth=8;
|
||||
/* ProfileSlotSelect enumerations*/
|
||||
static const int kProfileSlotSelect_Slot0 = 0;
|
||||
static const int kProfileSlotSelect_Slot1 = 1;
|
||||
/* status frame rate types */
|
||||
static const int kStatusFrame_General = 0;
|
||||
static const int kStatusFrame_Feedback = 1;
|
||||
static const int kStatusFrame_Encoder = 2;
|
||||
static const int kStatusFrame_AnalogTempVbat = 3;
|
||||
/**
|
||||
* Signal enumeration for generic signal access.
|
||||
* Although every signal is enumerated, only use this for traffic that must be solicited.
|
||||
* Use the auto generated getters/setters at bottom of this header as much as possible.
|
||||
*/
|
||||
typedef enum _param_t{
|
||||
eProfileParamSlot0_P=1,
|
||||
eProfileParamSlot0_I=2,
|
||||
eProfileParamSlot0_D=3,
|
||||
eProfileParamSlot0_F=4,
|
||||
eProfileParamSlot0_IZone=5,
|
||||
eProfileParamSlot0_CloseLoopRampRate=6,
|
||||
eProfileParamSlot1_P=11,
|
||||
eProfileParamSlot1_I=12,
|
||||
eProfileParamSlot1_D=13,
|
||||
eProfileParamSlot1_F=14,
|
||||
eProfileParamSlot1_IZone=15,
|
||||
eProfileParamSlot1_CloseLoopRampRate=16,
|
||||
eProfileParamSoftLimitForThreshold=21,
|
||||
eProfileParamSoftLimitRevThreshold=22,
|
||||
eProfileParamSoftLimitForEnable=23,
|
||||
eProfileParamSoftLimitRevEnable=24,
|
||||
eOnBoot_BrakeMode=31,
|
||||
eOnBoot_LimitSwitch_Forward_NormallyClosed=32,
|
||||
eOnBoot_LimitSwitch_Reverse_NormallyClosed=33,
|
||||
eOnBoot_LimitSwitch_Forward_Disable=34,
|
||||
eOnBoot_LimitSwitch_Reverse_Disable=35,
|
||||
eFault_OverTemp=41,
|
||||
eFault_UnderVoltage=42,
|
||||
eFault_ForLim=43,
|
||||
eFault_RevLim=44,
|
||||
eFault_HardwareFailure=45,
|
||||
eFault_ForSoftLim=46,
|
||||
eFault_RevSoftLim=47,
|
||||
eStckyFault_OverTemp=48,
|
||||
eStckyFault_UnderVoltage=49,
|
||||
eStckyFault_ForLim=50,
|
||||
eStckyFault_RevLim=51,
|
||||
eStckyFault_ForSoftLim=52,
|
||||
eStckyFault_RevSoftLim=53,
|
||||
eAppliedThrottle=61,
|
||||
eCloseLoopErr=62,
|
||||
eFeedbackDeviceSelect=63,
|
||||
eRevMotDuringCloseLoopEn=64,
|
||||
eModeSelect=65,
|
||||
eProfileSlotSelect=66,
|
||||
eRampThrottle=67,
|
||||
eRevFeedbackSensor=68,
|
||||
eLimitSwitchEn=69,
|
||||
eLimitSwitchClosedFor=70,
|
||||
eLimitSwitchClosedRev=71,
|
||||
eSensorPosition=73,
|
||||
eSensorVelocity=74,
|
||||
eCurrent=75,
|
||||
eBrakeIsEnabled=76,
|
||||
eEncPosition=77,
|
||||
eEncVel=78,
|
||||
eEncIndexRiseEvents=79,
|
||||
eQuadApin=80,
|
||||
eQuadBpin=81,
|
||||
eQuadIdxpin=82,
|
||||
eAnalogInWithOv=83,
|
||||
eAnalogInVel=84,
|
||||
eTemp=85,
|
||||
eBatteryV=86,
|
||||
eResetCount=87,
|
||||
eResetFlags=88,
|
||||
eFirmVers=89,
|
||||
eSettingsChanged=90,
|
||||
}param_t;
|
||||
/*---------------------setters and getters that use the solicated param request/response-------------*//**
|
||||
* Send a one shot frame to set an arbitrary signal.
|
||||
* Most signals are in the control frame so avoid using this API unless you have to.
|
||||
* Use this api for...
|
||||
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
|
||||
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
|
||||
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
|
||||
*/
|
||||
CTR_Code SetParam(param_t paramEnum, double value);
|
||||
/**
|
||||
* Asks TALON to immedietely respond with signal value. This API is only used for signals that are not sent periodically.
|
||||
* This can be useful for reading params that rarely change like Limit Switch settings and PIDF values.
|
||||
* @param param to request.
|
||||
*/
|
||||
CTR_Code RequestParam(param_t paramEnum);
|
||||
CTR_Code GetParamResponse(param_t paramEnum, double & value);
|
||||
CTR_Code GetParamResponseInt32(param_t paramEnum, int & value);
|
||||
/*----- getters and setters that use param request/response. These signals are backed up in flash and will survive a power cycle. ---------*/
|
||||
/*----- If your application requires changing these values consider using both slots and switch between slot0 <=> slot1. ------------------*/
|
||||
/*----- If your application requires changing these signals frequently then it makes sense to leverage this API. --------------------------*/
|
||||
/*----- Getters don't block, so it may require several calls to get the latest value. --------------------------*/
|
||||
CTR_Code SetPgain(unsigned slotIdx,double gain);
|
||||
CTR_Code SetIgain(unsigned slotIdx,double gain);
|
||||
CTR_Code SetDgain(unsigned slotIdx,double gain);
|
||||
CTR_Code SetFgain(unsigned slotIdx,double gain);
|
||||
CTR_Code SetIzone(unsigned slotIdx,int zone);
|
||||
CTR_Code SetCloseLoopRampRate(unsigned slotIdx,int closeLoopRampRate);
|
||||
CTR_Code SetSensorPosition(int pos);
|
||||
CTR_Code SetForwardSoftLimit(int forwardLimit);
|
||||
CTR_Code SetReverseSoftLimit(int reverseLimit);
|
||||
CTR_Code SetForwardSoftEnable(int enable);
|
||||
CTR_Code SetReverseSoftEnable(int enable);
|
||||
CTR_Code GetPgain(unsigned slotIdx,double & gain);
|
||||
CTR_Code GetIgain(unsigned slotIdx,double & gain);
|
||||
CTR_Code GetDgain(unsigned slotIdx,double & gain);
|
||||
CTR_Code GetFgain(unsigned slotIdx,double & gain);
|
||||
CTR_Code GetIzone(unsigned slotIdx,int & zone);
|
||||
CTR_Code GetCloseLoopRampRate(unsigned slotIdx,int & closeLoopRampRate);
|
||||
CTR_Code GetForwardSoftLimit(int & forwardLimit);
|
||||
CTR_Code GetReverseSoftLimit(int & reverseLimit);
|
||||
CTR_Code GetForwardSoftEnable(int & enable);
|
||||
CTR_Code GetReverseSoftEnable(int & enable);
|
||||
/**
|
||||
* Change the periodMs of a TALON's status frame. See kStatusFrame_* enums for what's available.
|
||||
*/
|
||||
CTR_Code SetStatusFrameRate(unsigned frameEnum, unsigned periodMs);
|
||||
/**
|
||||
* Clear all sticky faults in TALON.
|
||||
*/
|
||||
CTR_Code ClearStickyFaults();
|
||||
/*------------------------ auto generated. This API is optimal since it uses the fire-and-forget CAN interface ----------------------*/
|
||||
/*------------------------ These signals should cover the majority of all use cases. ----------------------------------*/
|
||||
CTR_Code GetFault_OverTemp(int ¶m);
|
||||
CTR_Code GetFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetFault_ForLim(int ¶m);
|
||||
CTR_Code GetFault_RevLim(int ¶m);
|
||||
CTR_Code GetFault_HardwareFailure(int ¶m);
|
||||
CTR_Code GetFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_OverTemp(int ¶m);
|
||||
CTR_Code GetStckyFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetStckyFault_ForLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevLim(int ¶m);
|
||||
CTR_Code GetStckyFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetAppliedThrottle(int ¶m);
|
||||
CTR_Code GetCloseLoopErr(int ¶m);
|
||||
CTR_Code GetFeedbackDeviceSelect(int ¶m);
|
||||
CTR_Code GetModeSelect(int ¶m);
|
||||
CTR_Code GetLimitSwitchEn(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedFor(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedRev(int ¶m);
|
||||
CTR_Code GetSensorPosition(int ¶m);
|
||||
CTR_Code GetSensorVelocity(int ¶m);
|
||||
CTR_Code GetCurrent(double ¶m);
|
||||
CTR_Code GetBrakeIsEnabled(int ¶m);
|
||||
CTR_Code GetEncPosition(int ¶m);
|
||||
CTR_Code GetEncVel(int ¶m);
|
||||
CTR_Code GetEncIndexRiseEvents(int ¶m);
|
||||
CTR_Code GetQuadApin(int ¶m);
|
||||
CTR_Code GetQuadBpin(int ¶m);
|
||||
CTR_Code GetQuadIdxpin(int ¶m);
|
||||
CTR_Code GetAnalogInWithOv(int ¶m);
|
||||
CTR_Code GetAnalogInVel(int ¶m);
|
||||
CTR_Code GetTemp(double ¶m);
|
||||
CTR_Code GetBatteryV(double ¶m);
|
||||
CTR_Code GetResetCount(int ¶m);
|
||||
CTR_Code GetResetFlags(int ¶m);
|
||||
CTR_Code GetFirmVers(int ¶m);
|
||||
CTR_Code SetDemand(int param);
|
||||
CTR_Code SetOverrideLimitSwitchEn(int param);
|
||||
CTR_Code SetFeedbackDeviceSelect(int param);
|
||||
CTR_Code SetRevMotDuringCloseLoopEn(int param);
|
||||
CTR_Code SetOverrideBrakeType(int param);
|
||||
CTR_Code SetModeSelect(int param);
|
||||
CTR_Code SetProfileSlotSelect(int param);
|
||||
CTR_Code SetRampThrottle(int param);
|
||||
CTR_Code SetRevFeedbackSensor(int param);
|
||||
};
|
||||
#endif
|
||||
|
||||
116
wpilibc/wpilibC++Devices/include/ctre/CtreCanNode.h
Normal file
116
wpilibc/wpilibC++Devices/include/ctre/CtreCanNode.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef CtreCanNode_H_
|
||||
#define CtreCanNode_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <string.h> // memcpy
|
||||
#include <sys/time.h>
|
||||
class CtreCanNode
|
||||
{
|
||||
public:
|
||||
CtreCanNode(UINT8 deviceNumber);
|
||||
~CtreCanNode();
|
||||
|
||||
UINT8 GetDeviceNumber()
|
||||
{
|
||||
return _deviceNumber;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
template <typename T> class txTask{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
T * toSend;
|
||||
T * operator -> ()
|
||||
{
|
||||
return toSend;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *toSend;
|
||||
}
|
||||
bool IsEmpty()
|
||||
{
|
||||
if(toSend == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template <typename T> class recMsg{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t bytes[8];
|
||||
CTR_Code err;
|
||||
T * operator -> ()
|
||||
{
|
||||
return (T *)bytes;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *(T *)bytes;
|
||||
}
|
||||
};
|
||||
UINT8 _deviceNumber;
|
||||
void RegisterRx(uint32_t arbId);
|
||||
void RegisterTx(uint32_t arbId, uint32_t periodMs);
|
||||
|
||||
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
|
||||
void FlushTx(uint32_t arbId);
|
||||
|
||||
template<typename T> txTask<T> GetTx(uint32_t arbId)
|
||||
{
|
||||
txTask<T> retval = {0};
|
||||
txJobs_t::iterator i = _txJobs.find(arbId);
|
||||
if(i != _txJobs.end()){
|
||||
retval.arbId = i->second.arbId;
|
||||
retval.toSend = (T*)i->second.toSend;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
template<class T> void FlushTx(T & par)
|
||||
{
|
||||
FlushTx(par.arbId);
|
||||
}
|
||||
|
||||
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
|
||||
{
|
||||
recMsg<T> retval;
|
||||
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class txJob_t {
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t toSend[8];
|
||||
uint32_t periodMs;
|
||||
};
|
||||
|
||||
class rxEvent_t{
|
||||
public:
|
||||
uint8_t bytes[8];
|
||||
struct timespec time;
|
||||
rxEvent_t()
|
||||
{
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
bytes[4] = 0;
|
||||
bytes[5] = 0;
|
||||
bytes[6] = 0;
|
||||
bytes[7] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint32_t,txJob_t> txJobs_t;
|
||||
txJobs_t _txJobs;
|
||||
|
||||
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
|
||||
rxRxEvents_t _rxRxEvents;
|
||||
};
|
||||
#endif
|
||||
50
wpilibc/wpilibC++Devices/include/ctre/ctre.h
Normal file
50
wpilibc/wpilibC++Devices/include/ctre/ctre.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
//Bit Defines
|
||||
#define BIT0 0x01
|
||||
#define BIT1 0x02
|
||||
#define BIT2 0x04
|
||||
#define BIT3 0x08
|
||||
#define BIT4 0x10
|
||||
#define BIT5 0x20
|
||||
#define BIT6 0x40
|
||||
#define BIT7 0x80
|
||||
#define BIT8 0x0100
|
||||
#define BIT9 0x0200
|
||||
#define BIT10 0x0400
|
||||
#define BIT11 0x0800
|
||||
#define BIT12 0x1000
|
||||
#define BIT13 0x2000
|
||||
#define BIT14 0x4000
|
||||
#define BIT15 0x8000
|
||||
|
||||
//Signed
|
||||
typedef signed char INT8;
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
typedef signed long long INT64;
|
||||
|
||||
//Unsigned
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned int UINT32;
|
||||
typedef unsigned long long UINT64;
|
||||
|
||||
//Other
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned long ULONG;
|
||||
|
||||
typedef enum {
|
||||
CTR_OKAY, //!< No Error - Function executed as expected
|
||||
CTR_RxTimeout, //!< CAN frame has not been received within specified period of time.
|
||||
CTR_TxTimeout, //!< Not used.
|
||||
CTR_InvalidParamValue, //!< Caller passed an invalid param
|
||||
CTR_UnexpectedArbId, //!< Specified CAN Id is invalid.
|
||||
CTR_TxFailed, //!< Could not transmit the CAN frame.
|
||||
CTR_SigNotUpdated, //!< Have not received an value response for signal.
|
||||
}CTR_Code;
|
||||
|
||||
#endif
|
||||
@@ -1,28 +1,29 @@
|
||||
|
||||
#include "AnalogPotentiometer.h"
|
||||
#include "ControllerPower.h"
|
||||
|
||||
/**
|
||||
* Common initialization code called by all constructors.
|
||||
*/
|
||||
void AnalogPotentiometer::initPot(AnalogInput *input, double scale, double offset) {
|
||||
m_scale = scale;
|
||||
void AnalogPotentiometer::initPot(AnalogInput *input, double fullRange, double offset) {
|
||||
m_fullRange = fullRange;
|
||||
m_offset = offset;
|
||||
m_analog_input = input;
|
||||
}
|
||||
|
||||
AnalogPotentiometer::AnalogPotentiometer(int channel, double scale, double offset) {
|
||||
AnalogPotentiometer::AnalogPotentiometer(int channel, double fullRange, double offset) {
|
||||
m_init_analog_input = true;
|
||||
initPot(new AnalogInput(channel), scale, offset);
|
||||
initPot(new AnalogInput(channel), fullRange, offset);
|
||||
}
|
||||
|
||||
AnalogPotentiometer::AnalogPotentiometer(AnalogInput *input, double scale, double offset) {
|
||||
AnalogPotentiometer::AnalogPotentiometer(AnalogInput *input, double fullRange, double offset) {
|
||||
m_init_analog_input = false;
|
||||
initPot(input, scale, offset);
|
||||
initPot(input, fullRange, offset);
|
||||
}
|
||||
|
||||
AnalogPotentiometer::AnalogPotentiometer(AnalogInput &input, double scale, double offset) {
|
||||
AnalogPotentiometer::AnalogPotentiometer(AnalogInput &input, double fullRange, double offset) {
|
||||
m_init_analog_input = false;
|
||||
initPot(&input, scale, offset);
|
||||
initPot(&input, fullRange, offset);
|
||||
}
|
||||
|
||||
AnalogPotentiometer::~AnalogPotentiometer() {
|
||||
@@ -33,12 +34,12 @@ AnalogPotentiometer::~AnalogPotentiometer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current reading of the potentiomere.
|
||||
* Get the current reading of the potentiometer.
|
||||
*
|
||||
* @return The current position of the potentiometer.
|
||||
*/
|
||||
double AnalogPotentiometer::Get() {
|
||||
return m_analog_input->GetVoltage() * m_scale + m_offset;
|
||||
return (m_analog_input->GetVoltage() / ControllerPower::GetVoltage5V()) * m_fullRange + m_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -342,8 +342,9 @@ void CANJaguar::Set(float outputValue, uint8_t syncGroup)
|
||||
dataSize = packFXP8_8(dataBuffer, outputValue);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
default:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "The Jaguar only supports Current, Voltage, Position, Speed, and Percent (Throttle) modes.");
|
||||
return;
|
||||
}
|
||||
if (syncGroup != 0)
|
||||
{
|
||||
@@ -565,7 +566,7 @@ void CANJaguar::setupPeriodicStatus() {
|
||||
LM_PSTAT_END
|
||||
};
|
||||
|
||||
dataSize = packint16_t(data, kSendMessagePeriod / 10);
|
||||
dataSize = packint16_t(data, kSendMessagePeriod);
|
||||
sendMessage(LM_API_PSTAT_PER_EN_S0, data, dataSize);
|
||||
sendMessage(LM_API_PSTAT_PER_EN_S1, data, dataSize);
|
||||
sendMessage(LM_API_PSTAT_PER_EN_S2, data, dataSize);
|
||||
@@ -1144,6 +1145,7 @@ void CANJaguar::SetP(double p)
|
||||
{
|
||||
case kPercentVbus:
|
||||
case kVoltage:
|
||||
case kFollower:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
|
||||
break;
|
||||
case kSpeed:
|
||||
@@ -1178,6 +1180,7 @@ void CANJaguar::SetI(double i)
|
||||
{
|
||||
case kPercentVbus:
|
||||
case kVoltage:
|
||||
case kFollower:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
|
||||
break;
|
||||
case kSpeed:
|
||||
@@ -1212,6 +1215,7 @@ void CANJaguar::SetD(double d)
|
||||
{
|
||||
case kPercentVbus:
|
||||
case kVoltage:
|
||||
case kFollower:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
|
||||
break;
|
||||
case kSpeed:
|
||||
@@ -1313,6 +1317,9 @@ void CANJaguar::EnableControl(double encoderInitialPosition)
|
||||
case kVoltage:
|
||||
sendMessage(LM_API_VCOMP_T_EN, dataBuffer, dataSize);
|
||||
break;
|
||||
default:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "The Jaguar only supports Current, Voltage, Position, Speed, and Percent (Throttle) modes.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_controlEnabled = true;
|
||||
@@ -1353,7 +1360,7 @@ void CANJaguar::DisableControl()
|
||||
*/
|
||||
void CANJaguar::SetPercentMode()
|
||||
{
|
||||
ChangeControlMode(kPercentVbus);
|
||||
SetControlMode(kPercentVbus);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
}
|
||||
@@ -1368,7 +1375,7 @@ void CANJaguar::SetPercentMode()
|
||||
*/
|
||||
void CANJaguar::SetPercentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
|
||||
{
|
||||
ChangeControlMode(kPercentVbus);
|
||||
SetControlMode(kPercentVbus);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1384,7 +1391,7 @@ void CANJaguar::SetPercentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
|
||||
*/
|
||||
void CANJaguar::SetPercentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev)
|
||||
{
|
||||
ChangeControlMode(kPercentVbus);
|
||||
SetControlMode(kPercentVbus);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
SetSpeedReference(LM_REF_QUAD_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1399,7 +1406,7 @@ void CANJaguar::SetPercentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
|
||||
*/
|
||||
void CANJaguar::SetPercentMode(CANJaguar::PotentiometerStruct)
|
||||
{
|
||||
ChangeControlMode(kPercentVbus);
|
||||
SetControlMode(kPercentVbus);
|
||||
SetPositionReference(LM_REF_POT);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
ConfigPotentiometerTurns(1);
|
||||
@@ -1415,7 +1422,7 @@ void CANJaguar::SetPercentMode(CANJaguar::PotentiometerStruct)
|
||||
*/
|
||||
void CANJaguar::SetCurrentMode(double p, double i, double d)
|
||||
{
|
||||
ChangeControlMode(kCurrent);
|
||||
SetControlMode(kCurrent);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
SetPID(p, i, d);
|
||||
@@ -1433,7 +1440,7 @@ void CANJaguar::SetCurrentMode(double p, double i, double d)
|
||||
*/
|
||||
void CANJaguar::SetCurrentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
ChangeControlMode(kCurrent);
|
||||
SetControlMode(kCurrent);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1452,7 +1459,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, d
|
||||
*/
|
||||
void CANJaguar::SetCurrentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
ChangeControlMode(kCurrent);
|
||||
SetControlMode(kCurrent);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
SetSpeedReference(LM_REF_QUAD_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1471,7 +1478,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
|
||||
*/
|
||||
void CANJaguar::SetCurrentMode(CANJaguar::PotentiometerStruct, double p, double i, double d)
|
||||
{
|
||||
ChangeControlMode(kCurrent);
|
||||
SetControlMode(kCurrent);
|
||||
SetPositionReference(LM_REF_POT);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
ConfigPotentiometerTurns(1);
|
||||
@@ -1491,7 +1498,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::PotentiometerStruct, double p, double
|
||||
*/
|
||||
void CANJaguar::SetSpeedMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
ChangeControlMode(kSpeed);
|
||||
SetControlMode(kSpeed);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1510,7 +1517,7 @@ void CANJaguar::SetSpeedMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, dou
|
||||
*/
|
||||
void CANJaguar::SetSpeedMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
ChangeControlMode(kSpeed);
|
||||
SetControlMode(kSpeed);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
SetSpeedReference(LM_REF_QUAD_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1530,7 +1537,7 @@ void CANJaguar::SetSpeedMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev,
|
||||
*/
|
||||
void CANJaguar::SetPositionMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
ChangeControlMode(kPosition);
|
||||
SetControlMode(kPosition);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
SetPID(p, i, d);
|
||||
@@ -1545,7 +1552,7 @@ void CANJaguar::SetPositionMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerR
|
||||
*/
|
||||
void CANJaguar::SetPositionMode(CANJaguar::PotentiometerStruct, double p, double i, double d)
|
||||
{
|
||||
ChangeControlMode(kPosition);
|
||||
SetControlMode(kPosition);
|
||||
SetPositionReference(LM_REF_POT);
|
||||
ConfigPotentiometerTurns(1);
|
||||
SetPID(p, i, d);
|
||||
@@ -1557,7 +1564,7 @@ void CANJaguar::SetPositionMode(CANJaguar::PotentiometerStruct, double p, double
|
||||
*/
|
||||
void CANJaguar::SetVoltageMode()
|
||||
{
|
||||
ChangeControlMode(kVoltage);
|
||||
SetControlMode(kVoltage);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
}
|
||||
@@ -1572,7 +1579,7 @@ void CANJaguar::SetVoltageMode()
|
||||
*/
|
||||
void CANJaguar::SetVoltageMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
|
||||
{
|
||||
ChangeControlMode(kVoltage);
|
||||
SetControlMode(kVoltage);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1588,7 +1595,7 @@ void CANJaguar::SetVoltageMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
|
||||
*/
|
||||
void CANJaguar::SetVoltageMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev)
|
||||
{
|
||||
ChangeControlMode(kVoltage);
|
||||
SetControlMode(kVoltage);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
SetSpeedReference(LM_REF_QUAD_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1603,7 +1610,7 @@ void CANJaguar::SetVoltageMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
|
||||
*/
|
||||
void CANJaguar::SetVoltageMode(CANJaguar::PotentiometerStruct)
|
||||
{
|
||||
ChangeControlMode(kVoltage);
|
||||
SetControlMode(kVoltage);
|
||||
SetPositionReference(LM_REF_POT);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
ConfigPotentiometerTurns(1);
|
||||
@@ -1618,11 +1625,14 @@ void CANJaguar::SetVoltageMode(CANJaguar::PotentiometerStruct)
|
||||
*
|
||||
* @param controlMode The new mode.
|
||||
*/
|
||||
void CANJaguar::ChangeControlMode(ControlMode controlMode)
|
||||
void CANJaguar::SetControlMode(ControlMode controlMode)
|
||||
{
|
||||
// Disable the previous mode
|
||||
DisableControl();
|
||||
|
||||
if (controlMode == kFollower)
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "The Jaguar only supports Current, Voltage, Position, Speed, and Percent (Throttle) modes.");
|
||||
|
||||
// Update the local mode
|
||||
m_controlMode = controlMode;
|
||||
m_controlModeVerified = false;
|
||||
|
||||
1081
wpilibc/wpilibC++Devices/src/CANTalon.cpp
Normal file
1081
wpilibc/wpilibC++Devices/src/CANTalon.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@
|
||||
|
||||
// set the logging level
|
||||
TLogLevel dsLogLevel = logDEBUG;
|
||||
const double JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL = 1.0;
|
||||
|
||||
#define DS_LOG(level) \
|
||||
if (level > dsLogLevel) ; \
|
||||
@@ -32,26 +33,16 @@ DriverStation* DriverStation::m_instance = NULL;
|
||||
* This is only called once the first time GetInstance() is called
|
||||
*/
|
||||
DriverStation::DriverStation()
|
||||
: m_statusDataSemaphore (initializeMutexNormal())
|
||||
, m_task ("DriverStation", (FUNCPTR)DriverStation::InitTask)
|
||||
: m_task ("DriverStation", (FUNCPTR)DriverStation::InitTask)
|
||||
, m_newControlData(0)
|
||||
, m_packetDataAvailableMultiWait(0)
|
||||
, m_waitForDataSem(0)
|
||||
, m_approxMatchTimeOffset(-1.0)
|
||||
, m_userInDisabled(false)
|
||||
, m_userInAutonomous(false)
|
||||
, m_userInTeleop(false)
|
||||
, m_userInTest(false)
|
||||
, m_nextMessageTime(0)
|
||||
{
|
||||
memset(&m_controlWord, 0, sizeof(m_controlWord));
|
||||
|
||||
// All joysticks should default to having zero axes and povs, so
|
||||
// uninitialized memory doesn't get sent to speed controllers.
|
||||
for(unsigned int i = 0; i < kJoystickPorts; i++) {
|
||||
m_joystickAxes[i].count = 0;
|
||||
m_joystickPOVs[i].count = 0;
|
||||
}
|
||||
|
||||
// Create a new semaphore
|
||||
m_packetDataAvailableMultiWait = initializeMultiWait();
|
||||
m_newControlData = initializeSemaphore(SEMAPHORE_EMPTY);
|
||||
@@ -77,7 +68,6 @@ DriverStation::DriverStation()
|
||||
DriverStation::~DriverStation()
|
||||
{
|
||||
m_task.Stop();
|
||||
deleteMutex(m_statusDataSemaphore);
|
||||
m_instance = NULL;
|
||||
deleteMultiWait(m_waitForDataSem);
|
||||
// Unregister our semaphore.
|
||||
@@ -94,12 +84,16 @@ void DriverStation::InitTask(DriverStation *ds)
|
||||
|
||||
void DriverStation::Run()
|
||||
{
|
||||
HALControlWord controlWord;
|
||||
int period = 0;
|
||||
while (true)
|
||||
{
|
||||
takeMultiWait(m_packetDataAvailableMultiWait, m_packetDataAvailableMutex, 0);
|
||||
GetData();
|
||||
// need to get the controlWord to keep the motors enabled
|
||||
HALGetControlWord(&controlWord);
|
||||
takeMultiWait(m_packetDataAvailableMultiWait, m_packetDataAvailableMutex, 0);
|
||||
giveMultiWait(m_waitForDataSem);
|
||||
giveSemaphore(m_newControlData);
|
||||
|
||||
if (++period >= 4)
|
||||
{
|
||||
MotorSafetyHelper::CheckMotors();
|
||||
@@ -128,46 +122,6 @@ DriverStation* DriverStation::GetInstance()
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy data from the DS task for the user.
|
||||
* If no new data exists, it will just be returned, otherwise
|
||||
* the data will be copied from the DS polling loop.
|
||||
*/
|
||||
void DriverStation::GetData()
|
||||
{
|
||||
static bool lastEnabled = false;
|
||||
|
||||
// Get the status data
|
||||
HALGetControlWord(&m_controlWord);
|
||||
|
||||
// Get the location/alliance data
|
||||
HALGetAllianceStation(&m_allianceStationID);
|
||||
|
||||
// Get the status of all of the joysticks
|
||||
for(uint8_t stick = 0; stick < kJoystickPorts; stick++) {
|
||||
uint8_t count;
|
||||
|
||||
HALGetJoystickAxes(stick, &m_joystickAxes[stick]);
|
||||
HALGetJoystickPOVs(stick, &m_joystickPOVs[stick]);
|
||||
HALGetJoystickButtons(stick, &m_joystickButtons[stick], &count);
|
||||
}
|
||||
|
||||
if (!lastEnabled && IsEnabled())
|
||||
{
|
||||
// If starting teleop, assume that autonomous just took up 15 seconds
|
||||
if (IsAutonomous())
|
||||
m_approxMatchTimeOffset = Timer::GetFPGATimestamp();
|
||||
else
|
||||
m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 15.0;
|
||||
}
|
||||
else if (lastEnabled && !IsEnabled())
|
||||
{
|
||||
m_approxMatchTimeOffset = -1.0;
|
||||
}
|
||||
lastEnabled = IsEnabled();
|
||||
giveSemaphore(m_newControlData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the battery voltage.
|
||||
*
|
||||
@@ -182,6 +136,65 @@ float DriverStation::GetBatteryVoltage()
|
||||
return voltage;
|
||||
}
|
||||
|
||||
void DriverStation::ReportJoystickUnpluggedError(std::string message) {
|
||||
double currentTime = Timer::GetFPGATimestamp();
|
||||
if (currentTime > m_nextMessageTime) {
|
||||
ReportError(message);
|
||||
m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the number of axis on a given joystick port
|
||||
*
|
||||
* @param stick The joystick port number
|
||||
* @return the number of axis on the indicated joystick
|
||||
*/
|
||||
int DriverStation::GetStickAxisCount(uint32_t stick)
|
||||
{
|
||||
if (stick >= kJoystickPorts)
|
||||
{
|
||||
wpi_setWPIError(BadJoystickIndex);
|
||||
return 0;
|
||||
}
|
||||
HALJoystickAxes joystickAxes;
|
||||
HALGetJoystickAxes(stick, &joystickAxes);
|
||||
return joystickAxes.count;
|
||||
}
|
||||
|
||||
/** Returns the number of POVs on a given joystick port
|
||||
*
|
||||
* @param stick The joystick port number
|
||||
* @return thenumber of POVs on the indicated joystick
|
||||
*/
|
||||
int DriverStation::GetStickPOVCount(uint32_t stick)
|
||||
{
|
||||
if (stick >= kJoystickPorts)
|
||||
{
|
||||
wpi_setWPIError(BadJoystickIndex);
|
||||
return 0;
|
||||
}
|
||||
HALJoystickPOVs joystickPOVs;
|
||||
HALGetJoystickPOVs(stick, &joystickPOVs);
|
||||
return joystickPOVs.count;
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
if (stick >= kJoystickPorts)
|
||||
{
|
||||
wpi_setWPIError(BadJoystickIndex);
|
||||
return 0;
|
||||
}
|
||||
HALJoystickButtons joystickButtons;
|
||||
HALGetJoystickButtons(stick, &joystickButtons);
|
||||
return joystickButtons.count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the axis on a joystick.
|
||||
* This depends on the mapping of the joystick connected to the specified port.
|
||||
@@ -198,16 +211,18 @@ float DriverStation::GetStickAxis(uint32_t stick, uint32_t axis)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (axis >= m_joystickAxes[stick].count)
|
||||
HALJoystickAxes joystickAxes;
|
||||
HALGetJoystickAxes(stick, &joystickAxes);
|
||||
if (axis >= joystickAxes.count)
|
||||
{
|
||||
if (axis >= kMaxJoystickAxes)
|
||||
wpi_setWPIError(BadJoystickAxis);
|
||||
else
|
||||
ReportError("WARNING: Joystick Axis missing, check if all controllers are plugged in\n");
|
||||
ReportJoystickUnpluggedError("WARNING: Joystick Axis missing, check if all controllers are plugged in\n");
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
int8_t value = m_joystickAxes[stick].axes[axis];
|
||||
int8_t value = joystickAxes.axes[axis];
|
||||
|
||||
if(value < 0)
|
||||
{
|
||||
@@ -230,65 +245,87 @@ int DriverStation::GetStickPOV(uint32_t stick, uint32_t pov) {
|
||||
wpi_setWPIError(BadJoystickIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pov >= m_joystickPOVs[stick].count)
|
||||
|
||||
HALJoystickPOVs joystickPOVs;
|
||||
HALGetJoystickPOVs(stick, &joystickPOVs);
|
||||
if (pov >= joystickPOVs.count)
|
||||
{
|
||||
if (pov >= kMaxJoystickPOVs)
|
||||
wpi_setWPIError(BadJoystickAxis);
|
||||
else
|
||||
ReportError("WARNING: Joystick POV missing, check if all controllers are plugged in\n");
|
||||
ReportJoystickUnpluggedError("WARNING: Joystick POV missing, check if all controllers are plugged in\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_joystickPOVs[stick].povs[pov];
|
||||
return joystickPOVs.povs[pov];
|
||||
}
|
||||
|
||||
/**
|
||||
* The state of the buttons on the joystick.
|
||||
* 12 buttons (4 msb are unused) from the joystick.
|
||||
*
|
||||
* @param stick The joystick to read.
|
||||
* @return The state of the buttons on the joystick.
|
||||
*/
|
||||
short DriverStation::GetStickButtons(uint32_t stick)
|
||||
bool DriverStation::GetStickButton(uint32_t stick, uint8_t button)
|
||||
{
|
||||
if (stick >= kJoystickPorts)
|
||||
{
|
||||
wpi_setWPIError(BadJoystickIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_joystickButtons[stick];
|
||||
HALJoystickButtons joystickButtons;
|
||||
HALGetJoystickButtons(stick, &joystickButtons);
|
||||
if(button > joystickButtons.count)
|
||||
{
|
||||
ReportJoystickUnpluggedError("WARNING: Joystick Button missing, check if all controllers are plugged in\n");
|
||||
return false;
|
||||
}
|
||||
return ((0x1 << (button-1)) & joystickButtons.buttons) !=0;
|
||||
}
|
||||
|
||||
bool DriverStation::IsEnabled()
|
||||
{
|
||||
return m_controlWord.enabled;
|
||||
HALControlWord controlWord;
|
||||
memset(&controlWord, 0, sizeof(controlWord));
|
||||
HALGetControlWord(&controlWord);
|
||||
return controlWord.enabled && controlWord.dsAttached;
|
||||
}
|
||||
|
||||
bool DriverStation::IsDisabled()
|
||||
{
|
||||
return !m_controlWord.enabled;
|
||||
HALControlWord controlWord;
|
||||
memset(&controlWord, 0, sizeof(controlWord));
|
||||
HALGetControlWord(&controlWord);
|
||||
return !(controlWord.enabled && controlWord.dsAttached);
|
||||
}
|
||||
|
||||
bool DriverStation::IsAutonomous()
|
||||
{
|
||||
return m_controlWord.autonomous;
|
||||
HALControlWord controlWord;
|
||||
memset(&controlWord, 0, sizeof(controlWord));
|
||||
HALGetControlWord(&controlWord);
|
||||
return controlWord.autonomous;
|
||||
}
|
||||
|
||||
bool DriverStation::IsOperatorControl()
|
||||
{
|
||||
return !(m_controlWord.autonomous || m_controlWord.test);
|
||||
HALControlWord controlWord;
|
||||
memset(&controlWord, 0, sizeof(controlWord));
|
||||
HALGetControlWord(&controlWord);
|
||||
return !(controlWord.autonomous || controlWord.test);
|
||||
}
|
||||
|
||||
bool DriverStation::IsTest()
|
||||
{
|
||||
return m_controlWord.test;
|
||||
HALControlWord controlWord;
|
||||
HALGetControlWord(&controlWord);
|
||||
return controlWord.test;
|
||||
}
|
||||
|
||||
bool DriverStation::IsDSAttached()
|
||||
{
|
||||
HALControlWord controlWord;
|
||||
memset(&controlWord, 0, sizeof(controlWord));
|
||||
HALGetControlWord(&controlWord);
|
||||
return controlWord.dsAttached;
|
||||
}
|
||||
@@ -327,7 +364,9 @@ bool DriverStation::IsNewControlData()
|
||||
*/
|
||||
bool DriverStation::IsFMSAttached()
|
||||
{
|
||||
return m_controlWord.fmsAttached;
|
||||
HALControlWord controlWord;
|
||||
HALGetControlWord(&controlWord);
|
||||
return controlWord.fmsAttached;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +376,9 @@ bool DriverStation::IsFMSAttached()
|
||||
*/
|
||||
DriverStation::Alliance DriverStation::GetAlliance()
|
||||
{
|
||||
switch(m_allianceStationID)
|
||||
HALAllianceStationID allianceStationID;
|
||||
HALGetAllianceStation(&allianceStationID);
|
||||
switch(allianceStationID)
|
||||
{
|
||||
case kHALAllianceStationID_red1:
|
||||
case kHALAllianceStationID_red2:
|
||||
@@ -359,7 +400,9 @@ DriverStation::Alliance DriverStation::GetAlliance()
|
||||
*/
|
||||
uint32_t DriverStation::GetLocation()
|
||||
{
|
||||
switch(m_allianceStationID)
|
||||
HALAllianceStationID allianceStationID;
|
||||
HALGetAllianceStation(&allianceStationID);
|
||||
switch(allianceStationID)
|
||||
{
|
||||
case kHALAllianceStationID_red1:
|
||||
case kHALAllianceStationID_blue1:
|
||||
@@ -397,9 +440,9 @@ void DriverStation::WaitForData()
|
||||
*/
|
||||
double DriverStation::GetMatchTime()
|
||||
{
|
||||
if (m_approxMatchTimeOffset < 0.0)
|
||||
return 0.0;
|
||||
return Timer::GetFPGATimestamp() - m_approxMatchTimeOffset;
|
||||
float matchTime;
|
||||
HALGetMatchTime(&matchTime);
|
||||
return (double)matchTime;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,9 @@ Joystick::Joystick(uint32_t port)
|
||||
, m_port (port)
|
||||
, m_axes (NULL)
|
||||
, m_buttons (NULL)
|
||||
, m_outputs (0)
|
||||
, m_leftRumble (0)
|
||||
, m_rightRumble (0)
|
||||
{
|
||||
InitJoystick(kNumAxisTypes, kNumButtonTypes);
|
||||
|
||||
@@ -228,7 +231,7 @@ bool Joystick::GetBumper(JoystickHand hand)
|
||||
**/
|
||||
bool Joystick::GetRawButton(uint32_t button)
|
||||
{
|
||||
return ((0x1 << (button-1)) & m_ds->GetStickButtons(m_port)) != 0;
|
||||
return m_ds->GetStickButton(m_port, button);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,6 +262,37 @@ bool Joystick::GetButton(ButtonType button)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of axis for a joystick
|
||||
*
|
||||
* @return the number of axis for the current joystick
|
||||
*/
|
||||
int Joystick::GetAxisCount()
|
||||
{
|
||||
return m_ds->GetStickAxisCount(m_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of axis for a joystick
|
||||
*
|
||||
* @return the number of buttons on the current joystick
|
||||
*/
|
||||
int Joystick::GetButtonCount()
|
||||
{
|
||||
return m_ds->GetStickButtonCount(m_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of axis for a joystick
|
||||
*
|
||||
* @return then umber of POVs for the current joystick
|
||||
*/
|
||||
int Joystick::GetPOVCount()
|
||||
{
|
||||
return m_ds->GetStickPOVCount(m_port);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the channel currently associated with the specified axis.
|
||||
*
|
||||
@@ -305,7 +339,7 @@ float Joystick::GetDirectionRadians(){
|
||||
* Get the direction of the vector formed by the joystick and its origin
|
||||
* in degrees
|
||||
*
|
||||
* uses acos(-1) to represent Pi due to absence of readily accessable Pi
|
||||
* uses acos(-1) to represent Pi due to absence of readily accessible Pi
|
||||
* constant in C++
|
||||
*
|
||||
* @return The direction of the vector in degrees
|
||||
@@ -313,3 +347,38 @@ float Joystick::GetDirectionRadians(){
|
||||
float Joystick::GetDirectionDegrees(){
|
||||
return (180/acos(-1))*GetDirectionRadians();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the rumble output for the joystick. The DS currently supports 2 rumble values,
|
||||
* left rumble and right rumble
|
||||
* @param type Which rumble value to set
|
||||
* @param value The normalized value (0 to 1) to set the rumble to
|
||||
*/
|
||||
void Joystick::SetRumble(RumbleType type, float value) {
|
||||
if (type == kLeftRumble)
|
||||
m_leftRumble = value*65535;
|
||||
else
|
||||
m_rightRumble = value*65535;
|
||||
HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a single HID output value for the joystick.
|
||||
* @param outputNumber The index of the output to set (1-32)
|
||||
* @param value The value to set the output to
|
||||
*/
|
||||
|
||||
void Joystick::SetOutput(uint8_t outputNumber, bool value) {
|
||||
m_outputs = (m_outputs & ~(1 << (outputNumber-1))) | (value << (outputNumber-1));
|
||||
|
||||
HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all HID output values for the joystick.
|
||||
* @param value The 32 bit output value (1 bit for each output)
|
||||
*/
|
||||
void Joystick::SetOutputs(uint32_t value) {
|
||||
m_outputs = value;
|
||||
HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
|
||||
}
|
||||
|
||||
@@ -69,3 +69,80 @@ PowerDistributionPanel::GetCurrent(uint8_t channel) {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The the total current drawn from the PDP channels in Amperes
|
||||
*/
|
||||
double
|
||||
PowerDistributionPanel::GetTotalCurrent() {
|
||||
int32_t status = 0;
|
||||
|
||||
double current = getPDPTotalCurrent(&status);
|
||||
|
||||
if(status) {
|
||||
wpi_setWPIErrorWithContext(Timeout, "");
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The the total power drawn from the PDP channels in Joules
|
||||
*/
|
||||
double
|
||||
PowerDistributionPanel::GetTotalPower() {
|
||||
int32_t status = 0;
|
||||
|
||||
double power = getPDPTotalPower(&status);
|
||||
|
||||
if(status) {
|
||||
wpi_setWPIErrorWithContext(Timeout, "");
|
||||
}
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The the total energy drawn from the PDP channels in Watts
|
||||
*/
|
||||
double
|
||||
PowerDistributionPanel::GetTotalEnergy() {
|
||||
int32_t status = 0;
|
||||
|
||||
double energy = getPDPTotalEnergy(&status);
|
||||
|
||||
if(status) {
|
||||
wpi_setWPIErrorWithContext(Timeout, "");
|
||||
}
|
||||
|
||||
return energy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the total energy drawn from the PDP
|
||||
* @see PowerDistributionPanel#GetTotalEnergy
|
||||
*/
|
||||
void
|
||||
PowerDistributionPanel::ResetTotalEnergy() {
|
||||
int32_t status = 0;
|
||||
|
||||
resetPDPTotalEnergy(&status);
|
||||
|
||||
if(status) {
|
||||
wpi_setWPIErrorWithContext(Timeout, "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all of the fault flags on the PDP
|
||||
*/
|
||||
void
|
||||
PowerDistributionPanel::ClearStickyFaults() {
|
||||
int32_t status = 0;
|
||||
|
||||
clearPDPStickyFaults(&status);
|
||||
|
||||
if(status) {
|
||||
wpi_setWPIErrorWithContext(Timeout, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -735,4 +735,5 @@ void RobotDrive::StopMotor()
|
||||
if (m_frontRightMotor != NULL) m_frontRightMotor->Disable();
|
||||
if (m_rearLeftMotor != NULL) m_rearLeftMotor->Disable();
|
||||
if (m_rearRightMotor != NULL) m_rearRightMotor->Disable();
|
||||
m_safetyHelper->Feed();
|
||||
}
|
||||
|
||||
15
wpilibc/wpilibC++Devices/src/TalonSRX.cpp
Normal file
15
wpilibc/wpilibC++Devices/src/TalonSRX.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "TalonSRX.h"
|
||||
|
||||
TalonSRX::TalonSRX(uint32_t channel) : Talon(channel) {
|
||||
|
||||
}
|
||||
|
||||
TalonSRX::~TalonSRX() {
|
||||
}
|
||||
|
||||
15
wpilibc/wpilibC++Devices/src/VictorSP.cpp
Normal file
15
wpilibc/wpilibC++Devices/src/VictorSP.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "VictorSP.h"
|
||||
|
||||
VictorSP::VictorSP(uint32_t channel) : Talon(channel) {
|
||||
|
||||
}
|
||||
|
||||
VictorSP::~VictorSP() {
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "TestBench.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
static const double kScale = 54.0;
|
||||
static const double kScale = 270.0;
|
||||
static const double kVoltage = 3.33;
|
||||
static const double kAngle = 180.0;
|
||||
|
||||
@@ -40,6 +40,6 @@ TEST_F(AnalogPotentiometerTest, TestInitialSettings) {
|
||||
TEST_F(AnalogPotentiometerTest,TestRangeValues) {
|
||||
m_fakePot->SetVoltage(kVoltage);
|
||||
Wait(0.1);
|
||||
EXPECT_NEAR(kAngle, m_pot->Get(), 1.0)
|
||||
EXPECT_NEAR(kAngle, m_pot->Get(), 2.0)
|
||||
<< "The potentiometer did not measure the correct angle.";
|
||||
}
|
||||
|
||||
@@ -161,12 +161,12 @@ TEST_F(CANJaguarTest, Disable) {
|
||||
* behaves like it should in that control mode.
|
||||
*/
|
||||
TEST_F(CANJaguarTest, BrownOut) {
|
||||
double setpoint = 10.0;
|
||||
|
||||
/* Set the jaguar to quad encoder position mode */
|
||||
m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 10.0f, 0.1f, 0.0f);
|
||||
m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 20.0f, 0.01f, 0.0f);
|
||||
m_jaguar->EnableControl();
|
||||
SetJaguar(kMotorTime, 0.0);
|
||||
double setpoint = m_jaguar->GetPosition() + 1.0f;
|
||||
|
||||
/* Turn the spike off and on again */
|
||||
m_spike->Set(Relay::kOff);
|
||||
@@ -274,7 +274,7 @@ TEST_F(CANJaguarTest, SpeedModeWorks) {
|
||||
m_jaguar->SetSpeedMode(CANJaguar::QuadEncoder, 360, 0.1f, 0.003f, 0.01f);
|
||||
m_jaguar->EnableControl();
|
||||
|
||||
constexpr float speed = 200.0f;
|
||||
constexpr float speed = 100.0f;
|
||||
|
||||
SetJaguar(kMotorTime, speed);
|
||||
EXPECT_NEAR(speed, m_jaguar->GetSpeed(), kEncoderSpeedTolerance);
|
||||
@@ -285,9 +285,9 @@ TEST_F(CANJaguarTest, SpeedModeWorks) {
|
||||
* the Jaguar.
|
||||
*/
|
||||
TEST_F(CANJaguarTest, PositionModeWorks) {
|
||||
m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 10.0f, 0.1f, 0.0f);
|
||||
m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 15.0f, 0.02f, 0.0f);
|
||||
|
||||
double setpoint = m_jaguar->GetPosition() + 10.0f;
|
||||
double setpoint = m_jaguar->GetPosition() + 1.0f;
|
||||
|
||||
m_jaguar->EnableControl();
|
||||
|
||||
|
||||
68
wpilibc/wpilibC++IntegrationTests/src/CANTalonTest.cpp
Normal file
68
wpilibc/wpilibC++IntegrationTests/src/CANTalonTest.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2014. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WPILib.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "TestBench.h"
|
||||
#include "ctre/CanTalonSRX.h"
|
||||
|
||||
const int deviceId = 0;
|
||||
|
||||
TEST(CANTalonTest, QuickTest) {
|
||||
double throttle = 0.1;
|
||||
CANTalon talon(deviceId);
|
||||
talon.SetControlMode(CANSpeedController::kPercentVbus);
|
||||
talon.EnableControl();
|
||||
talon.Set(throttle);
|
||||
Wait(0.25);
|
||||
EXPECT_NEAR(talon.Get(), throttle, 5e-3);
|
||||
talon.Set(-throttle);
|
||||
Wait(0.25);
|
||||
EXPECT_NEAR(talon.Get(), -throttle, 5e-3);
|
||||
|
||||
talon.Disable();
|
||||
Wait(0.1);
|
||||
EXPECT_FLOAT_EQ(talon.Get(), 0.0);
|
||||
}
|
||||
|
||||
TEST(CANTalonTest, SetGetPID) {
|
||||
// Tests that we can actually set and get PID values as intended.
|
||||
CANTalon talon(deviceId);
|
||||
double p = 0.05, i = 0.098, d = 1.23;
|
||||
talon.SetPID(p, i , d);
|
||||
// Wait(0.03);
|
||||
EXPECT_NEAR(p, talon.GetP(), 1e-5);
|
||||
EXPECT_NEAR(i, talon.GetI(), 1e-5);
|
||||
EXPECT_NEAR(d, talon.GetD(), 1e-5);
|
||||
// Test with new values in case the talon was already set to the previous ones.
|
||||
p = 0.15;
|
||||
i = 0.198;
|
||||
d = 1.03;
|
||||
talon.SetPID(p, i , d);
|
||||
// Wait(0.03);
|
||||
EXPECT_NEAR(p, talon.GetP(), 1e-5);
|
||||
EXPECT_NEAR(i, talon.GetI(), 1e-5);
|
||||
EXPECT_NEAR(d, talon.GetD(), 1e-5);
|
||||
}
|
||||
|
||||
TEST(CANTalonTest, DISABLED_PositionModeWorks) {
|
||||
CANTalon talon(deviceId);
|
||||
talon.SetFeedbackDevice(CANTalon::AnalogPot);
|
||||
talon.SetControlMode(CANSpeedController::kPosition);
|
||||
Wait(0.1);
|
||||
double p = 2;
|
||||
double i = 0.00;
|
||||
double d = 0.00;
|
||||
Wait(0.2);
|
||||
talon.SetControlMode(CANSpeedController::kPosition);
|
||||
talon.SetFeedbackDevice(CANTalon::AnalogPot);
|
||||
talon.SetPID(p, i, d);
|
||||
Wait(0.2);
|
||||
talon.Set(100);
|
||||
Wait(100);
|
||||
talon.Disable();
|
||||
EXPECT_NEAR(talon.Get(), 500, 1000);
|
||||
}
|
||||
@@ -13,9 +13,9 @@ static constexpr double kServoResetTime = 2.0;
|
||||
|
||||
static constexpr double kTestAngle = 180.0;
|
||||
|
||||
static constexpr double kTiltSetpoint0 = 0.16;
|
||||
static constexpr double kTiltSetpoint45 = 0.385;
|
||||
static constexpr double kTiltSetpoint90 = 0.61;
|
||||
static constexpr double kTiltSetpoint0 = 0.22;
|
||||
static constexpr double kTiltSetpoint45 = 0.45;
|
||||
static constexpr double kTiltSetpoint90 = 0.68;
|
||||
static constexpr double kTiltTime = 1.0;
|
||||
static constexpr double kAccelerometerTolerance = 0.2;
|
||||
|
||||
@@ -73,9 +73,13 @@ TEST_F(TiltPanCameraTest, DefaultGyroAngle) {
|
||||
* Test if the servo turns 180 degrees and the gyroscope measures this angle
|
||||
*/
|
||||
TEST_F(TiltPanCameraTest, GyroAngle) {
|
||||
// Make sure that the gyro doesn't get jerked when the servo goes to zero.
|
||||
m_pan->SetAngle(0.0);
|
||||
Wait(0.25);
|
||||
m_gyro->Reset();
|
||||
|
||||
for(int i = 0; i < 1800; i++) {
|
||||
m_pan->SetAngle(i / 10.0);
|
||||
|
||||
Wait(0.001);
|
||||
}
|
||||
|
||||
|
||||
@@ -113,6 +113,19 @@ public class Timer {
|
||||
timer.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the period specified has passed and if it has, advance the start
|
||||
* time by that period. This is useful to decide if it's time to do periodic
|
||||
* work without drifting later by the time it took to get around to checking.
|
||||
*
|
||||
* @param period The period to check for (in seconds).
|
||||
* @return If the period has passed.
|
||||
*/
|
||||
public boolean hasPeriodPassed(double period)
|
||||
{
|
||||
return timer.hasPeriodPassed(period);
|
||||
}
|
||||
|
||||
public interface Interface {
|
||||
/**
|
||||
* Get the current time from the timer. If the clock is running it is derived from
|
||||
@@ -143,5 +156,16 @@ public class Timer {
|
||||
* looking at the system clock.
|
||||
*/
|
||||
public void stop();
|
||||
|
||||
|
||||
/**
|
||||
* Check if the period specified has passed and if it has, advance the start
|
||||
* time by that period. This is useful to decide if it's time to do periodic
|
||||
* work without drifting later by the time it took to get around to checking.
|
||||
*
|
||||
* @param period The period to check for (in seconds).
|
||||
* @return If the period has passed.
|
||||
*/
|
||||
public boolean hasPeriodPassed(double period);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ import java.util.Vector;
|
||||
public class CommandGroup extends Command {
|
||||
|
||||
/** The commands in this group (stored in entries) */
|
||||
private Vector m_commands = new Vector();
|
||||
Vector m_commands = new Vector();
|
||||
/** The active children in this group (stored in entries) */
|
||||
Vector m_children = new Vector();
|
||||
/** The current command, -1 signifies that none have been run */
|
||||
private int m_currentCommandIndex = -1;
|
||||
int m_currentCommandIndex = -1;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CommandGroup CommandGroup}.
|
||||
|
||||
@@ -53,8 +53,8 @@ public class LiveWindow {
|
||||
private static Vector sensors = new Vector();
|
||||
// private static Vector actuators = new Vector();
|
||||
private static Hashtable components = new Hashtable();
|
||||
private static ITable livewindowTable = NetworkTable.getTable("LiveWindow");
|
||||
private static ITable statusTable = livewindowTable.getSubTable("~STATUS~");
|
||||
private static ITable livewindowTable;
|
||||
private static ITable statusTable;
|
||||
private static boolean liveWindowEnabled = false;
|
||||
private static boolean firstTime = true;
|
||||
|
||||
@@ -67,6 +67,8 @@ public class LiveWindow {
|
||||
*/
|
||||
private static void initializeLiveWindowComponents() {
|
||||
System.out.println("Initializing the components first time");
|
||||
livewindowTable = NetworkTable.getTable("LiveWindow");
|
||||
statusTable = livewindowTable.getSubTable("~STATUS~");
|
||||
for (Enumeration e = components.keys(); e.hasMoreElements();) {
|
||||
LiveWindowSendable component = (LiveWindowSendable) e.nextElement();
|
||||
LiveWindowComponent c = (LiveWindowComponent) components.get(component);
|
||||
|
||||
@@ -5,31 +5,37 @@
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
package edu.wpi.first.wpilibj;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import edu.wpi.first.wpilibj.hal.HALUtil;
|
||||
import edu.wpi.first.wpilibj.hal.PowerJNI;
|
||||
import edu.wpi.first.wpilibj.interfaces.Potentiometer;
|
||||
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
|
||||
import edu.wpi.first.wpilibj.tables.ITable;
|
||||
|
||||
/**
|
||||
* Class for reading analog potentiometers. Analog potentiometers read
|
||||
* in an analog voltage that corresponds to a position. Usually the
|
||||
* position is either degrees or meters. However, if no conversion is
|
||||
* given it remains volts.
|
||||
* 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.
|
||||
*
|
||||
* @author Alex Henning
|
||||
* @author Colby Skeggs (rail voltage)
|
||||
*/
|
||||
public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
|
||||
private double m_scale, m_offset;
|
||||
private double m_fullRange, m_offset;
|
||||
private AnalogInput m_analog_input;
|
||||
private boolean m_init_analog_input;
|
||||
|
||||
/**
|
||||
* Common initialization code called by all constructors.
|
||||
* @param input The {@link AnalogInput} this potentiometer is plugged into.
|
||||
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
|
||||
* @param fullRange The scaling to multiply the voltage by to get a meaningful unit.
|
||||
* @param offset The offset to add to the scaled value for controlling the zero value
|
||||
*/
|
||||
private void initPot(final AnalogInput input, double scale, double offset) {
|
||||
this.m_scale = scale;
|
||||
private void initPot(final AnalogInput input, double fullRange, double offset) {
|
||||
this.m_fullRange = fullRange;
|
||||
this.m_offset = offset;
|
||||
m_analog_input = input;
|
||||
}
|
||||
@@ -37,51 +43,54 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
|
||||
/**
|
||||
* AnalogPotentiometer constructor.
|
||||
*
|
||||
* Use the scaling and offset values so that the output produces
|
||||
* 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 scale value is 270.0(degrees)/5.0(volts) and the
|
||||
* offset is -135.0 since the halfway point after scaling is 135
|
||||
* degrees.
|
||||
* 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 channel this potentiometer is plugged into.
|
||||
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
|
||||
* @param fullRange The scaling to multiply the fraction by to get a meaningful unit.
|
||||
* @param offset The offset to add to the scaled value for controlling the zero value
|
||||
*/
|
||||
public AnalogPotentiometer(final int channel, double scale, double offset) {
|
||||
public AnalogPotentiometer(final int channel, double fullRange, double offset) {
|
||||
AnalogInput input = new AnalogInput(channel);
|
||||
m_init_analog_input = true;
|
||||
initPot(input, scale, offset);
|
||||
initPot(input, fullRange, offset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AnalogPotentiometer constructor.
|
||||
*
|
||||
* Use the scaling and offset values so that the output produces
|
||||
* 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 scale value is 270.0(degrees)/5.0(volts) and the
|
||||
* offset is -135.0 since the halfway point after scaling is 135
|
||||
* degrees.
|
||||
* 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 {@link AnalogInput} this potentiometer is plugged into.
|
||||
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
|
||||
* @param fullRange The scaling to multiply the fraction by to get a meaningful unit.
|
||||
* @param offset The offset to add to the scaled value for controlling the zero value
|
||||
*/
|
||||
public AnalogPotentiometer(final AnalogInput input, double scale, double offset) {
|
||||
public AnalogPotentiometer(final AnalogInput input, double fullRange, double offset) {
|
||||
m_init_analog_input = false;
|
||||
initPot(input, scale, offset);
|
||||
initPot(input, fullRange, offset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AnalogPotentiometer constructor.
|
||||
*
|
||||
* Use the scaling and offset values so that the output produces
|
||||
* 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 scale value is 270.0(degrees)/5.0(volts) and the
|
||||
* offset is -135.0 since the halfway point after scaling is 135
|
||||
* degrees.
|
||||
* degrees. The fullRange value is 270.0(degrees) and the offset is
|
||||
* -135.0 since the halfway point after scaling is 135 degrees.
|
||||
*
|
||||
* @param channel The analog channel this potentiometer is plugged into.
|
||||
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
|
||||
@@ -93,12 +102,11 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
|
||||
/**
|
||||
* AnalogPotentiometer constructor.
|
||||
*
|
||||
* Use the scaling and offset values so that the output produces
|
||||
* 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 scale value is 270.0(degrees)/5.0(volts) and the
|
||||
* offset is -135.0 since the halfway point after scaling is 135
|
||||
* degrees.
|
||||
* degrees. The fullRange value is 270.0(degrees) and the offset is
|
||||
* -135.0 since the halfway point after scaling is 135 degrees.
|
||||
*
|
||||
* @param input The {@link AnalogInput} this potentiometer is plugged into.
|
||||
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
|
||||
@@ -115,7 +123,7 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
|
||||
public AnalogPotentiometer(final int channel) {
|
||||
this(channel, 1, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AnalogPotentiometer constructor.
|
||||
*
|
||||
@@ -126,12 +134,12 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current reading of the potentiomere.
|
||||
* Get the current reading of the potentiometer.
|
||||
*
|
||||
* @return The current position of the potentiometer.
|
||||
*/
|
||||
public double get() {
|
||||
return m_analog_input.getVoltage() * m_scale + m_offset;
|
||||
return (m_analog_input.getVoltage() / ControllerPower.getVoltage5V()) * m_fullRange + m_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1928,7 +1928,7 @@ public class CANJaguar implements MotorSafety, PIDOutput, SpeedController, LiveW
|
||||
(byte)0,
|
||||
};
|
||||
|
||||
dataSize = packINT16(data, (short)(kSendMessagePeriod / 10));
|
||||
dataSize = packINT16(data, (short)(kSendMessagePeriod));
|
||||
sendMessage(CANJNI.LM_API_PSTAT_PER_EN_S0, data, dataSize);
|
||||
sendMessage(CANJNI.LM_API_PSTAT_PER_EN_S1, data, dataSize);
|
||||
sendMessage(CANJNI.LM_API_PSTAT_PER_EN_S2, data, dataSize);
|
||||
|
||||
@@ -0,0 +1,758 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 2.0.11
|
||||
*
|
||||
* Do not make changes to this file unless you know what you are doing--modify
|
||||
* the SWIG interface file instead.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
package edu.wpi.first.wpilibj;
|
||||
|
||||
import edu.wpi.first.wpilibj.hal.CanTalonSRX;
|
||||
import edu.wpi.first.wpilibj.hal.CanTalonJNI;
|
||||
import edu.wpi.first.wpilibj.hal.SWIGTYPE_p_double;
|
||||
import edu.wpi.first.wpilibj.hal.SWIGTYPE_p_int;
|
||||
import edu.wpi.first.wpilibj.hal.SWIGTYPE_p_uint32_t;
|
||||
import edu.wpi.first.wpilibj.hal.SWIGTYPE_p_CTR_Code;
|
||||
|
||||
public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
|
||||
private MotorSafetyHelper m_safetyHelper;
|
||||
public enum ControlMode {
|
||||
PercentVbus(0), Follower(5), Voltage(4), Position(1), Speed(2), Current(3), Disabled(15);
|
||||
|
||||
public int value;
|
||||
|
||||
public static ControlMode valueOf(int value) {
|
||||
for(ControlMode mode : values()) {
|
||||
if(mode.value == value) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ControlMode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public enum FeedbackDevice {
|
||||
QuadEncoder(0), AnalogPot(2), AnalogEncoder(3), EncRising(4), EncFalling(5);
|
||||
|
||||
public int value;
|
||||
|
||||
public static FeedbackDevice valueOf(int value) {
|
||||
for(FeedbackDevice mode : values()) {
|
||||
if(mode.value == value) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private FeedbackDevice(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private CanTalonSRX m_impl;
|
||||
ControlMode m_controlMode;
|
||||
|
||||
int m_deviceNumber;
|
||||
boolean m_controlEnabled;
|
||||
int m_profile;
|
||||
|
||||
public CANTalon(int deviceNumber) {
|
||||
m_deviceNumber = deviceNumber;
|
||||
m_impl = new CanTalonSRX(deviceNumber);
|
||||
m_safetyHelper = new MotorSafetyHelper(this);
|
||||
m_controlEnabled = true;
|
||||
m_profile = 0;
|
||||
setProfile(m_profile);
|
||||
changeControlMode(ControlMode.PercentVbus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pidWrite(double output)
|
||||
{
|
||||
if (getControlMode() == ControlMode.PercentVbus) {
|
||||
set(output);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("PID only supported in PercentVbus mode");
|
||||
}
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
m_impl.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the appropriate output on the talon, depending on the mode.
|
||||
*
|
||||
* In PercentVbus, the output is between -1.0 and 1.0, with 0.0 as stopped.
|
||||
* In Follower mode, the output is the integer device ID of the talon to duplicate.
|
||||
* In Voltage mode, outputValue is in volts.
|
||||
* In Current mode, outputValue is in amperes.
|
||||
* In Speed mode, outputValue is in position change / 10ms.
|
||||
* In Position mode, outputValue is in encoder ticks or an analog value,
|
||||
* depending on the sensor.
|
||||
*
|
||||
* @param outputValue The setpoint value, as described above.
|
||||
*/
|
||||
public void set(double outputValue) {
|
||||
System.out.println("Enabled: " + m_controlEnabled + " Mode: " + m_controlMode);
|
||||
m_controlMode = ControlMode.PercentVbus;
|
||||
if (m_controlEnabled) {
|
||||
switch (getControlMode()) {
|
||||
case PercentVbus:
|
||||
m_impl.Set(outputValue);
|
||||
break;
|
||||
case Follower:
|
||||
m_impl.SetDemand((int)outputValue);
|
||||
break;
|
||||
case Voltage:
|
||||
// Voltage is an 8.8 fixed point number.
|
||||
int volts = (int)(outputValue * 256);
|
||||
m_impl.SetDemand(volts);
|
||||
break;
|
||||
case Speed:
|
||||
m_impl.SetDemand((int)outputValue);
|
||||
break;
|
||||
case Position:
|
||||
m_impl.SetDemand((int)outputValue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("Enabled: " + m_controlEnabled + " Mode: " + m_controlMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the output of the Talon.
|
||||
*
|
||||
* @param outputValue See set().
|
||||
* @param thisValueDoesNotDoAnything corresponds to syncGroup from Jaguar; not relevant here.
|
||||
*/
|
||||
@Override
|
||||
public void set(double outputValue, byte thisValueDoesNotDoAnything) {
|
||||
set(outputValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips the sign (multiplies by negative one) the sensor values going into
|
||||
*the talon.
|
||||
*
|
||||
* This only affects position and velocity closed loop control. Allows for
|
||||
* situations where you may have a sensor flipped and going in the wrong
|
||||
* direction.
|
||||
*
|
||||
* @param flip True if sensor input should be flipped; False if not.
|
||||
*/
|
||||
public void reverseSensor(boolean flip) {
|
||||
m_impl.SetRevFeedbackSensor(flip ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips the sign (multiplies by negative one) the throttle values going into
|
||||
* the motor on the talon in closed loop modes.
|
||||
*
|
||||
* @param flip True if motor output should be flipped; False if not.
|
||||
*/
|
||||
public void reverseOutput(boolean flip) {
|
||||
m_impl.SetRevMotDuringCloseLoopEn(flip ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current status of the Talon (usually a sensor value).
|
||||
*
|
||||
* In Current mode: returns output current.
|
||||
* In Speed mode: returns current speed.
|
||||
* In Position omde: returns current sensor position.
|
||||
* In Throttle and Follower modes: returns current applied throttle.
|
||||
*
|
||||
* @return The current sensor value of the Talon.
|
||||
*/
|
||||
public double get() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
|
||||
switch (m_controlMode) {
|
||||
case Voltage:
|
||||
return getOutputVoltage();
|
||||
case Current:
|
||||
return getOutputCurrent();
|
||||
case Speed:
|
||||
m_impl.GetSensorVelocity(swigp);
|
||||
return (double)CanTalonJNI.intp_value(valuep);
|
||||
case Position:
|
||||
m_impl.GetSensorPosition(swigp);
|
||||
return (double)CanTalonJNI.intp_value(valuep);
|
||||
case PercentVbus:
|
||||
default:
|
||||
m_impl.GetAppliedThrottle(swigp);
|
||||
return (double)CanTalonJNI.intp_value(valuep) / 1023.0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current encoder position, regardless of whether it is the current feedback device.
|
||||
*
|
||||
* @return The current position of the encoder.
|
||||
*/
|
||||
public int getEncPosition() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
|
||||
m_impl.GetEncPosition(swigp);
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current encoder velocity, regardless of whether it is the current feedback device.
|
||||
*
|
||||
* @return The current speed of the encoder.
|
||||
*/
|
||||
public int getEncVelocity() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
|
||||
m_impl.GetEncVel(swigp);
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current analog in position, regardless of whether it is the current
|
||||
* feedback device.
|
||||
*
|
||||
* @return The current value from the analog in (0 - 1023).
|
||||
*/
|
||||
public int getAnalogInPosition() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
|
||||
m_impl.GetAnalogInWithOv(swigp);
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current encoder velocity, regardless of whether it is the current
|
||||
* feedback device.
|
||||
*
|
||||
* @return The current speed of the analog in device.
|
||||
*/
|
||||
public int getAnalogInVelocity() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
|
||||
m_impl.GetAnalogInVel(swigp);
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current difference between the setpoint and the sensor value.
|
||||
*
|
||||
* @return The error, in whatever units are appropriate.
|
||||
*/
|
||||
public int getClosedLoopError() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
|
||||
m_impl.GetCloseLoopErr(swigp);
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
// Returns temperature of Talon, in degrees Celsius.
|
||||
public double getTemp() {
|
||||
long tempp = CanTalonJNI.new_doublep(); // Create a new swig pointer.
|
||||
m_impl.GetTemp(new SWIGTYPE_p_double(tempp, true));
|
||||
return CanTalonJNI.doublep_value(tempp);
|
||||
}
|
||||
|
||||
// Returns the current going through the Talon, in Amperes.
|
||||
public double getOutputCurrent() {
|
||||
long curp = CanTalonJNI.new_doublep(); // Create a new swig pointer.
|
||||
m_impl.GetCurrent(new SWIGTYPE_p_double(curp, true));
|
||||
return CanTalonJNI.doublep_value(curp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The voltage being output by the Talon, in Volts.
|
||||
*/
|
||||
public double getOutputVoltage() {
|
||||
long throttlep = CanTalonJNI.new_intp();
|
||||
m_impl.GetAppliedThrottle(new SWIGTYPE_p_int(throttlep, true));
|
||||
double voltage = getBusVoltage() * (double)CanTalonJNI.intp_value(throttlep) / 1023.0;
|
||||
return voltage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The voltage at the battery terminals of the Talon, in Volts.
|
||||
*/
|
||||
public double getBusVoltage() {
|
||||
long voltagep = CanTalonJNI.new_doublep();
|
||||
SWIGTYPE_p_CTR_Code status = m_impl.GetBatteryV(new SWIGTYPE_p_double(voltagep, true));
|
||||
/* Note: This section needs the JNI bindings regenerated with
|
||||
pointer_functions for CTR_Code included in order to be able to catch notice
|
||||
and throw errors.
|
||||
if (CanTalonJNI.CTR_Codep_value(status) != 0) {
|
||||
// TODO throw an error.
|
||||
}*/
|
||||
|
||||
return CanTalonJNI.doublep_value(voltagep);
|
||||
}
|
||||
|
||||
public double getPosition() {
|
||||
long positionp = CanTalonJNI.new_intp();
|
||||
m_impl.GetSensorPosition(new SWIGTYPE_p_int(positionp, true));
|
||||
return CanTalonJNI.intp_value(positionp);
|
||||
}
|
||||
|
||||
public void setPosition(double pos) {
|
||||
m_impl.SetSensorPosition((int)pos);
|
||||
}
|
||||
|
||||
public double getSpeed() {
|
||||
long speedp = CanTalonJNI.new_intp();
|
||||
m_impl.GetSensorVelocity(new SWIGTYPE_p_int(speedp, true));
|
||||
return CanTalonJNI.intp_value(speedp);
|
||||
}
|
||||
|
||||
public ControlMode getControlMode() {
|
||||
long tempp = CanTalonJNI.new_intp();
|
||||
m_impl.GetModeSelect(new SWIGTYPE_p_int(tempp, true));
|
||||
ControlMode mode = ControlMode.valueOf(CanTalonJNI.intp_value(tempp));
|
||||
if (mode == ControlMode.Disabled) {
|
||||
m_controlEnabled = false;
|
||||
}
|
||||
else {
|
||||
m_controlMode = mode;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
public void changeControlMode(ControlMode controlMode) {
|
||||
m_controlMode = controlMode;
|
||||
m_impl.SetModeSelect(controlMode.value);
|
||||
}
|
||||
|
||||
public void setFeedbackDevice(FeedbackDevice device) {
|
||||
m_impl.SetFeedbackDeviceSelect(device.value);
|
||||
}
|
||||
|
||||
public void enableControl() {
|
||||
changeControlMode(m_controlMode);
|
||||
m_controlEnabled = true;
|
||||
}
|
||||
|
||||
public void disableControl() {
|
||||
m_impl.SetModeSelect(ControlMode.Disabled.value);
|
||||
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.");
|
||||
//}
|
||||
|
||||
// Update the information that we have.
|
||||
if (m_profile == 0)
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot0_P);
|
||||
else
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_P);
|
||||
|
||||
// Briefly wait for new values from the Talon.
|
||||
Timer.delay(0.001);
|
||||
|
||||
long pp = CanTalonJNI.new_doublep();
|
||||
m_impl.GetPgain(m_profile, new SWIGTYPE_p_double(pp, true));
|
||||
return CanTalonJNI.doublep_value(pp);
|
||||
}
|
||||
|
||||
public double getI() {
|
||||
//if(!(m_controlMode.equals(ControlMode.Position) || m_controlMode.equals(ControlMode.Speed))) {
|
||||
// throw new IllegalStateException("PID mode only applies in Position and Speed modes.");
|
||||
//}
|
||||
|
||||
// Update the information that we have.
|
||||
if (m_profile == 0)
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot0_I);
|
||||
else
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_I);
|
||||
|
||||
// Briefly wait for new values from the Talon.
|
||||
Timer.delay(0.001);
|
||||
|
||||
long ip = CanTalonJNI.new_doublep();
|
||||
m_impl.GetIgain(m_profile, new SWIGTYPE_p_double(ip, true));
|
||||
return CanTalonJNI.doublep_value(ip);
|
||||
}
|
||||
|
||||
public double getD() {
|
||||
//if(!(m_controlMode.equals(ControlMode.Position) || m_controlMode.equals(ControlMode.Speed))) {
|
||||
// throw new IllegalStateException("PID mode only applies in Position and Speed modes.");
|
||||
//}
|
||||
|
||||
// Update the information that we have.
|
||||
if (m_profile == 0)
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot0_D);
|
||||
else
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_D);
|
||||
|
||||
// Briefly wait for new values from the Talon.
|
||||
Timer.delay(0.001);
|
||||
|
||||
long dp = CanTalonJNI.new_doublep();
|
||||
m_impl.GetDgain(m_profile, new SWIGTYPE_p_double(dp, true));
|
||||
return CanTalonJNI.doublep_value(dp);
|
||||
}
|
||||
|
||||
public double getF() {
|
||||
//if(!(m_controlMode.equals(ControlMode.Position) || m_controlMode.equals(ControlMode.Speed))) {
|
||||
// throw new IllegalStateException("PID mode only applies in Position and Speed modes.");
|
||||
//}
|
||||
|
||||
// Update the information that we have.
|
||||
if (m_profile == 0)
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot0_F);
|
||||
else
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_F);
|
||||
|
||||
// Briefly wait for new values from the Talon.
|
||||
Timer.delay(0.001);
|
||||
|
||||
long fp = CanTalonJNI.new_doublep();
|
||||
m_impl.GetFgain(m_profile, new SWIGTYPE_p_double(fp, true));
|
||||
return CanTalonJNI.doublep_value(fp);
|
||||
}
|
||||
|
||||
public double getIZone() {
|
||||
//if(!(m_controlMode.equals(ControlMode.Position) || m_controlMode.equals(ControlMode.Speed))) {
|
||||
// throw new IllegalStateException("PID mode only applies in Position and Speed modes.");
|
||||
//}
|
||||
|
||||
// Update the information that we have.
|
||||
if (m_profile == 0)
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot0_IZone);
|
||||
else
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_IZone);
|
||||
|
||||
// Briefly wait for new values from the Talon.
|
||||
Timer.delay(0.001);
|
||||
|
||||
long fp = CanTalonJNI.new_intp();
|
||||
m_impl.GetIzone(m_profile, new SWIGTYPE_p_int(fp, true));
|
||||
return CanTalonJNI.intp_value(fp);
|
||||
}
|
||||
|
||||
public double getRampRate() {
|
||||
// if(!(m_controlMode.equals(ControlMode.Position) || m_controlMode.equals(ControlMode.Speed))) {
|
||||
// throw new IllegalStateException("PID mode only applies in Position and Speed modes.");
|
||||
// }
|
||||
|
||||
// Update the information that we have.
|
||||
if (m_profile == 0)
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot0_CloseLoopRampRate);
|
||||
else
|
||||
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_CloseLoopRampRate);
|
||||
|
||||
// Briefly wait for new values from the Talon.
|
||||
Timer.delay(0.001);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets control values for closed loop control.
|
||||
*
|
||||
* @param p Proportional constant.
|
||||
* @param i Integration constant.
|
||||
* @param d Differential constant.
|
||||
* @param f Feedforward constant.
|
||||
* @param izone Integration zone -- prevents accumulation of integration error
|
||||
* with large errors. Setting this to zero will ignore any izone stuff.
|
||||
* @param ramprate Closed loop ramp rate. Represents maximum change in
|
||||
* throttle every 10ms.
|
||||
* @param profile which profile to set the pid constants for. You can have two
|
||||
* profiles, with values of 0 or 1, allowing you to keep a second set of values
|
||||
* 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)
|
||||
{
|
||||
if (profile != 0 && profile != 1)
|
||||
throw new IllegalArgumentException("Talon PID profile must be 0 or 1.");
|
||||
m_profile = profile;
|
||||
setProfile(profile);
|
||||
setP(p);
|
||||
setI(i);
|
||||
setD(d);
|
||||
setF(f);
|
||||
setIZone(izone);
|
||||
setCloseLoopRampRate(ramprate);
|
||||
}
|
||||
public void setPID(double p, double i, double d) {
|
||||
setPID(p, i, d, 0, 0, 0, m_profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select which closed loop profile to use, and uses whatever PIDF gains and
|
||||
* the such that are already there.
|
||||
*/
|
||||
public void setProfile(int profile)
|
||||
{
|
||||
if (profile != 0 && profile != 1)
|
||||
throw new IllegalArgumentException("Talon PID profile must be 0 or 1.");
|
||||
m_profile = profile;
|
||||
m_impl.SetProfileSlotSelect(m_profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Common interface for stopping a motor.
|
||||
*
|
||||
* @deprecated Use disableControl instead.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void stopMotor() {
|
||||
disableControl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
disableControl();
|
||||
}
|
||||
|
||||
public int getDeviceID() {
|
||||
return m_deviceNumber;
|
||||
}
|
||||
|
||||
// TODO: Documentation for all these accessors/setters for misc. stuff.
|
||||
public void setForwardSoftLimit(int forwardLimit) {
|
||||
m_impl.SetForwardSoftLimit(forwardLimit);
|
||||
}
|
||||
|
||||
public void enableForwardSoftLimit(boolean enable) {
|
||||
m_impl.SetForwardSoftEnable(enable ? 1 : 0);
|
||||
}
|
||||
|
||||
public void setReverseSoftLimit(int forwardLimit) {
|
||||
m_impl.SetReverseSoftLimit(forwardLimit);
|
||||
}
|
||||
|
||||
public void enableReverseSoftLimit(boolean enable) {
|
||||
m_impl.SetReverseSoftEnable(enable ? 1 : 0);
|
||||
}
|
||||
|
||||
public void clearStickyFaults() {
|
||||
m_impl.ClearStickyFaults();
|
||||
}
|
||||
|
||||
public void enableLimitSwitch(boolean forward, boolean reverse) {
|
||||
int mask = 4 + (forward ? 1 : 0) * 2 + (reverse ? 1 : 0);
|
||||
m_impl.SetOverrideLimitSwitchEn(mask);
|
||||
}
|
||||
|
||||
public void enableBrakeMode(boolean brake) {
|
||||
m_impl.SetOverrideBrakeType(brake ? 2 : 1);
|
||||
}
|
||||
|
||||
public int getFaultOverTemp() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetFault_OverTemp(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getFaultUnderVoltage() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetFault_UnderVoltage(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getFaultForLim() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetFault_ForLim(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getFaultRevLim() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetFault_RevLim(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getFaultHardwareFailure() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetFault_HardwareFailure(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getFaultForSoftLim() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetFault_ForSoftLim(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getFaultRevSoftLim() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetFault_RevSoftLim(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getStickyFaultOverTemp() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetStckyFault_OverTemp(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getStickyFaultUnderVoltage() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetStckyFault_UnderVoltage(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getStickyFaultForLim() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetStckyFault_ForLim(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getStickyFaultRevLim() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetStckyFault_RevLim(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getStickyFaultForSoftLim() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetStckyFault_ForSoftLim(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
public int getStickyFaultRevSoftLim() {
|
||||
long valuep = CanTalonJNI.new_intp();
|
||||
m_impl.GetStckyFault_RevSoftLim(new SWIGTYPE_p_int(valuep, true));
|
||||
return CanTalonJNI.intp_value(valuep);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setExpiration(double timeout) {
|
||||
m_safetyHelper.setExpiration(timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getExpiration() {
|
||||
return m_safetyHelper.getExpiration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAlive() {
|
||||
return m_safetyHelper.isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafetyEnabled() {
|
||||
return m_safetyHelper.isSafetyEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSafetyEnabled(boolean enabled) {
|
||||
m_safetyHelper.setSafetyEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "CANJaguar ID "+m_deviceNumber;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 2.0.11
|
||||
*
|
||||
* Do not make changes to this file unless you know what you are doing--modify
|
||||
* the SWIG interface file instead.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
package edu.wpi.first.wpilibj.hal;
|
||||
|
||||
public class CanTalonSRX extends CtreCanNode {
|
||||
private long swigCPtr;
|
||||
|
||||
protected CanTalonSRX(long cPtr, boolean cMemoryOwn) {
|
||||
super(CanTalonJNI.CanTalonSRX_SWIGUpcast(cPtr), cMemoryOwn);
|
||||
swigCPtr = cPtr;
|
||||
}
|
||||
|
||||
protected static long getCPtr(CanTalonSRX obj) {
|
||||
return (obj == null) ? 0 : obj.swigCPtr;
|
||||
}
|
||||
|
||||
protected void finalize() {
|
||||
delete();
|
||||
}
|
||||
|
||||
public synchronized void delete() {
|
||||
if (swigCPtr != 0) {
|
||||
if (swigCMemOwn) {
|
||||
swigCMemOwn = false;
|
||||
CanTalonJNI.delete_CanTalonSRX(swigCPtr);
|
||||
}
|
||||
swigCPtr = 0;
|
||||
}
|
||||
super.delete();
|
||||
}
|
||||
|
||||
public CanTalonSRX(int deviceNumber, int controlPeriodMs) {
|
||||
this(CanTalonJNI.new_CanTalonSRX__SWIG_0(deviceNumber, controlPeriodMs), true);
|
||||
}
|
||||
|
||||
public CanTalonSRX(int deviceNumber) {
|
||||
this(CanTalonJNI.new_CanTalonSRX__SWIG_1(deviceNumber), true);
|
||||
}
|
||||
|
||||
public CanTalonSRX() {
|
||||
this(CanTalonJNI.new_CanTalonSRX__SWIG_2(), true);
|
||||
}
|
||||
|
||||
public void Set(double value) {
|
||||
CanTalonJNI.CanTalonSRX_Set(swigCPtr, this, value);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetParam(CanTalonSRX.param_t paramEnum, double value) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetParam(swigCPtr, this, paramEnum.swigValue(), value), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code RequestParam(CanTalonSRX.param_t paramEnum) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_RequestParam(swigCPtr, this, paramEnum.swigValue()), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetParamResponse(CanTalonSRX.param_t paramEnum, SWIGTYPE_p_double value) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetParamResponse(swigCPtr, this, paramEnum.swigValue(), SWIGTYPE_p_double.getCPtr(value)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetParamResponseInt32(CanTalonSRX.param_t paramEnum, SWIGTYPE_p_int value) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetParamResponseInt32(swigCPtr, this, paramEnum.swigValue(), SWIGTYPE_p_int.getCPtr(value)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetPgain(long slotIdx, double gain) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetPgain(swigCPtr, this, slotIdx, gain), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetIgain(long slotIdx, double gain) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetIgain(swigCPtr, this, slotIdx, gain), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetDgain(long slotIdx, double gain) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetDgain(swigCPtr, this, slotIdx, gain), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetFgain(long slotIdx, double gain) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetFgain(swigCPtr, this, slotIdx, gain), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetIzone(long slotIdx, int zone) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetIzone(swigCPtr, this, slotIdx, zone), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetCloseLoopRampRate(long slotIdx, int closeLoopRampRate) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetCloseLoopRampRate(swigCPtr, this, slotIdx, closeLoopRampRate), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetSensorPosition(int pos) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetSensorPosition(swigCPtr, this, pos), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetForwardSoftLimit(int forwardLimit) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetForwardSoftLimit(swigCPtr, this, forwardLimit), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetReverseSoftLimit(int reverseLimit) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetReverseSoftLimit(swigCPtr, this, reverseLimit), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetForwardSoftEnable(int enable) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetForwardSoftEnable(swigCPtr, this, enable), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetReverseSoftEnable(int enable) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetReverseSoftEnable(swigCPtr, this, enable), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetPgain(long slotIdx, SWIGTYPE_p_double gain) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetPgain(swigCPtr, this, slotIdx, SWIGTYPE_p_double.getCPtr(gain)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetIgain(long slotIdx, SWIGTYPE_p_double gain) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetIgain(swigCPtr, this, slotIdx, SWIGTYPE_p_double.getCPtr(gain)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetDgain(long slotIdx, SWIGTYPE_p_double gain) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetDgain(swigCPtr, this, slotIdx, SWIGTYPE_p_double.getCPtr(gain)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFgain(long slotIdx, SWIGTYPE_p_double gain) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFgain(swigCPtr, this, slotIdx, SWIGTYPE_p_double.getCPtr(gain)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetIzone(long slotIdx, SWIGTYPE_p_int zone) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetIzone(swigCPtr, this, slotIdx, SWIGTYPE_p_int.getCPtr(zone)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetCloseLoopRampRate(long slotIdx, SWIGTYPE_p_int closeLoopRampRate) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetCloseLoopRampRate(swigCPtr, this, slotIdx, SWIGTYPE_p_int.getCPtr(closeLoopRampRate)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetForwardSoftLimit(SWIGTYPE_p_int forwardLimit) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetForwardSoftLimit(swigCPtr, this, SWIGTYPE_p_int.getCPtr(forwardLimit)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetReverseSoftLimit(SWIGTYPE_p_int reverseLimit) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetReverseSoftLimit(swigCPtr, this, SWIGTYPE_p_int.getCPtr(reverseLimit)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetForwardSoftEnable(SWIGTYPE_p_int enable) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetForwardSoftEnable(swigCPtr, this, SWIGTYPE_p_int.getCPtr(enable)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetReverseSoftEnable(SWIGTYPE_p_int enable) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetReverseSoftEnable(swigCPtr, this, SWIGTYPE_p_int.getCPtr(enable)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetStatusFrameRate(long frameEnum, long periodMs) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetStatusFrameRate(swigCPtr, this, frameEnum, periodMs), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code ClearStickyFaults() {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_ClearStickyFaults(swigCPtr, this), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFault_OverTemp(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFault_OverTemp(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFault_UnderVoltage(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFault_UnderVoltage(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFault_ForLim(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFault_ForLim(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFault_RevLim(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFault_RevLim(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFault_HardwareFailure(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFault_HardwareFailure(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFault_ForSoftLim(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFault_ForSoftLim(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFault_RevSoftLim(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFault_RevSoftLim(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetStckyFault_OverTemp(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetStckyFault_OverTemp(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetStckyFault_UnderVoltage(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetStckyFault_UnderVoltage(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetStckyFault_ForLim(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetStckyFault_ForLim(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetStckyFault_RevLim(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetStckyFault_RevLim(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetStckyFault_ForSoftLim(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetStckyFault_ForSoftLim(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetStckyFault_RevSoftLim(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetStckyFault_RevSoftLim(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetAppliedThrottle(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetAppliedThrottle(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetCloseLoopErr(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetCloseLoopErr(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFeedbackDeviceSelect(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFeedbackDeviceSelect(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetModeSelect(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetModeSelect(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetLimitSwitchEn(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetLimitSwitchEn(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetLimitSwitchClosedFor(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetLimitSwitchClosedFor(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetLimitSwitchClosedRev(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetLimitSwitchClosedRev(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetSensorPosition(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetSensorPosition(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetSensorVelocity(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetSensorVelocity(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetCurrent(SWIGTYPE_p_double param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetCurrent(swigCPtr, this, SWIGTYPE_p_double.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetBrakeIsEnabled(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetBrakeIsEnabled(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetEncPosition(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetEncPosition(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetEncVel(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetEncVel(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetEncIndexRiseEvents(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetEncIndexRiseEvents(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetQuadApin(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetQuadApin(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetQuadBpin(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetQuadBpin(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetQuadIdxpin(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetQuadIdxpin(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetAnalogInWithOv(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetAnalogInWithOv(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetAnalogInVel(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetAnalogInVel(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetTemp(SWIGTYPE_p_double param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetTemp(swigCPtr, this, SWIGTYPE_p_double.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetBatteryV(SWIGTYPE_p_double param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetBatteryV(swigCPtr, this, SWIGTYPE_p_double.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetResetCount(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetResetCount(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetResetFlags(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetResetFlags(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code GetFirmVers(SWIGTYPE_p_int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_GetFirmVers(swigCPtr, this, SWIGTYPE_p_int.getCPtr(param)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetDemand(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetDemand(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetOverrideLimitSwitchEn(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetOverrideLimitSwitchEn(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetFeedbackDeviceSelect(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetFeedbackDeviceSelect(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetRevMotDuringCloseLoopEn(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetRevMotDuringCloseLoopEn(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetOverrideBrakeType(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetOverrideBrakeType(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetModeSelect(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetModeSelect(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetProfileSlotSelect(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetProfileSlotSelect(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetRampThrottle(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetRampThrottle(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_CTR_Code SetRevFeedbackSensor(int param) {
|
||||
return new SWIGTYPE_p_CTR_Code(CanTalonJNI.CanTalonSRX_SetRevFeedbackSensor(swigCPtr, this, param), true);
|
||||
}
|
||||
|
||||
public final static int kDefaultControlPeriodMs = CanTalonJNI.CanTalonSRX_kDefaultControlPeriodMs_get();
|
||||
public final static int kMode_DutyCycle = CanTalonJNI.CanTalonSRX_kMode_DutyCycle_get();
|
||||
public final static int kMode_PositionCloseLoop = CanTalonJNI.CanTalonSRX_kMode_PositionCloseLoop_get();
|
||||
public final static int kMode_VelocityCloseLoop = CanTalonJNI.CanTalonSRX_kMode_VelocityCloseLoop_get();
|
||||
public final static int kMode_CurrentCloseLoop = CanTalonJNI.CanTalonSRX_kMode_CurrentCloseLoop_get();
|
||||
public final static int kMode_VoltCompen = CanTalonJNI.CanTalonSRX_kMode_VoltCompen_get();
|
||||
public final static int kMode_SlaveFollower = CanTalonJNI.CanTalonSRX_kMode_SlaveFollower_get();
|
||||
public final static int kMode_NoDrive = CanTalonJNI.CanTalonSRX_kMode_NoDrive_get();
|
||||
public final static int kLimitSwitchOverride_UseDefaultsFromFlash = CanTalonJNI.CanTalonSRX_kLimitSwitchOverride_UseDefaultsFromFlash_get();
|
||||
public final static int kLimitSwitchOverride_DisableFwd_DisableRev = CanTalonJNI.CanTalonSRX_kLimitSwitchOverride_DisableFwd_DisableRev_get();
|
||||
public final static int kLimitSwitchOverride_DisableFwd_EnableRev = CanTalonJNI.CanTalonSRX_kLimitSwitchOverride_DisableFwd_EnableRev_get();
|
||||
public final static int kLimitSwitchOverride_EnableFwd_DisableRev = CanTalonJNI.CanTalonSRX_kLimitSwitchOverride_EnableFwd_DisableRev_get();
|
||||
public final static int kLimitSwitchOverride_EnableFwd_EnableRev = CanTalonJNI.CanTalonSRX_kLimitSwitchOverride_EnableFwd_EnableRev_get();
|
||||
public final static int kBrakeOverride_UseDefaultsFromFlash = CanTalonJNI.CanTalonSRX_kBrakeOverride_UseDefaultsFromFlash_get();
|
||||
public final static int kBrakeOverride_OverrideCoast = CanTalonJNI.CanTalonSRX_kBrakeOverride_OverrideCoast_get();
|
||||
public final static int kBrakeOverride_OverrideBrake = CanTalonJNI.CanTalonSRX_kBrakeOverride_OverrideBrake_get();
|
||||
public final static int kFeedbackDev_DigitalQuadEnc = CanTalonJNI.CanTalonSRX_kFeedbackDev_DigitalQuadEnc_get();
|
||||
public final static int kFeedbackDev_AnalogPot = CanTalonJNI.CanTalonSRX_kFeedbackDev_AnalogPot_get();
|
||||
public final static int kFeedbackDev_AnalogEncoder = CanTalonJNI.CanTalonSRX_kFeedbackDev_AnalogEncoder_get();
|
||||
public final static int kFeedbackDev_CountEveryRisingEdge = CanTalonJNI.CanTalonSRX_kFeedbackDev_CountEveryRisingEdge_get();
|
||||
public final static int kFeedbackDev_CountEveryFallingEdge = CanTalonJNI.CanTalonSRX_kFeedbackDev_CountEveryFallingEdge_get();
|
||||
public final static int kFeedbackDev_PosIsPulseWidth = CanTalonJNI.CanTalonSRX_kFeedbackDev_PosIsPulseWidth_get();
|
||||
public final static int kProfileSlotSelect_Slot0 = CanTalonJNI.CanTalonSRX_kProfileSlotSelect_Slot0_get();
|
||||
public final static int kProfileSlotSelect_Slot1 = CanTalonJNI.CanTalonSRX_kProfileSlotSelect_Slot1_get();
|
||||
public final static int kStatusFrame_General = CanTalonJNI.CanTalonSRX_kStatusFrame_General_get();
|
||||
public final static int kStatusFrame_Feedback = CanTalonJNI.CanTalonSRX_kStatusFrame_Feedback_get();
|
||||
public final static int kStatusFrame_Encoder = CanTalonJNI.CanTalonSRX_kStatusFrame_Encoder_get();
|
||||
public final static int kStatusFrame_AnalogTempVbat = CanTalonJNI.CanTalonSRX_kStatusFrame_AnalogTempVbat_get();
|
||||
public final static class param_t {
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot0_P = new CanTalonSRX.param_t("eProfileParamSlot0_P", CanTalonJNI.CanTalonSRX_eProfileParamSlot0_P_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot0_I = new CanTalonSRX.param_t("eProfileParamSlot0_I", CanTalonJNI.CanTalonSRX_eProfileParamSlot0_I_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot0_D = new CanTalonSRX.param_t("eProfileParamSlot0_D", CanTalonJNI.CanTalonSRX_eProfileParamSlot0_D_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot0_F = new CanTalonSRX.param_t("eProfileParamSlot0_F", CanTalonJNI.CanTalonSRX_eProfileParamSlot0_F_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot0_IZone = new CanTalonSRX.param_t("eProfileParamSlot0_IZone", CanTalonJNI.CanTalonSRX_eProfileParamSlot0_IZone_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot0_CloseLoopRampRate = new CanTalonSRX.param_t("eProfileParamSlot0_CloseLoopRampRate", CanTalonJNI.CanTalonSRX_eProfileParamSlot0_CloseLoopRampRate_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot1_P = new CanTalonSRX.param_t("eProfileParamSlot1_P", CanTalonJNI.CanTalonSRX_eProfileParamSlot1_P_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot1_I = new CanTalonSRX.param_t("eProfileParamSlot1_I", CanTalonJNI.CanTalonSRX_eProfileParamSlot1_I_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot1_D = new CanTalonSRX.param_t("eProfileParamSlot1_D", CanTalonJNI.CanTalonSRX_eProfileParamSlot1_D_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot1_F = new CanTalonSRX.param_t("eProfileParamSlot1_F", CanTalonJNI.CanTalonSRX_eProfileParamSlot1_F_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot1_IZone = new CanTalonSRX.param_t("eProfileParamSlot1_IZone", CanTalonJNI.CanTalonSRX_eProfileParamSlot1_IZone_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSlot1_CloseLoopRampRate = new CanTalonSRX.param_t("eProfileParamSlot1_CloseLoopRampRate", CanTalonJNI.CanTalonSRX_eProfileParamSlot1_CloseLoopRampRate_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSoftLimitForThreshold = new CanTalonSRX.param_t("eProfileParamSoftLimitForThreshold", CanTalonJNI.CanTalonSRX_eProfileParamSoftLimitForThreshold_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSoftLimitRevThreshold = new CanTalonSRX.param_t("eProfileParamSoftLimitRevThreshold", CanTalonJNI.CanTalonSRX_eProfileParamSoftLimitRevThreshold_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSoftLimitForEnable = new CanTalonSRX.param_t("eProfileParamSoftLimitForEnable", CanTalonJNI.CanTalonSRX_eProfileParamSoftLimitForEnable_get());
|
||||
public final static CanTalonSRX.param_t eProfileParamSoftLimitRevEnable = new CanTalonSRX.param_t("eProfileParamSoftLimitRevEnable", CanTalonJNI.CanTalonSRX_eProfileParamSoftLimitRevEnable_get());
|
||||
public final static CanTalonSRX.param_t eOnBoot_BrakeMode = new CanTalonSRX.param_t("eOnBoot_BrakeMode", CanTalonJNI.CanTalonSRX_eOnBoot_BrakeMode_get());
|
||||
public final static CanTalonSRX.param_t eOnBoot_LimitSwitch_Forward_NormallyClosed = new CanTalonSRX.param_t("eOnBoot_LimitSwitch_Forward_NormallyClosed", CanTalonJNI.CanTalonSRX_eOnBoot_LimitSwitch_Forward_NormallyClosed_get());
|
||||
public final static CanTalonSRX.param_t eOnBoot_LimitSwitch_Reverse_NormallyClosed = new CanTalonSRX.param_t("eOnBoot_LimitSwitch_Reverse_NormallyClosed", CanTalonJNI.CanTalonSRX_eOnBoot_LimitSwitch_Reverse_NormallyClosed_get());
|
||||
public final static CanTalonSRX.param_t eOnBoot_LimitSwitch_Forward_Disable = new CanTalonSRX.param_t("eOnBoot_LimitSwitch_Forward_Disable", CanTalonJNI.CanTalonSRX_eOnBoot_LimitSwitch_Forward_Disable_get());
|
||||
public final static CanTalonSRX.param_t eOnBoot_LimitSwitch_Reverse_Disable = new CanTalonSRX.param_t("eOnBoot_LimitSwitch_Reverse_Disable", CanTalonJNI.CanTalonSRX_eOnBoot_LimitSwitch_Reverse_Disable_get());
|
||||
public final static CanTalonSRX.param_t eFault_OverTemp = new CanTalonSRX.param_t("eFault_OverTemp", CanTalonJNI.CanTalonSRX_eFault_OverTemp_get());
|
||||
public final static CanTalonSRX.param_t eFault_UnderVoltage = new CanTalonSRX.param_t("eFault_UnderVoltage", CanTalonJNI.CanTalonSRX_eFault_UnderVoltage_get());
|
||||
public final static CanTalonSRX.param_t eFault_ForLim = new CanTalonSRX.param_t("eFault_ForLim", CanTalonJNI.CanTalonSRX_eFault_ForLim_get());
|
||||
public final static CanTalonSRX.param_t eFault_RevLim = new CanTalonSRX.param_t("eFault_RevLim", CanTalonJNI.CanTalonSRX_eFault_RevLim_get());
|
||||
public final static CanTalonSRX.param_t eFault_HardwareFailure = new CanTalonSRX.param_t("eFault_HardwareFailure", CanTalonJNI.CanTalonSRX_eFault_HardwareFailure_get());
|
||||
public final static CanTalonSRX.param_t eFault_ForSoftLim = new CanTalonSRX.param_t("eFault_ForSoftLim", CanTalonJNI.CanTalonSRX_eFault_ForSoftLim_get());
|
||||
public final static CanTalonSRX.param_t eFault_RevSoftLim = new CanTalonSRX.param_t("eFault_RevSoftLim", CanTalonJNI.CanTalonSRX_eFault_RevSoftLim_get());
|
||||
public final static CanTalonSRX.param_t eStckyFault_OverTemp = new CanTalonSRX.param_t("eStckyFault_OverTemp", CanTalonJNI.CanTalonSRX_eStckyFault_OverTemp_get());
|
||||
public final static CanTalonSRX.param_t eStckyFault_UnderVoltage = new CanTalonSRX.param_t("eStckyFault_UnderVoltage", CanTalonJNI.CanTalonSRX_eStckyFault_UnderVoltage_get());
|
||||
public final static CanTalonSRX.param_t eStckyFault_ForLim = new CanTalonSRX.param_t("eStckyFault_ForLim", CanTalonJNI.CanTalonSRX_eStckyFault_ForLim_get());
|
||||
public final static CanTalonSRX.param_t eStckyFault_RevLim = new CanTalonSRX.param_t("eStckyFault_RevLim", CanTalonJNI.CanTalonSRX_eStckyFault_RevLim_get());
|
||||
public final static CanTalonSRX.param_t eStckyFault_ForSoftLim = new CanTalonSRX.param_t("eStckyFault_ForSoftLim", CanTalonJNI.CanTalonSRX_eStckyFault_ForSoftLim_get());
|
||||
public final static CanTalonSRX.param_t eStckyFault_RevSoftLim = new CanTalonSRX.param_t("eStckyFault_RevSoftLim", CanTalonJNI.CanTalonSRX_eStckyFault_RevSoftLim_get());
|
||||
public final static CanTalonSRX.param_t eAppliedThrottle = new CanTalonSRX.param_t("eAppliedThrottle", CanTalonJNI.CanTalonSRX_eAppliedThrottle_get());
|
||||
public final static CanTalonSRX.param_t eCloseLoopErr = new CanTalonSRX.param_t("eCloseLoopErr", CanTalonJNI.CanTalonSRX_eCloseLoopErr_get());
|
||||
public final static CanTalonSRX.param_t eFeedbackDeviceSelect = new CanTalonSRX.param_t("eFeedbackDeviceSelect", CanTalonJNI.CanTalonSRX_eFeedbackDeviceSelect_get());
|
||||
public final static CanTalonSRX.param_t eRevMotDuringCloseLoopEn = new CanTalonSRX.param_t("eRevMotDuringCloseLoopEn", CanTalonJNI.CanTalonSRX_eRevMotDuringCloseLoopEn_get());
|
||||
public final static CanTalonSRX.param_t eModeSelect = new CanTalonSRX.param_t("eModeSelect", CanTalonJNI.CanTalonSRX_eModeSelect_get());
|
||||
public final static CanTalonSRX.param_t eProfileSlotSelect = new CanTalonSRX.param_t("eProfileSlotSelect", CanTalonJNI.CanTalonSRX_eProfileSlotSelect_get());
|
||||
public final static CanTalonSRX.param_t eRampThrottle = new CanTalonSRX.param_t("eRampThrottle", CanTalonJNI.CanTalonSRX_eRampThrottle_get());
|
||||
public final static CanTalonSRX.param_t eRevFeedbackSensor = new CanTalonSRX.param_t("eRevFeedbackSensor", CanTalonJNI.CanTalonSRX_eRevFeedbackSensor_get());
|
||||
public final static CanTalonSRX.param_t eLimitSwitchEn = new CanTalonSRX.param_t("eLimitSwitchEn", CanTalonJNI.CanTalonSRX_eLimitSwitchEn_get());
|
||||
public final static CanTalonSRX.param_t eLimitSwitchClosedFor = new CanTalonSRX.param_t("eLimitSwitchClosedFor", CanTalonJNI.CanTalonSRX_eLimitSwitchClosedFor_get());
|
||||
public final static CanTalonSRX.param_t eLimitSwitchClosedRev = new CanTalonSRX.param_t("eLimitSwitchClosedRev", CanTalonJNI.CanTalonSRX_eLimitSwitchClosedRev_get());
|
||||
public final static CanTalonSRX.param_t eSensorPosition = new CanTalonSRX.param_t("eSensorPosition", CanTalonJNI.CanTalonSRX_eSensorPosition_get());
|
||||
public final static CanTalonSRX.param_t eSensorVelocity = new CanTalonSRX.param_t("eSensorVelocity", CanTalonJNI.CanTalonSRX_eSensorVelocity_get());
|
||||
public final static CanTalonSRX.param_t eCurrent = new CanTalonSRX.param_t("eCurrent", CanTalonJNI.CanTalonSRX_eCurrent_get());
|
||||
public final static CanTalonSRX.param_t eBrakeIsEnabled = new CanTalonSRX.param_t("eBrakeIsEnabled", CanTalonJNI.CanTalonSRX_eBrakeIsEnabled_get());
|
||||
public final static CanTalonSRX.param_t eEncPosition = new CanTalonSRX.param_t("eEncPosition", CanTalonJNI.CanTalonSRX_eEncPosition_get());
|
||||
public final static CanTalonSRX.param_t eEncVel = new CanTalonSRX.param_t("eEncVel", CanTalonJNI.CanTalonSRX_eEncVel_get());
|
||||
public final static CanTalonSRX.param_t eEncIndexRiseEvents = new CanTalonSRX.param_t("eEncIndexRiseEvents", CanTalonJNI.CanTalonSRX_eEncIndexRiseEvents_get());
|
||||
public final static CanTalonSRX.param_t eQuadApin = new CanTalonSRX.param_t("eQuadApin", CanTalonJNI.CanTalonSRX_eQuadApin_get());
|
||||
public final static CanTalonSRX.param_t eQuadBpin = new CanTalonSRX.param_t("eQuadBpin", CanTalonJNI.CanTalonSRX_eQuadBpin_get());
|
||||
public final static CanTalonSRX.param_t eQuadIdxpin = new CanTalonSRX.param_t("eQuadIdxpin", CanTalonJNI.CanTalonSRX_eQuadIdxpin_get());
|
||||
public final static CanTalonSRX.param_t eAnalogInWithOv = new CanTalonSRX.param_t("eAnalogInWithOv", CanTalonJNI.CanTalonSRX_eAnalogInWithOv_get());
|
||||
public final static CanTalonSRX.param_t eAnalogInVel = new CanTalonSRX.param_t("eAnalogInVel", CanTalonJNI.CanTalonSRX_eAnalogInVel_get());
|
||||
public final static CanTalonSRX.param_t eTemp = new CanTalonSRX.param_t("eTemp", CanTalonJNI.CanTalonSRX_eTemp_get());
|
||||
public final static CanTalonSRX.param_t eBatteryV = new CanTalonSRX.param_t("eBatteryV", CanTalonJNI.CanTalonSRX_eBatteryV_get());
|
||||
public final static CanTalonSRX.param_t eResetCount = new CanTalonSRX.param_t("eResetCount", CanTalonJNI.CanTalonSRX_eResetCount_get());
|
||||
public final static CanTalonSRX.param_t eResetFlags = new CanTalonSRX.param_t("eResetFlags", CanTalonJNI.CanTalonSRX_eResetFlags_get());
|
||||
public final static CanTalonSRX.param_t eFirmVers = new CanTalonSRX.param_t("eFirmVers", CanTalonJNI.CanTalonSRX_eFirmVers_get());
|
||||
public final static CanTalonSRX.param_t eSettingsChanged = new CanTalonSRX.param_t("eSettingsChanged", CanTalonJNI.CanTalonSRX_eSettingsChanged_get());
|
||||
|
||||
public final int swigValue() {
|
||||
return swigValue;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return swigName;
|
||||
}
|
||||
|
||||
public static param_t swigToEnum(int swigValue) {
|
||||
if (swigValue < swigValues.length && swigValue >= 0 && swigValues[swigValue].swigValue == swigValue)
|
||||
return swigValues[swigValue];
|
||||
for (int i = 0; i < swigValues.length; i++)
|
||||
if (swigValues[i].swigValue == swigValue)
|
||||
return swigValues[i];
|
||||
throw new IllegalArgumentException("No enum " + param_t.class + " with value " + swigValue);
|
||||
}
|
||||
|
||||
private param_t(String swigName) {
|
||||
this.swigName = swigName;
|
||||
this.swigValue = swigNext++;
|
||||
}
|
||||
|
||||
private param_t(String swigName, int swigValue) {
|
||||
this.swigName = swigName;
|
||||
this.swigValue = swigValue;
|
||||
swigNext = swigValue+1;
|
||||
}
|
||||
|
||||
private param_t(String swigName, param_t swigEnum) {
|
||||
this.swigName = swigName;
|
||||
this.swigValue = swigEnum.swigValue;
|
||||
swigNext = this.swigValue+1;
|
||||
}
|
||||
|
||||
private static param_t[] swigValues = { eProfileParamSlot0_P, eProfileParamSlot0_I, eProfileParamSlot0_D, eProfileParamSlot0_F, eProfileParamSlot0_IZone, eProfileParamSlot0_CloseLoopRampRate, eProfileParamSlot1_P, eProfileParamSlot1_I, eProfileParamSlot1_D, eProfileParamSlot1_F, eProfileParamSlot1_IZone, eProfileParamSlot1_CloseLoopRampRate, eProfileParamSoftLimitForThreshold, eProfileParamSoftLimitRevThreshold, eProfileParamSoftLimitForEnable, eProfileParamSoftLimitRevEnable, eOnBoot_BrakeMode, eOnBoot_LimitSwitch_Forward_NormallyClosed, eOnBoot_LimitSwitch_Reverse_NormallyClosed, eOnBoot_LimitSwitch_Forward_Disable, eOnBoot_LimitSwitch_Reverse_Disable, eFault_OverTemp, eFault_UnderVoltage, eFault_ForLim, eFault_RevLim, eFault_HardwareFailure, eFault_ForSoftLim, eFault_RevSoftLim, eStckyFault_OverTemp, eStckyFault_UnderVoltage, eStckyFault_ForLim, eStckyFault_RevLim, eStckyFault_ForSoftLim, eStckyFault_RevSoftLim, eAppliedThrottle, eCloseLoopErr, eFeedbackDeviceSelect, eRevMotDuringCloseLoopEn, eModeSelect, eProfileSlotSelect, eRampThrottle, eRevFeedbackSensor, eLimitSwitchEn, eLimitSwitchClosedFor, eLimitSwitchClosedRev, eSensorPosition, eSensorVelocity, eCurrent, eBrakeIsEnabled, eEncPosition, eEncVel, eEncIndexRiseEvents, eQuadApin, eQuadBpin, eQuadIdxpin, eAnalogInWithOv, eAnalogInVel, eTemp, eBatteryV, eResetCount, eResetFlags, eFirmVers, eSettingsChanged };
|
||||
private static int swigNext = 0;
|
||||
private final int swigValue;
|
||||
private final String swigName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 2.0.11
|
||||
*
|
||||
* Do not make changes to this file unless you know what you are doing--modify
|
||||
* the SWIG interface file instead.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
package edu.wpi.first.wpilibj.hal;
|
||||
|
||||
public class CtreCanNode {
|
||||
private long swigCPtr;
|
||||
protected boolean swigCMemOwn;
|
||||
|
||||
protected CtreCanNode(long cPtr, boolean cMemoryOwn) {
|
||||
swigCMemOwn = cMemoryOwn;
|
||||
swigCPtr = cPtr;
|
||||
}
|
||||
|
||||
protected static long getCPtr(CtreCanNode obj) {
|
||||
return (obj == null) ? 0 : obj.swigCPtr;
|
||||
}
|
||||
|
||||
protected void finalize() {
|
||||
delete();
|
||||
}
|
||||
|
||||
public synchronized void delete() {
|
||||
if (swigCPtr != 0) {
|
||||
if (swigCMemOwn) {
|
||||
swigCMemOwn = false;
|
||||
CanTalonJNI.delete_CtreCanNode(swigCPtr);
|
||||
}
|
||||
swigCPtr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public CtreCanNode(SWIGTYPE_p_UINT8 deviceNumber) {
|
||||
this(CanTalonJNI.new_CtreCanNode(SWIGTYPE_p_UINT8.getCPtr(deviceNumber)), true);
|
||||
}
|
||||
|
||||
public SWIGTYPE_p_UINT8 GetDeviceNumber() {
|
||||
return new SWIGTYPE_p_UINT8(CanTalonJNI.CtreCanNode_GetDeviceNumber(swigCPtr, this), true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,24 +21,19 @@ import edu.wpi.first.wpilibj.hal.PowerJNI;
|
||||
*/
|
||||
public class DriverStation implements RobotState.Interface {
|
||||
|
||||
/**
|
||||
* The size of the user status data
|
||||
*/
|
||||
public static final int USER_STATUS_DATA_SIZE = FRCNetworkCommunicationsLibrary.USER_STATUS_DATA_SIZE;
|
||||
/**
|
||||
* Number of Joystick Ports
|
||||
*/
|
||||
public static final int kJoystickPorts = 6;
|
||||
/**
|
||||
* Convert from raw values to volts
|
||||
*/
|
||||
public static final double kDSAnalogInScaling = 5.0 / 1023.0;
|
||||
|
||||
/**
|
||||
* The robot alliance that the robot is a part of
|
||||
*/
|
||||
public enum Alliance { Red, Blue, Invalid }
|
||||
|
||||
private static final double JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL = 1.0;
|
||||
private double m_nextMessageTime = 0.0;
|
||||
|
||||
private static class DriverStationTask implements Runnable {
|
||||
|
||||
private DriverStation m_ds;
|
||||
@@ -54,19 +49,10 @@ public class DriverStation implements RobotState.Interface {
|
||||
|
||||
private static DriverStation instance = new DriverStation();
|
||||
|
||||
private HALControlWord m_controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
||||
private HALAllianceStationID m_allianceStationID;
|
||||
private short[][] m_joystickAxes = new short[kJoystickPorts][FRCNetworkCommunicationsLibrary.kMaxJoystickAxes];
|
||||
private short[][] m_joystickPOVs = new short[kJoystickPorts][FRCNetworkCommunicationsLibrary.kMaxJoystickPOVs];
|
||||
private int[] m_joystickButtons = new int[kJoystickPorts];
|
||||
|
||||
private Thread m_thread;
|
||||
private final Object m_semaphore;
|
||||
private final Object m_dataSem;
|
||||
private int m_digitalOut;
|
||||
private volatile boolean m_thread_keepalive = true;
|
||||
private int m_updateNumber = 0;
|
||||
private double m_approxMatchTimeOffset = -1.0;
|
||||
private boolean m_userInDisabled = false;
|
||||
private boolean m_userInAutonomous = false;
|
||||
private boolean m_userInTeleop = false;
|
||||
@@ -91,7 +77,6 @@ public class DriverStation implements RobotState.Interface {
|
||||
* instance static member variable.
|
||||
*/
|
||||
protected DriverStation() {
|
||||
m_semaphore = new Object();
|
||||
m_dataSem = new Object();
|
||||
|
||||
m_packetDataAvailableMutex = HALUtil.initializeMutexNormal();
|
||||
@@ -118,14 +103,13 @@ public class DriverStation implements RobotState.Interface {
|
||||
int safetyCounter = 0;
|
||||
while (m_thread_keepalive) {
|
||||
HALUtil.takeMultiWait(m_packetDataAvailableSem, m_packetDataAvailableMutex, 0);
|
||||
synchronized (this) {
|
||||
getData();
|
||||
}
|
||||
synchronized (m_dataSem) {
|
||||
m_dataSem.notifyAll();
|
||||
}
|
||||
// need to get the controlWord to keep the motors enabled
|
||||
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
||||
m_newControlData = true;
|
||||
if (++safetyCounter >= 5) {
|
||||
// System.out.println("Checking safety");
|
||||
MotorSafetyHelper.checkMotors();
|
||||
safetyCounter = 0;
|
||||
}
|
||||
@@ -165,41 +149,6 @@ public class DriverStation implements RobotState.Interface {
|
||||
}
|
||||
}
|
||||
}
|
||||
private static boolean lastEnabled = false;
|
||||
|
||||
/**
|
||||
* Copy data from the DS task for the user.
|
||||
* If no new data exists, it will just be returned, otherwise
|
||||
* the data will be copied from the DS polling loop.
|
||||
*/
|
||||
protected synchronized void getData() {
|
||||
// Get the status data
|
||||
m_controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
||||
|
||||
// Get the location/alliance data
|
||||
m_allianceStationID = FRCNetworkCommunicationsLibrary.HALGetAllianceStation();
|
||||
|
||||
// Get the status of all of the joysticks
|
||||
for(byte stick = 0; stick < kJoystickPorts; stick++) {
|
||||
m_joystickButtons[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickButtons(stick);
|
||||
m_joystickAxes[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickAxes(stick);
|
||||
m_joystickPOVs[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickPOVs(stick);
|
||||
}
|
||||
|
||||
if (!lastEnabled && isEnabled()) {
|
||||
// If starting teleop, assume that autonomous just took up 15 seconds
|
||||
if (isAutonomous()) {
|
||||
m_approxMatchTimeOffset = Timer.getFPGATimestamp();
|
||||
} else {
|
||||
m_approxMatchTimeOffset = Timer.getFPGATimestamp() - 15.0;
|
||||
}
|
||||
} else if (lastEnabled && !isEnabled()) {
|
||||
m_approxMatchTimeOffset = -1.0;
|
||||
}
|
||||
lastEnabled = isEnabled();
|
||||
|
||||
m_newControlData = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the battery voltage.
|
||||
@@ -214,6 +163,14 @@ public class DriverStation implements RobotState.Interface {
|
||||
return voltage;
|
||||
}
|
||||
|
||||
private void reportJoystickUnpluggedError(String message) {
|
||||
double currentTime = Timer.getFPGATimestamp();
|
||||
if (currentTime > m_nextMessageTime) {
|
||||
reportError(message, false);
|
||||
m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the axis on a joystick.
|
||||
* This depends on the mapping of the joystick connected to the specified port.
|
||||
@@ -230,13 +187,15 @@ public class DriverStation implements RobotState.Interface {
|
||||
if (axis < 0 || axis >= FRCNetworkCommunicationsLibrary.kMaxJoystickAxes) {
|
||||
throw new RuntimeException("Joystick axis is out of range");
|
||||
}
|
||||
|
||||
short[] joystickAxes = FRCNetworkCommunicationsLibrary.HALGetJoystickAxes((byte)stick);
|
||||
|
||||
if (axis >= m_joystickAxes[stick].length) {
|
||||
reportError("WARNING: Joystick axis " + axis + " on port " + stick + " not available, check if controller is plugged in\n", false);
|
||||
if (axis >= joystickAxes.length) {
|
||||
reportJoystickUnpluggedError("WARNING: Joystick axis " + axis + " on port " + stick + " not available, check if controller is plugged in\n");
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
byte value = (byte)m_joystickAxes[stick][axis];
|
||||
byte value = (byte)joystickAxes[axis];
|
||||
|
||||
if(value < 0) {
|
||||
return value / 128.0;
|
||||
@@ -245,6 +204,20 @@ public class DriverStation implements RobotState.Interface {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of axis on a given joystick port
|
||||
*
|
||||
* @param stick The joystick port number
|
||||
*/
|
||||
public int getStickAxisCount(int stick){
|
||||
|
||||
if(stick < 0 || stick >= kJoystickPorts) {
|
||||
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
||||
}
|
||||
|
||||
return FRCNetworkCommunicationsLibrary.HALGetJoystickAxes((byte)stick).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state of a POV on the joystick.
|
||||
*
|
||||
@@ -258,13 +231,29 @@ public class DriverStation implements RobotState.Interface {
|
||||
if (pov < 0 || pov >= FRCNetworkCommunicationsLibrary.kMaxJoystickPOVs) {
|
||||
throw new RuntimeException("Joystick POV is out of range");
|
||||
}
|
||||
|
||||
short[] joystickPOVs = FRCNetworkCommunicationsLibrary.HALGetJoystickPOVs((byte)stick);
|
||||
|
||||
if (pov >= m_joystickPOVs[stick].length) {
|
||||
reportError("WARNING: Joystick POV " + pov + " on port " + stick + " not available, check if controller is plugged in\n", false);
|
||||
if (pov >= joystickPOVs.length) {
|
||||
reportJoystickUnpluggedError("WARNING: Joystick POV " + pov + " on port " + stick + " not available, check if controller is plugged in\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_joystickPOVs[stick][pov];
|
||||
return joystickPOVs[pov];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of POVs on a given joystick port
|
||||
*
|
||||
* @param stick The joystick port number
|
||||
*/
|
||||
public int getStickPOVCount(int stick){
|
||||
|
||||
if(stick < 0 || stick >= kJoystickPorts) {
|
||||
throw new RuntimeException("Joystick index is out of range, should be 0-5");
|
||||
}
|
||||
|
||||
return FRCNetworkCommunicationsLibrary.HALGetJoystickPOVs((byte)stick).length;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,12 +263,38 @@ public class DriverStation implements RobotState.Interface {
|
||||
* @param stick The joystick to read.
|
||||
* @return The state of the buttons on the joystick.
|
||||
*/
|
||||
public int getStickButtons(final int stick) {
|
||||
public boolean getStickButton(final int stick, byte button) {
|
||||
if(stick < 0 || stick >= kJoystickPorts) {
|
||||
throw new RuntimeException("Joystick index is out of range, should be 0-3");
|
||||
}
|
||||
|
||||
ByteBuffer countBuffer = ByteBuffer.allocateDirect(1);
|
||||
int buttons = FRCNetworkCommunicationsLibrary.HALGetJoystickButtons((byte)stick, countBuffer);
|
||||
byte count = 0;
|
||||
count = countBuffer.get();
|
||||
if(button > count) {
|
||||
reportJoystickUnpluggedError("WARNING: Joystick Button " + button + " on port " + stick + " not available, check if controller is plugged in\n");
|
||||
return false;
|
||||
}
|
||||
return ((0x1 << (button - 1)) & buttons) != 0;
|
||||
}
|
||||
|
||||
return (int)m_joystickButtons[stick];
|
||||
/**
|
||||
* Gets the number of buttons on a joystick
|
||||
*
|
||||
* @param stick the joystick port number
|
||||
*/
|
||||
public int getStickButtonCount(int stick){
|
||||
|
||||
if(stick < 0 || stick >= kJoystickPorts) {
|
||||
throw new RuntimeException("Joystick index is out of range, should be 0-3");
|
||||
}
|
||||
|
||||
ByteBuffer countBuffer = ByteBuffer.allocateDirect(1);
|
||||
|
||||
int buttons = FRCNetworkCommunicationsLibrary.HALGetJoystickButtons((byte)stick, countBuffer);
|
||||
byte count = countBuffer.get();
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,7 +304,8 @@ public class DriverStation implements RobotState.Interface {
|
||||
* @return True if the robot is enabled, false otherwise.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return m_controlWord.getEnabled() && isDSAttached();
|
||||
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
||||
return controlWord.getEnabled() && controlWord.getDSAttached();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,7 +325,8 @@ public class DriverStation implements RobotState.Interface {
|
||||
* @return True if autonomous mode should be enabled, false otherwise.
|
||||
*/
|
||||
public boolean isAutonomous() {
|
||||
return m_controlWord.getAutonomous();
|
||||
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
||||
return controlWord.getAutonomous();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,7 +335,8 @@ public class DriverStation implements RobotState.Interface {
|
||||
* @return True if test mode should be enabled, false otherwise.
|
||||
*/
|
||||
public boolean isTest() {
|
||||
return m_controlWord.getTest();
|
||||
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
||||
return controlWord.getTest();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -362,10 +380,12 @@ public class DriverStation implements RobotState.Interface {
|
||||
* @return the current alliance
|
||||
*/
|
||||
public Alliance getAlliance() {
|
||||
if(m_allianceStationID == null) {
|
||||
HALAllianceStationID allianceStationID = FRCNetworkCommunicationsLibrary.HALGetAllianceStation();
|
||||
if(allianceStationID == null) {
|
||||
return Alliance.Invalid;
|
||||
}
|
||||
switch (m_allianceStationID) {
|
||||
|
||||
switch (allianceStationID) {
|
||||
case Red1:
|
||||
case Red2:
|
||||
case Red3:
|
||||
@@ -387,10 +407,11 @@ public class DriverStation implements RobotState.Interface {
|
||||
* @return the location of the team's driver station controls: 1, 2, or 3
|
||||
*/
|
||||
public int getLocation() {
|
||||
if(m_allianceStationID == null) {
|
||||
HALAllianceStationID allianceStationID = FRCNetworkCommunicationsLibrary.HALGetAllianceStation();
|
||||
if(allianceStationID == null) {
|
||||
return 0;
|
||||
}
|
||||
switch (m_allianceStationID) {
|
||||
switch (allianceStationID) {
|
||||
case Red1:
|
||||
case Blue1:
|
||||
return 1;
|
||||
@@ -414,7 +435,8 @@ public class DriverStation implements RobotState.Interface {
|
||||
* @return True if the robot is competing on a field being controlled by a Field Management System
|
||||
*/
|
||||
public boolean isFMSAttached() {
|
||||
return m_controlWord.getFMSAttached();
|
||||
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
|
||||
return controlWord.getFMSAttached();
|
||||
}
|
||||
|
||||
public boolean isDSAttached() {
|
||||
@@ -433,10 +455,7 @@ public class DriverStation implements RobotState.Interface {
|
||||
* @return Match time in seconds since the beginning of autonomous
|
||||
*/
|
||||
public double getMatchTime() {
|
||||
if (m_approxMatchTimeOffset < 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
return Timer.getFPGATimestamp() - m_approxMatchTimeOffset;
|
||||
return FRCNetworkCommunicationsLibrary.HALGetMatchTime();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user