Compare commits

...

71 Commits

Author SHA1 Message Date
Brad Miller (WPI)
ff2ea1287d Merge "Added C++ versions of the joystick query functions" 2014-12-05 17:29:55 -08:00
Brad Miller
b41690b387 Added C++ versions of the joystick query functions
Change-Id: I4acdb0a54493e633b2a7a9b265c3958a9ba163d1
2014-12-05 20:13:23 -05:00
Fred Silberberg (WPI)
ce8e65d41e Merge "Changed AnalogPotentiometer to use angle specification and rail voltage." 2014-12-05 16:58:04 -08:00
James Kuszmaul
66622b43e7 Fixed accidental confusion between seconds/milliseconds.
get* in CANTalon would've blocked for 1 sec instead of 1ms.

Change-Id: I1b6fce24329e2789053372181dbef5c28f4b747a
2014-12-05 19:16:53 -05:00
Omar Zrien
568b842c73 added setPosition to java. Great for zero-ing your relative sensors, also exists in cpp and LV.
Change-Id: Idfd8c0d2c568306cb6853803315a99b92992b388
2014-12-05 19:11:17 -05:00
Omar Zrien
4d142cdafa commented out throws in getP,getI,getD,getIzone, getRampRate.
Getting/setting these should be available all the time.

Change-Id: I8ecc6dc8847c946c63c83081a338c1bd70a656b5
2014-12-05 19:05:25 -05:00
Colby Skeggs
2ae8f40a58 Changed AnalogPotentiometer to use angle specification and rail voltage.
Change-Id: I98f2c1c16726496a69c86174cdb870c74e05822c
2014-12-05 23:40:20 +00:00
James Kuszmaul
4833316571 Added more Talon SRX documentation and PID samples.
Change-Id: I2b1326c11452c6895846ded1277dbf4d38a5222d
2014-12-05 17:21:36 -05:00
Brad Miller (WPI)
16f9db30a9 Merge "fixed bug artf3676 : Typing in a project name into the create command dialog in eclipse is broken" 2014-12-05 14:07:38 -08:00
PetaroMitaro
e092742f40 fixed bug artf3676 : Typing in a project name into the create command dialog in eclipse is broken
Change-Id: I591f1950624e280feb8f7cb262bce11783cb3ff1
2014-12-05 16:32:51 -05:00
PetaroMitaro
4f6fa2482b added joystick and driverstation counts for POV, buttons, and axis 2014-12-05 16:30:20 -05:00
Joe Ross
52408e2658 Add classes for VictorSP and TalonSRX PWM control.
Update documentation for existing classes to better describe what
they control

Change-Id: I1932b39a3f082c2eb57f41edb4ba55c73cce2938
2014-12-05 16:20:58 -05:00
Brad Miller (WPI)
d986ffac81 Merge "Java-Installer" 2014-12-05 13:02:54 -08:00
Fredric Silberberg
bc3c5447e7 Java-Installer
Added the java-installer to the tools-zip created by the plugins

Change-Id: Ibf03e3cf83c6c8a7663c4c55c0fb18623020039e
2014-12-05 16:02:15 -05:00
Brad Miller (WPI)
b125e6b40a Merge "Various getters and setters added to C++. usleep added to the getters that require a little time for solicted response (getPIDF, getIzone, and getFirmwareVers. Tested against the TALON SRX unit test originally written for CanTalonSrx HAL class." 2014-12-05 12:52:51 -08:00
Brad Miller (WPI)
88a043bda4 Merge "Change Periodic Status rate to 20ms. Jaguar firmware v109 fixes issue with periodic status sending." 2014-12-05 11:49:52 -08:00
Fred Silberberg (WPI)
c57d01af94 Merge "Add USB IP to deploy fallbacks and make fallbacks work." 2014-12-05 11:48:44 -08:00
Brad Miller (WPI)
6abde412c1 Merge "Image v20" 2014-12-05 11:42:40 -08:00
Brad Miller (WPI)
5e6cd0bf9e Merge "Implement Joystick Outputs and Rumble (fixes artf3807)" 2014-12-05 11:42:14 -08:00
Kevin O'Connor
ec03c3068d Add USB IP to deploy fallbacks and make fallbacks work.
Change-Id: Iae28b1bc883e65cd6f3a88858405d43815c7323b
2014-12-05 13:53:44 -05:00
Kevin O'Connor
45f3b76103 Fix off-by-one in button checking (fixes artf3861)
Change-Id: Ic3c33bf08417fef9c7432a19a419534b76cb8597
2014-12-05 12:26:05 -05:00
Kevin O'Connor
dac04cb4a2 Implement Joystick Outputs and Rumble (fixes artf3807)
Change-Id: I7e2fa3990f47b6c51ae498035878a29c02817c1b
2014-12-05 12:24:50 -05:00
Omar Zrien
7d026be264 Various getters and setters added to C++.
usleep added to the getters that require a little time for solicted response (getPIDF, getIzone, and getFirmwareVers.
Tested against the TALON SRX unit test originally written for CanTalonSrx HAL class.

Change-Id: I7e75b8b63ac9ffecb5d48b87cbe0e0ee05bbb5a2
2014-12-05 05:08:10 -05:00
James Kuszmaul
5893d28f39 Added support for basic PID in java Talon SRX.
Tested analog PID in Java and C++.
Changed to default to controlEnabled.
Loosely wrapped a bunch of CanTalonSRX functions in Java.

Change-Id: I9da380e2368d9a72f08be4434ac63b5710a9f90f
2014-12-04 17:00:36 -05:00
Fredric Silberberg
cd01945908 Image v20
This adds the updated v20 libraries, and bumps the image version number
in the ant build scripts

Change-Id: I7c4431c167dd77763d4004709454767daefccbf0
2014-12-04 14:50:21 -05:00
Omar Zrien
ea610eb302 Getters for : AppliedThrotte, CloseLoopErr, Sensor/Ain/Enc Pos and Vel are now signed extended. Before this negative values would not de-serialize correctly.
There are some redundant TALON fixes in this particular commit, hopefully it handles ok on Jenkins.
Tested with Talon SRX Unit Test (firm 0.34)

Change-Id: I67db546fea2867cc6bd53ea26dc1cb61ac106490
2014-12-04 10:40:59 -05:00
Omar Zrien
d04476bb2f Wired close loop pos and vel to CANTalon::Set().
Did basic testing with close loop pos with talon slaving.

Change-Id: I880a29bff29a43d45b7af1be05e08b09063bf5d7
2014-12-04 10:40:59 -05:00
Kevin O'Connor
2bb0a32c15 Change Periodic Status rate to 20ms. Jaguar firmware v109 fixes issue with periodic status sending.
Change-Id: I9d5e1f8dce5f63ea97fc3d14de518980d299b5eb
2014-12-04 10:22:01 -05:00
Fredric Silberberg
cdbe80315f Image v19
This updates the hal headers and ni libraries for image v19. There were
very few changes this time around, only some network communications stuff.
Also updated the minimum version number in the build properties to the new
image version

Change-Id: Ic8cb384b92c54d938dec36df34fc609626b4cd5d
2014-12-03 18:19:25 -05:00
Brad Miller (WPI)
517e708fd8 Merge "Reorded network table init to avoid error and added disabledInit to template (artf3841, artf3840)" 2014-12-03 14:37:07 -08:00
Brad Miller
70825be690 Reorded network table init to avoid error and added disabledInit to template (artf3841, artf3840)
Change-Id: I5d1b1925f594e8019541033b20f70be003798d82
2014-12-03 17:36:26 -05:00
Brad Miller (WPI)
43532198c7 Merge "Artifact artf3520 : Need a PDP Clear Sticky Faults API" 2014-12-03 11:40:18 -08:00
Omar Zrien
4da9ebe1fd Artifact artf3520 : Need a PDP Clear Sticky Faults API
Artifact artf3740 : C++ and Java don't implement all PDP features

Change-Id: I6a519d16de412a4d477b1f9c57e9b405b2e1aae0
2014-12-03 14:36:43 -05:00
Brad Miller (WPI)
9479793e1d Merge "Open scope of several data fields to be able to extend CommandGroup" 2014-12-03 11:08:06 -08:00
Brad Miller (WPI)
20e9f499b0 Merge "Add hasPeriodPassed function to java, for parity with C++ Timer API" 2014-12-03 11:06:58 -08:00
Brad Miller
3d897cef58 Make robot programs deploy as lvuser for correct permissions (artf3860)
Change-Id: Ia996f9c1b910c5c9cf33ca8a4305acd8b141b40c
2014-12-03 11:40:35 -05:00
Brad Miller
fa229f2b13 Added java joystick message spam fix (artf3836)
Change-Id: I1e29aea00dc61574272f47fc3e1bcd98bd825d22
2014-12-03 11:05:49 -05:00
Brad Miller
b1056cf6d7 Prevented missing joystick messages from coming out more than once a seccond (fixes artf3836)
Change-Id: I78c0862b0d1c65951a01169db56dbe4eaddf8247
2014-12-03 07:42:48 -05:00
Dustin Spicuzza
8e707169a1 Add hasPeriodPassed function to java, for parity with C++ Timer API
Change-Id: I0f9a2714f20deaaccce610bd3eec58409eac3104
2014-11-30 23:51:01 -05:00
Joe Ross
47961c8b13 Open scope of several data fields to be able to extend CommandGroup
Change-Id: I81ac59dd45aa50ed3d8dc4fdd1d5807899af546b
2014-11-30 08:28:15 -08:00
Brad Miller (WPI)
b59f4141c4 Merge "Open scope for gyro methods. Fixes FirstForge artf1699." 2014-11-28 08:34:15 -08:00
Brad Miller (WPI)
d62d82b28b Merge "Feed motor safety when StopMotor is called. Fixes artf1687 on FirstForge." 2014-11-28 08:29:27 -08:00
Brad Miller
a9d30c0389 Fixed a typo in the SRX sample project to correct a variable name error
Change-Id: I68f9cf33062bf2ef5df88247af8a5ee470a28d77
2014-11-28 11:07:08 -05:00
Joe Ross
6e0c84d942 Feed motor safety when StopMotor is called. Fixes artf1687 on FirstForge.
Change-Id: I75c1b30c28193c1e5ed5f6fad502ab88ebc345fa
2014-11-27 11:31:00 -08:00
Joe Ross
bb8ea17acf Open scope for gyro methods. Fixes FirstForge artf1699.
Allows user to cause gyro calibration on demand. It also exposes
the AnalogInput object as protected to allow the user to extend
the gyro class and implement their own calibration.

Change-Id: Ib4206a9b16ce6d5e8e5ca9c28a14471974705a7f
2014-11-27 08:37:27 -08:00
Brad Miller (WPI)
c683e24aa9 Merge changes If51bf61d,Ia6f4997b
* changes:
  Added Omar's new CanTalonSRX code.
  Added nicer Java interface for Talon SRX -- throttle mode works.
2014-11-26 12:53:44 -08:00
James Kuszmaul
7b371f6d7c Added Omar's new CanTalonSRX code.
I also updated the C++ and Java code some. For C++, this meant making it
compile and adding in the framework for the closed-loop control of the
motor. For Java, I updated the JNI bindings with SWIG and created an
GetTemperature accessor function to demonstrate how to use the accessors
because swig does funny stuff with pass-by-reference functions.

Change-Id: If51bf61d0a9bc65a8d497f8d91a5be8d6ff4fdcc
2014-11-26 15:51:16 -05:00
Brad Miller (WPI)
f6de7bc961 Merge "Java debug launcher no longer waits for text marker to appear in console." 2014-11-26 12:05:27 -08:00
Brad Miller
c00d9f1523 Updated the names and descriptions for the c++ vision examples
Change-Id: I7f4e72ddd3e5f5ad20012ed81bd74fa5373e0ebd
2014-11-26 14:26:32 -05:00
James Kuszmaul
6ec2d262c8 Added nicer Java interface for Talon SRX -- throttle mode works.
Change-Id: Ia6f4997b4836826f56a3dd4c8f7f29a0bf62d94c
2014-11-26 14:02:20 -05:00
Brad Miller (WPI)
3c8b31608c Merge "Use standard eclipse dialogs instead of Swing dialogs" 2014-11-26 10:32:19 -08:00
Brad Miller (WPI)
29f36b0eac Merge "Overwrite instead of append during version check. Fixes artf3818" 2014-11-26 09:10:17 -08:00
Brad Miller (WPI)
486885e8bf Merge changes Id7a97940,I6234fe06
* changes:
  Simulator makefiles: Set file extension based on platform
  Fix CMakeLists.txt to not be platform specific
2014-11-26 09:02:01 -08:00
Brad Miller (WPI)
020d97580a Merge "Fixed bug with SDFormat version changing." 2014-11-26 09:01:36 -08:00
James Kuszmaul
28a41e4ac2 Added support for CAN Talon SRX in C++ and Java.
Currently, the JNI bindings are generated by Swig and, unfortunately,
  the interface available through Java is lower-level than that for C++
  (ie, direct access to the ctre code through the JNI bindings, rather
   than an interface on top of that), but it does work.
See eclipse plugins for some short samples.
There are a couple of short unit tests as placeholders.
Still needs some cleaning up.

Change-Id: Iae2f74693ca6b80bf7d5aca0625c66aa6e0b7f85

Added quick samples for C++/Java CAN Talon stuff.

Change-Id: I3acb27d6fd5568d88931e0d678c09973d436735d
2014-11-26 11:55:37 -05:00
Brad Miller (WPI)
f590cda8f9 Merge "match templates with robot builder." 2014-11-26 08:34:03 -08:00
Joe Ross
c98f54dbbc match templates with robot builder.
Change-Id: Iedb8b9efc58ca73bc654b119d5d1aed5b4eb5553
2014-11-26 07:41:56 -08:00
Brad Miller
81840b2c49 Add a getControlWord() call to the run thread in DS so that the program is kept alive
Change-Id: I8b86506f6125422e19e8b5ab23e3667bf808bdc4
2014-11-25 17:34:38 -05:00
Paul Malmsten
78ccb48fd3 Java debug launcher no longer waits for text marker to appear in console.
Lanucher immediately attempts to attach 20 times before giving up
and waits 2 seconds between attempts.

Change-Id: Ib0a70b8bbf5e90d5a733ea4e0d6b17d91b36db87
2014-11-23 15:34:52 -05:00
Kevin O'Connor
b9913d3e12 Overwrite instead of append during version check. Fixes artf3818
Change-Id: I05bde0997e13318c113a7f7ee228fa1c007bfd2f
2014-11-22 14:32:13 -05:00
Brad Miller (WPI)
56430ccd7c Merge "Pipe java program output through NetConsole" 2014-11-22 11:14:06 -08:00
Brad Miller (WPI)
d412584f16 Merge "Tried to improve reliability of a couple of unit tests." 2014-11-22 10:58:09 -08:00
Kevin O'Connor
364a3afad4 Pipe java program output through NetConsole
Change-Id: Ia012d73236d8e9c73cb53eb011f1b1f9d3c2ce83
2014-11-21 16:39:46 -05:00
Kevin O'Connor
97456f40f7 Don't buffer NetComms data and add IsDSAttached() check to C++ IsEnabled() method (fixes artf3747)
Change-Id: Idaa7edcd601147c39fb31b7966d9e975869dea87
2014-11-21 13:14:48 -05:00
Kevin O'Connor
7e5ed03d28 Check if Joystick Button exists when requested and pass 0 and warn if it doesn't
Change-Id: I2194859ef8b263f1a20aba52ec154fb0a1fc8078
2014-11-21 12:07:08 -05:00
Kevin O'Connor
14a1e6ae8e Get MatchTime from NetComms (fixes artf2538)
Change-Id: I7ea438ce4610087bceac696a958e3c1e3ead238a
2014-11-21 10:37:29 -05:00
Dustin Spicuzza
529f5b773f Use standard eclipse dialogs instead of Swing dialogs
- Swing dialog triggers freeze on Eclipse Luna on OSX 10.10

Change-Id: I9f59e884d19dd397502537286d2730be9eb0fec1
2014-11-20 23:39:54 -08:00
James Kuszmaul
91c70daf5b Tried to improve reliability of a couple of unit tests.
Change-Id: I45307da855808e85c8f9b9958c7590d60636f8e9
2014-11-20 16:39:32 -05:00
Alex Henning
e86312cd6f Fixed bug with SDFormat version changing.
Change-Id: Ia2d17fc60763678ad4971d108861988157537fc3
2014-11-20 16:07:00 -05:00
Dustin Spicuzza
d7a9794080 Simulator makefiles: Set file extension based on platform 2014-11-17 21:36:29 -08:00
Dustin Spicuzza
6234fe06f5 Fix CMakeLists.txt to not be platform specific
- Additionally, use the boost macro to properly find its library
2014-11-17 21:36:29 -08:00
130 changed files with 10438 additions and 933 deletions

View File

@@ -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>

View File

@@ -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) {
}
}

View File

@@ -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."));
}

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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"/>

View File

@@ -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()

View File

@@ -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);

View File

@@ -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);

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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

View File

@@ -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>

View File

@@ -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(){
}
/**

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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);
}
}
}

View File

@@ -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 "";
}
}
}

View File

@@ -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

View File

@@ -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}"

View File

@@ -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

View File

@@ -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

View File

@@ -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 *);

View File

@@ -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);
}

View File

@@ -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, &timestamp, &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;
}

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();
}

View 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 &param)
{
GET_STATUS1();
param = rx->Fault_OverTemp;
return rx.err;
}
CTR_Code CanTalonSRX::GetFault_UnderVoltage(int &param)
{
GET_STATUS1();
param = rx->Fault_UnderVoltage;
return rx.err;
}
CTR_Code CanTalonSRX::GetFault_ForLim(int &param)
{
GET_STATUS1();
param = rx->Fault_ForLim;
return rx.err;
}
CTR_Code CanTalonSRX::GetFault_RevLim(int &param)
{
GET_STATUS1();
param = rx->Fault_RevLim;
return rx.err;
}
CTR_Code CanTalonSRX::GetFault_HardwareFailure(int &param)
{
GET_STATUS1();
param = rx->Fault_HardwareFailure;
return rx.err;
}
CTR_Code CanTalonSRX::GetFault_ForSoftLim(int &param)
{
GET_STATUS1();
param = rx->Fault_ForSoftLim;
return rx.err;
}
CTR_Code CanTalonSRX::GetFault_RevSoftLim(int &param)
{
GET_STATUS1();
param = rx->Fault_RevSoftLim;
return rx.err;
}
CTR_Code CanTalonSRX::GetStckyFault_OverTemp(int &param)
{
GET_STATUS2();
param = rx->StckyFault_OverTemp;
return rx.err;
}
CTR_Code CanTalonSRX::GetStckyFault_UnderVoltage(int &param)
{
GET_STATUS2();
param = rx->StckyFault_UnderVoltage;
return rx.err;
}
CTR_Code CanTalonSRX::GetStckyFault_ForLim(int &param)
{
GET_STATUS2();
param = rx->StckyFault_ForLim;
return rx.err;
}
CTR_Code CanTalonSRX::GetStckyFault_RevLim(int &param)
{
GET_STATUS2();
param = rx->StckyFault_RevLim;
return rx.err;
}
CTR_Code CanTalonSRX::GetStckyFault_ForSoftLim(int &param)
{
GET_STATUS2();
param = rx->StckyFault_ForSoftLim;
return rx.err;
}
CTR_Code CanTalonSRX::GetStckyFault_RevSoftLim(int &param)
{
GET_STATUS2();
param = rx->StckyFault_RevSoftLim;
return rx.err;
}
CTR_Code CanTalonSRX::GetAppliedThrottle(int &param)
{
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 &param)
{
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 &param)
{
GET_STATUS1();
param = rx->FeedbackDeviceSelect;
return rx.err;
}
CTR_Code CanTalonSRX::GetModeSelect(int &param)
{
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 &param)
{
GET_STATUS1();
param = rx->LimitSwitchEn;
return rx.err;
}
CTR_Code CanTalonSRX::GetLimitSwitchClosedFor(int &param)
{
GET_STATUS1();
param = rx->LimitSwitchClosedFor;
return rx.err;
}
CTR_Code CanTalonSRX::GetLimitSwitchClosedRev(int &param)
{
GET_STATUS1();
param = rx->LimitSwitchClosedRev;
return rx.err;
}
CTR_Code CanTalonSRX::GetSensorPosition(int &param)
{
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 &param)
{
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 &param)
{
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 &param)
{
GET_STATUS2();
param = rx->BrakeIsEnabled;
return rx.err;
}
CTR_Code CanTalonSRX::GetEncPosition(int &param)
{
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 &param)
{
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 &param)
{
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 &param)
{
GET_STATUS3();
param = rx->QuadApin;
return rx.err;
}
CTR_Code CanTalonSRX::GetQuadBpin(int &param)
{
GET_STATUS3();
param = rx->QuadBpin;
return rx.err;
}
CTR_Code CanTalonSRX::GetQuadIdxpin(int &param)
{
GET_STATUS3();
param = rx->QuadIdxpin;
return rx.err;
}
CTR_Code CanTalonSRX::GetAnalogInWithOv(int &param)
{
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 &param)
{
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 &param)
{
GET_STATUS4();
uint32_t raw = rx->Temp;
param = (double)raw * 0.6451612903 + -50;
return rx.err;
}
CTR_Code CanTalonSRX::GetBatteryV(double &param)
{
GET_STATUS4();
uint32_t raw = rx->BatteryV;
param = (double)raw * 0.05 + 4;
return rx.err;
}
CTR_Code CanTalonSRX::GetResetCount(int &param)
{
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 &param)
{
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 &param)
{
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;
}

View 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 &param);
CTR_Code GetFault_UnderVoltage(int &param);
CTR_Code GetFault_ForLim(int &param);
CTR_Code GetFault_RevLim(int &param);
CTR_Code GetFault_HardwareFailure(int &param);
CTR_Code GetFault_ForSoftLim(int &param);
CTR_Code GetFault_RevSoftLim(int &param);
CTR_Code GetStckyFault_OverTemp(int &param);
CTR_Code GetStckyFault_UnderVoltage(int &param);
CTR_Code GetStckyFault_ForLim(int &param);
CTR_Code GetStckyFault_RevLim(int &param);
CTR_Code GetStckyFault_ForSoftLim(int &param);
CTR_Code GetStckyFault_RevSoftLim(int &param);
CTR_Code GetAppliedThrottle(int &param);
CTR_Code GetCloseLoopErr(int &param);
CTR_Code GetFeedbackDeviceSelect(int &param);
CTR_Code GetModeSelect(int &param);
CTR_Code GetLimitSwitchEn(int &param);
CTR_Code GetLimitSwitchClosedFor(int &param);
CTR_Code GetLimitSwitchClosedRev(int &param);
CTR_Code GetSensorPosition(int &param);
CTR_Code GetSensorVelocity(int &param);
CTR_Code GetCurrent(double &param);
CTR_Code GetBrakeIsEnabled(int &param);
CTR_Code GetEncPosition(int &param);
CTR_Code GetEncVel(int &param);
CTR_Code GetEncIndexRiseEvents(int &param);
CTR_Code GetQuadApin(int &param);
CTR_Code GetQuadBpin(int &param);
CTR_Code GetQuadIdxpin(int &param);
CTR_Code GetAnalogInWithOv(int &param);
CTR_Code GetAnalogInVel(int &param);
CTR_Code GetTemp(double &param);
CTR_Code GetBatteryV(double &param);
CTR_Code GetResetCount(int &param);
CTR_Code GetResetFlags(int &param);
CTR_Code GetFirmVers(int &param);
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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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 &currentAmps)
{
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)

View File

@@ -38,6 +38,19 @@ public:
* @Param - status - Temperature of PDP in Centigrade / Celcius (C)
*/
CTR_Code GetTemperature(double &status);
CTR_Code GetTotalCurrent(double &currentAmps);
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);
};

View File

@@ -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.

View File

@@ -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

View File

@@ -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})

View File

@@ -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)

View File

@@ -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})

View File

@@ -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)

View File

@@ -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})

View File

@@ -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)

View File

@@ -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})

View File

@@ -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)

View File

@@ -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})

View File

@@ -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)

View File

@@ -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)

View File

@@ -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})

View File

@@ -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)

View File

@@ -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})

View File

@@ -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)

View File

@@ -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})

View File

@@ -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)

View File

@@ -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);
};

View File

@@ -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();

View 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;
};

View 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;
};

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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

View File

@@ -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__ */

View File

@@ -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
{

View 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();
};

View File

@@ -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
{

View 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();
};

View File

@@ -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"

View 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 &param);
CTR_Code GetFault_UnderVoltage(int &param);
CTR_Code GetFault_ForLim(int &param);
CTR_Code GetFault_RevLim(int &param);
CTR_Code GetFault_HardwareFailure(int &param);
CTR_Code GetFault_ForSoftLim(int &param);
CTR_Code GetFault_RevSoftLim(int &param);
CTR_Code GetStckyFault_OverTemp(int &param);
CTR_Code GetStckyFault_UnderVoltage(int &param);
CTR_Code GetStckyFault_ForLim(int &param);
CTR_Code GetStckyFault_RevLim(int &param);
CTR_Code GetStckyFault_ForSoftLim(int &param);
CTR_Code GetStckyFault_RevSoftLim(int &param);
CTR_Code GetAppliedThrottle(int &param);
CTR_Code GetCloseLoopErr(int &param);
CTR_Code GetFeedbackDeviceSelect(int &param);
CTR_Code GetModeSelect(int &param);
CTR_Code GetLimitSwitchEn(int &param);
CTR_Code GetLimitSwitchClosedFor(int &param);
CTR_Code GetLimitSwitchClosedRev(int &param);
CTR_Code GetSensorPosition(int &param);
CTR_Code GetSensorVelocity(int &param);
CTR_Code GetCurrent(double &param);
CTR_Code GetBrakeIsEnabled(int &param);
CTR_Code GetEncPosition(int &param);
CTR_Code GetEncVel(int &param);
CTR_Code GetEncIndexRiseEvents(int &param);
CTR_Code GetQuadApin(int &param);
CTR_Code GetQuadBpin(int &param);
CTR_Code GetQuadIdxpin(int &param);
CTR_Code GetAnalogInWithOv(int &param);
CTR_Code GetAnalogInVel(int &param);
CTR_Code GetTemp(double &param);
CTR_Code GetBatteryV(double &param);
CTR_Code GetResetCount(int &param);
CTR_Code GetResetFlags(int &param);
CTR_Code GetFirmVers(int &param);
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

View 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

View 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

View File

@@ -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;
}
/**

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}
/**

View File

@@ -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);
}

View File

@@ -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, "");
}
}

View File

@@ -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();
}

View 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() {
}

View 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() {
}

View File

@@ -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.";
}

View File

@@ -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();

View 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);
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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}.

View File

@@ -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);

View File

@@ -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;
}
/**

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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