diff --git a/.classpath b/.classpath index 01c6aa5..2491ec3 100644 --- a/.classpath +++ b/.classpath @@ -22,7 +22,7 @@ - + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 62a317c..c788ee3 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,8 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.travis.yml b/.travis.yml index ac97283..0f79bcf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,55 +2,24 @@ language: java install: true -before_deploy: -- echo - - - - - - - - - - - - - - - - - - - -- echo M a v e n P a c k a g i n g -- echo - - - - - - - - - - - - - - - - - - - -- mvn package -- echo - - - - - - - - - - - - - - - - - -- echo E n d M a v e n P k g -- echo - - - - - - - - - - - - - - - - - -- ls -R -- echo ===================================== -- echo Automatic development preparation -- echo ===================================== -- echo This state:.$TRAVIS_BRANCH -- echo Project Version:.$projectversion -- git config --global user.email "builds@travis-ci.com" -- git config --global user.name "Travis CI" -- export GIT_TAG=$projectversion-$TRAVIS_BRANCH-B$TRAVIS_BUILD_NUMBER -- git tag $GIT_TAG -a -m "Generated tag from TravisCI for $TRAVIS_BRANCH build $TRAVIS_BUILD_NUMBER" -- git push -q https://$GITPERM@github.com/mob41/ev3dev-lang-java --tags -- echo ===================================== -- echo Deploy Preparation done. -- echo ===================================== +before_install: +- sudo apt-get update +- sudo apt-get install gnupg gnupg2 +- chmod +x .travis/prepare +- .travis/prepare -deploy: - - provider: releases - skip_cleanup: true - api_key: $GITPERM - file: - - target/ev3dev-lang-java-$projectversion.jar - - target/ev3dev-lang-java-$projectversion-jar-with-dependencies.jar - on: - tags: false - branch: unstable - - provider: releases - skip_cleanup: true - api_key: $GITPERM - file: - - target/ev3dev-lang-java-$projectversion.jar - - target/ev3dev-lang-java-$projectversion-jar-with-dependencies.jar - on: - tags: false - branch: develop +after_success: +- ls +- chmod +x .travis/deploy +- .travis/deploy branches: only: - master - - unstable - - stable - develop env: -- projectversion=0.0.2-SNAPSHOT \ No newline at end of file + global: + - secure: "GcIwBLB8ZVeUtxibJsnbvtol/msXvSv2+iIjbf2ZW13f75E5J3mpsE/yzcATStjGSK2KXf4KKpwaqj5XI76I53qrbo5fmAQtHVJ13CoPYgDesRbMj2KKQHlr2tuXHYMjp85KvWMlPR8idZ7YBy4GFnoBZzH3N517K/X2kwsQHrKz2m/7MVtZoNgWSr3FZZW+BkUK6L0rebKECxICqtCua2XoL2j1UwfN/u4fk4qdPGaOWhhaSgjIdvlPRqikZXJ0Ia9X/ankJ89Ee0M6iLOJ3mjOZMPQU06XGu6Etse7jy2w3jaYgZaTjQ1ekIZXIDRP9pwaZ1ew+vHZSC3Ug97jSeevQmaKW+IwrXOZXp4ID4Uo2fYUSVcBB9zkAaZNO/Xu+viXuCgIVVl9DCevOT89Vq2OAEBJ9k/EgIy7njup7k6p0QKKl8id9gd59XN9pinYgM8g8ltdBfbIRAYCz+5m4PGAkE3IKzY3FxFAnrp+Qgs4LPB4Z4hTni+LeJGzw2RtUGHBq9HcmOSJ8tFGNUrtFXB+/06CqsugtmDF5aDXfuVGPzJoaq1Hs5wytzt4GhtUDyPhoNmaElBnkR1oIUhQ9bjtRJvQkH4RExsXJjOzThNHQfydTBcE/nwhLWKoYLO8//wcbYi22UJXgjbSWS/PeUNkm+JrGLws7QgjwZEc+Pc=" + - secure: "EsZpjMxtRHHbmIz/eS/i2rAzRD3BzpGti//gTyLMXv1nbs7eHjJdYu4qjM4Ry0SzR+OIcTZk0+qsdjzZqeN8VgR+OpDp86lvZDCy4rKey3sXsgOlxFBMeQ5DJaJgIMosyeAu/o+s75bYAu2PMq8AmfQS8KX6qppF+GfxLKMUd8RYfZCls/VGovZs4Fn5LRa/tGsmrBbq+QxVLRApt9GaRd7vpZ48b6LfxOd/xkH7c9rD4nTzMusFrveE5KAgK6P5XdPeRzeDbtVXFbdL6Gw7ZasSxwhh+d8Chv3ffVCD3s9zvsIv9JJUjbKNCvTBNFP9pHZxckNvd3ZK8gY809iK2BRNMpYKCcH5n3lJkL9YU224bTqUSQbe/ozDvR2Rs26S8WuHHm5BBsg5MRwQJFvGzVnt650rCqDNxSVPGYxTuzpa3lvC9z8aFadVYbKec8CoHd+u4yNe5eW13bNTbV/rI0j1WfC2Ked+O9De0AlumcS/Z0cUXASS0duemFWwdirRheCRPDbp57K2XGj3EdQbMsU/0s1llcbTS8YFqLtDU6zPZuMbwTx0Bcfk7tjzkAc84g3zUCeCg9vN3QZYVFsZDq6pGx31FrGy1HQRA8uaGFE2Liq6rgzFElJUOPf6BO7Pv0FhvtTorzw3EjnLZZfP0iG3Br/JJWjCCfnO5r6CZxk=" + - secure: "M8il7KAiot0/P+PNKzhTVDCeFbL99PIDiG8O3kZaRaj1oMlO7VKQkm9LD1ZhBEQJm7MsyO4dr9ScXa6rEsB8B1hRmP062EL/0/7cwvZhj3xLc2dP8Jl7JNuZF3XwiQnqin61nXaKCzfpF7rQv/lz1FhCVytTwbUWBKVKPcjg5auk4gGQU0FWk0UgOiyB/8pMFPwRo9emBS/DCCt61/P9TTZwZsFpyWpWEe34SZ9xNU8qYdjP2z1pJtDNX0Uw89NBF5aFY8JSj17yp1LYoZhG8NhjpkYY6tahs21vuT24grFBcapuo1gkXKTV0GRdiI0XQn54Poto9n2Rn0/Ewx/fCP/MWTJVNHq9ddbqerY/+pd7DZCtlAjHvLVFAwxVXmJaHLYtgf14h2VHTM6V9ba5kRZxviaWmEU60IhVZ2KHeWzhSAeNI/XzHgczceYeK+t2MUNWM0Z4gzLZhVlCO2ZCCpOo8RHiPAIP+NMeM0+zOcX5D5jujkXP19SNbFNINaTUiUH7+Wa3/cRwQ2qcTF2OiJPVB7FBCgmaDz5OFIow+o3Q4BQKRbrApLpoE5oHiFVGBLvVo55NqMw9pBmz3B/4dnBHaB5xDa2DKnHN7eJKXBCH0VenkkqhpEfw6vwz384fsE39tMFLamhmMhlwvMQAKupQJUoaiPYESw/L+wXWfzY=" \ No newline at end of file diff --git a/.travis/codesigning.asc.enc b/.travis/codesigning.asc.enc new file mode 100644 index 0000000..4248ed2 Binary files /dev/null and b/.travis/codesigning.asc.enc differ diff --git a/.travis/deploy b/.travis/deploy new file mode 100644 index 0000000..272ace6 --- /dev/null +++ b/.travis/deploy @@ -0,0 +1,7 @@ +#!/bin/bash +if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then + if [ "$TRAVIS_BRANCH" = 'master' ] || [ "$TRAVIS_BRANCH" = 'develop' ]; then + mvn deploy --settings settings.xml + fi +fi + diff --git a/.travis/prepare b/.travis/prepare new file mode 100644 index 0000000..63a3248 --- /dev/null +++ b/.travis/prepare @@ -0,0 +1,7 @@ +#!/bin/bash +if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then + if [ "$TRAVIS_BRANCH" = 'master' ] || [ "$TRAVIS_BRANCH" = 'develop' ]; then + openssl aes-256-cbc -K $encrypted_040459e821a3_key -iv $encrypted_040459e821a3_iv -in .travis/codesigning.asc.enc -out .travis/codesigning.asc -d + gpg --fast-import .travis/codesigning.asc + fi +fi diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..58790fe --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Anthony Law + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 9617259..b2fb942 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,105 @@ # ev3dev-lang-java [![Build Status](https://travis-ci.org/mob41/ev3dev-lang-java.svg?branch=master)](https://travis-ci.org/mob41/ev3dev-lang-java) -A ev3dev unified language binding for Java, that followed with the [language wrapper specification](http://ev3dev-lang.readthedocs.org/en/latest/spec.html). +>This project isn't dead. Just "not very active" in development. -# Outdated library +An ev3dev unified language binding for Java, that followed with the [language wrapper specification](http://ev3dev-lang.readthedocs.org/en/latest/spec.html). -This library is currently outdated, and only support few drivers. Please consider using another [Java-compatible library](https://github.com/ev3dev-lang-java/ev3dev-lang-java/) or wait few weeks to let this library to be ready up. +If you are finding a document or a tutorial for a specific version, come to https://mob41.github.io/ev3dev-lang-java -Check out #15 for more details. \ No newline at end of file +## Library + +This library supports ev3dev kernel version 17: + +- ```v4.4.32-17-ev3dev-ev3``` for EV3 +- ```v4.4.31-ti-rt-r67-17-ev3dev-bb.org``` for BeagleBone +- ```v4.4.32-17-ev3dev-rpi``` for Raspberry Pi 0/1 +- ```v4.4.32-17-ev3dev-rpi2``` for Raspberry Pi 2/3 + +All the drivers and functions listed in the [language wrapper specification](http://ev3dev-lang.readthedocs.org/en/latest/spec.html) are all supported, but without confirming the stability of those devices. + +Other motors listed in http://www.ev3dev.org/docs/motors are also supported. ```DCMotor``` handles ```rcx-motor``` motors. + +Other sensors listed in http://www.ev3dev.org/docs/sensors are still in heavy development. + +Still in heavy development, please don't expect all things to be working, see issue [#15](https://github.com/mob41/ev3dev-lang-java/issues/15) for more details or tracking development stage. + +## Release + +This library currently **does not have any** releases, but snapshots (nightly builds) instead. + +You can download the latest snapshot from the [OSSRH repository](https://oss.sonatype.org/content/groups/public/org/ev3dev/ev3dev-lang-java/) directly or via Maven: + +1. Add the Sonatype snapshot repository. + + ```xml + + + oss-sonatype + oss-sonatype + https://oss.sonatype.org/content/repositories/snapshots/ + + true + + + + ``` + +2. Add the dependency. + + ```xml + + org.ev3dev + ev3dev-lang-java + 1.0.0-SNAPSHOT + + ``` + +## Build your own + +You can build your own library with some steps. + +1. Ensure you have Maven installed in your system + +2. Clone this repository + + >git clone https://github.com/mob41/ev3dev-lang-java.git + +3. Switch to the repository directory + + >cd ev3dev-lang-java + +4. Build! + + >maven package + +5. Switch to the ```target``` directory + + >cd target + +6. There should have ```ev3dev-lang-java-x.x.x-x.jar``` and ```ev3dev-lang-java-x.x.x-x-jar-with-dependencies.jar``` in the directory. + +## License + +This project is based on the MIT License + +>MIT License +> +>Copyright (c) 2016 Anthony Law +> +>Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +> +>The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +> +>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 59cb18f..976360e 100644 --- a/pom.xml +++ b/pom.xml @@ -2,38 +2,92 @@ 4.0.0 org.ev3dev ev3dev-lang-java - 0.0.2-SNAPSHOT + 1.0.0-SNAPSHOT + ev3dev-lang-java - A ev3dev programming language binding for Java. + An ev3dev programming language binding for Java. + https://github.com/mob41/ev3dev-lang-java + + + + MIT License + http://www.opensource.org/licenses/mit-license.php + + + + + + Anthony Law + anthonylaw0401@gmail.com + Anthony Law + http://github.com/mob41 + + + + + scm:git:git://github.com/mob41/ev3dev-lang-java.git + scm:git:ssh://github.com:mob41/ev3dev-lang-java.git + http://github.com/mob41/ev3dev-lang-java/tree/master + + 1.7 1.7 + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + - - maven-surefire-plugin - 2.10 - - false - - - - maven-assembly-plugin - - - package - - single - - - - - - jar-with-dependencies - - - - - + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + \ No newline at end of file diff --git a/settings.xml b/settings.xml new file mode 100644 index 0000000..8071dcc --- /dev/null +++ b/settings.xml @@ -0,0 +1,21 @@ + + + + ossrh + ${env.CI_DEPLOY_USERNAME} + ${env.CI_DEPLOY_PASSWORD} + + + + + ossrh + + true + + + gpg2 + ${env.CI_KEY_PASSPHRASE} + + + + \ No newline at end of file diff --git a/src/main/java/org/ev3dev/exception/EV3LibraryException.java b/src/main/java/org/ev3dev/exception/EV3LibraryException.java new file mode 100644 index 0000000..3416978 --- /dev/null +++ b/src/main/java/org/ev3dev/exception/EV3LibraryException.java @@ -0,0 +1,30 @@ +package org.ev3dev.exception; + +/*** + * This exception is thrown if something was invalid. + * @author Anthony + * + */ +public class EV3LibraryException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public EV3LibraryException(){ + super(); + } + + public EV3LibraryException(String message){ + super(message); + } + + public EV3LibraryException(String message, Throwable cause){ + super(message, cause); + } + + public EV3LibraryException(Throwable cause){ + super(cause); + } +} diff --git a/src/main/java/org/ev3dev/exception/InvalidButtonException.java b/src/main/java/org/ev3dev/exception/InvalidButtonException.java index a5c9479..08d3cc5 100644 --- a/src/main/java/org/ev3dev/exception/InvalidButtonException.java +++ b/src/main/java/org/ev3dev/exception/InvalidButtonException.java @@ -7,7 +7,7 @@ * @author Anthony * */ -public class InvalidButtonException extends InvalidException { +public class InvalidButtonException extends EV3LibraryException { /** * diff --git a/src/main/java/org/ev3dev/exception/InvalidException.java b/src/main/java/org/ev3dev/exception/InvalidException.java deleted file mode 100644 index d2b1357..0000000 --- a/src/main/java/org/ev3dev/exception/InvalidException.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.ev3dev.exception; - -/*** - * This exception is thrown if something was invalid. - * @author Anthony - * - */ -public class InvalidException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public InvalidException(){ - super(); - } - - public InvalidException(String message){ - super(message); - } - - public InvalidException(String message, Throwable cause){ - super(message, cause); - } - - public InvalidException(Throwable cause){ - super(cause); - } -} diff --git a/src/main/java/org/ev3dev/exception/InvalidLEDException.java b/src/main/java/org/ev3dev/exception/InvalidLEDException.java index 0a067bf..11a4047 100644 --- a/src/main/java/org/ev3dev/exception/InvalidLEDException.java +++ b/src/main/java/org/ev3dev/exception/InvalidLEDException.java @@ -6,7 +6,7 @@ * @author Anthony * */ -public class InvalidLEDException extends InvalidException { +public class InvalidLEDException extends EV3LibraryException { /** * diff --git a/src/main/java/org/ev3dev/exception/InvalidModeException.java b/src/main/java/org/ev3dev/exception/InvalidModeException.java index 710f446..f7b94fd 100644 --- a/src/main/java/org/ev3dev/exception/InvalidModeException.java +++ b/src/main/java/org/ev3dev/exception/InvalidModeException.java @@ -5,7 +5,7 @@ * @author Anthony * */ -public class InvalidModeException extends InvalidException { +public class InvalidModeException extends EV3LibraryException { /** * diff --git a/src/main/java/org/ev3dev/exception/InvalidMotorException.java b/src/main/java/org/ev3dev/exception/InvalidMotorException.java index d97837a..22f0679 100644 --- a/src/main/java/org/ev3dev/exception/InvalidMotorException.java +++ b/src/main/java/org/ev3dev/exception/InvalidMotorException.java @@ -7,7 +7,7 @@ * @author Anthony * */ -public class InvalidMotorException extends InvalidException { +public class InvalidMotorException extends EV3LibraryException { /** * diff --git a/src/main/java/org/ev3dev/exception/InvalidPortException.java b/src/main/java/org/ev3dev/exception/InvalidPortException.java index ee63721..8fc0215 100644 --- a/src/main/java/org/ev3dev/exception/InvalidPortException.java +++ b/src/main/java/org/ev3dev/exception/InvalidPortException.java @@ -7,7 +7,7 @@ * @author Anthony * */ -public class InvalidPortException extends InvalidException { +public class InvalidPortException extends EV3LibraryException { /** * diff --git a/src/main/java/org/ev3dev/exception/InvalidSensorException.java b/src/main/java/org/ev3dev/exception/InvalidSensorException.java index ccb3477..cc1d6ad 100644 --- a/src/main/java/org/ev3dev/exception/InvalidSensorException.java +++ b/src/main/java/org/ev3dev/exception/InvalidSensorException.java @@ -9,7 +9,7 @@ * @author Anthony * */ -public class InvalidSensorException extends InvalidException { +public class InvalidSensorException extends EV3LibraryException { /** * diff --git a/src/main/java/org/ev3dev/hardware/Button.java b/src/main/java/org/ev3dev/hardware/Button.java index b831f95..1dc681b 100644 --- a/src/main/java/org/ev3dev/hardware/Button.java +++ b/src/main/java/org/ev3dev/hardware/Button.java @@ -6,27 +6,28 @@ import java.io.IOException; import org.ev3dev.exception.InvalidButtonException; -import org.ev3dev.io.Def; /*** * Provides a generic button reading mechanism that can be adapted to platform specific implementations. - * Each platform・s specific button capabilites are enumerated in the .platforms・ section of this specification. + * Each platform's specific button capabilites are enumerated in the 'platforms' section of this specification. * @author Anthony * */ public class Button { - public static final int UP = Def.PROPERTY_EV3_BUTTON_UP; + public static final String SYSTEM_EVENT_PATH = "/dev/input/by-path/platform-gpio-keys.0-event"; - public static final int DOWN = Def.PROPERTY_EV3_BUTTON_DOWN; + public static final int BUTTON_UP = 103; - public static final int LEFT = Def.PROPERTY_EV3_BUTTON_LEFT; + public static final int BUTTON_DOWN = 108; - public static final int RIGHT = Def.PROPERTY_EV3_BUTTON_RIGHT; + public static final int BUTTON_LEFT = 105; - public static final int ENTER = Def.PROPERTY_EV3_BUTTON_ENTER; + public static final int BUTTON_RIGHT = 106; - public static final int BACKSPACE = Def.PROPERTY_EV3_BUTTON_BACKSPACE; + public static final int BUTTON_ENTER = 28; + + public static final int BUTTON_BACKSPACE = 14; private int button; @@ -36,10 +37,10 @@ public class Button { * @throws InvalidButtonException If the specified button isn't a valid button. */ public Button(int button) throws InvalidButtonException{ - if (button != UP && button != DOWN && button != LEFT && - button != RIGHT && button != ENTER && button != ENTER && - button != BACKSPACE){ - throw new InvalidButtonException("The button that you specified does not exist. Better use the integer fields like Button.UP"); + if (button != BUTTON_UP && button != BUTTON_DOWN && button != BUTTON_LEFT && + button != BUTTON_RIGHT && button != BUTTON_ENTER && button != BUTTON_ENTER && + button != BUTTON_BACKSPACE){ + throw new InvalidButtonException("The button that you specified does not exist. Better use the integer fields like Button.BUTTON_UP"); } this.button = button; } @@ -50,7 +51,7 @@ public Button(int button) throws InvalidButtonException{ */ public boolean isPressed(){ try { - DataInputStream in = new DataInputStream(new FileInputStream(Def.PROPERTY_EV3_BUTTON_SYSTEM_EVENT_PATH)); + DataInputStream in = new DataInputStream(new FileInputStream(SYSTEM_EVENT_PATH)); byte[] val = new byte[16]; in.readFully(val); in.close(); diff --git a/src/main/java/org/ev3dev/hardware/Device.java b/src/main/java/org/ev3dev/hardware/Device.java index 388f54f..ae0262c 100644 --- a/src/main/java/org/ev3dev/hardware/Device.java +++ b/src/main/java/org/ev3dev/hardware/Device.java @@ -2,13 +2,15 @@ import java.io.IOException; +import org.ev3dev.exception.EV3LibraryException; + import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Sysclass; +import org.ev3dev.io.Sysfs; /** * This is the base class that handles control tasks for a single port or index. The class must chose one device out of the available ports to control. Given an IO port (in the constructor), an implementation should:

-- If the specified port is blank or unspecified/undefined/null, the available devices should be enumerated until a suitable device is found. Any device is suitable when it・s type is known to be compatible with the controlling class, and it meets any other requirements specified by the caller.
+- If the specified port is blank or unspecified/undefined/null, the available devices should be enumerated until a suitable device is found. Any device is suitable when it's type is known to be compatible with the controlling class, and it meets any other requirements specified by the caller.

- If the specified port name is not blank, the available devices should be enumerated until a device is found that is plugged in to the specified port. The supplied port name should be compared directly to the value from the file, so that advanced port strings will match, such as in1:mux3.

@@ -21,11 +23,11 @@ public abstract class Device { private String className; - private String subClassName = null; + private String classNamePrefix = null; private String address; - private String hardwareName = null; + private String classFullName = null; private LegoPort port; @@ -41,47 +43,58 @@ public Device(String className){ } /** - * Create a new device with a LegoPort, ClassName, SubClassName + * Create a new device with a LegoPort, ClassName, classNamePrefix * @param port A LegoPort delared before. * @param className Sysfs class name - * @param subClassName The filename inside the "Sysfs class" (I called it sub-class) - * @throws IOException If I/O goes wrong + * @param classNamePrefix The filename prefix inside the "Sysfs class" (e.g. motor[n], which "motor" is the prefix) + * @throws EV3LibraryException If I/O goes wrong */ - public Device(LegoPort port, String className, String subClassName) throws IOException{ + public Device(LegoPort port, String className, String classNamePrefix) throws EV3LibraryException{ this.port = port; this.className = className; - this.subClassName = subClassName; - try { - address = port.getAddress(); - } catch (IOException e){ - System.err.println(className + "-" + this.hashCode() + ": The lego-port system class wasn't found."); - throw new IOException("Cannot access to the target address. Are you using a EV3?", e); - } + this.classNamePrefix = classNamePrefix; + + address = port.getAddress(); connected = checkIsConnected(); if (!connected){ System.out.println(className + "-" + this.hashCode() + ": No port connected. Searching until port \"" + address + "\" connected..."); + + while (!connected){ + connected = checkIsConnected(); + } + + System.out.println(className + "-" + this.hashCode() + ": Connected to " + address); } - while (!connected){ - connected = checkIsConnected(); - } - System.out.println(className + "-" + this.hashCode() + ": Connected to " + address); + } + public abstract String getAddress() throws EV3LibraryException; + + public abstract String getDriverName() throws EV3LibraryException; + /** - * Set the Sysfs class name(location) of this Device - * @param className A Sysfs class name located in /sys/class + * Set the Sysfs class name (location) of this Device + * @param className The Sysfs class name located in /sys/class */ public void setClassName(String className){ this.className = className; } /** - * Set the filename inside the Sysfs class (sub-class) of this Device - * @param subClassName A filename inside the Sysfs class (e.g. "/sys/class/motor/motor0" motor0 is sub-class name) + * Set the Sysfs class full name (including prefix if any) + * @param classFullName The Sysfs class name located in /sys/class/[className] */ - public void setSubClassName(String subClassName){ - this.subClassName = subClassName; + public void setClassFullname(String classFullName){ + this.classFullName = classFullName; + } + + /** + * Set the filename prefix inside the Sysfs class (prefix (e.g. motor)) of this Device + * @param classNamePrefix The filename inside the Sysfs class (e.g. "/sys/class/motor/motor0" motor is a prefix) + */ + public void setClassNamePrefix(String classNamePrefix){ + this.classNamePrefix = classNamePrefix; } /** @@ -101,54 +114,59 @@ public LegoPort getPort(){ } /** - * Get the sub-class name of this Device - * @return A filename inside the Sysfs class (e.g. "/sys/class/motor/motor0" motor0 is sub-class name) + * Get the filename prefix inside the Sysfs class (prefix (e.g. motor)) of this Device + * @return The filename inside the Sysfs class (e.g. "/sys/class/motor/motor0" motor is a prefix) */ - public String getSubClassName(){ - return hardwareName; + public String getClassNamePrefix(){ + return classNamePrefix; + } + + /** + * Get the full filename (not prefix) inside the Sysfs class of this Device. This must be already searched by the checkIsConnected() method + * @return The filename inside the Sysfs class (e.g. "/sys/class/motor/motor0" motor0 is the full name) + */ + public String getClassFullName(){ + return classNamePrefix; } /*** - * Reads the property of the class specified. - * @param property The property name of the class. + * Reads the property specified. + * @param property The property name * @return The value of the property */ - public final String getAttribute(String property){ + public final String getAttribute(String property) throws EV3LibraryException{ try { - String str = Sysclass.getAttribute(className, hardwareName, property); + String str = Sysfs.getAttribute(className, classFullName, property); connected = true; return str; } catch (IOException e){ - e.printStackTrace(); connected = false; - return null; + throw new EV3LibraryException("Get device attribute failed: " + property, e); } } /*** - * Writes the property of the class specified. - * @param property The property name of the class + * Writes the property specified. + * @param property The property name * @param new_value The new value of the property - * @return Boolean whether the attribute was successfully written */ - public final boolean setAttribute(String property, String new_value){ + public final void setAttribute(String property, String new_value) throws EV3LibraryException{ try { - Sysclass.setAttribute(className, hardwareName, property, new_value); + Sysfs.setAttribute(className, classFullName, property, new_value); connected = true; } catch (IOException e){ - e.printStackTrace(); connected = false; + throw new EV3LibraryException("Set device attribute failed: " + property, e); } - return connected; } private boolean checkIsConnected(){ try { - hardwareName = Sysclass.getHardwareName(className, subClassName, address); + classFullName = Sysfs.searchClassFullName(className, classNamePrefix, address); } catch (Exception ignore){ - hardwareName = null; + classFullName = null; return false; } - return hardwareName != null; + return classFullName != null; } } \ No newline at end of file diff --git a/src/main/java/org/ev3dev/hardware/LCD.java b/src/main/java/org/ev3dev/hardware/LCD.java new file mode 100644 index 0000000..3d1d485 --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/LCD.java @@ -0,0 +1,49 @@ +package org.ev3dev.hardware; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.ev3dev.exception.EV3LibraryException; + +/** + * Provides an interface to draw to the EV3's LCD + * @author Anthony + * + */ +public class LCD { + + public static final String FB_PATH = "/dev/fb0"; + + //This should not be hard-coded, however just for testing + public static final int SCREEN_WIDTH = 178; + + public static final int SCREEN_HEIGHT = 128; + + public LCD() { + + } + + /** + * Draws a byte array into the EV3 framebuffer + * @param data Byte array to be drawn (128 (height) * 178 / 8 (length) = 3072 bytes) + * @throws EV3LibraryException + */ + public void draw(byte[] data) throws EV3LibraryException{ + File file = new File(FB_PATH); + if (!file.exists()){ + throw new EV3LibraryException("The framebuffer device does not exist! Are you using a EV3?"); + } + try { + DataOutputStream out = new DataOutputStream(new FileOutputStream(file)); + out.write(data); + out.flush(); + out.close(); + } catch (IOException e) { + throw new EV3LibraryException("Unable to draw the LCD", e); + } + } + +} diff --git a/src/main/java/org/ev3dev/hardware/LCDGraphics.java b/src/main/java/org/ev3dev/hardware/LCDGraphics.java new file mode 100644 index 0000000..c36a65c --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/LCDGraphics.java @@ -0,0 +1,351 @@ +package org.ev3dev.hardware; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.image.ImageObserver; +import java.text.AttributedCharacterIterator; + +import org.ev3dev.exception.EV3LibraryException; + +public class LCDGraphics extends Graphics { + + public static final int LINE_LEN = 24; + + public static final int ROWS = 128; + + public static final int BUF_SIZE = LINE_LEN * ROWS; + + private LCD lcd; + + private boolean whiteColor = false; + + private byte[] buf; + + private int transx = 0; + + private int transy = 0; + + private Font font; + + public LCDGraphics(LCD lcd) { + this.lcd = lcd; + buf = new byte[BUF_SIZE]; + } + + /** + * Applies the Graphics context onto the ev3dev's LCD + */ + public void flush(){ + lcd.draw(buf); + } + + /** + * Not implemented + */ + @Override + public Graphics create() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void translate(int x, int y) { + this.transx = x; + this.transy = y; + } + + public void setWhiteColor(){ + whiteColor = true; + } + + public void setBlackColor(){ + whiteColor = false; + } + + @Override + public Color getColor() { + return whiteColor ? Color.WHITE : Color.BLACK; + } + + @Override + public void setColor(Color c) throws EV3LibraryException{ + if (c == null || !c.equals(Color.BLACK) || !c.equals(Color.WHITE)){ + throw new EV3LibraryException("The EV3 LCD only supports Color.BLACK and Color.WHITE"); + } + whiteColor = c.equals(Color.WHITE); + } + + /** + * The ev3 LCD does not support PaintMode + */ + @Override + public void setPaintMode() { + throw new EV3LibraryException("The EV3 LCD does not support PaintMode"); + } + + /** + * The ev3 LCD does not support XORMode + */ + @Override + public void setXORMode(Color c1) { + throw new EV3LibraryException("The EV3 LCD does not support XORMode"); + } + + /** + * Not implemented + */ + @Override + public Font getFont() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setFont(Font font) { + // TODO Auto-generated method stub + + } + + /** + * Not implemented + */ + @Override + public FontMetrics getFontMetrics(Font f) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Rectangle getClipBounds() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void clipRect(int x, int y, int width, int height) { + // TODO Auto-generated method stub + + } + + @Override + public void setClip(int x, int y, int width, int height) { + // TODO Auto-generated method stub + + } + + @Override + public Shape getClip() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setClip(Shape clip) { + // TODO Auto-generated method stub + + } + + @Override + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + + } + + @Override + public void drawLine(int x1, int y1, int x2, int y2) { //Uses Bresenham's line algorithm + boolean steep = Math.abs(y2 - y1) > Math.abs(x2 - x1); + + if (steep){ + int tmp = x1; + x1 = y1; + y1 = tmp; + + tmp = x2; + x2 = y2; + y2 = x2; + } + + if (x1 > x2){ + int tmp = x1; + x1 = x2; + x2 = tmp; + + tmp = y1; + y1 = y2; + y2 = tmp; + } + + double deltax = x2 - x1; + double deltay = Math.abs(y2 - y1); + + double err = deltax / 2; + + int xlen = x2 - x1; + int y = y1; + + int ystep; + if (y1 < y2){ + ystep = 1; + } else { + ystep = -1; + } + + for (int i = 0; i < xlen; i++){ + if (steep){ + plot(y,i); + } else { + plot(i,y); + } + + err -= deltay; + if (err < 0){ + y += ystep; + err += deltax; + } + } + } + + /** + * Plot the specified (x,y) position with the selected color (Color.BLACK or Color.WHITE) + * @param x Position x + * @param y Position y + */ + public void plot(int x, int y){ + buf[y * LINE_LEN + x / 8] = (byte) (whiteColor ? 0x00 : 0xff); + } + + @Override + public void fillRect(int x, int y, int width, int height) { + for (int i = 0; i < height; i++){ + for (int j = 0; j < width; j++){ + buf[(((i+y) * LINE_LEN)) + (x + j) / 8] = (byte) (whiteColor ? 0x00 : 0xff); + } + } + } + + @Override + public void clearRect(int x, int y, int width, int height) { + for (int i = 0; i < height; i++){ + for (int j = 0; j < width; j++){ + buf[(((i+y) * LINE_LEN)) + (x + j) / 8] = (byte) 0x00; + } + } + } + + @Override + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + // TODO Auto-generated method stub + + } + + @Override + public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + // TODO Auto-generated method stub + + } + + @Override + public void drawOval(int x, int y, int width, int height) { + // TODO Auto-generated method stub + + } + + @Override + public void fillOval(int x, int y, int width, int height) { + // TODO Auto-generated method stub + + } + + @Override + public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + // TODO Auto-generated method stub + + } + + @Override + public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + // TODO Auto-generated method stub + + } + + @Override + public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { + // TODO Auto-generated method stub + + } + + @Override + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { + // TODO Auto-generated method stub + + } + + @Override + public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { + // TODO Auto-generated method stub + + } + + @Override + public void drawString(String str, int x, int y) { + System.out.println("Draw string"); + // TODO Auto-generated method stub + + } + + @Override + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + System.out.println("Draw string2"); + // TODO Auto-generated method stub + + } + + @Override + public boolean drawImage(Image img, int x, int y, ImageObserver observer) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, + ImageObserver observer) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void dispose() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/org/ev3dev/hardware/LED.java b/src/main/java/org/ev3dev/hardware/LED.java index 69a7614..fc94c55 100644 --- a/src/main/java/org/ev3dev/hardware/LED.java +++ b/src/main/java/org/ev3dev/hardware/LED.java @@ -1,11 +1,10 @@ package org.ev3dev.hardware; import java.io.File; -import java.io.IOException; +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidLEDException; -import org.ev3dev.io.Def; -import org.ev3dev.io.Sysclass; +import org.ev3dev.io.Sysfs; /*** * Any device controlled by the generic LED driver.
@@ -18,6 +17,31 @@ */ public class LED extends Device{ + /** + * The Sysfs class's max_brightness property name + */ + public static final String SYSFS_PROPERTY_MAX_BRIGHTNESS = "max_brightness"; + + /** + * The Sysfs class's brightness property name + */ + public static final String SYSFS_PROPERTY_BRIGHTNESS = "brightness"; + + /** + * The Sysfs class's trigger property name + */ + public static final String SYSFS_PROPERTY_TRIGGER = "trigger"; + + /** + * The Sysfs class's delay_on property name + */ + public static final String SYSFS_PROPERTY_DELAY_ON = "delay_on"; + + /** + * The Sysfs class's delay_off property name + */ + public static final String SYSFS_PROPERTY_DELAY_OFF = "delay_off"; + /** * Left EV3 Button */ @@ -38,6 +62,11 @@ public class LED extends Device{ */ public static final int RED = 1; + /** + * This Sysfs's class name (e.g. /sys/class/lego-sensor, and lego-sensor is the class name) + */ + public static final String CLASS_NAME = "leds"; + /** * Creates a new LED instance. * @param leftRightField The integer field from LED class (e.g. Button.LEFT, Button.RIGHT) @@ -45,16 +74,17 @@ public class LED extends Device{ * @throws InvalidLEDException If the specified LEFT RIGHT field or color field isn't valid. */ public LED(int leftRightField, int colorField) throws InvalidLEDException{ - super(Def.LED_CLASS_NAME); + super(CLASS_NAME); if (leftRightField != 0 && leftRightField != 1){ throw new InvalidLEDException("You are not specifying a EV3_LEFT_LED or EV3_RIGHT_LED field!"); - } else if (colorField != 0 && colorField != 1){ + } + if (colorField != 0 && colorField != 1){ throw new InvalidLEDException("You are not specifying a EV3_LED_GREEN or EV3_LED_RED field!"); } String direction = leftRightField == 0 ? "left" : "right"; String color = colorField == 0 ? "green" : "red"; - this.setSubClassName("ev3:" + direction + ":" + color + ":ev3dev"); + this.setClassFullname("ev3:" + direction + ":" + color + ":ev3dev"); } /** @@ -68,41 +98,41 @@ public LED(int leftRightField, int colorField) throws InvalidLEDException{ * @throws InvalidLEDException If the specified ledName does not exist */ public LED(String ledName) throws InvalidLEDException{ - super(Def.LED_CLASS_NAME); - File file = new File(Def.SYSTEM_CLASS_PATH + Def.LED_CLASS_NAME + "/" + ledName); + super(CLASS_NAME); + File file = new File(Sysfs.getSysfsPath() + CLASS_NAME + "/" + ledName); if (!file.exists()){ throw new InvalidLEDException("The specified LED does not exist"); } - this.setSubClassName(ledName); + this.setClassName(ledName); } /** * Returns the maximum allowable brightness value. * @return The maximum allowable brightness value. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getMaxBrightness() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_MAX_BRIGHTNESS); + public int getMaxBrightness() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_MAX_BRIGHTNESS); return Integer.parseInt(str); } /** * Gets the brightness level. Possible values are from 0 to max_brightness. * @return The brightness level - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getBrightness() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_BRIGHTNESS); + public int getBrightness() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_BRIGHTNESS); return Integer.parseInt(str); } /** * Sets the brightness level. Possible values are from 0 to max_brightness. * @param brightness The brightness level - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setBrightness(int brightness) throws IOException{ - this.setAttribute(Def.PROPERTY_BRIGHTNESS, Integer.toString(brightness)); + public void setBrightness(int brightness) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_BRIGHTNESS, Integer.toString(brightness)); } /** @@ -113,25 +143,25 @@ public void setBrightness(int brightness) throws IOException{ * * Returns a list of available triggers. * @return A spaced-array String - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getTriggersViaString() throws IOException{ - return this.getAttribute(Def.PROPERTY_TRIGGER); + public String getTriggersViaString() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_TRIGGER); } /** * Returns a list of available triggers. * @return A String Array with a list of available triggers - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getTriggers() throws IOException{ + public String[] getTriggers() throws EV3LibraryException{ String str = getTriggersViaString(); - return Sysclass.separateSpace(str); + return Sysfs.separateSpace(str); } /** * Gets the led trigger. A trigger is a kernel based source of led events. Triggers can either be simple or complex. - * A simple trigger isn・t configurable and is designed to slot into existing subsystems with minimal additional code. + * A simple trigger isn't configurable and is designed to slot into existing subsystems with minimal additional code. * Examples are the ide-disk and nand-disk triggers.
*
* Complex triggers whilst available to all LEDs have LED specific parameters and work on a per LED basis. The timer @@ -140,15 +170,15 @@ public String[] getTriggers() throws IOException{ * change the brightness value of a LED independently of the timer trigger. However, if you set the brightness value * to 0 it will also disable the timer trigger. * @return The LED trigger - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getTrigger() throws IOException{ - return this.getAttribute(Def.PROPERTY_TRIGGER); + public String getTrigger() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_TRIGGER); } /** * Sets the led trigger. A trigger is a kernel based source of led events. Triggers can either be simple or complex. - * A simple trigger isn・t configurable and is designed to slot into existing subsystems with minimal additional code. + * A simple trigger isn't configurable and is designed to slot into existing subsystems with minimal additional code. * Examples are the ide-disk and nand-disk triggers.
*
* Complex triggers whilst available to all LEDs have LED specific parameters and work on a per LED basis. The timer @@ -157,20 +187,20 @@ public String getTrigger() throws IOException{ * change the brightness value of a LED independently of the timer trigger. However, if you set the brightness value * to 0 it will also disable the timer trigger. * @param selector The LED trigger that listed using getTriggers() - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setTrigger(String selector) throws IOException{ - this.setAttribute(Def.PROPERTY_TRIGGER, selector); + public void setTrigger(String selector) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_TRIGGER, selector); } /** * The timer trigger will periodically change the LED brightness between 0 and the current brightness setting. * The on time can be specified via delay_on attribute in milliseconds. * @return The Delay_On Value in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getDelay_On() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_DELAY_ON); + public int getDelay_On() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_DELAY_ON); return Integer.parseInt(str); } @@ -178,10 +208,10 @@ public int getDelay_On() throws IOException{ * The timer trigger will periodically change the LED brightness between 0 and the current brightness setting. * The off time can be specified via delay_off attribute in milliseconds. * @return The Delay_Off Value in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getDelay_Off() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_DELAY_OFF); + public int getDelay_Off() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_DELAY_OFF); return Integer.parseInt(str); } @@ -189,19 +219,29 @@ public int getDelay_Off() throws IOException{ * The timer trigger will periodically change the LED brightness between 0 and the current brightness setting. * The on time can be specified via delay_on attribute in milliseconds. * @param delay_on The Delay_On Value in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setDelay_On(int delay_on) throws IOException{ - this.setAttribute(Def.PROPERTY_DELAY_ON, Integer.toString(delay_on)); + public void setDelay_On(int delay_on) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_DELAY_ON, Integer.toString(delay_on)); } /** * The timer trigger will periodically change the LED brightness between 0 and the current brightness setting. * The off time can be specified via delay_off attribute in milliseconds. * @param delay_off The Delay_Off Value in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setDelay_Off(int delay_off) throws IOException{ - this.setAttribute(Def.PROPERTY_DELAY_OFF, Integer.toString(delay_off)); + public void setDelay_Off(int delay_off) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_DELAY_OFF, Integer.toString(delay_off)); + } + + @Override + public String getAddress() throws EV3LibraryException { + return null; + } + + @Override + public String getDriverName() throws EV3LibraryException { + return null; } } \ No newline at end of file diff --git a/src/main/java/org/ev3dev/hardware/PowerSupply.java b/src/main/java/org/ev3dev/hardware/PowerSupply.java index 5d7f452..27eb760 100644 --- a/src/main/java/org/ev3dev/hardware/PowerSupply.java +++ b/src/main/java/org/ev3dev/hardware/PowerSupply.java @@ -1,72 +1,136 @@ package org.ev3dev.hardware; +import java.io.FileNotFoundException; import java.io.IOException; -import org.ev3dev.io.Def; -import org.ev3dev.io.Sysclass; +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.io.Sysfs; /*** - * A generic interface to read data from the system・s power_supply class. Uses the built-in legoev3-battery if none is specified. + * A generic interface to read data from the system's power_supply class. Uses the built-in legoev3-battery if none is specified. * @author Anthony * */ public class PowerSupply{ + /** + * The Sysfs class's measured_current property name + */ + public static final String SYSFS_MEASURED_CURRENT = "measured_current"; + + /** + * The Sysfs class's measured_voltage property name + */ + public static final String SYSFS_MEASURED_VOLTAGE = "measured_voltage"; + + /** + * The Sysfs class's max_voltage property name + */ + public static final String SYSFS_MAX_VOLTAGE = "max_voltage"; + + /** + * The Sysfs class's min_voltage property name + */ + public static final String SYSFS_MIN_VOLTAGE = "min_voltage"; + + /** + * The Sysfs class's technology property name + */ + public static final String SYSFS_TECHNOLOGY = "technology"; + + /** + * The Sysfs class's type property name + */ + public static final String SYSFS_TYPE = "type"; + + /** + * This Sysfs's class name (e.g. /sys/class/lego-sensor, and lego-sensor is the class name) + */ + public static final String POWER_SUPPLY_CLASS_NAME = "power_supply"; + /*** * The measured current that the battery is supplying (in microamps) * @return Measured Current - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public static int getMeasuredCurrent() throws IOException{ - String str = Sysclass.getAttribute(Def.POWER_SUPPLY_CLASS_NAME, Def.PROPERTY_MEASURED_CURRENT); + public static int getMeasuredCurrent() throws EV3LibraryException{ + String str; + try { + str = Sysfs.getAttribute(POWER_SUPPLY_CLASS_NAME, SYSFS_MEASURED_CURRENT); + } catch (IOException e) { + throw new EV3LibraryException("Get measured current attribute failed", e); + } return Integer.parseInt(str); } /*** * The measured voltage that the battery is supplying (in microvolts) * @return Measured Voltage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public static int getMeasuredVoltage() throws IOException{ - String str = Sysclass.getAttribute(Def.POWER_SUPPLY_CLASS_NAME, Def.PROPERTY_MEASURED_VOLTAGE); + public static int getMeasuredVoltage() throws EV3LibraryException{ + String str; + try { + str = Sysfs.getAttribute(POWER_SUPPLY_CLASS_NAME, SYSFS_MEASURED_VOLTAGE); + } catch (IOException e) { + throw new EV3LibraryException("Get measured voltage attribute failed", e); + } return Integer.parseInt(str); } /*** * Get the maximum voltage * @return Maximum Voltage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public static int getMaxVoltage() throws IOException{ - String str = Sysclass.getAttribute(Def.POWER_SUPPLY_CLASS_NAME, Def.PROPERTY_MAX_VOLTAGE); + public static int getMaxVoltage() throws EV3LibraryException{ + String str; + try { + str = Sysfs.getAttribute(POWER_SUPPLY_CLASS_NAME, SYSFS_MAX_VOLTAGE); + } catch (IOException e) { + throw new EV3LibraryException("Get max voltage attribute failed", e); + } return Integer.parseInt(str); } /*** * Get the minimum voltage * @return Minimum Voltage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public static int getMinVoltage() throws IOException{ - String str = Sysclass.getAttribute(Def.POWER_SUPPLY_CLASS_NAME, Def.PROPERTY_MIN_VOLTAGE); + public static int getMinVoltage() throws EV3LibraryException{ + String str; + try { + str = Sysfs.getAttribute(POWER_SUPPLY_CLASS_NAME, SYSFS_MIN_VOLTAGE); + } catch (IOException e) { + throw new EV3LibraryException("Get min voltage attribute failed", e); + } return Integer.parseInt(str); } /*** * Get the technology of this power supply * @return String - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public static String getTechnology() throws IOException{ - return Sysclass.getAttribute(Def.POWER_SUPPLY_CLASS_NAME, Def.PROPERTY_TECHNOLOGY); + public static String getTechnology() throws EV3LibraryException{ + try { + return Sysfs.getAttribute(POWER_SUPPLY_CLASS_NAME, SYSFS_TECHNOLOGY); + } catch (IOException e) { + throw new EV3LibraryException("Get technology attribute failed", e); + } } /*** * Get the type of this power supply * @return String - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public static String getType() throws IOException{ - return Sysclass.getAttribute(Def.POWER_SUPPLY_CLASS_NAME, Def.PROPERTY_TYPE); + public static String getType() throws EV3LibraryException{ + try { + return Sysfs.getAttribute(POWER_SUPPLY_CLASS_NAME, SYSFS_TYPE); + } catch (IOException e) { + throw new EV3LibraryException("Get type attribute failed", e); + } } } diff --git a/src/main/java/org/ev3dev/hardware/VLCDFrame.java b/src/main/java/org/ev3dev/hardware/VLCDFrame.java new file mode 100644 index 0000000..972f43b --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/VLCDFrame.java @@ -0,0 +1,54 @@ +package org.ev3dev.hardware; + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.Timer; +import javax.swing.border.EmptyBorder; + +import org.ev3dev.hardware.VirtualLCD; +import javax.swing.JLabel; +import javax.swing.SwingConstants; +import java.awt.Color; + +public class VLCDFrame extends JFrame { + + private JPanel contentPane; + private VirtualLCD lcd; + private Thread thread; + private JLabel lblImg; + + /** + * Create the frame. + */ + public VLCDFrame(VirtualLCD vlcd) { + setTitle("ev3dev-lang-java VirtualLCD"); + this.lcd = vlcd; + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(100, 100, 418, 321); + contentPane = new JPanel(); + contentPane.setBackground(Color.LIGHT_GRAY); + contentPane.setBorder(null); + contentPane.setLayout(new BorderLayout(0, 0)); + setContentPane(contentPane); + + lblImg = new JLabel(""); + lblImg.setHorizontalAlignment(SwingConstants.CENTER); + contentPane.add(lblImg, BorderLayout.CENTER); + + thread = new Thread(new Runnable(){ + + public void run() { + lblImg.setIcon(new ImageIcon(lcd.getImage())); + } + + }); + thread.start(); + } + +} diff --git a/src/main/java/org/ev3dev/hardware/VirtualLCD.java b/src/main/java/org/ev3dev/hardware/VirtualLCD.java new file mode 100644 index 0000000..930bd24 --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/VirtualLCD.java @@ -0,0 +1,70 @@ +package org.ev3dev.hardware; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.io.IOException; + +import javax.imageio.ImageIO; + +/** + * Provides an interface for developers to emulate the LCD in ev3 + * @author Anthony + * + */ +public class VirtualLCD extends LCD{ + + private BufferedImage image; + + /** + * Creates a new virtual LCD instance + */ + public VirtualLCD(){ + //image = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_ARGB); + try { + image = ImageIO.read(VirtualLCD.class.getResource("/org/ev3dev/hardware/defaultvirtuallcd.fw.png")); + } catch (IOException e) { + } + } + + /** + * Returns the image drawn + * @return BufferedImage + */ + public BufferedImage getImage(){ + return image; + } + + /** + * Starts up an UI showing the virtual LCD + */ + public void showVLCD(){ + VLCDFrame frame = new VLCDFrame(this); + frame.setVisible(true); + frame.setTitle(this.hashCode() + " - VirtualLCD"); + } + + /** + * This function overrides the original draw() function to draw directly into a BufferedImage + */ + @Override + public void draw(byte[] data){ + if (data == null){ + return; + } + + Graphics g = image.getGraphics(); + for (int i = 0; i < 128; i++){ + for (int j = 0; j < 178; j++){ + if (data[i * 24 + j / 8] == (byte) 0xff){ + g.setColor(Color.BLACK); + g.drawLine(j, i, j, i); + } else { + g.setColor(Color.WHITE); + g.drawLine(j, i, j, i); + } + } + } + } +} diff --git a/src/main/java/org/ev3dev/hardware/defaultvirtuallcd.fw.png b/src/main/java/org/ev3dev/hardware/defaultvirtuallcd.fw.png new file mode 100644 index 0000000..c6cb3ef Binary files /dev/null and b/src/main/java/org/ev3dev/hardware/defaultvirtuallcd.fw.png differ diff --git a/src/main/java/org/ev3dev/hardware/motors/DCMotor.java b/src/main/java/org/ev3dev/hardware/motors/DCMotor.java index 0da9e33..2707c23 100644 --- a/src/main/java/org/ev3dev/hardware/motors/DCMotor.java +++ b/src/main/java/org/ev3dev/hardware/motors/DCMotor.java @@ -1,13 +1,11 @@ package org.ev3dev.hardware.motors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidMotorException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.hardware.Device; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; -import org.ev3dev.io.Sysclass; +import org.ev3dev.io.Sysfs; /** * The DC motor class provides a uniform interface for using regular DC motors @@ -16,24 +14,118 @@ * */ public class DCMotor extends Device{ + + /** + * The Sysfs class's address property name + */ + public static final String SYSFS_PROPERTY_ADDRESS = "address"; + + /** + * The Sysfs class's command property name + */ + public static final String SYSFS_PROPERTY_COMMAND = "command"; + + /** + * The Sysfs class's commands property name + */ + public static final String SYSFS_PROPERTY_COMMANDS = "commands"; + + /** + * The Sysfs class's driver_name property name + */ + public static final String SYSFS_PROPERTY_DRIVER_NAME = "driver_name"; + + /** + * The Sysfs class's duty_cycle property name + */ + public static final String SYSFS_PROPERTY_DUTY_CYCLE = "duty_cycle"; + + /** + * The Sysfs class's duty_cycle_sp property name + */ + public static final String SYSFS_PROPERTY_DUTY_CYCLE_SP = "duty_cycle_sp"; + + /** + * The Sysfs class's polarity property name + */ + public static final String SYSFS_PROPERTY_POLARITY = "polarity"; + + /** + * The Sysfs class's ramp_up_sp property name + */ + public static final String SYSFS_PROPERTY_RAMP_UP_SP = "ramp_up_sp"; + + /** + * The Sysfs class's ramp_down_sp property name + */ + public static final String SYSFS_PROPERTY_RAMP_DOWN_SP = "ramp_down_sp"; + + /** + * The Sysfs class's state property name + */ + public static final String SYSFS_PROPERTY_STATE = "state"; + + /** + * The Sysfs class's stop_action property name + */ + public static final String SYSFS_PROPERTY_STOP_ACTION = "stop_action"; + + /** + * The Sysfs class's stop_actions property name + */ + public static final String SYSFS_PROPERTY_STOP_ACTIONS = "stop_actions"; + + /** + * The Sysfs class's time_sp property name + */ + public static final String SYSFS_PROPERTY_TIME_SP = "time_sp"; + + /** + * The Sysfs class's run-forever command + */ + public static final String SYSFS_COMMAND_RUN_FOREVER = "run-forever"; + + /** + * The Sysfs class's run-timed command + */ + public static final String SYSFS_COMMAND_RUN_TIMED = "run-timed"; + + /** + * The Sysfs class's run-direct command + */ + public static final String SYSFS_COMMAND_RUN_DIRECT = "run-direct"; + + /** + * The Sysfs class's stop command + */ + public static final String SYSFS_COMMAND_STOP = "stop"; + + /** + * This Sysfs's class name (e.g. /sys/class/lego-sensor, and lego-sensor is the class name) + */ + public static final String CLASS_NAME = "dc-motor"; + + /** + * This Sysfs's class name prefix (e.g. /sys/class/lego-sensor/sensor0, and sensor is the class name prefix without the [N] value.) + */ + public static final String CLASS_NAME_PREFIX = "motor"; private String address; /*** * Creates a new DC motor object. * @param port LegoPort - * @throws InvalidPortException If the LegoPort isn't a OUTPUT, invalid. - * @throws IOException If the LegoPort specified goes wrong - * @throws InvalidMotorException If the specified port wasn't exist a ServoMotor + * @throws EV3LibraryException If the LegoPort specified goes wrong */ - public DCMotor(LegoPort port) throws InvalidPortException, IOException, InvalidMotorException{ - super(port, Def.DC_MOTOR_CLASS_NAME, Def.SUB_MOTOR_CLASS_NAME); + public DCMotor(LegoPort port) throws EV3LibraryException{ + super(port, CLASS_NAME, CLASS_NAME_PREFIX); + address = port.getAddress(); //Verify is the LegoPort connecting a motor / is a output if (!address.contains("out")){ throw new InvalidPortException("The specified port (" + port.getAddress() + ") isn't a output."); - } else if (!port.getStatus().equals(Def.DC_MOTOR_CLASS_NAME)){ + } else if (!port.getStatus().equals(CLASS_NAME)){ throw new InvalidMotorException("The specified port (" + port.getAddress() + ") isn't a motor (" + port.getStatus() + ")"); } } @@ -41,45 +133,55 @@ public DCMotor(LegoPort port) throws InvalidPortException, IOException, InvalidM /*** * Get the address of this motor. * @return LegoPort address described in String - * @throws IOException If the motor doesn't exist or IO ERROR + * @throws EV3LibraryException If the motor doesn't exist or IO ERROR */ - public String getAddress() throws IOException{ - return this.getAttribute(Def.PROPERTY_ADDRESS); + public String getAddress() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_ADDRESS); } /*** * Generic method to send commands to the motor controller. * @param command Command that suits for the motor driver - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void sendCommand(String command) throws IOException{ - this.setAttribute(Def.PROPERTY_COMMAND, command); + public void sendCommand(String command) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_COMMAND, command); } /*** * Cause the motor to run until another command is sent - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void runForever() throws IOException{ - sendCommand(Def.COMMAND_RUN_FOREVER); + public void runForever() throws EV3LibraryException{ + sendCommand(SYSFS_COMMAND_RUN_FOREVER); } /*** * Run the motor for the amount of time specified in time_sp * and then stop the motor using the command specified by * stop_command - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong + */ + public void runTimed() throws EV3LibraryException{ + sendCommand(SYSFS_COMMAND_RUN_TIMED); + } + + /** + * Runs the motor at the duty cycle specified by duty_cycle_sp. + * Unlike other run commands, changing duty_cycle_sp while running + * will take effect immediately. + * @throws EV3LibraryException If I/O goes wrong */ - public void runTimed() throws IOException{ - sendCommand(Def.COMMAND_RUN_TIMED); + public void runDirect() throws EV3LibraryException{ + sendCommand(SYSFS_COMMAND_RUN_DIRECT); } /** * Stop any of the run commands before they are complete using the command specified by stop_command. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void stop() throws IOException{ - sendCommand(Def.COMMAND_STOP); + public void stop() throws EV3LibraryException{ + sendCommand(SYSFS_COMMAND_STOP); } /** @@ -87,29 +189,29 @@ public void stop() throws IOException{ * Possible values are run-forever, run-to-abs-pos, run-to-rel-pos, * run-timed, run-direct, stop and reset. Not all commands may be supported. * @return A String Arrays with all the supported commands - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getCommands() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_COMMANDS); - return Sysclass.separateSpace(str); + public String[] getCommands() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_COMMANDS); + return Sysfs.separateSpace(str); } /** * Returns the name of the driver that provides this tacho motor device. * @return The name of the driver - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getDriverName() throws IOException{ - return this.getAttribute(Def.PROPERTY_DRIVER_NAME); + public String getDriverName() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_DRIVER_NAME); } /** * Returns the current duty cycle of the motor. Units are percent. Values are -100 to 100. * @return Percentage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getDutyCycle() throws IOException{ - String dutycycle = this.getAttribute(Def.PROPERTY_DUTY_CYCLE); + public int getDutyCycle() throws EV3LibraryException{ + String dutycycle = this.getAttribute(SYSFS_PROPERTY_DUTY_CYCLE); return Integer.parseInt(dutycycle); } @@ -118,10 +220,10 @@ public int getDutyCycle() throws IOException{ * Valid values are -100 to 100. A negative value causes the motor to rotate in reverse. * This value is only used when speed_regulation is off. * @return Percentage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getDutyCycleSP() throws IOException{ - String dutycyclesp = this.getAttribute(Def.PROPERTY_DUTY_CYCLE_SP); + public int getDutyCycleSP() throws EV3LibraryException{ + String dutycyclesp = this.getAttribute(SYSFS_PROPERTY_DUTY_CYCLE_SP); return Integer.parseInt(dutycyclesp); } @@ -130,30 +232,30 @@ public int getDutyCycleSP() throws IOException{ * Valid values are -100 to 100. A negative value causes the motor to rotate in reverse. * This value is only used when speed_regulation is off. * @param sp Percentage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setDutyCycleSP(int sp) throws IOException{ - this.setAttribute(Def.PROPERTY_DUTY_CYCLE_SP, Integer.toString(sp)); + public void setDutyCycleSP(int sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_DUTY_CYCLE_SP, Integer.toString(sp)); } /** * Sets the polarity of the motor. With normal polarity, a positive duty cycle will cause the motor to rotate clockwise. * With inversed polarity, a positive duty cycle will cause the motor to rotate counter-clockwise. Valid values are normal and inversed. * @return The polarity of the motor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getPolarity() throws IOException{ - return this.getAttribute(Def.PROPERTY_POLARITY); + public String getPolarity() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_POLARITY); } /** * Sets the polarity of the motor. With normal polarity, a positive duty cycle will cause the motor to rotate clockwise. With inversed polarity, * a positive duty cycle will cause the motor to rotate counter-clockwise. Valid values are normal and inversed. * @param polarity The polarity of the motor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPolarity(String polarity) throws IOException{ - this.setAttribute(Def.PROPERTY_POLARITY, polarity); + public void setPolarity(String polarity) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_POLARITY, polarity); } /** @@ -163,10 +265,10 @@ public void setPolarity(String polarity) throws IOException{ * limited by duty_cycle_sp or speed regulation, * the actual ramp time duration will be less than the setpoint. * @return The ramp-up set-point - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getRamp_Up_SP() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_RAMP_UP_SP); + public int getRamp_Up_SP() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_RAMP_UP_SP); return Integer.parseInt(str); } @@ -177,10 +279,10 @@ public int getRamp_Up_SP() throws IOException{ * limited by duty_cycle_sp or speed regulation, * the actual ramp time duration will be less than the setpoint. * @param ramp_up_sp The ramp-up set-point - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setRamp_Up_SP(int ramp_up_sp) throws IOException{ - this.setAttribute(Def.PROPERTY_RAMP_UP_SP, Integer.toString(ramp_up_sp)); + public void setRamp_Up_SP(int ramp_up_sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_RAMP_UP_SP, Integer.toString(ramp_up_sp)); } /** @@ -189,10 +291,10 @@ public void setRamp_Up_SP(int ramp_up_sp) throws IOException{ * to 0 over the span of this setpoint when stopping the motor. If the starting * duty cycle is less than 100%, the ramp time duration will be less than the full span of the setpoint. * @return The ramp-down set-point - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getRamp_Down_SP() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_RAMP_DOWN_SP); + public int getRamp_Down_SP() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_RAMP_DOWN_SP); return Integer.parseInt(str); } @@ -202,10 +304,10 @@ public int getRamp_Down_SP() throws IOException{ * to 0 over the span of this setpoint when stopping the motor. If the starting * duty cycle is less than 100%, the ramp time duration will be less than the full span of the setpoint. * @param ramp_down_sp The ramp-down set-point - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setRamp_Down_SP(int ramp_down_sp) throws IOException{ - this.setAttribute(Def.PROPERTY_RAMP_DOWN_SP, Integer.toString(ramp_down_sp)); + public void setRamp_Down_SP(int ramp_down_sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_RAMP_DOWN_SP, Integer.toString(ramp_down_sp)); } /** @@ -216,40 +318,40 @@ public void setRamp_Down_SP(int ramp_down_sp) throws IOException{ * * Reading returns a list of state flags. Possible flags are running, ramping holding and stalled. * @return A list of state flags. String spaced-array - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getStateViaString() throws IOException{ - return this.getAttribute(Def.PROPERTY_STATE); + public String getStateViaString() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_STATE); } /** * Reading returns a list of state flags. Possible flags are running, ramping holding and stalled. * @return A list(String array) of state flags. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getState() throws IOException{ + public String[] getState() throws EV3LibraryException{ String str = getStateViaString(); - return Sysclass.separateSpace(str); + return Sysfs.separateSpace(str); } /** * Reading returns the current stop command. Writing sets the stop command. The value determines the motors behavior when command is set to stop. * Also, it determines the motors behavior when a run command completes. See stop_commands for a list of possible values. - * @return A stop command that listed using getStopCommands() - * @throws IOException If I/O goes wrong + * @return A stop command that listed using getStopActions() + * @throws EV3LibraryException If I/O goes wrong */ - public String getStopCommand() throws IOException{ - return this.getAttribute(Def.PROPERTY_STOP_ACTION); + public String getStopAction() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_STOP_ACTION); } /** * Reading returns the current stop command. Writing sets the stop command. The value determines the motors behavior when command is set to stop. * Also, it determines the motors behavior when a run command completes. See stop_commands for a list of possible values. * @param stop_command A stop command that listed using getStopCommands() - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setStopCommand(String stop_command) throws IOException{ - this.setAttribute(Def.PROPERTY_STOP_ACTION, stop_command); + public void setStopAction(String stop_command) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_STOP_ACTION, stop_command); } /** @@ -265,12 +367,12 @@ public void setStopCommand(String stop_command) throws IOException{ * terminals together. This load will absorb the energy from the rotation of the motors * and cause the motor to stop more quickly than coasting. hold does not remove power from * the motor. Instead it actively try to hold the motor at the current position. - * If an external force tries to turn the motor, the motor will .push back・ to maintain its position. + * If an external force tries to turn the motor, the motor will 'push back' to maintain its position. * @return A list of stop modes supported by the motor controller - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getStopCommandsViaString() throws IOException{ - return this.getAttribute(Def.PROPERTY_STOP_ACTIONS); + public String getStopActionsViaString() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_STOP_ACTIONS); } /** @@ -281,31 +383,31 @@ public String getStopCommandsViaString() throws IOException{ * terminals together. This load will absorb the energy from the rotation of the motors * and cause the motor to stop more quickly than coasting. hold does not remove power from * the motor. Instead it actively try to hold the motor at the current position. - * If an external force tries to turn the motor, the motor will .push back・ to maintain its position. + * If an external force tries to turn the motor, the motor will 'push back' to maintain its position. * @return A list of stop modes supported by the motor controller - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getStopCommands() throws IOException{ - String str = getStopCommandsViaString(); - return Sysclass.separateSpace(str); + public String[] getStopActions() throws EV3LibraryException{ + String str = getStopActionsViaString(); + return Sysfs.separateSpace(str); } /** * Writing specifies the amount of time the motor will run when using the run-timed command. Reading returns the current value. Units are in milliseconds. * @return Amount of time in ms - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getTime_SP() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_TIME_SP); + public int getTime_SP() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_TIME_SP); return Integer.parseInt(str); } /** * Writing specifies the amount of time the motor will run when using the run-timed command. Reading returns the current value. Units are in milliseconds. * @param time_sp Amount of time in ms - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setTime_SP(int time_sp) throws IOException{ - this.setAttribute(Def.PROPERTY_TIME_SP, Integer.toString(time_sp)); + public void setTime_SP(int time_sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_TIME_SP, Integer.toString(time_sp)); } } diff --git a/src/main/java/org/ev3dev/hardware/motors/FirgelliL12100Motor.java b/src/main/java/org/ev3dev/hardware/motors/FirgelliL12100Motor.java new file mode 100644 index 0000000..52b2cd9 --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/motors/FirgelliL12100Motor.java @@ -0,0 +1,80 @@ +package org.ev3dev.hardware.motors; + +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.exception.InvalidPortException; +import org.ev3dev.hardware.ports.LegoPort; + +public class FirgelliL12100Motor extends Motor { + + /** + * The Sysfs class's count_per_m property name + */ + public static final String SYSFS_PROPERTY_COUNT_PER_M = "count_per_m"; + + /** + * The Sysfs class's full_travel_count property name + */ + public static final String SYSFS_PROPERTY_FULL_TRAVEL_COUNT = "full_travel_count"; + + /** + * This Sysfs's class name prefix (e.g. /sys/class/lego-sensor/sensor0, and sensor is the class name prefix without the [N] value.) + */ + public static final String LINEAR_MOTOR_CLASS_NAME_PREFIX = "linear"; + + /** + * The driver name for the L12 EV3 100mm by Actuonix + */ + public static final String DRIVER_NAME_100MM = "act-l12-ev3-100"; + + public FirgelliL12100Motor(int portField) throws EV3LibraryException { + this(new LegoPort(portField)); + } + + public FirgelliL12100Motor(LegoPort port) throws EV3LibraryException { + super(port, LINEAR_MOTOR_CLASS_NAME_PREFIX); + if (!port.getDriverName().equals(DRIVER_NAME_100MM)){ + throw new InvalidPortException("The port does not have a Firgelli L12 100 Motor."); + } + } + + /** + * Do not use this on Firgelli L12 50/100 Motors (Linear motors).
+ * -1 will be returned instead, use getCountPerMetre() + */ + @Override + public int getCountPerRot() throws EV3LibraryException{ + return -1; + } + + /** + * Returns the number of tacho counts in one meter of travel of the motor. + * Tacho counts are used by the position and speed attributes, so you can + * use this value to convert from distance to tacho counts. (linear motors only) + * @return Counts per metre + * @throws EV3LibraryException If I/O goes wrong + */ + public int getCountPerMetre() throws EV3LibraryException{ + if (!this.isConnected()){ + return -1; + } + String countpermetre = this.getAttribute(SYSFS_PROPERTY_COUNT_PER_M); + return Integer.parseInt(countpermetre); + } + + /** + * Returns the number of tacho counts in the full travel of the motor. + * When combined with the count_per_m attribute, you can use this value + * to calculate the maximum travel distance of the motor. + * (linear motors only) + * @return Full Travel Count + * @throws EV3LibraryException If I/O goes wrong + */ + public int getFullTravelCount() throws EV3LibraryException{ + if (!this.isConnected()){ + return -1; + } + String str = this.getAttribute(SYSFS_PROPERTY_FULL_TRAVEL_COUNT); + return Integer.parseInt(str); + } + +} diff --git a/src/main/java/org/ev3dev/hardware/motors/FirgelliL1250Motor.java b/src/main/java/org/ev3dev/hardware/motors/FirgelliL1250Motor.java new file mode 100644 index 0000000..ea1d49f --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/motors/FirgelliL1250Motor.java @@ -0,0 +1,80 @@ +package org.ev3dev.hardware.motors; + +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.exception.InvalidPortException; +import org.ev3dev.hardware.ports.LegoPort; + +public class FirgelliL1250Motor extends Motor { + + /** + * The Sysfs class's count_per_m property name + */ + public static final String SYSFS_PROPERTY_COUNT_PER_M = "count_per_m"; + + /** + * The Sysfs class's full_travel_count property name + */ + public static final String SYSFS_PROPERTY_FULL_TRAVEL_COUNT = "full_travel_count"; + + /** + * This Sysfs's class name prefix (e.g. /sys/class/lego-sensor/sensor0, and sensor is the class name prefix without the [N] value.) + */ + public static final String LINEAR_MOTOR_CLASS_NAME_PREFIX = "linear"; + + /** + * The driver name for the L12 EV3 50mm by Actuonix + */ + public static final String DRIVER_NAME_50MM = "act-l12-ev3-50"; + + public FirgelliL1250Motor(int portField) throws EV3LibraryException { + this(new LegoPort(portField)); + } + + public FirgelliL1250Motor(LegoPort port) throws EV3LibraryException { + super(port, LINEAR_MOTOR_CLASS_NAME_PREFIX); + if (!port.getDriverName().equals(DRIVER_NAME_50MM)){ + throw new InvalidPortException("The port does not have a Firgelli L12 50 Motor driver."); + } + } + + /** + * Do not use this on Firgelli L12 50/100 Motors (Linear motors).
+ * -1 will be returned instead, use getCountPerMetre() + */ + @Override + public int getCountPerRot() throws EV3LibraryException{ + return -1; + } + + /** + * Returns the number of tacho counts in one meter of travel of the motor. + * Tacho counts are used by the position and speed attributes, so you can + * use this value to convert from distance to tacho counts. (linear motors only) + * @return Counts per metre + * @throws EV3LibraryException If I/O goes wrong + */ + public int getCountPerMetre() throws EV3LibraryException{ + if (!this.isConnected()){ + return -1; + } + String countpermetre = this.getAttribute(SYSFS_PROPERTY_COUNT_PER_M); + return Integer.parseInt(countpermetre); + } + + /** + * Returns the number of tacho counts in the full travel of the motor. + * When combined with the count_per_m attribute, you can use this value + * to calculate the maximum travel distance of the motor. + * (linear motors only) + * @return Full Travel Count + * @throws EV3LibraryException If I/O goes wrong + */ + public int getFullTravelCount() throws EV3LibraryException{ + if (!this.isConnected()){ + return -1; + } + String str = this.getAttribute(SYSFS_PROPERTY_FULL_TRAVEL_COUNT); + return Integer.parseInt(str); + } + +} diff --git a/src/main/java/org/ev3dev/hardware/motors/LargeMotor.java b/src/main/java/org/ev3dev/hardware/motors/LargeMotor.java index b4ab86a..1cc063c 100644 --- a/src/main/java/org/ev3dev/hardware/motors/LargeMotor.java +++ b/src/main/java/org/ev3dev/hardware/motors/LargeMotor.java @@ -5,15 +5,23 @@ import org.ev3dev.exception.InvalidMotorException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; public class LargeMotor extends Motor { + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "lego-ev3-l-motor"; + + public LargeMotor(int portField) throws InvalidPortException, IOException { + this(new LegoPort(portField)); + } + public LargeMotor(LegoPort port) throws InvalidPortException, IOException, InvalidMotorException { super(port); String drivername = this.getDriverName(); - if (!drivername.equals(Def.LARGE_MOTOR_DRIVER_NAME)){ - throw new InvalidMotorException("It is not a LargeMotor (" + Def.LARGE_MOTOR_DRIVER_NAME + "): " + drivername); + if (!drivername.equals(DRIVER_NAME)){ + throw new InvalidMotorException("The port is not connected to a LargeMotor (" + DRIVER_NAME + "): " + drivername); } } diff --git a/src/main/java/org/ev3dev/hardware/motors/Linear.java b/src/main/java/org/ev3dev/hardware/motors/Linear.java deleted file mode 100644 index b40ec36..0000000 --- a/src/main/java/org/ev3dev/hardware/motors/Linear.java +++ /dev/null @@ -1,735 +0,0 @@ -//----------------------------------------------------------------------------- -//~autogen autogen-header - -//~autogen -//----------------------------------------------------------------------------- - -package org.ev3dev.hardware.motors; - -//----------------------------------------------------------------------------- - -import java.io.IOException; - -import org.ev3dev.exception.InvalidPortException; -import org.ev3dev.hardware.Device; -import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; -import org.ev3dev.io.Sysclass; - -//----------------------------------------------------------------------------- - -//~autogen generic-classes classes.motor>currentClass - - -//~autogen - - -/** - * The motor class provides a uniform interface for using motors with positional and directional feedback such as the EV3 and NXT motors. - * This feedback allows for precise control of the motors. This is the most common type of motor, so we just call it motor. - * @author Anthony - * - */ -public class Linear extends Device{ - -//----------------------------------------------------------------------------- - - private String address; - -//----------------------------------------------------------------------------- - - /*** - * Creates a new motor object. - * @param port LegoPort - * @throws InvalidPortException If the LegoPort isn't a OUTPUT, invalid or a tacho-motor. - * @throws IOException If the LegoPort specified goes wrong - */ - public Linear(LegoPort port) throws InvalidPortException, IOException{ - super(port, Def.MOTOR_CLASS_NAME, Def.SUB_LINEAR_CLASS_NAME); - address = port.getAddress(); - - //Verify is the LegoPort connecting a motor / is a output - if (!address.contains("out")){ - throw new InvalidPortException("The specified port (" + port.getAddress() + ") isn't a output."); - } - } - -//----------------------------------------------------------------------------- - -//~autogen generic-get-set classes.motor>currentClass - /*** - * Get the address of this motor. - * @return LegoPort address described in String - * @throws IOException If the motor doesn't exist or IO ERROR - */ - public String getAddress() throws IOException{ - if (!this.isConnected()){ - return null; - } - return this.getAttribute(Def.PROPERTY_ADDRESS); - } - - /*** - * Generic method to send commands to the motor controller. - * @param command Command that suits for the motor driver - * @throws IOException If I/O goes wrong - */ - public void sendCommand(String command) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_COMMAND, command); - } - - /*** - * Cause the motor to run until another command is sent - * @throws IOException If I/O goes wrong - */ - public void runForever() throws IOException{ - if (!this.isConnected()){ - return; - } - sendCommand(Def.COMMAND_RUN_FOREVER); - } - - /*** - * Run to an absolute position specified by position_sp - * and then stop using the command specified in stop_command - * @throws IOException If I/O goes wrong - */ - public void runToAbsPos() throws IOException{ - if (!this.isConnected()){ - return; - } - sendCommand(Def.COMMAND_RUN_TO_ABS_POS); - } - - /*** - * Run to a position relative to the current position value. - * The new position will be current position + position_sp. - * When the new position is reached, the motor will stop - * using the command specified by stop_command. - * @throws IOException If I/O goes wrong. - */ - public void runToRelPos() throws IOException{ - if (!this.isConnected()){ - return; - } - sendCommand(Def.COMMAND_RUN_TO_REL_POS); - } - - /*** - * Run the motor for the amount of time specified in time_sp - * and then stop the motor using the command specified by - * stop_command - * @throws IOException If I/O goes wrong - */ - public void runTimed() throws IOException{ - if (!this.isConnected()){ - return; - } - sendCommand(Def.COMMAND_RUN_TIMED); - } - - /*** - * Run the motor at the duty cycle specified by duty_cycle_sp. - * Unlike other run commands, changing duty_cycle_sp while - * running will take effect immediately - * @throws IOException If I/O goes wrong - */ - public void runDirect() throws IOException{ - if (!this.isConnected()){ - return; - } - sendCommand(Def.COMMAND_RUN_DIRECT); - } - - /** - * Stop any of the run commands before they are complete using the command specified by stop_command. - * @throws IOException If I/O goes wrong - */ - public void stop() throws IOException{ - if (!this.isConnected()){ - return; - } - sendCommand(Def.COMMAND_STOP); - } - - /** - * Reset all of the motor parameter attributes to their default value. This will also have the effect of stopping the motor. - * @throws IOException If I/O goes wrong - */ - public void reset() throws IOException{ - if (!this.isConnected()){ - return; - } - sendCommand(Def.COMMAND_RESET); - } - - /** - * Returns a list of commands that are supported by the motor controller. - * Possible values are run-forever, run-to-abs-pos, run-to-rel-pos, - * run-timed, run-direct, stop and reset. Not all commands may be supported. - * @return A String Arrays with all the supported commands - * @throws IOException If I/O goes wrong - */ - public String[] getCommands() throws IOException{ - if (!this.isConnected()){ - return null; - } - String str = this.getAttribute(Def.PROPERTY_COMMANDS); - return Sysclass.separateSpace(str); - } - - /** - * Returns the number of tacho counts in one metre of the motor. - * @return Counts per metre - * @throws IOException If I/O goes wrong - */ - public int getCountPerMetre() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String countpermetre = this.getAttribute(Def.PROPERTY_COUNT_PER_M); - return Integer.parseInt(countpermetre); - } - - /** - * Returns the name of the driver that provides this tacho motor device. - * @return The name of the driver - * @throws IOException If I/O goes wrong - */ - public String getDriverName() throws IOException{ - if (!this.isConnected()){ - return null; - } - return this.getAttribute(Def.PROPERTY_DRIVER_NAME); - } - - - /** - * Returns the current duty cycle of the motor. Units are percent. Values are -100 to 100. - * @return Percentage - * @throws IOException If I/O goes wrong - */ - public int getDutyCycle() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String dutycycle = this.getAttribute(Def.PROPERTY_DUTY_CYCLE); - return Integer.parseInt(dutycycle); - } - - /** - * Writing sets the duty cycle setpoint. Reading returns the current value. Units are in percent. - * Valid values are -100 to 100. A negative value causes the motor to rotate in reverse. - * This value is only used when speed_regulation is off. - * @return Percentage - * @throws IOException If I/O goes wrong - */ - public int getDutyCycleSP() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String dutycyclesp = this.getAttribute(Def.PROPERTY_DUTY_CYCLE_SP); - return Integer.parseInt(dutycyclesp); - } - - /** - * Writing sets the duty cycle setpoint. Reading returns the current value. Units are in percent. - * Valid values are -100 to 100. A negative value causes the motor to rotate in reverse. - * This value is only used when speed_regulation is off. - * @param sp Percentage - * @throws IOException If I/O goes wrong - */ - public void setDutyCycleSP(int sp) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_DUTY_CYCLE_SP, Integer.toString(sp)); - } - - /** - * Sets the polarity of the motor. With normal polarity, a positive duty cycle will cause the motor to rotate clockwise. - * With inversed polarity, a positive duty cycle will cause the motor to rotate counter-clockwise. Valid values are normal and inversed. - * @return The polarity of the motor - * @throws IOException If I/O goes wrong - */ - public String getPolarity() throws IOException{ - if (!this.isConnected()){ - return null; - } - return this.getAttribute(Def.PROPERTY_POLARITY); - } - - /** - * Sets the polarity of the motor. With normal polarity, a positive duty cycle will cause the motor to rotate clockwise. With inversed polarity, - * a positive duty cycle will cause the motor to rotate counter-clockwise. Valid values are normal and inversed. - * @param polarity The polarity of the motor - * @throws IOException If I/O goes wrong - */ - public void setPolarity(String polarity) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_POLARITY, polarity); - } - - /** - * Returns the current position of the motor in pulses of the rotary encoder. When the motor rotates clockwise, the position will increase. Likewise, - * rotating counter-clockwise causes the position to decrease. Writing will set the position to that value. - * @return The current position - * @throws IOException If I/O goes wrong - */ - public int getPosition() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute("position_p"); - return Integer.parseInt(str); - } - - /** - * Returns the current position of the motor in pulses of the rotary encoder. When the motor rotates clockwise, the position will increase. - * Likewise, rotating counter-clockwise causes the position to decrease. Writing will set the position to that value. - * @param position The current position - * @throws IOException If I/O goes wrong - */ - public void setPosition(int position) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_POSITION, Integer.toString(position)); - } - - /** - * The proportional constant for the position PID. - * @return The proportional constant for the position PID. - * @throws IOException If I/O goes wrong - */ - public int getPosition_P() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_POSITION_P); - return Integer.parseInt(str); - } - - /** - * The integral constant for the position PID. - * @return The integral constant for the position PID. - * @throws IOException If I/O goes wrong - */ - public int getPosition_I() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_POSITION_I); - return Integer.parseInt(str); - } - - /** - * The derivative constant for the position PID. - * @return The derivative constant for the position PID. - * @throws IOException If I/O goes wrong - */ - public int getPosition_D() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_POSITION_D); - return Integer.parseInt(str); - } - - /** - * The proportional constant for the position PID. - * @param position_p The proportional constant for the position PID. - * @throws IOException If I/O goes wrong - */ - public void setPosition_P(int position_p) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_POSITION_P, Integer.toString(position_p)); - } - - /** - * The integral constant for the position PID. - * @param position_i The integral constant for the position PID. - * @throws IOException If I/O goes wrong - */ - public void setPosition_I(int position_i) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_POSITION_I, Integer.toString(position_i)); - } - - /** - * The derivative constant for the position PID. - * @param position_d The derivative constant for the position PID. - * @throws IOException If I/O goes wrong - */ - public void setPosition_D(int position_d) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_POSITION_D, Integer.toString(position_d)); - } - - /** - * Writing specifies the target position for the run-to-abs-pos and run-to-rel-pos commands. Reading returns the current value. - * Units are in tacho counts. You can use the value returned by counts_per_rot to convert tacho counts to/from rotations or degrees. - * @return The target position - * @throws IOException if I/O goes wrong - */ - public int getPosition_SP() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_POSITION_SP); - return Integer.parseInt(str); - } - - /** - * Writing specifies the target position for the run-to-abs-pos and run-to-rel-pos commands. Reading returns the current value. - * Units are in tacho counts. You can use the value returned by counts_per_rot to convert tacho counts to/from rotations or degrees. - * @param position_sp The target position - * @throws IOException If I/O goes wrong - */ - public void setPosition_SP(int position_sp) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_POSITION_SP, Integer.toString(position_sp)); - } - - /** - * Returns the current motor speed in tacho counts per second. Note, this is not necessarily degrees - * (although it is for LEGO motors). Use the count_per_rot attribute to convert this value to RPM or deg/sec. - * @return The current speed - * @throws IOException If I/O goes wrong - */ - public int getSpeed() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_SPEED); - return Integer.parseInt(str); - } - - /** - * Writing sets the target speed in tacho counts per second used when speed_regulation is on. - * Reading returns the current value. Use the count_per_rot attribute to convert RPM or deg/sec to tacho counts per second. - * @return The target speed - * @throws IOException If I/O goes wrong - */ - public int getSpeed_SP() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_SPEED); - return Integer.parseInt(str); - } - - /** - * Writing sets the target speed in tacho counts per second used when speed_regulation is on. Reading returns the current value. - * Use the count_per_rot attribute to convert RPM or deg/sec to tacho counts per second. - * @param speed_sp The target speed - * @throws IOException If I/O goes wrong - */ - public void setSpeed_SP(int speed_sp) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_SPEED_SP, Integer.toString(speed_sp)); - } - - /** - * Writing sets the ramp up setpoint. Reading returns the current value. Units are in milliseconds. - * When set to a value bigger than 0, the motor will ramp the power sent to the motor from 0 to 100% duty - * cycle over the span of this setpoint when starting the motor. If the maximum duty cycle is - * limited by duty_cycle_sp or speed regulation, - * the actual ramp time duration will be less than the setpoint. - * @return The ramp-up set-point - * @throws IOException If I/O goes wrong - */ - public int getRamp_Up_SP() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_RAMP_UP_SP); - return Integer.parseInt(str); - } - - /** - * Writing sets the ramp up setpoint. Reading returns the current value. Units are in milliseconds. - * When set to a value bigger than 0, the motor will ramp the power sent to the motor from 0 to 100% duty - * cycle over the span of this setpoint when starting the motor. If the maximum duty cycle is - * limited by duty_cycle_sp or speed regulation, - * the actual ramp time duration will be less than the setpoint. - * @param ramp_up_sp The ramp-up set-point - * @throws IOException If I/O goes wrong - */ - public void setRamp_Up_SP(int ramp_up_sp) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_RAMP_UP_SP, Integer.toString(ramp_up_sp)); - } - - /** - * Writing sets the ramp down setpoint. Reading returns the current value. Units are in milliseconds. - * When set to a value bigger than 0, the motor will ramp the power sent to the motor from 100% duty cycle down - * to 0 over the span of this setpoint when stopping the motor. If the starting - * duty cycle is less than 100%, the ramp time duration will be less than the full span of the setpoint. - * @return The ramp-down set-point - * @throws IOException If I/O goes wrong - */ - public int getRamp_Down_SP() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_RAMP_DOWN_SP); - return Integer.parseInt(str); - } - - /** - * Writing sets the ramp down setpoint. Reading returns the current value. Units are in milliseconds. - * When set to a value bigger than 0, the motor will ramp the power sent to the motor from 100% duty cycle down - * to 0 over the span of this setpoint when stopping the motor. If the starting - * duty cycle is less than 100%, the ramp time duration will be less than the full span of the setpoint. - * @param ramp_down_sp The ramp-down set-point - * @throws IOException If I/O goes wrong - */ - public void setRamp_Down_SP(int ramp_down_sp) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_RAMP_DOWN_SP, Integer.toString(ramp_down_sp)); - } - - /** - * Get the proportional constant for the speed regulation PID. - * @return The proportional constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public int getSpeedRegulation_P() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_SPEED_REGULATION_P); - return Integer.parseInt(str); - } - - /** - * Set the proportional constant for the speed regulation PID. - * @param p The proportional constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public void setSpeedRegulation_P(int p) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_SPEED_REGULATION_P, Integer.toString(p)); - } - - /** - * Get the integral constant for the speed regulation PID. - * @return The integral constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public int getSpeedRegulation_I() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_SPEED_REGULATION_I); - return Integer.parseInt(str); - } - - /** - * Set The integral constant for the speed regulation PID. - * @param i The integral constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public void setSpeedRegulation_I(int i) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_SPEED_REGULATION_I, Integer.toString(i)); - } - - /** - * Get the derivative constant for the speed regulation PID. - * @return The derivative constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public int getSpeedRegulation_D() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_SPEED_REGULATION_D); - return Integer.parseInt(str); - } - - /** - * Set the derivative constant for the speed regulation PID. - * @param d The derivative constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public void setSpeedRegulation_D(int d) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_SPEED_REGULATION_D, Integer.toString(d)); - } - - /** - * This function returns a string that is likely a "spaced-array".
- * Use this function to directly to return a String array: - *
-	 * getState()
-	 * 
- * Reading returns a list of state flags. Possible flags are running, ramping holding and stalled. - * @return A list of state flags. String spaced-array - * @throws IOException If I/O goes wrong - */ - public String getStateViaString() throws IOException{ - if (!this.isConnected()){ - return null; - } - return this.getAttribute(Def.PROPERTY_STATE); - } - - /** - * Reading returns a list of state flags. Possible flags are running, ramping holding and stalled. - * @return A list(String array) of state flags. - * @throws IOException If I/O goes wrong - */ - public String[] getState() throws IOException{ - if (!this.isConnected()){ - return null; - } - String str = getStateViaString(); - return Sysclass.separateSpace(str); - } - - /** - * Reading returns the current stop command. Writing sets the stop command. The value determines the motors behavior when command is set to stop. - * Also, it determines the motors behavior when a run command completes. See stop_commands for a list of possible values. - * @return A stop command that listed using getStopCommands() - * @throws IOException If I/O goes wrong - */ - public String getStopAction() throws IOException{ - if (!this.isConnected()){ - return null; - } - return this.getAttribute(Def.PROPERTY_STOP_ACTION); - } - - /** - * Reading returns the current stop command. Writing sets the stop command. The value determines the motors behavior when command is set to stop. - * Also, it determines the motors behavior when a run command completes. See stop_commands for a list of possible values. - * @param stop_command A stop command that listed using getStopCommands() - * @throws IOException If I/O goes wrong - */ - public void setStopAction(String stop_action) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_STOP_ACTION, stop_action); - } - - /** - * This function returns a string that is likely a "spaced-array".
- * Use this function to directly to return a String array: - *
-	 * getStopCommands()
-	 * 
- * Returns a list of stop modes supported by the motor controller. Possible values are coast, - * brake and hold. coast means that power will be removed from the motor and it will freely - * coast to a stop. brake means that power will be removed from the motor and a passive - * electrical load will be placed on the motor. This is usually done by shorting the motor - * terminals together. This load will absorb the energy from the rotation of the motors - * and cause the motor to stop more quickly than coasting. hold does not remove power from - * the motor. Instead it actively try to hold the motor at the current position. - * If an external force tries to turn the motor, the motor will .push back・ to maintain its position. - * @return A list of stop modes supported by the motor controller - * @throws IOException If I/O goes wrong - */ - public String getStopCommandsViaString() throws IOException{ - if (!this.isConnected()){ - return null; - } - return this.getAttribute(Def.PROPERTY_STOP_ACTIONS); - } - - /** - * Returns a list of stop modes supported by the motor controller. Possible values are coast, - * brake and hold. coast means that power will be removed from the motor and it will freely - * coast to a stop. brake means that power will be removed from the motor and a passive - * electrical load will be placed on the motor. This is usually done by shorting the motor - * terminals together. This load will absorb the energy from the rotation of the motors - * and cause the motor to stop more quickly than coasting. hold does not remove power from - * the motor. Instead it actively try to hold the motor at the current position. - * If an external force tries to turn the motor, the motor will .push back・ to maintain its position. - * @return A list of stop modes supported by the motor controller - * @throws IOException If I/O goes wrong - */ - public String[] getStopCommands() throws IOException{ - if (!this.isConnected()){ - return null; - } - String str = getStopCommandsViaString(); - return Sysclass.separateSpace(str); - } - - /** - * Writing specifies the amount of time the motor will run when using the run-timed command. Reading returns the current value. Units are in milliseconds. - * @return Amount of time in ms - * @throws IOException If I/O goes wrong - */ - public int getTime_SP() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_TIME_SP); - return Integer.parseInt(str); - } - - /** - * Writing specifies the amount of time the motor will run when using the run-timed command. Reading returns the current value. Units are in milliseconds. - * @param time_sp Amount of time in ms - * @throws IOException If I/O goes wrong - */ - public void setTime_SP(int time_sp) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_TIME_SP, Integer.toString(time_sp)); - } - - /** - * This returns the maximum speed of the motor with no load at 9V. - * @return The maximum speed - * @throws IOException If I/O goes wrong - */ - public int getMax_Speed() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_MAX_SPEED); - return Integer.parseInt(str); - } - - public int getFullTravelCount() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_FULL_TRAVEL_COUNT); - return Integer.parseInt(str); - } - -//~autogen -} -//----------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/main/java/org/ev3dev/hardware/motors/MediumMotor.java b/src/main/java/org/ev3dev/hardware/motors/MediumMotor.java index 5286b08..1674c6f 100644 --- a/src/main/java/org/ev3dev/hardware/motors/MediumMotor.java +++ b/src/main/java/org/ev3dev/hardware/motors/MediumMotor.java @@ -5,15 +5,23 @@ import org.ev3dev.exception.InvalidMotorException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; public class MediumMotor extends Motor { + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "lego-ev3-m-motor"; + + public MediumMotor(int portField) throws InvalidPortException, IOException { + this(new LegoPort(portField)); + } public MediumMotor(LegoPort port) throws InvalidPortException, IOException, InvalidMotorException { super(port); String drivername = this.getDriverName(); - if (!drivername.equals(Def.MEDIUM_MOTOR_DRIVER_NAME)){ - throw new InvalidMotorException("It is not a MediumMotor (" + Def.MEDIUM_MOTOR_DRIVER_NAME + "): " + drivername); + if (!drivername.equals(DRIVER_NAME)){ + throw new InvalidMotorException("The port is not connected to a LargeMotor (" + DRIVER_NAME + "): " + drivername); } } diff --git a/src/main/java/org/ev3dev/hardware/motors/Motor.java b/src/main/java/org/ev3dev/hardware/motors/Motor.java index e3397fe..dff8009 100644 --- a/src/main/java/org/ev3dev/hardware/motors/Motor.java +++ b/src/main/java/org/ev3dev/hardware/motors/Motor.java @@ -8,13 +8,11 @@ //----------------------------------------------------------------------------- -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.hardware.Device; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; -import org.ev3dev.io.Sysclass; +import org.ev3dev.io.Sysfs; //----------------------------------------------------------------------------- @@ -32,26 +30,194 @@ */ public class Motor extends Device{ + /** + * The Sysfs class's address property name + */ + public static final String SYSFS_PROPERTY_ADDRESS = "address"; + + /** + * The Sysfs class's command property name + */ + public static final String SYSFS_PROPERTY_COMMAND = "command"; + + /** + * The Sysfs class's commands property name + */ + public static final String SYSFS_PROPERTY_COMMANDS = "commands"; + + /** + * The Sysfs class's count_per_rot property name + */ + public static final String SYSFS_PROPERTY_COUNT_PER_ROT = "count_per_rot"; + + /** + * The Sysfs class's driver_name property name + */ + public static final String SYSFS_PROPERTY_DRIVER_NAME = "driver_name"; + + /** + * The Sysfs class's duty_cycle property name + */ + public static final String SYSFS_PROPERTY_DUTY_CYCLE = "duty_cycle"; + + /** + * The Sysfs class's duty_cycle_sp property name + */ + public static final String SYSFS_PROPERTY_DUTY_CYCLE_SP = "duty_cycle_sp"; + + /** + * The Sysfs class's polarity property name + */ + public static final String SYSFS_PROPERTY_POLARITY = "polarity"; + + /** + * The Sysfs class's position property name + */ + public static final String SYSFS_PROPERTY_POSITION = "position"; + + /** + * The Sysfs class's position_p property name + */ + public static final String SYSFS_PROPERTY_POSITION_P = "hold_pid/Kp"; + + /** + * The Sysfs class's position_i property name + */ + public static final String SYSFS_PROPERTY_POSITION_I = "hold_pid/Ki"; + + /** + * The Sysfs class's position_d property name + */ + public static final String SYSFS_PROPERTY_POSITION_D = "hold_pid/Kd"; + + /** + * The Sysfs class's position_sp property name + */ + public static final String SYSFS_PROPERTY_POSITION_SP = "position_sp"; + + /** + * The Sysfs class's speed property name + */ + public static final String SYSFS_PROPERTY_SPEED = "speed"; + + /** + * The Sysfs class's speed_sp property name + */ + public static final String SYSFS_PROPERTY_SPEED_SP = "speed_sp"; + + /** + * The Sysfs class's ramp_up_sp property name + */ + public static final String SYSFS_PROPERTY_RAMP_UP_SP = "ramp_up_sp"; + + /** + * The Sysfs class's ramp_down_sp property name + */ + public static final String SYSFS_PROPERTY_RAMP_DOWN_SP = "ramp_down_sp"; + + /** + * The Sysfs class's state property name + */ + public static final String SYSFS_PROPERTY_STATE = "state"; + + /** + * The Sysfs class's stop_action property name + */ + public static final String SYSFS_PROPERTY_STOP_ACTION = "stop_action"; + + /** + * The Sysfs class's stop_actions property name + */ + public static final String SYSFS_PROPERTY_STOP_ACTIONS = "stop_actions"; + + /** + * The Sysfs class's time_sp property name + */ + public static final String SYSFS_PROPERTY_TIME_SP = "time_sp"; + + /** + * The Sysfs class's run-forever command + */ + public static final String SYSFS_COMMAND_RUN_FOREVER = "run-forever"; + + /** + * The Sysfs class's run-to-abs-pos command + */ + public static final String SYSFS_COMMAND_RUN_TO_ABS_POS = "run-to-abs-pos"; + + /** + * The Sysfs class's run-to-rel-pos command + */ + public static final String SYSFS_COMMAND_RUN_TO_REL_POS = "run-to-rel-pos"; + + /** + * The Sysfs class's run-timed command + */ + public static final String SYSFS_COMMAND_RUN_TIMED = "run-timed"; + + /** + * The Sysfs class's run-direct command + */ + public static final String SYSFS_COMMAND_RUN_DIRECT = "run-direct"; + + /** + * The Sysfs class's stop command + */ + public static final String SYSFS_COMMAND_STOP = "stop"; + + /** + * The Sysfs class's reset command + */ + public static final String SYSFS_COMMAND_RESET = "reset"; + + /** + * This Sysfs's class name (e.g. /sys/class/lego-sensor, and lego-sensor is the class name) + */ + public static final String CLASS_NAME = "tacho-motor"; + + /** + * This Sysfs's class name prefix (e.g. /sys/class/lego-sensor/sensor0, and sensor is the class name prefix without the [N] value.) + */ + public static final String CLASS_NAME_PREFIX = "motor"; + //----------------------------------------------------------------------------- private String address; //----------------------------------------------------------------------------- + /*** + * Creates a new motor object. + * @param portField a LegoPort field (e.g. LegoPort.INPUT_1) + * @throws EV3LibraryException If the LegoPort specified goes wrong + */ + public Motor(int portField) throws EV3LibraryException{ + this(new LegoPort(portField)); + } + /*** * Creates a new motor object. * @param port LegoPort - * @throws InvalidPortException If the LegoPort isn't a OUTPUT, invalid or a tacho-motor. - * @throws IOException If the LegoPort specified goes wrong + * @throws EV3LibraryException If the LegoPort specified goes wrong */ - public Motor(LegoPort port) throws InvalidPortException, IOException{ - super(port, Def.MOTOR_CLASS_NAME, Def.SUB_MOTOR_CLASS_NAME); + public Motor(LegoPort port) throws EV3LibraryException{ + this(port, CLASS_NAME_PREFIX); + } + + /*** + * Creates a new motor object. + * @param port LegoPort + * @param class_name_prefix Specify a class name prefix (e.g. motor[N], which "motor" is the prefix) + * @throws EV3LibraryException If the LegoPort specified goes wrong + */ + public Motor(LegoPort port, String class_name_prefix) throws EV3LibraryException{ + super(port, CLASS_NAME, CLASS_NAME_PREFIX); address = port.getAddress(); //Verify is the LegoPort connecting a motor / is a output if (!address.contains("out")){ throw new InvalidPortException("The specified port (" + port.getAddress() + ") isn't a output."); - } else if (!port.getStatus().equals(Def.MOTOR_CLASS_NAME)){ + } else if (!port.getStatus().equals(CLASS_NAME)){ throw new InvalidPortException("The specified port (" + port.getAddress() + ") isn't a motor (" + port.getStatus() + ")"); } } @@ -62,48 +228,48 @@ public Motor(LegoPort port) throws InvalidPortException, IOException{ /*** * Get the address of this motor. * @return LegoPort address described in String - * @throws IOException If the motor doesn't exist or IO ERROR + * @throws EV3LibraryException If the motor doesn't exist or IO ERROR */ - public String getAddress() throws IOException{ + public String getAddress() throws EV3LibraryException{ if (!this.isConnected()){ return null; } - return this.getAttribute(Def.PROPERTY_ADDRESS); + return this.getAttribute(SYSFS_PROPERTY_ADDRESS); } /*** * Generic method to send commands to the motor controller. * @param command Command that suits for the motor driver - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void sendCommand(String command) throws IOException{ + public void sendCommand(String command) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_COMMAND, command); + this.setAttribute(SYSFS_PROPERTY_COMMAND, command); } /*** * Cause the motor to run until another command is sent - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void runForever() throws IOException{ + public void runForever() throws EV3LibraryException{ if (!this.isConnected()){ return; } - sendCommand(Def.COMMAND_RUN_FOREVER); + sendCommand(SYSFS_COMMAND_RUN_FOREVER); } /*** * Run to an absolute position specified by position_sp * and then stop using the command specified in stop_command - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void runToAbsPos() throws IOException{ + public void runToAbsPos() throws EV3LibraryException{ if (!this.isConnected()){ return; } - sendCommand(Def.COMMAND_RUN_TO_ABS_POS); + sendCommand(SYSFS_COMMAND_RUN_TO_ABS_POS); } /*** @@ -111,61 +277,61 @@ public void runToAbsPos() throws IOException{ * The new position will be current position + position_sp. * When the new position is reached, the motor will stop * using the command specified by stop_command. - * @throws IOException If I/O goes wrong. + * @throws EV3LibraryException If I/O goes wrong. */ - public void runToRelPos() throws IOException{ + public void runToRelPos() throws EV3LibraryException{ if (!this.isConnected()){ return; } - sendCommand(Def.COMMAND_RUN_TO_REL_POS); + sendCommand(SYSFS_COMMAND_RUN_TO_REL_POS); } /*** * Run the motor for the amount of time specified in time_sp * and then stop the motor using the command specified by * stop_command - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void runTimed() throws IOException{ + public void runTimed() throws EV3LibraryException{ if (!this.isConnected()){ return; } - sendCommand(Def.COMMAND_RUN_TIMED); + sendCommand(SYSFS_COMMAND_RUN_TIMED); } /*** * Run the motor at the duty cycle specified by duty_cycle_sp. * Unlike other run commands, changing duty_cycle_sp while * running will take effect immediately - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void runDirect() throws IOException{ + public void runDirect() throws EV3LibraryException{ if (!this.isConnected()){ return; } - sendCommand(Def.COMMAND_RUN_DIRECT); + sendCommand(SYSFS_COMMAND_RUN_DIRECT); } /** * Stop any of the run commands before they are complete using the command specified by stop_command. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void stop() throws IOException{ + public void stop() throws EV3LibraryException{ if (!this.isConnected()){ return; } - sendCommand(Def.COMMAND_STOP); + sendCommand(SYSFS_COMMAND_STOP); } /** * Reset all of the motor parameter attributes to their default value. This will also have the effect of stopping the motor. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void reset() throws IOException{ + public void reset() throws EV3LibraryException{ if (!this.isConnected()){ return; } - sendCommand(Def.COMMAND_RESET); + sendCommand(SYSFS_COMMAND_RESET); } /** @@ -173,14 +339,14 @@ public void reset() throws IOException{ * Possible values are run-forever, run-to-abs-pos, run-to-rel-pos, * run-timed, run-direct, stop and reset. Not all commands may be supported. * @return A String Arrays with all the supported commands - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getCommands() throws IOException{ + public String[] getCommands() throws EV3LibraryException{ if (!this.isConnected()){ return null; } - String str = this.getAttribute(Def.PROPERTY_COMMANDS); - return Sysclass.separateSpace(str); + String str = this.getAttribute(SYSFS_PROPERTY_COMMANDS); + return Sysfs.separateSpace(str); } /** @@ -190,39 +356,41 @@ public String[] getCommands() throws IOException{ * counts. In the case of linear actuators, the units here will * be counts per centimeter. * @return Counts per cm - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getCountPerRot() throws IOException{ + public int getCountPerRot() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String countperrot = this.getAttribute(Def.PROPERTY_COUNT_PER_ROT); + String countperrot = this.getAttribute(SYSFS_PROPERTY_COUNT_PER_ROT); return Integer.parseInt(countperrot); } + //getCountPerM() Linear Motor (Just for mark down) + /** * Returns the name of the driver that provides this tacho motor device. * @return The name of the driver - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getDriverName() throws IOException{ + public String getDriverName() throws EV3LibraryException{ if (!this.isConnected()){ return null; } - return this.getAttribute(Def.PROPERTY_DRIVER_NAME); + return this.getAttribute(SYSFS_PROPERTY_DRIVER_NAME); } /** * Returns the current duty cycle of the motor. Units are percent. Values are -100 to 100. * @return Percentage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getDutyCycle() throws IOException{ + public int getDutyCycle() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String dutycycle = this.getAttribute(Def.PROPERTY_DUTY_CYCLE); + String dutycycle = this.getAttribute(SYSFS_PROPERTY_DUTY_CYCLE); return Integer.parseInt(dutycycle); } @@ -231,13 +399,13 @@ public int getDutyCycle() throws IOException{ * Valid values are -100 to 100. A negative value causes the motor to rotate in reverse. * This value is only used when speed_regulation is off. * @return Percentage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getDutyCycleSP() throws IOException{ + public int getDutyCycleSP() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String dutycyclesp = this.getAttribute(Def.PROPERTY_DUTY_CYCLE_SP); + String dutycyclesp = this.getAttribute(SYSFS_PROPERTY_DUTY_CYCLE_SP); return Integer.parseInt(dutycyclesp); } @@ -246,48 +414,50 @@ public int getDutyCycleSP() throws IOException{ * Valid values are -100 to 100. A negative value causes the motor to rotate in reverse. * This value is only used when speed_regulation is off. * @param sp Percentage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setDutyCycleSP(int sp) throws IOException{ + public void setDutyCycleSP(int sp) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_DUTY_CYCLE_SP, Integer.toString(sp)); + this.setAttribute(SYSFS_PROPERTY_DUTY_CYCLE_SP, Integer.toString(sp)); } + //getFullTravelCount() Linear Motor Only (Mark down) + /** * Sets the polarity of the motor. With normal polarity, a positive duty cycle will cause the motor to rotate clockwise. * With inversed polarity, a positive duty cycle will cause the motor to rotate counter-clockwise. Valid values are normal and inversed. * @return The polarity of the motor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getPolarity() throws IOException{ + public String getPolarity() throws EV3LibraryException{ if (!this.isConnected()){ return null; } - return this.getAttribute(Def.PROPERTY_POLARITY); + return this.getAttribute(SYSFS_PROPERTY_POLARITY); } /** * Sets the polarity of the motor. With normal polarity, a positive duty cycle will cause the motor to rotate clockwise. With inversed polarity, * a positive duty cycle will cause the motor to rotate counter-clockwise. Valid values are normal and inversed. * @param polarity The polarity of the motor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPolarity(String polarity) throws IOException{ + public void setPolarity(String polarity) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_POLARITY, polarity); + this.setAttribute(SYSFS_PROPERTY_POLARITY, polarity); } /** * Returns the current position of the motor in pulses of the rotary encoder. When the motor rotates clockwise, the position will increase. Likewise, * rotating counter-clockwise causes the position to decrease. Writing will set the position to that value. * @return The current position - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getPosition() throws IOException{ + public int getPosition() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } @@ -299,101 +469,101 @@ public int getPosition() throws IOException{ * Returns the current position of the motor in pulses of the rotary encoder. When the motor rotates clockwise, the position will increase. * Likewise, rotating counter-clockwise causes the position to decrease. Writing will set the position to that value. * @param position The current position - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPosition(int position) throws IOException{ + public void setPosition(int position) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_POSITION, Integer.toString(position)); + this.setAttribute(SYSFS_PROPERTY_POSITION, Integer.toString(position)); } /** * The proportional constant for the position PID. * @return The proportional constant for the position PID. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getPosition_P() throws IOException{ + public int getPosition_P() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_POSITION_P); + String str = this.getAttribute(SYSFS_PROPERTY_POSITION_P); return Integer.parseInt(str); } /** * The integral constant for the position PID. * @return The integral constant for the position PID. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getPosition_I() throws IOException{ + public int getPosition_I() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_POSITION_I); + String str = this.getAttribute(SYSFS_PROPERTY_POSITION_I); return Integer.parseInt(str); } /** * The derivative constant for the position PID. * @return The derivative constant for the position PID. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getPosition_D() throws IOException{ + public int getPosition_D() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_POSITION_D); + String str = this.getAttribute(SYSFS_PROPERTY_POSITION_D); return Integer.parseInt(str); } /** * The proportional constant for the position PID. * @param position_p The proportional constant for the position PID. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPosition_P(int position_p) throws IOException{ + public void setPosition_P(int position_p) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_POSITION_P, Integer.toString(position_p)); + this.setAttribute(SYSFS_PROPERTY_POSITION_P, Integer.toString(position_p)); } /** * The integral constant for the position PID. * @param position_i The integral constant for the position PID. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPosition_I(int position_i) throws IOException{ + public void setPosition_I(int position_i) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_POSITION_I, Integer.toString(position_i)); + this.setAttribute(SYSFS_PROPERTY_POSITION_I, Integer.toString(position_i)); } /** * The derivative constant for the position PID. * @param position_d The derivative constant for the position PID. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPosition_D(int position_d) throws IOException{ + public void setPosition_D(int position_d) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_POSITION_D, Integer.toString(position_d)); + this.setAttribute(SYSFS_PROPERTY_POSITION_D, Integer.toString(position_d)); } /** * Writing specifies the target position for the run-to-abs-pos and run-to-rel-pos commands. Reading returns the current value. * Units are in tacho counts. You can use the value returned by counts_per_rot to convert tacho counts to/from rotations or degrees. * @return The target position - * @throws IOException if I/O goes wrong + * @throws EV3LibraryException if I/O goes wrong */ - public int getPosition_SP() throws IOException{ + public int getPosition_SP() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_POSITION_SP); + String str = this.getAttribute(SYSFS_PROPERTY_POSITION_SP); return Integer.parseInt(str); } @@ -401,26 +571,26 @@ public int getPosition_SP() throws IOException{ * Writing specifies the target position for the run-to-abs-pos and run-to-rel-pos commands. Reading returns the current value. * Units are in tacho counts. You can use the value returned by counts_per_rot to convert tacho counts to/from rotations or degrees. * @param position_sp The target position - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPosition_SP(int position_sp) throws IOException{ + public void setPosition_SP(int position_sp) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_POSITION_SP, Integer.toString(position_sp)); + this.setAttribute(SYSFS_PROPERTY_POSITION_SP, Integer.toString(position_sp)); } /** * Returns the current motor speed in tacho counts per second. Note, this is not necessarily degrees * (although it is for LEGO motors). Use the count_per_rot attribute to convert this value to RPM or deg/sec. * @return The current speed - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getSpeed() throws IOException{ + public int getSpeed() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_SPEED); + String str = this.getAttribute(SYSFS_PROPERTY_SPEED); return Integer.parseInt(str); } @@ -428,13 +598,13 @@ public int getSpeed() throws IOException{ * Writing sets the target speed in tacho counts per second used when speed_regulation is on. * Reading returns the current value. Use the count_per_rot attribute to convert RPM or deg/sec to tacho counts per second. * @return The target speed - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getSpeed_SP() throws IOException{ + public int getSpeed_SP() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_SPEED); + String str = this.getAttribute(SYSFS_PROPERTY_SPEED); return Integer.parseInt(str); } @@ -442,13 +612,13 @@ public int getSpeed_SP() throws IOException{ * Writing sets the target speed in tacho counts per second used when speed_regulation is on. Reading returns the current value. * Use the count_per_rot attribute to convert RPM or deg/sec to tacho counts per second. * @param speed_sp The target speed - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setSpeed_SP(int speed_sp) throws IOException{ + public void setSpeed_SP(int speed_sp) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_SPEED_SP, Integer.toString(speed_sp)); + this.setAttribute(SYSFS_PROPERTY_SPEED_SP, Integer.toString(speed_sp)); } /** @@ -458,13 +628,13 @@ public void setSpeed_SP(int speed_sp) throws IOException{ * limited by duty_cycle_sp or speed regulation, * the actual ramp time duration will be less than the setpoint. * @return The ramp-up set-point - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getRamp_Up_SP() throws IOException{ + public int getRamp_Up_SP() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_RAMP_UP_SP); + String str = this.getAttribute(SYSFS_PROPERTY_RAMP_UP_SP); return Integer.parseInt(str); } @@ -475,13 +645,13 @@ public int getRamp_Up_SP() throws IOException{ * limited by duty_cycle_sp or speed regulation, * the actual ramp time duration will be less than the setpoint. * @param ramp_up_sp The ramp-up set-point - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setRamp_Up_SP(int ramp_up_sp) throws IOException{ + public void setRamp_Up_SP(int ramp_up_sp) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_RAMP_UP_SP, Integer.toString(ramp_up_sp)); + this.setAttribute(SYSFS_PROPERTY_RAMP_UP_SP, Integer.toString(ramp_up_sp)); } /** @@ -490,13 +660,13 @@ public void setRamp_Up_SP(int ramp_up_sp) throws IOException{ * to 0 over the span of this setpoint when stopping the motor. If the starting * duty cycle is less than 100%, the ramp time duration will be less than the full span of the setpoint. * @return The ramp-down set-point - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getRamp_Down_SP() throws IOException{ + public int getRamp_Down_SP() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_RAMP_DOWN_SP); + String str = this.getAttribute(SYSFS_PROPERTY_RAMP_DOWN_SP); return Integer.parseInt(str); } @@ -506,88 +676,13 @@ public int getRamp_Down_SP() throws IOException{ * to 0 over the span of this setpoint when stopping the motor. If the starting * duty cycle is less than 100%, the ramp time duration will be less than the full span of the setpoint. * @param ramp_down_sp The ramp-down set-point - * @throws IOException If I/O goes wrong - */ - public void setRamp_Down_SP(int ramp_down_sp) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_RAMP_DOWN_SP, Integer.toString(ramp_down_sp)); - } - - /** - * Get the proportional constant for the speed regulation PID. - * @return The proportional constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public int getSpeedRegulation_P() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_SPEED_REGULATION_P); - return Integer.parseInt(str); - } - - /** - * Set the proportional constant for the speed regulation PID. - * @param p The proportional constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public void setSpeedRegulation_P(int p) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_SPEED_REGULATION_P, Integer.toString(p)); - } - - /** - * Get the integral constant for the speed regulation PID. - * @return The integral constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public int getSpeedRegulation_I() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_SPEED_REGULATION_I); - return Integer.parseInt(str); - } - - /** - * Set The integral constant for the speed regulation PID. - * @param i The integral constant for the speed regulation PID. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setSpeedRegulation_I(int i) throws IOException{ + public void setRamp_Down_SP(int ramp_down_sp) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_SPEED_REGULATION_I, Integer.toString(i)); - } - - /** - * Get the derivative constant for the speed regulation PID. - * @return The derivative constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public int getSpeedRegulation_D() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_SPEED_REGULATION_D); - return Integer.parseInt(str); - } - - /** - * Set the derivative constant for the speed regulation PID. - * @param d The derivative constant for the speed regulation PID. - * @throws IOException If I/O goes wrong - */ - public void setSpeedRegulation_D(int d) throws IOException{ - if (!this.isConnected()){ - return; - } - this.setAttribute(Def.PROPERTY_SPEED_REGULATION_D, Integer.toString(d)); + this.setAttribute(SYSFS_PROPERTY_RAMP_DOWN_SP, Integer.toString(ramp_down_sp)); } /** @@ -598,52 +693,52 @@ public void setSpeedRegulation_D(int d) throws IOException{ * * Reading returns a list of state flags. Possible flags are running, ramping holding and stalled. * @return A list of state flags. String spaced-array - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getStateViaString() throws IOException{ + public String getStateViaString() throws EV3LibraryException{ if (!this.isConnected()){ return null; } - return this.getAttribute(Def.PROPERTY_STATE); + return this.getAttribute(SYSFS_PROPERTY_STATE); } /** * Reading returns a list of state flags. Possible flags are running, ramping holding and stalled. * @return A list(String array) of state flags. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getState() throws IOException{ + public String[] getState() throws EV3LibraryException{ if (!this.isConnected()){ return null; } String str = getStateViaString(); - return Sysclass.separateSpace(str); + return Sysfs.separateSpace(str); } /** * Reading returns the current stop command. Writing sets the stop command. The value determines the motors behavior when command is set to stop. * Also, it determines the motors behavior when a run command completes. See stop_commands for a list of possible values. * @return A stop command that listed using getStopCommands() - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getStopAction() throws IOException{ + public String getStopAction() throws EV3LibraryException{ if (!this.isConnected()){ return null; } - return this.getAttribute(Def.PROPERTY_STOP_ACTION); + return this.getAttribute(SYSFS_PROPERTY_STOP_ACTION); } /** * Reading returns the current stop command. Writing sets the stop command. The value determines the motors behavior when command is set to stop. * Also, it determines the motors behavior when a run command completes. See stop_commands for a list of possible values. - * @param stop_command A stop command that listed using getStopCommands() - * @throws IOException If I/O goes wrong + * @param stop_action A stop command that listed using getStopCommands() + * @throws EV3LibraryException If I/O goes wrong */ - public void setStopAction(String stop_action) throws IOException{ + public void setStopAction(String stop_action) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_STOP_ACTION, stop_action); + this.setAttribute(SYSFS_PROPERTY_STOP_ACTION, stop_action); } /** @@ -659,15 +754,15 @@ public void setStopAction(String stop_action) throws IOException{ * terminals together. This load will absorb the energy from the rotation of the motors * and cause the motor to stop more quickly than coasting. hold does not remove power from * the motor. Instead it actively try to hold the motor at the current position. - * If an external force tries to turn the motor, the motor will .push back・ to maintain its position. + * If an external force tries to turn the motor, the motor will 'push back' to maintain its position. * @return A list of stop modes supported by the motor controller - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getStopCommandsViaString() throws IOException{ + public String getStopCommandsViaString() throws EV3LibraryException{ if (!this.isConnected()){ return null; } - return this.getAttribute(Def.PROPERTY_STOP_ACTIONS); + return this.getAttribute(SYSFS_PROPERTY_STOP_ACTIONS); } /** @@ -678,54 +773,41 @@ public String getStopCommandsViaString() throws IOException{ * terminals together. This load will absorb the energy from the rotation of the motors * and cause the motor to stop more quickly than coasting. hold does not remove power from * the motor. Instead it actively try to hold the motor at the current position. - * If an external force tries to turn the motor, the motor will .push back・ to maintain its position. + * If an external force tries to turn the motor, the motor will 'push back' to maintain its position. * @return A list of stop modes supported by the motor controller - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getStopCommands() throws IOException{ + public String[] getStopCommands() throws EV3LibraryException{ if (!this.isConnected()){ return null; } String str = getStopCommandsViaString(); - return Sysclass.separateSpace(str); + return Sysfs.separateSpace(str); } /** * Writing specifies the amount of time the motor will run when using the run-timed command. Reading returns the current value. Units are in milliseconds. * @return Amount of time in ms - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getTime_SP() throws IOException{ + public int getTime_SP() throws EV3LibraryException{ if (!this.isConnected()){ return -1; } - String str = this.getAttribute(Def.PROPERTY_TIME_SP); + String str = this.getAttribute(SYSFS_PROPERTY_TIME_SP); return Integer.parseInt(str); } /** * Writing specifies the amount of time the motor will run when using the run-timed command. Reading returns the current value. Units are in milliseconds. * @param time_sp Amount of time in ms - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setTime_SP(int time_sp) throws IOException{ + public void setTime_SP(int time_sp) throws EV3LibraryException{ if (!this.isConnected()){ return; } - this.setAttribute(Def.PROPERTY_TIME_SP, Integer.toString(time_sp)); - } - - /** - * This returns the maximum speed of the motor with no load at 9V. - * @return The maximum speed - * @throws IOException If I/O goes wrong - */ - public int getMax_Speed() throws IOException{ - if (!this.isConnected()){ - return -1; - } - String str = this.getAttribute(Def.PROPERTY_MAX_SPEED); - return Integer.parseInt(str); + this.setAttribute(SYSFS_PROPERTY_TIME_SP, Integer.toString(time_sp)); } //~autogen diff --git a/src/main/java/org/ev3dev/hardware/motors/NXTMotor.java b/src/main/java/org/ev3dev/hardware/motors/NXTMotor.java new file mode 100644 index 0000000..499e8b8 --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/motors/NXTMotor.java @@ -0,0 +1,28 @@ +package org.ev3dev.hardware.motors; + +import java.io.IOException; + +import org.ev3dev.exception.InvalidMotorException; +import org.ev3dev.exception.InvalidPortException; +import org.ev3dev.hardware.ports.LegoPort; + +public class NXTMotor extends Motor { + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "lego-nxt-motor"; + + public NXTMotor(int portField) throws InvalidPortException, IOException { + this(new LegoPort(portField)); + } + + public NXTMotor(LegoPort port) throws InvalidPortException, IOException { + super(port); + String drivername = port.getDriverName(); + if (!drivername.equals(DRIVER_NAME)){ + throw new InvalidMotorException("The port is not connected to a Lego NXT Motor (" + DRIVER_NAME + "): " + drivername); + } + } + +} diff --git a/src/main/java/org/ev3dev/hardware/motors/ServoMotor.java b/src/main/java/org/ev3dev/hardware/motors/ServoMotor.java index d61a4fa..bd22e42 100644 --- a/src/main/java/org/ev3dev/hardware/motors/ServoMotor.java +++ b/src/main/java/org/ev3dev/hardware/motors/ServoMotor.java @@ -1,13 +1,11 @@ package org.ev3dev.hardware.motors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidMotorException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.hardware.Device; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; -import org.ev3dev.io.Sysclass; +import org.ev3dev.io.Sysfs; /** * The servo motor class provides a uniform interface for using hobby type servo motors. @@ -15,6 +13,76 @@ * */ public class ServoMotor extends Device{ + + /** + * The Sysfs class's address property name + */ + private static final String SYSFS_PROPERTY_ADDRESS = "address"; + + /** + * The Sysfs class's command property name + */ + private static final String SYSFS_PROPERTY_COMMAND = "command"; + + /** + * The Sysfs class's driver_name property name + */ + private static final String SYSFS_PROPERTY_DRIVER_NAME = "driver_name"; + + /** + * The Sysfs class's polarity property name + */ + private static final String SYSFS_PROPERTY_POLARITY = "polarity"; + + /** + * The Sysfs class's position_sp property name + */ + private static final String SYSFS_PROPERTY_POSITION_SP = "position_sp"; + + /** + * The Sysfs class's state property name + */ + private static final String SYSFS_PROPERTY_STATE = "state"; + + /** + * The Sysfs class's max_pulse_sp property name + */ + private static final String SYSFS_PROPERTY_MAX_PULSE_SP = "max_pulse_sp"; + + /** + * The Sysfs class's mid_pulse_sp property name + */ + private static final String SYSFS_PROPERTY_MID_PULSE_SP = "mid_pulse_sp"; + + /** + * The Sysfs class's min_pulse_sp property name + */ + private static final String SYSFS_PROPERTY_MIN_PULSE_SP = "min_pulse_sp"; + + /** + * The Sysfs class's rate_sp property name + */ + private static final String SYSFS_PROPERTY_RATE_SP = "rate_sp"; + + /** + * The Sysfs class's run command + */ + public static final String SYSFS_COMMAND_RUN = "run"; + + /** + * The Sysfs class's float command + */ + public static final String SYSFS_COMMAND_FLOAT = "float"; + + /** + * This Sysfs's class name (e.g. /sys/class/lego-sensor, and lego-sensor is the class name) + */ + public static final String CLASS_NAME = "servo-motor"; + + /** + * This Sysfs's class name prefix (e.g. /sys/class/lego-sensor/sensor0, and sensor is the class name prefix without the [N] value.) + */ + public static final String CLASS_NAME_PREFIX = "motor"; private String address; @@ -22,17 +90,17 @@ public class ServoMotor extends Device{ * Creates a new motor object. * @param port LegoPort * @throws InvalidPortException If the LegoPort isn't a OUTPUT, invalid or a tacho-motor. - * @throws IOException If the LegoPort specified goes wrong + * @throws EV3LibraryException If the LegoPort specified goes wrong * @throws InvalidMotorException The specified motor wasn't a motor */ - public ServoMotor(LegoPort port) throws InvalidPortException, InvalidMotorException, IOException{ - super(port, Def.SERVO_MOTOR_CLASS_NAME, Def.SUB_MOTOR_CLASS_NAME); + public ServoMotor(LegoPort port) throws EV3LibraryException{ + super(port, CLASS_NAME, CLASS_NAME_PREFIX); address = port.getAddress(); //Verify is the LegoPort connecting a motor / is a output if (!address.contains("out")){ throw new InvalidPortException("The specified port (" + port.getAddress() + ") isn't a output."); - } else if (!port.getStatus().equals(Def.SERVO_MOTOR_CLASS_NAME)){ + } else if (!port.getStatus().equals(CLASS_NAME)){ throw new InvalidMotorException("The specified port (" + port.getAddress() + ") isn't a motor (" + port.getStatus() + ")"); } } @@ -40,55 +108,55 @@ public ServoMotor(LegoPort port) throws InvalidPortException, InvalidMotorExcept /*** * Get the address of this motor. * @return LegoPort address described in String - * @throws IOException If the motor doesn't exist or IO ERROR + * @throws EV3LibraryException If the motor doesn't exist or IO ERROR */ - public String getAddress() throws IOException{ - return this.getAttribute(Def.PROPERTY_ADDRESS); + public String getAddress() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_ADDRESS); } /*** * Generic method to send commands to the motor controller. * @param command Command that suits for the motor driver - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void sendCommand(String command) throws IOException{ - this.setAttribute(Def.PROPERTY_COMMAND, command); + public void sendCommand(String command) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_COMMAND, command); } /*** * Setting to run will cause the servo to be driven to the position_sp set in the position_sp attribute. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void run() throws IOException{ - sendCommand(Def.COMMAND_RUN); + public void run() throws EV3LibraryException{ + sendCommand(SYSFS_COMMAND_RUN); } /*** * Run to an absolute position specified by position_sp * and then stop using the command specified in stop_command - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void Float() throws IOException{ - sendCommand(Def.COMMAND_FLOAT); + public void Float() throws EV3LibraryException{ + sendCommand(SYSFS_COMMAND_FLOAT); } /** * Returns the name of the driver that provides this tacho motor device. * @return The name of the driver - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getDriverName() throws IOException{ - return this.getAttribute(Def.PROPERTY_DRIVER_NAME); + public String getDriverName() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_DRIVER_NAME); } /** * Used to set the pulse size in milliseconds for the signal that tells the servo to drive to the maximum (clockwise) position_sp. Default value is 2400. * Valid values are 2300 to 2700. You must write to the position_sp attribute for changes to this attribute to take effect. * @return The pulse size in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getMaxPulse_SP() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_MAX_PULSE_SP); + public int getMaxPulse_SP() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_MAX_PULSE_SP); return Integer.parseInt(str); } @@ -96,35 +164,35 @@ public int getMaxPulse_SP() throws IOException{ * Used to set the pulse size in milliseconds for the signal that tells the servo to drive to the maximum (clockwise) position_sp. Default value is 2400. * Valid values are 2300 to 2700. You must write to the position_sp attribute for changes to this attribute to take effect. * @param max_pulse_sp The pulse size in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setMaxPulse_SP(int max_pulse_sp) throws IOException{ - this.setAttribute(Def.PROPERTY_MAX_PULSE_SP, Integer.toString(max_pulse_sp)); + public void setMaxPulse_SP(int max_pulse_sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_MAX_PULSE_SP, Integer.toString(max_pulse_sp)); } /** * Used to set the pulse size in milliseconds for the signal that tells the servo to drive to the mid position_sp. * Default value is 1500. Valid values are 1300 to 1700. For example, on a 180 degree servo, this would be 90 degrees. - * On continuous rotation servo, this is the .neutral・ position_sp where the motor does not turn. + * On continuous rotation servo, this is the 'neutral' position_sp where the motor does not turn. * You must write to the position_sp attribute for changes to this attribute to take effect. * @return The pulse size in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getMidPulse_SP() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_MID_PULSE_SP); + public int getMidPulse_SP() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_MID_PULSE_SP); return Integer.parseInt(str); } /** * Used to set the pulse size in milliseconds for the signal that tells the servo to drive to the mid position_sp. * Default value is 1500. Valid values are 1300 to 1700. For example, on a 180 degree servo, this would be 90 degrees. - * On continuous rotation servo, this is the .neutral・ position_sp where the motor does not turn. + * On continuous rotation servo, this is the 'neutral' position_sp where the motor does not turn. * You must write to the position_sp attribute for changes to this attribute to take effect. * @param mid_pulse_sp The pulse size in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setMidPulse_SP(int mid_pulse_sp) throws IOException{ - this.setAttribute(Def.PROPERTY_MID_PULSE_SP, Integer.toString(mid_pulse_sp)); + public void setMidPulse_SP(int mid_pulse_sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_MID_PULSE_SP, Integer.toString(mid_pulse_sp)); } /** @@ -132,10 +200,10 @@ public void setMidPulse_SP(int mid_pulse_sp) throws IOException{ * minimum (counter-clockwise) position_sp. Default value is 600. Valid values are 300 to 700. * You must write to the position_sp attribute for changes to this attribute to take effect. * @return The pulse size in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getMinPulse_SP() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_MIN_PULSE_SP); + public int getMinPulse_SP() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_MIN_PULSE_SP); return Integer.parseInt(str); } @@ -144,30 +212,30 @@ public int getMinPulse_SP() throws IOException{ * minimum (counter-clockwise) position_sp. Default value is 600. Valid values are 300 to 700. * You must write to the position_sp attribute for changes to this attribute to take effect. * @param min_pulse_sp The pulse size in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setMinPulse_SP(int min_pulse_sp) throws IOException{ - this.setAttribute(Def.PROPERTY_MIN_PULSE_SP, Integer.toString(min_pulse_sp)); + public void setMinPulse_SP(int min_pulse_sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_MIN_PULSE_SP, Integer.toString(min_pulse_sp)); } /** * Sets the polarity of the servo. Valid values are normal and inversed. Setting the value to inversed will cause the position_sp value to be inversed. * i.e -100 will correspond to max_pulse_sp, and 100 will correspond to min_pulse_sp. * @return The polarity of the servo - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getPolarity() throws IOException{ - return this.getAttribute(Def.PROPERTY_POLARITY); + public String getPolarity() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_POLARITY); } /** * Sets the polarity of the servo. Valid values are normal and inversed. Setting the value to inversed will cause the position_sp value to be inversed. * i.e -100 will correspond to max_pulse_sp, and 100 will correspond to min_pulse_sp. * @param polarity The polarity of the servo - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPolarity(String polarity) throws IOException{ - this.setAttribute(Def.PROPERTY_POLARITY, polarity); + public void setPolarity(String polarity) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_POLARITY, polarity); } /** @@ -175,10 +243,10 @@ public void setPolarity(String polarity) throws IOException{ * Units are percent. Valid values are -100 to 100 (-100% to 100%) * where -100 corresponds to min_pulse_sp, 0 corresponds to mid_pulse_sp and 100 corresponds to max_pulse_sp. * @return The current position_sp of the servo - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getPosition_SP() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_POSITION_SP); + public int getPosition_SP() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_POSITION_SP); return Integer.parseInt(str); } @@ -187,10 +255,10 @@ public int getPosition_SP() throws IOException{ * Units are percent. Valid values are -100 to 100 (-100% to 100%) * where -100 corresponds to min_pulse_sp, 0 corresponds to mid_pulse_sp and 100 corresponds to max_pulse_sp. * @param position_sp The current position_sp of the servo - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPosition_SP(int position_sp) throws IOException{ - this.setAttribute(Def.PROPERTY_POSITION_SP, Integer.toString(position_sp)); + public void setPosition_SP(int position_sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_POSITION_SP, Integer.toString(position_sp)); } /** @@ -200,10 +268,10 @@ public void setPosition_SP(int position_sp) throws IOException{ * in which case reading and writing will fail with -EOPNOTSUPP. * In continuous rotation servos, this value will affect the rate_sp at which the speed ramps up or down. * @param rate_sp The rate_sp value - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setRate_SP(int rate_sp) throws IOException{ - this.setAttribute(Def.PROPERTY_RATE_SP, Integer.toString(rate_sp)); + public void setRate_SP(int rate_sp) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_RATE_SP, Integer.toString(rate_sp)); } /** @@ -214,19 +282,19 @@ public void setRate_SP(int rate_sp) throws IOException{ * * Reading returns a list of state flags. Possible flags are running, ramping holding and stalled. * @return A list of state flags. String spaced-array - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getStateViaString() throws IOException{ - return this.getAttribute(Def.PROPERTY_STATE); + public String getStateViaString() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_STATE); } /** * Reading returns a list of state flags. Possible flags are running, ramping holding and stalled. * @return A list(String array) of state flags. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getState() throws IOException{ + public String[] getState() throws EV3LibraryException{ String str = getStateViaString(); - return Sysclass.separateSpace(str); + return Sysfs.separateSpace(str); } } diff --git a/src/main/java/org/ev3dev/hardware/ports/LegoPort.java b/src/main/java/org/ev3dev/hardware/ports/LegoPort.java index 98e68a4..6ca28aa 100644 --- a/src/main/java/org/ev3dev/hardware/ports/LegoPort.java +++ b/src/main/java/org/ev3dev/hardware/ports/LegoPort.java @@ -2,9 +2,9 @@ import java.io.IOException; +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidPortException; -import org.ev3dev.hardware.Device; -import org.ev3dev.io.Sysclass; +import org.ev3dev.io.Sysfs; /*** * The lego-port class provides an interface for working with input and output ports that are compatible with LEGO MINDSTORMS RCX/NXT/EV3, @@ -33,7 +33,7 @@ public class LegoPort{ /** * The sysfs class name of LegoPort */ - public static final String SYSTEM_CLASS_NAME = "lego-port"; + public static final String CLASS_NAME = "lego-port"; /** * Sensor Port 1 on the EV3 @@ -92,31 +92,46 @@ public LegoPort(int port) throws InvalidPortException{ /** * Returns the name of the port. See individual driver documentation for the name that will be returned. * @return Address (e.g. in1, outA) - * @throws IOException If I/O goes wrong - */ - public String getAddress() throws IOException{ - String address = Sysclass.getAttribute(SYSTEM_CLASS_NAME, "port" + port, "address"); + * @throws EV3LibraryException If I/O goes wrong + */ + public String getAddress() throws EV3LibraryException{ + String address; + try { + address = Sysfs.getAttribute(CLASS_NAME, "port" + port, "address"); + } catch (IOException e) { + throw new EV3LibraryException("Get address attribute failed", e); + } return address; } /** * Returns the name of the driver that loaded this device. You can find the complete list of drivers in the [list of port drivers]. * @return Driver Name of this port - * @throws IOException if I/O goes wrong - */ - public String getDriverName() throws IOException{ - String drivername = Sysclass.getAttribute(SYSTEM_CLASS_NAME, "port" + port, "driver_name"); + * @throws EV3LibraryException if I/O goes wrong + */ + public String getDriverName() throws EV3LibraryException{ + String drivername; + try { + drivername = Sysfs.getAttribute(CLASS_NAME, "port" + port, "driver_name"); + } catch (IOException e) { + throw new EV3LibraryException("Get driver name attribute failed", e); + } return drivername; } /** * Returns a list of the available modes of the port. * @return A String Array with a list of available modes - * @throws IOException If I/O goes wrong - */ - public String[] getModes() throws IOException{ - String modesstr = Sysclass.getAttribute(SYSTEM_CLASS_NAME, "port" + port, "modes"); - return Sysclass.separateSpace(modesstr); + * @throws EV3LibraryException If I/O goes wrong + */ + public String[] getModes() throws EV3LibraryException{ + String modesstr; + try { + modesstr = Sysfs.getAttribute(CLASS_NAME, "port" + port, "modes"); + } catch (IOException e) { + throw new EV3LibraryException("Get modes attribute failed", e); + } + return Sysfs.separateSpace(modesstr); } /** @@ -125,10 +140,15 @@ public String[] getModes() throws IOException{ * the port will be removed new ones loaded, * however this this will depend on the individual driver implementing this class. * @return The currently selected mode - * @throws IOException If I/O goes wrong - */ - public String getMode() throws IOException{ - String mode = Sysclass.getAttribute(SYSTEM_CLASS_NAME, "port" + port, "mode"); + * @throws EV3LibraryException If I/O goes wrong + */ + public String getMode() throws EV3LibraryException{ + String mode; + try { + mode = Sysfs.getAttribute(CLASS_NAME, "port" + port, "mode"); + } catch (IOException e) { + throw new EV3LibraryException("Get mode attribute failed", e); + } return mode; } @@ -138,10 +158,14 @@ public String getMode() throws IOException{ * the port will be removed new ones loaded, * however this this will depend on the individual driver implementing this class. * @param mode A available mode listed using getModes() - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setMode(String mode) throws IOException{ - Sysclass.setAttribute(SYSTEM_CLASS_NAME, "port" + port, "mode", mode); + public void setMode(String mode) throws EV3LibraryException{ + try { + Sysfs.setAttribute(CLASS_NAME, "port" + port, "mode", mode); + } catch (IOException e) { + throw new EV3LibraryException("Set mode attribute failed", e); + } } /** @@ -149,10 +173,14 @@ public void setMode(String mode) throws IOException{ * attached to this port. For example, since NXT/Analog sensors cannot be auto-detected, you must use this attribute to * load the correct driver. Returns -EOPNOTSUPP if setting a device is not supported. * @param driver A generic driver name - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setDevice(String driver) throws IOException{ - Sysclass.setAttribute(SYSTEM_CLASS_NAME, "port" + port, "set_device", driver); + public void setDevice(String driver) throws EV3LibraryException{ + try { + Sysfs.setAttribute(CLASS_NAME, "port" + port, "set_device", driver); + } catch (IOException e) { + throw new EV3LibraryException("Set device attribute failed", e); + } } /** @@ -160,10 +188,15 @@ public void setDevice(String driver) throws IOException{ * auto mode additional values may be returned, such as no-device or error. * See individual port driver documentation for the full list of possible values. * @return The same as mode or some errors like: no-device or error. - * @throws IOException If I/O goes wrong - */ - public String getStatus() throws IOException{ - String status = Sysclass.getAttribute(SYSTEM_CLASS_NAME, "port" + port, "status"); + * @throws EV3LibraryException If I/O goes wrong + */ + public String getStatus() throws EV3LibraryException{ + String status; + try { + status = Sysfs.getAttribute(CLASS_NAME, "port" + port, "status"); + } catch (IOException e) { + throw new EV3LibraryException("Get status attribute failed", e); + } return status; } } diff --git a/src/main/java/org/ev3dev/hardware/sensors/ColorSensor.java b/src/main/java/org/ev3dev/hardware/sensors/ColorSensor.java index 04b92fb..153cdf4 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/ColorSensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/ColorSensor.java @@ -1,13 +1,10 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidModeException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.exception.InvalidSensorException; -import org.ev3dev.hardware.Device; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; /** * LEGO EV3 color sensor. @@ -16,6 +13,61 @@ */ public class ColorSensor extends Sensor { + /** + * Reflected Light Intensity required Sysfs mode + */ + public static final String SYSFS_REFLECTED_LIGHT_INTENSITY_MODE = "COL-REFLECT"; + + /** + * Reflected Light Intensity Sysfs value index + */ + public static final int SYSFS_REFLECTED_LIGHT_INTENSITY_VALUE_INDEX = 0; + + /** + * Ambient Light Intensity required Sysfs mode + */ + public static final String SYSFS_AMBIENT_LIGHT_INTENSITY_MODE = "COL-AMBIENT"; + + /** + * Ambient Light Intensity Sysfs value index + */ + public static final int SYSFS_AMBIENT_LIGHT_INTENSITY_VALUE_INDEX = 0; + + /** + * Color required Sysfs mode + */ + public static final String SYSFS_COLOR_MODE = "COL-COLOR"; + + /** + * Color Sysfs value index + */ + public static final int SYSFS_COLOR_VALUE_INDEX = 0; + + /** + * RGB required Sysfs mode + */ + public static final String SYSFS_RGB_MODE = "RGB-RAW"; + + /** + * RGB Red Sysfs value index + */ + public static final int SYSFS_RGB_R_VALUE_INDEX = 0; + + /** + * RGB Green Sysfs value index + */ + public static final int SYSFS_RGB_G_VALUE_INDEX = 1; + + /** + * RGB Blue Sysfs value index + */ + public static final int SYSFS_RGB_B_VALUE_INDEX = 2; + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "lego-ev3-color"; + private boolean autoSwitchMode = true; /** @@ -23,11 +75,11 @@ public class ColorSensor extends Sensor { * @param port LegoPort * @throws InvalidPortException If the specified port wasn't valid * @throws InvalidSensorException If the specified sensor wasn't a ColorSensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public ColorSensor(LegoPort port) throws IOException, InvalidPortException, InvalidSensorException { + public ColorSensor(LegoPort port) throws EV3LibraryException { super(port); - if (!Def.COLOR_SENSOR_DRIVER_NAME.equals(this.getDriverName())){ + if (!DRIVER_NAME.equals(this.getDriverName())){ throw new InvalidSensorException("The specified device is not a color sensor."); } port.getAddress(); @@ -36,36 +88,36 @@ public ColorSensor(LegoPort port) throws IOException, InvalidPortException, Inva /** * Reflected light intensity as a percentage. Light on sensor is red. * @return Reflected Light Intensity in percentage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getReflectedLightIntensity() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_COLOR_SENSOR_REFLECTED_LIGHT_INTENSITY_REQUIRED_MODE)){ + public int getReflectedLightIntensity() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_REFLECTED_LIGHT_INTENSITY_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_COLOR_SENSOR_REFLECTED_LIGHT_INTENSITY_REQUIRED_MODE); + this.setMode(SYSFS_REFLECTED_LIGHT_INTENSITY_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_COLOR_SENSOR_REFLECTED_LIGHT_INTENSITY_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_REFLECTED_LIGHT_INTENSITY_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_COLOR_SENSOR_REFLECTED_LIGHT_INTENSITY_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_REFLECTED_LIGHT_INTENSITY_VALUE_INDEX); return Integer.parseInt(str); } /** * Ambient light intensity. Light on sensor is dimly lit blue. * @return Ambient light intensity in percentage - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getAmbientLightIntensity() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_COLOR_SENSOR_AMBIENT_LIGHT_INTENSITY_REQUIRED_MODE)){ + public int getAmbientLightIntensity() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_AMBIENT_LIGHT_INTENSITY_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_COLOR_SENSOR_AMBIENT_LIGHT_INTENSITY_REQUIRED_MODE); + this.setMode(SYSFS_AMBIENT_LIGHT_INTENSITY_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_COLOR_SENSOR_AMBIENT_LIGHT_INTENSITY_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_AMBIENT_LIGHT_INTENSITY_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_COLOR_SENSOR_AMBIENT_LIGHT_INTENSITY_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_AMBIENT_LIGHT_INTENSITY_VALUE_INDEX); return Integer.parseInt(str); } @@ -80,72 +132,72 @@ public int getAmbientLightIntensity() throws IOException, InvalidModeException{ * - 6: White
* - 7: Brown * @return Color value - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getColor() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_COLOR_SENSOR_COLOR_REQUIRED_MODE)){ + public int getColor() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_COLOR_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_COLOR_SENSOR_COLOR_REQUIRED_MODE); + this.setMode(SYSFS_COLOR_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_COLOR_SENSOR_COLOR_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_COLOR_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_COLOR_SENSOR_COLOR_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_COLOR_VALUE_INDEX); return Integer.parseInt(str); } /** * Red component of the detected color, in the range 0-1020 * @return RGB Red component - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getRGB_Red() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_COLOR_SENSOR_RGB_R_REQUIRED_MODE)){ + public int getRGB_Red() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_RGB_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_COLOR_SENSOR_RGB_R_REQUIRED_MODE); + this.setMode(SYSFS_RGB_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_COLOR_SENSOR_RGB_R_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_RGB_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_COLOR_SENSOR_RGB_R_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_RGB_R_VALUE_INDEX); return Integer.parseInt(str); } /** * Green component of the detected color, in the range 0-1020 * @return Green Red component - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getRGB_Green() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_COLOR_SENSOR_RGB_G_REQUIRED_MODE)){ + public int getRGB_Green() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_RGB_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_COLOR_SENSOR_RGB_G_REQUIRED_MODE); + this.setMode(SYSFS_RGB_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_COLOR_SENSOR_RGB_G_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_RGB_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_COLOR_SENSOR_RGB_G_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_RGB_G_VALUE_INDEX); return Integer.parseInt(str); } /** * Blue component of the detected color, in the range 0-1020 * @return Blue Red component - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getRGB_Blue() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_COLOR_SENSOR_RGB_B_REQUIRED_MODE)){ + public int getRGB_Blue() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_RGB_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_COLOR_SENSOR_RGB_B_REQUIRED_MODE); + this.setMode(SYSFS_RGB_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_COLOR_SENSOR_RGB_B_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_RGB_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_COLOR_SENSOR_RGB_B_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_RGB_B_VALUE_INDEX); return Integer.parseInt(str); } diff --git a/src/main/java/org/ev3dev/hardware/sensors/GyroSensor.java b/src/main/java/org/ev3dev/hardware/sensors/GyroSensor.java index 520738d..24cc4eb 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/GyroSensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/GyroSensor.java @@ -1,12 +1,10 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidModeException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.exception.InvalidSensorException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; /** * LEGO EV3 gyro sensor. @@ -15,6 +13,31 @@ */ public class GyroSensor extends Sensor { + /** + * Gyro angle required Sysfs mode + */ + public static final String SYSFS_ANGLE_MODE = "GYRO-ANG"; + + /** + * Gyro angle Sysfs value index + */ + public static final int SYSFS_ANGLE_VALUE_INDEX = 0; + + /** + * Gyro rate required Sysfs mode + */ + public static final String SYSFS_RATE_MODE = "GYRO-RATE"; + + /** + * Gyro angle Sysfs value index + */ + public static final int SYSFS_RATE_VALUE_INDEX = 0; + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "lego-ev3-gyro"; + private boolean autoSwitchMode = true; /** @@ -22,11 +45,11 @@ public class GyroSensor extends Sensor { * @param port LegoPort * @throws InvalidPortException If the specified port wasn't valid * @throws InvalidSensorException If the specified sensor wasn't a GyroSensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public GyroSensor(LegoPort port) throws IOException, InvalidPortException, InvalidSensorException { + public GyroSensor(LegoPort port) throws EV3LibraryException, InvalidPortException, InvalidSensorException { super(port); - if (!this.getDriverName().equals(Def.GYRO_SENSOR_DRIVER_NAME)){ + if (!this.getDriverName().equals(DRIVER_NAME)){ throw new InvalidSensorException("Can't create a GyroSensor instance if port isn't connected to a GyroSensor!"); } } @@ -34,36 +57,36 @@ public GyroSensor(LegoPort port) throws IOException, InvalidPortException, Inval /** * The number of degrees that the sensor has been rotated since it was put into this mode. * @return The number of degrees - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getAngle() throws InvalidModeException, IOException{ - if (!this.getMode().equals(Def.PROPERTY_GYRO_SENSOR_ANGLE_REQUIRED_MODE)){ + public int getAngle() throws InvalidModeException, EV3LibraryException{ + if (!this.getMode().equals(SYSFS_ANGLE_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_GYRO_SENSOR_ANGLE_REQUIRED_MODE); + this.setMode(SYSFS_ANGLE_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_GYRO_SENSOR_ANGLE_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_ANGLE_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_GYRO_SENSOR_ANGLE_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_ANGLE_VALUE_INDEX); return Integer.parseInt(str); } /** * The rate at which the sensor is rotating, in degrees/second. * @return The rate at which the sensor is rotating - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getRate() throws InvalidModeException, IOException{ - if (!this.getMode().equals(Def.PROPERTY_GYRO_SENSOR_RATE_REQUIRED_MODE)){ + public int getRate() throws InvalidModeException, EV3LibraryException{ + if (!this.getMode().equals(SYSFS_RATE_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_GYRO_SENSOR_RATE_REQUIRED_MODE); + this.setMode(SYSFS_RATE_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_GYRO_SENSOR_RATE_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_RATE_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_GYRO_SENSOR_RATE_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_RATE_VALUE_INDEX); return Integer.parseInt(str); } diff --git a/src/main/java/org/ev3dev/hardware/sensors/I2CSensor.java b/src/main/java/org/ev3dev/hardware/sensors/I2CSensor.java index 54394f3..c441766 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/I2CSensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/I2CSensor.java @@ -1,11 +1,9 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.exception.InvalidSensorException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; /** * A generic interface to control I2C-type EV3 sensors. @@ -13,17 +11,44 @@ * */ public class I2CSensor extends Sensor { + + /** + * The Sysfs class's fw_version property name + */ + public static final String SYSFS_PROPERTY_FIRMWARE_VERSION = "fw_version"; + + /** + * The Sysfs class's poll_ms property name + */ + public static final String SYSFS_PROPERTY_POLL_MS = "poll_ms"; + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "nxt-i2c-sensor"; /** * Creates a new I2CSensor instance. * @param port LegoPort * @throws InvalidPortException If the specified port wasn't valid * @throws InvalidSensorException If the specified sensor wasn't a I2CSensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong + */ + public I2CSensor(LegoPort port) throws InvalidPortException, InvalidSensorException, EV3LibraryException { + this(port, DRIVER_NAME); + } + + /** + * Creates a new I2CSensor instance, and an alternative driver name can be specified. + * @param port LegoPort + * @param target_driver_name The target driver name to be checked. + * @throws InvalidPortException If the specified port wasn't valid + * @throws InvalidSensorException If the specified sensor wasn't a I2CSensor + * @throws EV3LibraryException If I/O goes wrong */ - public I2CSensor(LegoPort port) throws InvalidPortException, InvalidSensorException, IOException { + public I2CSensor(LegoPort port, String target_driver_name) throws InvalidPortException, InvalidSensorException, EV3LibraryException { super(port); - if (!this.getDriverName().equals(Def.I2CSENSOR_DRIVER_NAME)){ + if (!this.getDriverName().equals(target_driver_name)){ throw new InvalidSensorException("The specified port is not a I2C sensor."); } } @@ -31,10 +56,10 @@ public I2CSensor(LegoPort port) throws InvalidPortException, InvalidSensorExcept /** * Returns the firmware version of the sensor if available. Currently only I2C/NXT sensors support this. * @return The firmware version - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getFirmwareVersion() throws IOException{ - return this.getAttribute(Def.PROPERTY_FIRMWARE_VERSION); + public String getFirmwareVersion() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_FIRMWARE_VERSION); } /** @@ -42,10 +67,10 @@ public String getFirmwareVersion() throws IOException{ * Minimum value is hard coded as 50 msec. Returns -EOPNOTSUPP if changing polling is not supported. * Currently only I2C/NXT sensors support changing the polling period. * @return The polling period in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getPollMs() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_POLL_MS); + public int getPollMs() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_POLL_MS); return Integer.parseInt(str); } @@ -54,9 +79,9 @@ public int getPollMs() throws IOException{ * Minimum value is hard coded as 50 msec. Returns -EOPNOTSUPP if changing polling is not supported. * Currently only I2C/NXT sensors support changing the polling period. * @param ms The polling period in milliseconds - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setPollMs(int ms) throws IOException{ - this.setAttribute(Def.PROPERTY_POLL_MS, Integer.toString(ms)); + public void setPollMs(int ms) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_POLL_MS, Integer.toString(ms)); } } diff --git a/src/main/java/org/ev3dev/hardware/sensors/InfraredSensor.java b/src/main/java/org/ev3dev/hardware/sensors/InfraredSensor.java index 1fd0ade..8f28447 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/InfraredSensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/InfraredSensor.java @@ -1,12 +1,10 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidModeException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.exception.InvalidSensorException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; /** * LEGO EV3 infrared sensor. @@ -14,6 +12,21 @@ * */ public class InfraredSensor extends Sensor { + + /** + * Proximity required Sysfs mode + */ + public static final String SYSFS_PROXIMITY_REQUIRED_MODE = "IR-PROX"; + + /** + * Proximity Sysfs value index + */ + public static final int SYSFS_PROXIMITY_VALUE_INDEX = 0; + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "lego-ev3-ir"; private boolean autoSwitchMode = true; @@ -22,11 +35,11 @@ public class InfraredSensor extends Sensor { * @param port LegoPort * @throws InvalidPortException If the specified port wasn't valid * @throws InvalidSensorException If the specified sensor wasn't a InfraredSensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public InfraredSensor(LegoPort port) throws IOException, InvalidPortException, InvalidSensorException { + public InfraredSensor(LegoPort port) throws EV3LibraryException, InvalidPortException, InvalidSensorException { super(port); - if (!this.getDriverName().equals(Def.INFRARED_SENSOR_DRIVER_NAME)){ + if (!this.getDriverName().equals(DRIVER_NAME)){ throw new InvalidSensorException("Can't create a InfraredSensor instance if the port isn't connected a infrared sensor!"); } } @@ -34,18 +47,18 @@ public InfraredSensor(LegoPort port) throws IOException, InvalidPortException, I /** * A measurement of the distance between the sensor and the remote, as a percentage. 100% is approximately 70cm/27in. * @return A measurement of the distance - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public int getProximity() throws InvalidModeException, IOException{ - if (!this.getMode().equals(Def.PROPERTY_INFRARED_SENSOR_PROXIMITY_REQUIRED_MODE)){ + public int getProximity() throws InvalidModeException, EV3LibraryException{ + if (!this.getMode().equals(SYSFS_PROXIMITY_REQUIRED_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_INFRARED_SENSOR_PROXIMITY_REQUIRED_MODE); + this.setMode(SYSFS_PROXIMITY_REQUIRED_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_INFRARED_SENSOR_PROXIMITY_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_PROXIMITY_REQUIRED_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_INFRARED_SENSOR_PROXIMITY_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_PROXIMITY_VALUE_INDEX); return Integer.parseInt(str); } diff --git a/src/main/java/org/ev3dev/hardware/sensors/LightSensor.java b/src/main/java/org/ev3dev/hardware/sensors/LightSensor.java index 91b5fd9..1618fa9 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/LightSensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/LightSensor.java @@ -1,12 +1,10 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidModeException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.exception.InvalidSensorException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; /** * LEGO NXT Light Sensor @@ -14,6 +12,31 @@ * */ public class LightSensor extends Sensor { + + /** + * Reflected light Sysfs required mode + */ + public static final String SYSFS_REFLECTED_REQUIRED_MODE = "REFLECT"; + + /** + * Reflected light Sysfs value index + */ + public static final int SYSFS_REFLECTED_VALUE_INDEX = 0; + + /** + * Ambient light Sysfs required mode + */ + public static final String SYSFS_AMBIENT_REQUIRED_MODE = "AMBIENT"; + + /** + * Ambient light Sysfs value index + */ + public static final int SYSFS_AMBIENT_VALUE_INDEX = 0; + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "lego-nxt-light"; public boolean autoSwitchMode = true; @@ -22,11 +45,11 @@ public class LightSensor extends Sensor { * @param port LegoPort * @throws InvalidPortException If the specified port wasn't valid * @throws InvalidSensorException If the specified sensor wasn't a LightSensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public LightSensor(LegoPort port) throws IOException, InvalidPortException, InvalidSensorException { + public LightSensor(LegoPort port) throws EV3LibraryException, InvalidPortException, InvalidSensorException { super(port); - if(!this.getDriverName().equals(Def.LIGHT_SENSOR_DRIVER_NAME)){ + if(!this.getDriverName().equals(DRIVER_NAME)){ throw new InvalidSensorException("Can't create a LightSensor instance if the port isn't connected to a light sensor!"); } } @@ -34,36 +57,36 @@ public LightSensor(LegoPort port) throws IOException, InvalidPortException, Inva /** * A measurement of the reflected light intensity, as a percentage. * @return A measurement of the reflected light intensity - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public float getReflectedLightIntensity() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_LIGHT_SENSOR_REFLECTED_REQUIRED_MODE)){ + public float getReflectedLightIntensity() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_REFLECTED_REQUIRED_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_LIGHT_SENSOR_REFLECTED_REQUIRED_MODE); + this.setMode(SYSFS_REFLECTED_REQUIRED_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_LIGHT_SENSOR_REFLECTED_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_REFLECTED_REQUIRED_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_LIGHT_SENSOR_REFLECTED_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_REFLECTED_VALUE_INDEX); return Float.parseFloat(str); } /** * A measurement of the ambient light intensity, as a percentage. * @return A measurement of the ambient light intensity - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public float getAmbientLightIntensity() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_LIGHT_SENSOR_AMBIENT_REQUIRED_MODE)){ + public float getAmbientLightIntensity() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_AMBIENT_REQUIRED_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_LIGHT_SENSOR_AMBIENT_REQUIRED_MODE); + this.setMode(SYSFS_AMBIENT_REQUIRED_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_LIGHT_SENSOR_AMBIENT_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_AMBIENT_REQUIRED_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_LIGHT_SENSOR_AMBIENT_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_AMBIENT_VALUE_INDEX); return Float.parseFloat(str); } diff --git a/src/main/java/org/ev3dev/hardware/sensors/Sensor.java b/src/main/java/org/ev3dev/hardware/sensors/Sensor.java index d4bd18e..deea682 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/Sensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/Sensor.java @@ -1,12 +1,10 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.hardware.Device; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; -import org.ev3dev.io.Sysclass; +import org.ev3dev.io.Sysfs; /** * The sensor class provides a uniform interface for using most of the sensors available for the EV3. @@ -17,40 +15,95 @@ *
* Since the name of the sensor[N] device node does not correspond to the port that a sensor is plugged in * to, you must look at the address attribute if you need to know which port a sensor is plugged in to. - * However, if you don・t have more than one sensor of each type, you can just look for a matching driver_name. + * However, if you don't have more than one sensor of each type, you can just look for a matching driver_name. * Then it will not matter which port a sensor is plugged in to - your program will still work. * @author Anthony * */ public class Sensor extends Device{ + + /** + * The Sysfs class's address property name + */ + public static final String SYSFS_PROPERTY_ADDRESS = "address"; + + /** + * The Sysfs class's command property name + */ + public static final String SYSFS_PROPERTY_COMMAND = "command"; + + /** + * The Sysfs class's commands property name + */ + public static final String SYSFS_PROPERTY_COMMANDS = "commands"; + + /** + * The Sysfs class's driver_name property name + */ + public static final String SYSFS_PROPERTY_DRIVER_NAME = "driver_name"; + + /** + * The Sysfs class's decimals property name + */ + public static final String SYSFS_PROPERTY_DECIMALS = "decimals"; + + /** + * The Sysfs class's mode property name + */ + public static final String SYSFS_PROPERTY_MODE = "mode"; + + /** + * The Sysfs class's modes property name + */ + public static final String SYSFS_PROPERTY_MODES = "modes"; + + /** + * The Sysfs class's num_values property name + */ + public static final String SYSFS_PROPERTY_NUM_VALUES = "num_values"; + + /** + * The Sysfs class's units property name + */ + public static final String SYSFS_PROPERTY_UNITS = "units"; + + /** + * This Sysfs's class name (e.g. /sys/class/lego-sensor, and lego-sensor is the class name) + */ + public static final String CLASS_NAME = "lego-sensor"; + + /** + * This Sysfs's class name prefix (e.g. /sys/class/lego-sensor/sensor0, and sensor is the class name prefix without the [N] value.) + */ + public static final String CLASS_NAME_PREFIX = "sensor"; /** * Creates a new Sensor instance using a LegoPort * @param port LegoPort - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidPortException If the specified LegoPort was invalid */ - public Sensor(LegoPort port) throws IOException, InvalidPortException{ - super(port, Def.SENSOR_CLASS_NAME, Def.SUB_SENSOR_CLASS_NAME); + public Sensor(LegoPort port) throws EV3LibraryException{ + super(port, CLASS_NAME, CLASS_NAME_PREFIX); } /** * Returns the name of the port that the sensor is connected to, e.g. ev3:in1. * I2C sensors also include the I2C address (decimal), e.g. ev3:in1:i2c8. * @return A sensor address - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getAddress() throws IOException{ - return this.getAttribute(Def.PROPERTY_ADDRESS); + public String getAddress() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_ADDRESS); } /*** * Generic method to send commands to the sensor controller. * @param command Command that suits for the sensor driver - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void sendCommand(String command) throws IOException{ - this.setAttribute(Def.PROPERTY_COMMAND, command); + public void sendCommand(String command) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_COMMAND, command); } /** @@ -61,57 +114,57 @@ public void sendCommand(String command) throws IOException{ * * Returns a list of the valid commands for the sensor. Returns -EOPNOTSUPP if no commands are supported. * @return A list of valid commands - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getCommandsViaString() throws IOException{ - return this.getAttribute(Def.PROPERTY_COMMANDS); + public String getCommandsViaString() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_COMMANDS); } /** * Returns a list of the valid commands for the sensor. Returns -EOPNOTSUPP if no commands are supported. * @return A list of valid commands - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getCommands() throws IOException{ + public String[] getCommands() throws EV3LibraryException{ String str = getCommandsViaString(); - return Sysclass.separateSpace(str); + return Sysfs.separateSpace(str); } /** * Returns the number of decimal places for the values in the value[N] attributes of the current mode. * @return The number of decimal places - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getDecimals() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_DECIMALS); + public int getDecimals() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_DECIMALS); return Integer.parseInt(str); } /** * Returns the name of the sensor device/driver. See the list of [supported sensors] for a complete list of drivers. * @return The name of the sensor device or driver - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getDriverName() throws IOException{ - return this.getAttribute(Def.PROPERTY_DRIVER_NAME); + public String getDriverName() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_DRIVER_NAME); } /** * Returns the current mode. Writing one of the values returned by modes sets the sensor to that mode. * @return The current mode - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getMode() throws IOException{ - return this.getAttribute(Def.PROPERTY_MODE); + public String getMode() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_MODE); } /** * Sets the current mode. Writing one of the values returned by modes sets the sensor to that mode. * @param mode The mode listed using getModes() - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public void setMode(String mode) throws IOException{ - this.setAttribute(Def.PROPERTY_MODE, mode); + public void setMode(String mode) throws EV3LibraryException{ + this.setAttribute(SYSFS_PROPERTY_MODE, mode); } /** @@ -122,39 +175,39 @@ public void setMode(String mode) throws IOException{ * * Returns a list of the valid modes for the sensor. * @return A list of valid modes for the sensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getModesViaString() throws IOException{ - return this.getAttribute(Def.PROPERTY_MODES); + public String getModesViaString() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_MODES); } /** * Returns a list of the valid modes for the sensor. * @return A list of valid modes for the sensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String[] getModes() throws IOException{ + public String[] getModes() throws EV3LibraryException{ String str = getModesViaString(); - return Sysclass.separateSpace(str); + return Sysfs.separateSpace(str); } /** * Returns the number of value[N] attributes that will return a valid value for the current mode. * @return The number if value[N] attributes - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public int getNumValues() throws IOException{ - String str = this.getAttribute(Def.PROPERTY_NUM_VALUES); + public int getNumValues() throws EV3LibraryException{ + String str = this.getAttribute(SYSFS_PROPERTY_NUM_VALUES); return Integer.parseInt(str); } /** * Returns the units of the measured value for the current mode. May return empty string * @return The units of measured value - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public String getUnits() throws IOException{ - return this.getAttribute(Def.PROPERTY_UNITS); + public String getUnits() throws EV3LibraryException{ + return this.getAttribute(SYSFS_PROPERTY_UNITS); } } diff --git a/src/main/java/org/ev3dev/hardware/sensors/SoundSensor.java b/src/main/java/org/ev3dev/hardware/sensors/SoundSensor.java index 9c1f726..8f4455b 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/SoundSensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/SoundSensor.java @@ -1,12 +1,10 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidModeException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.exception.InvalidSensorException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; /** * LEGO NXT Sound Sensor @@ -15,6 +13,31 @@ */ public class SoundSensor extends Sensor { + /** + * Sound pressure Sysfs required mode + */ + public static final String SYSFS_SOUND_PRESSURE_REQUIRED_MODE = "DB"; + + /** + * Sound pressure Sysfs value index + */ + public static final int SYSFS_SOUND_PRESSURE_VALUE_INDEX = 0; + + /** + * Sound pressure Low Sysfs required mode + */ + public static final String SYSFS_SOUND_PRESSURE_LOW_REQUIRED_MODE = "DBA"; + + /** + * Sound pressure Low Sysfs value index + */ + public static final int SYSFS_SOUND_PRESSURE_LOW_VALUE_INDEX = 0; + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "lego-nxt-sound"; + public boolean autoSwitchMode = true; /** @@ -22,11 +45,11 @@ public class SoundSensor extends Sensor { * @param port LegoPort * @throws InvalidPortException If the specified port wasn't valid * @throws InvalidSensorException If the specified sensor wasn't a SoundSensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public SoundSensor(LegoPort port) throws IOException, InvalidPortException, InvalidSensorException { + public SoundSensor(LegoPort port) throws EV3LibraryException, InvalidPortException, InvalidSensorException { super(port); - if(!this.getDriverName().equals(Def.SOUND_SENSOR_DRIVER_NAME)){ + if(!this.getDriverName().equals(DRIVER_NAME)){ throw new InvalidSensorException("Can't create a SoundSensor instance if the port isn't connected to a sound sensor!"); } } @@ -34,36 +57,36 @@ public SoundSensor(LegoPort port) throws IOException, InvalidPortException, Inva /** * A measurement of the measured sound pressure level, as a percent. Uses a flat weighting. * @return The measured sound pressure level - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public float getSoundPressure() throws InvalidModeException, IOException{ - if (!this.getMode().equals(Def.PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_REQUIRED_MODE)){ + public float getSoundPressure() throws InvalidModeException, EV3LibraryException{ + if (!this.getMode().equals(SYSFS_SOUND_PRESSURE_REQUIRED_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_REQUIRED_MODE); + this.setMode(SYSFS_SOUND_PRESSURE_REQUIRED_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_SOUND_PRESSURE_REQUIRED_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_SOUND_PRESSURE_VALUE_INDEX); return Float.parseFloat(str); } /** * A measurement of the measured sound pressure level, as a percent. Uses A-weighting, which focuses on levels up to 55 dB. * @return The measured sound pressure level, A-weighting. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public float getSoundPressureLow() throws InvalidModeException, IOException{ - if (!this.getMode().equals(Def.PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_LOW_REQUIRED_MODE)){ + public float getSoundPressureLow() throws InvalidModeException, EV3LibraryException{ + if (!this.getMode().equals(SYSFS_SOUND_PRESSURE_LOW_REQUIRED_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_LOW_REQUIRED_MODE); + this.setMode(SYSFS_SOUND_PRESSURE_LOW_REQUIRED_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_LOW_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_SOUND_PRESSURE_LOW_REQUIRED_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_LOW_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_SOUND_PRESSURE_LOW_VALUE_INDEX); return Float.parseFloat(str); } diff --git a/src/main/java/org/ev3dev/hardware/sensors/TouchSensor.java b/src/main/java/org/ev3dev/hardware/sensors/TouchSensor.java index 4749b17..95c285c 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/TouchSensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/TouchSensor.java @@ -1,15 +1,33 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidModeException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.exception.InvalidSensorException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; public class TouchSensor extends Sensor { + /** + * Sysfs class TouchSensor required mode + */ + public static final String SYSFS_REQUIRED_MODE = "TOUCH"; + + /** + * Sysfs class TouchSensor Value Index + */ + public static final int SYSFS_VALUE_INDEX = 0; + + /** + * This device's default driver name (EV3 Touch Sensor) + */ + public static final String DRIVER_NAME_EV3 = "lego-ev3-touch"; + + /** + * This device's default driver name (NXT Touch Sensor) + */ + public static final String DRIVER_NAME_NXT = "lego-nxt-touch"; + public boolean autoSwitchMode = true; /** @@ -17,35 +35,35 @@ public class TouchSensor extends Sensor { * @param port LegoPort * @throws InvalidPortException If the specified port wasn't valid * @throws InvalidSensorException If the specified sensor wasn't a TouchSensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public TouchSensor(LegoPort port) throws IOException, InvalidPortException, InvalidSensorException { + public TouchSensor(LegoPort port) throws EV3LibraryException, InvalidPortException, InvalidSensorException { super(port); - if (!this.getDriverName().equals(Def.TOUCH_SENSOR_DRIVER_NAME_EV3) && - !this.getDriverName().equals(Def.TOUCH_SENSOR_DRIVER_NAME_NXT)){ + if (!this.getDriverName().equals(DRIVER_NAME_EV3) && + !this.getDriverName().equals(DRIVER_NAME_NXT)){ throw new InvalidSensorException("Can't create a TouchSensor instance that isn't a touch sensor!"); } port.getAddress(); - if (!this.getMode().equals(Def.PROPERTY_TOUCH_REQUIRED_MODE)){ - throw new InvalidSensorException("Can't create a TouchSensor instance that does not support: " + Def.PROPERTY_TOUCH_REQUIRED_MODE); + if (!this.getMode().equals(SYSFS_REQUIRED_MODE)){ + throw new InvalidSensorException("Can't create a TouchSensor instance that does not support: " + SYSFS_REQUIRED_MODE); } } /** * A boolean indicating whether the current touch sensor is being pressed. * @return The touch sensor is pressed or not. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public boolean isPressed() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_TOUCH_REQUIRED_MODE)){ + public boolean isPressed() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_REQUIRED_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_TOUCH_REQUIRED_MODE); + this.setMode(SYSFS_REQUIRED_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_TOUCH_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_REQUIRED_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_TOUCH_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_VALUE_INDEX); return str.equals("1"); } diff --git a/src/main/java/org/ev3dev/hardware/sensors/UltrasonicSensor.java b/src/main/java/org/ev3dev/hardware/sensors/UltrasonicSensor.java index 1be1d29..075f543 100644 --- a/src/main/java/org/ev3dev/hardware/sensors/UltrasonicSensor.java +++ b/src/main/java/org/ev3dev/hardware/sensors/UltrasonicSensor.java @@ -1,15 +1,53 @@ package org.ev3dev.hardware.sensors; -import java.io.IOException; - +import org.ev3dev.exception.EV3LibraryException; import org.ev3dev.exception.InvalidModeException; import org.ev3dev.exception.InvalidPortException; import org.ev3dev.exception.InvalidSensorException; import org.ev3dev.hardware.ports.LegoPort; -import org.ev3dev.io.Def; public class UltrasonicSensor extends Sensor { + /** + * Distance in cm required Sysfs mode + */ + public static final String SYSFS_CM_MODE = "US-DIST-CM"; + + /** + * Distance in cm Sysfs value index + */ + public static final int SYSFS_CM_VALUE_INDEX = 0; + + /** + * Distance in inch required Sysfs mode + */ + public static final String SYSFS_IN_MODE = "US-DIST-IN"; + + /** + * Distance in inch Sysfs value index + */ + public static final int SYSFS_IN_VALUE_INDEX = 0; + + /** + * Other present sensor detection required Sysfs mode + */ + public static final String SYSFS_OTHER_PRESENT_MODE = "US-LISTEN"; + + /** + * Other present sensor detection Sysfs value index + */ + public static final int SYSFS_OTHER_PRESENT_VALUE_INDEX = 0; + + /** + * This device's default driver name (EV3 Ultrasonic Sensor) + */ + public static final String DRIVER_NAME_EV3 = "lego-ev3-us"; + + /** + * This device's default driver name (NXT Ultrasonic Sensor) + */ + public static final String DRIVER_NAME_NXT = "lego-nxt-us"; + public boolean autoSwitchMode = true; /** @@ -17,13 +55,13 @@ public class UltrasonicSensor extends Sensor { * @param port LegoPort * @throws InvalidPortException If the specified port wasn't valid * @throws InvalidSensorException If the specified sensor wasn't a UltrasonicSensor - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong */ - public UltrasonicSensor(LegoPort port) throws IOException, InvalidPortException, InvalidSensorException { + public UltrasonicSensor(LegoPort port) throws EV3LibraryException, InvalidPortException, InvalidSensorException { super(port); String driverName = this.getDriverName(); - if (!driverName.equals(Def.ULTRASONIC_SENSOR_DRIVER_NAME_EV3) && - !driverName.equals(Def.ULTRASONIC_SENSOR_DRIVER_NAME_NXT)){ + if (!driverName.equals(DRIVER_NAME_EV3) && + !driverName.equals(DRIVER_NAME_NXT)){ throw new InvalidSensorException("Can't create a UltrasonicSensor instance if it is not a ultrasonic sensor! Yours: " + driverName); } } @@ -31,54 +69,54 @@ public UltrasonicSensor(LegoPort port) throws IOException, InvalidPortException, /** * Measurement of the distance detected by the sensor, in centimeters. * @return The distance in centimeters - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public float getDistanceCentimeters() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_ULTRASONIC_SENSOR_CM_REQUIRED_MODE)){ + public float getDistanceCentimeters() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_CM_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_ULTRASONIC_SENSOR_CM_REQUIRED_MODE); + this.setMode(SYSFS_CM_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_ULTRASONIC_SENSOR_CM_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_CM_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_ULTRASONIC_SENSOR_CM_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_CM_VALUE_INDEX); return Float.parseFloat(str); } /** * Measurement of the distance detected by the sensor, in inches. * @return The distance in inches. - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public float getDistanceInches() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_ULTRASONIC_SENSOR_IN_REQUIRED_MODE)){ + public float getDistanceInches() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_IN_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_ULTRASONIC_SENSOR_IN_REQUIRED_MODE); + this.setMode(SYSFS_IN_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_ULTRASONIC_SENSOR_IN_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_IN_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_ULTRASONIC_SENSOR_IN_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_IN_VALUE_INDEX); return Float.parseFloat(str); } /** * Value indicating whether another ultrasonic sensor could be heard nearby. * @return Boolean - * @throws IOException If I/O goes wrong + * @throws EV3LibraryException If I/O goes wrong * @throws InvalidModeException The mode selected wasn't valid, or Auto Switch Mode has disabled. */ - public boolean isOtherSensorPresent() throws IOException, InvalidModeException{ - if (!this.getMode().equals(Def.PROPERTY_ULTRASONIC_SENSOR_OTHER_PRESENT_REQUIRED_MODE)){ + public boolean isOtherSensorPresent() throws EV3LibraryException, InvalidModeException{ + if (!this.getMode().equals(SYSFS_OTHER_PRESENT_MODE)){ if (autoSwitchMode){ - this.setMode(Def.PROPERTY_ULTRASONIC_SENSOR_OTHER_PRESENT_REQUIRED_MODE); + this.setMode(SYSFS_OTHER_PRESENT_MODE); } else { - throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + Def.PROPERTY_ULTRASONIC_SENSOR_OTHER_PRESENT_REQUIRED_MODE + ")! Yours: " + this.getMode()); + throw new InvalidModeException("[Auto-switch is off] You are not using a correct mode(" + SYSFS_OTHER_PRESENT_MODE + ")! Yours: " + this.getMode()); } } - String str = this.getAttribute("value" + Def.PROPERTY_ULTRASONIC_SENSOR_OTHER_PRESENT_VALUE_INDEX); + String str = this.getAttribute("value" + SYSFS_OTHER_PRESENT_VALUE_INDEX); return str.equals("1"); } diff --git a/src/main/java/org/ev3dev/hardware/sensors/charmedlabs/PixyCmucam5Sensor.java b/src/main/java/org/ev3dev/hardware/sensors/charmedlabs/PixyCmucam5Sensor.java new file mode 100644 index 0000000..5429fef --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/sensors/charmedlabs/PixyCmucam5Sensor.java @@ -0,0 +1,475 @@ +package org.ev3dev.hardware.sensors.charmedlabs; + +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.hardware.ports.LegoPort; +import org.ev3dev.hardware.sensors.I2CSensor; + +/** + * Pixy Cmucam 5 for Lego + * @author Anthony + * + */ +public class PixyCmucam5Sensor extends I2CSensor { + + /** + * ALL Mode - All + */ + public static final String MODE_ALL = "ALL"; + + /** + * ALL Mode - Signature low byte Sysfs value index + */ + public static final int MODE_ALL_SIG_LOW_BYTE_VALUE_INDEX = 0; + + /** + * ALL Mode - Signature high byte Sysfs value index + */ + public static final int MODE_ALL_SIG_HIGH_BYTE_VALUE_INDEX = 1; + + /** + * ALL Mode - X Sysfs value index + */ + public static final int MODE_ALL_X_VALUE_INDEX = 2; + + /** + * ALL Mode - Y Sysfs value index + */ + public static final int MODE_ALL_Y_VALUE_INDEX = 3; + + /** + * ALL Mode - Width Sysfs value index + */ + public static final int MODE_ALL_WIDTH_VALUE_INDEX = 4; + + /** + * ALL Mode - Height Sysfs value index + */ + public static final int MODE_ALL_HEIGHT_VALUE_INDEX = 5; + + /** + * SIG[N] Mode (All signature modes) - Count Sysfs value index + */ + public static final int MODE_SIG_COUNT_VALUE_INDEX = 0; + + /** + * SIG[N] Mode (All signature modes) - X Sysfs value index + */ + public static final int MODE_SIG_X_VALUE_INDEX = 1; + + /** + * SIG[N] Mode (All signature modes) - Y Sysfs value index + */ + public static final int MODE_SIG_Y_VALUE_INDEX = 2; + + /** + * SIG[N] Mode (All signature modes) - Width Sysfs value index + */ + public static final int MODE_SIG_WIDTH_VALUE_INDEX = 3; + + /** + * SIG[N] Mode (All signature modes) - Height Sysfs value index + */ + public static final int MODE_SIG_HEIGHT_VALUE_INDEX = 4; + + /** + * The prefix of modes SIG[N], where SIG is the prefix. + */ + public static final String PREFIX_MODE_SIG = "SIG"; + + /** + * SIG1 Mode - Signature #1 + */ + public static final String MODE_SIG1 = "SIG1"; + + /** + * SIG2 Mode - Signature #2 + */ + public static final String MODE_SIG2 = "SIG2"; + + /** + * SIG3 Mode - Signature #3 + */ + public static final String MODE_SIG3 = "SIG3"; + + /** + * SIG4 Mode - Signature #4 + */ + public static final String MODE_SIG4 = "SIG4"; + + /** + * SIG5 Mode - Signature #5 + */ + public static final String MODE_SIG5 = "SIG5"; + + /** + * SIG6 Mode - Signature #6 + */ + public static final String MODE_SIG6 = "SIG6"; + + /** + * SIG7 Mode - Signature #7 + */ + public static final String MODE_SIG7 = "SIG7"; + + /** + * Vendor ID + */ + public static final String VENDOR_ID = "Pixy"; + + /** + * Product ID + */ + public static final String PRODUCT_ID = "Pixy"; + + /** + * Pixy Cmucam 5 Sensor driver name + */ + public static final String DRIVER_NAME = "pixy-lego"; + + /** + * Address + */ + public static final byte ADDRESS = 0x01; + + /** + * Creates a new Pixy Cmucam 5 instnace + * @param port The LegoPort instance + * @throws EV3LibraryException If I/O goes wrong + */ + public PixyCmucam5Sensor(LegoPort port) throws EV3LibraryException { + super(port, DRIVER_NAME); + } + + /** + * Returns the vendor id + * @return Vendor Id + */ + public String getVendorId(){ + return VENDOR_ID; + } + + /** + * Returns the product id + * @return Product Id + */ + public String getProductId(){ + return PRODUCT_ID; + } + + /** + * Set mode to ALL.
+ *
+ * And returns a ModeAll instance for communication. + * @return ModeAll instance + */ + public ModeAll modeAll(){ + setMode(MODE_ALL); + return new ModeAll(MODE_ALL); + } + + /** + * Set mode to SIG[N], where [N] is the integer parameter specified
+ *
+ * And returns a ModeSig instance for communication. + * @param sigcount The value [N] of mode SIG[N]. (e.g. SIG1 specify 1) + * @return ModeSig instance + */ + public ModeSig modeSig(int sigcount){ + setMode(PREFIX_MODE_SIG + sigcount); + return new ModeSig(PREFIX_MODE_SIG + sigcount); + } + + /** + * Set mode to SIG1
+ *
+ * And returns a ModeSig instance for communication. + * @return ModeSig instance + */ + public ModeSig modeSig1(){ + return modeSig(1); + } + + /** + * Set mode to SIG2
+ *
+ * And returns a ModeSig instance for communication. + * @return ModeSig instance + */ + public ModeSig modeSig2(){ + return modeSig(2); + } + + /** + * Set mode to SIG3
+ *
+ * And returns a ModeSig instance for communication. + * @return ModeSig instance + */ + public ModeSig modeSig3(){ + return modeSig(3); + } + + /** + * Set mode to SIG4
+ *
+ * And returns a ModeSig instance for communication. + * @return ModeSig instance + */ + public ModeSig modeSig4(){ + return modeSig(4); + } + + /** + * Set mode to SIG5
+ *
+ * And returns a ModeSig instance for communication. + * @return ModeSig instance + */ + public ModeSig modeSig5(){ + return modeSig(5); + } + + /** + * Set mode to SIG6
+ *
+ * And returns a ModeSig instance for communication. + * @return ModeSig instance + */ + public ModeSig modeSig6(){ + return modeSig(6); + } + + /** + * Set mode to SIG7
+ *
+ * And returns a ModeSig instance for communication. + * @return ModeSig instance + */ + public ModeSig modeSig7(){ + return modeSig(7); + } + + /** + * A class to communicate with Pixy Cmucam 5 using mode ALL + * @author Anthony + * + */ + public class ModeAll { + + private final String mode; + + private boolean autoSwitchMode = true; + + private ModeAll(String mode){ + this.mode = mode; + } + + /** + * Check mode and switch automatically if autoSwitchMode is false
+ * Otherwise, EV3LibraryException will be thrown.
+ *
+ * Formerly called Fix Mode. + * @throws EV3LibraryException + */ + private void fixMode() throws EV3LibraryException{ + String currMode = getMode(); + if (!currMode.equals(mode)){ + if (autoSwitchMode){ + setMode(mode); + } else { + throw new EV3LibraryException("[Auto Switch Mode Off] You cannot use this function of mode " + mode + " with the current mode: " + currMode); + } + } + } + + /** + * Sets whether it should switch mode automatically if the mode is invalid.
+ * By default, it will auto switch mode. + * @param autoSwitchMode Switch or not + */ + public void setAutoSwitchMode(boolean autoSwitchMode){ + this.autoSwitchMode = autoSwitchMode; + } + + /** + * Returns whether it will auto switch mode or not. + * @return Boolean + */ + public boolean isAutoSwitchMode(){ + return autoSwitchMode; + } + + /** + * Get the signature low byte + * @return A byte representing the signature low byte + * @throws EV3LibraryException If I/O goes wrong + */ + public byte getSignatureLowByte() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_ALL_SIG_LOW_BYTE_VALUE_INDEX); + return Byte.parseByte(str); + } + + /** + * Get the signature high byte + * @return A byte representing the signature high byte + * @throws EV3LibraryException If I/O goes wrong + */ + public byte getSignatureHighByte() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_ALL_SIG_HIGH_BYTE_VALUE_INDEX); + return Byte.parseByte(str); + } + + /** + * Get the X point + * @return X point + * @throws EV3LibraryException If I/O goes wrong + */ + public int getX() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_ALL_X_VALUE_INDEX); + return Integer.parseInt(str); + } + + /** + * Get the Y point + * @return Y point + * @throws EV3LibraryException If I/O goes wrong + */ + public int getY() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_ALL_Y_VALUE_INDEX); + return Integer.parseInt(str); + } + + /** + * Get the width + * @return Width + * @throws EV3LibraryException If I/O goes wrong + */ + public int getWidth() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_ALL_WIDTH_VALUE_INDEX); + return Integer.parseInt(str); + } + + /** + * Get the height + * @return Height + * @throws EV3LibraryException If I/O goes wrong + */ + public int getHeight() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_ALL_HEIGHT_VALUE_INDEX); + return Integer.parseInt(str); + } + } + + /** + * A class to communicate with Pixy Cmucam 5 using mode SIG[N] + * @author Anthony + * + */ + public class ModeSig { + + private final String mode; + + private boolean autoSwitchMode = true; + + private ModeSig(String mode){ + this.mode = mode; + } + + /** + * Check mode and switch automatically if autoSwitchMode is false
+ * Otherwise, EV3LibraryException will be thrown.
+ *
+ * Formerly called Fix Mode. + * @throws EV3LibraryException + */ + private void fixMode() throws EV3LibraryException{ + String currMode = getMode(); + if (!currMode.equals(mode)){ + if (autoSwitchMode){ + setMode(mode); + } else { + throw new EV3LibraryException("[Auto Switch Mode Off] You cannot use this function of mode " + mode + " with the current mode: " + currMode); + } + } + } + + /** + * Sets whether it should switch mode automatically if the mode is invalid.
+ * By default, it will auto switch mode. + * @param autoSwitchMode Switch or not + */ + public void setAutoSwitchMode(boolean autoSwitchMode){ + this.autoSwitchMode = autoSwitchMode; + } + + /** + * Returns whether it will auto switch mode or not. + * @return Boolean + */ + public boolean isAutoSwitchMode(){ + return autoSwitchMode; + } + + /** + * Get the count + * @return Count + * @throws EV3LibraryException If I/O goes wrong + */ + public byte getCount() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_SIG_COUNT_VALUE_INDEX); + return Byte.parseByte(str); + } + + /** + * Get the X point + * @return X point + * @throws EV3LibraryException If I/O goes wrong + */ + public int getX() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_SIG_X_VALUE_INDEX); + return Integer.parseInt(str); + } + + /** + * Get the Y point + * @return Y point + * @throws EV3LibraryException If I/O goes wrong + */ + public int getY() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_SIG_Y_VALUE_INDEX); + return Integer.parseInt(str); + } + + /** + * Get the width + * @return Width + * @throws EV3LibraryException If I/O goes wrong + */ + public int getWidth() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_SIG_WIDTH_VALUE_INDEX); + return Integer.parseInt(str); + } + + /** + * Get the height + * @return Height + * @throws EV3LibraryException If I/O goes wrong + */ + public int getHeight() throws EV3LibraryException{ + fixMode(); + String str = getAttribute("value" + MODE_SIG_HEIGHT_VALUE_INDEX); + return Integer.parseInt(str); + } + } + +} diff --git a/src/main/java/org/ev3dev/hardware/sensors/di/DflexSensor.java b/src/main/java/org/ev3dev/hardware/sensors/di/DflexSensor.java new file mode 100644 index 0000000..b441dd1 --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/sensors/di/DflexSensor.java @@ -0,0 +1,41 @@ +package org.ev3dev.hardware.sensors.di; + +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.hardware.ports.LegoPort; +import org.ev3dev.hardware.sensors.generic.NXTAnalogSensor; + +public class DflexSensor extends NXTAnalogSensor { + + /** + * FLEX Mode - Flex + */ + public static final String MODE_FLEX = "FLEX"; + + /** + * FLEX Mode - Flex Sysfs value index + */ + public static final int MODE_FLEX_VALUE_INDEX = 0; + + /** + * dFlex Sensor driver name + */ + public static final String DRIVER_NAME = "di-dflex"; + + /** + * Creates a DflexSensor instance. + * @param port The LegoPort instance + * @throws EV3LibraryException If I/O goes wrong + */ + public DflexSensor(LegoPort port) throws EV3LibraryException { + super(port, DRIVER_NAME); + } + + /** + * Flex + * @return an integer from 0-100 + */ + public int getFlex(){ + return Integer.parseInt(this.getAttribute("value" + MODE_FLEX_VALUE_INDEX)); + } + +} diff --git a/src/main/java/org/ev3dev/hardware/sensors/fatcatlab/ADCAdapter.java b/src/main/java/org/ev3dev/hardware/sensors/fatcatlab/ADCAdapter.java new file mode 100644 index 0000000..ca32e5d --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/sensors/fatcatlab/ADCAdapter.java @@ -0,0 +1,122 @@ +package org.ev3dev.hardware.sensors.fatcatlab; + +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.exception.InvalidModeException; +import org.ev3dev.exception.InvalidSensorException; +import org.ev3dev.hardware.ports.LegoPort; +import org.ev3dev.hardware.sensors.Sensor; + +public class ADCAdapter extends Sensor { + + /** + * Channel 1 voltage Mode + */ + public static final String MODE_CH1_VOLTAGE = "CH1-VOLTAGE"; + + /** + * Channel 1 voltage mode Sysfs value index + */ + public static final int INDEX_MODE_CH1_VOLTAGE = 0; + + /** + * Channel 2 voltage Mode + */ + public static final String MODE_CH2_VOLTAGE = "CH2-VOLTAGE"; + + /** + * Channel 2 voltage mode Sysfs value index + */ + public static final int INDEX_MODE_CH2_VOLTAGE = 0; + + /** + * All channels voltage Mode + */ + public static final String MODE_ALL_VOLTAGE = "VOLTAGE"; + + /** + * All channels mode channel 1 voltage Sysfs value index + */ + public static final int INDEX_MODE_ALL_CH1_VOLTAGE = 0; + + /** + * All channels mode channel 2 voltage Sysfs value index + */ + public static final int INDEX_MODE_ALL_CH2_VOLTAGE = 1; + + /** + * The property "valueX" prefix + */ + public static final String PROPERTY_PREFIX = "value"; + + /** + * This device's default driver name + */ + public static final String DRIVER_NAME = "fcl-adc"; + + /** + * Creates a new ADCAdapter instance + * @param port LegoPort + * @throws EV3LibraryException If I/O goes wrong + */ + public ADCAdapter(LegoPort port) throws EV3LibraryException { + super(port); + if(!this.getDriverName().equals(DRIVER_NAME)){ + throw new InvalidSensorException("Can't create a ADCAdapter instance if the port isn't connected to a light sensor!"); + } + } + + /** + * Set the device mode as Channel 1 Voltage Mode + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsCh1() throws EV3LibraryException{ + setMode(MODE_CH1_VOLTAGE); + } + + /** + * Set the device mode as Channel 2 Voltage Mode + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsCh2() throws EV3LibraryException{ + setMode(MODE_CH2_VOLTAGE); + } + + /** + * Set the device mode as All Channels Voltage Mode + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsAllCh() throws EV3LibraryException{ + setMode(MODE_ALL_VOLTAGE); + } + + /** + * Gets the voltage in millivolts from channel 1. The device mode must be CH1-VOLTAGE or VOLTAGE. Otherwise, a InvalidModeException will be thrown. + * @return millivolts in Integer + * @throws EV3LibraryException If the mode is invalid or I/O goes wrong + */ + public int getCh1Volt() throws EV3LibraryException{ + String mode = getAttribute(SYSFS_PROPERTY_MODE); + if (mode.equals(MODE_CH1_VOLTAGE) || mode.equals(MODE_ALL_VOLTAGE)){ + String str = getAttribute(PROPERTY_PREFIX + INDEX_MODE_CH1_VOLTAGE); + return Integer.parseInt(str); + } else { + throw new InvalidModeException("The Channel 1 voltage property cannot be accessed if the mode is not \"" + MODE_CH1_VOLTAGE + "\" or \"" + MODE_ALL_VOLTAGE + "\""); + } + } + + /** + * Gets the voltage in millivolts from channel 2. The device mode must be CH2-VOLTAGE or VOLTAGE. Otherwise, a InvalidModeException will be thrown. + * @return millivolts in Integer + * @throws EV3LibraryException If the mode is invalid or I/O goes wrong + */ + public int getCh2Volt() throws EV3LibraryException{ + String mode = getAttribute(SYSFS_PROPERTY_MODE); + if (mode.equals(MODE_CH2_VOLTAGE) || mode.equals(MODE_ALL_VOLTAGE)){ + String str = getAttribute(PROPERTY_PREFIX + (mode.equals(MODE_ALL_VOLTAGE) ? INDEX_MODE_ALL_CH2_VOLTAGE : INDEX_MODE_CH1_VOLTAGE)); + return Integer.parseInt(str); + } else { + throw new InvalidModeException("The Channel 2 voltage property cannot be accessed if the mode is not \"" + MODE_CH2_VOLTAGE + "\" or \"" + MODE_ALL_VOLTAGE + "\""); + } + } + +} diff --git a/src/main/java/org/ev3dev/hardware/sensors/generic/EV3AnalogSensor.java b/src/main/java/org/ev3dev/hardware/sensors/generic/EV3AnalogSensor.java new file mode 100644 index 0000000..c93248e --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/sensors/generic/EV3AnalogSensor.java @@ -0,0 +1,80 @@ +package org.ev3dev.hardware.sensors.generic; + +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.hardware.ports.LegoPort; +import org.ev3dev.hardware.sensors.Sensor; + +/** + * Generic EV3 Analog Sensor driver + * @author Anthony + * + */ +public class EV3AnalogSensor extends Sensor { + + /** + * ANALOG Mode - Raw analog value + */ + public static final String MODE_ANALOG = "ANALOG"; + + /** + * The Sysfs value index + */ + public static final int VALUE_INDEX = 0; + + /** + * The EV3 Analog sensor driver name + */ + public static final String DRIVER_NAME = "ev3-analog"; + + /** + * Creates a new EV3 analog sensor + * @param port The LegoPort instance + * @param typeId The sensor type ID, see here for more details. + * @throws EV3LibraryException If I/O goes wrong + */ + public EV3AnalogSensor(LegoPort port, String typeId) throws EV3LibraryException{ + super(port); + String drivername = port.getDriverName(); + if (!drivername.equals(DRIVER_NAME + "-" + typeId)){ + throw new EV3LibraryException("The port is not connected to a EV3 analog sensor with type id \"" + typeId + "\": " + drivername); + } + } + + /** + * Set mode as ANALOG Mode - Raw analog value + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAnalog() throws EV3LibraryException{ + setMode(MODE_ANALOG); + } + + /** + * Returns the raw analog voltage / value (0-5000).
+ *
+ * This function does not calculate decimal places. + * @throws EV3LibraryException If I/O goes wrong + * @return The voltage + */ + public int getRawValue() throws EV3LibraryException{ + String str = getAttribute("value" + VALUE_INDEX); + return Integer.parseInt(str); + } + + /** + * Returns the raw analog voltage / value (0-5000), and with decimal places
+ * @throws EV3LibraryException If I/O goes wrong + * @return The voltage + */ + public float getValue() throws EV3LibraryException{ + float out = getRawValue(); + + int dec = getDecimals(); + for (int i = 1; i <= dec; i++){ + out /= 10; + } + + return out; + } + + +} diff --git a/src/main/java/org/ev3dev/hardware/sensors/generic/NXTAnalogSensor.java b/src/main/java/org/ev3dev/hardware/sensors/generic/NXTAnalogSensor.java new file mode 100644 index 0000000..5aaaa7d --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/sensors/generic/NXTAnalogSensor.java @@ -0,0 +1,103 @@ +package org.ev3dev.hardware.sensors.generic; + +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.hardware.ports.LegoPort; +import org.ev3dev.hardware.sensors.Sensor; + +/** + * Generic NXT Analog Sensor driver + * @author Anthony + * + */ +public class NXTAnalogSensor extends Sensor { + + /** + * ANALOG-0 Mode - Raw analog value + */ + public static final String MODE_ANALOG_0 = "ANALOG-0"; + + /** + * ANALOG-1 Mode - Raw analog value, Pin 5 high + */ + public static final String MODE_ANALOG_1 = "ANALOG-1"; + + /** + * The Sysfs value index + */ + public static final int VALUE_INDEX = 0; + + /** + * The NXT Analog sensor driver name + */ + public static final String DRIVER_NAME = "nxt-analog"; + + /** + * Creates a new NXT analog sensor. + * @param port The LegoPort instance + * @throws EV3LibraryException If I/O goes wrong + */ + public NXTAnalogSensor(LegoPort port) throws EV3LibraryException{ + this(port, DRIVER_NAME); + } + + /** + * Creates a new NXT analog sensor, and an alternative driver name can be specified. + * @param port The LegoPort instance + * @param target_driver_name The target driver name to be checked. + * @throws EV3LibraryException If I/O goes wrong + */ + public NXTAnalogSensor(LegoPort port, String target_driver_name) throws EV3LibraryException{ + super(port); + String drivername = port.getDriverName(); + if (!drivername.equals(target_driver_name)){ + throw new EV3LibraryException("The port is not connected to a NXT analog sensor: " + drivername); + } + } + + /** + * Set mode as ANALOG-0 Mode - Raw analog value + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAnalog0() throws EV3LibraryException{ + setMode(MODE_ANALOG_0); + } + + /** + * Set mode as ANALOG-1 Mode - Raw analog value, Pin 5 high + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAnalog1() throws EV3LibraryException{ + setMode(MODE_ANALOG_1); + } + + /** + * Returns the raw analog voltage / value (0-5000).
+ * Both mode uses the same value index (value0)
+ *
+ * This function does not calculate decimal places. + * @throws EV3LibraryException If I/O goes wrong + * @return The voltage + */ + public int getRawValue() throws EV3LibraryException{ + String str = getAttribute("value" + VALUE_INDEX); + return Integer.parseInt(str); + } + + /** + * Returns the raw analog voltage / value (0-5000), and with decimal places
+ * Both mode uses the same value index (value0)
+ * @throws EV3LibraryException If I/O goes wrong + * @return The voltage + */ + public float getValue() throws EV3LibraryException{ + float out = getRawValue(); + + int dec = getDecimals(); + for (int i = 1; i <= dec; i++){ + out /= 10; + } + + return out; + } + +} diff --git a/src/main/java/org/ev3dev/hardware/sensors/hitechnic/HTNXTColorSensor.java b/src/main/java/org/ev3dev/hardware/sensors/hitechnic/HTNXTColorSensor.java new file mode 100644 index 0000000..832f475 --- /dev/null +++ b/src/main/java/org/ev3dev/hardware/sensors/hitechnic/HTNXTColorSensor.java @@ -0,0 +1,226 @@ +package org.ev3dev.hardware.sensors.hitechnic; + +import org.ev3dev.exception.EV3LibraryException; +import org.ev3dev.exception.InvalidPortException; +import org.ev3dev.exception.InvalidSensorException; +import org.ev3dev.hardware.ports.LegoPort; +import org.ev3dev.hardware.sensors.I2CSensor; + +public class HTNXTColorSensor extends I2CSensor { + + /** + * HiTechnic NXT Color sensor + */ + public static final String DRIVER_NAME = "ht-nxt-color"; + + /** + * The vendor id of this sensor + */ + public static final String VENDOR_ID = "HiTechnic"; + + /** + * The product id of this sensor + */ + public static final String PRODUCT_ID = "Color"; + + /** + * Mode "Color" + */ + public static final String MODE_COLOR = "COLOR"; + + /** + * Mode "Red component" + */ + public static final String MODE_RED = "RED"; + + /** + * Mode "Green component" + */ + public static final String MODE_GREEN = "GREEN"; + + /** + * Mode "Blue component" + */ + public static final String MODE_BLUE = "BLUE"; + + /** + * Mode "Raw values" + */ + public static final String MODE_RAW = "RAW"; + + /** + * Mode "Normalized values" + */ + public static final String MODE_NORM = "NORM"; + + /** + * Mode "All values" + */ + public static final String MODE_ALL = "ALL"; + + /** + * Color (0 to 17) Sysfs value index of mode "Color" + */ + public static final int INDEX_MODE_COLOR_COLOR = 0; + + /** + * Reflected light intensity (0 to 255) Sysfs value index of mode "Red","Green","Blue" + */ + public static final int INDEX_REFLECTED = 0; + + /** + * Red component color value (0 to 255) Sysfs value index of mode "Raw","Normalized values" + */ + public static final int INDEX_RED_COMP = 0; + + /** + * Green component color value (0 to 255) Sysfs value index of mode "Raw","Normalized values" + */ + public static final int INDEX_GREEN_COMP = 1; + + /** + * Blue component color value (0 to 255) Sysfs value index of mode "Raw","Normalized values" + */ + public static final int INDEX_BLUE_COMP = 2; + + /** + * ??? (Unknown) component color value (0 to 255) Sysfs value index of mode "Normalized values" + */ + public static final int INDEX_MODE_NORM_UNKNOWN = 3; + + /** + * Color value (0 to 17) Sysfs value index of mode "All" + */ + public static final int INDEX_MODE_ALL_COLOR = 0; + + /** + * Red component color value (0 to 255) Sysfs value index of mode "All" + */ + public static final int INDEX_MODE_ALL_RED = 1; + + /** + * Green component color value (0 to 255) Sysfs value index of mode "All" + */ + public static final int INDEX_MODE_ALL_GREEN = 2; + + /** + * Blue component color value (0 to 255) Sysfs value index of mode "All" + */ + public static final int INDEX_MODE_ALL_BLUE = 3; + + /** + * The attribute prefix before the value index + */ + public static final String VALUE_PREFIX = "value"; + + /** + * I2C Address + */ + public static final byte address = 0x01; + + /** + * Creates a HTNXTColorSensor instance. + * @param port The LegoPort instance + * @throws EV3LibraryException If I/O goes wrong + */ + public HTNXTColorSensor(LegoPort port) throws EV3LibraryException { + super(port, DRIVER_NAME); + } + + /** + * Set mode as mode "Color" + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsColor() throws EV3LibraryException { + setMode(MODE_COLOR); + } + + /** + * Set mode as mode "Red" + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsRed() throws EV3LibraryException { + setMode(MODE_RED); + } + + /** + * Set mode as mode "Green" + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsGreen() throws EV3LibraryException{ + setMode(MODE_GREEN); + } + + /** + * Set mode as mode "Blue" + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsBlue() throws EV3LibraryException{ + setMode(MODE_BLUE); + } + + /** + * Set mode as mode "Raw" + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsRaw() throws EV3LibraryException{ + setMode(MODE_RAW); + } + + /** + * Set mode as mode "Normalized values" + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsNorm() throws EV3LibraryException{ + setMode(MODE_NORM); + } + + /** + * Set mode as mode "All" + * @throws EV3LibraryException If I/O goes wrong + */ + public void setModeAsAll() throws EV3LibraryException{ + setMode(MODE_ALL); + } + + /** + * This function requires mode COLOR or ALL.
+ *
+ * Get the color value from 0 to 17. Color values chart can be found at http://www.ev3dev.org/docs/sensors/hitechnic-nxt-color-sensor/ + * @return a integer from 0 to 17 + */ + public int getColor(){ + String str = getAttribute(VALUE_PREFIX + INDEX_MODE_COLOR_COLOR); + return Integer.parseInt(str); + } + + /** + * This function requires mode RED, GREEN or BLUE.
+ *
+ * Get the reflected color intensity. + * @return a integer from 0 to 255 + */ + public int getReflectedLightIntensity(){ + String str = getAttribute(VALUE_PREFIX + INDEX_REFLECTED); + return Integer.parseInt(str); + } + + /** + * This function requires mode RAW, NORM or ALL.
+ *
+ * Get the red component + * @return + */ + public int getRedComponent(){ + String mode = getMode(); + String str; + if (mode.equals(MODE_ALL)){ + str = getAttribute(VALUE_PREFIX + INDEX_MODE_ALL_RED); + } else if (mode.equals(MODE_RAW) || mode.equals(MODE_NORM)){ + str = getAttribute(VALUE_PREFIX + INDEX_RED_COMP); + } else { + throw new EV3LibraryException("The function does not support with the current mode: " + mode); + } + return Integer.parseInt(str); + } +} diff --git a/src/main/java/org/ev3dev/io/Def.java b/src/main/java/org/ev3dev/io/Def.java deleted file mode 100644 index bb76c4f..0000000 --- a/src/main/java/org/ev3dev/io/Def.java +++ /dev/null @@ -1,306 +0,0 @@ -package org.ev3dev.io; - -/** - * Application-specified System Defaults - * @author Anthony - * - */ -public class Def { - - //System class path - - public static final String SYSTEM_CLASS_PATH = "/sys/class/"; - - //Class names - - public static final String MOTOR_CLASS_NAME = "tacho-motor"; - - public static final String DC_MOTOR_CLASS_NAME = "dc-motor"; - - public static final String SERVO_MOTOR_CLASS_NAME = "servo-motor"; - - public static final String LED_CLASS_NAME = "leds"; - - public static final String SENSOR_CLASS_NAME = "lego-sensor"; - - public static final String SUB_SENSOR_CLASS_NAME = "sensor"; - - public static final String SUB_MOTOR_CLASS_NAME = "motor"; - - public static final String SUB_LINEAR_CLASS_NAME = "linear"; - - public static final String POWER_SUPPLY_CLASS_NAME = "power_supply"; - - //Driver names - - public static final String MEDIUM_MOTOR_DRIVER_NAME = "lego-ev3-m-motor"; - - public static final String LARGE_MOTOR_DRIVER_NAME = "lego-ev3-l-motor"; - - public static final String I2CSENSOR_DRIVER_NAME = "nxt-i2c-sensor"; - - public static final String TOUCH_SENSOR_DRIVER_NAME_EV3 = "lego-ev3-touch"; - - public static final String TOUCH_SENSOR_DRIVER_NAME_NXT = "lego-nxt-touch"; - - public static final String COLOR_SENSOR_DRIVER_NAME = "lego-ev3-color"; - - public static final String ULTRASONIC_SENSOR_DRIVER_NAME_EV3 = "lego-ev3-us"; - - public static final String ULTRASONIC_SENSOR_DRIVER_NAME_NXT = "lego-nxt-us"; - - public static final String GYRO_SENSOR_DRIVER_NAME = "lego-ev3-gyro"; - - public static final String INFRARED_SENSOR_DRIVER_NAME = "lego-ev3-ir"; - - public static final String SOUND_SENSOR_DRIVER_NAME = "lego-nxt-sound"; - - public static final String LIGHT_SENSOR_DRIVER_NAME = "lego-nxt-light"; - - //Properties defaults - - public static final String PROPERTY_ADDRESS = "address"; - - public static final String PROPERTY_COMMAND = "command"; - - public static final String PROPERTY_COMMANDS = "commands"; - - public static final String PROPERTY_COUNT_PER_ROT = "count_per_rot"; - - public static final String PROPERTY_DRIVER_NAME = "driver_name"; - - public static final String PROPERTY_DUTY_CYCLE = "duty_cycle"; - - public static final String PROPERTY_DUTY_CYCLE_SP = "duty_cycle_sp"; - - public static final String PROPERTY_POLARITY = "polarity"; - - public static final String PROPERTY_POSITION = "position"; - - public static final String PROPERTY_POSITION_P = "hold_pid/Kp"; - - public static final String PROPERTY_POSITION_I = "hold_pid/Ki"; - - public static final String PROPERTY_POSITION_D = "hold_pid/Kd"; - - public static final String PROPERTY_POSITION_SP = "position_sp"; - - public static final String PROPERTY_SPEED = "speed"; - - public static final String PROPERTY_SPEED_SP = "speed_sp"; - - public static final String PROPERTY_RAMP_UP_SP = "ramp_up_sp"; - - public static final String PROPERTY_RAMP_DOWN_SP = "ramp_down_sp"; - - public static final String PROPERTY_SPEED_REGULATION_ENABLED = "speed_regulation_enabled"; - - public static final String PROPERTY_SPEED_REGULATION_P = "speed_pid/Kp"; - - public static final String PROPERTY_SPEED_REGULATION_I = "speed_pid/Ki"; - - public static final String PROPERTY_SPEED_REGULATION_D = "speed_pid/Kd"; - - public static final String PROPERTY_STATE = "state"; - - public static final String PROPERTY_STOP_ACTION = "stop_action"; - - public static final String PROPERTY_STOP_ACTIONS = "stop_actions"; - - public static final String PROPERTY_TIME_SP = "time_sp"; - - public static final String PROPERTY_MAX_PULSE_SP = "max_pulse_sp"; - - public static final String PROPERTY_MID_PULSE_SP = "mid_pulse_sp"; - - public static final String PROPERTY_MIN_PULSE_SP = "min_pulse_sp"; - - public static final String PROPERTY_RATE_SP = "rate_sp"; - - public static final String PROPERTY_MAX_SPEED = "max_speed"; - - public static final String PROPERTY_COUNT_PER_M = "count_per_m"; - - public static final String PROPERTY_FULL_TRAVEL_COUNT = "full_travel_count"; - - //LED Properties defaults - - public static final String PROPERTY_MAX_BRIGHTNESS = "max_brightness"; - - public static final String PROPERTY_BRIGHTNESS = "brightness"; - - public static final String PROPERTY_TRIGGER = "trigger"; - - public static final String PROPERTY_DELAY_ON = "delay_on"; - - public static final String PROPERTY_DELAY_OFF = "delay_off"; - - //Sensor Properties defaults - - public static final String PROPERTY_DECIMALS = "decimals"; - - public static final String PROPERTY_MODE = "mode"; - - public static final String PROPERTY_MODES = "modes"; - - public static final String PROPERTY_NUM_VALUES = "num_values"; - - public static final String PROPERTY_UNITS = "units"; - - //I2C Sensor properties - - public static final String PROPERTY_FIRMWARE_VERSION = "fw_version"; - - public static final String PROPERTY_POLL_MS = "poll_ms"; - - //Touch Sensor properties - - public static final String PROPERTY_TOUCH_REQUIRED_MODE = "TOUCH"; - - public static final int PROPERTY_TOUCH_VALUE_INDEX = 0; - - //Color Sensor properties - - public static final String PROPERTY_COLOR_SENSOR_REFLECTED_LIGHT_INTENSITY = "reflected_light_intensity"; - - public static final String PROPERTY_COLOR_SENSOR_REFLECTED_LIGHT_INTENSITY_REQUIRED_MODE = "COL-REFLECT"; - - public static final int PROPERTY_COLOR_SENSOR_REFLECTED_LIGHT_INTENSITY_VALUE_INDEX = 0; - - public static final String PROPERTY_COLOR_SENSOR_AMBIENT_LIGHT_INTENSITY = "ambient_light_intensity"; - - public static final String PROPERTY_COLOR_SENSOR_AMBIENT_LIGHT_INTENSITY_REQUIRED_MODE = "COL-AMBIENT"; - - public static final int PROPERTY_COLOR_SENSOR_AMBIENT_LIGHT_INTENSITY_VALUE_INDEX = 0; - - public static final String PROPERTY_COLOR_SENSOR_COLOR = "color"; - - public static final String PROPERTY_COLOR_SENSOR_COLOR_REQUIRED_MODE = "COL-COLOR"; - - public static final int PROPERTY_COLOR_SENSOR_COLOR_VALUE_INDEX = 0; - - public static final String PROPERTY_COLOR_SENSOR_RGB_R = "red"; - - public static final String PROPERTY_COLOR_SENSOR_RGB_R_REQUIRED_MODE = "RGB-RAW"; - - public static final int PROPERTY_COLOR_SENSOR_RGB_R_VALUE_INDEX = 0; - - public static final String PROPERTY_COLOR_SENSOR_RGB_G = "green"; - - public static final String PROPERTY_COLOR_SENSOR_RGB_G_REQUIRED_MODE = "RGB-RAW"; - - public static final int PROPERTY_COLOR_SENSOR_RGB_G_VALUE_INDEX = 1; - - public static final String PROPERTY_COLOR_SENSOR_RGB_B = "blue"; - - public static final String PROPERTY_COLOR_SENSOR_RGB_B_REQUIRED_MODE = "RGB-RAW"; - - public static final int PROPERTY_COLOR_SENSOR_RGB_B_VALUE_INDEX = 2; - - //Ultrasonic sensor properties - - public static final String PROPERTY_ULTRASONIC_SENSOR_CM = "distance_centimeters"; - - public static final String PROPERTY_ULTRASONIC_SENSOR_CM_REQUIRED_MODE = "US-DIST-CM"; - - public static final int PROPERTY_ULTRASONIC_SENSOR_CM_VALUE_INDEX = 0; - - public static final String PROPERTY_ULTRASONIC_SENSOR_IN = "distance_inches"; - - public static final String PROPERTY_ULTRASONIC_SENSOR_IN_REQUIRED_MODE = "US-DIST-IN"; - - public static final int PROPERTY_ULTRASONIC_SENSOR_IN_VALUE_INDEX = 0; - - public static final String PROPERTY_ULTRASONIC_SENSOR_OTHER_PRESENT = "other_sensor_present"; - - public static final String PROPERTY_ULTRASONIC_SENSOR_OTHER_PRESENT_REQUIRED_MODE = "US-LISTEN"; - - public static final int PROPERTY_ULTRASONIC_SENSOR_OTHER_PRESENT_VALUE_INDEX = 0; - - //Gyro sensor properties - - public static final String PROPERTY_GYRO_SENSOR_ANGLE_REQUIRED_MODE = "GYRO-ANG"; - - public static final int PROPERTY_GYRO_SENSOR_ANGLE_VALUE_INDEX = 0; - - public static final String PROPERTY_GYRO_SENSOR_RATE_REQUIRED_MODE = "GYRO-RATE"; - - public static final int PROPERTY_GYRO_SENSOR_RATE_VALUE_INDEX = 0; - - //Infrared Sensor properties - - public static final String PROPERTY_INFRARED_SENSOR_PROXIMITY_REQUIRED_MODE = "IR-PROX"; - - public static final int PROPERTY_INFRARED_SENSOR_PROXIMITY_VALUE_INDEX = 0; - - //Sound Sensor properties - - public static final String PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_REQUIRED_MODE = "DB"; - - public static final int PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_VALUE_INDEX = 0; - - public static final String PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_LOW_REQUIRED_MODE = "DBA"; - - public static final int PROPERTY_SOUND_SENSOR_SOUND_PRESSURE_LOW_VALUE_INDEX = 0; - - //Light Sensor properties - - public static final String PROPERTY_LIGHT_SENSOR_REFLECTED_REQUIRED_MODE = "REFLECT"; - - public static final int PROPERTY_LIGHT_SENSOR_REFLECTED_VALUE_INDEX = 0; - - public static final String PROPERTY_LIGHT_SENSOR_AMBIENT_REQUIRED_MODE = "AMBIENT"; - - public static final int PROPERTY_LIGHT_SENSOR_AMBIENT_VALUE_INDEX = 0; - - //Power supply properties - - public static final String PROPERTY_MEASURED_CURRENT = "measured_current"; - - public static final String PROPERTY_MEASURED_VOLTAGE = "measured_voltage"; - - public static final String PROPERTY_MAX_VOLTAGE = "max_voltage"; - - public static final String PROPERTY_MIN_VOLTAGE = "min_voltage"; - - public static final String PROPERTY_TECHNOLOGY = "technology"; - - public static final String PROPERTY_TYPE = "type"; - - //Buttons properties - - public static final String PROPERTY_EV3_BUTTON_SYSTEM_EVENT_PATH = "/dev/input/by-path/platform-gpio-keys.0-event"; - - public static final int PROPERTY_EV3_BUTTON_UP = 103; - - public static final int PROPERTY_EV3_BUTTON_DOWN = 108; - - public static final int PROPERTY_EV3_BUTTON_LEFT = 105; - - public static final int PROPERTY_EV3_BUTTON_RIGHT = 106; - - public static final int PROPERTY_EV3_BUTTON_ENTER = 28; - - public static final int PROPERTY_EV3_BUTTON_BACKSPACE = 14; - - //Commands defaults - - public static final String COMMAND_RUN_FOREVER = "run-forever"; - - public static final String COMMAND_RUN_TO_ABS_POS = "run-to-abs-pos"; - - public static final String COMMAND_RUN_TO_REL_POS = "run-to-rel-pos"; - - public static final String COMMAND_RUN_TIMED = "run-timed"; - - public static final String COMMAND_RUN_DIRECT = "run-direct"; - - public static final String COMMAND_STOP = "stop"; - - public static final String COMMAND_RESET = "reset"; - - public static final String COMMAND_RUN = "run"; - - public static final String COMMAND_FLOAT = "float"; - -} diff --git a/src/main/java/org/ev3dev/io/Sysclass.java b/src/main/java/org/ev3dev/io/Sysfs.java similarity index 72% rename from src/main/java/org/ev3dev/io/Sysclass.java rename to src/main/java/org/ev3dev/io/Sysfs.java index 24671ca..90bc93f 100644 --- a/src/main/java/org/ev3dev/io/Sysclass.java +++ b/src/main/java/org/ev3dev/io/Sysfs.java @@ -7,7 +7,6 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; -import java.security.AccessControlException; import java.util.ArrayList; import java.util.List; @@ -16,7 +15,14 @@ * @author Anthony * */ -public class Sysclass { +public class Sysfs { + + /** + * The default ev3dev Sysfs class path (/sys/class/) + */ + public static final String DEFAULT_SYSTEM_CLASS_PATH = "/sys/class/"; + + private static String SYSTEM_CLASS_PATH = DEFAULT_SYSTEM_CLASS_PATH; /** * Get all sub-class files @@ -24,11 +30,34 @@ public class Sysclass { * @return File Array */ public static File[] getAllSubClass(String class_name){ - File file = new File(Def.SYSTEM_CLASS_PATH + class_name); + File file = new File(SYSTEM_CLASS_PATH + class_name); File[] files = file.listFiles(); return files; } + /** + * Returns the current ev3dev Sysfs path. + * @return the current Sysfs path + */ + public static String getSysfsPath(){ + return SYSTEM_CLASS_PATH; + } + + /** + * Modify the current ev3dev Sysfs path in this library instance to be used. This is probably used for debugging purpose. Any invalid modification to the path will break the library. + * @param path The file-system path to be used + */ + public static void setSysfsPath(String path){ + SYSTEM_CLASS_PATH = path; + } + + /** + * Sets the current ev3dev Sysfs path to default + */ + public static void resetSysfsPath(){ + SYSTEM_CLASS_PATH = DEFAULT_SYSTEM_CLASS_PATH; + } + /*** * Reads the property of the class specified. * @param class_name The class name @@ -38,7 +67,7 @@ public static File[] getAllSubClass(String class_name){ * @throws IOException If the API couldn't read the class's property */ public static String getAttribute(String class_name, String property) throws FileNotFoundException, IOException{ - File file = new File(Def.SYSTEM_CLASS_PATH + class_name + "/" + property); + File file = new File(SYSTEM_CLASS_PATH + class_name + "/" + property); class_name = class_name.toLowerCase(); property = property.toLowerCase(); FileInputStream in = new FileInputStream(file); @@ -100,10 +129,7 @@ public static void setAttribute(String class_name, String subclass, String prope * @throws IOException If the API couldn't read the class's property */ public static void setAttribute(String class_name, String property, String new_value) throws FileNotFoundException, IOException{ - PrintWriter out = new PrintWriter(Def.SYSTEM_CLASS_PATH + class_name + "/" + property); - class_name = class_name.toLowerCase(); - property = property.toLowerCase(); - new_value = new_value.toLowerCase(); + PrintWriter out = new PrintWriter(SYSTEM_CLASS_PATH + class_name + "/" + property); out.write(new_value); out.flush(); out.close(); @@ -166,14 +192,14 @@ private static String readFile(File file) throws IOException{ } /** - * Get the hardware name, using a class name, sub-class name and a address - * @param classname A Main Class Name (e.g. lego-port, tacho-motor) - * @param subclassname A Sub-Class Name, without the value [N] (e.g. motor, sensor) - * @param address Address (e.g. outA, in1) - * @return A hardware name that with equal address, if none, returns null + * Search the full class name, using a class name, FS folder prefix and an address + * @param classname The class Name (e.g. lego-port, tacho-motor) + * @param fsFolderPrefix The FS folder prefix, without the value [N] (e.g. motor, sensor) + * @param address Port address (e.g. outA, in1) + * @return The full FS class folder name, with the same port address, if none, returns null */ - public static String getHardwareName(String classname, String subclassname, String address){ - File[] sub = Sysclass.getAllSubClass(classname); + public static String searchClassFullName(String classname, String fsFolderPrefix, String address){ + File[] sub = Sysfs.getAllSubClass(classname); File file; String data; for (File asub : sub){