Applies Google Styleguide to Java parts of the library (#23)

This was partially applied to simulation but
simulation is a bit of a mess and has a lot of duplicated code.
This commit is contained in:
Jonathan Leitschuh
2016-05-20 12:07:40 -04:00
committed by Peter Johnson
parent 64ab6e51fe
commit a834fff7b2
266 changed files with 15574 additions and 14718 deletions

View File

@@ -27,6 +27,12 @@ allprojects {
subprojects {
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'checkstyle'
checkstyle {
toolVersion = "6.18"
configFile = new File(rootDir, "styleguide/checkstyle.xml")
}
ext.armBuild = true

215
styleguide/checkstyle.xml Normal file
View File

@@ -0,0 +1,215 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the Google coding conventions from Google Java Style
that can be found at https://google.github.io/styleguide/javaguide.html.
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net (or in your downloaded distribution).
To completely disable a check, just comment it out or delete it from the file.
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
-->
<module name = "Checker">
<property name="charset" value="UTF-8"/>
<property name="severity" value="error"/>
<module name="SuppressionFilter">
<property name="file" value="styleguide/suppressions.xml" />
</module>
<property name="fileExtensions" value="java, properties, xml"/>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="SuppressWarningsFilter" />
<module name="TreeWalker">
<module name="SuppressWarningsHolder" />
<module name="OuterTypeFilename"/>
<module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
<property name="format" value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message" value="Avoid using corresponding octal or Unicode escape."/>
</module>
<module name="AvoidEscapedUnicodeCharacters">
<property name="allowEscapesForControlCharacters" value="true"/>
<property name="allowByTailComment" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="LineLength">
<property name="max" value="100"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<module name="AvoidStarImport"/>
<module name="OneTopLevelClass"/>
<module name="NoLineWrap"/>
<module name="EmptyBlock">
<property name="option" value="TEXT"/>
<property name="tokens" value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
</module>
<module name="NeedBraces"/>
<module name="LeftCurly">
<property name="maxLineLength" value="100"/>
</module>
<module name="RightCurly"/>
<module name="RightCurly">
<property name="option" value="alone"/>
<property name="tokens" value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, STATIC_INIT, INSTANCE_INIT"/>
</module>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyMethods" value="true"/>
<property name="allowEmptyTypes" value="true"/>
<property name="allowEmptyLoops" value="true"/>
<message key="ws.notFollowed"
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
<message key="ws.notPreceded"
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
</module>
<module name="OneStatementPerLine"/>
<module name="MultipleVariableDeclarations"/>
<module name="ArrayTypeStyle"/>
<module name="MissingSwitchDefault"/>
<module name="FallThrough"/>
<module name="UpperEll"/>
<module name="ModifierOrder"/>
<module name="EmptyLineSeparator">
<property name="allowNoEmptyLineBetweenFields" value="true"/>
</module>
<module name="SeparatorWrap">
<property name="tokens" value="DOT"/>
<property name="option" value="nl"/>
</module>
<module name="SeparatorWrap">
<property name="tokens" value="COMMA"/>
<property name="option" value="EOL"/>
</module>
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
<message key="name.invalidPattern"
value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="TypeName">
<message key="name.invalidPattern"
value="Type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MemberName">
<property name="format" value="^m_[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Member name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ParameterName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="CatchParameterName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LocalVariableName">
<property name="tokens" value="VARIABLE_DEF"/>
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<property name="allowOneCharVarInForLoop" value="true"/>
<message key="name.invalidPattern"
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MethodTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Method type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="InterfaceTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="NoFinalizer"/>
<module name="GenericWhitespace">
<message key="ws.followed"
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
<message key="ws.preceded"
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
<message key="ws.illegalFollow"
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
<message key="ws.notPreceded"
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
</module>
<module name="Indentation">
<property name="basicOffset" value="2"/>
<property name="braceAdjustment" value="0"/>
<property name="caseIndent" value="2"/>
<property name="throwsIndent" value="4"/>
<property name="lineWrappingIndentation" value="4"/>
<property name="arrayInitIndent" value="2"/>
</module>
<module name="AbbreviationAsWordInName">
<property name="ignoreFinal" value="false"/>
<property name="allowedAbbreviationLength" value="3"/>
</module>
<module name="OverloadMethodsDeclarationOrder"/>
<module name="VariableDeclarationUsageDistance"/>
<module name="MethodParamPad"/>
<module name="OperatorWrap">
<property name="option" value="NL"/>
<property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR "/>
</module>
<module name="AnnotationLocation">
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
</module>
<module name="AnnotationLocation">
<property name="tokens" value="VARIABLE_DEF"/>
<property name="allowSamelineMultipleAnnotations" value="true"/>
</module>
<module name="NonEmptyAtclauseDescription"/>
<module name="JavadocTagContinuationIndentation"/>
<module name="SummaryJavadoc">
<property name="forbiddenSummaryFragments" value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
</module>
<module name="JavadocParagraph"/>
<module name="AtclauseOrder">
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
<property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
</module>
<module name="JavadocMethod">
<property name="scope" value="public"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="minLineCount" value="2"/>
<property name="allowedAnnotations"
value="Override, Test, Before, After, BeforeClass, AfterClass, Parameters"/>
<property name="allowUndeclaredRTE" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="suppressLoadErrors" value="true"/>
</module>
<module name="MethodName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
<message key="name.invalidPattern"
value="Method name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="SingleLineJavadoc">
<property name="ignoreInlineTags" value="false"/>
</module>
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="expected"/>
</module>
<module name="CommentsIndentation"/>
</module>
</module>

View File

@@ -0,0 +1,475 @@
<?xml version="1.0" encoding="UTF-8"?>
<code_scheme name="GoogleStyle">
<option name="JAVA_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</value>
</option>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="com.google" withSubpackages="true" static="false" />
<emptyLine />
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="antenna" withSubpackages="true" static="false" />
<emptyLine />
<package name="antlr" withSubpackages="true" static="false" />
<emptyLine />
<package name="ar" withSubpackages="true" static="false" />
<emptyLine />
<package name="asposewobfuscated" withSubpackages="true" static="false" />
<emptyLine />
<package name="asquare" withSubpackages="true" static="false" />
<emptyLine />
<package name="atg" withSubpackages="true" static="false" />
<emptyLine />
<package name="au" withSubpackages="true" static="false" />
<emptyLine />
<package name="beaver" withSubpackages="true" static="false" />
<emptyLine />
<package name="bibtex" withSubpackages="true" static="false" />
<emptyLine />
<package name="bmsi" withSubpackages="true" static="false" />
<emptyLine />
<package name="bsh" withSubpackages="true" static="false" />
<emptyLine />
<package name="ccl" withSubpackages="true" static="false" />
<emptyLine />
<package name="cern" withSubpackages="true" static="false" />
<emptyLine />
<package name="ChartDirector" withSubpackages="true" static="false" />
<emptyLine />
<package name="checkers" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="COM" withSubpackages="true" static="false" />
<emptyLine />
<package name="common" withSubpackages="true" static="false" />
<emptyLine />
<package name="contribs" withSubpackages="true" static="false" />
<emptyLine />
<package name="corejava" withSubpackages="true" static="false" />
<emptyLine />
<package name="cryptix" withSubpackages="true" static="false" />
<emptyLine />
<package name="cybervillains" withSubpackages="true" static="false" />
<emptyLine />
<package name="dalvik" withSubpackages="true" static="false" />
<emptyLine />
<package name="danbikel" withSubpackages="true" static="false" />
<emptyLine />
<package name="de" withSubpackages="true" static="false" />
<emptyLine />
<package name="EDU" withSubpackages="true" static="false" />
<emptyLine />
<package name="eg" withSubpackages="true" static="false" />
<emptyLine />
<package name="eu" withSubpackages="true" static="false" />
<emptyLine />
<package name="examples" withSubpackages="true" static="false" />
<emptyLine />
<package name="fat" withSubpackages="true" static="false" />
<emptyLine />
<package name="fit" withSubpackages="true" static="false" />
<emptyLine />
<package name="fitlibrary" withSubpackages="true" static="false" />
<emptyLine />
<package name="fmpp" withSubpackages="true" static="false" />
<emptyLine />
<package name="freemarker" withSubpackages="true" static="false" />
<emptyLine />
<package name="gnu" withSubpackages="true" static="false" />
<emptyLine />
<package name="groovy" withSubpackages="true" static="false" />
<emptyLine />
<package name="groovyjarjarantlr" withSubpackages="true" static="false" />
<emptyLine />
<package name="groovyjarjarasm" withSubpackages="true" static="false" />
<emptyLine />
<package name="hak" withSubpackages="true" static="false" />
<emptyLine />
<package name="hep" withSubpackages="true" static="false" />
<emptyLine />
<package name="ie" withSubpackages="true" static="false" />
<emptyLine />
<package name="imageinfo" withSubpackages="true" static="false" />
<emptyLine />
<package name="info" withSubpackages="true" static="false" />
<emptyLine />
<package name="it" withSubpackages="true" static="false" />
<emptyLine />
<package name="jal" withSubpackages="true" static="false" />
<emptyLine />
<package name="Jama" withSubpackages="true" static="false" />
<emptyLine />
<package name="japa" withSubpackages="true" static="false" />
<emptyLine />
<package name="japacheckers" withSubpackages="true" static="false" />
<emptyLine />
<package name="jas" withSubpackages="true" static="false" />
<emptyLine />
<package name="jasmin" withSubpackages="true" static="false" />
<emptyLine />
<package name="javancss" withSubpackages="true" static="false" />
<emptyLine />
<package name="javanet" withSubpackages="true" static="false" />
<emptyLine />
<package name="javassist" withSubpackages="true" static="false" />
<emptyLine />
<package name="javazoom" withSubpackages="true" static="false" />
<emptyLine />
<package name="java_cup" withSubpackages="true" static="false" />
<emptyLine />
<package name="jcifs" withSubpackages="true" static="false" />
<emptyLine />
<package name="jetty" withSubpackages="true" static="false" />
<emptyLine />
<package name="JFlex" withSubpackages="true" static="false" />
<emptyLine />
<package name="jj2000" withSubpackages="true" static="false" />
<emptyLine />
<package name="jline" withSubpackages="true" static="false" />
<emptyLine />
<package name="jp" withSubpackages="true" static="false" />
<emptyLine />
<package name="JSci" withSubpackages="true" static="false" />
<emptyLine />
<package name="jsr166y" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="jxl" withSubpackages="true" static="false" />
<emptyLine />
<package name="jxxload_help" withSubpackages="true" static="false" />
<emptyLine />
<package name="kawa" withSubpackages="true" static="false" />
<emptyLine />
<package name="kea" withSubpackages="true" static="false" />
<emptyLine />
<package name="libcore" withSubpackages="true" static="false" />
<emptyLine />
<package name="libsvm" withSubpackages="true" static="false" />
<emptyLine />
<package name="lti" withSubpackages="true" static="false" />
<emptyLine />
<package name="memetic" withSubpackages="true" static="false" />
<emptyLine />
<package name="mt" withSubpackages="true" static="false" />
<emptyLine />
<package name="mx4j" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="netscape" withSubpackages="true" static="false" />
<emptyLine />
<package name="nl" withSubpackages="true" static="false" />
<emptyLine />
<package name="nu" withSubpackages="true" static="false" />
<emptyLine />
<package name="oauth" withSubpackages="true" static="false" />
<emptyLine />
<package name="ognl" withSubpackages="true" static="false" />
<emptyLine />
<package name="opennlp" withSubpackages="true" static="false" />
<emptyLine />
<package name="oracle" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="penn2dg" withSubpackages="true" static="false" />
<emptyLine />
<package name="pennconverter" withSubpackages="true" static="false" />
<emptyLine />
<package name="pl" withSubpackages="true" static="false" />
<emptyLine />
<package name="prefuse" withSubpackages="true" static="false" />
<emptyLine />
<package name="proguard" withSubpackages="true" static="false" />
<emptyLine />
<package name="repackage" withSubpackages="true" static="false" />
<emptyLine />
<package name="scm" withSubpackages="true" static="false" />
<emptyLine />
<package name="se" withSubpackages="true" static="false" />
<emptyLine />
<package name="serp" withSubpackages="true" static="false" />
<emptyLine />
<package name="simple" withSubpackages="true" static="false" />
<emptyLine />
<package name="soot" withSubpackages="true" static="false" />
<emptyLine />
<package name="sqlj" withSubpackages="true" static="false" />
<emptyLine />
<package name="src" withSubpackages="true" static="false" />
<emptyLine />
<package name="ssa" withSubpackages="true" static="false" />
<emptyLine />
<package name="sun" withSubpackages="true" static="false" />
<emptyLine />
<package name="sunlabs" withSubpackages="true" static="false" />
<emptyLine />
<package name="tcl" withSubpackages="true" static="false" />
<emptyLine />
<package name="testdata" withSubpackages="true" static="false" />
<emptyLine />
<package name="testshell" withSubpackages="true" static="false" />
<emptyLine />
<package name="testsuite" withSubpackages="true" static="false" />
<emptyLine />
<package name="twitter4j" withSubpackages="true" static="false" />
<emptyLine />
<package name="uk" withSubpackages="true" static="false" />
<emptyLine />
<package name="ViolinStrings" withSubpackages="true" static="false" />
<emptyLine />
<package name="weka" withSubpackages="true" static="false" />
<emptyLine />
<package name="wet" withSubpackages="true" static="false" />
<emptyLine />
<package name="winstone" withSubpackages="true" static="false" />
<emptyLine />
<package name="woolfel" withSubpackages="true" static="false" />
<emptyLine />
<package name="wowza" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
</value>
</option>
<option name="RIGHT_MARGIN" value="100" />
<option name="JD_P_AT_EMPTY_LINES" value="false" />
<option name="JD_KEEP_EMPTY_PARAMETER" value="false" />
<option name="JD_KEEP_EMPTY_EXCEPTION" value="false" />
<option name="JD_KEEP_EMPTY_RETURN" value="false" />
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="5" />
<option name="WRAP_COMMENTS" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<ADDITIONAL_INDENT_OPTIONS fileType="css">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="haml">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="java">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="js">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="jsp">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="php">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="sass">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="xml">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="yml">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<codeStyleSettings language="ECMA Script Level 4">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="5" />
<option name="WRAP_COMMENTS" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="5" />
<option name="WRAP_COMMENTS" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="PHP">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="5" />
<option name="WRAP_COMMENTS" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
</code_scheme>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files=".*sim.*" checks="[a-zA-Z0-9]*"/>
</suppressions>

View File

@@ -107,7 +107,7 @@ task wpilibjSources(type: Jar, dependsOn: classes) {
}
def ntSourcesDependency =
project.dependencies.create('edu.wpi.first.wpilib.networktables.java:NetworkTables:3.0.0-SNAPSHOT:sources@jar')
project.dependencies.create('edu.wpi.first.wpilib.networktables.java:NetworkTables:3.0.0-SNAPSHOT:sources@jar')
def ntSourcesConfig = project.configurations.detachedConfiguration(ntSourcesDependency)
ntSourcesDependency.setTransitive(false)
def ntSources = ntSourcesConfig.singleFile

View File

@@ -12,6 +12,6 @@ dependencies {
apply from: 'athena.gradle'
if (project.hasProperty('makeSim')){
apply from: 'simulation.gradle'
if (project.hasProperty('makeSim')) {
apply from: 'simulation.gradle'
}

View File

@@ -1,8 +1,9 @@
from __future__ import print_function
import codecs
import sys
import os
import re
import sys
try:
import configparser
except ImportError:
@@ -12,31 +13,33 @@ from nivision_parse import *
# base, cast-out-pre, cast-out-post, cast-in-pre, cast-in-post
java_accessor_map = {
"B": ("", "", "", "", ""),
"C": ("Char", "", "", "", ""),
"S": ("Short", "", "", "", ""),
"I": ("Int", "", "", "", ""),
"J": ("Long", "", "", "", ""),
"F": ("Float", "", "", "", ""),
"D": ("Double", "", "", "", ""),
"Z": ("Boolean", "", "", "", ""),
"X": ("", "(short)(", " & 0xff)", "(byte)(", " & 0xff)"),
"Y": ("Short", "(int)(", " & 0xffff)", "(short)(", " & 0xffff)"),
}
"B": ("", "", "", "", ""),
"C": ("Char", "", "", "", ""),
"S": ("Short", "", "", "", ""),
"I": ("Int", "", "", "", ""),
"J": ("Long", "", "", "", ""),
"F": ("Float", "", "", "", ""),
"D": ("Double", "", "", "", ""),
"Z": ("Boolean", "", "", "", ""),
"X": ("", "(short)(", " & 0xff)", "(byte)(", " & 0xff)"),
"Y": ("Short", "(int)(", " & 0xffff)", "(short)(", " & 0xffff)"),
}
java_size_map = {
"B": 1,
"C": 2,
"S": 2,
"I": 4,
"J": 8,
"F": 4,
"D": 8,
"Z": 1,
}
"B": 1,
"C": 2,
"S": 2,
"I": 4,
"J": 8,
"F": 4,
"D": 8,
"Z": 1,
}
class JavaType:
def __init__(self, j_type, jn_type, jni_type, jni_sig, is_enum=False, is_struct=False, is_opaque=False, string_array=False, array_size=None):
def __init__(self, j_type, jn_type, jni_type, jni_sig, is_enum=False, is_struct=False,
is_opaque=False, string_array=False, array_size=None):
self.j_type = j_type
self.jn_type = jn_type
self.jni_type = jni_type
@@ -56,52 +59,57 @@ class JavaType:
def __repr__(self):
return "JavaType(%s, %s, %s, %s, is_enum=%s, is_struct=%s, is_opaque=%s, string_array=%s, array_size=%s)" % (
self.j_type, self.jn_type, self.jni_type, self.jni_sig,
self.is_enum, self.is_struct,
self.is_opaque, self.string_array, self.array_size)
self.j_type, self.jn_type, self.jni_type, self.jni_sig,
self.is_enum, self.is_struct,
self.is_opaque, self.string_array, self.array_size)
java_types_map = {
("void", None): JavaType("void", "void", "void", None),
("env", None): JavaType("", "", "JNIEnv*", None),
("cls", None): JavaType("", "", "jclass", None),
("int", None): JavaType("int", "int", "jint", "I"),
("char", None): JavaType("byte", "byte", "jbyte", "B"),
("wchar_t", None): JavaType("char", "char", "jchar", "C"),
("unsigned char", None): JavaType("short", "short", "jshort", "X"),
("short", None): JavaType("short", "short", "jshort", "S"),
("unsigned short", None): JavaType("int", "int", "jint", "Y"),
("unsigned", None): JavaType("int", "int", "jint", "I"),
("unsigned int", None): JavaType("int", "int", "jint", "I"),
("uInt32", None): JavaType("int", "int", "jint", "I"),
("IMAQdxSession", None): JavaType("int", "int", "jint", "I"),
("bool32", None): JavaType("int", "int", "jint", "I"),
("long", None): JavaType("long", "long", "jlong", "J"),
("unsigned long", None): JavaType("long", "long", "jlong", "J"),
("__int64", None): JavaType("long", "long", "jlong", "J"),
("long long", None): JavaType("long", "long", "jlong", "J"),
("unsigned __int64", None): JavaType("long", "long", "jlong", "J"),
("__uint64", None): JavaType("long", "long", "jlong", "J"),
("unsigned long long", None): JavaType("long", "long", "jlong", "J"),
("float", None): JavaType("float", "float", "jfloat", "F"),
("double", None): JavaType("double", "double", "jdouble", "D"),
("long double", None): JavaType("double", "double", "jdouble", "D"),
("unsigned char*", None): JavaType("String", "String", "jstring", "Ljava/lang/String;"),
("char*", None): JavaType("String", "String", "jstring", "Ljava/lang/String;"),
("void*", None): JavaType("RawData", "long", "jlong", "J", is_opaque=True),
#("size_t", None): JavaType("long", "long", "jlong", "J"),
("String255", None): JavaType("String", "String", "jstring", "Ljava/lang/String;", string_array=True, array_size="256"),
("String255", ""): JavaType("String[]", "String[]", "jstringArray", "[Ljava/lang/String;", string_array=True, array_size="256"),
("char*", ""): JavaType("String[]", "String[]", "jstringArray", "[Ljava/lang/String;"),
("char", ""): JavaType("String", "String", "jstring", "Ljava/lang/String;", string_array=True, array_size=""),
("unsigned char", ""): JavaType("byte[]", "byte[]", "jbyteArray", "[B"),
("short", ""): JavaType("short[]", "short[]", "jshortArray", "[S"),
("int", ""): JavaType("int[]", "int[]", "jintArray", "[I"),
("unsigned int", ""): JavaType("int[]", "int[]", "jintArray", "[I"),
("uInt32", ""): JavaType("int[]", "int[]", "jintArray", "[I"),
("long", ""): JavaType("long[]", "long[]", "jlongArray", "[J"),
("float", ""): JavaType("float[]", "float[]", "jfloatArray", "[F"),
("double", ""): JavaType("double[]", "double[]", "jdoubleArray", "[D"),
}
("void", None): JavaType("void", "void", "void", None),
("env", None): JavaType("", "", "JNIEnv*", None),
("cls", None): JavaType("", "", "jclass", None),
("int", None): JavaType("int", "int", "jint", "I"),
("char", None): JavaType("byte", "byte", "jbyte", "B"),
("wchar_t", None): JavaType("char", "char", "jchar", "C"),
("unsigned char", None): JavaType("short", "short", "jshort", "X"),
("short", None): JavaType("short", "short", "jshort", "S"),
("unsigned short", None): JavaType("int", "int", "jint", "Y"),
("unsigned", None): JavaType("int", "int", "jint", "I"),
("unsigned int", None): JavaType("int", "int", "jint", "I"),
("uInt32", None): JavaType("int", "int", "jint", "I"),
("IMAQdxSession", None): JavaType("int", "int", "jint", "I"),
("bool32", None): JavaType("int", "int", "jint", "I"),
("long", None): JavaType("long", "long", "jlong", "J"),
("unsigned long", None): JavaType("long", "long", "jlong", "J"),
("__int64", None): JavaType("long", "long", "jlong", "J"),
("long long", None): JavaType("long", "long", "jlong", "J"),
("unsigned __int64", None): JavaType("long", "long", "jlong", "J"),
("__uint64", None): JavaType("long", "long", "jlong", "J"),
("unsigned long long", None): JavaType("long", "long", "jlong", "J"),
("float", None): JavaType("float", "float", "jfloat", "F"),
("double", None): JavaType("double", "double", "jdouble", "D"),
("long double", None): JavaType("double", "double", "jdouble", "D"),
("unsigned char*", None): JavaType("String", "String", "jstring", "Ljava/lang/String;"),
("char*", None): JavaType("String", "String", "jstring", "Ljava/lang/String;"),
("void*", None): JavaType("RawData", "long", "jlong", "J", is_opaque=True),
# ("size_t", None): JavaType("long", "long", "jlong", "J"),
("String255", None): JavaType("String", "String", "jstring", "Ljava/lang/String;",
string_array=True, array_size="256"),
("String255", ""): JavaType("String[]", "String[]", "jstringArray", "[Ljava/lang/String;",
string_array=True, array_size="256"),
("char*", ""): JavaType("String[]", "String[]", "jstringArray", "[Ljava/lang/String;"),
("char", ""): JavaType("String", "String", "jstring", "Ljava/lang/String;", string_array=True,
array_size=""),
("unsigned char", ""): JavaType("byte[]", "byte[]", "jbyteArray", "[B"),
("short", ""): JavaType("short[]", "short[]", "jshortArray", "[S"),
("int", ""): JavaType("int[]", "int[]", "jintArray", "[I"),
("unsigned int", ""): JavaType("int[]", "int[]", "jintArray", "[I"),
("uInt32", ""): JavaType("int[]", "int[]", "jintArray", "[I"),
("long", ""): JavaType("long[]", "long[]", "jlongArray", "[J"),
("float", ""): JavaType("float[]", "float[]", "jfloatArray", "[F"),
("double", ""): JavaType("double[]", "double[]", "jdoubleArray", "[D"),
}
def c_to_jtype(name, arr):
jtype = java_types_map.get((name, arr), None)
@@ -112,7 +120,7 @@ def c_to_jtype(name, arr):
if arr is not None and arr != "":
jtype = c_to_jtype(name, "").copy()
jtype.array_size = arr
java_types_map[(name, arr)] = jtype # cache
java_types_map[(name, arr)] = jtype # cache
return jtype
# Opaque structures
@@ -121,8 +129,8 @@ def c_to_jtype(name, arr):
jtype = JavaType(name, "long", "jlong", "J", is_opaque=True)
else:
# FIXME
jtype = JavaType(name+"[]", "long[]", "jlongArray", "[J", is_opaque=True)
java_types_map[(name, arr)] = jtype # cache
jtype = JavaType(name + "[]", "long[]", "jlongArray", "[J", is_opaque=True)
java_types_map[(name, arr)] = jtype # cache
return jtype
# Enums
@@ -131,8 +139,8 @@ def c_to_jtype(name, arr):
jtype = JavaType(name, "int", "jint", "I", is_enum=True)
else:
# FIXME
jtype = JavaType(name+"[]", "int[]", "jintArray", "[I", is_enum=True)
java_types_map[(name, arr)] = jtype # cache
jtype = JavaType(name + "[]", "int[]", "jintArray", "[I", is_enum=True)
java_types_map[(name, arr)] = jtype # cache
return jtype
# handle pointers as void* (FIXME)
@@ -146,10 +154,11 @@ def c_to_jtype(name, arr):
jtype = JavaType(name, "long", "jlong", "J", is_struct=True)
else:
# FIXME
jtype = JavaType(name+"[]", "long[]", "jlongArray", "[J", is_struct=True)
jtype = JavaType(name + "[]", "long[]", "jlongArray", "[J", is_struct=True)
java_types_map[(name, arr)] = jtype
return jtype
class JavaEmitData:
def __init__(self):
self.construct = []
@@ -161,22 +170,23 @@ class JavaEmitData:
self.toArg = ""
def addConstruct(self, s):
self.construct.extend(s.split('\n')[1 if s[0]=='\n' else 0:])
self.construct.extend(s.split('\n')[1 if s[0] == '\n' else 0:])
def addBackingRead(self, s):
self.backingRead.extend(s.split('\n')[1 if s[0]=='\n' else 0:])
self.backingRead.extend(s.split('\n')[1 if s[0] == '\n' else 0:])
def addRead(self, s):
self.read.extend(s.split('\n')[1 if s[0]=='\n' else 0:])
self.read.extend(s.split('\n')[1 if s[0] == '\n' else 0:])
def addWriteBuf(self, s):
self.writeBufs.append(s)
def addWrite(self, s):
self.write.extend(s.split('\n')[1 if s[0]=='\n' else 0:])
self.write.extend(s.split('\n')[1 if s[0] == '\n' else 0:])
def addBackingWrite(self, s):
self.backingWrite.extend(s.split('\n')[1 if s[0]=='\n' else 0:])
self.backingWrite.extend(s.split('\n')[1 if s[0] == '\n' else 0:])
class JavaEmitArrayData(JavaEmitData):
def __init__(self):
@@ -185,6 +195,7 @@ class JavaEmitArrayData(JavaEmitData):
self.addBackingRead("int {size_fname} = {backing}.get{jaccessor}({size_foffset});")
self.addBackingWrite("{backing}.put{jaccessor}({size_foffset}, {fname}.length);")
# sized array of null-terminated strings
strzArrayEmitSized = JavaEmitArrayData()
strzArrayEmitSized.addBackingRead("long {fname}_addr = getPointer({backing}, {foffset});")
@@ -435,8 +446,10 @@ structEmit.toArg = "{fname}.getAddress()"
# java type
jtypeEmit = JavaEmitData()
jtypeEmit.addBackingRead("{fname} = {jaccessor_cast_out_pre}{backing}.get{jaccessor}({foffset}){jaccessor_cast_out_post};")
jtypeEmit.addBackingWrite("{backing}.put{jaccessor}({foffset}, {jaccessor_cast_in_pre}{fname}{jaccessor_cast_in_post});")
jtypeEmit.addBackingRead(
"{fname} = {jaccessor_cast_out_pre}{backing}.get{jaccessor}({foffset}){jaccessor_cast_out_post};")
jtypeEmit.addBackingWrite(
"{backing}.put{jaccessor}({foffset}, {jaccessor_cast_in_pre}{fname}{jaccessor_cast_in_post});")
# string - array of characters
strSizedEmit = JavaEmitData()
@@ -493,9 +506,11 @@ if ({fname} != null) {{
{fname}_buf = ByteBuffer.allocateDirect({fname}_bytes.length+1);
putBytes({fname}_buf, {fname}_bytes, 0, {fname}_bytes.length).put({fname}_bytes.length, (byte)0);
}}""")
strzEmit.addBackingWrite("putPointer({backing}, {foffset}, {fname} == null ? 0 : getByteBufferAddress({fname}_buf));")
strzEmit.addBackingWrite(
"putPointer({backing}, {foffset}, {fname} == null ? 0 : getByteBufferAddress({fname}_buf));")
strzEmit.toArg = "{fname} == null ? 0 : getByteBufferAddress({fname}_buf)"
class JavaStructEmitHelper:
def __init__(self, emit, name, fields, sized_members=None):
self.emit = emit
@@ -503,19 +518,21 @@ class JavaStructEmitHelper:
self.fields = fields
self.exclude_members = set(self.config_get("exclude_members", "").split(','))
self.exclude_members |= set(x.split(':')[0] for x in self.config_get("uniontype", "").split(','))
self.exclude_members |= set(
x.split(':')[0] for x in self.config_get("uniontype", "").split(','))
self.union_members = {}
for v in self.config_get("uniontype", "").split(','):
if not v:
continue
vl = v.split(':')
self.union_members[vl[0]] = (vl[1], [tuple(y.strip() for y in x.split('=')) for x in vl[2:]])
self.union_members[vl[0]] = (
vl[1], [tuple(y.strip() for y in x.split('=')) for x in vl[2:]])
if sized_members is not None:
self.sized_members = sized_members
else:
self.sized_members = dict(tuple(y.strip() for y in x.split(':')) for x in
self.config_get("arraysize", "").split(',') if x)
self.config_get("arraysize", "").split(',') if x)
self.size_members = dict((x, None) for x in self.sized_members.values())
# get type of each sized member
@@ -532,7 +549,8 @@ class JavaStructEmitHelper:
def config_struct_get(self, option):
return self.emit.config_struct.get(self.name, option)
def get_field_java_code(self, fname, ftype, arr, foffset, jfielddefs_private, backing="backing"):
def get_field_java_code(self, fname, ftype, arr, foffset, jfielddefs_private,
backing="backing"):
"""Returns dict of fielddef, init, read, write, type
"""
if ftype.startswith("const"):
@@ -546,9 +564,9 @@ class JavaStructEmitHelper:
size_jtype = c_to_jtype(self.size_members[size_fname], None)
size_foffset = self.config_struct_get(size_fname)
else:
size_fname=""
size_jtype=None
size_foffset=None
size_fname = ""
size_jtype = None
size_foffset = None
is_pointer = False
if ftype[-1] == '*' and ftype[:-1] in opaque_structs:
@@ -658,7 +676,7 @@ for (int i=0, off={foffset}; i<%s; i++, off += {struct_sz})
ftype=jtype.j_type,
ftype_one=jtype.j_type[:-2],
foffset=foffset,
size_fname=fname+"_"+size_fname,
size_fname=fname + "_" + size_fname,
size_foffset=size_foffset,
pointer_sz=self.emit.config_struct.get("_platform_", "pointer"),
struct_sz=struct_sz,
@@ -705,10 +723,10 @@ for (int i=0, off={foffset}; i<%s; i++, off += {struct_sz})
# standard struct fields
for fname, ftype, arr, comment in self.fields:
if fname in self.size_members or fname in self.exclude_members:
continue # don't emit
continue # don't emit
if ":" in fname:
continue # TODO: bit field
continue # TODO: bit field
foffset = self.config_struct_get(fname)
field = self.get_field_java_code(fname, ftype, arr, foffset, jfielddefs_private)
@@ -756,7 +774,8 @@ for (int i=0, off={foffset}; i<%s; i++, off += {struct_sz})
# find the rest of the info from the union fields
ftype, arr, comment = ufieldmap[fname]
field = self.get_field_java_code(fname, ftype, arr, foffset, jfielddefs_union_private)
field = self.get_field_java_code(fname, ftype, arr, foffset,
jfielddefs_union_private)
fielddef = field["fielddef"]
read = field["backing_read"]
@@ -832,15 +851,15 @@ for (int i=0, off={foffset}; i<%s; i++, off += {struct_sz})
return {size};
}}
}}"""
return "".join([p1,p2,p3]).format(
name=self.name,
jfielddefs="\n ".join(jfielddefs),
jread="\n ".join(jread),
jwrite="\n ".join(jwrite),
jconstruct="\n ".join(jconstruct),
jcargs=", ".join(jcargs),
jcinit="\n ".join(jcinit),
size=self.config_struct_get("_SIZE_"))
return "".join([p1, p2, p3]).format(
name=self.name,
jfielddefs="\n ".join(jfielddefs),
jread="\n ".join(jread),
jwrite="\n ".join(jwrite),
jconstruct="\n ".join(jconstruct),
jcargs=", ".join(jcargs),
jcinit="\n ".join(jcinit),
size=self.config_struct_get("_SIZE_"))
class JavaEmitter:
@@ -1278,7 +1297,9 @@ static const char* getErrorText(int err) {{
{errs}
default: return "Unknown error";
}}
}}""".format(errs="\n ".join('case %s: return "%s";' % (x, self.errors[x]) for x in sorted(self.errors))), file=self.outc)
}}""".format(errs="\n ".join(
'case %s: return "%s";' % (x, self.errors[x]) for x in sorted(self.errors))),
file=self.outc)
def config_get(self, section, option, fallback):
try:
@@ -1357,7 +1378,7 @@ static const char* getErrorText(int err) {{
name = name[5:]
code = " public static final {type} {name} = {value};" \
.format(type=type, name=name, value=clean)
.format(type=type, name=name, value=clean)
if after_struct:
define_after_struct.append((name, code))
return
@@ -1428,7 +1449,9 @@ static const char* getErrorText(int err) {{
private {name}(int value) {{
this.value = value;
}}
public static {name} fromValue(int val) {{""".format(name=name, values="\n ".join(valuestrs)), file=self.out)
public static {name} fromValue(int val) {{""".format(name=name,
values="\n ".join(valuestrs)),
file=self.out)
if need_search:
print(""" for ({name} v : values()) {{
if (v.value == val)
@@ -1503,7 +1526,8 @@ static const char* getErrorText(int err) {{
dxEnumerateVideoModesResult rv = new dxEnumerateVideoModesResult(rv_buf, videoModeArray_buf);
return rv;
}}
private static native void _IMAQdxEnumerateVideoModes(int id, long videoModeArray, long count, long currentMode);""".format(struct_sz=self.config_struct.get("IMAQdxEnumItem", "_SIZE_")), file=self.out)
private static native void _IMAQdxEnumerateVideoModes(int id, long videoModeArray, long count, long currentMode);""".format(
struct_sz=self.config_struct.get("IMAQdxEnumItem", "_SIZE_")), file=self.out)
print("""
JNIEXPORT void JNICALL Java_{package}_{classname}__1IMAQdxEnumerateVideoModes(JNIEnv* env, jclass , jint id, jlong videoModeArray, jlong count, jlong currentMode)
{{
@@ -1519,7 +1543,8 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1IMAQdxEnumerateVideoModes(JN
int buffer_size = buffer.capacity();
return _IMAQdxGetImageData(id, buffer_addr, buffer_size, mode.getValue(), desiredBufferNumber);
}}
private static native int _IMAQdxGetImageData(int id, long buffer, int bufferSize, int mode, int desiredBufferNumber);""".format(), file=self.out)
private static native int _IMAQdxGetImageData(int id, long buffer, int bufferSize, int mode, int desiredBufferNumber);""".format(),
file=self.out)
print("""
JNIEXPORT jint JNICALL Java_{package}_{classname}__1IMAQdxGetImageData(JNIEnv* env, jclass , jint id, jlong buffer, jint bufferSize, jint mode, jint desiredBufferNumber)
{{
@@ -1543,7 +1568,8 @@ JNIEXPORT jint JNICALL Java_{package}_{classname}__1IMAQdxGetImageData(JNIEnv* e
putBytes(fileName_buf, fileName_bytes, 0, fileName_bytes.length).put(fileName_bytes.length, (byte)0);
_imaqReadFile(image.getAddress(), getByteBufferAddress(fileName_buf), 0, 0);
}}
private static native void _imaqReadFile(long image, long fileName, long colorTable, long numColors);""".format(), file=self.out)
private static native void _imaqReadFile(long image, long fileName, long colorTable, long numColors);""".format(),
file=self.out)
print("""
JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jclass , jlong image, jlong fileName, jlong colorTable, jlong numColors)
{{
@@ -1592,16 +1618,19 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
rettype = c_to_jtype(restype, None)
# TODO: defaults
#defaults = dict((y.strip() for y in x.split(':')) for x in
# defaults = dict((y.strip() for y in x.split(':')) for x in
# self.config_get(name, "defaults", "").split(',') if x)
sized_params = dict(tuple(y.strip() for y in x.split(':')) for x in
self.config_get(name, "arraysize", "").split(',') if x)
self.config_get(name, "arraysize", "").split(',') if x)
size_params = set(sized_params.values())
inparams = [x.strip() for x in self.config_get(name, "inparams", "").split(',') if x.strip()]
outparams = [x.strip() for x in self.config_get(name, "outparams", "").split(',') if x.strip()]
nullokparams = [x.strip() for x in self.config_get(name, "nullok", "").split(',') if x.strip()]
inparams = [x.strip() for x in self.config_get(name, "inparams", "").split(',') if
x.strip()]
outparams = [x.strip() for x in self.config_get(name, "outparams", "").split(',') if
x.strip()]
nullokparams = [x.strip() for x in self.config_get(name, "nullok", "").split(',') if
x.strip()]
# guess additional output parameters
for pname, ptype, arr in params:
if (pname not in inparams
@@ -1616,7 +1645,7 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
retarraysize = self.config_get(name, "retarraysize", "").strip()
if retarraysize:
size_params.add(retarraysize)
#rettype = c_to_jtype(restype, "")
# rettype = c_to_jtype(restype, "")
if retarraysize not in outparams:
outparams.append(retarraysize)
@@ -1644,7 +1673,7 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
jfielddefs_private = []
for fname, ftype, arr, comment in helper.fields:
#print(fname, ftype, arr)
# print(fname, ftype, arr)
is_outparam = (fname in outparams)
is_nullok = (fname in nullokparams) and not is_outparam
@@ -1653,7 +1682,8 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
ftype = ftype[:-1]
elif arr is None:
raise ValueError("outparam %s is not a pointer or array", fname)
field = helper.get_field_java_code(fname, ftype, arr, 0, jfielddefs_private, backing="%s_buf" % fname)
field = helper.get_field_java_code(fname, ftype, arr, 0, jfielddefs_private,
backing="%s_buf" % fname)
paramtypes[fname] = (ftype, arr, field["type"])
if is_outparam:
jn_funcargs.append((fname, jtype_ptr))
@@ -1685,7 +1715,9 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
if arr:
raise NotImplementedError("sized array")
else:
jinit.append("{size_jtype} {size_fname} = {fname}.length;".format(size_jtype=field["size_jtype"].j_type, size_fname=field["size_fname"], fname=fname))
jinit.append("{size_jtype} {size_fname} = {fname}.length;".format(
size_jtype=field["size_jtype"].j_type, size_fname=field["size_fname"],
fname=fname))
jinit.extend("%s = null;" % x for x in write_bufs)
jinit.extend(write)
jn_passedargs[fname] = to_arg
@@ -1703,9 +1735,13 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
jn_passedargs[fname] = fname
elif jtype.jni_sig == "Ljava/lang/String;":
if jtype.string_array:
jinit.append("ByteBuffer {fname}_buf = ByteBuffer.allocateDirect({array_size}).order(ByteOrder.nativeOrder());".format(fname=fname, array_size=256))
jinit.append(
"ByteBuffer {fname}_buf = ByteBuffer.allocateDirect({array_size}).order(ByteOrder.nativeOrder());".format(
fname=fname, array_size=256))
jinit.extend(field["backing_write"])
jn_passedargs[fname] = "{fname} == null ? 0 : getByteBufferAddress({fname}_buf)".format(fname=fname)
jn_passedargs[
fname] = "{fname} == null ? 0 : getByteBufferAddress({fname}_buf)".format(
fname=fname)
else:
jinit.extend("%s = null;" % x for x in write_bufs)
jinit.extend(write)
@@ -1716,7 +1752,7 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
jrettype = rettype.j_type
outstruct_name = None
#print(name, jrettype, outparams, retarraysize, retsize)
# print(name, jrettype, outparams, retarraysize, retsize)
if outparams or retarraysize or retsize:
# create a return structure
outstruct_fields = []
@@ -1738,7 +1774,9 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
outstruct_name = name[4:] + "Result"
# create a return buffer (TODO: optimize size)
jinit.append("ByteBuffer rv_buf = ByteBuffer.allocateDirect(%s).order(ByteOrder.nativeOrder());" % "+".join(outstruct_size))
jinit.append(
"ByteBuffer rv_buf = ByteBuffer.allocateDirect(%s).order(ByteOrder.nativeOrder());" % "+".join(
outstruct_size))
jinit.append("long rv_addr = getByteBufferAddress(rv_buf);")
jconstruct_args = [("rv_buf", "ByteBuffer")]
@@ -1760,17 +1798,20 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
jfielddefs_private = []
off = 0
for fname, ftype, arr, comment in helper.fields:
field = helper.get_field_java_code(fname, ftype, arr, off, jfielddefs_private, backing="rv_buf")
field = helper.get_field_java_code(fname, ftype, arr, off, jfielddefs_private,
backing="rv_buf")
if fname == retarraysize:
jconstruct.append(field["fielddef"].replace("public ", "").replace(fname, "array_%s" % fname))
jconstruct.extend(x.replace(fname, "array_%s" % fname) for x in field["backing_read"])
jconstruct.append(
field["fielddef"].replace("public ", "").replace(fname, "array_%s" % fname))
jconstruct.extend(
x.replace(fname, "array_%s" % fname) for x in field["backing_read"])
jn_passedargs[fname] = "rv_addr+%d" % off
off += 8
continue
jfielddefs.append(field["fielddef"])
if fname == "array":
#jconstruct.extend(field["backing_read"])
# jconstruct.extend(field["backing_read"])
jconstruct.extend(field["read"])
elif fname != "val":
jn_passedargs[fname] = "rv_addr+%d" % off
@@ -1788,24 +1829,29 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
jfini.extend(jconstruct)
jretc = "return %s;" % outparams[0]
jrettype = paramtypes[outparams[0]][2].j_type
#rettype = paramtypes[outparams[0]][2]
# rettype = paramtypes[outparams[0]][2]
elif len(outparams) == 1 and retsize:
jfini.extend(x.replace("public ", "") for x in jfielddefs)
jfini.extend(jconstruct)
jfini.append("val = new {type}(jn_rv, {owned}, {size});".format(type=rettype.j_type, owned="true" if retowned else "false", size=retsize))
jfini.append("val = new {type}(jn_rv, {owned}, {size});".format(type=rettype.j_type,
owned="true" if retowned else "false",
size=retsize))
jretc = "return val;"
else:
defined.add(outstruct_name)
jfini.append("{struct_name} rv = new {struct_name}({args});".format(struct_name=outstruct_name, args=", ".join(x[0] for x in jconstruct_args)))
jfini.append("{struct_name} rv = new {struct_name}({args});".format(
struct_name=outstruct_name, args=", ".join(x[0] for x in jconstruct_args)))
if retsize:
jfini.append("rv.val = new {type}(jn_rv, {owned}, rv.{size});".format(type=rettype.j_type, owned="true" if retowned else "false", size=retsize))
jfini.append("rv.val = new {type}(jn_rv, {owned}, rv.{size});".format(
type=rettype.j_type, owned="true" if retowned else "false", size=retsize))
elif not retarraysize and functype != "STDFUNC":
jfini.append("rv.val = new {type}(jn_rv, {owned});".format(type=rettype.j_type, owned="true" if retowned else "false"))
jfini.append("rv.val = new {type}(jn_rv, {owned});".format(type=rettype.j_type,
owned="true" if retowned else "false"))
jrettype = outstruct_name
if retarraysize:
rettype = c_to_jtype(outstruct_name, None)
#else:
# else:
# rettype = java_types_map[("void", None)]
print("""
@@ -1814,9 +1860,9 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
private {struct_name}({jconstruct_args}) {{
{jconstruct}
}}""".format(struct_name=outstruct_name,
jfielddefs="\n ".join(jfielddefs),
jconstruct_args=", ".join("%s %s" % (x[1], x[0]) for x in jconstruct_args),
jconstruct="\n ".join(jconstruct)),
jfielddefs="\n ".join(jfielddefs),
jconstruct_args=", ".join("%s %s" % (x[1], x[0]) for x in jconstruct_args),
jconstruct="\n ".join(jconstruct)),
file=self.out)
if retarraysize:
print("""
@@ -1834,15 +1880,16 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
if rettype.is_enum:
jretc = "return {type}.fromValue(jn_rv);".format(type=rettype.j_type)
elif rettype.is_struct or rettype.is_opaque:
jretc = "return new {type}(jn_rv, {owned});".format(type=rettype.j_type, owned="true" if retowned else "false")
jretc = "return new {type}(jn_rv, {owned});".format(type=rettype.j_type,
owned="true" if retowned else "false")
else:
jretc = "return jn_rv;"
#
# Java function
#
#assert name.startswith("imaq")
#name = name[4].lower() + name[5:]
# assert name.startswith("imaq")
# name = name[4].lower() + name[5:]
print("""
public static {rettype} {name}({args}) {{
@@ -1855,17 +1902,19 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
init="\n ".join(jinit),
fini="\n ".join(jfini),
rv="%s jn_rv = " % rettype.jn_type if rettype.jn_type != "void" else "",
retcode="\n "+jretc if jretc else "",
passedargs=", ".join(jn_passedargs[x[0]] if x[0] in jn_passedargs else "UNKNOWN" for x in jn_funcargs)),
file=self.out)
retcode="\n " + jretc if jretc else "",
passedargs=", ".join(
jn_passedargs[x[0]] if x[0] in jn_passedargs else "UNKNOWN" for x in
jn_funcargs)),
file=self.out)
#
# Native Java function
#
print(""" private static native {rettype} _{name}({args});""".format(
rettype=rettype.jn_type, name=name,
args=", ".join("%s %s" % (x[1].jn_type, x[0]) for x in jn_funcargs)),
file=self.out)
rettype=rettype.jn_type, name=name,
args=", ".join("%s %s" % (x[1].jn_type, x[0]) for x in jn_funcargs)),
file=self.out)
#
# C function
@@ -1897,8 +1946,8 @@ JNIEXPORT void JNICALL Java_{package}_{classname}__1imaqReadFile(JNIEnv* env, jc
cargs.append("(%s)%s" % (ptype, pname))
callcfunc = "{restype} rv = {name}({args});".format(name=name,
restype=restype,
args=", ".join(cargs))
restype=restype,
args=", ".join(cargs))
print("""
JNIEXPORT {rettype} JNICALL Java_{package}_{classname}__1{name}({args})
@@ -1930,6 +1979,7 @@ JNIEXPORT {rettype} JNICALL Java_{package}_{classname}__1{name}({args})
def union(self, name, fields):
self.unions[name] = fields
def generate(srcdir, outdir, inputs):
emit = None
@@ -1940,7 +1990,7 @@ def generate(srcdir, outdir, inputs):
config = configparser.ConfigParser()
config.read(configpath)
block_comment_exclude = set(x.strip() for x in
config.get("Block Comment", "exclude").splitlines())
config.get("Block Comment", "exclude").splitlines())
library_funcs = set()
with open(funcs_path) as ff:
@@ -1965,17 +2015,18 @@ def generate(srcdir, outdir, inputs):
emit.finish()
if __name__ == "__main__":
if len(sys.argv) < 5 or ((len(sys.argv)-1) % 4) != 0:
if len(sys.argv) < 5 or ((len(sys.argv) - 1) % 4) != 0:
print("Usage: gen_wrap.py <header.h config_struct.ini config.ini funcs.txt>...")
exit(0)
inputs = []
for i in range(1, len(sys.argv), 4):
fname = sys.argv[i]
config_struct_name = sys.argv[i+1]
configname = sys.argv[i+2]
funcs_name = sys.argv[i+3]
config_struct_name = sys.argv[i + 1]
configname = sys.argv[i + 2]
funcs_name = sys.argv[i + 3]
inputs.append((fname, config_struct_name, configname, funcs_name))
generate("", "", inputs)

View File

@@ -1,7 +1,8 @@
from __future__ import print_function
import sys
import os
import re
import sys
try:
import configparser
except ImportError:
@@ -9,6 +10,7 @@ except ImportError:
from nivision_parse import *
class StructSizerEmitter:
def __init__(self, out, config, hname):
self.out = out
@@ -70,12 +72,15 @@ int main()
return
print('asm("#STRUCT_SIZER [{name}]\\n");'.format(name=name), file=self.out)
print('asm("#STRUCT_SIZER _SIZE_=%0\\n" : : "n"((int)sizeof({name})));'.format(name=name), file=self.out)
print('asm("#STRUCT_SIZER _SIZE_=%0\\n" : : "n"((int)sizeof({name})));'.format(name=name),
file=self.out)
for fname, ftype, arr, comment in fields:
if ':' in fname:
continue # can't handle bitfields
print('asm("#STRUCT_SIZER {field}=%0\\n" : : "n"((int)offsetof({name}, {field})));'.format(name=name, field=fname), file=self.out)
continue # can't handle bitfields
print(
'asm("#STRUCT_SIZER {field}=%0\\n" : : "n"((int)offsetof({name}, {field})));'.format(
name=name, field=fname), file=self.out)
def struct(self, name, fields):
self.structunion("Structure", name, fields)
@@ -83,12 +88,13 @@ int main()
def union(self, name, fields):
self.structunion("Union", name, fields)
def generate(srcdir, configpath=None, hpath=None):
# read config file
config = configparser.ConfigParser()
config.read(configpath)
block_comment_exclude = set(x.strip() for x in
config.get("Block Comment", "exclude").splitlines())
config.get("Block Comment", "exclude").splitlines())
# open input file
inf = open(hpath)
@@ -103,6 +109,7 @@ def generate(srcdir, configpath=None, hpath=None):
parse_file(emit, inf, block_comment_exclude)
emit.finish()
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: gen_struct_sizer.py <header.h> <config.ini>")

View File

@@ -1,6 +1,8 @@
from __future__ import print_function
import sys
def main():
for line in sys.stdin:
line = line.strip()
@@ -10,5 +12,6 @@ def main():
line = line.replace("#", "")
print(line)
if __name__ == "__main__":
main()

View File

@@ -1,8 +1,10 @@
from __future__ import print_function
import re
import traceback
__all__ = ["define_after_struct", "defined", "forward_structs", "opaque_structs", "enums", "structs", "prescan_file", "parse_file", "number_re", "constant_re"]
__all__ = ["define_after_struct", "defined", "forward_structs", "opaque_structs", "enums",
"structs", "prescan_file", "parse_file", "number_re", "constant_re"]
# parser regular expressions
number_re = re.compile(r'-?[0-9]+')
@@ -12,9 +14,12 @@ enum_re = re.compile(r'^typedef\s+enum\s+(?P<name>[A-Za-z0-9]+)_enum\s*{')
enum_value_re = re.compile(r'^\s*(?P<name>[A-Za-z0-9_]+)\s*(=\s*(?P<value>-?[0-9A-Fx]+))?\s*,?')
struct_re = re.compile(r'^typedef\s+struct\s+(?P<name>[A-Za-z0-9]+)_struct\s*{')
union_re = re.compile(r'^typedef\s+union\s+(?P<name>[A-Za-z0-9]+)_union\s*{')
func_pointer_re = re.compile(r'\s*(?P<restype>[A-Za-z0-9_*]+)\s*\(\s*[A-Za-z0-9_]*\s*[*]\s*(?P<name>[A-Za-z0-9_]+)\s*\)\s*\((?P<params>[^)]*)\)')
static_const_re = re.compile(r'^static\s+const\s+(?P<type>[A-Za-z0-9_]+)\s+(?P<name>[A-Za-z0-9_]+)\s*=\s*(?P<value>[^;]+);')
function_re = re.compile(r'^((IMAQ|NI)_FUNC\s+)?(?P<restype>(const\s+)?[A-Za-z0-9_*]+)\s+((IMAQ_STDCALL|NI_FUNC[C]?)\s+)?(?P<name>[A-Za-z0-9_]+)\s*\((?P<params>[^)]*)\);')
func_pointer_re = re.compile(
r'\s*(?P<restype>[A-Za-z0-9_*]+)\s*\(\s*[A-Za-z0-9_]*\s*[*]\s*(?P<name>[A-Za-z0-9_]+)\s*\)\s*\((?P<params>[^)]*)\)')
static_const_re = re.compile(
r'^static\s+const\s+(?P<type>[A-Za-z0-9_]+)\s+(?P<name>[A-Za-z0-9_]+)\s*=\s*(?P<value>[^;]+);')
function_re = re.compile(
r'^((IMAQ|NI)_FUNC\s+)?(?P<restype>(const\s+)?[A-Za-z0-9_*]+)\s+((IMAQ_STDCALL|NI_FUNC[C]?)\s+)?(?P<name>[A-Za-z0-9_]+)\s*\((?P<params>[^)]*)\);')
# defines deferred until after structures
define_after_struct = []
@@ -24,6 +29,7 @@ opaque_structs = set()
enums = set()
structs = set()
def parse_cdecl(decl):
decl = " ".join(decl.split())
ctype, sep, name = decl.rpartition(' ')
@@ -35,6 +41,7 @@ def parse_cdecl(decl):
arr = None
return name, ctype, arr
def split_comment(line):
if line.startswith('/*'):
return "", ""
@@ -43,6 +50,7 @@ def split_comment(line):
comment = parts[1].strip() if len(parts) > 1 else None
return code, comment
def prescan_file(f):
for line in f:
code, comment = split_comment(line)
@@ -66,6 +74,7 @@ def prescan_file(f):
opaque_structs.update(forward_structs - structs)
def parse_file(emit, f, block_comment_exclude):
in_block_comment = False
cur_block = ""
@@ -77,7 +86,7 @@ def parse_file(emit, f, block_comment_exclude):
code, comment = split_comment(line)
if not code and not comment:
continue
#print(comment)
# print(comment)
# in block comment
if in_block_comment:
@@ -87,7 +96,8 @@ def parse_file(emit, f, block_comment_exclude):
try:
emit.block_comment(cur_block)
except Exception as e:
print("%d: exception in block_comment():\n%s" % (lineno+1, traceback.format_exc()))
print("%d: exception in block_comment():\n%s" % (
lineno + 1, traceback.format_exc()))
in_block_comment = False
# emit "after struct" constants in Globals
if cur_block == "Globals":
@@ -95,7 +105,8 @@ def parse_file(emit, f, block_comment_exclude):
try:
emit.text(dtext)
except Exception as e:
print("%d: exception in text():\n%s" % (lineno+1, traceback.format_exc()))
print("%d: exception in text():\n%s" % (
lineno + 1, traceback.format_exc()))
defined.add(dname)
continue
if not code and comment is not None:
@@ -110,7 +121,7 @@ def parse_file(emit, f, block_comment_exclude):
try:
emit.enum(*in_enum)
except Exception as e:
print("%d: exception in enum():\n%s" % (lineno+1, traceback.format_exc()))
print("%d: exception in enum():\n%s" % (lineno + 1, traceback.format_exc()))
in_enum = None
continue
m = enum_value_re.match(code)
@@ -126,13 +137,15 @@ def parse_file(emit, f, block_comment_exclude):
try:
emit.struct(*in_struct)
except Exception as e:
print("%d: exception in struct(\"%s\"):\n%s" % (lineno+1, in_struct[0], traceback.format_exc()))
print("%d: exception in struct(\"%s\"):\n%s" % (
lineno + 1, in_struct[0], traceback.format_exc()))
in_struct = None
if in_union is not None:
try:
emit.union(*in_union)
except Exception as e:
print("%d: exception in union(\"%s\"):\n%s" % (lineno+1, in_union[0], traceback.format_exc()))
print("%d: exception in union(\"%s\"):\n%s" % (
lineno + 1, in_union[0], traceback.format_exc()))
in_union = None
continue
name, ctype, arr = parse_cdecl(code[:-1])
@@ -153,7 +166,7 @@ def parse_file(emit, f, block_comment_exclude):
try:
emit.define(m.group('name'), m.group('value').strip(), comment)
except Exception as e:
print("%d: exception in define():\n%s" % (lineno+1, traceback.format_exc()))
print("%d: exception in define():\n%s" % (lineno + 1, traceback.format_exc()))
continue
# typedef enum {
@@ -179,11 +192,13 @@ def parse_file(emit, f, block_comment_exclude):
# typedef function?
m = func_pointer_re.match(code[8:-1])
if m is not None:
params = [parse_cdecl(param.strip()) for param in m.group('params').strip().split(',') if param.strip()]
params = [parse_cdecl(param.strip()) for param in
m.group('params').strip().split(',') if param.strip()]
try:
emit.typedef_function(m.group('name'), m.group('restype'), params)
except Exception as e:
print("%d: exception in typedef_function():\n%s" % (lineno+1, traceback.format_exc()))
print("%d: exception in typedef_function():\n%s" % (
lineno + 1, traceback.format_exc()))
continue
if '(' in code:
print("Invalid typedef: %s" % code)
@@ -194,11 +209,13 @@ def parse_file(emit, f, block_comment_exclude):
# function
m = function_re.match(code)
if m is not None:
params = [parse_cdecl(param.strip()) for param in m.group('params').strip().split(',') if param.strip()]
params = [parse_cdecl(param.strip()) for param in m.group('params').strip().split(',')
if param.strip()]
try:
emit.function(m.group('name'), m.group('restype'), params)
except Exception as e:
print("%d: exception in function(\"%s\"):\n%s" % (lineno+1, m.group('name'), traceback.format_exc()))
print("%d: exception in function(\"%s\"):\n%s" % (
lineno + 1, m.group('name'), traceback.format_exc()))
continue
# static const
@@ -210,7 +227,7 @@ def parse_file(emit, f, block_comment_exclude):
try:
emit.static_const(m.group('name'), m.group('type'), value)
except Exception as e:
print("%d: exception in static_const():\n%s" % (lineno+1, traceback.format_exc()))
print("%d: exception in static_const():\n%s" % (lineno + 1, traceback.format_exc()))
continue
if not code or code[0] == '#':
@@ -222,5 +239,4 @@ def parse_file(emit, f, block_comment_exclude):
if code == 'extern "C" {' or code == "}":
continue
print("%d: Unrecognized: %s" % (lineno+1, code))
print("%d: Unrecognized: %s" % (lineno + 1, code))

View File

@@ -5,12 +5,14 @@
package com.ni.vision;
import java.lang.reflect.*;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@SuppressWarnings("all")
public class NIVision {
private NIVision() {}

View File

@@ -7,8 +7,8 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
@@ -19,9 +19,11 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* ADXL345 I2C Accelerometer.
*
* @author dtjones
*/
@SuppressWarnings("TypeName")
public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindowSendable {
private static final byte kAddress = 0x1D;
@@ -29,26 +31,34 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
private static final byte kDataFormatRegister = 0x31;
private static final byte kDataRegister = 0x32;
private static final double kGsPerLSB = 0.00390625;
private static final byte kPowerCtl_Link = 0x20, kPowerCtl_AutoSleep = 0x10,
kPowerCtl_Measure = 0x08, kPowerCtl_Sleep = 0x04;
private static final byte kDataFormat_SelfTest = (byte) 0x80, kDataFormat_SPI = 0x40,
kDataFormat_IntInvert = 0x20, kDataFormat_FullRes = 0x08, kDataFormat_Justify = 0x04;
private static final byte kPowerCtl_Link = 0x20;
private static final byte kPowerCtl_AutoSleep = 0x10;
private static final byte kPowerCtl_Measure = 0x08;
private static final byte kPowerCtl_Sleep = 0x04;
public static enum Axes {
private static final byte kDataFormat_SelfTest = (byte) 0x80;
private static final byte kDataFormat_SPI = 0x40;
private static final byte kDataFormat_IntInvert = 0x20;
private static final byte kDataFormat_FullRes = 0x08;
private static final byte kDataFormat_Justify = 0x04;
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
kZ((byte) 0x04);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final byte value;
private Axes(byte value) {
Axes(byte value) {
this.value = value;
}
}
@SuppressWarnings("MemberName")
public static class AllAxes {
public double XAxis;
@@ -60,8 +70,8 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
/**
* Constructs the ADXL345 Accelerometer with I2C address 0x1D.
*$
* @param port The I2C port the accelerometer is attached to
*
* @param port The I2C port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure.
*/
public ADXL345_I2C(I2C.Port port, Range range) {
@@ -70,10 +80,10 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
/**
* Constructs the ADXL345 Accelerometer over I2C.
*$
* @param port The I2C port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure.
* @param the I2C address of the accelerometer (0x1D or 0x53)
*
* @param port The I2C port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure.
* @param deviceAddress I2C address of the accelerometer (0x1D or 0x53)
*/
public ADXL345_I2C(I2C.Port port, Range range, int deviceAddress) {
m_i2c = new I2C(port, deviceAddress);
@@ -87,10 +97,10 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
LiveWindow.addSensor("ADXL345_I2C", port.getValue(), this);
}
/** {inheritdoc} */
@Override
public void setRange(Range range) {
byte value = 0;
final byte value;
switch (range) {
case k2G:
@@ -105,25 +115,24 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
case k16G:
value = 3;
break;
default:
throw new IllegalArgumentException(range + " unsupported range type");
}
// Specify the data format to read
m_i2c.write(kDataFormatRegister, kDataFormat_FullRes | value);
}
/** {@inheritDoc} */
@Override
public double getX() {
return getAcceleration(Axes.kX);
}
/** {@inheritDoc} */
@Override
public double getY() {
return getAcceleration(Axes.kY);
}
/** {@inheritDoc} */
@Override
public double getZ() {
return getAcceleration(Axes.kZ);
@@ -147,8 +156,7 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL345 in Gs.
* @return An object containing the acceleration measured on each axis of the ADXL345 in Gs.
*/
public AllAxes getAccelerations() {
AllAxes data = new AllAxes();
@@ -163,19 +171,20 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
return data;
}
@Override
public String getSmartDashboardType() {
return "3AxisAccelerometer";
}
private ITable m_table;
/** {@inheritDoc} */
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/** {@inheritDoc} */
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("X", getX());
@@ -184,12 +193,16 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
}
}
/** {@inheritDoc} */
@Override
public ITable getTable() {
return m_table;
}
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,8 +7,8 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
@@ -19,10 +19,12 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* ADXL345 SPI Accelerometer.
*
* @author dtjones
* @author mwills
*/
@SuppressWarnings({"TypeName"})
public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindowSendable {
private static final int kPowerCtlRegister = 0x2D;
private static final int kDataFormatRegister = 0x31;
@@ -43,21 +45,23 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
private static final int kDataFormat_FullRes = 0x08;
private static final int kDataFormat_Justify = 0x04;
public static enum Axes {
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
kZ((byte) 0x04);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final byte value;
private Axes(byte value) {
Axes(byte value) {
this.value = value;
}
}
@SuppressWarnings("MemberName")
public static class AllAxes {
public double XAxis;
@@ -70,7 +74,7 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
/**
* Constructor.
*
* @param port The SPI port that the accelerometer is connected to
* @param port The SPI port that the accelerometer is connected to
* @param range The range (+ or -) that the accelerometer will measure.
*/
public ADXL345_SPI(SPI.Port port, Range range) {
@@ -84,7 +88,7 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
}
/**
* Set SPI bus parameters, bring device out of sleep and set format
* Set SPI bus parameters, bring device out of sleep and set format.
*
* @param range The range (+ or -) that the accelerometer will measure.
*/
@@ -106,10 +110,9 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
UsageReporting.report(tResourceType.kResourceType_ADXL345, tInstances.kADXL345_SPI);
}
/** {inheritdoc} */
@Override
public void setRange(Range range) {
byte value = 0;
final byte value;
switch (range) {
case k2G:
@@ -124,26 +127,25 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
case k16G:
value = 3;
break;
default:
throw new IllegalArgumentException(range + " unsupported");
}
// Specify the data format to read
byte[] commands = new byte[] {kDataFormatRegister, (byte) (kDataFormat_FullRes | value)};
byte[] commands = new byte[]{kDataFormatRegister, (byte) (kDataFormat_FullRes | value)};
m_spi.write(commands, commands.length);
}
/** {@inheritDoc} */
@Override
public double getX() {
return getAcceleration(Axes.kX);
}
/** {@inheritDoc} */
@Override
public double getY() {
return getAcceleration(Axes.kY);
}
/** {@inheritDoc} */
@Override
public double getZ() {
return getAcceleration(Axes.kZ);
@@ -157,7 +159,8 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
*/
public double getAcceleration(ADXL345_SPI.Axes axis) {
ByteBuffer transferBuffer = ByteBuffer.allocateDirect(3);
transferBuffer.put(0, (byte) ((kAddress_Read | kAddress_MultiByte | kDataRegister) + axis.value));
transferBuffer.put(0,
(byte) ((kAddress_Read | kAddress_MultiByte | kDataRegister) + axis.value));
m_spi.transaction(transferBuffer, transferBuffer, 3);
// Sensor is little endian
transferBuffer.order(ByteOrder.LITTLE_ENDIAN);
@@ -168,8 +171,7 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL345 in Gs.
* @return An object containing the acceleration measured on each axis of the ADXL345 in Gs.
*/
public ADXL345_SPI.AllAxes getAccelerations() {
ADXL345_SPI.AllAxes data = new ADXL345_SPI.AllAxes();
@@ -188,19 +190,20 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
return data;
}
@Override
public String getSmartDashboardType() {
return "3AxisAccelerometer";
}
private ITable m_table;
/** {@inheritDoc} */
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/** {@inheritDoc} */
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("X", getX());
@@ -209,12 +212,16 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
}
}
/** {@inheritDoc} */
@Override
public ITable getTable() {
return m_table;
}
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,10 +7,9 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
@@ -21,7 +20,7 @@ import edu.wpi.first.wpilibj.tables.ITable;
/**
* ADXL362 SPI Accelerometer.
*
* This class allows access to an Analog Devices ADXL362 3-axis accelerometer.
* <p>This class allows access to an Analog Devices ADXL362 3-axis accelerometer.
*/
public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSendable {
private static final byte kRegWrite = 0x0A;
@@ -41,21 +40,23 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
private static final byte kPowerCtl_AutoSleep = 0x04;
private static final byte kPowerCtl_Measure = 0x02;
public static enum Axes {
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
kZ((byte) 0x04);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final byte value;
private Axes(byte value) {
Axes(byte value) {
this.value = value;
}
}
@SuppressWarnings("MemberName")
public static class AllAxes {
public double XAxis;
@@ -78,7 +79,7 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
/**
* Constructor.
*
* @param port The SPI port that the accelerometer is connected to
* @param port The SPI port that the accelerometer is connected to
* @param range The range (+ or -) that the accelerometer will measure.
*/
public ADXL362(SPI.Port port, Range range) {
@@ -94,7 +95,7 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
transferBuffer.put(0, kRegRead);
transferBuffer.put(1, kPartIdRegister);
m_spi.transaction(transferBuffer, transferBuffer, 3);
if (transferBuffer.get(2) != (byte)0xF2) {
if (transferBuffer.get(2) != (byte) 0xF2) {
m_spi.free();
m_spi = null;
DriverStation.reportError("could not find ADXL362 on SPI port " + port.getValue(), false);
@@ -117,45 +118,46 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
m_spi.free();
}
/** {inheritdoc} */
@Override
public void setRange(Range range) {
byte value = 0;
final byte value;
switch (range) {
case k2G:
value = kFilterCtl_Range2G;
m_gsPerLSB = 0.001;
m_gsPerLSB = 0.001;
break;
case k4G:
value = kFilterCtl_Range4G;
m_gsPerLSB = 0.002;
m_gsPerLSB = 0.002;
break;
case k8G:
case k16G: // 16G not supported; treat as 8G
value = kFilterCtl_Range8G;
m_gsPerLSB = 0.004;
m_gsPerLSB = 0.004;
break;
default:
throw new IllegalArgumentException(range + " unsupported");
}
// Specify the data format to read
byte[] commands = new byte[] {kRegWrite, kFilterCtlRegister, (byte) (kFilterCtl_ODR_100Hz | value)};
byte[] commands = new byte[]{kRegWrite, kFilterCtlRegister, (byte) (kFilterCtl_ODR_100Hz
| value)};
m_spi.write(commands, commands.length);
}
/** {@inheritDoc} */
@Override
public double getX() {
return getAcceleration(Axes.kX);
}
/** {@inheritDoc} */
@Override
public double getY() {
return getAcceleration(Axes.kY);
}
/** {@inheritDoc} */
@Override
public double getZ() {
return getAcceleration(Axes.kZ);
@@ -168,8 +170,9 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
* @return Acceleration of the ADXL362 in Gs.
*/
public double getAcceleration(ADXL362.Axes axis) {
if (m_spi == null)
if (m_spi == null) {
return 0.0;
}
ByteBuffer transferBuffer = ByteBuffer.allocateDirect(4);
transferBuffer.put(0, kRegRead);
transferBuffer.put(1, (byte) (kDataRegister + axis.value));
@@ -183,8 +186,7 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL362 in Gs.
* @return An object containing the acceleration measured on each axis of the ADXL362 in Gs.
*/
public ADXL362.AllAxes getAccelerations() {
ADXL362.AllAxes data = new ADXL362.AllAxes();
@@ -204,19 +206,20 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
return data;
}
@Override
public String getSmartDashboardType() {
return "3AxisAccelerometer";
}
private ITable m_table;
/** {@inheritDoc} */
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/** {@inheritDoc} */
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("X", getX());
@@ -225,12 +228,16 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
}
}
/** {@inheritDoc} */
@Override
public ITable getTable() {
return m_table;
}
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,28 +7,25 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Use a rate gyro to return the robots heading relative to a starting position.
* The Gyro class tracks the robots heading based on the starting position. As
* the robot rotates the new heading is computed by integrating the rate of
* rotation returned by the sensor. When the class is instantiated, it does a
* short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to
* determine the heading.
* Use a rate gyro to return the robots heading relative to a starting position. The Gyro class
* tracks the robots heading based on the starting position. As the robot rotates the new heading is
* computed by integrating the rate of rotation returned by the sensor. When the class is
* instantiated, it does a short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to determine the heading.
*
* This class is for the digital ADXRS450 gyro sensor that connects via SPI.
* <p>This class is for the digital ADXRS450 gyro sensor that connects via SPI.
*/
@SuppressWarnings({"TypeName", "AbbreviationAsWordInName"})
public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWindowSendable {
private static final double kSamplePeriod = 0.001;
private static final double kCalibrationSampleTime = 5.0;
@@ -70,7 +67,8 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
if ((readRegister(kPIDRegister) & 0xff00) != 0x5200) {
m_spi.free();
m_spi = null;
DriverStation.reportError("could not find ADXRS450 gyro on SPI port " + port.getValue(), false);
DriverStation.reportError("could not find ADXRS450 gyro on SPI port " + port.getValue(),
false);
return;
}
@@ -83,12 +81,11 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
LiveWindow.addSensor("ADXRS450_Gyro", port.getValue(), this);
}
/**
* {@inheritDoc}
*/
@Override
public void calibrate() {
if (m_spi == null) return;
if (m_spi == null) {
return;
}
Timer.delay(0.1);
@@ -97,15 +94,15 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
Timer.delay(kCalibrationSampleTime);
m_spi.setAccumulatorCenter((int)m_spi.getAccumulatorAverage());
m_spi.setAccumulatorCenter((int) m_spi.getAccumulatorAverage());
m_spi.resetAccumulator();
}
private boolean calcParity(int v) {
private boolean calcParity(int value) {
boolean parity = false;
while (v != 0) {
while (value != 0) {
parity = !parity;
v = v & (v - 1);
value = value & (value - 1);
}
return parity;
}
@@ -130,9 +127,7 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
return (buf.getInt(0) >> 5) & 0xffff;
}
/**
* {@inheritDoc}
*/
@Override
public void reset() {
m_spi.resetAccumulator();
}
@@ -148,19 +143,19 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
}
}
/**
* {@inheritDoc}
*/
@Override
public double getAngle() {
if (m_spi == null) return 0.0;
if (m_spi == null) {
return 0.0;
}
return m_spi.getAccumulatorValue() * kDegreePerSecondPerLSB * kSamplePeriod;
}
/**
* {@inheritDoc}
*/
@Override
public double getRate() {
if (m_spi == null) return 0.0;
if (m_spi == null) {
return 0.0;
}
return m_spi.getAccumulatorLastValue() * kDegreePerSecondPerLSB;
}
}

View File

@@ -8,18 +8,20 @@
package edu.wpi.first.wpilibj;
/**
* Structure for holding the values stored in an accumulator
*$
* Structure for holding the values stored in an accumulator.
*
* @author brad
*/
public class AccumulatorResult {
/**
* The total value accumulated
* The total value accumulated.
*/
@SuppressWarnings("MemberName")
public long value;
/**
* The number of sample vaule was accumulated over
* The number of sample vaule was accumulated over.
*/
@SuppressWarnings("MemberName")
public long count;
}

View File

@@ -15,10 +15,9 @@ import edu.wpi.first.wpilibj.tables.ITable;
/**
* Handle operation of an analog accelerometer. The accelerometer reads
* acceleration directly through the sensor. Many sensors have multiple axis and
* can be treated as multiple devices. Each is calibrated by finding the center
* value over a period of time.
* Handle operation of an analog accelerometer. The accelerometer reads acceleration directly
* through the sensor. Many sensors have multiple axis and can be treated as multiple devices. Each
* is calibrated by finding the center value over a period of time.
*/
public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWindowSendable {
@@ -29,7 +28,7 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
protected PIDSourceType m_pidSource = PIDSourceType.kDisplacement;
/**
* Common initialization
* Common initialization.
*/
private void initAccelerometer() {
UsageReporting.report(tResourceType.kResourceType_Accelerometer, m_analogChannel.getChannel());
@@ -39,10 +38,9 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Create a new instance of an accelerometer.
*
* The constructor allocates desired analog channel.
*$
* @param channel The channel number for the analog input the accelerometer is
* connected to
* <p>The constructor allocates desired analog channel.
*
* @param channel The channel number for the analog input the accelerometer is connected to
*/
public AnalogAccelerometer(final int channel) {
m_allocatedChannel = true;
@@ -51,18 +49,18 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
}
/**
* Create a new instance of Accelerometer from an existing AnalogChannel. Make
* a new instance of accelerometer given an AnalogChannel. This is
* particularly useful if the port is going to be read as an analog channel as
* well as through the Accelerometer class.
*$
* @param channel The existing AnalogInput object for the analog input the
* accelerometer is connected to
* Create a new instance of Accelerometer from an existing AnalogChannel. Make a new instance of
* accelerometer given an AnalogChannel. This is particularly useful if the port is going to be
* read as an analog channel as well as through the Accelerometer class.
*
* @param channel The existing AnalogInput object for the analog input the accelerometer is
* connected to
*/
public AnalogAccelerometer(AnalogInput channel) {
m_allocatedChannel = false;
if (channel == null)
if (channel == null) {
throw new NullPointerException("Analog Channel given was null");
}
m_analogChannel = channel;
initAccelerometer();
}
@@ -70,6 +68,7 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Delete the analog components used for the accelerometer.
*/
@Override
public void free() {
if (m_analogChannel != null && m_allocatedChannel) {
m_analogChannel.free();
@@ -80,7 +79,7 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Return the acceleration in Gs.
*
* The acceleration is returned units of Gs.
* <p>The acceleration is returned units of Gs.
*
* @return The current acceleration of the sensor in Gs.
*/
@@ -91,9 +90,8 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Set the accelerometer sensitivity.
*
* This sets the sensitivity of the accelerometer used for calculating the
* acceleration. The sensitivity varies by accelerometer model. There are
* constants defined for various models.
* <p>This sets the sensitivity of the accelerometer used for calculating the acceleration. The
* sensitivity varies by accelerometer model. There are constants defined for various models.
*
* @param sensitivity The sensitivity of accelerometer in Volts per G.
*/
@@ -104,8 +102,8 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Set the voltage that corresponds to 0 G.
*
* The zero G voltage varies by accelerometer model. There are constants
* defined for various models.
* <p>The zero G voltage varies by accelerometer model. There are constants defined for various
* models.
*
* @param zero The zero G voltage.
*/
@@ -113,16 +111,12 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
m_zeroGVoltage = zero;
}
/**
* {@inheritDoc}
*/
@Override
public void setPIDSourceType(PIDSourceType pidSource) {
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -132,10 +126,12 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
*
* @return The current acceleration in Gs.
*/
@Override
public double pidGet() {
return getAcceleration();
}
@Override
public String getSmartDashboardType() {
return "Accelerometer";
}
@@ -145,24 +141,18 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
*/
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getAcceleration());
@@ -170,14 +160,16 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
}
/**
* Analog Channels don't have to do anything special when entering the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* Analog Channels don't have to do anything special when exiting the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -12,39 +12,35 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Use a rate gyro to return the robots heading relative to a starting position.
* The Gyro class tracks the robots heading based on the starting position. As
* the robot rotates the new heading is computed by integrating the rate of
* rotation returned by the sensor. When the class is instantiated, it does a
* short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to
* determine the heading.
* Use a rate gyro to return the robots heading relative to a starting position. The Gyro class
* tracks the robots heading based on the starting position. As the robot rotates the new heading is
* computed by integrating the rate of rotation returned by the sensor. When the class is
* instantiated, it does a short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to determine the heading.
*
* This class is for gyro sensors that connect to an analog input.
* <p>This class is for gyro sensors that connect to an analog input.
*/
public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowSendable {
static final int kOversampleBits = 10;
static final int kAverageBits = 0;
static final double kSamplesPerSecond = 50.0;
static final double kCalibrationSampleTime = 5.0;
static final double kDefaultVoltsPerDegreePerSecond = 0.007;
private static final int kOversampleBits = 10;
private static final int kAverageBits = 0;
private static final double kSamplesPerSecond = 50.0;
private static final double kCalibrationSampleTime = 5.0;
private static final double kDefaultVoltsPerDegreePerSecond = 0.007;
protected AnalogInput m_analog;
double m_voltsPerDegreePerSecond;
double m_offset;
int m_center;
boolean m_channelAllocated = false;
AccumulatorResult result;
private PIDSourceType m_pidSource;
private double m_voltsPerDegreePerSecond;
private double m_offset;
private int m_center;
private boolean m_channelAllocated = false;
private AccumulatorResult m_result;
/**
* Initialize the gyro. Calibration is handled by calibrate().
*/
public void initGyro() {
result = new AccumulatorResult();
m_result = new AccumulatorResult();
m_voltsPerDegreePerSecond = kDefaultVoltsPerDegreePerSecond;
m_analog.setAverageBits(kAverageBits);
@@ -61,20 +57,18 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
LiveWindow.addSensor("AnalogGyro", m_analog.getChannel(), this);
}
/**
* {@inheritDoc}
*/
@Override
public void calibrate() {
m_analog.initAccumulator();
m_analog.resetAccumulator();
Timer.delay(kCalibrationSampleTime);
m_analog.getAccumulatorOutput(result);
m_analog.getAccumulatorOutput(m_result);
m_center = (int) ((double) result.value / (double) result.count + .5);
m_center = (int) ((double) m_result.value / (double) m_result.count + .5);
m_offset = ((double) result.value / (double) result.count) - m_center;
m_offset = ((double) m_result.value / (double) m_result.count) - m_center;
m_analog.setAccumulatorCenter(m_center);
m_analog.resetAccumulator();
@@ -83,8 +77,8 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
/**
* Gyro constructor using the channel number
*
* @param channel The analog channel the gyro is connected to. Gyros can only
* be used on on-board channels 0-1.
* @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board
* channels 0-1.
*/
public AnalogGyro(int channel) {
this(new AnalogInput(channel));
@@ -92,11 +86,11 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Gyro constructor with a precreated analog channel object. Use this
* constructor when the analog channel needs to be shared.
* Gyro constructor with a precreated analog channel object. Use this constructor when the analog
* channel needs to be shared.
*
* @param channel The AnalogInput object that the gyro is connected to. Gyros
* can only be used on on-board channels 0-1.
* @param channel The AnalogInput object that the gyro is connected to. Gyros can only be used on
* on-board channels 0-1.
*/
public AnalogGyro(AnalogInput channel) {
m_analog = channel;
@@ -108,12 +102,13 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Gyro constructor using the channel number along with parameters for
* presetting the center and offset values. Bypasses calibration.
* @param channel The analog channel the gyro is connected to. Gyros can only
* be used on on-board channels 0-1.
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
* Gyro constructor using the channel number along with parameters for presetting the center and
* offset values. Bypasses calibration.
*
* @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board
* channels 0-1.
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
*/
public AnalogGyro(int channel, int center, double offset) {
this(new AnalogInput(channel), center, offset);
@@ -121,13 +116,13 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Gyro constructor with a precreated analog channel object along with
* parameters for presetting the center and offset values. Bypasses
* calibration.
* @param channel The analog channel the gyro is connected to. Gyros can only
* be used on on-board channels 0-1.
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
* Gyro constructor with a precreated analog channel object along with parameters for presetting
* the center and offset values. Bypasses calibration.
*
* @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board
* channels 0-1.
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
*/
public AnalogGyro(AnalogInput channel, int center, double offset) {
m_analog = channel;
@@ -142,9 +137,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
m_analog.resetAccumulator();
}
/**
* {@inheritDoc}
*/
@Override
public void reset() {
if (m_analog != null) {
m_analog.resetAccumulator();
@@ -162,16 +155,14 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
m_analog = null;
}
/**
* {@inheritDoc}
*/
@Override
public synchronized double getAngle() {
if (m_analog == null) {
return 0.0;
} else {
m_analog.getAccumulatorOutput(result);
m_analog.getAccumulatorOutput(m_result);
long value = result.value - (long) (result.count * m_offset);
long value = m_result.value - (long) (m_result.count * m_offset);
double scaledValue =
value * 1e-9 * m_analog.getLSBWeight() * (1 << m_analog.getAverageBits())
@@ -181,9 +172,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
}
/**
* {@inheritDoc}
*/
@Override
public double getRate() {
if (m_analog == null) {
return 0.0;
@@ -194,8 +183,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Return the gyro offset value set during calibration to
* use as a future preset
* Return the gyro offset value set during calibration to use as a future preset.
*
* @return the current offset value
*/
@@ -204,8 +192,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Return the gyro center value set during calibration to
* use as a future preset
* Return the gyro center value set during calibration to use as a future preset.
*
* @return the current center value
*/
@@ -214,10 +201,9 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Set the gyro sensitivity. This takes the number of volts/degree/second
* sensitivity of the gyro and uses it in subsequent calculations to allow the
* code to work with multiple gyros. This value is typically found in the gyro
* datasheet.
* Set the gyro sensitivity. This takes the number of volts/degree/second sensitivity of the gyro
* and uses it in subsequent calculations to allow the code to work with multiple gyros. This
* value is typically found in the gyro datasheet.
*
* @param voltsPerDegreePerSecond The sensitivity in Volts/degree/second.
*/
@@ -226,10 +212,9 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Set the size of the neutral zone. Any voltage from the gyro less than this
* amount from the center is considered stationary. Setting a deadband will
* decrease the amount of drift when the gyro isn't rotating, but will make it
* less accurate.
* Set the size of the neutral zone. Any voltage from the gyro less than this amount from the
* center is considered stationary. Setting a deadband will decrease the amount of drift when the
* gyro isn't rotating, but will make it less accurate.
*
* @param volts The size of the deadband in volts
*/

View File

@@ -7,12 +7,8 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ByteBuffer;
// import com.sun.jna.Pointer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
@@ -26,17 +22,14 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Analog channel class.
*
* Each analog channel is read from hardware as a 12-bit number representing 0V
* to 5V.
* <p>Each analog channel is read from hardware as a 12-bit number representing 0V to 5V.
*
* Connected to each analog channel is an averaging and oversampling engine.
* This engine accumulates the specified ( by setAverageBits() and
* setOversampleBits() ) number of samples before returning a new value. This is
* not a sliding window average. The only difference between the oversampled
* samples and the averaged samples is that the oversampled samples are simply
* accumulated effectively increasing the resolution, while the averaged samples
* are divided by the number of samples to retain the resolution, but get more
* stable values.
* <p>Connected to each analog channel is an averaging and oversampling engine. This engine
* accumulates the specified ( by setAverageBits() and setOversampleBits() ) number of samples
* before returning a new value. This is not a sliding window average. The only difference between
* the oversampled samples and the averaged samples is that the oversampled samples are simply
* accumulated effectively increasing the resolution, while the averaged samples are divided by the
* number of samples to retain the resolution, but get more stable values.
*/
public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSendable {
@@ -51,8 +44,7 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Construct an analog channel.
*
* @param channel The channel number to represent. 0-3 are on-board 4-7 are on
* the MXP port.
* @param channel The channel number to represent. 0-3 are on-board 4-7 are on the MXP port.
*/
public AnalogInput(final int channel) {
m_channel = channel;
@@ -63,12 +55,12 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
try {
channels.allocate(channel);
} catch (CheckedAllocationException e) {
} catch (CheckedAllocationException ex) {
throw new AllocationException("Analog input channel " + m_channel + " is already allocated");
}
long port_pointer = AnalogJNI.getPort((byte) channel);
m_port = AnalogJNI.initializeAnalogInputPort(port_pointer);
final long portPointer = AnalogJNI.getPort((byte) channel);
m_port = AnalogJNI.initializeAnalogInputPort(portPointer);
LiveWindow.addSensor("AnalogInput", channel, this);
UsageReporting.report(tResourceType.kResourceType_AnalogChannel, channel);
@@ -86,10 +78,9 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get a sample straight from this channel. The sample is a 12-bit value
* representing the 0V to 5V range of the A/D converter. The units are in A/D
* converter codes. Use GetVoltage() to get the analog value in calibrated
* units.
* Get a sample straight from this channel. The sample is a 12-bit value representing the 0V to 5V
* range of the A/D converter. The units are in A/D converter codes. Use GetVoltage() to get the
* analog value in calibrated units.
*
* @return A sample straight from this channel.
*/
@@ -98,13 +89,12 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get a sample from the output of the oversample and average engine for this
* channel. The sample is 12-bit + the bits configured in SetOversampleBits().
* The value configured in setAverageBits() will cause this value to be
* averaged 2^bits number of samples. This is not a sliding window. The sample
* will not change until 2^(OversampleBits + AverageBits) samples have been
* acquired from this channel. Use getAverageVoltage() to get the analog value
* in calibrated units.
* Get a sample from the output of the oversample and average engine for this channel. The sample
* is 12-bit + the bits configured in SetOversampleBits(). The value configured in
* setAverageBits() will cause this value to be averaged 2^bits number of samples. This is not a
* sliding window. The sample will not change until 2^(OversampleBits + AverageBits) samples have
* been acquired from this channel. Use getAverageVoltage() to get the analog value in calibrated
* units.
*
* @return A sample from the oversample and average engine for this channel.
*/
@@ -113,9 +103,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get a scaled sample straight from this channel. The value is scaled to
* units of Volts using the calibrated scaling data from getLSBWeight() and
* getOffset().
* Get a scaled sample straight from this channel. The value is scaled to units of Volts using the
* calibrated scaling data from getLSBWeight() and getOffset().
*
* @return A scaled sample straight from this channel.
*/
@@ -124,26 +113,23 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get a scaled sample from the output of the oversample and average engine
* for this channel. The value is scaled to units of Volts using the
* calibrated scaling data from getLSBWeight() and getOffset(). Using
* oversampling will cause this value to be higher resolution, but it will
* update more slowly. Using averaging will cause this value to be more
* stable, but it will update more slowly.
* Get a scaled sample from the output of the oversample and average engine for this channel. The
* value is scaled to units of Volts using the calibrated scaling data from getLSBWeight() and
* getOffset(). Using oversampling will cause this value to be higher resolution, but it will
* update more slowly. Using averaging will cause this value to be more stable, but it will update
* more slowly.
*
* @return A scaled sample from the output of the oversample and average
* engine for this channel.
* @return A scaled sample from the output of the oversample and average engine for this channel.
*/
public double getAverageVoltage() {
return AnalogJNI.getAnalogAverageVoltage(m_port);
}
/**
* Get the factory scaling least significant bit weight constant. The least
* significant bit weight constant for the channel that was calibrated in
* manufacturing and stored in an eeprom.
* Get the factory scaling least significant bit weight constant. The least significant bit weight
* constant for the channel that was calibrated in manufacturing and stored in an eeprom.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
* <p>Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @return Least significant bit weight.
*/
@@ -152,10 +138,10 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get the factory scaling offset constant. The offset constant for the
* channel that was calibrated in manufacturing and stored in an eeprom.
* Get the factory scaling offset constant. The offset constant for the channel that was
* calibrated in manufacturing and stored in an eeprom.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
* <p>Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @return Offset constant.
*/
@@ -173,9 +159,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Set the number of averaging bits. This sets the number of averaging bits.
* The actual number of averaged samples is 2^bits. The averaging is done
* automatically in the FPGA.
* Set the number of averaging bits. This sets the number of averaging bits. The actual number of
* averaged samples is 2^bits. The averaging is done automatically in the FPGA.
*
* @param bits The number of averaging bits.
*/
@@ -184,9 +169,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get the number of averaging bits. This gets the number of averaging bits
* from the FPGA. The actual number of averaged samples is 2^bits. The
* averaging is done automatically in the FPGA.
* Get the number of averaging bits. This gets the number of averaging bits from the FPGA. The
* actual number of averaged samples is 2^bits. The averaging is done automatically in the FPGA.
*
* @return The number of averaging bits.
*/
@@ -195,9 +179,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Set the number of oversample bits. This sets the number of oversample bits.
* The actual number of oversampled values is 2^bits. The oversampling is done
* automatically in the FPGA.
* Set the number of oversample bits. This sets the number of oversample bits. The actual number
* of oversampled values is 2^bits. The oversampling is done automatically in the FPGA.
*
* @param bits The number of oversample bits.
*/
@@ -206,9 +189,9 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get the number of oversample bits. This gets the number of oversample bits
* from the FPGA. The actual number of oversampled values is 2^bits. The
* oversampling is done automatically in the FPGA.
* Get the number of oversample bits. This gets the number of oversample bits from the FPGA. The
* actual number of oversampled values is 2^bits. The oversampling is done automatically in the
* FPGA.
*
* @return The number of oversample bits.
*/
@@ -231,10 +214,9 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Set an initial value for the accumulator.
*
* This will be added to all values returned to the user.
* <p>This will be added to all values returned to the user.
*
* @param initialValue The value that the accumulator should start from when
* reset.
* @param initialValue The value that the accumulator should start from when reset.
*/
public void setAccumulatorInitialValue(long initialValue) {
m_accumulatorOffset = initialValue;
@@ -258,13 +240,13 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Set the center value of the accumulator.
*
* The center value is subtracted from each A/D value before it is added to
* the accumulator. This is used for the center value of devices like gyros
* and accelerometers to take the device offset into account when integrating.
* <p>The center value is subtracted from each A/D value before it is added to the accumulator.
* This is used for the center value of devices like gyros and accelerometers to take the device
* offset into account when integrating.
*
* This center value is based on the output of the oversampled and averaged
* source the accumulator channel. Because of this, any non-zero oversample
* bits will affect the size of the value for this field.
* <p>This center value is based on the output of the oversampled and averaged source the
* accumulator channel. Because of this, any non-zero oversample bits will affect the size of the
* value for this field.
*/
public void setAccumulatorCenter(int center) {
AnalogJNI.setAccumulatorCenter(m_port, center);
@@ -272,7 +254,7 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Set the accumulator's deadband.
*$
*
* @param deadband The deadband size in ADC codes (12-bit value)
*/
public void setAccumulatorDeadband(int deadband) {
@@ -282,8 +264,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Read the accumulated value.
*
* Read the value that has been accumulating. The accumulator is attached
* after the oversample and average engine.
* <p>Read the value that has been accumulating. The accumulator is attached after the oversample
* and average engine.
*
* @return The 64-bit value accumulated since the last Reset().
*/
@@ -294,8 +276,7 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last
* Reset().
* <p>Read the count of the accumulated values since the accumulator was last Reset().
*
* @return The number of times samples from the channel were accumulated.
*/
@@ -306,8 +287,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* This function reads the value and count from the FPGA atomically. This can
* be used for averaging.
* <p>This function reads the value and count from the FPGA atomically. This can be used for
* averaging.
*
* @param result AccumulatorResult object to store the results in.
*/
@@ -316,7 +297,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
throw new IllegalArgumentException("Null parameter `result'");
}
if (!isAccumulatorChannel()) {
throw new IllegalArgumentException("Channel " + m_channel + " is not an accumulator channel.");
throw new IllegalArgumentException(
"Channel " + m_channel + " is not an accumulator channel.");
}
ByteBuffer value = ByteBuffer.allocateDirect(8);
// set the byte order
@@ -346,10 +328,9 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Set the sample rate per channel.
*
* This is a global setting for all channels. The maximum rate is 500kS/s
* divided by the number of channels in use. This is 62500 samples/s per
* channel if all 8 channels are used.
*$
* <p>This is a global setting for all channels. The maximum rate is 500kS/s divided by the number
* of channels in use. This is 62500 samples/s per channel if all 8 channels are used.
*
* @param samplesPerSecond The number of samples per second.
*/
public static void setGlobalSampleRate(final double samplesPerSecond) {
@@ -359,8 +340,7 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Get the current sample rate.
*
* This assumes one entry in the scan list. This is a global setting for all
* channels.
* <p>This assumes one entry in the scan list. This is a global setting for all channels.
*
* @return Sample rate.
*/
@@ -368,25 +348,22 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
return AnalogJNI.getAnalogSampleRate();
}
/**
* {@inheritDoc}
*/
@Override
public void setPIDSourceType(PIDSourceType pidSource) {
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
/**
* Get the average voltage for use with PIDController
* Get the average voltage for use with PIDController.
*
* @return the average voltage
*/
@Override
public double pidGet() {
return getAverageVoltage();
}
@@ -394,45 +371,42 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Analog Input";
}
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getAverageVoltage());
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* Analog Channels don't have to do anything special when entering the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* Analog Channels don't have to do anything special when exiting the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -38,12 +38,12 @@ public class AnalogOutput extends SensorBase implements LiveWindowSendable {
}
try {
channels.allocate(channel);
} catch (CheckedAllocationException e) {
} catch (CheckedAllocationException ex) {
throw new AllocationException("Analog output channel " + m_channel + " is already allocated");
}
long port_pointer = AnalogJNI.getPort((byte) channel);
m_port = AnalogJNI.initializeAnalogOutputPort(port_pointer);
final long portPointer = AnalogJNI.getPort((byte) channel);
m_port = AnalogJNI.initializeAnalogOutputPort(portPointer);
LiveWindow.addSensor("AnalogOutput", channel, this);
UsageReporting.report(tResourceType.kResourceType_AnalogOutput, channel);
@@ -70,45 +70,42 @@ public class AnalogOutput extends SensorBase implements LiveWindowSendable {
/*
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Analog Output";
}
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getVoltage());
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* Analog Channels don't have to do anything special when entering the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* Analog Channels don't have to do anything special when exiting the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,104 +7,85 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.hal.PowerJNI;
import edu.wpi.first.wpilibj.interfaces.Potentiometer;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Class for reading analog potentiometers. Analog potentiometers read in an
* analog voltage that corresponds to a position. The position is in whichever
* units you choose, by way of the scaling and offset constants passed to the
* constructor.
* Class for reading analog potentiometers. Analog potentiometers read in an analog voltage that
* corresponds to a position. The position is in whichever units you choose, by way of the scaling
* and offset constants passed to the constructor.
*
* @author Alex Henning
* @author Colby Skeggs (rail voltage)
*/
public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
private double m_fullRange, m_offset;
private AnalogInput m_analog_input;
private boolean m_init_analog_input;
private double m_fullRange;
private double m_offset;
private AnalogInput m_analogInput;
private boolean m_initAnalogInput;
protected PIDSourceType m_pidSource = PIDSourceType.kDisplacement;
/**
* Common initialization code called by all constructors.
*$
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param fullRange The scaling to multiply the voltage by to get a meaningful
* unit.
* @param offset The offset to add to the scaled value for controlling the
* zero value
*
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param fullRange The scaling to multiply the voltage by to get a meaningful unit.
* @param offset The offset to add to the scaled value for controlling the zero value
*/
private void initPot(final AnalogInput input, double fullRange, double offset) {
this.m_fullRange = fullRange;
this.m_offset = offset;
m_analog_input = input;
m_fullRange = fullRange;
m_offset = offset;
m_analogInput = input;
}
/**
* AnalogPotentiometer constructor.
*
* Use the fullRange and offset values so that the output produces meaningful
* values. I.E: you have a 270 degree potentiometer and you want the output to
* be degrees with the halfway point as 0 degrees. The fullRange value is
* 270.0(degrees) and the offset is -135.0 since the halfway point after
* scaling is 135 degrees.
*$
* This will calculate the result from the fullRange times the fraction of the
* supply voltage, plus the offset.
* <p>Use the fullRange and offset values so that the output produces meaningful values. I.E: you
* have a 270 degree potentiometer and you want the output to be degrees with the halfway point as
* 0 degrees. The fullRange value is 270.0(degrees) and the offset is -135.0 since the halfway
* point after scaling is 135 degrees. This will calculate the result from the fullRange times
* the fraction of the supply voltage, plus the offset.
*
* @param channel The analog channel this potentiometer is plugged into.
* @param fullRange The scaling to multiply the fraction by to get a
* meaningful unit.
* @param offset The offset to add to the scaled value for controlling the
* zero value
* @param channel The analog channel this potentiometer is plugged into.
* @param fullRange The scaling to multiply the fraction by to get a meaningful unit.
* @param offset The offset to add to the scaled value for controlling the zero value
*/
public AnalogPotentiometer(final int channel, double fullRange, double offset) {
AnalogInput input = new AnalogInput(channel);
m_init_analog_input = true;
m_initAnalogInput = true;
initPot(input, fullRange, offset);
}
/**
* AnalogPotentiometer constructor.
*
* Use the fullRange and offset values so that the output produces meaningful
* values. I.E: you have a 270 degree potentiometer and you want the output to
* be degrees with the halfway point as 0 degrees. The fullRange value is
* 270.0(degrees) and the offset is -135.0 since the halfway point after
* scaling is 135 degrees.
*$
* This will calculate the result from the fullRange times the fraction of the
* supply voltage, plus the offset.
* <p>Use the fullRange and offset values so that the output produces meaningful values. I.E: you
* have a 270 degree potentiometer and you want the output to be degrees with the halfway point as
* 0 degrees. The fullRange value is 270.0(degrees) and the offset is -135.0 since the halfway
* point after scaling is 135 degrees. This will calculate the result from the fullRange times
* the fraction of the supply voltage, plus the offset.
*
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param fullRange The scaling to multiply the fraction by to get a
* meaningful unit.
* @param offset The offset to add to the scaled value for controlling the
* zero value
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param fullRange The scaling to multiply the fraction by to get a meaningful unit.
* @param offset The offset to add to the scaled value for controlling the zero value
*/
public AnalogPotentiometer(final AnalogInput input, double fullRange, double offset) {
m_init_analog_input = false;
m_initAnalogInput = false;
initPot(input, fullRange, offset);
}
/**
* AnalogPotentiometer constructor.
*
* Use the fullRange and offset values so that the output produces meaningful
* values. I.E: you have a 270 degree potentiometer and you want the output to
* be degrees with the halfway point as 0 degrees. The fullRange value is
* 270.0(degrees) and the offset is -135.0 since the halfway point after
* scaling is 135 degrees.
* <p>Use the fullRange and offset values so that the output produces meaningful values. I.E: you
* have a 270 degree potentiometer and you want the output to be degrees with the halfway point as
* 0 degrees. The fullRange value is 270.0(degrees) and the offset is -135.0 since the halfway
* point after scaling is 135 degrees.
*
* @param channel The analog channel this potentiometer is plugged into.
* @param scale The scaling to multiply the voltage by to get a meaningful
* unit.
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
*/
public AnalogPotentiometer(final int channel, double scale) {
this(channel, scale, 0);
@@ -113,15 +94,13 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
/**
* AnalogPotentiometer constructor.
*
* Use the fullRange and offset values so that the output produces meaningful
* values. I.E: you have a 270 degree potentiometer and you want the output to
* be degrees with the halfway point as 0 degrees. The fullRange value is
* 270.0(degrees) and the offset is -135.0 since the halfway point after
* scaling is 135 degrees.
* <p>Use the fullRange and offset values so that the output produces meaningful values. I.E: you
* have a 270 degree potentiometer and you want the output to be degrees with the halfway point as
* 0 degrees. The fullRange value is 270.0(degrees) and the offset is -135.0 since the halfway
* point after scaling is 135 degrees.
*
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param scale The scaling to multiply the voltage by to get a meaningful
* unit.
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
*/
public AnalogPotentiometer(final AnalogInput input, double scale) {
this(input, scale, 0);
@@ -150,13 +129,12 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
*
* @return The current position of the potentiometer.
*/
@Override
public double get() {
return (m_analog_input.getVoltage() / ControllerPower.getVoltage5V()) * m_fullRange + m_offset;
return (m_analogInput.getVoltage() / ControllerPower.getVoltage5V()) * m_fullRange + m_offset;
}
/**
* {@inheritDoc}
*/
@Override
public void setPIDSourceType(PIDSourceType pidSource) {
if (!pidSource.equals(PIDSourceType.kDisplacement)) {
throw new IllegalArgumentException("Only displacement PID is allowed for potentiometers.");
@@ -164,9 +142,7 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -176,6 +152,7 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
*
* @return The current reading.
*/
@Override
public double pidGet() {
return get();
}
@@ -184,53 +161,53 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
/**
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Analog Input";
}
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", get());
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* Frees this resource.
*/
public void free() {
if (m_init_analog_input) {
m_analog_input.free();
m_analog_input = null;
m_init_analog_input = false;
if (m_initAnalogInput) {
m_analogInput.free();
m_analogInput = null;
m_initAnalogInput = false;
}
}
/**
* Analog Channels don't have to do anything special when entering the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* Analog Channels don't have to do anything special when exiting the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,32 +7,31 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.AnalogJNI;
import edu.wpi.first.wpilibj.util.BoundaryException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
// import com.sun.jna.Pointer;
/**
* Class for creating and configuring Analog Triggers
* Class for creating and configuring Analog Triggers.
*
* @author dtjones
*/
public class AnalogTrigger {
/**
* Exceptions dealing with improper operation of the Analog trigger
* Exceptions dealing with improper operation of the Analog trigger.
*/
public class AnalogTriggerException extends RuntimeException {
/**
* Create a new exception with the given message
* Create a new exception with the given message.
*
* @param message the message to pass with the exception
*/
@@ -43,7 +42,7 @@ public class AnalogTrigger {
}
/**
* Where the analog trigger is attached
* Where the analog trigger is attached.
*/
protected long m_port;
protected int m_index;
@@ -54,12 +53,12 @@ public class AnalogTrigger {
* @param channel the port to use for the analog trigger
*/
protected void initTrigger(final int channel) {
long port_pointer = AnalogJNI.getPort((byte) channel);
final long portPointer = AnalogJNI.getPort((byte) channel);
ByteBuffer index = ByteBuffer.allocateDirect(4);
index.order(ByteOrder.LITTLE_ENDIAN);
m_port =
AnalogJNI.initializeAnalogTrigger(port_pointer, index.asIntBuffer());
AnalogJNI.initializeAnalogTrigger(portPointer, index.asIntBuffer());
m_index = index.asIntBuffer().get(0);
UsageReporting.report(tResourceType.kResourceType_AnalogTrigger, channel);
@@ -68,17 +67,16 @@ public class AnalogTrigger {
/**
* Constructor for an analog trigger given a channel number.
*
* @param channel the port to use for the analog trigger 0-3 are on-board, 4-7
* are on the MXP port
* @param channel the port to use for the analog trigger 0-3 are on-board, 4-7 are on the MXP
* port
*/
public AnalogTrigger(final int channel) {
initTrigger(channel);
}
/**
* Construct an analog trigger given an analog channel. This should be used in
* the case of sharing an analog channel between the trigger and an analog
* input object.
* Construct an analog trigger given an analog channel. This should be used in the case of sharing
* an analog channel between the trigger and an analog input object.
*
* @param channel the AnalogInput to use for the analog trigger
*/
@@ -90,7 +88,7 @@ public class AnalogTrigger {
}
/**
* Release the resources used by this object
* Release the resources used by this object.
*/
public void free() {
AnalogJNI.cleanAnalogTrigger(m_port);
@@ -98,9 +96,8 @@ public class AnalogTrigger {
}
/**
* Set the upper and lower limits of the analog trigger. The limits are given
* in ADC codes. If oversampling is used, the units must be scaled
* appropriately.
* Set the upper and lower limits of the analog trigger. The limits are given in ADC codes. If
* oversampling is used, the units must be scaled appropriately.
*
* @param lower the lower raw limit
* @param upper the upper raw limit
@@ -113,8 +110,8 @@ public class AnalogTrigger {
}
/**
* Set the upper and lower limits of the analog trigger. The limits are given
* as floating point voltage values.
* Set the upper and lower limits of the analog trigger. The limits are given as floating point
* voltage values.
*
* @param lower the lower voltage limit
* @param upper the upper voltage limit
@@ -127,9 +124,8 @@ public class AnalogTrigger {
}
/**
* Configure the analog trigger to use the averaged vs. raw values. If the
* value is true, then the averaged value is selected for the analog trigger,
* otherwise the immediate value is used.
* Configure the analog trigger to use the averaged vs. raw values. If the value is true, then the
* averaged value is selected for the analog trigger, otherwise the immediate value is used.
*
* @param useAveragedValue true to use an averaged value, false otherwise
*/
@@ -138,10 +134,9 @@ public class AnalogTrigger {
}
/**
* Configure the analog trigger to use a filtered value. The analog trigger
* will operate with a 3 point average rejection filter. This is designed to
* help with 360 degree pot applications for the period where the pot crosses
* through zero.
* Configure the analog trigger to use a filtered value. The analog trigger will operate with a 3
* point average rejection filter. This is designed to help with 360 degree pot applications for
* the period where the pot crosses through zero.
*
* @param useFilteredValue true to use a filterd value, false otherwise
*/
@@ -150,8 +145,8 @@ public class AnalogTrigger {
}
/**
* Return the index of the analog trigger. This is the FPGA index of this
* analog trigger instance.
* Return the index of the analog trigger. This is the FPGA index of this analog trigger
* instance.
*
* @return The index of the analog trigger.
*/
@@ -160,8 +155,8 @@ public class AnalogTrigger {
}
/**
* Return the InWindow output of the analog trigger. True if the analog input
* is between the upper and lower limits.
* Return the InWindow output of the analog trigger. True if the analog input is between the upper
* and lower limits.
*
* @return The InWindow output of the analog trigger.
*/
@@ -170,9 +165,8 @@ public class AnalogTrigger {
}
/**
* Return the TriggerState output of the analog trigger. True if above upper
* limit. False if below lower limit. If in Hysteresis, maintain previous
* state.
* Return the TriggerState output of the analog trigger. True if above upper limit. False if below
* lower limit. If in Hysteresis, maintain previous state.
*
* @return The TriggerState output of the analog trigger.
*/
@@ -181,9 +175,8 @@ public class AnalogTrigger {
}
/**
* Creates an AnalogTriggerOutput object. Gets an output object that can be
* used for routing. Caller is responsible for deleting the
* AnalogTriggerOutput object.
* Creates an AnalogTriggerOutput object. Gets an output object that can be used for routing.
* Caller is responsible for deleting the AnalogTriggerOutput object.
*
* @param type An enum of the type of output object to create.
* @return A pointer to a new AnalogTriggerOutput object.

View File

@@ -11,47 +11,41 @@ import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tReso
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.AnalogJNI;
import java.nio.IntBuffer;
/**
* Class to represent a specific output from an analog trigger. This class is
* used to get the current output value and also as a DigitalSource to provide
* routing of an output to digital subsystems on the FPGA such as Counter,
* Encoder, and Interrupt.
* Class to represent a specific output from an analog trigger. This class is used to get the
* current output value and also as a DigitalSource to provide routing of an output to digital
* subsystems on the FPGA such as Counter, Encoder, and Interrupt.
*
* The TriggerState output indicates the primary output value of the trigger. If
* the analog signal is less than the lower limit, the output is false. If the
* analog value is greater than the upper limit, then the output is true. If the
* analog value is in between, then the trigger output state maintains its most
* recent value.
* <p>The TriggerState output indicates the primary output value of the trigger. If the analog
* signal is less than the lower limit, the output is false. If the analog value is greater than the
* upper limit, then the output is true. If the analog value is in between, then the trigger output
* state maintains its most recent value.
*
* The InWindow output indicates whether or not the analog signal is inside the
* range defined by the limits.
* <p>The InWindow output indicates whether or not the analog signal is inside the range defined by
* the limits.
*
* 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
* 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.
* This will reject a sample that is (due to averaging or sampling) errantly
* between the two limits. This filter will fail if more than one sample in a
* row is errantly in between the two limits. You may see this problem if
* attempting to use this feature with a mechanical rollover sensor, such as a
* 360 degree no-stop potentiometer without signal conditioning, because the
* rollover transition is not sharp / clean enough. Using the averaging engine
* may help with this, but rotational speeds of the sensor will then be limited.
* <p>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 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. This will reject a sample that is (due
* to averaging or sampling) errantly between the two limits. This filter will fail if more than one
* sample in a row is errantly in between the two limits. You may see this problem if attempting to
* use this feature with a mechanical rollover sensor, such as a 360 degree no-stop potentiometer
* without signal conditioning, because the rollover transition is not sharp / clean enough. Using
* the averaging engine may help with this, but rotational speeds of the sensor will then be
* limited.
*/
public class AnalogTriggerOutput extends DigitalSource {
/**
* Exceptions dealing with improper operation of the Analog trigger output
* Exceptions dealing with improper operation of the Analog trigger output.
*/
public class AnalogTriggerOutputException extends RuntimeException {
/**
* Create a new exception with the given message
* Create a new exception with the given message.
*
* @param message the message to pass with the exception
*/
@@ -65,26 +59,26 @@ public class AnalogTriggerOutput extends DigitalSource {
private final AnalogTriggerType m_outputType;
/**
* Create an object that represents one of the four outputs from an analog
* trigger.
* Create an object that represents one of the four outputs from an analog trigger.
*
* Because this class derives from DigitalSource, it can be passed into
* routing functions for Counter, Encoder, etc.
* <p>Because this class derives from DigitalSource, it can be passed into routing functions for
* Counter, Encoder, etc.
*
* @param trigger The trigger for which this is an output.
* @param outputType An enum that specifies the output on the trigger to
* represent.
* @param trigger The trigger for which this is an output.
* @param outputType An enum that specifies the output on the trigger to represent.
*/
public AnalogTriggerOutput(AnalogTrigger trigger, final AnalogTriggerType outputType) {
if (trigger == null)
if (trigger == null) {
throw new NullPointerException("Analog Trigger given was null");
if (outputType == null)
}
if (outputType == null) {
throw new NullPointerException("Analog Trigger Type given was null");
}
m_trigger = trigger;
m_outputType = outputType;
UsageReporting.report(tResourceType.kResourceType_AnalogTriggerOutput, trigger.getIndex(),
outputType.value);
outputType.m_value);
}
@Override
@@ -98,12 +92,12 @@ public class AnalogTriggerOutput extends DigitalSource {
* @return The state of the analog trigger output.
*/
public boolean get() {
return AnalogJNI.getAnalogTriggerOutput(m_trigger.m_port, m_outputType.value);
return AnalogJNI.getAnalogTriggerOutput(m_trigger.m_port, m_outputType.m_value);
}
@Override
public int getChannelForRouting() {
return (m_trigger.m_index << 2) + m_outputType.value;
return (m_trigger.m_index << 2) + m_outputType.m_value;
}
@Override
@@ -117,19 +111,19 @@ public class AnalogTriggerOutput extends DigitalSource {
}
/**
* Defines the state in which the AnalogTrigger triggers
*$
* Defines the state in which the AnalogTrigger triggers.
*
* @author jonathanleitschuh
*/
public enum AnalogTriggerType {
kInWindow(AnalogJNI.AnalogTriggerType.kInWindow), kState(AnalogJNI.AnalogTriggerType.kState), kRisingPulse(
AnalogJNI.AnalogTriggerType.kRisingPulse), kFallingPulse(
AnalogJNI.AnalogTriggerType.kFallingPulse);
kInWindow(AnalogJNI.AnalogTriggerType.kInWindow), kState(AnalogJNI.AnalogTriggerType.kState),
kRisingPulse(AnalogJNI.AnalogTriggerType.kRisingPulse),
kFallingPulse(AnalogJNI.AnalogTriggerType.kFallingPulse);
private final int value;
private final int m_value;
private AnalogTriggerType(int value) {
this.value = value;
AnalogTriggerType(int value) {
m_value = value;
}
}
}

View File

@@ -7,10 +7,10 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.hal.AccelerometerJNI;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.AccelerometerJNI;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
@@ -18,12 +18,12 @@ import edu.wpi.first.wpilibj.tables.ITable;
/**
* Built-in accelerometer.
*
* This class allows access to the RoboRIO's internal accelerometer.
* <p>This class allows access to the RoboRIO's internal accelerometer.
*/
public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
/**
* Constructor.
*$
*
* @param range The range the accelerometer will measure
*/
public BuiltInAccelerometer(Range range) {
@@ -40,7 +40,6 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
this(Range.k8G);
}
/** {inheritdoc} */
@Override
public void setRange(Range range) {
AccelerometerJNI.setAccelerometerActive(false);
@@ -56,13 +55,17 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
AccelerometerJNI.setAccelerometerRange(2);
break;
case k16G:
throw new RuntimeException("16G range not supported (use k2G, k4G, or k8G)");
default:
throw new IllegalArgumentException(range + " range not supported (use k2G, k4G, or k8G)");
}
AccelerometerJNI.setAccelerometerActive(true);
}
/**
* The acceleration in the X axis.
*
* @return The acceleration of the RoboRIO along the X axis in g-forces
*/
@Override
@@ -71,6 +74,8 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
}
/**
* The acceleration in the Y axis.
*
* @return The acceleration of the RoboRIO along the Y axis in g-forces
*/
@Override
@@ -79,6 +84,8 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
}
/**
* The acceleration in the Z axis.
*
* @return The acceleration of the RoboRIO along the Z axis in g-forces
*/
@Override
@@ -86,19 +93,20 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
return AccelerometerJNI.getAccelerometerZ();
}
@Override
public String getSmartDashboardType() {
return "3AxisAccelerometer";
}
private ITable m_table;
/** {@inheritDoc} */
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/** {@inheritDoc} */
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("X", getX());
@@ -107,12 +115,16 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
}
}
/** {@inheritDoc} */
@Override
public ITable getTable() {
return m_table;
}
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
public void stopLiveWindowMode() {}
};
@Override
public void stopLiveWindowMode() {
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,28 +13,27 @@ import edu.wpi.first.wpilibj.tables.ITableListener;
public interface CANSpeedController extends SpeedController, PIDInterface, LiveWindowSendable {
/**
* Mode determines how the motor is controlled, used internally. This is meant
* to be subclassed by enums
* (see {@link CANTalon.TalonControlMode CANTalon.TalonControlMode}).
* Mode determines how the motor is controlled, used internally. This is meant to be subclassed by
* enums (see {@link CANTalon.TalonControlMode CANTalon.TalonControlMode}).
*
*
* Note that the Jaguar does not support follower mode.
* <p>Note that the Jaguar does not support follower mode.
*/
public interface ControlMode {
/**
* Gets the name of this control mode. Since this interface should only be
* subclassed by enumerations, this will be overridden by the builtin
* name() method.
*/
public String name();
/**
* Checks if this control mode is PID-compatible.
*/
public boolean isPID();
/**
* Gets the integer value of this control mode.
*/
public int getValue();
interface ControlMode {
/**
* Gets the name of this control mode. Since this interface should only be subclassed by
* enumerations, this will be overridden by the builtin name() method.
*/
String name();
/**
* Checks if this control mode is PID-compatible.
*/
boolean isPID();
/**
* Gets the integer value of this control mode.
*/
int getValue();
}
/**
@@ -42,42 +41,46 @@ public interface CANSpeedController extends SpeedController, PIDInterface, LiveW
*
* @return the current control mode
*/
public ControlMode getControlMode();
ControlMode getControlMode();
/**
* Sets the control mode of this speed controller.
*
* @param mode the the new mode
*/
public void setControlMode(int mode);
void setControlMode(int mode);
/**
* Set the proportional PID constant.
*/
public void setP(double p);
@SuppressWarnings("ParameterName")
void setP(double p);
/**
* Set the integral PID constant.
*/
public void setI(double i);
@SuppressWarnings("ParameterName")
void setI(double i);
/**
* Set the derivative PID constant.
*/
public void setD(double d);
@SuppressWarnings("ParameterName")
void setD(double d);
/**
* Set the feed-forward PID constant. This method is optional to implement.
*/
public default void setF(double f) {
@SuppressWarnings("ParameterName")
default void setF(double f) {
}
/**
* Gets the feed-forward PID constant. This method is optional to implement.
* If a subclass does not implement this, it will always return zero.
* Gets the feed-forward PID constant. This method is optional to implement. If a subclass does
* not implement this, it will always return zero.
*/
public default double getF() {
return 0.0;
default double getF() {
return 0.0;
}
/**
@@ -85,55 +88,53 @@ public interface CANSpeedController extends SpeedController, PIDInterface, LiveW
*
* @return the input voltage to the controller (in Volts).
*/
public double getBusVoltage();
double getBusVoltage();
/**
* Get the current output voltage.
*
* @return the output voltage to the motor in volts.
*/
public double getOutputVoltage();
double getOutputVoltage();
/**
* Get the current being applied to the motor.
*
* @return the current motor current (in Amperes).
*/
public double getOutputCurrent();
double getOutputCurrent();
/**
* Get the current temperature of the controller.
*
* @return the current temperature of the controller, in degrees Celsius.
*/
public double getTemperature();
double getTemperature();
/**
* Return the current position of whatever the current selected sensor is.
*
* See specific implementations for more information on selecting feedback
* sensors.
* <p>See specific implementations for more information on selecting feedback sensors.
*
* @return the current sensor position.
*/
public double getPosition();
double getPosition();
/**
* Return the current velocity of whatever the current selected sensor is.
*
* See specific implementations for more information on selecting feedback
* sensors.
* <p>See specific implementations for more information on selecting feedback sensors.
*
* @return the current sensor velocity.
*/
public double getSpeed();
double getSpeed();
/**
* Set the maximum rate of change of the output voltage.
*
* @param rampRate the maximum rate of change of the votlage, in Volts / sec.
*/
public void setVoltageRampRate(double rampRate);
void setVoltageRampRate(double rampRate);
/**
* All CAN Speed Controllers have the same SmartDashboard type: "CANSpeedController".
@@ -141,56 +142,71 @@ public interface CANSpeedController extends SpeedController, PIDInterface, LiveW
String SMART_DASHBOARD_TYPE = "CANSpeedController";
@Override
public default void updateTable() {
ITable table = getTable();
if(table != null) {
table.putString("~TYPE~", SMART_DASHBOARD_TYPE);
table.putString("Type", getClass().getSimpleName()); // "CANTalon", "CANJaguar"
table.putNumber("Mode", getControlMode().getValue());
if (getControlMode().isPID()) {
// CANJaguar throws an exception if you try to get its PID constants
// when it's not in a PID-compatible mode
table.putNumber("p", getP());
table.putNumber("i", getI());
table.putNumber("d", getD());
table.putNumber("f", getF());
}
table.putBoolean("Enabled", isEnabled());
table.putNumber("Value", get());
default void updateTable() {
ITable table = getTable();
if (table != null) {
table.putString("~TYPE~", SMART_DASHBOARD_TYPE);
table.putString("Type", getClass().getSimpleName()); // "CANTalon", "CANJaguar"
table.putNumber("Mode", getControlMode().getValue());
if (getControlMode().isPID()) {
// CANJaguar throws an exception if you try to get its PID constants
// when it's not in a PID-compatible mode
table.putNumber("p", getP());
table.putNumber("i", getI());
table.putNumber("d", getD());
table.putNumber("f", getF());
}
table.putBoolean("Enabled", isEnabled());
table.putNumber("Value", get());
}
}
@Override
public default String getSmartDashboardType() {
return SMART_DASHBOARD_TYPE;
default String getSmartDashboardType() {
return SMART_DASHBOARD_TYPE;
}
/**
* Creates an ITableListener for the LiveWindow table for this CAN speed
* controller.
* Creates an ITableListener for the LiveWindow table for this CAN speed controller.
*/
public default ITableListener createTableListener() {
return (table, key, value, isNew) -> {
switch(key) {
case "Enabled":
if ((Boolean) value) {
enable();
} else {
disable();
}
break;
case "Value": set((Double) value); break;
case "Mode": setControlMode(((Double) value).intValue()); break;
default ITableListener createTableListener() {
return (table, key, value, isNew) -> {
switch (key) {
case "Enabled":
if ((Boolean) value) {
enable();
} else {
disable();
}
if(getControlMode().isPID()) {
switch(key) {
case "p": setP((Double) value); break;
case "i": setI((Double) value); break;
case "d": setD((Double) value); break;
case "f": setF((Double) value); break;
}
}
};
break;
case "Value":
set((Double) value);
break;
case "Mode":
setControlMode(((Double) value).intValue());
break;
default:
break;
}
if (getControlMode().isPID()) {
switch (key) {
case "p":
setP((Double) value);
break;
case "i":
setI((Double) value);
break;
case "d":
setD((Double) value);
break;
case "f":
setF((Double) value);
break;
default:
break;
}
}
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,29 +7,21 @@
package edu.wpi.first.wpilibj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicBoolean;
import com.ni.vision.NIVision;
import com.ni.vision.NIVision.Image;
import com.ni.vision.NIVision.RawData;
import com.ni.vision.VisionException;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.Timer;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.Deque;
import edu.wpi.first.wpilibj.vision.USBCamera;
// replicates CameraServer.cpp in java lib
@@ -46,6 +38,7 @@ public class CameraServer {
private static final int kMaxImageSize = 200000;
private static CameraServer server;
@SuppressWarnings("JavadocMethod")
public static CameraServer getInstance() {
if (server == null) {
server = new CameraServer();
@@ -53,7 +46,6 @@ public class CameraServer {
return server;
}
private Thread serverThread;
private int m_quality;
private boolean m_autoCaptureStarted;
private boolean m_hwClient = true;
@@ -61,16 +53,20 @@ public class CameraServer {
private CameraData m_imageData;
private Deque<ByteBuffer> m_imageDataPool;
private class CameraData {
RawData data;
int start;
@SuppressWarnings("JavadocMethod")
private final class CameraData {
@SuppressWarnings("MemberName")
private final RawData data;
@SuppressWarnings("MemberName")
private final int start;
public CameraData(RawData d, int s) {
data = d;
start = s;
CameraData(RawData data, int start) {
this.data = data;
this.start = start;
}
}
@SuppressWarnings("JavadocMethod")
private CameraServer() {
m_quality = 50;
m_camera = null;
@@ -79,14 +75,14 @@ public class CameraServer {
for (int i = 0; i < 3; i++) {
m_imageDataPool.addLast(ByteBuffer.allocateDirect(kMaxImageSize));
}
serverThread = new Thread(new Runnable() {
final Thread serverThread = new Thread(new Runnable() {
public void run() {
try {
serve();
} catch (IOException e) {
// do stuff here
} catch (InterruptedException e) {
} catch (IOException ex) {
// do stuff here
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
});
@@ -94,11 +90,13 @@ public class CameraServer {
serverThread.start();
}
@SuppressWarnings("JavadocMethod")
private synchronized void setImageData(RawData data, int start) {
if (m_imageData != null && m_imageData.data != null) {
m_imageData.data.free();
if (m_imageData.data.getBuffer() != null)
if (m_imageData.data.getBuffer() != null) {
m_imageDataPool.addLast(m_imageData.data.getBuffer());
}
m_imageData = null;
}
m_imageData = new CameraData(data, start);
@@ -106,12 +104,11 @@ public class CameraServer {
}
/**
* Manually change the image that is served by the MJPEG stream. This can be
* called to pass custom annotated images to the dashboard. Note that, for
* 640x480 video, this method could take between 40 and 50 milliseconds to
* complete.
* Manually change the image that is served by the MJPEG stream. This can be called to pass custom
* annotated images to the dashboard. Note that, for 640x480 video, this method could take between
* 40 and 50 milliseconds to complete.
*
* This shouldn't be called if {@link #startAutomaticCapture} is called.
* <p>This shouldn't be called if {@link #startAutomaticCapture} is called.
*
* @param image The IMAQ image to show on the dashboard
*/
@@ -134,25 +131,26 @@ public class CameraServer {
int index = 0;
if (hwClient) {
while (index < buffer.limit() - 1) {
if ((buffer.get(index) & 0xff) == 0xFF && (buffer.get(index + 1) & 0xff) == 0xD8)
if ((buffer.get(index) & 0xff) == 0xFF && (buffer.get(index + 1) & 0xff) == 0xD8) {
break;
}
index++;
}
}
if (buffer.limit() - index - 1 <= 2) {
throw new VisionException("data size of flattened image is less than 2. Try another camera! ");
throw new VisionException("data size of flattened image is less than 2. Try another "
+ "camera!");
}
setImageData(data, index);
}
/**
* Start automatically capturing images to send to the dashboard. You should
* call this method to just see a camera feed on the dashboard without doing
* any vision processing on the roboRIO. {@link #setImage} shouldn't be called
* after this is called. This overload calles
* {@link #startAutomaticCapture(String)} with the default camera name
* Start automatically capturing images to send to the dashboard. You should call this method to
* just see a camera feed on the dashboard without doing any vision processing on the roboRIO.
* {@link #setImage} shouldn't be called after this is called. This overload calles {@link
* #startAutomaticCapture(String)} with the default camera name
*/
public void startAutomaticCapture() {
startAutomaticCapture(USBCamera.kDefaultCameraName);
@@ -161,9 +159,8 @@ public class CameraServer {
/**
* Start automatically capturing images to send to the dashboard.
*
* You should call this method to just see a camera feed on the dashboard
* without doing any vision processing on the roboRIO. {@link #setImage}
* shouldn't be called after this is called.
* <p>You should call this method to just see a camera feed on the dashboard without doing any
* vision processing on the roboRIO. {@link #setImage} shouldn't be called after this is called.
*
* @param cameraName The name of the camera interface (e.g. "cam1")
*/
@@ -178,9 +175,11 @@ public class CameraServer {
}
}
@SuppressWarnings("JavadocMethod")
public synchronized void startAutomaticCapture(USBCamera camera) {
if (m_autoCaptureStarted)
if (m_autoCaptureStarted) {
return;
}
m_autoCaptureStarted = true;
m_camera = camera;
@@ -232,25 +231,23 @@ public class CameraServer {
}
/**
* check if auto capture is started
*
* Check if auto capture is started.
*/
public synchronized boolean isAutoCaptureStarted() {
return m_autoCaptureStarted;
}
/**
* Sets the size of the image to use. Use the public kSize constants to set
* the correct mode, or set it directory on a camera and call the appropriate
* autoCapture method
*$
* Sets the size of the image to use. Use the public kSize constants to set the correct mode, or
* set it directory on a camera and call the appropriate autoCapture method.
*
* @param size The size to use
*/
public synchronized void setSize(int size) {
if (m_camera == null)
if (m_camera == null) {
return;
}
switch (size) {
case kSize640x480:
m_camera.setSize(640, 480);
@@ -261,11 +258,13 @@ public class CameraServer {
case kSize160x120:
m_camera.setSize(160, 120);
break;
default:
throw new IllegalArgumentException("Unsupported size: " + size);
}
}
/**
* Set the quality of the compressed image sent to the dashboard
* Set the quality of the compressed image sent to the dashboard.
*
* @param quality The quality of the JPEG image, from 0 to 100
*/
@@ -274,7 +273,7 @@ public class CameraServer {
}
/**
* Get the quality of the compressed image sent to the dashboard
* Get the quality of the compressed image sent to the dashboard.
*
* @return The quality, from 0 to 100
*/
@@ -285,10 +284,10 @@ public class CameraServer {
/**
* Run the M-JPEG server.
*
* This function listens for a connection from the dashboard in a background
* thread, then sends back the M-JPEG stream.
* <p>This function listens for a connection from the dashboard in a background thread, then
* sends back the M-JPEG stream.
*
* @throws IOException if the Socket connection fails
* @throws IOException if the Socket connection fails
* @throws InterruptedException if the sleep is interrupted
*/
protected void serve() throws IOException, InterruptedException {
@@ -300,10 +299,10 @@ public class CameraServer {
while (true) {
try {
Socket s = socket.accept();
Socket socket1 = socket.accept();
DataInputStream is = new DataInputStream(s.getInputStream());
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(socket1.getInputStream());
DataOutputStream os = new DataOutputStream(socket1.getOutputStream());
int fps = is.readInt();
int compression = is.readInt();
@@ -311,35 +310,38 @@ public class CameraServer {
if (compression != kHardwareCompression) {
DriverStation.reportError("Choose \"USB Camera HW\" on the dashboard", false);
s.close();
socket1.close();
continue;
}
// Wait for the camera
synchronized (this) {
System.out.println("Camera not yet ready, awaiting image");
if (m_camera == null)
if (m_camera == null) {
wait();
}
m_hwClient = compression == kHardwareCompression;
if (!m_hwClient)
if (!m_hwClient) {
setQuality(100 - compression);
else if (m_camera != null)
} else if (m_camera != null) {
m_camera.setFPS(fps);
}
setSize(size);
}
long period = (long) (1000 / (1.0 * fps));
while (true) {
long t0 = System.currentTimeMillis();
CameraData imageData = null;
final CameraData imageData;
synchronized (this) {
wait();
imageData = m_imageData;
m_imageData = null;
}
if (imageData == null)
if (imageData == null) {
continue;
}
// Set the buffer position to the start of the data,
// and then create a new wrapper for the data at
// exactly that position

View File

@@ -7,41 +7,38 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.SensorBase;
import edu.wpi.first.wpilibj.hal.CompressorJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Class for operating the PCM (Pneumatics compressor module) The PCM
* automatically will run in close-loop mode by default whenever a Solenoid
* object is created. For most cases the Compressor object does not need to be
* instantiated or used in a robot program.
*$
* This class is only required in cases where more detailed status or to
* enable/disable closed loop control. Note: you cannot operate the compressor
* directly from this class as doing so would circumvent the safety provided in
* using the pressure switch and closed loop control. You can only turn off
* closed loop control, thereby stopping the compressor from operating.
* Class for operating the PCM (Pneumatics compressor module) The PCM automatically will run in
* close-loop mode by default whenever a Solenoid object is created. For most cases the Compressor
* object does not need to be instantiated or used in a robot program. This class is only required
* in cases where more detailed status or to enable/disable closed loop control. Note: you cannot
* operate the compressor directly from this class as doing so would circumvent the safety provided
* in using the pressure switch and closed loop control. You can only turn off closed loop control,
* thereby stopping the compressor from operating.
*/
public class Compressor extends SensorBase implements LiveWindowSendable {
private long m_pcm;
/**
* Create an instance of the Compressor
*$
* @param pcmId The PCM CAN device ID. Most robots that use PCM will have a
* single module. Use this for supporting a second module other than
* the default.
* Create an instance of the Compressor.
*
* <p>Most robots that use PCM will have a single module. Use this for supporting a second module
* other than the default.
*
* @param pcmId The PCM CAN device ID.
*/
public Compressor(int pcmId) {
initCompressor(pcmId);
}
/**
* Create an instance of the Compressor Makes a new instance of the compressor
* using the default PCM ID (0). Additional modules can be supported by making
* a new instance and specifying the CAN ID
* Create an instance of the Compressor Makes a new instance of the compressor using the default
* PCM ID (0). Additional modules can be supported by making a new instance and specifying the CAN
* ID.
*/
public Compressor() {
initCompressor(getDefaultSolenoidModule());
@@ -54,28 +51,26 @@ public class Compressor extends SensorBase implements LiveWindowSendable {
}
/**
* Start the compressor running in closed loop control mode Use the method in
* cases where you would like to manually stop and start the compressor for
* applications such as conserving battery or making sure that the compressor
* motor doesn't start during critical operations.
* Start the compressor running in closed loop control mode Use the method in cases where you
* would like to manually stop and start the compressor for applications such as conserving
* battery or making sure that the compressor motor doesn't start during critical operations.
*/
public void start() {
setClosedLoopControl(true);
}
/**
* Stop the compressor from running in closed loop control mode. Use the
* method in cases where you would like to manually stop and start the
* compressor for applications such as conserving battery or making sure that
* the compressor motor doesn't start during critical operations.
* Stop the compressor from running in closed loop control mode. Use the method in cases where you
* would like to manually stop and start the compressor for applications such as conserving
* battery or making sure that the compressor motor doesn't start during critical operations.
*/
public void stop() {
setClosedLoopControl(false);
}
/**
* Get the enabled status of the compressor
*$
* Get the enabled status of the compressor.
*
* @return true if the compressor is on
*/
public boolean enabled() {
@@ -83,18 +78,17 @@ public class Compressor extends SensorBase implements LiveWindowSendable {
}
/**
* Get the current pressure switch value
*$
* @return true if the pressure is low by reading the pressure switch that is
* plugged into the PCM
* Get the current pressure switch value.
*
* @return true if the pressure is low by reading the pressure switch that is plugged into the PCM
*/
public boolean getPressureSwitchValue() {
return CompressorJNI.getPressureSwitch(m_pcm);
}
/**
* Get the current being used by the compressor
*$
* Get the current being used by the compressor.
*
* @return current consumed in amps for the compressor motor
*/
public float getCompressorCurrent() {
@@ -102,68 +96,73 @@ public class Compressor extends SensorBase implements LiveWindowSendable {
}
/**
* Set the PCM in closed loop control mode
*$
* @param on If true sets the compressor to be in closed loop control mode
* otherwise normal operation of the compressor is disabled.
* Set the PCM in closed loop control mode.
*
* @param on If true sets the compressor to be in closed loop control mode otherwise normal
* operation of the compressor is disabled.
*/
public void setClosedLoopControl(boolean on) {
CompressorJNI.setClosedLoopControl(m_pcm, on);
}
/**
* Gets the current operating mode of the PCM
*$
* @return true if compressor is operating on closed-loop mode, otherwise
* return false.
* Gets the current operating mode of the PCM.
*
* @return true if compressor is operating on closed-loop mode, otherwise return false.
*/
public boolean getClosedLoopControl() {
return CompressorJNI.getClosedLoopControl(m_pcm);
}
/**
* @return true if PCM is in fault state : Compressor Drive is disabled due to
* compressor current being too high.
* If PCM is in fault state : Compressor Drive is disabled due to compressor current being too
* high.
*
* @return true if PCM is in fault state.
*/
public boolean getCompressorCurrentTooHighFault() {
return CompressorJNI.getCompressorCurrentTooHighFault(m_pcm);
}
/**
* @return true if PCM sticky fault is set : Compressor Drive is disabled due
* to compressor current being too high.
* If PCM sticky fault is set : Compressor Drive is disabled due to compressor current being too
* high.
*
* @return true if PCM sticky fault is set.
*/
public boolean getCompressorCurrentTooHighStickyFault() {
return CompressorJNI.getCompressorCurrentTooHighStickyFault(m_pcm);
}
/**
* @return true if PCM sticky fault is set : Compressor output appears to be
* shorted.
* @return true if PCM sticky fault is set : Compressor output appears to be shorted.
*/
public boolean getCompressorShortedStickyFault() {
return CompressorJNI.getCompressorShortedStickyFault(m_pcm);
}
/**
* @return true if PCM is in fault state : Compressor output appears to be
* shorted.
* @return true if PCM is in fault state : Compressor output appears to be shorted.
*/
public boolean getCompressorShortedFault() {
return CompressorJNI.getCompressorShortedFault(m_pcm);
}
/**
* @return true if PCM sticky fault is set : Compressor does not appear to be
* wired, i.e. compressor is not drawing enough current.
* If PCM sticky fault is set : Compressor does not appear to be wired, i.e. compressor is not
* drawing enough current.
*
* @return true if PCM sticky fault is set.
*/
public boolean getCompressorNotConnectedStickyFault() {
return CompressorJNI.getCompressorNotConnectedStickyFault(m_pcm);
}
/**
* @return true if PCM is in fault state : Compressor does not appear to be
* wired, i.e. compressor is not drawing enough current.
* If PCM is in fault state : Compressor does not appear to be wired, i.e. compressor is not
* drawing enough current.
*
* @return true if PCM is in fault state.
*/
public boolean getCompressorNotConnectedFault() {
return CompressorJNI.getCompressorNotConnectedFault(m_pcm);
@@ -172,22 +171,23 @@ public class Compressor extends SensorBase implements LiveWindowSendable {
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* If a sticky fault is set, then it will be persistently cleared. Compressor
* drive maybe momentarily disable while flags are being cleared. Care should
* be taken to not call this too frequently, otherwise normal compressor
* functionality may be prevented.
* <p>If a sticky fault is set, then it will be persistently cleared. Compressor drive maybe
* momentarily disable while flags are being cleared. Care should be taken to not call this too
* frequently, otherwise normal compressor functionality may be prevented.
*
* If no sticky faults are set then this call will have no effect.
* <p>If no sticky faults are set then this call will have no effect.
*/
public void clearAllPCMStickyFaults() {
CompressorJNI.clearAllPCMStickyFaults(m_pcm);
}
@Override
public void startLiveWindowMode() {}
public void startLiveWindowMode() {
}
@Override
public void stopLiveWindowMode() {}
public void stopLiveWindowMode() {
}
@Override
public String getSmartDashboardType() {

View File

@@ -11,8 +11,8 @@ import edu.wpi.first.wpilibj.hal.PowerJNI;
public class ControllerPower {
/**
* Get the input voltage to the robot controller
*$
* Get the input voltage to the robot controller.
*
* @return The controller input voltage value in Volts
*/
public static double getInputVoltage() {
@@ -20,8 +20,8 @@ public class ControllerPower {
}
/**
* Get the input current to the robot controller
*$
* Get the input current to the robot controller.
*
* @return The controller input current value in Amps
*/
public static double getInputCurrent() {
@@ -29,8 +29,8 @@ public class ControllerPower {
}
/**
* Get the voltage of the 3.3V rail
*$
* Get the voltage of the 3.3V rail.
*
* @return The controller 3.3V rail voltage value in Volts
*/
public static double getVoltage3V3() {
@@ -38,8 +38,8 @@ public class ControllerPower {
}
/**
* Get the current output of the 3.3V rail
*$
* Get the current output of the 3.3V rail.
*
* @return The controller 3.3V rail output current value in Volts
*/
public static double getCurrent3V3() {
@@ -47,10 +47,9 @@ public class ControllerPower {
}
/**
* Get the enabled state of the 3.3V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller
* over-voltage
*$
* Get the enabled state of the 3.3V rail. The rail may be disabled due to a controller brownout,
* a short circuit on the rail, or controller over-voltage.
*
* @return The controller 3.3V rail enabled value
*/
public static boolean getEnabled3V3() {
@@ -58,9 +57,8 @@ public class ControllerPower {
}
/**
* Get the count of the total current faults on the 3.3V rail since the
* controller has booted
*$
* Get the count of the total current faults on the 3.3V rail since the controller has booted.
*
* @return The number of faults
*/
public static int getFaultCount3V3() {
@@ -68,8 +66,8 @@ public class ControllerPower {
}
/**
* Get the voltage of the 5V rail
*$
* Get the voltage of the 5V rail.
*
* @return The controller 5V rail voltage value in Volts
*/
public static double getVoltage5V() {
@@ -77,8 +75,8 @@ public class ControllerPower {
}
/**
* Get the current output of the 5V rail
*$
* Get the current output of the 5V rail.
*
* @return The controller 5V rail output current value in Amps
*/
public static double getCurrent5V() {
@@ -86,10 +84,9 @@ public class ControllerPower {
}
/**
* Get the enabled state of the 5V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller
* over-voltage
*$
* Get the enabled state of the 5V rail. The rail may be disabled due to a controller brownout, a
* short circuit on the rail, or controller over-voltage.
*
* @return The controller 5V rail enabled value
*/
public static boolean getEnabled5V() {
@@ -97,9 +94,8 @@ public class ControllerPower {
}
/**
* Get the count of the total current faults on the 5V rail since the
* controller has booted
*$
* Get the count of the total current faults on the 5V rail since the controller has booted.
*
* @return The number of faults
*/
public static int getFaultCount5V() {
@@ -107,8 +103,8 @@ public class ControllerPower {
}
/**
* Get the voltage of the 6V rail
*$
* Get the voltage of the 6V rail.
*
* @return The controller 6V rail voltage value in Volts
*/
public static double getVoltage6V() {
@@ -116,8 +112,8 @@ public class ControllerPower {
}
/**
* Get the current output of the 6V rail
*$
* Get the current output of the 6V rail.
*
* @return The controller 6V rail output current value in Amps
*/
public static double getCurrent6V() {
@@ -125,10 +121,9 @@ public class ControllerPower {
}
/**
* Get the enabled state of the 6V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller
* over-voltage
*$
* Get the enabled state of the 6V rail. The rail may be disabled due to a controller brownout, a
* short circuit on the rail, or controller over-voltage.
*
* @return The controller 6V rail enabled value
*/
public static boolean getEnabled6V() {
@@ -136,9 +131,8 @@ public class ControllerPower {
}
/**
* Get the count of the total current faults on the 6V rail since the
* controller has booted
*$
* Get the count of the total current faults on the 6V rail since the controller has booted.
*
* @return The number of faults
*/
public static int getFaultCount6V() {

View File

@@ -19,43 +19,44 @@ import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.util.BoundaryException;
/**
* Class for counting the number of ticks on a digital input channel. This is a
* general purpose class for counting repetitive events. It can return the
* number of counts, the period of the most recent cycle, and detect when the
* signal being counted has stopped by supplying a maximum cycle time.
* Class for counting the number of ticks on a digital input channel. This is a general purpose
* class for counting repetitive events. It can return the number of counts, the period of the most
* recent cycle, and detect when the signal being counted has stopped by supplying a maximum cycle
* time.
*
* All counters will immediately start counting - reset() them if you need them
* to be zeroed before use.
* <p>All counters will immediately start counting - reset() them if you need them to be zeroed
* before use.
*/
public class Counter extends SensorBase implements CounterBase, LiveWindowSendable, PIDSource {
/**
* Mode determines how and what the counter counts
* Mode determines how and what the counter counts.
*/
public static enum Mode {
public enum Mode {
/**
* mode: two pulse
* mode: two pulse.
*/
kTwoPulse(0),
/**
* mode: semi period
* mode: semi period.
*/
kSemiperiod(1),
/**
* mode: pulse length
* mode: pulse length.
*/
kPulseLength(2),
/**
* mode: external direction
* mode: external direction.
*/
kExternalDirection(3);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
private Mode(int value) {
Mode(int value) {
this.value = value;
}
}
@@ -87,41 +88,38 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Create an instance of a counter where no sources are selected. Then they
* all must be selected by calling functions to specify the upsource and the
* downsource independently.
* Create an instance of a counter where no sources are selected. Then they all must be selected
* by calling functions to specify the upsource and the downsource independently.
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*/
public Counter() {
initCounter(Mode.kTwoPulse);
}
/**
* Create an instance of a counter from a Digital Input. This is used if an
* existing digital input is to be shared by multiple other objects such as
* encoders or if the Digital Source is not a DIO channel (such as an Analog
* Trigger)
* Create an instance of a counter from a Digital Input. This is used if an existing digital input
* is to be shared by multiple other objects such as encoders or if the Digital Source is not a
* DIO channel (such as an Analog Trigger)
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*
* @param source the digital source to count
*/
public Counter(DigitalSource source) {
if (source == null)
if (source == null) {
throw new NullPointerException("Digital Source given was null");
}
initCounter(Mode.kTwoPulse);
setUpSource(source);
}
/**
* Create an instance of a Counter object. Create an up-Counter instance given
* a channel.
* Create an instance of a Counter object. Create an up-Counter instance given a channel.
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*
* @param channel the DIO channel to use as the up source. 0-9 are on-board,
* 10-25 are on the MXP
* @param channel the DIO channel to use as the up source. 0-9 are on-board, 10-25 are on the MXP
*/
public Counter(int channel) {
initCounter(Mode.kTwoPulse);
@@ -129,33 +127,35 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Create an instance of a Counter object. Create an instance of a simple
* up-Counter given an analog trigger. Use the trigger state output from the
* analog trigger.
* Create an instance of a Counter object. Create an instance of a simple up-Counter given an
* analog trigger. Use the trigger state output from the analog trigger.
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*
* @param encodingType which edges to count
* @param upSource first source to count
* @param downSource second source for direction
* @param inverted true to invert the count
* @param upSource first source to count
* @param downSource second source for direction
* @param inverted true to invert the count
*/
public Counter(EncodingType encodingType, DigitalSource upSource, DigitalSource downSource,
boolean inverted) {
boolean inverted) {
initCounter(Mode.kExternalDirection);
if (encodingType == null) {
throw new NullPointerException("Encoding type given was null");
}
if (encodingType != EncodingType.k1X && encodingType != EncodingType.k2X) {
throw new RuntimeException("Counters only support 1X and 2X quadreature decoding!");
}
if (upSource == null)
if (upSource == null) {
throw new NullPointerException("Up Source given was null");
}
setUpSource(upSource);
if (downSource == null)
if (downSource == null) {
throw new NullPointerException("Down Source given was null");
}
setDownSource(downSource);
if (encodingType == null)
throw new NullPointerException("Encoding type given was null");
if (encodingType == EncodingType.k1X) {
setUpSourceEdge(true, false);
CounterJNI.setCounterAverageSize(m_counter, 1);
@@ -168,11 +168,10 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Create an instance of a Counter object. Create an instance of a simple
* up-Counter given an analog trigger. Use the trigger state output from the
* analog trigger.
* Create an instance of a Counter object. Create an instance of a simple up-Counter given an
* analog trigger. Use the trigger state output from the analog trigger.
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*
* @param trigger the analog trigger to count
*/
@@ -199,8 +198,11 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* The counter's FPGA index.
*
* @return the Counter's FPGA index
*/
@SuppressWarnings("AbbreviationAsWordInName")
public int getFPGAIndex() {
return m_index;
}
@@ -208,8 +210,7 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
/**
* Set the upsource for the counter as a digital input channel.
*
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the
* MXP
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the MXP
*/
public void setUpSource(int channel) {
setUpSource(new DigitalInput(channel));
@@ -217,8 +218,7 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the source object that causes the counter to count up. Set the up
* counting DigitalSource.
* Set the source object that causes the counter to count up. Set the up counting DigitalSource.
*
* @param source the digital source to count
*/
@@ -235,9 +235,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
/**
* Set the up counting source to be an analog trigger.
*
* @param analogTrigger The analog trigger object that is used for the Up
* Source
* @param triggerType The analog trigger output that will trigger the counter.
* @param analogTrigger The analog trigger object that is used for the Up Source
* @param triggerType The analog trigger output that will trigger the counter.
*/
public void setUpSource(AnalogTrigger analogTrigger, AnalogTriggerType triggerType) {
if (analogTrigger == null) {
@@ -251,15 +250,16 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the edge sensitivity on an up counting source. Set the up source to
* either detect rising edges or falling edges.
* Set the edge sensitivity on an up counting source. Set the up source to either detect rising
* edges or falling edges.
*
* @param risingEdge true to count rising edge
* @param risingEdge true to count rising edge
* @param fallingEdge true to count falling edge
*/
public void setUpSourceEdge(boolean risingEdge, boolean fallingEdge) {
if (m_upSource == null)
if (m_upSource == null) {
throw new RuntimeException("Up Source must be set before setting the edge!");
}
CounterJNI.setCounterUpSourceEdge(m_counter, risingEdge, fallingEdge);
}
@@ -279,8 +279,7 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
/**
* Set the down counting source to be a digital input channel.
*
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the
* MXP
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the MXP
*/
public void setDownSource(int channel) {
setDownSource(new DigitalInput(channel));
@@ -288,8 +287,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the source object that causes the counter to count down. Set the down
* counting DigitalSource.
* Set the source object that causes the counter to count down. Set the down counting
* DigitalSource.
*
* @param source the digital source to count
*/
@@ -310,9 +309,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
/**
* Set the down counting source to be an analog trigger.
*
* @param analogTrigger The analog trigger object that is used for the Down
* Source
* @param triggerType The analog trigger output that will trigger the counter.
* @param analogTrigger The analog trigger object that is used for the Down Source
* @param triggerType The analog trigger output that will trigger the counter.
*/
public void setDownSource(AnalogTrigger analogTrigger, AnalogTriggerType triggerType) {
if (analogTrigger == null) {
@@ -327,15 +325,16 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the edge sensitivity on a down counting source. Set the down source to
* either detect rising edges or falling edges.
* Set the edge sensitivity on a down counting source. Set the down source to either detect rising
* edges or falling edges.
*
* @param risingEdge true to count the rising edge
* @param risingEdge true to count the rising edge
* @param fallingEdge true to count the falling edge
*/
public void setDownSourceEdge(boolean risingEdge, boolean fallingEdge) {
if (m_downSource == null)
if (m_downSource == null) {
throw new RuntimeException(" Down Source must be set before setting the edge!");
}
CounterJNI.setCounterDownSourceEdge(m_counter, risingEdge, fallingEdge);
}
@@ -353,24 +352,23 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set standard up / down counting mode on this counter. Up and down counts
* are sourced independently from two inputs.
* Set standard up / down counting mode on this counter. Up and down counts are sourced
* independently from two inputs.
*/
public void setUpDownCounterMode() {
CounterJNI.setCounterUpDownMode(m_counter);
}
/**
* Set external direction mode on this counter. Counts are sourced on the Up
* counter input. The Down counter input represents the direction to count.
* Set external direction mode on this counter. Counts are sourced on the Up counter input. The
* Down counter input represents the direction to count.
*/
public void setExternalDirectionMode() {
CounterJNI.setCounterExternalDirectionMode(m_counter);
}
/**
* Set Semi-period mode on this counter. Counts up on both rising and falling
* edges.
* Set Semi-period mode on this counter. Counts up on both rising and falling edges.
*
* @param highSemiPeriod true to count up on both rising and falling
*/
@@ -379,21 +377,19 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Configure the counter to count in up or down based on the length of the
* input pulse. This mode is most useful for direction sensitive gear tooth
* sensors.
* Configure the counter to count in up or down based on the length of the input pulse. This mode
* is most useful for direction sensitive gear tooth sensors.
*
* @param threshold The pulse length beyond which the counter counts the
* opposite direction. Units are seconds.
* @param threshold The pulse length beyond which the counter counts the opposite direction. Units
* are seconds.
*/
public void setPulseLengthMode(double threshold) {
CounterJNI.setCounterPulseLengthMode(m_counter, threshold);
}
/**
* Read the current counter value. Read the value at this instant. It may
* still be running, so it reflects the current value. Next time it is read,
* it might have a different value.
* Read the current counter value. Read the value at this instant. It may still be running, so it
* reflects the current value. Next time it is read, it might have a different value.
*/
@Override
public int get() {
@@ -401,8 +397,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Read the current scaled counter value. Read the value at this instant,
* scaled by the distance per pulse (defaults to 1).
* Read the current scaled counter value. Read the value at this instant, scaled by the distance
* per pulse (defaults to 1).
*
* @return The distance since the last reset
*/
@@ -411,9 +407,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Reset the Counter to zero. Set the counter value to zero. This doesn't
* effect the running state of the counter, just sets the current value to
* zero.
* Reset the Counter to zero. Set the counter value to zero. This doesn't effect the running state
* of the counter, just sets the current value to zero.
*/
@Override
public void reset() {
@@ -421,13 +416,11 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the maximum period where the device is still considered "moving". Sets
* the maximum period where the device is considered moving. This value is
* used to determine the "stopped" state of the counter using the GetStopped
* method.
* Set the maximum period where the device is still considered "moving". Sets the maximum period
* where the device is considered moving. This value is used to determine the "stopped" state of
* the counter using the GetStopped method.
*
* @param maxPeriod The maximum period where the counted device is considered
* moving in seconds.
* @param maxPeriod The maximum period where the counted device is considered moving in seconds.
*/
@Override
public void setMaxPeriod(double maxPeriod) {
@@ -435,18 +428,15 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Select whether you want to continue updating the event timer output when
* there are no samples captured. The output of the event timer has a buffer
* of periods that are averaged and posted to a register on the FPGA. When the
* timer detects that the event source has stopped (based on the MaxPeriod)
* the buffer of samples to be averaged is emptied. If you enable the update
* when empty, you will be notified of the stopped source and the event time
* will report 0 samples. If you disable update when empty, the most recent
* average will remain on the output until a new sample is acquired. You will
* never see 0 samples output (except when there have been no events since an
* FPGA reset) and you will likely not see the stopped bit become true (since
* it is updated at the end of an average and there are no samples to
* average).
* Select whether you want to continue updating the event timer output when there are no samples
* captured. The output of the event timer has a buffer of periods that are averaged and posted to
* a register on the FPGA. When the timer detects that the event source has stopped (based on the
* MaxPeriod) the buffer of samples to be averaged is emptied. If you enable the update when
* empty, you will be notified of the stopped source and the event time will report 0 samples. If
* you disable update when empty, the most recent average will remain on the output until a new
* sample is acquired. You will never see 0 samples output (except when there have been no events
* since an FPGA reset) and you will likely not see the stopped bit become true (since it is
* updated at the end of an average and there are no samples to average).
*
* @param enabled true to continue updating
*/
@@ -455,13 +445,11 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Determine if the clock is stopped. Determine if the clocked input is
* stopped based on the MaxPeriod value set using the SetMaxPeriod method. If
* the clock exceeds the MaxPeriod, then the device (and counter) are assumed
* to be stopped and it returns true.
* Determine if the clock is stopped. Determine if the clocked input is stopped based on the
* MaxPeriod value set using the SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the
* device (and counter) are assumed to be stopped and it returns true.
*
* @return Returns true if the most recent counter period exceeds the
* MaxPeriod value set by SetMaxPeriod.
* @return true if the most recent counter period exceeds the MaxPeriod value set by SetMaxPeriod.
*/
@Override
public boolean getStopped() {
@@ -479,9 +467,9 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the Counter to return reversed sensing on the direction. This allows
* counters to change the direction they are counting in the case of 1X and 2X
* quadrature encoding only. Any other counter mode isn't supported.
* Set the Counter to return reversed sensing on the direction. This allows counters to change the
* direction they are counting in the case of 1X and 2X quadrature encoding only. Any other
* counter mode isn't supported.
*
* @param reverseDirection true if the value counted should be negated.
*/
@@ -490,9 +478,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Get the Period of the most recent count. Returns the time interval of the
* most recent count. This can be used for velocity calculations to determine
* shaft speed.
* Get the Period of the most recent count. Returns the time interval of the most recent count.
* This can be used for velocity calculations to determine shaft speed.
*
* @return The period of the last two pulses in units of seconds.
*/
@@ -502,9 +489,9 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Get the current rate of the Counter. Read the current rate of the counter
* accounting for the distance per pulse value. The default value for distance
* per pulse (1) yields units of pulses per second.
* Get the current rate of the Counter. Read the current rate of the counter accounting for the
* distance per pulse value. The default value for distance per pulse (1) yields units of pulses
* per second.
*
* @return The rate in units/sec
*/
@@ -513,9 +500,9 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
* Set the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @param samplesToAverage The number of samples to average from 1 to 127.
*/
@@ -524,33 +511,31 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Get the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
* Get the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @return SamplesToAverage The number of samples being averaged (from 1 to
* 127)
* @return SamplesToAverage The number of samples being averaged (from 1 to 127)
*/
public int getSamplesToAverage() {
return CounterJNI.getCounterSamplesToAverage(m_counter);
}
/**
* Set the distance per pulse for this counter. This sets the multiplier used
* to determine the distance driven based on the count value from the encoder.
* Set this value based on the Pulses per Revolution and factor in any gearing
* reductions. This distance can be in any units you like, linear or angular.
* Set the distance per pulse for this counter. This sets the multiplier used to determine the
* distance driven based on the count value from the encoder. Set this value based on the Pulses
* per Revolution and factor in any gearing reductions. This distance can be in any units you
* like, linear or angular.
*
* @param distancePerPulse The scale factor that will be used to convert
* pulses to useful units.
* @param distancePerPulse The scale factor that will be used to convert pulses to useful units.
*/
public void setDistancePerPulse(double distancePerPulse) {
m_distancePerPulse = distancePerPulse;
}
/**
* Set which parameter of the encoder you are using as a process control
* variable. The counter class supports the rate and distance parameters.
* Set which parameter of the encoder you are using as a process control variable. The counter
* class supports the rate and distance parameters.
*
* @param pidSource An enum to select the parameter.
*/
@@ -562,9 +547,6 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -581,9 +563,6 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
}
/**
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Counter";
@@ -591,26 +570,17 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
@@ -618,15 +588,11 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {}
public void startLiveWindowMode() {
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {}
public void stopLiveWindowMode() {
}
}

View File

@@ -8,78 +8,79 @@
package edu.wpi.first.wpilibj;
/**
* Interface for counting the number of ticks on a digital input channel.
* Encoders, Gear tooth sensors, and counters should all subclass this so it can
* be used to build more advanced classes for control and driving.
* Interface for counting the number of ticks on a digital input channel. Encoders, Gear tooth
* sensors, and counters should all subclass this so it can be used to build more advanced classes
* for control and driving.
*
* All counters will immediately start counting - reset() them if you need them
* to be zeroed before use.
* <p>All counters will immediately start counting - reset() them if you need them to be zeroed
* before use.
*/
public interface CounterBase {
/**
* The number of edges for the counterbase to increment or decrement on
* The number of edges for the counterbase to increment or decrement on.
*/
public enum EncodingType {
enum EncodingType {
/**
* Count only the rising edge
* Count only the rising edge.
*/
k1X(0),
/**
* Count both the rising and falling edge
* Count both the rising and falling edge.
*/
k2X(1),
/**
* Count rising and falling on both channels
* Count rising and falling on both channels.
*/
k4X(2);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
private EncodingType(int value) {
EncodingType(int value) {
this.value = value;
}
}
/**
* Get the count
*$
* Get the count.
*
* @return the count
*/
int get();
/**
* Reset the count to zero
* Reset the count to zero.
*/
void reset();
/**
* Get the time between the last two edges counted
*$
* Get the time between the last two edges counted.
*
* @return the time beteween the last two ticks in seconds
*/
double getPeriod();
/**
* Set the maximum time between edges to be considered stalled
*$
* Set the maximum time between edges to be considered stalled.
*
* @param maxPeriod the maximum period in seconds
*/
void setMaxPeriod(double maxPeriod);
/**
* Determine if the counter is not moving
*$
* Determine if the counter is not moving.
*
* @return true if the counter has not changed for the max period
*/
boolean getStopped();
/**
* Determine which direction the counter is going
*$
* Determine which direction the counter is going.
*
* @return true for one direction, false for the other
*/
boolean getDirection();

View File

@@ -10,40 +10,41 @@ package edu.wpi.first.wpilibj;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.wpilibj.DigitalSource;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Counter;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.DigitalGlitchFilterJNI;
/**
* Class to enable glitch filtering on a set of digital inputs.
* This class will manage adding and removing digital inputs from a FPGA glitch
* filter. The filter lets the user configure the time that an input must remain
* high or low before it is classified as high or low.
* Class to enable glitch filtering on a set of digital inputs. This class will manage adding and
* removing digital inputs from a FPGA glitch filter. The filter lets the user configure the time
* that an input must remain high or low before it is classified as high or low.
*/
public class DigitalGlitchFilter extends SensorBase {
/**
* Configures the Digital Glitch Filter to its default settings.
*/
public DigitalGlitchFilter() {
synchronized(m_mutex) {
int i = 0;
while (m_filterAllocated[i] != false && i < m_filterAllocated.length) {
i++;
synchronized (m_mutex) {
int index = 0;
while (m_filterAllocated[index] != false && index < m_filterAllocated.length) {
index++;
}
if (i != m_filterAllocated.length) {
m_channelIndex = i;
m_filterAllocated[i] = true;
if (index != m_filterAllocated.length) {
m_channelIndex = index;
m_filterAllocated[index] = true;
UsageReporting.report(tResourceType.kResourceType_DigitalFilter,
m_channelIndex, 0);
m_channelIndex, 0);
}
}
}
/**
* Free the resources used by this object.
*/
public void free() {
if (m_channelIndex >= 0) {
synchronized(m_mutex) {
synchronized (m_mutex) {
m_filterAllocated[m_channelIndex] = false;
}
m_channelIndex = -1;
@@ -121,30 +122,30 @@ public class DigitalGlitchFilter extends SensorBase {
}
/**
* Sets the number of FPGA cycles that the input must hold steady to pass
* through this glitch filter.
* Sets the number of FPGA cycles that the input must hold steady to pass through this glitch
* filter.
*
* @param fpga_cycles The number of FPGA cycles.
* @param fpgaCycles The number of FPGA cycles.
*/
public void setPeriodCycles(int fpga_cycles) {
DigitalGlitchFilterJNI.setFilterPeriod(m_channelIndex, fpga_cycles);
public void setPeriodCycles(int fpgaCycles) {
DigitalGlitchFilterJNI.setFilterPeriod(m_channelIndex, fpgaCycles);
}
/**
* Sets the number of nanoseconds that the input must hold steady to pass
* through this glitch filter.
* Sets the number of nanoseconds that the input must hold steady to pass through this glitch
* filter.
*
* @param nanoseconds The number of nanoseconds.
*/
public void setPeriodNanoSeconds(long nanoseconds) {
int fpga_cycles = (int) (nanoseconds * kSystemClockTicksPerMicrosecond / 4 /
1000);
setPeriodCycles(fpga_cycles);
int fpgaCycles = (int) (nanoseconds * kSystemClockTicksPerMicrosecond / 4
/ 1000);
setPeriodCycles(fpgaCycles);
}
/**
* Gets the number of FPGA cycles that the input must hold steady to pass
* through this glitch filter.
* Gets the number of FPGA cycles that the input must hold steady to pass through this glitch
* filter.
*
* @return The number of cycles.
*/
@@ -153,19 +154,19 @@ public class DigitalGlitchFilter extends SensorBase {
}
/**
* Gets the number of nanoseconds that the input must hold steady to pass
* through this glitch filter.
* Gets the number of nanoseconds that the input must hold steady to pass through this glitch
* filter.
*
* @return The number of nanoseconds.
*/
public long getPeriodNanoSeconds() {
int fpga_cycles = getPeriodCycles();
int fpgaCycles = getPeriodCycles();
return (long) fpga_cycles * 1000L /
(long) (kSystemClockTicksPerMicrosecond / 4);
return (long) fpgaCycles * 1000L
/ (long) (kSystemClockTicksPerMicrosecond / 4);
}
private int m_channelIndex = -1;
private static final Lock m_mutex = new ReentrantLock(true);
private static final boolean[] m_filterAllocated = new boolean[3];
};
}

View File

@@ -15,20 +15,17 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Class to read a digital input. This class will read digital inputs and return
* the current value on the channel. Other devices such as encoders, gear tooth
* sensors, etc. that are implemented elsewhere will automatically allocate
* digital inputs and outputs as required. This class is only for devices like
* switches etc. that aren't implemented anywhere else.
* Class to read a digital input. This class will read digital inputs and return the current value
* on the channel. Other devices such as encoders, gear tooth sensors, etc. that are implemented
* elsewhere will automatically allocate digital inputs and outputs as required. This class is only
* for devices like switches etc. that aren't implemented anywhere else.
*/
public class DigitalInput extends DigitalSource implements LiveWindowSendable {
/**
* Create an instance of a Digital Input class. Creates a digital input given
* a channel.
* Create an instance of a Digital Input class. Creates a digital input given a channel.
*
* @param channel the DIO channel for the digital input 0-9 are on-board,
* 10-25 are on the MXP
* @param channel the DIO channel for the digital input 0-9 are on-board, 10-25 are on the MXP
*/
public DigitalInput(int channel) {
initDigitalPort(channel, true);
@@ -38,13 +35,13 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
}
/**
* Get the value from a digital input channel. Retrieve the value of a single
* digital input channel from the FPGA.
* Get the value from a digital input channel. Retrieve the value of a single digital input
* channel from the FPGA.
*
* @return the status of the digital input
*/
public boolean get() {
return DIOJNI.getDIO(m_port);
return DIOJNI.getDIO(super.m_port);
}
/**
@@ -53,7 +50,7 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
* @return The GPIO channel number that this object represents.
*/
public int getChannel() {
return m_channel;
return super.m_channel;
}
@Override
@@ -61,9 +58,7 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
return false;
}
/*
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Digital Input";
@@ -71,18 +66,14 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
@@ -90,23 +81,19 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {}
public void startLiveWindowMode() {
}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,18 +7,17 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.DIOJNI;
import edu.wpi.first.wpilibj.hal.PWMJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
/**
* Class to write digital outputs. This class will write digital outputs. Other
* devices that are implemented elsewhere will automatically allocate digital
* inputs and outputs as required.
* Class to write digital outputs. This class will write digital outputs. Other devices that are
* implemented elsewhere will automatically allocate digital inputs and outputs as required.
*/
public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
@@ -27,11 +26,11 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
private long m_pwmGenerator = invalidPwmGenerator;
/**
* Create an instance of a digital output. Create an instance of a digital
* output given a channel.
* Create an instance of a digital output. Create an instance of a digital output given a
* channel.
*
* @param channel the DIO channel to use for the digital output. 0-9 are
* on-board, 10-25 are on the MXP
* @param channel the DIO channel to use for the digital output. 0-9 are on-board, 10-25 are on
* the MXP
*/
public DigitalOutput(int channel) {
initDigitalPort(channel, false);
@@ -57,34 +56,32 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
* @param value true is on, off is false
*/
public void set(boolean value) {
DIOJNI.setDIO(m_port, (short) (value ? 1 : 0));
DIOJNI.setDIO(super.m_port, (short) (value ? 1 : 0));
}
/**
* @return The GPIO channel number that this object represents.
*/
public int getChannel() {
return m_channel;
return super.m_channel;
}
/**
* Generate a single pulse. Write a pulse to the specified digital output
* channel. There can only be a single pulse going at any time.
* Generate a single pulse. Write a pulse to the specified digital output channel. There can only
* be a single pulse going at any time.
*
* @param channel The channel to pulse.
* @param channel The channel to pulse.
* @param pulseLength The length of the pulse.
*/
public void pulse(final int channel, final float pulseLength) {
DIOJNI.pulse(m_port, pulseLength);
DIOJNI.pulse(super.m_port, pulseLength);
}
/**
* @deprecated Generate a single pulse. Write a pulse to the specified digital
* output channel. There can only be a single pulse going at any
* time.
*
* @param channel The channel to pulse.
* @param channel The channel to pulse.
* @param pulseLength The length of the pulse.
* @deprecated Generate a single pulse. Write a pulse to the specified digital output channel.
* There can only be a single pulse going at any time.
*/
@Deprecated
public void pulse(final int channel, final int pulseLength) {
@@ -92,26 +89,24 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
(float) (pulseLength / 1.0e9 * (DIOJNI.getLoopTiming() * 25));
System.err
.println("You should use the float version of pulse for portability. This is deprecated");
DIOJNI.pulse(m_port, convertedPulse);
DIOJNI.pulse(super.m_port, convertedPulse);
}
/**
* Determine if the pulse is still going. Determine if a previously started
* pulse is still going.
* Determine if the pulse is still going. Determine if a previously started pulse is still going.
*
* @return true if pulsing
*/
public boolean isPulsing() {
return DIOJNI.isPulsing(m_port);
return DIOJNI.isPulsing(super.m_port);
}
/**
* Change the PWM frequency of the PWM output on a Digital Output line.
*
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is
* logarithmic.
* <p>The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is logarithmic.
*
* There is only one PWM frequency for all channnels.
* <p>There is only one PWM frequency for all channnels.
*
* @param rate The frequency to output all digital output PWM signals.
*/
@@ -122,19 +117,19 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* Enable a PWM Output on this line.
*
* Allocate one of the 6 DO PWM generator resources.
* <p>Allocate one of the 6 DO PWM generator resources.
*
* Supply the initial duty-cycle to output so as to avoid a glitch when first
* starting.
* <p>Supply the initial duty-cycle to output so as to avoid a glitch when first starting.
*
* The resolution of the duty cycle is 8-bit for low frequencies (1kHz or
* less) but is reduced the higher the frequency of the PWM signal is.
* <p>The resolution of the duty cycle is 8-bit for low frequencies (1kHz or less) but is reduced
* the higher the frequency of the PWM signal is.
*
* @param initialDutyCycle The duty-cycle to start generating. [0..1]
*/
public void enablePWM(double initialDutyCycle) {
if (m_pwmGenerator != invalidPwmGenerator)
if (m_pwmGenerator != invalidPwmGenerator) {
return;
}
m_pwmGenerator = PWMJNI.allocatePWM();
PWMJNI.setPWMDutyCycle(m_pwmGenerator, initialDutyCycle);
PWMJNI.setPWMOutputChannel(m_pwmGenerator, m_channel);
@@ -143,11 +138,12 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* Change this line from a PWM output back to a static Digital Output line.
*
* Free up one of the 6 DO PWM generator resources that were in use.
* <p>Free up one of the 6 DO PWM generator resources that were in use.
*/
public void disablePWM() {
if (m_pwmGenerator == invalidPwmGenerator)
if (m_pwmGenerator == invalidPwmGenerator) {
return;
}
// Disable the output by routing to a dead bit.
PWMJNI.setPWMOutputChannel(m_pwmGenerator, kDigitalChannels);
PWMJNI.freePWM(m_pwmGenerator);
@@ -157,14 +153,16 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* Change the duty-cycle that is being generated on the line.
*
* The resolution of the duty cycle is 8-bit for low frequencies (1kHz or
* less) but is reduced the higher the frequency of the PWM signal is.
* <p>The resolution of the duty cycle is 8-bit for low frequencies (1kHz or less) but is reduced
* the
* higher the frequency of the PWM signal is.
*
* @param dutyCycle The duty-cycle to change to. [0..1]
*/
public void updateDutyCycle(double dutyCycle) {
if (m_pwmGenerator == invalidPwmGenerator)
if (m_pwmGenerator == invalidPwmGenerator) {
return;
}
PWMJNI.setPWMDutyCycle(m_pwmGenerator, dutyCycle);
}
@@ -177,53 +175,43 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
// TODO: Put current value.
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
@Override
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
set(((Boolean) value).booleanValue());
set((Boolean) value);
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -12,11 +12,10 @@ import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* DigitalSource Interface. The DigitalSource represents all the possible inputs
* for a counter or a quadrature encoder. The source may be either a digital
* input or an analog input. If the caller just provides a channel, then a
* digital input will be constructed and freed when finished for the source. The
* source can either be a digital input or analog trigger but not both.
* DigitalSource Interface. The DigitalSource represents all the possible inputs for a counter or a
* quadrature encoder. The source may be either a digital input or an analog input. If the caller
* just provides a channel, then a digital input will be constructed and freed when finished for the
* source. The source can either be a digital input or analog trigger but not both.
*/
public abstract class DigitalSource extends InterruptableSensorBase {
@@ -36,8 +35,8 @@ public abstract class DigitalSource extends InterruptableSensorBase {
throw new AllocationException("Digital input " + m_channel + " is already allocated");
}
long port_pointer = DIOJNI.getPort((byte) channel);
m_port = DIOJNI.initializeDigitalPort(port_pointer);
long portPointer = DIOJNI.getPort((byte) channel);
m_port = DIOJNI.initializeDigitalPort(portPointer);
DIOJNI.allocateDIO(m_port, input);
}
@@ -51,7 +50,7 @@ public abstract class DigitalSource extends InterruptableSensorBase {
}
/**
* Get the channel routing number
* Get the channel routing number.
*
* @return channel routing number
*/
@@ -61,7 +60,7 @@ public abstract class DigitalSource extends InterruptableSensorBase {
}
/**
* Get the module routing number
* Get the module routing number.
*
* @return 0
*/
@@ -71,8 +70,8 @@ public abstract class DigitalSource extends InterruptableSensorBase {
}
/**
* Is this an analog trigger
*$
* Is this an analog trigger.
*
* @return true if this is an analog trigger
*/
@Override

View File

@@ -19,24 +19,22 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* DoubleSolenoid class for running 2 channels of high voltage Digital Output.
*
* The DoubleSolenoid class is typically used for pneumatics solenoids that have
* two positions controlled by two separate channels.
* <p>The DoubleSolenoid class is typically used for pneumatics solenoids that have two positions
* controlled by two separate channels.
*/
public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
/**
* Possible values for a DoubleSolenoid
* Possible values for a DoubleSolenoid.
*/
public static enum Value {
public enum Value {
kOff,
kForward,
kReverse
}
private int m_forwardChannel; // /< The forward channel on the module to
// control.
private int m_reverseChannel; // /< The reverse channel on the module to
// control.
private int m_forwardChannel; // /< The forward channel on the module to control.
private int m_reverseChannel; // /< The reverse channel on the module to control.
private byte m_forwardMask; // /< The mask for the forward channel.
private byte m_reverseMask; // /< The mask for the reverse channel.
@@ -49,14 +47,14 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
checkSolenoidChannel(m_reverseChannel);
try {
m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
} catch (CheckedAllocationException e) {
allocated.allocate(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
} catch (CheckedAllocationException exception) {
throw new AllocationException("Solenoid channel " + m_forwardChannel + " on module "
+ m_moduleNumber + " is already allocated");
}
try {
m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
} catch (CheckedAllocationException e) {
allocated.allocate(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
} catch (CheckedAllocationException exception) {
throw new AllocationException("Solenoid channel " + m_reverseChannel + " on module "
+ m_moduleNumber + " is already allocated");
}
@@ -69,8 +67,8 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
}
/**
* Constructor. Uses the default PCM ID of 0
*$
* Constructor. Uses the default PCM ID of 0.
*
* @param forwardChannel The forward channel number on the PCM (0..7).
* @param reverseChannel The reverse channel number on the PCM (0..7).
*/
@@ -84,11 +82,12 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
/**
* Constructor.
*
* @param moduleNumber The module number of the solenoid module to use.
* @param moduleNumber The module number of the solenoid module to use.
* @param forwardChannel The forward channel on the module to control (0..7).
* @param reverseChannel The reverse channel on the module to control (0..7).
*/
public DoubleSolenoid(final int moduleNumber, final int forwardChannel, final int reverseChannel) {
public DoubleSolenoid(final int moduleNumber, final int forwardChannel,
final int reverseChannel) {
super(moduleNumber);
m_forwardChannel = forwardChannel;
m_reverseChannel = reverseChannel;
@@ -99,8 +98,8 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
* Destructor.
*/
public synchronized void free() {
m_allocated.free(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
m_allocated.free(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
allocated.free(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
allocated.free(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
super.free();
}
@@ -110,7 +109,7 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
* @param value The value to set (Off, Forward, Reverse)
*/
public void set(final Value value) {
byte rawValue = 0;
final byte rawValue;
switch (value) {
case kOff:
@@ -122,6 +121,9 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
case kReverse:
rawValue = m_reverseMask;
break;
default:
throw new AssertionError("Illegal value: " + value);
}
set(rawValue, m_forwardMask | m_reverseMask);
@@ -135,21 +137,21 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
public Value get() {
byte value = getAll();
if ((value & m_forwardMask) != 0)
if ((value & m_forwardMask) != 0) {
return Value.kForward;
if ((value & m_reverseMask) != 0)
}
if ((value & m_reverseMask) != 0) {
return Value.kReverse;
}
return Value.kOff;
}
/**
* Check if the forward solenoid is blacklisted. If a solenoid is shorted, it
* is added to the blacklist and disabled until power cycle, or until faults
* are cleared.
*
* @see #clearAllPCMStickyFaults()
* Check if the forward solenoid is blacklisted. If a solenoid is shorted, it is added to the
* blacklist and disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isFwdSolenoidBlackListed() {
int blackList = getPCMSolenoidBlackList();
@@ -157,13 +159,11 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
}
/**
* Check if the reverse solenoid is blacklisted. If a solenoid is shorted, it
* is added to the blacklist and disabled until power cycle, or until faults
* are cleared.
*
* @see #clearAllPCMStickyFaults()
* Check if the reverse solenoid is blacklisted. If a solenoid is shorted, it is added to the
* blacklist and disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isRevSolenoidBlackListed() {
int blackList = getPCMSolenoidBlackList();
@@ -178,26 +178,20 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
// TODO: this is bad
@@ -206,31 +200,28 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
}
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
set(Value.kOff); // Stop for safety
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
// TODO: this is bad also
if (value.toString().equals("Reverse"))
if (value.toString().equals("Reverse")) {
set(Value.kReverse);
else if (value.toString().equals("Forward"))
} else if (value.toString().equals("Forward")) {
set(Value.kForward);
else
} else {
set(Value.kOff);
}
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
set(Value.kOff); // Stop for safety
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -10,29 +10,28 @@ package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.HALControlWord;
import edu.wpi.first.wpilibj.communication.HALAllianceStationID;
import edu.wpi.first.wpilibj.communication.HALControlWord;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.hal.PowerJNI;
/**
* Provide access to the network communication data to / from the Driver
* Station.
* Provide access to the network communication data to / from the Driver Station.
*/
public class DriverStation implements RobotState.Interface {
/**
* Number of Joystick Ports
* Number of Joystick Ports.
*/
public static final int kJoystickPorts = 6;
private class HALJoystickButtons {
public int buttons;
public byte count;
public int m_buttons;
public byte m_count;
}
/**
* The robot alliance that the robot is a part of
* The robot alliance that the robot is a part of.
*/
public enum Alliance {
Red, Blue, Invalid
@@ -69,7 +68,7 @@ public class DriverStation implements RobotState.Interface {
private Thread m_thread;
private final Object m_dataSem;
private volatile boolean m_thread_keepalive = true;
private volatile boolean m_threadKeepAlive = true;
private boolean m_userInDisabled = false;
private boolean m_userInAutonomous = false;
private boolean m_userInTeleop = false;
@@ -90,8 +89,8 @@ public class DriverStation implements RobotState.Interface {
/**
* DriverStation constructor.
*
* The single DriverStation instance is created statically with the instance
* static member variable.
* <p>The single DriverStation instance is created statically with the instance static member
* variable.
*/
protected DriverStation() {
m_dataSem = new Object();
@@ -110,18 +109,18 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Kill the thread
* Kill the thread.
*/
public void release() {
m_thread_keepalive = false;
m_threadKeepAlive = false;
}
/**
* Provides the service routine for the DS polling thread.
* Provides the service routine for the DS polling m_thread.
*/
private void task() {
int safetyCounter = 0;
while (m_thread_keepalive) {
while (m_threadKeepAlive) {
HALUtil.takeMultiWait(m_packetDataAvailableSem, m_packetDataAvailableMutex);
synchronized (this) {
getData();
@@ -156,8 +155,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Wait for new data or for timeout, which ever comes first. If timeout is 0,
* wait for new data only.
* Wait for new data or for timeout, which ever comes first. If timeout is 0, wait for new data
* only.
*
* @param timeout The maximum time in milliseconds to wait.
*/
@@ -166,14 +165,14 @@ public class DriverStation implements RobotState.Interface {
try {
m_dataSem.wait(timeout);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
/**
* Copy data from the DS task for the user. If no new data exists, it will
* just be returned, otherwise the data will be copied from the DS polling
* loop.
* Copy data from the DS task for the user. If no new data exists, it will just be returned,
* otherwise the data will be copied from the DS polling loop.
*/
protected synchronized void getData() {
@@ -182,9 +181,9 @@ public class DriverStation implements RobotState.Interface {
m_joystickAxes[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickAxes(stick);
m_joystickPOVs[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickPOVs(stick);
ByteBuffer countBuffer = ByteBuffer.allocateDirect(1);
m_joystickButtons[stick].buttons =
FRCNetworkCommunicationsLibrary.HALGetJoystickButtons((byte) stick, countBuffer);
m_joystickButtons[stick].count = countBuffer.get();
m_joystickButtons[stick].m_buttons =
FRCNetworkCommunicationsLibrary.HALGetJoystickButtons(stick, countBuffer);
m_joystickButtons[stick].m_count = countBuffer.get();
}
m_newControlData = true;
@@ -200,8 +199,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Reports errors related to unplugged joysticks Throttles the errors so that
* they don't overwhelm the DS
* Reports errors related to unplugged joysticks Throttles the errors so that they don't overwhelm
* the DS.
*/
private void reportJoystickUnpluggedError(String message) {
double currentTime = Timer.getFPGATimestamp();
@@ -212,8 +211,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Reports errors related to unplugged joysticks Throttles the errors so that
* they don't overwhelm the DS
* Reports errors related to unplugged joysticks Throttles the errors so that they don't overwhelm
* the DS.
*/
private void reportJoystickUnpluggedWarning(String message) {
double currentTime = Timer.getFPGATimestamp();
@@ -224,11 +223,11 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Get the value of the axis on a joystick. This depends on the mapping of the
* joystick connected to the specified port.
* Get the value of the axis on a joystick. This depends on the mapping of the joystick connected
* to the specified port.
*
* @param stick The joystick to read.
* @param axis The analog axis value to read from the joystick.
* @param axis The analog axis value to read from the joystick.
* @return The value of the axis on the joystick.
*/
public synchronized double getStickAxis(int stick, int axis) {
@@ -256,7 +255,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Returns the number of axes on a given joystick port
* Returns the number of axes on a given joystick port.
*
* @param stick The joystick port number
* @return The number of axes on the indicated joystick
@@ -294,7 +293,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Returns the number of POVs on a given joystick port
* Returns the number of POVs on a given joystick port.
*
* @param stick The joystick port number
* @return The number of POVs on the indicated joystick
@@ -319,13 +318,13 @@ public class DriverStation implements RobotState.Interface {
throw new RuntimeException("Joystick index is out of range, should be 0-3");
}
return m_joystickButtons[stick].buttons;
return m_joystickButtons[stick].m_buttons;
}
/**
* The state of one joystick button. Button indexes begin at 1.
*
* @param stick The joystick to read.
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return The state of the joystick button.
*/
@@ -335,7 +334,7 @@ public class DriverStation implements RobotState.Interface {
}
if (button > m_joystickButtons[stick].count) {
if (button > m_joystickButtons[stick].m_count) {
reportJoystickUnpluggedWarning("Joystick Button " + button + " on port " + stick
+ " not available, check if controller is plugged in");
return false;
@@ -344,11 +343,11 @@ public class DriverStation implements RobotState.Interface {
reportJoystickUnpluggedError("Button indexes begin at 1 in WPILib for C++ and Java");
return false;
}
return ((0x1 << (button - 1)) & m_joystickButtons[stick].buttons) != 0;
return ((0x1 << (button - 1)) & m_joystickButtons[stick].m_buttons) != 0;
}
/**
* Gets the number of buttons on a joystick
* Gets the number of buttons on a joystick.
*
* @param stick The joystick port number
* @return The number of buttons on the indicated joystick
@@ -360,11 +359,11 @@ public class DriverStation implements RobotState.Interface {
}
return m_joystickButtons[stick].count;
return m_joystickButtons[stick].m_count;
}
/**
* Gets the value of isXbox on a joystick
* Gets the value of isXbox on a joystick.
*
* @param stick The joystick port number
* @return A boolean that returns the value of isXbox
@@ -376,7 +375,7 @@ public class DriverStation implements RobotState.Interface {
}
// TODO: Remove this when calling for descriptor on empty stick no longer
// crashes
if (1 > m_joystickButtons[stick].count && 1 > m_joystickAxes[stick].length) {
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
reportJoystickUnpluggedWarning("Joystick on port " + stick
+ " not available, check if controller is plugged in");
return false;
@@ -389,7 +388,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets the value of type on a joystick
* Gets the value of type on a joystick.
*
* @param stick The joystick port number
* @return The value of type
@@ -401,7 +400,7 @@ public class DriverStation implements RobotState.Interface {
}
// TODO: Remove this when calling for descriptor on empty stick no longer
// crashes
if (1 > m_joystickButtons[stick].count && 1 > m_joystickAxes[stick].length) {
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
reportJoystickUnpluggedWarning("Joystick on port " + stick
+ " not available, check if controller is plugged in");
return -1;
@@ -410,7 +409,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets the name of the joystick at a port
* Gets the name of the joystick at a port.
*
* @param stick The joystick port number
* @return The value of name
@@ -422,7 +421,7 @@ public class DriverStation implements RobotState.Interface {
}
// TODO: Remove this when calling for descriptor on empty stick no longer
// crashes
if (1 > m_joystickButtons[stick].count && 1 > m_joystickAxes[stick].length) {
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
reportJoystickUnpluggedWarning("Joystick on port " + stick
+ " not available, check if controller is plugged in");
return "";
@@ -431,8 +430,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* enabled.
* Gets a value indicating whether the Driver Station requires the robot to be enabled.
*
* @return True if the robot is enabled, false otherwise.
*/
@@ -442,8 +440,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* disabled.
* Gets a value indicating whether the Driver Station requires the robot to be disabled.
*
* @return True if the robot should be disabled, false otherwise.
*/
@@ -452,8 +449,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* running in autonomous mode.
* Gets a value indicating whether the Driver Station requires the robot to be running in
* autonomous mode.
*
* @return True if autonomous mode should be enabled, false otherwise.
*/
@@ -463,9 +460,9 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* running in test mode.
*$
* Gets a value indicating whether the Driver Station requires the robot to be running in test
* mode.
*
* @return True if test mode should be enabled, false otherwise.
*/
public boolean isTest() {
@@ -474,20 +471,18 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* running in operator-controlled mode.
* Gets a value indicating whether the Driver Station requires the robot to be running in
* operator-controlled mode.
*
* @return True if operator-controlled mode should be enabled, false
* otherwise.
* @return True if operator-controlled mode should be enabled, false otherwise.
*/
public boolean isOperatorControl() {
return !(isAutonomous() || isTest());
}
/**
* Gets a value indicating whether the FPGA outputs are enabled. The outputs
* may be disabled if the robot is disabled or e-stopped, the watdhog has
* expired, or if the roboRIO browns out.
* Gets a value indicating whether the FPGA outputs are enabled. The outputs may be disabled if
* the robot is disabled or e-stopped, the watdhog has expired, or if the roboRIO browns out.
*
* @return True if the FPGA outputs are enabled.
*/
@@ -497,7 +492,7 @@ public class DriverStation implements RobotState.Interface {
/**
* Check if the system is browned out.
*$
*
* @return True if the system is browned out
*/
public boolean isBrownedOut() {
@@ -505,9 +500,9 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Has a new control packet from the driver station arrived since the last
* time this function was called?
*$
* Has a new control packet from the driver station arrived since the last time this function was
* called?
*
* @return True if the control data has been updated since the last call.
*/
public synchronized boolean isNewControlData() {
@@ -517,8 +512,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Get the current alliance from the FMS
*$
* Get the current alliance from the FMS.
*
* @return the current alliance
*/
public Alliance getAlliance() {
@@ -574,11 +569,10 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Is the driver station attached to a Field Management System? Note: This
* does not work with the Blue DS.
*$
* @return True if the robot is competing on a field being controlled by a
* Field Management System
* Is the driver station attached to a Field Management System? Note: This does not work with the
* Blue DS.
*
* @return True if the robot is competing on a field being controlled by a Field Management System
*/
public boolean isFMSAttached() {
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
@@ -591,14 +585,12 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Return the approximate match time The FMS does not send an official match
* time to the robots, but does send an approximate match time. The value will
* count down the time remaining in the current period (auto or teleop).
* Warning: This is not an official time (so it cannot be used to dispute ref
* calls or guarantee that a function will trigger before the match ends) The
* Practice Match function of the DS approximates the behaviour seen on the
* field.
*$
* Return the approximate match time The FMS does not send an official match time to the robots,
* but does send an approximate match time. The value will count down the time remaining in the
* current period (auto or teleop). Warning: This is not an official time (so it cannot be used to
* dispute ref calls or guarantee that a function will trigger before the match ends) The
* Practice Match function of the DS approximates the behaviour seen on the field.
*
* @return Time remaining in current match period (auto or teleop) in seconds
*/
public double getMatchTime() {
@@ -606,9 +598,9 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Report error to Driver Station. Also prints error to System.err Optionally
* appends Stack trace to error message
*$
* Report error to Driver Station. Also prints error to System.err Optionally appends Stack trace
* to error message.
*
* @param printTrace If true, append stack trace to error string
*/
public static void reportError(String error, boolean printTrace) {
@@ -616,25 +608,26 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Report warning to Driver Station. Also prints error to System.err Optionally
* appends Stack trace to warning message
*$
* Report warning to Driver Station. Also prints error to System.err Optionally appends Stack
* trace to warning message.
*
* @param printTrace If true, append stack trace to warning string
*/
public static void reportWarning(String error, boolean printTrace) {
reportErrorImpl(false, 1, error, printTrace);
}
private static void reportErrorImpl(boolean is_error, int code, String error, boolean printTrace) {
private static void reportErrorImpl(boolean isError, int code, String error, boolean
printTrace) {
StackTraceElement[] traces = Thread.currentThread().getStackTrace();
String locString;
if (traces.length > 3)
if (traces.length > 3) {
locString = traces[3].toString();
else
} else {
locString = new String();
}
boolean haveLoc = false;
String traceString = new String();
traceString = " at ";
String traceString = " at ";
for (int i = 3; i < traces.length; i++) {
String loc = traces[i].toString();
traceString += loc + "\n";
@@ -644,48 +637,50 @@ public class DriverStation implements RobotState.Interface {
haveLoc = true;
}
}
FRCNetworkCommunicationsLibrary.HALSendError(is_error, code, false, error, locString, printTrace ? traceString : "", true);
FRCNetworkCommunicationsLibrary.HALSendError(isError, code, false, error, locString,
printTrace ? traceString : "", true);
}
/**
* Only to be used to tell the Driver Station what code you claim to be
* executing for diagnostic purposes only
*$
* @param entering If true, starting disabled code; if false, leaving disabled
* code
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
* purposes only.
*
* @param entering If true, starting disabled code; if false, leaving disabled code
*/
@SuppressWarnings("MethodName")
public void InDisabled(boolean entering) {
m_userInDisabled = entering;
}
/**
* Only to be used to tell the Driver Station what code you claim to be
* executing for diagnostic purposes only
*$
* @param entering If true, starting autonomous code; if false, leaving
* autonomous code
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
* purposes only.
*
* @param entering If true, starting autonomous code; if false, leaving autonomous code
*/
@SuppressWarnings("MethodName")
public void InAutonomous(boolean entering) {
m_userInAutonomous = entering;
}
/**
* Only to be used to tell the Driver Station what code you claim to be
* executing for diagnostic purposes only
*$
* @param entering If true, starting teleop code; if false, leaving teleop
* code
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
* purposes only.
*
* @param entering If true, starting teleop code; if false, leaving teleop code
*/
@SuppressWarnings("MethodName")
public void InOperatorControl(boolean entering) {
m_userInTeleop = entering;
}
/**
* Only to be used to tell the Driver Station what code you claim to be
* executing for diagnostic purposes only
*$
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
* purposes only.
*
* @param entering If true, starting test code; if false, leaving test code
*/
@SuppressWarnings("MethodName")
public void InTest(boolean entering) {
m_userInTest = entering;
}

View File

@@ -7,30 +7,27 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.EncoderJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.util.BoundaryException;
/**
* Class to read quad encoders. Quadrature encoders are devices that count shaft
* rotation and can sense direction. The output of the QuadEncoder class is an
* integer that can count either up or down, and can go negative for reverse
* direction counting. When creating QuadEncoders, a direction is supplied that
* changes the sense of the output to make code more readable if the encoder is
* mounted such that forward movement generates negative values. Quadrature
* encoders have two digital outputs, an A Channel and a B Channel that are out
* of phase with each other to allow the FPGA to do direction sensing.
* Class to read quad encoders. Quadrature encoders are devices that count shaft rotation and can
* sense direction. The output of the QuadEncoder class is an integer that can count either up or
* down, and can go negative for reverse direction counting. When creating QuadEncoders, a direction
* is supplied that changes the sense of the output to make code more readable if the encoder is
* mounted such that forward movement generates negative values. Quadrature encoders have two
* digital outputs, an A Channel and a B Channel that are out of phase with each other to allow the
* FPGA to do direction sensing.
*
* All encoders will immediately start counting - reset() them if you need them
* to be zeroed before use.
* <p>All encoders will immediately start counting - reset() them if you need them to be zeroed
* before use.
*/
public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveWindowSendable {
public enum IndexingType {
@@ -38,15 +35,17 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* The a source
* The a source.
*/
@SuppressWarnings("MemberName")
protected DigitalSource m_aSource; // the A phase of the quad encoder
/**
* The b source
* The b source.
*/
@SuppressWarnings("MemberName")
protected DigitalSource m_bSource; // the B phase of the quad encoder
/**
* The index source
* The index source.
*/
protected DigitalSource m_indexSource = null; // Index on some encoders
private long m_encoder;
@@ -54,27 +53,27 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
private double m_distancePerPulse; // distance of travel for each encoder
// tick
private Counter m_counter; // Counter object for 1x and 2x encoding
/**
* Either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is selected, then an encoder
* FPGA object is used and the returned counts will be 4x the encoder spec'd value since all
* rising and falling edges are counted. If 1X or 2X are selected then a counter object will be
* used and the returned value will either exactly match the spec'd count or be double (2x) the
* spec'd count.
*/
private EncodingType m_encodingType = EncodingType.k4X;
private int m_encodingScale; // 1x, 2x, or 4x, per the encodingType
private int m_encodingScale; // 1x, 2x, or 4x, per the m_encodingType
private boolean m_allocatedA;
private boolean m_allocatedB;
private boolean m_allocatedI;
private PIDSourceType m_pidSource;
/**
* Common initialization code for Encoders. This code allocates resources for
* Encoders and is common to all constructors.
* Common initialization code for Encoders. This code allocates resources for Encoders and is
* common to all constructors.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param reverseDirection If true, counts down instead of up (this is all
* relative)
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
* decoding. If 4X is selected, then an encoder FPGA object is used and
* the returned counts will be 4x the encoder spec'd value since all
* rising and falling edges are counted. If 1X or 2X are selected then
* a counter object will be used and the returned value will either
* exactly match the spec'd count or be double (2x) the spec'd count.
* @param reverseDirection If true, counts down instead of up (this is all relative)
*/
private void initEncoder(boolean reverseDirection) {
switch (m_encodingType) {
@@ -84,9 +83,9 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
// set the byte order
index.order(ByteOrder.LITTLE_ENDIAN);
m_encoder =
EncoderJNI.initializeEncoder((byte) m_aSource.getModuleForRouting(), m_aSource
.getChannelForRouting(), m_aSource.getAnalogTriggerForRouting(),
(byte) m_bSource.getModuleForRouting(), m_bSource.getChannelForRouting(),
EncoderJNI.initializeEncoder(m_aSource.getModuleForRouting(), m_aSource
.getChannelForRouting(), m_aSource.getAnalogTriggerForRouting(),
m_bSource.getModuleForRouting(), m_bSource.getChannelForRouting(),
m_bSource.getAnalogTriggerForRouting(),
reverseDirection, index.asIntBuffer());
m_index = index.asIntBuffer().get(0);
@@ -99,6 +98,8 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
m_counter = new Counter(m_encodingType, m_aSource, m_bSource, reverseDirection);
m_index = m_counter.getFPGAIndex();
break;
default:
throw new AssertionError("Illegal encoding type: " + m_encodingType);
}
m_distancePerPulse = 1.0;
m_pidSource = PIDSourceType.kDisplacement;
@@ -110,249 +111,249 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
/**
* Encoder constructor. Construct a Encoder given a and b channels.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel DIO channel. 0-9 are on-board, 10-25 are on
* the MXP port
* @param bChannel The b channel DIO channel. 0-9 are on-board, 10-25 are on
* the MXP port
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward represents
* positive values.
* @param channelA The a channel DIO channel. 0-9 are on-board, 10-25 are on the MXP port
* @param channelB The b channel DIO channel. 0-9 are on-board, 10-25 are on the MXP port
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
*/
public Encoder(final int aChannel, final int bChannel, boolean reverseDirection) {
public Encoder(final int channelA, final int channelB, boolean reverseDirection) {
m_allocatedA = true;
m_allocatedB = true;
m_allocatedI = false;
m_aSource = new DigitalInput(aChannel);
m_bSource = new DigitalInput(bChannel);
m_aSource = new DigitalInput(channelA);
m_bSource = new DigitalInput(channelB);
initEncoder(reverseDirection);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel digital input channel.
* @param bChannel The b channel digital input channel.
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
*/
public Encoder(final int aChannel, final int bChannel) {
this(aChannel, bChannel, false);
public Encoder(final int channelA, final int channelB) {
this(channelA, channelB, false);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel digital input channel.
* @param bChannel The b channel digital input channel.
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward represents
* positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
* decoding. If 4X is selected, then an encoder FPGA object is used and
* the returned counts will be 4x the encoder spec'd value since all
* rising and falling edges are counted. If 1X or 2X are selected then
* a counter object will be used and the returned value will either
* exactly match the spec'd count or be double (2x) the spec'd count.
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
* selected, then an encoder FPGA object is used and the returned counts
* will be 4x the encoder spec'd value since all rising and falling edges
* are counted. If 1X or 2X are selected then a m_counter object will be
* used and the returned value will either exactly match the spec'd count
* or be double (2x) the spec'd count.
*/
public Encoder(final int aChannel, final int bChannel, boolean reverseDirection,
final EncodingType encodingType) {
public Encoder(final int channelA, final int channelB, boolean reverseDirection,
final EncodingType encodingType) {
m_allocatedA = true;
m_allocatedB = true;
m_allocatedI = false;
if (encodingType == null)
if (encodingType == null) {
throw new NullPointerException("Given encoding type was null");
}
m_encodingType = encodingType;
m_aSource = new DigitalInput(aChannel);
m_bSource = new DigitalInput(bChannel);
m_aSource = new DigitalInput(channelA);
m_bSource = new DigitalInput(channelB);
initEncoder(reverseDirection);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels. Using an
* index pulse forces 4x encoding
* Encoder constructor. Construct a Encoder given a and b channels. Using an index pulse forces 4x
* encoding
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel digital input channel.
* @param bChannel The b channel digital input channel.
* @param indexChannel The index channel digital input channel.
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward represents
* positive values.
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param indexChannel The index channel digital input channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
*/
public Encoder(final int aChannel, final int bChannel, final int indexChannel,
boolean reverseDirection) {
public Encoder(final int channelA, final int channelB, final int indexChannel,
boolean reverseDirection) {
m_allocatedA = true;
m_allocatedB = true;
m_allocatedI = true;
m_aSource = new DigitalInput(aChannel);
m_bSource = new DigitalInput(bChannel);
m_aSource = new DigitalInput(channelA);
m_bSource = new DigitalInput(channelB);
m_indexSource = new DigitalInput(indexChannel);
initEncoder(reverseDirection);
setIndexSource(indexChannel);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels. Using an
* index pulse forces 4x encoding
* Encoder constructor. Construct a Encoder given a and b channels. Using an index pulse forces 4x
* encoding
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel digital input channel.
* @param bChannel The b channel digital input channel.
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param indexChannel The index channel digital input channel.
*/
public Encoder(final int aChannel, final int bChannel, final int indexChannel) {
this(aChannel, bChannel, indexChannel, false);
public Encoder(final int channelA, final int channelB, final int indexChannel) {
this(channelA, channelB, indexChannel, false);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels as digital
* inputs. This is used in the case where the digital inputs are shared. The
* Encoder class will not allocate the digital inputs and assume that they
* already are counted.
* Encoder constructor. Construct a Encoder given a and b channels as digital inputs. This is used
* in the case where the digital inputs are shared. The Encoder class will not allocate the
* digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource the source that should be used for the b channel.
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward represents
* positive values.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource, boolean reverseDirection) {
public Encoder(DigitalSource sourceA, DigitalSource sourceB, boolean reverseDirection) {
m_allocatedA = false;
m_allocatedB = false;
m_allocatedI = false;
if (aSource == null)
if (sourceA == null) {
throw new NullPointerException("Digital Source A was null");
m_aSource = aSource;
if (bSource == null)
}
m_aSource = sourceA;
if (sourceB == null) {
throw new NullPointerException("Digital Source B was null");
m_bSource = bSource;
}
m_bSource = sourceB;
initEncoder(reverseDirection);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels as digital
* inputs. This is used in the case where the digital inputs are shared. The
* Encoder class will not allocate the digital inputs and assume that they
* already are counted.
* Encoder constructor. Construct a Encoder given a and b channels as digital inputs. This is used
* in the case where the digital inputs are shared. The Encoder class will not allocate the
* digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource the source that should be used for the b channel.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource) {
this(aSource, bSource, false);
public Encoder(DigitalSource sourceA, DigitalSource sourceB) {
this(sourceA, sourceB, false);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels as digital
* inputs. This is used in the case where the digital inputs are shared. The
* Encoder class will not allocate the digital inputs and assume that they
* already are counted.
* Encoder constructor. Construct a Encoder given a and b channels as digital inputs. This is used
* in the case where the digital inputs are shared. The Encoder class will not allocate the
* digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource the source that should be used for the b channel.
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward represents
* positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
* decoding. If 4X is selected, then an encoder FPGA object is used and
* the returned counts will be 4x the encoder spec'd value since all
* rising and falling edges are counted. If 1X or 2X are selected then
* a counter object will be used and the returned value will either
* exactly match the spec'd count or be double (2x) the spec'd count.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
* selected, then an encoder FPGA object is used and the returned counts
* will be 4x the encoder spec'd value since all rising and falling edges
* are counted. If 1X or 2X are selected then a m_counter object will be
* used and the returned value will either exactly match the spec'd count
* or be double (2x) the spec'd count.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource, boolean reverseDirection,
final EncodingType encodingType) {
public Encoder(DigitalSource sourceA, DigitalSource sourceB, boolean reverseDirection,
final EncodingType encodingType) {
m_allocatedA = false;
m_allocatedB = false;
m_allocatedI = false;
if (encodingType == null)
if (encodingType == null) {
throw new NullPointerException("Given encoding type was null");
}
m_encodingType = encodingType;
if (aSource == null)
if (sourceA == null) {
throw new NullPointerException("Digital Source A was null");
m_aSource = aSource;
if (bSource == null)
}
m_aSource = sourceA;
if (sourceB == null) {
throw new NullPointerException("Digital Source B was null");
m_aSource = aSource;
m_bSource = bSource;
}
m_aSource = sourceA;
m_bSource = sourceB;
initEncoder(reverseDirection);
}
/**
* Encoder constructor. Construct a Encoder given a, b and index channels as
* digital inputs. This is used in the case where the digital inputs are
* shared. The Encoder class will not allocate the digital inputs and assume
* that they already are counted.
* Encoder constructor. Construct a Encoder given a, b and index channels as digital inputs. This
* is used in the case where the digital inputs are shared. The Encoder class will not allocate
* the digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource the source that should be used for the b channel.
* @param indexSource the source that should be used for the index channel.
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward represents
* positive values.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param indexSource the source that should be used for the index channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource, DigitalSource indexSource,
boolean reverseDirection) {
public Encoder(DigitalSource sourceA, DigitalSource sourceB, DigitalSource indexSource,
boolean reverseDirection) {
m_allocatedA = false;
m_allocatedB = false;
m_allocatedI = false;
if (aSource == null)
if (sourceB == null) {
throw new NullPointerException("Digital Source A was null");
m_aSource = aSource;
if (bSource == null)
}
m_aSource = sourceA;
if (sourceB == null) {
throw new NullPointerException("Digital Source B was null");
m_aSource = aSource;
m_bSource = bSource;
}
m_aSource = sourceA;
m_bSource = sourceB;
m_indexSource = indexSource;
initEncoder(reverseDirection);
setIndexSource(indexSource);
}
/**
* Encoder constructor. Construct a Encoder given a, b and index channels as
* digital inputs. This is used in the case where the digital inputs are
* shared. The Encoder class will not allocate the digital inputs and assume
* that they already are counted.
* Encoder constructor. Construct a Encoder given a, b and index channels as digital inputs. This
* is used in the case where the digital inputs are shared. The Encoder class will not allocate
* the digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource the source that should be used for the b channel.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param indexSource the source that should be used for the index channel.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource, DigitalSource indexSource) {
this(aSource, bSource, indexSource, false);
public Encoder(DigitalSource sourceA, DigitalSource sourceB, DigitalSource indexSource) {
this(sourceA, sourceB, indexSource, false);
}
/**
* @return the Encoder's FPGA index
* @return The Encoder's FPGA index.
*/
@SuppressWarnings("AbbreviationAsWordInName")
public int getFPGAIndex() {
return m_index;
}
/**
* @return the encoding scale factor 1x, 2x, or 4x, per the requested
* encodingType. Used to divide raw edge counts down to spec'd counts.
* Used to divide raw edge counts down to spec'd counts.
*
* @return The encoding scale factor 1x, 2x, or 4x, per the requested encoding type.
*/
public int getEncodingScale() {
return m_encodingScale;
}
/**
* Free the resources used by this object.
*/
public void free() {
if (m_aSource != null && m_allocatedA) {
m_aSource.free();
@@ -379,8 +380,8 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Gets the raw value from the encoder. The raw value is the actual count
* unscaled by the 1x, 2x, or 4x scale factor.
* Gets the raw value from the encoder. The raw value is the actual count unscaled by the 1x, 2x,
* or 4x scale factor.
*
* @return Current raw count from the encoder
*/
@@ -395,19 +396,17 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Gets the current count. Returns the current count on the Encoder. This
* method compensates for the decoding type.
* Gets the current count. Returns the current count on the Encoder. This method compensates for
* the decoding type.
*
* @return Current count from the Encoder adjusted for the 1x, 2x, or 4x scale
* factor.
* @return Current count from the Encoder adjusted for the 1x, 2x, or 4x scale factor.
*/
public int get() {
return (int) (getRaw() * decodingScaleFactor());
}
/**
* Reset the Encoder distance to zero. Resets the current count to zero on the
* encoder.
* Reset the Encoder distance to zero. Resets the current count to zero on the encoder.
*/
public void reset() {
if (m_counter != null) {
@@ -418,15 +417,14 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Returns the period of the most recent pulse. Returns the period of the most
* recent Encoder pulse in seconds. This method compensates for the decoding
* type.
* Returns the period of the most recent pulse. Returns the period of the most recent Encoder
* pulse in seconds. This method compensates for the decoding type.
*
* @deprecated Use getRate() in favor of this method. This returns unscaled
* periods and getRate() scales using value from
* setDistancePerPulse().
* <p></p><b>Warning:</b> This returns unscaled periods and getRate() scales using value from
* setDistancePerPulse().
*
* @return Period in seconds of the most recent pulse.
* @deprecated Use getRate() in favor of this method.
*/
public double getPeriod() {
double measuredPeriod;
@@ -439,16 +437,13 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Sets the maximum period for stopped detection. Sets the value that
* represents the maximum period of the Encoder before it will assume that the
* attached device is stopped. This timeout allows users to determine if the
* wheels or other shaft has stopped rotating. This method compensates for the
* decoding type.
* Sets the maximum period for stopped detection. Sets the value that represents the maximum
* period of the Encoder before it will assume that the attached device is stopped. This timeout
* allows users to determine if the wheels or other shaft has stopped rotating. This method
* compensates for the decoding type.
*
*
* @param maxPeriod The maximum time between rising and falling edges before
* the FPGA will report the device stopped. This is expressed in
* seconds.
* @param maxPeriod The maximum time between rising and falling edges before the FPGA will report
* the device stopped. This is expressed in seconds.
*/
public void setMaxPeriod(double maxPeriod) {
if (m_counter != null) {
@@ -459,10 +454,9 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Determine if the encoder is stopped. Using the MaxPeriod value, a boolean
* is returned that is true if the encoder is considered stopped and false if
* it is still moving. A stopped encoder is one where the most recent pulse
* width exceeds the MaxPeriod.
* Determine if the encoder is stopped. Using the MaxPeriod value, a boolean is returned that is
* true if the encoder is considered stopped and false if it is still moving. A stopped encoder is
* one where the most recent pulse width exceeds the MaxPeriod.
*
* @return True if the encoder is considered stopped.
*/
@@ -488,8 +482,7 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* The scale needed to convert a raw counter value into a number of encoder
* pulses.
* The scale needed to convert a raw counter value into a number of encoder pulses.
*/
private double decodingScaleFactor() {
switch (m_encodingType) {
@@ -506,18 +499,18 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Get the distance the robot has driven since the last reset.
* Get the distance the robot has driven since the last reset as scaled by the value from {@link
* #setDistancePerPulse(double)}.
*
* @return The distance driven since the last reset as scaled by the value
* from setDistancePerPulse().
* @return The distance driven since the last reset
*/
public double getDistance() {
return getRaw() * decodingScaleFactor() * m_distancePerPulse;
}
/**
* Get the current rate of the encoder. Units are distance per second as
* scaled by the value from setDistancePerPulse().
* Get the current rate of the encoder. Units are distance per second as scaled by the value from
* setDistancePerPulse().
*
* @return The current rate of the encoder.
*/
@@ -528,51 +521,42 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
/**
* Set the minimum rate of the device before the hardware reports it stopped.
*
* @param minRate The minimum rate. The units are in distance per second as
* scaled by the value from setDistancePerPulse().
* @param minRate The minimum rate. The units are in distance per second as scaled by the value
* from setDistancePerPulse().
*/
public void setMinRate(double minRate) {
setMaxPeriod(m_distancePerPulse / minRate);
}
/**
* Set the distance per pulse for this encoder. This sets the multiplier used
* to determine the distance driven based on the count value from the encoder.
* Do not include the decoding type in this scale. The library already
* compensates for the decoding type. Set this value based on the encoder's
* rated Pulses per Revolution and factor in gearing reductions following the
* encoder shaft. This distance can be in any units you like, linear or
* angular.
* Set the distance per pulse for this encoder. This sets the multiplier used to determine the
* distance driven based on the count value from the encoder. Do not include the decoding type in
* this scale. The library already compensates for the decoding type. Set this value based on the
* encoder's rated Pulses per Revolution and factor in gearing reductions following the encoder
* shaft. This distance can be in any units you like, linear or angular.
*
* @param distancePerPulse The scale factor that will be used to convert
* pulses to useful units.
* @param distancePerPulse The scale factor that will be used to convert pulses to useful units.
*/
public void setDistancePerPulse(double distancePerPulse) {
m_distancePerPulse = distancePerPulse;
}
/**
* Set the direction sensing for this encoder. This sets the direction sensing
* on the encoder so that it could count in the correct software direction
* regardless of the mounting.
* Set the direction sensing for this encoder. This sets the direction sensing on the encoder so
* that it could count in the correct software direction regardless of the mounting.
*
* @param reverseDirection true if the encoder direction should be reversed
*/
public void setReverseDirection(boolean reverseDirection) {
if (m_counter != null) {
m_counter.setReverseDirection(reverseDirection);
} else {
}
}
/**
* Set the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
*
* TODO: Should this throw a checked exception, so that the user has to deal
* with giving an incorrect value?
* Set the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @param samplesToAverage The number of samples to average from 1 to 127.
*/
@@ -584,17 +568,18 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
case k1X:
case k2X:
m_counter.setSamplesToAverage(samplesToAverage);
break;
break;
default:
throw new AssertionError("Illegal encoding type: " + m_encodingType);
}
}
/**
* Get the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
* Get the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @return SamplesToAverage The number of samples being averaged (from 1 to
* 127)
* @return SamplesToAverage The number of samples being averaged (from 1 to 127)
*/
public int getSamplesToAverage() {
switch (m_encodingType) {
@@ -603,13 +588,14 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
case k1X:
case k2X:
return m_counter.getSamplesToAverage();
default:
return 1;
}
return 1;
}
/**
* Set which parameter of the encoder you are using as a process control
* variable. The encoder class supports the rate and distance parameters.
* Set which parameter of the encoder you are using as a process control variable. The encoder
* class supports the rate and distance parameters.
*
* @param pidSource An enum to select the parameter.
*/
@@ -617,9 +603,7 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -641,11 +625,31 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Set the index source for the encoder. When this source rises, the encoder
* count automatically resets.
* Set the index source for the encoder. When this source is activated, the encoder count
* automatically resets.
*
* @param channel A DIO channel to set as the encoder index
* @param type The state that will cause the encoder to reset
*/
public void setIndexSource(int channel) {
setIndexSource(channel, IndexingType.kResetOnRisingEdge);
}
/**
* Set the index source for the encoder. When this source is activated, the encoder count
* automatically resets.
*
* @param source A digital source to set as the encoder index
*/
public void setIndexSource(DigitalSource source) {
setIndexSource(source, IndexingType.kResetOnRisingEdge);
}
/**
* Set the index source for the encoder. When this source rises, the encoder count automatically
* resets.
*
* @param channel A DIO channel to set as the encoder index
* @param type The state that will cause the encoder to reset
*/
public void setIndexSource(int channel, IndexingType type) {
boolean activeHigh =
@@ -657,21 +661,11 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Set the index source for the encoder. When this source is activated, the
* encoder count automatically resets.
*
* @param channel A DIO channel to set as the encoder index
*/
public void setIndexSource(int channel) {
this.setIndexSource(channel, IndexingType.kResetOnRisingEdge);
}
/**
* Set the index source for the encoder. When this source rises, the encoder
* count automatically resets.
* Set the index source for the encoder. When this source rises, the encoder count automatically
* resets.
*
* @param source A digital source to set as the encoder index
* @param type The state that will cause the encoder to reset
* @param type The state that will cause the encoder to reset
*/
public void setIndexSource(DigitalSource source, IndexingType type) {
boolean activeHigh =
@@ -684,16 +678,6 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Set the index source for the encoder. When this source is activated, the
* encoder count automatically resets.
*
* @param source A digital source to set as the encoder index
*/
public void setIndexSource(DigitalSource source) {
this.setIndexSource(source, IndexingType.kResetOnRisingEdge);
}
/*
* Live Window code, only does anything if live window is activated.
*/
public String getSmartDashboardType() {
@@ -707,24 +691,18 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Speed", getRate());
@@ -733,13 +711,11 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
}
/**
* {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -12,10 +12,9 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Alias for counter class. Implement the gear tooth sensor supplied by FIRST.
* Currently there is no reverse sensing on the gear tooth sensor, but in future
* versions we might implement the necessary timing in the FPGA to sense
* direction.
* Alias for counter class. Implement the gear tooth sensor supplied by FIRST. Currently there is no
* reverse sensing on the gear tooth sensor, but in future versions we might implement the necessary
* timing in the FPGA to sense direction.
*/
public class GearTooth extends Counter {
@@ -33,7 +32,7 @@ public class GearTooth extends Counter {
/**
* Construct a GearTooth sensor given a channel.
*
* No direction sensing is assumed.
* <p>No direction sensing is assumed.
*
* @param channel The GPIO channel that the sensor is connected to.
*/
@@ -44,10 +43,10 @@ public class GearTooth extends Counter {
/**
* Construct a GearTooth sensor given a channel.
*
* @param channel The DIO channel that the sensor is connected to. 0-9 are
* on-board, 10-25 are on the MXP port
* @param directionSensitive True to enable the pulse length decoding in
* hardware to specify count direction.
* @param channel The DIO channel that the sensor is connected to. 0-9 are on-board,
* 10-25 are on the MXP port
* @param directionSensitive True to enable the pulse length decoding in hardware to specify count
* direction.
*/
public GearTooth(final int channel, boolean directionSensitive) {
super(channel);
@@ -61,12 +60,12 @@ public class GearTooth extends Counter {
}
/**
* Construct a GearTooth sensor given a digital input. This should be used
* when sharing digital inputs.
* Construct a GearTooth sensor given a digital input. This should be used when sharing digital
* inputs.
*
* @param source An existing DigitalSource object (such as a DigitalInput)
* @param directionSensitive True to enable the pulse length decoding in
* hardware to specify count direction.
* @param source An existing DigitalSource object (such as a DigitalInput)
* @param directionSensitive True to enable the pulse length decoding in hardware to specify count
* direction.
*/
public GearTooth(DigitalSource source, boolean directionSensitive) {
super(source);
@@ -74,13 +73,12 @@ public class GearTooth extends Counter {
}
/**
* Construct a GearTooth sensor given a digital input. This should be used
* when sharing digial inputs.
* Construct a GearTooth sensor given a digital input. This should be used when sharing digial
* inputs.
*
* No direction sensing is assumed.
* <p>No direction sensing is assumed.
*
* @param source An object that fully descibes the input that the sensor is
* connected to.
* @param source An object that fully descibes the input that the sensor is connected to.
*/
public GearTooth(DigitalSource source) {
this(source, false);

View File

@@ -7,7 +7,6 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
@@ -18,38 +17,38 @@ import edu.wpi.first.wpilibj.util.BoundaryException;
/**
* I2C bus interface class.
*
* This class is intended to be used by sensor (and other I2C device) drivers.
* It probably should not be used directly.
*
* <p>This class is intended to be used by sensor (and other I2C device) drivers. It probably should
* not be used directly.
*/
public class I2C extends SensorBase {
public enum Port {
kOnboard(0), kMXP(1);
private int value;
private int m_value;
private Port(int value) {
this.value = value;
Port(int value) {
m_value = value;
}
public int getValue() {
return this.value;
return m_value;
}
};
}
private Port m_port;
private int m_deviceAddress;
private final Port m_port;
private final int m_deviceAddress;
/**
* Constructor.
*
* @param port The I2C port the device is connected to.
* @param port The I2C port the device is connected to.
* @param deviceAddress The address of the device on the I2C bus.
*/
public I2C(Port port, int deviceAddress) {
m_port = port;
m_deviceAddress = deviceAddress;
I2CJNI.i2CInitialize((byte) m_port.getValue());
I2CJNI.i2CInitialize((byte) port.getValue());
UsageReporting.report(tResourceType.kResourceType_I2C, deviceAddress);
}
@@ -57,23 +56,24 @@ public class I2C extends SensorBase {
/**
* Destructor.
*/
public void free() {}
public void free() {
}
/**
* Generic transaction.
*
* This is a lower-level interface to the I2C hardware giving you more control
* over each transaction.
* <p>This is a lower-level interface to the I2C hardware giving you more control over each
* transaction.
*
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @param receiveSize Number of bytes to read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public synchronized boolean transaction(byte[] dataToSend, int sendSize, byte[] dataReceived,
int receiveSize) {
int status = -1;
public synchronized boolean transaction(byte[] dataToSend, int sendSize,
byte[] dataReceived, int receiveSize) {
final int status;
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(sendSize);
if (sendSize > 0 && dataToSend != null) {
@@ -81,9 +81,10 @@ public class I2C extends SensorBase {
}
ByteBuffer dataReceivedBuffer = ByteBuffer.allocateDirect(receiveSize);
status =
I2CJNI.i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer,
(byte) sendSize, dataReceivedBuffer, (byte) receiveSize);
status = I2CJNI
.i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress,
dataToSendBuffer, (byte) sendSize, dataReceivedBuffer,
(byte) receiveSize);
if (receiveSize > 0 && dataReceived != null) {
dataReceivedBuffer.get(dataReceived);
}
@@ -93,54 +94,58 @@ public class I2C extends SensorBase {
/**
* Generic transaction.
*
* This is a lower-level interface to the I2C hardware giving you more control
* over each transaction.
* <p>This is a lower-level interface to the I2C hardware giving you more control over each
* transaction.
*
* @param dataToSend Buffer of data to send as part of the transaction. Must
* be allocated using ByteBuffer.allocateDirect().
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into. Must be allocated using
* ByteBuffer.allocateDirect().
* @param receiveSize Number of bytes to read from the device.
* @param dataToSend Buffer of data to send as part of the transaction. Must be allocated using
* ByteBuffer.allocateDirect().
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into. Must be allocated using {@link
* ByteBuffer#allocateDirect(int)}.
* @param receiveSize Number of bytes to read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public synchronized boolean transaction(ByteBuffer dataToSend, int sendSize, ByteBuffer dataReceived,
int receiveSize) {
boolean aborted = true;
if (!dataToSend.isDirect())
public synchronized boolean transaction(ByteBuffer dataToSend, int sendSize,
ByteBuffer dataReceived, int receiveSize) {
if (!dataToSend.isDirect()) {
throw new IllegalArgumentException("dataToSend must be a direct buffer");
if (dataToSend.capacity() < sendSize)
}
if (dataToSend.capacity() < sendSize) {
throw new IllegalArgumentException("dataToSend is too small, must be at least " + sendSize);
if (!dataReceived.isDirect())
}
if (!dataReceived.isDirect()) {
throw new IllegalArgumentException("dataReceived must be a direct buffer");
if (dataReceived.capacity() < receiveSize)
throw new IllegalArgumentException("dataReceived is too small, must be at least " + receiveSize);
}
if (dataReceived.capacity() < receiveSize) {
throw new IllegalArgumentException(
"dataReceived is too small, must be at least " + receiveSize);
}
return I2CJNI.i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSend, (byte) sendSize, dataReceived, (byte) receiveSize) < receiveSize;
return I2CJNI
.i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress,
dataToSend, (byte) sendSize, dataReceived, (byte) receiveSize)
< receiveSize;
}
/**
* Attempt to address a device on the I2C bus.
*
* This allows you to figure out if there is a device on the I2C bus that
* responds to the address specified in the constructor.
* <p>This allows you to figure out if there is a device on the I2C bus that responds to the
* address specified in the constructor.
*
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean addressOnly() {
return transaction((byte[]) null, (byte) 0, (byte[]) null, (byte) 0);
return transaction((byte[]) null, (byte) 0, null, (byte) 0);
}
/**
* Execute a write transaction with the device.
*
* Write a single byte to a register on a device and wait until the
* transaction is complete.
* <p>Write a single byte to a register on a device and wait until the transaction is complete.
*
* @param registerAddress The address of the register on the device to be
* written.
* @param data The byte to write to the register on the device.
* @param registerAddress The address of the register on the device to be written.
* @param data The byte to write to the register on the device.
*/
public synchronized boolean write(int registerAddress, int data) {
byte[] buffer = new byte[2];
@@ -150,15 +155,14 @@ public class I2C extends SensorBase {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(2);
dataToSendBuffer.put(buffer);
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer,
(byte) buffer.length) < buffer.length;
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress,
dataToSendBuffer, (byte) buffer.length) < buffer.length;
}
/**
* Execute a write transaction with the device.
*
* Write multiple bytes to a register on a device and wait until the
* transaction is complete.
* <p>Write multiple bytes to a register on a device and wait until the transaction is complete.
*
* @param data The data to write to the device.
*/
@@ -166,46 +170,44 @@ public class I2C extends SensorBase {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(data.length);
dataToSendBuffer.put(data);
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer,
(byte) data.length) < data.length;
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress,
dataToSendBuffer, (byte) data.length) < data.length;
}
/**
* Execute a write transaction with the device.
*
* Write multiple bytes to a register on a device and wait until the
* transaction is complete.
* <p>Write multiple bytes to a register on a device and wait until the transaction is complete.
*
* @param data The data to write to the device. Must be created using
* ByteBuffer.allocateDirect().
* @param data The data to write to the device. Must be created using ByteBuffer.allocateDirect().
*/
public synchronized boolean writeBulk(ByteBuffer data, int size) {
if (!data.isDirect())
if (!data.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (data.capacity() < size)
throw new IllegalArgumentException("buffer is too small, must be at least " + size);
}
if (data.capacity() < size) {
throw new IllegalArgumentException(
"buffer is too small, must be at least " + size);
}
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress, data,
(byte) size) < size;
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress,
data, (byte) size) < size;
}
/**
* Execute a read transaction with the device.
*
* Read bytes from a device. Most I2C devices will auto-increment the
* register pointer internally allowing you to read consecutive
* registers on a device in a single transaction.
* <p>Read bytes from a device. Most I2C devices will auto-increment the register pointer
* internally allowing you to read consecutive registers on a device in a single transaction.
*
* @param registerAddress The register to read first in the transaction.
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from
* the device.
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean read(int registerAddress, int count, byte[] buffer) {
if (count < 1) {
throw new BoundaryException("Value must be at least 1, " + count +
" given");
throw new BoundaryException("Value must be at least 1, " + count + " given");
}
if (buffer == null) {
@@ -220,26 +222,26 @@ public class I2C extends SensorBase {
/**
* Execute a read transaction with the device.
*
* Read bytes from a device. Most I2C devices will auto-increment the
* register pointer internally allowing you to read consecutive
* registers on a device in a single transaction.
* <p>Read bytes from a device. Most I2C devices will auto-increment the register pointer
* internally allowing you to read consecutive registers on a device in a single transaction.
*
* @param registerAddress The register to read first in the transaction.
* @param count The number of bytes to read in the transaction.
* @param buffer A buffer to store the data read from the device. Must be
* created using ByteBuffer.allocateDirect().
* @param count The number of bytes to read in the transaction.
* @param buffer A buffer to store the data read from the device. Must be created using
* ByteBuffer.allocateDirect().
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean read(int registerAddress, int count, ByteBuffer buffer) {
if (count < 1) {
throw new BoundaryException("Value must be at least 1, " + count +
" given");
throw new BoundaryException("Value must be at least 1, " + count + " given");
}
if (!buffer.isDirect())
if (!buffer.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (buffer.capacity() < count)
}
if (buffer.capacity() < count) {
throw new IllegalArgumentException("buffer is too small, must be at least " + count);
}
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(1);
dataToSendBuffer.put(0, (byte) registerAddress);
@@ -250,18 +252,15 @@ public class I2C extends SensorBase {
/**
* Execute a read only transaction with the device.
*
* Read bytes from a device. This method does not write any data to prompt
* the device.
* <p>Read bytes from a device. This method does not write any data to prompt the device.
*
* @param buffer A pointer to the array of bytes to store the data read from
* the device.
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from the device.
* @param count The number of bytes to read in the transaction.
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean readOnly(byte[] buffer, int count) {
if (count < 1) {
throw new BoundaryException("Value must be at least 1, " + count +
" given");
throw new BoundaryException("Value must be at least 1, " + count + " given");
}
if (buffer == null) {
@@ -270,8 +269,8 @@ public class I2C extends SensorBase {
ByteBuffer dataReceivedBuffer = ByteBuffer.allocateDirect(count);
int retVal =
I2CJNI.i2CRead((byte) m_port.getValue(), (byte) m_deviceAddress, dataReceivedBuffer,
int retVal = I2CJNI
.i2CRead((byte) m_port.getValue(), (byte) m_deviceAddress, dataReceivedBuffer,
(byte) count);
dataReceivedBuffer.get(buffer);
return retVal < count;
@@ -280,61 +279,62 @@ public class I2C extends SensorBase {
/**
* Execute a read only transaction with the device.
*
* Read bytes from a device. This method does not write any data to prompt
* the device.
* <p>Read bytes from a device. This method does not write any data to prompt the device.
*
* @param buffer A pointer to the array of bytes to store the data read from
* the device. Must be created using ByteBuffer.allocateDirect().
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from the device. Must be
* created using ByteBuffer.allocateDirect().
* @param count The number of bytes to read in the transaction.
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean readOnly(ByteBuffer buffer, int count) {
if (count < 1) {
throw new BoundaryException("Value must be at least 1, " + count +
" given");
throw new BoundaryException("Value must be at least 1, " + count
+ " given");
}
if (!buffer.isDirect())
if (!buffer.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (buffer.capacity() < count)
}
if (buffer.capacity() < count) {
throw new IllegalArgumentException("buffer is too small, must be at least " + count);
}
return I2CJNI.i2CRead((byte) m_port.getValue(), (byte) m_deviceAddress, buffer,
(byte) count) < count;
return I2CJNI
.i2CRead((byte) m_port.getValue(), (byte) m_deviceAddress, buffer, (byte) count) < count;
}
/**
* Send a broadcast write to all devices on the I2C bus.
*
* This is not currently implemented!
* <p>This is not currently implemented!
*
* @param registerAddress The register to write on all devices on the bus.
* @param data The value to write to the devices.
* @param data The value to write to the devices.
*/
public void broadcast(int registerAddress, int data) {}
public void broadcast(int registerAddress, int data) {
}
/**
* Verify that a device's registers contain expected values.
*
* Most devices will have a set of registers that contain a known value that
* can be used to identify them. This allows an I2C device driver to easily
* verify that the device contains the expected value.
*
* @pre The device must support and be configured to use register
* auto-increment.
* <p>Most devices will have a set of registers that contain a known value that can be used to
* identify them. This allows an I2C device driver to easily verify that the device contains the
* expected value.
*
* @param registerAddress The base register to start reading from the device.
* @param count The size of the field to be verified.
* @param expected A buffer containing the values expected from the device.
* @param count The size of the field to be verified.
* @param expected A buffer containing the values expected from the device.
* @return true if the sensor was verified to be connected
* @pre The device must support and be configured to use register auto-increment.
*/
public boolean verifySensor(int registerAddress, int count, byte[] expected) {
public boolean verifySensor(int registerAddress, int count,
byte[] expected) {
// TODO: Make use of all 7 read bytes
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(1);
ByteBuffer deviceData = ByteBuffer.allocateDirect(4);
for (int i = 0, curRegisterAddress = registerAddress; i < count; i += 4, curRegisterAddress +=
4) {
for (int i = 0, curRegisterAddress = registerAddress;
i < count; i += 4, curRegisterAddress += 4) {
int toRead = count - i < 4 ? count - i : 4;
// Read the chunk of data. Return false if the sensor does not
// respond.

View File

@@ -11,21 +11,19 @@ import edu.wpi.first.wpilibj.hal.InterruptJNI.InterruptJNIHandlerFunction;
/**
* It is recommended that you use this class in conjunction with classes from
* {@link java.util.concurrent.atomic} as these objects are all thread safe.
* It is recommended that you use this class in conjunction with classes from {@link
* java.util.concurrent.atomic} as these objects are all thread safe.
*
* @param <T> The type of the parameter that should be returned to the the method {@link
* #interruptFired(int, Object)}
* @author Jonathan Leitschuh
*
* @param <T> The type of the parameter that should be returned to the the
* method {@link #interruptFired(int, Object)}
*/
public abstract class InterruptHandlerFunction<T> {
/**
* The entry point for the interrupt. When the interrupt fires the
* {@link #apply(int, Object)} method is called. The outer class is provided
* as an interface to allow the implementer to pass a generic object to the
* interrupt fired method.
*$
* The entry point for the interrupt. When the interrupt fires the {@link #apply(int, Object)}
* method is called. The outer class is provided as an interface to allow the implementer to pass
* a generic object to the interrupt fired method.
*
* @author Jonathan Leitschuh
*/
private class Function implements InterruptJNIHandlerFunction {
@@ -36,25 +34,23 @@ public abstract class InterruptHandlerFunction<T> {
}
}
final Function function = new Function();
final Function m_function = new Function();
/**
* This method is run every time an interrupt is fired.
*$
*
* @param interruptAssertedMask Interrupt Mask
* @param param The parameter provided by overriding the
* {@link #overridableParameter()} method.
* @param param The parameter provided by overriding the {@link
* #overridableParameter()} method.
*/
public abstract void interruptFired(int interruptAssertedMask, T param);
/**
* Override this method if you would like to pass a specific parameter to the
* {@link #interruptFired(int, Object)} when it is fired by the interrupt.
* This method is called once when
* {@link InterruptableSensorBase#requestInterrupts(InterruptHandlerFunction)}
* is run.
*$
* Override this method if you would like to pass a specific parameter to the {@link
* #interruptFired(int, Object)} when it is fired by the interrupt. This method is called once
* when {@link InterruptableSensorBase#requestInterrupts(InterruptHandlerFunction)} is run.
*
* @return The object that should be passed to the interrupt when it runs
*/
public T overridableParameter() {

View File

@@ -12,15 +12,18 @@ import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Base for sensors to be used with interrupts
* Base for sensors to be used with interrupts.
*/
public abstract class InterruptableSensorBase extends SensorBase {
public static enum WaitResult {
@SuppressWarnings("JavadocMethod")
public enum WaitResult {
kTimeout(0x0), kRisingEdge(0x1), kFallingEdge(0x100), kBoth(0x101);
@SuppressWarnings("MemberName")
public final int value;
@SuppressWarnings("JavadocMethod")
public static WaitResult valueOf(int value) {
for (WaitResult mode : values()) {
if (mode.value == value) {
@@ -31,48 +34,54 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
private WaitResult(int value) {
WaitResult(int value) {
this.value = value;
}
}
/**
* The interrupt resource
* The interrupt resource.
*/
protected long m_interrupt = 0;
/**
* Flags if the interrupt being allocated is synchronous
* Flags if the interrupt being allocated is synchronous.
*/
protected boolean m_isSynchronousInterrupt = false;
/**
* The index of the interrupt
* The index of the interrupt.
*/
protected int m_interruptIndex;
/**
* Resource manager
* Resource manager.
*/
protected static Resource interrupts = new Resource(8);
protected static Resource m_interrupts = new Resource(8);
/**
* Create a new InterrupatableSensorBase
* Create a new InterrupatableSensorBase.
*/
public InterruptableSensorBase() {
m_interrupt = 0;
}
/**
* @return true if this is an analog trigger
* If this is an analog trigger.
*
* @return true if this is an analog trigger.
*/
abstract boolean getAnalogTriggerForRouting();
/**
* The channel routing number.
*
* @return channel routing number
*/
abstract int getChannelForRouting();
/**
* The modules routing number.
*
* @return module routing number
*/
abstract byte getModuleForRouting();
@@ -80,12 +89,11 @@ public abstract class InterruptableSensorBase extends SensorBase {
/**
* Request one of the 8 interrupts asynchronously on this digital input.
*
* @param handler The {@link InterruptHandlerFunction} that contains the
* method {@link InterruptHandlerFunction#interruptFired(int, Object)}
* that will be called whenever there is an interrupt on this device.
* Request interrupts in synchronous mode where the user program
* interrupt handler will be called when an interrupt occurs. The
* default is interrupt on rising edges only.
* @param handler The {@link InterruptHandlerFunction} that contains the method {@link
* InterruptHandlerFunction#interruptFired(int, Object)} that will be called
* whenever there is an interrupt on this device. Request interrupts in synchronous
* mode where the user program interrupt handler will be called when an interrupt
* occurs. The default is interrupt on rising edges only.
*/
public void requestInterrupts(InterruptHandlerFunction<?> handler) {
if (m_interrupt != 0) {
@@ -99,15 +107,14 @@ public abstract class InterruptableSensorBase extends SensorBase {
InterruptJNI.requestInterrupts(m_interrupt, getModuleForRouting(), getChannelForRouting(),
getAnalogTriggerForRouting());
setUpSourceEdge(true, false);
InterruptJNI.attachInterruptHandler(m_interrupt, handler.function,
InterruptJNI.attachInterruptHandler(m_interrupt, handler.m_function,
handler.overridableParameter());
}
/**
* Request one of the 8 interrupts synchronously on this digital input.
* Request interrupts in synchronous mode where the user program will have to
* explicitly wait for the interrupt to occur using {@link #waitForInterrupt}.
* The default is interrupt on rising edges only.
* Request one of the 8 interrupts synchronously on this digital input. Request interrupts in
* synchronous mode where the user program will have to explicitly wait for the interrupt to occur
* using {@link #waitForInterrupt}. The default is interrupt on rising edges only.
*/
public void requestInterrupts() {
if (m_interrupt != 0) {
@@ -127,14 +134,13 @@ public abstract class InterruptableSensorBase extends SensorBase {
/**
* Allocate the interrupt
*
* @param watcher true if the interrupt should be in synchronous mode where
* the user program will have to explicitly wait for the interrupt to
* occur.
* @param watcher true if the interrupt should be in synchronous mode where the user program will
* have to explicitly wait for the interrupt to occur.
*/
protected void allocateInterrupts(boolean watcher) {
try {
m_interruptIndex = interrupts.allocate();
} catch (CheckedAllocationException e) {
m_interruptIndex = m_interrupts.allocate();
} catch (CheckedAllocationException ex) {
throw new AllocationException("No interrupts are left to be allocated");
}
m_isSynchronousInterrupt = watcher;
@@ -144,8 +150,8 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Cancel interrupts on this device. This deallocates all the chipobject
* structures and disables any interrupts.
* Cancel interrupts on this device. This deallocates all the chipobject structures and disables
* any interrupts.
*/
public void cancelInterrupts() {
if (m_interrupt == 0) {
@@ -153,15 +159,15 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
InterruptJNI.cleanInterrupts(m_interrupt);
m_interrupt = 0;
interrupts.free(m_interruptIndex);
m_interrupts.free(m_interruptIndex);
}
/**
* In synchronous mode, wait for the defined interrupt to occur.
*
* @param timeout Timeout in seconds
* @param ignorePrevious If true, ignore interrupts that happened before
* waitForInterrupt was called.
* @param timeout Timeout in seconds
* @param ignorePrevious If true, ignore interrupts that happened before waitForInterrupt was
* called.
* @return Result of the wait.
*/
public WaitResult waitForInterrupt(double timeout, boolean ignorePrevious) {
@@ -184,9 +190,9 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Enable interrupts to occur on this input. Interrupts are disabled when the
* RequestInterrupt call is made. This gives time to do the setup of the other
* options before starting to field interrupts.
* Enable interrupts to occur on this input. Interrupts are disabled when the RequestInterrupt
* call is made. This gives time to do the setup of the other options before starting to field
* interrupts.
*/
public void enableInterrupts() {
if (m_interrupt == 0) {
@@ -212,10 +218,10 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Return the timestamp for the rising interrupt that occurred most recently.
* This is in the same time domain as getClock(). The rising-edge interrupt
* should be enabled with {@link #setUpSourceEdge}
*$
* Return the timestamp for the rising interrupt that occurred most recently. This is in the same
* time domain as getClock(). The rising-edge interrupt should be enabled with {@link
* #setUpSourceEdge}.
*
* @return Timestamp in seconds since boot.
*/
public double readRisingTimestamp() {
@@ -226,10 +232,10 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Return the timestamp for the falling interrupt that occurred most recently.
* This is in the same time domain as getClock(). The falling-edge interrupt
* should be enabled with {@link #setUpSourceEdge}
*$
* Return the timestamp for the falling interrupt that occurred most recently. This is in the same
* time domain as getClock(). The falling-edge interrupt should be enabled with {@link
* #setUpSourceEdge}.
*
* @return Timestamp in seconds since boot.
*/
public double readFallingTimestamp() {
@@ -240,9 +246,9 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Set which edge to trigger interrupts on
* Set which edge to trigger interrupts on.
*
* @param risingEdge true to interrupt on rising edge
* @param risingEdge true to interrupt on rising edge
* @param fallingEdge true to interrupt on falling edge
*/
public void setUpSourceEdge(boolean risingEdge, boolean fallingEdge) {

View File

@@ -11,35 +11,29 @@ import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* IterativeRobot implements a specific type of Robot Program framework,
* extending the RobotBase class.
* IterativeRobot implements a specific type of Robot Program framework, extending the RobotBase
* class.
*
* The IterativeRobot class is intended to be subclassed by a user creating a
* robot program.
* <p>The IterativeRobot class is intended to be subclassed by a user creating a robot program.
*
* This class is intended to implement the "old style" default code, by
* providing the following functions which are called by the main loop,
* startCompetition(), at the appropriate times:
* <p>This class is intended to implement the "old style" default code, by providing the following
* functions which are called by the main loop, startCompetition(), at the appropriate times:
*
* robotInit() -- provide for initialization at robot power-on
* <p>robotInit() -- provide for initialization at robot power-on
*
* init() functions -- each of the following functions is called once when the
* appropriate mode is entered: - DisabledInit() -- called only when first
* disabled - AutonomousInit() -- called each and every time autonomous is
* entered from another mode - TeleopInit() -- called each and every time teleop
* is entered from another mode - TestInit() -- called each and every time test
* mode is entered from anothermode
*
* Periodic() functions -- each of these functions is called iteratively at the
* appropriate periodic rate (aka the "slow loop"). The period of the iterative
* robot is synced to the driver station control packets, giving a periodic
* frequency of about 50Hz (50 times per second). - disabledPeriodic() -
* autonomousPeriodic() - teleopPeriodic() - testPeriodoc()
* <p>init() functions -- each of the following functions is called once when the appropriate mode
* is entered: - DisabledInit() -- called only when first disabled - AutonomousInit() -- called each
* and every time autonomous is entered from another mode - TeleopInit() -- called each and every
* time teleop is entered from another mode - TestInit() -- called each and every time test mode is
* entered from anothermode
*
* <p>Periodic() functions -- each of these functions is called iteratively at the appropriate
* periodic rate (aka the "slow loop"). The period of the iterative robot is synced to the driver
* station control packets, giving a periodic frequency of about 50Hz (50 times per second). -
* disabledPeriodic() - autonomousPeriodic() - teleopPeriodic() - testPeriodoc()
*/
public class IterativeRobot extends RobotBase {
private boolean m_disabledInitialized;
@@ -48,11 +42,10 @@ public class IterativeRobot extends RobotBase {
private boolean m_testInitialized;
/**
* Constructor for RobotIterativeBase
* Constructor for RobotIterativeBase.
*
* The constructor initializes the instance variables for the robot to
* indicate the status of initialization for disabled, autonomous, and teleop
* code.
* <p>The constructor initializes the instance variables for the robot to indicate the status of
* initialization for disabled, autonomous, and teleop code.
*/
public IterativeRobot() {
// set status for initialization of disabled, autonomous, and teleop code.
@@ -64,7 +57,6 @@ public class IterativeRobot extends RobotBase {
/**
* Provide an alternate "main loop" via startCompetition().
*
*/
public void startCompetition() {
UsageReporting.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Iterative);
@@ -148,9 +140,8 @@ public class IterativeRobot extends RobotBase {
}
/**
* Determine if the appropriate next periodic function should be called. Call
* the periodic functions whenever a packet is received from the Driver
* Station, or about every 20ms.
* Determine if the appropriate next periodic function should be called. Call the periodic
* functions whenever a packet is received from the Driver Station, or about every 20ms.
*/
private boolean nextPeriodReady() {
return m_ds.isNewControlData();
@@ -161,14 +152,12 @@ public class IterativeRobot extends RobotBase {
/**
* Robot-wide initialization code should go here.
*
* Users should override this method for default Robot-wide initialization
* which will be called when the robot is first powered on. It will be called
* exactly one time.
* <p>Users should override this method for default Robot-wide initialization which will be called
* when the robot is first powered on. It will be called exactly one time.
*
* Warning: the Driver Station "Robot Code" light and FMS "Robot Ready"
* indicators will be off until RobotInit() exits. Code in RobotInit() that
* waits for enable will cause the robot to never indicate that the code is
* ready, causing the robot to be bypassed in a match.
* <p>Warning: the Driver Station "Robot Code" light and FMS "Robot Ready" indicators will be off
* until RobotInit() exits. Code in RobotInit() that waits for enable will cause the robot to
* never indicate that the code is ready, causing the robot to be bypassed in a match.
*/
public void robotInit() {
System.out.println("Default IterativeRobot.robotInit() method... Overload me!");
@@ -177,8 +166,8 @@ public class IterativeRobot extends RobotBase {
/**
* Initialization code for disabled mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters disabled mode.
* <p>Users should override this method for initialization code which will be called each time the
* robot enters disabled mode.
*/
public void disabledInit() {
System.out.println("Default IterativeRobot.disabledInit() method... Overload me!");
@@ -187,8 +176,8 @@ public class IterativeRobot extends RobotBase {
/**
* Initialization code for autonomous mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters autonomous mode.
* <p>Users should override this method for initialization code which will be called each time the
* robot enters autonomous mode.
*/
public void autonomousInit() {
System.out.println("Default IterativeRobot.autonomousInit() method... Overload me!");
@@ -197,8 +186,8 @@ public class IterativeRobot extends RobotBase {
/**
* Initialization code for teleop mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters teleop mode.
* <p>Users should override this method for initialization code which will be called each time the
* robot enters teleop mode.
*/
public void teleopInit() {
System.out.println("Default IterativeRobot.teleopInit() method... Overload me!");
@@ -207,8 +196,8 @@ public class IterativeRobot extends RobotBase {
/**
* Initialization code for test mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters test mode.
* <p>Users should override this method for initialization code which will be called each time the
* robot enters test mode.
*/
public void testInit() {
System.out.println("Default IterativeRobot.testInit() method... Overload me!");
@@ -216,66 +205,66 @@ public class IterativeRobot extends RobotBase {
/* ----------- Overridable periodic code ----------------- */
private boolean dpFirstRun = true;
private boolean m_dpFirstRun = true;
/**
* Periodic code for disabled mode should go here.
*
* Users should override this method for code which will be called
* periodically at a regular rate while the robot is in disabled mode.
* <p>Users should override this method for code which will be called periodically at a regular
* rate while the robot is in disabled mode.
*/
public void disabledPeriodic() {
if (dpFirstRun) {
if (m_dpFirstRun) {
System.out.println("Default IterativeRobot.disabledPeriodic() method... Overload me!");
dpFirstRun = false;
m_dpFirstRun = false;
}
Timer.delay(0.001);
}
private boolean apFirstRun = true;
private boolean m_apFirstRun = true;
/**
* Periodic code for autonomous mode should go here.
*
* Users should override this method for code which will be called
* periodically at a regular rate while the robot is in autonomous mode.
* <p>Users should override this method for code which will be called periodically at a regular
* rate while the robot is in autonomous mode.
*/
public void autonomousPeriodic() {
if (apFirstRun) {
if (m_apFirstRun) {
System.out.println("Default IterativeRobot.autonomousPeriodic() method... Overload me!");
apFirstRun = false;
m_apFirstRun = false;
}
Timer.delay(0.001);
}
private boolean tpFirstRun = true;
private boolean m_tpFirstRun = true;
/**
* Periodic code for teleop mode should go here.
*
* Users should override this method for code which will be called
* periodically at a regular rate while the robot is in teleop mode.
* <p>Users should override this method for code which will be called periodically at a regular
* rate while the robot is in teleop mode.
*/
public void teleopPeriodic() {
if (tpFirstRun) {
if (m_tpFirstRun) {
System.out.println("Default IterativeRobot.teleopPeriodic() method... Overload me!");
tpFirstRun = false;
m_tpFirstRun = false;
}
Timer.delay(0.001);
}
private boolean tmpFirstRun = true;
private boolean m_tmpFirstRun = true;
/**
* Periodic code for test mode should go here
* Periodic code for test mode should go here.
*
* Users should override this method for code which will be called
* periodically at a regular rate while the robot is in test mode.
* <p>Users should override this method for code which will be called periodically at a regular
* rate while the robot is in test mode.
*/
public void testPeriodic() {
if (tmpFirstRun) {
if (m_tmpFirstRun) {
System.out.println("Default IterativeRobot.testPeriodic() method... Overload me!");
tmpFirstRun = false;
m_tmpFirstRun = false;
}
}
}

View File

@@ -13,7 +13,7 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Texas Instruments / Vex Robotics Jaguar Speed Controller as a PWM device.
*$
*
* @see CANJaguar CANJaguar for CAN control
*/
public class Jaguar extends PWMSpeedController {
@@ -24,7 +24,7 @@ public class Jaguar extends PWMSpeedController {
private void initJaguar() {
/*
* Input profile defined by Luminary Micro.
*$
*
* Full reverse ranges from 0.671325ms to 0.6972211ms Proportional reverse
* ranges from 0.6972211ms to 1.4482078ms Neutral ranges from 1.4482078ms to
* 1.5517922ms Proportional forward ranges from 1.5517922ms to 2.3027789ms
@@ -42,8 +42,8 @@ public class Jaguar extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the Jaguar is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the Jaguar is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Jaguar(final int channel) {
super(channel);

View File

@@ -7,16 +7,15 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
/**
* Handle input from standard Joysticks connected to the Driver Station. This
* class handles standard input that comes from the Driver Station. Each time a
* value is requested the most recent value is returned. There is a single class
* instance for each joystick and the mapping of ports to hardware buttons
* depends on the code in the driver station.
* Handle input from standard Joysticks connected to the Driver Station. This class handles standard
* input that comes from the Driver Station. Each time a value is requested the most recent value is
* returned. There is a single class instance for each joystick and the mapping of ports to hardware
* buttons depends on the code in the driver station.
*/
public class Joystick extends GenericHID {
@@ -31,11 +30,12 @@ public class Joystick extends GenericHID {
/**
* Represents an analog axis on a joystick.
*/
public static class AxisType {
public static final class AxisType {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kX_val = 0;
static final int kY_val = 1;
@@ -44,27 +44,27 @@ public class Joystick extends GenericHID {
static final int kThrottle_val = 4;
static final int kNumAxis_val = 5;
/**
* axis: x-axis
* axis: x-axis.
*/
public static final AxisType kX = new AxisType(kX_val);
/**
* axis: y-axis
* axis: y-axis.
*/
public static final AxisType kY = new AxisType(kY_val);
/**
* axis: z-axis
* axis: z-axis.
*/
public static final AxisType kZ = new AxisType(kZ_val);
/**
* axis: twist
* axis: twist.
*/
public static final AxisType kTwist = new AxisType(kTwist_val);
/**
* axis: throttle
* axis: throttle.
*/
public static final AxisType kThrottle = new AxisType(kThrottle_val);
/**
* axis: number of axis
* axis: number of axis.
*/
public static final AxisType kNumAxis = new AxisType(kNumAxis_val);
@@ -74,27 +74,28 @@ public class Joystick extends GenericHID {
}
/**
* Represents a digital button on the JoyStick
* Represents a digital button on the JoyStick.
*/
public static class ButtonType {
public static final class ButtonType {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kTrigger_val = 0;
static final int kTop_val = 1;
static final int kNumButton_val = 2;
/**
* button: trigger
* button: trigger.
*/
public static final ButtonType kTrigger = new ButtonType((kTrigger_val));
/**
* button: top button
* button: top button.
*/
public static final ButtonType kTop = new ButtonType(kTop_val);
/**
* button: num button types
* button: num button types.
*/
public static final ButtonType kNumButton = new ButtonType((kNumButton_val));
@@ -105,22 +106,23 @@ public class Joystick extends GenericHID {
/**
* Represents a rumble output on the JoyStick
* Represents a rumble output on the JoyStick.
*/
public static class RumbleType {
public static final class RumbleType {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kLeftRumble_val = 0;
static final int kRightRumble_val = 1;
/**
* Left Rumble
* Left Rumble.
*/
public static final RumbleType kLeftRumble = new RumbleType((kLeftRumble_val));
/**
* Right Rumble
* Right Rumble.
*/
public static final RumbleType kRightRumble = new RumbleType(kRightRumble_val);
@@ -129,7 +131,7 @@ public class Joystick extends GenericHID {
}
}
private DriverStation m_ds;
private final DriverStation m_ds;
private final int m_port;
private final byte[] m_axes;
private final byte[] m_buttons;
@@ -138,11 +140,10 @@ public class Joystick extends GenericHID {
private short m_rightRumble;
/**
* Construct an instance of a joystick. The joystick index is the usb port on
* the drivers station.
* Construct an instance of a joystick. The joystick index is the usb port on the drivers
* station.
*
* @param port The port on the driver station that the joystick is plugged
* into.
* @param port The port on the driver station that the joystick is plugged into.
*/
public Joystick(final int port) {
this(port, AxisType.kNumAxis.value, ButtonType.kNumButton.value);
@@ -162,12 +163,11 @@ public class Joystick extends GenericHID {
/**
* Protected version of the constructor to be called by sub-classes.
*
* This constructor allows the subclass to configure the number of constants
* for axes and buttons.
* <p>This constructor allows the subclass to configure the number of constants for axes and
* buttons.
*
* @param port The port on the driver station that the joystick is plugged
* into.
* @param numAxisTypes The number of axis types in the enum.
* @param port The port on the driver station that the joystick is plugged into.
* @param numAxisTypes The number of axis types in the enum.
* @param numButtonTypes The number of button types in the enum.
*/
protected Joystick(int port, int numAxisTypes, int numButtonTypes) {
@@ -178,8 +178,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the X value of the joystick. This depends on the mapping of the
* joystick connected to the current port.
* Get the X value of the joystick. This depends on the mapping of the joystick connected to the
* current port.
*
* @param hand Unused
* @return The X value of the joystick.
@@ -189,8 +189,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the Y value of the joystick. This depends on the mapping of the
* joystick connected to the current port.
* Get the Y value of the joystick. This depends on the mapping of the joystick connected to the
* current port.
*
* @param hand Unused
* @return The Y value of the joystick.
@@ -200,8 +200,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the Z value of the joystick. This depends on the mapping of the
* joystick connected to the current port.
* Get the Z value of the joystick. This depends on the mapping of the joystick connected to the
* current port.
*
* @param hand Unused
* @return The Z value of the joystick.
@@ -211,8 +211,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the twist value of the current joystick. This depends on the mapping of
* the joystick connected to the current port.
* Get the twist value of the current joystick. This depends on the mapping of the joystick
* connected to the current port.
*
* @return The Twist value of the joystick.
*/
@@ -221,8 +221,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the throttle value of the current joystick. This depends on the mapping
* of the joystick connected to the current port.
* Get the throttle value of the current joystick. This depends on the mapping of the joystick
* connected to the current port.
*
* @return The Throttle value of the joystick.
*/
@@ -243,9 +243,8 @@ public class Joystick extends GenericHID {
/**
* For the current joystick, return the axis determined by the argument.
*
* This is for cases where the joystick axis is returned programatically,
* otherwise one of the previous functions would be preferable (for example
* getX()).
* <p>This is for cases where the joystick axis is returned programatically, otherwise one of the
* previous functions would be preferable (for example getX()).
*
* @param axis The axis to read.
* @return The value of the axis.
@@ -268,7 +267,7 @@ public class Joystick extends GenericHID {
}
/**
* For the current joystick, return the number of axis
* For the current joystick, return the number of axis.
*/
public int getAxisCount() {
return m_ds.getStickAxisCount(m_port);
@@ -277,10 +276,10 @@ public class Joystick extends GenericHID {
/**
* Read the state of the trigger on the joystick.
*
* Look up which button has been assigned to the trigger and read its state.
* <p>Look up which button has been assigned to the trigger and read its state.
*
* @param hand This parameter is ignored for the Joystick class and is only
* here to complete the GenericHID interface.
* @param hand This parameter is ignored for the Joystick class and is only here to complete the
* GenericHID interface.
* @return The state of the trigger.
*/
public boolean getTrigger(Hand hand) {
@@ -290,10 +289,10 @@ public class Joystick extends GenericHID {
/**
* Read the state of the top button on the joystick.
*
* Look up which button has been assigned to the top and read its state.
* <p>Look up which button has been assigned to the top and read its state.
*
* @param hand This parameter is ignored for the Joystick class and is only
* here to complete the GenericHID interface.
* @param hand This parameter is ignored for the Joystick class and is only here to complete the
* GenericHID interface.
* @return The state of the top button.
*/
public boolean getTop(Hand hand) {
@@ -301,11 +300,11 @@ public class Joystick extends GenericHID {
}
/**
* This is not supported for the Joystick. This method is only here to
* complete the GenericHID interface.
* This is not supported for the Joystick. This method is only here to complete the GenericHID
* interface.
*
* @param hand This parameter is ignored for the Joystick class and is only
* here to complete the GenericHID interface.
* @param hand This parameter is ignored for the Joystick class and is only here to complete the
* GenericHID interface.
* @return The state of the bumper (always false)
*/
public boolean getBumper(Hand hand) {
@@ -313,9 +312,9 @@ public class Joystick extends GenericHID {
}
/**
* Get the button value (starting at button 1)
* Get the button value (starting at button 1).
*
* The appropriate button is returned as a boolean value.
* <p>The appropriate button is returned as a boolean value.
*
* @param button The button number to be read (starting at 1).
* @return The state of the button.
@@ -325,7 +324,7 @@ public class Joystick extends GenericHID {
}
/**
* For the current joystick, return the number of buttons
* For the current joystick, return the number of buttons.
*/
public int getButtonCount() {
return m_ds.getStickButtonCount(m_port);
@@ -334,8 +333,8 @@ public class Joystick extends GenericHID {
/**
* Get the angle in degrees of a POV on the joystick.
*
* The POV angles start at 0 in the up direction, and increase
* clockwise (eg right is 90, upper-left is 315).
* <p>The POV angles start at 0 in the up direction, and increase clockwise (eg right is 90,
* upper-left is 315).
*
* @param pov The index of the POV to read (starting at 0)
* @return the angle of the POV in degrees, or -1 if the POV is not pressed.
@@ -345,7 +344,7 @@ public class Joystick extends GenericHID {
}
/**
* For the current joystick, return the number of POVs
* For the current joystick, return the number of POVs.
*/
public int getPOVCount() {
return m_ds.getStickPOVCount(m_port);
@@ -354,7 +353,7 @@ public class Joystick extends GenericHID {
/**
* Get buttons based on an enumerated type.
*
* The button type will be looked up in the list of buttons and then read.
* <p>The button type will be looked up in the list of buttons and then read.
*
* @param button The type of button to read.
* @return The state of the button.
@@ -371,8 +370,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the magnitude of the direction vector formed by the joystick's current
* position relative to its origin
* Get the magnitude of the direction vector formed by the joystick's current position relative to
* its origin.
*
* @return The magnitude of the direction vector
*/
@@ -381,8 +380,7 @@ public class Joystick extends GenericHID {
}
/**
* Get the direction of the vector formed by the joystick and its origin in
* radians
* Get the direction of the vector formed by the joystick and its origin in radians.
*
* @return The direction of the vector in radians
*/
@@ -391,11 +389,9 @@ public class Joystick extends GenericHID {
}
/**
* Get the direction of the vector formed by the joystick and its origin in
* degrees
* Get the direction of the vector formed by the joystick and its origin in degrees.
*
* uses acos(-1) to represent Pi due to absence of readily accessable Pi
* constant in C++
* <p>Uses acos(-1) to represent Pi due to absence of readily accessable Pi constant in C++
*
* @return The direction of the vector in degrees
*/
@@ -416,7 +412,7 @@ public class Joystick extends GenericHID {
/**
* Set the channel associated with a specified axis.
*
* @param axis The axis to set the channel for.
* @param axis The axis to set the channel for.
* @param channel The channel to set the axis to.
*/
public void setAxisChannel(AxisType axis, int channel) {
@@ -425,9 +421,8 @@ public class Joystick extends GenericHID {
/**
* Get the value of isXbox for the current joystick.
*$
* @return A boolean that is true if the controller is an xbox
* controller.
*
* @return A boolean that is true if the controller is an xbox controller.
*/
public boolean getIsXbox() {
return m_ds.getJoystickIsXbox(m_port);
@@ -435,7 +430,7 @@ public class Joystick extends GenericHID {
/**
* Get the HID type of the current joystick.
*$
*
* @return The HID type value of the current joystick.
*/
public int getType() {
@@ -444,7 +439,7 @@ public class Joystick extends GenericHID {
/**
* Get the name of the current joystick.
*$
*
* @return The name of the current joystick.
*/
public String getName() {
@@ -452,30 +447,32 @@ public class Joystick extends GenericHID {
}
/**
* Set the rumble output for the joystick. The DS currently supports 2 rumble
* values, left rumble and right rumble
*$
* @param type Which rumble value to set
* Set the rumble output for the joystick. The DS currently supports 2 rumble values, left rumble
* and right rumble.
*
* @param type Which rumble value to set
* @param value The normalized value (0 to 1) to set the rumble to
*/
public void setRumble(RumbleType type, float value) {
if (value < 0)
if (value < 0) {
value = 0;
else if (value > 1)
} else if (value > 1) {
value = 1;
if (type.value == RumbleType.kLeftRumble_val)
}
if (type.value == RumbleType.kLeftRumble_val) {
m_leftRumble = (short) (value * 65535);
else
} else {
m_rightRumble = (short) (value * 65535);
}
FRCNetworkCommunicationsLibrary.HALSetJoystickOutputs((byte) m_port, m_outputs, m_leftRumble,
m_rightRumble);
}
/**
* Set a single HID output value for the joystick.
*$
*
* @param outputNumber The index of the output to set (1-32)
* @param value The value to set the output to
* @param value The value to set the output to
*/
public void setOutput(int outputNumber, boolean value) {
@@ -486,7 +483,7 @@ public class Joystick extends GenericHID {
/**
* Set all HID output values for the joystick.
*$
*
* @param value The 32 bit output value (1 bit for each output)
*/
public void setOutputs(int value) {

View File

@@ -7,48 +7,43 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.Timer;
/**
* The MotorSafetyHelper object is constructed for every object that wants to
* implement the Motor Safety protocol. The helper object has the code to
* actually do the timing and call the motors Stop() method when the timeout
* expires. The motor object is expected to call the Feed() method whenever the
* motors value is updated.
* The MotorSafetyHelper object is constructed for every object that wants to implement the Motor
* Safety protocol. The helper object has the code to actually do the timing and call the motors
* Stop() method when the timeout expires. The motor object is expected to call the Feed() method
* whenever the motors value is updated.
*
* @author brad
*/
public class MotorSafetyHelper {
public final class MotorSafetyHelper {
double m_expiration;
boolean m_enabled;
double m_stopTime;
MotorSafety m_safeObject;
MotorSafetyHelper m_nextHelper;
static MotorSafetyHelper m_headHelper = null;
private double m_expiration;
private boolean m_enabled;
private double m_stopTime;
private final MotorSafety m_safeObject;
private final MotorSafetyHelper m_nextHelper;
private static MotorSafetyHelper headHelper = null;
/**
* The constructor for a MotorSafetyHelper object. The helper object is
* constructed for every object that wants to implement the Motor Safety
* protocol. The helper object has the code to actually do the timing and call
* the motors Stop() method when the timeout expires. The motor object is
* expected to call the Feed() method whenever the motors value is updated.
* The constructor for a MotorSafetyHelper object. The helper object is constructed for every
* object that wants to implement the Motor Safety protocol. The helper object has the code to
* actually do the timing and call the motors Stop() method when the timeout expires. The motor
* object is expected to call the Feed() method whenever the motors value is updated.
*
* @param safeObject a pointer to the motor object implementing MotorSafety.
* This is used to call the Stop() method on the motor.
* @param safeObject a pointer to the motor object implementing MotorSafety. This is used to call
* the Stop() method on the motor.
*/
public MotorSafetyHelper(MotorSafety safeObject) {
m_safeObject = safeObject;
m_enabled = false;
m_expiration = MotorSafety.DEFAULT_SAFETY_EXPIRATION;
m_stopTime = Timer.getFPGATimestamp();
m_nextHelper = m_headHelper;
m_headHelper = this;
m_nextHelper = headHelper;
headHelper = this;
}
/**
* Feed the motor safety object. Resets the timer on this object that is used
* to do the timeouts.
* Feed the motor safety object. Resets the timer on this object that is used to do the timeouts.
*/
public void feed() {
m_stopTime = Timer.getFPGATimestamp() + m_expiration;
@@ -56,7 +51,7 @@ public class MotorSafetyHelper {
/**
* Set the expiration time for the corresponding motor safety object.
*$
*
* @param expirationTime The timeout value in seconds.
*/
public void setExpiration(double expirationTime) {
@@ -65,7 +60,7 @@ public class MotorSafetyHelper {
/**
* Retrieve the timeout value for the corresponding motor safety object.
*$
*
* @return the timeout value in seconds.
*/
public double getExpiration() {
@@ -74,34 +69,34 @@ public class MotorSafetyHelper {
/**
* Determine of the motor is still operating or has timed out.
*$
* @return a true value if the motor is still operating normally and hasn't
* timed out.
*
* @return a true value if the motor is still operating normally and hasn't timed out.
*/
public boolean isAlive() {
return !m_enabled || m_stopTime > Timer.getFPGATimestamp();
}
/**
* Check if this motor has exceeded its timeout. This method is called
* periodically to determine if this motor has exceeded its timeout value. If
* it has, the stop method is called, and the motor is shut down until its
* value is updated again.
* Check if this motor has exceeded its timeout. This method is called periodically to determine
* if this motor has exceeded its timeout value. If it has, the stop method is called, and the
* motor is shut down until its value is updated again.
*/
public void check() {
if (!m_enabled || RobotState.isDisabled() || RobotState.isTest())
if (!m_enabled || RobotState.isDisabled() || RobotState.isTest()) {
return;
}
if (m_stopTime < Timer.getFPGATimestamp()) {
DriverStation.reportError(m_safeObject.getDescription() + "... Output not updated often enough.", false);
DriverStation.reportError(m_safeObject.getDescription() + "... Output not updated often "
+ "enough.", false);
m_safeObject.stopMotor();
}
}
/**
* Enable/disable motor safety for this device Turn on and off the motor
* safety option for this PWM object.
*$
* Enable/disable motor safety for this device Turn on and off the motor safety option for this
* PWM object.
*
* @param enabled True if motor safety is enforced for this object
*/
public void setSafetyEnabled(boolean enabled) {
@@ -109,9 +104,9 @@ public class MotorSafetyHelper {
}
/**
* Return the state of the motor safety enabled flag Return if the motor
* safety is currently enabled for this devicce.
*$
* Return the state of the motor safety enabled flag Return if the motor safety is currently
* enabled for this devicce.
*
* @return True if motor safety is enforced for this device
*/
public boolean isSafetyEnabled() {
@@ -119,13 +114,13 @@ public class MotorSafetyHelper {
}
/**
* Check the motors to see if any have timed out. This static method is called
* periodically to poll all the motors and stop any that have timed out.
* Check the motors to see if any have timed out. This static method is called periodically to
* poll all the motors and stop any that have timed out.
*/
// TODO: these should be synchronized with the setting methods in case it's
// called from a different thread
public static void checkMotors() {
for (MotorSafetyHelper msh = m_headHelper; msh != null; msh = msh.m_nextHelper) {
for (MotorSafetyHelper msh = headHelper; msh != null; msh = msh.m_nextHelper) {
msh.check();
}
}

View File

@@ -7,18 +7,15 @@
package edu.wpi.first.wpilibj;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.lang.Runtime;
import edu.wpi.first.wpilibj.hal.NotifierJNI;
import edu.wpi.first.wpilibj.Utility;
public class Notifier {
private static class Process implements NotifierJNI.NotifierJNIHandlerFunction {
// The lock for the process information.
private ReentrantLock m_processLock = new ReentrantLock();
private final ReentrantLock m_processLock = new ReentrantLock();
// The C pointer to the notifier object. We don't use it directly, it is
// just passed to the JNI bindings.
private long m_notifier;
@@ -37,7 +34,7 @@ public class Notifier {
// completed. This is only relevant if the handler takes a very long time
// to complete (or the period is very short) and when everything is being
// destructed.
private ReentrantLock m_handlerLock = new ReentrantLock();
private final ReentrantLock m_handlerLock = new ReentrantLock();
public Process(Runnable run) {
m_handler = run;
@@ -45,10 +42,10 @@ public class Notifier {
}
@Override
@SuppressWarnings("NoFinalizer")
protected void finalize() {
NotifierJNI.cleanNotifier(m_notifier);
m_handlerLock.lock();
m_handlerLock = null;
}
/**
@@ -59,8 +56,8 @@ public class Notifier {
}
/**
* Handler which is called by the HAL library; it handles the subsequent
* calling of the user handler.
* Handler which is called by the HAL library; it handles the subsequent calling of the user
* handler.
*/
@Override
public void apply(long time) {
@@ -81,7 +78,7 @@ public class Notifier {
synchronized (m_processLock) {
m_periodic = periodic;
m_period = period;
m_expirationTime = Utility.getFPGATime() * 1e-6 + m_period;
m_expirationTime = Utility.getFPGATime() * 1e-6 + period;
updateAlarm();
}
}
@@ -101,16 +98,16 @@ public class Notifier {
/**
* Create a Notifier for timer event notification.
*
* @param run The handler that is called at the notification time which is set
* using StartSingle or StartPeriodic.
* @param run The handler that is called at the notification time which is set using StartSingle
* or StartPeriodic.
*/
public Notifier(Runnable run) {
m_process = new Process(run);
}
/**
* Register for single event notification. A timer event is queued for a
* single event after the specified delay.
* Register for single event notification. A timer event is queued for a single event after the
* specified delay.
*
* @param delay Seconds to wait before the handler is called.
*/
@@ -119,22 +116,21 @@ public class Notifier {
}
/**
* Register for periodic event notification. A timer event is queued for
* periodic event notification. Each time the interrupt occurs, the event will
* be immediately requeued for the same time interval.
* Register for periodic event notification. A timer event is queued for periodic event
* notification. Each time the interrupt occurs, the event will be immediately requeued for the
* same time interval.
*
* @param period Period in seconds to call the handler starting one period
* after the call to this method.
* @param period Period in seconds to call the handler starting one period after the call to this
* method.
*/
public void startPeriodic(double period) {
m_process.start(period, true);
}
/**
* Stop timer events from occuring. Stop any repeating timer events from
* occuring. This will also remove any single notification events from the
* queue. If a timer-based call to the registered handler is in progress, this
* function will block until the handler call is complete.
* Stop timer events from occuring. Stop any repeating timer events from occuring. This will also
* remove any single notification events from the queue. If a timer-based call to the registered
* handler is in progress, this function will block until the handler call is complete.
*/
public void stop() {
m_process.stop();

View File

@@ -9,27 +9,24 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.PWMJNI;
import edu.wpi.first.wpilibj.hal.DIOJNI;
import edu.wpi.first.wpilibj.hal.PWMJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Class implements the PWM generation in the FPGA.
*
* The values supplied as arguments for PWM outputs range from -1.0 to 1.0. They
* are mapped to the hardware dependent values, in this case 0-2000 for the
* FPGA. Changes are immediately sent to the FPGA, and the update occurs at the
* next FPGA cycle. There is no delay.
* <p>The values supplied as arguments for PWM outputs range from -1.0 to 1.0. They are mapped to
* the hardware dependent values, in this case 0-2000 for the FPGA. Changes are immediately sent to
* the FPGA, and the update occurs at the next FPGA cycle. There is no delay.
*
* As of revision 0.1.10 of the FPGA, the FPGA interprets the 0-2000 values as
* follows: - 2000 = maximum pulse width - 1999 to 1001 = linear scaling from
* "full forward" to "center" - 1000 = center value - 999 to 2 = linear scaling
* from "center" to "full reverse" - 1 = minimum pulse width (currently .5ms) -
* 0 = disabled (i.e. PWM output is held low)
* <p>As of revision 0.1.10 of the FPGA, the FPGA interprets the 0-2000 values as follows: - 2000 =
* maximum pulse width - 1999 to 1001 = linear scaling from "full forward" to "center" - 1000 =
* center value - 999 to 2 = linear scaling from "center" to "full reverse" - 1 = minimum pulse
* width (currently .5ms) - 0 = disabled (i.e. PWM output is held low)
*/
public class PWM extends SensorBase implements LiveWindowSendable {
/**
@@ -38,22 +35,23 @@ public class PWM extends SensorBase implements LiveWindowSendable {
public static class PeriodMultiplier {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int k1X_val = 1;
static final int k2X_val = 2;
static final int k4X_val = 4;
/**
* Period Multiplier: don't skip pulses
* Period Multiplier: don't skip pulses.
*/
public static final PeriodMultiplier k1X = new PeriodMultiplier(k1X_val);
/**
* Period Multiplier: skip every other pulse
* Period Multiplier: skip every other pulse.
*/
public static final PeriodMultiplier k2X = new PeriodMultiplier(k2X_val);
/**
* Period Multiplier: skip three out of four pulses
* Period Multiplier: skip three out of four pulses.
*/
public static final PeriodMultiplier k4X = new PeriodMultiplier(k4X_val);
@@ -64,55 +62,55 @@ public class PWM extends SensorBase implements LiveWindowSendable {
private int m_channel;
private long m_port;
/**
* kDefaultPwmPeriod is in ms
* kDefaultPwmPeriod is in ms.
*
* - 20ms periods (50 Hz) are the "safest" setting in that this works for all
* devices - 20ms periods seem to be desirable for Vex Motors - 20ms periods
* are the specified period for HS-322HD servos, but work reliably down to
* 10.0 ms; starting at about 8.5ms, the servo sometimes hums and get hot; by
* 5.0ms the hum is nearly continuous - 10ms periods work well for Victor 884
* - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
* controllers. Due to the shipping firmware on the Jaguar, we can't run the
* update period less than 5.05 ms.
* <p>- 20ms periods (50 Hz) are the "safest" setting in that this works for all devices - 20ms
* periods seem to be desirable for Vex Motors - 20ms periods are the specified period for
* HS-322HD servos, but work reliably down to 10.0 ms; starting at about 8.5ms, the servo
* sometimes hums and get hot; by 5.0ms the hum is nearly continuous - 10ms periods work well for
* Victor 884 - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
* controllers. Due to the shipping firmware on the Jaguar, we can't run the update period less
* than 5.05 ms.
*
* kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period
* scaling is implemented as an output squelch to get longer periods for old
* devices.
* <p>kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period scaling is implemented
* as an output squelch to get longer periods for old devices.
*/
protected static final double kDefaultPwmPeriod = 5.05;
/**
* kDefaultPwmCenter is the PWM range center in ms
* kDefaultPwmCenter is the PWM range center in ms.
*/
protected static final double kDefaultPwmCenter = 1.5;
/**
* kDefaultPWMStepsDown is the number of PWM steps below the centerpoint
* kDefaultPWMStepsDown is the number of PWM steps below the centerpoint.
*/
protected static final int kDefaultPwmStepsDown = 1000;
public static final int kPwmDisabled = 0;
boolean m_eliminateDeadband;
int m_maxPwm;
int m_deadbandMaxPwm;
private boolean m_eliminateDeadband;
private int m_maxPwm;
private int m_deadbandMaxPwm;
/*
* Intentionally package private
*/
int m_centerPwm;
int m_deadbandMinPwm;
int m_minPwm;
private int m_deadbandMinPwm;
private int m_minPwm;
/**
* Initialize PWMs given a channel.
*
* This method is private and is the common path for all the constructors for
* creating PWM instances. Checks channel value ranges and allocates the
* appropriate channel. The allocation is only done to help users ensure that
* they don't double assign channels.
*$
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the
* MXP port
* <p>This method is private and is the common path for all the constructors for creating PWM
* instances. Checks channel value ranges and allocates the appropriate channel. The allocation is
* only done to help users ensure that they don't double assign channels.
*
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the MXP port
*/
private void initPWM(final int channel) {
checkPWMChannel(channel);
m_channel = channel;
m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) m_channel));
m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) channel));
if (!PWMJNI.allocatePWMChannel(m_port)) {
throw new AllocationException("PWM channel " + channel + " is already allocated");
@@ -137,10 +135,12 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Free the PWM channel.
*
* Free the resource associated with the PWM channel and set the value to 0.
* <p>Free the resource associated with the PWM channel and set the value to 0.
*/
public void free() {
if (m_port == 0) return;
if (m_port == 0) {
return;
}
PWMJNI.setPWM(m_port, (short) 0);
PWMJNI.freePWMChannel(m_port);
PWMJNI.freeDIO(m_port);
@@ -150,30 +150,30 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Optionally eliminate the deadband from a speed controller.
*$
* @param eliminateDeadband If true, set the motor curve on the Jaguar to
* eliminate the deadband in the middle of the range. Otherwise, keep
* the full range without modifying any values.
*
* @param eliminateDeadband If true, set the motor curve on the Jaguar to eliminate the deadband
* in the middle of the range. Otherwise, keep the full range without
* modifying any values.
*/
public void enableDeadbandElimination(boolean eliminateDeadband) {
m_eliminateDeadband = eliminateDeadband;
}
/**
* Set the bounds on the PWM values. This sets the bounds on the PWM values
* for a particular each type of controller. The values determine the upper
* and lower speeds as well as the deadband bracket.
*$
* @deprecated Recommended to set bounds in ms using
* {@link #setBounds(double, double, double, double, double)}
* @param max The Minimum pwm value
* Set the bounds on the PWM values. This sets the bounds on the PWM values for a particular each
* type of controller. The values determine the upper and lower speeds as well as the deadband
* bracket.
*
* @param max The Minimum pwm value
* @param deadbandMax The high end of the deadband range
* @param center The center speed (off)
* @param center The center speed (off)
* @param deadbandMin The low end of the deadband range
* @param min The minimum pwm value
* @param min The minimum pwm value
* @deprecated Recommended to set bounds in ms using {@link #setBounds(double, double, double,
* double, double)}
*/
public void setBounds(final int max, final int deadbandMax, final int center,
final int deadbandMin, final int min) {
final int deadbandMin, final int min) {
m_maxPwm = max;
m_deadbandMaxPwm = deadbandMax;
m_centerPwm = center;
@@ -182,18 +182,18 @@ public class PWM extends SensorBase implements LiveWindowSendable {
}
/**
* Set the bounds on the PWM pulse widths. This sets the bounds on the PWM
* values for a particular type of controller. The values determine the upper
* and lower speeds as well as the deadband bracket.
*$
* @param max The max PWM pulse width in ms
* Set the bounds on the PWM pulse widths. This sets the bounds on the PWM values for a particular
* type of controller. The values determine the upper and lower speeds as well as the deadband
* bracket.
*
* @param max The max PWM pulse width in ms
* @param deadbandMax The high end of the deadband range pulse width in ms
* @param center The center (off) pulse width in ms
* @param center The center (off) pulse width in ms
* @param deadbandMin The low end of the deadband pulse width in ms
* @param min The minimum pulse width in ms
* @param min The minimum pulse width in ms
*/
protected void setBounds(double max, double deadbandMax, double center, double deadbandMin,
double min) {
double min) {
double loopTime =
DIOJNI.getLoopTiming() / (kSystemClockTicksPerMicrosecond * 1e3);
@@ -218,12 +218,11 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Set the PWM value based on a position.
*
* This is intended to be used by servos.
*
* @pre SetMaxPositivePwm() called.
* @pre SetMinNegativePwm() called.
* <p>This is intended to be used by servos.
*
* @param pos The position to set the servo between 0.0 and 1.0.
* @pre SetMaxPositivePwm() called.
* @pre SetMinNegativePwm() called.
*/
public void setPosition(double pos) {
if (pos < 0.0) {
@@ -244,12 +243,11 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Get the PWM value in terms of a position.
*
* This is intended to be used by servos.
*
* @pre SetMaxPositivePwm() called.
* @pre SetMinNegativePwm() called.
* <p>This is intended to be used by servos.
*
* @return The position the servo is set to between 0.0 and 1.0.
* @pre SetMaxPositivePwm() called.
* @pre SetMinNegativePwm() called.
*/
public double getPosition() {
int value = getRaw();
@@ -265,15 +263,14 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Set the PWM value based on a speed.
*
* This is intended to be used by speed controllers.
* <p>This is intended to be used by speed controllers.
*
* @param speed The speed to set the speed controller between -1.0 and 1.0.
* @pre SetMaxPositivePwm() called.
* @pre SetMinPositivePwm() called.
* @pre SetCenterPwm() called.
* @pre SetMaxNegativePwm() called.
* @pre SetMinNegativePwm() called.
*
* @param speed The speed to set the speed controller between -1.0 and 1.0.
*/
final void setSpeed(double speed) {
// clamp speed to be in the range 1.0 >= speed >= -1.0
@@ -289,10 +286,12 @@ public class PWM extends SensorBase implements LiveWindowSendable {
rawValue = getCenterPwm();
} else if (speed > 0.0) {
rawValue =
(int) (speed * ((double) getPositiveScaleFactor()) + ((double) getMinPositivePwm()) + 0.5);
(int) (speed * ((double) getPositiveScaleFactor())
+ ((double) getMinPositivePwm()) + 0.5);
} else {
rawValue =
(int) (speed * ((double) getNegativeScaleFactor()) + ((double) getMaxNegativePwm()) + 0.5);
(int) (speed * ((double) getNegativeScaleFactor())
+ ((double) getMaxNegativePwm()) + 0.5);
}
// send the computed pwm value to the FPGA
@@ -302,14 +301,13 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Get the PWM value in terms of speed.
*
* This is intended to be used by speed controllers.
* <p>This is intended to be used by speed controllers.
*
* @return The most recently set speed between -1.0 and 1.0.
* @pre SetMaxPositivePwm() called.
* @pre SetMinPositivePwm() called.
* @pre SetMaxNegativePwm() called.
* @pre SetMinNegativePwm() called.
*
* @return The most recently set speed between -1.0 and 1.0.
*/
public double getSpeed() {
int value = getRaw();
@@ -329,7 +327,7 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Set the PWM value directly to the hardware.
*
* Write a raw value to a PWM channel.
* <p>Write a raw value to a PWM channel.
*
* @param value Raw PWM value. Range 0 - 255.
*/
@@ -340,7 +338,7 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Get the PWM value directly from the hardware.
*
* Read a raw value from a PWM channel.
* <p>Read a raw value from a PWM channel.
*
* @return Raw PWM control value. Range: 0 - 255.
*/
@@ -411,56 +409,47 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/*
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Speed Controller";
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getSpeed());
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
setSpeed(0); // Stop for safety
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
setSpeed(((Double) value).doubleValue());
setSpeed((Double) value);
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
setSpeed(0); // Stop for safety
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -11,13 +11,13 @@ package edu.wpi.first.wpilibj;
* Common base class for all PWM Speed Controllers.
*/
public abstract class PWMSpeedController extends SafePWM implements SpeedController {
private boolean isInverted = false;
private boolean m_isInverted = false;
/**
* Constructor.
*
* @param channel The PWM channel that the controller is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the controller is attached to. 0-9 are on-board, 10-19 are
* on the MXP port
*/
protected PWMSpeedController(int channel) {
super(channel);
@@ -26,53 +26,54 @@ public abstract class PWMSpeedController extends SafePWM implements SpeedControl
/**
* Set the PWM value.
*
* <p>The PWM value is set using a range of -1.0 to 1.0, appropriately scaling the value for the
* FPGA.
*
* @param speed The speed to set. Value should be between -1.0 and 1.0.
* @param syncGroup The update group to add this Set() to, pending UpdateSyncGroup(). If 0, update
* immediately.
* @deprecated For compatibility with CANJaguar
*
* The PWM value is set using a range of -1.0 to 1.0,
* appropriately scaling the value for the FPGA.
*
* @param speed The speed to set. Value should be between -1.0 and 1.0.
* @param syncGroup The update group to add this Set() to, pending
* UpdateSyncGroup(). If 0, update immediately.
*/
@Deprecated
@Override
public void set(double speed, byte syncGroup) {
setSpeed(isInverted ? -speed : speed);
setSpeed(m_isInverted ? -speed : speed);
Feed();
}
/**
* Set the PWM value.
*
* The PWM value is set using a range of -1.0 to 1.0, appropriately scaling
* the value for the FPGA.
* <p>The PWM value is set using a range of -1.0 to 1.0, appropriately scaling the value for the
* FPGA.
*
* @param speed The speed value between -1.0 and 1.0 to set.
*/
@Override
public void set(double speed) {
setSpeed(isInverted ? -speed : speed);
setSpeed(m_isInverted ? -speed : speed);
Feed();
}
/**
* Common interface for inverting direction of a speed controller
* Common interface for inverting direction of a speed controller.
*
* @param isInverted The state of inversion true is inverted
*/
@Override
public void setInverted(boolean isInverted) {
this.isInverted = isInverted;
m_isInverted = isInverted;
}
/**
* Common interface for the inverting direction of a speed controller.
*
* @return isInverted The state of inversion, true is inverted.
*
*/
@Override
public boolean getInverted() {
return this.isInverted;
return m_isInverted;
}
/**
@@ -80,6 +81,7 @@ public abstract class PWMSpeedController extends SafePWM implements SpeedControl
*
* @return The most recently set value for the PWM between -1.0 and 1.0.
*/
@Override
public double get() {
return getSpeed();
}
@@ -89,7 +91,8 @@ public abstract class PWMSpeedController extends SafePWM implements SpeedControl
*
* @param output Write out the PWM value as was found in the PIDController
*/
@Override
public void pidWrite(double output) {
set(output);
}
}
}

View File

@@ -8,35 +8,34 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.hal.PDPJNI;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Class for getting voltage, current, temperature, power and energy from the
* CAN PDP.
*$
* Class for getting voltage, current, temperature, power and energy from the CAN PDP.
*
* @author Thomas Clark
*/
public class PowerDistributionPanel extends SensorBase implements LiveWindowSendable {
int m_module;
private final int m_module;
@SuppressWarnings("JavadocMethod")
public PowerDistributionPanel(int module) {
m_module = module;
checkPDPModule(m_module);
PDPJNI.initializePDP(m_module);
checkPDPModule(module);
PDPJNI.initializePDP(module);
}
@SuppressWarnings("JavadocMethod")
public PowerDistributionPanel() {
this(0);
}
/**
* Query the input voltage of the PDP
*$
* Query the input voltage of the PDP.
*
* @return The voltage of the PDP in volts
*/
public double getVoltage() {
@@ -44,8 +43,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the temperature of the PDP
*$
* Query the temperature of the PDP.
*
* @return The temperature of the PDP in degrees Celsius
*/
public double getTemperature() {
@@ -53,8 +52,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the current of a single channel of the PDP
*$
* Query the current of a single channel of the PDP.
*
* @return The current of one of the PDP channels (channels 0-15) in Amperes
*/
public double getCurrent(int channel) {
@@ -66,8 +65,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the current of all monitored PDP channels (0-15)
*$
* Query the current of all monitored PDP channels (0-15).
*
* @return The current of all the channels in Amperes
*/
public double getTotalCurrent() {
@@ -75,8 +74,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the total power drawn from the monitored PDP channels
*$
* Query the total power drawn from the monitored PDP channels.
*
* @return the total power in Watts
*/
public double getTotalPower() {
@@ -84,8 +83,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the total energy drawn from the monitored PDP channels
*$
* Query the total energy drawn from the monitored PDP channels.
*
* @return the total energy in Joules
*/
public double getTotalEnergy() {
@@ -93,19 +92,20 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Reset the total energy to 0
* Reset the total energy to 0.
*/
public void resetTotalEnergy() {
PDPJNI.resetPDPTotalEnergy(m_module);
}
/**
* Clear all PDP sticky faults
* Clear all PDP sticky faults.
*/
public void clearStickyFaults() {
PDPJNI.clearPDPStickyFaults(m_module);
}
@Override
public String getSmartDashboardType() {
return "PowerDistributionPanel";
}
@@ -115,24 +115,18 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
*/
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Chan0", getCurrent(0));
@@ -157,15 +151,17 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* PDP doesn't have to do anything special when entering the LiveWindow.
* {@inheritDoc}
* PDP doesn't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* PDP doesn't have to do anything special when exiting the LiveWindow.
* {@inheritDoc}
* PDP doesn't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -17,49 +17,44 @@ import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.tables.TableKeyNotDefinedException;
/**
* The preferences class provides a relatively simple way to save important
* values to the RoboRIO to access the next time the RoboRIO is booted.
* The preferences class provides a relatively simple way to save important values to the RoboRIO to
* access the next time the RoboRIO is booted.
*
* <p>
* This class loads and saves from a file inside the RoboRIO. The user can not
* access the file directly, but may modify values at specific fields which will
* then be automatically saved to the file by the NetworkTables server.
* </p>
* <p> This class loads and saves from a file inside the RoboRIO. The user can not access the file
* directly, but may modify values at specific fields which will then be automatically saved to the
* file by the NetworkTables server. </p>
*
* <p>
* This class is thread safe.
* </p>
* <p> This class is thread safe. </p>
*
* <p>
* This will also interact with {@link NetworkTable} by creating a table called
* "Preferences" with all the key-value pairs.
* </p>
* <p> This will also interact with {@link NetworkTable} by creating a table called "Preferences"
* with all the key-value pairs. </p>
*
* @author Joe Grinstead
*/
public class Preferences {
/**
* The Preferences table name
* The Preferences table name.
*/
private static final String TABLE_NAME = "Preferences";
/**
* The singleton instance
* The singleton instance.
*/
private static Preferences instance;
/**
* The network table
* The network table.
*/
private NetworkTable table;
private final NetworkTable m_table;
/**
* Listener to set all Preferences values to persistent (for backwards
* compatibility with old dashboards).
* Listener to set all Preferences values to persistent (for backwards compatibility with old
* dashboards).
*/
private final ITableListener listener = new ITableListener() {
private final ITableListener m_listener = new ITableListener() {
@Override
public void valueChanged(ITable table, String key, Object value, boolean isNew) {
// unused
}
@Override
public void valueChangedEx(ITable table, String key, Object value, int flags) {
table.setPersistent(key);
@@ -71,7 +66,7 @@ public class Preferences {
*
* @return the preferences instance
*/
public synchronized static Preferences getInstance() {
public static synchronized Preferences getInstance() {
if (instance == null) {
instance = new Preferences();
}
@@ -82,17 +77,18 @@ public class Preferences {
* Creates a preference class.
*/
private Preferences() {
table = NetworkTable.getTable(TABLE_NAME);
table.addTableListenerEx(listener, ITable.NOTIFY_NEW | ITable.NOTIFY_IMMEDIATE);
m_table = NetworkTable.getTable(TABLE_NAME);
m_table.addTableListenerEx(m_listener, ITable.NOTIFY_NEW | ITable.NOTIFY_IMMEDIATE);
UsageReporting.report(tResourceType.kResourceType_Preferences, 0);
}
/**
* Gets the vector of keys.
* @return a vector of the keys
*/
public Vector getKeys() {
Vector<String> keys = new Vector<String>();
for (String key : table.getKeys()) {
for (String key : m_table.getKeys()) {
keys.add(key);
}
return keys;
@@ -101,71 +97,71 @@ public class Preferences {
/**
* Puts the given string into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
* @throws NullPointerException if value is null
*/
public void putString(String key, String value) {
if (value == null) {
throw new NullPointerException();
throw new NullPointerException("Value is null");
}
table.putString(key, value);
table.setPersistent(key);
m_table.putString(key, value);
m_table.setPersistent(key);
}
/**
* Puts the given int into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putInt(String key, int value) {
table.putNumber(key, value);
table.setPersistent(key);
m_table.putNumber(key, value);
m_table.setPersistent(key);
}
/**
* Puts the given double into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putDouble(String key, double value) {
table.putNumber(key, value);
table.setPersistent(key);
m_table.putNumber(key, value);
m_table.setPersistent(key);
}
/**
* Puts the given float into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putFloat(String key, float value) {
table.putNumber(key, value);
table.setPersistent(key);
m_table.putNumber(key, value);
m_table.setPersistent(key);
}
/**
* Puts the given boolean into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putBoolean(String key, boolean value) {
table.putBoolean(key, value);
table.setPersistent(key);
m_table.putBoolean(key, value);
m_table.setPersistent(key);
}
/**
* Puts the given long into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putLong(String key, long value) {
table.putNumber(key, value);
table.setPersistent(key);
m_table.putNumber(key, value);
m_table.setPersistent(key);
}
/**
@@ -175,106 +171,106 @@ public class Preferences {
* @return if there is a value at the given key
*/
public boolean containsKey(String key) {
return table.containsKey(key);
return m_table.containsKey(key);
}
/**
* Remove a preference
* Remove a preference.
*
* @param key the key
*/
public void remove(String key) {
table.delete(key);
m_table.delete(key);
}
/**
* Returns the string at the given key. If this table does not have a value
* for that position, then the given backup value will be returned.
* Returns the string at the given key. If this table does not have a value for that position,
* then the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
public String getString(String key, String backup) {
return table.getString(key, backup);
return m_table.getString(key, backup);
}
/**
* Returns the int at the given key. If this table does not have a value for
* that position, then the given backup value will be returned.
* Returns the int at the given key. If this table does not have a value for that position, then
* the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
public int getInt(String key, int backup) {
try {
return (int)table.getNumber(key);
} catch (TableKeyNotDefinedException e) {
return (int) m_table.getNumber(key);
} catch (TableKeyNotDefinedException ex) {
return backup;
}
}
/**
* Returns the double at the given key. If this table does not have a value
* for that position, then the given backup value will be returned.
* Returns the double at the given key. If this table does not have a value for that position,
* then the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
public double getDouble(String key, double backup) {
return table.getDouble(key, backup);
return m_table.getDouble(key, backup);
}
/**
* Returns the boolean at the given key. If this table does not have a value
* for that position, then the given backup value will be returned.
* Returns the boolean at the given key. If this table does not have a value for that position,
* then the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
public boolean getBoolean(String key, boolean backup) {
return table.getBoolean(key, backup);
return m_table.getBoolean(key, backup);
}
/**
* Returns the float at the given key. If this table does not have a value for
* that position, then the given backup value will be returned.
* Returns the float at the given key. If this table does not have a value for that position, then
* the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
public float getFloat(String key, float backup) {
try {
return (float)table.getNumber(key);
} catch (TableKeyNotDefinedException e) {
return (float) m_table.getNumber(key);
} catch (TableKeyNotDefinedException ex) {
return backup;
}
}
/**
* Returns the long at the given key. If this table does not have a value for
* that position, then the given backup value will be returned.
* Returns the long at the given key. If this table does not have a value for that position, then
* the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
public long getLong(String key, long backup) {
try {
return (long)table.getNumber(key);
} catch (TableKeyNotDefinedException e) {
return (long) m_table.getNumber(key);
} catch (TableKeyNotDefinedException ex) {
return backup;
}
}
/**
* This function is no longer required, as NetworkTables automatically
* saves persistent values (which all Preferences values are) periodically
* when running as a server.
* This function is no longer required, as NetworkTables automatically saves persistent values
* (which all Preferences values are) periodically when running as a server.
*
* @deprecated backwards compatibility shim
*/
public void save() {

View File

@@ -18,27 +18,28 @@ import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
import static java.util.Objects.requireNonNull;
/**
* Class for VEX Robotics Spike style relay outputs. Relays are intended to be
* connected to Spikes or similar relays. The relay channels controls a pair of
* pins that are either both off, one on, the other on, or both on. This
* translates into two Spike outputs at 0v, one at 12v and one at 0v, one at 0v
* and the other at 12v, or two Spike outputs at 12V. This allows off, full
* forward, or full reverse control of motors without variable speed. It also
* allows the two channels (forward and reverse) to be used independently for
* something that does not care about voltage polarity (like a solenoid).
* Class for VEX Robotics Spike style relay outputs. Relays are intended to be connected to Spikes
* or similar relays. The relay channels controls a pair of pins that are either both off, one on,
* the other on, or both on. This translates into two Spike outputs at 0v, one at 12v and one at 0v,
* one at 0v and the other at 12v, or two Spike outputs at 12V. This allows off, full forward, or
* full reverse control of motors without variable speed. It also allows the two channels (forward
* and reverse) to be used independently for something that does not care about voltage polarity
* (like a solenoid).
*/
public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable {
private MotorSafetyHelper m_safetyHelper;
/**
* This class represents errors in trying to set relay values contradictory to
* the direction to which the relay is set.
* This class represents errors in trying to set relay values contradictory to the direction to
* which the relay is set.
*/
public class InvalidValueException extends RuntimeException {
/**
* Create a new exception with the given message
* Create a new exception with the given message.
*
* @param message the message to pass with the exception
*/
@@ -50,30 +51,31 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
/**
* The state to drive a Relay to.
*/
public static enum Value {
public enum Value {
/**
* value: off
* value: off.
*/
kOff(0),
/**
* value: on for relays with defined direction
* value: on for relays with defined direction.
*/
kOn(1),
/**
* value: forward
* value: forward.
*/
kForward(2),
/**
* value: reverse
* value: reverse.
*/
kReverse(3);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
private Value(int value) {
Value(int value) {
this.value = value;
}
}
@@ -81,27 +83,28 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
/**
* The Direction(s) that a relay is configured to operate in.
*/
public static enum Direction {
public enum Direction {
/**
* direction: both directions are valid
* direction: both directions are valid.
*/
kBoth(0),
/**
* direction: Only forward is valid
* direction: Only forward is valid.
*/
kForward(1),
/**
* direction: only reverse is valid
* direction: only reverse is valid.
*/
kReverse(2);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
private Direction(int value) {
Direction(int value) {
this.value = value;
}
@@ -114,9 +117,9 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
private static Resource relayChannels = new Resource(kRelayChannels * 2);
/**
* Common relay initialization method. This code is common to all Relay
* constructors and initializes the relay and reserves all resources that need
* to be locked. Initially the relay is set to both lines at 0v.
* Common relay initialization method. This code is common to all Relay constructors and
* initializes the relay and reserves all resources that need to be locked. Initially the relay is
* set to both lines at 0v.
*/
private void initRelay() {
SensorBase.checkRelayChannel(m_channel);
@@ -129,7 +132,7 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
relayChannels.allocate(m_channel * 2 + 1);
UsageReporting.report(tResourceType.kResourceType_Relay, m_channel + 128);
}
} catch (CheckedAllocationException e) {
} catch (CheckedAllocationException ex) {
throw new AllocationException("Relay channel " + m_channel + " is already allocated");
}
@@ -144,14 +147,12 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
/**
* Relay constructor given a channel.
*
* @param channel The channel number for this relay (0 - 3).
* @param channel The channel number for this relay (0 - 3).
* @param direction The direction that the Relay object will control.
*/
public Relay(final int channel, Direction direction) {
if (direction == null)
throw new NullPointerException("Null Direction was given");
m_channel = channel;
m_direction = direction;
m_direction = requireNonNull( direction, "Null Direction was given");
initRelay();
set(Value.kOff);
}
@@ -185,15 +186,13 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
/**
* Set the relay state.
*
* Valid values depend on which directions of the relay are controlled by the
* object.
* <p>Valid values depend on which directions of the relay are controlled by the object.
*
* When set to kBothDirections, the relay can be set to any of the four
* states: 0v-0v, 12v-0v, 0v-12v, 12v-12v
* <p>When set to kBothDirections, the relay can be set to any of the four states: 0v-0v, 12v-0v,
* 0v-12v, 12v-12v
*
* When set to kForwardOnly or kReverseOnly, you can specify the constant for
* the direction or you can simply specify kOff_val and kOn_val. Using only
* kOff_val and kOn_val is recommended.
* <p>When set to kForwardOnly or kReverseOnly, you can specify the constant for the direction or
* you can simply specify kOff_val and kOn_val. Using only kOff_val and kOn_val is recommended.
*
* @param value The state to set the relay.
*/
@@ -216,8 +215,10 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
break;
case kForward:
if (m_direction == Direction.kReverse)
throw new InvalidValueException("A relay configured for reverse cannot be set to forward");
if (m_direction == Direction.kReverse) {
throw new InvalidValueException("A relay configured for reverse cannot be set to "
+ "forward");
}
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
RelayJNI.setRelayForward(m_port, true);
}
@@ -226,8 +227,10 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
break;
case kReverse:
if (m_direction == Direction.kForward)
throw new InvalidValueException("A relay configured for forward cannot be set to reverse");
if (m_direction == Direction.kForward) {
throw new InvalidValueException("A relay configured for forward cannot be set to "
+ "reverse");
}
if (m_direction == Direction.kBoth) {
RelayJNI.setRelayForward(m_port, false);
}
@@ -241,11 +244,11 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
/**
* Get the Relay State
* Get the Relay State.
*
* Gets the current state of the relay.
* <p>Gets the current state of the relay.
*
* When set to kForwardOnly or kReverseOnly, value is returned as kOn/kOff not
* <p>When set to kForwardOnly or kReverseOnly, value is returned as kOn/kOff not
* kForward/kReverse (per the recommendation in Set)
*
* @return The current state of the relay as a Relay::Value
@@ -319,18 +322,18 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
/**
* Set the Relay Direction
* Set the Relay Direction.
*
* Changes which values the relay can be set to depending on which direction
* is used
* <p>Changes which values the relay can be set to depending on which direction is used
*
* Valid inputs are kBothDirections, kForwardOnly, and kReverseOnly
* <p>Valid inputs are kBothDirections, kForwardOnly, and kReverseOnly
*
* @param direction The direction for the relay to operate in
*/
public void setDirection(Direction direction) {
if (direction == null)
if (direction == null) {
throw new NullPointerException("Null Direction was given");
}
if (m_direction == direction) {
return;
}
@@ -351,28 +354,19 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
@@ -388,12 +382,9 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
@Override
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
String val = ((String) value);
@@ -408,15 +399,12 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -11,31 +11,30 @@ import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Track resources in the program. The Resource class is a convenient way of
* keeping track of allocated arbitrary resources in the program. Resources are
* just indicies that have an lower and upper bound that are tracked by this
* class. In the library they are used for tracking allocation of hardware
* channels but this is purely arbitrary. The resource class does not do any
* actual allocation, but simply tracks if a given index is currently in use.
* Track resources in the program. The Resource class is a convenient way of keeping track of
* allocated arbitrary resources in the program. Resources are just indicies that have an lower and
* upper bound that are tracked by this class. In the library they are used for tracking allocation
* of hardware channels but this is purely arbitrary. The resource class does not do any actual
* allocation, but simply tracks if a given index is currently in use.
*
* WARNING: this should only be statically allocated. When the program loads
* into memory all the static constructors are called. At that time a linked
* list of all the "Resources" is created. Then when the program actually starts
* - in the Robot constructor, all resources are initialized. This ensures that
* the program is restartable in memory without having to unload/reload.
* <p><b>WARNING:</b> this should only be statically allocated. When the program loads into memory
* all the static constructors are called. At that time a linked list of all the "Resources" is
* created. Then when the program actually starts - in the Robot constructor, all resources are
* initialized. This ensures that the program is restartable in memory without having to
* unload/reload.
*/
public class Resource {
public final class Resource {
private static Resource m_resourceList = null;
private final boolean m_numAllocated[];
private static Resource resourceList = null;
private final boolean[] m_numAllocated;
private final int m_size;
private final Resource m_nextResource;
/**
* Clears all allocated resources
* Clears all allocated resources.
*/
public static void restartProgram() {
for (Resource r = Resource.m_resourceList; r != null; r = r.m_nextResource) {
for (Resource r = Resource.resourceList; r != null; r = r.m_nextResource) {
for (int i = 0; i < r.m_size; i++) {
r.m_numAllocated[i] = false;
}
@@ -43,30 +42,28 @@ public class Resource {
}
/**
* Allocate storage for a new instance of Resource. Allocate a bool array of
* values that will get initialized to indicate that no resources have been
* allocated yet. The indicies of the resources are 0..size-1.
* Allocate storage for a new instance of Resource. Allocate a bool array of values that will get
* initialized to indicate that no resources have been allocated yet. The indicies of the
* resources are 0..size-1.
*
* @param size The number of blocks to allocate
*/
public Resource(final int size) {
m_size = size;
m_numAllocated = new boolean[m_size];
for (int i = 0; i < m_size; i++) {
m_numAllocated = new boolean[size];
for (int i = 0; i < size; i++) {
m_numAllocated[i] = false;
}
m_nextResource = Resource.m_resourceList;
Resource.m_resourceList = this;
m_nextResource = Resource.resourceList;
Resource.resourceList = this;
}
/**
* Allocate a resource. When a resource is requested, mark it allocated. In
* this case, a free resource value within the range is located and returned
* after it is marked allocated.
* Allocate a resource. When a resource is requested, mark it allocated. In this case, a free
* resource value within the range is located and returned after it is marked allocated.
*
* @return The index of the allocated block.
* @throws CheckedAllocationException If there are no resources available to
* be allocated.
* @throws CheckedAllocationException If there are no resources available to be allocated.
*/
public int allocate() throws CheckedAllocationException {
for (int i = 0; i < m_size; i++) {
@@ -79,13 +76,12 @@ public class Resource {
}
/**
* Allocate a specific resource value. The user requests a specific resource
* value, i.e. channel number and it is verified unallocated, then returned.
* Allocate a specific resource value. The user requests a specific resource value, i.e. channel
* number and it is verified unallocated, then returned.
*
* @param index The resource to allocate
* @return The index of the allocated block
* @throws CheckedAllocationException If there are no resources available to
* be allocated.
* @throws CheckedAllocationException If there are no resources available to be allocated.
*/
public int allocate(final int index) throws CheckedAllocationException {
if (index >= m_size || index < 0) {
@@ -99,16 +95,16 @@ public class Resource {
}
/**
* Free an allocated resource. After a resource is no longer needed, for
* example a destructor is called for a channel assignment class, Free will
* release the resource value so it can be reused somewhere else in the
* program.
* Free an allocated resource. After a resource is no longer needed, for example a destructor is
* called for a channel assignment class, Free will release the resource value so it can be reused
* somewhere else in the program.
*
* @param index The index of the resource to free.
*/
public void free(final int index) {
if (m_numAllocated[index] == false)
if (m_numAllocated[index] == false) {
throw new AllocationException("No resource available to be freed");
}
m_numAllocated[index] = false;
}

View File

@@ -10,12 +10,10 @@ package edu.wpi.first.wpilibj;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.jar.Manifest;
import java.util.Arrays;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
@@ -24,35 +22,30 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.internal.HardwareHLUsageReporting;
import edu.wpi.first.wpilibj.internal.HardwareTimer;
import edu.wpi.first.wpilibj.networktables.NetworkTable;
import edu.wpi.first.wpilibj.Utility;
/**
* Implement a Robot Program framework. The RobotBase class is intended to be
* subclassed by a user creating a robot program. Overridden autonomous() and
* operatorControl() methods are called at the appropriate time as the match
* proceeds. In the current implementation, the Autonomous code will run to
* completion before the OperatorControl code could start. In the future the
* Autonomous code might be spawned as a task, then killed at the end of the
* Autonomous period.
* Implement a Robot Program framework. The RobotBase class is intended to be subclassed by a user
* creating a robot program. Overridden autonomous() and operatorControl() methods are called at the
* appropriate time as the match proceeds. In the current implementation, the Autonomous code will
* run to completion before the OperatorControl code could start. In the future the Autonomous code
* might be spawned as a task, then killed at the end of the Autonomous period.
*/
public abstract class RobotBase {
/**
* The VxWorks priority that robot code should work at (so Java code should
* run at)
* The VxWorks priority that robot code should work at (so Java code should run at).
*/
public static final int ROBOT_TASK_PRIORITY = 101;
protected final DriverStation m_ds;
/**
* Constructor for a generic robot program. User code should be placed in the
* constructor that runs before the Autonomous or Operator Control period
* starts. The constructor will run to completion before Autonomous is
* entered.
* Constructor for a generic robot program. User code should be placed in the constructor that
* runs before the Autonomous or Operator Control period starts. The constructor will run to
* completion before Autonomous is entered.
*
* This must be used to ensure that the communications code starts. In the
* future it would be nice to put this code into it's own task that loads on
* boot so ensure that it runs.
* <p>This must be used to ensure that the communications code starts. In the future it would be
* nice
* to put this code into it's own task that loads on boot so ensure that it runs.
*/
protected RobotBase() {
// TODO: StartCAPI();
@@ -70,7 +63,8 @@ public abstract class RobotBase {
/**
* Free the resources for a RobotBase class.
*/
public void free() {}
public void free() {
}
/**
* @return If the robot is running in simulation.
@@ -88,7 +82,7 @@ public abstract class RobotBase {
/**
* Determine if the Robot is currently disabled.
*$
*
* @return True if the Robot is currently disabled by the field controls.
*/
public boolean isDisabled() {
@@ -97,7 +91,7 @@ public abstract class RobotBase {
/**
* Determine if the Robot is currently enabled.
*$
*
* @return True if the Robot is currently enabled by the field controls.
*/
public boolean isEnabled() {
@@ -105,30 +99,30 @@ public abstract class RobotBase {
}
/**
* Determine if the robot is currently in Autonomous mode.
*$
* @return True if the robot is currently operating Autonomously as determined
* by the field controls.
* Determine if the robot is currently in Autonomous mode as determined by the field
* controls.
*
* @return True if the robot is currently operating Autonomously.
*/
public boolean isAutonomous() {
return m_ds.isAutonomous();
}
/**
* Determine if the robot is currently in Test mode
*$
* @return True if the robot is currently operating in Test mode as determined
* by the driver station.
* Determine if the robot is currently in Test mode as determined by the driver
* station.
*
* @return True if the robot is currently operating in Test mode.
*/
public boolean isTest() {
return m_ds.isTest();
}
/**
* Determine if the robot is currently in Operator Control mode.
*$
* @return True if the robot is currently operating in Tele-Op mode as
* determined by the field controls.
* Determine if the robot is currently in Operator Control mode as determined by the field
* controls.
*
* @return True if the robot is currently operating in Tele-Op mode.
*/
public boolean isOperatorControl() {
return m_ds.isOperatorControl();
@@ -136,9 +130,8 @@ public abstract class RobotBase {
/**
* Indicates if new data is available from the driver station.
*$
* @return Has new data arrived over the network since the last time this
* function was called?
*
* @return Has new data arrived over the network since the last time this function was called?
*/
public boolean isNewDataAvailable() {
return m_ds.isNewControlData();
@@ -149,6 +142,7 @@ public abstract class RobotBase {
*/
public abstract void startCompetition();
@SuppressWarnings("JavadocMethod")
public static boolean getBooleanProperty(String name, boolean defaultValue) {
String propVal = System.getProperty(name);
if (propVal == null) {
@@ -178,7 +172,7 @@ public abstract class RobotBase {
/**
* Starting point for the applications.
*/
public static void main(String args[]) {
public static void main(String... args) {
initializeHardwareConfiguration();
UsageReporting.report(tResourceType.kResourceType_Language, tInstances.kLanguage_Java);
@@ -187,70 +181,63 @@ public abstract class RobotBase {
Enumeration<URL> resources = null;
try {
resources = RobotBase.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
} catch (IOException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
while (resources != null && resources.hasMoreElements()) {
try {
Manifest manifest = new Manifest(resources.nextElement().openStream());
robotName = manifest.getMainAttributes().getValue("Robot-Class");
} catch (IOException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
RobotBase robot;
try {
robot = (RobotBase) Class.forName(robotName).newInstance();
} catch (Throwable t) {
} catch (Throwable throwable) {
DriverStation.reportError("ERROR Unhandled exception instantiating robot " + robotName + " "
+ t.toString() + " at " + Arrays.toString(t.getStackTrace()), false);
+ throwable.toString() + " at " + Arrays.toString(throwable.getStackTrace()), false);
System.err.println("WARNING: Robots don't quit!");
System.err.println("ERROR: Could not instantiate robot " + robotName + "!");
System.exit(1);
return;
}
File file = null;
FileOutputStream output = null;
try {
file = new File("/tmp/frc_versions/FRC_Lib_Version.ini");
final File file = new File("/tmp/frc_versions/FRC_Lib_Version.ini");
if (file.exists())
if (file.exists()) {
file.delete();
}
file.createNewFile();
output = new FileOutputStream(file);
output.write("2016 Java Release 5".getBytes());
try (FileOutputStream output = new FileOutputStream(file)) {
output.write("2016 Java Release 5".getBytes());
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException ex) {
}
}
}
boolean errorOnExit = false;
try {
System.out.println("********** Robot program starting **********");
robot.startCompetition();
} catch (Throwable t) {
} catch (Throwable throwable) {
DriverStation.reportError(
"ERROR Unhandled exception: " + t.toString() + " at "
+ Arrays.toString(t.getStackTrace()), false);
"ERROR Unhandled exception: " + throwable.toString() + " at "
+ Arrays.toString(throwable.getStackTrace()), false);
errorOnExit = true;
} finally {
// startCompetition never returns unless exception occurs....
System.err.println("WARNING: Robots don't quit!");
if (errorOnExit) {
System.err
.println("---> The startCompetition() method (or methods called by it) should have handled the exception above.");
.println("---> The startCompetition() method (or methods called by it) should have "
+ "handled the exception above.");
} else {
System.err.println("---> Unexpected return from startCompetition() method.");
}

View File

@@ -11,47 +11,48 @@ import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInst
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import static java.util.Objects.requireNonNull;
/**
* Utility class for handling Robot drive based on a definition of the motor
* configuration. The robot drive class handles basic driving for a robot.
* Currently, 2 and 4 motor tank and mecanum drive trains are supported. In the
* future other drive types like swerve might be implemented. Motor channel
* numbers are supplied on creation of the class. Those are used for either the
* drive function (intended for hand created drive code, such as autonomous) or
* with the Tank/Arcade functions intended to be used for Operator Control
* driving.
* Utility class for handling Robot drive based on a definition of the motor configuration. The
* robot drive class handles basic driving for a robot. Currently, 2 and 4 motor tank and mecanum
* drive trains are supported. In the future other drive types like swerve might be implemented.
* Motor channel numbers are supplied on creation of the class. Those are used for either the drive
* function (intended for hand created drive code, such as autonomous) or with the Tank/Arcade
* functions intended to be used for Operator Control driving.
*/
public class RobotDrive implements MotorSafety {
protected MotorSafetyHelper m_safetyHelper;
/**
* The location of a motor on the robot for the purpose of driving
* The location of a motor on the robot for the purpose of driving.
*/
public static class MotorType {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kFrontLeft_val = 0;
static final int kFrontRight_val = 1;
static final int kRearLeft_val = 2;
static final int kRearRight_val = 3;
/**
* motortype: front left
* motortype: front left.
*/
public static final MotorType kFrontLeft = new MotorType(kFrontLeft_val);
/**
* motortype: front right
* motortype: front right.
*/
public static final MotorType kFrontRight = new MotorType(kFrontRight_val);
/**
* motortype: rear left
* motortype: rear left.
*/
public static final MotorType kRearLeft = new MotorType(kRearLeft_val);
/**
* motortype: rear right
* motortype: rear right.
*/
public static final MotorType kRearRight = new MotorType(kRearRight_val);
@@ -79,14 +80,12 @@ public class RobotDrive implements MotorSafety {
protected static boolean kMecanumPolar_Reported = false;
/**
* Constructor for RobotDrive with 2 motors specified with channel numbers.
* Set up parameters for a two wheel drive system where the left and right
* motor pwm channels are specified in the call. This call assumes Talons for
* controlling the motors.
*$
* @param leftMotorChannel The PWM channel number that drives the left motor.
* @param rightMotorChannel The PWM channel number that drives the right
* motor.
* Constructor for RobotDrive with 2 motors specified with channel numbers. Set up parameters for
* a two wheel drive system where the left and right motor pwm channels are specified in the call.
* This call assumes Talons for controlling the motors.
*
* @param leftMotorChannel The PWM channel number that drives the left motor.
* @param rightMotorChannel The PWM channel number that drives the right motor.
*/
public RobotDrive(final int leftMotorChannel, final int rightMotorChannel) {
m_sensitivity = kDefaultSensitivity;
@@ -101,18 +100,17 @@ public class RobotDrive implements MotorSafety {
}
/**
* Constructor for RobotDrive with 4 motors specified with channel numbers.
* Set up parameters for a four wheel drive system where all four motor pwm
* channels are specified in the call. This call assumes Talons for
* controlling the motors.
*$
* @param frontLeftMotor Front left motor channel number
* @param rearLeftMotor Rear Left motor channel number
* Constructor for RobotDrive with 4 motors specified with channel numbers. Set up parameters for
* a four wheel drive system where all four motor pwm channels are specified in the call. This
* call assumes Talons for controlling the motors.
*
* @param frontLeftMotor Front left motor channel number
* @param rearLeftMotor Rear Left motor channel number
* @param frontRightMotor Front right motor channel number
* @param rearRightMotor Rear Right motor channel number
* @param rearRightMotor Rear Right motor channel number
*/
public RobotDrive(final int frontLeftMotor, final int rearLeftMotor, final int frontRightMotor,
final int rearRightMotor) {
final int rearRightMotor) {
m_sensitivity = kDefaultSensitivity;
m_maxOutput = kDefaultMaxOutput;
m_rearLeftMotor = new Talon(rearLeftMotor);
@@ -125,13 +123,12 @@ public class RobotDrive implements MotorSafety {
}
/**
* Constructor for RobotDrive with 2 motors specified as SpeedController
* objects. The SpeedController version of the constructor enables programs to
* use the RobotDrive classes with subclasses of the SpeedController objects,
* for example, versions with ramping or reshaping of the curve to suit motor
* bias or dead-band elimination.
*$
* @param leftMotor The left SpeedController object used to drive the robot.
* Constructor for RobotDrive with 2 motors specified as SpeedController objects. The
* SpeedController version of the constructor enables programs to use the RobotDrive classes with
* subclasses of the SpeedController objects, for example, versions with ramping or reshaping of
* the curve to suit motor bias or dead-band elimination.
*
* @param leftMotor The left SpeedController object used to drive the robot.
* @param rightMotor the right SpeedController object used to drive the robot.
*/
public RobotDrive(SpeedController leftMotor, SpeedController rightMotor) {
@@ -151,30 +148,20 @@ public class RobotDrive implements MotorSafety {
}
/**
* Constructor for RobotDrive with 4 motors specified as SpeedController
* objects. Speed controller input version of RobotDrive (see previous
* comments).
*$
* @param rearLeftMotor The back left SpeedController object used to drive the
* robot.
* @param frontLeftMotor The front left SpeedController object used to drive
* the robot
* @param rearRightMotor The back right SpeedController object used to drive
* the robot.
* @param frontRightMotor The front right SpeedController object used to drive
* the robot.
* Constructor for RobotDrive with 4 motors specified as SpeedController objects. Speed controller
* input version of RobotDrive (see previous comments).
*
* @param rearLeftMotor The back left SpeedController object used to drive the robot.
* @param frontLeftMotor The front left SpeedController object used to drive the robot
* @param rearRightMotor The back right SpeedController object used to drive the robot.
* @param frontRightMotor The front right SpeedController object used to drive the robot.
*/
public RobotDrive(SpeedController frontLeftMotor, SpeedController rearLeftMotor,
SpeedController frontRightMotor, SpeedController rearRightMotor) {
if (frontLeftMotor == null || rearLeftMotor == null || frontRightMotor == null
|| rearRightMotor == null) {
m_frontLeftMotor = m_rearLeftMotor = m_frontRightMotor = m_rearRightMotor = null;
throw new NullPointerException("Null motor provided");
}
m_frontLeftMotor = frontLeftMotor;
m_rearLeftMotor = rearLeftMotor;
m_frontRightMotor = frontRightMotor;
m_rearRightMotor = rearRightMotor;
SpeedController frontRightMotor, SpeedController rearRightMotor) {
m_frontLeftMotor = requireNonNull(frontLeftMotor, "frontLeftMotor cannot be null");
m_rearLeftMotor = requireNonNull(rearLeftMotor, "rearLeftMotor cannot be null");
m_frontRightMotor = requireNonNull(frontRightMotor, "frontRightMotor cannot be null");
m_rearRightMotor = requireNonNull(rearRightMotor, "rearRightMotor cannot be null");
m_sensitivity = kDefaultSensitivity;
m_maxOutput = kDefaultMaxOutput;
m_allocatedSpeedControllers = false;
@@ -183,27 +170,26 @@ public class RobotDrive implements MotorSafety {
}
/**
* Drive the motors at "outputMagnitude" and "curve".
* Both outputMagnitude and curve are -1.0 to +1.0 values, where 0.0
* represents stopped and not turning. {@literal curve < 0 will turn left and curve > 0}
* will turn right.
* Drive the motors at "outputMagnitude" and "curve". Both outputMagnitude and curve are -1.0 to
* +1.0 values, where 0.0 represents stopped and not turning. {@literal curve < 0 will turn left
* and curve > 0} will turn right.
*
* The algorithm for steering provides a constant turn radius for any normal
* speed range, both forward and backward. Increasing m_sensitivity causes
* sharper turns for fixed values of curve.
* <p>The algorithm for steering provides a constant turn radius for any normal speed range, both
* forward and backward. Increasing sensitivity causes sharper turns for fixed values of curve.
*
* This function will most likely be used in an autonomous routine.
* <p>This function will most likely be used in an autonomous routine.
*
* @param outputMagnitude The speed setting for the outside wheel in a turn,
* forward or backwards, +1 to -1.
* @param curve The rate of turn, constant for different forward speeds. Set
* {@literal curve < 0 for left turn or curve > 0 for right turn.}
* Set curve = e^(-r/w) to get a turn radius r for wheelbase w of your robot.
* Conversely, turn radius r = -ln(curve)*w for a given value of curve and
* wheelbase w.
* @param outputMagnitude The speed setting for the outside wheel in a turn, forward or backwards,
* +1 to -1.
* @param curve The rate of turn, constant for different forward speeds. Set {@literal
* curve < 0 for left turn or curve > 0 for right turn.} Set curve =
* e^(-r/w) to get a turn radius r for wheelbase w of your robot.
* Conversely, turn radius r = -ln(curve)*w for a given value of curve and
* wheelbase w.
*/
public void drive(double outputMagnitude, double curve) {
double leftOutput, rightOutput;
final double leftOutput;
final double rightOutput;
if (!kArcadeRatioCurve_Reported) {
UsageReporting.report(tResourceType.kResourceType_RobotDrive, getNumMotors(),
@@ -234,11 +220,10 @@ public class RobotDrive implements MotorSafety {
}
/**
* Provide tank steering using the stored robot configuration. drive the robot
* using two joystick inputs. The Y-axis will be selected from each Joystick
* object.
*$
* @param leftStick The joystick to control the left side of the robot.
* Provide tank steering using the stored robot configuration. drive the robot using two joystick
* inputs. The Y-axis will be selected from each Joystick object.
*
* @param leftStick The joystick to control the left side of the robot.
* @param rightStick The joystick to control the right side of the robot.
*/
public void tankDrive(GenericHID leftStick, GenericHID rightStick) {
@@ -249,14 +234,12 @@ public class RobotDrive implements MotorSafety {
}
/**
* Provide tank steering using the stored robot configuration. drive the robot
* using two joystick inputs. The Y-axis will be selected from each Joystick
* object.
*$
* @param leftStick The joystick to control the left side of the robot.
* @param rightStick The joystick to control the right side of the robot.
* @param squaredInputs Setting this parameter to true decreases the
* sensitivity at lower speeds
* Provide tank steering using the stored robot configuration. drive the robot using two joystick
* inputs. The Y-axis will be selected from each Joystick object.
*
* @param leftStick The joystick to control the left side of the robot.
* @param rightStick The joystick to control the right side of the robot.
* @param squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void tankDrive(GenericHID leftStick, GenericHID rightStick, boolean squaredInputs) {
if (leftStick == null || rightStick == null) {
@@ -266,18 +249,16 @@ public class RobotDrive implements MotorSafety {
}
/**
* Provide tank steering using the stored robot configuration. This function
* lets you pick the axis to be used on each Joystick object for the left and
* right sides of the robot.
*$
* @param leftStick The Joystick object to use for the left side of the robot.
* @param leftAxis The axis to select on the left side Joystick object.
* @param rightStick The Joystick object to use for the right side of the
* robot.
* @param rightAxis The axis to select on the right side Joystick object.
* Provide tank steering using the stored robot configuration. This function lets you pick the
* axis to be used on each Joystick object for the left and right sides of the robot.
*
* @param leftStick The Joystick object to use for the left side of the robot.
* @param leftAxis The axis to select on the left side Joystick object.
* @param rightStick The Joystick object to use for the right side of the robot.
* @param rightAxis The axis to select on the right side Joystick object.
*/
public void tankDrive(GenericHID leftStick, final int leftAxis, GenericHID rightStick,
final int rightAxis) {
final int rightAxis) {
if (leftStick == null || rightStick == null) {
throw new NullPointerException("Null HID provided");
}
@@ -285,20 +266,17 @@ public class RobotDrive implements MotorSafety {
}
/**
* Provide tank steering using the stored robot configuration. This function
* lets you pick the axis to be used on each Joystick object for the left and
* right sides of the robot.
*$
* @param leftStick The Joystick object to use for the left side of the robot.
* @param leftAxis The axis to select on the left side Joystick object.
* @param rightStick The Joystick object to use for the right side of the
* robot.
* @param rightAxis The axis to select on the right side Joystick object.
* @param squaredInputs Setting this parameter to true decreases the
* sensitivity at lower speeds
* Provide tank steering using the stored robot configuration. This function lets you pick the
* axis to be used on each Joystick object for the left and right sides of the robot.
*
* @param leftStick The Joystick object to use for the left side of the robot.
* @param leftAxis The axis to select on the left side Joystick object.
* @param rightStick The Joystick object to use for the right side of the robot.
* @param rightAxis The axis to select on the right side Joystick object.
* @param squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void tankDrive(GenericHID leftStick, final int leftAxis, GenericHID rightStick,
final int rightAxis, boolean squaredInputs) {
final int rightAxis, boolean squaredInputs) {
if (leftStick == null || rightStick == null) {
throw new NullPointerException("Null HID provided");
}
@@ -306,13 +284,12 @@ public class RobotDrive implements MotorSafety {
}
/**
* Provide tank steering using the stored robot configuration. This function
* lets you directly provide joystick values from any source.
*$
* @param leftValue The value of the left stick.
* @param rightValue The value of the right stick.
* @param squaredInputs Setting this parameter to true decreases the
* sensitivity at lower speeds
* Provide tank steering using the stored robot configuration. This function lets you directly
* provide joystick values from any source.
*
* @param leftValue The value of the left stick.
* @param rightValue The value of the right stick.
* @param squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void tankDrive(double leftValue, double rightValue, boolean squaredInputs) {
@@ -342,10 +319,10 @@ public class RobotDrive implements MotorSafety {
}
/**
* Provide tank steering using the stored robot configuration. This function
* lets you directly provide joystick values from any source.
*$
* @param leftValue The value of the left stick.
* Provide tank steering using the stored robot configuration. This function lets you directly
* provide joystick values from any source.
*
* @param leftValue The value of the left stick.
* @param rightValue The value of the right stick.
*/
public void tankDrive(double leftValue, double rightValue) {
@@ -353,16 +330,14 @@ public class RobotDrive implements MotorSafety {
}
/**
* Arcade drive implements single stick driving. Given a single Joystick, the
* class assumes the Y axis for the move value and the X axis for the rotate
* value. (Should add more information here regarding the way that arcade
* drive works.)
*$
* @param stick The joystick to use for Arcade single-stick driving. The
* Y-axis will be selected for forwards/backwards and the X-axis will
* be selected for rotation rate.
* @param squaredInputs If true, the sensitivity will be decreased for small
* values
* Arcade drive implements single stick driving. Given a single Joystick, the class assumes the Y
* axis for the move value and the X axis for the rotate value. (Should add more information here
* regarding the way that arcade drive works.)
*
* @param stick The joystick to use for Arcade single-stick driving. The Y-axis will be
* selected for forwards/backwards and the X-axis will be selected for
* rotation rate.
* @param squaredInputs If true, the sensitivity will be decreased for small values
*/
public void arcadeDrive(GenericHID stick, boolean squaredInputs) {
// simply call the full-featured arcadeDrive with the appropriate values
@@ -370,35 +345,31 @@ public class RobotDrive implements MotorSafety {
}
/**
* Arcade drive implements single stick driving. Given a single Joystick, the
* class assumes the Y axis for the move value and the X axis for the rotate
* value. (Should add more information here regarding the way that arcade
* drive works.)
*$
* @param stick The joystick to use for Arcade single-stick driving. The
* Y-axis will be selected for forwards/backwards and the X-axis will
* be selected for rotation rate.
* Arcade drive implements single stick driving. Given a single Joystick, the class assumes the Y
* axis for the move value and the X axis for the rotate value. (Should add more information here
* regarding the way that arcade drive works.)
*
* @param stick The joystick to use for Arcade single-stick driving. The Y-axis will be selected
* for forwards/backwards and the X-axis will be selected for rotation rate.
*/
public void arcadeDrive(GenericHID stick) {
this.arcadeDrive(stick, true);
arcadeDrive(stick, true);
}
/**
* Arcade drive implements single stick driving. Given two joystick instances
* and two axis, compute the values to send to either two or four motors.
*$
* @param moveStick The Joystick object that represents the forward/backward
* direction
* @param moveAxis The axis on the moveStick object to use for
* forwards/backwards (typically Y_AXIS)
* @param rotateStick The Joystick object that represents the rotation value
* @param rotateAxis The axis on the rotation object to use for the rotate
* right/left (typically X_AXIS)
* @param squaredInputs Setting this parameter to true decreases the
* sensitivity at lower speeds
* Arcade drive implements single stick driving. Given two joystick instances and two axis,
* compute the values to send to either two or four motors.
*
* @param moveStick The Joystick object that represents the forward/backward direction
* @param moveAxis The axis on the moveStick object to use for forwards/backwards (typically
* Y_AXIS)
* @param rotateStick The Joystick object that represents the rotation value
* @param rotateAxis The axis on the rotation object to use for the rotate right/left
* (typically X_AXIS)
* @param squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void arcadeDrive(GenericHID moveStick, final int moveAxis, GenericHID rotateStick,
final int rotateAxis, boolean squaredInputs) {
final int rotateAxis, boolean squaredInputs) {
double moveValue = moveStick.getRawAxis(moveAxis);
double rotateValue = rotateStick.getRawAxis(rotateAxis);
@@ -406,28 +377,27 @@ public class RobotDrive implements MotorSafety {
}
/**
* Arcade drive implements single stick driving. Given two joystick instances
* and two axis, compute the values to send to either two or four motors.
*$
* @param moveStick The Joystick object that represents the forward/backward
* direction
* @param moveAxis The axis on the moveStick object to use for
* forwards/backwards (typically Y_AXIS)
* Arcade drive implements single stick driving. Given two joystick instances and two axis,
* compute the values to send to either two or four motors.
*
* @param moveStick The Joystick object that represents the forward/backward direction
* @param moveAxis The axis on the moveStick object to use for forwards/backwards (typically
* Y_AXIS)
* @param rotateStick The Joystick object that represents the rotation value
* @param rotateAxis The axis on the rotation object to use for the rotate
* right/left (typically X_AXIS)
* @param rotateAxis The axis on the rotation object to use for the rotate right/left (typically
* X_AXIS)
*/
public void arcadeDrive(GenericHID moveStick, final int moveAxis, GenericHID rotateStick,
final int rotateAxis) {
this.arcadeDrive(moveStick, moveAxis, rotateStick, rotateAxis, true);
final int rotateAxis) {
arcadeDrive(moveStick, moveAxis, rotateStick, rotateAxis, true);
}
/**
* Arcade drive implements single stick driving. This function lets you
* directly provide joystick values from any source.
*$
* @param moveValue The value to use for forwards/backwards
* @param rotateValue The value to use for the rotate right/left
* Arcade drive implements single stick driving. This function lets you directly provide
* joystick values from any source.
*
* @param moveValue The value to use for forwards/backwards
* @param rotateValue The value to use for the rotate right/left
* @param squaredInputs If set, decreases the sensitivity at low speeds
*/
public void arcadeDrive(double moveValue, double rotateValue, boolean squaredInputs) {
@@ -481,52 +451,52 @@ public class RobotDrive implements MotorSafety {
}
/**
* Arcade drive implements single stick driving. This function lets you
* directly provide joystick values from any source.
*$
* @param moveValue The value to use for fowards/backwards
* Arcade drive implements single stick driving. This function lets you directly provide
* joystick values from any source.
*
* @param moveValue The value to use for fowards/backwards
* @param rotateValue The value to use for the rotate right/left
*/
public void arcadeDrive(double moveValue, double rotateValue) {
this.arcadeDrive(moveValue, rotateValue, true);
arcadeDrive(moveValue, rotateValue, true);
}
/**
* Drive method for Mecanum wheeled robots.
*
* A method for driving with Mecanum wheeled robots. There are 4 wheels on the
* robot, arranged so that the front and back wheels are toed in 45 degrees.
* When looking at the wheels from the top, the roller axles should form an X
* across the robot.
* <p>A method for driving with Mecanum wheeled robots. There are 4 wheels on the robot, arranged
* so that the front and back wheels are toed in 45 degrees. When looking at the wheels from the
* top, the roller axles should form an X across the robot.
*
* This is designed to be directly driven by joystick axes.
* <p>This is designed to be directly driven by joystick axes.
*
* @param x The speed that the robot should drive in the X direction.
* [-1.0..1.0]
* @param y The speed that the robot should drive in the Y direction. This
* input is inverted to match the forward == -1.0 that joysticks
* produce. [-1.0..1.0]
* @param rotation The rate of rotation for the robot that is completely
* independent of the translation. [-1.0..1.0]
* @param gyroAngle The current angle reading from the gyro. Use this to
* implement field-oriented controls.
* @param x The speed that the robot should drive in the X direction. [-1.0..1.0]
* @param y The speed that the robot should drive in the Y direction. This input is
* inverted to match the forward == -1.0 that joysticks produce. [-1.0..1.0]
* @param rotation The rate of rotation for the robot that is completely independent of the
* translation. [-1.0..1.0]
* @param gyroAngle The current angle reading from the gyro. Use this to implement field-oriented
* controls.
*/
@SuppressWarnings("ParameterName")
public void mecanumDrive_Cartesian(double x, double y, double rotation, double gyroAngle) {
if (!kMecanumCartesian_Reported) {
UsageReporting.report(tResourceType.kResourceType_RobotDrive, getNumMotors(),
tInstances.kRobotDrive_MecanumCartesian);
kMecanumCartesian_Reported = true;
}
@SuppressWarnings("LocalVariableName")
double xIn = x;
@SuppressWarnings("LocalVariableName")
double yIn = y;
// Negate y for the joystick.
yIn = -yIn;
// Compenstate for gyro angle.
double rotated[] = rotateVector(xIn, yIn, gyroAngle);
double[] rotated = rotateVector(xIn, yIn, gyroAngle);
xIn = rotated[0];
yIn = rotated[1];
double wheelSpeeds[] = new double[kMaxNumberOfMotors];
double[] wheelSpeeds = new double[kMaxNumberOfMotors];
wheelSpeeds[MotorType.kFrontLeft_val] = xIn + yIn + rotation;
wheelSpeeds[MotorType.kFrontRight_val] = -xIn + yIn - rotation;
wheelSpeeds[MotorType.kRearLeft_val] = -xIn + yIn + rotation;
@@ -542,24 +512,23 @@ public class RobotDrive implements MotorSafety {
CANJaguar.updateSyncGroup(m_syncGroup);
}
if (m_safetyHelper != null)
if (m_safetyHelper != null) {
m_safetyHelper.feed();
}
}
/**
* Drive method for Mecanum wheeled robots.
*
* A method for driving with Mecanum wheeled robots. There are 4 wheels on the
* robot, arranged so that the front and back wheels are toed in 45 degrees.
* When looking at the wheels from the top, the roller axles should form an X
* across the robot.
* <p>A method for driving with Mecanum wheeled robots. There are 4 wheels on the robot, arranged
* so that the front and back wheels are toed in 45 degrees. When looking at the wheels from the
* top, the roller axles should form an X across the robot.
*
* @param magnitude The speed that the robot should drive in a given
* direction.
* @param direction The direction the robot should drive in degrees. The
* direction and maginitute are independent of the rotation rate.
* @param rotation The rate of rotation for the robot that is completely
* independent of the magnitute or direction. [-1.0..1.0]
* @param magnitude The speed that the robot should drive in a given direction.
* @param direction The direction the robot should drive in degrees. The direction and maginitute
* are independent of the rotation rate.
* @param rotation The rate of rotation for the robot that is completely independent of the
* magnitute or direction. [-1.0..1.0]
*/
public void mecanumDrive_Polar(double magnitude, double direction, double rotation) {
if (!kMecanumPolar_Reported) {
@@ -567,7 +536,6 @@ public class RobotDrive implements MotorSafety {
tInstances.kRobotDrive_MecanumPolar);
kMecanumPolar_Reported = true;
}
double frontLeftSpeed, rearLeftSpeed, frontRightSpeed, rearRightSpeed;
// Normalized for full power along the Cartesian axes.
magnitude = limit(magnitude) * Math.sqrt(2.0);
// The rollers are at 45 degree angles.
@@ -575,7 +543,7 @@ public class RobotDrive implements MotorSafety {
double cosD = Math.cos(dirInRad);
double sinD = Math.sin(dirInRad);
double wheelSpeeds[] = new double[kMaxNumberOfMotors];
double[] wheelSpeeds = new double[kMaxNumberOfMotors];
wheelSpeeds[MotorType.kFrontLeft_val] = (sinD * magnitude + rotation);
wheelSpeeds[MotorType.kFrontRight_val] = (cosD * magnitude - rotation);
wheelSpeeds[MotorType.kRearLeft_val] = (cosD * magnitude + rotation);
@@ -588,37 +556,36 @@ public class RobotDrive implements MotorSafety {
m_rearLeftMotor.set(wheelSpeeds[MotorType.kRearLeft_val] * m_maxOutput, m_syncGroup);
m_rearRightMotor.set(wheelSpeeds[MotorType.kRearRight_val] * m_maxOutput, m_syncGroup);
if (this.m_syncGroup != 0) {
if (m_syncGroup != 0) {
CANJaguar.updateSyncGroup(m_syncGroup);
}
if (m_safetyHelper != null)
if (m_safetyHelper != null) {
m_safetyHelper.feed();
}
}
/**
* Holonomic Drive method for Mecanum wheeled robots.
*
* This is an alias to mecanumDrive_Polar() for backward compatability
* <p>This is an alias to mecanumDrive_Polar() for backward compatability
*
* @param magnitude The speed that the robot should drive in a given
* direction. [-1.0..1.0]
* @param direction The direction the robot should drive. The direction and
* maginitute are independent of the rotation rate.
* @param rotation The rate of rotation for the robot that is completely
* independent of the magnitute or direction. [-1.0..1.0]
* @param magnitude The speed that the robot should drive in a given direction. [-1.0..1.0]
* @param direction The direction the robot should drive. The direction and maginitute are
* independent of the rotation rate.
* @param rotation The rate of rotation for the robot that is completely independent of the
* magnitute or direction. [-1.0..1.0]
*/
void holonomicDrive(float magnitude, float direction, float rotation) {
mecanumDrive_Polar(magnitude, direction, rotation);
}
/**
* Set the speed of the right and left motors. This is used once an
* appropriate drive setup function is called such as twoWheelDrive(). The
* motors are set to "leftSpeed" and "rightSpeed" and includes flipping the
* direction of one side for opposing motors.
*$
* @param leftOutput The speed to send to the left side of the robot.
* Set the speed of the right and left motors. This is used once an appropriate drive setup
* function is called such as twoWheelDrive(). The motors are set to "leftSpeed" and
* "rightSpeed" and includes flipping the direction of one side for opposing motors.
*
* @param leftOutput The speed to send to the left side of the robot.
* @param rightOutput The speed to send to the right side of the robot.
*/
public void setLeftRightMotorOutputs(double leftOutput, double rightOutput) {
@@ -636,12 +603,13 @@ public class RobotDrive implements MotorSafety {
}
m_rearRightMotor.set(-limit(rightOutput) * m_maxOutput, m_syncGroup);
if (this.m_syncGroup != 0) {
if (m_syncGroup != 0) {
CANJaguar.updateSyncGroup(m_syncGroup);
}
if (m_safetyHelper != null)
if (m_safetyHelper != null) {
m_safetyHelper.feed();
}
}
/**
@@ -658,19 +626,18 @@ public class RobotDrive implements MotorSafety {
}
/**
* Normalize all wheel speeds if the magnitude of any wheel is greater than
* 1.0.
* Normalize all wheel speeds if the magnitude of any wheel is greater than 1.0.
*/
protected static void normalize(double wheelSpeeds[]) {
protected static void normalize(double[] wheelSpeeds) {
double maxMagnitude = Math.abs(wheelSpeeds[0]);
int i;
for (i = 1; i < kMaxNumberOfMotors; i++) {
for (int i = 1; i < kMaxNumberOfMotors; i++) {
double temp = Math.abs(wheelSpeeds[i]);
if (maxMagnitude < temp)
if (maxMagnitude < temp) {
maxMagnitude = temp;
}
}
if (maxMagnitude > 1.0) {
for (i = 0; i < kMaxNumberOfMotors; i++) {
for (int i = 0; i < kMaxNumberOfMotors; i++) {
wheelSpeeds[i] = wheelSpeeds[i] / maxMagnitude;
}
}
@@ -679,22 +646,22 @@ public class RobotDrive implements MotorSafety {
/**
* Rotate a vector in Cartesian space.
*/
@SuppressWarnings("ParameterName")
protected static double[] rotateVector(double x, double y, double angle) {
double cosA = Math.cos(angle * (3.14159 / 180.0));
double sinA = Math.sin(angle * (3.14159 / 180.0));
double out[] = new double[2];
double[] out = new double[2];
out[0] = x * cosA - y * sinA;
out[1] = x * sinA + y * cosA;
return out;
}
/**
* Invert a motor direction. This is used when a motor should run in the
* opposite direction as the drive code would normally run it. Motors that are
* direct drive would be inverted, the drive code assumes that the motors are
* geared with one reversal.
*$
* @param motor The motor index to invert.
* Invert a motor direction. This is used when a motor should run in the opposite direction as the
* drive code would normally run it. Motors that are direct drive would be inverted, the drive
* code assumes that the motors are geared with one reversal.
*
* @param motor The motor index to invert.
* @param isInverted True if the motor should be inverted when operated.
*/
public void setInvertedMotor(MotorType motor, boolean isInverted) {
@@ -711,36 +678,36 @@ public class RobotDrive implements MotorSafety {
case MotorType.kRearRight_val:
m_rearRightMotor.setInverted(isInverted);
break;
default:
throw new IllegalArgumentException("Illegal motor type: " + motor);
}
}
/**
* Set the turning sensitivity.
*
* This only impacts the drive() entry-point.
*$
* @param sensitivity Effectively sets the turning sensitivity (or turn radius
* for a given value)
* <p>This only impacts the drive() entry-point.
*
* @param sensitivity Effectively sets the turning sensitivity (or turn radius for a given value)
*/
public void setSensitivity(double sensitivity) {
m_sensitivity = sensitivity;
}
/**
* Configure the scaling factor for using RobotDrive with motor controllers in
* a mode other than PercentVbus.
*$
* @param maxOutput Multiplied with the output percentage computed by the
* drive functions.
* Configure the scaling factor for using RobotDrive with motor controllers in a mode other than
* PercentVbus.
*
* @param maxOutput Multiplied with the output percentage computed by the drive functions.
*/
public void setMaxOutput(double maxOutput) {
m_maxOutput = maxOutput;
}
/**
* Set the number of the sync group for the motor controllers. If the motor
* controllers are {@link CANJaguar}s, then they will all be added to this
* sync group, causing them to update their values at the same time.
* Set the number of the sync group for the motor controllers. If the motor controllers are {@link
* CANJaguar}s, then they will all be added to this sync group, causing them to update their
* values at the same time.
*
* @param syncGroup the update group to add the motor controllers to
*/
@@ -749,7 +716,7 @@ public class RobotDrive implements MotorSafety {
}
/**
* Free the speed controllers if they were allocated locally
* Free the speed controllers if they were allocated locally.
*/
public void free() {
if (m_allocatedSpeedControllers) {
@@ -768,30 +735,37 @@ public class RobotDrive implements MotorSafety {
}
}
@Override
public void setExpiration(double timeout) {
m_safetyHelper.setExpiration(timeout);
}
@Override
public double getExpiration() {
return m_safetyHelper.getExpiration();
}
@Override
public boolean isAlive() {
return m_safetyHelper.isAlive();
}
@Override
public boolean isSafetyEnabled() {
return m_safetyHelper.isSafetyEnabled();
}
@Override
public void setSafetyEnabled(boolean enabled) {
m_safetyHelper.setSafetyEnabled(enabled);
}
@Override
public String getDescription() {
return "Robot Drive";
}
@Override
public void stopMotor() {
if (m_frontLeftMotor != null) {
m_frontLeftMotor.stopMotor();
@@ -805,8 +779,9 @@ public class RobotDrive implements MotorSafety {
if (m_rearRightMotor != null) {
m_rearRightMotor.stopMotor();
}
if (m_safetyHelper != null)
if (m_safetyHelper != null) {
m_safetyHelper.feed();
}
}
private void setupMotorSafety() {
@@ -817,14 +792,18 @@ public class RobotDrive implements MotorSafety {
protected int getNumMotors() {
int motors = 0;
if (m_frontLeftMotor != null)
if (m_frontLeftMotor != null) {
motors++;
if (m_frontRightMotor != null)
}
if (m_frontRightMotor != null) {
motors++;
if (m_rearLeftMotor != null)
}
if (m_rearLeftMotor != null) {
motors++;
if (m_rearRightMotor != null)
}
if (m_rearRightMotor != null) {
motors++;
}
return motors;
}
}

View File

@@ -12,23 +12,22 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Mindsensors SD540 Speed Controller
* Mindsensors SD540 Speed Controller.
*/
public class SD540 extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* Note that the SD540 uses the following bounds for PWM values. These
* values should work reasonably well for most controllers, but if users
* experience issues such as asymmetric behavior around the deadband or
* inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the SD540 User
* Manual available from Mindsensors.
* <p>Note that the SD540 uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the SD540 User Manual
* available from Mindsensors.
*
* - 2.05ms = full "forward" - 1.55ms = the "high end" of the deadband range
* - 1.50ms = center of the deadband range (off) - 1.44ms = the "low end" of
* the deadband range - .94ms = full "reverse"
* <p>- 2.05ms = full "forward" - 1.55ms = the "high end" of the deadband range - 1.50ms = center
* of the deadband range (off) - 1.44ms = the "low end" of the deadband range - .94ms = full
* "reverse"
*/
protected void initSD540() {
setBounds(2.05, 1.55, 1.50, 1.44, .94);
@@ -43,8 +42,8 @@ public class SD540 extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the SD540 is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the SD540 is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public SD540(final int channel) {
super(channel);

View File

@@ -7,19 +7,16 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.SPIJNI;
/**
* Represents a SPI bus port.
*
* Represents a SPI bus port
*$
* @author koconnor
*/
public class SPI extends SensorBase {
@@ -27,26 +24,26 @@ public class SPI extends SensorBase {
public enum Port {
kOnboardCS0(0), kOnboardCS1(1), kOnboardCS2(2), kOnboardCS3(3), kMXP(4);
private int value;
private int m_value;
private Port(int value) {
this.value = value;
Port(int value) {
m_value = value;
}
public int getValue() {
return this.value;
return m_value;
}
};
}
private static int devices = 0;
private byte m_port;
private int bitOrder;
private int clockPolarity;
private int dataOnTrailing;
private int m_bitOrder;
private int m_clockPolarity;
private int m_dataOnTrailing;
/**
* Constructor
* Constructor.
*
* @param port the physical SPI port
*/
@@ -60,15 +57,15 @@ public class SPI extends SensorBase {
}
/**
* Free the resources used by this object
* Free the resources used by this object.
*/
public void free() {
SPIJNI.spiClose(m_port);
}
/**
* Configure the rate of the generated clock signal. The default value is
* 500,000 Hz. The maximum value is 4,000,000 Hz.
* Configure the rate of the generated clock signal. The default value is 500,000 Hz. The maximum
* value is 4,000,000 Hz.
*
* @param hz The clock rate in Hertz.
*/
@@ -77,57 +74,55 @@ public class SPI extends SensorBase {
}
/**
* Configure the order that bits are sent and received on the wire to be most
* significant bit first.
* Configure the order that bits are sent and received on the wire to be most significant bit
* first.
*/
public final void setMSBFirst() {
this.bitOrder = 1;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_bitOrder = 1;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure the order that bits are sent and received on the wire to be least
* significant bit first.
* Configure the order that bits are sent and received on the wire to be least significant bit
* first.
*/
public final void setLSBFirst() {
this.bitOrder = 0;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_bitOrder = 0;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure the clock output line to be active low. This is sometimes called
* clock polarity high or clock idle high.
* Configure the clock output line to be active low. This is sometimes called clock polarity high
* or clock idle high.
*/
public final void setClockActiveLow() {
this.clockPolarity = 1;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_clockPolarity = 1;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure the clock output line to be active high. This is sometimes called
* clock polarity low or clock idle low.
* Configure the clock output line to be active high. This is sometimes called clock polarity low
* or clock idle low.
*/
public final void setClockActiveHigh() {
this.clockPolarity = 0;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_clockPolarity = 0;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure that the data is stable on the falling edge and the data changes
* on the rising edge.
* Configure that the data is stable on the falling edge and the data changes on the rising edge.
*/
public final void setSampleDataOnFalling() {
this.dataOnTrailing = 1;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_dataOnTrailing = 1;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure that the data is stable on the rising edge and the data changes
* on the falling edge.
* Configure that the data is stable on the rising edge and the data changes on the falling edge.
*/
public final void setSampleDataOnRising() {
this.dataOnTrailing = 0;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_dataOnTrailing = 0;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
@@ -145,11 +140,10 @@ public class SPI extends SensorBase {
}
/**
* Write data to the slave device. Blocks until there is space in the output
* FIFO.
* Write data to the slave device. Blocks until there is space in the output FIFO.
*
* If not running in output only mode, also saves the data received on the
* MISO input during the transfer into the receive FIFO.
* <p>If not running in output only mode, also saves the data received on the MISO input during
* the transfer into the receive FIFO.
*/
public int write(byte[] dataToSend, int size) {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(size);
@@ -158,43 +152,44 @@ public class SPI extends SensorBase {
}
/**
* Write data to the slave device. Blocks until there is space in the output
* FIFO.
* Write data to the slave device. Blocks until there is space in the output FIFO.
*
* If not running in output only mode, also saves the data received on the
* MISO input during the transfer into the receive FIFO.
* <p>If not running in output only mode, also saves the data received on the MISO input during
* the transfer into the receive FIFO.
*
* @param dataToSend The buffer containing the data to send. Must be created
* using ByteBuffer.allocateDirect().
* @param dataToSend The buffer containing the data to send. Must be created using
* ByteBuffer.allocateDirect().
*/
public int write(ByteBuffer dataToSend, int size) {
if (!dataToSend.isDirect())
if (!dataToSend.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (dataToSend.capacity() < size)
}
if (dataToSend.capacity() < size) {
throw new IllegalArgumentException("buffer is too small, must be at least " + size);
}
return SPIJNI.spiWrite(m_port, dataToSend, (byte) size);
}
/**
* Read a word from the receive FIFO.
*
* Waits for the current transfer to complete if the receive FIFO is empty.
* <p>Waits for the current transfer to complete if the receive FIFO is empty.
*
* If the receive FIFO is empty, there is no active transfer, and initiate is
* false, errors.
* <p>If the receive FIFO is empty, there is no active transfer, and initiate is false, errors.
*
* @param initiate If true, this function pushes "0" into the transmit buffer
* and initiates a transfer. If false, this function assumes that data
* is already in the receive FIFO from a previous write.
* @param initiate If true, this function pushes "0" into the transmit buffer and initiates a
* transfer. If false, this function assumes that data is already in the receive
* FIFO from a previous write.
*/
public int read(boolean initiate, byte[] dataReceived, int size) {
int retVal = 0;
final int retVal;
ByteBuffer dataReceivedBuffer = ByteBuffer.allocateDirect(size);
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(size);
if (initiate)
if (initiate) {
retVal = SPIJNI.spiTransaction(m_port, dataToSendBuffer, dataReceivedBuffer, (byte) size);
else
} else {
retVal = SPIJNI.spiRead(m_port, dataReceivedBuffer, (byte) size);
}
dataReceivedBuffer.get(dataReceived);
return retVal;
}
@@ -202,25 +197,24 @@ public class SPI extends SensorBase {
/**
* Read a word from the receive FIFO.
*
* Waits for the current transfer to complete if the receive FIFO is empty.
* <p>Waits for the current transfer to complete if the receive FIFO is empty.
*
* If the receive FIFO is empty, there is no active transfer, and initiate is
* false, errors.
* <p>If the receive FIFO is empty, there is no active transfer, and initiate is false, errors.
*
* @param initiate If true, this function pushes "0" into the transmit buffer
* and initiates a transfer. If false, this function assumes that data
* is already in the receive FIFO from a previous write.
*
* @param dataReceived The buffer to be filled with the received data. Must be
* created using ByteBuffer.allocateDirect().
*
* @param size The length of the transaction, in bytes
* @param initiate If true, this function pushes "0" into the transmit buffer and initiates
* a transfer. If false, this function assumes that data is already in the
* receive FIFO from a previous write.
* @param dataReceived The buffer to be filled with the received data. Must be created using
* ByteBuffer.allocateDirect().
* @param size The length of the transaction, in bytes
*/
public int read(boolean initiate, ByteBuffer dataReceived, int size) {
if (!dataReceived.isDirect())
if (!dataReceived.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (dataReceived.capacity() < size)
}
if (dataReceived.capacity() < size) {
throw new IllegalArgumentException("buffer is too small, must be at least " + size);
}
if (initiate) {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(size);
return SPIJNI.spiTransaction(m_port, dataToSendBuffer, dataReceived, (byte) size);
@@ -229,11 +223,11 @@ public class SPI extends SensorBase {
}
/**
* Perform a simultaneous read/write transaction with the device
* Perform a simultaneous read/write transaction with the device.
*
* @param dataToSend The data to be written out to the device
* @param dataToSend The data to be written out to the device
* @param dataReceived Buffer to receive data from the device
* @param size The length of the transaction, in bytes
* @param size The length of the transaction, in bytes
*/
public int transaction(byte[] dataToSend, byte[] dataReceived, int size) {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(size);
@@ -247,46 +241,48 @@ public class SPI extends SensorBase {
/**
* Perform a simultaneous read/write transaction with the device
*
* @param dataToSend The data to be written out to the device. Must be
* created using ByteBuffer.allocateDirect().
* @param dataReceived Buffer to receive data from the device. Must be
* created using ByteBuffer.allocateDirect().
* @param size The length of the transaction, in bytes
* @param dataToSend The data to be written out to the device. Must be created using
* ByteBuffer.allocateDirect().
* @param dataReceived Buffer to receive data from the device. Must be created using
* ByteBuffer.allocateDirect().
* @param size The length of the transaction, in bytes
*/
public int transaction(ByteBuffer dataToSend, ByteBuffer dataReceived, int size) {
if (!dataToSend.isDirect())
if (!dataToSend.isDirect()) {
throw new IllegalArgumentException("dataToSend must be a direct buffer");
if (dataToSend.capacity() < size)
}
if (dataToSend.capacity() < size) {
throw new IllegalArgumentException("dataToSend is too small, must be at least " + size);
if (!dataReceived.isDirect())
}
if (!dataReceived.isDirect()) {
throw new IllegalArgumentException("dataReceived must be a direct buffer");
if (dataReceived.capacity() < size)
}
if (dataReceived.capacity() < size) {
throw new IllegalArgumentException("dataReceived is too small, must be at least " + size);
}
return SPIJNI.spiTransaction(m_port, dataToSend, dataReceived, (byte) size);
}
/**
* Initialize the accumulator.
*
* @param period Time between reads
* @param cmd SPI command to send to request data
* @param xfer_size SPI transfer size, in bytes
* @param valid_mask Mask to apply to received data for validity checking
* @param valid_data After valid_mask is applied, required matching value for
* validity checking
* @param data_shift Bit shift to apply to received data to get actual data
* value
* @param data_size Size (in bits) of data field
* @param is_signed Is data field signed?
* @param big_endian Is device big endian?
* @param period Time between reads
* @param cmd SPI command to send to request data
* @param xferSize SPI transfer size, in bytes
* @param validMask Mask to apply to received data for validity checking
* @param validValue After validMask is applied, required matching value for validity checking
* @param dataShift Bit shift to apply to received data to get actual data value
* @param dataSize Size (in bits) of data field
* @param isSigned Is data field signed?
* @param bigEndian Is device big endian?
*/
public void initAccumulator(double period, int cmd, int xfer_size,
int valid_mask, int valid_value,
int data_shift, int data_size,
boolean is_signed, boolean big_endian) {
SPIJNI.spiInitAccumulator(m_port, (int)(period * 1.0e6), cmd,
(byte)xfer_size, valid_mask, valid_value, (byte)data_shift,
(byte)data_size, is_signed, big_endian);
public void initAccumulator(double period, int cmd, int xferSize,
int validMask, int validValue,
int dataShift, int dataSize,
boolean isSigned, boolean bigEndian) {
SPIJNI.spiInitAccumulator(m_port, (int) (period * 1.0e6), cmd,
(byte) xferSize, validMask, validValue, (byte) dataShift,
(byte) dataSize, isSigned, bigEndian);
}
/**
@@ -306,7 +302,7 @@ public class SPI extends SensorBase {
/**
* Set the center value of the accumulator.
*
* The center value is subtracted from each value before it is added to the accumulator. This
* <p>The center value is subtracted from each value before it is added to the accumulator. This
* is used for the center value of devices like gyros and accelerometers to make integration work
* and to take the device offset into account when integrating.
*/
@@ -340,7 +336,7 @@ public class SPI extends SensorBase {
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last Reset().
* <p>Read the count of the accumulated values since the accumulator was last Reset().
*
* @return The number of times samples from the channel were accumulated.
*/
@@ -360,8 +356,7 @@ public class SPI extends SensorBase {
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* This function reads the value and count atomically.
* This can be used for averaging.
* <p>This function reads the value and count atomically. This can be used for averaging.
*
* @param result AccumulatorResult object to store the results in.
*/

View File

@@ -8,37 +8,30 @@
package edu.wpi.first.wpilibj;
/**
* Manages a PWM object.
*
* @author brad
*/
public class SafePWM extends PWM implements MotorSafety {
private MotorSafetyHelper m_safetyHelper;
private final MotorSafetyHelper m_safetyHelper;
/**
* Initialize a SafePWM object by setting defaults
* Constructor for a SafePWM object taking a channel number.
*
* @param channel The channel number to be used for the underlying PWM object. 0-9 are on-board,
* 10-19 are on the MXP port.
*/
void initSafePWM() {
public SafePWM(final int channel) {
super(channel);
m_safetyHelper = new MotorSafetyHelper(this);
m_safetyHelper.setExpiration(0.0);
m_safetyHelper.setSafetyEnabled(false);
}
/**
* Constructor for a SafePWM object taking a channel number
*$
* @param channel The channel number to be used for the underlying PWM object.
* 0-9 are on-board, 10-19 are on the MXP port.
*/
public SafePWM(final int channel) {
super(channel);
initSafePWM();
}
/*
* Set the expiration time for the PWM object
*$
* Set the expiration time for the PWM object.
*
* @param timeout The timeout (in seconds) for this motor object
*/
public void setExpiration(double timeout) {
@@ -47,7 +40,7 @@ public class SafePWM extends PWM implements MotorSafety {
/**
* Return the expiration time for the PWM object.
*$
*
* @return The expiration time value.
*/
public double getExpiration() {
@@ -56,26 +49,24 @@ public class SafePWM extends PWM implements MotorSafety {
/**
* Check if the PWM object is currently alive or stopped due to a timeout.
*$
* @return a bool value that is true if the motor has NOT timed out and should
* still be running.
*
* @return a bool value that is true if the motor has NOT timed out and should still be running.
*/
public boolean isAlive() {
return m_safetyHelper.isAlive();
}
/**
* Stop the motor associated with this PWM object. This is called by the
* MotorSafetyHelper object when it has a timeout for this PWM and needs to
* stop it from running.
* Stop the motor associated with this PWM object. This is called by the MotorSafetyHelper object
* when it has a timeout for this PWM and needs to stop it from running.
*/
public void stopMotor() {
disable();
}
/**
* Check if motor safety is enabled for this object
*$
* Check if motor safety is enabled for this object.
*
* @return True if motor safety is enforced for this object
*/
public boolean isSafetyEnabled() {
@@ -83,9 +74,10 @@ public class SafePWM extends PWM implements MotorSafety {
}
/**
* Feed the MotorSafety timer. This method is called by the subclass motor
* whenever it updates its speed, thereby reseting the timeout value.
* Feed the MotorSafety timer. This method is called by the subclass motor whenever it updates its
* speed, thereby reseting the timeout value.
*/
@SuppressWarnings("MethodName")
public void Feed() {
m_safetyHelper.feed();
}

View File

@@ -7,31 +7,29 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* A simple robot base class that knows the standard FRC competition states
* (disabled, autonomous, or operator controlled).
* A simple robot base class that knows the standard FRC competition states (disabled, autonomous,
* or operator controlled).
*
* You can build a simple robot program off of this by overriding the
* robotinit(), disabled(), autonomous() and operatorControl() methods. The
* startCompetition() method will calls these methods (sometimes repeatedly).
* depending on the state of the competition.
* <p>You can build a simple robot program off of this by overriding the robotinit(), disabled(),
* autonomous() and operatorControl() methods. The startCompetition() method will calls these
* methods (sometimes repeatedly). depending on the state of the competition.
*
* Alternatively you can override the robotMain() method and manage all aspects
* of the robot yourself.
* <p>Alternatively you can override the robotMain() method and manage all aspects of the robot
* yourself.
*/
public class SampleRobot extends RobotBase {
private boolean m_robotMainOverridden;
/**
* Create a new SampleRobot
* Create a new SampleRobot.
*/
public SampleRobot() {
super();
@@ -41,53 +39,50 @@ public class SampleRobot extends RobotBase {
/**
* Robot-wide initialization code should go here.
*
* Users should override this method for default Robot-wide initialization
* which will be called when the robot is first powered on. It will be called
* exactly one time.
* <p>Users should override this method for default Robot-wide initialization which will be called
* when the robot is first powered on. It will be called exactly one time.
*
* Warning: the Driver Station "Robot Code" light and FMS "Robot Ready"
* indicators will be off until RobotInit() exits. Code in RobotInit() that
* waits for enable will cause the robot to never indicate that the code is
* ready, causing the robot to be bypassed in a match.
* <p>Warning: the Driver Station "Robot Code" light and FMS "Robot Ready" indicators will be off
* until RobotInit() exits. Code in RobotInit() that waits for enable will cause the robot to
* never indicate that the code is ready, causing the robot to be bypassed in a match.
*/
protected void robotInit() {
System.out.println("Default robotInit() method running, consider providing your own");
}
/**
* Disabled should go here. Users should overload this method to run code that
* should run while the field is disabled.
* Disabled should go here. Users should overload this method to run code that should run while
* the field is disabled.
*
* Called once each time the robot enters the disabled state.
* <p>Called once each time the robot enters the disabled state.
*/
protected void disabled() {
System.out.println("Default disabled() method running, consider providing your own");
}
/**
* Autonomous should go here. Users should add autonomous code to this method
* that should run while the field is in the autonomous period.
* Autonomous should go here. Users should add autonomous code to this method that should run
* while the field is in the autonomous period.
*
* Called once each time the robot enters the autonomous state.
* <p>Called once each time the robot enters the autonomous state.
*/
public void autonomous() {
System.out.println("Default autonomous() method running, consider providing your own");
}
/**
* Operator control (tele-operated) code should go here. Users should add
* Operator Control code to this method that should run while the field is in
* the Operator Control (tele-operated) period.
* Operator control (tele-operated) code should go here. Users should add Operator Control code to
* this method that should run while the field is in the Operator Control (tele-operated) period.
*
* Called once each time the robot enters the operator-controlled state.
* <p>Called once each time the robot enters the operator-controlled state.
*/
public void operatorControl() {
System.out.println("Default operatorControl() method running, consider providing your own");
}
/**
* Test code should go here. Users should add test code to this method that
* should run while the robot is in test mode.
* Test code should go here. Users should add test code to this method that should run while the
* robot is in test mode.
*/
public void test() {
System.out.println("Default test() method running, consider providing your own");
@@ -96,27 +91,24 @@ public class SampleRobot extends RobotBase {
/**
* Robot main program for free-form programs.
*
* This should be overridden by user subclasses if the intent is to not use
* the autonomous() and operatorControl() methods. In that case, the program
* is responsible for sensing when to run the autonomous and operator control
* functions in their program.
* <p>This should be overridden by user subclasses if the intent is to not use the autonomous()
* and operatorControl() methods. In that case, the program is responsible for sensing when to run
* the autonomous and operator control functions in their program.
*
* This method will be called immediately after the constructor is called. If
* it has not been overridden by a user subclass (i.e. the default version
* runs), then the robotInit(), disabled(), autonomous() and operatorControl()
* methods will be called.
* <p>This method will be called immediately after the constructor is called. If it has not been
* overridden by a user subclass (i.e. the default version runs), then the robotInit(),
* disabled(), autonomous() and operatorControl() methods will be called.
*/
public void robotMain() {
m_robotMainOverridden = false;
}
/**
* Start a competition. This code tracks the order of the field starting to
* ensure that everything happens in the right order. Repeatedly run the
* correct method, either Autonomous or OperatorControl when the robot is
* enabled. After running the correct method, wait for some state to change,
* either the other mode starts or the robot is disabled. Then go back and
* wait for the robot to be enabled again.
* Start a competition. This code tracks the order of the field starting to ensure that everything
* happens in the right order. Repeatedly run the correct method, either Autonomous or
* OperatorControl when the robot is enabled. After running the correct method, wait for some
* state to change, either the other mode starts or the robot is disabled. Then go back and wait
* for the robot to be enabled again.
*/
public void startCompetition() {
UsageReporting.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Sample);
@@ -151,8 +143,9 @@ public class SampleRobot extends RobotBase {
m_ds.InTest(true);
test();
m_ds.InTest(false);
while (isTest() && isEnabled())
while (isTest() && isEnabled()) {
Timer.delay(0.01);
}
LiveWindow.setEnabled(false);
} else {
m_ds.InOperatorControl(true);

View File

@@ -8,7 +8,6 @@
package edu.wpi.first.wpilibj;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
@@ -18,14 +17,13 @@ import edu.wpi.first.wpilibj.hal.SerialPortJNI;
/**
* Driver for the RS-232 serial port on the RoboRIO.
*
* The current implementation uses the VISA formatted I/O mode. This means that
* all traffic goes through the formatted buffers. This allows the intermingled
* use of print(), readString(), and the raw buffer accessors read() and
* write().
* <p>The current implementation uses the VISA formatted I/O mode. This means that all traffic goes
* through the formatted buffers. This allows the intermingled use of print(), readString(), and the
* raw buffer accessors read() and write().
*
* More information can be found in the NI-VISA User Manual here:
* http://www.ni.com/pdf/manuals/370423a.pdf and the NI-VISA Programmer's
* Reference Manual here: http://www.ni.com/pdf/manuals/370132c.pdf
* <p>More information can be found in the NI-VISA User Manual here: http://www.ni
* .com/pdf/manuals/370423a.pdf and the NI-VISA Programmer's Reference Manual here:
* http://www.ni.com/pdf/manuals/370132c.pdf
*/
public class SerialPort {
@@ -34,25 +32,26 @@ public class SerialPort {
public enum Port {
kOnboard(0), kMXP(1), kUSB(2);
private int value;
private int m_value;
private Port(int value) {
this.value = value;
Port(int value) {
m_value = value;
}
public int getValue() {
return this.value;
return m_value;
}
};
}
/**
* Represents the parity to use for serial communications
* Represents the parity to use for serial communications.
*/
public static class Parity {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kNone_val = 0;
static final int kOdd_val = 1;
@@ -60,23 +59,23 @@ public class SerialPort {
static final int kMark_val = 3;
static final int kSpace_val = 4;
/**
* parity: Use no parity
* parity: Use no parity.
*/
public static final Parity kNone = new Parity(kNone_val);
/**
* parity: Use odd parity
* parity: Use odd parity.
*/
public static final Parity kOdd = new Parity(kOdd_val);
/**
* parity: Use even parity
* parity: Use even parity.
*/
public static final Parity kEven = new Parity(kEven_val);
/**
* parity: Use mark parity
* parity: Use mark parity.
*/
public static final Parity kMark = new Parity(kMark_val);
/**
* parity: Use space parity
* parity: Use space parity.
*/
public static final Parity kSpace = new Parity((kSpace_val));
@@ -86,27 +85,28 @@ public class SerialPort {
}
/**
* Represents the number of stop bits to use for Serial Communication
* Represents the number of stop bits to use for Serial Communication.
*/
public static class StopBits {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kOne_val = 10;
static final int kOnePointFive_val = 15;
static final int kTwo_val = 20;
/**
* stopBits: use 1
* stopBits: use 1.
*/
public static final StopBits kOne = new StopBits(kOne_val);
/**
* stopBits: use 1.5
* stopBits: use 1.5.
*/
public static final StopBits kOnePointFive = new StopBits(kOnePointFive_val);
/**
* stopBits: use 2
* stopBits: use 2.
*/
public static final StopBits kTwo = new StopBits(kTwo_val);
@@ -116,32 +116,33 @@ public class SerialPort {
}
/**
* Represents what type of flow control to use for serial communication
* Represents what type of flow control to use for serial communication.
*/
public static class FlowControl {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kNone_val = 0;
static final int kXonXoff_val = 1;
static final int kRtsCts_val = 2;
static final int kDtrDsr_val = 4;
/**
* flowControl: use none
* flowControl: use none.
*/
public static final FlowControl kNone = new FlowControl(kNone_val);
/**
* flowcontrol: use on/off
* flowcontrol: use on/off.
*/
public static final FlowControl kXonXoff = new FlowControl(kXonXoff_val);
/**
* flowcontrol: use rts cts
* flowcontrol: use rts cts.
*/
public static final FlowControl kRtsCts = new FlowControl(kRtsCts_val);
/**
* flowcontrol: use dts dsr
* flowcontrol: use dts dsr.
*/
public static final FlowControl kDtrDsr = new FlowControl(kDtrDsr_val);
@@ -151,22 +152,23 @@ public class SerialPort {
}
/**
* Represents which type of buffer mode to use when writing to a serial port
* Represents which type of buffer mode to use when writing to a serial m_port.
*/
public static class WriteBufferMode {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kFlushOnAccess_val = 1;
static final int kFlushWhenFull_val = 2;
/**
* Flush on access
* Flush on access.
*/
public static final WriteBufferMode kFlushOnAccess = new WriteBufferMode(kFlushOnAccess_val);
/**
* Flush when full
* Flush when full.
*/
public static final WriteBufferMode kFlushWhenFull = new WriteBufferMode(kFlushWhenFull_val);
@@ -179,15 +181,13 @@ public class SerialPort {
* Create an instance of a Serial Port class.
*
* @param baudRate The baud rate to configure the serial port.
* @param port The Serial port to use
* @param dataBits The number of data bits per transfer. Valid values are
* between 5 and 8 bits.
* @param parity Select the type of parity checking to use.
* @param stopBits The number of stop bits to use as defined by the enum
* StopBits.
* @param port The Serial port to use
* @param dataBits The number of data bits per transfer. Valid values are between 5 and 8 bits.
* @param parity Select the type of parity checking to use.
* @param stopBits The number of stop bits to use as defined by the enum StopBits.
*/
public SerialPort(final int baudRate, Port port, final int dataBits, Parity parity,
StopBits stopBits) {
StopBits stopBits) {
m_port = (byte) port.getValue();
SerialPortJNI.serialInitializePort(m_port);
@@ -214,29 +214,26 @@ public class SerialPort {
* Create an instance of a Serial Port class. Defaults to one stop bit.
*
* @param baudRate The baud rate to configure the serial port.
* @param dataBits The number of data bits per transfer. Valid values are
* between 5 and 8 bits.
* @param parity Select the type of parity checking to use.
* @param dataBits The number of data bits per transfer. Valid values are between 5 and 8 bits.
* @param parity Select the type of parity checking to use.
*/
public SerialPort(final int baudRate, Port port, final int dataBits, Parity parity) {
this(baudRate, port, dataBits, parity, StopBits.kOne);
}
/**
* Create an instance of a Serial Port class. Defaults to no parity and one
* stop bit.
* Create an instance of a Serial Port class. Defaults to no parity and one stop bit.
*
* @param baudRate The baud rate to configure the serial port.
* @param dataBits The number of data bits per transfer. Valid values are
* between 5 and 8 bits.
* @param dataBits The number of data bits per transfer. Valid values are between 5 and 8 bits.
*/
public SerialPort(final int baudRate, Port port, final int dataBits) {
this(baudRate, port, dataBits, Parity.kNone, StopBits.kOne);
}
/**
* Create an instance of a Serial Port class. Defaults to 8 databits, no
* parity, and one stop bit.
* Create an instance of a Serial Port class. Defaults to 8 databits, no parity, and one stop
* bit.
*
* @param baudRate The baud rate to configure the serial port.
*/
@@ -254,9 +251,9 @@ public class SerialPort {
/**
* Set the type of flow control to enable on this port.
*
* By default, flow control is disabled.
*$
* @param flowControl the FlowControl value to use
* <p>By default, flow control is disabled.
*
* @param flowControl the FlowControl m_value to use
*/
public void setFlowControl(FlowControl flowControl) {
SerialPortJNI.serialSetFlowControl(m_port, (byte) flowControl.value);
@@ -265,9 +262,9 @@ public class SerialPort {
/**
* Enable termination and specify the termination character.
*
* Termination is currently only implemented for receive. When the the
* terminator is received, the read() or readString() will return fewer bytes
* than requested, stopping after the terminator.
* <p>Termination is currently only implemented for receive. When the the terminator is received,
* the read() or readString() will return fewer bytes than requested, stopping after the
* terminator.
*
* @param terminator The character to use for termination.
*/
@@ -278,14 +275,14 @@ public class SerialPort {
/**
* Enable termination with the default terminator '\n'
*
* Termination is currently only implemented for receive. When the the
* terminator is received, the read() or readString() will return fewer bytes
* than requested, stopping after the terminator.
* <p>Termination is currently only implemented for receive. When the the terminator is received,
* the read() or readString() will return fewer bytes than requested, stopping after the
* terminator.
*
* The default terminator is '\n'
* <p>The default terminator is '\n'
*/
public void enableTermination() {
this.enableTermination('\n');
enableTermination('\n');
}
/**
@@ -325,7 +322,7 @@ public class SerialPort {
return new String(out, 0, out.length, "US-ASCII");
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
return new String();
return "";
}
}
@@ -347,7 +344,7 @@ public class SerialPort {
* Write raw bytes to the serial port.
*
* @param buffer The buffer of bytes to write.
* @param count The maximum number of bytes to write.
* @param count The maximum number of bytes to write.
* @return The number of bytes actually written into the port.
*/
public int write(byte[] buffer, int count) {
@@ -367,11 +364,10 @@ public class SerialPort {
}
/**
* Configure the timeout of the serial port.
* Configure the timeout of the serial m_port.
*
* This defines the timeout for transactions with the hardware. It will affect
* reads if less bytes are available than the read buffer size (defaults to 1)
* and very large writes.
* <p>This defines the timeout for transactions with the hardware. It will affect reads if less
* bytes are available than the read buffer size (defaults to 1) and very large writes.
*
* @param timeout The number of seconds to to wait for I/O.
*/
@@ -382,12 +378,11 @@ public class SerialPort {
/**
* Specify the size of the input buffer.
*
* Specify the amount of data that can be stored before data from the device
* is returned to Read. If you want data that is received to be returned
* immediately, set this to 1.
* <p>Specify the amount of data that can be stored before data from the device is returned to
* Read. If you want data that is received to be returned immediately, set this to 1.
*
* It the buffer is not filled before the read timeout expires, all data that
* has been received so far will be returned.
* <p>It the buffer is not filled before the read timeout expires, all data that has been received
* so far will be returned.
*
* @param size The read buffer size.
*/
@@ -398,8 +393,7 @@ public class SerialPort {
/**
* Specify the size of the output buffer.
*
* Specify the amount of data that can be stored before being transmitted to
* the device.
* <p>Specify the amount of data that can be stored before being transmitted to the device.
*
* @param size The write buffer size.
*/
@@ -410,11 +404,11 @@ public class SerialPort {
/**
* Specify the flushing behavior of the output buffer.
*
* When set to kFlushOnAccess, data is synchronously written to the serial
* port after each call to either print() or write().
* <p>When set to kFlushOnAccess, data is synchronously written to the serial port after each
* call to either print() or write().
*
* When set to kFlushWhenFull, data will only be written to the serial port
* when the buffer is full or when flush() is called.
* <p>When set to kFlushWhenFull, data will only be written to the serial port when the buffer
* is full or when flush() is called.
*
* @param mode The write buffer mode.
*/
@@ -425,8 +419,8 @@ public class SerialPort {
/**
* Force the output buffer to be written to the port.
*
* This is used when setWriteBufferMode() is set to kFlushWhenFull to force a
* flush before the buffer is full.
* <p>This is used when setWriteBufferMode() is set to kFlushWhenFull to force a flush before the
* buffer is full.
*/
public void flush() {
SerialPortJNI.serialFlush(m_port);
@@ -435,7 +429,7 @@ public class SerialPort {
/**
* Reset the serial port driver to a known state.
*
* Empty the transmit and receive buffers in the device and formatted I/O.
* <p>Empty the transmit and receive buffers in the device and formatted I/O.
*/
public void reset() {
SerialPortJNI.serialClear(m_port);

View File

@@ -16,8 +16,8 @@ import edu.wpi.first.wpilibj.tables.ITableListener;
/**
* Standard hobby style servo.
*
* The range parameters default to the appropriate values for the Hitec HS-322HD
* servo provided in the FIRST Kit of Parts in 2008.
* <p>The range parameters default to the appropriate values for the Hitec HS-322HD servo provided
* in the FIRST Kit of Parts in 2008.
*/
public class Servo extends PWM {
@@ -30,10 +30,8 @@ public class Servo extends PWM {
/**
* Common initialization code called by all constructors.
*
* InitServo() assigns defaults for the period multiplier for the servo PWM
* control signal, as well as the minimum and maximum PWM values supported by
* the servo.
*
* <p>InitServo() assigns defaults for the period multiplier for the servo PWM control signal, as
* well as the minimum and maximum PWM values supported by the servo.
*/
private void initServo() {
setBounds(kDefaultMaxServoPWM, 0, 0, 0, kDefaultMinServoPWM);
@@ -46,11 +44,11 @@ public class Servo extends PWM {
/**
* Constructor.<br>
*
* By default {@value #kDefaultMaxServoPWM} ms is used as the maxPWM value<br>
* By default {@value #kDefaultMinServoPWM} ms is used as the minPWM value<br>
* <p>By default {@value #kDefaultMaxServoPWM} ms is used as the maxPWM value<br> By default
* {@value #kDefaultMinServoPWM} ms is used as the minPWM value<br>
*
* @param channel The PWM channel to which the servo is attached. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel to which the servo is attached. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Servo(final int channel) {
super(channel);
@@ -61,8 +59,7 @@ public class Servo extends PWM {
/**
* Set the servo position.
*
* Servo values range from 0.0 to 1.0 corresponding to the range of full left
* to full right.
* <p>Servo values range from 0.0 to 1.0 corresponding to the range of full left to full right.
*
* @param value Position from 0.0 to 1.0.
*/
@@ -73,8 +70,7 @@ public class Servo extends PWM {
/**
* Get the servo position.
*
* Servo values range from 0.0 to 1.0 corresponding to the range of full left
* to full right.
* <p>Servo values range from 0.0 to 1.0 corresponding to the range of full left to full right.
*
* @return Position from 0.0 to 1.0.
*/
@@ -85,14 +81,13 @@ public class Servo extends PWM {
/**
* Set the servo angle.
*
* Assume that the servo angle is linear with respect to the PWM value (big
* assumption, need to test).
* <p>Assume that the servo angle is linear with respect to the PWM value (big assumption, need to
* test).
*
* Servo angles that are out of the supported range of the servo simply
* "saturate" in that direction In other words, if the servo has a range of (X
* degrees to Y degrees) than angles of less than X result in an angle of X
* being set and angles of more than Y degrees result in an angle of Y being
* set.
* <p>Servo angles that are out of the supported range of the servo simply "saturate" in that
* direction In other words, if the servo has a range of (X degrees to Y degrees) than angles of
* less than X result in an angle of X being set and angles of more than Y degrees result in an
* angle of Y being set.
*
* @param degrees The angle in degrees to set the servo.
*/
@@ -109,9 +104,9 @@ public class Servo extends PWM {
/**
* Get the servo angle.
*
* Assume that the servo angle is linear with respect to the PWM value (big
* assumption, need to test).
*$
* <p>Assume that the servo angle is linear with respect to the PWM value (big assumption, need to
* test).
*
* @return The angle in degrees to which the servo is set.
*/
public double getAngle() {
@@ -130,42 +125,34 @@ public class Servo extends PWM {
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", get());
}
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
set(((Double) value).doubleValue());
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -20,13 +20,13 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Solenoid class for running high voltage Digital Output.
*
* The Solenoid class is typically used for pneumatics solenoids, but could be
* used for any device within the current spec of the PCM.
* <p>The Solenoid class is typically used for pneumatics solenoids, but could be used for any
* device within the current spec of the PCM.
*/
public class Solenoid extends SolenoidBase implements LiveWindowSendable {
private int m_channel; // /< The channel to control.
private long m_solenoid_port;
private final int m_channel; // /< The channel to control.
private long m_solenoidPort;
/**
* Common function to implement constructor behavior.
@@ -36,14 +36,14 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
checkSolenoidChannel(m_channel);
try {
m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_channel);
} catch (CheckedAllocationException e) {
allocated.allocate(m_moduleNumber * kSolenoidChannels + m_channel);
} catch (CheckedAllocationException ex) {
throw new AllocationException("Solenoid channel " + m_channel + " on module "
+ m_moduleNumber + " is already allocated");
+ m_moduleNumber + " is already allocated");
}
long port = SolenoidJNI.getPortWithModule((byte) m_moduleNumber, (byte) m_channel);
m_solenoid_port = SolenoidJNI.initializeSolenoidPort(port);
m_solenoidPort = SolenoidJNI.initializeSolenoidPort(port);
LiveWindow.addActuator("Solenoid", m_moduleNumber, m_channel, this);
UsageReporting.report(tResourceType.kResourceType_Solenoid, m_channel, m_moduleNumber);
@@ -64,7 +64,7 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
* Constructor.
*
* @param moduleNumber The CAN ID of the PCM the solenoid is attached to.
* @param channel The channel on the PCM to control (0..7).
* @param channel The channel on the PCM to control (0..7).
*/
public Solenoid(final int moduleNumber, final int channel) {
super(moduleNumber);
@@ -76,9 +76,9 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
* Destructor.
*/
public synchronized void free() {
m_allocated.free(m_moduleNumber * kSolenoidChannels + m_channel);
SolenoidJNI.freeSolenoidPort(m_solenoid_port);
m_solenoid_port = 0;
allocated.free(m_moduleNumber * kSolenoidChannels + m_channel);
SolenoidJNI.freeSolenoidPort(m_solenoidPort);
m_solenoidPort = 0;
super.free();
}
@@ -105,12 +105,11 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
}
/**
* Check if solenoid is blacklisted. If a solenoid is shorted, it is added to
* the blacklist and disabled until power cycle, or until faults are cleared.
*
* @see #clearAllPCMStickyFaults()
* Check if solenoid is blacklisted. If a solenoid is shorted, it is added to the blacklist and
* disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isBlackListed() {
int value = getPCMSolenoidBlackList() & (1 << m_channel);
@@ -125,26 +124,20 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putBoolean("Value", get());
@@ -152,25 +145,17 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
set(false); // Stop for safety
m_table_listener = new ITableListener() {
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
set(((Boolean) value).booleanValue());
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_tableListener = (itable, key, value, bln) -> set((Boolean) value);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
set(false); // Stop for safety
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -10,15 +10,14 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.hal.SolenoidJNI;
/**
* SolenoidBase class is the common base class for the Solenoid and
* DoubleSolenoid classes.
* SolenoidBase class is the common base class for the Solenoid and DoubleSolenoid classes.
*/
public abstract class SolenoidBase extends SensorBase {
private long[] m_ports;
protected int m_moduleNumber; // /< The number of the solenoid module being
// used.
protected static Resource m_allocated = new Resource(63 * SensorBase.kSolenoidChannels);
private final long[] m_ports;
protected final int m_moduleNumber; // /< The number of the solenoid module being
// used.
protected static final Resource allocated = new Resource(63 * SensorBase.kSolenoidChannels);
/**
* Constructor.
@@ -49,18 +48,19 @@ public abstract class SolenoidBase extends SensorBase {
* Set the value of a solenoid.
*
* @param value The value you want to set on the module.
* @param mask The channels you want to be affected.
* @param mask The channels you want to be affected.
*/
protected synchronized void set(int value, int mask) {
for (int i = 0; i < SensorBase.kSolenoidChannels; i++) {
int local_mask = 1 << i;
if ((mask & local_mask) != 0)
SolenoidJNI.setSolenoid(m_ports[i], (value & local_mask) != 0);
int localMask = 1 << i;
if ((mask & localMask) != 0) {
SolenoidJNI.setSolenoid(m_ports[i], (value & localMask) != 0);
}
}
}
/**
* Read all 8 solenoids from the module used by this solenoid as a single byte
* Read all 8 solenoids from the module used by this solenoid as a single byte.
*
* @return The current value of all 8 solenoids on this module.
*/
@@ -69,30 +69,32 @@ public abstract class SolenoidBase extends SensorBase {
}
/**
* Reads complete solenoid blacklist for all 8 solenoids as a single byte.
*$
* If a solenoid is shorted, it is added to the blacklist and disabled until
* power cycle, or until faults are cleared.
* Reads complete solenoid blacklist for all 8 solenoids as a single byte. If a solenoid is
* shorted, it is added to the blacklist and disabled until power cycle, or until faults are
* cleared.
*
* @see #clearAllPCMStickyFaults()
*$
* @return The solenoid blacklist of all 8 solenoids on the module.
* @see #clearAllPCMStickyFaults()
*/
public byte getPCMSolenoidBlackList() {
return (byte)SolenoidJNI.getPCMSolenoidBlackList(m_ports[0]);
return (byte) SolenoidJNI.getPCMSolenoidBlackList(m_ports[0]);
}
/**
* @return true if PCM sticky fault is set : The common highside solenoid
* voltage rail is too low, most likely a solenoid channel is shorted.
* If true, the common highside solenoid voltage rail is too low, most likely a solenoid channel
* is shorted.
*
* @return true if PCM sticky fault is set
*/
public boolean getPCMSolenoidVoltageStickyFault() {
return SolenoidJNI.getPCMSolenoidVoltageStickyFault(m_ports[0]);
}
/**
* @return true if PCM is in fault state : The common highside solenoid
* voltage rail is too low, most likely a solenoid channel is shorted.
* The common highside solenoid voltage rail is too low, most likely a solenoid channel is
* shorted.
*
* @return true if PCM is in fault state.
*/
public boolean getPCMSolenoidVoltageFault() {
return SolenoidJNI.getPCMSolenoidVoltageFault(m_ports[0]);
@@ -101,12 +103,11 @@ public abstract class SolenoidBase extends SensorBase {
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* If a sticky fault is set, then it will be persistently cleared. Compressor
* drive maybe momentarily disable while flags are being cleared. Care should
* be taken to not call this too frequently, otherwise normal compressor
* functionality may be prevented.
* <p>If a sticky fault is set, then it will be persistently cleared. Compressor drive maybe
* momentarily disable while flags are being cleared. Care should be taken to not call this too
* frequently, otherwise normal compressor functionality may be prevented.
*
* If no sticky faults are set then this call will have no effect.
* <p>If no sticky faults are set then this call will have no effect.
*/
public void clearAllPCMStickyFaults() {
SolenoidJNI.clearAllPCMStickyFaults(m_ports[0]);

View File

@@ -12,23 +12,22 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* REV Robotics SPARK Speed Controller
* REV Robotics SPARK Speed Controller.
*/
public class Spark extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* Note that the SPARK uses the following bounds for PWM values. These
* values should work reasonably well for most controllers, but if users
* experience issues such as asymmetric behavior around the deadband or
* inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the Spark User
* Manual available from REV Robotics.
* <p>Note that the SPARK uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the Spark User Manual
* available from REV Robotics.
*
* - 2.003ms = full "forward" - 1.55ms = the "high end" of the deadband range
* - 1.50ms = center of the deadband range (off) - 1.46ms = the "low end" of
* the deadband range - .999ms = full "reverse"
* <p>- 2.003ms = full "forward" - 1.55ms = the "high end" of the deadband range - 1.50ms =
* center of the deadband range (off) - 1.46ms = the "low end" of the deadband range - .999ms =
* full "reverse"
*/
protected void initSpark() {
setBounds(2.003, 1.55, 1.50, 1.46, .999);
@@ -43,8 +42,8 @@ public class Spark extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the SPARK is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the SPARK is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Spark(final int channel) {
super(channel);

View File

@@ -12,23 +12,22 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Cross the Road Electronics (CTRE) Talon and Talon SR Speed Controller
* Cross the Road Electronics (CTRE) Talon and Talon SR Speed Controller.
*/
public class Talon extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* Note that the Talon uses the following bounds for PWM values. These values
* should work reasonably well for most controllers, but if users experience
* issues such as asymmetric behavior around the deadband or inability to
* saturate the controller in either direction, calibration is recommended.
* The calibration procedure can be found in the Talon User Manual available
* from CTRE.
* <p>Note that the Talon uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the Talon User Manual
* available from CTRE.
*
* - 2.037ms = full "forward" - 1.539ms = the "high end" of the deadband range
* - 1.513ms = center of the deadband range (off) - 1.487ms = the "low end" of
* the deadband range - .989ms = full "reverse"
* <p>- 2.037ms = full "forward" - 1.539ms = the "high end" of the deadband range - 1.513ms =
* center of the deadband range (off) - 1.487ms = the "low end" of the deadband range - .989ms
* = full "reverse"
*/
private void initTalon() {
setBounds(2.037, 1.539, 1.513, 1.487, .989);
@@ -41,10 +40,10 @@ public class Talon extends PWMSpeedController {
}
/**
* Constructor for a Talon (original or Talon SR)
* Constructor for a Talon (original or Talon SR).
*
* @param channel The PWM channel that the Talon is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the Talon is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Talon(final int channel) {
super(channel);

View File

@@ -12,8 +12,8 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control
*$
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control.
*
* @see CANTalon CANTalon for CAN control of Talon SRX
*/
public class TalonSRX extends PWMSpeedController {
@@ -21,16 +21,16 @@ public class TalonSRX extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* Note that the TalonSRX uses the following bounds for PWM values. These
* values should work reasonably well for most controllers, but if users
* experience issues such as asymmetric behavior around the deadband or
* inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the TalonSRX User
* Manual available from CTRE.
* <p>Note that the TalonSRX uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the TalonSRX User Manual
* available from CTRE.
*
* - 2.0004ms = full "forward" - 1.52ms = the "high end" of the deadband range
* - 1.50ms = center of the deadband range (off) - 1.48ms = the "low end" of
* the deadband range - .997ms = full "reverse"
* <p>- 2.0004ms = full "forward" - 1.52ms = the "high end" of the deadband range - 1.50ms =
* center
* of the deadband range (off) - 1.48ms = the "low end" of the deadband range - .997ms = full
* "reverse"
*/
protected void initTalonSRX() {
setBounds(2.004, 1.52, 1.50, 1.48, .997);
@@ -43,10 +43,10 @@ public class TalonSRX extends PWMSpeedController {
}
/**
* Constructor for a TalonSRX connected via PWM
* Constructor for a TalonSRX connected via PWM.
*
* @param channel The PWM channel that the TalonSRX is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the TalonSRX is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public TalonSRX(final int channel) {
super(channel);

View File

@@ -9,104 +9,101 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Ultrasonic rangefinder class. The Ultrasonic rangefinder measures absolute
* distance based on the round-trip time of a ping generated by the controller.
* These sensors use two transducers, a speaker and a microphone both tuned to
* the ultrasonic range. A common ultrasonic sensor, the Daventech SRF04
* requires a short pulse to be generated on a digital channel. This causes the
* chirp to be emmitted. A second line becomes high as the ping is transmitted
* and goes low when the echo is received. The time that the line is high
* determines the round trip distance (time of flight).
* Ultrasonic rangefinder class. The Ultrasonic rangefinder measures absolute distance based on the
* round-trip time of a ping generated by the controller. These sensors use two transducers, a
* speaker and a microphone both tuned to the ultrasonic range. A common ultrasonic sensor, the
* Daventech SRF04 requires a short pulse to be generated on a digital channel. This causes the
* chirp to be emmitted. A second line becomes high as the ping is transmitted and goes low when the
* echo is received. The time that the line is high determines the round trip distance (time of
* flight).
*/
public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSendable {
/**
* The units to return when PIDGet is called
* The units to return when PIDGet is called.
*/
public static enum Unit {
public enum Unit {
/**
* Use inches for PIDGet
* Use inches for PIDGet.
*/
kInches,
/**
* Use millimeters for PIDGet
* Use millimeters for PIDGet.
*/
kMillimeters
}
private static final double kPingTime = 10 * 1e-6; // /< Time (sec) for the
// ping trigger pulse.
private static final int kPriority = 90; // /< Priority that the ultrasonic
// round robin task runs.
private static final double kMaxUltrasonicTime = 0.1; // /< Max time (ms)
// between readings.
// Time (sec) for the ping trigger pulse.
private static final double kPingTime = 10 * 1e-6;
// Priority that the ultrasonic round robin task runs.
private static final int kPriority = 90;
// Max time (ms) between readings.
private static final double kMaxUltrasonicTime = 0.1;
private static final double kSpeedOfSoundInchesPerSec = 1130.0 * 12.0;
private static Ultrasonic m_firstSensor = null; // head of the ultrasonic
// sensor list
private static boolean m_automaticEnabled = false; // automatic round robin
// mode
private DigitalInput m_echoChannel = null;
// head of the ultrasonic sensor list
private static Ultrasonic m_firstSensor = null;
// automatic round robin mode
private static boolean m_automaticEnabled = false;
private DigitalInput m_echoChannel;
private DigitalOutput m_pingChannel = null;
private boolean m_allocatedChannels;
private boolean m_enabled = false;
private Counter m_counter = null;
private Ultrasonic m_nextSensor = null;
private static Thread m_task = null; // task doing the round-robin automatic
// sensing
// task doing the round-robin automatic sensing
private static Thread m_task = null;
private Unit m_units;
private static int m_instances = 0;
protected PIDSourceType m_pidSource = PIDSourceType.kDisplacement;
/**
* Background task that goes through the list of ultrasonic sensors and pings
* each one in turn. The counter is configured to read the timing of the
* returned echo pulse.
* Background task that goes through the list of ultrasonic sensors and pings each one in turn.
* The counter is configured to read the timing of the returned echo pulse.
*
* DANGER WILL ROBINSON, DANGER WILL ROBINSON: This code runs as a task and
* assumes that none of the ultrasonic sensors will change while it's running.
* If one does, then this will certainly break. Make sure to disable automatic
* mode before changing anything with the sensors!!
* <p><b>DANGER WILL ROBINSON, DANGER WILL ROBINSON:</b> This code runs as a task and assumes that
* none of the ultrasonic sensors will change while it's running. If one does, then this will
* certainly break. Make sure to disable automatic mode before changing anything with the
* sensors!!
*/
private class UltrasonicChecker extends Thread {
@Override
public synchronized void run() {
Ultrasonic u = null;
Ultrasonic ultrasonic = null;
while (m_automaticEnabled) {
if (u == null) {
u = m_firstSensor;
if (ultrasonic == null) {
ultrasonic = m_firstSensor;
}
if (u == null) {
if (ultrasonic == null) {
return;
}
if (u.isEnabled()) {
u.m_pingChannel.pulse(m_pingChannel.m_channel, (float) kPingTime); // do
// the
// ping
if (ultrasonic.isEnabled()) {
ultrasonic.m_pingChannel.pulse(m_pingChannel.m_channel, (float) kPingTime); // do
// the
// ping
}
u = u.m_nextSensor;
ultrasonic = ultrasonic.m_nextSensor;
Timer.delay(.1); // wait for ping to return
}
}
}
/**
* Initialize the Ultrasonic Sensor. This is the common code that initializes
* the ultrasonic sensor given that there are two digital I/O channels
* allocated. If the system was running in automatic mode (round robin) when
* the new sensor is added, it is stopped, the sensor is added, then automatic
* mode is restored.
* Initialize the Ultrasonic Sensor. This is the common code that initializes the ultrasonic
* sensor given that there are two digital I/O channels allocated. If the system was running in
* automatic mode (round robin) when the new sensor is added, it is stopped, the sensor is added,
* then automatic mode is restored.
*/
private synchronized void initialize() {
if (m_task == null) {
m_task = new UltrasonicChecker();
}
boolean originalMode = m_automaticEnabled;
final boolean originalMode = m_automaticEnabled;
setAutomaticMode(false); // kill task when adding a new sensor
m_nextSensor = m_firstSensor;
m_firstSensor = this;
@@ -125,15 +122,15 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Create an instance of the Ultrasonic Sensor. This is designed to supchannel
* the Daventech SRF04 and Vex ultrasonic sensors.
* Create an instance of the Ultrasonic Sensor. This is designed to supchannel the Daventech SRF04
* and Vex ultrasonic sensors.
*
* @param pingChannel The digital output channel that sends the pulse to
* initiate the sensor sending the ping.
* @param echoChannel The digital input channel that receives the echo. The
* length of time that the echo is high represents the round trip time
* of the ping, and the distance.
* @param units The units returned in either kInches or kMilliMeters
* @param pingChannel The digital output channel that sends the pulse to initiate the sensor
* sending the ping.
* @param echoChannel The digital input channel that receives the echo. The length of time that
* the echo is high represents the round trip time of the ping, and the
* distance.
* @param units The units returned in either kInches or kMilliMeters
*/
public Ultrasonic(final int pingChannel, final int echoChannel, Unit units) {
m_pingChannel = new DigitalOutput(pingChannel);
@@ -144,28 +141,28 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Create an instance of the Ultrasonic Sensor. This is designed to supchannel
* the Daventech SRF04 and Vex ultrasonic sensors. Default unit is inches.
* Create an instance of the Ultrasonic Sensor. This is designed to supchannel the Daventech SRF04
* and Vex ultrasonic sensors. Default unit is inches.
*
* @param pingChannel The digital output channel that sends the pulse to
* initiate the sensor sending the ping.
* @param echoChannel The digital input channel that receives the echo. The
* length of time that the echo is high represents the round trip time
* of the ping, and the distance.
* @param pingChannel The digital output channel that sends the pulse to initiate the sensor
* sending the ping.
* @param echoChannel The digital input channel that receives the echo. The length of time that
* the echo is high represents the round trip time of the ping, and the
* distance.
*/
public Ultrasonic(final int pingChannel, final int echoChannel) {
this(pingChannel, echoChannel, Unit.kInches);
}
/**
* Create an instance of an Ultrasonic Sensor from a DigitalInput for the echo
* channel and a DigitalOutput for the ping channel.
* Create an instance of an Ultrasonic Sensor from a DigitalInput for the echo channel and a
* DigitalOutput for the ping channel.
*
* @param pingChannel The digital output object that starts the sensor doing a
* ping. Requires a 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to
* determine the range.
* @param units The units returned in either kInches or kMilliMeters
* @param pingChannel The digital output object that starts the sensor doing a ping. Requires a
* 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to determine the
* range.
* @param units The units returned in either kInches or kMilliMeters
*/
public Ultrasonic(DigitalOutput pingChannel, DigitalInput echoChannel, Unit units) {
if (pingChannel == null || echoChannel == null) {
@@ -179,26 +176,27 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Create an instance of an Ultrasonic Sensor from a DigitalInput for the echo
* channel and a DigitalOutput for the ping channel. Default unit is inches.
* Create an instance of an Ultrasonic Sensor from a DigitalInput for the echo channel and a
* DigitalOutput for the ping channel. Default unit is inches.
*
* @param pingChannel The digital output object that starts the sensor doing a
* ping. Requires a 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to
* determine the range.
* @param pingChannel The digital output object that starts the sensor doing a ping. Requires a
* 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to determine the
* range.
*/
public Ultrasonic(DigitalOutput pingChannel, DigitalInput echoChannel) {
this(pingChannel, echoChannel, Unit.kInches);
}
/**
* Destructor for the ultrasonic sensor. Delete the instance of the ultrasonic
* sensor by freeing the allocated digital channels. If the system was in
* automatic mode (round robin), then it is stopped, then started again after
* this sensor is removed (provided this wasn't the last sensor).
* Destructor for the ultrasonic sensor. Delete the instance of the ultrasonic sensor by freeing
* the allocated digital channels. If the system was in automatic mode (round robin), then it is
* stopped, then started again after this sensor is removed (provided this wasn't the last
* sensor).
*/
@Override
public synchronized void free() {
boolean wasAutomaticMode = m_automaticEnabled;
final boolean wasAutomaticMode = m_automaticEnabled;
setAutomaticMode(false);
if (m_allocatedChannels) {
if (m_pingChannel != null) {
@@ -236,15 +234,14 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Turn Automatic mode on/off. When in Automatic mode, all sensors will fire
* in round robin, waiting a set time between each sensor.
* Turn Automatic mode on/off. When in Automatic mode, all sensors will fire in round robin,
* waiting a set time between each sensor.
*
* @param enabling Set to true if round robin scheduling should start for all
* the ultrasonic sensors. This scheduling method assures that the
* sensors are non-interfering because no two sensors fire at the same
* time. If another scheduling algorithm is preffered, it can be
* implemented by pinging the sensors manually and waiting for the
* results to come back.
* @param enabling Set to true if round robin scheduling should start for all the ultrasonic
* sensors. This scheduling method assures that the sensors are non-interfering
* because no two sensors fire at the same time. If another scheduling algorithm
* is preffered, it can be implemented by pinging the sensors manually and waiting
* for the results to come back.
*/
public void setAutomaticMode(boolean enabling) {
if (enabling == m_automaticEnabled) {
@@ -266,8 +263,9 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
// Wait for background task to stop running
try {
m_task.join();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}
/* Clear all the counters (data now invalid) since automatic mode is
@@ -281,10 +279,10 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Single ping to ultrasonic sensor. Send out a single ping to the ultrasonic
* sensor. This only works if automatic (round robin) mode is disabled. A
* single ping is sent out, and the counter should count the semi-period when
* it comes in. The counter is reset to make the current value invalid.
* Single ping to ultrasonic sensor. Send out a single ping to the ultrasonic sensor. This only
* works if automatic (round robin) mode is disabled. A single ping is sent out, and the counter
* should count the semi-period when it comes in. The counter is reset to make the current value
* invalid.
*/
public void ping() {
setAutomaticMode(false); // turn off automatic round robin if pinging
@@ -302,10 +300,9 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Check if there is a valid range measurement. The ranges are accumulated in
* a counter that will increment on each edge of the echo (return) signal. If
* the count is not at least 2, then the range has not yet been measured, and
* is invalid.
* Check if there is a valid range measurement. The ranges are accumulated in a counter that will
* increment on each edge of the echo (return) signal. If the count is not at least 2, then the
* range has not yet been measured, and is invalid.
*
* @return true if the range is valid
*/
@@ -314,11 +311,10 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Get the range in inches from the ultrasonic sensor.
* Get the range in inches from the ultrasonic sensor. If there is no valid value yet, i.e. at
* least one measurement hasn't completed, then return 0.
*
* @return double Range in inches of the target returned from the ultrasonic
* sensor. If there is no valid value yet, i.e. at least one
* measurement hasn't completed, then return 0.
* @return double Range in inches of the target returned from the ultrasonic sensor.
*/
public double getRangeInches() {
if (isRangeValid()) {
@@ -329,19 +325,16 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Get the range in millimeters from the ultrasonic sensor.
* Get the range in millimeters from the ultrasonic sensor. If there is no valid value yet, i.e.
* at least one measurement hasn't completed, then return 0.
*
* @return double Range in millimeters of the target returned by the
* ultrasonic sensor. If there is no valid value yet, i.e. at least
* one measurement hasn't complted, then return 0.
* @return double Range in millimeters of the target returned by the ultrasonic sensor.
*/
public double getRangeMM() {
return getRangeInches() * 25.4;
}
/**
* {@inheritDoc}
*/
@Override
public void setPIDSourceType(PIDSourceType pidSource) {
if (!pidSource.equals(PIDSourceType.kDisplacement)) {
throw new IllegalArgumentException("Only displacement PID is allowed for ultrasonics.");
@@ -349,9 +342,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -361,6 +352,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
*
* @return The range in DistanceUnit
*/
@Override
public double pidGet() {
switch (m_units) {
case kInches:
@@ -373,8 +365,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Set the current DistanceUnit that should be used for the PIDSource base
* object.
* Set the current DistanceUnit that should be used for the PIDSource base object.
*
* @param units The DistanceUnit that should be used.
*/
@@ -392,7 +383,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Is the ultrasonic enabled
* Is the ultrasonic enabled.
*
* @return true if the ultrasonic is enabled
*/
@@ -401,7 +392,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Set if the ultrasonic is enabled
* Set if the ultrasonic is enabled.
*
* @param enable set to true to enable the ultrasonic
*/
@@ -409,46 +400,39 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
m_enabled = enable;
}
/*
/**
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Ultrasonic";
}
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getRangeInches());
}
}
/**
* {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -10,28 +10,31 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.hal.HALUtil;
/**
* Contains global utility functions
* Contains global utility functions.
*/
public class Utility {
public final class Utility {
private Utility() {}
private Utility() {
}
/**
* Return the FPGA Version number. For now, expect this to be 2009.
*
* @return FPGA Version number.
*/
@SuppressWarnings("AbbreviationAsWordInName")
int getFPGAVersion() {
return HALUtil.getFPGAVersion();
}
/**
* Return the FPGA Revision number. The format of the revision is 3 numbers.
* The 12 most significant bits are the Major Revision. the next 8 bits are
* the Minor Revision. The 12 least significant bits are the Build Number.
* Return the FPGA Revision number. The format of the revision is 3 numbers. The 12 most
* significant bits are the Major Revision. the next 8 bits are the Minor Revision. The 12 least
* significant bits are the Build Number.
*
* @return FPGA Revision number.
*/
@SuppressWarnings("AbbreviationAsWordInName")
long getFPGARevision() {
return (long) HALUtil.getFPGARevision();
}
@@ -46,8 +49,8 @@ public class Utility {
}
/**
* Get the state of the "USER" button on the RoboRIO
*$
* Get the state of the "USER" button on the RoboRIO.
*
* @return true if the button is currently pressed down
*/
public static boolean getUserButton() {

View File

@@ -12,28 +12,24 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* VEX Robotics Victor 888 Speed Controller
*$
* The Vex Robotics Victor 884 Speed Controller can also be used with this class
* but may need to be calibrated per the Victor 884 user manual.
* VEX Robotics Victor 888 Speed Controller The Vex Robotics Victor 884 Speed Controller can also
* be used with this class but may need to be calibrated per the Victor 884 user manual.
*/
public class Victor extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* Note that the Victor uses the following bounds for PWM values. These values
* were determined empirically and optimized for the Victor 888. These values
* should work reasonably well for Victor 884 controllers also but if users
* experience issues such as asymmetric behaviour around the deadband or
* inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the Victor 884 User
* Manual available from VEX Robotics:
* http://content.vexrobotics.com/docs/ifi-v884-users-manual-9-25-06.pdf
* <p>Note that the Victor uses the following bounds for PWM values. These values were determined
* empirically and optimized for the Victor 888. These values should work reasonably well for
* Victor 884 controllers also but if users experience issues such as asymmetric behaviour around
* the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the Victor 884 User Manual available
* from VEX Robotics: http://content.vexrobotics.com/docs/ifi-v884-users-manual-9-25-06.pdf
*
* - 2.027ms = full "forward" - 1.525ms = the "high end" of the deadband range
* - 1.507ms = center of the deadband range (off) - 1.49ms = the "low end" of
* the deadband range - 1.026ms = full "reverse"
* <p>- 2.027ms = full "forward" - 1.525ms = the "high end" of the deadband range - 1.507ms =
* center of the deadband range (off) - 1.49ms = the "low end" of the deadband range - 1.026ms =
* full "reverse"
*/
private void initVictor() {
setBounds(2.027, 1.525, 1.507, 1.49, 1.026);
@@ -48,8 +44,8 @@ public class Victor extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the Victor is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the Victor is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Victor(final int channel) {
super(channel);

View File

@@ -12,23 +12,22 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* VEX Robotics Victor SP Speed Controller
* VEX Robotics Victor SP Speed Controller.
*/
public class VictorSP extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* Note that the VictorSP uses the following bounds for PWM values. These
* values should work reasonably well for most controllers, but if users
* experience issues such as asymmetric behavior around the deadband or
* inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the VictorSP User
* Manual available from CTRE.
* <p>Note that the VictorSP uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the VictorSP User Manual
* available from CTRE.
*
* - 2.004ms = full "forward" - 1.52ms = the "high end" of the deadband range
* - 1.50ms = center of the deadband range (off) - 1.48ms = the "low end" of
* the deadband range - .997ms = full "reverse"
* <p>- 2.004ms = full "forward" - 1.52ms = the "high end" of the deadband range - 1.50ms =
* center of the deadband range (off) - 1.48ms = the "low end" of the deadband range - .997ms =
* full "reverse"
*/
protected void initVictorSP() {
setBounds(2.004, 1.52, 1.50, 1.48, .997);
@@ -43,8 +42,8 @@ public class VictorSP extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the VictorSP is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the VictorSP is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public VictorSP(final int channel) {
super(channel);

View File

@@ -17,6 +17,7 @@ public class CANExceptionFactory {
static final int ERR_CANSessionMux_NotAllowed = -44088;
static final int ERR_CANSessionMux_NotInitialized = -44089;
@SuppressWarnings("JavadocMethod")
public static void checkStatus(int status, int messageID) throws CANInvalidBufferException,
CANMessageNotAllowedException, CANNotInitializedException, UncleanStatusException {
switch (status) {
@@ -36,7 +37,8 @@ public class CANExceptionFactory {
case NIRioStatus.kRIOStatusResourceNotInitialized:
throw new CANNotInitializedException();
default:
throw new UncleanStatusException("Fatal status code detected: " + Integer.toString(status));
throw new UncleanStatusException("Fatal status code detected: " + Integer.toString(
status));
}
}
}

View File

@@ -8,9 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that a CAN driver library entry-point was passed an
* invalid buffer. Typically, this is due to a buffer being too small to include
* the needed safety token.
* Exception indicating that a CAN driver library entry-point was passed an invalid buffer.
* Typically, this is due to a buffer being too small to include the needed safety token.
*/
public class CANInvalidBufferException extends RuntimeException {
public CANInvalidBufferException() {

File diff suppressed because it is too large Load Diff

View File

@@ -8,9 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that the CAN driver layer has not been initialized. This
* happens when an entry-point is called before a CAN driver plugin has been
* installed.
* Exception indicating that the CAN driver layer has not been initialized. This happens when an
* entry-point is called before a CAN driver plugin has been installed.
*/
public class CANJaguarVersionException extends RuntimeException {

View File

@@ -8,8 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that the Jaguar CAN Driver layer refused to send a
* restricted message ID to the CAN bus.
* Exception indicating that the Jaguar CAN Driver layer refused to send a restricted message ID to
* the CAN bus.
*/
public class CANMessageNotAllowedException extends RuntimeException {
public CANMessageNotAllowedException(String msg) {

View File

@@ -8,9 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that a can message is not available from Network
* Communications. This usually just means we already have the most recent value
* cached locally.
* Exception indicating that a can message is not available from Network Communications. This
* usually just means we already have the most recent value cached locally.
*/
public class CANMessageNotFoundException extends RuntimeException {
public CANMessageNotFoundException() {

View File

@@ -8,9 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that the CAN driver layer has not been initialized. This
* happens when an entry-point is called before a CAN driver plugin has been
* installed.
* Exception indicating that the CAN driver layer has not been initialized. This happens when an
* entry-point is called before a CAN driver plugin has been installed.
*/
public class CANNotInitializedException extends RuntimeException {
public CANNotInitializedException() {

View File

@@ -8,160 +8,174 @@
package edu.wpi.first.wpilibj.communication;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import edu.wpi.first.wpilibj.hal.JNIWrapper;
/**
* JNI Wrapper for library <b>FRC_NetworkCommunications</b><br>
* JNI Wrapper for library <b>FRC_NetworkCommunications</b><br>.
*/
@SuppressWarnings("MethodName")
public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
/** Module type from LoadOut.h */
public static interface tModuleType {
public static final int kModuleType_Unknown = 0x00;
public static final int kModuleType_Analog = 0x01;
public static final int kModuleType_Digital = 0x02;
public static final int kModuleType_Solenoid = 0x03;
};
/** Target class from LoadOut.h */
public static interface tTargetClass {
public static final int kTargetClass_Unknown = 0x00;
public static final int kTargetClass_FRC1 = 0x10;
public static final int kTargetClass_FRC2 = 0x20;
public static final int kTargetClass_FRC2_Analog =
/**
* Module type from LoadOut.h
*/
@SuppressWarnings("TypeName")
public interface tModuleType {
int kModuleType_Unknown = 0x00;
int kModuleType_Analog = 0x01;
int kModuleType_Digital = 0x02;
int kModuleType_Solenoid = 0x03;
}
/**
* Target class from LoadOut.h
*/
@SuppressWarnings("TypeName")
public interface tTargetClass {
int kTargetClass_Unknown = 0x00;
int kTargetClass_FRC1 = 0x10;
int kTargetClass_FRC2 = 0x20;
int kTargetClass_FRC2_Analog =
kTargetClass_FRC2 | FRCNetworkCommunicationsLibrary.tModuleType.kModuleType_Analog;
public static final int kTargetClass_FRC2_Digital =
int kTargetClass_FRC2_Digital =
kTargetClass_FRC2 | FRCNetworkCommunicationsLibrary.tModuleType.kModuleType_Digital;
public static final int kTargetClass_FRC2_Solenoid =
int kTargetClass_FRC2_Solenoid =
kTargetClass_FRC2 | FRCNetworkCommunicationsLibrary.tModuleType.kModuleType_Solenoid;
public static final int kTargetClass_FamilyMask = 0xF0;
public static final int kTargetClass_ModuleMask = 0x0F;
};
/** Resource types from UsageReporting.h */
public static interface tResourceType {
public static final int kResourceType_Controller = 0;
public static final int kResourceType_Module = 1;
public static final int kResourceType_Language = 2;
public static final int kResourceType_CANPlugin = 3;
public static final int kResourceType_Accelerometer = 4;
public static final int kResourceType_ADXL345 = 5;
public static final int kResourceType_AnalogChannel = 6;
public static final int kResourceType_AnalogTrigger = 7;
public static final int kResourceType_AnalogTriggerOutput = 8;
public static final int kResourceType_CANJaguar = 9;
public static final int kResourceType_Compressor = 10;
public static final int kResourceType_Counter = 11;
public static final int kResourceType_Dashboard = 12;
public static final int kResourceType_DigitalInput = 13;
public static final int kResourceType_DigitalOutput = 14;
public static final int kResourceType_DriverStationCIO = 15;
public static final int kResourceType_DriverStationEIO = 16;
public static final int kResourceType_DriverStationLCD = 17;
public static final int kResourceType_Encoder = 18;
public static final int kResourceType_GearTooth = 19;
public static final int kResourceType_Gyro = 20;
public static final int kResourceType_I2C = 21;
public static final int kResourceType_Framework = 22;
public static final int kResourceType_Jaguar = 23;
public static final int kResourceType_Joystick = 24;
public static final int kResourceType_Kinect = 25;
public static final int kResourceType_KinectStick = 26;
public static final int kResourceType_PIDController = 27;
public static final int kResourceType_Preferences = 28;
public static final int kResourceType_PWM = 29;
public static final int kResourceType_Relay = 30;
public static final int kResourceType_RobotDrive = 31;
public static final int kResourceType_SerialPort = 32;
public static final int kResourceType_Servo = 33;
public static final int kResourceType_Solenoid = 34;
public static final int kResourceType_SPI = 35;
public static final int kResourceType_Task = 36;
public static final int kResourceType_Ultrasonic = 37;
public static final int kResourceType_Victor = 38;
public static final int kResourceType_Button = 39;
public static final int kResourceType_Command = 40;
public static final int kResourceType_AxisCamera = 41;
public static final int kResourceType_PCVideoServer = 42;
public static final int kResourceType_SmartDashboard = 43;
public static final int kResourceType_Talon = 44;
public static final int kResourceType_HiTechnicColorSensor = 45;
public static final int kResourceType_HiTechnicAccel = 46;
public static final int kResourceType_HiTechnicCompass = 47;
public static final int kResourceType_SRF08 = 48;
public static final int kResourceType_AnalogOutput = 49;
public static final int kResourceType_VictorSP = 50;
public static final int kResourceType_TalonSRX = 51;
public static final int kResourceType_CANTalonSRX = 52;
public static final int kResourceType_ADXL362 = 53;
public static final int kResourceType_ADXRS450 = 54;
public static final int kResourceType_RevSPARK = 55;
public static final int kResourceType_MindsensorsSD540 = 56;
public static final int kResourceType_DigitalFilter = 57;
};
/** Instances from UsageReporting.h */
public static interface tInstances {
public static final int kLanguage_LabVIEW = 1;
public static final int kLanguage_CPlusPlus = 2;
public static final int kLanguage_Java = 3;
public static final int kLanguage_Python = 4;
int kTargetClass_FamilyMask = 0xF0;
int kTargetClass_ModuleMask = 0x0F;
}
public static final int kCANPlugin_BlackJagBridge = 1;
public static final int kCANPlugin_2CAN = 2;
/**
* Resource types from UsageReporting.h
*/
@SuppressWarnings("TypeName")
public interface tResourceType {
int kResourceType_Controller = 0;
int kResourceType_Module = 1;
int kResourceType_Language = 2;
int kResourceType_CANPlugin = 3;
int kResourceType_Accelerometer = 4;
int kResourceType_ADXL345 = 5;
int kResourceType_AnalogChannel = 6;
int kResourceType_AnalogTrigger = 7;
int kResourceType_AnalogTriggerOutput = 8;
int kResourceType_CANJaguar = 9;
int kResourceType_Compressor = 10;
int kResourceType_Counter = 11;
int kResourceType_Dashboard = 12;
int kResourceType_DigitalInput = 13;
int kResourceType_DigitalOutput = 14;
int kResourceType_DriverStationCIO = 15;
int kResourceType_DriverStationEIO = 16;
int kResourceType_DriverStationLCD = 17;
int kResourceType_Encoder = 18;
int kResourceType_GearTooth = 19;
int kResourceType_Gyro = 20;
int kResourceType_I2C = 21;
int kResourceType_Framework = 22;
int kResourceType_Jaguar = 23;
int kResourceType_Joystick = 24;
int kResourceType_Kinect = 25;
int kResourceType_KinectStick = 26;
int kResourceType_PIDController = 27;
int kResourceType_Preferences = 28;
int kResourceType_PWM = 29;
int kResourceType_Relay = 30;
int kResourceType_RobotDrive = 31;
int kResourceType_SerialPort = 32;
int kResourceType_Servo = 33;
int kResourceType_Solenoid = 34;
int kResourceType_SPI = 35;
int kResourceType_Task = 36;
int kResourceType_Ultrasonic = 37;
int kResourceType_Victor = 38;
int kResourceType_Button = 39;
int kResourceType_Command = 40;
int kResourceType_AxisCamera = 41;
int kResourceType_PCVideoServer = 42;
int kResourceType_SmartDashboard = 43;
int kResourceType_Talon = 44;
int kResourceType_HiTechnicColorSensor = 45;
int kResourceType_HiTechnicAccel = 46;
int kResourceType_HiTechnicCompass = 47;
int kResourceType_SRF08 = 48;
int kResourceType_AnalogOutput = 49;
int kResourceType_VictorSP = 50;
int kResourceType_TalonSRX = 51;
int kResourceType_CANTalonSRX = 52;
int kResourceType_ADXL362 = 53;
int kResourceType_ADXRS450 = 54;
int kResourceType_RevSPARK = 55;
int kResourceType_MindsensorsSD540 = 56;
int kResourceType_DigitalFilter = 57;
}
public static final int kFramework_Iterative = 1;
public static final int kFramework_Sample = 2;
public static final int kFramework_CommandControl = 3;
/**
* Instances from UsageReporting.h
*/
@SuppressWarnings("TypeName")
public interface tInstances {
int kLanguage_LabVIEW = 1;
int kLanguage_CPlusPlus = 2;
int kLanguage_Java = 3;
int kLanguage_Python = 4;
public static final int kRobotDrive_ArcadeStandard = 1;
public static final int kRobotDrive_ArcadeButtonSpin = 2;
public static final int kRobotDrive_ArcadeRatioCurve = 3;
public static final int kRobotDrive_Tank = 4;
public static final int kRobotDrive_MecanumPolar = 5;
public static final int kRobotDrive_MecanumCartesian = 6;
int kCANPlugin_BlackJagBridge = 1;
int kCANPlugin_2CAN = 2;
public static final int kDriverStationCIO_Analog = 1;
public static final int kDriverStationCIO_DigitalIn = 2;
public static final int kDriverStationCIO_DigitalOut = 3;
int kFramework_Iterative = 1;
int kFramework_Sample = 2;
int kFramework_CommandControl = 3;
public static final int kDriverStationEIO_Acceleration = 1;
public static final int kDriverStationEIO_AnalogIn = 2;
public static final int kDriverStationEIO_AnalogOut = 3;
public static final int kDriverStationEIO_Button = 4;
public static final int kDriverStationEIO_LED = 5;
public static final int kDriverStationEIO_DigitalIn = 6;
public static final int kDriverStationEIO_DigitalOut = 7;
public static final int kDriverStationEIO_FixedDigitalOut = 8;
public static final int kDriverStationEIO_PWM = 9;
public static final int kDriverStationEIO_Encoder = 10;
public static final int kDriverStationEIO_TouchSlider = 11;
int kRobotDrive_ArcadeStandard = 1;
int kRobotDrive_ArcadeButtonSpin = 2;
int kRobotDrive_ArcadeRatioCurve = 3;
int kRobotDrive_Tank = 4;
int kRobotDrive_MecanumPolar = 5;
int kRobotDrive_MecanumCartesian = 6;
public static final int kADXL345_SPI = 1;
public static final int kADXL345_I2C = 2;
int kDriverStationCIO_Analog = 1;
int kDriverStationCIO_DigitalIn = 2;
int kDriverStationCIO_DigitalOut = 3;
public static final int kCommand_Scheduler = 1;
int kDriverStationEIO_Acceleration = 1;
int kDriverStationEIO_AnalogIn = 2;
int kDriverStationEIO_AnalogOut = 3;
int kDriverStationEIO_Button = 4;
int kDriverStationEIO_LED = 5;
int kDriverStationEIO_DigitalIn = 6;
int kDriverStationEIO_DigitalOut = 7;
int kDriverStationEIO_FixedDigitalOut = 8;
int kDriverStationEIO_PWM = 9;
int kDriverStationEIO_Encoder = 10;
int kDriverStationEIO_TouchSlider = 11;
public static final int kSmartDashboard_Instance = 1;
};
int kADXL345_SPI = 1;
int kADXL345_I2C = 2;
int kCommand_Scheduler = 1;
int kSmartDashboard_Instance = 1;
}
/**
* Report the usage of a resource of interest. <br>
*
* <br>
*$
* @param resource one of the values in the tResourceType above (max value
* 51). <br>
* <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
* char*)</code>
*
* @param resource one of the values in the tResourceType above (max value 51). <br>
* @param instanceNumber an index that identifies the resource instance. <br>
* @param context an optional additional context number for some cases (such
* as module number). Set to 0 to omit. <br>
* @param feature a string to be included describing features in use on a
* specific resource. Setting the same resource more than once allows
* you to change the feature string.<br>
* Original signature :
* <code>uint32_t report(tResourceType, uint8_t, uint8_t, const char*)</code>
* @param context an optional additional context number for some cases (such as module
* number). Set to 0 to omit. <br>
* @param feature a string to be included describing features in use on a specific
* resource. Setting the same resource more than once allows you to change
* the feature string.
*/
public static native int FRCNetworkCommunicationUsageReportingReport(byte resource,
byte instanceNumber, byte context, String feature);
byte instanceNumber,
byte context,
String feature);
public static native void setNewDataSem(long mutexId);
@@ -179,6 +193,7 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
private static native int NativeHALGetControlWord();
@SuppressWarnings("JavadocMethod")
public static HALControlWord HALGetControlWord() {
int word = NativeHALGetControlWord();
return new HALControlWord((word & 1) != 0, ((word >> 1) & 1) != 0, ((word >> 2) & 1) != 0,
@@ -187,6 +202,7 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
private static native int NativeHALGetAllianceStation();
@SuppressWarnings("JavadocMethod")
public static HALAllianceStationID HALGetAllianceStation() {
switch (NativeHALGetAllianceStation()) {
case 0:
@@ -216,7 +232,7 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
public static native int HALGetJoystickButtons(byte joystickNum, ByteBuffer count);
public static native int HALSetJoystickOutputs(byte joystickNum, int outputs, short leftRumble,
short rightRumble);
short rightRumble);
public static native int HALGetJoystickIsXbox(byte joystickNum);
@@ -234,5 +250,7 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
public static native int HALSetErrorData(String error);
public static native int HALSendError(boolean isError, int errorCode, boolean isLVCode, String details, String location, String callStack, boolean printMsg);
public static native int HALSendError(boolean isError, int errorCode, boolean isLVCode,
String details, String location, String callStack,
boolean printMsg);
}

View File

@@ -8,22 +8,22 @@
package edu.wpi.first.wpilibj.communication;
/**
* A wrapper for the HALControlWord bitfield
* A wrapper for the HALControlWord bitfield.
*/
public class HALControlWord {
private boolean m_enabled;
private boolean m_autonomous;
private boolean m_test;
private boolean m_eStop;
private boolean m_fmsAttached;
private boolean m_dsAttached;
private final boolean m_enabled;
private final boolean m_autonomous;
private final boolean m_test;
private final boolean m_emergencyStop;
private final boolean m_fmsAttached;
private final boolean m_dsAttached;
protected HALControlWord(boolean enabled, boolean autonomous, boolean test, boolean eStop,
boolean fmsAttached, boolean dsAttached) {
protected HALControlWord(boolean enabled, boolean autonomous, boolean test, boolean emergencyStop,
boolean fmsAttached, boolean dsAttached) {
m_enabled = enabled;
m_autonomous = autonomous;
m_test = test;
m_eStop = eStop;
m_emergencyStop = emergencyStop;
m_fmsAttached = fmsAttached;
m_dsAttached = dsAttached;
}
@@ -41,7 +41,7 @@ public class HALControlWord {
}
public boolean getEStop() {
return m_eStop;
return m_emergencyStop;
}
public boolean getFMSAttached() {

View File

@@ -9,17 +9,17 @@ package edu.wpi.first.wpilibj.communication;
public class UsageReporting {
public static void report(int resource, int instanceNumber, int i) {
report(resource, instanceNumber, i, "");
public static void report(int resource, int instanceNumber, int context) {
report(resource, instanceNumber, context, "");
}
public static void report(int resource, int instanceNumber) {
report(resource, instanceNumber, 0, "");
}
public static void report(int resource, int instanceNumber, int i, String string) {
public static void report(int resource, int instanceNumber, int context, String string) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationUsageReportingReport((byte) resource,
(byte) instanceNumber, (byte) i, string);
(byte) instanceNumber, (byte) context, string);
}
}

View File

@@ -12,40 +12,34 @@ import java.nio.LongBuffer;
public class AnalogJNI extends JNIWrapper {
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:58</i><br>
* enum values
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:58</i><br> enum values
*/
public static interface AnalogTriggerType {
public interface AnalogTriggerType {
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:54</i>
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:54</i>
*/
public static final int kInWindow = 0;
int kInWindow = 0;
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:55</i>
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:55</i>
*/
public static final int kState = 1;
int kState = 1;
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:56</i>
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:56</i>
*/
public static final int kRisingPulse = 2;
int kRisingPulse = 2;
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:57</i>
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:57</i>
*/
public static final int kFallingPulse = 3;
};
int kFallingPulse = 3;
}
public static native long initializeAnalogInputPort(long port_pointer);
public static native long initializeAnalogInputPort(long portPointer);
public static native void freeAnalogInputPort(long port_pointer);
public static native void freeAnalogInputPort(long portPointer);
public static native long initializeAnalogOutputPort(long port_pointer);
public static native long initializeAnalogOutputPort(long portPointer);
public static native void freeAnalogOutputPort(long port_pointer);
public static native void freeAnalogOutputPort(long portPointer);
public static native boolean checkAnalogModule(byte module);
@@ -53,72 +47,72 @@ public class AnalogJNI extends JNIWrapper {
public static native boolean checkAnalogOutputChannel(int pin);
public static native void setAnalogOutput(long port_pointer, double voltage);
public static native void setAnalogOutput(long portPointer, double voltage);
public static native double getAnalogOutput(long port_pointer);
public static native double getAnalogOutput(long portPointer);
public static native void setAnalogSampleRate(double samplesPerSecond);
public static native double getAnalogSampleRate();
public static native void setAnalogAverageBits(long analog_port_pointer, int bits);
public static native void setAnalogAverageBits(long analogPortPointer, int bits);
public static native int getAnalogAverageBits(long analog_port_pointer);
public static native int getAnalogAverageBits(long analogPortPointer);
public static native void setAnalogOversampleBits(long analog_port_pointer, int bits);
public static native void setAnalogOversampleBits(long analogPortPointer, int bits);
public static native int getAnalogOversampleBits(long analog_port_pointer);
public static native int getAnalogOversampleBits(long analogPortPointer);
public static native short getAnalogValue(long analog_port_pointer);
public static native short getAnalogValue(long analogPortPointer);
public static native int getAnalogAverageValue(long analog_port_pointer);
public static native int getAnalogAverageValue(long analogPortPointer);
public static native int getAnalogVoltsToValue(long analog_port_pointer, double voltage);
public static native int getAnalogVoltsToValue(long analogPortPointer, double voltage);
public static native double getAnalogVoltage(long analog_port_pointer);
public static native double getAnalogVoltage(long analogPortPointer);
public static native double getAnalogAverageVoltage(long analog_port_pointer);
public static native double getAnalogAverageVoltage(long analogPortPointer);
public static native int getAnalogLSBWeight(long analog_port_pointer);
public static native int getAnalogLSBWeight(long analogPortPointer);
public static native int getAnalogOffset(long analog_port_pointer);
public static native int getAnalogOffset(long analogPortPointer);
public static native boolean isAccumulatorChannel(long analog_port_pointer);
public static native boolean isAccumulatorChannel(long analogPortPointer);
public static native void initAccumulator(long analog_port_pointer);
public static native void initAccumulator(long analogPortPointer);
public static native void resetAccumulator(long analog_port_pointer);
public static native void resetAccumulator(long analogPortPointer);
public static native void setAccumulatorCenter(long analog_port_pointer, int center);
public static native void setAccumulatorCenter(long analogPortPointer, int center);
public static native void setAccumulatorDeadband(long analog_port_pointer, int deadband);
public static native void setAccumulatorDeadband(long analogPortPointer, int deadband);
public static native long getAccumulatorValue(long analog_port_pointer);
public static native long getAccumulatorValue(long analogPortPointer);
public static native int getAccumulatorCount(long analog_port_pointer);
public static native int getAccumulatorCount(long analogPortPointer);
public static native void getAccumulatorOutput(long analog_port_pointer, LongBuffer value,
IntBuffer count);
public static native void getAccumulatorOutput(long analogPortPointer, LongBuffer value,
IntBuffer count);
public static native long initializeAnalogTrigger(long port_pointer, IntBuffer index);
public static native long initializeAnalogTrigger(long portPointer, IntBuffer index);
public static native void cleanAnalogTrigger(long analog_trigger_pointer);
public static native void cleanAnalogTrigger(long analogTriggerPointer);
public static native void setAnalogTriggerLimitsRaw(long analog_trigger_pointer, int lower,
int upper);
public static native void setAnalogTriggerLimitsRaw(long analogTriggerPointer, int lower,
int upper);
public static native void setAnalogTriggerLimitsVoltage(long analog_trigger_pointer,
double lower, double upper);
public static native void setAnalogTriggerLimitsVoltage(long analogTriggerPointer,
double lower, double upper);
public static native void setAnalogTriggerAveraged(long analog_trigger_pointer,
boolean useAveragedValue);
public static native void setAnalogTriggerAveraged(long analogTriggerPointer,
boolean useAveragedValue);
public static native void setAnalogTriggerFiltered(long analog_trigger_pointer,
boolean useFilteredValue);
public static native void setAnalogTriggerFiltered(long analogTriggerPointer,
boolean useFilteredValue);
public static native boolean getAnalogTriggerInWindow(long analog_trigger_pointer);
public static native boolean getAnalogTriggerInWindow(long analogTriggerPointer);
public static native boolean getAnalogTriggerTriggerState(long analog_trigger_pointer);
public static native boolean getAnalogTriggerTriggerState(long analogTriggerPointer);
public static native boolean getAnalogTriggerOutput(long analog_trigger_pointer, int type);
public static native boolean getAnalogTriggerOutput(long analogTriggerPointer, int type);
}

View File

@@ -7,19 +7,21 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("MethodName")
public class CanTalonJNI extends JNIWrapper {
// Motion Profile status bits
public static final int kMotionProfileFlag_ActTraj_IsValid = 0x1;
public static final int kMotionProfileFlag_HasUnderrun = 0x2;
public static final int kMotionProfileFlag_IsUnderrun = 0x4;
public static final int kMotionProfileFlag_ActTraj_IsLast = 0x8;
public static final int kMotionProfileFlag_HasUnderrun = 0x2;
public static final int kMotionProfileFlag_IsUnderrun = 0x4;
public static final int kMotionProfileFlag_ActTraj_IsLast = 0x8;
public static final int kMotionProfileFlag_ActTraj_VelOnly = 0x10;
/**
* Signal enumeration for generic signal access.
* Although every signal is enumerated, only use this for traffic that must be solicited.
* Use the auto generated getters/setters at bottom of this header as much as possible.
* Signal enumeration for generic signal access. Although every signal is enumerated, only use
* this for traffic that must be solicited. Use the auto generated getters/setters at bottom of
* this header as much as possible.
*/
@SuppressWarnings("TypeName")
public enum param_t {
eProfileParamSlot0_P(1),
eProfileParamSlot0_I(2),
@@ -115,118 +117,227 @@ public class CanTalonJNI extends JNIWrapper {
eReserved120(120),
eLegacyControlMode(121);
@SuppressWarnings("MemberName")
public final int value;
private param_t(int value) {
param_t(int value) {
this.value = value;
}
}
public static native long new_CanTalonSRX(int deviceNumber, int controlPeriodMs, int enablePeriodMs);
public static native long new_CanTalonSRX(int deviceNumber, int controlPeriodMs,
int enablePeriodMs);
public static native long new_CanTalonSRX(int deviceNumber, int controlPeriodMs);
public static native long new_CanTalonSRX(int deviceNumber);
public static native long new_CanTalonSRX();
public static native void delete_CanTalonSRX(long handle);
public static native void GetMotionProfileStatus(long handle, Object canTalon, Object motionProfileStatus);
public static native void GetMotionProfileStatus(long handle, Object canTalon,
Object motionProfileStatus);
public static native void Set(long handle, double value);
public static native void SetParam(long handle, int paramEnum, double value);
public static native void RequestParam(long handle, int paramEnum);
public static native double GetParamResponse(long handle, int paramEnum);
public static native int GetParamResponseInt32(long handle, int paramEnum);
public static native void SetPgain(long handle, int slotIdx, double gain);
public static native void SetIgain(long handle, int slotIdx, double gain);
public static native void SetDgain(long handle, int slotIdx, double gain);
public static native void SetFgain(long handle, int slotIdx, double gain);
public static native void SetIzone(long handle, int slotIdx, int zone);
public static native void SetCloseLoopRampRate(long handle, int slotIdx, int closeLoopRampRate);
public static native void SetVoltageCompensationRate(long handle, double voltagePerMs);
public static native void SetSensorPosition(long handle, int pos);
public static native void SetForwardSoftLimit(long handle, int forwardLimit);
public static native void SetReverseSoftLimit(long handle, int reverseLimit);
public static native void SetForwardSoftEnable(long handle, int enable);
public static native void SetReverseSoftEnable(long handle, int enable);
public static native double GetPgain(long handle, int slotIdx);
public static native double GetIgain(long handle, int slotIdx);
public static native double GetDgain(long handle, int slotIdx);
public static native double GetFgain(long handle, int slotIdx);
public static native int GetIzone(long handle, int slotIdx);
public static native int GetCloseLoopRampRate(long handle, int slotIdx);
public static native double GetVoltageCompensationRate(long handle);
public static native int GetForwardSoftLimit(long handle);
public static native int GetReverseSoftLimit(long handle);
public static native int GetForwardSoftEnable(long handle);
public static native int GetReverseSoftEnable(long handle);
public static native int GetPulseWidthRiseToFallUs(long handle);
public static native int IsPulseWidthSensorPresent(long handle);
public static native void SetModeSelect2(long handle, int modeSelect, int demand);
public static native void SetStatusFrameRate(long handle, int frameEnum, int periodMs);
public static native void ClearStickyFaults(long handle);
public static native void ChangeMotionControlFramePeriod(long handle, int periodMs);
public static native void ClearMotionProfileTrajectories(long handle);
public static native int GetMotionProfileTopLevelBufferCount(long handle);
public static native boolean IsMotionProfileTopLevelBufferFull(long handle);
public static native void PushMotionProfileTrajectory(long handle, int targPos, int targVel, int profileSlotSelect, int timeDurMs, int velOnly, int isLastPoint, int zeroPos);
public static native void PushMotionProfileTrajectory(long handle, int targPos, int targVel,
int profileSlotSelect, int timeDurMs,
int velOnly, int isLastPoint, int zeroPos);
public static native void ProcessMotionProfileBuffer(long handle);
public static native int GetFault_OverTemp(long handle);
public static native int GetFault_UnderVoltage(long handle);
public static native int GetFault_ForLim(long handle);
public static native int GetFault_RevLim(long handle);
public static native int GetFault_HardwareFailure(long handle);
public static native int GetFault_ForSoftLim(long handle);
public static native int GetFault_RevSoftLim(long handle);
public static native int GetStckyFault_OverTemp(long handle);
public static native int GetStckyFault_UnderVoltage(long handle);
public static native int GetStckyFault_ForLim(long handle);
public static native int GetStckyFault_RevLim(long handle);
public static native int GetStckyFault_ForSoftLim(long handle);
public static native int GetStckyFault_RevSoftLim(long handle);
public static native int GetAppliedThrottle(long handle);
public static native int GetCloseLoopErr(long handle);
public static native int GetFeedbackDeviceSelect(long handle);
public static native int GetModeSelect(long handle);
public static native int GetLimitSwitchEn(long handle);
public static native int GetLimitSwitchClosedFor(long handle);
public static native int GetLimitSwitchClosedRev(long handle);
public static native int GetSensorPosition(long handle);
public static native int GetSensorVelocity(long handle);
public static native double GetCurrent(long handle);
public static native int GetBrakeIsEnabled(long handle);
public static native int GetEncPosition(long handle);
public static native int GetEncVel(long handle);
public static native int GetEncIndexRiseEvents(long handle);
public static native int GetQuadApin(long handle);
public static native int GetQuadBpin(long handle);
public static native int GetQuadIdxpin(long handle);
public static native int GetAnalogInWithOv(long handle);
public static native int GetAnalogInVel(long handle);
public static native double GetTemp(long handle);
public static native double GetBatteryV(long handle);
public static native int GetResetCount(long handle);
public static native int GetResetFlags(long handle);
public static native int GetFirmVers(long handle);
public static native int GetPulseWidthPosition(long handle);
public static native int GetPulseWidthVelocity(long handle);
public static native int GetPulseWidthRiseToRiseUs(long handle);
public static native int GetActTraj_IsValid(long handle);
public static native int GetActTraj_ProfileSlotSelect(long handle);
public static native int GetActTraj_VelOnly(long handle);
public static native int GetActTraj_IsLast(long handle);
public static native int GetOutputType(long handle);
public static native int GetHasUnderrun(long handle);
public static native int GetIsUnderrun(long handle);
public static native int GetNextID(long handle);
public static native int GetBufferIsFull(long handle);
public static native int GetCount(long handle);
public static native int GetActTraj_Velocity(long handle);
public static native int GetActTraj_Position(long handle);
public static native void SetDemand(long handle, int param);
public static native void SetOverrideLimitSwitchEn(long handle, int param);
public static native void SetFeedbackDeviceSelect(long handle, int param);
public static native void SetRevMotDuringCloseLoopEn(long handle, int param);
public static native void SetOverrideBrakeType(long handle, int param);
public static native void SetModeSelect(long handle, int param);
public static native void SetProfileSlotSelect(long handle, int param);
public static native void SetRampThrottle(long handle, int param);
public static native void SetRevFeedbackSensor(long handle, int param);
}

View File

@@ -12,27 +12,27 @@ public class CompressorJNI extends JNIWrapper {
public static native boolean checkCompressorModule(byte module);
public static native boolean getCompressor(long pcm_pointer);
public static native boolean getCompressor(long pcmPointer);
public static native void setClosedLoopControl(long pcm_pointer, boolean value);
public static native void setClosedLoopControl(long pcmPointer, boolean value);
public static native boolean getClosedLoopControl(long pcm_pointer);
public static native boolean getClosedLoopControl(long pcmPointer);
public static native boolean getPressureSwitch(long pcm_pointer);
public static native boolean getPressureSwitch(long pcmPointer);
public static native float getCompressorCurrent(long pcm_pointer);
public static native float getCompressorCurrent(long pcmPointer);
public static native boolean getCompressorCurrentTooHighFault(long pcm_pointer);
public static native boolean getCompressorCurrentTooHighFault(long pcmPointer);
public static native boolean getCompressorCurrentTooHighStickyFault(long pcm_pointer);
public static native boolean getCompressorCurrentTooHighStickyFault(long pcmPointer);
public static native boolean getCompressorShortedStickyFault(long pcm_pointer);
public static native boolean getCompressorShortedStickyFault(long pcmPointer);
public static native boolean getCompressorShortedFault(long pcm_pointer);
public static native boolean getCompressorShortedFault(long pcmPointer);
public static native boolean getCompressorNotConnectedStickyFault(long pcm_pointer);
public static native boolean getCompressorNotConnectedStickyFault(long pcmPointer);
public static native boolean getCompressorNotConnectedFault(long pcm_pointer);
public static native boolean getCompressorNotConnectedFault(long pcmPointer);
public static native void clearAllPCMStickyFaults(long pcm_pointer);
public static native void clearAllPCMStickyFaults(long pcmPointer);
}

View File

@@ -12,54 +12,54 @@ import java.nio.IntBuffer;
public class CounterJNI extends JNIWrapper {
public static native long initializeCounter(int mode, IntBuffer index);
public static native void freeCounter(long counter_pointer);
public static native void freeCounter(long counterPointer);
public static native void setCounterAverageSize(long counter_pointer, int size);
public static native void setCounterAverageSize(long counterPointer, int size);
public static native void setCounterUpSource(long counter_pointer, int pin,
boolean analogTrigger);
public static native void setCounterUpSource(long counterPointer, int pin,
boolean analogTrigger);
public static native void setCounterUpSourceEdge(long counter_pointer, boolean risingEdge,
boolean fallingEdge);
public static native void setCounterUpSourceEdge(long counterPointer, boolean risingEdge,
boolean fallingEdge);
public static native void clearCounterUpSource(long counter_pointer);
public static native void clearCounterUpSource(long counterPointer);
public static native void setCounterDownSource(long counter_pointer, int pin,
boolean analogTrigger);
public static native void setCounterDownSource(long counterPointer, int pin,
boolean analogTrigger);
public static native void setCounterDownSourceEdge(long counter_pointer, boolean risingEdge,
boolean fallingEdge);
public static native void setCounterDownSourceEdge(long counterPointer, boolean risingEdge,
boolean fallingEdge);
public static native void clearCounterDownSource(long counter_pointer);
public static native void clearCounterDownSource(long counterPointer);
public static native void setCounterUpDownMode(long counter_pointer);
public static native void setCounterUpDownMode(long counterPointer);
public static native void setCounterExternalDirectionMode(long counter_pointer);
public static native void setCounterExternalDirectionMode(long counterPointer);
public static native void setCounterSemiPeriodMode(long counter_pointer,
boolean highSemiPeriod);
public static native void setCounterSemiPeriodMode(long counterPointer,
boolean highSemiPeriod);
public static native void setCounterPulseLengthMode(long counter_pointer, double threshold);
public static native void setCounterPulseLengthMode(long counterPointer, double threshold);
public static native int getCounterSamplesToAverage(long counter_pointer);
public static native int getCounterSamplesToAverage(long counterPointer);
public static native void setCounterSamplesToAverage(long counter_pointer,
int samplesToAverage);
public static native void setCounterSamplesToAverage(long counterPointer,
int samplesToAverage);
public static native void resetCounter(long counter_pointer);
public static native void resetCounter(long counterPointer);
public static native int getCounter(long counter_pointer);
public static native int getCounter(long counterPointer);
public static native double getCounterPeriod(long counter_pointer);
public static native double getCounterPeriod(long counterPointer);
public static native void setCounterMaxPeriod(long counter_pointer, double maxPeriod);
public static native void setCounterMaxPeriod(long counterPointer, double maxPeriod);
public static native void setCounterUpdateWhenEmpty(long counter_pointer, boolean enabled);
public static native void setCounterUpdateWhenEmpty(long counterPointer, boolean enabled);
public static native boolean getCounterStopped(long counter_pointer);
public static native boolean getCounterStopped(long counterPointer);
public static native boolean getCounterDirection(long counter_pointer);
public static native boolean getCounterDirection(long counterPointer);
public static native void setCounterReverseDirection(long counter_pointer,
boolean reverseDirection);
public static native void setCounterReverseDirection(long counterPointer,
boolean reverseDirection);
}

View File

@@ -7,24 +7,25 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class DIOJNI extends JNIWrapper {
public static native long initializeDigitalPort(long port_pointer);
public static native long initializeDigitalPort(long portPointer);
public static native void freeDigitalPort(long port_pointer);
public static native void freeDigitalPort(long portPointer);
public static native boolean allocateDIO(long digital_port_pointer, boolean input);
public static native boolean allocateDIO(long digitalPortPointer, boolean input);
public static native void freeDIO(long digital_port_pointer);
public static native void freeDIO(long digitalPortPointer);
public static native void setDIO(long digital_port_pointer, short value);
public static native void setDIO(long digitalPortPointer, short value);
public static native boolean getDIO(long digital_port_pointer);
public static native boolean getDIO(long digitalPortPointer);
public static native boolean getDIODirection(long digital_port_pointer);
public static native boolean getDIODirection(long digitalPortPointer);
public static native void pulse(long digital_port_pointer, double pulseLength);
public static native void pulse(long digitalPortPointer, double pulseLength);
public static native boolean isPulsing(long digital_port_pointer);
public static native boolean isPulsing(long digitalPortPointer);
public static native boolean isAnyPulsing();

View File

@@ -8,8 +8,11 @@
package edu.wpi.first.wpilibj.hal;
public class DigitalGlitchFilterJNI extends JNIWrapper {
public static native void setFilterSelect(long digital_port_pointer, int filter_index);
public static native int getFilterSelect(long digital_port_pointer);
public static native void setFilterPeriod(int filter_index, int fpga_cycles);
public static native int getFilterPeriod(int filter_index);
public static native void setFilterSelect(long digitalPortPointer, int filterIndex);
public static native int getFilterSelect(long digitalPortPointer);
public static native void setFilterPeriod(int filterIndex, int fpgaCycles);
public static native int getFilterPeriod(int filterIndex);
}

View File

@@ -10,32 +10,34 @@ package edu.wpi.first.wpilibj.hal;
import java.nio.IntBuffer;
public class EncoderJNI extends JNIWrapper {
public static native long initializeEncoder(byte port_a_module, int port_a_pin,
boolean port_a_analog_trigger, byte port_b_module, int port_b_pin, boolean port_b_analog_trigger,
boolean reverseDirection, IntBuffer index);
public static native long initializeEncoder(byte portAModule, int portAPin,
boolean portAAnalogTrigger, byte portBModule,
int portBPin, boolean portBAnalogTrigger,
boolean reverseDirection, IntBuffer index);
public static native void freeEncoder(long encoder_pointer);
public static native void freeEncoder(long encoderPointer);
public static native void resetEncoder(long encoder_pointer);
public static native void resetEncoder(long encoderPointer);
public static native int getEncoder(long encoder_pointer);
public static native int getEncoder(long encoderPointer);
public static native double getEncoderPeriod(long encoder_pointer);
public static native double getEncoderPeriod(long encoderPointer);
public static native void setEncoderMaxPeriod(long encoder_pointer, double maxPeriod);
public static native void setEncoderMaxPeriod(long encoderPointer, double maxPeriod);
public static native boolean getEncoderStopped(long encoder_pointer);
public static native boolean getEncoderStopped(long encoderPointer);
public static native boolean getEncoderDirection(long encoder_pointer);
public static native boolean getEncoderDirection(long encoderPointer);
public static native void setEncoderReverseDirection(long encoder_pointer,
boolean reverseDirection);
public static native void setEncoderReverseDirection(long encoderPointer,
boolean reverseDirection);
public static native void setEncoderSamplesToAverage(long encoder_pointer,
int samplesToAverage);
public static native void setEncoderSamplesToAverage(long encoderPointer,
int samplesToAverage);
public static native int getEncoderSamplesToAverage(long encoder_pointer);
public static native int getEncoderSamplesToAverage(long encoderPointer);
public static native void setEncoderIndexSource(long digital_port, int pin,
boolean analogTrigger, boolean activeHigh, boolean edgeSensitive);
public static native void setEncoderIndexSource(long digitalPort, int pin,
boolean analogTrigger, boolean activeHigh,
boolean edgeSensitive);
}

View File

@@ -7,6 +7,7 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class HALUtil extends JNIWrapper {
public static final int NULL_PARAMETER = -1005;
public static final int SAMPLE_RATE_TOO_HIGH = 1001;
@@ -33,7 +34,7 @@ public class HALUtil extends JNIWrapper {
public static native void deleteMultiWait(long sem);
public static native void takeMultiWait(long sem, long m);
public static native void takeMultiWait(long sem, long ms);
public static native short getFPGAVersion();

View File

@@ -9,16 +9,17 @@ package edu.wpi.first.wpilibj.hal;
import java.nio.ByteBuffer;
@SuppressWarnings("AbbreviationAsWordInName")
public class I2CJNI extends JNIWrapper {
public static native void i2CInitialize(byte port);
public static native int i2CTransaction(byte port, byte address, ByteBuffer dataToSend,
byte sendSize, ByteBuffer dataReceived, byte receiveSize);
byte sendSize, ByteBuffer dataReceived, byte receiveSize);
public static native int i2CWrite(byte port, byte address, ByteBuffer dataToSend, byte sendSize);
public static native int i2CRead(byte port, byte address, ByteBuffer dataRecieved,
byte receiveSize);
byte receiveSize);
public static native void i2CClose(byte port);
}

View File

@@ -10,29 +10,30 @@ package edu.wpi.first.wpilibj.hal;
public class InterruptJNI extends JNIWrapper {
public interface InterruptJNIHandlerFunction {
void apply(int interruptAssertedMask, Object param);
};
}
public static native long initializeInterrupts(int interruptIndex, boolean watcher);
public static native void cleanInterrupts(long interrupt_pointer);
public static native void cleanInterrupts(long interruptPointer);
public static native int waitForInterrupt(long interrupt_pointer, double timeout,
boolean ignorePrevious);
public static native int waitForInterrupt(long interruptPointer, double timeout,
boolean ignorePrevious);
public static native void enableInterrupts(long interrupt_pointer);
public static native void enableInterrupts(long interruptPointer);
public static native void disableInterrupts(long interrupt_pointer);
public static native void disableInterrupts(long interruptPointer);
public static native double readRisingTimestamp(long interrupt_pointer);
public static native double readRisingTimestamp(long interruptPointer);
public static native double readFallingTimestamp(long interrupt_pointer);
public static native double readFallingTimestamp(long interruptPointer);
public static native void requestInterrupts(long interrupt_pointer, byte routing_module,
int routing_pin, boolean routing_analog_trigger);
public static native void requestInterrupts(long interruptPointer, byte routingModule,
int routingPin, boolean routingAnalogTrigger);
public static native void attachInterruptHandler(long interrupt_pointer,
InterruptJNIHandlerFunction handler, Object param);
public static native void attachInterruptHandler(long interruptPointer,
InterruptJNIHandlerFunction handler,
Object param);
public static native void setInterruptUpSourceEdge(long interrupt_pointer, boolean risingEdge,
boolean fallingEdge);
public static native void setInterruptUpSourceEdge(long interruptPointer, boolean risingEdge,
boolean fallingEdge);
}

View File

@@ -8,9 +8,9 @@
package edu.wpi.first.wpilibj.hal;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
//
// base class for all JNI wrappers
@@ -18,6 +18,7 @@ import java.io.FileOutputStream;
public class JNIWrapper {
static boolean libraryLoaded = false;
static File jniLibrary = null;
static {
try {
if (!libraryLoaded) {
@@ -62,5 +63,5 @@ public class JNIWrapper {
public static native long getPort(byte pin);
public static native void freePort(long port_pointer);
public static native void freePort(long portPointer);
}

View File

@@ -7,18 +7,15 @@
package edu.wpi.first.wpilibj.hal;
import java.lang.Runtime;
/**
* The NotifierJNI class directly wraps the C++ HAL Notifier.
*
* This class is not meant for direct use by teams. Instead, the
* edu.wpi.first.wpilibj.Notifier class, which corresponds to the C++ Notifier
* class, should be used.
* <p>This class is not meant for direct use by teams. Instead, the edu.wpi.first.wpilibj.Notifier
* class, which corresponds to the C++ Notifier class, should be used.
*/
public class NotifierJNI extends JNIWrapper {
/**
* Callback function
* Callback function.
*/
public interface NotifierJNIHandlerFunction {
void apply(long curTime);

View File

@@ -7,6 +7,7 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class PDPJNI extends JNIWrapper {
public static native void initializePDP(int module);

View File

@@ -7,18 +7,19 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class PWMJNI extends DIOJNI {
public static native boolean allocatePWMChannel(long digital_port_pointer);
public static native boolean allocatePWMChannel(long digitalPortPointer);
public static native void freePWMChannel(long digital_port_pointer);
public static native void freePWMChannel(long digitalPortPointer);
public static native void setPWM(long digital_port_pointer, short value);
public static native void setPWM(long digitalPortPointer, short value);
public static native short getPWM(long digital_port_pointer);
public static native short getPWM(long digitalPortPointer);
public static native void latchPWMZero(long digital_port_pointer);
public static native void latchPWMZero(long digitalPortPointer);
public static native void setPWMPeriodScale(long digital_port_pointer, int squelchMask);
public static native void setPWMPeriodScale(long digitalPortPointer, int squelchMask);
public static native long allocatePWM();

View File

@@ -8,11 +8,11 @@
package edu.wpi.first.wpilibj.hal;
public class RelayJNI extends DIOJNI {
public static native void setRelayForward(long digital_port_pointer, boolean on);
public static native void setRelayForward(long digitalPortPointer, boolean on);
public static native void setRelayReverse(long digital_port_pointer, boolean on);
public static native void setRelayReverse(long digitalPortPointer, boolean on);
public static native boolean getRelayForward(long digital_port_pointer);
public static native boolean getRelayForward(long digitalPortPointer);
public static native boolean getRelayReverse(long digital_port_pointer);
public static native boolean getRelayReverse(long digitalPortPointer);
}

View File

@@ -11,11 +11,12 @@ import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
@SuppressWarnings("AbbreviationAsWordInName")
public class SPIJNI extends JNIWrapper {
public static native void spiInitialize(byte port);
public static native int spiTransaction(byte port, ByteBuffer dataToSend,
ByteBuffer dataReceived, byte size);
ByteBuffer dataReceived, byte size);
public static native int spiWrite(byte port, ByteBuffer dataToSend, byte sendSize);
@@ -25,16 +26,16 @@ public class SPIJNI extends JNIWrapper {
public static native void spiSetSpeed(byte port, int speed);
public static native void spiSetOpts(byte port, int msb_first, int sample_on_trailing,
int clk_idle_high);
public static native void spiSetOpts(byte port, int msbFirst, int sampleOnTrailing,
int clkIdleHigh);
public static native void spiSetChipSelectActiveHigh(byte port);
public static native void spiSetChipSelectActiveLow(byte port);
public static native void spiInitAccumulator(byte port, int period, int cmd,
byte xferSize, int validMask, int validValue, byte dataShift,
byte dataSize, boolean isSigned, boolean bigEndian);
public static native void spiInitAccumulator(byte port, int period, int cmd, byte xferSize,
int validMask, int validValue, byte dataShift,
byte dataSize, boolean isSigned, boolean bigEndian);
public static native void spiFreeAccumulator(byte port);
@@ -53,5 +54,5 @@ public class SPIJNI extends JNIWrapper {
public static native double spiGetAccumulatorAverage(byte port);
public static native void spiGetAccumulatorOutput(byte port, LongBuffer value,
IntBuffer count);
IntBuffer count);
}

View File

@@ -10,7 +10,7 @@ package edu.wpi.first.wpilibj.hal;
public class SolenoidJNI extends JNIWrapper {
public static native long initializeSolenoidPort(long portPointer);
public static native void freeSolenoidPort(long port_pointer);
public static native void freeSolenoidPort(long portPointer);
public static native long getPortWithModule(byte module, byte channel);
@@ -20,11 +20,11 @@ public class SolenoidJNI extends JNIWrapper {
public static native byte getAllSolenoids(long port);
public static native int getPCMSolenoidBlackList(long pcm_pointer);
public static native int getPCMSolenoidBlackList(long pcmPointer);
public static native boolean getPCMSolenoidVoltageStickyFault(long pcm_pointer);
public static native boolean getPCMSolenoidVoltageStickyFault(long pcmPointer);
public static native boolean getPCMSolenoidVoltageFault(long pcm_pointer);
public static native boolean getPCMSolenoidVoltageFault(long pcmPointer);
public static native void clearAllPCMStickyFaults(long pcm_pointer);
public static native void clearAllPCMStickyFaults(long pcmPointer);
}

View File

@@ -7,18 +7,20 @@
package edu.wpi.first.wpilibj.image;
import edu.wpi.first.wpilibj.util.SortedVector;
import com.ni.vision.NIVision;
import edu.wpi.first.wpilibj.util.SortedVector;
/**
* An image where each pixel is treated as either on or off.
*
* @author dtjones
*/
public class BinaryImage extends MonoImage {
private int numParticles = -1;
private int m_numParticles = -1;
BinaryImage() throws NIVisionException {}
BinaryImage() throws NIVisionException {
}
BinaryImage(BinaryImage sourceImage) {
super(sourceImage);
@@ -30,25 +32,27 @@ public class BinaryImage extends MonoImage {
* @return The number of particles
*/
public int getNumberParticles() throws NIVisionException {
if (numParticles < 0)
numParticles = NIVision.imaqCountParticles(image, 1);
return numParticles;
if (m_numParticles < 0) {
m_numParticles = NIVision.imaqCountParticles(image, 1);
}
return m_numParticles;
}
private class ParticleSizeReport {
final int index;
final double size;
final int m_index;
final double m_size;
public ParticleSizeReport(int index) throws NIVisionException {
if ((!(index < BinaryImage.this.getNumberParticles())) || index < 0)
if ((!(index < BinaryImage.this.getNumberParticles())) || index < 0) {
throw new IndexOutOfBoundsException();
this.index = index;
size = ParticleAnalysisReport.getParticleToImagePercent(BinaryImage.this, index);
}
m_index = index;
m_size = ParticleAnalysisReport.getParticleToImagePercent(BinaryImage.this, index);
}
public ParticleAnalysisReport getParticleAnalysisReport() throws NIVisionException {
return new ParticleAnalysisReport(BinaryImage.this, index);
return new ParticleAnalysisReport(BinaryImage.this, m_index);
}
}
@@ -59,47 +63,50 @@ public class BinaryImage extends MonoImage {
* @return The ParticleAnalysisReport for the particle at the given index
*/
public ParticleAnalysisReport getParticleAnalysisReport(int index) throws NIVisionException {
if (!(index < getNumberParticles()))
if (!(index < getNumberParticles())) {
throw new IndexOutOfBoundsException();
}
return new ParticleAnalysisReport(this, index);
}
/**
* Gets all the particle analysis reports ordered from largest area to
* smallest.
* Gets all the particle analysis reports ordered from largest area to smallest.
*
* @param size The number of particles to return
* @return An array of ParticleReports from largest area to smallest
*/
public ParticleAnalysisReport[] getOrderedParticleAnalysisReports(int size)
throws NIVisionException {
if (size > getNumberParticles())
if (size > getNumberParticles()) {
size = getNumberParticles();
}
ParticleSizeReport[] reports = new ParticleSizeReport[size];
SortedVector sorter = new SortedVector(new SortedVector.Comparator() {
public int compare(Object object1, Object object2) {
ParticleSizeReport p1 = (ParticleSizeReport) object1;
ParticleSizeReport p2 = (ParticleSizeReport) object2;
if (p1.size < p2.size)
if (p1.m_size < p2.m_size) {
return -1;
else if (p1.size > p2.size)
} else if (p1.m_size > p2.m_size) {
return 1;
}
return 0;
}
});
for (int i = 0; i < getNumberParticles(); i++)
for (int i = 0; i < getNumberParticles(); i++) {
sorter.addElement(new ParticleSizeReport(i));
}
sorter.setSize(size);
sorter.copyInto(reports);
ParticleAnalysisReport[] finalReports = new ParticleAnalysisReport[reports.length];
for (int i = 0; i < finalReports.length; i++)
for (int i = 0; i < finalReports.length; i++) {
finalReports[i] = reports[i].getParticleAnalysisReport();
}
return finalReports;
}
/**
* Gets all the particle analysis reports ordered from largest area to
* smallest.
* Gets all the particle analysis reports ordered from largest area to smallest.
*
* @return An array of ParticleReports from largest are to smallest
*/
@@ -107,7 +114,7 @@ public class BinaryImage extends MonoImage {
return getOrderedParticleAnalysisReports(getNumberParticles());
}
@SuppressWarnings({"summaryjavadoc", "javadocmethod"})
public void write(String fileName) throws NIVisionException {
NIVision.RGBValue colorTable = new NIVision.RGBValue(0, 0, 255, 0);
try {
@@ -118,15 +125,14 @@ public class BinaryImage extends MonoImage {
}
/**
* removeSmallObjects filters particles based on their size. The algorithm
* erodes the image a specified number of times and keeps the particles from
* the original image that remain in the eroded image.
* removeSmallObjects filters particles based on their m_size. The algorithm erodes the image a
* specified number of times and keeps the particles from the original image that remain in the
* eroded image.
*
* @param connectivity8 true to use connectivity-8 or false for connectivity-4
* to determine whether particles are touching. For more information
* about connectivity, see Chapter 9, Binary Morphology, in the NI
* Vision Concepts manual.
* @param erosions the number of erosions to perform
* @param connectivity8 true to use connectivity-8 or false for connectivity-4 to determine
* whether particles are touching. For more information about connectivity,
* see Chapter 9, Binary Morphology, in the NI Vision Concepts manual.
* @param erosions the number of erosions to perform
* @return a BinaryImage after applying the filter
*/
public BinaryImage removeSmallObjects(boolean connectivity8, int erosions)
@@ -139,15 +145,14 @@ public class BinaryImage extends MonoImage {
}
/**
* removeLargeObjects filters particles based on their size. The algorithm
* erodes the image a specified number of times and discards the particles
* from the original image that remain in the eroded image.
* removeLargeObjects filters particles based on their m_size. The algorithm erodes the image a
* specified number of times and discards the particles from the original image that remain in the
* eroded image.
*
* @param connectivity8 true to use connectivity-8 or false for connectivity-4
* to determine whether particles are touching. For more information
* about connectivity, see Chapter 9, Binary Morphology, in the NI
* Vision Concepts manual.
* @param erosions the number of erosions to perform
* @param connectivity8 true to use connectivity-8 or false for connectivity-4 to determine
* whether particles are touching. For more information about connectivity,
* see Chapter 9, Binary Morphology, in the NI Vision Concepts manual.
* @param erosions the number of erosions to perform
* @return a BinaryImage after applying the filter
*/
public BinaryImage removeLargeObjects(boolean connectivity8, int erosions)
@@ -158,12 +163,14 @@ public class BinaryImage extends MonoImage {
return result;
}
@SuppressWarnings({"summaryjavadoc", "javadocmethod"})
public BinaryImage convexHull(boolean connectivity8) throws NIVisionException {
BinaryImage result = new BinaryImage();
NIVision.imaqConvexHull(result.image, image, connectivity8 ? 1 : 0);
return result;
}
@SuppressWarnings({"summaryjavadoc", "javadocmethod"})
public BinaryImage particleFilter(NIVision.ParticleFilterCriteria2[] criteria)
throws NIVisionException {
BinaryImage result = new BinaryImage();

View File

@@ -25,7 +25,7 @@ public abstract class ColorImage extends ImageBase {
}
private BinaryImage threshold(NIVision.ColorMode colorMode, int low1, int high1, int low2,
int high2, int low3, int high3) throws NIVisionException {
int high2, int low3, int high3) throws NIVisionException {
BinaryImage res = new BinaryImage();
NIVision.Range range1 = new NIVision.Range(low1, high1);
NIVision.Range range2 = new NIVision.Range(low2, high2);
@@ -39,73 +39,69 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Return a mask of the areas of the image that fall within the given ranges
* for color values
* Return a mask of the areas of the image that fall within the given ranges for color values
*
* @param redLow The lower red limit.
* @param redHigh The upper red limit.
* @param greenLow The lower green limit.
* @param redLow The lower red limit.
* @param redHigh The upper red limit.
* @param greenLow The lower green limit.
* @param greenHigh The upper green limit.
* @param blueLow The lower blue limit.
* @param blueHigh The upper blue limit.
* @param blueLow The lower blue limit.
* @param blueHigh The upper blue limit.
* @return A BinaryImage masking the areas which match the given thresholds.
*/
public BinaryImage thresholdRGB(int redLow, int redHigh, int greenLow, int greenHigh,
int blueLow, int blueHigh) throws NIVisionException {
int blueLow, int blueHigh) throws NIVisionException {
return threshold(NIVision.ColorMode.RGB, redLow, redHigh, greenLow, greenHigh, blueLow,
blueHigh);
}
/**
* Return a mask of the areas of the image that fall within the given ranges
* for color values
* Return a mask of the areas of the image that fall within the given ranges for color values
*
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param saturationHigh The upper saturation limit.
* @param luminenceLow The lower luminence limit.
* @param luminenceHigh The upper luminence limit.
* @param luminenceLow The lower luminence limit.
* @param luminenceHigh The upper luminence limit.
* @return A BinaryImage masking the areas which match the given thresholds.
*/
public BinaryImage thresholdHSL(int hueLow, int hueHigh, int saturationLow, int saturationHigh,
int luminenceLow, int luminenceHigh) throws NIVisionException {
int luminenceLow, int luminenceHigh) throws NIVisionException {
return threshold(NIVision.ColorMode.HSL, hueLow, hueHigh, saturationLow, saturationHigh,
luminenceLow, luminenceHigh);
}
/**
* Return a mask of the areas of the image that fall within the given ranges
* for color values
* Return a mask of the areas of the image that fall within the given ranges for color values
*
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param saturationHigh The upper saturation limit.
* @param valueHigh The lower value limit.
* @param valueLow The upper value limit.
* @param valueHigh The lower value limit.
* @param valueLow The upper value limit.
* @return A BinaryImage masking the areas which match the given thresholds.
*/
public BinaryImage thresholdHSV(int hueLow, int hueHigh, int saturationLow, int saturationHigh,
int valueLow, int valueHigh) throws NIVisionException {
int valueLow, int valueHigh) throws NIVisionException {
return threshold(NIVision.ColorMode.HSV, hueLow, hueHigh, saturationLow, saturationHigh,
valueLow, valueHigh);
}
/**
* Return a mask of the areas of the image that fall within the given ranges
* for color values
* Return a mask of the areas of the image that fall within the given ranges for color values
*
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param saturationHigh The upper saturation limit.
* @param intansityLow The lower intensity limit.
* @param intensityHigh The upper intensity limit.
* @param intansityLow The lower intensity limit.
* @param intensityHigh The upper intensity limit.
* @return A BinaryImage masking the areas which match the given thresholds.
*/
public BinaryImage thresholdHSI(int hueLow, int hueHigh, int saturationLow, int saturationHigh,
int intansityLow, int intensityHigh) throws NIVisionException {
int intansityLow, int intensityHigh) throws NIVisionException {
return threshold(NIVision.ColorMode.HSI, hueLow, hueHigh, saturationLow, saturationHigh,
intansityLow, intensityHigh);
}
@@ -141,8 +137,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the green color plane from the image when represented in RGB color
* space.
* Get the green color plane from the image when represented in RGB color space.
*
* @return The green color plane from the image.
*/
@@ -151,8 +146,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the blue color plane from the image when represented in RGB color
* space.
* Get the blue color plane from the image when represented in RGB color space.
*
* @return The blue color plane from the image.
*/
@@ -188,8 +182,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the saturation color plane from the image when represented in HSL color
* space.
* Get the saturation color plane from the image when represented in HSL color space.
*
* @return The saturation color plane from the image.
*/
@@ -198,8 +191,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the saturation color plane from the image when represented in HSV color
* space.
* Get the saturation color plane from the image when represented in HSV color space.
*
* @return The saturation color plane from the image.
*/
@@ -208,8 +200,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the saturation color plane from the image when represented in HSI color
* space.
* Get the saturation color plane from the image when represented in HSI color space.
*
* @return The saturation color plane from the image.
*/
@@ -218,8 +209,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the luminance color plane from the image when represented in HSL color
* space.
* Get the luminance color plane from the image when represented in HSL color space.
*
* @return The luminance color plane from the image.
*/
@@ -228,8 +218,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the value color plane from the image when represented in HSV color
* space.
* Get the value color plane from the image when represented in HSV color space.
*
* @return The value color plane from the image.
*/
@@ -238,8 +227,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the intensity color plane from the image when represented in HSI color
* space.
* Get the intensity color plane from the image when represented in HSI color space.
*
* @return The intensity color plane from the image.
*/
@@ -266,9 +254,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the red color plane from the image when represented in RGB color space.
* This does not create a new image, but modifies this one instead. Create a
* copy before hand if you need to continue using the original.
* Set the red color plane from the image when represented in RGB color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -278,9 +266,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the green color plane from the image when represented in RGB color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the green color plane from the image when represented in RGB color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -290,9 +278,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the blue color plane from the image when represented in RGB color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the blue color plane from the image when represented in RGB color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -302,9 +290,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the hue color plane from the image when represented in HSL color space.
* This does not create a new image, but modifies this one instead. Create a
* copy before hand if you need to continue using the original.
* Set the hue color plane from the image when represented in HSL color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -314,9 +302,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the hue color plane from the image when represented in HSV color space.
* This does not create a new image, but modifies this one instead. Create a
* copy before hand if you need to continue using the original.
* Set the hue color plane from the image when represented in HSV color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -326,9 +314,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the hue color plane from the image when represented in HSI color space.
* This does not create a new image, but modifies this one instead. Create a
* copy before hand if you need to continue using the original.
* Set the hue color plane from the image when represented in HSI color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -338,9 +326,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the saturation color plane from the image when represented in HSL color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the saturation color plane from the image when represented in HSL color space. This does
* not create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -350,9 +338,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the saturation color plane from the image when represented in HSV color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the saturation color plane from the image when represented in HSV color space. This does
* not create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -362,9 +350,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the saturation color plane from the image when represented in HSI color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the saturation color plane from the image when represented in HSI color space. This does
* not create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -374,9 +362,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the luminance color plane from the image when represented in HSL color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the luminance color plane from the image when represented in HSL color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -386,9 +374,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the value color plane from the image when represented in HSV color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the value color plane from the image when represented in HSV color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -398,9 +386,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the intensity color plane from the image when represented in HSI color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the intensity color plane from the image when represented in HSI color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -410,10 +398,10 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Calculates the histogram of each plane of a color image and redistributes
* pixel values across the desired range while maintaining pixel value
* groupings. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Calculates the histogram of each plane of a color image and redistributes pixel values across
* the desired range while maintaining pixel value groupings. This does not create a new image,
* but modifies this one instead. Create a copy before hand if you need to continue using the
* original.
*
* @return The modified image.
*/
@@ -423,11 +411,10 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Calculates the histogram of each plane of a color image and redistributes
* pixel values across the desired range while maintaining pixel value
* groupings for the Luminance plane only. This does not create a new image,
* but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
* Calculates the histogram of each plane of a color image and redistributes pixel values across
* the desired range while maintaining pixel value groupings for the Luminance plane only. This
* does not create a new image, but modifies this one instead. Create a copy before hand if you
* need to continue using the original.
*
* @return The modified image.
*/

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