Compare commits

...

80 Commits

Author SHA1 Message Date
Patrick Plenefisch
46dc99a115 Adding SFX to tools zip
Change-Id: I09a04506682a5d0ccbe8e556285de587915f7383
2014-12-19 09:52:25 -08:00
Brad Miller (WPI)
91d714d2e9 Merge "Single line bug in CanTalonSRX::GetAnalogInVel(). return value was not being sign-extended." 2014-12-19 07:02:09 -08:00
Brad Miller (WPI)
9a28aaaa7c Merge "Change expected voltage on CAN tests" 2014-12-19 07:01:20 -08:00
Omar Zrien
96a76ba89e Single line bug in CanTalonSRX::GetAnalogInVel(). return value was not being sign-extended.
Change-Id: I44271726ece9aaa7b94f35e611f24a18dbb53825
2014-12-19 03:27:29 -05:00
Brad Miller
d26059a4fb Change expected voltage on CAN tests
Change-Id: I8c4533c7bcc81e7904d10792316382d4c01a840a
2014-12-18 21:22:31 -05:00
Brad Miller
ee0d835304 Remove an extra constructor from a bad merge
Change-Id: I0475eef143814ebf8ee4ec71a019872420442c4f
2014-12-18 18:28:15 -05:00
James Kuszmaul
6080a3b186 Duplicate of gerrit 739; changed method from public to private.
Change-Id: Ib15210ff0e5d8d99a649397499bab4737a1a489e
2014-12-18 16:08:46 -05:00
Omar Zrien
3d06a763a2 CanTalon : Adding config routines for limit switch normally open vs normally closed.
They already existed in Labview, so this will keep parity
New C++/Java funcs
ConfigFwdLimitSwitchNormallyOpen
ConfigRevLimitSwitchNormallyOpen

Change-Id: Ifd65ead827838e7158f7261c67adc3738c72eabf
2014-12-18 15:57:26 -05:00
Omar Zrien
e1480ec798 Noticed that if changeControlMode() is called every teleop loop, it causes motor to stutter as it enters and immediately leaves kDisabled.
A simple improvement was to only perform the disable-before-next-set strategy if the caller's request mode is not equal to the current mode.

To keep things simple, SetControlMode was renamed to private method ApplyControlMode so we can still invoke it from c'tor.
Then, the new impl'n of SetControlMode() just calls ApplyControlMode() when caller's request mode is different.  That takes care of direct-calls from team source, and indirect calls through enableControl().

Applied to both c++ and java.
Tested in java so far...

Change-Id: I934c06c5339d933918470659acd635e12eb4d113
2014-12-18 15:54:47 -05:00
Omar Zrien
a5d9ba412c Second pass through all the HAL functions and cpp/java API. Filled in some parity holes between java and cpp.
Java...
added setStatusFrameRateMs() to modify the frame rate for status frames
added missing func that already exists in c++
	isFwdLimitSwitchClosed()
	isRevLimitSwitchClosed()
	getNumberOfQuadIdxRises()
	getPinStateQuadA()
	getPinStateQuadB()
	getPinStateQuadIdx()
added getAnalogInRaw() that doesn't count overflows (for potentiometers).
added setStatusFrameRateMs() to modify the frame rate for status frames
added getBrakeEnableDuringNeutral()

C++...
added GetAnalogInRaw() that doesn't count overflows (for potentiometers).
added SetStatusFrameRateMs() to modify the frame rate for status frames
added GetBrakeEnableDuringNeutral()
added kLimitMode_SrxDisableSwitchInputs to CANSpeedController::LimitMode

Patch set 2: Joe Ross, fixed two javadoc errors

Change-Id: I0bf871e138953de60eeacb547dc359f2125b1327
2014-12-18 15:51:47 -05:00
Omar Zrien
2434515d41 artf3913
Increased wait delay to 4ms to cover worst case delays for solicted signal getters.
Specifically....
-Get firmware vers
-Get P,I,D,F gains
-Get IZone, Get CloseLoopRampRate
-Get IAccum (integral accumulator)

Change-Id: I313ea984832cce5182af8e5af5e775837fd54fdc
2014-12-18 15:49:29 -05:00
Brad Miller (WPI)
741618250b Merge "C++ CANTalon was missing SetIzone. Added SetIzone to match java, and made the set/get Izone integral." 2014-12-18 12:45:34 -08:00
Omar Zrien
8b8d7e77cd C++ CANTalon was missing SetIzone. Added SetIzone to match java, and made the set/get Izone integral.
Change-Id: I264ac8faaab0ebd208062923f6da2094e7e28b0a
2014-12-18 15:16:10 -05:00
Omar Zrien
c093a553ee changed variable type of closeLoopRampRate in setpid to double from int. It's represents V per sec since it calls setCloseLoopRampRate() underneath.
The other remaining closeloopramprate changes are also merged into this commit, so they may be redundant on gerrit.

Change-Id: Ic3108bb3669e487009b8f52412da3c2f44c42f6f
2014-12-18 15:11:39 -05:00
Fred Silberberg (WPI)
a1375e58cd Merge "Don't fail silently if DIO or PWM allocation fails" 2014-12-18 11:25:39 -08:00
Brad Miller (WPI)
15ff7f5038 Merge "Added the getButtons method back that reads all the buttons at the same time" 2014-12-18 10:33:11 -08:00
Brad Miller
c17ba98f72 Added the getButtons method back that reads all the buttons at the same time
Change-Id: I0f7f35b6a70f861911166de7be3802547ff4b2eb
2014-12-18 10:57:11 -05:00
Brad Miller (WPI)
dee755ab19 Merge "renamed param to match function name." 2014-12-18 07:06:20 -08:00
Brad Miller (WPI)
92c54f5f5d Merge "Image v23" 2014-12-17 15:10:36 -08:00
Fred Silberberg (WPI)
1fde00643f Merge "Fixed post4066 bug: Prestart() inaccessible." 2014-12-17 14:19:03 -08:00
Colby Skeggs
47443b4e1e Fixed post4066 bug: Prestart() inaccessible.
Change-Id: Ie179453b038458e77257c1b2d0acba7a4224f6c4
2014-12-17 13:39:54 -08:00
PetaroMitaro
f01e5b5570 fixed robotCommand in src
Change-Id: I591939301da4427e9139b824b016bb00d4b24485
2014-12-17 16:11:48 -05:00
Fredric Silberberg
22c4207553 Image v23
This updates the image version to version 23. It also moves the vision libraries
to follow the same conventions as the rest of the ni libraries.

Change-Id: I39e6fb3d8bbd2fd3141c2a43a5bae2fd15149003
2014-12-17 11:04:21 -05:00
Omar Zrien
bea9eb0efa renamed param to match function name.
Change-Id: I89c483691e0f99a6d20bed1271209a8141e71c0e
2014-12-16 20:05:30 -05:00
Brad Miller (WPI)
b72eb4b812 Merge "added Java vision example programs" 2014-12-16 11:43:02 -08:00
Dustin Spicuzza
0d8c454727 Don't fail silently if DIO or PWM allocation fails
Change-Id: I800c429507c3436c2d49561ba279700ad52569fe
2014-12-16 14:24:14 -05:00
PetaroMitaro
d61d491a02 added Java vision example programs
Change-Id: Icd99f53cc544c2609a333f0a86f4eac064d565bd
2014-12-16 11:14:37 -05:00
Brad Miller (WPI)
786e844a9f Merge "Fix ControllerPower 5v faults and add javadocs. Fixes artf3918." 2014-12-16 08:07:30 -08:00
Joe Ross
170b5860ee Fix javadoc compile errors that broke build.
Change-Id: Ie110743154f842dc3a2e756f7917e3aa131c87bd
2014-12-15 19:03:27 -08:00
PetaroMitaro
26c50ebe02 fixed java CameraServer
Change-Id: I34b8c1e2ff05199afdcab579f7ac7188fbe40fd7
2014-12-15 19:45:56 -05:00
Joe Ross
46c659d6b6 Enable Java 8 doclint checking (except for missing tags).
Change-Id: Iebfc7b99cbe43375f9cc067cca322244af44395b
2014-12-15 15:50:44 -08:00
Joe Ross
6fdd491081 Fix javadoc warnings.
Change-Id: I37049f234c6dfddc138121822525794d74e1b74c
2014-12-15 18:48:46 -05:00
Fred Silberberg (WPI)
fe4535dfa0 Merge "Resolved artf3579: robot can no longer be enabled until robotInit() finishes in IterativeRobot; similar options available by overriding prestart() for other base classes." 2014-12-15 15:39:21 -08:00
Brad Miller
636e2e13ad Wrong package declaration in camera server
Change-Id: Ia35d7f78d37aa0db51eb98901364fc228dabaa53
2014-12-15 13:40:25 -05:00
PetaroMitaro
d3f5b74668 added CameraServer.java
Change-Id: I4c41b560d879ffc6d8aa4681cad8f75297fe6cda

Fixed some issues with the camera server class

Change-Id: Ifda524b55f84053be004a404a2890905ded7b266
2014-12-15 11:00:49 -05:00
Brad Miller (WPI)
8116bbd15b Merge "Fix various bugs in nivision wrappers." 2014-12-15 05:42:07 -08:00
Peter Johnson
37052246a5 Fix various bugs in nivision wrappers.
- IMAQdx typedef overrides were being ignored, resulting in incorrect types
(e.g. IMAQdxSession was a long instead of an int).

- Allocated byte buffers byte order was not being set.

- imaqDispose was incorrectly named.

Change-Id: I5d038d45e82755615f0a5bb928defb98f557f93e
2014-12-15 02:44:07 -08:00
Joe Ross
a649d3b553 Fix ControllerPower 5v faults and add javadocs. Fixes artf3918.
5V faults was returning count of 3.3V faults. Copied javadocs from
C++.

Change-Id: I95b5c6ed1213ed235ecde11ef7e28ad05aabca6e
2014-12-14 16:55:22 -08:00
Omar Zrien
6a7e7cf611 Two param constructor added to C++/java CANTalon so caller can optionally specify the periodMs at which the talon control frame is sent.
The param is capped in the HAL C++ class to [1ms, 95ms] so that zero and negative periods are caped to 1ms, and so that caller can't pass an absurdly large value, which causes TALON is appear disabled.

Change-Id: I4207194be25a33bbd6ad281a75301ce6684659a5
2014-12-14 17:09:52 -05:00
Brad Miller (WPI)
77997e52fb Merge "added PDP methods to javalib" 2014-12-14 07:34:56 -08:00
Peter Johnson
e655072efc Synchronize access to buffered Joystick data.
Change-Id: Iae453872e89c7b6364d486a6bbc8b210c94defee
2014-12-14 10:22:18 -05:00
Brad Miller (WPI)
0427fc34c4 Merge "Check for negative button value and add missing newline." 2014-12-14 07:07:01 -08:00
Brad Miller (WPI)
e33d80be14 Merge "Add USB serial port option. Uses kUSB for ALSR3" 2014-12-14 07:05:52 -08:00
Brad Miller (WPI)
8381eee185 Merge "Wrap IMAQdx functions." 2014-12-14 06:57:00 -08:00
Colby Skeggs
1c24096cc9 Resolved artf3579: robot can no longer be enabled until robotInit() finishes in IterativeRobot; similar options available by overriding prestart() for other base classes.
Change-Id: I07fde4b1bd2fae0c2e2a04336639b44ec715628a
2014-12-14 01:22:41 +00:00
Omar Zrien
3a684d28b2 PWM timing change for SP and SRX. added 3us to outer bounds
Change-Id: Idce12f8290b5f5646d0d3b14c2a4414fba3120cd
2014-12-13 18:06:43 -05:00
Joe Ross
8786b242b2 Add USB serial port option. Uses kUSB for ALSR3
Change-Id: Ie43fa14fff6aa2f332d3ebacfba099984f8b4eb7
2014-12-13 11:52:27 -08:00
Peter Johnson
b29a4bebf2 Check for negative button value and add missing newline.
Change-Id: I407ab2e0090c22b08503c6de0460d6c1291fa07f
2014-12-13 02:37:35 -08:00
Peter Johnson
db0b421019 Wrap IMAQdx functions.
Quite a few functions aren't wrapped, but the most critical ones for
vision should be.

This also fixes a couple of issues:
- nivision_arm.ini (and imaqdx_arm.ini) are now generated without need for
  running the output on the RoboRIO.
- enum values are generated even if the value is not directly specified.
2014-12-13 00:32:20 -08:00
Kevin O'Connor
8efe998270 Make VictorSP and TalonSRX use correct bounds (give an extra 1us on min and max to ensure saturation). Fixes artf3914 for C++ and Java
Change-Id: Ia1a848e011615e4ff50b9f5ef6e1017764aeb904
2014-12-12 18:09:44 -05:00
Brad Miller (WPI)
ac60198842 Merge "Change vision defaults from "cam1" to cam0". Add some error reporting to Intermediate Vision example" 2014-12-12 14:01:26 -08:00
Brad Miller (WPI)
8a5ee71fd8 Merge "Make SetImaqError actually set the error" 2014-12-12 14:00:48 -08:00
Brad Miller (WPI)
af4ce1074a Merge "Image v22" 2014-12-12 12:49:11 -08:00
Dustin Spicuzza
7636041393 Don't use raw type for HALSetNewDataSem
Change-Id: Ifb6561a33b8e0c49072f9d9c00a2c9c8f4cc3fe3
2014-12-12 15:26:47 -05:00
Fredric Silberberg
745489fec7 Image v22
Added the v22 libraries and headers, and updated the minimum version number to version 22

Change-Id: Ie89dcde0212f164296c01e906b3ee9f332fb0b02
2014-12-12 15:15:45 -05:00
Kevin O'Connor
04f9ca4feb Change vision defaults from "cam1" to cam0". Add some error reporting to Intermediate Vision example
Change-Id: If0bb60611c6c5e6f2411ad5d0432c712b24efb24
2014-12-12 15:08:07 -05:00
Kevin O'Connor
ca5dfbe492 Make SetImaqError actually set the error
Change-Id: Ib714a2ff380319c60f42c859454441e4b69736e0
2014-12-12 14:36:27 -05:00
Brad Miller (WPI)
07619a37a0 Merge "Add C function wrappers for CanTalonSRX." 2014-12-12 05:12:07 -08:00
Brad Miller (WPI)
34d3d756ea Merge "Update javadoc for RobotDrive. Mecanum methods are implemented." 2014-12-12 05:11:06 -08:00
Brad Miller (WPI)
61a5fcce18 Merge "Squashed commit of the following:" 2014-12-12 05:10:34 -08:00
Brad Miller (WPI)
82c4563d34 Merge "getHALErrorMessage(): Add missing CTRE errors." 2014-12-12 05:06:37 -08:00
Peter Johnson
fa337bc747 Add C function wrappers for CanTalonSRX.
Also sync wpilibC++Devices copy of CanTalonSRX.h.

Change-Id: Ideabb0493230ab37563698d37b0360c590f4bbbb
2014-12-12 01:41:08 -08:00
Peter Johnson
8ae7e973f2 getHALErrorMessage(): Add missing CTRE errors.
Change-Id: Ifea0bd9c57d007744616c8808e8f4b1429199898
2014-12-12 00:11:50 -08:00
Peter Johnson
574f2e692a Java nivision: Add RawData to wrap void*.
Change-Id: I8a5dc2a208a39b3c0a26a1a9f906a5c19738628d
2014-12-11 22:19:08 -08:00
Kevin O'Connor
827341caa2 Squashed commit of the following:
commit c8543f97f77a0fef282b6598ae094ac75ea1dd22
Author: Kevin O'Connor <koconnor@usfirst.org>
Date:   Thu Dec 11 16:41:08 2014 -0500

    Go back to buffering Joystick data.

    Change-Id: I0b4204bfc6e81f50dc4a01c58cfbe14a771e902f

commit a8ddee2a923749903aafe2a8121171b1d70750e7
Author: Kevin O'Connor <koconnor@usfirst.org>
Date:   Fri Dec 5 17:38:58 2014 -0500

    Add error for using non-existent button 0. Fixes artf3870.

    Change-Id: I5b83cc7e3f0e4ab957279a877c76eeab6cb4b77b

Change-Id: Iae36482fd82176a9e09da1cfdfb69591411b2be2
2014-12-11 16:47:29 -05:00
Brad Miller (WPI)
dd272e6bcb Merge "Add Java nivision wrappers." 2014-12-11 10:00:38 -08:00
Joe Ross
3bdaa63a28 Update javadoc for RobotDrive. Mecanum methods are implemented.
Change-Id: Ia0e0fc62f8deae778eaa14789086ff47210796bb
2014-12-10 19:34:56 -08:00
Brad Miller (WPI)
41b393c210 Merge "Fixed minor issues in CANTalon. Fixes artf3884, 3885, 3887." 2014-12-10 05:53:56 -08:00
Brad Miller (WPI)
11cf860ecd Merge "Check and coerce rumble inputs to range of 0 - 1." 2014-12-10 05:31:55 -08:00
Brad Miller (WPI)
2168d2cb77 Merge "Require Jaguar version v108 or higher." 2014-12-09 14:21:10 -08:00
Peter Johnson
430722c4a3 Add Java nivision wrappers.
Only very basic testing performed to date.

The wrappers are still a bit incomplete (some structures and functions),
but are much more complete than the old ones.

Fixes artf3796.

Changes from initial changeset:
- Use // for comments.
- Add auto-generate notices to the beginning of each generated file.
- Include error number with error text in exception.
- Add free() function to structures.
- Fix out-of-order / non-array enums.
- Avoid duplicate calls to DisposedStruct.write() as .getAddress() does it.
- Refactor OpaqueStruct.
- Default to no null allowed except when overridden.
- Implement unowned return values.
- Add gen_struct_sizer script.

Change-Id: Ie0d102c45817ea8812d98fe4938d1a2255c61664
2014-12-09 00:48:57 -08:00
Joe Ross
497f38fe0e Check and coerce rumble inputs to range of 0 - 1.
Change-Id: Ic2ee301549e68e8cc56f91755521f456c8d0b5f7
2014-12-08 20:45:22 -08:00
James Kuszmaul
9f2dcdeab6 Fixed minor issues in CANTalon. Fixes artf3884, 3885, 3887.
Adds isEnabled and getSetpoint functions to CANTalon classes.
Sets m_controlEnabled=false in Java if changeControlMode(Disabled) is
called.

Change-Id: I08fd0972df22ad83c5578dd43dd6b3536f3b365b
2014-12-08 15:32:54 -05:00
PetaroMitaro
ac07142e4c added PDP methods to javalib
Change-Id: I60f3f615b01dba6e05721c78ba890859c7c9f027
2014-12-07 14:40:27 -05:00
Omar Zrien
19a7243bfc C++
Added Get/clear routine for IntegralAccumulator
Added missing status check in GetFirmwareVersion().  I don't expect this to affect anything.

JAVA
Renamed getRampRate to getCloseLoopRampRate in java to match the set routines in java, and match all routines in cpp.
Added GetFirmwareVersion to java to match cpp.
Added Get/clear routine for IntegralAccumulator
Retested all three routines in java.

Change-Id: I4ce9d9c87a379b9d4a76aae226e2072876218688
2014-12-07 11:19:14 -05:00
Brad Miller (WPI)
e3ac0b628c Merge "Fixed issue in setting CANTalon values." 2014-12-07 08:12:14 -08:00
James Kuszmaul
709a88ad68 Fixed issue in setting CANTalon values.
Used to be that if you called Set less than ~20 ms after changing the
mode, potentially unwanted behavior could ensue.

Change-Id: I27cb3603286d8fddd894649787d88c0446b00615
2014-12-07 10:52:32 -05:00
Omar Zrien
6b844b52ec comment change and added SetModeSelect(int modeSelect,int demand)
{

Change-Id: Iadac7ec70cf04cdc339771c4e919e93723cf62ec
2014-12-06 15:32:14 -05:00
Omar Zrien
9056edf932 commented out system.out.prints in CANTalon.set()
Change-Id: I85bc50c5f1ee7364395eb28d03e3845fe70649c0
2014-12-06 13:39:49 -05:00
Kevin O'Connor
36c53667cd Require Jaguar version v108 or higher.
Change-Id: Ib3a29a9182a776771db8b45bf82df3168e800277
2014-12-04 14:15:01 -05:00
91 changed files with 36775 additions and 378 deletions

9
.gitignore vendored
View File

@@ -10,6 +10,11 @@ bin/
.project
.classpath
**/dependency-reduced-pom.xml
wpilibj/wpilibJavaJNI/nivision/*.c
wpilibj/wpilibJavaJNI/nivision/*.cpp
wpilibj/wpilibJavaJNI/nivision/*.s
wpilibj/wpilibJavaJNI/nivision/*_arm.ini
wpilibj/wpilibJavaJNI/nivision/*.java
# Created by the jenkins test script
test-reports
@@ -155,6 +160,10 @@ local.properties
.settings/
.loadpath
### Python ###
*.pyc
__pycache__
# External tool builders
.externalToolBuilders/

View File

@@ -85,6 +85,14 @@
<outputDirectory>${tools-zip}</outputDirectory>
<destFileName>SmartDashboard.jar</destFileName>
</artifactItem>
<artifactItem>
<groupId>edu.wpi.first.wpilib</groupId>
<artifactId>sfx</artifactId>
<type>zip</type>
<classifier>zip</classifier>
<outputDirectory>${tools-zip}/../</outputDirectory>
<destFileName>sfx.zip</destFileName>
</artifactItem>
<artifactItem>
<groupId>edu.wpi.first.wpilib.networktables</groupId>
<artifactId>OutlineViewer</artifactId>
@@ -143,6 +151,7 @@
</goals>
<configuration>
<target>
<unzip src="${tools-zip}/../sfx.zip" dest="${tools-zip}"/>
<zip destfile="${project.build.directory}/classes/resources/tools.zip"
basedir="${tools-zip}"
update="true" />
@@ -208,6 +217,12 @@
<artifactId>SmartDashboard</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilib</groupId>
<artifactId>sfx</artifactId>
<type>zip</type>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilib.networktables</groupId>
<artifactId>OutlineViewer</artifactId>

View File

@@ -8,14 +8,21 @@ class IntermediateVisionRobot : public SampleRobot
{
IMAQdxSession session;
Image *frame;
IMAQdxError imaqError;
public:
void RobotInit() override {
// create an image
frame = imaqCreateImage(IMAQ_IMAGE_RGB, 0);
// open the camera
IMAQdxOpenCamera("cam1", IMAQdxCameraControlModeController, &session);
IMAQdxConfigureGrab(session);
imaqError = IMAQdxOpenCamera("cam0", IMAQdxCameraControlModeController, &session);
if(imaqError != IMAQdxErrorSuccess) {
DriverStation::ReportError("IMAQdxOpenCamera error: " + std::to_string((long)imaqError) + "\n");
}
imaqError = IMAQdxConfigureGrab(session);
if(imaqError != IMAQdxErrorSuccess) {
DriverStation::ReportError("IMAQdxConfigureGrab error: " + std::to_string((long)imaqError) + "\n");
}
}
void OperatorControl() override {
@@ -26,10 +33,12 @@ public:
// in turn send it to the dashboard.
while(IsOperatorControl() && IsEnabled()) {
IMAQdxGrab(session, frame, true, NULL);
imaqDrawShapeOnImage(frame, frame, { 10, 10, 100, 100 }, DrawMode::IMAQ_DRAW_VALUE, ShapeMode::IMAQ_SHAPE_OVAL, 0.0f);
CameraServer::GetInstance()->SetImage(frame);
if(imaqError != IMAQdxErrorSuccess) {
DriverStation::ReportError("IMAQdxGrab error: " + std::to_string((long)imaqError) + "\n");
} else {
imaqDrawShapeOnImage(frame, frame, { 10, 10, 100, 100 }, DrawMode::IMAQ_DRAW_VALUE, ShapeMode::IMAQ_SHAPE_OVAL, 0.0f);
CameraServer::GetInstance()->SetImage(frame);
}
}
// stop image acquisition
IMAQdxStopAcquisition(session);

View File

@@ -8,7 +8,7 @@ command.dir=/home/lvuser/
# Libraries to use
wpilib=${user.home}/wpilib/cpp/${cpp-version}
wpilib.lib=${wpilib}/lib
roboRIOAllowedImages=20
roboRIOAllowedImages=23
# Ant support
wpilib.ant.dir=${wpilib}/ant

View File

@@ -0,0 +1,53 @@
package $package;
import com.ni.vision.NIVision;
import com.ni.vision.NIVision.DrawMode;
import com.ni.vision.NIVision.Image;
import com.ni.vision.NIVision.ShapeMode;
import edu.wpi.first.wpilibj.SampleRobot;
/**
* This is a demo program showing the use of the NIVision class to do vision processing.
* The image is acquired from the USB Webcam, then a circle is overlayed on it.
* The NIVision class supplies dozens of methods for different types of processing.
* The resulting image can then be sent to the FRC PC Dashboard with setImage()
*/
public class Robot extends SampleRobot {
int session;
Image frame;
public void robotInit() {
frame = NIVision.imaqCreateImage(NIVision.ImageType.IMAGE_RGB, 0);
/**
* the camera name (ex "cam1") can be found through the roborio web interface
*/
session = NIVision.IMAQdxOpenCamera("cam1",
NIVision.IMAQdxCameraControlMode.CameraControlModeController);
NIVision.IMAQdxConfigureGrab(session);
}
public void operatorControl() {
NIVision.IMAQdxStartAcquisition(session);
/**
* grab an image, draw the circle, and provide it for the camera server
* which will in turn send it to the dashboard.
*/
NIVision.Rect rect = new NIVision.Rect(10, 10, 100, 100);
while (isOperatorControl() && isEnabled()) {
NIVision.IMAQdxGrab(session, frame, 1);
NIVision.imaqDrawShapeOnImage(frame, frame, rect,
DrawMode.DRAW_VALUE, ShapeMode.SHAPE_OVAL, 0.0f);
CameraServer.getInstance().setImage(frame);
}
NIVision.IMAQdxStopAcquisition(session);
}
public void test() {
}
}

View File

@@ -0,0 +1,35 @@
package $package;
import edu.wpi.first.wpilibj.SampleRobot;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.Timer;
/**
* This is a demo program showing the use of the CameraServer class.
* With start automatic capture, there is no opertunity to process the image.
* Look at the AdvancedVision sample for how to process the image before sending it to the FRC PC Dashboard.
*/
public class Robot extends SampleRobot {
CameraServer server;
public Robot() {
server = CameraServer.getInstance();
server.setQuality(50);
}
/**
* start up automatic capture you should see the video stream from the
* webcam in your FRC PC Dashboard.
*/
public void operatorControl() {
server.startAutomaticCapture("cam1");
while (isOperatorControl() && isEnabled()) {
/** robot code here! **/
}
}
}

View File

@@ -81,6 +81,11 @@
<description>Example programs that demonstrate the use of the various commonly used sensors on FRC robots</description>
</tagDescription>
<tagDescription>
<name>Vision</name>
<description>Example programs that demonstrate the use of USB Cameras and image processing</description>
</tagDescription>
<example>
<name>Getting Started</name>
<description>An example program which demonstrates the simplest autonomous and
@@ -287,4 +292,35 @@
destination="src/$package-dir/triggers/DoubleButton.java"></file>
</files>
</example>
<example>
<name>Quick Vision</name>
<description>Demonstrate the use of the CameraServer class to stream from a USB Webcam without processing the images.</description>
<tags>
<tag>Vision</tag>
</tags>
<packages>
<package>src/$package-dir</package>
</packages>
<files>
<file source="examples/QuickVision/src/org/usfirst/frc/team190/robot/Robot.java"
destination="src/$package-dir/Robot.java"></file>
</files>
</example>
<example>
<name>Advanced Vision</name>
<description>Demonstrate the use of the NIVision class to capture image from a Webcam, process them, and then send them to the dashboard.</description>
<tags>
<tag>Vision</tag>
</tags>
<packages>
<package>src/$package-dir</package>
</packages>
<files>
<file source="examples/AdvancedVision/src/org/usfirst/frc/team190/robot/Robot.java"
destination="src/$package-dir/Robot.java"></file>
</files>
</example>
</examples>

View File

@@ -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=20
roboRIOAllowedImages=23
# Ant support
wpilib.ant.dir=${wpilib}/ant

View File

@@ -1,2 +1,2 @@
/usr/local/frc/bin/netconsole-host /usr/local/frc/JRE/bin/java -jar /home/lvuser/FRCUserProgram.jar
env LD_PRELOAD=/lib/libstdc++.so.6.0.20 /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/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
env LD_PRELOAD=/lib/libstdc++.so.6.0.20 /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

@@ -4,6 +4,8 @@
#define CTR_TxTimeout_MESSAGE "CTRE CAN Transmit Timeout"
#define CTR_InvalidParamValue_MESSAGE "CTRE CAN Invalid Parameter"
#define CTR_UnexpectedArbId_MESSAGE "CTRE Unexpected Arbitration ID (CAN Node ID)"
#define CTR_TxFailed_MESSAGE "CTRE CAN Transmit Error"
#define CTR_SigNotUpdated_MESSAGE "CTRE CAN Signal Not Updated"
#define NiFpga_Status_FifoTimeout_MESSAGE "NIFPGA: FIFO timeout error"
#define NiFpga_Status_TransferAborted_MESSAGE "NIFPGA: Transfer aborted error"
@@ -45,6 +47,8 @@
#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE "HAL: Attempted to read AnalogTrigger pulse output."
#define PARAMETER_OUT_OF_RANGE -1028
#define PARAMETER_OUT_OF_RANGE_MESSAGE "HAL: A parameter is out of range."
#define RESOURCE_IS_ALLOCATED -1029
#define RESOURCE_IS_ALLOCATED_MESSAGE "HAL: Resource already allocated"
#define VI_ERROR_SYSTEM_ERROR_MESSAGE "HAL - VISA: System Error";
#define VI_ERROR_INV_OBJECT_MESSAGE "HAL - VISA: Invalid Object"

View File

@@ -230,7 +230,7 @@ extern "C"
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble);
int HALGetMatchTime(float *matchTime);
void HALSetNewDataSem(pthread_cond_t *);
void HALSetNewDataSem(MULTIWAIT_ID sem);
bool HALGetSystemActive(int32_t *status);
bool HALGetBrownedOut(int32_t *status);

View File

@@ -384,7 +384,11 @@ bool allocateDIO(void* digital_port_pointer, bool input, int32_t *status) {
DigitalPort* port = (DigitalPort*) digital_port_pointer;
char buf[64];
snprintf(buf, 64, "DIO %d", port->port.pin);
if (DIOChannels->Allocate(port->port.pin, buf) == ~0ul) return false;
if (DIOChannels->Allocate(port->port.pin, buf) == ~0ul) {
*status = RESOURCE_IS_ALLOCATED;
return false;
}
{
Synchronized sync(digitalDIOSemaphore);
@@ -420,7 +424,11 @@ bool allocatePWMChannel(void* digital_port_pointer, int32_t *status) {
DigitalPort* port = (DigitalPort*) digital_port_pointer;
char buf[64];
snprintf(buf, 64, "PWM %d", port->port.pin);
if (PWMChannels->Allocate(port->port.pin, buf) == ~0ul) return false;
if (PWMChannels->Allocate(port->port.pin, buf) == ~0ul) {
*status = RESOURCE_IS_ALLOCATED;
return false;
}
if (port->port.pin > tPWM::kNumHdrRegisters-1) {
snprintf(buf, 64, "PWM %d and DIO %d", port->port.pin, remapMXPPWMChannel(port->port.pin) + 10);
if (DIOChannels->Allocate(remapMXPPWMChannel(port->port.pin) + 10, buf) == ~0ul) return false;

View File

@@ -54,6 +54,10 @@ const char* getHALErrorMessage(int32_t code)
return CTR_InvalidParamValue_MESSAGE;
case CTR_UnexpectedArbId:
return CTR_UnexpectedArbId_MESSAGE;
case CTR_TxFailed:
return CTR_TxFailed_MESSAGE;
case CTR_SigNotUpdated:
return CTR_SigNotUpdated_MESSAGE;
case NiFpga_Status_FifoTimeout:
return NiFpga_Status_FifoTimeout_MESSAGE;
case NiFpga_Status_TransferAborted:
@@ -223,9 +227,9 @@ int HALGetMatchTime(float *matchTime)
return FRC_NetworkCommunication_getMatchTime(matchTime);
}
void HALSetNewDataSem(pthread_cond_t * param)
void HALSetNewDataSem(MULTIWAIT_ID sem)
{
setNewDataSem(param);
setNewDataSem(sem);
}
bool HALGetSystemActive(int32_t *status)

View File

@@ -13,8 +13,10 @@ void serialInitializePort(uint8_t port, int32_t *status) {
if(port == 0)
portName = "ASRL1::INSTR";
else
else if (port == 1)
portName = "ASRL2::INSTR";
else
portName = "ASRL3::INSTR";
*status = viOpen(m_resourceManagerHandle, const_cast<char*>(portName), VI_NULL, VI_NULL, (ViSession*)&m_portHandle[port]);
if(*status > 0)

View File

@@ -63,9 +63,8 @@
* 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.
* CloseLoopRampRate is in throttle units per 1ms. Set to zero to disable ramping.
* Works the same as RampThrottle but only is in effect when a close loop mode and profile slot is selected.
*
* auto generated using spreadsheet and WpiClassGen.csproj
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
@@ -243,6 +242,11 @@ typedef struct _TALON_Param_Response_t {
CanTalonSRX::CanTalonSRX(int deviceNumber,int controlPeriodMs): CtreCanNode(deviceNumber), _can_h(0), _can_stat(0)
{
/* bound period to be within [1 ms,95 ms] */
if(controlPeriodMs < 1)
controlPeriodMs = 1;
else if(controlPeriodMs > 95)
controlPeriodMs = 95;
RegisterRx(STATUS_1 | (UINT8)deviceNumber );
RegisterRx(STATUS_2 | (UINT8)deviceNumber );
RegisterRx(STATUS_3 | (UINT8)deviceNumber );
@@ -567,6 +571,11 @@ CTR_Code CanTalonSRX::GetReverseSoftEnable(int & enable)
CTR_Code CanTalonSRX::SetStatusFrameRate(unsigned frameEnum, unsigned periodMs)
{
int32_t status = 0;
/* bounds check the period */
if(periodMs < 1)
periodMs = 1;
else if (periodMs > 255)
periodMs = 255;
uint8_t period = (uint8_t)periodMs;
/* tweak just the status messsage rate the caller cares about */
switch(frameEnum){
@@ -867,9 +876,9 @@ CTR_Code CanTalonSRX::GetAnalogInVel(int &param)
raw |= rx->AnalogInVelH;
raw <<= 8;
raw |= rx->AnalogInVelL;
param = (int)raw;
raw <<= (32-16); /* sign extend */
raw >>= (32-16); /* sign extend */
param = (int)raw;
return rx.err;
}
CTR_Code CanTalonSRX::GetTemp(double &param)
@@ -966,6 +975,23 @@ CTR_Code CanTalonSRX::SetModeSelect(int param)
FlushTx(toFill);
return CTR_OKAY;
}
/**
* @param modeSelect selects which mode.
* @param demand setpt or throttle or masterId to follow.
* @return error code, 0 iff successful.
* This function has the advantage of atomically setting mode and demand.
*/
CTR_Code CanTalonSRX::SetModeSelect(int modeSelect,int demand)
{
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 = modeSelect;
toFill->DemandH = demand>>16;
toFill->DemandM = demand>>8;
toFill->DemandL = demand>>0;
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());
@@ -990,3 +1016,222 @@ CTR_Code CanTalonSRX::SetRevFeedbackSensor(int param)
FlushTx(toFill);
return CTR_OKAY;
}
//------------------ C interface --------------------------------------------//
extern "C" {
void *c_TalonSRX_Create(int deviceNumber, int controlPeriodMs)
{
return new CanTalonSRX(deviceNumber, controlPeriodMs);
}
void c_TalonSRX_Destroy(void *handle)
{
delete (CanTalonSRX*)handle;
}
CTR_Code c_TalonSRX_SetParam(void *handle, int paramEnum, double value)
{
return ((CanTalonSRX*)handle)->SetParam((CanTalonSRX::param_t)paramEnum, value);
}
CTR_Code c_TalonSRX_RequestParam(void *handle, int paramEnum)
{
return ((CanTalonSRX*)handle)->RequestParam((CanTalonSRX::param_t)paramEnum);
}
CTR_Code c_TalonSRX_GetParamResponse(void *handle, int paramEnum, double *value)
{
return ((CanTalonSRX*)handle)->GetParamResponse((CanTalonSRX::param_t)paramEnum, *value);
}
CTR_Code c_TalonSRX_GetParamResponseInt32(void *handle, int paramEnum, int *value)
{
return ((CanTalonSRX*)handle)->GetParamResponseInt32((CanTalonSRX::param_t)paramEnum, *value);
}
CTR_Code c_TalonSRX_SetStatusFrameRate(void *handle, unsigned frameEnum, unsigned periodMs)
{
return ((CanTalonSRX*)handle)->SetStatusFrameRate(frameEnum, periodMs);
}
CTR_Code c_TalonSRX_ClearStickyFaults(void *handle)
{
return ((CanTalonSRX*)handle)->ClearStickyFaults();
}
CTR_Code c_TalonSRX_GetFault_OverTemp(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFault_OverTemp(*param);
}
CTR_Code c_TalonSRX_GetFault_UnderVoltage(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFault_UnderVoltage(*param);
}
CTR_Code c_TalonSRX_GetFault_ForLim(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFault_ForLim(*param);
}
CTR_Code c_TalonSRX_GetFault_RevLim(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFault_RevLim(*param);
}
CTR_Code c_TalonSRX_GetFault_HardwareFailure(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFault_HardwareFailure(*param);
}
CTR_Code c_TalonSRX_GetFault_ForSoftLim(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFault_ForSoftLim(*param);
}
CTR_Code c_TalonSRX_GetFault_RevSoftLim(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFault_RevSoftLim(*param);
}
CTR_Code c_TalonSRX_GetStckyFault_OverTemp(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetStckyFault_OverTemp(*param);
}
CTR_Code c_TalonSRX_GetStckyFault_UnderVoltage(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetStckyFault_UnderVoltage(*param);
}
CTR_Code c_TalonSRX_GetStckyFault_ForLim(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetStckyFault_ForLim(*param);
}
CTR_Code c_TalonSRX_GetStckyFault_RevLim(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetStckyFault_RevLim(*param);
}
CTR_Code c_TalonSRX_GetStckyFault_ForSoftLim(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetStckyFault_ForSoftLim(*param);
}
CTR_Code c_TalonSRX_GetStckyFault_RevSoftLim(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetStckyFault_RevSoftLim(*param);
}
CTR_Code c_TalonSRX_GetAppliedThrottle(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetAppliedThrottle(*param);
}
CTR_Code c_TalonSRX_GetCloseLoopErr(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetCloseLoopErr(*param);
}
CTR_Code c_TalonSRX_GetFeedbackDeviceSelect(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFeedbackDeviceSelect(*param);
}
CTR_Code c_TalonSRX_GetModeSelect(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetModeSelect(*param);
}
CTR_Code c_TalonSRX_GetLimitSwitchEn(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetLimitSwitchEn(*param);
}
CTR_Code c_TalonSRX_GetLimitSwitchClosedFor(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetLimitSwitchClosedFor(*param);
}
CTR_Code c_TalonSRX_GetLimitSwitchClosedRev(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetLimitSwitchClosedRev(*param);
}
CTR_Code c_TalonSRX_GetSensorPosition(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetSensorPosition(*param);
}
CTR_Code c_TalonSRX_GetSensorVelocity(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetSensorVelocity(*param);
}
CTR_Code c_TalonSRX_GetCurrent(void *handle, double *param)
{
return ((CanTalonSRX*)handle)->GetCurrent(*param);
}
CTR_Code c_TalonSRX_GetBrakeIsEnabled(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetBrakeIsEnabled(*param);
}
CTR_Code c_TalonSRX_GetEncPosition(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetEncPosition(*param);
}
CTR_Code c_TalonSRX_GetEncVel(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetEncVel(*param);
}
CTR_Code c_TalonSRX_GetEncIndexRiseEvents(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetEncIndexRiseEvents(*param);
}
CTR_Code c_TalonSRX_GetQuadApin(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetQuadApin(*param);
}
CTR_Code c_TalonSRX_GetQuadBpin(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetQuadBpin(*param);
}
CTR_Code c_TalonSRX_GetQuadIdxpin(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetQuadIdxpin(*param);
}
CTR_Code c_TalonSRX_GetAnalogInWithOv(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetAnalogInWithOv(*param);
}
CTR_Code c_TalonSRX_GetAnalogInVel(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetAnalogInVel(*param);
}
CTR_Code c_TalonSRX_GetTemp(void *handle, double *param)
{
return ((CanTalonSRX*)handle)->GetTemp(*param);
}
CTR_Code c_TalonSRX_GetBatteryV(void *handle, double *param)
{
return ((CanTalonSRX*)handle)->GetBatteryV(*param);
}
CTR_Code c_TalonSRX_GetResetCount(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetResetCount(*param);
}
CTR_Code c_TalonSRX_GetResetFlags(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetResetFlags(*param);
}
CTR_Code c_TalonSRX_GetFirmVers(void *handle, int *param)
{
return ((CanTalonSRX*)handle)->GetFirmVers(*param);
}
CTR_Code c_TalonSRX_SetDemand(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetDemand(param);
}
CTR_Code c_TalonSRX_SetOverrideLimitSwitchEn(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetOverrideLimitSwitchEn(param);
}
CTR_Code c_TalonSRX_SetFeedbackDeviceSelect(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetFeedbackDeviceSelect(param);
}
CTR_Code c_TalonSRX_SetRevMotDuringCloseLoopEn(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetRevMotDuringCloseLoopEn(param);
}
CTR_Code c_TalonSRX_SetOverrideBrakeType(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetOverrideBrakeType(param);
}
CTR_Code c_TalonSRX_SetModeSelect(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetModeSelect(param);
}
CTR_Code c_TalonSRX_SetProfileSlotSelect(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetProfileSlotSelect(param);
}
CTR_Code c_TalonSRX_SetRampThrottle(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetRampThrottle(param);
}
CTR_Code c_TalonSRX_SetRevFeedbackSensor(void *handle, int param)
{
return ((CanTalonSRX*)handle)->SetRevFeedbackSensor(param);
}
}

View File

@@ -63,9 +63,8 @@
* 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.
* CloseLoopRampRate is in throttle units per 1ms. Set to zero to disable ramping.
* Works the same as RampThrottle but only is in effect when a close loop mode and profile slot is selected.
*
* auto generated using spreadsheet and WpiClassGen.csproj
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
@@ -212,6 +211,8 @@ public:
eResetFlags=88,
eFirmVers=89,
eSettingsChanged=90,
eQuadFilterEn=91,
ePidIaccum=93,
}param_t;
/*---------------------setters and getters that use the solicated param request/response-------------*//**
* Send a one shot frame to set an arbitrary signal.
@@ -308,9 +309,66 @@ public:
CTR_Code SetRevMotDuringCloseLoopEn(int param);
CTR_Code SetOverrideBrakeType(int param);
CTR_Code SetModeSelect(int param);
CTR_Code SetModeSelect(int modeSelect,int demand);
CTR_Code SetProfileSlotSelect(int param);
CTR_Code SetRampThrottle(int param);
CTR_Code SetRevFeedbackSensor(int param);
};
extern "C" {
void *c_TalonSRX_Create(int deviceNumber, int controlPeriodMs);
void c_TalonSRX_Destroy(void *handle);
CTR_Code c_TalonSRX_SetParam(void *handle, int paramEnum, double value);
CTR_Code c_TalonSRX_RequestParam(void *handle, int paramEnum);
CTR_Code c_TalonSRX_GetParamResponse(void *handle, int paramEnum, double *value);
CTR_Code c_TalonSRX_GetParamResponseInt32(void *handle, int paramEnum, int *value);
CTR_Code c_TalonSRX_SetStatusFrameRate(void *handle, unsigned frameEnum, unsigned periodMs);
CTR_Code c_TalonSRX_ClearStickyFaults(void *handle);
CTR_Code c_TalonSRX_GetFault_OverTemp(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_UnderVoltage(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_ForLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_RevLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_HardwareFailure(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_ForSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_RevSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_OverTemp(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_UnderVoltage(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_ForLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_RevLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_ForSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_RevSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetAppliedThrottle(void *handle, int *param);
CTR_Code c_TalonSRX_GetCloseLoopErr(void *handle, int *param);
CTR_Code c_TalonSRX_GetFeedbackDeviceSelect(void *handle, int *param);
CTR_Code c_TalonSRX_GetModeSelect(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchEn(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchClosedFor(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchClosedRev(void *handle, int *param);
CTR_Code c_TalonSRX_GetSensorPosition(void *handle, int *param);
CTR_Code c_TalonSRX_GetSensorVelocity(void *handle, int *param);
CTR_Code c_TalonSRX_GetCurrent(void *handle, double *param);
CTR_Code c_TalonSRX_GetBrakeIsEnabled(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncPosition(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncVel(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncIndexRiseEvents(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadApin(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadBpin(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadIdxpin(void *handle, int *param);
CTR_Code c_TalonSRX_GetAnalogInWithOv(void *handle, int *param);
CTR_Code c_TalonSRX_GetAnalogInVel(void *handle, int *param);
CTR_Code c_TalonSRX_GetTemp(void *handle, double *param);
CTR_Code c_TalonSRX_GetBatteryV(void *handle, double *param);
CTR_Code c_TalonSRX_GetResetCount(void *handle, int *param);
CTR_Code c_TalonSRX_GetResetFlags(void *handle, int *param);
CTR_Code c_TalonSRX_GetFirmVers(void *handle, int *param);
CTR_Code c_TalonSRX_SetDemand(void *handle, int param);
CTR_Code c_TalonSRX_SetOverrideLimitSwitchEn(void *handle, int param);
CTR_Code c_TalonSRX_SetFeedbackDeviceSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetRevMotDuringCloseLoopEn(void *handle, int param);
CTR_Code c_TalonSRX_SetOverrideBrakeType(void *handle, int param);
CTR_Code c_TalonSRX_SetModeSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetProfileSlotSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetRampThrottle(void *handle, int param);
CTR_Code c_TalonSRX_SetRevFeedbackSensor(void *handle, int param);
}
#endif

View File

@@ -1,16 +1,16 @@
#pragma once
#ifndef __I2C_LIB_H__
#define __I2C_LIB_H__
#ifdef __cplusplus
extern "C" {
#endif
int i2clib_open(const char *device);
void i2clib_close(int handle);
int i2clib_read(int handle, uint8_t dev_addr, char *recv_buf, int32_t recv_size);
int i2clib_write(int handle, uint8_t dev_addr, const char *send_buf, int32_t send_size);
int i2clib_writeread(int handle, uint8_t dev_addr, const char *send_buf, int32_t send_size, char *recv_buf, int32_t recv_size);
#ifdef __cplusplus
}
#endif
#endif /* __I2C_LIB_H__ */

View File

@@ -1,12 +1,9 @@
#ifndef __SPI_LIB_H__
#define __SPI_LIB_H__
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int spilib_open(const char *device);
void spilib_close(int handle);
int spilib_setspeed(int handle, uint32_t speed);
@@ -15,11 +12,8 @@ int spilib_setopts(int handle, int msb_first, int sample_on_trailing, int clk_id
int spilib_read(int handle, char *recv_buf, int32_t size);
int spilib_write(int handle, const char *send_buf, int32_t size);
int spilib_writeread(int handle, const char *send_buf, char *recv_buf, int32_t size);
#ifdef __cplusplus
}
#endif
#endif /* __SPI_LIB_H__ */
#endif /* __SPI_LIB_H__ */

BIN
ni-libraries/libniimaqdx.so Executable file → Normal file

Binary file not shown.

View File

@@ -0,0 +1,2 @@
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libniimaqdx.so.14.0 )

View File

@@ -0,0 +1,2 @@
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libniimaqdx.so.14.0.0 )

Binary file not shown.

BIN
ni-libraries/libnivision.so Executable file → Normal file

Binary file not shown.

View File

@@ -0,0 +1,2 @@
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libnivision.so.14.0 )

View File

@@ -0,0 +1,2 @@
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libnivision.so.14.0.0 )

Binary file not shown.

BIN
ni-libraries/libnivissvc.so Executable file → Normal file

Binary file not shown.

View File

@@ -0,0 +1,2 @@
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libnivissvc.so.14.0 )

View File

@@ -0,0 +1,2 @@
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libnivissvc.so.14.0.0 )

Binary file not shown.

View File

@@ -91,11 +91,11 @@ void ErrorBase::SetImaqError(int success, const char *contextMessage, const char
{
// If there was an error
if (success <= 0) {
//TODO: ??? char err[256];
// XXX: sprintf(err, "%s: %s", contextMessage, imaqGetErrorText(imaqGetLastError()));
char err[256];
sprintf(err, "%i: %s", success, contextMessage);
// Set the current error information for this object.
// XXX: m_error.Set(imaqGetLastError(), err, filename, function, lineNumber, this);
m_error.Set(success, err, filename, function, lineNumber, this);
// Update the global error if there is not one already set.
Synchronized mutex(_globalErrorMutex);

View File

@@ -54,7 +54,10 @@ public:
/** Only use switches for limits */
kLimitMode_SwitchInputsOnly = 0,
/** Use both switches and soft limits */
kLimitMode_SoftPositionLimits = 1
kLimitMode_SoftPositionLimits = 1,
/* SRX extensions */
/** Disable switches and disable soft limits */
kLimitMode_SrxDisableSwitchInputs = 2,
};
virtual float Get() = 0;

View File

@@ -26,8 +26,15 @@ public:
AnalogEncoder=3,
EncRising=4,
EncFalling=5
};
enum StatusFrameRate {
StatusFrameRateGeneral=0,
StatusFrameRateFeedback=1,
StatusFrameRateQuadEncoder=2,
StatusFrameRateAnalogTempVbat=3,
};
explicit CANTalon(int deviceNumber);
explicit CANTalon(int deviceNumber,int controlPeriodMs);
virtual ~CANTalon();
// PIDController interface
@@ -51,6 +58,7 @@ public:
virtual void SetI(double i) override;
virtual void SetD(double d) override;
void SetF(double f);
void SetIzone(unsigned iz);
virtual void SetPID(double p, double i, double d) override;
void SetPID(double p, double i, double d, double f);
virtual double GetP() override;
@@ -66,6 +74,7 @@ public:
virtual double GetSpeed() override;
virtual int GetClosedLoopError();
virtual int GetAnalogIn();
virtual int GetAnalogInRaw();
virtual int GetAnalogInVel();
virtual int GetEncPosition();
virtual int GetEncVel();
@@ -91,15 +100,44 @@ public:
virtual void ConfigLimitMode(LimitMode mode) override;
virtual void ConfigForwardLimit(double forwardLimitPosition) override;
virtual void ConfigReverseLimit(double reverseLimitPosition) override;
/**
* Change the fwd limit switch setting to normally open or closed.
* Talon will disable momentarilly if the Talon's current setting
* is dissimilar to the caller's requested setting.
*
* Since Talon saves setting to flash this should only affect
* a given Talon initially during robot install.
*
* @param normallyOpen true for normally open. false for normally closed.
*/
void ConfigFwdLimitSwitchNormallyOpen(bool normallyOpen);
/**
* Change the rev limit switch setting to normally open or closed.
* Talon will disable momentarilly if the Talon's current setting
* is dissimilar to the caller's requested setting.
*
* Since Talon saves setting to flash this should only affect
* a given Talon initially during robot install.
*
* @param normallyOpen true for normally open. false for normally closed.
*/
void ConfigRevLimitSwitchNormallyOpen(bool normallyOpen);
virtual void ConfigMaxOutputVoltage(double voltage) override;
virtual void ConfigFaultTime(float faultTime) override;
virtual void SetControlMode(ControlMode mode);
void SetFeedbackDevice(FeedbackDevice device);
void SetStatusFrameRateMs(StatusFrameRate stateFrame, int periodMs);
virtual ControlMode GetControlMode();
void SetSensorDirection(bool reverseSensor);
void SetCloseLoopRampRate(double rampRate);
void SelectProfileSlot(int slotIdx);
double GetIzone();
int GetIzone();
int GetIaccum();
void ClearIaccum();
int GetBrakeEnableDuringNeutral();
bool IsControlEnabled();
double GetSetpoint();
private:
// Values for various modes as is sent in the CAN packets for the Talon.
enum TalonControlMode {
@@ -119,4 +157,15 @@ private:
bool m_controlEnabled;
ControlMode m_controlMode;
TalonControlMode m_sendMode;
double m_setPoint;
static const unsigned int kDelayForSolicitedSignalsUs = 4000;
/**
* Fixup the sendMode so Set() serializes the correct demand value.
* Also fills the modeSelecet in the control frame to disabled.
* @param mode Control mode to ultimately enter once user calls Set().
* @see Set()
*/
void ApplyControlMode(CANSpeedController::ControlMode mode);
};

View File

@@ -25,7 +25,7 @@ class CameraServer : public ErrorBase {
static constexpr uint32_t kSize320x240 = 1;
static constexpr uint32_t kSize160x120 = 2;
static constexpr int32_t kHardwareCompression = -1;
static constexpr char const *kDefaultCameraName = "cam1";
static constexpr char const *kDefaultCameraName = "cam0";
public:
static CameraServer *GetInstance();

View File

@@ -34,6 +34,7 @@ public:
float GetStickAxis(uint32_t stick, uint32_t axis);
int GetStickPOV(uint32_t stick, uint32_t pov);
uint32_t GetStickButtons(uint32_t stick);
bool GetStickButton(uint32_t stick, uint8_t button);
int GetStickAxisCount(uint32_t stick);
@@ -89,12 +90,16 @@ public:
protected:
DriverStation();
void GetData();
private:
static void InitTask(DriverStation *ds);
static DriverStation *m_instance;
void ReportJoystickUnpluggedError(std::string message);
void Run();
HALJoystickAxes m_joystickAxes[kJoystickPorts];
HALJoystickPOVs m_joystickPOVs[kJoystickPorts];
HALJoystickButtons m_joystickButtons[kJoystickPorts];
Task m_task;
SEMAPHORE_ID m_newControlData;
MULTIWAIT_ID m_packetDataAvailableMultiWait;

View File

@@ -60,6 +60,8 @@ public:
virtual void TestPeriodic();
protected:
virtual void Prestart();
virtual ~IterativeRobot();
IterativeRobot();

View File

@@ -14,9 +14,9 @@ class DriverStation;
int main() \
{ \
if (!HALInitialize()){std::cerr<<"FATAL ERROR: HAL could not be initialized"<<std::endl;return -1;} \
HALNetworkCommunicationObserveUserProgramStarting(); \
HALReport(HALUsageReporting::kResourceType_Language, HALUsageReporting::kLanguage_CPlusPlus); \
(new _ClassName_())->StartCompetition(); \
_ClassName_ *robot = new _ClassName_(); \
RobotBase::robotSetup(robot); \
return 0; \
}
@@ -44,11 +44,15 @@ public:
static void startRobotTask(FUNCPTR factory);
static void robotTask(FUNCPTR factory, Task *task);
virtual void StartCompetition() = 0;
static void robotSetup(RobotBase *robot);
protected:
virtual ~RobotBase();
RobotBase();
virtual void Prestart();
Task *m_task;
DriverStation *m_ds;

View File

@@ -16,11 +16,12 @@ class GenericHID;
/**
* Utility class for handling Robot drive based on a definition of the motor configuration.
* The robot drive class handles basic driving for a robot. Currently, 2 and 4 motor standard
* drive trains are supported. In the future other drive types like swerve and meccanum might
* be implemented. Motor channel numbers are passed supplied on creation of the class. Those are
* used for either the Drive function (intended for hand created drive code, such as autonomous)
* or with the Tank/Arcade functions intended to be used for Operator Control driving.
* The robot drive class handles basic driving for a robot. Currently, 2 and 4 motor tank and
* mecanum drive trains are supported. In the future other drive types like swerve might be
* implemented. Motor channel numbers are passed supplied on creation of the class. Those
* are used for either the Drive function (intended for hand created drive code, such as
* autonomous) or with the Tank/Arcade functions intended to be used for Operator Control
* driving.
*/
class RobotDrive : public MotorSafety, public ErrorBase
{

View File

@@ -27,7 +27,7 @@ public:
enum StopBits {kStopBits_One=10, kStopBits_OnePointFive=15, kStopBits_Two=20};
enum FlowControl {kFlowControl_None=0, kFlowControl_XonXoff=1, kFlowControl_RtsCts=2, kFlowControl_DtrDsr=4};
enum WriteBufferMode {kFlushOnAccess=1, kFlushWhenFull=2};
enum Port {kOnboard=0, kMXP=1};
enum Port {kOnboard=0, kMXP=1, kUSB=2};
SerialPort(uint32_t baudRate, Port port = kOnboard, uint8_t dataBits = 8, Parity parity = kParity_None,
StopBits stopBits = kStopBits_One);

View File

@@ -5,14 +5,25 @@
/*----------------------------------------------------------------------------*/
#pragma once
#include "Talon.h"
#include "SafePWM.h"
#include "SpeedController.h"
#include "PIDOutput.h"
/**
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control
* @see CANTalon for CAN control
*/
class TalonSRX: public Talon {
class TalonSRX : public SafePWM, public SpeedController
{
public:
explicit TalonSRX(uint32_t channel);
virtual ~TalonSRX();
virtual void Set(float value, uint8_t syncGroup = 0);
virtual float Get();
virtual void Disable();
virtual void PIDWrite(float output);
private:
void InitTalonSRX();
};

View File

@@ -5,13 +5,24 @@
/*----------------------------------------------------------------------------*/
#pragma once
#include "Talon.h"
#include "SafePWM.h"
#include "SpeedController.h"
#include "PIDOutput.h"
/**
* Vex Robotics Victor SP Speed Controller
*/
class VictorSP: public Talon {
class VictorSP : public SafePWM, public SpeedController
{
public:
explicit VictorSP(uint32_t channel);
virtual ~VictorSP();
virtual void Set(float value, uint8_t syncGroup = 0);
virtual float Get();
virtual void Disable();
virtual void PIDWrite(float output);
private:
void InitVictorSP();
};

View File

@@ -63,9 +63,8 @@
* 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.
* CloseLoopRampRate is in throttle units per 1ms. Set to zero to disable ramping.
* Works the same as RampThrottle but only is in effect when a close loop mode and profile slot is selected.
*
* auto generated using spreadsheet and WpiClassGen.csproj
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
@@ -212,6 +211,8 @@ public:
eResetFlags=88,
eFirmVers=89,
eSettingsChanged=90,
eQuadFilterEn=91,
ePidIaccum=93,
}param_t;
/*---------------------setters and getters that use the solicated param request/response-------------*//**
* Send a one shot frame to set an arbitrary signal.
@@ -308,9 +309,66 @@ public:
CTR_Code SetRevMotDuringCloseLoopEn(int param);
CTR_Code SetOverrideBrakeType(int param);
CTR_Code SetModeSelect(int param);
CTR_Code SetModeSelect(int modeSelect,int demand);
CTR_Code SetProfileSlotSelect(int param);
CTR_Code SetRampThrottle(int param);
CTR_Code SetRevFeedbackSensor(int param);
};
extern "C" {
void *c_TalonSRX_Create(int deviceNumber, int controlPeriodMs);
void c_TalonSRX_Destroy(void *handle);
CTR_Code c_TalonSRX_SetParam(void *handle, int paramEnum, double value);
CTR_Code c_TalonSRX_RequestParam(void *handle, int paramEnum);
CTR_Code c_TalonSRX_GetParamResponse(void *handle, int paramEnum, double *value);
CTR_Code c_TalonSRX_GetParamResponseInt32(void *handle, int paramEnum, int *value);
CTR_Code c_TalonSRX_SetStatusFrameRate(void *handle, unsigned frameEnum, unsigned periodMs);
CTR_Code c_TalonSRX_ClearStickyFaults(void *handle);
CTR_Code c_TalonSRX_GetFault_OverTemp(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_UnderVoltage(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_ForLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_RevLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_HardwareFailure(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_ForSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetFault_RevSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_OverTemp(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_UnderVoltage(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_ForLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_RevLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_ForSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetStckyFault_RevSoftLim(void *handle, int *param);
CTR_Code c_TalonSRX_GetAppliedThrottle(void *handle, int *param);
CTR_Code c_TalonSRX_GetCloseLoopErr(void *handle, int *param);
CTR_Code c_TalonSRX_GetFeedbackDeviceSelect(void *handle, int *param);
CTR_Code c_TalonSRX_GetModeSelect(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchEn(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchClosedFor(void *handle, int *param);
CTR_Code c_TalonSRX_GetLimitSwitchClosedRev(void *handle, int *param);
CTR_Code c_TalonSRX_GetSensorPosition(void *handle, int *param);
CTR_Code c_TalonSRX_GetSensorVelocity(void *handle, int *param);
CTR_Code c_TalonSRX_GetCurrent(void *handle, double *param);
CTR_Code c_TalonSRX_GetBrakeIsEnabled(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncPosition(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncVel(void *handle, int *param);
CTR_Code c_TalonSRX_GetEncIndexRiseEvents(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadApin(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadBpin(void *handle, int *param);
CTR_Code c_TalonSRX_GetQuadIdxpin(void *handle, int *param);
CTR_Code c_TalonSRX_GetAnalogInWithOv(void *handle, int *param);
CTR_Code c_TalonSRX_GetAnalogInVel(void *handle, int *param);
CTR_Code c_TalonSRX_GetTemp(void *handle, double *param);
CTR_Code c_TalonSRX_GetBatteryV(void *handle, double *param);
CTR_Code c_TalonSRX_GetResetCount(void *handle, int *param);
CTR_Code c_TalonSRX_GetResetFlags(void *handle, int *param);
CTR_Code c_TalonSRX_GetFirmVers(void *handle, int *param);
CTR_Code c_TalonSRX_SetDemand(void *handle, int param);
CTR_Code c_TalonSRX_SetOverrideLimitSwitchEn(void *handle, int param);
CTR_Code c_TalonSRX_SetFeedbackDeviceSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetRevMotDuringCloseLoopEn(void *handle, int param);
CTR_Code c_TalonSRX_SetOverrideBrakeType(void *handle, int param);
CTR_Code c_TalonSRX_SetModeSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetProfileSlotSelect(void *handle, int param);
CTR_Code c_TalonSRX_SetRampThrottle(void *handle, int param);
CTR_Code c_TalonSRX_SetRevFeedbackSensor(void *handle, int param);
}
#endif

View File

@@ -179,16 +179,16 @@ void CANJaguar::InitCANJaguar()
return;
// 3330 was the first shipping RDK firmware version for the Jaguar
if (m_firmwareVersion >= 3330 || m_firmwareVersion < 101)
if (m_firmwareVersion >= 3330 || m_firmwareVersion < 108)
{
char buf[256];
if (m_firmwareVersion < 3330)
{
snprintf(buf, 256, "Jag #%d firmware (%d) is too old (must be at least version 101 of the FIRST approved firmware)", m_deviceNumber, m_firmwareVersion);
snprintf(buf, 256, "Jag #%d firmware (%d) is too old (must be at least version 108 of the FIRST approved firmware)", m_deviceNumber, m_firmwareVersion);
}
else
{
snprintf(buf, 256, "Jag #%d firmware (%d) is not FIRST approved (must be at least version 101 of the FIRST approved firmware)", m_deviceNumber, m_firmwareVersion);
snprintf(buf, 256, "Jag #%d firmware (%d) is not FIRST approved (must be at least version 108 of the FIRST approved firmware)", m_deviceNumber, m_firmwareVersion);
}
wpi_setWPIErrorWithContext(JaguarVersionError, buf);
return;

View File

@@ -19,13 +19,29 @@ CANTalon::CANTalon(int deviceNumber)
, m_profile(0)
, m_controlEnabled(true)
, m_controlMode(kPercentVbus)
, m_setPoint(0)
{
// The control mode may already have been set; GetControlMode will reset
// m_controlMode to match the Talon.
GetControlMode();
ApplyControlMode(m_controlMode);
m_impl->SetProfileSlotSelect(m_profile);
}
/**
* Constructor for the CANTalon device.
* @param deviceNumber The CAN ID of the Talon SRX
* @param controlPeriodMs The period in ms to send the CAN control frame.
* Period is bounded to [1ms, 95ms].
*/
CANTalon::CANTalon(int deviceNumber,int controlPeriodMs)
: m_deviceNumber(deviceNumber)
, m_impl(new CanTalonSRX(deviceNumber,controlPeriodMs)) /* bounded underneath to be within [1 ms,95 ms] */
, m_safetyHelper(new MotorSafetyHelper(this))
, m_profile(0)
, m_controlEnabled(true)
, m_controlMode(kPercentVbus)
, m_setPoint(0)
{
ApplyControlMode(m_controlMode);
m_impl->SetProfileSlotSelect(m_profile);
}
CANTalon::~CANTalon() {
delete m_impl;
delete m_safetyHelper;
@@ -90,8 +106,9 @@ float CANTalon::Get()
void CANTalon::Set(float value, uint8_t syncGroup)
{
if(m_controlEnabled) {
m_setPoint = value;
CTR_Code status;
switch(GetControlMode()) {
switch(m_controlMode) {
case CANSpeedController::kPercentVbus:
{
m_impl->Set(value);
@@ -122,6 +139,13 @@ void CANTalon::Set(float value, uint8_t syncGroup)
if (status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
status = m_impl->SetModeSelect(m_sendMode);
if (status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
}
@@ -143,6 +167,13 @@ void CANTalon::EnableControl() {
m_controlEnabled = true;
}
/**
* @return Whether the Talon is currently enabled.
*/
bool CANTalon::IsControlEnabled() {
return m_controlEnabled;
}
/**
* @param p Proportional constant to use in PID loop.
* @see SelectProfileSlot to choose between the two sets of gains.
@@ -189,6 +220,19 @@ void CANTalon::SetF(double f)
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* Set the Izone to a nonzero value to auto clear the integral accumulator
* when the absolute value of CloseLoopError exceeds Izone.
*
* @see SelectProfileSlot to choose between the two sets of gains.
*/
void CANTalon::SetIzone(unsigned iz)
{
CTR_Code status = m_impl->SetIzone(m_profile, iz);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* SRX has two available slots for PID.
* @param slotIdx one or zero depending on which slot caller wants.
@@ -229,6 +273,16 @@ void CANTalon::SetFeedbackDevice(FeedbackDevice device)
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* Select the feedback device to use in closed-loop
*/
void CANTalon::SetStatusFrameRateMs(StatusFrameRate stateFrame, int periodMs)
{
CTR_Code status = m_impl->SetStatusFrameRate((int)stateFrame,periodMs);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* TODO documentation (see CANJaguar.cpp)
@@ -242,7 +296,7 @@ double CANTalon::GetP()
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
usleep(1000); /* small yield for getting response */
usleep(kDelayForSolicitedSignalsUs); /* small yield for getting response */
double p;
status = m_impl->GetPgain(m_profile, p);
if(status != CTR_OKAY) {
@@ -263,7 +317,7 @@ double CANTalon::GetI()
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
usleep(1000); /* small yield for getting response */
usleep(kDelayForSolicitedSignalsUs); /* small yield for getting response */
double i;
status = m_impl->GetIgain(m_profile, i);
@@ -285,7 +339,7 @@ double CANTalon::GetD()
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
usleep(1000); /* small yield for getting response */
usleep(kDelayForSolicitedSignalsUs); /* small yield for getting response */
double d;
status = m_impl->GetDgain(m_profile, d);
@@ -307,7 +361,7 @@ double CANTalon::GetF()
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
usleep(1000); /* small yield for getting response */
usleep(kDelayForSolicitedSignalsUs); /* small yield for getting response */
double f;
status = m_impl->GetFgain(m_profile, f);
if(status != CTR_OKAY) {
@@ -318,7 +372,7 @@ double CANTalon::GetF()
/**
* @see SelectProfileSlot to choose between the two sets of gains.
*/
double CANTalon::GetIzone()
int CANTalon::GetIzone()
{
CanTalonSRX::param_t param = m_profile ? CanTalonSRX::eProfileParamSlot1_IZone: CanTalonSRX::eProfileParamSlot0_IZone;
// Update the info in m_impl.
@@ -326,14 +380,21 @@ double CANTalon::GetIzone()
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
usleep(1000);
usleep(kDelayForSolicitedSignalsUs);
int iz;
status = m_impl->GetIzone(m_profile, iz);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
return (double)iz;
return iz;
}
/**
* @return the current setpoint; ie, whatever was last passed to Set().
*/
double CANTalon::GetSetpoint() {
return m_setPoint;
}
/**
@@ -478,7 +539,9 @@ double CANTalon::GetSpeed()
* Get the position of whatever is in the analog pin of the Talon, regardless of
* whether it is actually being used for feedback.
*
* @returns The value (0 - 1023) on the analog pin of the Talon.
* @returns The 24bit analog value. The bottom ten bits is the ADC (0 - 1023) on
* the analog pin of the Talon. The upper 14 bits
* tracks the overflows and underflows (continuous sensor).
*/
int CANTalon::GetAnalogIn()
{
@@ -489,7 +552,16 @@ int CANTalon::GetAnalogIn()
}
return position;
}
/**
* Get the position of whatever is in the analog pin of the Talon, regardless of
* whether it is actually being used for feedback.
*
* @returns The ADC (0 - 1023) on analog pin of the Talon.
*/
int CANTalon::GetAnalogInRaw()
{
return GetAnalogIn() & 0x3FF;
}
/**
* Get the position of whatever is in the analog pin of the Talon, regardless of
* whether it is actually being used for feedback.
@@ -810,9 +882,12 @@ void CANTalon::SetCloseLoopRampRate(double rampRate)
uint32_t CANTalon::GetFirmwareVersion()
{
int firmwareVersion;
m_impl->RequestParam(CanTalonSRX::eFirmVers);
usleep(1000);
CTR_Code status = m_impl->GetParamResponseInt32(CanTalonSRX::eFirmVers,firmwareVersion);
CTR_Code status = m_impl->RequestParam(CanTalonSRX::eFirmVers);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
usleep(kDelayForSolicitedSignalsUs);
status = m_impl->GetParamResponseInt32(CanTalonSRX::eFirmVers,firmwareVersion);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
@@ -825,6 +900,33 @@ uint32_t CANTalon::GetFirmwareVersion()
return firmwareVersion;
}
/**
* @return The accumulator for I gain.
*/
int CANTalon::GetIaccum()
{
CTR_Code status = m_impl->RequestParam(CanTalonSRX::ePidIaccum);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
usleep(kDelayForSolicitedSignalsUs); /* small yield for getting response */
int iaccum;
status = m_impl->GetParamResponseInt32(CanTalonSRX::ePidIaccum,iaccum);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
return iaccum;
}
/**
* Clear the accumulator for I gain.
*/
void CANTalon::ClearIaccum()
{
CTR_Code status = m_impl->SetParam(CanTalonSRX::ePidIaccum, 0);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* TODO documentation (see CANJaguar.cpp)
@@ -848,7 +950,18 @@ void CANTalon::ConfigNeutralMode(NeutralMode mode)
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* @return nonzero if brake is enabled during neutral. Zero if coast is enabled during neutral.
*/
int CANTalon::GetBrakeEnableDuringNeutral()
{
int brakeEn = 0;
CTR_Code status = m_impl->GetBrakeIsEnabled(brakeEn);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
return brakeEn;
}
/**
* TODO documentation (see CANJaguar.cpp)
*/
@@ -924,6 +1037,23 @@ void CANTalon::ConfigLimitMode(LimitMode mode)
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
break;
case kLimitMode_SrxDisableSwitchInputs: /** disable both limit switches and soft limits */
/* turn on both limits. SRX has individual enables and polarity for each limit switch.*/
status = m_impl->SetForwardSoftEnable(false);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
status = m_impl->SetReverseSoftEnable(false);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
/* override enable the limit switches, this circumvents the webdash */
status = m_impl->SetOverrideLimitSwitchEn(CanTalonSRX::kLimitSwitchOverride_DisableFwd_DisableRev);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
break;
}
}
@@ -938,7 +1068,40 @@ void CANTalon::ConfigForwardLimit(double forwardLimitPosition)
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* Change the fwd limit switch setting to normally open or closed.
* Talon will disable momentarilly if the Talon's current setting
* is dissimilar to the caller's requested setting.
*
* Since Talon saves setting to flash this should only affect
* a given Talon initially during robot install.
*
* @param normallyOpen true for normally open. false for normally closed.
*/
void CANTalon::ConfigFwdLimitSwitchNormallyOpen(bool normallyOpen)
{
CTR_Code status = m_impl->SetParam(CanTalonSRX::eOnBoot_LimitSwitch_Forward_NormallyClosed, normallyOpen ? 0 : 1);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* Change the rev limit switch setting to normally open or closed.
* Talon will disable momentarilly if the Talon's current setting
* is dissimilar to the caller's requested setting.
*
* Since Talon saves setting to flash this should only affect
* a given Talon initially during robot install.
*
* @param normallyOpen true for normally open. false for normally closed.
*/
void CANTalon::ConfigRevLimitSwitchNormallyOpen(bool normallyOpen)
{
CTR_Code status = m_impl->SetParam(CanTalonSRX::eOnBoot_LimitSwitch_Reverse_NormallyClosed, normallyOpen ? 0 : 1);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* TODO documentation (see CANJaguar.cpp)
*/
@@ -969,37 +1132,51 @@ void CANTalon::ConfigFaultTime(float faultTime)
wpi_setWPIErrorWithContext(IncompatibleMode, "Fault Time not supported.");
}
/**
* Fixup the sendMode so Set() serializes the correct demand value.
* Also fills the modeSelecet in the control frame to disabled.
* @param mode Control mode to ultimately enter once user calls Set().
* @see Set()
*/
void CANTalon::ApplyControlMode(CANSpeedController::ControlMode mode)
{
m_controlMode = mode;
switch (mode) {
case kPercentVbus:
m_sendMode = kThrottle;
break;
case kCurrent:
m_sendMode = kCurrentMode;
break;
case kSpeed:
m_sendMode = kSpeedMode;
break;
case kPosition:
m_sendMode = kPositionMode;
break;
case kVoltage:
m_sendMode = kVoltageMode;
break;
case kFollower:
m_sendMode = kFollowerMode;
break;
}
// Keep the talon disabled until Set() is called.
CTR_Code status = m_impl->SetModeSelect((int)kDisabled);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
* TODO documentation (see CANJaguar.cpp)
*/
void CANTalon::SetControlMode(CANSpeedController::ControlMode mode)
{
m_controlMode = mode;
TalonControlMode sendMode;
switch (mode) {
case kPercentVbus:
sendMode = kThrottle;
break;
case kCurrent:
sendMode = kCurrentMode;
break;
case kSpeed:
sendMode = kSpeedMode;
break;
case kPosition:
sendMode = kPositionMode;
break;
case kVoltage:
sendMode = kVoltageMode;
break;
case kFollower:
sendMode = kFollowerMode;
break;
if(m_controlMode == mode){
/* we already are in this mode, don't perform disable workaround */
}else{
ApplyControlMode(mode);
}
CTR_Code status = m_impl->SetModeSelect((int)sendMode);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
/**
@@ -1007,35 +1184,6 @@ void CANTalon::SetControlMode(CANSpeedController::ControlMode mode)
*/
CANSpeedController::ControlMode CANTalon::GetControlMode()
{
// Take the opportunity to check that the control mode is what we think it is.
int temp;
CTR_Code status = m_impl->GetModeSelect(temp);
if(status != CTR_OKAY) {
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
switch ((TalonControlMode)temp) {
case kThrottle:
m_controlMode = kPercentVbus;
break;
case kCurrentMode:
m_controlMode = kCurrent;
break;
case kSpeedMode:
m_controlMode = kSpeed;
break;
case kPositionMode:
m_controlMode = kPosition;
break;
case kVoltageMode:
m_controlMode = kVoltage;
break;
case kFollowerMode:
m_controlMode = kFollower;
break;
case kDisabled:
m_controlEnabled = false;
break;
}
return m_controlMode;
}

View File

@@ -28,7 +28,7 @@ const uint32_t DriverStation::kJoystickPorts;
DriverStation* DriverStation::m_instance = NULL;
/**
* DriverStation contructor.
* DriverStation constructor.
*
* This is only called once the first time GetInstance() is called
*/
@@ -43,6 +43,13 @@ DriverStation::DriverStation()
, m_userInTest(false)
, m_nextMessageTime(0)
{
// All joysticks should default to having zero axes, povs and buttons, 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;
m_joystickButtons[i].count = 0;
}
// Create a new semaphore
m_packetDataAvailableMultiWait = initializeMultiWait();
m_newControlData = initializeSemaphore(SEMAPHORE_EMPTY);
@@ -84,15 +91,12 @@ void DriverStation::InitTask(DriverStation *ds)
void DriverStation::Run()
{
HALControlWord controlWord;
int period = 0;
while (true)
{
// need to get the controlWord to keep the motors enabled
HALGetControlWord(&controlWord);
takeMultiWait(m_packetDataAvailableMultiWait, m_packetDataAvailableMutex, 0);
GetData();
giveMultiWait(m_waitForDataSem);
giveSemaphore(m_newControlData);
if (++period >= 4)
{
@@ -122,6 +126,23 @@ 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()
{
// Get the status of all of the joysticks
for(uint8_t stick = 0; stick < kJoystickPorts; stick++) {
HALGetJoystickAxes(stick, &m_joystickAxes[stick]);
HALGetJoystickPOVs(stick, &m_joystickPOVs[stick]);
HALGetJoystickButtons(stick, &m_joystickButtons[stick]);
}
giveSemaphore(m_newControlData);
}
/**
* Read the battery voltage.
*
@@ -211,9 +232,7 @@ float DriverStation::GetStickAxis(uint32_t stick, uint32_t axis)
return 0;
}
HALJoystickAxes joystickAxes;
HALGetJoystickAxes(stick, &joystickAxes);
if (axis >= joystickAxes.count)
if (axis >= m_joystickAxes[stick].count)
{
if (axis >= kMaxJoystickAxes)
wpi_setWPIError(BadJoystickAxis);
@@ -222,7 +241,7 @@ float DriverStation::GetStickAxis(uint32_t stick, uint32_t axis)
return 0.0f;
}
int8_t value = joystickAxes.axes[axis];
int8_t value = m_joystickAxes[stick].axes[axis];
if(value < 0)
{
@@ -245,10 +264,8 @@ int DriverStation::GetStickPOV(uint32_t stick, uint32_t pov) {
wpi_setWPIError(BadJoystickIndex);
return 0;
}
HALJoystickPOVs joystickPOVs;
HALGetJoystickPOVs(stick, &joystickPOVs);
if (pov >= joystickPOVs.count)
if (pov >= m_joystickPOVs[stick].count)
{
if (pov >= kMaxJoystickPOVs)
wpi_setWPIError(BadJoystickAxis);
@@ -257,7 +274,7 @@ int DriverStation::GetStickPOV(uint32_t stick, uint32_t pov) {
return 0;
}
return joystickPOVs.povs[pov];
return m_joystickPOVs[stick].povs[pov];
}
/**
@@ -266,21 +283,43 @@ int DriverStation::GetStickPOV(uint32_t stick, uint32_t pov) {
* @param stick The joystick to read.
* @return The state of the buttons on the joystick.
*/
bool DriverStation::GetStickButton(uint32_t stick, uint8_t button)
uint32_t DriverStation::GetStickButtons(uint32_t stick)
{
if (stick >= kJoystickPorts)
{
wpi_setWPIError(BadJoystickIndex);
return 0;
}
HALJoystickButtons joystickButtons;
HALGetJoystickButtons(stick, &joystickButtons);
if(button > joystickButtons.count)
return m_joystickButtons[stick].buttons;
}
/**
* The state of one joystick button. Button indexes begin at 1.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return The state of the joystick button.
*/
bool DriverStation::GetStickButton(uint32_t stick, uint8_t button)
{
if (stick >= kJoystickPorts)
{
wpi_setWPIError(BadJoystickIndex);
return false;
}
if(button > m_joystickButtons[stick].count)
{
ReportJoystickUnpluggedError("WARNING: Joystick Button missing, check if all controllers are plugged in\n");
return false;
}
return ((0x1 << (button-1)) & joystickButtons.buttons) !=0;
if(button == 0)
{
ReportJoystickUnpluggedError("ERROR: Button indexes begin at 1 in WPILib for C++ and Java");
return false;
}
return ((0x1 << (button-1)) & m_joystickButtons[stick].buttons) !=0;
}
bool DriverStation::IsEnabled()

View File

@@ -36,6 +36,11 @@ IterativeRobot::~IterativeRobot()
{
}
void IterativeRobot::Prestart() {
// Don't immediately say that the robot's ready to be enabled.
// See below.
}
/**
* Provide an alternate "main loop" via StartCompetition().
*
@@ -54,6 +59,12 @@ void IterativeRobot::StartCompetition()
NetworkTable::GetTable("LiveWindow")->GetSubTable("~STATUS~")->PutBoolean("LW Enabled", false);
RobotInit();
// We call this now (not in Prestart like default) so that the robot
// won't enable until the initialization has finished. This is useful
// because otherwise it's sometimes possible to enable the robot
// before the code is ready.
HALNetworkCommunicationObserveUserProgramStarting();
// loop forever, calling the appropriate mode-dependent function
lw->SetEnabled(false);
while (true)

View File

@@ -355,6 +355,10 @@ float Joystick::GetDirectionDegrees(){
* @param value The normalized value (0 to 1) to set the rumble to
*/
void Joystick::SetRumble(RumbleType type, float value) {
if (value < 0)
value = 0;
else if (value > 1)
value = 1;
if (type == kLeftRumble)
m_leftRumble = value*65535;
else

View File

@@ -37,9 +37,15 @@ RobotBase &RobotBase::getInstance()
return *m_instance;
}
void RobotBase::robotSetup(RobotBase *robot)
{
robot->Prestart();
robot->StartCompetition();
}
/**
* Constructor for a generic robot program.
* User code should be placed in the constuctor that runs before the Autonomous or Operator
* User code should be placed in the constructor that runs before the Autonomous or Operator
* Control period starts. The constructor will run to completion before Autonomous is entered.
*
* This must be used to ensure that the communications code starts. In the future it would be
@@ -88,7 +94,7 @@ bool RobotBase::IsDisabled()
}
/**
* Determine if the robot is currently in Autnomous mode.
* Determine if the robot is currently in Autonomous mode.
* @return True if the robot is currently operating Autonomously as determined by the field controls.
*/
bool RobotBase::IsAutonomous()
@@ -114,6 +120,15 @@ bool RobotBase::IsTest()
return m_ds->IsTest();
}
/**
* This hook is called right before startCompetition(). By default, tell the DS that the robot is now ready to
* be enabled. If you don't want for the robot to be enabled yet, you can override this method to do nothing.
*/
void RobotBase::Prestart()
{
HALNetworkCommunicationObserveUserProgramStarting();
}
/**
* Indicates if new data is available from the driver station.
* @return Has new data arrived over the network since the last time this function was called?

View File

@@ -6,10 +6,78 @@
#include "TalonSRX.h"
TalonSRX::TalonSRX(uint32_t channel) : Talon(channel) {
//#include "NetworkCommunication/UsageReporting.h"
#include "LiveWindow/LiveWindow.h"
/**
* Common initialization code called by all constructors.
*
* Note that the TalonSRX uses the following bounds for PWM values. These values should work reasonably well for
* most controllers, but if users experience issues such as asymmetric behavior around
* the deadband or inability to saturate the controller in either direction, calibration is recommended.
* The calibration procedure can be found in the TalonSRX User Manual available from Cross The Road Electronics.
*
*/
void TalonSRX::InitTalonSRX() {
SetBounds(2.004, 1.52, 1.50, 1.48, .997);
SetPeriodMultiplier(kPeriodMultiplier_1X);
SetRaw(m_centerPwm);
SetZeroLatch();
HALReport(HALUsageReporting::kResourceType_Talon, GetChannel());
LiveWindow::GetInstance()->AddActuator("TalonSRX", GetChannel(), this);
}
TalonSRX::~TalonSRX() {
/**
* @param channel The PWM channel that the TalonSRX is attached to.
*/
TalonSRX::TalonSRX(uint32_t channel) : SafePWM(channel)
{
InitTalonSRX();
}
TalonSRX::~TalonSRX()
{
}
/**
* Set the PWM value.
*
* The PWM value is set using a range of -1.0 to 1.0, appropriately
* scaling the value for the FPGA.
*
* @param speed The speed value between -1.0 and 1.0 to set.
* @param syncGroup Unused interface.
*/
void TalonSRX::Set(float speed, uint8_t syncGroup)
{
SetSpeed(speed);
}
/**
* Get the recently set value of the PWM.
*
* @return The most recently set value for the PWM between -1.0 and 1.0.
*/
float TalonSRX::Get()
{
return GetSpeed();
}
/**
* Common interface for disabling a motor.
*/
void TalonSRX::Disable()
{
SetRaw(kPwmDisabled);
}
/**
* Write out the PID value as seen in the PIDOutput base object.
*
* @param output Write out the PWM value as was found in the PIDController
*/
void TalonSRX::PIDWrite(float output)
{
Set(output);
}

View File

@@ -6,10 +6,78 @@
#include "VictorSP.h"
VictorSP::VictorSP(uint32_t channel) : Talon(channel) {
//#include "NetworkCommunication/UsageReporting.h"
#include "LiveWindow/LiveWindow.h"
/**
* Common initialization code called by all constructors.
*
* Note that the VictorSP uses the following bounds for PWM values. These values should work reasonably well for
* most controllers, but if users experience issues such as asymmetric behavior around
* the deadband or inability to saturate the controller in either direction, calibration is recommended.
* The calibration procedure can be found in the VictorSP User Manual available from Vex.
*
*/
void VictorSP::InitVictorSP() {
SetBounds(2.004, 1.52, 1.50, 1.48, .997);
SetPeriodMultiplier(kPeriodMultiplier_1X);
SetRaw(m_centerPwm);
SetZeroLatch();
HALReport(HALUsageReporting::kResourceType_Talon, GetChannel());
LiveWindow::GetInstance()->AddActuator("VictorSP", GetChannel(), this);
}
VictorSP::~VictorSP() {
/**
* @param channel The PWM channel that the VictorSP is attached to.
*/
VictorSP::VictorSP(uint32_t channel) : SafePWM(channel)
{
InitVictorSP();
}
VictorSP::~VictorSP()
{
}
/**
* Set the PWM value.
*
* The PWM value is set using a range of -1.0 to 1.0, appropriately
* scaling the value for the FPGA.
*
* @param speed The speed value between -1.0 and 1.0 to set.
* @param syncGroup Unused interface.
*/
void VictorSP::Set(float speed, uint8_t syncGroup)
{
SetSpeed(speed);
}
/**
* Get the recently set value of the PWM.
*
* @return The most recently set value for the PWM between -1.0 and 1.0.
*/
float VictorSP::Get()
{
return GetSpeed();
}
/**
* Common interface for disabling a motor.
*/
void VictorSP::Disable()
{
SetRaw(kPwmDisabled);
}
/**
* Write out the PID value as seen in the PIDOutput base object.
*
* @param output Write out the PWM value as was found in the PIDController
*/
void VictorSP::PIDWrite(float output)
{
Set(output);
}

View File

@@ -54,7 +54,7 @@ public abstract class Button extends Trigger {
/**
* Toggles the command whenever the button is pressed (on then off then on)
* @param command
* @param command the command to start
*/
public void toggleWhenPressed(final Command command) {
toggleWhenActive(command);
@@ -62,7 +62,7 @@ public abstract class Button extends Trigger {
/**
* Cancel the command when the button is pressed
* @param command
* @param command the command to start
*/
public void cancelWhenPressed(final Command command) {
cancelWhenActive(command);

View File

@@ -149,7 +149,7 @@ public class SmartDashboard {
* @param key the key
* @param defaultValue the value returned if the key is undefined
* @return the value
* @throws NoSuchEleNetworkTableKeyNotDefinedmentException if there is no value mapped to by the key
* @throws NetworkTableKeyNotDefined if there is no value mapped to by the key
* @throws IllegalArgumentException if the value mapped to by the key is not a double
* @throws IllegalArgumentException if the key is null
*/
@@ -241,7 +241,7 @@ public class SmartDashboard {
* @param key the key
* @param defaultValue the value returned if the key is undefined
* @return the value
* @throws NetworkTableKeyNotDefined if there is no value mapped to by the key
* @throws TableKeyNotDefinedException if there is no value mapped to by the key
* @throws IllegalArgumentException if the value mapped to by the key is not an int
* @throws IllegalArgumentException if the key is null
*/
@@ -274,7 +274,7 @@ public class SmartDashboard {
* @deprecated Use {@link #getNumber(java.lang.String) getNumber} instead
* @param key the key
* @return the value
* @throws NoSuchEleNetworkTableKeyNotDefinedmentException if there is no value mapped to by the key
* @throws TableKeyNotDefinedException if there is no value mapped to by the key
* @throws IllegalArgumentException if the value mapped to by the key is not a double
* @throws IllegalArgumentException if the key is null
*/
@@ -289,7 +289,7 @@ public class SmartDashboard {
* @param key the key
* @param defaultValue the value returned if the key is undefined
* @return the value
* @throws NoSuchEleNetworkTableKeyNotDefinedmentException if there is no value mapped to by the key
* @throws TableKeyNotDefinedException if there is no value mapped to by the key
* @throws IllegalArgumentException if the value mapped to by the key is not a double
* @throws IllegalArgumentException if the key is null
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
//
// This file is auto-generated by wpilibj/wpilibJavaJNI/nivision/gen_java.py
// Please do not edit!
//
package com.ni.vision;
public class VisionException extends RuntimeException {
private static final long serialVersionUID = 1L;
public VisionException(String msg) {
super(msg);
}
@Override
public String toString() {
return "VisionException [" + super.toString() + "]";
}
}

View File

@@ -217,6 +217,20 @@ public class CANJaguar implements MotorSafety, PIDOutput, SpeedController, LiveW
// Not all Jaguar firmware reports a hardware version.
m_hardwareVersion = 0;
}
// 3330 was the first shipping RDK firmware version for the Jaguar
if (m_firmwareVersion >= 3330 || m_firmwareVersion < 108)
{
if (m_firmwareVersion < 3330)
{
DriverStation.reportError("Jag " + m_deviceNumber + " firmware " + m_firmwareVersion + " is too old (must be at least version 108 of the FIRST approved firmware)", false);
}
else
{
DriverStation.reportError("Jag" + m_deviceNumber + " firmware " + m_firmwareVersion + " is not FIRST approved (must be at least version 108 of the FIRST approved firmware)", false);
}
return;
}
}
/**

View File

@@ -21,7 +21,6 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
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) {
@@ -56,22 +55,53 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
this.value = value;
}
}
/** enumerated types for frame rate ms */
public enum StatusFrameRate {
General(0), Feedback(1), QuadEncoder(2), AnalogTempVbat(3);
public int value;
public static StatusFrameRate valueOf(int value) {
for(StatusFrameRate mode : values()) {
if(mode.value == value) {
return mode;
}
}
return null;
}
private StatusFrameRate(int value) {
this.value = value;
}
}
private CanTalonSRX m_impl;
ControlMode m_controlMode;
private static double kDelayForSolicitedSignals = 0.004;
int m_deviceNumber;
boolean m_controlEnabled;
int m_profile;
double m_setPoint;
public CANTalon(int deviceNumber) {
m_deviceNumber = deviceNumber;
m_impl = new CanTalonSRX(deviceNumber);
m_safetyHelper = new MotorSafetyHelper(this);
m_controlEnabled = true;
m_profile = 0;
m_setPoint = 0;
setProfile(m_profile);
changeControlMode(ControlMode.PercentVbus);
applyControlMode(ControlMode.PercentVbus);
}
public CANTalon(int deviceNumber,int controlPeriodMs) {
m_deviceNumber = deviceNumber;
m_impl = new CanTalonSRX(deviceNumber,controlPeriodMs); /* bound period to be within [1 ms,95 ms] */
m_safetyHelper = new MotorSafetyHelper(this);
m_controlEnabled = true;
m_profile = 0;
m_setPoint = 0;
setProfile(m_profile);
applyControlMode(ControlMode.PercentVbus);
}
@Override
@@ -103,10 +133,9 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* @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()) {
m_setPoint = outputValue;
switch (m_controlMode) {
case PercentVbus:
m_impl.Set(outputValue);
break;
@@ -127,8 +156,8 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
default:
break;
}
m_impl.SetModeSelect(m_controlMode.value);
}
System.out.println("Enabled: " + m_controlEnabled + " Mode: " + m_controlMode);
}
/**
@@ -221,11 +250,52 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
return CanTalonJNI.intp_value(valuep);
}
/**
* Get the number of of rising edges seen on the index pin.
*
* @return number of rising edges on idx pin.
*/
public int getNumberOfQuadIdxRises() {
long valuep = CanTalonJNI.new_intp();
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
m_impl.GetEncIndexRiseEvents(swigp);
return CanTalonJNI.intp_value(valuep);
}
/**
* @return IO level of QUADA pin.
*/
public int getPinStateQuadA(){
long valuep = CanTalonJNI.new_intp();
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
m_impl.GetQuadApin(swigp);
return CanTalonJNI.intp_value(valuep);
}
/**
* @return IO level of QUADB pin.
*/
public int getPinStateQuadB() {
long valuep = CanTalonJNI.new_intp();
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
m_impl.GetQuadBpin(swigp);
return CanTalonJNI.intp_value(valuep);
}
/**
* @return IO level of QUAD Index pin.
*/
public int getPinStateQuadIdx(){
long valuep = CanTalonJNI.new_intp();
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
m_impl.GetQuadIdxpin(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).
* @return The 24bit analog position. The bottom ten bits is the ADC (0 - 1023) on
* the analog pin of the Talon. The upper 14 bits
* tracks the overflows and underflows (continuous sensor).
*/
public int getAnalogInPosition() {
long valuep = CanTalonJNI.new_intp();
@@ -233,7 +303,14 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_impl.GetAnalogInWithOv(swigp);
return CanTalonJNI.intp_value(valuep);
}
/**
* Get the current analog in position, regardless of whether it is the current
* feedback device.
* @return The ADC (0 - 1023) on analog pin of the Talon.
*/
public int getAnalogInRaw() {
return getAnalogInPosition() & 0x3FF;
}
/**
* Get the current encoder velocity, regardless of whether it is the current
* feedback device.
@@ -258,7 +335,27 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_impl.GetCloseLoopErr(swigp);
return CanTalonJNI.intp_value(valuep);
}
// Returns true if limit switch is closed. false if open.
public boolean isFwdLimitSwitchClosed() {
long valuep = CanTalonJNI.new_intp();
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
m_impl.GetLimitSwitchClosedFor(swigp);
return (CanTalonJNI.intp_value(valuep)==0) ? true : false;
}
// Returns true if limit switch is closed. false if open.
public boolean isRevLimitSwitchClosed() {
long valuep = CanTalonJNI.new_intp();
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
m_impl.GetLimitSwitchClosedRev(swigp);
return (CanTalonJNI.intp_value(valuep)==0) ? true : false;
}
// Returns true if break is enabled during neutral. false if coast.
public boolean getBrakeEnableDuringNeutral() {
long valuep = CanTalonJNI.new_intp();
SWIGTYPE_p_int swigp = new SWIGTYPE_p_int(valuep, true);
m_impl.GetBrakeIsEnabled(swigp);
return (CanTalonJNI.intp_value(valuep)==0) ? false : true;
}
// Returns temperature of Talon, in degrees Celsius.
public double getTemp() {
long tempp = CanTalonJNI.new_doublep(); // Create a new swig pointer.
@@ -316,27 +413,35 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
}
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;
return m_controlMode;
}
public void changeControlMode(ControlMode controlMode) {
/**
* Fixup the m_controlMode so set() serializes the correct demand value.
* Also fills the modeSelecet in the control frame to disabled.
* @param controlMode Control mode to ultimately enter once user calls set().
* @see #set
*/
private void applyControlMode(ControlMode controlMode) {
m_controlMode = controlMode;
m_impl.SetModeSelect(controlMode.value);
if (controlMode == ControlMode.Disabled)
m_controlEnabled = false;
// Disable until set() is called.
m_impl.SetModeSelect(ControlMode.Disabled.value);
}
public void changeControlMode(ControlMode controlMode) {
if(m_controlMode == controlMode){
/* we already are in this mode, don't perform disable workaround */
}else{
applyControlMode(controlMode);
}
}
public void setFeedbackDevice(FeedbackDevice device) {
m_impl.SetFeedbackDeviceSelect(device.value);
}
public void setStatusFrameRateMs(StatusFrameRate stateFrame, int periodMs){
m_impl.SetStatusFrameRate(stateFrame.value,periodMs);
}
public void enableControl() {
changeControlMode(m_controlMode);
m_controlEnabled = true;
@@ -347,10 +452,14 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_controlEnabled = false;
}
public boolean isControlEnabled() {
return m_controlEnabled;
}
/**
* Get the current proportional constant.
*
* @returns double proportional constant for current profile.
* @return double proportional constant for current profile.
* @throws IllegalStateException if not in Position of Speed mode.
*/
public double getP() {
@@ -365,7 +474,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_P);
// Briefly wait for new values from the Talon.
Timer.delay(0.001);
Timer.delay(kDelayForSolicitedSignals);
long pp = CanTalonJNI.new_doublep();
m_impl.GetPgain(m_profile, new SWIGTYPE_p_double(pp, true));
@@ -384,7 +493,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_I);
// Briefly wait for new values from the Talon.
Timer.delay(0.001);
Timer.delay(kDelayForSolicitedSignals);
long ip = CanTalonJNI.new_doublep();
m_impl.GetIgain(m_profile, new SWIGTYPE_p_double(ip, true));
@@ -403,7 +512,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_D);
// Briefly wait for new values from the Talon.
Timer.delay(0.001);
Timer.delay(kDelayForSolicitedSignals);
long dp = CanTalonJNI.new_doublep();
m_impl.GetDgain(m_profile, new SWIGTYPE_p_double(dp, true));
@@ -422,7 +531,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_F);
// Briefly wait for new values from the Talon.
Timer.delay(0.001);
Timer.delay(kDelayForSolicitedSignals);
long fp = CanTalonJNI.new_doublep();
m_impl.GetFgain(m_profile, new SWIGTYPE_p_double(fp, true));
@@ -441,14 +550,22 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_IZone);
// Briefly wait for new values from the Talon.
Timer.delay(0.001);
Timer.delay(kDelayForSolicitedSignals);
long fp = CanTalonJNI.new_intp();
m_impl.GetIzone(m_profile, new SWIGTYPE_p_int(fp, true));
return CanTalonJNI.intp_value(fp);
}
public double getRampRate() {
/**
* Get 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.
*
* @return rampRate Maximum change in voltage, in volts / sec.
* @see #setProfile For selecting a certain profile.
*/
public double getCloseLoopRampRate() {
// if(!(m_controlMode.equals(ControlMode.Position) || m_controlMode.equals(ControlMode.Speed))) {
// throw new IllegalStateException("PID mode only applies in Position and Speed modes.");
// }
@@ -460,19 +577,53 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
m_impl.RequestParam(CanTalonSRX.param_t.eProfileParamSlot1_CloseLoopRampRate);
// Briefly wait for new values from the Talon.
Timer.delay(0.001);
Timer.delay(kDelayForSolicitedSignals);
long fp = CanTalonJNI.new_intp();
m_impl.GetCloseLoopRampRate(m_profile, new SWIGTYPE_p_int(fp, true));
double throttlePerMs = CanTalonJNI.intp_value(fp);
return throttlePerMs / 1023.0 * 12.0 * 1000.0;
}
/**
* @return The version of the firmware running on the Talon
*/
public long GetFirmwareVersion() {
// Update the information that we have.
m_impl.RequestParam(CanTalonSRX.param_t.eFirmVers);
// Briefly wait for new values from the Talon.
Timer.delay(kDelayForSolicitedSignals);
long fp = CanTalonJNI.new_intp();
m_impl.GetParamResponseInt32(CanTalonSRX.param_t.eFirmVers, new SWIGTYPE_p_int(fp, true));
return CanTalonJNI.intp_value(fp);
}
public long GetIaccum() {
// Update the information that we have.
m_impl.RequestParam(CanTalonSRX.param_t.ePidIaccum);
// Briefly wait for new values from the Talon.
Timer.delay(kDelayForSolicitedSignals);
long fp = CanTalonJNI.new_intp();
m_impl.GetParamResponseInt32(CanTalonSRX.param_t.ePidIaccum, new SWIGTYPE_p_int(fp, true));
return CanTalonJNI.intp_value(fp);
}
/**
* Clear the accumulator for I gain.
*/
public void ClearIaccum()
{
SWIGTYPE_p_CTR_Code status = m_impl.SetParam(CanTalonSRX.param_t.ePidIaccum, 0);
}
/**
* 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.
* @see #setProfile For selecting a certain profile.
*/
public void setP(double p) {
m_impl.SetPgain(m_profile, p);
@@ -482,7 +633,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* 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.
* @see #setProfile For selecting a certain profile.
*/
public void setI(double i) {
m_impl.SetIgain(m_profile, i);
@@ -492,7 +643,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* 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.
* @see #setProfile For selecting a certain profile.
*/
public void setD(double d) {
m_impl.SetDgain(m_profile, d);
@@ -502,7 +653,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* 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.
* @see #setProfile For selecting a certain profile.
*/
public void setF(double f) {
m_impl.SetFgain(m_profile, f);
@@ -517,7 +668,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* 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.
* @see #setProfile For selecting a certain profile.
*/
public void setIZone(int izone) {
m_impl.SetIzone(m_profile, izone);
@@ -530,11 +681,11 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* Only affects position and speed closed loop modes.
*
* @param rampRate Maximum change in voltage, in volts / sec.
* @see setProfile For selecting a certain profile.
* @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);
// CanTalonSRX takes units of Throttle (0 - 1023) / 1ms.
int rate = (int) (rampRate * 1023.0 / 12.0 / 1000.0);
m_impl.SetCloseLoopRampRate(m_profile, rate);
}
@@ -548,7 +699,7 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
*/
public void setVoltageRampRate(double rampRate) {
// CanTalonSRX takes units of Throttle (0 - 1023) / 10ms.
int rate = (int) (rampRate * 1023.0 / 12.0 * 100.0);
int rate = (int) (rampRate * 1023.0 / 12.0 /100.0);
m_impl.SetRampThrottle(rate);
}
@@ -561,14 +712,13 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
* @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 closeLoopRampRate Closed loop ramp rate. Maximum change in voltage, in volts / sec.
* @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)
public void setPID(double p, double i, double d, double f, int izone, double closeLoopRampRate, int profile)
{
if (profile != 0 && profile != 1)
throw new IllegalArgumentException("Talon PID profile must be 0 or 1.");
@@ -579,12 +729,20 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
setD(d);
setF(f);
setIZone(izone);
setCloseLoopRampRate(ramprate);
setCloseLoopRampRate(closeLoopRampRate);
}
public void setPID(double p, double i, double d) {
setPID(p, i, d, 0, 0, 0, m_profile);
}
/**
* @return The latest value set using set().
*/
public double getSetpoint() {
return m_setPoint;
}
/**
* Select which closed loop profile to use, and uses whatever PIDF gains and
* the such that are already there.
@@ -621,15 +779,15 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
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 setReverseSoftLimit(int reverseLimit) {
m_impl.SetReverseSoftLimit(reverseLimit);
}
public void enableReverseSoftLimit(boolean enable) {
m_impl.SetReverseSoftEnable(enable ? 1 : 0);
}
@@ -642,6 +800,34 @@ public class CANTalon implements MotorSafety, PIDOutput, SpeedController {
int mask = 4 + (forward ? 1 : 0) * 2 + (reverse ? 1 : 0);
m_impl.SetOverrideLimitSwitchEn(mask);
}
/**
* Configure the fwd limit switch to be normally open or normally closed.
* Talon will disable momentarilly if the Talon's current setting
* is dissimilar to the caller's requested setting.
*
* Since Talon saves setting to flash this should only affect
* a given Talon initially during robot install.
*
* @param normallyOpen true for normally open. false for normally closed.
*/
public void ConfigFwdLimitSwitchNormallyOpen(boolean normallyOpen)
{
SWIGTYPE_p_CTR_Code status = m_impl.SetParam(CanTalonSRX.param_t.eOnBoot_LimitSwitch_Forward_NormallyClosed,normallyOpen ? 0 : 1);
}
/**
* Configure the rev limit switch to be normally open or normally closed.
* Talon will disable momentarilly if the Talon's current setting
* is dissimilar to the caller's requested setting.
*
* Since Talon saves setting to flash this should only affect
* a given Talon initially during robot install.
*
* @param normallyOpen true for normally open. false for normally closed.
*/
public void ConfigRevLimitSwitchNormallyOpen(boolean normallyOpen)
{
SWIGTYPE_p_CTR_Code status = m_impl.SetParam(CanTalonSRX.param_t.eOnBoot_LimitSwitch_Reverse_NormallyClosed,normallyOpen ? 0 : 1);
}
public void enableBrakeMode(boolean brake) {
m_impl.SetOverrideBrakeType(brake ? 2 : 1);

View File

@@ -0,0 +1,278 @@
package edu.wpi.first.wpilibj;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import com.ni.vision.NIVision;
import com.ni.vision.NIVision.Image;
import com.ni.vision.NIVision.RawData;
import com.ni.vision.VisionException;
//replicates CameraServer.cpp in java lib
public class CameraServer {
public static CameraServer getInstance() {
if (server == null) {
server = new CameraServer();
}
return server;
}
private static CameraServer server;
private AtomicBoolean ready;
private Thread serverThread;
private int m_quality;
private static final int kPort = 1180;
private static final byte[] kMagicNumber = { 0x01, 0x00, 0x00, 0x00 };
private static final int kSize640x480 = 0;
private static final int kSize320x240 = 1;
private static final int kSize160x120 = 2;
private static final int kHardwareCompression = -1;
private static final String kDefaultCameraName = "cam1";
private List<Byte> m_imageData;
private boolean m_autoCaptureStarted;
private CameraServer() {
ready = new AtomicBoolean(false);
m_imageData = new ArrayList<Byte>();
m_quality = 50;
serverThread = new Thread(new Runnable() {
public void run() {
try {
serve();
} catch (IOException e) {
// do stuff here
} catch (InterruptedException e) {
// do stuff here
}
}
});
serverThread.start();
}
/**
* Manually change the image that is served by the MJPEG stream. This can be
* called to pass custom annotated images to the dashboard. Note that, for
* 640x480 video, this method could take between 40 and 50 milliseconds to
* complete.
*
* This shouldn't be called if {@link #startAutomaticCapture} is called.
*
* @param image
* The IMAQ image to show on the dashboard
*/
public synchronized void setImage(Image image) {
// handle multi-threadedness
/* Flatten the IMAQ image to a JPEG */
RawData data = NIVision.imaqFlatten(image,
NIVision.FlattenType.FLATTEN_IMAGE,
NIVision.CompressionType.COMPRESSION_JPEG, 10 * m_quality);
ByteBuffer buffer = data.getBuffer();
m_imageData.clear();
/* Find the start of the JPEG data */
int index = 0;
while (index < buffer.limit() - 1) {
if ((buffer.get(index) & 0xff) == 0xFF
&& (buffer.get(index + 1) & 0xff) == 0xD8)
break;
index++;
}
while (index < buffer.limit()) {
m_imageData.add(buffer.get(index++));
}
if (m_imageData.size() <= 2) {
throw new VisionException(
"data size of flattened image is less than 2. Try another camera! ");
}
data.free();
ready.set(true);
}
/**
* Start automatically capturing images to send to the dashboard.
*
* You should call this method to just see a camera feed on the dashboard
* without doing any vision processing on the roboRIO. {@link #setImage}
* shouldn't be called after this is called.
*
* @param cameraName
* The name of the camera interface (e.g. "cam1")
*/
public void startAutomaticCapture(String cameraName) {
synchronized (this) {
if (m_autoCaptureStarted) {
// print
// "you fucked up \"Automatic capture has already been started\""
return;
}
m_autoCaptureStarted = true;
}
CaptureRunnable runnable = new CaptureRunnable(cameraName);
Thread captureThread = new Thread(runnable);
captureThread.start();
}
private class CaptureRunnable implements Runnable {
String name;
public CaptureRunnable(String name) {
this.name = name;
}
@Override
public void run() {
Image frame = NIVision.imaqCreateImage(
NIVision.ImageType.IMAGE_RGB, 0);
int id = NIVision.IMAQdxOpenCamera(name,
NIVision.IMAQdxCameraControlMode.CameraControlModeController);
NIVision.IMAQdxConfigureGrab(id);
NIVision.IMAQdxStartAcquisition(id);
while (true) {
NIVision.IMAQdxGrab(id, frame, 1);
setImage(frame);
}
// NIVision.IMAQdxStopAcquisition(id);
// NIVision.IMAQdxCloseCamera(id);
}
}
/**
* check if auto capture is started
*
*/
public synchronized boolean isAutoCaptureStarted() {
return m_autoCaptureStarted;
}
/**
* Set the quality of the compressed image sent to the dashboard
*
* @param quality
* The quality of the JPEG image, from 0 to 100
*/
public synchronized void setQuality(int quality) {
m_quality = quality > 100 ? 100 : quality < 0 ? 0 : quality;
}
/**
* Get the quality of the compressed image sent to the dashboard
*
* @return The quality, from 0 to 100
*/
public synchronized int getQuality() {
return m_quality;
}
/**
* Run the M-JPEG server.
*
* This function listens for a connection from the dashboard in a background
* thread, then sends back the M-JPEG stream.
*
* @throws IOException if the Socket connection fails
* @throws InterruptedException if the sleep is interrupted
*/
protected void serve() throws IOException, InterruptedException {
ServerSocket socket = new ServerSocket();
socket.setReuseAddress(true);
InetSocketAddress address = new InetSocketAddress(kPort);
socket.bind(address);
while (true) {
try {
Socket s = socket.accept();
DataInputStream is = new DataInputStream(s.getInputStream());
OutputStream os = s.getOutputStream();
int fps = is.readInt();
int compression = is.readInt();
int size = is.readInt();
if (compression != kHardwareCompression) {
// print to driverstation -->
// ("Choose \"USB Camera HW\" on the dashboard");
s.close();
continue;
}
long period = (long) (1000 / (1.0 * fps));
while (true) {
long t0 = System.currentTimeMillis();
while (!ready.get())
;
ready.set(false);
// write numbers
try {
os.write(kMagicNumber);
// write size of image
synchronized (this) {
os.write(intTobyteArray(m_imageData.size()));
byte[] imageData = new byte[m_imageData.size()];
for (int i = 0; i < m_imageData.size(); i++) {
imageData[i] = m_imageData.get(i).byteValue();
}
os.write(imageData);
}
long dt = System.currentTimeMillis() - t0;
if (dt < period) {
Thread.sleep(period - dt);
}
} catch (IOException ex) {
// print error to driverstation
break;
}
}
} catch (IOException ex) {
// print error to driverstation
continue;
}
}
}
public byte[] intTobyteArray(int n) {
byte[] arr = new byte[4];
arr[0] = (byte) ((n >> 24) & 0xFF);
arr[1] = (byte) ((n >> 16) & 0xFF);
arr[2] = (byte) ((n >> 8) & 0xFF);
arr[3] = (byte) (n & 0xFF);
return arr;
}
}

View File

@@ -435,6 +435,8 @@ public class CanTalonSRX extends CtreCanNode {
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 static CanTalonSRX.param_t eQuadFilterEn = new CanTalonSRX.param_t("eQuadFilterEn", CanTalonJNI.CanTalonSRX_eQuadFilterEn_get());
public final static CanTalonSRX.param_t ePidIaccum = new CanTalonSRX.param_t("ePidIaccum", CanTalonJNI.CanTalonSRX_ePidIaccum_get());
public final int swigValue() {
return swigValue;
@@ -470,7 +472,7 @@ public class CanTalonSRX extends CtreCanNode {
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 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, eQuadFilterEn, ePidIaccum };
private static int swigNext = 0;
private final int swigValue;
private final String swigName;

View File

@@ -16,6 +16,10 @@ import edu.wpi.first.wpilibj.hal.PowerJNI;
public class ControllerPower
{
/**
* Get the input voltage to the robot controller
* @return The controller input voltage value
*/
public static double getInputVoltage()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -24,7 +28,11 @@ public class ControllerPower
HALUtil.checkStatus(status.asIntBuffer());
return retVal;
}
/**
* Get the input current to the robot controller
* @return The controller input current value
*/
public static double getInputCurrent()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -34,6 +42,10 @@ public class ControllerPower
return retVal;
}
/**
* Get the voltage of the 3.3V rail
* @return The controller 3.3V rail voltage value
*/
public static double getVoltage3V3()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -43,6 +55,10 @@ public class ControllerPower
return retVal;
}
/**
* Get the current output of the 3.3V rail
* @return The controller 3.3V rail output current value
*/
public static double getCurrent3V3()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -52,6 +68,11 @@ public class ControllerPower
return retVal;
}
/**
* Get the enabled state of the 3.3V rail. The rail may be disabled due to a controller
* brownout, a short circuit on the rail, or controller over-voltage
* @return The controller 3.3V rail enabled value
*/
public static boolean getEnabled3V3()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -61,6 +82,10 @@ public class ControllerPower
return retVal;
}
/**
* Get the count of the total current faults on the 3.3V rail since the controller has booted
* @return The number of faults
*/
public static int getFaultCount3V3()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -70,6 +95,10 @@ public class ControllerPower
return retVal;
}
/**
* Get the voltage of the 5V rail
* @return The controller 5V rail voltage value
*/
public static double getVoltage5V()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -79,6 +108,10 @@ public class ControllerPower
return retVal;
}
/**
* Get the current output of the 5V rail
* @return The controller 5V rail output current value
*/
public static double getCurrent5V()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -88,6 +121,11 @@ public class ControllerPower
return retVal;
}
/**
* Get the enabled state of the 5V rail. The rail may be disabled due to a controller
* brownout, a short circuit on the rail, or controller over-voltage
* @return The controller 5V rail enabled value
*/
public static boolean getEnabled5V()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -97,6 +135,10 @@ public class ControllerPower
return retVal;
}
/**
* Get the count of the total current faults on the 5V rail since the controller has booted
* @return The number of faults
*/
public static int getFaultCount5V()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -106,6 +148,10 @@ public class ControllerPower
return retVal;
}
/**
* Get the voltage of the 6V rail
* @return The controller 6V rail voltage value
*/
public static double getVoltage6V()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -115,6 +161,10 @@ public class ControllerPower
return retVal;
}
/**
* Get the current output of the 6V rail
* @return The controller 6V rail output current value
*/
public static double getCurrent6V()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -124,6 +174,11 @@ public class ControllerPower
return retVal;
}
/**
* Get the enabled state of the 6V rail. The rail may be disabled due to a controller
* brownout, a short circuit on the rail, or controller over-voltage
* @return The controller 6V rail enabled value
*/
public static boolean getEnabled6V()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -132,7 +187,11 @@ public class ControllerPower
HALUtil.checkStatus(status.asIntBuffer());
return retVal;
}
/**
* Get the count of the total current faults on the 6V rail since the controller has booted
* @return The number of faults
*/
public static int getFaultCount6V()
{
ByteBuffer status = ByteBuffer.allocateDirect(4);

View File

@@ -25,6 +25,11 @@ public class DriverStation implements RobotState.Interface {
* Number of Joystick Ports
*/
public static final int kJoystickPorts = 6;
private class HALJoystickButtons {
public int buttons;
public byte count;
}
/**
* The robot alliance that the robot is a part of
@@ -49,6 +54,9 @@ public class DriverStation implements RobotState.Interface {
private static DriverStation instance = new DriverStation();
private short[][] m_joystickAxes = new short[kJoystickPorts][FRCNetworkCommunicationsLibrary.kMaxJoystickAxes];
private short[][] m_joystickPOVs = new short[kJoystickPorts][FRCNetworkCommunicationsLibrary.kMaxJoystickPOVs];
private HALJoystickButtons[] m_joystickButtons = new HALJoystickButtons[kJoystickPorts];
private Thread m_thread;
private final Object m_dataSem;
@@ -78,6 +86,10 @@ public class DriverStation implements RobotState.Interface {
*/
protected DriverStation() {
m_dataSem = new Object();
for(int i=0; i<kJoystickPorts; i++)
{
m_joystickButtons[i] = new HALJoystickButtons();
}
m_packetDataAvailableMutex = HALUtil.initializeMutexNormal();
m_packetDataAvailableSem = HALUtil.initializeMultiWait();
@@ -103,13 +115,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) {
if (++safetyCounter >= 4) {
MotorSafetyHelper.checkMotors();
safetyCounter = 0;
}
@@ -149,6 +161,24 @@ public class DriverStation implements RobotState.Interface {
}
}
}
/**
* 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 of all of the joysticks
for(byte stick = 0; stick < kJoystickPorts; stick++) {
m_joystickAxes[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickAxes(stick);
m_joystickPOVs[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickPOVs(stick);
ByteBuffer countBuffer = ByteBuffer.allocateDirect(1);
m_joystickButtons[stick].buttons = FRCNetworkCommunicationsLibrary.HALGetJoystickButtons((byte)stick, countBuffer);
m_joystickButtons[stick].count = countBuffer.get();
}
m_newControlData = true;
}
/**
* Read the battery voltage.
@@ -179,7 +209,7 @@ public class DriverStation implements RobotState.Interface {
* @param axis The analog axis value to read from the joystick.
* @return The value of the axis on the joystick.
*/
public double getStickAxis(int stick, int axis) {
public synchronized double getStickAxis(int stick, int axis) {
if(stick < 0 || stick >= kJoystickPorts) {
throw new RuntimeException("Joystick index is out of range, should be 0-5");
}
@@ -187,15 +217,13 @@ 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 >= joystickAxes.length) {
if (axis >= m_joystickAxes[stick].length) {
reportJoystickUnpluggedError("WARNING: Joystick axis " + axis + " on port " + stick + " not available, check if controller is plugged in\n");
return 0.0;
}
byte value = (byte)joystickAxes[axis];
byte value = (byte)m_joystickAxes[stick][axis];
if(value < 0) {
return value / 128.0;
@@ -209,13 +237,13 @@ public class DriverStation implements RobotState.Interface {
*
* @param stick The joystick port number
*/
public int getStickAxisCount(int stick){
public synchronized 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;
return m_joystickAxes[stick].length;
}
/**
@@ -223,7 +251,7 @@ public class DriverStation implements RobotState.Interface {
*
* @return the angle of the POV in degrees, or -1 if the POV is not pressed.
*/
public int getStickPOV(int stick, int pov) {
public synchronized int getStickPOV(int stick, int pov) {
if(stick < 0 || stick >= kJoystickPorts) {
throw new RuntimeException("Joystick index is out of range, should be 0-5");
}
@@ -231,15 +259,13 @@ 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 >= joystickPOVs.length) {
if (pov >= m_joystickPOVs[stick].length) {
reportJoystickUnpluggedError("WARNING: Joystick POV " + pov + " on port " + stick + " not available, check if controller is plugged in\n");
return 0;
}
return joystickPOVs[pov];
return m_joystickPOVs[stick][pov];
}
/**
@@ -247,13 +273,13 @@ public class DriverStation implements RobotState.Interface {
*
* @param stick The joystick port number
*/
public int getStickPOVCount(int stick){
public synchronized 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;
return m_joystickPOVs[stick].length;
}
/**
@@ -263,20 +289,37 @@ public class DriverStation implements RobotState.Interface {
* @param stick The joystick to read.
* @return The state of the buttons on the joystick.
*/
public boolean getStickButton(final int stick, byte button) {
public synchronized int getStickButtons(final int stick) {
if(stick < 0 || stick >= kJoystickPorts) {
throw new RuntimeException("Joystick index is out of range, should be 0-3");
}
return m_joystickButtons[stick].buttons;
}
/**
* The state of one joystick button. Button indexes begin at 1.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return The state of the joystick button.
*/
public synchronized 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) {
if(button > m_joystickButtons[stick].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;
if(button <= 0)
{
reportJoystickUnpluggedError("ERROR: Button indexes begin at 1 in WPILib for C++ and Java\n");
return false;
}
return ((0x1 << (button - 1)) & m_joystickButtons[stick].buttons) != 0;
}
/**
@@ -284,17 +327,14 @@ public class DriverStation implements RobotState.Interface {
*
* @param stick the joystick port number
*/
public int getStickButtonCount(int stick){
public synchronized 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;
return m_joystickButtons[stick].count;
}
/**

View File

@@ -107,7 +107,7 @@ public abstract class InterruptableSensorBase extends SensorBase {
/**
* Request one of the 8 interrupts synchronously on this digital input. Request
* interrupts in synchronous mode where the user program will have to
* explicitly wait for the interrupt to occur using {@link waitForInterrupt}.
* explicitly wait for the interrupt to occur using {@link #waitForInterrupt}.
* The default is interrupt on rising edges only.
*/
public void requestInterrupts() {

View File

@@ -59,6 +59,12 @@ public class IterativeRobot extends RobotBase {
m_teleopInitialized = false;
m_testInitialized = false;
}
@Override
protected void prestart() {
// Don't immediately say that the robot's ready to be enabled.
// See below.
}
/**
* Provide an alternate "main loop" via startCompetition().
@@ -68,15 +74,12 @@ public class IterativeRobot extends RobotBase {
UsageReporting.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Iterative);
robotInit();
// tracing support:
final int TRACE_LOOP_MAX = 100;
int loopCount = TRACE_LOOP_MAX;
Object marker = null;
boolean didDisabledPeriodic = false;
boolean didAutonomousPeriodic = false;
boolean didTeleopPeriodic = false;
boolean didTestPeriodic = false;
// We call this now (not in prestart like default) so that the robot
// won't enable until the initialization has finished. This is useful
// because otherwise it's sometimes possible to enable the robot
// before the code is ready.
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting();
// loop forever, calling the appropriate mode-dependent function
LiveWindow.setEnabled(false);
@@ -97,7 +100,6 @@ public class IterativeRobot extends RobotBase {
if (nextPeriodReady()) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramDisabled();
disabledPeriodic();
didDisabledPeriodic = true;
}
} else if (isTest()) {
// call TestInit() if we are now just entering test mode from either
@@ -113,7 +115,6 @@ public class IterativeRobot extends RobotBase {
if (nextPeriodReady()) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramTest();
testPeriodic();
didTestPeriodic = true;
}
} else if (isAutonomous()) {
// call Autonomous_Init() if this is the first time
@@ -132,7 +133,6 @@ public class IterativeRobot extends RobotBase {
if (nextPeriodReady()) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramAutonomous();
autonomousPeriodic();
didAutonomousPeriodic = true;
}
} else {
// call Teleop_Init() if this is the first time
@@ -148,7 +148,6 @@ public class IterativeRobot extends RobotBase {
if (nextPeriodReady()) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramTeleop();
teleopPeriodic();
didTeleopPeriodic = true;
}
}
m_ds.waitForData();

View File

@@ -419,6 +419,10 @@ public class Joystick extends GenericHID {
* @param value The normalized value (0 to 1) to set the rumble to
*/
public void setRumble(RumbleType type, float value) {
if (value < 0)
value = 0;
else if (value > 1)
value = 1;
if (type.value == RumbleType.kLeftRumble_val)
m_leftRumble = (short)(value*65535);
else

View File

@@ -59,4 +59,53 @@ public class PowerDistributionPanel extends SensorBase {
return current;
}
/**
* @return The current of all the channels
*/
public double getTotalCurrent(){
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
double current = PDPJNI.getPDPTotalCurrent(status.asIntBuffer());
return current;
}
/**
* @return the total power
*/
public double getTotalPower(){
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
double power = PDPJNI.getPDPTotalPower(status.asIntBuffer());
return power;
}
public double getTotalEnergy(){
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
double energy = PDPJNI.getPDPTotalEnergy(status.asIntBuffer());
return energy;
}
public void resetTotalEnergy(){
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
PDPJNI.resetPDPTotalEnergy(status.asIntBuffer());
}
public void clearStickyFaults(){
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
PDPJNI.clearPDPStickyFaults(status.asIntBuffer());
}
}

View File

@@ -814,7 +814,7 @@ public class Preferences {
* Returns whether or not the given string is ok to use in the
* preference table.
*
* @param value
* @param value the string to check
* @return true if the given string is ok to use in the preference table
*/
public static boolean isAcceptable(String value) {

View File

@@ -130,6 +130,15 @@ public abstract class RobotBase {
*/
public abstract void startCompetition();
/**
* This hook is called right before startCompetition(). By default, tell the
* DS that the robot is now ready to be enabled. If you don't want for the
* robot to be enabled yet, you can override this method to do nothing.
*/
protected void prestart() {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting();
}
public static boolean getBooleanProperty(String name, boolean defaultValue) {
String propVal = System.getProperty(name);
if (propVal == null) {
@@ -149,7 +158,6 @@ public abstract class RobotBase {
*/
public static void initializeHardwareConfiguration(){
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationReserve();
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting();
// Set some implementations so that the static methods work properly
Timer.SetImplementation(new HardwareTimer());
@@ -161,8 +169,6 @@ public abstract class RobotBase {
* Starting point for the applications.
*/
public static void main(String args[]) {
boolean errorOnExit = false;
initializeHardwareConfiguration();
UsageReporting.report(tResourceType.kResourceType_Language, tInstances.kLanguage_Java);
@@ -182,14 +188,16 @@ public abstract class RobotBase {
RobotBase robot;
try {
robot = (RobotBase) Class.forName(robotName).newInstance();
robot.prestart();
} catch (Throwable t) {
DriverStation.reportError("ERROR Unhandled exception instantiating robot " + robotName + " " + t.toString() + " at " + Arrays.toString(t.getStackTrace()), false);
System.err.println("WARNING: Robots don't quit!");
System.err.println("ERROR: Could not instantiate robot "+robotName+"!");
System.err.println("ERROR: Could not instantiate robot " + robotName + "!");
System.exit(1);
return;
}
boolean errorOnExit = false;
try {
robot.startCompetition();
} catch (Throwable t) {

View File

@@ -13,9 +13,9 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
/**
* Utility class for handling Robot drive based on a definition of the motor configuration.
* The robot drive class handles basic driving for a robot. Currently, 2 and 4 motor standard
* drive trains are supported. In the future other drive types like swerve and meccanum might
* be implemented. Motor channel numbers are passed supplied on creation of the class. Those are
* The robot drive class handles basic driving for a robot. Currently, 2 and 4 motor tank and
* mecanum drive trains are supported. In the future other drive types like swerve might
* be implemented. Motor channel numbers are supplied on creation of the class. Those are
* used for either the drive function (intended for hand created drive code, such as autonomous)
* or with the Tank/Arcade functions intended to be used for Operator Control driving.
*/

View File

@@ -36,7 +36,8 @@ public class SerialPort {
public enum Port {
kOnboard(0),
kMXP(1);
kMXP(1),
kUSB(2);
private int value;
@@ -263,7 +264,7 @@ public class SerialPort {
* Set the type of flow control to enable on this port.
*
* By default, flow control is disabled.
* @param flowControl
* @param flowControl the FlowControl value to use
*/
public void setFlowControl(FlowControl flowControl) {
ByteBuffer status = ByteBuffer.allocateDirect(4);

View File

@@ -7,17 +7,94 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control
* @see CANTalon CANTalon for CAN control of Talon SRX
*/
public class TalonSRX extends Talon {
public class TalonSRX extends SafePWM implements SpeedController {
/**
* Common initialization code called by all constructors.
*
* Note that the TalonSRX uses the following bounds for PWM values. These values should work reasonably well for
* most controllers, but if users experience issues such as asymmetric behavior around
* the deadband or inability to saturate the controller in either direction, calibration is recommended.
* The calibration procedure can be found in the TalonSRX User Manual available from CTRE.
*
* - 2.037ms = full "forward"
* - 1.539ms = the "high end" of the deadband range
* - 1.513ms = center of the deadband range (off)
* - 1.487ms = the "low end" of the deadband range
* - .989ms = full "reverse"
*/
protected void initTalonSRX() {
setBounds(2.004, 1.52, 1.50, 1.48, .997);
setPeriodMultiplier(PeriodMultiplier.k1X);
setRaw(m_centerPwm);
setZeroLatch();
LiveWindow.addActuator("TalonSRX", getChannel(), this);
UsageReporting.report(tResourceType.kResourceType_Talon, getChannel());
}
/**
* Constructor.
*
* @param channel The PWM channel that the Talon SRX is attached to.
* @param channel The PWM channel that the Talon is attached to.
*/
public TalonSRX(final int channel) {
super(channel);
initTalonSRX();
}
/**
* Set the PWM value.
*
* @deprecated For compatibility with CANJaguar
*
* The PWM value is set using a range of -1.0 to 1.0, appropriately
* scaling the value for the FPGA.
*
* @param speed The speed to set. Value should be between -1.0 and 1.0.
* @param syncGroup The update group to add this Set() to, pending UpdateSyncGroup(). If 0, update immediately.
*/
public void set(double speed, byte syncGroup) {
setSpeed(speed);
Feed();
}
/**
* Set the PWM value.
*
* The PWM value is set using a range of -1.0 to 1.0, appropriately
* scaling the value for the FPGA.
*
* @param speed The speed value between -1.0 and 1.0 to set.
*/
public void set(double speed) {
setSpeed(speed);
Feed();
}
/**
* Get the recently set value of the PWM.
*
* @return The most recently set value for the PWM between -1.0 and 1.0.
*/
public double get() {
return getSpeed();
}
/**
* Write out the PID value as seen in the PIDOutput base object.
*
* @param output Write out the PWM value as was found in the PIDController
*/
public void pidWrite(double output) {
set(output);
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Copyright (c) FIRST 2008-2012. 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 the root directory of */
/* the project. */
@@ -7,11 +7,39 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Vex Robotics Victor SP Speed Controller
* VEX Robotics Victor SP Speed Controller
*/
public class VictorSP extends Talon {
public class VictorSP extends SafePWM implements SpeedController {
/**
* Common initialization code called by all constructors.
*
* Note that the VictorSP uses the following bounds for PWM values. These values should work reasonably well for
* most controllers, but if users experience issues such as asymmetric behavior around
* the deadband or inability to saturate the controller in either direction, calibration is recommended.
* The calibration procedure can be found in the VictorSP User Manual available from CTRE.
*
* - 2.037ms = full "forward"
* - 1.539ms = the "high end" of the deadband range
* - 1.513ms = center of the deadband range (off)
* - 1.487ms = the "low end" of the deadband range
* - .989ms = full "reverse"
*/
protected void initVictorSP() {
setBounds(2.004, 1.52, 1.50, 1.48, .997);
setPeriodMultiplier(PeriodMultiplier.k1X);
setRaw(m_centerPwm);
setZeroLatch();
LiveWindow.addActuator("VictorSP", getChannel(), this);
UsageReporting.report(tResourceType.kResourceType_Talon, getChannel());
}
/**
* Constructor.
*
@@ -19,6 +47,53 @@ public class VictorSP extends Talon {
*/
public VictorSP(final int channel) {
super(channel);
initVictorSP();
}
/**
* Set the PWM value.
*
* @deprecated For compatibility with CANJaguar
*
* The PWM value is set using a range of -1.0 to 1.0, appropriately
* scaling the value for the FPGA.
*
* @param speed The speed to set. Value should be between -1.0 and 1.0.
* @param syncGroup The update group to add this Set() to, pending UpdateSyncGroup(). If 0, update immediately.
*/
public void set(double speed, byte syncGroup) {
setSpeed(speed);
Feed();
}
/**
* Set the PWM value.
*
* The PWM value is set using a range of -1.0 to 1.0, appropriately
* scaling the value for the FPGA.
*
* @param speed The speed value between -1.0 and 1.0 to set.
*/
public void set(double speed) {
setSpeed(speed);
Feed();
}
/**
* Get the recently set value of the PWM.
*
* @return The most recently set value for the PWM between -1.0 and 1.0.
*/
public double get() {
return getSpeed();
}
/**
* Write out the PID value as seen in the PIDOutput base object.
*
* @param output Write out the PWM value as was found in the PIDController
*/
public void pidWrite(double output) {
set(output);
}
}

View File

@@ -143,6 +143,8 @@ public class CanTalonJNI {
public final static native int CanTalonSRX_eResetFlags_get();
public final static native int CanTalonSRX_eFirmVers_get();
public final static native int CanTalonSRX_eSettingsChanged_get();
public final static native int CanTalonSRX_eQuadFilterEn_get();
public final static native int CanTalonSRX_ePidIaccum_get();
public final static native long CanTalonSRX_SetParam(long jarg1, CanTalonSRX jarg1_, int jarg2, double jarg3);
public final static native long CanTalonSRX_RequestParam(long jarg1, CanTalonSRX jarg1_, int jarg2);
public final static native long CanTalonSRX_GetParamResponse(long jarg1, CanTalonSRX jarg1_, int jarg2, long jarg3);

View File

@@ -7,4 +7,9 @@ public class PDPJNI extends JNIWrapper {
public static native double getPDPTemperature(IntBuffer status);
public static native double getPDPVoltage(IntBuffer status);
public static native double getPDPChannelCurrent(byte channel, IntBuffer status);
}
public static native double getPDPTotalCurrent(IntBuffer status);
public static native double getPDPTotalPower(IntBuffer status);
public static native double getPDPTotalEnergy(IntBuffer status);
public static native void resetPDPTotalEnergy(IntBuffer status);
public static native void clearPDPStickyFaults(IntBuffer status);
}

View File

@@ -1,74 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJavaFinal</artifactId>
<packaging>jar</packaging>
<version>0.1.0-SNAPSHOT</version>
<parent>
<groupId>edu.wpi.first.wpilib.templates.athena</groupId>
<artifactId>library-jar</artifactId>
<version>0.1.0-SNAPSHOT</version>
<relativePath>../../maven-utilities/athena/library-jar/pom.xml</relativePath>
</parent>
<profiles>
<profile>
<id>docline-java8-disable</id>
<activation>
<jdk>[1.8,</jdk>
<jdk>[1.8,</jdk>
</activation>
<build>
<plugins>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
<additionalparam>-Xdoclint:all -Xdoclint:-missing</additionalparam>
<tags>
<tag>
<name>pre</name>
<placement>a</placement>
<head>Precondition:</head>
</tag>
</tags>
</configuration>
</plugin>
</plugins>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJava</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJavaDevices</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJavaJNI</artifactId>
<version>0.1.0-SNAPSHOT</version>
<type>so</type>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJava</artifactId>
<version>0.1.0-SNAPSHOT</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJavaDevices</artifactId>
<version>0.1.0-SNAPSHOT</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJava</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJavaDevices</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJavaJNI</artifactId>
<version>0.1.0-SNAPSHOT</version>
<type>so</type>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJava</artifactId>
<version>0.1.0-SNAPSHOT</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.wpilibj</groupId>
<artifactId>wpilibJavaDevices</artifactId>
<version>0.1.0-SNAPSHOT</version>
<classifier>sources</classifier>
</dependency>
</dependencies>
<build>
<plugins>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
@@ -96,7 +103,7 @@
</then>
<else>
<copy todir="${project.build.directory}/classes" >
<fileset dir="${mvn.wpilibJava.jar.path}" />
<fileset dir="${mvn.wpilibJava.jar.path}" />
</copy>
</else>
</if>
@@ -112,7 +119,7 @@
</then>
<else>
<copy todir="${project.build.directory}/classes" >
<fileset dir="${mvn.wpilibJavaDevices.jar.path}" />
<fileset dir="${mvn.wpilibJavaDevices.jar.path}" />
</copy>
</else>
</if>
@@ -128,12 +135,12 @@
<phase>generate-sources</phase>
<configuration>
<target>
<copy todir="${project.build.directory}/classes/linux-arm"
file="${edu.wpi.first.wpilibj:wpilibJavaJNI:so}" />
<copy todir="${project.build.directory}/classes/linux-arm"
file="${edu.wpi.first.wpilibj:wpilibJavaJNI:so}" />
</target>
</configuration>
</execution>
<execution>
<id>generate-sources</id>
<goals>
@@ -172,17 +179,16 @@
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<sourceFileExcludes>
<exclude>edu/wpi/first/wpilibj/image/</exclude>
<exclude>edu/wpi/first/wpilibj/camera/</exclude>
<exclude>edu/wpi/first/wpilibj/visa/</exclude>
<exclude>edu/wpi/first/wpilibj/SerialPort.java</exclude>
</sourceFileExcludes>
<includeDependencySources>true</includeDependencySources>
<sourceFileExcludes>
<exclude>edu/wpi/first/wpilibj/image/</exclude>
<exclude>edu/wpi/first/wpilibj/camera/</exclude>
<exclude>edu/wpi/first/wpilibj/visa/</exclude>
</sourceFileExcludes>
<includeDependencySources>true</includeDependencySources>
</configuration>
</plugin>
@@ -201,52 +207,52 @@
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<versionRange>[2.8,)</versionRange>
<goals>
<goal>copy</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[2.8,)</versionRange>
<goals>
<goal>unpack</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<versionRange>[2.8,)</versionRange>
<goals>
<goal>copy</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[2.8,)</versionRange>
<goals>
<goal>unpack</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -33,7 +33,7 @@ public class CANVoltageQuadEncoderModeTest extends AbstractCANTest {
/** The stopped value in volts */
private static final double kStoppedValue = 0;
/** The running value in volts */
private static final double kRunningValue = 14;
private static final double kRunningValue = 12;
private static final double kVoltageTolerance = .25;

View File

@@ -18,6 +18,7 @@ import org.junit.runners.model.MultipleFailureException;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.RobotBase;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
@@ -44,6 +45,7 @@ public abstract class AbstractComsSetup {
if (!initialized) {
// Set some implementations so that the static methods work properly
RobotBase.initializeHardwareConfiguration();
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting();
LiveWindow.setEnabled(false);
TestBench.out().println("Started coms");

View File

@@ -2049,6 +2049,30 @@ SWIGEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_CanTalonJNI_CanTalonSRX_1
}
SWIGEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_CanTalonJNI_CanTalonSRX_1eQuadFilterEn_1get(JNIEnv *jenv, jclass jcls) {
jint jresult = 0 ;
CanTalonSRX::_param_t result;
(void)jenv;
(void)jcls;
result = (CanTalonSRX::_param_t)CanTalonSRX::eQuadFilterEn;
jresult = (jint)result;
return jresult;
}
SWIGEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_CanTalonJNI_CanTalonSRX_1ePidIaccum_1get(JNIEnv *jenv, jclass jcls) {
jint jresult = 0 ;
CanTalonSRX::_param_t result;
(void)jenv;
(void)jcls;
result = (CanTalonSRX::_param_t)CanTalonSRX::ePidIaccum;
jresult = (jint)result;
return jresult;
}
SWIGEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_CanTalonJNI_CanTalonSRX_1SetParam(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jdouble jarg3) {
jlong jresult = 0 ;
CanTalonSRX *arg1 = (CanTalonSRX *) 0 ;

File diff suppressed because it is too large Load Diff

View File

@@ -40,3 +40,68 @@ JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_getPDPChannelCur
return getPDPChannelCurrent(channel, status_ptr);
}
/*
* Class: edu_wpi_first_wpilibj_hal_PDPJNI
* Method: getPDPTotalCurrent
* Signature: (BLjava/nio/IntBuffer;)D
*/
JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_getPDPTotalCurrent
(JNIEnv *env, jclass, jobject status)
{
jint *status_ptr = (jint *)env->GetDirectBufferAddress(status);
return getPDPTotalCurrent(status_ptr);
}
/*
* Class: edu_wpi_first_wpilibj_hal_PDPJNI
* Method: getPDPTotalPower
* Signature: (BLjava/nio/IntBuffer;)D
*/
JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_getPDPTotalPower
(JNIEnv *env, jclass, jobject status)
{
jint *status_ptr = (jint *)env->GetDirectBufferAddress(status);
return getPDPTotalPower(status_ptr);
}
/*
* Class: edu_wpi_first_wpilibj_hal_PDPJNI
* Method: resetPDPTotalEnergy
* Signature: (BLjava/nio/IntBuffer;)D
*/
JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_getPDPTotalEnergy
(JNIEnv *env, jclass, jobject status)
{
jint *status_ptr = (jint *)env->GetDirectBufferAddress(status);
return getPDPTotalEnergy(status_ptr);
}
/*
* Class: edu_wpi_first_wpilibj_hal_PDPJNI
* Method: resetPDPTotalEnergy
* Signature: (BLjava/nio/IntBuffer;)D
*/
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_resetPDPTotalEnergy
(JNIEnv *env, jclass, jobject status)
{
jint *status_ptr = (jint *)env->GetDirectBufferAddress(status);
resetPDPTotalEnergy(status_ptr);
}
/*
* Class: edu_wpi_first_wpilibj_hal_PDPJNI
* Method: clearStickyFaults
* Signature: (BLjava/nio/IntBuffer;)D
*/
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_clearPDPStickyFaults
(JNIEnv *env, jclass, jobject status)
{
jint *status_ptr = (jint *)env->GetDirectBufferAddress(status);
clearPDPStickyFaults(status_ptr);
}

View File

@@ -119,7 +119,7 @@ JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_PowerJNI_getUserCurrentFau
(JNIEnv * env, jclass, jobject status)
{
jint * statusPtr = (jint*)env->GetDirectBufferAddress(status);
return getUserCurrentFaults3V3(statusPtr);
return getUserCurrentFaults5V(statusPtr);
}
/*

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,114 @@
from __future__ import print_function
import sys
import os
import re
try:
import configparser
except ImportError:
import ConfigParser as configparser
from nivision_parse import *
class StructSizerEmitter:
def __init__(self, out, config, hname):
self.out = out
self.config = config
print("""#include <stdio.h>
#include <stddef.h>
#include <{hname}>
int main()
{{
asm("#STRUCT_SIZER [_platform_]\\n");
asm("#STRUCT_SIZER pointer=%0\\n" : : "n"((int)sizeof(void*)));
""".format(hname=hname), file=self.out)
def finish(self):
print("}", file=self.out)
def config_get(self, section, option, fallback):
try:
return self.config.get(section, option)
except (ValueError, configparser.NoSectionError, configparser.NoOptionError):
return fallback
def config_getboolean(self, section, option, fallback):
try:
return self.config.getboolean(section, option)
except (ValueError, configparser.NoSectionError, configparser.NoOptionError):
return fallback
def block_comment(self, comment):
pass
def opaque_struct(self, name):
pass
def define(self, name, value, comment):
pass
def text(self, text):
print(text, file=self.out)
def static_const(self, name, ctype, value):
pass
def enum(self, name, values):
pass
def typedef(self, name, typedef, arr):
pass
def typedef_function(self, name, restype, params):
pass
def function(self, name, restype, params):
pass
def structunion(self, ctype, name, fields):
if name in opaque_structs:
return
print('asm("#STRUCT_SIZER [{name}]\\n");'.format(name=name), file=self.out)
print('asm("#STRUCT_SIZER _SIZE_=%0\\n" : : "n"((int)sizeof({name})));'.format(name=name), file=self.out)
for fname, ftype, arr, comment in fields:
if ':' in fname:
continue # can't handle bitfields
print('asm("#STRUCT_SIZER {field}=%0\\n" : : "n"((int)offsetof({name}, {field})));'.format(name=name, field=fname), file=self.out)
def struct(self, name, fields):
self.structunion("Structure", name, fields)
def union(self, name, fields):
self.structunion("Union", name, fields)
def generate(srcdir, configpath=None, hpath=None):
# read config file
config = configparser.ConfigParser()
config.read(configpath)
block_comment_exclude = set(x.strip() for x in
config.get("Block Comment", "exclude").splitlines())
# open input file
inf = open(hpath)
# prescan for undefined structures
prescan_file(inf)
inf.seek(0)
# generate
with open("struct_sizer.c", "wt") as out:
emit = StructSizerEmitter(out, config, os.path.basename(hpath))
parse_file(emit, inf, block_comment_exclude)
emit.finish()
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: gen_struct_sizer.py <header.h> <config.ini>")
exit(0)
fname = sys.argv[1]
configname = sys.argv[2]
generate("", configname, fname)

View File

@@ -0,0 +1,29 @@
#!/bin/bash
#This script should be able to generate the JNI
# bindings for NIVision. At some point,
# it should be integrated into the build system.
# Assumes running from allwpilib/wpilibj/wpilibJavaJNI/nivision
# Get structure sizes.
python gen_struct_sizer.py ../../../wpilibc/wpilibC++Devices/include/nivision.h nivision_2011.ini
arm-frc-linux-gnueabi-gcc -I../../../wpilibc/wpilibC++Devices/include -S struct_sizer.c
cat struct_sizer.s | python get_struct_size.py > nivision_arm.ini
python gen_struct_sizer.py ../../../wpilibc/wpilibC++Devices/include/NIIMAQdx.h imaqdx.ini
arm-frc-linux-gnueabi-gcc -I../../../wpilibc/wpilibC++Devices/include -S struct_sizer.c
cat struct_sizer.s | python get_struct_size.py > imaqdx_arm.ini
# Run python generator.
python gen_java.py \
../../../wpilibc/wpilibC++Devices/include/nivision.h \
nivision_arm.ini \
nivision_2011.ini \
\
../../../wpilibc/wpilibC++Devices/include/NIIMAQdx.h \
imaqdx_arm.ini \
imaqdx.ini
# Stick generated files into appropriate places.
cp NIVision.cpp ../lib/NIVisionJNI.cpp
mkdir -p ../../wpilibJavaDevices/src/main/java/com/ni/vision
cp *.java ../../wpilibJavaDevices/src/main/java/com/ni/vision/

View File

@@ -0,0 +1,14 @@
from __future__ import print_function
import sys
def main():
for line in sys.stdin:
line = line.strip()
if not line.startswith("#STRUCT_SIZER"):
continue
line = line[14:]
line = line.replace("#", "")
print(line)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,81 @@
[Block Comment]
exclude=
Typedefs
Forward Declare Data Structures
Error Codes Enumeration
Callbacks
; Error Codes Enumeration
[IMAQdxError]
exclude=True
; Callbacks
[FrameDoneEventCallbackPtr]
exclude=True
[PnpEventCallbackPtr]
exclude=True
[AttributeUpdatedEventCallbackPtr]
exclude=True
; Functions
[IMAQdxSequence]
arraysize=images:count
exclude=True
[IMAQdxEnumerateCameras]
arraysize=cameraInformationArray:count
exclude=True
[IMAQdxGetImageData]
#arraysize=buffer:bufferSize
[IMAQdxEnumerateVideoModes]
arraysize=videoModeArray:count
exclude=True
[IMAQdxEnumerateAttributes]
arraysize=attributeInformationArray:count
exclude=True
[IMAQdxGetAttribute]
exclude=True
[IMAQdxSetAttribute]
# has to be manual due to "..."
exclude=True
[IMAQdxGetAttributeMinimum]
exclude=True
[IMAQdxGetAttributeMaximum]
exclude=True
[IMAQdxGetAttributeIncrement]
exclude=True
[IMAQdxEnumerateAttributeValues]
arraysize=list:size
exclude=True
[IMAQdxGetAttributeTooltip]
exclude=True
[IMAQdxGetAttributeUnits]
exclude=True
[IMAQdxRegisterFrameDoneEvent]
# callback
exclude=True
[IMAQdxRegisterPnpEvent]
# callback
exclude=True
[IMAQdxWriteMemory]
arraysize=values:count
exclude=True
[IMAQdxReadMemory]
arraysize=values:count
exclude=True
[IMAQdxGetErrorString]
exclude=True
[IMAQdxEnumerateAttributes2]
arraysize=attributeInformationArray:count
exclude=True
[IMAQdxGetAttributeDescription]
exclude=True
[IMAQdxGetAttributeDisplayName]
exclude=True
[IMAQdxDispose]
exclude=True
[IMAQdxRegisterAttributeUpdatedEvent]
# callback
exclude=True
[IMAQdxEnumerateAttributes3]
arraysize=attributeInformationArray:count
exclude=True

View File

@@ -0,0 +1,835 @@
;
; [name]
; arraysize -- comma separated list of "param:numParam" where param is the
; name of the pointer parameter, and numParam is the name of
; the parameter that contains the array size for the pointer
; retarraysize -- name of the pass-by-reference parameter that on function
; return contains the array size of the returned pointer
; exclude -- if True, no code is output for this name (full custom)
; underscore -- if True, only underscored raw wrapper is output (partial custom)
; outparams -- comma separated list of output parameter names
; inparams -- comma separated list of parameter names that are input
; parameters (e.g. not output parameters)
; defaults -- comma separated list of "param:default" where param is the
; parameter name and default is the default value
; exclude_members -- for structures, members to not emit
; nullok -- comma separated list of parameter names that may be null
; retref -- parameter that (if non-null) is returned as a reference
; retunowned -- if True, return value should not be owned
;
; The generator code auto-detects many parameters, so this file is only needed
; for overriding the auto-detected behavior.
; defines
[IMAQ_IMPORT]
exclude=True
[IMAQ_FUNC]
exclude=True
[IMAQ_STDCALL]
exclude=True
[IMAQ_CALLBACK]
exclude=True
[IMAQ_DEFAULT_LEARNING_MODE]
exclude=True
[ERR_INVALID_COLORCOMPLEXITY]
exclude=True
; structures
[PolyModel]
arraysize=kCoeffs:numKCoeffs
[CalibrationReferencePoints]
arraysize=pixelCoords:numPixelCoords,realCoords:numRealCoords
[GetCameraParametersReport]
#TODO: projectionMatrix:projectionMatrixRows*projectionMatrixCols
exclude_members=projectionMatrix
[GetCalibrationInfoReport]
#TODO: errorMap:errorMapRows*errorMapCols
exclude_members=errorMap
[ContourFitSplineReport]
arraysize=points:numberOfPoints
[ContourFitPolynomialReport]
arraysize=bestFit:numberOfPoints,polynomialCoefficients:numberOfCoefficients
[SetupMatchPatternData]
arraysize=matchSetupData:numMatchSetupData
[ContourInfoReport]
arraysize=pointsPixel:numPointsPixel,pointsReal:numPointsReal,curvaturePixel:numCurvaturePixel,curvatureReal:numCurvatureReal
[SupervisedColorSegmentationReport]
arraysize=labelOut:numLabelOut
[LabelToROIReport]
arraysize=roiArray:numOfROIs,labelsOutArray:numOfLabels,isTooManyVectorsArray:isTooManyVectorsArraySize
[ClassifiedCurve]
arraysize=curvePoints:numCurvePoints
[CurvatureAnalysisReport]
arraysize=curves:numCurves
[ComputeDistancesReport]
arraysize=distances:numDistances,distancesReal:numDistancesReal
[ClassifiedDisparity]
arraysize=templateSubsection:numTemplateSubsection,targetSubsection:numTargetSubsection
[ClassifyDistancesReport]
arraysize=classifiedDistances:numClassifiedDistances
[ContourComputeCurvatureReport]
arraysize=curvaturePixel:numCurvaturePixel,curvatureReal:numCurvatureReal
[ExtractContourReport]
arraysize=contourPoints:numContourPoints,sourcePoints:numSourcePoints
[ExtractTextureFeaturesReport]
arraysize=waveletBands:numWaveletBands
#TODO: textureFeatures:textureFeaturesRows:textureFeaturesCols
exclude_members=textureFeatures
[WaveletBandsReport]
#TODO: LLBand:rows:cols
#TODO: LHBand:rows:cols
#TODO: HLBand:rows:cols
#TODO: HHBand:rows:cols
#TODO: LLLBand:rows:cols
#TODO: LLHBand:rows:cols
#TODO: LHHBand:rows:cols
exclude_members=LLBand,LHBand,HLBand,HHBand,LLLBand,LLHBand,LHHBand
[MeasureParticlesReport]
#TODO: pixelMeasurements:numParticles:numMeasurements
#TODO: calibratedMeasurements:numParticles:numMeasurements
exclude_members=pixelMeasurements,calibratedMeasurements
[ClassifierReportAdvanced]
arraysize=allScores:allScoresSize,sampleScores:sampleScoresSize
[FindEdgeReport]
arraysize=straightEdges:numStraightEdges
[ReadTextReport3]
arraysize=characterReport:numCharacterReports
[EdgeReport2]
arraysize=edges:numEdges,gradientInfo:numGradientInfo
[ConcentricRakeReport2]
arraysize=firstEdges:numFirstEdges,lastEdges:numLastEdges,searchArcs:numSearchArcs
[SpokeReport2]
arraysize=firstEdges:numFirstEdges,lastEdges:numLastEdges,searchLines:numSearchLines
[RakeReport2]
arraysize=firstEdges:numFirstEdges,lastEdges:numLastEdges,searchLines:numSearchLines
[QRCodeDataToken]
arraysize=data:dataLength
[StraightEdgeReport2]
arraysize=straightEdges:numStraightEdges,searchLines:numSearchLines
[StraightEdge]
arraysize=usedEdges:numUsedEdges
[QRCodeReport]
arraysize=data:dataLength,tokenizedData:sizeOfTokenizedData
[DataMatrixReport]
arraysize=data:dataLength
[ReadTextReport2]
arraysize=characterReport:numCharacterReports
[FeatureData]
arraysize=contourPoints:numContourPoints
uniontype=feature:type:IMAQ_CIRCLE_FEATURE=circle:IMAQ_ELLIPSE_FEATURE=ellipse:IMAQ_CONST_CURVE_FEATURE=constCurve:IMAQ_RECTANGLE_FEATURE=rectangle:IMAQ_LEG_FEATURE=leg:IMAQ_CORNER_FEATURE=corner:IMAQ_PARALLEL_LINE_PAIR_FEATURE=parallelLinePair:IMAQ_PAIR_OF_PARALLEL_LINE_PAIRS_FEATURE=pairOfParallelLinePairs:IMAQ_LINE_FEATURE=line:IMAQ_CLOSED_CURVE_FEATURE=closedCurve
[GeometricPatternMatch2]
arraysize=featureData:numFeatureData
[ShapeDetectionOptions]
arraysize=angleRanges:numAngleRanges
[Curve]
arraysize=points:numPoints
[Barcode2DInfo]
arraysize=data:dataLength
[ClassifierAccuracyReport]
arraysize=classNames:size,classAccuracy:size,classPredictiveValue:size
#TODO: classificationDistribution:classPredictiveValue:size
exclude_members=classificationDistribution
[NearestNeighborTrainingReport]
arraysize=allScores:allScoresSize
#TODO: classDistancesTable
exclude_members=classDistancesTable
[ClassifierSampleInfo]
arraysize=featureVector:featureVectorSize
[ClassifierReport]
arraysize=allScores:allScoresSize
[MatchGeometricPatternOptions]
arraysize=angleRanges:numAngleRanges
[ConstructROIOptions2]
arraysize=palette:numColors
[BestEllipse2]
arraysize=pointsUsed:numPointsUsed
[BestCircle2]
arraysize=pointsUsed:numPointsUsed
[ReadTextOptions]
arraysize=validChars:numValidChars
[ReadTextReport]
arraysize=characterReport:numCharacterReports
[EdgeLocationReport]
arraysize=edges:numEdges
[ImageInfo]
#TODO: imageStart
exclude_members=reserved0,reserved1,imageStart
[LCDReport]
arraysize=segmentInfo:numCharacters
exclude_members=reserved
[LCDSegments]
exclude_members=reserved
[LearnColorPatternOptions]
arraysize=colorsToIgnore:numColorsToIgnore
[LinearAverages]
arraysize=columnAverages:columnCount,rowAverages:rowCount,risingDiagAverages:risingDiagCount,fallingDiagAverages:fallingDiagCount
[LineProfile]
arraysize=profileData:dataCount
[MatchColorPatternOptions]
arraysize=angleRanges:numRanges
[HistogramReport]
arraysize=histogram:histogramCount
[BestLine]
arraysize=pointsUsed:numPointsUsed
[CalibrationInfo]
#TODO: errorMap:mapColumns*mapRows
exclude_members=errorMap
[CalibrationPoints]
arraysize=pixelCoordinates:numCoordinates,realWorldCoordinates:numCoordinates
[CaliperReport]
exclude_members=reserved
[ClosedContour]
arraysize=points:numPoints
[ColorInformation]
arraysize=info:infoCount
[ConcentricRakeReport]
arraysize=rakeArcs:numArcs,firstEdges:numFirstEdges,lastEdges:numLastEdges,allEdges:numLinesWithEdges,linesWithEdges:numLinesWithEdges
[ConstructROIOptions]
arraysize=palette:numColors
[ContourInfo]
arraysize=points:numPoints
[ContourInfo2]
uniontype=structure:type:IMAQ_POINT=point:IMAQ_LINE=line:IMAQ_RECT=rect:IMAQ_OVAL=ovalBoundingBox:IMAQ_CLOSED_CONTOUR=closedContour:IMAQ_OPEN_CONTOUR=openContour:IMAQ_ANNULUS=annulus:IMAQ_ROTATED_RECT=rotatedRect
[UserPointSymbol]
#TODO: pixels:cols*rows
exclude_members=pixels
[MatchPatternOptions]
arraysize=angleRanges:numRanges
[OpenContour]
arraysize=points:numPoints
[QuantifyReport]
arraysize=regions:regionCount
[RakeReport]
arraysize=rakeLines:numRakeLines,firstEdges:numFirstEdges,lastEdges:numLastEdges,allEdges:numLinesWithEdges,linesWithEdges:numLinesWithEdges
[TransformReport]
arraysize=points:numPoints,validPoints:numPoints
[MeterArc]
arraysize=arcCoordPoints:numOfArcCoordPoints
[StructuringElement]
#TODO: arraysize=kernel:matrixRows*matrixCols
exclude_members=kernel
[SpokeReport]
arraysize=spokeLines:numSpokeLines,firstEdges:numFirstEdges,lastEdges:numLastEdges,allEdges:numLinesWithEdges,linesWithEdges:numLinesWithEdges
[ToolWindowOptions]
exclude_members=reserved2,reserved3,reserved4
[EventCallback]
exclude=True
; Logical functions
; TODO: constant versions
[imaqAndConstant]
exclude=True
[imaqCompareConstant]
exclude=True
[imaqLogicalDifferenceConstant]
exclude=True
[imaqNandConstant]
exclude=True
[imaqNorConstant]
exclude=True
[imaqOrConstant]
exclude=True
[imaqXnorConstant]
exclude=True
[imaqXorConstant]
exclude=True
; Arithmetic functions
; TODO: constant versions
[imaqAbsoluteDifferenceConstant]
exclude=True
[imaqAddConstant]
exclude=True
[imaqAverageConstant]
exclude=True
[imaqDivideConstant2]
exclude=True
[imaqMaxConstant2]
exclude=True
[imaqMinConstant]
exclude=True
[imaqModuloConstant]
exclude=True
[imaqMultiplyConstant]
exclude=True
[imaqSubtractConstant]
exclude=True
; Particle Analysis functions
[imaqCountParticles]
outparams=numParticles
[imaqMeasureParticle]
outparams=value
[imaqMeasureParticles]
arraysize=measurements:numMeasurements
[imaqParticleFilter4]
arraysize=criteria:criteriaCount
outparams=numParticles
; Morphology functions
[imaqFindCircles]
retarraysize=numCircles
[imaqLabel2]
outparams=particleCount
[imaqMorphology]
nullok=structuringElement
[imaqSeparation]
nullok=structuringElement
[imaqSimpleDistance]
nullok=structuringElement
[imaqSizeFilter]
nullok=structuringElement
; Acquisition functions
[imaqCopyFromRing]
nullok=image,imageNumber
outparams=imageNumber
retref=image
[imaqExtractFromRing]
nullok=imageNumber
outparams=imageNumber
retunowned=True
[imaqGrab]
nullok=image
retref=image
[imaqSetupRing]
arraysize=images:numImages
inparams=images
[imaqSetupSequence]
arraysize=images:numImages
inparams=images
[imaqSnap]
nullok=image
retref=image
; Caliper functions
[imaqCaliperTool]
retarraysize=numEdgePairs
arraysize=points:numPoints
[imaqDetectExtremes]
retarraysize=numExtremes
arraysize=pixels:numPixels
[imaqFindTransformRect2]
outparams=baseSystem,newSystem,axisReport
[imaqFindTransformRects2]
outparams=baseSystem,newSystem,axisReport
[imaqSimpleEdge]
retarraysize=numEdges
arraysize=points:numPoints
; Spatial Filters functions
[imaqCannyEdgeFilter]
nullok=options
[imaqConvolve2]
inparams=kernel
exclude=True
[imaqEdgeFilter]
nullok=mask
[imaqLowPass]
nullok=mask
[imaqMedianFilter]
nullok=mask
[imaqNthOrderFilter]
nullok=mask
; Drawing functions
[imaqDrawTextOnImage]
nullok=options,fontNameUsed
; Interlacing functions
[imaqInterlaceSeparate]
nullok=odd,even
; Image Information functions
[imaqEnumerateCustomKeys]
retarraysize=size
[imaqGetImageSize]
nullok=width,height
[imaqGetPixelAddress]
underscored=True
exclude=True
[imaqReadCustomData]
retsize=size
retunowned=True
[imaqWriteCustomData]
size=data:size
; Display functions
[imaqGetLastKey]
nullok=keyPressed,windowNumber,modifiers
[imaqGetSystemWindowHandle]
exclude=True
[imaqGetWindowCenterPos]
outparams=centerPosition
; Image Manipulation functions
[imaqCast]
nullok=lookup
exclude=True
[imaqFlatten]
retsize=size
[imaqRotate2]
# TODO because of PixelValue
exclude=True
[imaqShift]
# TODO because of PixelValue
exclude=True
[imaqUnflatten]
size=data:size
; File I/O functions
[imaqGetAVIInfo]
outparams=info
[imaqGetFileInfo]
nullok=calibrationUnit,calibrationX,calibrationY,width,height,imageType
[imaqGetFilterNames]
retarraysize=numFilters
[imaqLoadImagePopup]
retarraysize=numPaths
[imaqReadAVIFrame]
size=data:dataSize
# unclear whether dataSize is input or output parameter
exclude=True
[imaqReadFile]
nullok=colorTable,numColors
[imaqWriteAVIFrame]
size=data:dataLength
[imaqWriteBMPFile]
nullok=colorTable
defaults=colorTable:null
[imaqWriteFile]
nullok=colorTable
defaults=colorTable:null
[imaqWriteJPEGFile]
nullok=colorTable
defaults=colorTable:null
inparams=colorTable
[imaqWritePNGFile2]
nullok=colorTable
defaults=colorTable:null
[imaqWriteTIFFFile]
nullok=options,colorTable
defaults=options:null,colorTable:null
; Analytic Geometry functions
[imaqBuildCoordinateSystem]
outparams=system
[imaqFitCircle2]
arraysize=points:numPoints
[imaqFitEllipse2]
arraysize=points:numPoints
[imaqFitLine]
arraysize=points:numPoints
[imaqGetBisectingLine]
outparams=bisectStart,bisectEnd
[imaqGetIntersection]
outparams=intersection
[imaqGetMidLine]
outparams=midLineStart,midLineEnd
[imaqGetPerpendicularLine]
outparams=perpLineStart,perpLineEnd
[imaqGetPointsOnContour]
retarraysize=numSegments
[imaqGetPointsOnLine]
retarraysize=numPoints
[imaqInterpolatePoints]
retarraysize=interpCount
arraysize=points:numPoints
; Clipboard functions
[imaqClipboardToImage]
nullok=palette
[imaqImageToClipboard]
nullok=palette
; Image Management functions
[imaqCreateImage]
defaults=borderSize:0
[imaqImageToArray]
nullok=columns,rows
underscored=True
exclude=True
; Color Processing functions
[imaqChangeColorSpace2]
# TODO because of Color2
exclude=True
[imaqColorBCGTransform]
nullok=redOptions,greenOptions,blueOptions,mask
[imaqColorHistogram2]
nullok=mask
[imaqColorLookup]
nullok=mask,plane1,plane2,plane3
exclude=True
[imaqColorThreshold]
nullok=plane1Range,plane2Range,plane3Range
; Transform functions
[imaqBCGTransform]
nullok=mask
[imaqEqualize]
nullok=mask
[imaqInverse]
nullok=mask
[imaqMathTransform]
nullok=mask
[imaqLookup2]
nullok=mask
exclude=True
; Window Management functions
[imaqGetMousePos]
nullok=position,windowNumber
[imaqGetWindowBackground]
outparams=backgroundColor
[imaqGetWindowDisplayMapping]
outparams=mapping
[imaqGetWindowGrid]
nullok=xResolution,yResolution
[imaqGetWindowPos]
outparams=position
[imaqGetWindowSize]
nullok=width,height
[imaqSetWindowPalette]
arraysize=palette:numColors
nullok=palette
; Utilities functions
; Many Make* functions are faster in native Python
[imaqGetKernel]
exclude=True
[imaqMakeAnnulus]
exclude=True
[imaqMakePoint]
exclude=True
[imaqMakePointFloat]
exclude=True
[imaqMakeRect]
exclude=True
[imaqMakeRectFromRotatedRect]
exclude=True
[imaqMakeRotatedRect]
exclude=True
[imaqMakeRotatedRectFromRect]
exclude=True
[imaqMulticoreOptions]
underscored=True
; Tool Window functions
[imaqGetLastEvent]
nullok=windowNumber,tool,rect
outparams=type,tool,rect
[imaqGetToolWindowHandle]
exclude=True
[imaqGetToolWindowPos]
outparams=position
[imaqSetEventCallback]
exclude=True
[imaqSetupToolWindow]
nullok=options
; Meter functions
[imaqReadMeter]
outparams=endOfNeedle
; Calibration functions
[imaqCorrectCalibratedImage]
# TODO because of PixelValue
exclude=True
[imaqTransformPixelToRealWorld]
arraysize=pixelCoordinates:numCoordinates
[imaqTransformRealWorldToPixel]
arraysize=realWorldCoordinates:numCoordinates
; Pixel Manipulation functions
[imaqArrayToComplexPlane]
exclude=True
[imaqComplexPlaneToArray]
nullok=columns,rows
underscored=True
exclude=True
[imaqExtractColorPlanes]
nullok=plane1,plane2,plane3
[imaqFillImage]
nullok=mask
# TODO because of PixelValue
exclude=True
[imaqGetLine]
nullok=numPoints
underscored=True
exclude=True
[imaqGetPixel]
outparams=value
# TODO because of PixelValue
exclude=True
[imaqReplaceColorPlanes]
nullok=plane1,plane2,plane3
[imaqSetLine]
underscored=True
exclude=True
[imaqSetPixel]
# TODO because of PixelValue
exclude=True
; Color Matching functions
[imaqLearnColor]
nullok=roi
[imaqMatchColor]
retarraysize=numScores
nullok=roi
; Barcode I/O functions
[imaqGradeDataMatrixBarcodeAIM]
outparams=report
[imaqReadBarcode]
nullok=roi
[imaqReadPDF417Barcode]
retarraysize=numBarcodes
[imaqReadQRCode]
defaults=reserved:IMAQ_QR_NO_GRADING
; LCD functions
[imaqFindLCDSegments]
nullok=options
[imaqReadLCD]
nullok=options
; Shape Matching functions
[imaqMatchShape]
retarraysize=numMatches
; Contours functions
[imaqAddClosedContour]
arraysize=points:numPoints
[imaqAddOpenContour]
arraysize=points:numPoints
[imaqGetContourColor]
outparams=contourColor
; Regions of Interest functions
[imaqGetROIBoundingBox]
outparams=boundingBox
[imaqGetROIColor]
outparams=roiColor
[imaqSetWindowROI]
nullok=roi
; Image Analysis functions
[imaqExtractCurves]
retarraysize=numCurves
[imaqHistogram]
nullok=mask
[imaqQuantify]
nullok=mask
; Error Management functions
[imaqClearError]
exclude=True
[imaqGetErrorText]
exclude=True
[imaqGetLastError]
exclude=True
[imaqGetLastErrorFunc]
exclude=True
[imaqSetError]
nullok=function
exclude=True
; Threshold functions
[imaqMultithreshold]
arraysize=ranges:numRanges
; Memory Management functions
[imaqDispose]
# This is done as a full-custom function
exclude=True
; Pattern Matching functions
[imaqDetectCircles]
retarraysize=numMatchesReturned
[imaqDetectEllipses]
retarraysize=numMatchesReturned
[imaqDetectLines]
retarraysize=numMatchesReturned
[imaqDetectRectangles]
retarraysize=numMatchesReturned
[imaqGetGeometricFeaturesFromCurves]
retarraysize=numFeatures
arraysize=curves:numCurves,featureTypes:numFeatureTypes
[imaqGetGeometricTemplateFeatureInfo]
retarraysize=numFeatures
[imaqLearnMultipleGeometricPatterns]
arraysize=patterns:numberOfPatterns
exclude=True
[imaqMatchColorPattern]
retarraysize=numMatches
[imaqMatchGeometricPattern2]
retarraysize=numMatches
[imaqMatchMultipleGeometricPatterns]
retarraysize=numMatches
[imaqReadMultipleGeometricPatternFile]
underscored=True
[imaqRefineMatches]
retarraysize=numCandidatesOut
arraysize=candidatesIn:numCandidatesIn
[imaqMatchGeometricPattern3]
retarraysize=numMatches
[imaqMatchPattern3]
retarraysize=numMatches
nullok=options
; Overlay functions
[imaqGetOverlayProperties]
outparams=transformBehaviors
[imaqMergeOverlay]
arraysize=palette:numColors
[imaqOverlayBitmap]
underscored=True
[imaqOverlayClosedContour]
arraysize=points:numPoints
[imaqOverlayOpenContour]
arraysize=points:numPoints
[imaqOverlayPoints]
arraysize=points:numPoints,colors:numColors
; OCR functions
[imaqVerifyPatterns]
arraysize=expectedPatterns:patternCount
retarraysize=numScores
[imaqVerifyText]
retarraysize=numScores
; Geometric Matching functions
[imaqContourClassifyCurvature]
arraysize=curvatureClasses:numCurvatureClasses
[imaqContourClassifyDistances]
arraysize=distanceRanges:numDistanceRanges
[imaqContourSetupMatchPattern]
arraysize=rangeSettings:numRangeSettings
[imaqContourAdvancedSetupMatchPattern]
arraysize=geometricOptions:numGeometricOptions
; Morphology Reconstruction functions
[imaqGrayMorphologyReconstruct]
arraysize=points:numOfPoints
[imaqMorphologyReconstruct]
arraysize=points:numOfPoints
; Texture functions
[imaqClassificationTextureDefectOptions]
exclude=True
[imaqCooccurrenceMatrix]
exclude=True
[imaqExtractTextureFeatures]
inparams=waveletBands
exclude=True
[imaqExtractWaveletBands]
inparams=waveletBands
exclude=True
; Regions of Interest Manipulation functions
[imaqMaskToROI]
nullok=withinLimit
[imaqROIToMask]
nullok=imageModel,inSpace
[imaqLabelToROI]
arraysize=labelsIn:numLabelsIn
; Morphology functions
[imaqGrayMorphology]
nullok=structuringElement
; Classification functions
[imaqAddClassifierSample]
arraysize=featureVector:vectorSize
[imaqAdvanceClassify]
arraysize=featureVector:vectorSize
[imaqClassify]
arraysize=featureVector:vectorSize
[imaqGetColorClassifierOptions]
outparams=options
[imaqGetNearestNeighborOptions]
outparams=options
;[imaqReadClassifierFile]
;[imaqWriteClassifierFile]
; Obsolete functions
[imaqWritePNGFile]
nullok=colorTable
defaults=colorTable:null
[imaqRotate]
# TODO because of PixelValue
exclude=True
[imaqSelectParticles]
retarraysize=selectedCount
[imaqGetParticleInfo]
retarraysize=reportCount
[imaqEdgeTool]
retarraysize=numEdges
[imaqCircles]
retarraysize=numCircles
[imaqFitEllipse]
arraysize=points:numPoints
outparams=ellipse
[imaqFitCircle]
arraysize=points:numPoints
outparams=circle
[imaqChangeColorSpace]
# TODO because of Color
exclude=True
[imaqMatchPattern]
retarraysize=numMatches
nullok=options
[imaqLineGaugeTool]
nullok=reference
[imaqBestCircle]
arraysize=points:numPoints
outparams=center
[imaqCoordinateReference]
outparams=origin
[imaqSetWindowOverlay]
nullok=overlay
[imaqGetCalibrationInfo]
outparams=unit,xDistance,yDistance
nullok=unit,xDistance,yDistance
[imaqGetParticleClassifierOptions]
outparams=preprocessingOptions,options
[imaqConvolve]
nullok=mask
inparams=kernel
exclude=True
[imaqDivideConstant]
# TODO because of PixelValue
exclude=True
[imaqLookup]
nullok=mask
exclude=True
[imaqMatchPattern2]
retarraysize=numMatches
nullok=options
[imaqMaxConstant]
# TODO because of PixelValue
exclude=True
[imaqParticleFilter2]
arraysize=criteria:criteriaCount
[imaqEdgeTool2]
retarraysize=numEdges
[imaqReadDataMatrixBarcode]
retarraysize=numBarcodes
[imaqMatchGeometricPattern]
retarraysize=numMatches
[imaqColorHistogram]
nullok=mask
; block comment exclusion list
[Block Comment]
exclude=
Includes
Control Defines
Macros
This accomplishes said task.
If using Visual C++, force startup & shutdown code to run.
Error Management functions
Callback Function Type
Backwards Compatibility
Error Codes

View File

@@ -0,0 +1,226 @@
from __future__ import print_function
import re
import traceback
__all__ = ["define_after_struct", "defined", "forward_structs", "opaque_structs", "enums", "structs", "prescan_file", "parse_file", "number_re", "constant_re"]
# parser regular expressions
number_re = re.compile(r'-?[0-9]+')
constant_re = re.compile(r'[A-Z0-9_]+')
define_re = re.compile(r'^#define\s+(?P<name>(IMAQ|ERR)[A-Z0-9_]+)\s+(?P<value>.*)')
enum_re = re.compile(r'^typedef\s+enum\s+(?P<name>[A-Za-z0-9]+)_enum\s*{')
enum_value_re = re.compile(r'^\s*(?P<name>[A-Za-z0-9_]+)\s*(=\s*(?P<value>-?[0-9A-Fx]+))?\s*,?')
struct_re = re.compile(r'^typedef\s+struct\s+(?P<name>[A-Za-z0-9]+)_struct\s*{')
union_re = re.compile(r'^typedef\s+union\s+(?P<name>[A-Za-z0-9]+)_union\s*{')
func_pointer_re = re.compile(r'\s*(?P<restype>[A-Za-z0-9_*]+)\s*\(\s*[A-Za-z0-9_]*\s*[*]\s*(?P<name>[A-Za-z0-9_]+)\s*\)\s*\((?P<params>[^)]*)\)')
static_const_re = re.compile(r'^static\s+const\s+(?P<type>[A-Za-z0-9_]+)\s+(?P<name>[A-Za-z0-9_]+)\s*=\s*(?P<value>[^;]+);')
function_re = re.compile(r'^((IMAQ|NI)_FUNC\s+)?(?P<restype>(const\s+)?[A-Za-z0-9_*]+)\s+((IMAQ_STDCALL|NI_FUNC[C]?)\s+)?(?P<name>[A-Za-z0-9_]+)\s*\((?P<params>[^)]*)\);')
# defines deferred until after structures
define_after_struct = []
defined = set()
forward_structs = set()
opaque_structs = set()
enums = set()
structs = set()
def parse_cdecl(decl):
decl = " ".join(decl.split())
ctype, sep, name = decl.rpartition(' ')
# look for array[]
name, bracket, arr = name.partition('[')
if arr:
arr = arr[:-1]
else:
arr = None
return name, ctype, arr
def split_comment(line):
if line.startswith('/*'):
return "", ""
parts = line.split('//', 1)
code = parts[0].strip()
comment = parts[1].strip() if len(parts) > 1 else None
return code, comment
def prescan_file(f):
for line in f:
code, comment = split_comment(line)
if not code and not comment:
continue
# typedef struct {
m = struct_re.match(code)
if m is not None:
structs.add(m.group('name'))
continue
# other typedef
if code.startswith("typedef"):
if '(' in code:
continue
name, typedef, arr = parse_cdecl(code[8:-1])
if typedef.startswith("struct"):
forward_structs.add(name)
continue
opaque_structs.update(forward_structs - structs)
def parse_file(emit, f, block_comment_exclude):
in_block_comment = False
cur_block = ""
in_enum = None
in_struct = None
in_union = None
for lineno, line in enumerate(f):
code, comment = split_comment(line)
if not code and not comment:
continue
#print(comment)
# in block comment
if in_block_comment:
if not code and comment is not None and comment[0] == '=':
# closing block comment; emit if not excluded
if cur_block not in block_comment_exclude:
try:
emit.block_comment(cur_block)
except Exception as e:
print("%d: exception in block_comment():\n%s" % (lineno+1, traceback.format_exc()))
in_block_comment = False
# emit "after struct" constants in Globals
if cur_block == "Globals":
for dname, dtext in define_after_struct:
try:
emit.text(dtext)
except Exception as e:
print("%d: exception in text():\n%s" % (lineno+1, traceback.format_exc()))
defined.add(dname)
continue
if not code and comment is not None:
# remember current block
cur_block = comment
continue
# inside enum
if in_enum is not None:
if code[0] == '}':
# closing
try:
emit.enum(*in_enum)
except Exception as e:
print("%d: exception in enum():\n%s" % (lineno+1, traceback.format_exc()))
in_enum = None
continue
m = enum_value_re.match(code)
if m is not None:
in_enum[1].append((m.group('name'), m.group('value'), comment))
continue
# inside struct/union
if in_struct is not None or in_union is not None:
if code[0] == '}':
# closing
if in_struct is not None:
try:
emit.struct(*in_struct)
except Exception as e:
print("%d: exception in struct(\"%s\"):\n%s" % (lineno+1, in_struct[0], traceback.format_exc()))
in_struct = None
if in_union is not None:
try:
emit.union(*in_union)
except Exception as e:
print("%d: exception in union(\"%s\"):\n%s" % (lineno+1, in_union[0], traceback.format_exc()))
in_union = None
continue
name, ctype, arr = parse_cdecl(code[:-1])
# add to fields
if in_struct is not None:
in_struct[1].append((name, ctype, arr, comment))
if in_union is not None:
in_union[1].append((name, ctype, arr, comment))
continue
# block comment
if not code and comment is not None and comment[0] == '=':
in_block_comment = True
# #define
m = define_re.match(code)
if m is not None:
try:
emit.define(m.group('name'), m.group('value').strip(), comment)
except Exception as e:
print("%d: exception in define():\n%s" % (lineno+1, traceback.format_exc()))
continue
# typedef enum {
m = enum_re.match(code)
if m is not None:
in_enum = (m.group('name'), [])
continue
# typedef struct {
m = struct_re.match(code)
if m is not None:
in_struct = (m.group('name'), [])
continue
# typedef union {
m = union_re.match(code)
if m is not None:
in_union = (m.group('name'), [])
continue
# other typedef
if code.startswith("typedef"):
# typedef function?
m = func_pointer_re.match(code[8:-1])
if m is not None:
params = [parse_cdecl(param.strip()) for param in m.group('params').strip().split(',') if param.strip()]
try:
emit.typedef_function(m.group('name'), m.group('restype'), params)
except Exception as e:
print("%d: exception in typedef_function():\n%s" % (lineno+1, traceback.format_exc()))
continue
if '(' in code:
print("Invalid typedef: %s" % code)
continue
emit.typedef(*parse_cdecl(code[8:-1]))
continue
# function
m = function_re.match(code)
if m is not None:
params = [parse_cdecl(param.strip()) for param in m.group('params').strip().split(',') if param.strip()]
try:
emit.function(m.group('name'), m.group('restype'), params)
except Exception as e:
print("%d: exception in function(\"%s\"):\n%s" % (lineno+1, m.group('name'), traceback.format_exc()))
continue
# static const
m = static_const_re.match(code)
if m is not None:
value = m.group('value')
if value[0] == '{':
value = [v.strip() for v in value[1:-1].strip().split(',') if v.strip()]
try:
emit.static_const(m.group('name'), m.group('type'), value)
except Exception as e:
print("%d: exception in static_const():\n%s" % (lineno+1, traceback.format_exc()))
continue
if not code or code[0] == '#':
continue
if not code or code[0] == '#':
continue
if code == 'extern "C" {' or code == "}":
continue
print("%d: Unrecognized: %s" % (lineno+1, code))

View File

@@ -7,3 +7,4 @@ bindings are checked into git, so that it should work until someone goes and upd
In order for this to work, I had to change the CanTalonSRX constructor to take a int deviceNumber instead of a uint8_t.
Also, in all the SWIGTYPE* files, you must change protected methods to public functions.
Because the SWIGTYPE* files don't generally change, you can jsut do a git checkout -- SWIGTYPE* in wpilibJavaDevices/....../wpilibj/