Compare commits

...

45 Commits

Author SHA1 Message Date
Fred Silberberg
4e12ffb0ae Update the wpilib version plugin (#423) 2016-12-25 23:01:03 -08:00
Peter Johnson
4800c201e4 Add Axis camera creation functions and Http camera NT publishing. (#420) 2016-12-24 21:05:08 -06:00
Thad House
dc9a9e5d96 Fixes typo in SensorBase error message (#422) 2016-12-24 21:04:32 -06:00
Thad House
6844f05c3d Adds SetAllSolenoids function to CTRE PCM code (#419)
Closes #417.
2016-12-23 14:35:45 -06:00
Austin Shalit
8f67f2c24c Remove unused code and add pmd check (#395) 2016-12-23 13:20:13 -06:00
Thad House
cc246bb9ac Switches JNI to use new jni_util methods (#404)
* Uses WPIUtil string objects in JNI

* Switches JNI to use new jni_util classes
2016-12-23 13:13:17 -06:00
Sam Carlberg
bf9f0a9e6d Add vision pipeline API to make it easier to run OpenCV pipelines (#388) 2016-12-23 10:48:56 -06:00
Austin Shalit
c3160bad44 Update SendableChooser to use HashMap (#394) 2016-12-22 15:56:23 -08:00
Thad House
94b8ac42ca Adds CPP version of vision pipeline (#399) 2016-12-21 23:58:42 -06:00
Thad House
a03e3d7eb9 Fixes HAL to build without all headers included in HAL.h (#418) 2016-12-21 23:55:31 -06:00
Jaci R
a42ec08d16 Fix RoboRIO Cross-Toolchain GCC Status (#405)
* Dedicated RoboRIO Toolchain, allow Toolchain Path to change

* Add cCompiler Tool to correctly discover RoboRIO GCC on Mac

* Add @333fred requests for GString and ToolChainPath

* Add Toolchain Path option to README
2016-12-21 19:56:28 -08:00
Thad House
fddb6cd9d8 Fixes SPI Accumulator averages (#415) 2016-12-21 20:17:53 -06:00
Thad House
841f016017 Fixes SerialHelper when used with OS serial ports. (#411)
Also makes the SerialHelper API public so it can be used externally.
2016-12-21 00:16:05 -06:00
Thad House
8e4afc95c7 Switches C++ strings to StringRef (#336) 2016-12-21 00:08:24 -06:00
Tyler Veness
8cec948699 Fix typos (#409) 2016-12-19 22:06:39 -06:00
Tyler Veness
31ae7c942c Fixed signatures of deleted assignment operators (#408)
While it technically doesn't matter what the return type of the assignment operator is since it's deleted, assignment operators should return a reference instead of a value.
2016-12-19 11:24:23 -08:00
Tyler Veness
d0900626da Removed format.py shim (#393)
Now that our formatter is a Python package (wpiformat), the format.py shim for invoking it is no longer necessary. styleguide#29 should be merged before this patch.
2016-12-18 19:46:20 -08:00
Peter Johnson
0ee4cadca0 CameraServer: Workaround LabVIEW dashboard OpenCV compatibility. (#406)
The current LabVIEW dashboard (Beta 4) requires the source type to be either
"usb:" or "ip:" and does not support "cv:".  To work around this, use a source
type of "usb:" for OpenCV sources as well.

Workaround for #407.
2016-12-18 13:36:44 -08:00
Thad House
24b5a9c389 Adds UsageReporting include when using the LabVIEW shim (#401) 2016-12-16 22:42:45 -08:00
Austin Shalit
626220e9f3 Fix javadoc typo (#403) 2016-12-15 19:46:42 -08:00
Thad House
323d68d460 Fixes multiple initialization of HAL_BaseInitialize (#400) 2016-12-13 12:31:44 -08:00
Thad House
db2091dd94 Adds safe serial port write methods (#396)
The old method had a fairly large risk of undefined behavior, and the way the docs
were written could cause users to get confused.
Deprecate the old method and add StringRef method as preferred approach.
2016-12-10 22:40:44 -08:00
Thad House
8216d85e52 Adds check for PWM overallocation (#392) 2016-12-09 21:23:54 -08:00
Austin Shalit
a705eb1c61 Add PMD and solve issues (#389) 2016-12-07 21:24:44 -08:00
Thad House
77f664a6b1 Fixes simulator HAL builds (#391) 2016-12-06 19:56:31 -08:00
Austin Shalit
c30057e923 Remove unused imports (#387) 2016-12-05 21:36:52 -08:00
Peter Johnson
06108b9479 Update CameraServer support. (#386)
* Follow MixedCase rename.

* Add GetVideo function to get cameras by name.
2016-12-04 00:26:08 -08:00
sciencewhiz
16181523c9 Put language in version string (#377) 2016-12-02 20:36:22 -08:00
Jacob Caporuscio
7e0706cf83 Updated Usage Reporting for 2017 v8 Image (#385) 2016-12-02 18:16:49 -08:00
Thad House
bff67887fd Adds capabilities to support certain HAL functionality from LabVIEW (#382)
They can only include HAL/LV/HAL.h, HAL/cpp/*.h, and HAL/handles/*.h.
Nothing else will work properly.
2016-12-02 00:32:01 -08:00
Thad House
351ff5eb48 Adds new Threads API for priority setting while using std::thread (#379)
Also adds Java API for doing the same to Java threads (standard Java Thread.setPriority only works
when Java is run as root, even if the process has the right privileges).
2016-12-01 21:06:19 -08:00
Thad House
051df14046 Updates ni patch task to automatically switch all files to LF (#381)
Still requires manual intervention to make files not readonly, but
that's easier.
2016-11-29 20:20:49 -08:00
Thad House
ee0318f697 Updates NI Libraries to image 8 (#380) 2016-11-29 19:56:30 -08:00
Thad House
a6fb1efcbe Switches internal joystick errors to take StringRef (#378)
Previously this would have allocated the std::string every time, even if
the message wasn't printed. Now takes a StringRef, and only converts to
std::string when the message actually gets printed.
2016-11-26 21:22:39 -08:00
sciencewhiz
31fecc28a4 Check for NaN motor speed. Fixes artf5467. (#376) 2016-11-26 21:04:40 -08:00
Thad House
30b1efc354 Adds check to ensure all JNI symbols have been defined properly (#373) 2016-11-25 17:07:36 -08:00
Thad House
7d721eb569 Fixes memory leak in SerialHelper VISA (#366) 2016-11-25 15:52:21 -08:00
Fred Silberberg
d48aac5beb Gradle Update (#372)
This does a major cleanup on our gradle files, primarily converting all instances of manual dependency downloading to use the correct configuration-based method, which has the advantage of being both less code and more safe.
2016-11-24 23:44:35 -08:00
Fred Silberberg
14b56db99e Gradle 3.2.1 (#369)
Updated to gradle 3.2.1. This also moves all of the task graph listeners for dependency setup to use the gradle model, making it both safer and reducing line count.
2016-11-24 22:15:54 -08:00
Thad House
bfe429de51 Switches handles back to std::array (#367)
The binary size is being increased much less then when we originally
tried this. Using static arrays save a pointer indirection and will help
with cache in real time cases.
2016-11-24 21:55:20 -08:00
Thad House
57ef5cfd07 Splits out SerialHelper to allow using OS or VISA resources (#365)
Also removes regex and uses simple splits instead
2016-11-24 21:53:04 -08:00
Fred Silberberg
4bbb7c0bcc Fixed javadoc generation to actually download cscore and ntcore and include the source in its output. (#368) 2016-11-24 21:51:01 -08:00
Thad House
4de70bff5e Adds missing JNI method definitions (#371) 2016-11-24 21:49:34 -08:00
Peter Johnson
687f0c7dc0 Use const parameters in std::sort lambda. (#364)
This is more correct, and non-const fails on gcc 4.8.
2016-11-22 22:30:58 -08:00
Thad House
f3d66e92ec Searches for USB serial devices to get the correct VISA object (#363)
Fix was made in LabVIEW, and this matches what was done there.
2016-11-22 21:51:47 -08:00
152 changed files with 2731 additions and 1073 deletions

View File

@@ -8,7 +8,8 @@ before_install:
- sudo add-apt-repository ppa:wpilib/toolchain -y
- sudo apt-get update -q || true
- sudo apt-get install frc-toolchain libgazebo7-dev protobuf-compiler libprotobuf-dev python3 clang-format-3.8 -y
install:
- pip3 install wpiformat
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
@@ -17,10 +18,7 @@ cache:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
before_script:
- git clone git://github.com/wpilibsuite/styleguide $HOME/styleguide
script:
- WPI_FORMAT=$HOME/styleguide python3 styleguide/format.py
- wpiformat
- git --no-pager diff --exit-code HEAD # Ensure formatter made no changes
- ./gradlew build -PmakeSim

View File

@@ -37,7 +37,7 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
## Coding Guidelines
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running format.py, which is in the styleguide directory, is required for all contributions and is enforced by our continuous integration system.
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.

View File

@@ -25,13 +25,13 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
- [ARM Compiler Toolchain](http://first.wpi.edu/FRC/roborio/toolchains/)
- Doxygen (Only required if you want to build the C++ documentation)
- [format.py](https://github.com/wpilibsuite/styleguide)
- [wpiformat](https://github.com/wpilibsuite/styleguide)
## Setup
Clone the WPILib repository. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for format.py setup instructions.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for wpiformat setup instructions.
## Building
@@ -47,6 +47,12 @@ To build a specific subproject, such as WPILibC, you must access the subproject
./gradlew :wpilibc:build
```
If you have installed the FRC Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
```bash
./gradlew build -PtoolChainPath=some/path/to/frc/toolchain/bin
```
If you also want simulation to be built, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of Gazebo should work, even on Windows if you build Gazebo from source. Correct means CMake needs to be able to find gazebo-config.cmake. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
```bash
@@ -67,7 +73,7 @@ The gradlew wrapper only exists in the root of the main project, so be sure to r
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
format.py can be executed in either the styleguide or root directories of the repository via `python3 format.py` or `./format.py`.
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
## Publishing

View File

@@ -1,23 +1,38 @@
plugins {
id 'net.ltgt.errorprone' version '0.0.8'
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '1.4'
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '1.6'
}
def enableSimulation = hasProperty('enableSimulation')
if (!hasProperty('repo')) {
ext.repo = 'development'
// Ensure that the WPILibVersioningPlugin is setup by setting the release type, if releaseType wasn't
// already specified on the command line
if (!hasProperty('releaseType')) {
WPILibVersion {
releaseType = 'dev'
}
}
def enableSimulation = hasProperty('makeSim')
ext.simulationInstallDir = "$rootDir/build/install/simulation"
allprojects {
ext.enableSimulation = enableSimulation
ext.repo = repo
repositories {
mavenCentral()
}
ext.ntcoreDep = { lang, classifier, extension = null ->
return "edu.wpi.first.wpilib.networktables.$lang:NetworkTables:+:$classifier${extension == null ? '' : '@' + extension}"
}
ext.cscoreDep = { lang, classifier, extension = null ->
return "edu.wpi.cscore.$lang:cscore:+:$classifier${extension == null ? '' : '@' + extension}"
}
ext.wpiUtilDep = { classifier ->
return "edu.wpi.first.wpilib:wpiutil:+:$classifier@zip"
}
}
subprojects {
@@ -50,5 +65,5 @@ apply from: 'cppSettings.gradle'
apply from: 'ni-libraries/ni-libraries.gradle'
task wrapper(type: Wrapper) {
gradleVersion = '3.0'
gradleVersion = '3.2.1'
}

View File

@@ -2,173 +2,69 @@
def niLibraryPath = file('ni-libraries/lib').path
def niLibrary = niLibraryPath + "/libnilibraries.so"
task downloadArmNetworkTables() {
description = 'Downloads the C++ ARM NetworkTables maven dependency.'
group = 'WPILib'
def depFolder = "$buildDir/dependencies"
def ntZip = file("$depFolder/ntcore-arm.zip")
outputs.file(ntZip)
def armNetTables
configurations.create('armDeps')
doFirst {
def armNtDependency = project.dependencies.create('edu.wpi.first.wpilib.networktables.cpp:NetworkTables:+:arm@zip')
def armConfig = project.configurations.detachedConfiguration(armNtDependency)
armConfig.setTransitive(false)
armNetTables = armConfig.files[0].canonicalFile
}
dependencies {
armDeps ntcoreDep('cpp', 'arm', 'zip')
armDeps wpiUtilDep('arm')
armDeps cscoreDep('cpp', 'athena-uberzip', 'zip')
}
doLast {
copy {
from armNetTables
rename 'NetworkTables(.+)', 'ntcore-arm.zip'
into depFolder
}
def depLocation = "$buildDir/dependencies"
configurations.armDeps.files.each { file ->
def depName = file.name.substring(0, file.name.indexOf('-'))
def t = tasks.create("downloadArm${depName.capitalize()}", Copy) {
description = "Downloads and unzips the $depName dependency."
group = 'Dependencies'
from zipTree(file)
into "$depLocation/${depName.toLowerCase()}"
}
}
if (project.hasProperty('makeSim')) {
task downloadDesktopNetworkTables() {
description = 'Downloads the C++ Desktop NetworkTables maven dependency.'
group = 'WPILib'
def depFolder = "$buildDir/dependencies"
def ntZip = file("$depFolder/ntcore-desk.zip")
outputs.file(ntZip)
def desktopNetTables
doFirst {
def desktopNtDependency = project.dependencies.create("edu.wpi.first.wpilib.networktables.cpp:NetworkTables:+:desktop@zip")
def desktopConfig = project.configurations.detachedConfiguration(desktopNtDependency)
desktopConfig.setTransitive(false)
desktopNetTables = desktopConfig.files[0].canonicalFile
}
doLast {
copy {
from desktopNetTables
rename 'NetworkTables(.+)', 'ntcore-desk.zip'
into depFolder
}
}
}
}
def netTablesUnzipLocation = "$buildDir/networktables"
// Create a task that will unzip the networktables files into a temporary build directory
task unzipNetworkTables(type: Copy) {
description = 'Unzips the networktables maven dependency so that the include files and libraries can be used'
group = 'WPILib'
task downloadNetworkTables {
description = 'Downloads all needed versions of networktables.'
group = 'Dependencies'
dependsOn downloadArmNetworkTables
if (project.hasProperty('makeSim')) {
dependsOn downloadDesktopNetworkTables
from zipTree(downloadDesktopNetworkTables.outputs.files.singleFile)
}
from zipTree(downloadArmNetworkTables.outputs.files.singleFile)
into netTablesUnzipLocation
}
task downloadArmWpiUtil() {
description = 'Downloads the C++ ARM wpiutil maven dependency.'
group = 'WPILib'
def depFolder = "$buildDir/dependencies"
def utilZip = file("$depFolder/wpiutil-arm.zip")
outputs.file(utilZip)
def armWpiUtil
task downloadWpiutil {
description = 'Downloads all needed versions of WPIUtil.'
group = 'Dependencies'
dependsOn downloadArmWpiutil
}
doFirst {
def armWpiUtilDependency = project.dependencies.create("edu.wpi.first.wpilib:wpiutil:+:arm@zip")
def armWpiUtilConfig = project.configurations.detachedConfiguration(armWpiUtilDependency)
armWpiUtilConfig.setTransitive(false)
armWpiUtil = armWpiUtilConfig.files[0].canonicalFile
task downloadCscore {
description = 'Downloads all needed versions of cscore.'
group = 'Dependencies'
dependsOn downloadArmCscore
}
if (enableSimulation) {
configurations.create('nativeDeps')
dependencies {
nativeDeps ntcoreDep('cpp', 'desktop', 'zip')
nativeDeps wpiUtilDep('desktop')
}
doLast {
copy {
from armWpiUtil
rename 'wpiutil(.+)', 'wpiutil-arm.zip'
into depFolder
configurations.nativeDeps.files.each { file ->
def depName = file.name.substring(0, file.name.indexOf('-'))
def t = tasks.create("downloadNative${depName.capitalize()}", Copy) {
description = "Downloads and unzips the $depName dependency."
group = 'Dependencies'
from zipTree(file)
into "$depLocation/${depName.toLowerCase()}"
}
}
downloadNetworkTables.dependsOn downloadNativeNetworkTables
downloadWpiutil.dependsOn downloadNativeWpiutil
}
if (project.hasProperty('makeSim')) {
task downloadDesktopWpiUtil() {
description = 'Downloads the C++ Desktop wpiutil maven dependency.'
group = 'WPILib'
def depFolder = "$buildDir/dependencies"
def wpiutilZip = file("$depFolder/wpiutil-desk.zip")
outputs.file(wpiutilZip)
def wpiUtil
doFirst {
def desktopWpiUtilDependency = project.dependencies.create("edu.wpi.first.wpilib:wpiutil:+:desktop@zip")
def desktopWpiUtilConfig = project.configurations.detachedConfiguration(desktopWpiUtilDependency)
desktopWpiUtilConfig.setTransitive(false)
wpiUtil = desktopWpiUtilConfig.files[0].canonicalFile
}
doLast {
copy {
from wpiUtil
rename 'wpiutil(.+)', 'wpiutil-desk.zip'
into depFolder
}
}
}
}
def wpiUtilUnzipLocation = "$buildDir/wpiutil"
// Create a task that will unzip the wpiutil files into a temporary build directory
task unzipWpiUtil(type: Copy) {
description = 'Unzips the wpiutil maven dependency so that the include files and libraries can be used'
group = 'WPILib'
dependsOn downloadArmWpiUtil
if (project.hasProperty('makeSim')) {
dependsOn downloadDesktopWpiUtil
from zipTree(downloadDesktopWpiUtil.outputs.files.singleFile)
}
from zipTree(downloadArmWpiUtil.outputs.files.singleFile)
into wpiUtilUnzipLocation
}
task downloadArmCsCore() {
description = 'Downloads the C++ ARM CsCore Uberzip maven dependency.'
group = 'WPILib'
def depFolder = "$buildDir/dependencies"
def csZip = file("$depFolder/cscore-arm.zip")
outputs.file(csZip)
def armCsCore
doFirst {
def armCsDependency = project.dependencies.create('edu.wpi.cscore.cpp:cscore:+:athena-uberzip@zip')
def armConfig = project.configurations.detachedConfiguration(armCsDependency)
armConfig.setTransitive(false)
armCsCore = armConfig.files[0].canonicalFile
}
doLast {
copy {
from armCsCore
rename 'cscore(.+)', 'cscore-arm.zip'
into depFolder
}
}
}
def csCoreUnzipLocation = "$buildDir/cscore"
// Create a task that will unzip the cscore files into a temporary build directory
task unzipCsCore(type: Copy) {
description = 'Unzips the cscore maven dependency so that the include files and libraries can be used'
group = 'WPILib'
dependsOn downloadArmCsCore
from zipTree(downloadArmCsCore.outputs.files.singleFile)
into csCoreUnzipLocation
}
def netTablesUnzipLocation = "$depLocation/networktables"
def wpiUtilUnzipLocation = "$depLocation/wpiutil"
def csCoreUnzipLocation = "$depLocation/cscore"
task clean(type: Delete) {
description = "Deletes the build directory"
@@ -176,12 +72,16 @@ task clean(type: Delete) {
delete buildDir
}
if (!hasProperty("toolChainPath")) {
ext.toolChainPath = null
}
subprojects {
ext.defineWpiUtilProperties = {
ext.wpiUtil = wpiUtilUnzipLocation
ext.wpiUtilInclude = "$wpiUtilUnzipLocation/include"
ext.wpiUtilLibArmLocation = "$wpiUtilUnzipLocation/Linux/arm"
if (project.hasProperty('makeSim')) {
if (enableSimulation) {
ext.wpiUtilLibDesktopLocation = "$wpiUtilUnzipLocation/Linux/amd64"
}
ext.wpiUtilSharedLib = "$wpiUtilLibArmLocation/libwpiutil.so"
@@ -189,7 +89,7 @@ subprojects {
ext.wpiUtilStaticLib = "$wpiUtilLibArmLocation/libwpiutil.a"
ext.addWpiUtilLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').unzipWpiUtil
compileTask.dependsOn project(':').downloadWpiutil
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args wpiUtilSharedLib
@@ -197,7 +97,7 @@ subprojects {
}
ext.addStaticWpiUtilLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').unzipWpiUtil
compileTask.dependsOn project(':').downloadWpiutil
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args wpiUtilStaticLib
@@ -210,7 +110,7 @@ subprojects {
ext.netTables = netTablesUnzipLocation
ext.netTablesInclude = "$netTablesUnzipLocation/include"
ext.netLibArmLocation = "$netTablesUnzipLocation/Linux/arm"
if (project.hasProperty('makeSim')) {
if (enableSimulation) {
ext.netLibDesktopLocation = "$netTablesUnzipLocation/Linux/amd64"
}
ext.netSharedLib = "$netLibArmLocation/libntcore.so"
@@ -218,7 +118,7 @@ subprojects {
ext.netStaticLib = "$netLibArmLocation/libntcore.a"
ext.addNetworkTablesLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').unzipNetworkTables
compileTask.dependsOn project(':').downloadNetworkTables
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args netSharedLib
@@ -227,7 +127,7 @@ subprojects {
}
ext.addStaticNetworkTablesLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').unzipNetworkTables
compileTask.dependsOn project(':').downloadNetworkTables
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args netStaticLib
@@ -245,7 +145,7 @@ subprojects {
ext.cvSharedLib = "$csLibArmLocation/libopencv.so"
ext.addCsCoreLibraryLinks = { compileTask, linker, targetPlatform ->
compileTask.dependsOn project(':').unzipCsCore
compileTask.dependsOn project(':').downloadCscore
String architecture = targetPlatform.architecture
if (architecture.contains('arm')) {
linker.args << '-L' + csLibArmLocation
@@ -255,18 +155,25 @@ subprojects {
}
}
plugins.withType(CppPlugin).whenPluginAdded {
ext.defineCrossCompilerProperties = {
// We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
// If this ever changes, the prefix will need to be changed here
def compilerPrefix = 'arm-frc-linux-gnueabi-'
ext.compilerPrefix = 'arm-frc-linux-gnueabi-'
}
plugins.withType(CppPlugin).whenPluginAdded {
defineCrossCompilerProperties()
model {
buildTypes {
debug
}
// Adds a custom toolchain for our compiler prefix and options
toolChains {
gcc(Gcc) {
target('arm') {
roborioGcc(Gcc) {
if (toolChainPath != null)
path toolChainPath
target('roborio-arm') {
cCompiler.executable = compilerPrefix + cCompiler.executable
cppCompiler.executable = compilerPrefix + cppCompiler.executable
linker.executable = compilerPrefix + linker.executable
assembler.executable = compilerPrefix + assembler.executable
@@ -288,37 +195,10 @@ subprojects {
staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable
}
}
// Workaround for OS X. Macs for some reason want to use Xcode's gcc
// (which just wraps Clang), so we have to explicitly make it so
// that trying to compile with Clang will call gcc instead
macGcc(Clang) {
target('arm') {
cppCompiler.executable = compilerPrefix + 'g++'
linker.executable = compilerPrefix + 'g++'
assembler.executable = compilerPrefix + 'gcc'
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
// arm, and doesn't understand this flag, so it is removed from both
cppCompiler.withArguments { args ->
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-Og' << '-g3' << '-rdynamic'
//TODO: When the compiler allows us to actually call deprecated functions from within
// deprecated function, remove this line (this will cause calling deprecated functions
// to be treated as a warning rather than an error).
args << '-Wno-error=deprecated-declarations'
args.remove('-m32')
}
linker.withArguments { args ->
args << '-rdynamic'
args.remove('-m32')
}
staticLibArchiver.executable = compilerPrefix + 'ar'
}
}
}
// The only platform is arm linux
platforms {
arm {
'roborio-arm' {
architecture 'arm'
operatingSystem 'linux'
}
@@ -328,6 +208,11 @@ subprojects {
ext.niLibraryHeadersRoot = "${rootDir}/ni-libraries/include"
ext.niLibraryHeadersChipObject = "${rootDir}/ni-libraries/include/FRC_FPGA_ChipObject"
ext.binTool = { tool ->
if (toolChainPath != null) return "${toolChainPath}/${compilerPrefix}${tool}"
return "${compilerPrefix}${tool}"
}
// This task adds the appropriate linker flags for the NI libraries
ext.addNiLibraryLinks = { linker, targetPlatform ->
String architecture = targetPlatform.architecture
@@ -346,9 +231,9 @@ subprojects {
def library = task.outputFile.absolutePath
def debugLibrary = task.outputFile.absolutePath + ".debug"
task.doLast {
exec { commandLine "${compilerPrefix}objcopy", '--only-keep-debug', library, debugLibrary }
exec { commandLine "${compilerPrefix}strip", '-g', library }
exec { commandLine "${compilerPrefix}objcopy", "--add-gnu-debuglink=$debugLibrary", library }
exec { commandLine binTool('objcopy'), '--only-keep-debug', library, debugLibrary }
exec { commandLine binTool('strip'), '-g', library }
exec { commandLine binTool('objcopy'), "--add-gnu-debuglink=$debugLibrary", library }
}
}
}

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Mon Aug 22 20:26:07 PDT 2016
#Thu Nov 24 12:34:01 EST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip

19
gradlew vendored
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
##############################################################################
##
@@ -154,16 +154,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save ( ) {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
exec "$JAVACMD" "$@"

View File

@@ -14,7 +14,7 @@ debugStripSetup(project)
model {
components {
HALAthena(NativeLibrarySpec) {
targetPlatform 'arm'
targetPlatform 'roborio-arm'
binaries.all {
tasks.withType(CppCompile) {
addNiLibraryLinks(linker, targetPlatform)
@@ -33,26 +33,10 @@ model {
}
}
}
// HALSim(NativeLibrarySpec) {
// binaries.all {
// if (toolChain in Gcc){
// cppCompiler.args "-std=c++1y"
// }
// }
//
// sources {
// cpp {
// source {
// srcDirs = ["lib/sim", "lib/shared"]
// includes = ["**/*.cpp"]
// }
// exportedHeaders {
// srcDirs = ["include", "lib/sim", "lib/shared"]
// }
// }
// }
// }
}
tasks { tasks ->
tasks.halZip.dependsOn tasks.HALAthenaSharedLibrary
tasks.athenaRuntimeZip.dependsOn tasks.HALAthenaSharedLibrary
}
}
@@ -96,13 +80,6 @@ task halZip(type: Zip) {
exclude 'genlinks.bat'
exclude 'libwpi.so'
}
// Add the hal static and shared libraries as a dependency
project(':hal').tasks.whenTaskAdded { task ->
if (task.name.toLowerCase() == 'halathenastaticlibrary' || task.name.toLowerCase() == 'halathenasharedlibrary') {
halZip.dependsOn task
}
}
}
task athenaRuntimeZip(type: Zip) {
@@ -134,7 +111,7 @@ task athenaRuntimeZip(type: Zip) {
}
defineNetworkTablesProperties()
dependsOn project(':').unzipNetworkTables
dependsOn project(':').downloadNetworkTables
from(project.file(netTablesInclude)) {
into 'include'
@@ -155,13 +132,6 @@ task athenaRuntimeZip(type: Zip) {
from (file(wpiUtilSharedLibDebug)) {
into 'lib'
}
// Add the hal static and shared libraries as a dependency
project(':hal').tasks.whenTaskAdded { task ->
if (task.name.toLowerCase() == 'halathenastaticlibrary' || task.name.toLowerCase() == 'halathenasharedlibrary') {
athenaRuntimeZip.dependsOn task
}
}
}

View File

@@ -104,6 +104,8 @@ int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble);
double HAL_GetMatchTime(int32_t* status);
#ifndef HAL_USE_LABVIEW
void HAL_WaitForDSData(void);
void HAL_InitializeDriverStation(void);
@@ -112,6 +114,9 @@ void HAL_ObserveUserProgramDisabled(void);
void HAL_ObserveUserProgramAutonomous(void);
void HAL_ObserveUserProgramTeleop(void);
void HAL_ObserveUserProgramTest(void);
#endif // HAL_USE_LABVIEW
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -83,6 +83,18 @@
#define HAL_HANDLE_ERROR_MESSAGE \
"HAL: A handle parameter was passed incorrectly"
#define HAL_SERIAL_PORT_NOT_FOUND -1123
#define HAL_SERIAL_PORT_NOT_FOUND_MESSAGE \
"HAL: The specified serial port device was not found";
#define HAL_THREAD_PRIORITY_ERROR -1152
#define HAL_THREAD_PRIORITY_ERROR_MESSAGE \
"HAL: Getting or setting the priority of a thread has failed";
#define HAL_THREAD_PRIORITY_RANGE_ERROR -1153
#define HAL_THREAD_PRIORITY_RANGE_ERROR_MESSAGE \
"HAL: The priority requested to be set is invalid"
#define VI_ERROR_SYSTEM_ERROR_MESSAGE "HAL - VISA: System Error";
#define VI_ERROR_INV_OBJECT_MESSAGE "HAL - VISA: Invalid Object"
#define VI_ERROR_RSRC_LOCKED_MESSAGE "HAL - VISA: Resource Locked"

View File

@@ -9,7 +9,8 @@
#include <stdint.h>
#include "FRC_NetworkCommunication/UsageReporting.h"
#ifndef HAL_USE_LABVIEW
#include "HAL/Accelerometer.h"
#include "HAL/AnalogAccumulator.h"
#include "HAL/AnalogGyro.h"
@@ -33,6 +34,10 @@
#include "HAL/SPI.h"
#include "HAL/SerialPort.h"
#include "HAL/Solenoid.h"
#endif // HAL_USE_LABVIEW
#include "FRC_NetworkCommunication/UsageReporting.h"
#include "HAL/Types.h"
namespace HALUsageReporting = nUsageReporting;
@@ -42,13 +47,11 @@ enum HAL_RuntimeType : int32_t { HAL_Athena, HAL_Mock };
#ifdef __cplusplus
extern "C" {
#endif
HAL_PortHandle HAL_GetPort(int32_t channel);
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel);
const char* HAL_GetErrorMessage(int32_t code);
int32_t HAL_GetFPGAVersion(int32_t* status);
int64_t HAL_GetFPGARevision(int32_t* status);
uint64_t HAL_GetFPGATime(int32_t* status);
HAL_RuntimeType HAL_GetRuntimeType();
HAL_Bool HAL_GetFPGAButton(int32_t* status);
@@ -56,6 +59,15 @@ HAL_Bool HAL_GetFPGAButton(int32_t* status);
HAL_Bool HAL_GetSystemActive(int32_t* status);
HAL_Bool HAL_GetBrownedOut(int32_t* status);
void HAL_BaseInitialize(int32_t* status);
#ifndef HAL_USE_LABVIEW
HAL_PortHandle HAL_GetPort(int32_t channel);
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel);
uint64_t HAL_GetFPGATime(int32_t* status);
int32_t HAL_Initialize(int32_t mode);
// ifdef's definition is to allow for default parameters in C++.
@@ -66,6 +78,8 @@ int64_t HAL_Report(int32_t resource, int32_t instanceNumber,
int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
const char* feature);
#endif
#endif // HAL_USE_LABVIEW
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,14 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#pragma once
#define HAL_USE_LABVIEW
#include "HAL/DriverStation.h"
#include "HAL/HAL.h"
#include "HAL/Types.h"

View File

@@ -9,31 +9,42 @@
#include <stdint.h>
enum HAL_SerialPort : int32_t {
HAL_SerialPort_Onboard = 0,
HAL_SerialPort_MXP = 1,
HAL_SerialPort_USB1 = 2,
HAL_SerialPort_USB2 = 3
};
#ifdef __cplusplus
extern "C" {
#endif
void HAL_InitializeSerialPort(int32_t port, int32_t* status);
void HAL_SetSerialBaudRate(int32_t port, int32_t baud, int32_t* status);
void HAL_SetSerialDataBits(int32_t port, int32_t bits, int32_t* status);
void HAL_SetSerialParity(int32_t port, int32_t parity, int32_t* status);
void HAL_SetSerialStopBits(int32_t port, int32_t stopBits, int32_t* status);
void HAL_SetSerialWriteMode(int32_t port, int32_t mode, int32_t* status);
void HAL_SetSerialFlowControl(int32_t port, int32_t flow, int32_t* status);
void HAL_SetSerialTimeout(int32_t port, double timeout, int32_t* status);
void HAL_EnableSerialTermination(int32_t port, char terminator,
void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status);
void HAL_SetSerialBaudRate(HAL_SerialPort port, int32_t baud, int32_t* status);
void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status);
void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status);
void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits,
int32_t* status);
void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode, int32_t* status);
void HAL_SetSerialFlowControl(HAL_SerialPort port, int32_t flow,
int32_t* status);
void HAL_SetSerialTimeout(HAL_SerialPort port, double timeout, int32_t* status);
void HAL_EnableSerialTermination(HAL_SerialPort port, char terminator,
int32_t* status);
void HAL_DisableSerialTermination(int32_t port, int32_t* status);
void HAL_SetSerialReadBufferSize(int32_t port, int32_t size, int32_t* status);
void HAL_SetSerialWriteBufferSize(int32_t port, int32_t size, int32_t* status);
int32_t HAL_GetSerialBytesReceived(int32_t port, int32_t* status);
int32_t HAL_ReadSerial(int32_t port, char* buffer, int32_t count,
void HAL_DisableSerialTermination(HAL_SerialPort port, int32_t* status);
void HAL_SetSerialReadBufferSize(HAL_SerialPort port, int32_t size,
int32_t* status);
void HAL_SetSerialWriteBufferSize(HAL_SerialPort port, int32_t size,
int32_t* status);
int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status);
int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count,
int32_t* status);
int32_t HAL_WriteSerial(int32_t port, const char* buffer, int32_t count,
int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count,
int32_t* status);
void HAL_FlushSerial(int32_t port, int32_t* status);
void HAL_ClearSerial(int32_t port, int32_t* status);
void HAL_CloseSerial(int32_t port, int32_t* status);
void HAL_FlushSerial(HAL_SerialPort port, int32_t* status);
void HAL_ClearSerial(HAL_SerialPort port, int32_t* status);
void HAL_CloseSerial(HAL_SerialPort port, int32_t* status);
#ifdef __cplusplus
}
#endif

View File

@@ -25,6 +25,7 @@ HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status);
void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
int32_t* status);
void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status);
int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status);
HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status);
HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status);

26
hal/include/HAL/Threads.h Normal file
View File

@@ -0,0 +1,26 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "HAL/Types.h"
#ifdef _WIN32
#include <windows.h>
#define NativeThreadHandle const HANDLE*
#else
#include <pthread.h>
#define NativeThreadHandle const pthread_t*
#endif
int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
int32_t* status);
int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status);
HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
int32_t priority, int32_t* status);
HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
int32_t* status);

View File

@@ -0,0 +1,51 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <stdint.h>
#include <string>
#include <vector>
#include "HAL/SerialPort.h"
#include "HAL/cpp/priority_mutex.h"
#include "llvm/SmallString.h"
#include "llvm/SmallVector.h"
namespace hal {
class SerialHelper {
public:
SerialHelper();
std::string GetVISASerialPortName(HAL_SerialPort port, int32_t* status);
std::string GetOSSerialPortName(HAL_SerialPort port, int32_t* status);
std::vector<std::string> GetVISASerialPortList(int32_t* status);
std::vector<std::string> GetOSSerialPortList(int32_t* status);
private:
void SortHubPathVector();
void CoiteratedSort(llvm::SmallVectorImpl<llvm::SmallString<16>>& vec);
void QueryHubPaths(int32_t* status);
int32_t GetIndexForPort(HAL_SerialPort port, int32_t* status);
// Vectors to hold data before sorting.
// Note we will most likely have at max 2 instances, and the longest string
// is around 12, so these should never touch the heap;
llvm::SmallVector<llvm::SmallString<16>, 4> m_visaResource;
llvm::SmallVector<llvm::SmallString<16>, 4> m_osResource;
llvm::SmallVector<llvm::SmallString<16>, 4> m_unsortedHubPath;
llvm::SmallVector<llvm::SmallString<16>, 4> m_sortedHubPath;
int32_t m_resourceHandle;
static priority_mutex m_nameMutex;
static std::string m_usbNames[2];
};
} // namespace hal

View File

@@ -10,7 +10,7 @@
// Allows usage with std::lock_guard without including <mutex> separately
#include <mutex>
#ifdef FRC_SIMULATOR
#if defined(FRC_SIMULATOR) || defined(_WIN32)
// We do not want to use pthreads if in the simulator; however, in the
// simulator, we do not care about priority inversion.
typedef std::mutex priority_mutex;

View File

@@ -9,8 +9,8 @@
#include <stdint.h>
#include <array>
#include <memory>
#include <vector>
#include "HAL/Errors.h"
#include "HAL/Types.h"
@@ -37,25 +37,19 @@ class DigitalHandleResource {
friend class DigitalHandleResourceTest;
public:
DigitalHandleResource() = default;
DigitalHandleResource(const DigitalHandleResource&) = delete;
DigitalHandleResource operator=(const DigitalHandleResource&) = delete;
DigitalHandleResource();
DigitalHandleResource& operator=(const DigitalHandleResource&) = delete;
THandle Allocate(int16_t index, HAL_HandleEnum enumValue, int32_t* status);
std::shared_ptr<TStruct> Get(THandle handle, HAL_HandleEnum enumValue);
void Free(THandle handle, HAL_HandleEnum enumValue);
private:
// Dynamic array to shrink HAL file size.
std::unique_ptr<std::shared_ptr<TStruct>[]> m_structures;
std::unique_ptr<priority_mutex[]> m_handleMutexes;
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<priority_mutex, size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size>
DigitalHandleResource<THandle, TStruct, size>::DigitalHandleResource() {
m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
m_handleMutexes = std::make_unique<priority_mutex[]>(size);
}
template <typename THandle, typename TStruct, int16_t size>
THandle DigitalHandleResource<THandle, TStruct, size>::Allocate(
int16_t index, HAL_HandleEnum enumValue, int32_t* status) {

View File

@@ -39,10 +39,11 @@ class IndexedClassedHandleResource {
friend class IndexedClassedHandleResourceTest;
public:
IndexedClassedHandleResource(const IndexedClassedHandleResource&) = delete;
IndexedClassedHandleResource operator=(const IndexedClassedHandleResource&) =
delete;
IndexedClassedHandleResource();
IndexedClassedHandleResource(const IndexedClassedHandleResource&) = delete;
IndexedClassedHandleResource& operator=(const IndexedClassedHandleResource&) =
delete;
THandle Allocate(int16_t index, std::shared_ptr<TStruct> toSet,
int32_t* status);
std::shared_ptr<TStruct> Get(THandle handle);

View File

@@ -9,8 +9,8 @@
#include <stdint.h>
#include <array>
#include <memory>
#include <vector>
#include "HAL/Errors.h"
#include "HAL/Types.h"
@@ -38,27 +38,19 @@ class IndexedHandleResource {
friend class IndexedHandleResourceTest;
public:
IndexedHandleResource() = default;
IndexedHandleResource(const IndexedHandleResource&) = delete;
IndexedHandleResource operator=(const IndexedHandleResource&) = delete;
IndexedHandleResource();
IndexedHandleResource& operator=(const IndexedHandleResource&) = delete;
THandle Allocate(int16_t index, int32_t* status);
std::shared_ptr<TStruct> Get(THandle handle);
void Free(THandle handle);
private:
// Dynamic array to shrink HAL file size.
std::unique_ptr<std::shared_ptr<TStruct>[]> m_structures;
std::unique_ptr<priority_mutex[]> m_handleMutexes;
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<priority_mutex, size> m_handleMutexes;
};
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
IndexedHandleResource<THandle, TStruct, size,
enumValue>::IndexedHandleResource() {
m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
m_handleMutexes = std::make_unique<priority_mutex[]>(size);
}
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
THandle IndexedHandleResource<THandle, TStruct, size, enumValue>::Allocate(

View File

@@ -9,8 +9,8 @@
#include <stdint.h>
#include <array>
#include <memory>
#include <vector>
#include "HAL/Types.h"
#include "HAL/cpp/make_unique.h"
@@ -36,29 +36,21 @@ class LimitedClassedHandleResource {
friend class LimitedClassedHandleResourceTest;
public:
LimitedClassedHandleResource() = default;
LimitedClassedHandleResource(const LimitedClassedHandleResource&) = delete;
LimitedClassedHandleResource operator=(const LimitedClassedHandleResource&) =
LimitedClassedHandleResource& operator=(const LimitedClassedHandleResource&) =
delete;
LimitedClassedHandleResource();
THandle Allocate(std::shared_ptr<TStruct> toSet);
std::shared_ptr<TStruct> Get(THandle handle);
void Free(THandle handle);
private:
// Dynamic array to shrink HAL file size.
std::unique_ptr<std::shared_ptr<TStruct>[]> m_structures;
std::unique_ptr<priority_mutex[]> m_handleMutexes;
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<priority_mutex, size> m_handleMutexes;
priority_mutex m_allocateMutex;
};
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
LimitedClassedHandleResource<THandle, TStruct, size,
enumValue>::LimitedClassedHandleResource() {
m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
m_handleMutexes = std::make_unique<priority_mutex[]>(size);
}
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
THandle

View File

@@ -9,8 +9,8 @@
#include <stdint.h>
#include <array>
#include <memory>
#include <vector>
#include "HAL/Types.h"
#include "HAL/cpp/make_unique.h"
@@ -35,28 +35,20 @@ class LimitedHandleResource {
friend class LimitedHandleResourceTest;
public:
LimitedHandleResource() = default;
LimitedHandleResource(const LimitedHandleResource&) = delete;
LimitedHandleResource operator=(const LimitedHandleResource&) = delete;
LimitedHandleResource();
LimitedHandleResource& operator=(const LimitedHandleResource&) = delete;
THandle Allocate();
std::shared_ptr<TStruct> Get(THandle handle);
void Free(THandle handle);
private:
// Dynamic array to shrink HAL file size.
std::unique_ptr<std::shared_ptr<TStruct>[]> m_structures;
std::unique_ptr<priority_mutex[]> m_handleMutexes;
std::array<std::shared_ptr<TStruct>, size> m_structures;
std::array<priority_mutex, size> m_handleMutexes;
priority_mutex m_allocateMutex;
};
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
LimitedHandleResource<THandle, TStruct, size,
enumValue>::LimitedHandleResource() {
m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
m_handleMutexes = std::make_unique<priority_mutex[]>(size);
}
template <typename THandle, typename TStruct, int16_t size,
HAL_HandleEnum enumValue>
THandle LimitedHandleResource<THandle, TStruct, size, enumValue>::Allocate() {

View File

@@ -37,9 +37,10 @@ class UnlimitedHandleResource {
friend class UnlimitedHandleResourceTest;
public:
UnlimitedHandleResource(const UnlimitedHandleResource&) = delete;
UnlimitedHandleResource operator=(const UnlimitedHandleResource&) = delete;
UnlimitedHandleResource() = default;
UnlimitedHandleResource(const UnlimitedHandleResource&) = delete;
UnlimitedHandleResource& operator=(const UnlimitedHandleResource&) = delete;
THandle Allocate(std::shared_ptr<TStruct> structure);
std::shared_ptr<TStruct> Get(THandle handle);
void Free(THandle handle);

View File

@@ -16,6 +16,13 @@ public:
*/
CTR_Code SetSolenoid(unsigned char idx, bool en);
/* Set all PCM solenoid states
*
* @Return - CTR_Code - Error code (if any) for setting solenoids
* @Param - state Bitfield to set all solenoids to
*/
CTR_Code SetAllSolenoids(UINT8 state);
/* Enables PCM Closed Loop Control of Compressor via pressure switch
* @Return - CTR_Code - Error code (if any) for setting solenoid
* @Param - en - Enable / Disable Closed Loop Control
@@ -192,6 +199,7 @@ public:
extern "C" {
void * c_PCM_Init(void);
CTR_Code c_SetSolenoid(void * handle,unsigned char idx,INT8 param);
CTR_Code c_SetAllSolenoids(void * handle,UINT8 state);
CTR_Code c_SetClosedLoopControl(void * handle,INT8 param);
CTR_Code c_ClearStickyFaults(void * handle,INT8 param);
CTR_Code c_GetSolenoid(void * handle,UINT8 idx,INT8 * status);

View File

@@ -5,13 +5,14 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <limits>
#include "FRC_NetworkCommunication/FRCComm.h"
#include "HAL/HAL.h"
#include "HAL/DriverStation.h"
#include "HAL/cpp/priority_condition_variable.h"
#include "HAL/cpp/priority_mutex.h"
@@ -41,16 +42,24 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
static constexpr int KEEP_MSGS = 5;
std::lock_guard<priority_mutex> lock(msgMutex);
static std::string prevMsg[KEEP_MSGS];
static uint64_t prevMsgTime[KEEP_MSGS] = {0, 0, 0};
static std::chrono::time_point<std::chrono::steady_clock>
prevMsgTime[KEEP_MSGS];
static bool initialized = false;
if (!initialized) {
for (int i = 0; i < KEEP_MSGS; i++) {
prevMsgTime[i] =
std::chrono::steady_clock::now() - std::chrono::seconds(2);
}
initialized = true;
}
int32_t status = 0;
uint64_t curTime = HAL_GetFPGATime(&status);
auto curTime = std::chrono::steady_clock::now();
int i;
for (i = 0; i < KEEP_MSGS; ++i) {
if (prevMsg[i] == details) break;
}
int retval = 0;
if (i == KEEP_MSGS || (curTime - prevMsgTime[i]) >= 1000000) {
if (i == KEEP_MSGS || (curTime - prevMsgTime[i]) >= std::chrono::seconds(1)) {
retval = FRC_NetworkCommunication_sendError(isError, errorCode, isLVCode,
details, location, callStack);
if (printMsg) {
@@ -66,7 +75,7 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode,
if (i == KEEP_MSGS) {
// replace the oldest one
i = 0;
uint64_t first = prevMsgTime[0];
auto first = prevMsgTime[0];
for (int j = 1; j < KEEP_MSGS; ++j) {
if (prevMsgTime[j] < first) {
first = prevMsgTime[j];

View File

@@ -11,6 +11,7 @@
#include <sys/prctl.h>
#include <unistd.h>
#include <atomic>
#include <cstdlib>
#include <fstream>
#include <iostream>
@@ -21,7 +22,9 @@
#include "FRC_NetworkCommunication/FRCComm.h"
#include "FRC_NetworkCommunication/LoadOut.h"
#include "HAL/ChipObject.h"
#include "HAL/DriverStation.h"
#include "HAL/Errors.h"
#include "HAL/Notifier.h"
#include "HAL/cpp/priority_mutex.h"
#include "HAL/handles/HandlesInternal.h"
#include "ctre/ctre.h"
@@ -161,6 +164,12 @@ const char* HAL_GetErrorMessage(int32_t code) {
return VI_ERROR_INV_PARAMETER_MESSAGE;
case HAL_PWM_SCALE_ERROR:
return HAL_PWM_SCALE_ERROR_MESSAGE;
case HAL_SERIAL_PORT_NOT_FOUND:
return HAL_SERIAL_PORT_NOT_FOUND_MESSAGE;
case HAL_THREAD_PRIORITY_ERROR:
return HAL_THREAD_PRIORITY_ERROR_MESSAGE;
case HAL_THREAD_PRIORITY_RANGE_ERROR:
return HAL_THREAD_PRIORITY_RANGE_ERROR_MESSAGE;
default:
return "Unknown error status";
}
@@ -249,20 +258,30 @@ HAL_Bool HAL_GetBrownedOut(int32_t* status) {
return !(watchdog->readStatus_PowerAlive(status));
}
static void HALCleanupAtExit() {
global = nullptr;
watchdog = nullptr;
// Unregister our new data condition variable.
setNewDataSem(nullptr);
}
static void timerRollover(uint64_t currentTime, HAL_NotifierHandle handle) {
// reschedule timer for next rollover
int32_t status = 0;
HAL_UpdateNotifierAlarm(handle, currentTime + 0x80000000ULL, &status);
}
void HAL_BaseInitialize(int32_t* status) {
static std::atomic_bool initialized{false};
static priority_mutex initializeMutex;
// Initial check, as if it's true initialization has finished
if (initialized) return;
std::lock_guard<priority_mutex> lock(initializeMutex);
// Second check in case another thread was waiting
if (initialized) return;
// image 4; Fixes errors caused by multiple processes. Talk to NI about this
nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
nLoadOut::kTargetClass_RoboRIO;
global.reset(tGlobal::create(status));
watchdog.reset(tSysWatchdog::create(status));
initialized = true;
}
/**
* Call this to start up HAL. This is required for robot programs.
*/
@@ -273,15 +292,14 @@ int32_t HAL_Initialize(int32_t mode) {
prctl(PR_SET_PDEATHSIG, SIGTERM);
FRC_NetworkCommunication_Reserve(nullptr);
// image 4; Fixes errors caused by multiple processes. Talk to NI about this
nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
nLoadOut::kTargetClass_RoboRIO;
std::atexit([]() {
// Unregister our new data condition variable.
setNewDataSem(nullptr);
});
int32_t status = 0;
global.reset(tGlobal::create(&status));
watchdog.reset(tSysWatchdog::create(&status));
std::atexit(HALCleanupAtExit);
HAL_BaseInitialize(&status);
if (!rolloverNotifier)
rolloverNotifier = HAL_InitializeNotifier(timerRollover, nullptr, &status);

View File

@@ -15,6 +15,7 @@
#include <mutex>
#include "HAL/ChipObject.h"
#include "HAL/Errors.h"
#include "HAL/HAL.h"
#include "HAL/cpp/make_unique.h"
#include "HAL/cpp/priority_mutex.h"

View File

@@ -7,6 +7,8 @@
#include "HAL/PWM.h"
#include <cmath>
#include "ConstantsInternal.h"
#include "DigitalInternal.h"
#include "HAL/handles/HandlesInternal.h"
@@ -48,7 +50,7 @@ HAL_DigitalHandle HAL_InitializePWMPort(HAL_PortHandle portHandle,
if (*status != 0) return HAL_kInvalidHandle;
int16_t channel = getPortHandleChannel(portHandle);
if (channel == InvalidHandleIndex) {
if (channel == InvalidHandleIndex || channel >= kNumPWMChannels) {
*status = PARAMETER_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
@@ -241,6 +243,8 @@ void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
speed = -1.0;
} else if (speed > 1.0) {
speed = 1.0;
} else if (!std::isfinite(speed)) {
speed = 0.0;
}
// calculate the desired output pwm value by scaling the speed appropriately

View File

@@ -13,6 +13,7 @@
#include "DigitalInternal.h"
#include "HAL/DIO.h"
#include "HAL/HAL.h"
#include "HAL/Notifier.h"
#include "HAL/cpp/make_unique.h"
#include "HAL/cpp/priority_mutex.h"
#include "HAL/handles/HandlesInternal.h"
@@ -634,7 +635,7 @@ int64_t HAL_GetSPIAccumulatorCount(int32_t port, int32_t* status) {
double HAL_GetSPIAccumulatorAverage(int32_t port, int32_t* status) {
int64_t value;
int64_t count;
HAL_GetAccumulatorOutput(port, &value, &count, status);
HAL_GetSPIAccumulatorOutput(port, &value, &count, status);
if (count == 0) return 0.0;
return static_cast<double>(value) / count;
}

View File

@@ -7,109 +7,118 @@
#include "HAL/SerialPort.h"
#include <string>
#include "HAL/cpp/SerialHelper.h"
#include "visa/visa.h"
static int32_t m_resourceManagerHandle;
static int32_t m_portHandle[2];
static int32_t resourceManagerHandle;
static HAL_SerialPort portHandles[4];
extern "C" {
void HAL_InitializeSerialPort(int32_t port, int32_t* status) {
char const* portName;
void HAL_InitializeSerialPort(HAL_SerialPort port, int32_t* status) {
std::string portName;
if (m_resourceManagerHandle == 0)
viOpenDefaultRM(reinterpret_cast<ViSession*>(&m_resourceManagerHandle));
if (resourceManagerHandle == 0)
viOpenDefaultRM(reinterpret_cast<ViSession*>(&resourceManagerHandle));
if (port == 0)
portName = "ASRL1::INSTR";
else if (port == 1)
portName = "ASRL2::INSTR";
else
portName = "ASRL3::INSTR";
hal::SerialHelper serialHelper;
*status =
viOpen(m_resourceManagerHandle, const_cast<char*>(portName), VI_NULL,
VI_NULL, reinterpret_cast<ViSession*>(&m_portHandle[port]));
portName = serialHelper.GetVISASerialPortName(port, status);
if (*status < 0) {
return;
}
*status = viOpen(resourceManagerHandle, const_cast<char*>(portName.c_str()),
VI_NULL, VI_NULL,
reinterpret_cast<ViSession*>(&portHandles[port]));
if (*status > 0) *status = 0;
}
void HAL_SetSerialBaudRate(int32_t port, int32_t baud, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_BAUD, baud);
void HAL_SetSerialBaudRate(HAL_SerialPort port, int32_t baud, int32_t* status) {
*status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_BAUD, baud);
if (*status > 0) *status = 0;
}
void HAL_SetSerialDataBits(int32_t port, int32_t bits, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_DATA_BITS, bits);
void HAL_SetSerialDataBits(HAL_SerialPort port, int32_t bits, int32_t* status) {
*status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_DATA_BITS, bits);
if (*status > 0) *status = 0;
}
void HAL_SetSerialParity(int32_t port, int32_t parity, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_PARITY, parity);
void HAL_SetSerialParity(HAL_SerialPort port, int32_t parity, int32_t* status) {
*status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_PARITY, parity);
if (*status > 0) *status = 0;
}
void HAL_SetSerialStopBits(int32_t port, int32_t stopBits, int32_t* status) {
*status =
viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_STOP_BITS, stopBits);
void HAL_SetSerialStopBits(HAL_SerialPort port, int32_t stopBits,
int32_t* status) {
*status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_STOP_BITS, stopBits);
if (*status > 0) *status = 0;
}
void HAL_SetSerialWriteMode(int32_t port, int32_t mode, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_WR_BUF_OPER_MODE, mode);
void HAL_SetSerialWriteMode(HAL_SerialPort port, int32_t mode,
int32_t* status) {
*status = viSetAttribute(portHandles[port], VI_ATTR_WR_BUF_OPER_MODE, mode);
if (*status > 0) *status = 0;
}
void HAL_SetSerialFlowControl(int32_t port, int32_t flow, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_FLOW_CNTRL, flow);
void HAL_SetSerialFlowControl(HAL_SerialPort port, int32_t flow,
int32_t* status) {
*status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_FLOW_CNTRL, flow);
if (*status > 0) *status = 0;
}
void HAL_SetSerialTimeout(int32_t port, double timeout, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_TMO_VALUE,
void HAL_SetSerialTimeout(HAL_SerialPort port, double timeout,
int32_t* status) {
*status = viSetAttribute(portHandles[port], VI_ATTR_TMO_VALUE,
static_cast<uint32_t>(timeout * 1e3));
if (*status > 0) *status = 0;
}
void HAL_EnableSerialTermination(int32_t port, char terminator,
void HAL_EnableSerialTermination(HAL_SerialPort port, char terminator,
int32_t* status) {
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR, terminator);
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_END_IN,
viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR, terminator);
*status = viSetAttribute(portHandles[port], VI_ATTR_ASRL_END_IN,
VI_ASRL_END_TERMCHAR);
if (*status > 0) *status = 0;
}
void HAL_DisableSerialTermination(int32_t port, int32_t* status) {
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR_EN, VI_FALSE);
void HAL_DisableSerialTermination(HAL_SerialPort port, int32_t* status) {
viSetAttribute(portHandles[port], VI_ATTR_TERMCHAR_EN, VI_FALSE);
*status =
viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_END_IN, VI_ASRL_END_NONE);
viSetAttribute(portHandles[port], VI_ATTR_ASRL_END_IN, VI_ASRL_END_NONE);
if (*status > 0) *status = 0;
}
void HAL_SetSerialReadBufferSize(int32_t port, int32_t size, int32_t* status) {
*status = viSetBuf(m_portHandle[port], VI_READ_BUF, size);
void HAL_SetSerialReadBufferSize(HAL_SerialPort port, int32_t size,
int32_t* status) {
*status = viSetBuf(portHandles[port], VI_READ_BUF, size);
if (*status > 0) *status = 0;
}
void HAL_SetSerialWriteBufferSize(int32_t port, int32_t size, int32_t* status) {
*status = viSetBuf(m_portHandle[port], VI_WRITE_BUF, size);
void HAL_SetSerialWriteBufferSize(HAL_SerialPort port, int32_t size,
int32_t* status) {
*status = viSetBuf(portHandles[port], VI_WRITE_BUF, size);
if (*status > 0) *status = 0;
}
int32_t HAL_GetSerialBytesReceived(int32_t port, int32_t* status) {
int32_t HAL_GetSerialBytesReceived(HAL_SerialPort port, int32_t* status) {
int32_t bytes = 0;
*status = viGetAttribute(m_portHandle[port], VI_ATTR_ASRL_AVAIL_NUM, &bytes);
*status = viGetAttribute(portHandles[port], VI_ATTR_ASRL_AVAIL_NUM, &bytes);
if (*status > 0) *status = 0;
return bytes;
}
int32_t HAL_ReadSerial(int32_t port, char* buffer, int32_t count,
int32_t HAL_ReadSerial(HAL_SerialPort port, char* buffer, int32_t count,
int32_t* status) {
uint32_t retCount = 0;
*status =
viRead(m_portHandle[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
viRead(portHandles[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
if (*status == VI_ERROR_IO || *status == VI_ERROR_ASRL_OVERRUN ||
*status == VI_ERROR_ASRL_FRAMING || *status == VI_ERROR_ASRL_PARITY) {
@@ -121,29 +130,29 @@ int32_t HAL_ReadSerial(int32_t port, char* buffer, int32_t count,
return static_cast<int32_t>(retCount);
}
int32_t HAL_WriteSerial(int32_t port, const char* buffer, int32_t count,
int32_t HAL_WriteSerial(HAL_SerialPort port, const char* buffer, int32_t count,
int32_t* status) {
uint32_t retCount = 0;
*status =
viWrite(m_portHandle[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
viWrite(portHandles[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
if (*status > 0) *status = 0;
return static_cast<int32_t>(retCount);
}
void HAL_FlushSerial(int32_t port, int32_t* status) {
*status = viFlush(m_portHandle[port], VI_WRITE_BUF);
void HAL_FlushSerial(HAL_SerialPort port, int32_t* status) {
*status = viFlush(portHandles[port], VI_WRITE_BUF);
if (*status > 0) *status = 0;
}
void HAL_ClearSerial(int32_t port, int32_t* status) {
*status = viClear(m_portHandle[port]);
void HAL_ClearSerial(HAL_SerialPort port, int32_t* status) {
*status = viClear(portHandles[port]);
if (*status > 0) *status = 0;
}
void HAL_CloseSerial(int32_t port, int32_t* status) {
*status = viClose(m_portHandle[port]);
void HAL_CloseSerial(HAL_SerialPort port, int32_t* status) {
*status = viClose(portHandles[port]);
if (*status > 0) *status = 0;
}

View File

@@ -116,6 +116,12 @@ void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
*status = PCM_modules[port->module]->SetSolenoid(port->channel, value);
}
void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status) {
if (!checkPCMInit(module, status)) return;
*status = PCM_modules[module]->SetAllSolenoids(state);
}
int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
if (!checkPCMInit(module, status)) return 0;
uint8_t value;

120
hal/lib/athena/Threads.cpp Normal file
View File

@@ -0,0 +1,120 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#include "HAL/Threads.h"
#include <pthread.h>
#include <sched.h>
#include "HAL/Errors.h"
/**
* Get the thread priority for the specified thread.
*
* @param handle Native handle pointer to the thread to get the priority for
* @param isRealTime Set to true if thread is realtime, otherwise false
* @param status Error status variable. 0 on success
* @return The current thread priority. Scaled 1-99, with 1 being highest.
*/
int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
int32_t* status) {
sched_param sch;
int policy;
int success = pthread_getschedparam(*handle, &policy, &sch);
if (success == 0) {
*status = 0;
} else {
*status = HAL_THREAD_PRIORITY_ERROR;
return -1;
}
if (policy == SCHED_FIFO || policy == SCHED_RR) {
*isRealTime = true;
return sch.sched_priority;
} else {
*isRealTime = false;
// 0 is the only suppored priority for non-realtime, so scale to 1
return 1;
}
}
/**
* Get the thread priority for the current thread.
*
* @param handle Native handle pointer to the thread to get the priority for
* @param isRealTime Set to true if thread is realtime, otherwise false
* @param status Error status variable. 0 on success
* @return The current thread priority. Scaled 1-99, with 1 being highest.
*/
int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status) {
auto thread = pthread_self();
return HAL_GetThreadPriority(&thread, isRealTime, status);
}
/**
* Sets the thread priority for the specified thread
*
* @param thread Reference to the thread to set the priority of
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest
* @param status Error status variable. 0 on success
*
* @return The success state of setting the priority
*/
HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
int32_t priority, int32_t* status) {
if (handle == nullptr) {
*status = NULL_PARAMETER;
return false;
}
int scheduler = realTime ? SCHED_FIFO : SCHED_OTHER;
if (realTime) {
// We don't support setting priorities for non RT threads
// so we don't need to check for proper range
if (priority < sched_get_priority_min(scheduler) ||
priority > sched_get_priority_max(scheduler)) {
*status = HAL_THREAD_PRIORITY_RANGE_ERROR;
return false;
}
}
sched_param sch;
int policy;
pthread_getschedparam(*handle, &policy, &sch);
if (scheduler == SCHED_FIFO || scheduler == SCHED_RR)
sch.sched_priority = priority;
else
// Only need to set 0 priority for non RT thread
sch.sched_priority = 0;
if (pthread_setschedparam(*handle, scheduler, &sch)) {
*status = HAL_THREAD_PRIORITY_ERROR;
return true;
} else {
*status = 0;
return false;
}
}
/**
* Sets the thread priority for the current thread
*
* @param thread Reference to the thread to set the priority of
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest
* @param status Error status variable. 0 on success
*
* @return The success state of setting the priority
*/
HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
int32_t* status) {
auto thread = pthread_self();
return HAL_SetThreadPriority(&thread, realTime, priority, status);
}

View File

@@ -0,0 +1,343 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#include "HAL/cpp/SerialHelper.h"
#include <algorithm>
#include <cstdio>
#include <cstring>
#include "../visa/visa.h"
#include "HAL/Errors.h"
#include "llvm/StringRef.h"
constexpr const char* OnboardResourceVISA = "ASRL1::INSTR";
constexpr const char* MxpResourceVISA = "ASRL2::INSTR";
constexpr const char* OnboardResourceOS = "/dev/ttyS0";
constexpr const char* MxpResourceOS = "/dev/ttyS1";
namespace hal {
std::string SerialHelper::m_usbNames[2]{"", ""};
priority_mutex SerialHelper::m_nameMutex;
SerialHelper::SerialHelper() {
viOpenDefaultRM(reinterpret_cast<ViSession*>(&m_resourceHandle));
}
std::string SerialHelper::GetVISASerialPortName(HAL_SerialPort port,
int32_t* status) {
if (port == HAL_SerialPort::HAL_SerialPort_Onboard) {
return OnboardResourceVISA;
} else if (port == HAL_SerialPort::HAL_SerialPort_MXP) {
return MxpResourceVISA;
}
QueryHubPaths(status);
// If paths are empty or status error, return error
if (*status != 0 || m_visaResource.empty() || m_osResource.empty() ||
m_sortedHubPath.empty()) {
*status = HAL_SERIAL_PORT_NOT_FOUND;
return "";
}
int32_t visaIndex = GetIndexForPort(port, status);
if (visaIndex == -1) {
*status = HAL_SERIAL_PORT_NOT_FOUND;
return "";
// Error
} else {
return m_visaResource[visaIndex].str();
}
}
std::string SerialHelper::GetOSSerialPortName(HAL_SerialPort port,
int32_t* status) {
if (port == HAL_SerialPort::HAL_SerialPort_Onboard) {
return OnboardResourceOS;
} else if (port == HAL_SerialPort::HAL_SerialPort_MXP) {
return MxpResourceOS;
}
QueryHubPaths(status);
// If paths are empty or status error, return error
if (*status != 0 || m_visaResource.empty() || m_osResource.empty() ||
m_sortedHubPath.empty()) {
*status = HAL_SERIAL_PORT_NOT_FOUND;
return "";
}
int32_t osIndex = GetIndexForPort(port, status);
if (osIndex == -1) {
*status = HAL_SERIAL_PORT_NOT_FOUND;
return "";
// Error
} else {
return m_osResource[osIndex].str();
}
}
std::vector<std::string> SerialHelper::GetVISASerialPortList(int32_t* status) {
std::vector<std::string> retVec;
// Always add 2 onboard ports
retVec.emplace_back(OnboardResourceVISA);
retVec.emplace_back(MxpResourceVISA);
QueryHubPaths(status);
// If paths are empty or status error, return only onboard list
if (*status != 0 || m_visaResource.empty() || m_osResource.empty() ||
m_sortedHubPath.empty()) {
*status = 0;
return retVec;
}
for (auto& i : m_visaResource) {
retVec.emplace_back(i.str());
}
return retVec;
}
std::vector<std::string> SerialHelper::GetOSSerialPortList(int32_t* status) {
std::vector<std::string> retVec;
// Always add 2 onboard ports
retVec.emplace_back(OnboardResourceOS);
retVec.emplace_back(MxpResourceOS);
QueryHubPaths(status);
// If paths are empty or status error, return only onboard list
if (*status != 0 || m_visaResource.empty() || m_osResource.empty() ||
m_sortedHubPath.empty()) {
*status = 0;
return retVec;
}
for (auto& i : m_osResource) {
retVec.emplace_back(i.str());
}
return retVec;
}
void SerialHelper::SortHubPathVector() {
m_sortedHubPath.clear();
m_sortedHubPath = m_unsortedHubPath;
std::sort(m_sortedHubPath.begin(), m_sortedHubPath.end(),
[](const llvm::SmallVectorImpl<char>& lhs,
const llvm::SmallVectorImpl<char>& rhs) -> int {
llvm::StringRef lhsRef(lhs.begin(), lhs.size());
llvm::StringRef rhsRef(rhs.begin(), rhs.size());
return lhsRef.compare(rhsRef);
});
}
void SerialHelper::CoiteratedSort(
llvm::SmallVectorImpl<llvm::SmallString<16>>& vec) {
llvm::SmallVector<llvm::SmallString<16>, 4> sortedVec;
for (auto& str : m_sortedHubPath) {
for (size_t i = 0; i < m_unsortedHubPath.size(); i++) {
if (llvm::StringRef{m_unsortedHubPath[i].begin(),
m_unsortedHubPath[i].size()}
.equals(llvm::StringRef{str.begin(), str.size()})) {
sortedVec.push_back(vec[i]);
break;
}
}
}
vec = sortedVec;
}
void SerialHelper::QueryHubPaths(int32_t* status) {
// VISA resource matching string
const char* str = "?*";
// Items needed for VISA
ViUInt32 retCnt = 0;
ViFindList viList = 0;
ViChar desc[VI_FIND_BUFLEN];
*status = viFindRsrc(m_resourceHandle, const_cast<char*>(str), &viList,
&retCnt, desc);
if (*status < 0) {
// Handle the bad status elsewhere
// Note let positive statii (warnings) continue
goto done;
}
// Status might be positive, so reset it to 0
*status = 0;
// Storage buffers for Visa calls and system exec calls
char osName[256];
char execBuffer[128];
// Loop through all returned VISA objects.
// Increment the internal VISA ptr every loop
for (size_t i = 0; i < retCnt; i++, viFindNext(viList, desc)) {
// Ignore any matches to the 2 onboard ports
if (std::strcmp(OnboardResourceVISA, desc) == 0 ||
std::strcmp(MxpResourceVISA, desc) == 0) {
continue;
}
// Open the resource, grab its interface name, and close it.
ViSession vSession;
*status = viOpen(m_resourceHandle, desc, VI_NULL, VI_NULL, &vSession);
if (*status < 0) goto done;
*status = 0;
*status = viGetAttribute(vSession, VI_ATTR_INTF_INST_NAME, &osName);
// Ignore an error here, as we want to close the session on an error
// Use a seperate close variable so we can check
ViStatus closeStatus = viClose(vSession);
if (*status < 0) goto done;
if (closeStatus < 0) goto done;
*status = 0;
// split until (/dev/
llvm::StringRef devNameRef = llvm::StringRef{osName}.split("(/dev/").second;
// String not found, continue
if (devNameRef.equals("")) continue;
// Split at )
llvm::StringRef matchString = devNameRef.split(')').first;
if (matchString.equals(devNameRef)) continue;
// Run find using pipe to get a list of system accessors
llvm::SmallString<128> val(
"sh -c \"find /sys/devices/soc0 | grep amba | grep usb | grep ");
val += matchString;
val += "\"";
// Pipe code found on StackOverflow
// http://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c-using-posix
// Using std::string because this is guarenteed to be large
std::string output = "";
std::shared_ptr<FILE> pipe(popen(val.c_str(), "r"), pclose);
// Just check the next item on a pipe failure
if (!pipe) continue;
while (!feof(pipe.get())) {
if (std::fgets(execBuffer, 128, pipe.get()) != 0) output += execBuffer;
}
if (!output.empty()) {
llvm::SmallVector<llvm::StringRef, 16> pathSplitVec;
// Split output by line, grab first line, and split it into
// individual directories
llvm::StringRef{output}.split('\n').first.split(pathSplitVec, '/', -1,
false);
// Find each individual item index
const char* usb1 = "usb1";
const char* tty = "tty";
int findusb = -1;
int findtty = -1;
int findregex = -1;
for (size_t i = 0; i < pathSplitVec.size(); i++) {
if (findusb == -1 && pathSplitVec[i].equals(usb1)) {
findusb = i;
}
if (findtty == -1 && pathSplitVec[i].equals(tty)) {
findtty = i;
}
if (findregex == -1 && pathSplitVec[i].equals(matchString)) {
findregex = i;
}
}
// Get the index for our device
int hubIndex = findtty;
if (findtty == -1) hubIndex = findregex;
int devStart = findusb + 1;
if (hubIndex < devStart) continue;
// Add our devices to our list
m_unsortedHubPath.emplace_back(
llvm::StringRef{pathSplitVec[hubIndex - 2]});
m_visaResource.emplace_back(desc);
m_osResource.emplace_back(
llvm::StringRef{osName}.split("(").second.split(")").first);
}
}
SortHubPathVector();
CoiteratedSort(m_visaResource);
CoiteratedSort(m_osResource);
done:
viClose(viList);
}
int32_t SerialHelper::GetIndexForPort(HAL_SerialPort port, int32_t* status) {
// Hold lock whenever we're using the names array
std::lock_guard<priority_mutex> lock(m_nameMutex);
std::string portString = m_usbNames[port - 2];
llvm::SmallVector<int32_t, 4> indices;
// If port has not been assigned, find the one to assign
if (portString.empty()) {
for (size_t i = 0; i < 2; i++) {
// Remove all used ports
auto idx = std::find(m_sortedHubPath.begin(), m_sortedHubPath.end(),
m_usbNames[i]);
if (idx != m_sortedHubPath.end()) {
// found
m_sortedHubPath.erase(idx);
}
if (m_usbNames[i] == "") {
indices.push_back(i);
}
}
int32_t idx = -1;
for (size_t i = 0; i < indices.size(); i++) {
if (indices[i] == port - 2) {
idx = i;
break;
}
}
if (idx == -1) {
*status = HAL_SERIAL_PORT_NOT_FOUND;
return -1;
}
if (idx >= static_cast<int32_t>(m_sortedHubPath.size())) {
*status = HAL_SERIAL_PORT_NOT_FOUND;
return -1;
}
portString = m_sortedHubPath[idx].str();
m_usbNames[port - 2] = portString;
}
int retIndex = -1;
for (size_t i = 0; i < m_sortedHubPath.size(); i++) {
if (m_sortedHubPath[i].equals(portString)) {
retIndex = i;
break;
}
}
return retIndex;
}
} // namespace hal

View File

@@ -140,6 +140,19 @@ CTR_Code PCM::SetSolenoid(unsigned char idx, bool en)
return CTR_OKAY;
}
/* Set all PCM solenoid states
*
* @Return - CTR_Code - Error code (if any) for setting solenoids
* @Param - state Bitfield to set all solenoids to
*/
CTR_Code PCM::SetAllSolenoids(UINT8 state) {
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
toFill->solenoidBits = state;
FlushTx(toFill);
return CTR_OKAY;
}
/* Clears PCM sticky faults (indicators of past faults
*
* @Return - CTR_Code - Error code (if any) for setting solenoid
@@ -465,6 +478,9 @@ extern "C" {
CTR_Code c_SetSolenoid(void * handle, unsigned char idx, INT8 param) {
return ((PCM*) handle)->SetSolenoid(idx, param);
}
CTR_Code c_SetAllSolenoids(void * handle, UINT8 state) {
return ((PCM*) handle)->SetAllSolenoids(state);
}
CTR_Code c_SetClosedLoopControl(void * handle, INT8 param) {
return ((PCM*) handle)->SetClosedLoopControl(param);
}

View File

@@ -18,9 +18,8 @@ def wpilibj = project(':wpilibj')
dependencies {
compile wpilibj
compile files(wpilibj.sourceSets.test.output.classesDir)
compile 'edu.wpi.first.wpilib.networktables.java:NetworkTables:+:arm'
compile 'edu.wpi.first.wpilib.networktables.java:NetworkTables:+:arm'
compile 'edu.wpi.cscore.java:cscore:+:arm'
compile ntcoreDep('java', 'arm')
compile cscoreDep('java', 'arm')
compile 'org.opencv:opencv-java:+'
}

View File

@@ -10,7 +10,7 @@ ext.hal = project(':hal').projectDir.getAbsolutePath()
model {
components {
myRobotcpp(NativeExecutableSpec) {
targetPlatform 'arm'
targetPlatform 'roborio-arm'
binaries.all {
tasks.withType(CppCompile) {
addNiLibraryLinks(linker, targetPlatform)

View File

@@ -15,7 +15,7 @@
#define __FRC_COMM_H__
#ifdef _WIN32
# include <windows.h>
#include <windows.h>
#ifdef USE_THRIFT
# define EXPORT_FUNC
# else

View File

@@ -3,7 +3,7 @@
#define __LoadOut_h__
#ifdef _WIN32
#include <vxWorks_compat.h>
#include <windows.h>
#define EXPORT_FUNC __declspec(dllexport) __cdecl
#elif defined (__vxworks)
#include <vxWorks.h>

View File

@@ -79,6 +79,9 @@ namespace nUsageReporting
kResourceType_MindsensorsSD540,
kResourceType_DigitalFilter,
kResourceType_ADIS16448,
kResourceType_PDP,
kResourceType_PCM, // 60
kResourceType_PigeonIMU,
} tResourceType;
typedef enum

View File

@@ -6,20 +6,27 @@ task patchNiLibraries() {
// Patch ChipObject headers to be self contained
FileTree chipTree = fileTree(dir: "$rootDir/ni-libraries/include/FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace")
chipTree.each {File file ->
String contents = file.getText( 'UTF-8' )
contents = contents.replaceAll( '#include \"tSystemInterface.h\"', '#include \"../tSystem.h\"\n#include \"../tSystemInterface.h\"' )
file.write( contents, 'UTF-8' )
String contents = file.getText('UTF-8')
contents = contents.replaceAll('#include \"tSystemInterface.h\"', '#include \"../tSystem.h\"\n#include \"../tSystemInterface.h\"')
file.write(contents, 'UTF-8')
}
// Patch NetComm headers to work on Windows
FileTree netTree = fileTree(dir: "$rootDir/ni-libraries/include/FRC_NetworkCommunication")
netTree.each {File file ->
String contents = file.getText( 'UTF-8' )
contents = contents.replaceAll( '#ifdef WIN32', '#ifdef _WIN32' )
contents = contents.replaceAll( '# include <vxWorks_compat.h>', '# include <windows.h>' )
file.write( contents, 'UTF-8' )
String contents = file.getText('UTF-8')
contents = contents.replaceAll('#ifdef WIN32', '#ifdef _WIN32')
contents = contents.replaceAll('# include <vxWorks_compat.h>', '#include <windows.h>')
contents = contents.replaceAll('#include <vxWorks_compat.h>', '#include <windows.h>')
file.write(contents, 'UTF-8')
}
FileTree allTree = fileTree(dir: "$rootDir/ni-libraries/include/")
allTree.each {File file ->
String contents = file.getText('UTF-8')
contents = contents.replaceAll('\r\n', '\n')
file.write(contents, 'UTF-8')
}
// Generate genlinks

View File

@@ -7,7 +7,7 @@ include 'hal',
'myRobotCpp'
if (hasProperty("makeSim")){
include 'simulation',
'simulation:JavaGazebo',
'simulation:SimDS'
include 'simulation',
'simulation:JavaGazebo',
'simulation:SimDS'
}

View File

@@ -51,6 +51,8 @@
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<module name="AvoidStarImport"/>
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<module name="OneTopLevelClass"/>
<module name="NoLineWrap"/>
<module name="EmptyBlock">

View File

@@ -1,36 +0,0 @@
#!/usr/bin/env python3
"""This script invokes format.py in the wpilibsuite/styleguide repository.
Set the WPI_FORMAT environment variable to its location on disk before use. For
example:
WPI_FORMAT="$HOME/styleguide" ./format.py
"""
import os
import subprocess
import sys
def main():
path = os.environ.get("WPI_FORMAT")
if path == None:
print("Error: WPI_FORMAT environment variable not set")
sys.exit(1)
try:
# Run main format.py script
args = ["python3", path + "/format.py"]
args.extend(sys.argv[1:])
proc = subprocess.Popen(args)
sys.exit(proc.wait())
except FileNotFoundError:
# Run main format.py script on windows
args = ["py", "-3", path + "/format.py"]
args.extend(sys.argv[1:])
proc = subprocess.Popen(args)
sys.exit(proc.wait())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<ruleset name="WPILibRuleset"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<rule ref="rulesets/java/basic.xml" />
<rule ref="rulesets/java/braces.xml" />
<rule ref="rulesets/java/empty.xml" />
<rule ref="rulesets/java/empty.xml/EmptyCatchBlock">
<properties>
<property name="allowCommentedBlocks" value="true"/>
</properties>
</rule>
<rule ref="rulesets/java/imports.xml" />
<rule ref="rulesets/java/junit.xml">
<exclude name="JUnitTestContainsTooManyAsserts" />
</rule>
<rule ref="rulesets/java/strings.xml">
<exclude name="AvoidDuplicateLiterals" />
</rule>
<rule ref="rulesets/java/unnecessary.xml" />
<rule ref="rulesets/java/unusedcode.xml" />
<rule ref="rulesets/java/unusedcode.xml/UnusedFormalParameter">
<properties>
<property name="checkAll" value="true"/>
</properties>
</rule>
</ruleset>

View File

@@ -9,9 +9,10 @@ def ntSourceDir = "$buildDir/ntSources"
model {
components {
wpilibc(NativeLibrarySpec) {
targetPlatform 'arm'
targetPlatform 'roborio-arm'
binaries.all {
tasks.withType(CppCompile) {
dependsOn generateCppVersion
cppCompiler.args "-DNAMESPACED_WPILIB"
addNiLibraryLinks(linker, targetPlatform)
addNetworkTablesLibraryLinks(it, linker, targetPlatform)
@@ -33,6 +34,9 @@ model {
}
}
}
tasks { tasks ->
tasks.wpilibcZip.dependsOn tasks.wpilibcSharedLibrary
}
}
task wpilibcZip(type: Zip) {
@@ -71,40 +75,18 @@ task wpilibcZip(type: Zip) {
}
}
// Add the dependency on the wpilib_nonsharedStaticLibrary task to the wpilibc task. Because of the gradle lifecycle,
// this cannot be done purely with dependsOn in the task, as the static library task doesn't exist yet. Same goes for
// the networkTablesStaticLibrary task and the two HAL tasks below
tasks.whenTaskAdded { task ->
if (task.name.toLowerCase() == 'wpilibcsharedlibrary') {
wpilibcZip.dependsOn task
}
}
// Add the hal static and shared libraries as a dependency
project(':hal').tasks.whenTaskAdded { task ->
if (task.name.toLowerCase() == 'halathenastaticlibrary' || task.name.toLowerCase() == 'halathenasharedlibrary') {
wpilibcZip.dependsOn task
}
}
// Add the generate version file task as a dependency
tasks.whenTaskAdded { task ->
if (task.name.toLowerCase().startsWith('compilewpilib')) {
task.dependsOn generateCppVersion
}
}
if (checkDoxygen()) {
def ntSourcesDependency = project.dependencies.create('edu.wpi.first.wpilib.networktables.cpp:NetworkTables:+:sources@zip')
def ntSourcesConfig = project.configurations.detachedConfiguration(ntSourcesDependency)
ntSourcesDependency.setTransitive(false)
def ntSources = ntSourcesConfig.singleFile
configurations.create('doc')
dependencies {
doc ntcoreDep('cpp', 'sources', 'zip')
}
task unzipCppNtSources(type: Copy) {
description = 'Unzips the C++ networktables sources for doc creation'
group = 'WPILib'
from zipTree(ntSources)
description = 'Unzips the C++ networktables sources for doc creation.'
group = 'Dependencies'
configurations.doc.files.each {
from zipTree(it)
}
exclude 'META-INF/*'
into ntSourceDir
}

View File

@@ -28,6 +28,7 @@ class AnalogOutput : public SensorBase, public LiveWindowSendable {
void SetVoltage(double voltage);
double GetVoltage() const;
int GetChannel();
void UpdateTable() override;
void StartLiveWindowMode() override;

View File

@@ -33,7 +33,7 @@ class AnalogTrigger;
* The RisingPulse and FallingPulse outputs detect an instantaneous transition
* from above the upper limit to below the lower limit, and vise versa. These
* pulses represent a rollover condition of a sensor and can be routed to an up
* / down couter or to interrupts. Because the outputs generate a pulse, they
* / down counter or to interrupts. Because the outputs generate a pulse, they
* cannot be read directly. To help ensure that a rollover condition is not
* missed, there is an average rejection filter available that operates on the
* upper 8 bits of a 12 bit number and selects the nearest outlyer of 3 samples.

View File

@@ -44,16 +44,20 @@ class CameraServer : public ErrorBase {
* If you also want to perform vision processing on the roboRIO, use
* getVideo() to get access to the camera images.
*
* This overload calls {@link #startAutomaticCapture(int)} with device 0.
* This overload calls {@link #StartAutomaticCapture(int)} with device 0,
* creating a camera named "USB Camera 0".
*/
cs::USBCamera StartAutomaticCapture();
cs::UsbCamera StartAutomaticCapture();
/**
* Start automatically capturing images to send to the dashboard.
*
* <p>This overload calls {@link #StartAutomaticCapture(String, int)} with
* a name of "USB Camera {dev}".
*
* @param dev The device number of the camera interface
*/
cs::USBCamera StartAutomaticCapture(int dev);
cs::UsbCamera StartAutomaticCapture(int dev);
/**
* Start automatically capturing images to send to the dashboard.
@@ -61,7 +65,7 @@ class CameraServer : public ErrorBase {
* @param name The name to give the camera
* @param dev The device number of the camera interface
*/
cs::USBCamera StartAutomaticCapture(llvm::StringRef name, int dev);
cs::UsbCamera StartAutomaticCapture(llvm::StringRef name, int dev);
/**
* Start automatically capturing images to send to the dashboard.
@@ -69,7 +73,7 @@ class CameraServer : public ErrorBase {
* @param name The name to give the camera
* @param path The device path (e.g. "/dev/video0") of the camera
*/
cs::USBCamera StartAutomaticCapture(llvm::StringRef name,
cs::UsbCamera StartAutomaticCapture(llvm::StringRef name,
llvm::StringRef path);
/**
@@ -80,6 +84,100 @@ class CameraServer : public ErrorBase {
*/
void StartAutomaticCapture(const cs::VideoSource& camera);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String)} with
* name "Axis Camera".
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef host);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String)} with
* name "Axis Camera".
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const char* host);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String)} with
* name "Axis Camera".
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const std::string& host);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String[])} with
* name "Axis Camera".
*
* @param hosts Array of Camera host IPs/DNS names
*/
cs::AxisCamera AddAxisCamera(llvm::ArrayRef<std::string> hosts);
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #AddAxisCamera(String, String[])} with
* name "Axis Camera".
*
* @param hosts Array of Camera host IPs/DNS names
*/
template <typename T>
cs::AxisCamera AddAxisCamera(std::initializer_list<T> hosts);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef name, llvm::StringRef host);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef name, const char* host);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef name, const std::string& host);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param hosts Array of Camera host IPs/DNS names
*/
cs::AxisCamera AddAxisCamera(llvm::StringRef name,
llvm::ArrayRef<std::string> hosts);
/**
* Adds an Axis IP camera.
*
* @param name The name to give the camera
* @param hosts Array of Camera host IPs/DNS names
*/
template <typename T>
cs::AxisCamera AddAxisCamera(llvm::StringRef name,
std::initializer_list<T> hosts);
/**
* Get OpenCV access to the primary camera feed. This allows you to
* get images from the camera for image processing on the roboRIO.
@@ -97,6 +195,14 @@ class CameraServer : public ErrorBase {
*/
cs::CvSink GetVideo(const cs::VideoSource& camera);
/**
* Get OpenCV access to the specified camera. This allows you to get
* images from the camera for image processing on the roboRIO.
*
* @param name Camera name
*/
cs::CvSink GetVideo(llvm::StringRef name);
/**
* Create a MJPEG stream with OpenCV input. This can be called to pass custom
* annotated images to the dashboard.
@@ -112,14 +218,14 @@ class CameraServer : public ErrorBase {
*
* @param name Server name
*/
cs::MJPEGServer AddServer(llvm::StringRef name);
cs::MjpegServer AddServer(llvm::StringRef name);
/**
* Adds a MJPEG server.
*
* @param name Server name
*/
cs::MJPEGServer AddServer(llvm::StringRef name, int port);
cs::MjpegServer AddServer(llvm::StringRef name, int port);
/**
* Adds an already created server.
@@ -154,7 +260,7 @@ class CameraServer : public ErrorBase {
* the correct mode, or set it directly on a camera and call the appropriate
* StartAutomaticCapture method.
*
* @deprecated Use SetResolution on the USBCamera returned by
* @deprecated Use SetResolution on the UsbCamera returned by
* StartAutomaticCapture() instead.
* @param size The size to use
*/
@@ -164,6 +270,7 @@ class CameraServer : public ErrorBase {
CameraServer();
std::shared_ptr<ITable> GetSourceTable(CS_Source source);
std::vector<std::string> GetSinkStreamValues(CS_Sink sink);
void UpdateStreamValues();
static constexpr char const* kPublishName = "/CameraPublisher";
@@ -181,3 +288,5 @@ class CameraServer : public ErrorBase {
};
} // namespace frc
#include "CameraServer.inc"

View File

@@ -0,0 +1,30 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <string>
#include <vector>
namespace frc {
template <typename T>
inline cs::AxisCamera CameraServer::AddAxisCamera(
std::initializer_list<T> hosts) {
return AddAxisCamera("Axis Camera", hosts);
}
template <typename T>
inline cs::AxisCamera CameraServer::AddAxisCamera(
llvm::StringRef name, std::initializer_list<T> hosts) {
std::vector<std::string> vec;
vec.reserve(hosts.size());
for (const auto& host : hosts) vec.emplace_back(host);
return AddAxisCamera(name, vec);
}
} // namespace frc

View File

@@ -18,6 +18,7 @@
#include "HAL/cpp/priority_mutex.h"
#include "RobotState.h"
#include "SensorBase.h"
#include "llvm/StringRef.h"
namespace frc {
@@ -31,11 +32,10 @@ class DriverStation : public SensorBase, public RobotStateInterface {
virtual ~DriverStation();
static DriverStation& GetInstance();
static void ReportError(std::string error);
static void ReportWarning(std::string error);
static void ReportError(bool is_error, int code, const std::string& error,
const std::string& location,
const std::string& stack);
static void ReportError(llvm::StringRef error);
static void ReportWarning(llvm::StringRef error);
static void ReportError(bool is_error, int code, llvm::StringRef error,
llvm::StringRef location, llvm::StringRef stack);
static const int kJoystickPorts = 6;
@@ -96,8 +96,8 @@ class DriverStation : public SensorBase, public RobotStateInterface {
private:
DriverStation();
void ReportJoystickUnpluggedError(std::string message);
void ReportJoystickUnpluggedWarning(std::string message);
void ReportJoystickUnpluggedError(llvm::StringRef message);
void ReportJoystickUnpluggedWarning(llvm::StringRef message);
void Run();
void UpdateControlWord(bool force, HAL_ControlWord& controlWord) const;

View File

@@ -35,7 +35,7 @@ class I2C : SensorBase {
bool WriteBulk(uint8_t* data, int count);
bool Read(int registerAddress, int count, uint8_t* data);
bool ReadOnly(int count, uint8_t* buffer);
void Broadcast(int registerAddress, uint8_t data);
// void Broadcast(int registerAddress, uint8_t data);
bool VerifySensor(int registerAddress, int count, const uint8_t* expected);
private:

View File

@@ -9,6 +9,7 @@
#include <cstdio>
#include <iostream>
#include <thread>
#include "Base.h"
#include "HAL/HAL.h"
@@ -47,6 +48,7 @@ class RobotBase {
bool IsOperatorControl() const;
bool IsTest() const;
bool IsNewDataAvailable() const;
static std::thread::id GetThreadId();
virtual void StartCompetition() = 0;
protected:
@@ -57,6 +59,8 @@ class RobotBase {
RobotBase& operator=(const RobotBase&) = delete;
DriverStation& m_ds;
static std::thread::id m_threadId;
};
} // namespace frc

View File

@@ -10,6 +10,8 @@
#include <string>
#include "ErrorBase.h"
#include "llvm/StringRef.h"
#include "support/deprecated.h"
namespace frc {
@@ -46,7 +48,7 @@ class SerialPort : public ErrorBase {
kFlowControl_DtrDsr = 4
};
enum WriteBufferMode { kFlushOnAccess = 1, kFlushWhenFull = 2 };
enum Port { kOnboard = 0, kMXP = 1, kUSB = 2 };
enum Port { kOnboard = 0, kMXP = 1, kUSB = 2, kUSB1 = 2, kUSB2 = 3 };
SerialPort(int baudRate, Port port = kOnboard, int dataBits = 8,
Parity parity = kParity_None, StopBits stopBits = kStopBits_One);
@@ -60,7 +62,12 @@ class SerialPort : public ErrorBase {
void DisableTermination();
int GetBytesReceived();
int Read(char* buffer, int count);
WPI_DEPRECATED(
"Potential for unexpected behavior. Please use StringRef overload for "
"custom length buffers using std::string")
int Write(const std::string& buffer, int count);
int Write(const char* buffer, int count);
int Write(llvm::StringRef buffer);
void SetTimeout(double timeout);
void SetReadBufferSize(int size);
void SetWriteBufferSize(int size);

View File

@@ -20,8 +20,8 @@ namespace frc {
* Wrapper class around std::thread that allows changing thread priority
*/
class WPI_DEPRECATED(
"Task API scheduled for removal in 2018. Replace with std::thread") Task
: public ErrorBase {
"Task API scheduled for removal in 2018. Replace with std::thread, and use "
"Threads API for setting priority") Task : public ErrorBase {
public:
static const int kDefaultPriority = 60;

View File

@@ -0,0 +1,18 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <thread>
namespace frc {
int GetThreadPriority(std::thread& thread, bool* isRealTime);
int GetCurrentThreadPriority(bool* isRealTime);
bool SetThreadPriority(std::thread& thread, bool realTime, int priority);
bool SetCurrentThreadPriority(bool realTime, int priority);
} // namespace frc

View File

@@ -76,6 +76,7 @@
#include "SpeedController.h"
#include "Talon.h"
#include "TalonSRX.h"
#include "Threads.h"
#include "Timer.h"
#include "Ultrasonic.h"
#include "Utility.h"
@@ -86,3 +87,4 @@
#include "interfaces/Accelerometer.h"
#include "interfaces/Gyro.h"
#include "interfaces/Potentiometer.h"
#include "vision/VisionRunner.h"

View File

@@ -0,0 +1,32 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#pragma once
namespace cv {
class Mat;
}
namespace frc {
/**
* A vision pipeline is responsible for running a group of
* OpenCV algorithms to extract data from an image.
*
* @see VisionRunner
*/
class VisionPipeline {
public:
virtual ~VisionPipeline() = default;
/**
* Processes the image input and sets the result objects.
* Implementations should make these objects accessible.
*/
virtual void Process(cv::Mat& mat) = 0;
};
} // namespace frc

View File

@@ -0,0 +1,65 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <functional>
#include <memory>
#include "ErrorBase.h"
#include "cscore.h"
#include "vision/VisionPipeline.h"
namespace frc {
/**
* Non-template base class for VisionRunner.
*/
class VisionRunnerBase : public ErrorBase {
public:
explicit VisionRunnerBase(cs::VideoSource videoSource);
~VisionRunnerBase() override;
VisionRunnerBase(const VisionRunnerBase&) = delete;
VisionRunnerBase& operator=(const VisionRunnerBase&) = delete;
void RunOnce();
void RunForever();
protected:
virtual void DoProcess(cv::Mat& image) = 0;
private:
std::unique_ptr<cv::Mat> m_image;
cs::CvSink m_cvSink;
};
/**
* A vision runner is a convenient wrapper object to make it easy to run vision
* pipelines from robot code. The easiest way to use this is to run it in a
* std::thread and use the listener to take snapshots of the pipeline's outputs.
*
* @see VisionPipeline
*/
template <typename T>
class VisionRunner : public VisionRunnerBase {
public:
VisionRunner(cs::VideoSource videoSource, T* pipeline,
std::function<void(T&)> listener);
virtual ~VisionRunner() = default;
protected:
void DoProcess(cv::Mat& image) override;
private:
T* m_pipeline;
std::function<void(T&)> m_listener;
};
} // namespace frc
#include "VisionRunner.inc"

View File

@@ -0,0 +1,36 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#pragma once
namespace frc {
/**
* Creates a new vision runner. It will take images from the {@code
* videoSource}, send them to the {@code pipeline}, and call the {@code
* listener} when the pipeline has finished to alert user code when it is safe
* to access the pipeline's outputs.
*
* @param videoSource the video source to use to supply images for the pipeline
* @param pipeline the vision pipeline to run
* @param listener a function to call after the pipeline has finished
* running
*/
template <typename T>
VisionRunner<T>::VisionRunner(cs::VideoSource videoSource, T* pipeline,
std::function<void(T&)> listener)
: VisionRunnerBase(videoSource),
m_pipeline(pipeline),
m_listener(listener) {}
template <typename T>
void VisionRunner<T>::DoProcess(cv::Mat& image) {
m_pipeline->Process(image);
m_listener(*m_pipeline);
}
} // namespace frc

View File

@@ -6,10 +6,12 @@
/*----------------------------------------------------------------------------*/
#include "AnalogGyro.h"
#include "HAL/AnalogGyro.h"
#include <climits>
#include "AnalogInput.h"
#include "HAL/Errors.h"
#include "HAL/HAL.h"
#include "LiveWindow/LiveWindow.h"
#include "Timer.h"

View File

@@ -6,10 +6,13 @@
/*----------------------------------------------------------------------------*/
#include "AnalogInput.h"
#include "HAL/AnalogInput.h"
#include <sstream>
#include "HAL/AnalogAccumulator.h"
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "LiveWindow/LiveWindow.h"
#include "Timer.h"
#include "WPIErrors.h"

View File

@@ -11,6 +11,7 @@
#include <sstream>
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "LiveWindow/LiveWindow.h"
#include "WPIErrors.h"
@@ -58,6 +59,11 @@ AnalogOutput::AnalogOutput(int channel) {
*/
AnalogOutput::~AnalogOutput() { HAL_FreeAnalogOutputPort(m_port); }
/**
* Get the channel of this AnalogOutput.
*/
int AnalogOutput::GetChannel() { return m_channel; }
/**
* Set the value of the analog output.
*

View File

@@ -7,6 +7,7 @@
#include "BuiltInAccelerometer.h"
#include "HAL/Accelerometer.h"
#include "HAL/HAL.h"
#include "LiveWindow/LiveWindow.h"
#include "WPIErrors.h"

View File

@@ -24,21 +24,24 @@ static llvm::StringRef MakeSourceValue(CS_Source source,
CS_Status status = 0;
buf.clear();
switch (cs::GetSourceKind(source, &status)) {
case cs::VideoSource::kUSB: {
case cs::VideoSource::kUsb: {
llvm::StringRef prefix{"usb:"};
buf.append(prefix.begin(), prefix.end());
auto path = cs::GetUSBCameraPath(source, &status);
auto path = cs::GetUsbCameraPath(source, &status);
buf.append(path.begin(), path.end());
break;
}
case cs::VideoSource::kHTTP: {
case cs::VideoSource::kHttp: {
llvm::StringRef prefix{"ip:"};
buf.append(prefix.begin(), prefix.end());
// TODO
auto urls = cs::GetHttpCameraUrls(source, &status);
if (!urls.empty()) buf.append(urls[0].begin(), urls[0].end());
break;
}
case cs::VideoSource::kCv:
return "cv:";
// FIXME: Should be "cv:", but LabVIEW dashboard requires "usb:".
// https://github.com/wpilibsuite/allwpilib/issues/407
return "usb:";
default:
return "unknown:";
}
@@ -59,41 +62,78 @@ std::shared_ptr<ITable> CameraServer::GetSourceTable(CS_Source source) {
return m_tables.lookup(source);
}
std::vector<std::string> CameraServer::GetSinkStreamValues(CS_Sink sink) {
CS_Status status = 0;
// Ignore all but MjpegServer
if (cs::GetSinkKind(sink, &status) != CS_SINK_MJPEG)
return std::vector<std::string>{};
// Get port
int port = cs::GetMjpegServerPort(sink, &status);
// Generate values
std::vector<std::string> values;
auto listenAddress = cs::GetMjpegServerListenAddress(sink, &status);
if (!listenAddress.empty()) {
// If a listen address is specified, only use that
values.emplace_back(MakeStreamValue(listenAddress, port));
} else {
// Otherwise generate for hostname and all interface addresses
values.emplace_back(MakeStreamValue(cs::GetHostname() + ".local", port));
for (const auto& addr : m_addresses) {
if (addr == "127.0.0.1") continue; // ignore localhost
values.emplace_back(MakeStreamValue(addr, port));
}
}
return values;
}
static std::vector<std::string> GetSourceStreamValues(CS_Source source) {
CS_Status status = 0;
// Ignore all but HttpCamera
if (cs::GetSourceKind(source, &status) != CS_SOURCE_HTTP)
return std::vector<std::string>{};
// Generate values
auto values = cs::GetHttpCameraUrls(source, &status);
for (auto& value : values) value = "mjpg:" + value;
// Set table value
return values;
}
void CameraServer::UpdateStreamValues() {
std::lock_guard<std::mutex> lock(m_mutex);
// Over all the sinks...
for (const auto& i : m_sinks) {
CS_Status status = 0;
// Ignore all but MJPEGServer
if (i.second.GetKind() != cs::VideoSink::kMJPEG) continue;
CS_Sink sink = i.second.GetHandle();
// Get the source's subtable (if none exists, we're done)
CS_Source source = cs::GetSinkSource(sink, &status);
auto table = m_tables.lookup(source);
if (!table) continue;
// Get port
int port = cs::GetMJPEGServerPort(sink, &status);
// Generate values
std::vector<std::string> values;
auto listenAddress = cs::GetMJPEGServerListenAddress(sink, &status);
if (!listenAddress.empty()) {
// If a listen address is specified, only use that
values.emplace_back(MakeStreamValue(listenAddress, port));
} else {
// Otherwise generate for hostname and all interface addresses
values.emplace_back(MakeStreamValue(cs::GetHostname() + ".local", port));
for (const auto& addr : m_addresses) {
if (addr == "127.0.0.1") continue; // ignore localhost
values.emplace_back(MakeStreamValue(addr, port));
}
if (table) {
// Set table value
auto values = GetSinkStreamValues(sink);
if (!values.empty()) table->PutStringArray("streams", values);
}
}
// Set table value
table->PutStringArray("streams", values);
// Over all the sources...
for (const auto& i : m_sources) {
CS_Source source = i.second.GetHandle();
// Get the source's subtable (if none exists, we're done)
auto table = m_tables.lookup(source);
if (table) {
// Set table value
auto values = GetSourceStreamValues(source);
if (!values.empty()) table->PutStringArray("streams", values);
}
}
}
@@ -127,7 +167,8 @@ CameraServer::CameraServer()
cs::GetSourceDescription(event.sourceHandle, descBuf, &status));
table->PutBoolean("connected", cs::IsSourceConnected(
event.sourceHandle, &status));
table->PutStringArray("streams", std::vector<std::string>{});
table->PutStringArray("streams",
GetSourceStreamValues(event.sourceHandle));
break;
}
case cs::VideoEvent::kSourceDestroyed: {
@@ -197,34 +238,78 @@ CameraServer::CameraServer()
0x7fff, true};
}
cs::USBCamera CameraServer::StartAutomaticCapture() {
cs::UsbCamera CameraServer::StartAutomaticCapture() {
return StartAutomaticCapture(0);
}
cs::USBCamera CameraServer::StartAutomaticCapture(int dev) {
cs::UsbCamera CameraServer::StartAutomaticCapture(int dev) {
llvm::SmallString<64> buf;
llvm::raw_svector_ostream name{buf};
name << "USB Camera " << dev;
cs::USBCamera camera{name.str(), dev};
cs::UsbCamera camera{name.str(), dev};
StartAutomaticCapture(camera);
return camera;
}
cs::USBCamera CameraServer::StartAutomaticCapture(llvm::StringRef name,
cs::UsbCamera CameraServer::StartAutomaticCapture(llvm::StringRef name,
int dev) {
cs::USBCamera camera{name, dev};
cs::UsbCamera camera{name, dev};
StartAutomaticCapture(camera);
return camera;
}
cs::USBCamera CameraServer::StartAutomaticCapture(llvm::StringRef name,
cs::UsbCamera CameraServer::StartAutomaticCapture(llvm::StringRef name,
llvm::StringRef path) {
cs::USBCamera camera{name, path};
cs::UsbCamera camera{name, path};
StartAutomaticCapture(camera);
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef host) {
return AddAxisCamera("Axis Camera", host);
}
cs::AxisCamera CameraServer::AddAxisCamera(const char* host) {
return AddAxisCamera("Axis Camera", host);
}
cs::AxisCamera CameraServer::AddAxisCamera(const std::string& host) {
return AddAxisCamera("Axis Camera", host);
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::ArrayRef<std::string> hosts) {
return AddAxisCamera("Axis Camera", hosts);
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef name,
llvm::StringRef host) {
cs::AxisCamera camera{name, host};
AddCamera(camera);
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef name,
const char* host) {
cs::AxisCamera camera{name, host};
AddCamera(camera);
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef name,
const std::string& host) {
cs::AxisCamera camera{name, host};
AddCamera(camera);
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(llvm::StringRef name,
llvm::ArrayRef<std::string> hosts) {
cs::AxisCamera camera{name, hosts};
AddCamera(camera);
return camera;
}
void CameraServer::StartAutomaticCapture(const cs::VideoSource& camera) {
llvm::SmallString<64> name{"serve_"};
name += camera.GetName();
@@ -278,6 +363,23 @@ cs::CvSink CameraServer::GetVideo(const cs::VideoSource& camera) {
return newsink;
}
cs::CvSink CameraServer::GetVideo(llvm::StringRef name) {
cs::VideoSource source;
{
std::lock_guard<std::mutex> lock(m_mutex);
auto it = m_sources.find(name);
if (it == m_sources.end()) {
llvm::SmallString<64> buf;
llvm::raw_svector_ostream err{buf};
err << "could not find camera " << name;
wpi_setWPIErrorWithContext(CameraServerError, err.str());
return cs::CvSink{};
}
source = it->second;
}
return GetVideo(source);
}
cs::CvSource CameraServer::PutVideo(llvm::StringRef name, int width,
int height) {
cs::CvSource source{name, cs::VideoMode::kMJPEG, width, height, 30};
@@ -285,7 +387,7 @@ cs::CvSource CameraServer::PutVideo(llvm::StringRef name, int width,
return source;
}
cs::MJPEGServer CameraServer::AddServer(llvm::StringRef name) {
cs::MjpegServer CameraServer::AddServer(llvm::StringRef name) {
int port;
{
std::lock_guard<std::mutex> lock(m_mutex);
@@ -294,8 +396,8 @@ cs::MJPEGServer CameraServer::AddServer(llvm::StringRef name) {
return AddServer(name, port);
}
cs::MJPEGServer CameraServer::AddServer(llvm::StringRef name, int port) {
cs::MJPEGServer server{name, port};
cs::MjpegServer CameraServer::AddServer(llvm::StringRef name, int port) {
cs::MjpegServer server{name, port};
AddServer(server);
return server;
}

View File

@@ -6,8 +6,11 @@
/*----------------------------------------------------------------------------*/
#include "Compressor.h"
#include "HAL/Compressor.h"
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "HAL/Solenoid.h"
#include "WPIErrors.h"
using namespace frc;

View File

@@ -12,6 +12,8 @@
#include "Counter.h"
#include "Encoder.h"
#include "HAL/Constants.h"
#include "HAL/DIO.h"
#include "HAL/HAL.h"
#include "Utility.h"
#include "WPIErrors.h"

View File

@@ -10,7 +10,9 @@
#include <limits>
#include <sstream>
#include "HAL/DIO.h"
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "LiveWindow/LiveWindow.h"
#include "WPIErrors.h"

View File

@@ -10,7 +10,9 @@
#include <limits>
#include <sstream>
#include "HAL/DIO.h"
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "WPIErrors.h"
using namespace frc;
@@ -100,7 +102,7 @@ int DigitalOutput::GetChannel() const { return m_channel; }
* Send a single pulse on the digital output line where the pulse duration is
* specified in seconds. Maximum pulse length is 0.0016 seconds.
*
* @param length The pulselength in seconds
* @param length The pulse length in seconds
*/
void DigitalOutput::Pulse(double length) {
if (StatusIsFatal()) return;

View File

@@ -10,6 +10,8 @@
#include <sstream>
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "HAL/Solenoid.h"
#include "LiveWindow/LiveWindow.h"
#include "WPIErrors.h"

View File

@@ -12,11 +12,13 @@
#include "AnalogInput.h"
#include "FRC_NetworkCommunication/FRCComm.h"
#include "HAL/HAL.h"
#include "HAL/Power.h"
#include "HAL/cpp/Log.h"
#include "MotorSafetyHelper.h"
#include "Timer.h"
#include "Utility.h"
#include "WPIErrors.h"
#include "llvm/SmallString.h"
using namespace frc;
@@ -44,8 +46,9 @@ DriverStation& DriverStation::GetInstance() {
*
* The error is also printed to the program console.
*/
void DriverStation::ReportError(std::string error) {
HAL_SendError(1, 1, 0, error.c_str(), "", "", 1);
void DriverStation::ReportError(llvm::StringRef error) {
llvm::SmallString<128> temp;
HAL_SendError(1, 1, 0, error.c_str(temp), "", "", 1);
}
/**
@@ -53,8 +56,9 @@ void DriverStation::ReportError(std::string error) {
*
* The warning is also printed to the program console.
*/
void DriverStation::ReportWarning(std::string error) {
HAL_SendError(0, 1, 0, error.c_str(), "", "", 1);
void DriverStation::ReportWarning(llvm::StringRef error) {
llvm::SmallString<128> temp;
HAL_SendError(0, 1, 0, error.c_str(temp), "", "", 1);
}
/**
@@ -63,11 +67,13 @@ void DriverStation::ReportWarning(std::string error) {
* The error is also printed to the program console.
*/
void DriverStation::ReportError(bool is_error, int32_t code,
const std::string& error,
const std::string& location,
const std::string& stack) {
HAL_SendError(is_error, code, 0, error.c_str(), location.c_str(),
stack.c_str(), 1);
llvm::StringRef error, llvm::StringRef location,
llvm::StringRef stack) {
llvm::SmallString<128> errorTemp;
llvm::SmallString<128> locationTemp;
llvm::SmallString<128> stackTemp;
HAL_SendError(is_error, code, 0, error.c_str(errorTemp),
location.c_str(locationTemp), stack.c_str(stackTemp), 1);
}
/**
@@ -595,7 +601,7 @@ DriverStation::DriverStation() {
* Reports errors related to unplugged joysticks
* Throttles the errors so that they don't overwhelm the DS
*/
void DriverStation::ReportJoystickUnpluggedError(std::string message) {
void DriverStation::ReportJoystickUnpluggedError(llvm::StringRef message) {
double currentTime = Timer::GetFPGATimestamp();
if (currentTime > m_nextMessageTime) {
ReportError(message);
@@ -608,7 +614,7 @@ void DriverStation::ReportJoystickUnpluggedError(std::string message) {
*
* Throttles the errors so that they don't overwhelm the DS.
*/
void DriverStation::ReportJoystickUnpluggedWarning(std::string message) {
void DriverStation::ReportJoystickUnpluggedWarning(llvm::StringRef message) {
double currentTime = Timer::GetFPGATimestamp();
if (currentTime > m_nextMessageTime) {
ReportWarning(message);

View File

@@ -5,6 +5,7 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include "HAL/I2C.h"
#include "I2C.h"
#include "HAL/HAL.h"
@@ -158,8 +159,8 @@ bool I2C::ReadOnly(int count, uint8_t* buffer) {
* @param registerAddress The register to write on all devices on the bus.
* @param data The value to write to the devices.
*/
[[gnu::warning("I2C::Broadcast() is not implemented.")]] void I2C::Broadcast(
int registerAddress, uint8_t data) {}
// [[gnu::warning("I2C::Broadcast() is not implemented.")]] void I2C::Broadcast(
// int registerAddress, uint8_t data) {}
/**
* Verify that a device's registers contain expected values.

View File

@@ -5,11 +5,13 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include "HAL/PWM.h"
#include "PWM.h"
#include <sstream>
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "Utility.h"
#include "WPIErrors.h"

View File

@@ -10,6 +10,8 @@
#include <sstream>
#include "HAL/HAL.h"
#include "HAL/PDP.h"
#include "HAL/Ports.h"
#include "LiveWindow/LiveWindow.h"
#include "WPIErrors.h"

View File

@@ -11,11 +11,12 @@
#include "HAL/HAL.h"
#include "WPIErrors.h"
#include "llvm/StringRef.h"
using namespace frc;
/** The Preferences table name */
static const char* kTableName = "Preferences";
static llvm::StringRef kTableName{"Preferences"};
void Preferences::Listener::ValueChanged(ITable* source, llvm::StringRef key,
std::shared_ptr<nt::Value> value,

View File

@@ -5,11 +5,13 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include "HAL/Relay.h"
#include "Relay.h"
#include <sstream>
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "LiveWindow/LiveWindow.h"
#include "MotorSafetyHelper.h"
#include "WPIErrors.h"

View File

@@ -20,6 +20,8 @@
using namespace frc;
std::thread::id RobotBase::m_threadId;
/**
* Constructor for a generic robot program.
*
@@ -32,6 +34,8 @@ using namespace frc;
* boot so ensure that it runs.
*/
RobotBase::RobotBase() : m_ds(DriverStation::GetInstance()) {
m_threadId = std::this_thread::get_id();
RobotState::SetImplementation(DriverStation::GetInstance());
HLUsageReporting::SetImplementation(new HardwareHLReporting());
@@ -42,6 +46,7 @@ RobotBase::RobotBase() : m_ds(DriverStation::GetInstance()) {
file = std::fopen("/tmp/frc_versions/FRC_Lib_Version.ini", "w");
if (file != nullptr) {
std::fputs("C++ ", file);
std::fputs(WPILibVersion, file);
std::fclose(file);
}
@@ -86,3 +91,8 @@ bool RobotBase::IsTest() const { return m_ds.IsTest(); }
* function was called?
*/
bool RobotBase::IsNewDataAvailable() const { return m_ds.IsNewControlData(); }
/**
* Gets the ID of the main robot thread
*/
std::thread::id RobotBase::GetThreadId() { return m_threadId; }

View File

@@ -5,6 +5,7 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include "HAL/SPI.h"
#include "SPI.h"
#include <cstring>

View File

@@ -8,7 +8,15 @@
#include "SensorBase.h"
#include "FRC_NetworkCommunication/LoadOut.h"
#include "HAL/AnalogInput.h"
#include "HAL/AnalogOutput.h"
#include "HAL/DIO.h"
#include "HAL/HAL.h"
#include "HAL/PDP.h"
#include "HAL/PWM.h"
#include "HAL/Ports.h"
#include "HAL/Relay.h"
#include "HAL/Solenoid.h"
#include "WPIErrors.h"
using namespace frc;

View File

@@ -5,6 +5,7 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include "HAL/SerialPort.h"
#include "SerialPort.h"
#include "HAL/HAL.h"
@@ -32,15 +33,17 @@ SerialPort::SerialPort(int baudRate, Port port, int dataBits,
m_port = port;
HAL_InitializeSerialPort(port, &status);
HAL_InitializeSerialPort(static_cast<HAL_SerialPort>(port), &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
HAL_SetSerialBaudRate(port, baudRate, &status);
// Don't continue if initialization failed
if (status < 0) return;
HAL_SetSerialBaudRate(static_cast<HAL_SerialPort>(port), baudRate, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
HAL_SetSerialDataBits(port, dataBits, &status);
HAL_SetSerialDataBits(static_cast<HAL_SerialPort>(port), dataBits, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
HAL_SetSerialParity(port, parity, &status);
HAL_SetSerialParity(static_cast<HAL_SerialPort>(port), parity, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
HAL_SetSerialStopBits(port, stopBits, &status);
HAL_SetSerialStopBits(static_cast<HAL_SerialPort>(port), stopBits, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
// Set the default timeout to 5 seconds.
@@ -63,7 +66,7 @@ SerialPort::SerialPort(int baudRate, Port port, int dataBits,
*/
SerialPort::~SerialPort() {
int32_t status = 0;
HAL_CloseSerial(m_port, &status);
HAL_CloseSerial(static_cast<HAL_SerialPort>(m_port), &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -74,7 +77,8 @@ SerialPort::~SerialPort() {
*/
void SerialPort::SetFlowControl(SerialPort::FlowControl flowControl) {
int32_t status = 0;
HAL_SetSerialFlowControl(m_port, flowControl, &status);
HAL_SetSerialFlowControl(static_cast<HAL_SerialPort>(m_port), flowControl,
&status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -89,7 +93,8 @@ void SerialPort::SetFlowControl(SerialPort::FlowControl flowControl) {
*/
void SerialPort::EnableTermination(char terminator) {
int32_t status = 0;
HAL_EnableSerialTermination(m_port, terminator, &status);
HAL_EnableSerialTermination(static_cast<HAL_SerialPort>(m_port), terminator,
&status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -98,7 +103,7 @@ void SerialPort::EnableTermination(char terminator) {
*/
void SerialPort::DisableTermination() {
int32_t status = 0;
HAL_DisableSerialTermination(m_port, &status);
HAL_DisableSerialTermination(static_cast<HAL_SerialPort>(m_port), &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -109,7 +114,8 @@ void SerialPort::DisableTermination() {
*/
int SerialPort::GetBytesReceived() {
int32_t status = 0;
int retVal = HAL_GetSerialBytesReceived(m_port, &status);
int retVal =
HAL_GetSerialBytesReceived(static_cast<HAL_SerialPort>(m_port), &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
@@ -123,11 +129,27 @@ int SerialPort::GetBytesReceived() {
*/
int SerialPort::Read(char* buffer, int count) {
int32_t status = 0;
int retVal = HAL_ReadSerial(m_port, buffer, count, &status);
int retVal = HAL_ReadSerial(static_cast<HAL_SerialPort>(m_port), buffer,
count, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Write raw bytes to the buffer. Deprecated, please use StringRef overload. Use
* Write({data, len}) to get a buffer that is shorter then the length of the
* std::string.
*
* @param buffer Pointer to the buffer to read the bytes from. If string.size()
* is less then count, only the length of string.size() will be sent.
* @param count The maximum number of bytes to write.
* @return The number of bytes actually written into the port.
*/
int SerialPort::Write(const std::string& buffer, int count) {
return Write(llvm::StringRef(
buffer.data(), std::min(static_cast<int>(buffer.size()), count)));
}
/**
* Write raw bytes to the buffer.
*
@@ -135,9 +157,20 @@ int SerialPort::Read(char* buffer, int count) {
* @param count The maximum number of bytes to write.
* @return The number of bytes actually written into the port.
*/
int SerialPort::Write(const std::string& buffer, int count) {
int SerialPort::Write(const char* buffer, int count) {
return Write(llvm::StringRef(buffer, static_cast<size_t>(count)));
}
/**
* Write raw bytes to the buffer.
*
* @param buffer StringRef to the buffer to read the bytes from.
* @return The number of bytes actually written into the port.
*/
int SerialPort::Write(llvm::StringRef buffer) {
int32_t status = 0;
int retVal = HAL_WriteSerial(m_port, buffer.c_str(), count, &status);
int retVal = HAL_WriteSerial(static_cast<HAL_SerialPort>(m_port),
buffer.data(), buffer.size(), &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
@@ -152,7 +185,7 @@ int SerialPort::Write(const std::string& buffer, int count) {
*/
void SerialPort::SetTimeout(double timeout) {
int32_t status = 0;
HAL_SetSerialTimeout(m_port, timeout, &status);
HAL_SetSerialTimeout(static_cast<HAL_SerialPort>(m_port), timeout, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -170,7 +203,8 @@ void SerialPort::SetTimeout(double timeout) {
*/
void SerialPort::SetReadBufferSize(int size) {
int32_t status = 0;
HAL_SetSerialReadBufferSize(m_port, size, &status);
HAL_SetSerialReadBufferSize(static_cast<HAL_SerialPort>(m_port), size,
&status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -184,7 +218,8 @@ void SerialPort::SetReadBufferSize(int size) {
*/
void SerialPort::SetWriteBufferSize(int size) {
int32_t status = 0;
HAL_SetSerialWriteBufferSize(m_port, size, &status);
HAL_SetSerialWriteBufferSize(static_cast<HAL_SerialPort>(m_port), size,
&status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -201,7 +236,7 @@ void SerialPort::SetWriteBufferSize(int size) {
*/
void SerialPort::SetWriteBufferMode(SerialPort::WriteBufferMode mode) {
int32_t status = 0;
HAL_SetSerialWriteMode(m_port, mode, &status);
HAL_SetSerialWriteMode(static_cast<HAL_SerialPort>(m_port), mode, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -213,7 +248,7 @@ void SerialPort::SetWriteBufferMode(SerialPort::WriteBufferMode mode) {
*/
void SerialPort::Flush() {
int32_t status = 0;
HAL_FlushSerial(m_port, &status);
HAL_FlushSerial(static_cast<HAL_SerialPort>(m_port), &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
@@ -224,6 +259,6 @@ void SerialPort::Flush() {
*/
void SerialPort::Reset() {
int32_t status = 0;
HAL_ClearSerial(m_port, &status);
HAL_ClearSerial(static_cast<HAL_SerialPort>(m_port), &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}

View File

@@ -5,11 +5,13 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include "HAL/Solenoid.h"
#include "Solenoid.h"
#include <sstream>
#include "HAL/HAL.h"
#include "HAL/Ports.h"
#include "LiveWindow/LiveWindow.h"
#include "WPIErrors.h"

View File

@@ -8,6 +8,7 @@
#include "SolenoidBase.h"
#include "HAL/HAL.h"
#include "HAL/Solenoid.h"
using namespace frc;

View File

@@ -0,0 +1,82 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#include "HAL/Threads.h"
#include "Threads.h"
#include "ErrorBase.h"
#include "HAL/HAL.h"
namespace frc {
/**
* Get the thread priority for the specified thread.
*
* @param thread Reference to the thread to get the priority for
* @param isRealTime Set to true if thread is realtime, otherwise false
* @return The current thread priority. Scaled 1-99, with 1 being highest.
*/
int GetThreadPriority(std::thread& thread, bool* isRealTime) {
int32_t status = 0;
HAL_Bool rt = false;
auto native = thread.native_handle();
auto ret = HAL_GetThreadPriority(&native, &rt, &status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
*isRealTime = rt;
return ret;
}
/**
* Get the thread priority for the current thread
*
* @param isRealTime Set to true if thread is realtime, otherwise false
* @return The current thread priority. Scaled 1-99.
*/
int GetCurrentThreadPriority(bool* isRealTime) {
int32_t status = 0;
HAL_Bool rt = false;
auto ret = HAL_GetCurrentThreadPriority(&rt, &status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
*isRealTime = rt;
return ret;
}
/**
* Sets the thread priority for the specified thread
*
* @param thread Reference to the thread to set the priority of
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest. On RoboRIO, priority is ignored for non realtime setting
*
* @return The success state of setting the priority
*/
bool SetThreadPriority(std::thread& thread, bool realTime, int priority) {
int32_t status = 0;
auto native = thread.native_handle();
auto ret = HAL_SetThreadPriority(&native, realTime, priority, &status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return ret;
}
/**
* Sets the thread priority for the current thread
*
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest. On RoboRIO, priority is ignored for non realtime setting
*
* @return The success state of setting the priority
*/
bool SetCurrentThreadPriority(bool realTime, int priority) {
int32_t status = 0;
auto ret = HAL_SetCurrentThreadPriority(realTime, priority, &status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return ret;
}
} // namespace frc

View File

@@ -16,7 +16,9 @@
#include <sstream>
#include "ErrorBase.h"
#include "HAL/DriverStation.h"
#include "HAL/HAL.h"
#include "llvm/SmallString.h"
using namespace frc;
@@ -26,13 +28,14 @@ using namespace frc;
* The users don't call this, but instead use the wpi_assert macros in
* Utility.h.
*/
bool wpi_assert_impl(bool conditionValue, const char* conditionText,
const char* message, const char* fileName, int lineNumber,
const char* funcName) {
bool wpi_assert_impl(bool conditionValue, llvm::StringRef conditionText,
llvm::StringRef message, llvm::StringRef fileName,
int lineNumber, llvm::StringRef funcName) {
if (!conditionValue) {
std::stringstream locStream;
locStream << funcName << " [";
locStream << basename(fileName) << ":" << lineNumber << "]";
llvm::SmallString<128> fileTemp;
locStream << basename(fileName.c_str(fileTemp)) << ":" << lineNumber << "]";
std::stringstream errorStream;
@@ -60,13 +63,15 @@ bool wpi_assert_impl(bool conditionValue, const char* conditionText,
* This should not be called directly; it should only be used by
* wpi_assertEqual_impl and wpi_assertNotEqual_impl.
*/
void wpi_assertEqual_common_impl(const char* valueA, const char* valueB,
const char* equalityType, const char* message,
const char* fileName, int lineNumber,
const char* funcName) {
void wpi_assertEqual_common_impl(llvm::StringRef valueA, llvm::StringRef valueB,
llvm::StringRef equalityType,
llvm::StringRef message,
llvm::StringRef fileName, int lineNumber,
llvm::StringRef funcName) {
std::stringstream locStream;
locStream << funcName << " [";
locStream << basename(fileName) << ":" << lineNumber << "]";
llvm::SmallString<128> fileTemp;
locStream << basename(fileName.c_str(fileTemp)) << ":" << lineNumber << "]";
std::stringstream errorStream;
@@ -94,10 +99,10 @@ void wpi_assertEqual_common_impl(const char* valueA, const char* valueB,
* The users don't call this, but instead use the wpi_assertEqual macros in
* Utility.h.
*/
bool wpi_assertEqual_impl(int valueA, int valueB, const char* valueAString,
const char* valueBString, const char* message,
const char* fileName, int lineNumber,
const char* funcName) {
bool wpi_assertEqual_impl(int valueA, int valueB, llvm::StringRef valueAString,
llvm::StringRef valueBString, llvm::StringRef message,
llvm::StringRef fileName, int lineNumber,
llvm::StringRef funcName) {
if (!(valueA == valueB)) {
wpi_assertEqual_common_impl(valueAString, valueBString, "==", message,
fileName, lineNumber, funcName);
@@ -112,10 +117,11 @@ bool wpi_assertEqual_impl(int valueA, int valueB, const char* valueAString,
* The users don't call this, but instead use the wpi_assertNotEqual macros in
* Utility.h.
*/
bool wpi_assertNotEqual_impl(int valueA, int valueB, const char* valueAString,
const char* valueBString, const char* message,
const char* fileName, int lineNumber,
const char* funcName) {
bool wpi_assertNotEqual_impl(int valueA, int valueB,
llvm::StringRef valueAString,
llvm::StringRef valueBString,
llvm::StringRef message, llvm::StringRef fileName,
int lineNumber, llvm::StringRef funcName) {
if (!(valueA != valueB)) {
wpi_assertEqual_common_impl(valueAString, valueBString, "!=", message,
fileName, lineNumber, funcName);

View File

@@ -0,0 +1,76 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#include "vision/VisionRunner.h"
#include "DriverStation.h"
#include "RobotBase.h"
#include "opencv2/core/mat.hpp"
using namespace frc;
/**
* Creates a new vision runner. It will take images from the {@code
* videoSource}, and call the virtual DoProcess() method.
*
* @param videoSource the video source to use to supply images for the pipeline
*/
VisionRunnerBase::VisionRunnerBase(cs::VideoSource videoSource)
: m_image(std::make_unique<cv::Mat>()), m_cvSink("VisionRunner CvSink") {
m_cvSink.SetSource(videoSource);
}
// Located here and not in header due to cv::Mat forward declaration.
VisionRunnerBase::~VisionRunnerBase() {}
/**
* Runs the pipeline one time, giving it the next image from the video source
* specified in the constructor. This will block until the source either has an
* image or throws an error. If the source successfully supplied a frame, the
* pipeline's image input will be set, the pipeline will run, and the listener
* specified in the constructor will be called to notify it that the pipeline
* ran. This must be run in a dedicated thread, and cannot be used in the main
* robot thread because it will freeze the robot program.
*
* <p>This method is exposed to allow teams to add additional functionality or
* have their own ways to run the pipeline. Most teams, however, should just
* use {@link #runForever} in its own thread using a std::thread.</p>
*/
void VisionRunnerBase::RunOnce() {
if (std::this_thread::get_id() == RobotBase::GetThreadId()) {
wpi_setErrnoErrorWithContext(
"VisionRunner::RunOnce() cannot be called from the main robot thread");
return;
}
auto frameTime = m_cvSink.GrabFrame(*m_image);
if (frameTime == 0) {
auto error = m_cvSink.GetError();
DriverStation::ReportError(error);
} else {
DoProcess(*m_image);
}
}
/**
* A convenience method that calls {@link #runOnce()} in an infinite loop. This
* must be run in a dedicated thread, and cannot be used in the main robot
* thread because it will freeze the robot program.
*
* <p><strong>Do not call this method directly from the main
* thread.</strong></p>
*/
void VisionRunnerBase::RunForever() {
if (std::this_thread::get_id() == RobotBase::GetThreadId()) {
wpi_setErrnoErrorWithContext(
"VisionRunner::RunForever() cannot be called from the main robot "
"thread");
return;
}
while (true) {
RunOnce();
}
}

View File

@@ -65,6 +65,6 @@ ext.checkDoxygen = {
apply from: 'athena.gradle'
if (hasProperty('makeSim')){
if (enableSimulation){
apply from: 'simulation.gradle'
}

View File

@@ -15,6 +15,8 @@
#include <string>
#include "llvm/StringRef.h"
#define wpi_assert(condition) \
wpi_assert_impl(condition, #condition, "", __FILE__, __LINE__, __FUNCTION__)
#define wpi_assertWithMessage(condition, message) \
@@ -32,17 +34,18 @@
wpi_assertNotEqual_impl(a, b, #a, #b, message, __FILE__, __LINE__, \
__FUNCTION__)
bool wpi_assert_impl(bool conditionValue, const char* conditionText,
const char* message, const char* fileName, int lineNumber,
const char* funcName);
bool wpi_assertEqual_impl(int valueA, int valueB, const char* valueAString,
const char* valueBString, const char* message,
const char* fileName, int lineNumber,
const char* funcName);
bool wpi_assertNotEqual_impl(int valueA, int valueB, const char* valueAString,
const char* valueBString, const char* message,
const char* fileName, int lineNumber,
const char* funcName);
bool wpi_assert_impl(bool conditionValue, llvm::StringRef conditionText,
llvm::StringRef message, llvm::StringRef fileName,
int lineNumber, llvm::StringRef funcName);
bool wpi_assertEqual_impl(int valueA, int valueB, llvm::StringRef valueAString,
llvm::StringRef valueBString, llvm::StringRef message,
llvm::StringRef fileName, int lineNumber,
llvm::StringRef funcName);
bool wpi_assertNotEqual_impl(int valueA, int valueB,
llvm::StringRef valueAString,
llvm::StringRef valueBString,
llvm::StringRef message, llvm::StringRef fileName,
int lineNumber, llvm::StringRef funcName);
void wpi_suspendOnAssertEnabled(bool enabled);

View File

@@ -15,6 +15,7 @@
#include "RobotState.h"
#include "SensorBase.h"
#include "llvm/StringRef.h"
#include "simulation/gz_msgs/msgs.h"
#ifdef _WIN32
@@ -38,11 +39,10 @@ class DriverStation : public SensorBase, public RobotStateInterface {
virtual ~DriverStation() = default;
static DriverStation& GetInstance();
static void ReportError(std::string error);
static void ReportWarning(std::string error);
static void ReportError(bool is_error, int code, const std::string& error,
const std::string& location,
const std::string& stack);
static void ReportError(llvm::StringRef error);
static void ReportWarning(llvm::StringRef error);
static void ReportError(bool is_error, int code, llvm::StringRef error,
llvm::StringRef location, llvm::StringRef stack);
static const int kBatteryChannel = 7;
static const int kJoystickPorts = 4;

View File

@@ -330,7 +330,7 @@ double DriverStation::GetMatchTime() const {
* Report an error to the DriverStation messages window.
* The error is also printed to the program console.
*/
void DriverStation::ReportError(std::string error) {
void DriverStation::ReportError(llvm::StringRef error) {
std::cout << error << std::endl;
}
@@ -338,7 +338,7 @@ void DriverStation::ReportError(std::string error) {
* Report a warning to the DriverStation messages window.
* The warning is also printed to the program console.
*/
void DriverStation::ReportWarning(std::string error) {
void DriverStation::ReportWarning(llvm::StringRef error) {
std::cout << error << std::endl;
}
@@ -346,10 +346,9 @@ void DriverStation::ReportWarning(std::string error) {
* Report an error to the DriverStation messages window.
* The error is also printed to the program console.
*/
void DriverStation::ReportError(bool is_error, int code,
const std::string& error,
const std::string& location,
const std::string& stack) {
void DriverStation::ReportError(bool is_error, int code, llvm::StringRef error,
llvm::StringRef location,
llvm::StringRef stack) {
if (!location.empty())
std::cout << (is_error ? "Error" : "Warning") << " at " << location << ": ";
std::cout << error << std::endl;

View File

@@ -18,6 +18,7 @@
#include <sstream>
#include "Timer.h"
#include "llvm/SmallString.h"
#include "simulation/simTime.h"
using namespace frc;
@@ -56,15 +57,17 @@ static void wpi_handleTracing() {
* The users don't call this, but instead use the wpi_assert macros in
* Utility.h.
*/
bool wpi_assert_impl(bool conditionValue, const char* conditionText,
const char* message, const char* fileName, int lineNumber,
const char* funcName) {
bool wpi_assert_impl(bool conditionValue, llvm::StringRef conditionText,
llvm::StringRef message, llvm::StringRef fileName,
int lineNumber, llvm::StringRef funcName) {
if (!conditionValue) {
std::stringstream errorStream;
errorStream << "Assertion \"" << conditionText << "\" ";
errorStream << "on line " << lineNumber << " ";
errorStream << "of " << basename(fileName) << " ";
llvm::SmallString<128> fileTemp;
errorStream << "of " << basename(fileName.c_str(fileTemp)) << " ";
if (message[0] != '\0') {
errorStream << "failed: " << message << std::endl;
@@ -86,10 +89,10 @@ bool wpi_assert_impl(bool conditionValue, const char* conditionText,
* wpi_assertEqual_impl and wpi_assertNotEqual_impl.
*/
void wpi_assertEqual_common_impl(int valueA, int valueB,
const std::string& equalityType,
const std::string& message,
const std::string& fileName, int lineNumber,
const std::string& funcName) {
llvm::StringRef equalityType,
llvm::StringRef message,
llvm::StringRef fileName, int lineNumber,
llvm::StringRef funcName) {
// Error string buffer
std::stringstream error;
@@ -118,9 +121,9 @@ void wpi_assertEqual_common_impl(int valueA, int valueB,
* The users don't call this, but instead use the wpi_assertEqual macros in
* Utility.h.
*/
bool wpi_assertEqual_impl(int valueA, int valueB, const std::string& message,
const std::string& fileName, int lineNumber,
const std::string& funcName) {
bool wpi_assertEqual_impl(int valueA, int valueB, llvm::StringRef message,
llvm::StringRef fileName, int lineNumber,
llvm::StringRef funcName) {
if (!(valueA == valueB)) {
wpi_assertEqual_common_impl(valueA, valueB, "!=", message, fileName,
lineNumber, funcName);
@@ -135,9 +138,9 @@ bool wpi_assertEqual_impl(int valueA, int valueB, const std::string& message,
* The users don't call this, but instead use the wpi_assertNotEqual macros in
* Utility.h.
*/
bool wpi_assertNotEqual_impl(int valueA, int valueB, const std::string& message,
const std::string& fileName, int lineNumber,
const std::string& funcName) {
bool wpi_assertNotEqual_impl(int valueA, int valueB, llvm::StringRef message,
llvm::StringRef fileName, int lineNumber,
llvm::StringRef funcName) {
if (!(valueA != valueB)) {
wpi_assertEqual_common_impl(valueA, valueB, "==", message, fileName,
lineNumber, funcName);

View File

@@ -54,7 +54,7 @@ task gz_msgs(type: Exec, dependsOn: cmake) {
}
}
task wpilibcSim(type: Exec, dependsOn: ['cmake', ':unzipNetworkTables', ':unzipWpiUtil', 'generateCppVersion']) {
task wpilibcSim(type: Exec, dependsOn: ['cmake', ':downloadNetworkTables', ':downloadWpiutil', 'generateCppVersion']) {
description = 'build WPILib C++ for simulation with cmake'
group = 'WPILib Simulation'
workingDir '../build'

View File

@@ -11,7 +11,7 @@ ext.hal = project(':hal').projectDir.getAbsolutePath()
model {
components {
FRCUserProgram(NativeExecutableSpec) {
targetPlatform 'arm'
targetPlatform 'roborio-arm'
binaries.all {
tasks.withType(CppCompile) {
cppCompiler.args "-DNAMESPACED_WPILIB"

View File

@@ -0,0 +1,27 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. 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. */
/*----------------------------------------------------------------------------*/
#include "vision/VisionRunner.h"
using namespace frc;
class VisionTester : public VisionPipeline {
public:
virtual ~VisionTester() = default;
void Process(cv::Mat& mat) override {}
void TestThing() {}
};
void TestVisionInitialization() {
cs::CvSource source;
VisionTester tester;
VisionRunner<VisionTester> runner(source, &tester,
[](VisionTester& t) { t.TestThing(); });
runner.RunOnce();
runner.RunForever();
}

View File

@@ -2,7 +2,7 @@ apply plugin: 'cpp'
def jniDir = 'src/athena/cpp'
def generatedJNIHeaderLoc = "$buildDir/include"
def ntSourceDir = "$buildDir/ntSources"
def docSource = "$buildDir/docSource"
debugStripSetup(project)
@@ -10,14 +10,18 @@ sourceSets {
athena
}
configurations.create('doc')
dependencies {
athenaCompile sourceSets.shared.output
athenaCompile 'edu.wpi.first.wpilib.networktables.java:NetworkTables:+:arm'
athenaRuntime 'edu.wpi.first.wpilib.networktables.java:NetworkTables:+:arm'
athenaCompile 'edu.wpi.cscore.java:cscore:+:arm'
athenaRuntime 'edu.wpi.cscore.java:cscore:+:arm'
athenaCompile ntcoreDep('java', 'arm')
athenaRuntime ntcoreDep('java', 'arm')
athenaCompile cscoreDep('java', 'arm')
athenaRuntime cscoreDep('java', 'arm')
athenaCompile 'org.opencv:opencv-java:+'
athenaRuntime 'org.opencv:opencv-java:+'
doc ntcoreDep('java', 'sources')
doc cscoreDep('java', 'sources')
}
defineWpiUtilProperties()
@@ -26,7 +30,7 @@ defineWpiUtilProperties()
model {
components {
wpilibJavaJNI(NativeLibrarySpec) {
targetPlatform 'arm'
targetPlatform 'roborio-arm'
binaries.all {
tasks.withType(CppCompile) {
dependsOn jniHeaders
@@ -54,6 +58,10 @@ model {
}
}
}
tasks {
it.wpilibjNativeLibraries.dependsOn it.wpilibJavaJNISharedLibrary
it.checkJNISymbols.dependsOn it.wpilibJavaJNISharedLibrary
}
}
// Maven publishing configuration
@@ -91,11 +99,8 @@ jar {
from sourceSets.shared.output
}
tasks.whenTaskAdded { task ->
if (task.name == 'wpilibJavaJNISharedLibrary') {
jar.dependsOn task
wpilibjNativeLibraries.dependsOn task
}
pmd {
sourceSets = [sourceSets.shared, sourceSets.athena]
}
task wpilibjSources(type: Jar, dependsOn: classes) {
@@ -108,26 +113,16 @@ task wpilibjSources(type: Jar, dependsOn: classes) {
from sourceSets.shared.allJava
}
task unzipJavaNtSources(type: Copy) {
description = 'Unzips the java networktables sources for doc creation'
group = 'WPILib'
doFirst {
def ntSourcesDependency =
project.dependencies.create('edu.wpi.first.wpilib.networktables.java:NetworkTables:+:sources@jar')
def ntSourcesConfig = project.configurations.detachedConfiguration(ntSourcesDependency)
ntSourcesDependency.setTransitive(false)
def ntSources = ntSourcesConfig.singleFile
}
doLast {
from zipTree(ntSources)
exclude 'META-INF/*'
into ntSourceDir
task unzipDocSources(type: Copy) {
configurations.doc.files.each {
from zipTree(it)
}
include '**/*.java'
into docSource
}
task javadoc(type: Javadoc, overwrite: true) {
dependsOn unzipJavaNtSources
source sourceSets.athena.allJava, sourceSets.shared.allJava, unzipJavaNtSources.outputs.files
source sourceSets.athena.allJava, sourceSets.shared.allJava, unzipDocSources
classpath = files([sourceSets.athena.compileClasspath, sourceSets.shared.compileClasspath])
javadoc.options.links("http://docs.oracle.com/javase/8/docs/api/")
options.addStringOption "tag", "pre:a:Pre-Condition"
@@ -180,6 +175,50 @@ task jniHeaders {
args 'edu.wpi.first.wpilibj.hal.PDPJNI'
args 'edu.wpi.first.wpilibj.hal.PowerJNI'
args 'edu.wpi.first.wpilibj.hal.SerialPortJNI'
args 'edu.wpi.first.wpilibj.hal.ThreadsJNI'
}
}
}
task checkJNISymbols() {
description = 'Checks to make sure all native JNI symbols exist'
group = 'WPILib'
dependsOn jniHeaders
def nmOutput = new ByteArrayOutputStream()
def lib
model {
binaries {
withType(SharedLibraryBinarySpec) { spec ->
lib = new File(spec.sharedLibraryFile.absolutePath)
}
}
}
doLast {
defineCrossCompilerProperties()
exec {
commandLine binTool('nm'), lib
standardOutput = nmOutput
}
// Remove '\r' so we can check for full string contents
String nmSymbols = nmOutput.toString().replace('\r', '')
jniHeaders.outputs.files.each {
FileTree tree = fileTree(dir: it)
tree.each { File file ->
file.eachLine { line ->
if (line.trim()) {
if (line.startsWith("JNIEXPORT ") && line.contains('JNICALL')) {
def (p1, p2) = line.split('JNICALL').collect { it.trim() }
// p2 is our JNI call. Add \n so we can check for the exact symbol
def found = nmSymbols.contains(p2 + '\n')
if (!found) {
throw new GradleException("Found a definition that does not have a matching symbol ${p2}")
}
}
}
}
}
}
}
}
@@ -211,9 +250,10 @@ task wpilibjNativeLibraries(type: Jar) {
}
}
build.dependsOn checkJNISymbols
build.dependsOn wpilibjNativeLibraries
clean {
delete generatedJNIHeaderLoc
delete ntSourceDir
delete docSource
}

View File

@@ -1,6 +1,7 @@
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'net.ltgt.errorprone'
apply plugin: 'pmd'
configurations.errorprone {
resolutionStrategy.force 'com.google.errorprone:error_prone_core:2.0.9'
@@ -52,6 +53,13 @@ clean {
delete wpilibVersionFile
}
pmd {
consoleOutput = true
reportsDir = file("$project.buildDir/reports/pmd")
ruleSetFiles = files(new File(rootDir, "styleguide/pmd-ruleset.xml"))
ruleSets = []
}
sourceSets {
shared
}
@@ -59,18 +67,18 @@ sourceSets {
compileSharedJava.dependsOn generateJavaVersion
dependencies {
sharedCompile 'edu.wpi.first.wpilib.networktables.java:NetworkTables:+:arm'
sharedRuntime 'edu.wpi.first.wpilib.networktables.java:NetworkTables:+:arm'
sharedCompile ntcoreDep('java', 'arm')
sharedRuntime ntcoreDep('java', 'arm')
testCompile 'org.hamcrest:hamcrest-all:1.3'
testCompile 'junit:junit:4.12'
testCompile 'edu.wpi.first.wpilib.networktables.java:NetworkTables:+:desktop'
testCompile ntcoreDep('java', 'desktop')
testCompile 'com.google.guava:guava:19.0'
testCompile sourceSets.shared.output
}
apply from: 'athena.gradle'
if (project.hasProperty('makeSim')) {
if (enableSimulation) {
apply from: 'simulation.gradle'
}

View File

@@ -5,8 +5,8 @@ sourceSets {
dependencies {
simCompile sourceSets.shared.output
simCompile project(':simulation:JavaGazebo')
simCompile 'edu.wpi.first.wpilib.networktables.java:NetworkTables:+:desktop'
simRuntime "edu.wpi.first.wpilib.networktables.java:NetworkTables:+:desktop"
simCompile ntcoreDep('java', 'desktop')
simRuntime ntcoreDep('java', 'desktop')
}
task wpilibjSimJar(type: Jar, dependsOn: simClasses) {

View File

@@ -5,7 +5,9 @@
/* the project. */
/*----------------------------------------------------------------------------*/
#include "HAL/HAL.h"
#include "HAL/Compressor.h"
#include "HAL/Ports.h"
#include "HAL/Solenoid.h"
#include "HALUtil.h"
#include "HAL/cpp/Log.h"
#include "edu_wpi_first_wpilibj_hal_CompressorJNI.h"

View File

@@ -6,7 +6,7 @@
/*----------------------------------------------------------------------------*/
#include <jni.h>
#include "HAL/HAL.h"
#include "HAL/DIO.h"
#include "HALUtil.h"
#include "edu_wpi_first_wpilibj_hal_DigitalGlitchFilterJNI.h"

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