diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index acf2d376..f990ee85 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -9,7 +9,7 @@ EV3Dev-lang-java contributors (sorted alphabetically) * **[Aswin Bouwmeester](https://nxttime.wordpress.com/)** * LeJOS sensor framework - * LeJOS navigation stack + * LeJOS navigation stack * **[Andy Shaw](http://www.gloomy-place.com/legoindex.htm)** @@ -19,6 +19,11 @@ EV3Dev-lang-java contributors (sorted alphabetically) * LeJOS navigation stack +* **[Cameron Whyte](https://cameronwhyte.me)** + + * Debian Buster Support + * OpenJDK 17 for EV3Dev + * **[David Lechner](https://github.com/dlech)** * Main developer of EV3Dev @@ -43,14 +48,14 @@ EV3Dev-lang-java contributors (sorted alphabetically) * **[Lawrie Griffiths](https://github.com/lawrie)** - * LeJOS navigation stack - + * LeJOS navigation stack + * **[Peter Abeles](https://github.com/lessthanoptimal)** - * Initial RPLidar support + * Initial RPLidar support * **[Roger Glassey](http://ieor.berkeley.edu/people/faculty/glassey)** * LeJOS navigation stack -**[Full contributors list](https://github.com/ev3dev-lang-java/ev3dev-lang-java/graphs/contributors).** \ No newline at end of file +**[Full contributors list](https://github.com/ev3dev-lang-java/ev3dev-lang-java/graphs/contributors).** diff --git a/build.gradle b/build.gradle index 1c3ba8d6..357dc449 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,6 @@ plugins { version = '2.7.0-SNAPSHOT' repositories { - jcenter() mavenCentral() maven { url "https://jitpack.io" } } @@ -84,7 +83,7 @@ test.testLogging { //Coverage jacoco { toolVersion = "0.8.2" - reportsDir = file("$buildDir/customJacocoReportDir") + reportsDirectory = file("$buildDir/customJacocoReportDir") } jacocoTestReport { @@ -118,7 +117,7 @@ test.finalizedBy jacocoTestCoverageVerification //Jar jar { - baseName = "${rootProject.name}" + archiveBaseName = "${rootProject.name}" manifest { from file("${projectDir}/src/main/resources/META-INF/MANIFEST.MF") } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf0..e708b1c0 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a6113dcf..92f06b50 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Mon Dec 02 19:24:34 CET 2019 -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index b0d092c7..4f906e0c 100755 --- a/gradlew +++ b/gradlew @@ -44,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -82,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -129,6 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -154,19 +156,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -175,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 805a1b97..ac1b06f9 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -29,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="" +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -51,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -61,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/main/java/ev3dev/actuators/LCD.java b/src/main/java/ev3dev/actuators/LCD.java index 53f127ba..b8f46459 100644 --- a/src/main/java/ev3dev/actuators/LCD.java +++ b/src/main/java/ev3dev/actuators/LCD.java @@ -1,10 +1,10 @@ package ev3dev.actuators; -import ev3dev.hardware.EV3DevDistro; +import ev3dev.hardware.EV3DevDevice; import ev3dev.hardware.EV3DevDistros; import lejos.hardware.lcd.GraphicsLCD; -public class LCD { +public abstract class LCD extends EV3DevDevice implements GraphicsLCD { /** * Factory @@ -12,13 +12,14 @@ public class LCD { * @return GraphicsLCD */ public static GraphicsLCD getInstance() { - - if (EV3DevDistros.getInstance().getDistro().equals(EV3DevDistro.STRETCH)) { - return LCDStretch.getInstance(); - } else { - return LCDJessie.getInstance(); + switch (EV3DevDistros.getInstance().getDistro()) { + case BUSTER: + return LCDBuster.getInstance(); + case STRETCH: + return LCDStretch.getInstance(); + default: + return LCDJessie.getInstance(); } - } } diff --git a/src/main/java/ev3dev/actuators/LCDBuster.java b/src/main/java/ev3dev/actuators/LCDBuster.java new file mode 100644 index 00000000..3beff172 --- /dev/null +++ b/src/main/java/ev3dev/actuators/LCDBuster.java @@ -0,0 +1,567 @@ +package ev3dev.actuators; + +import ev3dev.hardware.EV3DevDevice; +import ev3dev.hardware.EV3DevPlatform; +import ev3dev.hardware.display.ImageUtils; +import ev3dev.hardware.display.JavaFramebuffer; +import ev3dev.hardware.display.SystemDisplay; +import lejos.hardware.lcd.GraphicsLCD; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferByte; +import java.awt.image.WritableRaster; +import java.util.Timer; +import java.util.TimerTask; + +/** + * Lejos LCD reimplementation using Java2D API + */ +public class LCDBuster extends LCD { + + // custom config + public static final String EV3DEV_LCD_KEY = "EV3DEV_LCD_KEY"; + public static final String EV3DEV_LCD_DEFAULT = "/dev/fb0"; + public static final String EV3DEV_LCD_MODE_KEY = "EV3DEV_LCD_MODE_KEY"; + + // logger + private static final Logger log = LoggerFactory.getLogger(LCDBuster.class); + private static LCDBuster instance; + // drawable + private final JavaFramebuffer fb; + private final BufferedImage image; + private final Graphics2D g2d; + // autorefresh + private final Timer timer; + private boolean timer_run = false; + private int timer_msec = 0; + // stroke + private int stroke; + + // Prevent duplicate objects + private LCDBuster() { + + log.info("Instancing LCD for Buster"); + + if (!CURRENT_PLATFORM.equals(EV3DevPlatform.EV3BRICK)) { + log.error("This actuator was only tested for: {}", EV3DevPlatform.EV3BRICK); + throw new RuntimeException("This actuator was only tested for: " + EV3DevPlatform.EV3BRICK); + } + + this.fb = SystemDisplay.initializeRealFramebuffer(); + this.timer = new Timer("LCD flusher", true); + this.image = fb.createCompatibleBuffer(); + this.g2d = this.image.createGraphics(); + this.clear(); + } + + /** + * Singleton constructor + * + * @return GraphicsLCD + */ + public static GraphicsLCD getInstance() { + //TODO Refactor + if (instance == null) { + instance = new LCDBuster(); + } + return instance; + } + + public JavaFramebuffer getFramebuffer() { + return fb; + } + + //Graphics LCD + + /** + * Write LCD with current context + */ + public void flush() { + if (log.isTraceEnabled()) { + log.trace("flushing framebuffer"); + } + + fb.flushScreen(image); + } + + @Override + public void translate(int x, int y) { + g2d.translate(x, y); + } + + @Override + public Font getFont() { + return g2d.getFont(); + } + + @Override + public void setFont(Font font) { + g2d.setFont(font); + } + + @Override + public int getTranslateX() { + return (int) g2d.getTransform().getTranslateX(); + } + + @Override + public int getTranslateY() { + return (int) g2d.getTransform().getTranslateY(); + } + + /** + * Set RGB value + * + * @param rgb rgb + */ + @Override + public void setColor(int rgb) { + g2d.setColor(new Color(rgb)); + } + + @Override + public void setColor(int r, int g, int b) { + g2d.setColor(new Color(r, g, b)); + } + + @Override + public void setPixel(int x, int y, int color) { + Point2D.Float in = new Point2D.Float(x, y); + Point2D.Float dst = new Point2D.Float(); + g2d.getTransform().transform(in, dst); + + Color fill = color == 0 ? Color.WHITE : Color.BLACK; + + image.setRGB((int) dst.x, (int) dst.y, fill.getRGB()); + } + + @Override + public int getPixel(int x, int y) { + Point2D.Float in = new Point2D.Float(x, y); + Point2D.Float dst = new Point2D.Float(); + g2d.getTransform().transform(in, dst); + + int rgb = image.getRGB((int) dst.x, (int) dst.y); + if ((rgb & 0x00FFFFFF) == 0x00FFFFFF) { + return 0; + } else { + return 1; + } + } + + @Override + public void drawString(String str, int x, int y, int anchor, boolean inverted) { + Color oldFg = g2d.getColor(); + Color oldBg = g2d.getBackground(); + g2d.setColor(inverted ? Color.WHITE : Color.BLACK); + g2d.setBackground(inverted ? Color.BLACK : Color.WHITE); + + drawString(str, x, y, anchor); + + g2d.setColor(oldFg); + g2d.setBackground(oldBg); + } + + @Override + public void drawString(String str, int x, int y, int anchor) { + FontMetrics metrics = g2d.getFontMetrics(); + int w = metrics.stringWidth(str); + int h = metrics.getHeight(); + x = adjustX(x, w, anchor); + y = adjustY(y, h, anchor); + + g2d.drawString(str, x, y); + } + + @Override + public void drawSubstring(String str, int offset, int len, + int x, int y, int anchor) { + String sub = str.substring(offset, offset + len); + drawString(sub, x, y, anchor); + } + + @Override + public void drawChar(char character, int x, int y, int anchor) { + String str = String.valueOf(character); + drawString(str, x, y, anchor); + } + + @Override + public void drawChars(char[] data, int offset, int length, + int x, int y, int anchor) { + String str = new String(data); + drawString(str, x, y, anchor); + } + + @Override + public int getStrokeStyle() { + return this.stroke; + } + + @Override + public void setStrokeStyle(int i) { + this.stroke = i; + Stroke stroke; + if (i == DOTTED) { + float[] dash = new float[]{3.0f, 3.0f}; + float dash_phase = 0.0f; + stroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0.0f, dash, dash_phase); + } else if (i == SOLID) { + stroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0.0f); + } else { + throw new IllegalArgumentException("Invalid stroke"); + } + g2d.setStroke(stroke); + } + + @Deprecated + @Override + public void drawRegionRop(Image src, int sx, int sy, int w, int h, int x, int y, int anchor, int rop) { + drawRegionRop(src, sx, sy, w, h, x, y, TRANS_NONE, anchor, rop); + } + + @Deprecated + @Override + public void drawRegionRop( + Image src, int sx, int sy, int w, int h, int transform, int x, int y, int anchor, int rop) { + x = adjustX(x, w, anchor); + y = adjustY(y, h, anchor); + BufferedImage srcI = any2rgb(src); + + double midx = srcI.getWidth() / 2.0; + double midy = srcI.getHeight() / 2.0; + AffineTransform tf = new AffineTransform(); + tf.translate(midx, midy); + int h0 = h; + switch (transform) { + case TRANS_MIRROR: + tf.scale(-1.0, 1.0); + break; + case TRANS_MIRROR_ROT90: + tf.scale(-1.0, 1.0); + tf.quadrantRotate(1); + h = w; + w = h0; + break; + case TRANS_MIRROR_ROT180: + tf.scale(-1.0, 1.0); + tf.quadrantRotate(2); + break; + case TRANS_MIRROR_ROT270: + tf.scale(-1.0, 1.0); + tf.quadrantRotate(3); + h = w; + w = h0; + break; + case TRANS_NONE: + break; + case TRANS_ROT90: + tf.quadrantRotate(1); + h = w; + w = h0; + break; + case TRANS_ROT180: + tf.quadrantRotate(2); + break; + case TRANS_ROT270: + tf.quadrantRotate(3); + h = w; + w = h0; + break; + default: + throw new RuntimeException("Bad Option"); + } + tf.translate(-midx, -midy); + AffineTransformOp op = new AffineTransformOp(tf, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); + BufferedImage transformed = ImageUtils.createXRGBImage(w, h); + transformed = op.filter(srcI, transformed); + + BufferedImage dstI = any2rgb(image); + bitBlt(srcI, sx, sy, dstI, x, y, w, h, rop); + g2d.drawImage(dstI, 0, 0, null); + } + + @Deprecated + @Override + public void drawRegion(Image src, + int sx, int sy, + int w, int h, + int transform, + int x, int y, + int anchor) { + drawRegionRop(src, sx, sy, w, h, transform, x, y, anchor, ROP_COPY); + } + + @Override + public void drawImage(Image image, int i, int i1, int i2) { + g2d.drawImage(image, i, i1, null); + } + + @Override + public void drawLine(int x1, int y1, int x2, int y2) { + g2d.drawLine(x1, y1, x2, y2); + } + + @Override + public void fillRect(int x, int y, int width, int height) { + g2d.fillRect(x, y, width, height); + } + + @Override + public void copyArea(int sx, int sy, + int w, int h, + int x, int y, int anchor) { + x = adjustX(x, w, anchor); + y = adjustY(y, h, anchor); + g2d.copyArea(sx, sy, w, h, x, y); + } + + /** + * Adjust the x co-ordinate to use the translation and anchor values. + */ + private int adjustX(int x, int w, int anchor) { + switch (anchor & (LEFT | RIGHT | HCENTER)) { + case LEFT: + break; + case RIGHT: + x -= w; + break; + case HCENTER: + x -= w / 2; + break; + default: + throw new RuntimeException("Bad Option"); + } + return x; + } + + /** + * Adjust the y co-ordinate to use the translation and anchor values. + */ + private int adjustY(int y, int h, int anchor) { + switch (anchor & (TOP | BOTTOM | VCENTER)) { + case TOP: + break; + case BOTTOM: + y -= h; + break; + case VCENTER: + y -= h / 2; + break; + default: + throw new RuntimeException("Bad Option"); + } + return y; + } + + @Override + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + g2d.drawRoundRect(x, y, width, height, arcWidth, arcHeight); + } + + // CommonLCD + + @Override + public void drawRect(int x, int y, int width, int height) { + g2d.drawRect(x, y, width, height); + } + + @Override + public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + g2d.drawArc(x, y, width, height, startAngle, arcAngle); + } + + @Override + public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { + g2d.fillArc(x, y, width, height, startAngle, arcAngle); + } + + @Override + public void refresh() { + flush(); + } + + @Override + public void clear() { + AffineTransform tf = (AffineTransform) g2d.getTransform().clone(); + g2d.getTransform().setToIdentity(); + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, fb.getWidth(), fb.getHeight()); + flush(); + g2d.setTransform(tf); + } + + @Override + public int getWidth() { + return fb.getWidth(); + } + + @Override + public int getHeight() { + return fb.getHeight(); + } + + @Override + public byte[] getDisplay() { + return ImageUtils.getImageBytes(image); + } + + + @Override + public byte[] getHWDisplay() { + return getDisplay(); + } + + @Override + public void setContrast(int i) { + // not implemented even on leJOS + log.debug("Feature not implemented"); + } + + /** + * Convert from leJOS image format to Java image + */ + private BufferedImage lejos2rgb(byte[] src, int width, int height) { + @SuppressWarnings("SuspiciousNameCombination") + BufferedImage in = ImageUtils.createBWImage(height, width, true, src); + BufferedImage out = ImageUtils.createXRGBImage(width, height); + return java_lejos_flip(in, out); + } + + private BufferedImage any2rgb(Image img) { + BufferedImage copy = ImageUtils.createXRGBImage(img.getWidth(null), img.getHeight(null)); + Graphics2D gfx = (Graphics2D) copy.getGraphics(); + gfx.drawImage(img, 0, 0, null); + gfx.dispose(); + return copy; + } + + /** + * Convert from Java image to leJOS image format + */ + private byte[] any2lejos(BufferedImage img) { + BufferedImage out = ImageUtils.createBWImage(img.getHeight(), img.getWidth(), true); + BufferedImage right = java_lejos_flip(img, out); + return ((DataBufferByte) right.getRaster().getDataBuffer()).getData(); + } + + private BufferedImage java_lejos_flip(BufferedImage in, BufferedImage out) { + AffineTransform tf = new AffineTransform(); + tf.quadrantRotate(1); + tf.scale(-1.0, +1.0); + AffineTransformOp op = new AffineTransformOp(tf, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); + return op.filter(in, out); + } + + /** + * Slow emulation of leJOS bitBlt() + */ + @Override + public void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, int dy, int w, int h, int rop) { + BufferedImage srcI = lejos2rgb(src, sw, sh); + BufferedImage dstI = any2rgb(image); + bitBlt(srcI, sx, sy, dstI, dx, dy, w, h, rop); + g2d.drawImage(dstI, 0, 0, null); + } + + /** + * Slow emulation of leJOS bitBlt() + */ + @Override + public void bitBlt( + byte[] src, int sw, int sh, int sx, int sy, byte[] dst, int dw, int dh, int dx, int dy, int w, int h, int rop) { + BufferedImage srcI = lejos2rgb(src, sw, sh); + BufferedImage dstI = lejos2rgb(dst, dw, dh); + bitBlt(srcI, sx, sy, dstI, dx, dy, w, h, rop); + Graphics2D gfx = dstI.createGraphics(); + gfx.drawImage(srcI, + dy, dx, dy + h, dx + w, + sy, sx, sy + h, sx + w, + Color.WHITE, null); + gfx.dispose(); + byte[] data = any2lejos(dstI); + System.arraycopy(data, 0, dst, 0, Math.min(data.length, dst.length)); + } + + private void bitBlt(BufferedImage src, int sx, int sy, BufferedImage dst, int dx, int dy, int w, int h, int rop) { + WritableRaster srcR = src.getRaster(); + WritableRaster dstR = dst.getRaster(); + + byte msk_dst = (byte) (0xFF & (rop >> 24)); + byte xor_dst = (byte) (0xFF & (rop >> 16)); + byte msk_src = (byte) (0xFF & (rop >> 8)); + byte xor_src = (byte) (0xFF & (rop)); + boolean dstskip = msk_dst == 0 && xor_dst == 0; + + int[] dstpix = new int[4]; + int[] srcpix = new int[4]; + for (int vx = 0; vx < w; vx++) { + for (int vy = 0; vy < h; vy++) { + int srcx = sx + vx; + int srcy = sy + vy; + int dstx = dx + vx; + int dsty = dy + vy; + srcR.getPixel(srcx, srcy, srcpix); + + if (dstskip) { + // only rgb, no a + for (int s = 0; s < 3; s++) { + dstpix[s] = ((srcpix[s] & msk_src) ^ xor_src); + } + } else { + dstR.getPixel(dstx, dsty, dstpix); + // only rgb, no a + for (int s = 0; s < 3; s++) { + dstpix[s] = ((dstpix[s] & msk_dst) ^ xor_dst) ^ ((srcpix[s] & msk_src) ^ xor_src); + } + } + dstR.setPixel(dstx, dsty, dstpix); + } + } + } + + + @Override + public void setAutoRefresh(boolean b) { + if (this.timer_run != b) { + this.timer_run = b; + timerUpdate(); + } + } + + @Override + public int setAutoRefreshPeriod(int i) { + int old = this.timer_msec; + if (old != i) { + this.timer_msec = i; + timerUpdate(); + } + return old; + } + + private void timerUpdate() { + timer.cancel(); + if (timer_run && timer_msec > 0) { + timer.scheduleAtFixedRate(new Flusher(), 0, timer_msec); + } + } + + @Override + public void drawOval(int x, int y, int width, int height) { + g2d.drawOval(x, y, width, height); + } + + private class Flusher extends TimerTask { + @Override + public void run() { + refresh(); + } + } + +} diff --git a/src/main/java/ev3dev/actuators/LCDJessie.java b/src/main/java/ev3dev/actuators/LCDJessie.java index f3e505e3..063b09ec 100644 --- a/src/main/java/ev3dev/actuators/LCDJessie.java +++ b/src/main/java/ev3dev/actuators/LCDJessie.java @@ -7,46 +7,45 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.awt.Color; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.image.IndexColorModel; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; +import java.awt.*; +import java.awt.image.*; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Objects; -public class LCDJessie extends EV3DevDevice implements GraphicsLCD { - - private static final Logger log = LoggerFactory.getLogger(LCDJessie.class); +public class LCDJessie extends LCD { public static final String EV3DEV_EV3_DEVICES_PATH = "/dev"; public static final String EV3DEV_EV3_LCD_NAME = "fb0"; public static final String EV3DEV_EV3_LCD_PATH = EV3DEV_EV3_DEVICES_PATH + "/" + EV3DEV_EV3_LCD_NAME; public static final String EV3DEV_LCD_KEY = "EV3DEV_LCD_KEY"; - public static final String FB_PATH = - Objects.nonNull(System.getProperty(EV3DEV_LCD_KEY)) ? System.getProperty(EV3DEV_LCD_KEY) : EV3DEV_EV3_LCD_PATH; - - private int SCREEN_WIDTH = 0; - private int SCREEN_HEIGHT = 0; - private int LINE_LEN = 0; - private int BUFFER_SIZE = 0; - + public static final String FB_PATH = Objects.nonNull(System.getProperty(EV3DEV_LCD_KEY)) ? System.getProperty(EV3DEV_LCD_KEY) : EV3DEV_EV3_LCD_PATH; public static final int EV3_SCREEN_WIDTH = 178; public static final int EV3_SCREEN_HEIGHT = 128; public static final int EV3_LINE_LEN = 24; public static final int EV3_ROWS = 128; public static final int EV3_BUFFER_SIZE = EV3_LINE_LEN * EV3_ROWS; - + private static final Logger log = LoggerFactory.getLogger(LCDJessie.class); + private static GraphicsLCD instance; + private int SCREEN_WIDTH = 0; + private int SCREEN_HEIGHT = 0; + private int LINE_LEN = 0; + private int BUFFER_SIZE = 0; private BufferedImage image; private Graphics2D g2d; - private static GraphicsLCD instance; + // Prevent duplicate objects + private LCDJessie() { + + log.info("Instancing LCD for Jessie"); + + if (CURRENT_PLATFORM.equals(EV3DevPlatform.EV3BRICK)) { + init(EV3_SCREEN_WIDTH, EV3_SCREEN_HEIGHT, EV3_LINE_LEN, EV3_BUFFER_SIZE); + } else { + log.error("This actuator was only tested for: {}", EV3DevPlatform.EV3BRICK); + throw new RuntimeException("This actuator was only tested for: " + EV3DevPlatform.EV3BRICK); + } + } /** * Singleton constructor @@ -61,19 +60,6 @@ public static GraphicsLCD getInstance() { return instance; } - // Prevent duplicate objects - private LCDJessie() { - - log.info("Instancing LCD for Jessie"); - - if (CURRENT_PLATFORM.equals(EV3DevPlatform.EV3BRICK)) { - init(EV3_SCREEN_WIDTH, EV3_SCREEN_HEIGHT, EV3_LINE_LEN, EV3_BUFFER_SIZE); - } else { - log.error("This actuator was only tested for: {}", EV3DevPlatform.EV3BRICK); - throw new RuntimeException("This actuator was only tested for: " + EV3DevPlatform.EV3BRICK); - } - } - private void init( final int width, final int height, diff --git a/src/main/java/ev3dev/actuators/LCDStretch.java b/src/main/java/ev3dev/actuators/LCDStretch.java index 4f552f81..c0ca846e 100644 --- a/src/main/java/ev3dev/actuators/LCDStretch.java +++ b/src/main/java/ev3dev/actuators/LCDStretch.java @@ -9,13 +9,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.Stroke; +import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.image.AffineTransformOp; @@ -28,7 +22,7 @@ /** * Lejos LCD reimplementation using Java2D API */ -public class LCDStretch extends EV3DevDevice implements GraphicsLCD { +public class LCDStretch extends LCD { // custom config public static final String EV3DEV_LCD_KEY = "EV3DEV_LCD_KEY"; @@ -37,35 +31,18 @@ public class LCDStretch extends EV3DevDevice implements GraphicsLCD { // logger private static final Logger log = LoggerFactory.getLogger(LCDStretch.class); - + private static LCDStretch instance; // drawable - private JavaFramebuffer fb; - private BufferedImage image; - private Graphics2D g2d; - + private final JavaFramebuffer fb; + private final BufferedImage image; + private final Graphics2D g2d; // autorefresh - private Timer timer; + private final Timer timer; private boolean timer_run = false; private int timer_msec = 0; - // stroke private int stroke; - private static LCDStretch instance; - - /** - * Singleton constructor - * - * @return GraphicsLCD - */ - public static GraphicsLCD getInstance() { - //TODO Refactor - if (instance == null) { - instance = new LCDStretch(); - } - return instance; - } - // Prevent duplicate objects private LCDStretch() { @@ -83,6 +60,19 @@ private LCDStretch() { this.clear(); } + /** + * Singleton constructor + * + * @return GraphicsLCD + */ + public static GraphicsLCD getInstance() { + //TODO Refactor + if (instance == null) { + instance = new LCDStretch(); + } + return instance; + } + public JavaFramebuffer getFramebuffer() { return fb; } @@ -198,7 +188,7 @@ public void drawSubstring(String str, int offset, int len, @Override public void drawChar(char character, int x, int y, int anchor) { - String str = new String(new char[]{character}); + String str = String.valueOf(character); drawString(str, x, y, anchor); } @@ -562,6 +552,11 @@ private void timerUpdate() { } } + @Override + public void drawOval(int x, int y, int width, int height) { + g2d.drawOval(x, y, width, height); + } + private class Flusher extends TimerTask { @Override public void run() { @@ -569,9 +564,4 @@ public void run() { } } - @Override - public void drawOval(int x, int y, int width, int height) { - g2d.drawOval(x, y, width, height); - } - } diff --git a/src/main/java/ev3dev/actuators/Sound.java b/src/main/java/ev3dev/actuators/Sound.java index bb571fb5..2f87d6df 100644 --- a/src/main/java/ev3dev/actuators/Sound.java +++ b/src/main/java/ev3dev/actuators/Sound.java @@ -10,11 +10,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.sound.sampled.AudioInputStream; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.Clip; -import javax.sound.sampled.LineUnavailableException; -import javax.sound.sampled.UnsupportedAudioFileException; +import javax.sound.sampled.*; import java.io.File; import java.io.IOException; import java.util.Objects; @@ -30,23 +26,29 @@ */ public class Sound extends EV3DevDevice { + public static final String EV3DEV_SOUND_KEY = "EV3DEV_SOUND_KEY"; + public static final String VOLUME = "volume"; private static final Logger LOGGER = LoggerFactory.getLogger(Sound.class); - private static final String EV3_PHYSICAL_SOUND_PATH = "/sys/devices/platform/snd-legoev3"; - public static final String EV3DEV_SOUND_KEY = "EV3DEV_SOUND_KEY"; - private static String EV3_SOUND_PATH; - private static final String CMD_BEEP = "beep"; - public static final String VOLUME = "volume"; - - private static String VOLUME_PATH; private static final String DISABLED_FEATURE_MESSAGE = "This feature is disabled for this platform."; - + private static String EV3_SOUND_PATH; + private static String VOLUME_PATH; + private static Sound instance; private final EV3DevDistro CURRENT_DISTRO; + private int volume = 0; - private static Sound instance; + // Prevent duplicate objects + private Sound() { - private int volume = 0; + LOGGER.info("Creating a instance of Sound"); + + EV3_SOUND_PATH = Objects.nonNull(System.getProperty(EV3DEV_SOUND_KEY)) + ? System.getProperty(EV3DEV_SOUND_KEY) : EV3_PHYSICAL_SOUND_PATH; + VOLUME_PATH = EV3_SOUND_PATH + "/" + VOLUME; + + CURRENT_DISTRO = EV3DevDistros.getInstance().getDistro(); + } /** * Return a Instance of Sound. @@ -63,18 +65,6 @@ public static Sound getInstance() { return instance; } - // Prevent duplicate objects - private Sound() { - - LOGGER.info("Creating a instance of Sound"); - - EV3_SOUND_PATH = Objects.nonNull(System.getProperty(EV3DEV_SOUND_KEY)) - ? System.getProperty(EV3DEV_SOUND_KEY) : EV3_PHYSICAL_SOUND_PATH; - VOLUME_PATH = EV3_SOUND_PATH + "/" + VOLUME; - - CURRENT_DISTRO = EV3DevDistros.getInstance().getDistro(); - } - /** * Beeps once. */ @@ -163,35 +153,35 @@ public void playSample(final File file) { } /** - * Set the master volume level + * Get the current master volume level * - * @param volume 0-100 + * @return the current master volume 0-100 */ - public void setVolume(final int volume) { - - this.volume = volume; + public int getVolume() { if (CURRENT_DISTRO.equals(EV3DevDistro.JESSIE)) { - //TODO Review to move to this.setIntegerAttribute(); - Sysfs.writeString(VOLUME_PATH, "" + volume); + //TODO Review to move to this.getIntegerAttribute() + return Sysfs.readInteger(VOLUME_PATH); } else { - final String cmdVolume = "amixer set PCM,0 " + volume + "%"; - Shell.execute(cmdVolume); + return this.volume; } } /** - * Get the current master volume level + * Set the master volume level * - * @return the current master volume 0-100 + * @param volume 0-100 */ - public int getVolume() { + public void setVolume(final int volume) { + + this.volume = volume; if (CURRENT_DISTRO.equals(EV3DevDistro.JESSIE)) { - //TODO Review to move to this.getIntegerAttribute() - return Sysfs.readInteger(VOLUME_PATH); + //TODO Review to move to this.setIntegerAttribute(); + Sysfs.writeString(VOLUME_PATH, "" + volume); } else { - return this.volume; + final String cmdVolume = "amixer set PCM,0 " + volume + "%"; + Shell.execute(cmdVolume); } } diff --git a/src/main/java/ev3dev/actuators/ev3/EV3Led.java b/src/main/java/ev3dev/actuators/ev3/EV3Led.java index f7d637e3..7c4fefb9 100644 --- a/src/main/java/ev3dev/actuators/ev3/EV3Led.java +++ b/src/main/java/ev3dev/actuators/ev3/EV3Led.java @@ -14,24 +14,12 @@ */ public class EV3Led extends EV3DevDevice implements LED { - /** - * Directions of the LED. - */ - public enum Direction { - LEFT, - RIGHT - } - - private static final Logger log = LoggerFactory.getLogger(EV3Led.class); - public static final int LEFT = 0; public static final int RIGHT = 1; - + private static final Logger log = LoggerFactory.getLogger(EV3Led.class); private final Direction direction; - private final String LED_RED; private final String LED_GREEN; - /** * Create an EV3LED object associated with the LED of the specified direction. * @@ -65,6 +53,7 @@ public EV3Led(final Direction direction) { * @throws RuntimeException if LED feature is not supported on the current platform. * @deprecated Use {@link #EV3Led(Direction)} instead. */ + @Deprecated public EV3Led(final int button) { checkPlatform(); @@ -95,13 +84,11 @@ private void checkPlatform() { } } - //TODO Add Enums for patterns - /** * Sets the pattern of light to be shown with this LED. * * @param pattern the pattern to show with this LED. - * + *
* 0: Turns off the LED light;
* 1/2/3: Static green/red/yellow light;
* 4/5/6: Normal blinking green/red/yellow light, not implemented;
@@ -127,6 +114,8 @@ public void setPattern(final int pattern) {
}
}
+ //TODO Add Enums for patterns
+
/**
* Returns the direction of the LED associated with this object.
*
@@ -135,4 +124,12 @@ public void setPattern(final int pattern) {
public Direction getDirection() {
return direction;
}
+
+ /**
+ * Directions of the LED.
+ */
+ public enum Direction {
+ LEFT,
+ RIGHT
+ }
}
diff --git a/src/main/java/ev3dev/actuators/lego/motors/BaseRegulatedMotor.java b/src/main/java/ev3dev/actuators/lego/motors/BaseRegulatedMotor.java
index 5f99e069..8ba09775 100644
--- a/src/main/java/ev3dev/actuators/lego/motors/BaseRegulatedMotor.java
+++ b/src/main/java/ev3dev/actuators/lego/motors/BaseRegulatedMotor.java
@@ -49,14 +49,11 @@ public abstract class BaseRegulatedMotor extends EV3DevMotorDevice implements Re
// Following should be set to the max SPEED (in deg/sec) of the motor when free running and powered by 9V
protected final int MAX_SPEED_AT_9V;
-
- private int speed = 360;
+ private final List
* - EV3 Brick
* - Raspberry Pi 1 + PiStorms
* - Raspberry Pi 1 + BrickPi
- *
- * At the moment, the class extends from Device,
- * but close method doesn´t close any real resource.
+ *
+ * At the moment, the class extends from Device,
+ * but close method doesn´t close any real resource.
*
* @author Juan Antonio Breña Moral
- *
- *
*/
public abstract class EV3DevDevice {
- private static final Logger LOGGER = LoggerFactory.getLogger(EV3DevDevice.class);
-
- protected final Properties ev3DevProperties;
- protected final EV3DevPlatform CURRENT_PLATFORM;
-
protected static final String LEGO_PORT = "lego-port";
protected static final String ADDRESS = "address";
protected static final String LEGO_SENSOR = "lego-sensor";
protected static final String MODE = "mode";
protected static final String DEVICE = "set_device";
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(EV3DevDevice.class);
+ protected final Properties ev3DevProperties;
+ protected final EV3DevPlatform CURRENT_PLATFORM;
protected File PATH_DEVICE = null;
/**
diff --git a/src/main/java/ev3dev/hardware/EV3DevDistro.java b/src/main/java/ev3dev/hardware/EV3DevDistro.java
index a2f4a4ad..fd812b76 100644
--- a/src/main/java/ev3dev/hardware/EV3DevDistro.java
+++ b/src/main/java/ev3dev/hardware/EV3DevDistro.java
@@ -2,5 +2,6 @@
public enum EV3DevDistro {
JESSIE,
- STRETCH
+ STRETCH,
+ BUSTER
}
diff --git a/src/main/java/ev3dev/hardware/EV3DevDistros.java b/src/main/java/ev3dev/hardware/EV3DevDistros.java
index 0dde8b4d..8e035633 100644
--- a/src/main/java/ev3dev/hardware/EV3DevDistros.java
+++ b/src/main/java/ev3dev/hardware/EV3DevDistros.java
@@ -8,17 +8,35 @@
@Slf4j
public class EV3DevDistros {
- private static EV3DevDistros instance;
-
private static final String DEBIAN_DISTRO_DETECTION_QUERY = "cat /etc/os-release";
private static final String JESSIE_DISTRO_DETECTION_PATTERN = "ev3dev-jessie";
private static final String STRETCH_DISTRO_DETECTION_PATTERN = "ev3dev-stretch";
+ private static final String BUSTER_DISTRO_DETECTION_PATTERN = "ev3dev-buster";
private static final String DEBIAN_DISTRO_DETECTION_KEY = "EV3DEV_DISTRO";
private static final String DEBIAN_DISTRO_DETECTION_JESSIE = "jessie";
private static final String DEBIAN_DISTRO_DETECTION_STRETCH = "stretch";
-
+ private static final String DEBIAN_DISTRO_DETECTION_BUSTER = "buster";
+ private static EV3DevDistros instance;
private EV3DevDistro CURRENT_DISTRO;
+ private EV3DevDistros() {
+
+ LOGGER.debug("Detecting EV3Dev Distro");
+
+ final String osResult = Shell.execute(DEBIAN_DISTRO_DETECTION_QUERY);
+ if (osResult.contains(DEBIAN_DISTRO_DETECTION_JESSIE)) {
+ setJessie();
+ } else if (osResult.contains(DEBIAN_DISTRO_DETECTION_STRETCH)) {
+ setStretch();
+ } else if (osResult.contains(DEBIAN_DISTRO_DETECTION_BUSTER)) {
+ setBuster();
+ } else {
+ //TODO Improve this flow
+ LOGGER.warn("Failed to detect distro, falling back to Stretch.");
+ setStretch();
+ }
+ }
+
/**
* Return a Instance of EV3DevDistros.
*
@@ -34,20 +52,9 @@ public static EV3DevDistros getInstance() {
return instance;
}
- private EV3DevDistros() {
-
- LOGGER.debug("Detecting EV3Dev Distro");
-
- final String osResult = Shell.execute(DEBIAN_DISTRO_DETECTION_QUERY);
- if (osResult.contains(DEBIAN_DISTRO_DETECTION_JESSIE)) {
- setJessie();
- } else if (osResult.contains(DEBIAN_DISTRO_DETECTION_STRETCH)) {
- setStretch();
- } else {
- //TODO Improve this flow
- LOGGER.warn("Failed to detect distro, falling back to Stretch.");
- setStretch();
- }
+ private void setBuster() {
+ LOGGER.debug("Debian Buster detected");
+ CURRENT_DISTRO = EV3DevDistro.BUSTER;
}
private void setStretch() {
diff --git a/src/main/java/ev3dev/hardware/EV3DevFileSystem.java b/src/main/java/ev3dev/hardware/EV3DevFileSystem.java
index 15521529..d5d265ca 100644
--- a/src/main/java/ev3dev/hardware/EV3DevFileSystem.java
+++ b/src/main/java/ev3dev/hardware/EV3DevFileSystem.java
@@ -9,14 +9,12 @@
* The class responsible to interact with EV3Dev file system
*
* @author Juan Antonio Breña Moral
- *
*/
public class EV3DevFileSystem {
- private static final Logger LOGGER = LoggerFactory.getLogger(EV3DevFileSystem.class);
-
public static final String EV3DEV_TESTING_KEY = "EV3DEV_TESTING_KEY";
public static final String EV3DEV_ROOT_PATH = "/sys/class";
+ private static final Logger LOGGER = LoggerFactory.getLogger(EV3DevFileSystem.class);
private static final String CURRENT_ROOT_PATH = retrieveRootPath();
private static String retrieveRootPath() {
diff --git a/src/main/java/ev3dev/hardware/EV3DevMotorDevice.java b/src/main/java/ev3dev/hardware/EV3DevMotorDevice.java
index c75ef832..1aa1a95b 100644
--- a/src/main/java/ev3dev/hardware/EV3DevMotorDevice.java
+++ b/src/main/java/ev3dev/hardware/EV3DevMotorDevice.java
@@ -2,9 +2,8 @@
/**
* Base class to interact with EV3Dev sysfs
- *
- * @author Juan Antonio Breña Moral
*
+ * @author Juan Antonio Breña Moral
*/
public abstract class EV3DevMotorDevice extends EV3DevDevice {
diff --git a/src/main/java/ev3dev/hardware/EV3DevPlatform.java b/src/main/java/ev3dev/hardware/EV3DevPlatform.java
index 77f13212..9ddf3f41 100644
--- a/src/main/java/ev3dev/hardware/EV3DevPlatform.java
+++ b/src/main/java/ev3dev/hardware/EV3DevPlatform.java
@@ -7,26 +7,18 @@ public enum EV3DevPlatform {
EV3BRICK("EV3BRICK", "ev3"),
PISTORMS("PISTORMS", "pistorms"),
- BRICKPI("BRICKPI", "brickpi"),
+ BRICKPI("BRICKPI", "brickpi"),
BRICKPI3("BRICKPI3", "brickpi3"),
- UNKNOWN("UNKNOWN", "unknown");
+ UNKNOWN("UNKNOWN", "unknown");
private final String platform;
private final String propNamespace;
- private EV3DevPlatform(String stringVal, String ns) {
+ EV3DevPlatform(String stringVal, String ns) {
platform = stringVal;
propNamespace = ns;
}
- public String toString() {
- return platform;
- }
-
- public String getPropertyNamespace() {
- return propNamespace;
- }
-
/**
* Method to find the platform
*
@@ -41,4 +33,12 @@ public static String getPlatformByString(final String code) {
}
return UNKNOWN.toString();
}
+
+ public String toString() {
+ return platform;
+ }
+
+ public String getPropertyNamespace() {
+ return propNamespace;
+ }
}
diff --git a/src/main/java/ev3dev/hardware/EV3DevPlatforms.java b/src/main/java/ev3dev/hardware/EV3DevPlatforms.java
index 5f5b9e3b..80a62ca2 100644
--- a/src/main/java/ev3dev/hardware/EV3DevPlatforms.java
+++ b/src/main/java/ev3dev/hardware/EV3DevPlatforms.java
@@ -18,22 +18,9 @@ public class EV3DevPlatforms {
private static EV3DevPlatforms instance;
private final EV3DevPlatform platform;
- private final String propPrefix;
+ private final String propPrefix;
private final Properties props;
- /**
- * Return a Instance of EV3DevPlatforms.
- *
- * @return A EV3DevPlatforms instance
- */
- public static EV3DevPlatforms getInstance() {
-
- if (Objects.isNull(instance)) {
- instance = new EV3DevPlatforms();
- }
- return instance;
- }
-
private EV3DevPlatforms() {
LOGGER.debug("Providing a EV3DevPlatforms instance");
@@ -47,10 +34,10 @@ private EV3DevPlatforms() {
// iterate over all platforms and check if they're the correct one
platform = EnumSet.allOf(EV3DevPlatform.class)
- .stream()
- .filter(e -> batteryTest(batteryDirectory, e.getPropertyNamespace()))
- .findFirst()
- .get();
+ .stream()
+ .filter(e -> batteryTest(batteryDirectory, e.getPropertyNamespace()))
+ .findFirst()
+ .get();
if (platform == EV3DevPlatform.UNKNOWN) {
throwNoPlatform();
@@ -64,12 +51,25 @@ private EV3DevPlatforms() {
}
+ /**
+ * Return a Instance of EV3DevPlatforms.
+ *
+ * @return A EV3DevPlatforms instance
+ */
+ public static EV3DevPlatforms getInstance() {
+
+ if (Objects.isNull(instance)) {
+ instance = new EV3DevPlatforms();
+ }
+ return instance;
+ }
+
private boolean batteryTest(final String batteryDir, final String propPrefix) {
LOGGER.debug("Detecting platform with the battery approach");
Path path = Paths.get(EV3DevFileSystem.getRootPath(),
- batteryDir,
- props.getProperty(propPrefix + ".battery"));
+ batteryDir,
+ props.getProperty(propPrefix + ".battery"));
return Sysfs.existPath(path.toString());
}
diff --git a/src/main/java/ev3dev/hardware/EV3DevPropertyLoader.java b/src/main/java/ev3dev/hardware/EV3DevPropertyLoader.java
index 81f77279..8648defe 100644
--- a/src/main/java/ev3dev/hardware/EV3DevPropertyLoader.java
+++ b/src/main/java/ev3dev/hardware/EV3DevPropertyLoader.java
@@ -9,11 +9,10 @@
public class EV3DevPropertyLoader {
private static final Logger LOGGER = LoggerFactory.getLogger(EV3DevPropertyLoader.class);
-
- private final Properties ev3DevProperties;
-
+ private static final String BUSTER_PROPERTY_FILENAME = "buster.properties";
private static final String STRETCH_PROPERTY_FILENAME = "stretch.properties";
private static final String JESSIE_PROPERTY_FILENAME = "jessie.properties";
+ private final Properties ev3DevProperties;
/**
* Constructor
@@ -21,10 +20,16 @@ public class EV3DevPropertyLoader {
public EV3DevPropertyLoader() {
String propertyName;
- if (EV3DevDistros.getInstance().getDistro().equals(EV3DevDistro.STRETCH)) {
- propertyName = STRETCH_PROPERTY_FILENAME;
- } else {
- propertyName = JESSIE_PROPERTY_FILENAME;
+ switch (EV3DevDistros.getInstance().getDistro()) {
+ case BUSTER:
+ propertyName = BUSTER_PROPERTY_FILENAME;
+ break;
+ case JESSIE:
+ propertyName = JESSIE_PROPERTY_FILENAME;
+ break;
+ default:
+ propertyName = STRETCH_PROPERTY_FILENAME;
+ break;
}
try {
@@ -39,6 +44,7 @@ public EV3DevPropertyLoader() {
/**
* Return the properties
+ *
* @return Properties
*/
public Properties getEV3DevProperties() {
diff --git a/src/main/java/ev3dev/hardware/EV3DevSensorDevice.java b/src/main/java/ev3dev/hardware/EV3DevSensorDevice.java
index 17e63ae3..758e96d9 100644
--- a/src/main/java/ev3dev/hardware/EV3DevSensorDevice.java
+++ b/src/main/java/ev3dev/hardware/EV3DevSensorDevice.java
@@ -55,7 +55,7 @@ protected EV3DevSensorDevice(final Port portName, final String mode, final Strin
* Constructor used for some Analog Sensors like EV3 Touch Sensors
*
* @param portName Port
- * @param mode Mode
+ * @param mode Mode
*/
protected EV3DevSensorDevice(final Port portName, final String mode) {
diff --git a/src/main/java/ev3dev/hardware/display/BitFramebuffer.java b/src/main/java/ev3dev/hardware/display/BitFramebuffer.java
index fff4b6aa..d7755e34 100644
--- a/src/main/java/ev3dev/hardware/display/BitFramebuffer.java
+++ b/src/main/java/ev3dev/hardware/display/BitFramebuffer.java
@@ -6,9 +6,7 @@
import java.awt.image.BufferedImage;
-import static ev3dev.utils.io.NativeConstants.FB_TYPE_PACKED_PIXELS;
-import static ev3dev.utils.io.NativeConstants.FB_VISUAL_MONO01;
-import static ev3dev.utils.io.NativeConstants.FB_VISUAL_MONO10;
+import static ev3dev.utils.io.NativeConstants.*;
/**
* Linux black-and-white 1bpp framebuffer
@@ -21,7 +19,7 @@ public class BitFramebuffer extends LinuxFramebuffer {
/**
* Create and initialize new Linux 1bpp framebuffer.
*
- * @param fb The framebuffer device (e.g. /dev/fb0)
+ * @param fb The framebuffer device (e.g. /dev/fb0)
* @param disp Display manager (e.g. /dev/tty)
*/
public BitFramebuffer(NativeFramebuffer fb, DisplayInterface disp)
diff --git a/src/main/java/ev3dev/hardware/display/DisplayInterface.java b/src/main/java/ev3dev/hardware/display/DisplayInterface.java
index 84f477f8..848dddc6 100644
--- a/src/main/java/ev3dev/hardware/display/DisplayInterface.java
+++ b/src/main/java/ev3dev/hardware/display/DisplayInterface.java
@@ -78,8 +78,9 @@ protected void closeFramebuffer() {
/**
* Initialize new internal instance of JavaFramebuffer.
+ *
* @param backend Device behind JavaFramebuffer.
- * @param enable Whether to enable framebuffer flushing from the beginning.
+ * @param enable Whether to enable framebuffer flushing from the beginning.
*/
protected void initializeFramebuffer(@NonNull NativeFramebuffer backend, boolean enable) {
try {
diff --git a/src/main/java/ev3dev/hardware/display/ImageUtils.java b/src/main/java/ev3dev/hardware/display/ImageUtils.java
index 3a738e2e..100c5b96 100644
--- a/src/main/java/ev3dev/hardware/display/ImageUtils.java
+++ b/src/main/java/ev3dev/hardware/display/ImageUtils.java
@@ -3,17 +3,9 @@
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
-import java.awt.Transparency;
+import java.awt.*;
import java.awt.color.ColorSpace;
-import java.awt.image.BufferedImage;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.IndexColorModel;
-import java.awt.image.MultiPixelPackedSampleModel;
-import java.awt.image.PixelInterleavedSampleModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
+import java.awt.image.*;
/**
* Common image utilities for framebuffer manipulation
@@ -83,13 +75,13 @@ public static BufferedImage createXRGBImage(
// initialize buffer <-> samples bridge
PixelInterleavedSampleModel sm = new PixelInterleavedSampleModel(
- DataBuffer.TYPE_BYTE, width, height,
- 4, stride, offsets);
+ DataBuffer.TYPE_BYTE, width, height,
+ 4, stride, offsets);
// initialize color interpreter
ColorSpace spc = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ComponentColorModel cm = new ComponentColorModel(spc, true, false,
- Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+ Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
// create raster
WritableRaster wr = Raster.createWritableRaster(sm, db, null);
@@ -173,9 +165,9 @@ public static BufferedImage createBWImage(
// initialize buffer <-> sample mapping
MultiPixelPackedSampleModel packing =
- new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
- width, height,
- 1, stride, 0);
+ new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+ width, height,
+ 1, stride, 0);
// initialize raster
WritableRaster wr = Raster.createWritableRaster(packing, db, null);
diff --git a/src/main/java/ev3dev/hardware/display/LinuxFramebuffer.java b/src/main/java/ev3dev/hardware/display/LinuxFramebuffer.java
index 45a4534d..4083e369 100644
--- a/src/main/java/ev3dev/hardware/display/LinuxFramebuffer.java
+++ b/src/main/java/ev3dev/hardware/display/LinuxFramebuffer.java
@@ -7,8 +7,7 @@
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
-import java.awt.Color;
-import java.awt.Graphics2D;
+import java.awt.*;
import java.awt.image.BufferedImage;
/**
@@ -226,7 +225,7 @@ public Pointer getMemory() {
* @see LinuxFramebuffer#getMemory() for memory pointer.
*/
public long getBufferSize() {
- return getHeight() * getStride();
+ return (long) getHeight() * getStride();
}
/**
diff --git a/src/main/java/ev3dev/hardware/display/OwnedDisplay.java b/src/main/java/ev3dev/hardware/display/OwnedDisplay.java
index 557fb297..0c54c4eb 100644
--- a/src/main/java/ev3dev/hardware/display/OwnedDisplay.java
+++ b/src/main/java/ev3dev/hardware/display/OwnedDisplay.java
@@ -9,13 +9,7 @@
import java.io.IOException;
-import static ev3dev.utils.io.NativeConstants.KD_GRAPHICS;
-import static ev3dev.utils.io.NativeConstants.KD_TEXT;
-import static ev3dev.utils.io.NativeConstants.K_OFF;
-import static ev3dev.utils.io.NativeConstants.O_RDWR;
-import static ev3dev.utils.io.NativeConstants.SIGUSR2;
-import static ev3dev.utils.io.NativeConstants.VT_AUTO;
-import static ev3dev.utils.io.NativeConstants.VT_PROCESS;
+import static ev3dev.utils.io.NativeConstants.*;
/**
* System console manager.
* This package handles the concept about a Input/Output Device.
* A Device could be a Motor or a Sensor, but not every device is supported for all Supported platforms on EV3Dev.
* Besides, it is possible that in Runtime a Device is not detected on EV3Dev.
- *
*/
-package ev3dev.hardware;
\ No newline at end of file
+package ev3dev.hardware;
diff --git a/src/main/java/ev3dev/robotics/tts/Espeak.java b/src/main/java/ev3dev/robotics/tts/Espeak.java
index b92252a4..cbae5811 100644
--- a/src/main/java/ev3dev/robotics/tts/Espeak.java
+++ b/src/main/java/ev3dev/robotics/tts/Espeak.java
@@ -9,16 +9,13 @@
*/
public class Espeak {
- private static final Logger log = LoggerFactory.getLogger(Espeak.class);
-
- private static final String ESPEAK = "espeak";
- private static final String CMD_APLAY = "aplay";
-
public static final String VOICE_ENGLISH = "en";
public static final String VOICE_SPANISH = "es";
public static final int DEFAULT_SPEED_READING = 105;
public static final int DEFAULT_PITCH = 60;
-
+ private static final Logger log = LoggerFactory.getLogger(Espeak.class);
+ private static final String ESPEAK = "espeak";
+ private static final String CMD_APLAY = "aplay";
private String voice = null;
private int volume = -1;
private int speedReading = -1;
@@ -68,12 +65,12 @@ private void build() {
if (this.speedReading != -1) {
sb.append(" -s ").append(this.speedReading);
} else {
- sb.append(" -s ").append(this.DEFAULT_SPEED_READING);
+ sb.append(" -s ").append(DEFAULT_SPEED_READING);
}
if (this.pitch != -1) {
sb.append(" -p ").append(this.pitch);
} else {
- sb.append(" -p ").append(this.DEFAULT_PITCH);
+ sb.append(" -p ").append(DEFAULT_PITCH);
}
//TODO Refactor
if (message != null) {
diff --git a/src/main/java/ev3dev/sensors/BaseSensor.java b/src/main/java/ev3dev/sensors/BaseSensor.java
index d35a636e..163e7ae4 100644
--- a/src/main/java/ev3dev/sensors/BaseSensor.java
+++ b/src/main/java/ev3dev/sensors/BaseSensor.java
@@ -14,16 +14,16 @@
public class BaseSensor extends EV3DevSensorDevice implements SensorModes {
public static final int SWITCH_DELAY = 400;
- private ArrayList
*
* @return A sampleProvider
- * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders}
+ * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders}
*/
public SensorMode getRemoteMode() {
switchMode(MODE_REMOTE, SWITCH_DELAY);
diff --git a/src/main/java/ev3dev/sensors/ev3/EV3TouchSensor.java b/src/main/java/ev3dev/sensors/ev3/EV3TouchSensor.java
index 73d08705..bb9fb7e2 100644
--- a/src/main/java/ev3dev/sensors/ev3/EV3TouchSensor.java
+++ b/src/main/java/ev3dev/sensors/ev3/EV3TouchSensor.java
@@ -42,7 +42,7 @@ public EV3TouchSensor(final Port portName) {
*
* Absolute IMU
* NXTCamV5
- *
*/
-package ev3dev.sensors.mindsensors;
\ No newline at end of file
+package ev3dev.sensors.mindsensors;
diff --git a/src/main/java/ev3dev/sensors/nxt/NXTSoundSensor.java b/src/main/java/ev3dev/sensors/nxt/NXTSoundSensor.java
new file mode 100644
index 00000000..ae3fe61f
--- /dev/null
+++ b/src/main/java/ev3dev/sensors/nxt/NXTSoundSensor.java
@@ -0,0 +1,108 @@
+package ev3dev.sensors.nxt;
+
+import ev3dev.sensors.BaseSensor;
+import ev3dev.utils.Sysfs;
+import lejos.hardware.port.Port;
+import lejos.hardware.sensor.EV3SensorConstants;
+import lejos.hardware.sensor.SensorMode;
+import lejos.robotics.SampleProvider;
+import lejos.utility.Delay;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public class NXTSoundSensor extends BaseSensor {
+ protected static final long SWITCH_DELAY = 10;
+ protected static float MIN_RANGE = 0F;
+ protected static float MAX_RANGE = 1000F;
+
+ protected int currentType = -1;
+
+
+ public NXTSoundSensor(Port sensorPort) {
+ super(sensorPort, "nxt-analog", "lego-nxt-sound");
+ }
+
+ public static float round(float d, int decimalPlace) {
+ BigDecimal bd = new BigDecimal(Float.toString(d));
+ bd = bd.setScale(decimalPlace, RoundingMode.HALF_UP);
+ return bd.floatValue();
+ }
+
+ public SampleProvider getDBMode() {
+ this.switchMode("Sound-DB", 400L);
+ return getMode(1);
+ }
+
+ public SampleProvider getDBAMode() {
+ this.switchMode("Sound-DBA", 400L);
+ return getMode(0);
+ }
+
+ /**
+ * Helper method. Take a voltage and return it as a normalized value in the
+ * range 0.0-1.0
+ *
+ * @param val input value
+ * @return normalized value
+ */
+ protected float normalize(float val) {
+ return val / EV3SensorConstants.ADC_REF;
+ }
+
+ /**
+ * Switch to the selected type (if not already in that type) and delay for the
+ * specified period to allow the sensor to settle in the new state.
+ * NOTE: This method is intended for use with NXT sensor drivers that use a
+ * sensor type to specify the operating mode.
+ *
+ * @param newType The type to switch to.
+ * @param switchDelay Time in mS to delay after the switch.
+ */
+ protected void switchType(int newType, long switchDelay) {
+ if (currentType != newType) {
+ currentType = newType;
+ Delay.msDelay(switchDelay);
+ }
+ }
+
+ private class DBMode implements SensorMode {
+
+ @Override
+ public int sampleSize() {
+ return 1;
+ }
+
+ @Override
+ public void fetchSample(float[] sample, int offset) {
+ switchType(7, SWITCH_DELAY);
+ float reading = Sysfs.readFloat(PATH_DEVICE + "/value" + 0);
+ sample[offset] = round(1.0F - normalize(reading) / MAX_RANGE, 2);
+ }
+
+ @Override
+ public String getName() {
+ return "Sound-DB";
+ }
+ }
+
+ private class DBAMode implements SensorMode {
+ @Override
+ public int sampleSize() {
+ return 1;
+ }
+
+ @Override
+ public void fetchSample(float[] sample, int offset) {
+ switchType(8, SWITCH_DELAY);
+ float reading = Sysfs.readFloat(PATH_DEVICE + "/value" + 0);
+ sample[offset] = round(1.0F - normalize(reading) / MAX_RANGE, 2);
+ }
+
+
+ @Override
+ public String getName() {
+ return "Sound-DBA";
+ }
+ }
+}
diff --git a/src/main/java/ev3dev/sensors/nxt/NXTTemperatureSensor.java b/src/main/java/ev3dev/sensors/nxt/NXTTemperatureSensor.java
index 55f94879..c578b05c 100644
--- a/src/main/java/ev3dev/sensors/nxt/NXTTemperatureSensor.java
+++ b/src/main/java/ev3dev/sensors/nxt/NXTTemperatureSensor.java
@@ -3,24 +3,22 @@
import ev3dev.sensors.BaseSensor;
import ev3dev.sensors.GenericMode;
import ev3dev.utils.Sysfs;
-import java.io.File;
import lejos.hardware.port.Port;
import lejos.hardware.sensor.SensorMode;
import lejos.robotics.SampleProvider;
+import java.io.File;
+
public class NXTTemperatureSensor extends BaseSensor {
private static final String LEGO_NXT_TEMP = "lego-nxt-temp";
-
+ private static final String MODE_CELSIUS = "NXT-TEMP-C";
+ private static final String MODE_FAHRENHEIT = "NXT-TEMP-F";
public static float CELSIUS_MIN_RANGE = -550f; //celsius degrees
public static float CELSIUS_MAX_RANGE = 1280f; //celsius degrees
-
public static float FAHRENHEIT_MIN_RANGE = -670f; //fahrenheit degrees
public static float FAHRENHEIT_MAX_RANGE = 2624f; //fahrenheit degrees
- private static final String MODE_CELSIUS = "NXT-TEMP-C";
- private static final String MODE_FAHRENHEIT = "NXT-TEMP-F";
-
/**
* Constructor
*
diff --git a/src/main/java/ev3dev/sensors/package-info.java b/src/main/java/ev3dev/sensors/package-info.java
index 8a164756..ad90e4fb 100644
--- a/src/main/java/ev3dev/sensors/package-info.java
+++ b/src/main/java/ev3dev/sensors/package-info.java
@@ -1,5 +1,4 @@
/**
* This package includes a set of classes to manage Sensor
- *
*/
-package ev3dev.sensors;
\ No newline at end of file
+package ev3dev.sensors;
diff --git a/src/main/java/ev3dev/utils/Brickman.java b/src/main/java/ev3dev/utils/Brickman.java
index b281a4e5..a81f5cba 100644
--- a/src/main/java/ev3dev/utils/Brickman.java
+++ b/src/main/java/ev3dev/utils/Brickman.java
@@ -2,8 +2,7 @@
import lombok.extern.slf4j.Slf4j;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
+import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
@@ -35,6 +34,7 @@ private static void restoreBrickman() {
/**
* Draw Duke.
+ *
* @param gfx Required context to draw an image.
*/
public static void drawJavaLogo(Graphics2D gfx) {
diff --git a/src/main/java/ev3dev/utils/DataChannelRereader.java b/src/main/java/ev3dev/utils/DataChannelRereader.java
index 2ba369f6..9f3ac2a1 100644
--- a/src/main/java/ev3dev/utils/DataChannelRereader.java
+++ b/src/main/java/ev3dev/utils/DataChannelRereader.java
@@ -23,7 +23,7 @@ public class DataChannelRereader implements Closeable {
/**
* Create a DataChannelRereader for path with a bufferLength byte buffer
*
- * @param path path to the file to reread
+ * @param path path to the file to reread
* @param bufferLength length of the buffer to hold the structure
* @throws IOException when things go wrong
*/
@@ -40,7 +40,7 @@ public DataChannelRereader(Path path, int bufferLength) throws IOException {
* @throws IOException when things go wrong
*/
public DataChannelRereader(String pathString) throws IOException {
- this(Paths.get(pathString),32);
+ this(Paths.get(pathString), 32);
}
/**
diff --git a/src/main/java/ev3dev/utils/Interpolation.java b/src/main/java/ev3dev/utils/Interpolation.java
index 7339ab9d..93407ead 100644
--- a/src/main/java/ev3dev/utils/Interpolation.java
+++ b/src/main/java/ev3dev/utils/Interpolation.java
@@ -6,7 +6,7 @@ public class Interpolation {
* Method implemented with the ideas from:
* http://wwwprof.uniandes.edu.co/~gprieto/classes/compufis/interpolacion.pdf
*
- * @param x parameter
+ * @param x parameter
* @param x0 parameter
* @param x1 parameter
* @param y0 parameter
@@ -14,11 +14,11 @@ public class Interpolation {
* @return result from interpolation
*/
public static float interpolate(
- float x,
- float x0,
- float x1,
- float y0,
- float y1) {
+ float x,
+ float x0,
+ float x1,
+ float y0,
+ float y1) {
return y0 + ((x - x0) * ((y1 - y0) / (x1 - x0)));
}
diff --git a/src/main/java/ev3dev/utils/JarResource.java b/src/main/java/ev3dev/utils/JarResource.java
index f16305a4..f9f043ea 100644
--- a/src/main/java/ev3dev/utils/JarResource.java
+++ b/src/main/java/ev3dev/utils/JarResource.java
@@ -4,12 +4,7 @@
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -75,8 +70,8 @@ public static String export(final String resourceName) throws IOException {
String jarFolder;
try {
jarFolder = new File(JarResource.class.getProtectionDomain()
- .getCodeSource().getLocation().toURI().getPath())
- .getParentFile().getPath().replace('\\', '/');
+ .getCodeSource().getLocation().toURI().getPath())
+ .getParentFile().getPath().replace('\\', '/');
} catch (Exception e) {
throw new RuntimeException("Cannot parse JAR folder", e);
}
diff --git a/src/main/java/ev3dev/utils/PilotProps.java b/src/main/java/ev3dev/utils/PilotProps.java
index 31bde253..8795884c 100644
--- a/src/main/java/ev3dev/utils/PilotProps.java
+++ b/src/main/java/ev3dev/utils/PilotProps.java
@@ -24,6 +24,25 @@ public class PilotProps extends Properties {
public static final String KEY_RIGHTMOTOR = "rightMotor";
public static final String KEY_REVERSE = "reverse";
+ /**
+ * Utility method to get Motor instance from string (A, B or C)
+ */
+ public static RegulatedMotor getMotor(String motor) {
+
+ if (motor.equals("A")) {
+ return Motor.A;
+ } else if (motor.equals("B")) {
+ return Motor.B;
+ } else if (motor.equals("C")) {
+ return Motor.C;
+ } else if (motor.equals("D")) {
+ return Motor.D;
+ } else {
+ //TODO Review this case.
+ return null;
+ }
+ }
+
/**
* Method to load values from file
*
@@ -49,23 +68,4 @@ public void storePersistentValues() throws IOException {
}
}
- /**
- * Utility method to get Motor instance from string (A, B or C)
- */
- public static RegulatedMotor getMotor(String motor) {
-
- if (motor.equals("A")) {
- return Motor.A;
- } else if (motor.equals("B")) {
- return Motor.B;
- } else if (motor.equals("C")) {
- return Motor.C;
- } else if (motor.equals("D")) {
- return Motor.D;
- } else {
- //TODO Review this case.
- return null;
- }
- }
-
}
diff --git a/src/main/java/ev3dev/utils/Sysfs.java b/src/main/java/ev3dev/utils/Sysfs.java
index a7ae339e..c14333e7 100644
--- a/src/main/java/ev3dev/utils/Sysfs.java
+++ b/src/main/java/ev3dev/utils/Sysfs.java
@@ -1,5 +1,7 @@
package ev3dev.utils;
+import lombok.extern.slf4j.Slf4j;
+
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
@@ -10,14 +12,12 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import lombok.extern.slf4j.Slf4j;
/**
* The class responsible to interact with Sysfs on EV3Dev
*
* @author Juan Antonio Breña Moral
* @author David Walend
- *
*/
@Slf4j
public class Sysfs {
@@ -54,7 +54,7 @@ public static boolean writeString(final String filePath, final String value) {
}
public static boolean writeInteger(final String filePath, final int value) {
- return writeString(filePath, new StringBuilder().append(value).toString());
+ return writeString(filePath, String.valueOf(value));
}
/**
@@ -137,7 +137,7 @@ public static boolean existFile(Path pathToFind) {
/**
* Method to write bytes in a path
*
- * @param path path
+ * @param path path
* @param value value to write
* @return Result
*/
diff --git a/src/main/java/ev3dev/utils/USBPort.java b/src/main/java/ev3dev/utils/USBPort.java
index 9e7f0ebc..e9b336a6 100644
--- a/src/main/java/ev3dev/utils/USBPort.java
+++ b/src/main/java/ev3dev/utils/USBPort.java
@@ -13,8 +13,8 @@
@Slf4j
public class USBPort {
- private String USBPath;
private final String defaultUSBPath = "/sys/bus/usb/drivers/usb/";
+ private final String USBPath;
/**
* Constructor
diff --git a/src/main/java/ev3dev/utils/io/ILibc.java b/src/main/java/ev3dev/utils/io/ILibc.java
index 1ce54347..9e545213 100644
--- a/src/main/java/ev3dev/utils/io/ILibc.java
+++ b/src/main/java/ev3dev/utils/io/ILibc.java
@@ -10,6 +10,7 @@
* POSIX Standard C Library wrapper interface
* For detailed reference, please see the
* Linux syscall manual pages
+ *
* @author Jakub Vaněk
* @since 2.4.7
*/
@@ -18,12 +19,13 @@ public interface ILibc {
/**
* Manipulate file descriptor
- * @param fd File descriptor to operate upon.
+ *
+ * @param fd File descriptor to operate upon.
* @param cmd Command code, see manpages for details.
* @param arg Command argument, command-speciic. See manpages for details.
* @return Depends on the command. On failure, -1 is returned.
- * @see man 2 fcntl
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 fcntl
*/
int fcntl(int fd, int cmd, int arg) throws LastErrorException;
@@ -31,23 +33,25 @@ public interface ILibc {
/**
* Invoke an I/O control request
- * @param fd Opened file descriptor to act upon.
+ *
+ * @param fd Opened file descriptor to act upon.
* @param cmd IO command code; this is device-specific (see manpages and/or kernel sources for details).
* @param arg IOCTL integer argument, this is device-specific (see manpages and/or kernel sources for details).
* @return -1 on failure, 0 otherwise (usually).
- * @see man 2 ioctl
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 ioctl
*/
int ioctl(int fd, int cmd, int arg) throws LastErrorException;
/**
* Invoke an I/O control request
- * @param fd Opened file descriptor to act upon.
+ *
+ * @param fd Opened file descriptor to act upon.
* @param cmd IO command code; this is device-specific (see manpages and/or kernel sources for details).
* @param arg IOCTL integer argument, this is device-specific (see manpages and/or kernel sources for details).
* @return -1 on failure, 0 otherwise (usually).
- * @see man 2 ioctl
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 ioctl
*/
int ioctl(int fd, int cmd, Pointer arg) throws LastErrorException;
@@ -55,21 +59,23 @@ public interface ILibc {
/**
* Try to open (or create) a file from the specified path.
- * @param path Path to try to open.
+ *
+ * @param path Path to try to open.
* @param flags Open mode; typically O_RDONLY/O_WRONLY/O_RDWR combined with other modifiers (see POSIX).
- * @param mode Permissions to be set on the file if it is going to be created (O_CREAT).
+ * @param mode Permissions to be set on the file if it is going to be created (O_CREAT).
* @return File descriptor or -1 if the file cannot be opened.
- * @see man 2 open
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 open
*/
int open(String path, int flags, int mode) throws LastErrorException;
/**
* Close the specified file descriptor.
+ *
* @param fd File descriptor to close.
* @return -1 on failure, 0 otherwise.
- * @see man 2 close
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 close
*/
int close(int fd) throws LastErrorException;
@@ -77,23 +83,25 @@ public interface ILibc {
/**
* Request a write to the current position in the file referred by a file descriptor.
- * @param fd File descriptor of the file to write.
+ *
+ * @param fd File descriptor of the file to write.
* @param buffer Buffer with bytes to write.
- * @param count Size of the buffer.
+ * @param count Size of the buffer.
* @return Number of bytes written or -1 if an error occurred.
- * @see man 2 write
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 write
*/
int write(int fd, Buffer buffer, int count) throws LastErrorException;
/**
* Request a read from the current position in the file referred by a file descriptor.
- * @param fd File descriptor of the file to read.
+ *
+ * @param fd File descriptor of the file to read.
* @param buffer Buffer where to put the data.
- * @param count Size of the buffer.
+ * @param count Size of the buffer.
* @return Number of bytes read or -1 if an error occurred.
- * @see man 2 read
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 read
*/
int read(int fd, Buffer buffer, int count) throws LastErrorException;
@@ -101,36 +109,39 @@ public interface ILibc {
/**
* Map a file to memory.
- * @param addr Address hint from the userspace where to put the mapping in memory. Pass NULL to ignore the hint.
- * @param len Length of the memory to map.
- * @param prot Memory protection flags (PROT_READ/PROT_WRITE/PROT_EXEC). See manpages for details.
+ *
+ * @param addr Address hint from the userspace where to put the mapping in memory. Pass NULL to ignore the hint.
+ * @param len Length of the memory to map.
+ * @param prot Memory protection flags (PROT_READ/PROT_WRITE/PROT_EXEC). See manpages for details.
* @param flags Memory mapping flags (MAP_SHARED/MAP_FILE/...). See manpages for deatils.
- * @param fd Opened file descriptor of the file that needs to be mapped to memory.
- * @param off Offset in the file from which to start the mapping.
+ * @param fd Opened file descriptor of the file that needs to be mapped to memory.
+ * @param off Offset in the file from which to start the mapping.
* @return On success, address of the mapped memory. On failure, -1 (MAP_FAILED) is returned.
- * @see man 2 mmap
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 mmap
*/
Pointer mmap(Pointer addr, NativeLong len, int prot, int flags, int fd, NativeLong off) throws LastErrorException;
/**
* Unmap a file from memory.
+ *
* @param addr Address where the file was mapped.
- * @param len Length of the mapped area.
+ * @param len Length of the mapped area.
* @return -1 on failure, 0 otherwise.
- * @see man 2 munmap
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 munmap
*/
int munmap(Pointer addr, NativeLong len) throws LastErrorException;
/**
* Synchronize memory-mapped data with file contents.
- * @param addr Address where the file was mapped.
- * @param len Length of the mapped area.
+ *
+ * @param addr Address where the file was mapped.
+ * @param len Length of the mapped area.
* @param flags Synchronization type (MS_SYNC/MS_ASYNC/MS_INVALIDATE). See manpages for details.
* @return -1 on failure, 0 otherwise.
- * @see man 2 msync
* @throws LastErrorException If errno is set during the operation. Use Native#getLastError to query the error code.
+ * @see man 2 msync
*/
int msync(Pointer addr, NativeLong len, int flags) throws LastErrorException;
}
diff --git a/src/main/java/ev3dev/utils/io/NativeDevice.java b/src/main/java/ev3dev/utils/io/NativeDevice.java
index 98e89cc8..4c02a106 100644
--- a/src/main/java/ev3dev/utils/io/NativeDevice.java
+++ b/src/main/java/ev3dev/utils/io/NativeDevice.java
@@ -4,10 +4,7 @@
import com.sun.jna.Pointer;
import lombok.NonNull;
-import static ev3dev.utils.io.NativeConstants.MAP_SHARED;
-import static ev3dev.utils.io.NativeConstants.O_RDWR;
-import static ev3dev.utils.io.NativeConstants.PROT_READ;
-import static ev3dev.utils.io.NativeConstants.PROT_WRITE;
+import static ev3dev.utils.io.NativeConstants.*;
/**
*
This class provides access from Java to Linux character devices. It is intended
diff --git a/src/main/java/ev3dev/utils/io/NativeFile.java b/src/main/java/ev3dev/utils/io/NativeFile.java
index d09bed2a..d60cc706 100644
--- a/src/main/java/ev3dev/utils/io/NativeFile.java
+++ b/src/main/java/ev3dev/utils/io/NativeFile.java
@@ -21,9 +21,9 @@
* @author andy, Jakub Vaněk
*/
public class NativeFile implements Closeable, AutoCloseable {
- private static int DEFAULT_PRIVS = 0777;
+ private static final int DEFAULT_PRIVS = 0777;
protected int fd = -1;
- private ILibc libc;
+ private final ILibc libc;
/**
* Basic constructor.
diff --git a/src/main/java/ev3dev/utils/io/NativeFramebuffer.java b/src/main/java/ev3dev/utils/io/NativeFramebuffer.java
index c98d9438..d342feba 100644
--- a/src/main/java/ev3dev/utils/io/NativeFramebuffer.java
+++ b/src/main/java/ev3dev/utils/io/NativeFramebuffer.java
@@ -9,10 +9,7 @@
import java.util.Arrays;
import java.util.List;
-import static ev3dev.utils.io.NativeConstants.FBIOGET_CON2FBMAP;
-import static ev3dev.utils.io.NativeConstants.FBIOGET_FSCREENINFO;
-import static ev3dev.utils.io.NativeConstants.FBIOGET_VSCREENINFO;
-import static ev3dev.utils.io.NativeConstants.FBIOPUT_VSCREENINFO;
+import static ev3dev.utils.io.NativeConstants.*;
/**
* Linux framebuffer wrapper class
@@ -196,9 +193,9 @@ public fb_fix_screeninfo(Pointer p) {
@Override
protected List