Compare commits

...

111 Commits

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Change-Id: Iae2f74693ca6b80bf7d5aca0625c66aa6e0b7f85

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

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

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

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

@@ -92,6 +92,13 @@
<outputDirectory>${tools-zip}</outputDirectory>
<destFileName>OutlineViewer.jar</destFileName>
</artifactItem>
<artifactItem>
<groupId>edu.wpi.first.wpilib</groupId>
<artifactId>java-installer</artifactId>
<version>1.0-SNAPSHOT</version>
<outputDirectory>${tools-zip}</outputDirectory>
<destFileName>java-installer.jar</destFileName>
</artifactItem>
</artifactItems>
<overWriteReleases>false</overWriteReleases>

View File

@@ -0,0 +1,77 @@
package edu.wpi.first.wpilib.plugins.core.actions;
import java.io.File;
import java.io.FilenameFilter;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
/**
* Our sample action implements workbench action delegate.
* The action proxy will be created by the workbench and
* shown in the UI. When the user tries to use the action,
* this delegate will be created and execution will be
* delegated to it.
* @see IWorkbenchWindowActionDelegate
*/
public class RunSimulationSmartDashboardAction implements IWorkbenchWindowActionDelegate {
/**
* The constructor.
*/
public RunSimulationSmartDashboardAction() {
}
/**
* The action has been activated. The argument of the
* method represents the 'real' action sitting
* in the workbench UI.
* @see IWorkbenchWindowActionDelegate#run
*/
public void run(IAction action) {
File dir = new File(WPILibCore.getDefault().getWPILibBaseDir()+File.separator+"tools");
File[] files = dir.listFiles(new FilenameFilter() {
@Override public boolean accept(File dir, String name) {
return name.startsWith("SmartDashboard") && name.endsWith(".jar");
}
});
if (files == null || files.length < 1) return;
String[] cmd = {"java", "-jar", files[0].getAbsolutePath(), "-ip", "localhost"};
try {
DebugPlugin.exec(cmd, new File(System.getProperty("user.home")));
} catch (CoreException e) {
WPILibCore.logError("Error running SmartDashboard.", e);
}
}
/**
* Selection in the workbench has been changed. We
* can change the state of the 'real' action here
* if we want, but this can only happen after
* the delegate has been created.
* @see IWorkbenchWindowActionDelegate#selectionChanged
*/
public void selectionChanged(IAction action, ISelection selection) {
}
/**
* We can use this method to dispose of any system
* resources we previously allocated.
* @see IWorkbenchWindowActionDelegate#dispose
*/
public void dispose() {
}
/**
* We will cache window object in order to
* be able to provide parent shell for the message dialog.
* @see IWorkbenchWindowActionDelegate#init
*/
public void init(IWorkbenchWindow window) {
}
}

View File

@@ -8,8 +8,6 @@ import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.swing.JOptionPane;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -17,6 +15,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.dialogs.MessageDialog;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
@@ -117,7 +116,7 @@ public abstract class AbstractInstaller {
protected void install() throws InstallException {
if(installLocation.exists()) {
if(!removeFileHandler(installLocation, true)) {
JOptionPane.showMessageDialog(null,
MessageDialog.openError(null, "Error",
String.format("Could not update the old wpilib folder.%n"
+ "Please close any WPILib tools and restart Eclipse."));
}

View File

@@ -6,10 +6,9 @@ import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JOptionPane;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jface.dialogs.MessageDialog;
import edu.wpi.first.wpilib.plugins.core.WPILibCore;
@@ -21,8 +20,8 @@ public class SimulationNotification {
public static void showUnsupported() {
String title = "Simulation Unsupported";
String message = SIMULATION_UNSUPPORTED_MSG;
JOptionPane.showMessageDialog(null, message, title, JOptionPane.OK_OPTION);
String message = SIMULATION_UNSUPPORTED_MSG;
MessageDialog.openError(null, title, message);
try {
Desktop.getDesktop().browse(new URI(URL));
} catch (IOException e) {

View File

@@ -5,6 +5,7 @@ import java.util.Arrays;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
@@ -48,4 +49,8 @@ public class ProjectComboField {
combo.addModifyListener(modifyListener);
}
public void addSelectionListener(SelectionListener selectionListener) {
combo.addSelectionListener(selectionListener);
}
}

View File

@@ -82,7 +82,7 @@
<listOptionValue builtIn="false" value="${WPILIB}/cpp/current/sim/include"/>
<listOptionValue builtIn="false" value="/usr/include"/>
<listOptionValue builtIn="false" value="/usr/include/gazebo-3.1"/>
<listOptionValue builtIn="false" value="/usr/include/sdformat-2.0"/>
<listOptionValue builtIn="false" value="/usr/include/sdformat-2.2"/>
</option>
<option id="gnu.cpp.compiler.option.optimization.level.1648211502" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.debugging.level.937474733" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>

View File

@@ -23,7 +23,8 @@ private:
void AutonomousInit()
{
autonomousCommand->Start();
if (autonomousCommand != NULL)
autonomousCommand->Start();
}
void AutonomousPeriodic()
@@ -37,7 +38,8 @@ private:
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// this line or comment it out.
autonomousCommand->Cancel();
if (autonomousCommand != NULL)
autonomousCommand->Cancel();
}
void TeleopPeriodic()

View File

@@ -0,0 +1,38 @@
#include "WPILib.h"
/**
* This sample shows how to use the new CANTalon to just run a motor in a basic
* throttle mode, in the same manner as you might control a traditional PWM
* controlled motor.
*
*/
class Robot : public SampleRobot {
CANTalon m_motor;
Joystick m_stick;
// update every 0.01 seconds/10 milliseconds.
// The talon only receives control packets every 10ms.
double kUpdatePeriod = 0.010;
public:
Robot()
: m_motor(1), // Initialize the Talon as device 1. Use the roboRIO web
// interface to change the device number on the talons.
m_stick(0)
{}
/**
* Runs the motor from the output of a Joystick.
*/
void OperatorControl() {
while (IsOperatorControl() && IsEnabled()) {
// Takes a number from -1.0 (full reverse) to +1.0 (full forwards).
m_motor.Set(m_stick.GetY());
Wait(kUpdatePeriod); // Wait a bit so that the loop doesn't lock everything up.
}
}
};
START_ROBOT_CLASS(Robot);

View File

@@ -0,0 +1,63 @@
#include "WPILib.h"
/**
* This is a quick sample program to show how to use the new Talon SRX over CAN.
* This particular sample demonstrates running a basic PID control loop with an
* analog potentiometer.
*
*/
class Robot : public SampleRobot {
CANTalon m_motor;
public:
Robot()
: m_motor(1) // Initialize the Talon as device 1. Use the roboRIO web
// interface to change the device number on the m_motors.
{
// This sets the mode of the m_motor. The options are:
// kPercentVbus: basic throttle; no closed-loop.
// kCurrent: Runs the motor with the specified current if possible.
// kSpeed: Runs a PID control loop to keep the motor going at a constant
// speed using the specified sensor.
// kPosition: Runs a PID control loop to move the motor to a specified move
// the motor to a specified sensor position.
// kVoltage: Runs the m_motor at a constant voltage, if possible.
// kFollower: The m_motor will run at the same throttle as the specified other talon.
m_motor.SetControlMode(CANSpeedController::kPosition);
// This command allows you to specify which feedback device to use when doing
// closed-loop control. The options are:
// AnalogPot: Basic analog potentiometer
// QuadEncoder: Quadrature Encoder
// AnalogEncoder: Analog Encoder
// EncRising: Counts the rising edges of the QuadA pin (allows use of a
// non-quadrature encoder)
// EncFalling: Same as EncRising, but counts on falling edges.
m_motor.SetFeedbackDevice(CANTalon::AnalogPot);
// This sets the basic P, I , and D values (F, Izone, and rampRate can also
// be set, but are ignored here).
// These must all be positive floating point numbers (SetSensorDirection will
// multiply the sensor values by negative one in case your sensor is flipped
// relative to your motor).
// These values are in units of throttle / sensor_units where throttle ranges
// from -1023 to +1023 and sensor units are from 0 - 1023 for analog
// potentiometers, encoder ticks for encoders, and position / 10ms for
// speeds.
m_motor.SetPID(1.0, 0.0, 0.0);
}
/**
* Runs the motor from the output of a Joystick.
*/
void OperatorControl() {
while (IsOperatorControl() && IsEnabled()) {
// In closed loop mode, this sets the goal in the units mentioned above.
// Since we are using an analog potentiometer, this will try to go to
// the middle of the potentiometer range.
m_motor.Set(512);
Wait(5.0);
}
}
};
START_ROBOT_CLASS(Robot);

View File

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

@@ -128,6 +128,40 @@
</files>
</example>
<example>
<name>CAN Talon SRX</name>
<description>Quick demo of running the SRX at a given throttle value.</description>
<tags>
<tag>Robot and Motor</tag>
<tag>Digital</tag>
<tag>Actuators</tag>
<tag>Complete List</tag>
</tags>
<packages>
<package>src</package>
</packages>
<files>
<file source="examples/CANTalon/src/Robot.cpp" destination="src/Robot.cpp"></file>
</files>
</example>
<example>
<name>CAN Talon SRX PID</name>
<description>Quick demo of running the SRX with a PID loop.</description>
<tags>
<tag>Robot and Motor</tag>
<tag>Digital</tag>
<tag>Actuators</tag>
<tag>Complete List</tag>
</tags>
<packages>
<package>src</package>
</packages>
<files>
<file source="examples/CANTalonPID/src/Robot.cpp" destination="src/Robot.cpp"></file>
</files>
</example>
<example>
<name>Relay</name>
<description>Demonstrate controlling a Relay from Joystick buttons.</description>
@@ -264,7 +298,7 @@
</example>
<example>
<name>Getting Started</name>
<name>Intermediate vision</name>
<description>An example program that acquires images from an attached USB camera and adds some
annotation to the image as you might do for showing operators the result of some image
recognition, and sends it to the dashboard for display.

View File

@@ -43,8 +43,8 @@ public class RSEUtils {
RSECorePlugin.getTheCoreRegistry().getSystemTypeById("org.eclipse.rse.systemtype.ssh");
host = registry.createHost(profile.getName(), systemType, connectionName, hostName,
"The remote target for debugging the robot for team "+teamNumber+".");
host.setDefaultUserId("admin");
SystemSignonInformation info = new SystemSignonInformation(hostName, "admin",
host.setDefaultUserId("lvuser");
SystemSignonInformation info = new SystemSignonInformation(hostName, "lvuser",
"", systemType);
PasswordPersistenceManager.getInstance().add(info, true, false);
} catch (Exception e) {

View File

@@ -1,5 +1,5 @@
# Deployment information
username=admin
username=lvuser
password=
deploy.dir=/home/lvuser
deploy.kill.command=/usr/local/frc/bin/frcKillRobot.sh -t -r
@@ -8,7 +8,7 @@ command.dir=/home/lvuser/
# Libraries to use
wpilib=${user.home}/wpilib/cpp/${cpp-version}
wpilib.lib=${wpilib}/lib
roboRIOAllowedImages=18
roboRIOAllowedImages=22
# Ant support
wpilib.ant.dir=${wpilib}/ant

View File

@@ -19,21 +19,37 @@
<!-- Targets -->
<target name="get-target-ip">
<property name="ant.enable.asserts" value="true"/>
<property name="target" value="roboRIO-${team-number}.local" />
<echo>Trying Target: ${target}</echo>
<if>
<isreachable host="${target}"/>
<isreachable host="${target}" timeout="5"/>
<then>
<echo>roboRIO found via mDNS</echo>
</then>
<else>
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
<property name="target" value="10.${ip-upper}.${ip.lower}.2"/>
<echo>roboRIO not found via mDNS, falling back to static address of ${target}</echo>
<assert name="roboRIOFound" message="roboRIO not found, please check that the roboRIO is connected, imaged and that the team number is set properly in Eclipse">
<isreachable host="${target}"/>
</assert>
<var name="target" unset="true"/>
<echo> roboRIO not found via mDNS, falling back to static USB</echo>
<property name="target" value="172.22.11.2"/>
<if>
<isreachable host="${target}" timeout="5"/>
<then>
<echo>roboRIO found via static USB</echo>
</then>
<else>
<var name="target" unset="true"/>
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
<property name="target" value="10.${ip.upper}.${ip.lower}.2"/>
<echo>roboRIO not found via USB, falling back to static address of ${target}</echo>
<assert name="roboRIOFound" message="roboRIO not found, please check that the roboRIO is connected, imaged and that the team number is set properly in Eclipse">
<bool>
<isreachable host="${target}" timeout="5"/>
</bool>
</assert>
<echo>roboRIO found via Ethernet static</echo>
</else>
</if>
</else>
</if>
</target>
@@ -93,7 +109,7 @@
<target name="dependencies" depends="get-target-ip">
<property name="ant.enable.asserts" value="true"/>
<post to="http://${target}/nisysapi/server" logfile="sysProps.xml" verbose="false" encoding="UTF-16LE">
<post to="http://${target}/nisysapi/server" logfile="sysProps.xml" verbose="false" encoding="UTF-16LE" append="false">
<prop name="Function" value="GetPropertiesOfItem"/>
<prop name="Plugins" value="nisyscfg"/>
<prop name="Items" value="system"/>
@@ -105,5 +121,6 @@
<contains string="${roboRIOAllowedImages}" substring="${roboRIOImage}"/>
</bool>
</assert>
<echo>roboRIO image version validated</echo>
</target>
</project>

View File

@@ -38,7 +38,7 @@ public class Robot extends IterativeRobot {
public void autonomousInit() {
// schedule the autonomous command (example)
autonomousCommand.start();
if (autonomousCommand != null) autonomousCommand.start();
}
/**
@@ -53,7 +53,15 @@ public class Robot extends IterativeRobot {
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// this line or comment it out.
autonomousCommand.cancel();
if (autonomousCommand != null) autonomousCommand.cancel();
}
/**
* This function is called when the disabled button is hit.
* You can use it to reset subsystems before shutting down.
*/
public void disabledInit(){
}
/**

View File

@@ -0,0 +1,37 @@
package $package;
import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.CANTalon;
import edu.wpi.first.wpilibj.SampleRobot;
import edu.wpi.first.wpilibj.Timer;
/**
* This is a short sample program demonstrating how to use the basic throttle
* mode of the new CAN Talon.
*/
public class Robot extends SampleRobot {
CANTalon motor;
public Robot() {
motor = new CANTalon(1); // Initialize the CanTalonSRX on device 1.
}
/**
* Runs the motor.
*/
public void operatorControl() {
while (isOperatorControl() && isEnabled()) {
// Set the motor's output to half power.
// This takes a number from -1 (100% speed in reverse) to +1 (100% speed
// going forward)
motor.set(0.5);
Timer.delay(0.01); // Note that the CANTalon only receives updates every
// 10ms, so updating more quickly would not gain you
// anything.
}
motor.disable();
}
}

View File

@@ -0,0 +1,62 @@
package $package;
import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.CANTalon;
import edu.wpi.first.wpilibj.SampleRobot;
import edu.wpi.first.wpilibj.Timer;
/**
* This is a short sample program demonstrating how to use the Talon SRX over
* CAN to run a closed-loop PID controller with an analog potentiometer.
*/
public class Robot extends SampleRobot {
CANTalon motor;
public Robot() {
motor = new CANTalon(1); // Initialize the CanTalonSRX on device 1.
// This sets the mode of the m_motor. The options are:
// PercentVbus: basic throttle; no closed-loop.
// Current: Runs the motor with the specified current if possible.
// Speed: Runs a PID control loop to keep the motor going at a constant
// speed using the specified sensor.
// Position: Runs a PID control loop to move the motor to a specified move
// the motor to a specified sensor position.
// Voltage: Runs the m_motor at a constant voltage, if possible.
// Follower: The m_motor will run at the same throttle as the specified
// other talon.
motor.changeControlMode(CANTalon.ControlMode.Position);
// This command allows you to specify which feedback device to use when doing
// closed-loop control. The options are:
// AnalogPot: Basic analog potentiometer
// QuadEncoder: Quadrature Encoder
// AnalogEncoder: Analog Encoder
// EncRising: Counts the rising edges of the QuadA pin (allows use of a
// non-quadrature encoder)
// EncFalling: Same as EncRising, but counts on falling edges.
motor.setFeedbackDevice(CANTalon.FeedbackDevice.AnalogPot);
// This sets the basic P, I , and D values (F, Izone, and rampRate can also
// be set, but are ignored here).
// These must all be positive floating point numbers (reverseSensor will
// multiply the sensor values by negative one in case your sensor is flipped
// relative to your motor).
// These values are in units of throttle / sensor_units where throttle ranges
// from -1023 to +1023 and sensor units are from 0 - 1023 for analog
// potentiometers, encoder ticks for encoders, and position / 10ms for
// speeds.
motor.setPID(1.0, 0.0, 0.0);
}
public void operatorControl() {
while (isOperatorControl() && isEnabled()) {
// In closed loop mode, this sets the goal in the units mentioned above.
// Since we are using an analog potentiometer, this will try to go to
// the middle of the potentiometer range.
motor.set(512);
Timer.delay(5.0);
}
}
}

View File

@@ -154,6 +154,40 @@
</files>
</example>
<example>
<name>CAN Talon SRX</name>
<description>Demonstrate running a Talon SRX with the basic throttle mode.</description>
<tags>
<tag>Actuators</tag>
<tag>Complete List</tag>
<tag>Robot and Motor</tag>
</tags>
<packages>
<package>src/$package-dir</package>
</packages>
<files>
<file source="examples/CANTalon/src/org/usfirst/frc/team190/robot/Robot.java"
destination="src/$package-dir/Robot.java"></file>
</files>
</example>
<example>
<name>CAN Talon SRX PID</name>
<description>Demonstrate running a Talon SRX with PID Closed Loop control.</description>
<tags>
<tag>Actuators</tag>
<tag>Complete List</tag>
<tag>Robot and Motor</tag>
</tags>
<packages>
<package>src/$package-dir</package>
</packages>
<files>
<file source="examples/CANTalonPID/src/org/usfirst/frc/team190/robot/Robot.java"
destination="src/$package-dir/Robot.java"></file>
</files>
</example>
<tagDescription>
<name>CommandBased Robot</name>

View File

@@ -2,6 +2,7 @@ package edu.wpi.first.wpilib.plugins.java.launching;
import java.io.File;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
@@ -15,8 +16,6 @@ import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.jdt.core.IJavaElement;
@@ -37,13 +36,13 @@ import edu.wpi.first.wpilib.plugins.java.WPILibJavaPlugin;
@SuppressWarnings("restriction")
public abstract class JavaLaunchShortcut implements ILaunchShortcut {
private static final int DEBUG_ATTACH_ATTEMPTS = 20;
private static final int DEBUG_ATTACH_RETRY_DELAY_SEC = 2;
//Class constants - used to delineate types for launch shortcuts
public static final String DEPLOY_TYPE = "edu.wpi.first.wpilib.plugins.core.deploy";
private static final String ANT_SERVER_THREAD_NAME = "Ant Build Server Connection";
// NOTE: This string must be changed if the port is changed.
private static final String DEBUG_START_TEXT = "Listening for transport dt_socket at address: 8348";
private static ILaunch lastDeploy = null;
/**
@@ -155,11 +154,9 @@ public abstract class JavaLaunchShortcut implements ILaunchShortcut {
lastDeploy = AntLauncher.runAntFile(new File (activeProj.getLocation().toOSString() + File.separator + "build.xml"), targets, null, mode);
if((mode.equals(ILaunchManager.DEBUG_MODE))&&(getLaunchType().equals(DEPLOY_TYPE))) {
ILaunchConfigurationWorkingCopy config;
try {
config = getRemoteDebugConfig(activeProj);
startDebugConfig(config, lastDeploy);
} catch (CoreException e) {
startDebugConfig(getRemoteDebugConfig(activeProj));
} catch (CoreException | InterruptedException e) {
WPILibJavaPlugin.logError("Debug attach failed", e);
}
}
@@ -190,20 +187,28 @@ public abstract class JavaLaunchShortcut implements ILaunchShortcut {
return WPILibCore.getDefault().getTargetIP(proj);
}
private void startDebugConfig(final ILaunchConfigurationWorkingCopy config, ILaunch deploy) throws CoreException {
IStreamListener listener = new IStreamListener() {
@Override
public void streamAppended(String text, IStreamMonitor monitor) {
if (text.contains(DEBUG_START_TEXT)) {
try {
config.launch(ILaunchManager.DEBUG_MODE, null);
} catch (CoreException e) {
WPILibJavaPlugin.logError("Error starting debug config..", e);
}
monitor.removeListener(this);
private void startDebugConfig(final ILaunchConfigurationWorkingCopy config)
throws CoreException, InterruptedException {
int remainingAttempts = DEBUG_ATTACH_ATTEMPTS;
// Retry until success or rethrow of exception on failure
while (true) {
try {
WPILibJavaPlugin.logInfo("Attemping to attach debugger...");
config.launch(ILaunchManager.DEBUG_MODE, null);
WPILibJavaPlugin.logInfo("Debugger attached.");
break;
} catch (CoreException e) {
if (--remainingAttempts > 0) {
String errorMsg = MessageFormat.format("Unable to attach debugger. "
+ "{0} attempts remain - waiting {1} second(s) before retrying...",
remainingAttempts, DEBUG_ATTACH_RETRY_DELAY_SEC);
WPILibJavaPlugin.logError(errorMsg, null);
Thread.sleep(DEBUG_ATTACH_RETRY_DELAY_SEC * 1000);
} else {
throw e;
}
}
};
deploy.getProcesses()[0].getStreamsProxy().getOutputStreamMonitor().addListener(listener);
}
}
}

View File

@@ -11,7 +11,9 @@ import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
@@ -76,6 +78,15 @@ public class FileTemplateWizardMainPage extends WizardPage {
});
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
projectsCombo.setLayoutData(gd);
projectsCombo.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e){
if (project == null){
project = projectsCombo.getProject();
}
packageText.setText(getDefaultPackage());
}
public void widgetDefaultSelected(SelectionEvent e){}
});
projectsCombo.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
dialogChanged();
@@ -116,6 +127,7 @@ public class FileTemplateWizardMainPage extends WizardPage {
*/
private void initialize() {
WPILibJavaPlugin.logInfo("initialize");
projectsCombo.setProject(project);
packageText.setText(getDefaultPackage());
}
@@ -130,7 +142,7 @@ public class FileTemplateWizardMainPage extends WizardPage {
// Update the default package if necessary
if (project == null || !project.equals(projectsCombo.getProject())) {
String oldDefault = getDefaultPackage();
String oldDefault = getDefaultPackage();
project = projectsCombo.getProject();
if (packageString.equals(oldDefault)) {
packageText.setText(getDefaultPackage());
@@ -200,4 +212,4 @@ public class FileTemplateWizardMainPage extends WizardPage {
if (defaultPackage != null) return defaultPackage;
else return "";
}
}
}

View File

@@ -1,5 +1,5 @@
# Deployment information
username=admin
username=lvuser
password=
deploy.dir=/home/lvuser
deploy.kill.command=. /etc/profile.d/natinst-path.sh; /usr/local/frc/bin/frcKillRobot.sh -t -r
@@ -20,7 +20,7 @@ networktables.sources=${wpilib.lib}/NetworkTables-sources.jar
#jnaerator.jar=${wpilib.lib}/jnaerator-runtime.jar
#classpath=${wpilib.jar}:${networktables.jar}:${jna.jar}:${jnaerator.jar}
classpath=${wpilib.jar}:${networktables.jar}
roboRIOAllowedImages=18
roboRIOAllowedImages=22
# Ant support
wpilib.ant.dir=${wpilib}/ant

View File

@@ -19,21 +19,37 @@
<!-- Targets -->
<target name="get-target-ip">
<property name="ant.enable.asserts" value="true"/>
<property name="target" value="roboRIO-${team-number}.local" />
<echo>Trying Target: ${target}</echo>
<if>
<isreachable host="${target}"/>
<isreachable host="${target}" timeout="5"/>
<then>
<echo>roboRIO found via mDNS</echo>
</then>
<else>
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
<property name="target" value="10.${ip-upper}.${ip.lower}.2"/>
<echo>roboRIO not found via mDNS, falling back to static address of ${target}</echo>
<assert name="roboRIOFound" message="roboRIO not found, please check that the roboRIO is connected, imaged and that the team number is set properly in Eclipse">
<isreachable host="${target}"/>
</assert>
<var name="target" unset="true"/>
<echo> roboRIO not found via mDNS, falling back to static USB</echo>
<property name="target" value="172.22.11.2"/>
<if>
<isreachable host="${target}" timeout="5"/>
<then>
<echo>roboRIO found via static USB</echo>
</then>
<else>
<var name="target" unset="true"/>
<math result="ip.upper" operand1="${team-number}" operation="/" operand2="100" datatype="int"/>
<math result="ip.lower" operand1="${team-number}" operation="%" operand2="100" datatype="int"/>
<property name="target" value="10.${ip.upper}.${ip.lower}.2"/>
<echo>roboRIO not found via USB, falling back to static address of ${target}</echo>
<assert name="roboRIOFound" message="roboRIO not found, please check that the roboRIO is connected, imaged and that the team number is set properly in Eclipse">
<bool>
<isreachable host="${target}" timeout="5"/>
</bool>
</assert>
<echo>roboRIO found via Ethernet static</echo>
</else>
</if>
</else>
</if>
</target>
@@ -192,7 +208,7 @@
<target name="dependencies" depends="get-target-ip">
<property name="ant.enable.asserts" value="true"/>
<post to="http://${target}/nisysapi/server" logfile="sysProps.xml" verbose="false" encoding="UTF-16LE">
<post to="http://${target}/nisysapi/server" logfile="sysProps.xml" verbose="false" encoding="UTF-16LE" append="false">
<prop name="Function" value="GetPropertiesOfItem"/>
<prop name="Plugins" value="nisyscfg"/>
<prop name="Items" value="system"/>
@@ -204,6 +220,7 @@
<contains string="${roboRIOAllowedImages}" substring="${roboRIOImage}"/>
</bool>
</assert>
<echo>roboRIO image version validated</echo>
<echo>Checking for JRE. If this fails install the JRE using these instructions: http://wpilib.screenstepslive.com/s/4485/m/13809/l/243933-installing-java-8-on-the-roborio-java-only</echo>
<sshexec host="${target}"
username="${username}"

View File

@@ -1,2 +1,2 @@
/usr/local/frc/JRE/bin/java -jar /home/lvuser/FRCUserProgram.jar
/usr/local/frc/bin/netconsole-host /usr/local/frc/JRE/bin/java -jar /home/lvuser/FRCUserProgram.jar

View File

@@ -1,2 +1,2 @@
/usr/local/frc/JRE/bin/java -XX:+UsePerfData -agentlib:jdwp=transport=dt_socket,address=8348,server=y,suspend=y -jar /home/lvuser/FRCUserProgram.jar
/usr/local/frc/bin/netconsole-host /usr/local/frc/JRE/bin/java -XX:+UsePerfData -agentlib:jdwp=transport=dt_socket,address=8348,server=y,suspend=y -jar /home/lvuser/FRCUserProgram.jar

View File

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

View File

@@ -14,7 +14,6 @@
#include "Accelerometer.hpp"
#include "Analog.hpp"
#include "CAN.hpp"
#include "Compressor.hpp"
#include "Digital.hpp"
#include "Solenoid.hpp"
@@ -178,7 +177,20 @@ struct HALJoystickPOVs {
int16_t povs[kMaxJoystickPOVs];
};
typedef uint32_t HALJoystickButtons;
struct HALJoystickButtons {
uint32_t buttons;
uint8_t count;
};
struct HALJoystickDescriptor {
uint8_t isXbox;
uint8_t type;
char name[256];
uint8_t axisCount;
uint8_t axisTypes;
uint8_t buttonCount;
uint8_t povCount;
};
inline float intToFloat(int value)
{
@@ -213,9 +225,12 @@ extern "C"
int HALGetAllianceStation(enum HALAllianceStationID *allianceStation);
int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes *axes);
int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs);
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons, uint8_t *count);
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons);
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc);
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble);
int HALGetMatchTime(float *matchTime);
void HALSetNewDataSem(pthread_cond_t *);
void HALSetNewDataSem(MULTIWAIT_ID sem);
bool HALGetSystemActive(int32_t *status);
bool HALGetBrownedOut(int32_t *status);

View File

@@ -11,4 +11,9 @@ extern "C"
double getPDPTemperature(int32_t *status);
double getPDPVoltage(int32_t *status);
double getPDPChannelCurrent(uint8_t channel, int32_t *status);
double getPDPTotalCurrent(int32_t *status);
double getPDPTotalPower(int32_t *status);
double getPDPTotalEnergy(int32_t *status);
void resetPDPTotalEnergy(int32_t *status);
void clearPDPStickyFaults(int32_t *status);
}

View File

@@ -1,232 +0,0 @@
#include "HAL/CAN.hpp"
#include <map>
struct CANMessage
{
uint8_t data[8];
};
static std::map<uint32_t, CANMessage> outgoingMessages;
static std::map<uint32_t, CANMessage> incomingMessages;
static const uint32_t kFullMessageIDMask = 0x1fffffff;
/**
* Gets the data from the outgoing hashmap and calls
* CANSessionMux...sendMessage.
*/
void canTxSend(uint32_t arbID, uint8_t length, int32_t period)
{
CANMessage &message = outgoingMessages[arbID];
int32_t status;
FRC_NetworkCommunication_CANSessionMux_sendMessage(
arbID, message.data, length, period, &status);
}
/**
* Updates a field in the outgoing hashmap.
*
* This is called every time an single byte field changes in a message.data,
* such as when a setter on a CAN device is called.
*/
void canTxPackInt8(uint32_t arbID, uint8_t offset, uint8_t value)
{
CANMessage &message = outgoingMessages[arbID];
message.data[offset] = value;
}
/**
* Updates a field in the outgoing hashmap.
*
* This is called every time a short integer field changes in a message.data,
* such as when a setter on a CAN device is called.
*/
void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value)
{
CANMessage &message = outgoingMessages[arbID];
*(uint16_t *)(message.data + offset) = value;
}
/**
* Updates a field in the outgoing hashmap.
*
* This is called every time a long integer field changes in a message.data,
* such as when a setter on a CAN device is called.
*/
void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value)
{
CANMessage &message = outgoingMessages[arbID];
*(uint32_t *)(message.data + offset) = value;
}
/**
* Updates a field in the outgoing hashmap.
*
* This is called every time an 8.8 fixed point field changes in a message,
* such as when a setter on a CAN device is called.
*/
void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value)
{
int16_t raw = value * 255.0;
canTxPackInt16(arbID, offset, raw);
}
/**
* Updates a field in the outgoing hashmap.
*
* This is called every time a 16.16 fixed point field changes in a message,
* such as when a setter on a CAN device is called.
*/
void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value)
{
int32_t raw = value * 65535.0;
canTxPackInt32(arbID, offset, raw);
}
/**
* Unpack a field from the outgoing hashmap.
*
* This is called in getters for configuration data.
*/
uint8_t canTxUnpackInt8(uint32_t arbID, uint8_t offset)
{
CANMessage &message = outgoingMessages[arbID];
return message.data[offset];
}
/**
* Unpack a field from the outgoing hashmap.
*
* This is called in getters for configuration data.
*/
uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset)
{
CANMessage &message = outgoingMessages[arbID];
return *reinterpret_cast<uint16_t *>(message.data + offset);
}
/**
* Unpack a field from the outgoing hashmap.
*
* This is called in getters for configuration data.
*/
uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset)
{
CANMessage &message = outgoingMessages[arbID];
return *reinterpret_cast<uint32_t *>(message.data + offset);
}
/**
* Unpack a field from the outgoing hashmap.
*
* This is called in getters for configuration data.
*/
double canTxUnpackFXP16(uint32_t arbID, uint8_t offset)
{
int16_t raw = canTxUnpackInt16(arbID, offset);
return raw / 255.0;
}
/**
* Unpack a field from the outgoing hashmap.
*
* This is called in getters for configuration data.
*/
double canTxUnpackFXP32(uint32_t arbID, uint8_t offset)
{
int32_t raw = canTxUnpackInt32(arbID, offset);
return raw / 65535.0;
}
/**
* Get data from CANSessionMux (if it's available) and put it in the incoming
* hashmap.
*
* @return true if there's new data. Otherwise, the last received value should
* still be in the hashmap.
*/
bool canRxReceive(uint32_t arbID)
{
CANMessage &message = incomingMessages[arbID];
uint8_t length;
uint32_t timestamp;
int32_t status;
FRC_NetworkCommunication_CANSessionMux_receiveMessage(
&arbID, kFullMessageIDMask, message.data, &length, &timestamp, &status);
return status != ERR_CANSessionMux_MessageNotFound;
}
/**
* Unpack a field from the incoming hashmap.
*
* This is called in getters for status data.
*/
uint8_t canRxUnpackInt8(uint32_t arbID, uint8_t offset)
{
CANMessage &message = incomingMessages[arbID];
return message.data[offset];
}
/**
* Unpack a field from the incoming hashmap.
*
* This is called in getters for status data.
*/
uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset)
{
CANMessage &message = incomingMessages[arbID];
return *reinterpret_cast<uint16_t *>(message.data + offset);
}
/**
* Unpack a field from the incoming hashmap.
*
* This is called in getters for status data.
*/
uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset)
{
CANMessage &message = incomingMessages[arbID];
return *reinterpret_cast<uint32_t *>(message.data + offset);
}
/**
* Unpack a field from the incoming hashmap.
*
* This is called in getters for status data.
*/
double canRxUnpackFXP16(uint32_t arbID, uint8_t offset)
{
int16_t raw = canRxUnpackInt16(arbID, offset);
return raw / 255.0;
}
/**
* Unpack a field from the incoming hashmap.
*
* This is called in getters for status data.
*/
double canRxUnpackFXP32(uint32_t arbID, uint8_t offset)
{
int32_t raw = canRxUnpackInt32(arbID, offset);
return raw / 65535.0;
}

View File

@@ -8,6 +8,7 @@
#include "NetworkCommunication/FRCComm.h"
#include "NetworkCommunication/UsageReporting.h"
#include "NetworkCommunication/LoadOut.h"
#include "NetworkCommunication/CANSessionMux.h"
#include <fstream>
#include <iostream>
#include <unistd.h>
@@ -53,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:
@@ -201,14 +206,30 @@ int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs)
return FRC_NetworkCommunication_getJoystickPOVs(joystickNum, (JoystickPOV_t*) povs, kMaxJoystickPOVs);
}
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons, uint8_t *count)
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons)
{
return FRC_NetworkCommunication_getJoystickButtons(joystickNum, buttons, count);
return FRC_NetworkCommunication_getJoystickButtons(joystickNum, &buttons->buttons, &buttons->count);
}
void HALSetNewDataSem(pthread_cond_t * param)
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc)
{
setNewDataSem(param);
return FRC_NetworkCommunication_getJoystickDesc(joystickNum, &desc->isXbox, &desc->type, (char *)(&desc->name),
&desc->axisCount, &desc->axisTypes, &desc->buttonCount, &desc->povCount);
}
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble)
{
return FRC_NetworkCommunication_setJoystickOutputs(joystickNum, outputs, leftRumble, rightRumble);
}
int HALGetMatchTime(float *matchTime)
{
return FRC_NetworkCommunication_getMatchTime(matchTime);
}
void HALSetNewDataSem(MULTIWAIT_ID sem)
{
setNewDataSem(sem);
}
bool HALGetSystemActive(int32_t *status)

View File

@@ -26,6 +26,7 @@
#define WARN_CANSessionMux_NoToken 44087
#define ERR_CANSessionMux_NotAllowed -44088
#define ERR_CANSessionMux_NotInitialized -44089
#define ERR_CANSessionMux_SessionOverrun 44050
struct tCANStreamMessage{
uint32_t messageID;

View File

@@ -33,6 +33,7 @@
#endif
#define ERR_FRCSystem_NetCommNotResponding -44049
#define ERR_FRCSystem_NoDSConnection -44018
enum AllianceStationID_t {
kAllianceStationID_red1,
@@ -43,6 +44,13 @@ enum AllianceStationID_t {
kAllianceStationID_blue3,
};
enum MatchType_t {
kMatchType_none,
kMatchType_practice,
kMatchType_qualification,
kMatchType_elimination,
};
struct ControlWord_t {
#ifndef __vxworks
uint32_t enabled : 1;

View File

@@ -26,3 +26,36 @@ double getPDPChannelCurrent(uint8_t channel, int32_t *status) {
return current;
}
double getPDPTotalCurrent(int32_t *status) {
double current;
*status = pdp.GetTotalCurrent(current);
return current;
}
double getPDPTotalPower(int32_t *status) {
double power;
*status = pdp.GetTotalPower(power);
return power;
}
double getPDPTotalEnergy(int32_t *status) {
double energy;
*status = pdp.GetTotalEnergy(energy);
return energy;
}
void resetPDPTotalEnergy(int32_t *status) {
*status = pdp.ResetEnergy();
}
void clearPDPStickyFaults(int32_t *status) {
*status = pdp.ClearStickyFaults();
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,374 @@
/**
* @brief CAN TALON SRX driver.
*
* The TALON SRX is designed to instrument all runtime signals periodically. The default periods are chosen to support 16 TALONs
* with 10ms update rate for control (throttle or setpoint). However these can be overridden with SetStatusFrameRate. @see SetStatusFrameRate
* The getters for these unsolicited signals are auto generated at the bottom of this module.
*
* Likewise most control signals are sent periodically using the fire-and-forget CAN API.
* The setters for these unsolicited signals are auto generated at the bottom of this module.
*
* Signals that are not available in an unsolicited fashion are the Close Loop gains.
* For teams that have a single profile for their TALON close loop they can use either the webpage to configure their TALONs once
* or set the PIDF,Izone,CloseLoopRampRate,etc... once in the robot application. These parameters are saved to flash so once they are
* loaded in the TALON, they will persist through power cycles and mode changes.
*
* For teams that have one or two profiles to switch between, they can use the same strategy since there are two slots to choose from
* and the ProfileSlotSelect is periodically sent in the 10 ms control frame.
*
* For teams that require changing gains frequently, they can use the soliciting API to get and set those parameters. Most likely
* they will only need to set them in a periodic fashion as a function of what motion the application is attempting.
* If this API is used, be mindful of the CAN utilization reported in the driver station.
*
* Encoder position is measured in encoder edges. Every edge is counted (similar to roboRIO 4X mode).
* Analog position is 10 bits, meaning 1024 ticks per rotation (0V => 3.3V).
* Use SetFeedbackDeviceSelect to select which sensor type you need. Once you do that you can use GetSensorPosition()
* and GetSensorVelocity(). These signals are updated on CANBus every 20ms (by default).
* If a relative sensor is selected, you can zero (or change the current value) using SetSensorPosition.
*
* Analog Input and quadrature position (and velocity) are also explicitly reported in GetEncPosition, GetEncVel, GetAnalogInWithOv, GetAnalogInVel.
* These signals are available all the time, regardless of what sensor is selected at a rate of 100ms. This allows easy instrumentation
* for "in the pits" checking of all sensors regardless of modeselect. The 100ms rate is overridable for teams who want to acquire sensor
* data for processing, not just instrumentation. Or just select the sensor using SetFeedbackDeviceSelect to get it at 20ms.
*
* Velocity is in position ticks / 100ms.
*
* All output units are in respect to duty cycle (throttle) which is -1023(full reverse) to +1023 (full forward).
* This includes demand (which specifies duty cycle when in duty cycle mode) and rampRamp, which is in throttle units per 10ms (if nonzero).
*
* Pos and velocity close loops are calc'd as
* err = target - posOrVel.
* iErr += err;
* if( (IZone!=0) and abs(err) > IZone)
* ClearIaccum()
* output = P X err + I X iErr + D X dErr + F X target
* dErr = err - lastErr
* P, I,and D gains are always positive. F can be negative.
* Motor direction can be reversed using SetRevMotDuringCloseLoopEn if sensor and motor are out of phase.
* Similarly feedback sensor can also be reversed (multiplied by -1) if you prefer the sensor to be inverted.
*
* P gain is specified in throttle per error tick. For example, a value of 102 is ~9.9% (which is 102/1023) throttle per 1
* ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
*
* I gain is specified in throttle per integrated error. For example, a value of 10 equates to ~0.99% (which is 10/1023)
* for each accumulated ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
* Close loop and integral accumulator runs every 1ms.
*
* D gain is specified in throttle per derivative error. For example a value of 102 equates to ~9.9% (which is 102/1023)
* per change of 1 unit (ADC or encoder) per ms.
*
* I Zone is specified in the same units as sensor position (ADC units or quadrature edges). If pos/vel error is outside of
* this value, the integrated error will auto-clear...
* if( (IZone!=0) and abs(err) > IZone)
* ClearIaccum()
* ...this is very useful in preventing integral windup and is highly recommended if using full PID to keep stability low.
*
* CloseLoopRampRate 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
*/
#ifndef CanTalonSRX_H_
#define CanTalonSRX_H_
#include "ctre.h" //BIT Defines + Typedefs
#include "CtreCanNode.h"
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
#include <map>
class CanTalonSRX : public CtreCanNode
{
private:
/** just in case user wants to modify periods of certain status frames.
* Default the vars to match the firmware default. */
uint32_t _statusRateMs[4];
//---------------------- Vars for opening a CAN stream if caller needs signals that require soliciting */
uint32_t _can_h; //!< Session handle for catching response params.
int32_t _can_stat; //!< Session handle status.
struct tCANStreamMessage _msgBuff[20];
static int const kMsgCapacity = 20;
typedef std::map<uint32_t, uint32_t> sigs_t;
sigs_t _sigs; //!< Catches signal updates that are solicited. Expect this to be very few.
void OpenSessionIfNeedBe();
void ProcessStreamMessages();
/**
* Send a one shot frame to set an arbitrary signal.
* Most signals are in the control frame so avoid using this API unless you have to.
* Use this api for...
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
*/
CTR_Code SetParamRaw(uint32_t paramEnum, int32_t rawBits);
/**
* Checks cached CAN frames and updating solicited signals.
*/
CTR_Code GetParamResponseRaw(uint32_t paramEnum, int32_t & rawBits);
public:
static const int kDefaultControlPeriodMs = 10; //!< default control update rate is 10ms.
CanTalonSRX(int deviceNumber = 0,int controlPeriodMs = kDefaultControlPeriodMs);
~CanTalonSRX();
void Set(double value);
/* mode select enumerations */
static const int kMode_DutyCycle = 0; //!< Demand is 11bit signed duty cycle [-1023,1023].
static const int kMode_PositionCloseLoop = 1; //!< Position PIDF.
static const int kMode_VelocityCloseLoop = 2; //!< Velocity PIDF.
static const int kMode_CurrentCloseLoop = 3; //!< Current close loop - not done.
static const int kMode_VoltCompen = 4; //!< Voltage Compensation Mode - not done. Demand is fixed pt target 8.8 volts.
static const int kMode_SlaveFollower = 5; //!< Demand is the 6 bit Device ID of the 'master' TALON SRX.
static const int kMode_NoDrive = 15; //!< Zero the output (honors brake/coast) regardless of demand. Might be useful if we need to change modes but can't atomically change all the signals we want in between.
/* limit switch enumerations */
static const int kLimitSwitchOverride_UseDefaultsFromFlash = 1;
static const int kLimitSwitchOverride_DisableFwd_DisableRev = 4;
static const int kLimitSwitchOverride_DisableFwd_EnableRev = 5;
static const int kLimitSwitchOverride_EnableFwd_DisableRev = 6;
static const int kLimitSwitchOverride_EnableFwd_EnableRev = 7;
/* brake override enumerations */
static const int kBrakeOverride_UseDefaultsFromFlash = 0;
static const int kBrakeOverride_OverrideCoast = 1;
static const int kBrakeOverride_OverrideBrake = 2;
/* feedback device enumerations */
static const int kFeedbackDev_DigitalQuadEnc=0;
static const int kFeedbackDev_AnalogPot=2;
static const int kFeedbackDev_AnalogEncoder=3;
static const int kFeedbackDev_CountEveryRisingEdge=4;
static const int kFeedbackDev_CountEveryFallingEdge=5;
static const int kFeedbackDev_PosIsPulseWidth=8;
/* ProfileSlotSelect enumerations*/
static const int kProfileSlotSelect_Slot0 = 0;
static const int kProfileSlotSelect_Slot1 = 1;
/* status frame rate types */
static const int kStatusFrame_General = 0;
static const int kStatusFrame_Feedback = 1;
static const int kStatusFrame_Encoder = 2;
static const int kStatusFrame_AnalogTempVbat = 3;
/**
* Signal enumeration for generic signal access.
* Although every signal is enumerated, only use this for traffic that must be solicited.
* Use the auto generated getters/setters at bottom of this header as much as possible.
*/
typedef enum _param_t{
eProfileParamSlot0_P=1,
eProfileParamSlot0_I=2,
eProfileParamSlot0_D=3,
eProfileParamSlot0_F=4,
eProfileParamSlot0_IZone=5,
eProfileParamSlot0_CloseLoopRampRate=6,
eProfileParamSlot1_P=11,
eProfileParamSlot1_I=12,
eProfileParamSlot1_D=13,
eProfileParamSlot1_F=14,
eProfileParamSlot1_IZone=15,
eProfileParamSlot1_CloseLoopRampRate=16,
eProfileParamSoftLimitForThreshold=21,
eProfileParamSoftLimitRevThreshold=22,
eProfileParamSoftLimitForEnable=23,
eProfileParamSoftLimitRevEnable=24,
eOnBoot_BrakeMode=31,
eOnBoot_LimitSwitch_Forward_NormallyClosed=32,
eOnBoot_LimitSwitch_Reverse_NormallyClosed=33,
eOnBoot_LimitSwitch_Forward_Disable=34,
eOnBoot_LimitSwitch_Reverse_Disable=35,
eFault_OverTemp=41,
eFault_UnderVoltage=42,
eFault_ForLim=43,
eFault_RevLim=44,
eFault_HardwareFailure=45,
eFault_ForSoftLim=46,
eFault_RevSoftLim=47,
eStckyFault_OverTemp=48,
eStckyFault_UnderVoltage=49,
eStckyFault_ForLim=50,
eStckyFault_RevLim=51,
eStckyFault_ForSoftLim=52,
eStckyFault_RevSoftLim=53,
eAppliedThrottle=61,
eCloseLoopErr=62,
eFeedbackDeviceSelect=63,
eRevMotDuringCloseLoopEn=64,
eModeSelect=65,
eProfileSlotSelect=66,
eRampThrottle=67,
eRevFeedbackSensor=68,
eLimitSwitchEn=69,
eLimitSwitchClosedFor=70,
eLimitSwitchClosedRev=71,
eSensorPosition=73,
eSensorVelocity=74,
eCurrent=75,
eBrakeIsEnabled=76,
eEncPosition=77,
eEncVel=78,
eEncIndexRiseEvents=79,
eQuadApin=80,
eQuadBpin=81,
eQuadIdxpin=82,
eAnalogInWithOv=83,
eAnalogInVel=84,
eTemp=85,
eBatteryV=86,
eResetCount=87,
eResetFlags=88,
eFirmVers=89,
eSettingsChanged=90,
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.
* Most signals are in the control frame so avoid using this API unless you have to.
* Use this api for...
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
*/
CTR_Code SetParam(param_t paramEnum, double value);
/**
* Asks TALON to immedietely respond with signal value. This API is only used for signals that are not sent periodically.
* This can be useful for reading params that rarely change like Limit Switch settings and PIDF values.
* @param param to request.
*/
CTR_Code RequestParam(param_t paramEnum);
CTR_Code GetParamResponse(param_t paramEnum, double & value);
CTR_Code GetParamResponseInt32(param_t paramEnum, int & value);
/*----- getters and setters that use param request/response. These signals are backed up in flash and will survive a power cycle. ---------*/
/*----- If your application requires changing these values consider using both slots and switch between slot0 <=> slot1. ------------------*/
/*----- If your application requires changing these signals frequently then it makes sense to leverage this API. --------------------------*/
/*----- Getters don't block, so it may require several calls to get the latest value. --------------------------*/
CTR_Code SetPgain(unsigned slotIdx,double gain);
CTR_Code SetIgain(unsigned slotIdx,double gain);
CTR_Code SetDgain(unsigned slotIdx,double gain);
CTR_Code SetFgain(unsigned slotIdx,double gain);
CTR_Code SetIzone(unsigned slotIdx,int zone);
CTR_Code SetCloseLoopRampRate(unsigned slotIdx,int closeLoopRampRate);
CTR_Code SetSensorPosition(int pos);
CTR_Code SetForwardSoftLimit(int forwardLimit);
CTR_Code SetReverseSoftLimit(int reverseLimit);
CTR_Code SetForwardSoftEnable(int enable);
CTR_Code SetReverseSoftEnable(int enable);
CTR_Code GetPgain(unsigned slotIdx,double & gain);
CTR_Code GetIgain(unsigned slotIdx,double & gain);
CTR_Code GetDgain(unsigned slotIdx,double & gain);
CTR_Code GetFgain(unsigned slotIdx,double & gain);
CTR_Code GetIzone(unsigned slotIdx,int & zone);
CTR_Code GetCloseLoopRampRate(unsigned slotIdx,int & closeLoopRampRate);
CTR_Code GetForwardSoftLimit(int & forwardLimit);
CTR_Code GetReverseSoftLimit(int & reverseLimit);
CTR_Code GetForwardSoftEnable(int & enable);
CTR_Code GetReverseSoftEnable(int & enable);
/**
* Change the periodMs of a TALON's status frame. See kStatusFrame_* enums for what's available.
*/
CTR_Code SetStatusFrameRate(unsigned frameEnum, unsigned periodMs);
/**
* Clear all sticky faults in TALON.
*/
CTR_Code ClearStickyFaults();
/*------------------------ auto generated. This API is optimal since it uses the fire-and-forget CAN interface ----------------------*/
/*------------------------ These signals should cover the majority of all use cases. ----------------------------------*/
CTR_Code GetFault_OverTemp(int &param);
CTR_Code GetFault_UnderVoltage(int &param);
CTR_Code GetFault_ForLim(int &param);
CTR_Code GetFault_RevLim(int &param);
CTR_Code GetFault_HardwareFailure(int &param);
CTR_Code GetFault_ForSoftLim(int &param);
CTR_Code GetFault_RevSoftLim(int &param);
CTR_Code GetStckyFault_OverTemp(int &param);
CTR_Code GetStckyFault_UnderVoltage(int &param);
CTR_Code GetStckyFault_ForLim(int &param);
CTR_Code GetStckyFault_RevLim(int &param);
CTR_Code GetStckyFault_ForSoftLim(int &param);
CTR_Code GetStckyFault_RevSoftLim(int &param);
CTR_Code GetAppliedThrottle(int &param);
CTR_Code GetCloseLoopErr(int &param);
CTR_Code GetFeedbackDeviceSelect(int &param);
CTR_Code GetModeSelect(int &param);
CTR_Code GetLimitSwitchEn(int &param);
CTR_Code GetLimitSwitchClosedFor(int &param);
CTR_Code GetLimitSwitchClosedRev(int &param);
CTR_Code GetSensorPosition(int &param);
CTR_Code GetSensorVelocity(int &param);
CTR_Code GetCurrent(double &param);
CTR_Code GetBrakeIsEnabled(int &param);
CTR_Code GetEncPosition(int &param);
CTR_Code GetEncVel(int &param);
CTR_Code GetEncIndexRiseEvents(int &param);
CTR_Code GetQuadApin(int &param);
CTR_Code GetQuadBpin(int &param);
CTR_Code GetQuadIdxpin(int &param);
CTR_Code GetAnalogInWithOv(int &param);
CTR_Code GetAnalogInVel(int &param);
CTR_Code GetTemp(double &param);
CTR_Code GetBatteryV(double &param);
CTR_Code GetResetCount(int &param);
CTR_Code GetResetFlags(int &param);
CTR_Code GetFirmVers(int &param);
CTR_Code SetDemand(int param);
CTR_Code SetOverrideLimitSwitchEn(int param);
CTR_Code SetFeedbackDeviceSelect(int param);
CTR_Code SetRevMotDuringCloseLoopEn(int param);
CTR_Code SetOverrideBrakeType(int param);
CTR_Code SetModeSelect(int param);
CTR_Code 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,98 +1,101 @@
#include "CtreCanNode.h"
#include "NetworkCommunication/CANSessionMux.h"
#include <string.h> // memset
#include <unistd.h> // usleep
static const UINT32 kFullMessageIDMask = 0x1fffffff;
CtreCanNode::CtreCanNode(UINT8 deviceNumber)
{
_deviceNumber = deviceNumber;
}
CtreCanNode::~CtreCanNode()
{
}
void CtreCanNode::RegisterRx(uint32_t arbId)
{
/* no need to do anything, we just use new API to poll last received message */
}
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
{
int32_t status = 0;
txJob_t job;
job.arbId = arbId;
job.periodMs = periodMs;
_txJobs[arbId] = job;
FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
job.toSend,
8,
job.periodMs,
&status);
}
timespec diff(const timespec & start, const timespec & end)
{
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
{
CTR_Code retval = CTR_OKAY;
int32_t status = 0;
uint8_t len = 0;
uint32_t timeStamp;
/* cap timeout at 999ms */
if(timeoutMs > 999)
timeoutMs = 999;
FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
if(status == 0){
/* fresh update */
rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
clock_gettime(2,&r.time); /* fill in time */
memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
}else{
/* did not get the message */
rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
if(i == _rxRxEvents.end()){
/* we've never gotten this mesage */
retval = CTR_RxTimeout;
/* fill caller's buffer with zeros */
memset(dataBytes,0,8);
}else{
/* we've gotten this message before but not recently */
memcpy(dataBytes,i->second.bytes,8);
/* get the time now */
struct timespec temp;
clock_gettime(2,&temp); /* get now */
/* how long has it been? */
temp = diff(i->second.time,temp); /* temp = now - last */
if(temp.tv_sec > 0){
retval = CTR_RxTimeout;
}else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){
retval = CTR_RxTimeout;
}else {
/* our last update was recent enough */
}
}
}
return retval;
}
void CtreCanNode::FlushTx(uint32_t arbId)
{
int32_t status = 0;
txJobs_t::iterator iter = _txJobs.find(arbId);
if(iter != _txJobs.end())
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
iter->second.toSend,
8,
iter->second.periodMs,
&status);
}
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#include "CtreCanNode.h"
#include "NetworkCommunication/CANSessionMux.h"
#include <string.h> // memset
#include <unistd.h> // usleep
static const UINT32 kFullMessageIDMask = 0x1fffffff;
CtreCanNode::CtreCanNode(UINT8 deviceNumber)
{
_deviceNumber = deviceNumber;
}
CtreCanNode::~CtreCanNode()
{
}
void CtreCanNode::RegisterRx(uint32_t arbId)
{
/* no need to do anything, we just use new API to poll last received message */
}
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
{
int32_t status = 0;
txJob_t job = {0};
job.arbId = arbId;
job.periodMs = periodMs;
_txJobs[arbId] = job;
FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
job.toSend,
8,
job.periodMs,
&status);
}
timespec diff(const timespec & start, const timespec & end)
{
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
{
CTR_Code retval = CTR_OKAY;
int32_t status = 0;
uint8_t len = 0;
uint32_t timeStamp;
/* cap timeout at 999ms */
if(timeoutMs > 999)
timeoutMs = 999;
FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
if(status == 0){
/* fresh update */
rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
clock_gettime(2,&r.time); /* fill in time */
memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
}else{
/* did not get the message */
rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
if(i == _rxRxEvents.end()){
/* we've never gotten this mesage */
retval = CTR_RxTimeout;
/* fill caller's buffer with zeros */
memset(dataBytes,0,8);
}else{
/* we've gotten this message before but not recently */
memcpy(dataBytes,i->second.bytes,8);
/* get the time now */
struct timespec temp;
clock_gettime(2,&temp); /* get now */
/* how long has it been? */
temp = diff(i->second.time,temp); /* temp = now - last */
if(temp.tv_sec > 0){
retval = CTR_RxTimeout;
}else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){
retval = CTR_RxTimeout;
}else {
/* our last update was recent enough */
}
}
}
return retval;
}
void CtreCanNode::FlushTx(uint32_t arbId)
{
int32_t status = 0;
txJobs_t::iterator iter = _txJobs.find(arbId);
if(iter != _txJobs.end())
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
iter->second.toSend,
8,
iter->second.periodMs,
&status);
}

View File

@@ -1,121 +1,116 @@
#ifndef CtreCanNode_H_
#define CtreCanNode_H_
#include "ctre.h" //BIT Defines + Typedefs
#include "NetworkCommunication/CANSessionMux.h" //CAN Comm
#include <pthread.h>
#include <map>
#include <string.h> // memcpy
#include <sys/time.h>
class CtreCanNode
{
public:
CtreCanNode(UINT8 deviceNumber);
~CtreCanNode();
UINT8 GetDeviceNumber()
{
return _deviceNumber;
}
protected:
template <typename T> class txTask{
public:
uint32_t arbId;
T * toSend;
T * operator -> ()
{
return toSend;
}
T & operator*()
{
return *toSend;
}
bool IsEmpty()
{
if(toSend == 0)
return true;
return false;
}
};
template <typename T> class recMsg{
public:
uint32_t arbId;
uint8_t bytes[8];
CTR_Code err;
T * operator -> ()
{
return (T *)bytes;
}
T & operator*()
{
return *(T *)bytes;
}
};
UINT8 _deviceNumber;
void RegisterRx(uint32_t arbId);
void RegisterTx(uint32_t arbId, uint32_t periodMs);
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
void FlushTx(uint32_t arbId);
template<typename T> txTask<T> GetTx(uint32_t arbId)
{
txTask<T> retval = {0};
txJobs_t::iterator i = _txJobs.find(arbId);
if(i != _txJobs.end()){
retval.arbId = i->second.arbId;
retval.toSend = (T*)i->second.toSend;
}
return retval;
}
template<class T> void FlushTx(T & par)
{
FlushTx(par.arbId);
}
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
{
recMsg<T> retval;
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
return retval;
}
private:
class txJob_t {
public:
uint32_t arbId;
uint8_t toSend[8];
uint32_t periodMs;
txJob_t() : arbId(0),periodMs(0)
{
for(unsigned i=0;i<sizeof(toSend);++i)
toSend[i] = 0;
}
};
class rxEvent_t{
public:
uint8_t bytes[8];
struct timespec time;
rxEvent_t()
{
bytes[0] = 0;
bytes[1] = 0;
bytes[2] = 0;
bytes[3] = 0;
bytes[4] = 0;
bytes[5] = 0;
bytes[6] = 0;
bytes[7] = 0;
}
};
typedef std::map<uint32_t,txJob_t> txJobs_t;
txJobs_t _txJobs;
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
rxRxEvents_t _rxRxEvents;
};
#endif
#ifndef CtreCanNode_H_
#define CtreCanNode_H_
#include "ctre.h" //BIT Defines + Typedefs
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
#include <pthread.h>
#include <map>
#include <string.h> // memcpy
#include <sys/time.h>
class CtreCanNode
{
public:
CtreCanNode(UINT8 deviceNumber);
~CtreCanNode();
UINT8 GetDeviceNumber()
{
return _deviceNumber;
}
protected:
template <typename T> class txTask{
public:
uint32_t arbId;
T * toSend;
T * operator -> ()
{
return toSend;
}
T & operator*()
{
return *toSend;
}
bool IsEmpty()
{
if(toSend == 0)
return true;
return false;
}
};
template <typename T> class recMsg{
public:
uint32_t arbId;
uint8_t bytes[8];
CTR_Code err;
T * operator -> ()
{
return (T *)bytes;
}
T & operator*()
{
return *(T *)bytes;
}
};
UINT8 _deviceNumber;
void RegisterRx(uint32_t arbId);
void RegisterTx(uint32_t arbId, uint32_t periodMs);
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
void FlushTx(uint32_t arbId);
template<typename T> txTask<T> GetTx(uint32_t arbId)
{
txTask<T> retval = {0, nullptr};
txJobs_t::iterator i = _txJobs.find(arbId);
if(i != _txJobs.end()){
retval.arbId = i->second.arbId;
retval.toSend = (T*)i->second.toSend;
}
return retval;
}
template<class T> void FlushTx(T & par)
{
FlushTx(par.arbId);
}
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
{
recMsg<T> retval;
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
return retval;
}
private:
class txJob_t {
public:
uint32_t arbId;
uint8_t toSend[8];
uint32_t periodMs;
};
class rxEvent_t{
public:
uint8_t bytes[8];
struct timespec time;
rxEvent_t()
{
bytes[0] = 0;
bytes[1] = 0;
bytes[2] = 0;
bytes[3] = 0;
bytes[4] = 0;
bytes[5] = 0;
bytes[6] = 0;
bytes[7] = 0;
}
};
typedef std::map<uint32_t,txJob_t> txJobs_t;
txJobs_t _txJobs;
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
rxRxEvents_t _rxRxEvents;
};
#endif

View File

@@ -6,11 +6,15 @@
#define STATUS_1 0x8041400
#define STATUS_2 0x8041440
#define STATUS_3 0x8041480
#define STATUS_ENERGY 0x8041740
#define CONTROL_1 0x08041C00 /* PDP_Control_ClearStats */
#define EXPECTED_RESPONSE_TIMEOUT_MS (50)
#define GET_STATUS1() CtreCanNode::recMsg<PdpStatus1_t> rx = GetRx<PdpStatus1_t>(STATUS_1,EXPECTED_RESPONSE_TIMEOUT_MS)
#define GET_STATUS2() CtreCanNode::recMsg<PdpStatus2_t> rx = GetRx<PdpStatus2_t>(STATUS_2,EXPECTED_RESPONSE_TIMEOUT_MS)
#define GET_STATUS3() CtreCanNode::recMsg<PdpStatus3_t> rx = GetRx<PdpStatus3_t>(STATUS_3,EXPECTED_RESPONSE_TIMEOUT_MS)
#define GET_STATUS_ENERGY() CtreCanNode::recMsg<PDP_Status_Energy_t> rx = GetRx<PDP_Status_Energy_t>(STATUS_ENERGY,EXPECTED_RESPONSE_TIMEOUT_MS)
/* encoder/decoders */
typedef struct _PdpStatus1_t{
@@ -56,6 +60,18 @@ typedef struct _PdpStatus3_t{
unsigned busVoltage:8;
unsigned temp:8;
}PdpStatus3_t;
typedef struct _PDP_Status_Energy_t {
unsigned TmeasMs_likelywillbe20ms_:8;
unsigned TotalCurrent_125mAperunit_h8:8;
unsigned Power_125mWperunit_h4:4;
unsigned TotalCurrent_125mAperunit_l4:4;
unsigned Power_125mWperunit_m8:8;
unsigned Energy_125mWPerUnitXTmeas_h4:4;
unsigned Power_125mWperunit_l4:4;
unsigned Energy_125mWPerUnitXTmeas_mh8:8;
unsigned Energy_125mWPerUnitXTmeas_ml8:8;
unsigned Energy_125mWPerUnitXTmeas_l8:8;
} PDP_Status_Energy_t ;
PDP::PDP(UINT8 deviceNumber): CtreCanNode(deviceNumber)
{
@@ -128,6 +144,68 @@ CTR_Code PDP::GetTemperature(double &tempC)
tempC = (double)raw * 1.03250836957542 - 67.8564500484966;
return rx.err;
}
CTR_Code PDP::GetTotalCurrent(double &currentAmps)
{
GET_STATUS_ENERGY();
uint32_t raw;
raw = rx->TotalCurrent_125mAperunit_h8;
raw <<= 4;
raw |= rx->TotalCurrent_125mAperunit_l4;
currentAmps = 0.125 * raw;
return rx.err;
}
CTR_Code PDP::GetTotalPower(double &powerWatts)
{
GET_STATUS_ENERGY();
uint32_t raw;
raw = rx->Power_125mWperunit_h4;
raw <<= 8;
raw |= rx->Power_125mWperunit_m8;
raw <<= 4;
raw |= rx->Power_125mWperunit_l4;
powerWatts = 0.125 * raw;
return rx.err;
}
CTR_Code PDP::GetTotalEnergy(double &energyJoules)
{
GET_STATUS_ENERGY();
uint32_t raw;
raw = rx->Energy_125mWPerUnitXTmeas_h4;
raw <<= 8;
raw |= rx->Energy_125mWPerUnitXTmeas_mh8;
raw <<= 8;
raw |= rx->Energy_125mWPerUnitXTmeas_ml8;
raw <<= 8;
raw |= rx->Energy_125mWPerUnitXTmeas_l8;
energyJoules = 0.125 * raw; /* mW integrated every TmeasMs */
energyJoules *= rx->TmeasMs_likelywillbe20ms_; /* multiplied by TmeasMs = joules */
return rx.err;
}
/* Clear sticky faults.
* @Return - CTR_Code - Error code (if any)
*/
CTR_Code PDP::ClearStickyFaults()
{
int32_t status = 0;
uint8_t pdpControl[] = { 0x80 }; /* only bit set is ClearStickyFaults */
FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_1 | GetDeviceNumber(), pdpControl, sizeof(pdpControl), 0, &status);
if(status)
return CTR_TxFailed;
return CTR_OKAY;
}
/* Reset Energy Signals
* @Return - CTR_Code - Error code (if any)
*/
CTR_Code PDP::ResetEnergy()
{
int32_t status = 0;
uint8_t pdpControl[] = { 0x40 }; /* only bit set is ResetEnergy */
FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_1 | GetDeviceNumber(), pdpControl, sizeof(pdpControl), 0, &status);
if(status)
return CTR_TxFailed;
return CTR_OKAY;
}
//------------------ C interface --------------------------------------------//
extern "C" {
void * c_PDP_Init(void)

View File

@@ -38,6 +38,19 @@ public:
* @Param - status - Temperature of PDP in Centigrade / Celcius (C)
*/
CTR_Code GetTemperature(double &status);
CTR_Code GetTotalCurrent(double &currentAmps);
CTR_Code GetTotalPower(double &powerWatts);
CTR_Code GetTotalEnergy(double &energyJoules);
/* Clear sticky faults.
* @Return - CTR_Code - Error code (if any)
*/
CTR_Code ClearStickyFaults();
/* Reset Energy Signals
* @Return - CTR_Code - Error code (if any)
*/
CTR_Code ResetEnergy();
private:
uint64_t ReadCurrents(uint8_t api);
};

View File

@@ -38,23 +38,13 @@ typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef enum {
CTR_OKAY, //No Error - Function executed as expected
CTR_RxTimeout, /*
* Receive Timeout
*
* No module-specific CAN frames have been received in
* the last 50ms. Function returns the latest received data
* but may be STALE DATA.
*/
CTR_TxTimeout, /*
* Transmission Timeout
*
* No module-specific CAN frames were transmitted in
* the last 50ms. Parameters passed in by the user are loaded
* for next transmission but have not sent.
*/
CTR_InvalidParamValue,
CTR_UnexpectedArbId,
CTR_OKAY, //!< No Error - Function executed as expected
CTR_RxTimeout, //!< CAN frame has not been received within specified period of time.
CTR_TxTimeout, //!< Not used.
CTR_InvalidParamValue, //!< Caller passed an invalid param
CTR_UnexpectedArbId, //!< Specified CAN Id is invalid.
CTR_TxFailed, //!< Could not transmit the CAN frame.
CTR_SigNotUpdated, //!< Have not received an value response for signal.
}CTR_Code;
#endif

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

Binary file not shown.

Binary file not shown.

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
.PHONY : all build copy-plugins clean docs clean-docs
all: build copy-plugins
@@ -20,15 +25,15 @@ build:
copy-plugins:
mkdir -p plugins
cp msgs/build/libgz_msgs.so plugins
cp dc_motor/build/libgz_dc_motor.so plugins
cp pneumatic_piston/build/libgz_pneumatic_piston.so plugins
cp potentiometer/build/libgz_potentiometer.so plugins
cp rangefinder/build/libgz_rangefinder.so plugins
cp encoder/build/libgz_encoder.so plugins
cp gyro/build/libgz_gyro.so plugins
cp limit_switch/build/libgz_limit_switch.so plugins
cp clock/build/libgz_clock.so plugins
cp msgs/build/libgz_msgs$(ext) plugins
cp dc_motor/build/libgz_dc_motor$(ext) plugins
cp pneumatic_piston/build/libgz_pneumatic_piston$(ext) plugins
cp potentiometer/build/libgz_potentiometer$(ext) plugins
cp rangefinder/build/libgz_rangefinder$(ext) plugins
cp encoder/build/libgz_encoder$(ext) plugins
cp gyro/build/libgz_gyro$(ext) plugins
cp limit_switch/build/libgz_limit_switch$(ext) plugins
cp clock/build/libgz_clock$(ext) plugins
clean: clean-docs
cd msgs && make clean

View File

@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
endif()
find_package(gazebo REQUIRED)
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
find_package(Boost COMPONENTS system REQUIRED)
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_clock.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_clock$(ext) $(DESTDIR)$(plugin.dir)

View File

@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
endif()
find_package(gazebo REQUIRED)
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
find_package(Boost COMPONENTS system REQUIRED)
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_dc_motor.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_dc_motor$(ext) $(DESTDIR)$(plugin.dir)

View File

@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
endif()
find_package(gazebo REQUIRED)
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
find_package(Boost COMPONENTS system REQUIRED)
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_encoder.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_encoder$(ext) $(DESTDIR)$(plugin.dir)

View File

@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
endif()
find_package(gazebo REQUIRED)
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
find_package(Boost COMPONENTS system REQUIRED)
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_gyro.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_gyro$(ext) $(DESTDIR)$(plugin.dir)

View File

@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
endif()
find_package(gazebo REQUIRED)
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
find_package(Boost COMPONENTS system REQUIRED)
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_limit_switch.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_limit_switch$(ext) $(DESTDIR)$(plugin.dir)

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_msgs.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_msgs$(ext) $(DESTDIR)$(plugin.dir)

View File

@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
endif()
find_package(gazebo REQUIRED)
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
find_package(Boost COMPONENTS system REQUIRED)
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_pneumatic_piston.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_pneumatic_piston$(ext) $(DESTDIR)$(plugin.dir)

View File

@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
endif()
find_package(gazebo REQUIRED)
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
find_package(Boost COMPONENTS system REQUIRED)
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_potentiometer.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_potentiometer$(ext) $(DESTDIR)$(plugin.dir)

View File

@@ -7,11 +7,12 @@ if (PKG_CONFIG_FOUND)
endif()
find_package(gazebo REQUIRED)
find_library(GZ_MSGS libgz_msgs.so ../msgs/build)
find_package(Boost COMPONENTS system REQUIRED)
find_library(GZ_MSGS NAMES gz_msgs PATHS ../msgs/build)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
include_directories(src ${Boost_INCLUDE_DIR} ${GAZEBO_INCLUDE_DIRS} ../msgs/src)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
link_directories(${GAZEBO_LIBRARY_DIRS} ../msgs/build/)
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${GZ_MSGS} ${GAZEBO_LIBRARIES} ${Boost_LIBRARIES})

View File

@@ -3,6 +3,11 @@ lib.dir = $(prefix)/lib
plugin.dir = $(lib.dir)/frcsim/plugins
build.dir = build
ext = .so
ifeq ($(shell uname), Darwin)
ext = .dylib
endif
all:
mkdir -p $(build.dir)
cd ${build.dir} && cmake .. && make
@@ -12,4 +17,4 @@ clean:
install: all
mkdir -p $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_rangefinder.so $(DESTDIR)$(plugin.dir)
install $(build.dir)/libgz_rangefinder$(ext) $(DESTDIR)$(plugin.dir)

View File

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

@@ -5,38 +5,41 @@
/**
* Class for reading analog potentiometers. Analog potentiometers read
* in an analog voltage that corresponds to a position. Usually the
* position is either degrees or meters. However, if no conversion is
* given it remains volts.
* in an analog voltage that corresponds to a position. The position is
* in whichever units you choose, by way of the scaling and offset
* constants passed to the constructor.
*
* @author Alex Henning
* @author Colby Skeggs (rail voltage)
*/
class AnalogPotentiometer : public Potentiometer, public LiveWindowSendable {
public:
/**
* AnalogPotentiometer constructor.
*
* Use the scaling and offset values so that the output produces
* Use the fullRange and offset values so that the output produces
* meaningful values. I.E: you have a 270 degree potentiometer and
* you want the output to be degrees with the halfway point as 0
* degrees. The scale value is 270.0(degrees)/5.0(volts) and the
* offset is -135.0 since the halfway point after scaling is 135
* degrees.
* degrees. The fullRange value is 270.0(degrees) and the offset is
* -135.0 since the halfway point after scaling is 135 degrees.
*
* This will calculate the result from the fullRange times the
* fraction of the supply voltage, plus the offset.
*
* @param channel The analog channel this potentiometer is plugged into.
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
* @param fullRange The scaling to multiply the voltage by to get a meaningful unit.
* @param offset The offset to add to the scaled value for controlling the zero value
*/
explicit AnalogPotentiometer(int channel, double scale = 1.0, double offset = 0.0);
explicit AnalogPotentiometer(int channel, double fullRange = 1.0, double offset = 0.0);
explicit AnalogPotentiometer(AnalogInput *input, double scale = 1.0, double offset = 0.0);
explicit AnalogPotentiometer(AnalogInput *input, double fullRange = 1.0, double offset = 0.0);
explicit AnalogPotentiometer(AnalogInput &input, double scale = 1.0, double offset = 0.0);
explicit AnalogPotentiometer(AnalogInput &input, double fullRange = 1.0, double offset = 0.0);
virtual ~AnalogPotentiometer();
/**
* Get the current reading of the potentiomere.
* Get the current reading of the potentiomer.
*
* @return The current position of the potentiometer.
*/
@@ -70,7 +73,7 @@ public:
virtual void StopLiveWindowMode() {}
private:
double m_scale, m_offset;
double m_fullRange, m_offset;
AnalogInput* m_analog_input;
ITable* m_table;
bool m_init_analog_input;
@@ -78,5 +81,5 @@ private:
/**
* Common initialization code called by all constructors.
*/
void initPot(AnalogInput *input, double scale, double offset);
void initPot(AnalogInput *input, double fullRange, double offset);
};

View File

@@ -10,7 +10,7 @@
#include "Resource.h"
#include "MotorSafetyHelper.h"
#include "PIDOutput.h"
#include "SpeedController.h"
#include "CANSpeedController.h"
#include "HAL/Semaphore.hpp"
#include "HAL/HAL.hpp"
#include "LiveWindow/LiveWindowSendable.h"
@@ -20,10 +20,10 @@
#include <utility>
/**
* Luminary Micro Jaguar Speed Control
* Luminary Micro / Vex Robotics Jaguar Speed Control
*/
class CANJaguar : public MotorSafety,
public SpeedController,
public CANSpeedController,
public ErrorBase,
public LiveWindowSendable,
public ITableListener
@@ -41,40 +41,11 @@ public:
/** Sets a potentiometer as the position reference only. <br> Passed as the "tag" when setting the control mode. */
static const struct PotentiometerStruct {} Potentiometer;
typedef enum {kPercentVbus, kCurrent, kSpeed, kPosition, kVoltage} ControlMode;
typedef enum {kCurrentFault = 1, kTemperatureFault = 2, kBusVoltageFault = 4, kGateDriverFault = 8} Faults;
typedef enum {kForwardLimit = 1, kReverseLimit = 2} Limits;
typedef enum {
kNeutralMode_Jumper = 0, /** Use the NeutralMode that is set by the jumper wire on the CAN device */
kNeutralMode_Brake = 1, /** Stop the motor's rotation by applying a force. */
kNeutralMode_Coast = 2 /** Do not attempt to stop the motor. Instead allow it to coast to a stop without applying resistance. */
} NeutralMode;
typedef enum {
/**
* Disables the soft position limits and only uses the limit switches to limit rotation.
* @see CANJaguar#GetForwardLimitOK()
* @see CANJaguar#GetReverseLimitOK()
*
*/
kLimitMode_SwitchInputsOnly = 0,
/**
* Enables the soft position limits on the Jaguar.
* These will be used in addition to the limit switches. This does not disable the behavior
* of the limit switch input.
* @see CANJaguar#ConfigSoftPositionLimits(double, double)
*/
kLimitMode_SoftPositionLimits = 1
} LimitMode;
explicit CANJaguar(uint8_t deviceNumber);
virtual ~CANJaguar();
uint8_t getDeviceNumber() const;
// SpeedController interface
virtual float Get();
virtual void Set(float value, uint8_t syncGroup=0);
virtual void Disable();
uint8_t GetHardwareVersion();
// PIDOutput interface
virtual void PIDWrite(float output);
@@ -104,39 +75,42 @@ public:
void SetVoltageMode(QuadEncoderStruct, uint16_t codesPerRev);
void SetVoltageMode(PotentiometerStruct);
// Other Accessors
void SetP(double p);
void SetI(double i);
void SetD(double d);
void SetPID(double p, double i, double d);
double GetP();
double GetI();
double GetD();
float GetBusVoltage();
float GetOutputVoltage();
float GetOutputCurrent();
float GetTemperature();
double GetPosition();
double GetSpeed();
bool GetForwardLimitOK();
bool GetReverseLimitOK();
uint16_t GetFaults();
void SetVoltageRampRate(double rampRate);
virtual uint32_t GetFirmwareVersion();
uint8_t GetHardwareVersion();
void ConfigNeutralMode(NeutralMode mode);
void ConfigEncoderCodesPerRev(uint16_t codesPerRev);
void ConfigPotentiometerTurns(uint16_t turns);
void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition);
void DisableSoftPositionLimits();
void ConfigLimitMode(LimitMode mode);
void ConfigForwardLimit(double forwardLimitPosition);
void ConfigReverseLimit(double reverseLimitPosition);
void ConfigMaxOutputVoltage(double voltage);
void ConfigFaultTime(float faultTime);
ControlMode GetControlMode();
// CANSpeedController interface
virtual float Get() override;
virtual void Set(float value, uint8_t syncGroup=0) override;
virtual void Disable() override;
virtual void SetP(double p) override;
virtual void SetI(double i) override;
virtual void SetD(double d) override;
virtual void SetPID(double p, double i, double d) override;
virtual double GetP() override;
virtual double GetI() override;
virtual double GetD() override;
virtual float GetBusVoltage() override;
virtual float GetOutputVoltage() override;
virtual float GetOutputCurrent() override;
virtual float GetTemperature() override;
virtual double GetPosition() override;
virtual double GetSpeed() override;
virtual bool GetForwardLimitOK() override;
virtual bool GetReverseLimitOK() override;
virtual uint16_t GetFaults() override;
virtual void SetVoltageRampRate(double rampRate) override;
virtual uint32_t GetFirmwareVersion() override;
virtual void ConfigNeutralMode(NeutralMode mode) override;
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) override;
virtual void ConfigPotentiometerTurns(uint16_t turns) override;
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) override;
virtual void DisableSoftPositionLimits() override;
virtual void ConfigLimitMode(LimitMode mode) override;
virtual void ConfigForwardLimit(double forwardLimitPosition) override;
virtual void ConfigReverseLimit(double reverseLimitPosition) override;
virtual void ConfigMaxOutputVoltage(double voltage) override;
virtual void ConfigFaultTime(float faultTime) override;
virtual void SetControlMode(ControlMode mode);
virtual ControlMode GetControlMode();
static void UpdateSyncGroup(uint8_t syncGroup);
static void UpdateSyncGroup(uint8_t syncGroup);
void SetExpiration(float timeout);
float GetExpiration();
@@ -149,9 +123,6 @@ public:
protected:
// Control mode helpers
void ChangeControlMode(ControlMode controlMode);
void SetSpeedReference(uint8_t reference);
uint8_t GetSpeedReference();

View File

@@ -0,0 +1,94 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "SpeedController.h"
/**
* Interface for "smart" CAN-based speed controllers.
* @see CANJaguar
* @see CANTalon
*/
class CANSpeedController : public SpeedController
{
public:
enum ControlMode {
kPercentVbus=0,
kCurrent=1,
kSpeed=2,
kPosition=3,
kVoltage=4,
kFollower=5 // Not supported in Jaguar.
};
enum Faults {
kCurrentFault = 1,
kTemperatureFault = 2,
kBusVoltageFault = 4,
kGateDriverFault = 8,
/* SRX extensions */
kFwdLimitSwitch = 0x10,
kRevLimitSwitch = 0x20,
kFwdSoftLimit = 0x40,
kRevSoftLimit = 0x80,
};
enum Limits {
kForwardLimit = 1,
kReverseLimit = 2
};
enum NeutralMode {
/** Use the NeutralMode that is set by the jumper wire on the CAN device */
kNeutralMode_Jumper = 0,
/** Stop the motor's rotation by applying a force. */
kNeutralMode_Brake = 1,
/** Do not attempt to stop the motor. Instead allow it to coast to a stop without applying resistance. */
kNeutralMode_Coast = 2
};
enum LimitMode {
/** Only use switches for limits */
kLimitMode_SwitchInputsOnly = 0,
/** Use both switches and soft limits */
kLimitMode_SoftPositionLimits = 1
};
virtual float Get() = 0;
virtual void Set(float value, uint8_t syncGroup=0) = 0;
virtual void Disable() = 0;
virtual void SetP(double p) = 0;
virtual void SetI(double i) = 0;
virtual void SetD(double d) = 0;
virtual void SetPID(double p, double i, double d) = 0;
virtual double GetP() = 0;
virtual double GetI() = 0;
virtual double GetD() = 0;
virtual float GetBusVoltage() = 0;
virtual float GetOutputVoltage() = 0;
virtual float GetOutputCurrent() = 0;
virtual float GetTemperature() = 0;
virtual double GetPosition() = 0;
virtual double GetSpeed() = 0;
virtual bool GetForwardLimitOK() = 0;
virtual bool GetReverseLimitOK() = 0;
virtual uint16_t GetFaults() = 0;
virtual void SetVoltageRampRate(double rampRate) = 0;
virtual uint32_t GetFirmwareVersion() = 0;
virtual void ConfigNeutralMode(NeutralMode mode) = 0;
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) = 0;
virtual void ConfigPotentiometerTurns(uint16_t turns) = 0;
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) = 0;
virtual void DisableSoftPositionLimits() = 0;
virtual void ConfigLimitMode(LimitMode mode) = 0;
virtual void ConfigForwardLimit(double forwardLimitPosition) = 0;
virtual void ConfigReverseLimit(double reverseLimitPosition) = 0;
virtual void ConfigMaxOutputVoltage(double voltage) = 0;
virtual void ConfigFaultTime(float faultTime) = 0;
// Hold off on interface until we figure out ControlMode enums.
// virtual void SetControlMode(ControlMode mode) = 0;
// virtual ControlMode GetControlMode() = 0;
};

View File

@@ -0,0 +1,130 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "SafePWM.h"
#include "CANSpeedController.h"
#include "PIDOutput.h"
#include "MotorSafetyHelper.h"
class CanTalonSRX;
/**
* CTRE Talon SRX Speed Controller with CAN Control
*/
class CANTalon : public MotorSafety,
public CANSpeedController,
public ErrorBase
{
public:
enum FeedbackDevice {
QuadEncoder=0,
AnalogPot=2,
AnalogEncoder=3,
EncRising=4,
EncFalling=5
};
explicit CANTalon(int deviceNumber);
virtual ~CANTalon();
// PIDController interface
virtual void PIDWrite(float output) override;
// MotorSafety interface
virtual void SetExpiration(float timeout) override;
virtual float GetExpiration() override;
virtual bool IsAlive() override;
virtual void StopMotor() override;
virtual void SetSafetyEnabled(bool enabled) override;
virtual bool IsSafetyEnabled() override;
virtual void GetDescription(char *desc) override;
// CANSpeedController interface
virtual float Get() override;
virtual void Set(float value, uint8_t syncGroup=0) override;
virtual void Disable() override;
virtual void EnableControl();
virtual void SetP(double p) override;
virtual void SetI(double i) override;
virtual void SetD(double d) override;
void SetF(double f);
virtual void SetPID(double p, double i, double d) override;
void SetPID(double p, double i, double d, double f);
virtual double GetP() override;
virtual double GetI() override;
virtual double GetD() override;
double GetF();
virtual float GetBusVoltage() override;
virtual float GetOutputVoltage() override;
virtual float GetOutputCurrent() override;
virtual float GetTemperature() override;
void SetPosition(double pos);
virtual double GetPosition() override;
virtual double GetSpeed() override;
virtual int GetClosedLoopError();
virtual int GetAnalogIn();
virtual int GetAnalogInVel();
virtual int GetEncPosition();
virtual int GetEncVel();
int GetPinStateQuadA();
int GetPinStateQuadB();
int GetPinStateQuadIdx();
int IsFwdLimitSwitchClosed();
int IsRevLimitSwitchClosed();
int GetNumberOfQuadIdxRises();
void SetNumberOfQuadIdxRises(int rises);
virtual bool GetForwardLimitOK() override;
virtual bool GetReverseLimitOK() override;
virtual uint16_t GetFaults() override;
uint16_t GetStickyFaults();
void ClearStickyFaults();
virtual void SetVoltageRampRate(double rampRate) override;
virtual uint32_t GetFirmwareVersion() override;
virtual void ConfigNeutralMode(NeutralMode mode) override;
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) override;
virtual void ConfigPotentiometerTurns(uint16_t turns) override;
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) override;
virtual void DisableSoftPositionLimits() override;
virtual void ConfigLimitMode(LimitMode mode) override;
virtual void ConfigForwardLimit(double forwardLimitPosition) override;
virtual void ConfigReverseLimit(double reverseLimitPosition) override;
virtual void ConfigMaxOutputVoltage(double voltage) override;
virtual void ConfigFaultTime(float faultTime) override;
virtual void SetControlMode(ControlMode mode);
void SetFeedbackDevice(FeedbackDevice device);
virtual ControlMode GetControlMode();
void SetSensorDirection(bool reverseSensor);
void SetCloseLoopRampRate(double rampRate);
void SelectProfileSlot(int slotIdx);
double GetIzone();
int GetIaccum();
void ClearIaccum();
bool IsControlEnabled();
double GetSetpoint();
private:
// Values for various modes as is sent in the CAN packets for the Talon.
enum TalonControlMode {
kThrottle=0,
kFollowerMode=5,
kVoltageMode=4,
kPositionMode=1,
kSpeedMode=2,
kCurrentMode=3,
kDisabled=15
};
int m_deviceNumber;
CanTalonSRX *m_impl;
MotorSafetyHelper *m_safetyHelper;
int m_profile; // Profile from CANTalon to use. Set to zero until we can actually test this.
bool m_controlEnabled;
ControlMode m_controlMode;
TalonControlMode m_sendMode;
double m_setPoint;
};

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,7 +34,11 @@ public:
float GetStickAxis(uint32_t stick, uint32_t axis);
int GetStickPOV(uint32_t stick, uint32_t pov);
short GetStickButtons(uint32_t stick);
bool GetStickButton(uint32_t stick, uint8_t button);
int GetStickAxisCount(uint32_t stick);
int GetStickPOVCount(uint32_t stick);
int GetStickButtonCount(uint32_t stick);
bool IsEnabled();
bool IsDisabled();
@@ -53,11 +57,6 @@ public:
double GetMatchTime();
float GetBatteryVoltage();
MUTEX_ID GetUserStatusDataSem()
{
return m_statusDataSemaphore;
}
/** Only to be used to tell the Driver Station what code you claim to be executing
* for diagnostic purposes only
* @param entering If true, starting disabled code; if false, leaving disabled code */
@@ -91,30 +90,24 @@ protected:
DriverStation();
void GetData();
void SetData();
private:
static void InitTask(DriverStation *ds);
static DriverStation *m_instance;
void ReportJoystickUnpluggedError(std::string message);
void Run();
HALControlWord m_controlWord;
HALAllianceStationID m_allianceStationID;
HALJoystickAxes m_joystickAxes[kJoystickPorts];
HALJoystickPOVs m_joystickPOVs[kJoystickPorts];
HALJoystickButtons m_joystickButtons[kJoystickPorts];
MUTEX_ID m_statusDataSemaphore;
Task m_task;
SEMAPHORE_ID m_newControlData;
MULTIWAIT_ID m_packetDataAvailableMultiWait;
MUTEX_ID m_packetDataAvailableMutex;
MULTIWAIT_ID m_waitForDataSem;
MUTEX_ID m_waitForDataMutex;
double m_approxMatchTimeOffset;
bool m_userInDisabled;
bool m_userInAutonomous;
bool m_userInTeleop;
bool m_userInTest;
double m_nextMessageTime;
};

View File

@@ -40,6 +40,7 @@ public:
void SetDeadband(float volts);
void SetPIDSourceParameter(PIDSourceParameter pidSource);
virtual void Reset();
void InitGyro();
// PIDSource interface
double PIDGet();
@@ -51,10 +52,10 @@ public:
void InitTable(ITable *subTable);
ITable * GetTable();
private:
void InitGyro();
protected:
AnalogInput *m_analog;
private:
float m_voltsPerDegreePerSecond;
float m_offset;
bool m_channelAllocated;

View File

@@ -10,7 +10,7 @@
#include "PIDOutput.h"
/**
* Luminary Micro Jaguar Speed Control
* Luminary Micro / Vex Robotics Jaguar Speed Controller with PWM control
*/
class Jaguar : public SafePWM, public SpeedController
{

View File

@@ -37,6 +37,10 @@ public:
{
kTriggerButton, kTopButton, kNumButtonTypes
} ButtonType;
typedef enum
{
kLeftRumble, kRightRumble
} RumbleType;
explicit Joystick(uint32_t port);
Joystick(uint32_t port, uint32_t numAxisTypes, uint32_t numButtonTypes);
@@ -65,6 +69,14 @@ public:
virtual float GetDirectionRadians();
virtual float GetDirectionDegrees();
int GetAxisCount();
int GetButtonCount();
int GetPOVCount();
void SetRumble(RumbleType type, float value);
void SetOutput(uint8_t outputNumber, bool value);
void SetOutputs(uint32_t value);
private:
DISALLOW_COPY_AND_ASSIGN(Joystick);
void InitJoystick(uint32_t numAxisTypes, uint32_t numButtonTypes);
@@ -73,6 +85,9 @@ private:
uint32_t m_port;
uint32_t *m_axes;
uint32_t *m_buttons;
uint32_t m_outputs;
uint16_t m_leftRumble;
uint16_t m_rightRumble;
};
#endif

View File

@@ -21,6 +21,11 @@ class PowerDistributionPanel : public SensorBase {
double GetVoltage();
double GetTemperature();
double GetCurrent(uint8_t channel);
double GetTotalCurrent();
double GetTotalPower();
double GetTotalEnergy();
void ResetTotalEnergy();
void ClearStickyFaults();
};
#endif /* __WPILIB_POWER_DISTRIBUTION_PANEL_H__ */

View File

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

@@ -10,7 +10,7 @@
#include "PIDOutput.h"
/**
* CTRE Talon Speed Controller
* Cross the Road Electronics (CTRE) Talon and Talon SR Speed Controller
*/
class Talon : public SafePWM, public SpeedController
{

View File

@@ -0,0 +1,29 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "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 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

@@ -10,7 +10,10 @@
#include "PIDOutput.h"
/**
* IFI Victor Speed Controller
* Vex Robotics Victor 888 Speed Controller
*
* The Vex Robotics Victor 884 Speed Controller can also be used with this
* class but may need to be calibrated per the Victor 884 user manual.
*/
class Victor : public SafePWM, public SpeedController
{

View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "SafePWM.h"
#include "SpeedController.h"
#include "PIDOutput.h"
/**
* Vex Robotics Victor SP Speed Controller
*/
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

@@ -24,6 +24,7 @@
#include "Buttons/NetworkButton.h"
#include "CameraServer.h"
#include "CANJaguar.h"
#include "CANTalon.h"
#include "Commands/Command.h"
#include "Commands/CommandGroup.h"
#include "Commands/PIDCommand.h"
@@ -77,10 +78,12 @@
#include "SPI.h"
#include "HAL/cpp/Synchronized.hpp"
#include "Talon.h"
#include "TalonSRX.h"
#include "Task.h"
#include "Timer.h"
#include "Ultrasonic.h"
#include "Utility.h"
#include "Victor.h"
#include "VictorSP.h"
// XXX: #include "Vision/AxisCamera.h"
#include "WPIErrors.h"

View File

@@ -0,0 +1,374 @@
/**
* @brief CAN TALON SRX driver.
*
* The TALON SRX is designed to instrument all runtime signals periodically. The default periods are chosen to support 16 TALONs
* with 10ms update rate for control (throttle or setpoint). However these can be overridden with SetStatusFrameRate. @see SetStatusFrameRate
* The getters for these unsolicited signals are auto generated at the bottom of this module.
*
* Likewise most control signals are sent periodically using the fire-and-forget CAN API.
* The setters for these unsolicited signals are auto generated at the bottom of this module.
*
* Signals that are not available in an unsolicited fashion are the Close Loop gains.
* For teams that have a single profile for their TALON close loop they can use either the webpage to configure their TALONs once
* or set the PIDF,Izone,CloseLoopRampRate,etc... once in the robot application. These parameters are saved to flash so once they are
* loaded in the TALON, they will persist through power cycles and mode changes.
*
* For teams that have one or two profiles to switch between, they can use the same strategy since there are two slots to choose from
* and the ProfileSlotSelect is periodically sent in the 10 ms control frame.
*
* For teams that require changing gains frequently, they can use the soliciting API to get and set those parameters. Most likely
* they will only need to set them in a periodic fashion as a function of what motion the application is attempting.
* If this API is used, be mindful of the CAN utilization reported in the driver station.
*
* Encoder position is measured in encoder edges. Every edge is counted (similar to roboRIO 4X mode).
* Analog position is 10 bits, meaning 1024 ticks per rotation (0V => 3.3V).
* Use SetFeedbackDeviceSelect to select which sensor type you need. Once you do that you can use GetSensorPosition()
* and GetSensorVelocity(). These signals are updated on CANBus every 20ms (by default).
* If a relative sensor is selected, you can zero (or change the current value) using SetSensorPosition.
*
* Analog Input and quadrature position (and velocity) are also explicitly reported in GetEncPosition, GetEncVel, GetAnalogInWithOv, GetAnalogInVel.
* These signals are available all the time, regardless of what sensor is selected at a rate of 100ms. This allows easy instrumentation
* for "in the pits" checking of all sensors regardless of modeselect. The 100ms rate is overridable for teams who want to acquire sensor
* data for processing, not just instrumentation. Or just select the sensor using SetFeedbackDeviceSelect to get it at 20ms.
*
* Velocity is in position ticks / 100ms.
*
* All output units are in respect to duty cycle (throttle) which is -1023(full reverse) to +1023 (full forward).
* This includes demand (which specifies duty cycle when in duty cycle mode) and rampRamp, which is in throttle units per 10ms (if nonzero).
*
* Pos and velocity close loops are calc'd as
* err = target - posOrVel.
* iErr += err;
* if( (IZone!=0) and abs(err) > IZone)
* ClearIaccum()
* output = P X err + I X iErr + D X dErr + F X target
* dErr = err - lastErr
* P, I,and D gains are always positive. F can be negative.
* Motor direction can be reversed using SetRevMotDuringCloseLoopEn if sensor and motor are out of phase.
* Similarly feedback sensor can also be reversed (multiplied by -1) if you prefer the sensor to be inverted.
*
* P gain is specified in throttle per error tick. For example, a value of 102 is ~9.9% (which is 102/1023) throttle per 1
* ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
*
* I gain is specified in throttle per integrated error. For example, a value of 10 equates to ~0.99% (which is 10/1023)
* for each accumulated ADC unit(10bit) or 1 quadrature encoder edge depending on selected sensor.
* Close loop and integral accumulator runs every 1ms.
*
* D gain is specified in throttle per derivative error. For example a value of 102 equates to ~9.9% (which is 102/1023)
* per change of 1 unit (ADC or encoder) per ms.
*
* I Zone is specified in the same units as sensor position (ADC units or quadrature edges). If pos/vel error is outside of
* this value, the integrated error will auto-clear...
* if( (IZone!=0) and abs(err) > IZone)
* ClearIaccum()
* ...this is very useful in preventing integral windup and is highly recommended if using full PID to keep stability low.
*
* CloseLoopRampRate 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
*/
#ifndef CanTalonSRX_H_
#define CanTalonSRX_H_
#include "ctre.h" //BIT Defines + Typedefs
#include "CtreCanNode.h"
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
#include <map>
class CanTalonSRX : public CtreCanNode
{
private:
/** just in case user wants to modify periods of certain status frames.
* Default the vars to match the firmware default. */
uint32_t _statusRateMs[4];
//---------------------- Vars for opening a CAN stream if caller needs signals that require soliciting */
uint32_t _can_h; //!< Session handle for catching response params.
int32_t _can_stat; //!< Session handle status.
struct tCANStreamMessage _msgBuff[20];
static int const kMsgCapacity = 20;
typedef std::map<uint32_t, uint32_t> sigs_t;
sigs_t _sigs; //!< Catches signal updates that are solicited. Expect this to be very few.
void OpenSessionIfNeedBe();
void ProcessStreamMessages();
/**
* Send a one shot frame to set an arbitrary signal.
* Most signals are in the control frame so avoid using this API unless you have to.
* Use this api for...
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
*/
CTR_Code SetParamRaw(uint32_t paramEnum, int32_t rawBits);
/**
* Checks cached CAN frames and updating solicited signals.
*/
CTR_Code GetParamResponseRaw(uint32_t paramEnum, int32_t & rawBits);
public:
static const int kDefaultControlPeriodMs = 10; //!< default control update rate is 10ms.
CanTalonSRX(int deviceNumber = 0,int controlPeriodMs = kDefaultControlPeriodMs);
~CanTalonSRX();
void Set(double value);
/* mode select enumerations */
static const int kMode_DutyCycle = 0; //!< Demand is 11bit signed duty cycle [-1023,1023].
static const int kMode_PositionCloseLoop = 1; //!< Position PIDF.
static const int kMode_VelocityCloseLoop = 2; //!< Velocity PIDF.
static const int kMode_CurrentCloseLoop = 3; //!< Current close loop - not done.
static const int kMode_VoltCompen = 4; //!< Voltage Compensation Mode - not done. Demand is fixed pt target 8.8 volts.
static const int kMode_SlaveFollower = 5; //!< Demand is the 6 bit Device ID of the 'master' TALON SRX.
static const int kMode_NoDrive = 15; //!< Zero the output (honors brake/coast) regardless of demand. Might be useful if we need to change modes but can't atomically change all the signals we want in between.
/* limit switch enumerations */
static const int kLimitSwitchOverride_UseDefaultsFromFlash = 1;
static const int kLimitSwitchOverride_DisableFwd_DisableRev = 4;
static const int kLimitSwitchOverride_DisableFwd_EnableRev = 5;
static const int kLimitSwitchOverride_EnableFwd_DisableRev = 6;
static const int kLimitSwitchOverride_EnableFwd_EnableRev = 7;
/* brake override enumerations */
static const int kBrakeOverride_UseDefaultsFromFlash = 0;
static const int kBrakeOverride_OverrideCoast = 1;
static const int kBrakeOverride_OverrideBrake = 2;
/* feedback device enumerations */
static const int kFeedbackDev_DigitalQuadEnc=0;
static const int kFeedbackDev_AnalogPot=2;
static const int kFeedbackDev_AnalogEncoder=3;
static const int kFeedbackDev_CountEveryRisingEdge=4;
static const int kFeedbackDev_CountEveryFallingEdge=5;
static const int kFeedbackDev_PosIsPulseWidth=8;
/* ProfileSlotSelect enumerations*/
static const int kProfileSlotSelect_Slot0 = 0;
static const int kProfileSlotSelect_Slot1 = 1;
/* status frame rate types */
static const int kStatusFrame_General = 0;
static const int kStatusFrame_Feedback = 1;
static const int kStatusFrame_Encoder = 2;
static const int kStatusFrame_AnalogTempVbat = 3;
/**
* Signal enumeration for generic signal access.
* Although every signal is enumerated, only use this for traffic that must be solicited.
* Use the auto generated getters/setters at bottom of this header as much as possible.
*/
typedef enum _param_t{
eProfileParamSlot0_P=1,
eProfileParamSlot0_I=2,
eProfileParamSlot0_D=3,
eProfileParamSlot0_F=4,
eProfileParamSlot0_IZone=5,
eProfileParamSlot0_CloseLoopRampRate=6,
eProfileParamSlot1_P=11,
eProfileParamSlot1_I=12,
eProfileParamSlot1_D=13,
eProfileParamSlot1_F=14,
eProfileParamSlot1_IZone=15,
eProfileParamSlot1_CloseLoopRampRate=16,
eProfileParamSoftLimitForThreshold=21,
eProfileParamSoftLimitRevThreshold=22,
eProfileParamSoftLimitForEnable=23,
eProfileParamSoftLimitRevEnable=24,
eOnBoot_BrakeMode=31,
eOnBoot_LimitSwitch_Forward_NormallyClosed=32,
eOnBoot_LimitSwitch_Reverse_NormallyClosed=33,
eOnBoot_LimitSwitch_Forward_Disable=34,
eOnBoot_LimitSwitch_Reverse_Disable=35,
eFault_OverTemp=41,
eFault_UnderVoltage=42,
eFault_ForLim=43,
eFault_RevLim=44,
eFault_HardwareFailure=45,
eFault_ForSoftLim=46,
eFault_RevSoftLim=47,
eStckyFault_OverTemp=48,
eStckyFault_UnderVoltage=49,
eStckyFault_ForLim=50,
eStckyFault_RevLim=51,
eStckyFault_ForSoftLim=52,
eStckyFault_RevSoftLim=53,
eAppliedThrottle=61,
eCloseLoopErr=62,
eFeedbackDeviceSelect=63,
eRevMotDuringCloseLoopEn=64,
eModeSelect=65,
eProfileSlotSelect=66,
eRampThrottle=67,
eRevFeedbackSensor=68,
eLimitSwitchEn=69,
eLimitSwitchClosedFor=70,
eLimitSwitchClosedRev=71,
eSensorPosition=73,
eSensorVelocity=74,
eCurrent=75,
eBrakeIsEnabled=76,
eEncPosition=77,
eEncVel=78,
eEncIndexRiseEvents=79,
eQuadApin=80,
eQuadBpin=81,
eQuadIdxpin=82,
eAnalogInWithOv=83,
eAnalogInVel=84,
eTemp=85,
eBatteryV=86,
eResetCount=87,
eResetFlags=88,
eFirmVers=89,
eSettingsChanged=90,
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.
* Most signals are in the control frame so avoid using this API unless you have to.
* Use this api for...
* -A motor controller profile signal eProfileParam_XXXs. These are backed up in flash. If you are gain-scheduling then call this periodically.
* -Default brake and limit switch signals... eOnBoot_XXXs. Avoid doing this, use the override signals in the control frame.
* Talon will automatically send a PARAM_RESPONSE after the set, so GetParamResponse will catch the latest value after a couple ms.
*/
CTR_Code SetParam(param_t paramEnum, double value);
/**
* Asks TALON to immedietely respond with signal value. This API is only used for signals that are not sent periodically.
* This can be useful for reading params that rarely change like Limit Switch settings and PIDF values.
* @param param to request.
*/
CTR_Code RequestParam(param_t paramEnum);
CTR_Code GetParamResponse(param_t paramEnum, double & value);
CTR_Code GetParamResponseInt32(param_t paramEnum, int & value);
/*----- getters and setters that use param request/response. These signals are backed up in flash and will survive a power cycle. ---------*/
/*----- If your application requires changing these values consider using both slots and switch between slot0 <=> slot1. ------------------*/
/*----- If your application requires changing these signals frequently then it makes sense to leverage this API. --------------------------*/
/*----- Getters don't block, so it may require several calls to get the latest value. --------------------------*/
CTR_Code SetPgain(unsigned slotIdx,double gain);
CTR_Code SetIgain(unsigned slotIdx,double gain);
CTR_Code SetDgain(unsigned slotIdx,double gain);
CTR_Code SetFgain(unsigned slotIdx,double gain);
CTR_Code SetIzone(unsigned slotIdx,int zone);
CTR_Code SetCloseLoopRampRate(unsigned slotIdx,int closeLoopRampRate);
CTR_Code SetSensorPosition(int pos);
CTR_Code SetForwardSoftLimit(int forwardLimit);
CTR_Code SetReverseSoftLimit(int reverseLimit);
CTR_Code SetForwardSoftEnable(int enable);
CTR_Code SetReverseSoftEnable(int enable);
CTR_Code GetPgain(unsigned slotIdx,double & gain);
CTR_Code GetIgain(unsigned slotIdx,double & gain);
CTR_Code GetDgain(unsigned slotIdx,double & gain);
CTR_Code GetFgain(unsigned slotIdx,double & gain);
CTR_Code GetIzone(unsigned slotIdx,int & zone);
CTR_Code GetCloseLoopRampRate(unsigned slotIdx,int & closeLoopRampRate);
CTR_Code GetForwardSoftLimit(int & forwardLimit);
CTR_Code GetReverseSoftLimit(int & reverseLimit);
CTR_Code GetForwardSoftEnable(int & enable);
CTR_Code GetReverseSoftEnable(int & enable);
/**
* Change the periodMs of a TALON's status frame. See kStatusFrame_* enums for what's available.
*/
CTR_Code SetStatusFrameRate(unsigned frameEnum, unsigned periodMs);
/**
* Clear all sticky faults in TALON.
*/
CTR_Code ClearStickyFaults();
/*------------------------ auto generated. This API is optimal since it uses the fire-and-forget CAN interface ----------------------*/
/*------------------------ These signals should cover the majority of all use cases. ----------------------------------*/
CTR_Code GetFault_OverTemp(int &param);
CTR_Code GetFault_UnderVoltage(int &param);
CTR_Code GetFault_ForLim(int &param);
CTR_Code GetFault_RevLim(int &param);
CTR_Code GetFault_HardwareFailure(int &param);
CTR_Code GetFault_ForSoftLim(int &param);
CTR_Code GetFault_RevSoftLim(int &param);
CTR_Code GetStckyFault_OverTemp(int &param);
CTR_Code GetStckyFault_UnderVoltage(int &param);
CTR_Code GetStckyFault_ForLim(int &param);
CTR_Code GetStckyFault_RevLim(int &param);
CTR_Code GetStckyFault_ForSoftLim(int &param);
CTR_Code GetStckyFault_RevSoftLim(int &param);
CTR_Code GetAppliedThrottle(int &param);
CTR_Code GetCloseLoopErr(int &param);
CTR_Code GetFeedbackDeviceSelect(int &param);
CTR_Code GetModeSelect(int &param);
CTR_Code GetLimitSwitchEn(int &param);
CTR_Code GetLimitSwitchClosedFor(int &param);
CTR_Code GetLimitSwitchClosedRev(int &param);
CTR_Code GetSensorPosition(int &param);
CTR_Code GetSensorVelocity(int &param);
CTR_Code GetCurrent(double &param);
CTR_Code GetBrakeIsEnabled(int &param);
CTR_Code GetEncPosition(int &param);
CTR_Code GetEncVel(int &param);
CTR_Code GetEncIndexRiseEvents(int &param);
CTR_Code GetQuadApin(int &param);
CTR_Code GetQuadBpin(int &param);
CTR_Code GetQuadIdxpin(int &param);
CTR_Code GetAnalogInWithOv(int &param);
CTR_Code GetAnalogInVel(int &param);
CTR_Code GetTemp(double &param);
CTR_Code GetBatteryV(double &param);
CTR_Code GetResetCount(int &param);
CTR_Code GetResetFlags(int &param);
CTR_Code GetFirmVers(int &param);
CTR_Code SetDemand(int param);
CTR_Code SetOverrideLimitSwitchEn(int param);
CTR_Code SetFeedbackDeviceSelect(int param);
CTR_Code SetRevMotDuringCloseLoopEn(int param);
CTR_Code SetOverrideBrakeType(int param);
CTR_Code SetModeSelect(int param);
CTR_Code 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

@@ -0,0 +1,116 @@
#ifndef CtreCanNode_H_
#define CtreCanNode_H_
#include "ctre.h" //BIT Defines + Typedefs
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
#include <pthread.h>
#include <map>
#include <string.h> // memcpy
#include <sys/time.h>
class CtreCanNode
{
public:
CtreCanNode(UINT8 deviceNumber);
~CtreCanNode();
UINT8 GetDeviceNumber()
{
return _deviceNumber;
}
protected:
template <typename T> class txTask{
public:
uint32_t arbId;
T * toSend;
T * operator -> ()
{
return toSend;
}
T & operator*()
{
return *toSend;
}
bool IsEmpty()
{
if(toSend == 0)
return true;
return false;
}
};
template <typename T> class recMsg{
public:
uint32_t arbId;
uint8_t bytes[8];
CTR_Code err;
T * operator -> ()
{
return (T *)bytes;
}
T & operator*()
{
return *(T *)bytes;
}
};
UINT8 _deviceNumber;
void RegisterRx(uint32_t arbId);
void RegisterTx(uint32_t arbId, uint32_t periodMs);
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
void FlushTx(uint32_t arbId);
template<typename T> txTask<T> GetTx(uint32_t arbId)
{
txTask<T> retval = {0};
txJobs_t::iterator i = _txJobs.find(arbId);
if(i != _txJobs.end()){
retval.arbId = i->second.arbId;
retval.toSend = (T*)i->second.toSend;
}
return retval;
}
template<class T> void FlushTx(T & par)
{
FlushTx(par.arbId);
}
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
{
recMsg<T> retval;
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
return retval;
}
private:
class txJob_t {
public:
uint32_t arbId;
uint8_t toSend[8];
uint32_t periodMs;
};
class rxEvent_t{
public:
uint8_t bytes[8];
struct timespec time;
rxEvent_t()
{
bytes[0] = 0;
bytes[1] = 0;
bytes[2] = 0;
bytes[3] = 0;
bytes[4] = 0;
bytes[5] = 0;
bytes[6] = 0;
bytes[7] = 0;
}
};
typedef std::map<uint32_t,txJob_t> txJobs_t;
txJobs_t _txJobs;
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
rxRxEvents_t _rxRxEvents;
};
#endif

View File

@@ -0,0 +1,50 @@
#ifndef GLOBAL_H
#define GLOBAL_H
//Bit Defines
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
//Signed
typedef signed char INT8;
typedef signed short INT16;
typedef signed int INT32;
typedef signed long long INT64;
//Unsigned
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
//Other
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef enum {
CTR_OKAY, //!< No Error - Function executed as expected
CTR_RxTimeout, //!< CAN frame has not been received within specified period of time.
CTR_TxTimeout, //!< Not used.
CTR_InvalidParamValue, //!< Caller passed an invalid param
CTR_UnexpectedArbId, //!< Specified CAN Id is invalid.
CTR_TxFailed, //!< Could not transmit the CAN frame.
CTR_SigNotUpdated, //!< Have not received an value response for signal.
}CTR_Code;
#endif

View File

@@ -1,28 +1,29 @@
#include "AnalogPotentiometer.h"
#include "ControllerPower.h"
/**
* Common initialization code called by all constructors.
*/
void AnalogPotentiometer::initPot(AnalogInput *input, double scale, double offset) {
m_scale = scale;
void AnalogPotentiometer::initPot(AnalogInput *input, double fullRange, double offset) {
m_fullRange = fullRange;
m_offset = offset;
m_analog_input = input;
}
AnalogPotentiometer::AnalogPotentiometer(int channel, double scale, double offset) {
AnalogPotentiometer::AnalogPotentiometer(int channel, double fullRange, double offset) {
m_init_analog_input = true;
initPot(new AnalogInput(channel), scale, offset);
initPot(new AnalogInput(channel), fullRange, offset);
}
AnalogPotentiometer::AnalogPotentiometer(AnalogInput *input, double scale, double offset) {
AnalogPotentiometer::AnalogPotentiometer(AnalogInput *input, double fullRange, double offset) {
m_init_analog_input = false;
initPot(input, scale, offset);
initPot(input, fullRange, offset);
}
AnalogPotentiometer::AnalogPotentiometer(AnalogInput &input, double scale, double offset) {
AnalogPotentiometer::AnalogPotentiometer(AnalogInput &input, double fullRange, double offset) {
m_init_analog_input = false;
initPot(&input, scale, offset);
initPot(&input, fullRange, offset);
}
AnalogPotentiometer::~AnalogPotentiometer() {
@@ -33,12 +34,12 @@ AnalogPotentiometer::~AnalogPotentiometer() {
}
/**
* Get the current reading of the potentiomere.
* Get the current reading of the potentiometer.
*
* @return The current position of the potentiometer.
*/
double AnalogPotentiometer::Get() {
return m_analog_input->GetVoltage() * m_scale + m_offset;
return (m_analog_input->GetVoltage() / ControllerPower::GetVoltage5V()) * m_fullRange + m_offset;
}
/**

View File

@@ -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;
@@ -342,8 +342,9 @@ void CANJaguar::Set(float outputValue, uint8_t syncGroup)
dataSize = packFXP8_8(dataBuffer, outputValue);
}
break;
default:
return;
default:
wpi_setWPIErrorWithContext(IncompatibleMode, "The Jaguar only supports Current, Voltage, Position, Speed, and Percent (Throttle) modes.");
return;
}
if (syncGroup != 0)
{
@@ -565,7 +566,7 @@ void CANJaguar::setupPeriodicStatus() {
LM_PSTAT_END
};
dataSize = packint16_t(data, kSendMessagePeriod / 10);
dataSize = packint16_t(data, kSendMessagePeriod);
sendMessage(LM_API_PSTAT_PER_EN_S0, data, dataSize);
sendMessage(LM_API_PSTAT_PER_EN_S1, data, dataSize);
sendMessage(LM_API_PSTAT_PER_EN_S2, data, dataSize);
@@ -1144,6 +1145,7 @@ void CANJaguar::SetP(double p)
{
case kPercentVbus:
case kVoltage:
case kFollower:
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
break;
case kSpeed:
@@ -1178,6 +1180,7 @@ void CANJaguar::SetI(double i)
{
case kPercentVbus:
case kVoltage:
case kFollower:
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
break;
case kSpeed:
@@ -1212,6 +1215,7 @@ void CANJaguar::SetD(double d)
{
case kPercentVbus:
case kVoltage:
case kFollower:
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
break;
case kSpeed:
@@ -1313,6 +1317,9 @@ void CANJaguar::EnableControl(double encoderInitialPosition)
case kVoltage:
sendMessage(LM_API_VCOMP_T_EN, dataBuffer, dataSize);
break;
default:
wpi_setWPIErrorWithContext(IncompatibleMode, "The Jaguar only supports Current, Voltage, Position, Speed, and Percent (Throttle) modes.");
return;
}
m_controlEnabled = true;
@@ -1353,7 +1360,7 @@ void CANJaguar::DisableControl()
*/
void CANJaguar::SetPercentMode()
{
ChangeControlMode(kPercentVbus);
SetControlMode(kPercentVbus);
SetPositionReference(LM_REF_NONE);
SetSpeedReference(LM_REF_NONE);
}
@@ -1368,7 +1375,7 @@ void CANJaguar::SetPercentMode()
*/
void CANJaguar::SetPercentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
{
ChangeControlMode(kPercentVbus);
SetControlMode(kPercentVbus);
SetPositionReference(LM_REF_NONE);
SetSpeedReference(LM_REF_ENCODER);
ConfigEncoderCodesPerRev(codesPerRev);
@@ -1384,7 +1391,7 @@ void CANJaguar::SetPercentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
*/
void CANJaguar::SetPercentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev)
{
ChangeControlMode(kPercentVbus);
SetControlMode(kPercentVbus);
SetPositionReference(LM_REF_ENCODER);
SetSpeedReference(LM_REF_QUAD_ENCODER);
ConfigEncoderCodesPerRev(codesPerRev);
@@ -1399,7 +1406,7 @@ void CANJaguar::SetPercentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
*/
void CANJaguar::SetPercentMode(CANJaguar::PotentiometerStruct)
{
ChangeControlMode(kPercentVbus);
SetControlMode(kPercentVbus);
SetPositionReference(LM_REF_POT);
SetSpeedReference(LM_REF_NONE);
ConfigPotentiometerTurns(1);
@@ -1415,7 +1422,7 @@ void CANJaguar::SetPercentMode(CANJaguar::PotentiometerStruct)
*/
void CANJaguar::SetCurrentMode(double p, double i, double d)
{
ChangeControlMode(kCurrent);
SetControlMode(kCurrent);
SetPositionReference(LM_REF_NONE);
SetSpeedReference(LM_REF_NONE);
SetPID(p, i, d);
@@ -1433,7 +1440,7 @@ void CANJaguar::SetCurrentMode(double p, double i, double d)
*/
void CANJaguar::SetCurrentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, double p, double i, double d)
{
ChangeControlMode(kCurrent);
SetControlMode(kCurrent);
SetPositionReference(LM_REF_NONE);
SetSpeedReference(LM_REF_NONE);
ConfigEncoderCodesPerRev(codesPerRev);
@@ -1452,7 +1459,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, d
*/
void CANJaguar::SetCurrentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
{
ChangeControlMode(kCurrent);
SetControlMode(kCurrent);
SetPositionReference(LM_REF_ENCODER);
SetSpeedReference(LM_REF_QUAD_ENCODER);
ConfigEncoderCodesPerRev(codesPerRev);
@@ -1471,7 +1478,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
*/
void CANJaguar::SetCurrentMode(CANJaguar::PotentiometerStruct, double p, double i, double d)
{
ChangeControlMode(kCurrent);
SetControlMode(kCurrent);
SetPositionReference(LM_REF_POT);
SetSpeedReference(LM_REF_NONE);
ConfigPotentiometerTurns(1);
@@ -1491,7 +1498,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::PotentiometerStruct, double p, double
*/
void CANJaguar::SetSpeedMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, double p, double i, double d)
{
ChangeControlMode(kSpeed);
SetControlMode(kSpeed);
SetPositionReference(LM_REF_NONE);
SetSpeedReference(LM_REF_ENCODER);
ConfigEncoderCodesPerRev(codesPerRev);
@@ -1510,7 +1517,7 @@ void CANJaguar::SetSpeedMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, dou
*/
void CANJaguar::SetSpeedMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
{
ChangeControlMode(kSpeed);
SetControlMode(kSpeed);
SetPositionReference(LM_REF_ENCODER);
SetSpeedReference(LM_REF_QUAD_ENCODER);
ConfigEncoderCodesPerRev(codesPerRev);
@@ -1530,7 +1537,7 @@ void CANJaguar::SetSpeedMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev,
*/
void CANJaguar::SetPositionMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
{
ChangeControlMode(kPosition);
SetControlMode(kPosition);
SetPositionReference(LM_REF_ENCODER);
ConfigEncoderCodesPerRev(codesPerRev);
SetPID(p, i, d);
@@ -1545,7 +1552,7 @@ void CANJaguar::SetPositionMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerR
*/
void CANJaguar::SetPositionMode(CANJaguar::PotentiometerStruct, double p, double i, double d)
{
ChangeControlMode(kPosition);
SetControlMode(kPosition);
SetPositionReference(LM_REF_POT);
ConfigPotentiometerTurns(1);
SetPID(p, i, d);
@@ -1557,7 +1564,7 @@ void CANJaguar::SetPositionMode(CANJaguar::PotentiometerStruct, double p, double
*/
void CANJaguar::SetVoltageMode()
{
ChangeControlMode(kVoltage);
SetControlMode(kVoltage);
SetPositionReference(LM_REF_NONE);
SetSpeedReference(LM_REF_NONE);
}
@@ -1572,7 +1579,7 @@ void CANJaguar::SetVoltageMode()
*/
void CANJaguar::SetVoltageMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
{
ChangeControlMode(kVoltage);
SetControlMode(kVoltage);
SetPositionReference(LM_REF_NONE);
SetSpeedReference(LM_REF_ENCODER);
ConfigEncoderCodesPerRev(codesPerRev);
@@ -1588,7 +1595,7 @@ void CANJaguar::SetVoltageMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
*/
void CANJaguar::SetVoltageMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev)
{
ChangeControlMode(kVoltage);
SetControlMode(kVoltage);
SetPositionReference(LM_REF_ENCODER);
SetSpeedReference(LM_REF_QUAD_ENCODER);
ConfigEncoderCodesPerRev(codesPerRev);
@@ -1603,7 +1610,7 @@ void CANJaguar::SetVoltageMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
*/
void CANJaguar::SetVoltageMode(CANJaguar::PotentiometerStruct)
{
ChangeControlMode(kVoltage);
SetControlMode(kVoltage);
SetPositionReference(LM_REF_POT);
SetSpeedReference(LM_REF_NONE);
ConfigPotentiometerTurns(1);
@@ -1618,11 +1625,14 @@ void CANJaguar::SetVoltageMode(CANJaguar::PotentiometerStruct)
*
* @param controlMode The new mode.
*/
void CANJaguar::ChangeControlMode(ControlMode controlMode)
void CANJaguar::SetControlMode(ControlMode controlMode)
{
// Disable the previous mode
DisableControl();
if (controlMode == kFollower)
wpi_setWPIErrorWithContext(IncompatibleMode, "The Jaguar only supports Current, Voltage, Position, Speed, and Percent (Throttle) modes.");
// Update the local mode
m_controlMode = controlMode;
m_controlModeVerified = false;

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,7 @@
// set the logging level
TLogLevel dsLogLevel = logDEBUG;
const double JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL = 1.0;
#define DS_LOG(level) \
if (level > dsLogLevel) ; \
@@ -27,31 +28,28 @@ 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
*/
DriverStation::DriverStation()
: m_statusDataSemaphore (initializeMutexNormal())
, m_task ("DriverStation", (FUNCPTR)DriverStation::InitTask)
: m_task ("DriverStation", (FUNCPTR)DriverStation::InitTask)
, m_newControlData(0)
, m_packetDataAvailableMultiWait(0)
, m_waitForDataSem(0)
, m_approxMatchTimeOffset(-1.0)
, m_userInDisabled(false)
, m_userInAutonomous(false)
, m_userInTeleop(false)
, m_userInTest(false)
, m_nextMessageTime(0)
{
memset(&m_controlWord, 0, sizeof(m_controlWord));
// All joysticks should default to having zero axes and povs, so
// 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);
@@ -77,7 +75,6 @@ DriverStation::DriverStation()
DriverStation::~DriverStation()
{
m_task.Stop();
deleteMutex(m_statusDataSemaphore);
m_instance = NULL;
deleteMultiWait(m_waitForDataSem);
// Unregister our semaphore.
@@ -97,9 +94,10 @@ void DriverStation::Run()
int period = 0;
while (true)
{
takeMultiWait(m_packetDataAvailableMultiWait, m_packetDataAvailableMutex, 0);
takeMultiWait(m_packetDataAvailableMultiWait, m_packetDataAvailableMutex, 0);
GetData();
giveMultiWait(m_waitForDataSem);
if (++period >= 4)
{
MotorSafetyHelper::CheckMotors();
@@ -135,36 +133,13 @@ DriverStation* DriverStation::GetInstance()
*/
void DriverStation::GetData()
{
static bool lastEnabled = false;
// Get the status data
HALGetControlWord(&m_controlWord);
// Get the location/alliance data
HALGetAllianceStation(&m_allianceStationID);
// Get the status of all of the joysticks
for(uint8_t stick = 0; stick < kJoystickPorts; stick++) {
uint8_t count;
HALGetJoystickAxes(stick, &m_joystickAxes[stick]);
HALGetJoystickPOVs(stick, &m_joystickPOVs[stick]);
HALGetJoystickButtons(stick, &m_joystickButtons[stick], &count);
HALGetJoystickButtons(stick, &m_joystickButtons[stick]);
}
if (!lastEnabled && IsEnabled())
{
// If starting teleop, assume that autonomous just took up 15 seconds
if (IsAutonomous())
m_approxMatchTimeOffset = Timer::GetFPGATimestamp();
else
m_approxMatchTimeOffset = Timer::GetFPGATimestamp() - 15.0;
}
else if (lastEnabled && !IsEnabled())
{
m_approxMatchTimeOffset = -1.0;
}
lastEnabled = IsEnabled();
giveSemaphore(m_newControlData);
}
@@ -182,6 +157,65 @@ float DriverStation::GetBatteryVoltage()
return voltage;
}
void DriverStation::ReportJoystickUnpluggedError(std::string message) {
double currentTime = Timer::GetFPGATimestamp();
if (currentTime > m_nextMessageTime) {
ReportError(message);
m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;
}
}
/** Returns the number of axis on a given joystick port
*
* @param stick The joystick port number
* @return the number of axis on the indicated joystick
*/
int DriverStation::GetStickAxisCount(uint32_t stick)
{
if (stick >= kJoystickPorts)
{
wpi_setWPIError(BadJoystickIndex);
return 0;
}
HALJoystickAxes joystickAxes;
HALGetJoystickAxes(stick, &joystickAxes);
return joystickAxes.count;
}
/** Returns the number of POVs on a given joystick port
*
* @param stick The joystick port number
* @return thenumber of POVs on the indicated joystick
*/
int DriverStation::GetStickPOVCount(uint32_t stick)
{
if (stick >= kJoystickPorts)
{
wpi_setWPIError(BadJoystickIndex);
return 0;
}
HALJoystickPOVs joystickPOVs;
HALGetJoystickPOVs(stick, &joystickPOVs);
return joystickPOVs.count;
}
/** Returns the number of buttons on a given joystick port
*
* @param stick The joystick port number
* @return The number of buttons on the indicated joystick
*/
int DriverStation::GetStickButtonCount(uint32_t stick)
{
if (stick >= kJoystickPorts)
{
wpi_setWPIError(BadJoystickIndex);
return 0;
}
HALJoystickButtons joystickButtons;
HALGetJoystickButtons(stick, &joystickButtons);
return joystickButtons.count;
}
/**
* Get the value of the axis on a joystick.
* This depends on the mapping of the joystick connected to the specified port.
@@ -203,7 +237,7 @@ float DriverStation::GetStickAxis(uint32_t stick, uint32_t axis)
if (axis >= kMaxJoystickAxes)
wpi_setWPIError(BadJoystickAxis);
else
ReportError("WARNING: Joystick Axis missing, check if all controllers are plugged in\n");
ReportJoystickUnpluggedError("WARNING: Joystick Axis missing, check if all controllers are plugged in\n");
return 0.0f;
}
@@ -236,7 +270,7 @@ int DriverStation::GetStickPOV(uint32_t stick, uint32_t pov) {
if (pov >= kMaxJoystickPOVs)
wpi_setWPIError(BadJoystickAxis);
else
ReportError("WARNING: Joystick POV missing, check if all controllers are plugged in\n");
ReportJoystickUnpluggedError("WARNING: Joystick POV missing, check if all controllers are plugged in\n");
return 0;
}
@@ -245,50 +279,74 @@ int DriverStation::GetStickPOV(uint32_t stick, uint32_t pov) {
/**
* The state of the buttons on the joystick.
* 12 buttons (4 msb are unused) from the joystick.
*
* @param stick The joystick to read.
* @return The state of the buttons on the joystick.
*/
short DriverStation::GetStickButtons(uint32_t stick)
bool DriverStation::GetStickButton(uint32_t stick, uint8_t button)
{
if (stick >= kJoystickPorts)
{
wpi_setWPIError(BadJoystickIndex);
return 0;
return false;
}
return m_joystickButtons[stick];
if(button > m_joystickButtons[stick].count)
{
ReportJoystickUnpluggedError("WARNING: Joystick Button missing, check if all controllers are plugged in\n");
return false;
}
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()
{
return m_controlWord.enabled;
HALControlWord controlWord;
memset(&controlWord, 0, sizeof(controlWord));
HALGetControlWord(&controlWord);
return controlWord.enabled && controlWord.dsAttached;
}
bool DriverStation::IsDisabled()
{
return !m_controlWord.enabled;
HALControlWord controlWord;
memset(&controlWord, 0, sizeof(controlWord));
HALGetControlWord(&controlWord);
return !(controlWord.enabled && controlWord.dsAttached);
}
bool DriverStation::IsAutonomous()
{
return m_controlWord.autonomous;
HALControlWord controlWord;
memset(&controlWord, 0, sizeof(controlWord));
HALGetControlWord(&controlWord);
return controlWord.autonomous;
}
bool DriverStation::IsOperatorControl()
{
return !(m_controlWord.autonomous || m_controlWord.test);
HALControlWord controlWord;
memset(&controlWord, 0, sizeof(controlWord));
HALGetControlWord(&controlWord);
return !(controlWord.autonomous || controlWord.test);
}
bool DriverStation::IsTest()
{
return m_controlWord.test;
HALControlWord controlWord;
HALGetControlWord(&controlWord);
return controlWord.test;
}
bool DriverStation::IsDSAttached()
{
HALControlWord controlWord;
memset(&controlWord, 0, sizeof(controlWord));
HALGetControlWord(&controlWord);
return controlWord.dsAttached;
}
@@ -327,7 +385,9 @@ bool DriverStation::IsNewControlData()
*/
bool DriverStation::IsFMSAttached()
{
return m_controlWord.fmsAttached;
HALControlWord controlWord;
HALGetControlWord(&controlWord);
return controlWord.fmsAttached;
}
/**
@@ -337,7 +397,9 @@ bool DriverStation::IsFMSAttached()
*/
DriverStation::Alliance DriverStation::GetAlliance()
{
switch(m_allianceStationID)
HALAllianceStationID allianceStationID;
HALGetAllianceStation(&allianceStationID);
switch(allianceStationID)
{
case kHALAllianceStationID_red1:
case kHALAllianceStationID_red2:
@@ -359,7 +421,9 @@ DriverStation::Alliance DriverStation::GetAlliance()
*/
uint32_t DriverStation::GetLocation()
{
switch(m_allianceStationID)
HALAllianceStationID allianceStationID;
HALGetAllianceStation(&allianceStationID);
switch(allianceStationID)
{
case kHALAllianceStationID_red1:
case kHALAllianceStationID_blue1:
@@ -397,9 +461,9 @@ void DriverStation::WaitForData()
*/
double DriverStation::GetMatchTime()
{
if (m_approxMatchTimeOffset < 0.0)
return 0.0;
return Timer::GetFPGATimestamp() - m_approxMatchTimeOffset;
float matchTime;
HALGetMatchTime(&matchTime);
return (double)matchTime;
}
/**

View File

@@ -31,6 +31,9 @@ Joystick::Joystick(uint32_t port)
, m_port (port)
, m_axes (NULL)
, m_buttons (NULL)
, m_outputs (0)
, m_leftRumble (0)
, m_rightRumble (0)
{
InitJoystick(kNumAxisTypes, kNumButtonTypes);
@@ -228,7 +231,7 @@ bool Joystick::GetBumper(JoystickHand hand)
**/
bool Joystick::GetRawButton(uint32_t button)
{
return ((0x1 << (button-1)) & m_ds->GetStickButtons(m_port)) != 0;
return m_ds->GetStickButton(m_port, button);
}
/**
@@ -259,6 +262,37 @@ bool Joystick::GetButton(ButtonType button)
}
}
/**
* Get the number of axis for a joystick
*
* @return the number of axis for the current joystick
*/
int Joystick::GetAxisCount()
{
return m_ds->GetStickAxisCount(m_port);
}
/**
* Get the number of axis for a joystick
*
* @return the number of buttons on the current joystick
*/
int Joystick::GetButtonCount()
{
return m_ds->GetStickButtonCount(m_port);
}
/**
* Get the number of axis for a joystick
*
* @return then umber of POVs for the current joystick
*/
int Joystick::GetPOVCount()
{
return m_ds->GetStickPOVCount(m_port);
}
/**
* Get the channel currently associated with the specified axis.
*
@@ -305,7 +339,7 @@ float Joystick::GetDirectionRadians(){
* Get the direction of the vector formed by the joystick and its origin
* in degrees
*
* uses acos(-1) to represent Pi due to absence of readily accessable Pi
* uses acos(-1) to represent Pi due to absence of readily accessible Pi
* constant in C++
*
* @return The direction of the vector in degrees
@@ -313,3 +347,42 @@ float Joystick::GetDirectionRadians(){
float Joystick::GetDirectionDegrees(){
return (180/acos(-1))*GetDirectionRadians();
}
/**
* Set the rumble output for the joystick. The DS currently supports 2 rumble values,
* left rumble and right rumble
* @param type Which rumble value to set
* @param value The normalized value (0 to 1) to set the rumble to
*/
void Joystick::SetRumble(RumbleType type, float value) {
if (value < 0)
value = 0;
else if (value > 1)
value = 1;
if (type == kLeftRumble)
m_leftRumble = value*65535;
else
m_rightRumble = value*65535;
HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
}
/**
* Set a single HID output value for the joystick.
* @param outputNumber The index of the output to set (1-32)
* @param value The value to set the output to
*/
void Joystick::SetOutput(uint8_t outputNumber, bool value) {
m_outputs = (m_outputs & ~(1 << (outputNumber-1))) | (value << (outputNumber-1));
HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
}
/**
* Set all HID output values for the joystick.
* @param value The 32 bit output value (1 bit for each output)
*/
void Joystick::SetOutputs(uint32_t value) {
m_outputs = value;
HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
}

View File

@@ -69,3 +69,80 @@ PowerDistributionPanel::GetCurrent(uint8_t channel) {
return current;
}
/**
* @return The the total current drawn from the PDP channels in Amperes
*/
double
PowerDistributionPanel::GetTotalCurrent() {
int32_t status = 0;
double current = getPDPTotalCurrent(&status);
if(status) {
wpi_setWPIErrorWithContext(Timeout, "");
}
return current;
}
/**
* @return The the total power drawn from the PDP channels in Joules
*/
double
PowerDistributionPanel::GetTotalPower() {
int32_t status = 0;
double power = getPDPTotalPower(&status);
if(status) {
wpi_setWPIErrorWithContext(Timeout, "");
}
return power;
}
/**
* @return The the total energy drawn from the PDP channels in Watts
*/
double
PowerDistributionPanel::GetTotalEnergy() {
int32_t status = 0;
double energy = getPDPTotalEnergy(&status);
if(status) {
wpi_setWPIErrorWithContext(Timeout, "");
}
return energy;
}
/**
* Reset the total energy drawn from the PDP
* @see PowerDistributionPanel#GetTotalEnergy
*/
void
PowerDistributionPanel::ResetTotalEnergy() {
int32_t status = 0;
resetPDPTotalEnergy(&status);
if(status) {
wpi_setWPIErrorWithContext(Timeout, "");
}
}
/**
* Remove all of the fault flags on the PDP
*/
void
PowerDistributionPanel::ClearStickyFaults() {
int32_t status = 0;
clearPDPStickyFaults(&status);
if(status) {
wpi_setWPIErrorWithContext(Timeout, "");
}
}

View File

@@ -735,4 +735,5 @@ void RobotDrive::StopMotor()
if (m_frontRightMotor != NULL) m_frontRightMotor->Disable();
if (m_rearLeftMotor != NULL) m_rearLeftMotor->Disable();
if (m_rearRightMotor != NULL) m_rearRightMotor->Disable();
m_safetyHelper->Feed();
}

View File

@@ -0,0 +1,83 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#include "TalonSRX.h"
//#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);
}
/**
* @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

@@ -0,0 +1,83 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#include "VictorSP.h"
//#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);
}
/**
* @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

@@ -10,7 +10,7 @@
#include "TestBench.h"
#include "gtest/gtest.h"
static const double kScale = 54.0;
static const double kScale = 270.0;
static const double kVoltage = 3.33;
static const double kAngle = 180.0;
@@ -40,6 +40,6 @@ TEST_F(AnalogPotentiometerTest, TestInitialSettings) {
TEST_F(AnalogPotentiometerTest,TestRangeValues) {
m_fakePot->SetVoltage(kVoltage);
Wait(0.1);
EXPECT_NEAR(kAngle, m_pot->Get(), 1.0)
EXPECT_NEAR(kAngle, m_pot->Get(), 2.0)
<< "The potentiometer did not measure the correct angle.";
}

View File

@@ -161,12 +161,12 @@ TEST_F(CANJaguarTest, Disable) {
* behaves like it should in that control mode.
*/
TEST_F(CANJaguarTest, BrownOut) {
double setpoint = 10.0;
/* Set the jaguar to quad encoder position mode */
m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 10.0f, 0.1f, 0.0f);
m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 20.0f, 0.01f, 0.0f);
m_jaguar->EnableControl();
SetJaguar(kMotorTime, 0.0);
double setpoint = m_jaguar->GetPosition() + 1.0f;
/* Turn the spike off and on again */
m_spike->Set(Relay::kOff);
@@ -274,7 +274,7 @@ TEST_F(CANJaguarTest, SpeedModeWorks) {
m_jaguar->SetSpeedMode(CANJaguar::QuadEncoder, 360, 0.1f, 0.003f, 0.01f);
m_jaguar->EnableControl();
constexpr float speed = 200.0f;
constexpr float speed = 100.0f;
SetJaguar(kMotorTime, speed);
EXPECT_NEAR(speed, m_jaguar->GetSpeed(), kEncoderSpeedTolerance);
@@ -285,9 +285,9 @@ TEST_F(CANJaguarTest, SpeedModeWorks) {
* the Jaguar.
*/
TEST_F(CANJaguarTest, PositionModeWorks) {
m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 10.0f, 0.1f, 0.0f);
m_jaguar->SetPositionMode(CANJaguar::QuadEncoder, 360, 15.0f, 0.02f, 0.0f);
double setpoint = m_jaguar->GetPosition() + 10.0f;
double setpoint = m_jaguar->GetPosition() + 1.0f;
m_jaguar->EnableControl();

View File

@@ -0,0 +1,68 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#include "WPILib.h"
#include "gtest/gtest.h"
#include "TestBench.h"
#include "ctre/CanTalonSRX.h"
const int deviceId = 0;
TEST(CANTalonTest, QuickTest) {
double throttle = 0.1;
CANTalon talon(deviceId);
talon.SetControlMode(CANSpeedController::kPercentVbus);
talon.EnableControl();
talon.Set(throttle);
Wait(0.25);
EXPECT_NEAR(talon.Get(), throttle, 5e-3);
talon.Set(-throttle);
Wait(0.25);
EXPECT_NEAR(talon.Get(), -throttle, 5e-3);
talon.Disable();
Wait(0.1);
EXPECT_FLOAT_EQ(talon.Get(), 0.0);
}
TEST(CANTalonTest, SetGetPID) {
// Tests that we can actually set and get PID values as intended.
CANTalon talon(deviceId);
double p = 0.05, i = 0.098, d = 1.23;
talon.SetPID(p, i , d);
// Wait(0.03);
EXPECT_NEAR(p, talon.GetP(), 1e-5);
EXPECT_NEAR(i, talon.GetI(), 1e-5);
EXPECT_NEAR(d, talon.GetD(), 1e-5);
// Test with new values in case the talon was already set to the previous ones.
p = 0.15;
i = 0.198;
d = 1.03;
talon.SetPID(p, i , d);
// Wait(0.03);
EXPECT_NEAR(p, talon.GetP(), 1e-5);
EXPECT_NEAR(i, talon.GetI(), 1e-5);
EXPECT_NEAR(d, talon.GetD(), 1e-5);
}
TEST(CANTalonTest, DISABLED_PositionModeWorks) {
CANTalon talon(deviceId);
talon.SetFeedbackDevice(CANTalon::AnalogPot);
talon.SetControlMode(CANSpeedController::kPosition);
Wait(0.1);
double p = 2;
double i = 0.00;
double d = 0.00;
Wait(0.2);
talon.SetControlMode(CANSpeedController::kPosition);
talon.SetFeedbackDevice(CANTalon::AnalogPot);
talon.SetPID(p, i, d);
Wait(0.2);
talon.Set(100);
Wait(100);
talon.Disable();
EXPECT_NEAR(talon.Get(), 500, 1000);
}

Some files were not shown because too many files have changed in this diff Show More