Compare commits

...

61 Commits

Author SHA1 Message Date
Joe Ross
da2ea9ea87 remove/fix references to cRIO documentation.
Edited comments related to sidecar, breakout, 9472. Some references were
to unused methods in simulation that were removed.

Change-Id: I99b6fe9e8cb982831ffbf29177f84e2f9f71ef47
2014-08-30 08:56:06 -07:00
Jonathan Leitschuh
b1ace79379 Fixes the MotorEncoderTest sometimes failing because a counter registers movement from the jaguar after reset.
Change-Id: I65b24e59a902637b19b24c08f0a02b86621c5590
2014-08-29 16:46:08 -04:00
Jonathan Leitschuh
2a8ade093a Adds the ability to run test classes with --repeat rule.
Fixes a bug in several tests where --repeat wouldn't work due to multiple teardown calls.

Change-Id: I26f9350e9c7da6e9b0aefd1ecefb7e8d8975a641
2014-08-29 16:34:03 -04:00
Brad Miller (WPI)
b7458e7ba6 Merge "Make Talon the default speed controller for RobotDrive" 2014-08-29 10:53:30 -07:00
Thomas Clark
3fddee51c2 Make Talon the default speed controller for RobotDrive
Change-Id: I87047e11efb26f5081a3e23dc8f36fa9bb76a88c
2014-08-29 13:00:48 -04:00
Brad Miller (WPI)
21967fcb24 Merge "Fixes testing framework typos & adds rule to keep unix line endings for .sh" 2014-08-29 09:56:51 -07:00
Thomas Clark
9b896eab70 Make DoubleSolenoid work in Java [artf3457]
Make DoubleSolenoid and Solenoid use SolenoidBase, like in C++.

Add an integration tests for double solenoids.

Change-Id: I9a7ff562d65a564c5adabfa73f85f23ad466215b
2014-08-29 12:50:44 -04:00
Thomas Clark (WPI)
f439adc2a3 Merge "fix for Artifact artf3431 : Solenoids initialize to random/arbitrary stat" 2014-08-29 09:38:51 -07:00
Jonathan Leitschuh
67cb854676 Fixes testing framework typos & adds rule to keep unix line endings for .sh
Change-Id: I33826b879ba2dce7da88aa399d37f711a6612d86
2014-08-29 11:40:03 -04:00
Brad Miller (WPI)
ef7c554029 Merge "Wrap CPP Lib and Include paths in quotes (fixes artf2390)" 2014-08-27 13:07:52 -07:00
Brad Miller (WPI)
359b4ec86b Merge "Added support for 32-bit builds." 2014-08-27 13:06:30 -07:00
Brad Miller (WPI)
21153fc63f Merge "Fix artf3476 move RobotState and HLReporting implementation set to somewhere they will get called" 2014-08-27 13:05:04 -07:00
Alex Henning
daa8bd67ef Added support for 32-bit builds.
Change-Id: I609844b3c72ca9d016a43a7b0e288abb4dc2400e
Note: Jenkins probably needs to be restarted to get proper sbuild permissions.
2014-08-27 15:46:41 -04:00
Kevin O'Connor
e5e568fa73 Wrap CPP Lib and Include paths in quotes (fixes artf2390)
Change-Id: Ied08c559140ecb28a41f61d968a37cd772255b8c
2014-08-27 15:27:18 -04:00
Kevin O'Connor
c9f6fcd969 Fix artf3447 Java only runs teleop - Correct off by one error in Control Word compares
Change-Id: I5965008ac75a9c3cc3a3473fa775729421b8957c
2014-08-27 15:22:20 -04:00
Kevin O'Connor
778620b0a9 Fix artf3476 move RobotState and HLReporting implementation set to somewhere they will get called
Change-Id: I863ba263b822a60f46a04f4de2e3c570df5f317d
2014-08-27 15:14:22 -04:00
Kevin O'Connor
d58c6f0c0f Merge "Kill program before debugging C++ so file upload doesn't fail" 2014-08-27 11:44:45 -07:00
Jonathan Leitschuh
a14d854211 Cpp tests without color for jenkins. Fixes startDS to not kill the driver station.
Change-Id: I538aae4e2d6d94f0f510203d2d4cb9f40ffa4303
2014-08-26 14:26:11 -04:00
Fred Silberberg (WPI)
c5fc1dc5be Merge "Change SampleRobot template to use 0 based PWM" 2014-08-26 10:35:43 -07:00
Jonathan Leitschuh
cded5351df Test scripts have permission to run and fixes sshpass.
Updates vagrant file to have sshpass by default.
Adds configuration for setting up the network in bridged mode so that the scripts can use mdns to connect to the roboRIO.

Change-Id: I7274a24c772790c9495e8a1c083385ef528044a6
2014-08-26 12:56:10 -04:00
Jonathan Leitschuh
47169e0ce1 Adds test scripts to deploy, run and retrieve results from integration tests.
Adds a simple script for jenkins to run to retrieve the test results from.
Adds a script that allows developers to download and run tests from a specific language easily.
Adds a script that allows the tests to be run from within an ssh session on the roborio.

Change-Id: Ibe6ddc4e1dcbb8192e6552c3901e96f6907a8020
2014-08-26 11:20:02 -04:00
Brad Miller (WPI)
4ef798a0c0 Merge "Updates gitignore to use a file generated using http://www.gitignore.io" 2014-08-26 08:08:11 -07:00
Jonathan Leitschuh
7ec8d4e9a3 Updates gitignore to use a file generated using http://www.gitignore.io
Removes more OSX/Windows/Linux files.
Adds gitignores for cmake, Gradle, and Maven

Change-Id: I96ada2ef360770975f4afc068985cd6a21880a5f
2014-08-26 11:05:43 -04:00
Omar Zrien
17e7fc8f20 fix for Artifact artf3431 : Solenoids initialize to random/arbitrary stat
Change-Id: I0bdcf073637a47a9e6864f6d561cc812a1d5b021
2014-08-24 19:57:40 -04:00
Joe Ross
023f955a56 Change SampleRobot template to use 0 based PWM
Change-Id: Ia299db32ba724e5a5ddc2e9a3c0dbb5d8acbb08f
2014-08-23 15:06:31 -07:00
Alex Henning (WPI)
52e358c180 Merge "Add Preferences to simulation" 2014-08-23 11:12:34 -07:00
Kevin O'Connor
7638e2b6e5 Kill program before debugging C++ so file upload doesn't fail
Change-Id: Ibd4fdb6cbf491f20d66f36c4fb84753a1abbfd1e
2014-08-21 17:19:23 -04:00
Jonathan Leitschuh
f9ab84d912 Integration tests now run with the Ant Junit test framework.
Removes TestNG as it wasn't reporting all of the tests correctly. Adds Ant as a dependency and uses it to run the JUnit tests so that tests are output in a way that Jenkins understands.

Change-Id: Ie98358476cebe94f233e687195a0fced8723a878
2014-08-21 15:29:17 -04:00
Joe Ross
04fadb85f5 Add Preferences to simulation
Change-Id: Id2891dac25ab6a929b5b90164cc5ecef49f40906
2014-08-20 21:07:12 -07:00
Brad Miller (WPI)
698b371b16 Merge "Add OI and RobotMap files to Command Project template (fixes artf2407)" 2014-08-20 13:41:50 -07:00
Brad Miller (WPI)
6dde2c2b4c Merge "Adds interrupts to Java" 2014-08-20 13:39:47 -07:00
Jonathan Leitschuh
8ba0eada17 Adds interrupts to Java
Implements the JNI bindings for java
Adds integration tests for Digital Inputs and AnalogTriggers.
Adds the ability to get the value and message from errno in java using the HALUtil JNI class.

Change-Id: I853529fdab9744ce95ee15d4cc73dc3953265552
2014-08-20 16:10:40 -04:00
Kevin O'Connor
bf5eaf657e Add OI and RobotMap files to Command Project template (fixes artf2407)
Change-Id: Ia3fb2a03b6435ae74bd70ad856a41a2c15f22f5a
2014-08-20 14:35:04 -04:00
Kevin O'Connor
3baaea5a44 Squashed commit of the following:
commit b4589d75b682d5bb99a98e9af975dd5c03a574dc
Author: Kevin O'Connor <koconnor@usfirst.org>
Date:   Tue Aug 19 17:15:12 2014 -0400

    Make CPP debugging from menu item work.

    Change-Id: I5bda07e088560adabbb9bc5fbfce9bd9456f7e1f

commit aaa832376700156abb1002ce7ad9334c4983be43
Author: Kevin O'Connor <koconnor@usfirst.org>
Date:   Tue Aug 19 17:13:22 2014 -0400

    Change CPP debug to use mDNS (artf3410)

    Change-Id: I01b97e1754c2abd4d18b41ab2f890b1b5470d616

Change-Id: I405bd1808d301f650f9293c60db161205ee6e704
2014-08-19 17:20:15 -04:00
Jonathan Leitschuh
2cc937f5e1 Fixes debugging in Java
When deploying a Java program in debug mode any previous running programs should be properly removed. [artf3408]
This should link with (https://usfirst.collab.net/sf/go/artf3408?nav=1&_pagenum=2&returnUrlKey=1408475631056)

[artf3415] is still an issue until NI resolves it.
This should link with (https://usfirst.collab.net/sf/go/artf3415?nav=1&_pagenum=1&returnUrlKey=1408475758258)

Change-Id: Ica9639b5a406b70be4d51aa4e45ffef56baddc93
2014-08-19 15:16:55 -04:00
Brad Miller (WPI)
23b6a980c2 Merge "Uses ${ant.java.version} for javac when compiling" 2014-08-18 14:32:10 -07:00
Thomas Clark
89b80db2d0 Merge "Fix PIDError property" 2014-08-18 13:32:52 -07:00
Thomas Clark
1f27d36884 Fix PIDError property
Change-Id: I3ea040ae4e0520a231bab95390746eba4315fd8d
2014-08-18 16:29:41 -04:00
Thomas Clark
125dfac8b4 Merge "Fix Java IT build" 2014-08-18 13:00:12 -07:00
Thomas Clark
4215d1c79b Fix Java IT build
The Java ITs should have jcommander as a dependency

Change-Id: Ide03fb245d21b21643bf7a9de6248db12dc54460
2014-08-18 15:52:13 -04:00
Kevin O'Connor
dddba82d18 Fix artf3337 - add include to define int32_t in CounterBase.h
Change-Id: Ia6ce4e57a36d628fb9f61e1ac8c3d3101e22f165
2014-08-18 14:19:13 -04:00
Jonathan Leitschuh
78e2a8d1b9 Uses ${ant.java.version} for javac when compiling
This uses the ant jvm version variable to compile teams robot projects.

Change-Id: I4f5b704e5230c1bd09323abea6c4044c709c3eff
2014-08-18 11:42:28 -04:00
Thomas Clark
687bc44ae5 Add new CTRE classes and update PDP tests
Change-Id: I489091c5b8b0f1f9890e5104bf01e40ae53cf6ce
2014-08-18 10:32:26 -04:00
Jonathan Leitschuh (WPI)
c82a94b268 Merge "Make Java tests run with TestNG" 2014-08-18 07:17:11 -07:00
Alex Henning (WPI)
d407fe546f Merge "Fixes for simulation parallel builds." 2014-08-17 17:23:44 -07:00
Alex Henning
699949fdf4 Fixes for simulation parallel builds.
Change-Id: I2b2385b6677a892fd1fd8a0c4b6f995418c33900
2014-08-17 19:48:08 -04:00
Thomas Clark
6d89974016 Make Java tests run with TestNG
TestNG generates xml reports that Jenkins can use, JUnit does not without
Ant or Maven.

To run the tests, deploy the Jar and run:
    /usr/local/frc/JRE/bin/java -jar wpilibJavaIntegrationTests-0.1.0-SNAPSHOT.jar -junit -testclass edu.wpi.first.wpilibj.test.TestSuite

Change-Id: I9e8a7dcab775f9c5ad1905afa798cd9191e25438
2014-08-15 16:40:56 -04:00
Brad Miller (WPI)
e523157507 Merge "Fixed bug with joystick buttons/axes out of range." 2014-08-15 10:03:02 -07:00
Brad Miller (WPI)
3eba1c4688 Merge "Add delays to make C++ ITs more reliable" 2014-08-15 10:00:30 -07:00
Thomas Clark
d466d17edd Add delays to make C++ ITs more reliable
Also disable PCM tests until it's actually wired right

Change-Id: I431031f66aaaa87fa201e577fedef5a1952c1bb4
2014-08-15 11:22:01 -04:00
Jonathan Leitschuh
9dfd6bde9d Adds a Vagrant configuration file and setup script
Vagrant allows developers to install Vagrant and their choice of virtual box in which to develop.
This provides a consistent environment where anyone can devlop WPIlib without having to go through a lengthy setup process.

Change-Id: Iced863d307f0e6a761441f17c3de377594197c38
2014-08-15 10:56:31 -04:00
Alex Henning
eded28ebfa Fixed bug with joystick buttons/axes out of range.
Change-Id: I85f0a9f47dfbb786f850c1f382c0e18a4e4b8254
2014-08-15 10:29:39 -04:00
Thomas Clark (WPI)
777dc2113d Merge "Updated installer to point to the new location." 2014-08-14 08:01:56 -07:00
Thomas Clark (WPI)
174f2c0e23 Merge "Increased build speed + caching of debs." 2014-08-14 08:01:23 -07:00
Thomas Clark (WPI)
434caf81d7 Merge "Add back SampleRobot Template Add GettingStarted example based on IterativeRobot" 2014-08-14 08:00:53 -07:00
Thomas Clark (WPI)
9327170069 Merge "Beginning of gradle conversion." 2014-08-14 08:00:03 -07:00
Kevin O'Connor
597e209c09 Add back SampleRobot Template
Add GettingStarted example based on IterativeRobot

Change-Id: Ic8caec4f62b7bdbaae7fafedfec5859b2f936809
2014-08-14 07:51:20 -04:00
Alex Henning
ad1ace1022 Increased build speed + caching of debs.
Make sure to add -j to improve build time by 10 minutes or more.

Change-Id: If2838a4042592fbfd1a0f40882efd7dd70270266
2014-08-13 18:22:40 -04:00
Alex Henning
70d09de2e9 Fixed frcsim script to have the proper LOAD_LIBRARY_PATH.
Change-Id: I83bdf3edcf5e69e1b5b358f92af26b8749039c7d
2014-08-13 15:22:36 -04:00
Alex Henning
df3f3cc0e1 Updated installer to point to the new location.
Change-Id: Id5f11a2952511bb781a4b4b38bcdcac1ec3ae2b0
2014-08-13 11:16:22 -04:00
Alex Henning
25308e2442 Beginning of gradle conversion.
Change-Id: Ic9690af60cd53b5237cd8c05d41598a94f6025f1
2014-08-12 17:25:10 -04:00
107 changed files with 4215 additions and 831 deletions

158
.gitignore vendored
View File

@@ -1,21 +1,82 @@
# WPIlib Specific
wpilibc/build/
hal/build/
networktables/cpp/build/
build/
networktables/OutlineViewer/nbproject/private
*~
target/
dist/
bin/
.project
.cproject
.settings/
.classpath
**/dependency-reduced-pom.xml
#Java File extentions
# Created by the jenkins test script
test-reports
# Added by the users of vagrant
jdk-7u45-linux-arm-vfp-sflt.gz
# Created by http://www.gitignore.io
### Linux ###
*~
# KDE directory preferences
.directory
### Windows ###
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
### OSX ###
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
@@ -23,3 +84,90 @@ bin/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### C++ ###
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Compiled Dynamic libraries
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
### CMake ###
CMakeCache.txt
CMakeFiles
cmake_install.cmake
install_manifest.txt
### Gradle ###
.gradle
build/
# Ignore Gradle GUI config
gradle-app.setting
### Vagrant ###
.vagrant/
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse

125
Vagrantfile vendored Normal file
View File

@@ -0,0 +1,125 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# All Vagrant configuration is done here. The most common configuration
# options are documented and commented below. For a complete reference,
# please see the online documentation at vagrantup.com.
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "puphpet/ubuntu1404-x64"
# Run the bootstrap.sh shell script to setup the enviroment
config.vm.provision :shell, path: "bootstrap.sh"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# config.vm.network "forwarded_port", guest: 80, host: 8080
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network "private_network", ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
config.vm.network "public_network", bridge: 'en0'
# If true, then any SSH connections made will enable agent forwarding.
# Default value: false
config.ssh.forward_agent = true
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Don't boot with headless mode
# vb.gui = true
#
# # Use VBoxManage to customize the VM. For example to change memory:
# vb.customize ["modifyvm", :id, "--memory", "1024"]
# end
#
# View the documentation for the provider you're using for more
# information on available options.
# Enable provisioning with CFEngine. CFEngine Community packages are
# automatically installed. For example, configure the host as a
# policy server and optionally a policy file to run:
#
# config.vm.provision "cfengine" do |cf|
# cf.am_policy_hub = true
# # cf.run_file = "motd.cf"
# end
#
# You can also configure and bootstrap a client to an existing
# policy server:
#
# config.vm.provision "cfengine" do |cf|
# cf.policy_server_address = "10.0.2.15"
# end
# Enable provisioning with Puppet stand alone. Puppet manifests
# are contained in a directory path relative to this Vagrantfile.
# You will need to create the manifests directory and a manifest in
# the file default.pp in the manifests_path directory.
#
# config.vm.provision "puppet" do |puppet|
# puppet.manifests_path = "manifests"
# puppet.manifest_file = "site.pp"
# end
# Enable provisioning with chef solo, specifying a cookbooks path, roles
# path, and data_bags path (all relative to this Vagrantfile), and adding
# some recipes and/or roles.
#
# config.vm.provision "chef_solo" do |chef|
# chef.cookbooks_path = "../my-recipes/cookbooks"
# chef.roles_path = "../my-recipes/roles"
# chef.data_bags_path = "../my-recipes/data_bags"
# chef.add_recipe "mysql"
# chef.add_role "web"
#
# # You may also specify custom JSON attributes:
# chef.json = { mysql_password: "foo" }
# end
# Enable provisioning with chef server, specifying the chef server URL,
# and the path to the validation key (relative to this Vagrantfile).
#
# The Opscode Platform uses HTTPS. Substitute your organization for
# ORGNAME in the URL and validation key.
#
# If you have your own Chef Server, use the appropriate URL, which may be
# HTTP instead of HTTPS depending on your configuration. Also change the
# validation key to validation.pem.
#
# config.vm.provision "chef_client" do |chef|
# chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
# chef.validation_key_path = "ORGNAME-validator.pem"
# end
#
# If you're using the Opscode platform, your validator client is
# ORGNAME-validator, replacing ORGNAME with your organization name.
#
# If you have your own Chef Server, the default validation client name is
# chef-validator, unless you changed the configuration.
#
# chef.validation_client_name = "ORGNAME-validator"
end

61
bootstrap.sh Normal file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Update the apt-get repository list
apt-get update
# Download and install Java
apt-get --yes --force-yes install default-jre
apt-get --yes --force-yes install default-jdk
# Install Maven
apt-get --yes --force-yes install maven
# Install git-review
apt-get --yes --force-yes install python-pip
apt-get --yes --force-yes install python-setuptools
easy_install pip
yes | pip install git-review
# Download and install the gcc linux arm-toolchains
# Get the 32 bit c library
apt-get --yes --force-yes install libc6-i386
# Download the tool to unzip .zip files
apt-get --yes --force-yes install unzip
# The variables associated with the toolchains
TOOL_VER="1.0.1"
TOOL_DIR=~/../home/vagrant/wpilib/toolchains
# Create the toolchains directory
mkdir -p $TOOL_DIR
# Download the toolchains to this directory
wget -P ${TOOL_DIR}/ http://first.wpi.edu/FRC/c/maven/edu/wpi/first/wpilib/plugins/cpp/toolchains/linux/${TOOL_VER}/linux-${TOOL_VER}.zip
# Unzip the file
unzip -q ${TOOL_DIR}/linux-${TOOL_VER}.zip -d ${TOOL_DIR}/
# Remove the unneeded zip file
rm ${TOOL_DIR}/linux-${TOOL_VER}.zip
# Change the name of the directory
mv -f $TOOL_DIR/linux-${TOOL_VER} ${TOOL_DIR}/arm-none-linux-gnueabi-4.4.1
chown -R vagrant $TOOL_DIR/arm-none-linux-gnueabi-4.4.1
# Add the arm toolchains to the path variable
echo 'PATH=$PATH:/home/vagrant/wpilib/toolchains/arm-none-linux-gnueabi-4.4.1/bin/' >> /home/vagrant/.bashrc
# Install the jdk-linux-arm-vfp-sflt
# Create the target directory for the jdk
mkdir -p /home/vagrant/jdk-linux-arm-vfp-sflt/
# Unzip the jdk into this new directory
tar -xzf /vagrant/jdk-7u45-linux-arm-vfp-sflt.gz -C /home/vagrant/jdk-linux-arm-vfp-sflt/
# Install sshpass for the test system
apt-get --yes --force-yes install sshpass
# Keep this at the end of this file
printf "\n\n"
printf "Your virtual enviroment is now nearly set-up.\n"
printf "You can access your enviroment using 'vagrant ssh'.\n"
printf "Please run 'cd /vagrant' to navigate to the repository.\n"
printf "Once you have navigated there please run 'git review -s' to complete the setup of git review.\n"

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env bash
# Temporary method to deploy C++ integration tests to the RoboRIO
if [ $(which sshpass) ]
then
# Send stderr to /dev/null - the only thing printed to it is the login prompt
sshpass -p "" ssh admin@10.1.90.2 killall FRCUserProgram java 2> /dev/null
sshpass -p "" scp target/cmake/wpilibc/wpilibC++IntegrationTests/FRCUserProgram admin@10.1.90.2:/home/admin 2> /dev/null
sshpass -p "" ssh admin@10.1.90.2 ./FRCUserProgram --gtest_color=yes $* 2> /dev/null
else
ssh admin@10.1.90.2 killall FRCUserProgram
scp target/cmake/wpilibc/wpilibC++IntegrationTests/FRCUserProgram admin@10.1.90.2:/home/admin
ssh admin@10.1.90.2 ./FRCUserProgram --gtest_color=yes $*
fi

View File

@@ -35,7 +35,7 @@ public class NewProjectMainPage extends WizardPage {
private Text worldText;
private Button worldButton;
Button iterativeRobot, commandRobot;
Button iterativeRobot, commandRobot, sampleRobot;
private boolean showPackage;
private boolean showProjectTypes;
private TeamNumberPage teamNumberPage;
@@ -109,6 +109,12 @@ public class NewProjectMainPage extends WizardPage {
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint = 300;
commandRobot.setLayoutData(gd);
sampleRobot = new Button(projectTypeGroup, SWT.RADIO | SWT.WRAP);
sampleRobot.setText("Sample Robot: A robot project used for small sample programs or for highly advanced programs with more complete control over program flow");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.widthHint = 300;
sampleRobot.setLayoutData(gd);
}
label = new Label(container, SWT.NULL);
@@ -214,6 +220,7 @@ public class NewProjectMainPage extends WizardPage {
public ProjectType getProjectType() {
if (!showProjectTypes) return null;
else if (iterativeRobot.getSelection()) return types.get(ProjectType.ITERATIVE);
else if (sampleRobot.getSelection()) return types.get(ProjectType.SAMPLE);
else return types.get(ProjectType.COMMAND_BASED);
}

View File

@@ -4,7 +4,7 @@ import java.net.URL;
import java.util.Map;
public interface ProjectType {
String SIMPLE = "SIMPLE";
String SAMPLE = "SAMPLE";
String ITERATIVE = "ITERATIVE";
String COMMAND_BASED = "COMMAND_BASED";

View File

@@ -29,14 +29,14 @@
<option id="gnu.cpp.compiler.option.debugging.level.1682909384" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.include.paths.1597382905" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/src&quot;"/>
<listOptionValue builtIn="false" value="$cpp-location/include"/>
<listOptionValue builtIn="false" value="&quot;$cpp-location/include&quot;"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.963785380" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.1367166630" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool command="g++" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="org.eclipse.cdt.core.GLDErrorParser" id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1568604896" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
<option id="gnu.cpp.link.option.paths.1928585110" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="$cpp-location/lib"/>
<listOptionValue builtIn="false" value="&quot;$cpp-location/lib&quot;"/>
</option>
<option id="gnu.cpp.link.option.libs.1072058280" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="WPILibAthena"/>

View File

@@ -0,0 +1,59 @@
#include "WPILib.h"
class Robot: public IterativeRobot
{
RobotDrive myRobot; // robot drive system
Joystick stick; // only joystick
LiveWindow *lw;
int autoLoopCounter;
public:
Robot() :
myRobot(0, 1), // these must be initialized in the same order
stick(1), // as they are declared above.
lw(NULL),
autoLoopCounter(0)
{
myRobot.SetExpiration(0.1);
}
private:
void RobotInit()
{
lw = LiveWindow::GetInstance();
}
void AutonomousInit()
{
autoLoopCounter = 0;
}
void AutonomousPeriodic()
{
if(autoLoopCounter < 100) //Check if we've completed 100 loops (approximately 2 seconds)
{
myRobot.Drive(-0.5, 0.0); // drive forwards half speed
autoLoopCounter++;
} else {
myRobot.Drive(0.0, 0.0); // stop robot
}
}
void TeleopInit()
{
}
void TeleopPeriodic()
{
myRobot.ArcadeDrive(stick); // drive with arcade style (use right stick)
}
void TestPeriodic()
{
lw->Run();
}
};
START_ROBOT_CLASS(Robot);

View File

@@ -15,6 +15,26 @@
<name>Simulation</name>
<description>Examples that can be run in simulation.</description>
</tagDescription>-->
<tagDescription>
<name>Getting Started with C++</name>
<description>Examples for getting started with FRC C++</description>
</tagDescription>
<example>
<name>Getting Started</name>
<description>An example program which demonstrates the simplest autonomous and
teleoperated routines.</description>
<tags>
<tag>Getting Started with C++</tag>
</tags>
<packages>
<package>src</package>
</packages>
<files>
<file source="examples/GettingStarted/src/Robot.cpp"
destination="src/Robot.cpp"></file>
</files>
</example>
<tagDescription>
<name>CommandBased Robot</name>
<description>Examples for CommandBased robot programs.</description>

View File

@@ -17,7 +17,7 @@ class Robot: public SampleRobot
public:
Robot() :
myRobot(1, 2), // these must be initialized in the same order
myRobot(0, 1), // these must be initialized in the same order
stick(1) // as they are declared above.
{
myRobot.SetExpiration(0.1);

View File

@@ -111,6 +111,11 @@ public class DeployLaunchShortcut implements ILaunchShortcut
// Debug deploys are done with the Eclipse Remote System Explorer,
// which lets it work with Eclipse's C++ debugger.
// Kill running program before using RSE as RSE can't
WPILibCPPPlugin.logInfo("Running ant file: " + activeProj.getLocation().toOSString() + File.separator + "build.xml");
WPILibCPPPlugin.logInfo("Targets: kill-program, Mode: " + mode);
AntLauncher.runAntFile(new File (activeProj.getLocation().toOSString() + File.separator + "build.xml"), "kill-program", null, mode);
// TODO: figure out UI issues. that's why this is undocumented
ILaunchConfigurationWorkingCopy config;
try {
@@ -139,21 +144,37 @@ public class DeployLaunchShortcut implements ILaunchShortcut
String remote_connection = RSEUtils.getTarget(teamNumber).getName();
ILaunchConfigurationWorkingCopy config = type.newInstance(null, activeProj.getName());
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, "");
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_REGISTER_BOOKKEEPING, false);
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, false);
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ID, "org.eclipse.rse.remotecdt.RemoteGDBDebugger");
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_REGISTER_GROUPS, "");
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, "run");
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, true);
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, "main");
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true);
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, activeProj.getName());
Collection<Executable> exes = ExecutablesManager.getExecutablesManager().getExecutablesForProject(activeProj);
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME,
exes.size() > 0 ? exes.toArray(new Executable[0])[0].getPath().makeRelativeTo(activeProj.getLocation()).toString():
"Debug/FRCUserProgram");
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, "/home/admin/FRCUserProgram");
config.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, WPILibCPPPlugin.getDefault().getToolchain() + "/bin/arm-none-linux-gnueabi-gdb");
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, remote_connection);
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ID, "gdbserver");
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, false);
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT, "2345");
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_COMMAND, "gdbserver");
config.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, WPILibCPPPlugin.getDefault().getToolchain() + "/bin/arm-none-linux-gnueabi-gdb");
List<String> solibs = new ArrayList<>();
solibs.add(WPILibCPPPlugin.getDefault().getToolchain() + "/arm-non-linux-gnueabi/libc/lib");
solibs.add(WPILibCPPPlugin.getDefault().getToolchain() + "/arm-non-linux-gnueabi/libc/usr/lib");
solibs.add(WPILibCPPPlugin.getDefault().getCPPDir() + "/lib");
config.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, solibs);
config.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB, true);
config.setAttribute(IMILaunchConfigurationConstants.ATTR_DEBUGGER_STOP_ON_SOLIB_EVENTS, false);
config.doSave();
return config;
}
}

View File

@@ -16,8 +16,10 @@ public class RSEUtils {
public static IHost getTarget(int teamNumber) {
// The ip address based on the team number
String hostName = "10."+(teamNumber/100)+"."+(teamNumber%100)+".2";
String connectionName = hostName; //"Team "+teamNumber;
//String hostName = "10."+(teamNumber/100)+"."+(teamNumber%100)+".2";
//String connectionName = hostName; //"Team "+teamNumber;
String hostName = "roboRIO-" + teamNumber + ".local";
String connectionName = hostName;
// get the singleton RSE registry
try {

View File

@@ -38,10 +38,18 @@ public class CPPProjectType implements ProjectType {
return files;
}
};
static ProjectType SAMPLE = new CPPProjectType() {
@Override public Map<String, String> getFiles(String packageName) {
Map<String, String> files = super.getFiles(packageName);
files.put("src/Robot.cpp", "sample/Robot.cpp");
return files;
}
};
@SuppressWarnings("serial")
static Map<String, ProjectType> TYPES = new HashMap<String, ProjectType>() {{
put(ProjectType.ITERATIVE, ITERATIVE);
put(ProjectType.COMMAND_BASED, COMMAND_BASED);
put(ProjectType.SAMPLE, SAMPLE);
}};
@Override

View File

@@ -48,6 +48,14 @@
trust="true"
command="tail -F -s 0 -n 0 ${deploy.log.file}"/>
</target>
<target name="kill-program" depends="get-target-ip" description="Kill the currently running FRC program">
<sshexec host="${target}"
username="${username}"
password="${password}"
trust="true"
command="/usr/local/frc/bin/frcKillRobot.sh"/>
</target>
<target name="debug-deploy" depends="get-target-ip" description="Deploy the jar and start the program running in debug mode.">
<echo>[athena-deploy] Killing running program</echo>

View File

@@ -0,0 +1,38 @@
package $package;
import edu.wpi.first.wpilibj.buttons.Button;
import $package.commands.ExampleCommand;
/**
* This class is the glue that binds the controls on the physical operator
* interface to the commands and command groups that allow control of the robot.
*/
public class OI {
//// CREATING BUTTONS
// One type of button is a joystick button which is any button on a joystick.
// You create one by telling it which joystick it's on and which button
// number it is.
// Joystick stick = new Joystick(port);
// Button button = new JoystickButton(stick, buttonNumber);
// There are a few additional built in buttons you can use. Additionally,
// by subclassing Button you can create custom triggers and bind those to
// commands the same as any other Button.
//// TRIGGERING COMMANDS WITH BUTTONS
// Once you have a button, it's trivial to bind it to a button in one of
// three ways:
// Start the command when the button is pressed and let it run the command
// until it is finished as determined by it's isFinished method.
// button.whenPressed(new ExampleCommand());
// Run the command while the button is being held down and interrupt it once
// the button is released.
// button.whileHeld(new ExampleCommand());
// Start the command when the button is released and let it run the command
// until it is finished as determined by it's isFinished method.
// button.whenReleased(new ExampleCommand());
}

View File

@@ -18,6 +18,7 @@ import $package.subsystems.ExampleSubsystem;
public class Robot extends IterativeRobot {
public static final ExampleSubsystem exampleSubsystem = new ExampleSubsystem();
public static OI oi;
Command autonomousCommand;
@@ -26,6 +27,7 @@ public class Robot extends IterativeRobot {
* used for any initialization code.
*/
public void robotInit() {
oi = new OI();
// instantiate the command used for the autonomous period
autonomousCommand = new ExampleCommand();
}

View File

@@ -0,0 +1,18 @@
package $package;
/**
* The RobotMap is a mapping from the ports sensors and actuators are wired into
* to a variable name. This provides flexibility changing wiring, makes checking
* the wiring easier and significantly reduces the number of magic numbers
* floating around.
*/
public class RobotMap {
// For example to map the left and right motors, you could define the
// following variables to use with your drivetrain subsystem.
// public static final int leftMotor = 1;
// public static final int rightMotor = 2;
// If you are using multiple modules, make sure to define both the port
// number and the module. For example you with a rangefinder:
// public static final int rangefinderPort = 1;
// public static final int rangefinderModule = 1;
}

View File

@@ -0,0 +1,69 @@
package $package;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* The VM is configured to automatically run this class, and to call the
* functions corresponding to each mode, as described in the IterativeRobot
* documentation. If you change the name of this class or the package after
* creating this project, you must also update the manifest file in the resource
* directory.
*/
public class Robot extends IterativeRobot {
RobotDrive myRobot;
Joystick stick;
int autoLoopCounter;
/**
* This function is run when the robot is first started up and should be
* used for any initialization code.
*/
public void robotInit() {
myRobot = new RobotDrive(0,1);
stick = new Joystick(1);
}
/**
* This function is run once each time the robot enters autonomous mode
*/
public void autonomousInit() {
autoLoopCounter = 0;
}
/**
* This function is called periodically during autonomous
*/
public void autonomousPeriodic() {
if(autoLoopCounter < 100) //Check if we've completed 100 loops (approximately 2 seconds)
{
myRobot.drive(-0.5, 0.0); // drive forwards half speed
autoLoopCounter++;
} else {
myRobot.drive(0.0, 0.0); // stop robot
}
}
/**
* This function is called once each time the robot enters tele-operated mode
*/
public void teleopInit(){
}
/**
* This function is called periodically during operator control
*/
public void teleopPeriodic() {
myRobot.arcadeDrive(stick);
}
/**
* This function is called periodically during test mode
*/
public void testPeriodic() {
LiveWindow.run();
}
}

View File

@@ -15,6 +15,25 @@
<name>Simulation</name>
<description>Examples that can be run in simulation.</description>
</tagDescription>-->
<tagDescription>
<name>Getting Started with Java</name>
<description>Examples for getting started with FRC Java</description>
</tagDescription>
<example>
<name>Getting Started</name>
<description>An example program which demonstrates the simplest autonomous and
teleoperated routines.</description>
<tags>
<tag>Getting Started with Java</tag>
</tags>
<packages>
<package>src/$package-dir</package>
</packages>
<files>
<file source="examples/GettingStarted/src/org/usfirst/frc/team190/robot/Robot.java"
destination="src/$package-dir/Robot.java"></file>
</files>
</example>
<tagDescription>
<name>CommandBased Robot</name>
<description>Examples for CommandBased robot programs.</description>

View File

@@ -3,6 +3,9 @@ package $package;
import edu.wpi.first.wpilibj.SampleRobot;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.Timer;
/**
* This is a demo program showing the use of the RobotDrive class.
@@ -25,7 +28,7 @@ public class Robot extends SampleRobot {
Joystick stick;
public Robot() {
myRobot = new RobotDrive(1, 2);
myRobot = new RobotDrive(0, 1);
myRobot.setExpiration(0.1);
stick = new Joystick(1);
}

View File

@@ -8,10 +8,10 @@ import edu.wpi.first.wpilib.plugins.core.wizards.ProjectType;
import edu.wpi.first.wpilib.plugins.java.WPILibJavaPlugin;
public class JavaProjectType implements ProjectType {
static ProjectType SIMPLE = new JavaProjectType() {
static ProjectType SAMPLE = new JavaProjectType() {
@Override public Map<String, String> getFiles(String packageName) {
Map<String, String> files = super.getFiles(packageName);
files.put("src/"+packageName.replace(".", "/")+"/Robot.java", "simple/Robot.java");
files.put("src/"+packageName.replace(".", "/")+"/Robot.java", "sample/Robot.java");
return files;
}
};
@@ -33,6 +33,8 @@ public class JavaProjectType implements ProjectType {
@Override public Map<String, String> getFiles(String packageName) {
Map<String, String> files = super.getFiles(packageName);
files.put("src/"+packageName.replace(".", "/")+"/Robot.java", "command-based/Robot.java");
files.put("src/"+packageName.replace(".", "/")+"/RobotMap.java", "command-based/RobotMap.java");
files.put("src/"+packageName.replace(".", "/")+"/OI.java", "command-based/OI.java");
files.put("src/"+packageName.replace(".", "/")+"/commands/ExampleCommand.java", "command-based/ExampleCommand.java");
files.put("src/"+packageName.replace(".", "/")+"/subsystems/ExampleSubsystem.java", "command-based/ExampleSubsystem.java");
return files;
@@ -40,7 +42,7 @@ public class JavaProjectType implements ProjectType {
};
@SuppressWarnings("serial")
static Map<String, ProjectType> TYPES = new HashMap<String, ProjectType>() {{
put(ProjectType.SIMPLE, SIMPLE);
put(ProjectType.SAMPLE, SAMPLE);
put(ProjectType.ITERATIVE, ITERATIVE);
put(ProjectType.COMMAND_BASED, COMMAND_BASED);
}};

View File

@@ -2,9 +2,10 @@
username=admin
password=
deploy.dir=/home/admin
deploy.kill.command=/usr/local/frc/bin/frcKillRobot.sh -t -r
deploy.debug.command = /usr/local/frc/JRE/bin/java -XX:+UsePerfData -agentlib:jdwp=transport=dt_socket,address=8348,server=y,suspend=y -jar ${deploy.dir}/FRCUserProgram.jar
deploy.kill.command=. /etc/profile.d/natinst-path.sh; /usr/local/frc/bin/frcKillRobot.sh -t -r
deploy.log.file=/var/local/natinst/log/FRC_UserProgram.log
deploy.log.command=tail -F -s 0 -n 0 ${deploy.log.file}
debug.flag.dir=/tmp/
command.dir=/home/lvuser/
# Libraries to use

View File

@@ -32,9 +32,9 @@
includeAntRuntime="no"
includeJavaRuntime="no"
classpath="${classpath}"
target="1.7"
source="1.7"
compiler="javac1.7"
target="${ant.java.version}"
source="${ant.java.version}"
compiler="javac${ant.java.version}"
debug="true">
</javac>
</target>
@@ -76,25 +76,35 @@
username="${username}"
password="${password}"
trust="true"
command=". /etc/profile.d/natinst-path.sh; ${deploy.kill.command};"/>
command="${deploy.kill.command};"/>
<sshexec host="${target}"
username="${username}"
password="${password}"
trust="true"
command="tail -F -s 0 -n 0 ${deploy.log.file}"/>
command="${deploy.log.command}"/>
</target>
<target name="debug-deploy" depends="get-target-ip,jar" description="Deploy the jar and start the program running.">
<echo>[athena-deploy] Copying code over.</echo>
<scp file="${dist.jar}" todir="${username}@${target}:${deploy.dir}" password="${password}" trust="true"/>
<!-- The remoteDebugCommand file is used by /usr/local/frc/bin/frcRunRobot.sh on the roboRIO -->
<scp file="${wpilib.ant.dir}/robotDebugCommand" todir="${username}@${target}:${command.dir}" password="${password}" trust="true"/>
<!-- The frcdebug file is used as a flag for /usr/local/frc/bin/frcRunRobot.sh to run the robot program in debug mode -->
<scp file="${wpilib.ant.dir}/frcdebug" todir="${username}@${target}:${debug.flag.dir}" password="${password}" trust="true"/>
<echo>[athena-deploy] Starting program.</echo>
<echo>[athena-deploy] Starting Debug program.</echo>
<sshexec host="${target}"
username="${username}"
password="${password}"
trust="true"
command=". /etc/profile.d/natinst-path.sh; ${deploy.debug.command}"/>
username="${username}"
password="${password}"
trust="true"
command="${deploy.kill.command}"/>
<sshexec host="${target}"
username="${username}"
password="${password}"
trust="true"
command="${deploy.log.command}"/>
</target>
<!-- Simulate -->

View File

@@ -0,0 +1,2 @@
# This file is used as a flag to determine if debugging should be used.
# It is uploaded to the robot when launched in debug mode and should be removed automatically once used.

View File

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

View File

@@ -6,6 +6,9 @@
#include <stdint.h>
#endif
#include <iostream>
#include "errno.h"
extern "C"
{
typedef void (*InterruptHandlerFunction)(uint32_t interruptAssertedMask, void *param);

View File

@@ -52,8 +52,10 @@ void enableInterrupts(void* interrupt_pointer, int32_t *status)
*/
void disableInterrupts(void* interrupt_pointer, int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->manager->disable(status);
}
/**

View File

@@ -88,6 +88,11 @@ private:
uint32_t arbId;
uint8_t toSend[8];
uint32_t periodMs;
txJob_t() : arbId(0),periodMs(0)
{
for(int i=0;i<sizeof(toSend);++i)
toSend[i] = 0;
}
};
class rxEvent_t{

View File

@@ -101,8 +101,7 @@ PCM::PCM(UINT8 deviceNumber): CtreCanNode(deviceNumber)
RegisterRx(STATUS_DEBUG | deviceNumber );
RegisterTx(CONTROL_1 | deviceNumber, kCANPeriod);
/* enable close loop */
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
toFill->closedLoopEnable = 1;
SetClosedLoopControl(1);
}
/* PCM D'tor
*/
@@ -216,7 +215,7 @@ CTR_Code PCM::GetCompressorCurrent(float &status)
uint32_t temp =(rx->compressorCurrentTop6);
temp <<= 4;
temp |= rx->compressorCurrentBtm4;
status = 20.1612903225806 * temp;
status = temp * 0.03125; /* 5.5 fixed pt value in Amps */
return rx.err;
}
@@ -230,7 +229,7 @@ CTR_Code PCM::GetSolenoidVoltage(float &status)
uint32_t raw =(rx->solenoidVoltageTop8);
raw <<= 2;
raw |= rx->solenoidVoltageBtm2;
status = (double) raw * 24.7800586510264 / 1000;
status = (double) raw * 0.03125; /* 5.5 fixed pt value in Volts */
return rx.err;
}
@@ -297,7 +296,7 @@ CTR_Code PCM::GetSolenoidStickyFault(bool &status)
CTR_Code PCM::GetBatteryVoltage(float &status)
{
GET_PCM_STATUS();
status = (float)rx->battVoltage * ((59.0420332355816) / 1000.0);;
status = (float)rx->battVoltage * 0.05 + 4.0; /* 50mV per unit plus 4V. */
return rx.err;
}
/* Return status of module enable/disable

View File

@@ -110,7 +110,7 @@ CTR_Code PDP::GetChannelCurrent(UINT8 idx, double &current)
}
}
/* convert to amps */
current = 0.06724511900000001*raw + 1.527114967;
current = (double)raw * 0.125; /* 7.3 fixed pt value in Amps */
/* signal caller with success */
return retval;
}
@@ -118,14 +118,14 @@ CTR_Code PDP::GetVoltage(double &voltage)
{
GET_STATUS3();
uint32_t raw = rx->busVoltage;
voltage = 0.0554413328606877 * raw;
voltage = (double)raw * 0.05 + 4.0; /* 50mV per unit plus 4V. */;
return rx.err;
}
CTR_Code PDP::GetTemperature(double &tempC)
{
GET_STATUS3();
uint32_t raw = rx->temp;
tempC = ((double)raw-67.8564500484966)*1.03250836957542;
tempC = (double)raw * 1.03250836957542 - 67.8564500484966;
return rx.err;
}
//------------------ C interface --------------------------------------------//

View File

@@ -0,0 +1,24 @@
apply plugin: 'java'
apply plugin: 'maven'
group = "edu.wpi.frc.wpilib"
version = "2.0"
sourceCompatibility = 1.7
sourceSets {
main {
java {
srcDirs = ["src"]
}
}
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile project(":java")
}

View File

@@ -0,0 +1,19 @@
apply plugin: 'cpp'
libraries {
main {}
}
sources {
main {
cpp {
source {
srcDirs = ["lib/share", "lib/Athena"]
// includes = "**/*.cpp"
}
exportedHeaders {
srcDirs = ["include"]
}
}
}
}

View File

@@ -0,0 +1,24 @@
apply plugin: 'java'
apply plugin: 'maven'
group = "edu.wpi.frc.wpilib"
version = "2.0"
sourceCompatibility = 1.7
sourceSets {
main {
java {
srcDirs = ["src"]
}
}
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile project(":java")
}

View File

@@ -0,0 +1,39 @@
apply plugin: 'java'
apply plugin: 'maven'
group = "edu.wpi.frc.wpilib"
version = "2.0"
sourceSets {
main {
java {
srcDirs = ["src/main/java", "Athena/src/main/java"]
}
}
test {
java {
srcDirs = ["Athena/src/test/java"]
excludes = ["edu/wpi/first/wpilibj/networktables2/system/SystemTest.java"]
}
}
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.+'
testCompile group: 'org.jmock', name: 'jmock-junit4', version: '2.6.0'
testCompile group: 'org.jmock', name: 'jmock-legacy', version: '2.6.0'
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://localhost/tmp/myRepo/")
pom.artifactId = 'networktables'
}
}
}

View File

@@ -0,0 +1 @@
include "java", "java-table-viewer"

View File

@@ -16,42 +16,32 @@ libwpilibsim-package-version = $(libwpilibsim-version)-$(package-version)
frcsim-version = 0.1
frcsim-package-version = $(frcsim-version)-$(package-version)
all: debs update-repository
# Main Targets
.PHONY: all jenkins allwpilib pull debs update-repository clean-repository clean install
jenkins: download-models pull-eclipse-toolchain pull all
all: update-repository
jenkins: update-repository
allwpilib:
cd $(allwpilib) && mvn -T 8 clean package -Dwith-eclipse-plugins -DskipTests -DskipIT
orig: pre-orig-clean
cd frcsim-gazebo-plugins && tar --exclude="./debian" -czvf \
frcsim-gazebo-plugins_${gazebo-plugins-version}.orig.tar.gz frcsim-gazebo-plugins
cd frcsim-gazebo-models && tar --exclude="./debian" -czvf \
frcsim-gazebo-models_${gazebo-models-version}.orig.tar.gz frcsim-gazebo-models
cd frcsim-eclipse-plugins && tar --exclude="./debian" -czvf \
frcsim-eclipse-plugins_${eclipse-plugins-version}.orig.tar.gz frcsim-eclipse-plugins
cd frcsim-eclipse-toolchain-plugin && tar --exclude="./debian" -czvf \
frcsim-eclipse-toolchain-plugin_${eclipse-toolchain-version}.orig.tar.gz frcsim-eclipse-toolchain-plugin
cd frcsim-libwpilibsim-cpp && tar --exclude="./debian" -czvf \
frcsim-libwpilibsim-cpp_${libwpilibsim-version}.orig.tar.gz frcsim-libwpilibsim-cpp
cd frcsim && tar --exclude="./debian" -czvf \
frcsim_${frcsim-version}.orig.tar.gz frcsim
orig: orig-frcsim-gazebo-plugins orig-frcsim-gazebo-models orig-frcsim-eclipse-plugins \
orig-frcsim-eclipse-toolchain-plugin orig-frcsim-libwpilibsim-cpp orig-frcsim
debs:
cd frcsim-gazebo-plugins/frcsim-gazebo-plugins && debuild -us -uc -iamd64
cd frcsim-gazebo-models/frcsim-gazebo-models && debuild -us -uc
cd frcsim-eclipse-plugins/frcsim-eclipse-plugins && debuild -us -uc
cd frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin && debuild -us -uc
cd frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp && debuild -us -uc
cd frcsim/frcsim && debuild -us -uc
debs: debs-frcsim-gazebo-plugins debs-frcsim-gazebo-models debs-frcsim-eclipse-plugins \
debs-frcsim-eclipse-toolchain-plugin debs-frcsim-libwpilibsim-cpp debs-frcsim
update-repository: clean-repository
update-repository: debs clean-repository
cd repository && reprepro includedeb $(codename) ../frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_amd64.deb
cd repository && reprepro includedeb $(codename) ../frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_i386.deb
cd repository && reprepro includedeb $(codename) ../frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-package-version)_all.deb
cd repository && reprepro includedeb $(codename) ../frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-package-version)_all.deb
cd repository && reprepro includedeb $(codename) ../frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-package-version)_all.deb
cd repository && reprepro includedeb $(codename) ../frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_amd64.deb
cd repository && reprepro includedeb $(codename) ../frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_i386.deb
cd repository && reprepro includedeb $(codename) ../frcsim/frcsim_$(frcsim-package-version)_all.deb
echo Repository Updated
clean-repository:
cd repository && reprepro remove $(codename) frcsim-gazebo-plugins
@@ -61,39 +51,53 @@ clean-repository:
cd repository && reprepro remove $(codename) frcsim-libwpilibsim-cpp
cd repository && reprepro remove $(codename) frcsim
pre-orig-clean:
cd frcsim-gazebo-plugins/frcsim-gazebo-plugins && debuild clean
cd frcsim-gazebo-models/frcsim-gazebo-models && debuild clean
cd frcsim-eclipse-plugins/frcsim-eclipse-plugins && debuild clean
cd frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin && debuild clean
cd frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp && debuild clean
cd frcsim/frcsim && debuild clean
clean:
-rm frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-version).orig.tar.gz
-rm frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-version).orig.tar.gz
-rm frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-version).orig.tar.gz
-rm frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-version).orig.tar.gz
-rm frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-version).orig.tar.gz
-rm frcsim/frcsim_$(frcsim-version).orig.tar.gz
rm -f frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-version).orig.tar.gz
rm -f frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-version).orig.tar.gz
rm -f frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-version).orig.tar.gz
rm -f frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-version).orig.tar.gz
rm -f frcsim-libwpilib-cpp/frcsim-libwpilib-cpp_$(libwpilibsim-version).orig.tar.gz
rm -f frcsim/frcsim_$(frcsim-version).orig.tar.gz
-rm frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_amd64.deb
-rm frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_i386.deb
-rm frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-package-version)_all.deb
-rm frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-package-version)_all.deb
-rm frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-package-version)_all.deb
-rm frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_amd64.deb
-rm frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_i386.deb
-rm frcsim/frcsim_$(frcsim-package-version)_all.deb
clean: pre-orig-clean
rm -rf frcsim-eclipse-plugins/frcsim-eclipse-plugins/plugins
rm -rf frcsim-eclipse-plugins/frcsim-eclipse-plugins/features
install:
sudo dpkg -i frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_amd64.deb \
frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-package-version)_all.deb \
frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-package-version)_all.deb \
frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-package-version)_all.deb \
frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_amd64.deb \
frcsim/frcsim_$(frcsim-package-version)_all.deb
rm -rf frcsim-gazebo-plugins/frcsim-gazebo-plugins/src
# orig support (for faster parallel builds)
.PHONY: orig-frcsim-gazebo-plugins orig-frcsim-gazebo-models orig-frcsim-eclipse-plugins \
orig-frcsim-eclipse-toolchain-plugin orig-frcsim-libwpilibsim-cpp orig-frcsim
.PHONY: pull-gazebo-plugins pull-eclipse-plugins pull-libwpilibsim-cpp
rm -rf frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/src
rm -rf frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/include
rm -f frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/Makefile
rm -f frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/CMakeLists.txt
rm -rf frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/target
pull: clean pull-gazebo-plugins pull-eclipse-plugins pull-libwpilibsim-cpp orig
orig-frcsim-gazebo-models: frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-version).orig.tar.gz
frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-version).orig.tar.gz:
cd frcsim-gazebo-models && \
wget --no-check-certificate $(gazebo-models-orig-url) -O frcsim-gazebo-models_$(gazebo-models-version).orig.tar.gz && \
tar xvf frcsim-gazebo-models_$(gazebo-models-version).orig.tar.gz
orig-frcsim-gazebo-plugins: frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-version).orig.tar.gz
pull-gazebo-plugins:
cp -rf -t frcsim-gazebo-plugins/frcsim-gazebo-plugins/ $(allwpilib)/simulation/frc_gazebo_plugins/*
echo Increment version?
frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-version).orig.tar.gz: pull-gazebo-plugins
cd frcsim-gazebo-plugins/frcsim-gazebo-plugins && debuild clean
rm -f frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-version).orig.tar.gz
cd frcsim-gazebo-plugins && tar --exclude="./debian" -czvf \
frcsim-gazebo-plugins_$(gazebo-plugins-version).orig.tar.gz frcsim-gazebo-plugins
orig-frcsim-eclipse-plugins: frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-version).orig.tar.gz
pull-eclipse-plugins:
rm -rf frcsim-eclipse-plugins/frcsim-eclipse-plugins/plugins
rm -rf frcsim-eclipse-plugins/frcsim-eclipse-plugins/features
@@ -106,7 +110,13 @@ pull-eclipse-plugins:
cp $(allwpilib)/eclipse-plugins/edu.wpi.first.wpilib.plugins.updatesite/target/site/features/edu.wpi.first.wpilib.plugins.cpp.feature_* frcsim-eclipse-plugins/frcsim-eclipse-plugins/features
cp $(allwpilib)/eclipse-plugins/edu.wpi.first.wpilib.plugins.updatesite/target/site/features/edu.wpi.first.wpilib.plugins.core.feature_* frcsim-eclipse-plugins/frcsim-eclipse-plugins/features
echo Increment version?
frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-version).orig.tar.gz: pull-eclipse-plugins
cd frcsim-eclipse-plugins/frcsim-eclipse-plugins && debuild clean
rm -f frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-version).orig.tar.gz
cd frcsim-eclipse-plugins && tar --exclude="./debian" -czvf \
frcsim-eclipse-plugins_$(eclipse-plugins-version).orig.tar.gz frcsim-eclipse-plugins
orig-frcsim-eclipse-toolchain-plugin: frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-version).orig.tar.gz
pull-eclipse-toolchain:
rm -rf frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin/plugins
rm -rf frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin/features
@@ -115,24 +125,76 @@ pull-eclipse-toolchain:
cp $(allwpilib)/eclipse-plugins/edu.wpi.first.wpilib.plugins.updatesite/target/site/plugins/edu.wpi.first.wpilib.plugins.cpp.toolchains.linux_* frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin/plugins/
cp $(allwpilib)/eclipse-plugins/edu.wpi.first.wpilib.plugins.updatesite/target/site/features/edu.wpi.first.wpilib.plugins.cpp.toolchains.linux.feature_* frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin/features/
echo Increment version?
frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-version).orig.tar.gz: pull-eclipse-toolchain
cd frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin && debuild clean
rm -f frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-version).orig.tar.gz
cd frcsim-eclipse-toolchain-plugin && tar --exclude="./debian" -czvf \
frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-version).orig.tar.gz frcsim-eclipse-toolchain-plugin
orig-frcsim-libwpilibsim-cpp: frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-version).orig.tar.gz
pull-libwpilibsim-cpp:
cp -rf -t frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/ $(allwpilib)/wpilibc/wpilibC++Sim/*
mkdir -p frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/allwpilib
cp -rf $(allwpilib)/hal frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/allwpilib
mkdir -p frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/allwpilib/networktables
cp -rf $(allwpilib)/networktables/cpp frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/allwpilib/networktables
mkdir -p frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/allwpilib/wpilibc
cp -r $(allwpilib)/wpilibc/wpilibC++ frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp/allwpilib/wpilibc
echo Increment version?
frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-version).orig.tar.gz: pull-libwpilibsim-cpp
cd frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp && debuild clean
rm -f frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-version).orig.tar.gz
cd frcsim-libwpilibsim-cpp && tar --exclude="./debian" -czvf \
frcsim-libwpilibsim-cpp_$(libwpilibsim-version).orig.tar.gz frcsim-libwpilibsim-cpp
download-models:
cd frcsim-gazebo-models && \
wget --no-check-certificate $(gazebo-models-orig-url) -O frcsim-gazebo-models_${gazebo-models-version}.orig.tar.gz && \
tar xvf frcsim-gazebo-models_${gazebo-models-version}.orig.tar.gz
orig-frcsim: frcsim/frcsim_$(frcsim-version).orig.tar.gz
frcsim/frcsim_$(frcsim-version).orig.tar.gz:
cd frcsim/frcsim && debuild clean
rm -f frcsim/frcsim_$(frcsim-version).orig.tar.gz
cd frcsim && tar --exclude="./debian" -czvf \
frcsim_$(frcsim-version).orig.tar.gz frcsim
install:
sudo dpkg -i frcsim-gazebo-plugins/frcsim-gazebo-plugins_0.2-1_amd64.deb \
frcsim-gazebo-models/frcsim-gazebo-models_0.2-1_all.deb \
frcsim-eclipse-plugins/frcsim-eclipse-plugins_0.1-1_all.deb \
frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_0.1-1_all.deb \
frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_0.1-1_amd64.deb \
frcsim/frcsim_0.1-1_all.deb
# debs support (for faster parallel builds)
.PHONY: debs-frcsim-gazebo-plugins debs-frcsim-gazebo-models debs-frcsim-eclipse-plugins \
debs-frcsim-eclipse-toolchain-plugin debs-frcsim-libwpilibsim-cpp debs-frcsim
deploy:
rsync -r -v -C -p repository/ adhenning@ccc.wpi.edu:public_html/frcsim/
debs-frcsim-gazebo-plugins: frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_amd64.deb frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_i386.deb
frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_i386.deb: frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-version).orig.tar.gz frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_amd64.deb
cd frcsim-gazebo-plugins/frcsim-gazebo-plugins && make clean
cd frcsim-gazebo-plugins && sbuild --arch=i386 -A -d trusty-i386 frcsim-gazebo-plugins_$(gazebo-plugins-package-version).dsc
frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-package-version)_amd64.deb: frcsim-gazebo-plugins/frcsim-gazebo-plugins_$(gazebo-plugins-version).orig.tar.gz
cd frcsim-gazebo-plugins/frcsim-gazebo-plugins && debuild --no-lintian -us -uc -aamd64
debs-frcsim-gazebo-models: frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-package-version)_all.deb
frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-package-version)_all.deb: frcsim-gazebo-models/frcsim-gazebo-models_$(gazebo-models-version).orig.tar.gz
cd frcsim-gazebo-models/frcsim-gazebo-models && debuild --no-lintian -us -uc
debs-frcsim-eclipse-plugins: frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-package-version)_all.deb
frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-package-version)_all.deb: frcsim-eclipse-plugins/frcsim-eclipse-plugins_$(eclipse-plugins-version).orig.tar.gz
cd frcsim-eclipse-plugins/frcsim-eclipse-plugins && debuild --no-lintian -us -uc
debs-frcsim-eclipse-toolchain-plugin: frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-package-version)_all.deb
frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-package-version)_all.deb: frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin_$(eclipse-toolchain-version).orig.tar.gz
cd frcsim-eclipse-toolchain-plugin/frcsim-eclipse-toolchain-plugin && debuild --no-lintian -us -uc
debs-frcsim-libwpilibsim-cpp: frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_amd64.deb frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_i386.deb
frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_i386.deb: frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-version).orig.tar.gz frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_amd64.deb
cd frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp && make clean
cd frcsim-libwpilibsim-cpp && sbuild --arch=i386 -A -d trusty-i386 frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version).dsc
frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-package-version)_amd64.deb: frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp_$(libwpilibsim-version).orig.tar.gz
cd frcsim-libwpilibsim-cpp/frcsim-libwpilibsim-cpp && debuild --no-lintian -us -uc -aamd64
debs-frcsim: frcsim/frcsim_$(frcsim-package-version)_all.deb
frcsim/frcsim_$(frcsim-package-version)_all.deb: frcsim/frcsim_$(frcsim-version).orig.tar.gz
cd frcsim/frcsim && debuild --no-lintian -us -uc
### SBUILD
#
# For building 32-bit builds on 64-bit machines
#
# $ mk-sbuild --arch i386 --personality=linux32 trusty
# To CHANGE the golden image: sudo schroot -c source:trusty-i386 -u root
# To ENTER an image snapshot: schroot -c trusty-i386
# To BUILD within a snapshot: sbuild -A -d trusty-i386 PACKAGE*.dsc
#
# sbuild --arch=i386 -A -d trusty-i386 frcsim-gazebo-plugins_0.2-1.dsc

View File

@@ -1,3 +1,6 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_strip:
strip --remove-section=.comment --remove-section=.note --strip-unneeded debian/frcsim-gazebo-plugins/usr/lib/frcsim/plugins/libgz_potentiometer.so

View File

@@ -3,7 +3,9 @@
dh $@
override_dh_auto_build:
$(MAKE) allwpilib=../../../..
$(MAKE) allwpilib=allwpilib
override_dh_auto_install:
$(MAKE) DESTDIR=$$(pwd)/debian/frcsim-libwpilibsim-cpp allwpilib=../../../.. install
$(MAKE) DESTDIR=$$(pwd)/debian/frcsim-libwpilibsim-cpp allwpilib=allwpilib install
override_dh_strip:

View File

@@ -1,4 +1,5 @@
#!/bin/bash
export GAZEBO_PLUGIN_PATH="${GAZEBO_PLUGIN_PATH}:/usr/lib/frcsim/plugins"
export GAZEBO_MODEL_PATH="${GAZEBO_MODEL_PATH}:/usr/share/frcsim/models"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/usr/lib/frcsim/plugins"
gazebo $@

View File

@@ -104,15 +104,15 @@ function install-frcsim {
fi
# Add FRCSim Repository and Key
if ! echo "deb http://users.wpi.edu/~adhenning/frcsim `lsb_release -cs` main" > /etc/apt/sources.list.d/frcsim-latest.list
if ! echo "deb http://first.wpi.edu/FRC/roborio/release/linux `lsb_release -cs` main" > /etc/apt/sources.list.d/frcsim-latest.list
then
echo "*** Cannot add FRCSim repository!" 1>&2
install-fail
fi
if ! (wget users.wpi.edu/~adhenning/frcsim.key -O - | apt-key add -)
if ! (wget first.wpi.edu/FRC/roborio/wpilib.gpg.key -O - | apt-key add -)
then
echo "*** Cannot add FRCSim repository key!" 1>&2
if ! ping users.wpi.edu -c 1 >/dev/null; then
if ! ping first.wpi.edu -c 1 >/dev/null; then
echo "*** The package host for FRCSim appears to be down. Try again later." 1>&2
fi
install-fail

4
test-scripts/.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
*.sh text eol=lf

381
test-scripts/README.html Normal file
View File

@@ -0,0 +1,381 @@
<!DOCTYPE html><html><head><meta charset="utf-8"><style>/* Fonts */
@font-face{
font-family: octicons-anchor;
src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
}
@font-face{
font-family: fontawesome-mini;
src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
}
/* Body */
html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
body{
color:#4d4d4c;
font-family:Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman',
"Hiragino Sans GB", "STXihei", "微软雅黑", serif;
font-size:12px;
line-height:1.5em;
background:#fefefe;
width: 45em;
margin: 10px auto;
padding: 30px;
border: 1px solid #ddd;
outline: 1300px solid #f8f8f8;
}
/* Links */
a{ color: #06d; text-decoration:none; }
a:hover{ color: #06e; text-decoration: underline; }
a:active{ color:#faa700; }
a:focus{ outline: thin dotted; }
a:hover, a:active{ outline: 0; }
::-moz-selection { background:#a8d1ff; color:#000 }
::selection { background:#a8d1ff; color:#000 }
a::-moz-selection { background:#a8d1ff; color:#0645ad }
a::selection { background:#a8d1ff; color:#0645ad }
/* Header Anchor Links*/
.headeranchor-link {
color:#111;
border: 0;
margin-left: -20px;
padding-right: 6px;
cursor: pointer;
position: absolute;
display: block;
top: 0;
left: 0;
bottom: 0;
}
.headeranchor {
font: normal normal 16px octicons-anchor;
line-height: 1;
-moz-osx-font-smoothing: grayscale;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.headeranchor-link:hover,
.headeranchor-link:visited,
.headeranchor-link:active
{ text-decoration: none; color:#4d4d4c; }
.headeranchor-link:hover .headeranchor:before,
h1:hover .headeranchor:before,
h2:hover .headeranchor:before,
h3:hover .headeranchor:before,
h4:hover .headeranchor:before,
h5:hover .headeranchor:before,
h6:hover .headeranchor:before
{ content: '\f05c'; }
abbr { cursor: pointer; }
/* Paragraphs */
p { margin:1em 0; }
/* Images */
img {
max-width:100%;
border: 0;
-ms-interpolation-mode: bicubic;
vertical-align: middle;
}
/* Headers */
h1,h2,h3,h4,h5,h6 {
font-weight:normal;
color:#111;
line-height: 1.7;
position: relative;
}
h4,h5,h6{ font-weight: bold; }
h1 { font-size:2.5em; border-bottom: 1px solid #ddd;}
h2 { font-size:2em; border-bottom:1px solid #eee; padding-bottom: 5px; }
h3 { font-size:1.5em; }
h4 { font-size:1.2em; }
h5 { font-size:1em; }
h6 { font-size:0.9em; }
/* Block Quotes */
blockquote {
color:#666666;
margin:0;
padding-left: 3em;
border-left: 0.5em #EEE solid;
}
hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa;border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; }
/* Raw Blocks */
pre, code, kbd, samp {
color: #000;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
font-size: 0.88em;
background-color: #F8F8F8;
border: 1px solid #CCC;
}
pre {
padding: 10px;
overflow: auto;
}
code { padding: 0 3px 0 3px; }
pre code { border: 0; padding: 0; }
/* Admonition */
.admonition {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
font-size: 0.88em;
padding: 0.5em 1em 0.5em 1em;
margin: 10px auto;
color: #888888;
background-color: #F8F8F8;
border: 1px solid #888888;
}
.admonition p { padding: 0; margin: 0; }
.admonition-title { font-weight: bold; margin: 0; }
.admonition-icon {
font: normal normal 16px fontawesome-mini;
line-height: 1.5;
-moz-osx-font-smoothing: grayscale;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
float: left;
}
.admonition.attention { color: #4F8A10; background-color: #DFF2BF; border: 1px solid #4F8A10; }
.admonition.caution { color: #D63301; background-color: #FFCCBA; border: 1px solid #D63301; }
.admonition.hint { color: #00529B; background-color: #BDE5F8; border: 1px solid #00529B; }
.admonition.danger { color: #D8000C; background-color: #FFBABA; border: 1px solid #D8000C; }
.admonition.question { color: #00049b; background-color: #BDC8F8; border: 1px solid #00049b; }
.admonition.note { color: #9F6000; background-color: #FEEFB3; border: 1px solid #9F6000; }
.attention > .admonition-icon:before { content: "\f058\00a0"; }
.caution > .admonition-icon:before { content: "\f06a\00a0"; }
.hint > .admonition-icon:before { content: "\f05a\00a0"; }
.danger > .admonition-icon:before { content: "\f056\00a0"; }
.question > .admonition-icon:before { content: "\f059\00a0"; }
.note > .admonition-icon:before { content: "\f040\00a0"; }
/* progress bar*/
.progress {
display: block;
width: 300px;
margin: 10px 0;
height: 24px;
border: 1px solid #ccc;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #F8F8F8;
position: relative;
box-shadow: inset -1px 1px 3px rgba(0, 0, 0, .1);
}
.progress-label {
position: absolute;
text-align: center;
font-weight: bold;
width: 100%; margin: 0;
line-height: 24px;
color: #333;
text-shadow:
1px 1px 0px #fefefe,
-1px -1px 0px #fefefe,
-1px 1px 0px #fefefe,
1px -1px 0px #fefefe,
0px 1px 0px #fefefe,
0px -1px 0px #fefefe,
1px 0px 0px #fefefe,
-1px 0px 0px #fefefe,
1px 1px 2px #000;
-webkit-font-smoothing: antialiased !important;
white-space: nowrap;
overflow: hidden;
}
.progress-bar {
height: 24px;
float: left;
border-right: 1px solid #ccc;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #34c2e3;
box-shadow: inset 0 1px 0px rgba(255, 255, 255, .5);
background-size: 30px 30px;
background-image: -webkit-linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
background-image: -moz-linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
background-image: -ms-linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
background-image: -o-linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
background-image: linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
}
.progress-100plus .progress-bar { background-color: #1ee038; }
.progress-80plus .progress-bar { background-color: #86e01e; }
.progress-60plus .progress-bar { background-color: #f2d31b; }
.progress-40plus .progress-bar { background-color: #f2b01e; }
.progress-20plus .progress-bar { background-color: #f27011; }
.progress-0plus .progress-bar { background-color: #f63a0f; }
.gloss .progress-bar {
box-shadow:
inset -1px 1px 0px rgba(255, 255, 255, .5),
inset 0 -4px 12px rgba(255, 255, 255, .7),
inset 0 4px 12px rgba(255, 255, 255, .7),
inset 0 -12px 0px rgba(0, 0, 0, .05),
inset 1px -1px 0px rgba(255, 255, 255, .2);
}
.candystripe-animate .progress-bar{
-webkit-animation: animate-stripes 3s linear infinite;
-moz-animation: animate-stripes 3s linear infinite;
animation: animate-stripes 3s linear infinite;
}
@-webkit-keyframes animate-stripes { 0% { background-position: 0 0; } 100% { background-position: 60px 0; } }
@-moz-keyframes animate-stripes { 0% { background-position: 0 0; } 100% { background-position: 60px 0; } }
@keyframes animate-stripes { 0% { background-position: 0 0; } 100% { background-position: 60px 0; } }
/* Inlines */
b, strong { font-weight: bold; }
mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }
dfn { font-style: italic; }
/* Lists */
ul, ol { padding-left: 30px; }
li p:last-child { margin:0 }
.task-list-item { list-style-type: none; }
.task-list-item input { float:left; margin-left: -20px; margin-top: 6px; }
dt { font-weight: bold; font-style: italic;}
dd { margin: 0 0 0 2em; }
/* Tables */
table { width: 100%; border-collapse: collapse; overflow-x: auto; overflow-y: hidden; display: block;}
table tr { background-color: #fefefe; }
table tr:nth-child(2n) { background-color: #f8f8f8; }
td, th { border: 1px solid #ddd; padding: 6px 13px; }
/* Codehilite Tables */
.codehilitetable { border: 0; border-spacing: 0; }
.linenos, .code, .codehilitetable td { border: 0; padding: 0; }
td:not(.linenos) .linenodiv { padding: 0 !important; }
.code { width: 100%; }
.linenos div pre, .linenodiv pre {
border: 0;
border-top: 1px solid #CCC;
border-left: 1px solid #CCC;
border-right: 1px solid #CCC;
border-bottom: 1px solid #CCC;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-border-top-left-radius: 3px;
-webkit-border-bottom-left-radius: 3px;
-moz-border-radius-topleft: 3px;
-moz-border-radius-bottomleft: 3px;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.code div pre {
border: 0;
border-top: 1px solid #CCC;
border-right: 1px solid #CCC;
border-bottom: 1px solid #CCC;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-border-top-right-radius: 3px;
-webkit-border-bottom-right-radius: 3px;
-moz-border-radius-topright: 3px;
-moz-border-radius-bottomright: 3px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
/* Media */
@media only screen and (min-width: 480px) {
body{ font-size:14px; }
}
@media only screen and (min-width: 768px) {
body{ font-size:16px; }
}
@media print {
* { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; }
body{ font-size:12pt; max-width:100%; outline:none; border: 0;}
a, a:visited { text-decoration: underline; }
.headeranchor-link { display: none; }
hr { height: 1px; border:0; border-bottom:1px solid black; }
a[href]:after { content: " (" attr(href) ")"; }
abbr[title]:after { content: " (" attr(title) ")"; }
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
pre, blockquote { border: 1px solid #999; padding-right: 1em; page-break-inside: avoid; }
.progress, .progress-bar { box-shadow: none; }
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
p, h2, h3 { orphans: 3; widows: 3; }
h2, h3 { page-break-after: avoid; }
}
</style><title>README</title></head><body><h1 id="wpilib-test-scripts"><a name="user-content-wpilib-test-scripts" href="#wpilib-test-scripts" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>WPILIB TEST SCRIPTS</h1>
<h2 id="overview"><a name="user-content-overview" href="#overview" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>Overview</h2>
<p>These test scripts are designed to allow the user of the WPILib test framework to quickly and easily deploy and run their tests on the WPI roboRIO.</p>
<p>In order for the automated test system to work there is a driver station onboard the roboRIO that handles a queue of users waiting to use the driver station. All of the interaction with this queue is handled internally by test scripts contained within this file.</p>
<h2 id="running-tests"><a name="user-content-running-tests" href="#running-tests" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>Running Tests</h2>
<p>See screen steps live: [TODO: Add link to screen steps live]</p></body></html>

9
test-scripts/README.md Normal file
View File

@@ -0,0 +1,9 @@
# WPILIB TEST SCRIPTS
## Overview
These test scripts are designed to allow the user of the WPILib test framework to quickly and easily deploy and run their tests on the WPI roboRIO.
In order for the automated test system to work there is a driver station onboard the roboRIO that handles a queue of users waiting to use the driver station. All of the interaction with this queue is handled internally by test scripts contained within this file.
## Running Tests
See screen steps live: [TODO: Add link to screen steps live]

38
test-scripts/config.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env bash
#*----------------------------------------------------------------------------*#
#* 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 the root directory of *#
#* the project. *#
#*----------------------------------------------------------------------------*#
# If this is changed, update the .gitignore
# so that test results are not commited to the repo
DEFAULT_LOCAL_TEST_RESULTS_DIR=../test-reports
ROBOT_ADDRESS=admin@roboRIO-190.local
DEFAULT_LOCAL_RUN_TEST_SCRIPT="run-tests-on-robot.sh"
DEFAULT_DESTINATION_DIR=/home/admin
DEFAULT_TEST_SCP_DIR=${DEFAULT_DESTINATION_DIR}/deployedTests
DEFAULT_DESTINATION_TEST_RESULTS_DIR=${DEFAULT_DESTINATION_DIR}/testResults
# C++ test variables
DEFAULT_CPP_TEST_NAME=FRCUserProgram
DEFAULT_CPP_TEST_ARGS="--gtest_color=yes"
DEFAULT_LOCAL_CPP_TEST_FILE=../cmake/target/cmake/wpilibc/wpilibC++IntegrationTests/FRCUserProgram
CPP_REPORT=cppreport.xml
DEFAULT_LOCAL_CPP_TEST_RESULT=${DEFAULT_LOCAL_TEST_RESULTS_DIR}/${CPP_REPORT}
DEFAULT_DESTINATION_CPP_TEST_RESULTS=${DEFAULT_DESTINATION_TEST_RESULTS_DIR}/${CPP_REPORT}
# Java test variables
DEFAULT_JAVA_TEST_NAME=FRCUserProgram.jar
DEFAULT_JAVA_TEST_ARGS=""
DEFAULT_LOCAL_JAVA_TEST_FILE=../wpilibj/wpilibJavaIntegrationTests/target/wpilibJavaIntegrationTests-0.1.0-SNAPSHOT.jar
JAVA_REPORT=javareport.xml
DEFAULT_LOCAL_JAVA_TEST_RESULT=${DEFAULT_LOCAL_TEST_RESULTS_DIR}/${JAVA_REPORT}
DEFAULT_DESTINATION_JAVA_TEST_RESULTS=${DEFAULT_DESTINATION_TEST_RESULTS_DIR}/AntReports/TEST-edu.wpi.first.wpilibj.test.TestSuite.xml

View File

@@ -0,0 +1,82 @@
#!/usr/bin/env bash
#*----------------------------------------------------------------------------*#
#* 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 the root directory of *#
#* the project. *#
#*----------------------------------------------------------------------------*#
# Configurable variables
source config.sh
# Java variables
DEFAULT_DESTINATION_JAVA_TEST_FILE=${DEFAULT_TEST_SCP_DIR}/${DEFAULT_JAVA_TEST_NAME}
# C++ Variables
DEFAULT_DESTINATION_CPP_TEST_FILE=${DEFAULT_TEST_SCP_DIR}/${DEFAULT_CPP_TEST_NAME}
DEFAULT_DESTINATION_RUN_TEST_SCRIPT=${DEFAULT_DESTINATION_DIR}/${DEFAULT_LOCAL_RUN_TEST_SCRIPT}
usage="$(basename "$0") [-h] (java|cpp) [-A] [arg] [arg]...
A script designed to run the integration tests.
This script should only be run on the roborio.
Where:
-h Show this help text.
-A Disable language recomended arguments.
arg Additional arguments to be passed to test."
# These variables are set when the language is selected
LANGUAGE=none
LOCAL_TEST_FILE=none
DESTINATION_TEST_FILE=none
TEST_RUN_ARGS=""
# Begin searching for options from the third paramater on
PARAM_ARGS=${@:2}
if [[ "$1" = java ]]; then
LANGUAGE=$1
LOCAL_TEST_FILE=$DEFAULT_LOCAL_JAVA_TEST_FILE
DESTINATION_TEST_FILE=$DEFAULT_DESTINATION_JAVA_TEST_FILE
elif [[ "$1" = cpp ]]; then
LANGUAGE=$1
LOCAL_TEST_FILE=$DEFAULT_LOCAL_CPP_TEST_FILE
DESTINATION_TEST_FILE=$DEFAULT_DESTINATION_CPP_TEST_FILE
elif [[ "$1" = "-h" ]]; then
printf "Usage:\n"
echo "$usage"
exit
else
printf "Invalid language selection: %s\n\n" "$1" >&2
echo "$usage" >&2
exit 1
fi
# Check if the test file to upload exists
if [[ ! -e ${LOCAL_TEST_FILE} ]]; then
printf "The test file does not exist: %s\nAre you sure that you compiled the tests??\n\n" "${LOCAL_TEST_FILE}" >&2
echo "$usage" >&2
exit 1
fi
TEST_RUN_ARGS="${@:2}"
shopt -s huponexit
SCP_TEST_SCRIPT="scp config.sh ${DEFAULT_LOCAL_RUN_TEST_SCRIPT} ${ROBOT_ADDRESS}:/${DEFAULT_DESTINATION_DIR}"
SSH_CHMOD_AND_MAKE_TEMP_TEST_DIR="ssh -t ${ROBOT_ADDRESS} chmod a+x ${DEFAULT_DESTINATION_RUN_TEST_SCRIPT}; mkdir ${DEFAULT_TEST_SCP_DIR} 2>/dev/null"
SCP_TEST_PROGRAM="scp ${LOCAL_TEST_FILE} ${ROBOT_ADDRESS}:/${DESTINATION_TEST_FILE}"
SSH_RUN_TESTS="ssh -t ${ROBOT_ADDRESS} ${DEFAULT_DESTINATION_RUN_TEST_SCRIPT} ${LANGUAGE} $(whoami) -d ${DEFAULT_TEST_SCP_DIR} ${TEST_RUN_ARGS}"
if [ $(which sshpass) ]; then
sshpass -p "" ${SCP_TEST_SCRIPT}
sshpass -p "" ${SSH_CHMOD_AND_MAKE_TEMP_TEST_DIR}
sshpass -p "" ${SCP_TEST_PROGRAM}
sshpass -p "" ${SSH_RUN_TESTS}
else
eval ${SCP_TEST_SCRIPT}
eval ${SSH_CHMOD_AND_MAKE_TEMP_TEST_DIR}
eval ${SCP_TEST_PROGRAM}
eval ${SSH_RUN_TESTS}
fi

View File

@@ -0,0 +1,50 @@
#!/usr/bin/env bash
#*----------------------------------------------------------------------------*#
#* 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 the root directory of *#
#* the project. *#
#*----------------------------------------------------------------------------*#
# Configurable variables
source config.sh
# If there are already test results in the repository then remove them
if [[ -e ${DEFAULT_LOCAL_TEST_RESULTS_DIR} ]]; then
rm -R ${DEFAULT_LOCAL_TEST_RESULTS_DIR}
fi
# Make the directory where the tests should live
mkdir ${DEFAULT_LOCAL_TEST_RESULTS_DIR} 2>/dev/null
# Remove the preivous test results from the the robot
SSH_REMOVE_OLD_TEST_RESULTS="ssh -t ${ROBOT_ADDRESS} rm -R ${DEFAULT_DESTINATION_TEST_RESULTS_DIR}; mkdir ${DEFAULT_DESTINATION_TEST_RESULTS_DIR}"
if [ $(which sshpass) ]; then
sshpass -p "" ${SSH_REMOVE_OLD_TEST_RESULTS}
else
eval ${SSH_REMOVE_OLD_TEST_RESULTS}
fi
printf "Running cpp test\n"
# Run the C++ Tests
./deploy-and-run-test-on-robot.sh cpp -A "--gtest_output=xml:${DEFAULT_DESTINATION_CPP_TEST_RESULTS}"
# Retrive the C++ Test Results
SCP_GET_CPP_TEST_RESULT="scp ${ROBOT_ADDRESS}:${DEFAULT_DESTINATION_CPP_TEST_RESULTS} ${DEFAULT_LOCAL_CPP_TEST_RESULT}"
if [ $(which sshpass) ]; then
sshpass -p "" ${SCP_GET_CPP_TEST_RESULT}
else
eval ${SCP_GET_CPP_TEST_RESULT}
fi
# Run the Java Tests
./deploy-and-run-test-on-robot.sh java
# Retrive the Java Test Results
SCP_GET_JAVA_TEST_RESULT="scp ${ROBOT_ADDRESS}:${DEFAULT_DESTINATION_JAVA_TEST_RESULTS} ${DEFAULT_LOCAL_JAVA_TEST_RESULT}"
if [ $(which sshpass) ]; then
sshpass -p "" ${SCP_GET_JAVA_TEST_RESULT}
else
eval ${SCP_GET_JAVA_TEST_RESULT}
fi

View File

@@ -0,0 +1,166 @@
#!/usr/bin/env bash
#*----------------------------------------------------------------------------*#
#* 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 the root directory of *#
#* the project. *#
#*----------------------------------------------------------------------------*#
# This file is intended to be run in the DEFAULT_TEST_DIR on the roboRIO.
# Do not attempt to run this file on your local system.
# There is one file (delploy-and-run-test-on-robot.sh) that is designed to
# deploy this file allong with the compiled tests for you.
# Configurable variables
source config.sh
DEFAULT_TEST_DIR=${DEFAULT_DESTINATION_DIR}
DEFAULT_PATH_TO_JRE=/usr/local/frc/JRE/bin/java
usage="$(basename "$0") [-h] (java|cpp) name [-d test_dir] [-A] [arg] [arg]...
A script designed to run the integration tests.
This script should only be run on the roborio.
Where:
-h Show this help text
name The name of the user trying to run the tests (used for driver station)
-d The directory where the tests have been placed.
This is done to prevent overwriting an already running program
in the case where another user already has the driver station mutex.
This scrip will automatically move the test into the ${DEFAULT_TEST_DIR}
directory when the driver station mutex is released.
Default: Assumes the test is in the same directory as this scrip.
-A Do not use the default arguments for the given language.
arg The arguments to be passed to test."
mutexTaken=false
# This function should run even if the script exits abnormally
function finish {
if [ "$mutexTaken" == true ]; then
/usr/local/frc/bin/teststand ds --name="${NAME}" disable
/usr/local/frc/bin/teststand give --name="${NAME}"
mutexTaken=false
fi
}
trap finish EXIT SIGINT
# This function should be run asynchronysly to enable the tests 10
# seconds after they have been run.
function enableIn10Seconds {
sleep 10
/usr/local/frc/bin/teststand ds --name="${NAME}" enable
}
# Are you trying to run this program on a platform other than the roboRIO?
if [[ ! -e "${DEFAULT_TEST_DIR}" ]]; then
printf "Failed to find %s\nAre you trying to run this file on your local computer?\n" "${DEFAULT_TEST_DIR}"
printf "This script should only be run on the roboRIO.\n\n"
echo "$usage"
exit 1
fi
LANGUAGE=none
TEST_FILE=none
NAME=$2
TEST_DIR="$DEFAULT_TEST_DIR"
# Begin searching for options from the third paramater on
PARAM_ARGS=${@:3}
# Where the test arguments start
TEST_RUN_ARGS=${@:3}
RUN_WITH_DEFAULT_ARGS=true
DEFAULT_ARGS=""
# Determine the language that we are attempting to run
if [[ "$1" = java ]]; then
LANGUAGE=$1
TEST_FILE=$DEFAULT_JAVA_TEST_NAME
DEFAULT_ARGS=$DEFAULT_JAVA_TEST_ARGS
elif [[ "$1" = cpp ]]; then
LANGUAGE=$1
TEST_FILE=$DEFAULT_CPP_TEST_NAME
DEFAULT_ARGS=$DEFAULT_CPP_TEST_ARGS
elif [[ "$1" = "-h" ]]; then
#If the first argument is the help option
#Allow it to be searhced for in getopts
PARAM_ARGS=${@}
else
printf "Invalid language selection: %s\n\n" "$1" >&2
echo "$usage" >&2
exit 1
fi
PARAM_COUNTER=2
printf "Param Args ${PARAM_ARGS}\n"
# Check for optional paramaters
while getopts ':hd:A' option $PARAM_ARGS ; do
case "$option" in
h)
# Print the help message
printf "Usage:\n"
echo "$usage"
exit
;;
A)
# Remove the default arguments
RUN_WITH_DEFAULT_ARGS=false
PARAM_COUNTER=$[$PARAM_COUNTER +1]
;;
d)
TEST_DIR=$OPTARG
# Since we are selecting the directory the run args start from the 5th argument
PARAM_COUNTER=$[$PARAM_COUNTER +2]
;;
?)
# When an unknown param is found then we are done so break
break
;;
esac
done
TEST_RUN_ARGS=${@:$[$PARAM_COUNTER +1]}
if [[ "$RUN_WITH_DEFAULT_ARGS" == true ]]; then
TEST_RUN_ARGS="${DEFAULT_ARGS} ${TEST_RUN_ARGS}"
fi
# Make sure at least two paramaters are passed or four if running with -d option
if [[ $# -lt $PARAM_COUNTER ]]; then
printf "Invalid arg count. Should be %s, was %s.\n" "${PARAM_COUNTER}" "$#"
echo "$usage"
exit 1
fi
# Attempt to take the mutex for the driver station
mutexTaken=true
/usr/local/frc/bin/teststand take --name="${NAME}"
# Kill all running robot programs
killall java FRCUserProgram
# Once we have the mutex no other tests are running
# If we are running with the -d argument move the test to the DEFAULT_TEST_DIR
if [[ ! -e "${TEST_DIR}/${TEST_FILE}" ]]; then
printf "Failed to find %s.\nDid you copy the test file correctly?\n" "${TEST_DIR}/${TEST_FILE}"
echo "$usage"
exit 1
elif [[ $TEST_DIR != "$DEFAULT_TEST_DIR" ]]; then
mv "${TEST_DIR}/${TEST_FILE}" "${DEFAULT_TEST_DIR}"
fi
# Make sure the excecutable file has permission to run
# Setup the driver station to enable automatically in 10 seconds without waiting for the function to excecute.
enableIn10Seconds&
# Store the run command for the language
RUN_COMMAND=none
if [[ ${LANGUAGE} = java ]]; then
chmod a+x ${DEFAULT_JAVA_TEST_NAME}
RUN_COMMAND="${DEFAULT_PATH_TO_JRE} -ea -jar ${DEFAULT_JAVA_TEST_NAME} ${TEST_RUN_ARGS}"
elif [[ ${LANGUAGE} = cpp ]]; then
chmod a+x ${DEFAULT_CPP_TEST_NAME}
RUN_COMMAND="./${DEFAULT_CPP_TEST_NAME} ${TEST_RUN_ARGS}"
fi
printf "Running: %s\n\n" "${RUN_COMMAND}"
eval ${RUN_COMMAND}

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
#*----------------------------------------------------------------------------*#
#* 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 the root directory of *#
#* the project. *#
#*----------------------------------------------------------------------------*#
source config.sh
TESTSTAND_SERVE_COMMAND=".scratch/teststand serve"
#Checks to see if the mutex driver station is running. If it isn't then start it.
SSH_CHECK_FOR_TESTSTAND="ssh -qn ${ROBOT_ADDRESS} 'pidof ${TESTSTAND_SERVE_COMMAND}' &>/dev/null"
if [ $(which sshpass) ]; then
SSH_CHECK_FOR_TESTSTAND="sshpass -p '' ${SSH_CHECK_FOR_TESTSTAND}"
fi
echo $SSH_CHECK_FOR_TESTSTAND
if $(eval $SSH_CHECK_FOR_TESTSTAND); then
echo "Driver Station is already running";
exit 0;
fi
echo "Starting Driver Station";
function startDS {
SSH_START_TESTSTAND_DRIVER_STATION="ssh ${ROBOT_ADDRESS} ${TESTSTAND_SERVE_COMMAND}"
if [ $(which sshpass) ]; then
sshpass -p "" ${SSH_START_TESTSTAND_DRIVER_STATION}
else
eval ${SSH_START_TESTSTAND_DRIVER_STATION}
fi
}
startDS&
sleep 1

View File

@@ -5,6 +5,8 @@
/*----------------------------------------------------------------------------*/
#pragma once
#include <stdint.h>
/**
* Interface for counting the number of ticks on a digital input channel.
* Encoders, Gear tooth sensors, and counters should all subclass this so it can

View File

@@ -11,7 +11,7 @@
/**
* DoubleSolenoid class for running 2 channels of high voltage Digital Output
* (9472 module).
* (PCM).
*
* The DoubleSolenoid class is typically used for pneumatics solenoids that
* have two positions controlled by two separate channels.

View File

@@ -10,10 +10,10 @@
#include "tables/ITableListener.h"
/**
* Solenoid class for running high voltage Digital Output (9472 module).
* Solenoid class for running high voltage Digital Output (PCM).
*
* The Solenoid class is typically used for pneumatics solenoids, but could be used
* for any device within the current spec of the 9472 module.
* for any device within the current spec of the PCM.
*/
class Solenoid : public SolenoidBase, public LiveWindowSendable, public ITableListener
{

View File

@@ -50,6 +50,8 @@ RobotBase::RobotBase()
, m_ds (NULL)
{
m_ds = DriverStation::GetInstance();
RobotState::SetImplementation(DriverStation::GetInstance()); \
HLUsageReporting::SetImplementation(new HardwareHLReporting()); \
}
/**
@@ -152,9 +154,6 @@ void RobotBase::startRobotTask(FUNCPTR factory)
printf("WPILib was compiled without -D'SVN_REV=nnnn'\n");
#endif
RobotState::SetImplementation(DriverStation::GetInstance());
HLUsageReporting::SetImplementation(new HardwareHLReporting());
#ifdef __vxworks
// Check for startup code already running
int32_t oldId = taskNameToId(const_cast<char*>("FRC_RobotTask"));

View File

@@ -9,7 +9,7 @@
#include "CANJaguar.h"
#include "GenericHID.h"
#include "Joystick.h"
#include "Jaguar.h"
#include "Talon.h"
//#include "NetworkCommunication/UsageReporting.h"
#include "Utility.h"
#include "WPIErrors.h"
@@ -46,15 +46,15 @@ void RobotDrive::InitRobotDrive() {
/** Constructor for RobotDrive with 2 motors specified with channel numbers.
* Set up parameters for a two wheel drive system where the
* left and right motor pwm channels are specified in the call.
* This call assumes Jaguars for controlling the motors.
* This call assumes Talons for controlling the motors.
* @param leftMotorChannel The PWM channel number that drives the left motor.
* @param rightMotorChannel The PWM channel number that drives the right motor.
*/
RobotDrive::RobotDrive(uint32_t leftMotorChannel, uint32_t rightMotorChannel)
{
InitRobotDrive();
m_rearLeftMotor = new Jaguar(leftMotorChannel);
m_rearRightMotor = new Jaguar(rightMotorChannel);
m_rearLeftMotor = new Talon(leftMotorChannel);
m_rearRightMotor = new Talon(rightMotorChannel);
for (int32_t i=0; i < kMaxNumberOfMotors; i++)
{
m_invertedMotors[i] = 1;
@@ -67,7 +67,7 @@ RobotDrive::RobotDrive(uint32_t leftMotorChannel, uint32_t rightMotorChannel)
* Constructor for RobotDrive with 4 motors specified with channel numbers.
* Set up parameters for a four wheel drive system where all four motor
* pwm channels are specified in the call.
* This call assumes Jaguars for controlling the motors.
* This call assumes Talons for controlling the motors.
* @param frontLeftMotor Front left motor channel number
* @param rearLeftMotor Rear Left motor channel number
* @param frontRightMotor Front right motor channel number
@@ -77,10 +77,10 @@ RobotDrive::RobotDrive(uint32_t frontLeftMotor, uint32_t rearLeftMotor,
uint32_t frontRightMotor, uint32_t rearRightMotor)
{
InitRobotDrive();
m_rearLeftMotor = new Jaguar(rearLeftMotor);
m_rearRightMotor = new Jaguar(rearRightMotor);
m_frontLeftMotor = new Jaguar(frontLeftMotor);
m_frontRightMotor = new Jaguar(frontRightMotor);
m_rearLeftMotor = new Talon(rearLeftMotor);
m_rearRightMotor = new Talon(rearRightMotor);
m_frontLeftMotor = new Talon(frontLeftMotor);
m_frontRightMotor = new Talon(frontRightMotor);
for (int32_t i=0; i < kMaxNumberOfMotors; i++)
{
m_invertedMotors[i] = 1;

View File

@@ -142,6 +142,8 @@ TEST_F(CANJaguarTest, Disable) {
m_jaguar->EnableControl();
m_jaguar->DisableControl();
Wait(kEncoderSettlingTime);
double initialPosition = m_jaguar->GetPosition();
SetJaguar(kMotorTime, 1.0f);

View File

@@ -9,6 +9,8 @@
#include "gtest/gtest.h"
#include "TestBench.h"
static const double kCounterTime = 0.001;
static const double kDelayTime = 0.1;
static const double kSynchronousInterruptTime = 2.0;
@@ -70,11 +72,11 @@ TEST_F(DIOLoopTest, FakeCounter) {
/* Count 100 ticks. The counter value should be 100 after this loop. */
for(int i = 0; i < 100; i++) {
m_output->Set(true);
Wait(kCounterTime);
m_output->Set(false);
Wait(kCounterTime);
}
Wait(kDelayTime);
EXPECT_EQ(100, counter.Get()) << "Counter did not count up to 100.";
}

View File

@@ -9,7 +9,7 @@
#include "gtest/gtest.h"
#include "TestBench.h"
static const double kDelayTime = 0.001;
static const double kDelayTime = 0.01;
class FakeEncoderTest : public testing::Test {
protected:
@@ -42,6 +42,10 @@ TEST_F(FakeEncoderTest, TestDefaultState) {
* Test the encoder by setting the digital outputs and reading the value.
*/
TEST_F(FakeEncoderTest, TestCountUp) {
m_outputA->Set(false);
m_outputB->Set(false);
m_encoder->Reset();
//Sets the outputs such that the encoder moves in the positive direction
for(int i = 0; i < 100; i++) {
m_outputA->Set(true);

View File

@@ -17,7 +17,7 @@ std::ostream &operator<<(std::ostream &os, MotorEncoderTestType const &type) {
case TEST_JAGUAR: os << "Jaguar"; break;
case TEST_TALON: os << "Talon"; break;
}
return os;
}
@@ -32,7 +32,7 @@ class MotorEncoderTest : public testing::TestWithParam<MotorEncoderTestType> {
protected:
SpeedController *m_speedController;
Encoder *m_encoder;
virtual void SetUp() {
switch(GetParam()) {
case TEST_VICTOR:
@@ -40,27 +40,27 @@ protected:
m_encoder = new Encoder(TestBench::kVictorEncoderChannelA,
TestBench::kVictorEncoderChannelB);
break;
case TEST_JAGUAR:
m_speedController = new Jaguar(TestBench::kJaguarChannel);
m_encoder = new Encoder(TestBench::kJaguarEncoderChannelA,
TestBench::kJaguarEncoderChannelB);
break;
case TEST_TALON:
m_speedController = new Talon(TestBench::kTalonChannel);
m_encoder = new Encoder(TestBench::kTalonEncoderChannelA,
TestBench::kTalonEncoderChannelB);
break;
}
}
virtual void TearDown() {
delete m_speedController;
delete m_encoder;
}
void Reset() {
m_speedController->Set(0.0f);
m_encoder->Reset();
@@ -73,12 +73,12 @@ protected:
*/
TEST_P(MotorEncoderTest, Increment) {
Reset();
/* Drive the speed controller briefly to move the encoder */
m_speedController->Set(1.0);
Wait(kMotorTime);
m_speedController->Set(0.0);
/* The encoder should be positive now */
EXPECT_GT(m_encoder->Get(), 0)
<< "Encoder should have incremented after the motor moved";
@@ -90,12 +90,12 @@ TEST_P(MotorEncoderTest, Increment) {
*/
TEST_P(MotorEncoderTest, Decrement) {
Reset();
/* Drive the speed controller briefly to move the encoder */
m_speedController->Set(-1.0f);
Wait(kMotorTime);
m_speedController->Set(0.0f);
/* The encoder should be positive now */
EXPECT_LT(m_encoder->Get(), 0.0f)
<< "Encoder should have decremented after the motor moved";
@@ -106,15 +106,15 @@ TEST_P(MotorEncoderTest, Decrement) {
*/
TEST_P(MotorEncoderTest, ClampSpeed) {
Reset();
m_speedController->Set(2.0f);
Wait(kMotorTime);
EXPECT_FLOAT_EQ(1.0f, m_speedController->Get());
m_speedController->Set(-2.0f);
Wait(kMotorTime);
EXPECT_FLOAT_EQ(-1.0f, m_speedController->Get());
}
@@ -123,19 +123,19 @@ TEST_P(MotorEncoderTest, ClampSpeed) {
*/
TEST_P(MotorEncoderTest, PIDController) {
Reset();
PIDController pid(0.003f, 0.001f, 0.0f, m_encoder, m_speedController);
pid.SetAbsoluteTolerance(20.0f);
pid.SetOutputRange(-0.2f, 0.2f);
pid.SetSetpoint(2500);
/* 5 seconds should be plenty time to get to the setpoint */
/* 10 seconds should be plenty time to get to the setpoint */
pid.Enable();
Wait(5.0);
Wait(10.0);
pid.Disable();
RecordProperty("PID Error", pid.GetError());
RecordProperty("PIDError", pid.GetError());
EXPECT_TRUE(pid.OnTarget()) << "PID loop did not converge within 5 seconds.";
}
@@ -144,10 +144,9 @@ TEST_P(MotorEncoderTest, PIDController) {
*/
TEST_P(MotorEncoderTest, Reset) {
Reset();
EXPECT_EQ(0, m_encoder->Get()) << "Encoder did not reset to 0";
}
INSTANTIATE_TEST_CASE_P(Test, MotorEncoderTest,
testing::Values(TEST_VICTOR, TEST_JAGUAR, TEST_TALON));

View File

@@ -9,12 +9,12 @@
#include "gtest/gtest.h"
#include "TestBench.h"
/* The PCM switches the compressor up to 2 seconds after the pressure switch
changes. */
static const double kCompressorDelayTime = 2.0;
/* The PCM switches the compressor up to a couple seconds after the pressure
switch changes. */
static const double kCompressorDelayTime = 3.0;
/* Solenoids should change much more quickly */
static const double kSolenoidDelayTime = 0.1;
static const double kSolenoidDelayTime = 0.5;
/* The voltage divider on the test bench should bring the compressor output
to around these values. */
@@ -56,7 +56,7 @@ protected:
/**
* Test if the compressor turns on and off when the pressure switch is toggled
*/
TEST_F(PCMTest, PressureSwitch) {
TEST_F(PCMTest, DISABLED_PressureSwitch) {
Reset();
m_compressor->SetClosedLoopControl(true);
@@ -77,7 +77,7 @@ TEST_F(PCMTest, PressureSwitch) {
/**
* Test if the correct solenoids turn on and off when they should
*/
TEST_F(PCMTest, Solenoid) {
TEST_F(PCMTest, DISABLED_Solenoid) {
Reset();
Solenoid solenoid1(TestBench::kSolenoidChannel1);
Solenoid solenoid2(TestBench::kSolenoidChannel2);
@@ -115,7 +115,7 @@ TEST_F(PCMTest, Solenoid) {
* Test if the correct solenoids turn on and off when they should when used
* with the DoubleSolenoid class.
*/
TEST_F(PCMTest, DoubleSolenoid) {
TEST_F(PCMTest, DISABLED_DoubleSolenoid) {
DoubleSolenoid solenoid(TestBench::kSolenoidChannel1, TestBench::kSolenoidChannel2);
solenoid.Set(DoubleSolenoid::kOff);

View File

@@ -9,92 +9,83 @@
#include "gtest/gtest.h"
#include "TestBench.h"
/* The current returned when the motor is not being driven */
static const double kLowCurrent = 1.52;
static const double kCurrentTolerance = 0.1;
static const double kMotorTime = 0.25;
class PowerDistributionPanelTest : public testing::Test {
protected:
PowerDistributionPanel *m_pdp;
Talon *m_talon;
Victor *m_victor;
Jaguar *m_jaguar;
PowerDistributionPanel *m_pdp;
Talon *m_talon;
Victor *m_victor;
Jaguar *m_jaguar;
virtual void SetUp() {
m_pdp = new PowerDistributionPanel();
m_talon = new Talon(TestBench::kTalonChannel);
m_victor = new Victor(TestBench::kVictorChannel);
m_jaguar = new Jaguar(TestBench::kJaguarChannel);
}
virtual void SetUp() {
m_pdp = new PowerDistributionPanel();
m_talon = new Talon(TestBench::kTalonChannel);
m_victor = new Victor(TestBench::kVictorChannel);
m_jaguar = new Jaguar(TestBench::kJaguarChannel);
}
virtual void TearDown() {
delete m_pdp;
delete m_talon;
delete m_victor;
delete m_jaguar;
}
void Reset() {
/* Reset all speed controllers to 0.0 */
m_talon->Set(0.0f);
m_victor->Set(0.0f);
m_jaguar->Set(0.0f);
}
virtual void TearDown() {
delete m_pdp;
delete m_talon;
delete m_victor;
delete m_jaguar;
}
};
/**
* Test if the current changes when the motor is driven using a talon
*/
TEST_F(PowerDistributionPanelTest, CheckCurrentTalon) {
Reset();
TEST_F(PowerDistributionPanelTest, CheckCurrentTalon) {
Wait(kMotorTime);
/* The Current should be kLowCurrent */
EXPECT_NEAR(kLowCurrent, m_pdp->GetCurrent(TestBench::kTalonPDPChannel), kCurrentTolerance)
<< "The low current was not within the expected range.";
/* The Current should be 0 */
EXPECT_FLOAT_EQ(0, m_pdp->GetCurrent(TestBench::kTalonPDPChannel))
<< "The Talon current was non-zero";
/* Set the motor to full forward */
m_talon->Set(1.0);
Wait(0.02);
/* Set the motor to full forward */
m_talon->Set(1.0);
Wait(kMotorTime);
/* The current should now be greater than the low current */
ASSERT_GT(m_pdp->GetCurrent(TestBench::kTalonPDPChannel), kLowCurrent)
<< "The driven current is not greater than the resting current.";
/* The current should now be positive */
ASSERT_GT(m_pdp->GetCurrent(TestBench::kTalonPDPChannel), 0)
<< "The Talon current was not positive";
}
/**
* Test if the current changes when the motor is driven using a victor
*/
TEST_F(PowerDistributionPanelTest,CheckCurrentVictor) {
Reset();
TEST_F(PowerDistributionPanelTest, CheckCurrentVictor) {
Wait(kMotorTime);
/* The Current should be kLowCurrent */
EXPECT_NEAR(kLowCurrent, m_pdp->GetCurrent(TestBench::kVictorPDPChannel), kCurrentTolerance)
<< "The low current was not within the expected range.";
/* The Current should be 0 */
EXPECT_FLOAT_EQ(0, m_pdp->GetCurrent(TestBench::kVictorPDPChannel))
<< "The Victor current was non-zero";
/* Set the motor to full forward */
m_victor->Set(1.0);
Wait(0.02);
/* Set the motor to full forward */
m_victor->Set(1.0);
Wait(kMotorTime);
/* The current should now be greater than the low current */
ASSERT_GT(m_pdp->GetCurrent(TestBench::kVictorPDPChannel), kLowCurrent)
<< "The driven current is not greater than the resting current.";
/* The current should now be positive */
ASSERT_GT(m_pdp->GetCurrent(TestBench::kVictorPDPChannel), 0)
<< "The Victor current was not positive";
}
/**
* Test if the current changes when the motor is driven using a jaguar
*/
TEST_F(PowerDistributionPanelTest, CheckCurrentJaguar) {
Reset();
TEST_F(PowerDistributionPanelTest, CheckCurrentJaguar) {
Wait(kMotorTime);
/* The Current should be kLowCurrent */
EXPECT_NEAR(kLowCurrent, m_pdp->GetCurrent(TestBench::kJaguarPDPChannel), kCurrentTolerance)
<< "The low current was not within the expected range.";
/* The Current should be 0 */
EXPECT_FLOAT_EQ(0, m_pdp->GetCurrent(TestBench::kJaguarPDPChannel))
<< "The Jaguar current was non-zero";
/* Set the motor to full forward */
m_jaguar->Set(1.0);
Wait(0.02);
/* Set the motor to full forward */
m_jaguar->Set(1.0);
Wait(kMotorTime);
/* The current should now be greater than the low current */
ASSERT_GT(m_pdp->GetCurrent(TestBench::kJaguarPDPChannel), kLowCurrent)
<< "The driven current is not greater than the resting current.";
/* The current should now be positive */
ASSERT_GT(m_pdp->GetCurrent(TestBench::kJaguarPDPChannel), 0)
<< "The Jaguar current was not positive";
}

View File

@@ -10,6 +10,8 @@
#include "TestBench.h"
#include "Relay.h"
static const double kDelayTime = 0.01;
class RelayTest : public testing::Test {
protected:
Relay *m_relay;
@@ -41,6 +43,7 @@ protected:
//set the relay to forward
m_relay->Set(Relay::kForward);
Wait(kDelayTime);
EXPECT_TRUE(m_forward->Get())
<<"Relay did not set forward";
EXPECT_FALSE(m_reverse->Get())
@@ -49,6 +52,7 @@ protected:
//set the relay to reverse
m_relay->Set(Relay::kReverse);
Wait(kDelayTime);
EXPECT_TRUE(m_reverse->Get())
<<"Relay did not set reverse";
EXPECT_FALSE(m_forward->Get())
@@ -56,6 +60,7 @@ protected:
//set the relay to off
m_relay->Set(Relay::kOff);
Wait(kDelayTime);
EXPECT_FALSE(m_forward->Get())
<<"Relay did not set off";
EXPECT_FALSE(m_reverse->Get())
@@ -64,6 +69,7 @@ protected:
//set the relay to on
m_relay->Set(Relay::kOn);
Wait(kDelayTime);
EXPECT_TRUE(m_forward->Get())
<<"Relay did not set on";
EXPECT_TRUE(m_reverse->Get())

View File

@@ -11,7 +11,7 @@
/**
* DoubleSolenoid class for running 2 channels of high voltage Digital Output
* (9472 module).
* (PCM).
*
* The DoubleSolenoid class is typically used for pneumatics solenoids that
* have two positions controlled by two separate channels.

View File

@@ -10,10 +10,10 @@
#include "tables/ITableListener.h"
/**
* Solenoid class for running high voltage Digital Output (9472 module).
* Solenoid class for running high voltage Digital Output (PCM).
*
* The Solenoid class is typically used for pneumatics solenoids, but could be used
* for any device within the current spec of the 9472 module.
* for any device within the current spec of the PCM.
*/
class Solenoid : public LiveWindowSendable, public ITableListener
{

View File

@@ -88,10 +88,7 @@ DriverStation* DriverStation::GetInstance()
}
/**
* Read the battery voltage from the specified AnalogInput.
*
* This accessor assumes that the battery voltage is being measured
* through the voltage divider on an analog breakout.
* Read the battery voltage. Hardcoded to 12 volts for Simulation.
*
* @return The battery voltage.
*/

View File

@@ -92,6 +92,7 @@ public class AnalogTriggerOutput extends DigitalSource {
@Override
public void free() {
}
/**
@@ -113,8 +114,8 @@ public class AnalogTriggerOutput extends DigitalSource {
}
@Override
public int getModuleForRouting() {
return m_trigger.m_index >> 2;
public byte getModuleForRouting() {
return (byte) (m_trigger.m_index >> 2);
}
@Override
@@ -122,27 +123,6 @@ public class AnalogTriggerOutput extends DigitalSource {
return true;
}
/**
* Request interrupts asynchronously on this digital input.
*
* @param handler
* the interrupt service routine
* @param param
* a parameter for the ISR
*/
// public void requestInterrupts(/*tInterruptHandler*/Object handler, Object
// param) {
// TODO: add interrupt support
// TODO: throw exception
// }
/**
* Request interrupts synchronously on this digital input.
*/
// public void requestInterrupts() {
// TODO: throw exception
// }
/**
* Defines the state in which the AnalogTrigger triggers
* @author jonathanleitschuh

View File

@@ -12,14 +12,10 @@ import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.InterruptJNI;
import edu.wpi.first.wpilibj.hal.DIOJNI;
import edu.wpi.first.wpilibj.hal.InterruptJNI.InterruptHandlerFunction;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Class to read a digital input. This class will read digital inputs and return
@@ -67,97 +63,15 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
return m_channel;
}
@Override
public boolean getAnalogTriggerForRouting() {
return false;
}
/**
* Request interrupts asynchronously on this digital input.
*
* @param handler
* The address of the interrupt handler function of type
* tInterruptHandler that will be called whenever there is an
* interrupt on the digitial input port. Request interrupts in
* synchronus mode where the user program interrupt handler will
* be called when an interrupt occurs. The default is interrupt
* on rising edges only.
*/
public void requestInterrupts(InterruptHandlerFunction handler) {
// TODO: add interrupt support
try {
m_interruptIndex = interrupts.allocate();
} catch (CheckedAllocationException e) {
throw new AllocationException(
"No interrupts are left to be allocated");
}
allocateInterrupts(false);
ByteBuffer status = ByteBuffer.allocateDirect(4);
// set the byte order
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.requestInterrupts(m_interrupt, (byte) getModuleForRouting(),
getChannelForRouting(),
(byte) (getAnalogTriggerForRouting() ? 1 : 0), status.asIntBuffer());
setUpSourceEdge(true, false);
InterruptJNI.attachInterruptHandler(m_interrupt, handler, null, status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
}
/**
* Request interrupts synchronously on this digital input. Request
* interrupts in synchronus mode where the user program will have to
* explicitly wait for the interrupt to occur. The default is interrupt on
* rising edges only.
*/
public void requestInterrupts() {
try {
m_interruptIndex = interrupts.allocate();
} catch (CheckedAllocationException e) {
throw new AllocationException(
"No interrupts are left to be allocated");
}
allocateInterrupts(true);
ByteBuffer status = ByteBuffer.allocateDirect(4);
// set the byte order
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.requestInterrupts(m_interrupt, (byte) getModuleForRouting(),
getChannelForRouting(),
(byte) (getAnalogTriggerForRouting() ? 1 : 0), status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
setUpSourceEdge(true, false);
}
/**
* Set which edge to trigger interrupts on
*
* @param risingEdge
* true to interrupt on rising edge
* @param fallingEdge
* true to interrupt on falling edge
*/
public void setUpSourceEdge(boolean risingEdge, boolean fallingEdge) {
if (m_interrupt != null) {
ByteBuffer status = ByteBuffer.allocateDirect(4);
// set the byte order
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.setInterruptUpSourceEdge(m_interrupt,
(byte) (risingEdge ? 1 : 0), (byte) (fallingEdge ? 1 : 0),
status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
} else {
throw new IllegalArgumentException(
"You must call RequestInterrupts before setUpSourceEdge");
}
}
/*
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Digital Input";
}
@@ -167,6 +81,7 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
@@ -175,6 +90,7 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putBoolean("Value", get());
@@ -184,6 +100,7 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
@@ -191,12 +108,14 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,24 +7,21 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
//import com.sun.jna.Pointer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.DIOJNI;
import edu.wpi.first.wpilibj.hal.PWMJNI;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.hal.PWMJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
//import com.sun.jna.Pointer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
/**
* Class to write digital outputs. This class will wrtie digital outputs. Other
* Class to write digital outputs. This class will write digital outputs. Other
* devices that are implemented elsewhere will automatically allocate digital
* inputs and outputs as required.
*/
@@ -48,6 +45,7 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* Free the resources associated with a digital output.
*/
@Override
public void free() {
// disable the pwm only if we have allocated it
if (m_pwmGenerator != null) {
@@ -104,6 +102,7 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
* @param pulseLength
* The length of the pulse.
*/
@Deprecated
public void pulse(final int channel, final int pulseLength) {
ByteBuffer status = ByteBuffer.allocateDirect(4);
// set the byte order
@@ -212,6 +211,7 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/*
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Digital Output";
}
@@ -222,6 +222,7 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
@@ -230,6 +231,7 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
@@ -237,6 +239,7 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
// TODO: Put current value.
}
@@ -244,8 +247,10 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
m_table_listener = new ITableListener() {
@Override
public void valueChanged(ITable itable, String key, Object value,
boolean bln) {
set(((Boolean) value).booleanValue());
@@ -257,6 +262,7 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);

View File

@@ -7,9 +7,8 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.hal.DIOJNI;
import edu.wpi.first.wpilibj.hal.HALUtil;
@@ -54,6 +53,7 @@ public abstract class DigitalSource extends InterruptableSensorBase {
HALUtil.checkStatus(status.asIntBuffer());
}
@Override
public void free() {
channels.free(m_channel);
ByteBuffer status = ByteBuffer.allocateDirect(4);
@@ -69,6 +69,7 @@ public abstract class DigitalSource extends InterruptableSensorBase {
*
* @return channel routing number
*/
@Override
public int getChannelForRouting() {
return m_channel;
}
@@ -78,15 +79,16 @@ public abstract class DigitalSource extends InterruptableSensorBase {
*
* @return 0
*/
public int getModuleForRouting() {
@Override
public byte getModuleForRouting() {
return 0;
}
/**
* Is this an analog trigger
*
* @return true if this is an analog trigger
*/
@Override
public boolean getAnalogTriggerForRouting() {
return false;
}

View File

@@ -16,8 +16,7 @@ import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* DoubleSolenoid class for running 2 channels of high voltage Digital Output
* (9472 module).
* DoubleSolenoid class for running 2 channels of high voltage Digital Output.
*
* The DoubleSolenoid class is typically used for pneumatics solenoids that
* have two positions controlled by two separate channels.
@@ -50,28 +49,28 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
* Common function to implement constructor behavior.
*/
private synchronized void initSolenoid() {
// checkSolenoidModule(m_moduleNumber);
// checkSolenoidChannel(m_forwardChannel);
// checkSolenoidChannel(m_reverseChannel);
//
// try {
// m_allocated.allocate((m_moduleNumber - 1) * kSolenoidChannels + m_forwardChannel - 1);
// } catch (CheckedAllocationException e) {
// throw new AllocationException(
// "Solenoid channel " + m_forwardChannel + " on module " + m_moduleNumber + " is already allocated");
// }
// try {
// m_allocated.allocate((m_moduleNumber - 1) * kSolenoidChannels + m_reverseChannel - 1);
// } catch (CheckedAllocationException e) {
// throw new AllocationException(
// "Solenoid channel " + m_reverseChannel + " on module " + m_moduleNumber + " is already allocated");
// }
// m_forwardMask = (byte) (1 << (m_forwardChannel - 1));
// m_reverseMask = (byte) (1 << (m_reverseChannel - 1));
//
// UsageReporting.report(tResourceType.kResourceType_Solenoid, m_forwardChannel, m_moduleNumber-1);
// UsageReporting.report(tResourceType.kResourceType_Solenoid, m_reverseChannel, m_moduleNumber-1);
// LiveWindow.addActuator("DoubleSolenoid", m_moduleNumber, m_forwardChannel, this);
checkSolenoidModule(m_moduleNumber);
checkSolenoidChannel(m_forwardChannel);
checkSolenoidChannel(m_reverseChannel);
try {
m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
} catch (CheckedAllocationException e) {
throw new AllocationException(
"Solenoid channel " + m_forwardChannel + " on module " + m_moduleNumber + " is already allocated");
}
try {
m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
} catch (CheckedAllocationException e) {
throw new AllocationException(
"Solenoid channel " + m_reverseChannel + " on module " + m_moduleNumber + " is already allocated");
}
m_forwardMask = (byte) (1 << m_forwardChannel);
m_reverseMask = (byte) (1 << m_reverseChannel);
UsageReporting.report(tResourceType.kResourceType_Solenoid, m_forwardChannel, m_moduleNumber);
UsageReporting.report(tResourceType.kResourceType_Solenoid, m_reverseChannel, m_moduleNumber);
LiveWindow.addActuator("DoubleSolenoid", m_moduleNumber, m_forwardChannel, this);
}
/**
@@ -105,8 +104,8 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
* Destructor.
*/
public synchronized void free() {
// m_allocated.free((m_moduleNumber - 1) * kSolenoidChannels + m_forwardChannel - 1);
// m_allocated.free((m_moduleNumber - 1) * kSolenoidChannels + m_reverseChannel - 1);
m_allocated.free(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
m_allocated.free(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
}
/**

View File

@@ -0,0 +1,57 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-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 the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.hal.InterruptJNI.InterruptJNIHandlerFunction;
/**
* It is recommended that you use this class in conjunction with classes from
* {@link java.util.concurrent.atomic} as these objects are all thread safe.
*
* @author Jonathan Leitschuh
*
* @param <T> The type of the parameter that should be returned to the the
* method {@link #interruptFired(int, Object)}
*/
public abstract class InterruptHandlerFunction<T>{
/**
* The entry point for the interrupt. When the interrupt fires the
* {@link #apply(int, Object)} method is called.
* The outer class is provided as an interface to allow the implementer to
* pass a generic object to the interrupt fired method.
* @author Jonathan Leitschuh
*/
private class Function implements InterruptJNIHandlerFunction{
@SuppressWarnings("unchecked")
@Override
public void apply(int interruptAssertedMask, Object param) {
interruptFired(interruptAssertedMask, (T)param);
}
}
final Function function = new Function();
/**
* This method is run every time an interrupt is fired.
* @param interruptAssertedMask
* @param param The parameter provided by overriding the {@link #overridableParamater()}
* method.
*/
abstract void interruptFired(int interruptAssertedMask, T param);
/**
* Override this method if you would like to pass a specific
* parameter to the {@link #interruptFired(int, Object)} when it is fired by the interrupt.
* This method is called once when {@link InterruptableSensorBase#requestInterrupts(InterruptHandlerFunction)}
* is run.
* @return The object that should be passed to the interrupt when it runs
*/
public T overridableParamater(){
return null;
}
}

View File

@@ -7,26 +7,40 @@
package edu.wpi.first.wpilibj;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.hal.InterruptJNI;
import edu.wpi.first.wpilibj.hal.InterruptJNI.InterruptHandlerFunction;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.hal.InterruptJNI;
import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Base for sensors to be used with interrupts
*/
public abstract class InterruptableSensorBase extends SensorBase {
/**
* This is done to store the JVM variable in the InterruptJNI
* This is done because the HAL must have access to the JVM variable
* in order to attach the newly spawned thread when an interrupt is fired.
*/
static{
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.initializeInterruptJVM(status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
}
/**
* The interrupt resource
*/
protected ByteBuffer m_interrupt;
protected ByteBuffer m_interrupt = null;
/**
* The interrupt manager resource
* Flags if the interrupt being allocated is synchronous
*/
protected InterruptHandlerFunction m_manager;
protected boolean m_isSynchronousInterrupt = false;
/**
* The index of the interrupt
*/
@@ -40,25 +54,102 @@ public abstract class InterruptableSensorBase extends SensorBase {
* Create a new InterrupatableSensorBase
*/
public InterruptableSensorBase() {
m_manager = null;
m_interrupt = null;
}
/**
* @return
*/
abstract boolean getAnalogTriggerForRouting();
/**
* @return
*/
abstract int getChannelForRouting();
/**
* @return
*/
abstract byte getModuleForRouting();
/**
* Request interrupts asynchronously on this digital input.
*
* @param handler
* The {@link #InterruptHandlerFunction} that contains the method
* {@link InterruptHandlerFunction#interruptFired(int, Object)} that
* will be called whenever there is an interrupt on this device.
* Request interrupts in synchronus mode where the user program
* interrupt handler will be called when an interrupt occurs. The
* default is interrupt on rising edges only.
*/
public void requestInterrupts(InterruptHandlerFunction<?> handler) {
if(m_interrupt != null){
throw new AllocationException("The interrupt has already been allocated");
}
allocateInterrupts(false);
assert (m_interrupt != null);
ByteBuffer status = ByteBuffer.allocateDirect(4);
// set the byte order
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.requestInterrupts(m_interrupt, getModuleForRouting(),
getChannelForRouting(),
(byte) (getAnalogTriggerForRouting() ? 1 : 0), status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
setUpSourceEdge(true, false);
InterruptJNI.attachInterruptHandler(m_interrupt, handler.function, handler.overridableParamater(), status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
}
/**
* Request interrupts synchronously on this digital input. Request
* interrupts in synchronous mode where the user program will have to
* explicitly wait for the interrupt to occur. The default is interrupt on
* rising edges only.
*/
public void requestInterrupts() {
if(m_interrupt != null){
throw new AllocationException("The interrupt has already been allocated");
}
allocateInterrupts(true);
assert (m_interrupt != null);
ByteBuffer status = ByteBuffer.allocateDirect(4);
// set the byte order
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.requestInterrupts(m_interrupt, getModuleForRouting(),
getChannelForRouting(),
(byte) (getAnalogTriggerForRouting() ? 1 : 0), status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
setUpSourceEdge(true, false);
}
/**
* Allocate the interrupt
*
* @param watcher
* @param watcher true if the interrupt should be in synchronous mode where the user
* program will have to explicitly wait for the interrupt to occur.
*/
public void allocateInterrupts(boolean watcher) {
if (!watcher) {
throw new IllegalArgumentException(
"Interrupt callbacks not yet supported");
protected void allocateInterrupts(boolean watcher) {
try {
m_interruptIndex = interrupts.allocate();
} catch (CheckedAllocationException e) {
throw new AllocationException(
"No interrupts are left to be allocated");
}
// Expects the calling leaf class to allocate an interrupt index.
IntBuffer status = IntBuffer.allocate(1);
m_isSynchronousInterrupt = watcher;
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
m_interrupt = InterruptJNI.initializeInterrupts(m_interruptIndex,
(byte) (watcher ? 1 : 0), status);
HALUtil.checkStatus(status);
(byte) (watcher ? 1 : 0), status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
}
/**
@@ -66,13 +157,15 @@ public abstract class InterruptableSensorBase extends SensorBase {
* structures and disables any interrupts.
*/
public void cancelInterrupts() {
if (m_interrupt == null || m_manager == null) {
throw new IllegalStateException();
if (m_interrupt == null) {
throw new IllegalStateException("The interrupt is not allocated.");
}
IntBuffer status = IntBuffer.allocate(1);
InterruptJNI.cleanInterrupts(m_interrupt, status);
HALUtil.checkStatus(status);
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.cleanInterrupts(m_interrupt, status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
m_interrupt = null;
interrupts.free(m_interruptIndex);
}
/**
@@ -82,12 +175,13 @@ public abstract class InterruptableSensorBase extends SensorBase {
* Timeout in seconds
*/
public void waitForInterrupt(double timeout) {
if (m_interrupt == null || m_manager == null) {
throw new IllegalStateException();
if (m_interrupt == null) {
throw new IllegalStateException("The interrupt is not allocated.");
}
IntBuffer status = IntBuffer.allocate(1);
InterruptJNI.waitForInterrupt(m_interrupt, (float) timeout, status);
HALUtil.checkStatus(status);
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.waitForInterrupt(m_interrupt, (float) timeout, status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
}
/**
@@ -96,24 +190,32 @@ public abstract class InterruptableSensorBase extends SensorBase {
* other options before starting to field interrupts.
*/
public void enableInterrupts() {
if (m_interrupt == null || m_manager == null) {
throw new IllegalStateException();
if (m_interrupt == null) {
throw new IllegalStateException("The interrupt is not allocated.");
}
IntBuffer status = IntBuffer.allocate(1);
InterruptJNI.enableInterrupts(m_interrupt, status);
HALUtil.checkStatus(status);
if(m_isSynchronousInterrupt){
throw new IllegalStateException("You do not need to enable synchronous interrupts");
}
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.enableInterrupts(m_interrupt, status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
}
/**
* Disable Interrupts without without deallocating structures.
*/
public void disableInterrupts() {
if (m_interrupt == null || m_manager == null) {
throw new IllegalStateException();
if (m_interrupt == null) {
throw new IllegalStateException("The interrupt is not allocated.");
}
IntBuffer status = IntBuffer.allocate(1);
InterruptJNI.disableInterrupts(m_interrupt, status);
HALUtil.checkStatus(status);
if(m_isSynchronousInterrupt){
throw new IllegalStateException("You can not disable synchronous interrupts");
}
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.disableInterrupts(m_interrupt, status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
}
/**
@@ -123,12 +225,36 @@ public abstract class InterruptableSensorBase extends SensorBase {
* @return Timestamp in seconds since boot.
*/
public double readInterruptTimestamp() {
if (m_interrupt == null || m_manager == null) {
throw new IllegalStateException();
if (m_interrupt == null) {
throw new IllegalStateException("The interrupt is not allocated.");
}
IntBuffer status = IntBuffer.allocate(1);
double timestamp = InterruptJNI.readInterruptTimestamp(m_interrupt, status);
HALUtil.checkStatus(status);
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
double timestamp = InterruptJNI.readInterruptTimestamp(m_interrupt, status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
return timestamp;
}
/**
* Set which edge to trigger interrupts on
*
* @param risingEdge
* true to interrupt on rising edge
* @param fallingEdge
* true to interrupt on falling edge
*/
public void setUpSourceEdge(boolean risingEdge, boolean fallingEdge) {
if (m_interrupt != null) {
ByteBuffer status = ByteBuffer.allocateDirect(4);
// set the byte order
status.order(ByteOrder.LITTLE_ENDIAN);
InterruptJNI.setInterruptUpSourceEdge(m_interrupt,
(byte) (risingEdge ? 1 : 0), (byte) (fallingEdge ? 1 : 0),
status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
} else {
throw new IllegalArgumentException(
"You must call RequestInterrupts before setUpSourceEdge");
}
}
}

View File

@@ -79,7 +79,7 @@ public class RobotDrive implements MotorSafety {
/** Constructor for RobotDrive with 2 motors specified with channel numbers.
* Set up parameters for a two wheel drive system where the
* left and right motor pwm channels are specified in the call.
* This call assumes Jaguars for controlling the motors.
* This call assumes Talons for controlling the motors.
* @param leftMotorChannel The PWM channel number that drives the left motor.
* @param rightMotorChannel The PWM channel number that drives the right motor.
*/
@@ -87,9 +87,9 @@ public class RobotDrive implements MotorSafety {
m_sensitivity = kDefaultSensitivity;
m_maxOutput = kDefaultMaxOutput;
m_frontLeftMotor = null;
m_rearLeftMotor = new Jaguar(leftMotorChannel);
m_rearLeftMotor = new Talon(leftMotorChannel);
m_frontRightMotor = null;
m_rearRightMotor = new Jaguar(rightMotorChannel);
m_rearRightMotor = new Talon(rightMotorChannel);
for (int i = 0; i < kMaxNumberOfMotors; i++) {
m_invertedMotors[i] = 1;
}
@@ -102,7 +102,7 @@ public class RobotDrive implements MotorSafety {
* Constructor for RobotDrive with 4 motors specified with channel numbers.
* Set up parameters for a four wheel drive system where all four motor
* pwm channels are specified in the call.
* This call assumes Jaguars for controlling the motors.
* This call assumes Talons for controlling the motors.
* @param frontLeftMotor Front left motor channel number
* @param rearLeftMotor Rear Left motor channel number
* @param frontRightMotor Front right motor channel number
@@ -112,10 +112,10 @@ public class RobotDrive implements MotorSafety {
final int frontRightMotor, final int rearRightMotor) {
m_sensitivity = kDefaultSensitivity;
m_maxOutput = kDefaultMaxOutput;
m_rearLeftMotor = new Jaguar(rearLeftMotor);
m_rearRightMotor = new Jaguar(rearRightMotor);
m_frontLeftMotor = new Jaguar(frontLeftMotor);
m_frontRightMotor = new Jaguar(frontRightMotor);
m_rearLeftMotor = new Talon(rearLeftMotor);
m_rearRightMotor = new Talon(rearRightMotor);
m_frontLeftMotor = new Talon(frontLeftMotor);
m_frontRightMotor = new Talon(frontRightMotor);
for (int i = 0; i < kMaxNumberOfMotors; i++) {
m_invertedMotors[i] = 1;
}

View File

@@ -24,7 +24,7 @@ public abstract class SensorBase { // TODO: Refactor
*/
public static final int kSystemClockTicksPerMicrosecond = 40;
/**
* Number of digital channels per digital sidecar
* Number of digital channels per roboRIO
*/
public static final int kDigitalChannels = 26;
/**
@@ -44,11 +44,11 @@ public abstract class SensorBase { // TODO: Refactor
*/
public static final int kSolenoidModules = 2;
/**
* Number of PWM channels per sidecar
* Number of PWM channels per roboRIO
*/
public static final int kPwmChannels = 20;
/**
* Number of relay channels per sidecar
* Number of relay channels per roboRIO
*/
public static final int kRelayChannels = 4;
/**
@@ -179,7 +179,7 @@ public abstract class SensorBase { // TODO: Refactor
/**
* Get the number of the default solenoid module.
*
* @return The number of the default analog module.
* @return The number of the default solenoid module.
*/
public static int getDefaultSolenoidModule() {
return SensorBase.m_defaultSolenoidModule;

View File

@@ -86,10 +86,10 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
* @param on Turn the solenoid output off or on.
*/
public void set(boolean on) {
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
SolenoidJNI.setSolenoid(m_solenoid_port, (byte) (on ? 1 : 0), status.asIntBuffer());
HALUtil.checkStatus(status.asIntBuffer());
byte value = (byte) (on ? 0xFF : 0x00);
byte mask = (byte) (1 << m_channel);
set(value, mask);
}
/**
@@ -98,11 +98,8 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
* @return The current value of the solenoid.
*/
public boolean get() {
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
boolean value = SolenoidJNI.getSolenoid(m_solenoid_port, status.asIntBuffer()) != 0;
HALUtil.checkStatus(status.asIntBuffer());
return value;
int value = getAll() & ( 1 << m_channel);
return (value != 0);
}
/*

View File

@@ -11,6 +11,7 @@ import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.hal.SolenoidJNI;
/**
* SolenoidBase class is the common base class for the Solenoid and
@@ -20,8 +21,7 @@ public abstract class SolenoidBase extends SensorBase {
private ByteBuffer[] m_ports;
protected int m_moduleNumber; ///< The number of the solenoid module being used.
// XXX: Move this to be both HAL calls
//protected Resource m_allocated = new Resource(SolenoidJNI.getModuleCount() * SensorBase.kSolenoidChannels);
protected Resource m_allocated = new Resource(63* SensorBase.kSolenoidChannels);
/**
* Constructor.
@@ -30,13 +30,13 @@ public abstract class SolenoidBase extends SensorBase {
*/
public SolenoidBase(final int moduleNumber) {
m_moduleNumber = moduleNumber;
// m_ports = new ByteBuffer[SensorBase.kSolenoidChannels];
// for (int i = 0; i < SensorBase.kSolenoidChannels; i++) {
// ByteBuffer port = SolenoidJNI.getPortWithModule((byte) moduleNumber, (byte) (i+1));
// IntBuffer status = IntBuffer.allocate(1);
// m_ports[i] = SolenoidJNI.initializeSolenoidPort(port, status);
// HALUtil.checkStatus(status);
// }
m_ports = new ByteBuffer[SensorBase.kSolenoidChannels];
for (int i = 0; i < SensorBase.kSolenoidChannels; i++) {
ByteBuffer port = SolenoidJNI.getPortWithModule((byte) moduleNumber, (byte) i);
IntBuffer status = IntBuffer.allocate(1);
m_ports[i] = SolenoidJNI.initializeSolenoidPort(port, status);
HALUtil.checkStatus(status);
}
}
/**
@@ -46,13 +46,13 @@ public abstract class SolenoidBase extends SensorBase {
* @param mask The channels you want to be affected.
*/
protected synchronized void set(int value, int mask) {
// IntBuffer status = IntBuffer.allocate(1);
// for (int i = 0; i < SensorBase.kSolenoidChannels; i++) {
// int local_mask = 1 << i;
// if ((mask & local_mask) != 0)
// SolenoidJNI.setSolenoid(m_ports[i], (byte) (value & local_mask), status);
// }
// HALUtil.checkStatus(status);
IntBuffer status = IntBuffer.allocate(1);
for (int i = 0; i < SensorBase.kSolenoidChannels; i++) {
int local_mask = 1 << i;
if ((mask & local_mask) != 0)
SolenoidJNI.setSolenoid(m_ports[i], (byte) (value & local_mask), status);
}
HALUtil.checkStatus(status);
}
/**
@@ -62,32 +62,11 @@ public abstract class SolenoidBase extends SensorBase {
*/
public byte getAll() {
byte value = 0;
// IntBuffer status = IntBuffer.allocate(1);
// for (int i = 0; i < SensorBase.kSolenoidChannels; i++) {
// value |= SolenoidJNI.getSolenoid(m_ports[i], status) << i;
// }
// HALUtil.checkStatus(status);
IntBuffer status = IntBuffer.allocate(1);
for (int i = 0; i < SensorBase.kSolenoidChannels; i++) {
value |= SolenoidJNI.getSolenoid(m_ports[i], status) << i;
}
HALUtil.checkStatus(status);
return value;
}
/**
* Read all 8 solenoids in the default solenoid module as a single byte
*
* @return The current value of all 8 solenoids on the default module.
*/
public static byte getAllFromDefaultModule() {
return getAllFromModule(getDefaultSolenoidModule());
}
/**
* Read all 8 solenoids in the specified solenoid module as a single byte
*
* @return The current value of all 8 solenoids on the specified module.
*/
public static byte getAllFromModule(int moduleNumber) {
byte value = 0;
// checkSolenoidModule(moduleNumber);
// throw new RuntimeException("Not supported right now.");
return value;
}
}

View File

@@ -435,11 +435,11 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
public static native void FRCNetworkCommunicationGetVersionString(ByteBuffer version);
public static native void FRCNetworkCommunicationObserveUserProgramStarting();
public static native void FRCNetworkCommunicationObserveUserProgramDisabled();
public static native void FRCNetworkCommunicationObserveUserProgramAutonomous();
public static native void FRCNetworkCommunicationObserveUserProgramTeleop();
public static native void FRCNetworkCommunicationObserveUserProgramTest();
public static native void FRCNetworkCommunicationReserve();
public static native void FRCNetworkCommunicationReserve();
private static native int NativeHALGetControlWord();
public static HALControlWord HALGetControlWord() {
int word = NativeHALGetControlWord();

View File

@@ -1,7 +1,7 @@
package edu.wpi.first.wpilibj.hal;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
public class HALUtil extends JNIWrapper {
public static final int NULL_PARAMETER = -5;
@@ -28,6 +28,12 @@ public class HALUtil extends JNIWrapper {
public static native boolean getFPGAButton(IntBuffer status);
public static native String getHALErrorMessage(int code);
public static native int getHALErrno();
public static native String getHALstrerror(int errno);
public static String getHALstrerror(){
return getHALstrerror(getHALErrno());
}
public static void checkStatus(IntBuffer status)
{

View File

@@ -1,12 +1,13 @@
package edu.wpi.first.wpilibj.hal;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
public class InterruptJNI extends JNIWrapper {
public interface InterruptHandlerFunction {
void apply(int interruptAssertedMask, ByteBuffer param);
public interface InterruptJNIHandlerFunction {
void apply(int interruptAssertedMask, Object param);
};
public static native void initializeInterruptJVM(IntBuffer status);
public static native ByteBuffer initializeInterrupts(int interruptIndex, byte watcher, IntBuffer status);
public static native void cleanInterrupts(ByteBuffer interrupt_pointer, IntBuffer status);
public static native void waitForInterrupt(ByteBuffer interrupt_pointer, double timeout, IntBuffer status);
@@ -14,6 +15,6 @@ public class InterruptJNI extends JNIWrapper {
public static native void disableInterrupts(ByteBuffer interrupt_pointer, IntBuffer status);
public static native double readInterruptTimestamp(ByteBuffer interrupt_pointer, IntBuffer status);
public static native void requestInterrupts(ByteBuffer interrupt_pointer, byte routing_module, int routing_pin, byte routing_analog_trigger, IntBuffer status);
public static native void attachInterruptHandler(ByteBuffer interrupt_pointer, InterruptHandlerFunction handler, ByteBuffer param, IntBuffer status);
public static native void attachInterruptHandler(ByteBuffer interrupt_pointer, InterruptJNIHandlerFunction handler, Object param, IntBuffer status);
public static native void setInterruptUpSourceEdge(ByteBuffer interrupt_pointer, byte risingEdge, byte fallingEdge, IntBuffer status);
}

View File

@@ -0,0 +1,377 @@
<!DOCTYPE html><html><head><meta charset="utf-8"><style>/* Fonts */
@font-face{
font-family: octicons-anchor;
src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
}
@font-face{
font-family: fontawesome-mini;
src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
}
/* Body */
html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
body{
color:#4d4d4c;
font-family:Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman',
"Hiragino Sans GB", "STXihei", "微软雅黑", serif;
font-size:12px;
line-height:1.5em;
background:#fefefe;
width: 45em;
margin: 10px auto;
padding: 30px;
border: 1px solid #ddd;
outline: 1300px solid #f8f8f8;
}
/* Links */
a{ color: #06d; text-decoration:none; }
a:hover{ color: #06e; text-decoration: underline; }
a:active{ color:#faa700; }
a:focus{ outline: thin dotted; }
a:hover, a:active{ outline: 0; }
::-moz-selection { background:#a8d1ff; color:#000 }
::selection { background:#a8d1ff; color:#000 }
a::-moz-selection { background:#a8d1ff; color:#0645ad }
a::selection { background:#a8d1ff; color:#0645ad }
/* Header Anchor Links*/
.headeranchor-link {
color:#111;
border: 0;
margin-left: -20px;
padding-right: 6px;
cursor: pointer;
position: absolute;
display: block;
top: 0;
left: 0;
bottom: 0;
}
.headeranchor {
font: normal normal 16px octicons-anchor;
line-height: 1;
-moz-osx-font-smoothing: grayscale;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.headeranchor-link:hover,
.headeranchor-link:visited,
.headeranchor-link:active
{ text-decoration: none; color:#4d4d4c; }
.headeranchor-link:hover .headeranchor:before,
h1:hover .headeranchor:before,
h2:hover .headeranchor:before,
h3:hover .headeranchor:before,
h4:hover .headeranchor:before,
h5:hover .headeranchor:before,
h6:hover .headeranchor:before
{ content: '\f05c'; }
abbr { cursor: pointer; }
/* Paragraphs */
p { margin:1em 0; }
/* Images */
img {
max-width:100%;
border: 0;
-ms-interpolation-mode: bicubic;
vertical-align: middle;
}
/* Headers */
h1,h2,h3,h4,h5,h6 {
font-weight:normal;
color:#111;
line-height: 1.7;
position: relative;
}
h4,h5,h6{ font-weight: bold; }
h1 { font-size:2.5em; border-bottom: 1px solid #ddd;}
h2 { font-size:2em; border-bottom:1px solid #eee; padding-bottom: 5px; }
h3 { font-size:1.5em; }
h4 { font-size:1.2em; }
h5 { font-size:1em; }
h6 { font-size:0.9em; }
/* Block Quotes */
blockquote {
color:#666666;
margin:0;
padding-left: 3em;
border-left: 0.5em #EEE solid;
}
hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa;border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; }
/* Raw Blocks */
pre, code, kbd, samp {
color: #000;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
font-size: 0.88em;
background-color: #F8F8F8;
border: 1px solid #CCC;
}
pre {
padding: 10px;
overflow: auto;
}
code { padding: 0 3px 0 3px; }
pre code { border: 0; padding: 0; }
/* Admonition */
.admonition {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
font-size: 0.88em;
padding: 0.5em 1em 0.5em 1em;
margin: 10px auto;
color: #888888;
background-color: #F8F8F8;
border: 1px solid #888888;
}
.admonition p { padding: 0; margin: 0; }
.admonition-title { font-weight: bold; margin: 0; }
.admonition-icon {
font: normal normal 16px fontawesome-mini;
line-height: 1.5;
-moz-osx-font-smoothing: grayscale;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
float: left;
}
.admonition.attention { color: #4F8A10; background-color: #DFF2BF; border: 1px solid #4F8A10; }
.admonition.caution { color: #D63301; background-color: #FFCCBA; border: 1px solid #D63301; }
.admonition.hint { color: #00529B; background-color: #BDE5F8; border: 1px solid #00529B; }
.admonition.danger { color: #D8000C; background-color: #FFBABA; border: 1px solid #D8000C; }
.admonition.question { color: #00049b; background-color: #BDC8F8; border: 1px solid #00049b; }
.admonition.note { color: #9F6000; background-color: #FEEFB3; border: 1px solid #9F6000; }
.attention > .admonition-icon:before { content: "\f058\00a0"; }
.caution > .admonition-icon:before { content: "\f06a\00a0"; }
.hint > .admonition-icon:before { content: "\f05a\00a0"; }
.danger > .admonition-icon:before { content: "\f056\00a0"; }
.question > .admonition-icon:before { content: "\f059\00a0"; }
.note > .admonition-icon:before { content: "\f040\00a0"; }
/* progress bar*/
.progress {
display: block;
width: 300px;
margin: 10px 0;
height: 24px;
border: 1px solid #ccc;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #F8F8F8;
position: relative;
box-shadow: inset -1px 1px 3px rgba(0, 0, 0, .1);
}
.progress-label {
position: absolute;
text-align: center;
font-weight: bold;
width: 100%; margin: 0;
line-height: 24px;
color: #333;
text-shadow:
1px 1px 0px #fefefe,
-1px -1px 0px #fefefe,
-1px 1px 0px #fefefe,
1px -1px 0px #fefefe,
0px 1px 0px #fefefe,
0px -1px 0px #fefefe,
1px 0px 0px #fefefe,
-1px 0px 0px #fefefe,
1px 1px 2px #000;
-webkit-font-smoothing: antialiased !important;
white-space: nowrap;
overflow: hidden;
}
.progress-bar {
height: 24px;
float: left;
border-right: 1px solid #ccc;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #34c2e3;
box-shadow: inset 0 1px 0px rgba(255, 255, 255, .5);
background-size: 30px 30px;
background-image: -webkit-linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
background-image: -moz-linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
background-image: -ms-linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
background-image: -o-linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
background-image: linear-gradient(
135deg,
rgba(255, 255, 255, .4) 27%, transparent 27%,
transparent 53%, rgba(255, 255, 255, .4) 53%,
rgba(255, 255, 255, .4) 77%, transparent 77%,
transparent
);
}
.progress-100plus .progress-bar { background-color: #1ee038; }
.progress-80plus .progress-bar { background-color: #86e01e; }
.progress-60plus .progress-bar { background-color: #f2d31b; }
.progress-40plus .progress-bar { background-color: #f2b01e; }
.progress-20plus .progress-bar { background-color: #f27011; }
.progress-0plus .progress-bar { background-color: #f63a0f; }
.gloss .progress-bar {
box-shadow:
inset -1px 1px 0px rgba(255, 255, 255, .5),
inset 0 -4px 12px rgba(255, 255, 255, .7),
inset 0 4px 12px rgba(255, 255, 255, .7),
inset 0 -12px 0px rgba(0, 0, 0, .05),
inset 1px -1px 0px rgba(255, 255, 255, .2);
}
.candystripe-animate .progress-bar{
-webkit-animation: animate-stripes 3s linear infinite;
-moz-animation: animate-stripes 3s linear infinite;
animation: animate-stripes 3s linear infinite;
}
@-webkit-keyframes animate-stripes { 0% { background-position: 0 0; } 100% { background-position: 60px 0; } }
@-moz-keyframes animate-stripes { 0% { background-position: 0 0; } 100% { background-position: 60px 0; } }
@keyframes animate-stripes { 0% { background-position: 0 0; } 100% { background-position: 60px 0; } }
/* Inlines */
b, strong { font-weight: bold; }
mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }
dfn { font-style: italic; }
/* Lists */
ul, ol { padding-left: 30px; }
li p:last-child { margin:0 }
.task-list-item { list-style-type: none; }
.task-list-item input { float:left; margin-left: -20px; margin-top: 6px; }
dt { font-weight: bold; font-style: italic;}
dd { margin: 0 0 0 2em; }
/* Tables */
table { width: 100%; border-collapse: collapse; overflow-x: auto; overflow-y: hidden; display: block;}
table tr { background-color: #fefefe; }
table tr:nth-child(2n) { background-color: #f8f8f8; }
td, th { border: 1px solid #ddd; padding: 6px 13px; }
/* Codehilite Tables */
.codehilitetable { border: 0; border-spacing: 0; }
.linenos, .code, .codehilitetable td { border: 0; padding: 0; }
td:not(.linenos) .linenodiv { padding: 0 !important; }
.code { width: 100%; }
.linenos div pre, .linenodiv pre {
border: 0;
border-top: 1px solid #CCC;
border-left: 1px solid #CCC;
border-right: 1px solid #CCC;
border-bottom: 1px solid #CCC;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-border-top-left-radius: 3px;
-webkit-border-bottom-left-radius: 3px;
-moz-border-radius-topleft: 3px;
-moz-border-radius-bottomleft: 3px;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.code div pre {
border: 0;
border-top: 1px solid #CCC;
border-right: 1px solid #CCC;
border-bottom: 1px solid #CCC;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-border-top-right-radius: 3px;
-webkit-border-bottom-right-radius: 3px;
-moz-border-radius-topright: 3px;
-moz-border-radius-bottomright: 3px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
/* Media */
@media only screen and (min-width: 480px) {
body{ font-size:14px; }
}
@media only screen and (min-width: 768px) {
body{ font-size:16px; }
}
@media print {
* { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; }
body{ font-size:12pt; max-width:100%; outline:none; border: 0;}
a, a:visited { text-decoration: underline; }
.headeranchor-link { display: none; }
hr { height: 1px; border:0; border-bottom:1px solid black; }
a[href]:after { content: " (" attr(href) ")"; }
abbr[title]:after { content: " (" attr(title) ")"; }
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
pre, blockquote { border: 1px solid #999; padding-right: 1em; page-break-inside: avoid; }
.progress, .progress-bar { box-shadow: none; }
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
p, h2, h3 { orphans: 3; widows: 3; }
h2, h3 { page-break-after: avoid; }
}
</style><title>README</title></head><body><h2 id="to-load-run-integration-tests"><a name="user-content-to-load-run-integration-tests" href="#to-load-run-integration-tests" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>TO LOAD &amp; RUN INTEGRATION TESTS</h2>
<p>See: allwpilib/test-scripts</p></body></html>

View File

@@ -1,7 +1,3 @@
TO LOAD & RUN INTEGRATION TESTS
## TO LOAD & RUN INTEGRATION TESTS
1. Run `mvn clean package` from this directory
2. Run `scp target/wpilibJavaIntegrationTests-0.1.0-SNAPSHOT.jar admin@10.1.90.2:/home/admin` and enter the password on the RoboRio
3. ssh into the RoboRio using `ssh admin@10.1.90.2`
4. Run the integration tests on the roborio using `./runintegrationjavaprogram`
5. Enable the robot using a driver station (this will be automatic eventually)
See: allwpilib/test-scripts

View File

@@ -34,6 +34,16 @@
<artifactId>junit-toolbox</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-junit</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
<profiles>
@@ -120,6 +130,18 @@
<version>2.0</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.4</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>org.apache.ant</groupId>
<artifactId>ant-junit</artifactId>
<version>1.9.4</version>
<type>jar</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
@@ -148,7 +170,7 @@
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>edu.wpi.first.wpilibj.test.TestSuite</mainClass>
<mainClass>edu.wpi.first.wpilibj.test.AntJunitLanucher</mainClass>
</manifest>
</archive>
</configuration>

View File

@@ -0,0 +1,239 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-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 the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import static org.hamcrest.Matchers.both;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.After;
import org.junit.Test;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
/**
* This class should not be run as a test explicitly. Instead it should be extended by tests that use the InterruptableSensorBase
*
* @author jonathanleitschuh
*
*/
public abstract class AbstractInterruptTest extends AbstractComsSetup {
private InterruptableSensorBase interruptable = null;
private InterruptableSensorBase getInterruptable(){
if(interruptable == null){
interruptable = giveInterruptableSensorBase();
}
return interruptable;
}
@After
public void interruptTeardown(){
if(interruptable != null){
freeInterruptableSensorBase();
interruptable = null;
}
}
/**
* Give the interruptible sensor base that interrupts can be attached to.
* @return
*/
abstract InterruptableSensorBase giveInterruptableSensorBase();
/**
* Cleans up the interruptible sensor base. This is only called if {@link #giveInterruptableSensorBase()} is called.
*/
abstract void freeInterruptableSensorBase();
/**
* Perform whatever action is required to set the interrupt high.
*/
abstract void setInterruptHigh();
/**
* Perform whatever action is required to set the interrupt low.
*/
abstract void setInterruptLow();
private class InterruptCounter{
private final AtomicInteger count = new AtomicInteger();
void increment(){
count.addAndGet(1);
}
int getCount(){
return count.get();
}
};
private class TestInterruptHandlerFunction extends InterruptHandlerFunction<InterruptCounter>{
protected final AtomicBoolean exceptionThrown = new AtomicBoolean(false);
/** Stores the time that the interrupt fires */
final AtomicLong interruptFireTime = new AtomicLong();
/** Stores if the interrupt has completed at least once */
final AtomicBoolean interruptComplete = new AtomicBoolean(false);
protected Exception ex;
final InterruptCounter counter;
TestInterruptHandlerFunction(InterruptCounter counter){
this.counter = counter;
}
@Override
void interruptFired(int interruptAssertedMask, InterruptCounter param) {
interruptFireTime.set(Utility.getFPGATime());
counter.increment();
try{
//This won't cause the test to fail
assertSame(counter, param);
} catch (Exception ex){
//So we must throw the exception within the test
exceptionThrown.set(true);
this.ex = ex;
}
interruptComplete.set(true);
};
@Override
public InterruptCounter overridableParamater(){
return counter;
}
};
@Test(timeout = 1000)
public void testSingleInterruptsTriggering() throws Exception{
//Given
final InterruptCounter counter = new InterruptCounter();
TestInterruptHandlerFunction function = new TestInterruptHandlerFunction(counter);
//When
getInterruptable().requestInterrupts(function);
getInterruptable().enableInterrupts();
setInterruptLow();
Timer.delay(0.01);
//Note: Utility.getFPGATime() is used because double values can turn over after the robot has been running for a long time
final long interruptTriggerTime = Utility.getFPGATime();
setInterruptHigh();
//Delay until the interrupt is complete
while(!function.interruptComplete.get()){
Timer.delay(.005);
}
//Then
assertEquals("The interrupt did not fire the expected number of times", 1, counter.getCount());
//If the test within the interrupt failed
if(function.exceptionThrown.get()){
throw function.ex;
}
final long range = 10000; //in microseconds
assertThat("The interrupt did not fire within the expected time period (values in milliseconds)",
function.interruptFireTime.get(), both(greaterThan(interruptTriggerTime - range))
.and(lessThan(interruptTriggerTime + range)));
assertThat("The readInterruptTimestamp() did not return the correct value (values in seconds)",
getInterruptable().readInterruptTimestamp(), both(greaterThan((interruptTriggerTime - range)/1e6))
.and(lessThan((interruptTriggerTime + range)/1e6)));
}
@Test(timeout = 1000)
public void testMultipleInterruptsTriggering() throws Exception{
//Given
final InterruptCounter counter = new InterruptCounter();
TestInterruptHandlerFunction function = new TestInterruptHandlerFunction(counter);
//When
getInterruptable().requestInterrupts(function);
getInterruptable().enableInterrupts();
final int fireCount = 50;
for(int i = 0; i < fireCount; i ++){
setInterruptLow();
setInterruptHigh();
//Wait for the interrupt to complete before moving on
while(!function.interruptComplete.getAndSet(false)){
Timer.delay(.005);
}
}
//Then
assertEquals("The interrupt did not fire the expected number of times", fireCount, counter.getCount());
}
/** The timeout length for this test in seconds */
private static final int synchronousTimeout = 5;
@Test(timeout = (long)(synchronousTimeout*1e3))
public void testSynchronousInterruptsTriggering(){
//Given
getInterruptable().requestInterrupts();
final double synchronousDelay = synchronousTimeout/2.;
Runnable r = new Runnable(){
@Override
public void run() {
Timer.delay(synchronousDelay);
setInterruptLow();
setInterruptHigh();
}
};
//When
//Note: the long time value is used because doubles can flip if the robot is left running for long enough
final long startTimeStamp = Utility.getFPGATime();
new Thread(r).start();
//Delay for twice as long as the timeout so the test should fail first
getInterruptable().waitForInterrupt(synchronousTimeout * 2);
final long stopTimeStamp = Utility.getFPGATime();
//Then
//The test will not have timed out and:
final double interruptRunTime = (stopTimeStamp - startTimeStamp)*1e-6;
assertEquals("The interrupt did not run for the expected amount of time (units in seconds)", synchronousDelay, interruptRunTime, .1);
}
@Test(timeout = 2000)
public void testDisableStopsInterruptFiring(){
final InterruptCounter counter = new InterruptCounter();
TestInterruptHandlerFunction function = new TestInterruptHandlerFunction(counter);
//When
getInterruptable().requestInterrupts(function);
getInterruptable().enableInterrupts();
final int fireCount = 50;
for(int i = 0; i < fireCount; i ++){
setInterruptLow();
setInterruptHigh();
//Wait for the interrupt to complete before moving on
while(!function.interruptComplete.getAndSet(false)){
Timer.delay(.005);
}
}
getInterruptable().disableInterrupts();
//TestBench.out().println("Finished disabling the robot");
for(int i = 0; i < fireCount; i ++){
setInterruptLow();
setInterruptHigh();
//Just wait because the interrupt should not fire
Timer.delay(.005);
}
//Then
assertEquals("The interrupt did not fire the expected number of times", fireCount, counter.getCount());
}
}

View File

@@ -6,7 +6,9 @@
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.logging.Logger;
@@ -16,15 +18,15 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType;
import edu.wpi.first.wpilibj.fixtures.AnalogCrossConnectFixture;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
import edu.wpi.first.wpilibj.test.TestBench;
/**
* @author jonathanleitschuh
*
*/
public class AnalogCrossConnectTest extends AbstractComsSetup {
public class AnalogCrossConnectTest extends AbstractInterruptTest {
private static final Logger logger = Logger.getLogger(AnalogCrossConnectTest.class.getName());
private static AnalogCrossConnectFixture analogIO;
@@ -51,6 +53,7 @@ public class AnalogCrossConnectTest extends AbstractComsSetup {
@AfterClass
public static void tearDownAfterClass() throws Exception {
analogIO.teardown();
analogIO=null;
}
/**
@@ -133,7 +136,6 @@ public class AnalogCrossConnectTest extends AbstractComsSetup {
// Given
AnalogTrigger trigger = new AnalogTrigger(analogIO.getInput());
trigger.setLimitsVoltage(2.0f, 3.0f);
Counter counter = new Counter(trigger);
// When the analog output is turned low and high 50 times
@@ -152,4 +154,48 @@ public class AnalogCrossConnectTest extends AbstractComsSetup {
public void testRuntimeExceptionOnInvalidAccumulatorPort(){
analogIO.getInput().getAccumulatorCount();
}
private AnalogTrigger interruptTrigger;
private AnalogTriggerOutput interruptTriggerOutput;
/* (non-Javadoc)
* @see edu.wpi.first.wpilibj.AbstractInterruptTest#giveInterruptableSensorBase()
*/
@Override
InterruptableSensorBase giveInterruptableSensorBase() {
interruptTrigger = new AnalogTrigger(analogIO.getInput());
interruptTrigger.setLimitsVoltage(2.0f, 3.0f);
interruptTriggerOutput = new AnalogTriggerOutput(interruptTrigger, AnalogTriggerType.STATE);
return interruptTriggerOutput;
}
/* (non-Javadoc)
* @see edu.wpi.first.wpilibj.AbstractInterruptTest#freeInterruptableSensorBase()
*/
@Override
void freeInterruptableSensorBase() {
interruptTriggerOutput.cancelInterrupts();
interruptTriggerOutput.free();
interruptTriggerOutput = null;
interruptTrigger.free();
interruptTrigger = null;
}
/* (non-Javadoc)
* @see edu.wpi.first.wpilibj.AbstractInterruptTest#setInterruptHigh()
*/
@Override
void setInterruptHigh() {
analogIO.getOutput().setVoltage(4.0);
}
/* (non-Javadoc)
* @see edu.wpi.first.wpilibj.AbstractInterruptTest#setInterruptLow()
*/
@Override
void setInterruptLow() {
analogIO.getOutput().setVoltage(1.0);
}
}

View File

@@ -6,14 +6,12 @@
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.util.logging.Logger;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import edu.wpi.first.wpilibj.fixtures.AnalogCrossConnectFixture;
@@ -68,8 +66,8 @@ public class AnalogPotentiometerTest extends AbstractComsSetup {
public void testRangeValues(){
for(double i = 0.0; i < 360.0; i = i+1.0){
potSource.setAngle(i);
assertEquals(i, pot.get(), DOUBLE_COMPARISON_DELTA);
Timer.delay(.02);
assertEquals(i, pot.get(), DOUBLE_COMPARISON_DELTA);
}
}

View File

@@ -12,7 +12,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -20,14 +19,13 @@ import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.BuiltInAccelerometer;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
@RunWith(Parameterized.class)
public class BuiltInAccelerometerTest extends AbstractComsSetup {
private static final Logger logger = Logger.getLogger(PIDTest.class.getName());
private static final Logger logger = Logger.getLogger(BuiltInAccelerometerTest.class.getName());
private static final double kAccelerationTolerance = 0.1;
private BuiltInAccelerometer m_accelerometer;
private final BuiltInAccelerometer m_accelerometer;
public BuiltInAccelerometerTest(Accelerometer.Range range) {
m_accelerometer = new BuiltInAccelerometer(range);

View File

@@ -37,6 +37,7 @@ public class CounterTest extends AbstractComsSetup {
Integer input;
Integer output;
@Override
protected Logger getClassLogger(){
return logger;
}
@@ -87,6 +88,7 @@ public class CounterTest extends AbstractComsSetup {
@AfterClass
public static void tearDownAfterClass() throws Exception {
counter.teardown();
counter=null;
}
/**

View File

@@ -14,16 +14,12 @@ import java.util.logging.Logger;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import edu.wpi.first.wpilibj.fixtures.DIOCrossConnectFixture;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
import edu.wpi.first.wpilibj.test.TestBench;
/**
@@ -31,11 +27,12 @@ import edu.wpi.first.wpilibj.test.TestBench;
* @author jonathanleitschuh
*/
@RunWith(Parameterized.class)
public class DIOCrossConnectTest extends AbstractComsSetup {
public class DIOCrossConnectTest extends AbstractInterruptTest {
private static final Logger logger = Logger.getLogger(DIOCrossConnectTest.class.getName());
private static DIOCrossConnectFixture dio = null;
@Override
protected Logger getClassLogger(){
return logger;
}
@@ -65,7 +62,7 @@ public class DIOCrossConnectTest extends AbstractComsSetup {
* Array in the Collection, each array element corresponds to a parameter
* in the constructor.
*/
@Parameters
@Parameters(name= "{index}: Input Port: {0} Output Port: {1}")
public static Collection<Integer[]> generateData() {
// In this example, the parameter generator returns a List of
// arrays. Each array has two elements: { Digital input port, Digital output port}.
@@ -74,24 +71,15 @@ public class DIOCrossConnectTest extends AbstractComsSetup {
return TestBench.getInstance().getDIOCrossConnectCollection();
}
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
dio.teardown();
}
@Before
public void setUp() throws Exception {
dio.reset();
dio=null;
}
@After
public void tearDown() throws Exception {
dio.reset();
}
/**
@@ -115,4 +103,38 @@ public class DIOCrossConnectTest extends AbstractComsSetup {
Timer.delay(.02);
assertFalse("DIO Not Low after .05s delay", dio.getInput().get());
}
/* (non-Javadoc)
* @see edu.wpi.first.wpilibj.AbstractInterruptTest#giveInterruptableSensorBase()
*/
@Override
InterruptableSensorBase giveInterruptableSensorBase() {
return dio.getInput();
}
/* (non-Javadoc)
* @see edu.wpi.first.wpilibj.AbstractInterruptTest#freeInterruptableSensorBase()
*/
@Override
void freeInterruptableSensorBase() {
// Handled in the fixture
}
/* (non-Javadoc)
* @see edu.wpi.first.wpilibj.AbstractInterruptTest#setInterruptHigh()
*/
@Override
void setInterruptHigh() {
dio.getOutput().set(true);
}
/* (non-Javadoc)
* @see edu.wpi.first.wpilibj.AbstractInterruptTest#setInterruptLow()
*/
@Override
void setInterruptLow() {
dio.getOutput().set(false);
}
}

View File

@@ -6,7 +6,7 @@
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
import java.util.Collection;
import java.util.logging.Logger;
@@ -14,13 +14,11 @@ import java.util.logging.Logger;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import edu.wpi.first.wpilibj.fixtures.DIOCrossConnectFixture;
import edu.wpi.first.wpilibj.fixtures.FakeEncoderFixture;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
import edu.wpi.first.wpilibj.test.TestBench;
@@ -43,6 +41,7 @@ public class EncoderTest extends AbstractComsSetup {
private final int outputA;
private final int outputB;
@Override
protected Logger getClassLogger(){
return logger;
}
@@ -78,19 +77,13 @@ public class EncoderTest extends AbstractComsSetup {
encoder = new FakeEncoderFixture(inputA, outputA, inputB, outputB);
}
/**
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
encoder.teardown();
encoder=null;
}
/**

View File

@@ -6,6 +6,7 @@
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -69,12 +70,14 @@ public class MotorEncoderTest extends AbstractComsSetup {
@After
public void tearDown() throws Exception {
me.reset();
encodersResetCheck(me);
}
@AfterClass
public static void tearDownAfterClass() {
// Clean up the fixture after the test
me.teardown();
me=null;
}
/**
@@ -104,8 +107,7 @@ public class MotorEncoderTest extends AbstractComsSetup {
assertTrue(me.getType() + " Encoder not incremented: start: "
+ startValue + "; current: " + currentValue,
startValue < currentValue);
me.reset();
encodersResetCheck(me);
}
/**
@@ -121,8 +123,6 @@ public class MotorEncoderTest extends AbstractComsSetup {
assertTrue(me.getType() + " Encoder not decremented: start: "
+ startValue + "; current: " + currentValue,
startValue > currentValue);
me.reset();
encodersResetCheck(me);
}
/**
@@ -155,7 +155,6 @@ public class MotorEncoderTest extends AbstractComsSetup {
me.getMotor().set(15);
assertTrue(me.getType() + " Motor speed was not close to 1.0, was: "
+ me.getMotor().get(), me.isMotorSpeedWithinRange(1.0, 0.001));
me.reset();
}
/**
@@ -166,7 +165,6 @@ public class MotorEncoderTest extends AbstractComsSetup {
me.getMotor().set(-15);
assertTrue(me.getType() + " Motor speed was not close to 1.0, was: "
+ me.getMotor().get(), me.isMotorSpeedWithinRange(-1.0, 0.001));
me.reset();
}
@@ -186,7 +184,6 @@ public class MotorEncoderTest extends AbstractComsSetup {
pid.onTarget());
pid.free();
me.reset();
}
@@ -195,18 +192,11 @@ public class MotorEncoderTest extends AbstractComsSetup {
* @param me The MotorEncoderFixture under test
*/
private void encodersResetCheck(MotorEncoderFixture<?> me){
int encoderVal = me.getEncoder().get();
int counterVal[] = new int[2];
for(int i = 0; i < 2; i++){
counterVal[i] = me.getCounters()[i].get();
}
double motorVal = me.getMotor().get();
assertTrue(me.getType() + " Encoder value: " + encoderVal + " when it should be 0", encoderVal == 0);
assertTrue(me.getType() + " Motor value: " + motorVal + " when it should be 0", motorVal == 0);
assertTrue(me.getType() + " Counter value " + counterVal[0] + " when is should be 0", counterVal[0] == 0);
assertTrue(me.getType() + " Counter value " + counterVal[1] + " when is should be 0", counterVal[1] == 0);
Timer.delay(.2);
assertTrue(me.getType() + " Encoder.getStopped() returned false", me.getEncoder().getStopped());
assertEquals(me.getType() + " Encoder value was incorrect after reset.", me.getEncoder().get(), 0);
assertEquals(me.getType() + " Motor value was incorrect after reset.", me.getMotor().get(), 0, 0);
assertEquals(me.getType() + " Counter1 value was incorrect after reset.", me.getCounters()[0].get(), 0);
assertEquals(me.getType() + " Counter2 value was incorrect after reset.", me.getCounters()[1].get(), 0);
assertTrue(me.getType() + " Encoder.getStopped() returned false after the motor was reset.", me.getEncoder().getStopped());
}
}

View File

@@ -32,7 +32,7 @@ public class PCMTest extends AbstractComsSetup {
protected static final double kCompressorDelayTime = 2.0;
/* Solenoids should change much more quickly */
protected static final double kSolenoidDelayTime = 0.1;
protected static final double kSolenoidDelayTime = 1.0;
/* The voltage divider on the test bench should bring the compressor output
to around these values. */
@@ -44,7 +44,6 @@ public class PCMTest extends AbstractComsSetup {
private static DigitalOutput fakePressureSwitch;
private static AnalogInput fakeCompressor;
private static Solenoid solenoid1, solenoid2;
private static DigitalInput fakeSolenoid1, fakeSolenoid2;
@BeforeClass
@@ -54,9 +53,6 @@ public class PCMTest extends AbstractComsSetup {
fakePressureSwitch = new DigitalOutput(11);
fakeCompressor = new AnalogInput(1);
solenoid1 = new Solenoid(7);
solenoid2 = new Solenoid(6);
fakeSolenoid1 = new DigitalInput(12);
fakeSolenoid2 = new DigitalInput(13);
}
@@ -68,9 +64,6 @@ public class PCMTest extends AbstractComsSetup {
fakePressureSwitch.free();
fakeCompressor.free();
solenoid1.free();
solenoid2.free();
fakeSolenoid1.free();
fakeSolenoid2.free();
}
@@ -83,8 +76,6 @@ public class PCMTest extends AbstractComsSetup {
public void reset() throws Exception {
compressor.stop();
fakePressureSwitch.set(false);
solenoid1.set(false);
solenoid2.set(false);
}
@After
@@ -120,6 +111,9 @@ public class PCMTest extends AbstractComsSetup {
public void testSolenoid() throws Exception {
reset();
Solenoid solenoid1 = new Solenoid(0);
Solenoid solenoid2 = new Solenoid(1);
solenoid1.set(false);
solenoid2.set(false);
Timer.delay(kSolenoidDelayTime);
@@ -146,6 +140,35 @@ public class PCMTest extends AbstractComsSetup {
Timer.delay(kSolenoidDelayTime);
assertFalse("Solenoid #1 did not turn on",fakeSolenoid1.get());
assertFalse("Solenoid #2 did not turn on",fakeSolenoid2.get());
solenoid1.free();
solenoid2.free();
}
/**
* Test if the correct solenoids turn on and off when they should when used
* with the DoubleSolenoid class.
*/
@Test
public void doubleSolenoid() {
DoubleSolenoid solenoid = new DoubleSolenoid(0, 1);
solenoid.set(DoubleSolenoid.Value.kOff);
Timer.delay(kSolenoidDelayTime);
assertTrue("Solenoid #1 did not turn off", fakeSolenoid1.get());
assertTrue("Solenoid #2 did not turn off", fakeSolenoid2.get());
solenoid.set(DoubleSolenoid.Value.kForward);
Timer.delay(kSolenoidDelayTime);
assertFalse("Solenoid #1 did not turn on", fakeSolenoid1.get());
assertTrue("Solenoid #2 did not turn off", fakeSolenoid2.get());
solenoid.set(DoubleSolenoid.Value.kReverse);
Timer.delay(kSolenoidDelayTime);
assertTrue("Solenoid #1 did not turn off", fakeSolenoid1.get());
assertFalse("Solenoid #2 did not turn on", fakeSolenoid2.get());
solenoid.free();
}
protected Logger getClassLogger(){

View File

@@ -25,40 +25,41 @@ import edu.wpi.first.wpilibj.test.TestBench;
@RunWith(Parameterized.class)
public class PDPTest extends AbstractComsSetup {
private static final Logger logger = Logger.getLogger(PCMTest.class.getName());
/* The current returned when the motor is not being driven */
protected static final double kLowCurrent = 1.52;
protected static final double kCurrentTolerance = 0.1;
private static PowerDistributionPanel pdp;
private static MotorEncoderFixture<?> me;
private final double expectedStoppedCurrentDraw;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
pdp = new PowerDistributionPanel();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
pdp.free();
pdp=null;
me.teardown();
me=null;
}
public PDPTest(MotorEncoderFixture<?> mef){
public PDPTest(MotorEncoderFixture<?> mef, Double expectedCurrentDraw){
logger.fine("Constructor with: " + mef.getType());
if(me != null && !me.equals(mef)) me.teardown();
me = mef;
me.setup();
this.expectedStoppedCurrentDraw = expectedCurrentDraw;
}
@Parameters(name= "{index}: {0}")
public static Collection<MotorEncoderFixture<?>[]> generateData(){
@Parameters(name= "{index}: {0}, Expected Stopped Current Draw: {1}")
public static Collection<Object[]> generateData(){
//logger.fine("Loading the MotorList");
return Arrays.asList(new MotorEncoderFixture<?>[][]{
{TestBench.getInstance().getTalonPair()},
{TestBench.getInstance().getVictorPair()},
{TestBench.getInstance().getJaguarPair()}
return Arrays.asList(new Object[][]{
{TestBench.getInstance().getTalonPair(), new Double(0.0)},
{TestBench.getInstance().getVictorPair(), new Double(0.0)},
{TestBench.getInstance().getJaguarPair(), new Double(0.0)}
});
}
@@ -66,19 +67,21 @@ public class PDPTest extends AbstractComsSetup {
public void tearDown() throws Exception {
me.reset();
}
/**
* Test if the current changes when the motor is driven using a talon
*/
@Test
public void CheckStoppedCurrentForSpeedController() throws CANMessageNotFoundException{
/* The Current should be kLowCurrent */
Timer.delay(0.25);
/* The Current should be 0 */
assertEquals("The low current was not within the expected range.",
kLowCurrent, pdp.getCurrent(me.getPDPChannel()), kCurrentTolerance);
expectedStoppedCurrentDraw, pdp.getCurrent(me.getPDPChannel()), 0.001);
}
/**
* Test if the current changes when the motor is driven using a talon
*/
@@ -87,10 +90,11 @@ public class PDPTest extends AbstractComsSetup {
/* Set the motor to full forward */
me.getMotor().set(1.0);
Timer.delay(0.02);
Timer.delay(0.25);
/* The current should now be greater than the low current */
assertThat("The driven current is not greater than the resting current.",
pdp.getCurrent(me.getPDPChannel()), is(greaterThan(kLowCurrent)));
pdp.getCurrent(me.getPDPChannel()), is(greaterThan(expectedStoppedCurrentDraw)));
}
@Override

View File

@@ -6,8 +6,12 @@
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
@@ -18,16 +22,11 @@ import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import edu.wpi.first.wpilibj.PIDSource.PIDSourceParameter;
import edu.wpi.first.wpilibj.fixtures.MotorEncoderFixture;
import edu.wpi.first.wpilibj.networktables.NetworkTable;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
@@ -54,6 +53,7 @@ public class PIDTest extends AbstractComsSetup {
private final Double k_p, k_i, k_d;
@Override
protected Logger getClassLogger(){
return logger;
}
@@ -99,6 +99,7 @@ public class PIDTest extends AbstractComsSetup {
public static void tearDownAfterClass() throws Exception {
logger.fine("TearDownAfterClass: " + me.getType());
me.teardown();
me=null;
}
/**

View File

@@ -6,7 +6,9 @@
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileOutputStream;
@@ -14,43 +16,28 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Logger;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import edu.wpi.first.wpilibj.command.AbstractCommandTest;
import edu.wpi.first.wpilibj.networktables.NetworkTable;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
/**
* @author jonathanleitschuh
*
*/
public class PrefrencesTest extends AbstractCommandTest {
public class PrefrencesTest extends AbstractComsSetup {
private static final Logger logger = Logger.getLogger(PrefrencesTest.class.getName());
private NetworkTable prefTable;
private Preferences pref;
private long check;
@Override
protected Logger getClassLogger(){
return logger;
}
/**
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
/**
* @throws java.lang.Exception
@@ -77,13 +64,7 @@ public class PrefrencesTest extends AbstractCommandTest {
check = System.currentTimeMillis();
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
public void remove() {
pref.remove("checkedValueLong");
pref.remove("checkedValueDouble");
@@ -101,7 +82,7 @@ public class PrefrencesTest extends AbstractCommandTest {
pref.putFloat("checkedValueFloat", 1);
pref.putBoolean("checkedValueBoolean", true);
}
@Test
public void testAddRemoveSave() {
assertEquals(pref.getLong("checkedValueLong", 0), 172L);

View File

@@ -13,26 +13,26 @@ import org.junit.runners.Suite.SuiteClasses;
import edu.wpi.first.wpilibj.test.AbstractTestSuite;
/**
* @author jonathanleitschuh
* Holds all of the tests in the roor wpilibj directory
* @author Jonathan Leitschuh
* Holds all of the tests in the root wpilibj directory
* Please list alphabetically so that it is easy to determine if a test is missing from the list
*/
@RunWith(Suite.class)
@SuiteClasses({
BuiltInAccelerometerTest.class,
AnalogCrossConnectTest.class,
AnalogPotentiometerTest.class,
BuiltInAccelerometerTest.class,
CounterTest.class,
DIOCrossConnectTest.class,
EncoderTest.class,
GyroTest.class,
MotorEncoderTest.class,
PCMTest.class,
PIDTest.class,
PDPTest.class,
PIDTest.class,
PrefrencesTest.class,
RelayCrossConnectTest.class,
SampleTest.class,
GyroTest.class,
TimerTest.class
})
public class WpiLibJTestSuite extends AbstractTestSuite {

View File

@@ -52,6 +52,11 @@ public class DIOCrossConnectFixture implements ITestFixture {
@Override
public boolean reset() {
try{
input.cancelInterrupts();
} catch(IllegalStateException e) {
//This will happen if the interrupt has not been allocated for this test.
}
output.set(false);
return true;
}

View File

@@ -1,8 +1,8 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Copyright (c) FIRST 2008-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 the root directory of */
/* the project. */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.test;
@@ -27,7 +27,6 @@ import org.junit.runners.model.InitializationError;
public abstract class AbstractTestSuite {
private static final Logger logger = Logger.getLogger(AbstractTestSuite.class.getName());
/**
* Gets all of the classes listed within the SuiteClasses annotation. To use it, annotate a class
* with <code>@RunWith(Suite.class)</code> and <code>@SuiteClasses({TestClass1.class, ...})</code>.
@@ -38,13 +37,13 @@ public abstract class AbstractTestSuite {
protected List<Class<?>> getAnnotatedTestClasses(){
SuiteClasses annotation = getClass().getAnnotation(SuiteClasses.class);
List<Class<?>> classes = new Vector<Class<?>>();
if (annotation == null) {
throw new RuntimeException(String.format("class '%s' must have a SuiteClasses annotation", getClass().getName()));
}
for(Class<?> c : annotation.value()){
classes.add(c);
}
return classes;
if (annotation == null) {
throw new RuntimeException(String.format("class '%s' must have a SuiteClasses annotation", getClass().getName()));
}
for(Class<?> c : annotation.value()){
classes.add(c);
}
return classes;
}
/**
@@ -135,7 +134,7 @@ public abstract class AbstractTestSuite {
* Gets all of the test classes listed in this suite. Does not include any of the test suites. All of these classes contain tests.
* @return The list of base test classes.
*/
protected List<Class<?>> getAllContainedBaseTests(){
public List<Class<?>> getAllContainedBaseTests(){
List<Class<?>> runningBaseTests = new Vector <Class<?>>();
return getAllContainedBaseTests(runningBaseTests);
}
@@ -161,7 +160,7 @@ public abstract class AbstractTestSuite {
* @param regex the text pattern to retrieve.
* @return The list of classes matching the regex pattern
*/
protected List<Class<?>> getAllClassMatching(final String regex){
public List<Class<?>> getAllClassMatching(final String regex){
final List<Class<?>> matchingClasses = new Vector<Class<?>>();
return getAllClassMatching(regex, matchingClasses);
}

View File

@@ -0,0 +1,89 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-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 the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.test;
import java.io.File;
import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.optional.junit.FormatterElement;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest;
/**
* Provides an entry point for tests to run with ANT. This allows ant to output
* JUnit XML test results for Jenkins.
*
* @author jonathanleitschuh
*
*/
public class AntJunitLanucher {
public static void main(String... args) {
if (args.length == 0) {
String path = String.format("%s/%s",
System.getProperty("user.dir"), "/testResults/AntReports");
String pathToReports = path;
Project project = new Project();
try {
// Create the file to store the test output
new File(pathToReports).mkdirs();
JUnitTask task = new JUnitTask();
project.setProperty("java.io.tmpdir", pathToReports);
/* Output to screen */
FormatterElement.TypeAttribute typeScreen = new FormatterElement.TypeAttribute();
typeScreen.setValue("plain");
FormatterElement formatToScreen = new FormatterElement();
formatToScreen.setType(typeScreen);
formatToScreen.setUseFile(false);
formatToScreen.setOutput(System.out);
task.addFormatter(formatToScreen);
// add a build listener to the project
BuildLogger logger = new DefaultLogger();
logger.setOutputPrintStream(System.out);
logger.setErrorPrintStream(System.err);
logger.setMessageOutputLevel(Project.MSG_INFO);
logger.setEmacsMode(true);
project.addBuildListener(logger);
task.setProject(project);
// Set the output to the XML file
FormatterElement.TypeAttribute type = new FormatterElement.TypeAttribute();
type.setValue("xml");
FormatterElement formater = new FormatterElement();
formater.setType(type);
task.addFormatter(formater);
// Create the JUnitTest
JUnitTest test = new JUnitTest(TestSuite.class.getName());
test.setTodir(new File(pathToReports));
task.addTest(test);
TestBench.out().println("Beginning Test Execution With ANT");
task.execute();
} catch (Exception e) {
e.printStackTrace();
}
} else {
TestBench.out().println(
"Run will not output XML for Jenkins because "
+ "tests are not being run with ANT");
// This should never return as it makes its own call to
// System.exit();
TestSuite.main(args);
}
System.exit(0);
}
}

View File

@@ -46,7 +46,7 @@ public final class TestBench {
* The time that it takes to have a motor go from rotating at full speed to
* completely stopped
*/
public static final double MOTOR_STOP_TIME = 0.20;
public static final double MOTOR_STOP_TIME = 0.25;
public static final int kTalonChannel = 10;
public static final int kVictorChannel = 1;

View File

@@ -16,6 +16,7 @@ import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import junit.framework.JUnit4TestAdapter;
import junit.runner.Version;
import org.junit.runner.JUnitCore;
@@ -73,6 +74,20 @@ public class TestSuite extends AbstractTestSuite {
private static final String METHOD_REPEAT_FILTER = "--repeat=";
private static final String CLASS_NAME_FILTER = "--filter=";
private static TestSuite instance = null;
public static TestSuite getInstance(){
if(instance == null){
instance = new TestSuite();
}
return instance;
}
/**
* This has to be public so that the JUnit4
*/
public TestSuite(){}
/**
* Displays a help message for the user when they use the --help flag at runtime.
*/
@@ -180,50 +195,50 @@ public class TestSuite extends AbstractTestSuite {
return JUnitCore.runClasses(QUICK_TEST);
}
/**
* Stores the data from multiple {@link Result}s in one class that can be returned to display the results.
*/
class MultipleResult extends Result{
private static final long serialVersionUID = 1L;
private final List<Failure> failures = new Vector<Failure>();
private int runCount = 0;
private int ignoreCount = 0;
private long runTime = 0;
@Override
public int getRunCount() {
return runCount;
}
@Override
public int getFailureCount() {
return failures.size();
}
@Override
public long getRunTime() {
return runTime;
}
@Override
public List<Failure> getFailures() {
return failures;
}
@Override
public int getIgnoreCount() {
return ignoreCount;
}
/**
* Adds the given result's data to this result
* @param r the result to add to this result
*/
void addResult(Result r){
failures.addAll(r.getFailures());
runCount += r.getRunCount();
ignoreCount += r.getIgnoreCount();
runTime += r.getRunTime();
}
}
//If a specific method has been requested
if(methodFilter){
/**
* Stores the data from multiple {@link Result}s in one class that can be returned to display the results.
*/
class MultipleResult extends Result{
private static final long serialVersionUID = 1L;
private final List<Failure> failures = new Vector<Failure>();
private int runCount = 0;
private int ignoreCount = 0;
private long runTime = 0;
@Override
public int getRunCount() {
return runCount;
}
@Override
public int getFailureCount() {
return failures.size();
}
@Override
public long getRunTime() {
return runTime;
}
@Override
public List<Failure> getFailures() {
return failures;
}
@Override
public int getIgnoreCount() {
return ignoreCount;
}
/**
* Adds the given result's data to this result
* @param r the result to add to this result
*/
void addResult(Result r){
failures.addAll(r.getFailures());
runCount += r.getRunCount();
ignoreCount += r.getIgnoreCount();
runTime += r.getRunTime();
}
}
List<ClassMethodPair> pairs = (new TestSuite()).getMethodMatching(methodRegex);
if(pairs.size() == 0){
displayInvalidUsage("None of the arguments passed to the method name filter matched.", args);
@@ -265,10 +280,17 @@ public class TestSuite extends AbstractTestSuite {
return null;
}
printLoadedTests(testClasses.toArray(new Class[0]));
return JUnitCore.runClasses(testClasses.toArray(new Class[0]));
MultipleResult results = new MultipleResult();
//Runs tests multiple times if the repeat rule is used
for(int i = 0; i < repeatCount; i++){
Result result = (new JUnitCore()).run(testClasses.toArray(new Class[0]));
//Store the given results in one cohesive result
results.addResult(result);
}
return results;
}
displayInvalidUsage("None of the parameters that you passed matched any of the accepted flags.", args);
return null;
}
@@ -309,9 +331,16 @@ public class TestSuite extends AbstractTestSuite {
}
TestBench.out().println();
}
/**
* This is used by ant to get the Junit tests. This is required because the tests try to load using a
* JUnit 3 framework. JUnit4 uses annotations to load tests. This method allows JUnit3 to load JUnit4 tests.
*/
public static junit.framework.Test suite(){
return new JUnit4TestAdapter(TestSuite.class);
}
/**
* The method called at runtime
* @param args The test suites to run

View File

@@ -3,6 +3,8 @@
#include "Log.hpp"
#include "edu_wpi_first_wpilibj_hal_HALUtil.h"
#include "HAL/HAL.hpp"
#include "errno.h"
#include <string.h>
// set the logging level
TLogLevel halUtilLogLevel = logWARNING;
@@ -145,3 +147,27 @@ JNIEXPORT jstring JNICALL Java_edu_wpi_first_wpilibj_hal_HALUtil_getHALErrorMess
HALUTIL_LOG(logDEBUG) << "Calling HALUtil getHALErrorMessage id=" << paramId << " msg=" << msg;
return paramEnv->NewStringUTF(msg);
}
/*
* Class: edu_wpi_first_wpilibj_hal_HALUtil
* Method: getHALErrno
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_hal_HALUtil_getHALErrno
(JNIEnv *, jclass)
{
return errno;
}
/*
* Class: edu_wpi_first_wpilibj_hal_HALUtil
* Method: getHALstrerror
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_edu_wpi_first_wpilibj_hal_HALUtil_getHALstrerror
(JNIEnv * env, jclass, jint errorCode)
{
const char * msg = strerror(errno);
HALUTIL_LOG(logDEBUG) << "Calling HALUtil getHALstrerror errorCode=" << errorCode << " msg=" << msg;
return env->NewStringUTF(msg);
}

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