From 3e752cc43f556a27a227db1b30d48b31448e0f2b Mon Sep 17 00:00:00 2001 From: Randall Hauch Date: Fri, 2 Oct 2015 17:07:48 -0500 Subject: [PATCH] Usability improvements and documentation changes --- README.md | 2 + .../src/org/strongback/mock/Mock.java | 8 ++++ .../src/org/strongback/DataRecorder.java | 37 +++++++++++++------ .../org/strongback/DataRecorderChannels.java | 8 ++-- .../src/org/strongback/ExecutorDriver.java | 2 + strongback/src/org/strongback/Strongback.java | 16 +++++++- .../src/org/strongback/SwitchReactor.java | 23 ++++++++++++ .../org/strongback/components/Solenoid.java | 5 +-- .../src/org/strongback/hardware/Hardware.java | 21 ++++++----- 9 files changed, 93 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 26dce75..8b23f3b 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,6 @@ Strongback is a new open source software library that makes your robot code ligh * **Logging** - Simple extendable framework to log messages at different levels. * **Uses WPILib** - Uses the WPILib classes underneath for safety and consistency. +Check out our new [Using Strongback](https://www.gitbook.com/book/strongback/using-strongback/welcome) online book. It's chocked full of descriptions, details, and example code. + We're just getting started, so stay tuned. See [our wiki](https://github.com/strongback/strongback-java/wiki) for more details, including how you can help out! diff --git a/strongback-testing/src/org/strongback/mock/Mock.java b/strongback-testing/src/org/strongback/mock/Mock.java index 3e300f7..130e9d4 100644 --- a/strongback-testing/src/org/strongback/mock/Mock.java +++ b/strongback-testing/src/org/strongback/mock/Mock.java @@ -173,6 +173,14 @@ public static MockSolenoid manualSolenoid() { return new MockSolenoid(true); } + /** + * Create a relay that operates instantaneously. + * @return the mock relay; never null + */ + public static MockRelay relay() { + return new MockRelay(); + } + /** * Create a mock gyroscope. * diff --git a/strongback/src/org/strongback/DataRecorder.java b/strongback/src/org/strongback/DataRecorder.java index adea129..4d0aded 100644 --- a/strongback/src/org/strongback/DataRecorder.java +++ b/strongback/src/org/strongback/DataRecorder.java @@ -16,9 +16,10 @@ package org.strongback; +import java.util.function.DoubleSupplier; import java.util.function.IntSupplier; -import org.strongback.components.Motor; +import org.strongback.components.SpeedSensor; import org.strongback.components.Switch; /** @@ -27,8 +28,8 @@ */ public interface DataRecorder { /** - * Registers the value of the specified {@link IntSupplier} to be logged. This method will remove any previously-registered - * supplier, switch, or motor with the same name. + * Registers by name a function that will be periodically polled to obtain and record an integer value. This method will + * remove any previously-registered supplier, switch, or motor with the same name. * * @param name the name of this data supplier * @param supplier the {@link IntSupplier} of the value to be logged @@ -38,8 +39,22 @@ public interface DataRecorder { public DataRecorder register(String name, IntSupplier supplier); /** - * Registers a {@link Switch} to be logged. This method will remove any previously-registered supplier, switch, or motor - * with the same name. + * Registers by name a function that will be periodically polled to obtain a double value and scale it to an integer value + * that can be recorded. This method will remove any previously-registered supplier, switch, or motor with the same name. + * + * @param name the name of this data supplier + * @param scale the scale factor to multiply the supplier's double values before casting to an integer value + * @param supplier the {@link IntSupplier} of the value to be logged + * @return this instance so methods can be chained together; never null + * @throws IllegalArgumentException if the {@code supplier} parameter is null + */ + default public DataRecorder register(String name, double scale, DoubleSupplier supplier) { + return register(name, () -> (int) (supplier.getAsDouble() * scale)); + } + + /** + * Registers by name a switch that will be periodically polled to obtain and record the switch state. This method will + * remove any previously-registered supplier, switch, or motor with the same name. * * @param name the name of the {@link Switch} * @param swtch the {@link Switch} to be logged @@ -49,13 +64,13 @@ public interface DataRecorder { public DataRecorder register(String name, Switch swtch); /** - * Registers a {@link Motor} to be logged. This method will remove any previously-registered supplier, switch, or motor with - * the same name. + * Registers by name a speed sensor that will be periodically polled to obtain and record the current speed. This method + * will remove any previously-registered supplier, switch, or motor with the same name. * - * @param name the name of the {@link Motor} - * @param motor the {@link Motor} to be logged + * @param name the name of the {@link SpeedSensor} + * @param sensor the {@link SpeedSensor} to be logged * @return this instance so methods can be chained together; never null - * @throws IllegalArgumentException if the {@code motor} parameter is null + * @throws IllegalArgumentException if the {@code sensor} parameter is null */ - public DataRecorder register(String name, Motor motor); + public DataRecorder register(String name, SpeedSensor sensor); } diff --git a/strongback/src/org/strongback/DataRecorderChannels.java b/strongback/src/org/strongback/DataRecorderChannels.java index f415ca0..687ffdc 100644 --- a/strongback/src/org/strongback/DataRecorderChannels.java +++ b/strongback/src/org/strongback/DataRecorderChannels.java @@ -21,7 +21,7 @@ import java.util.function.IntSupplier; import org.strongback.annotation.ThreadSafe; -import org.strongback.components.Motor; +import org.strongback.components.SpeedSensor; import org.strongback.components.Switch; import org.strongback.util.Iterators; @@ -56,10 +56,10 @@ public DataRecorder register(String name, Switch swtch) { } @Override - public DataRecorder register(String name, Motor motor) { + public DataRecorder register(String name, SpeedSensor sensor) { if (name == null) throw new IllegalArgumentException("The name may not be null"); - if (motor == null) throw new IllegalArgumentException("The motor may not be null"); - channels.addIfAbsent(new DataRecorderChannel(name + " speed", () -> (short) (motor.getSpeed() * 1000))); + if (sensor == null) throw new IllegalArgumentException("The motor may not be null"); + channels.addIfAbsent(new DataRecorderChannel(name + " speed", () -> (int) (sensor.getSpeed() * 1000))); return this; } diff --git a/strongback/src/org/strongback/ExecutorDriver.java b/strongback/src/org/strongback/ExecutorDriver.java index 09852c9..90ba662 100644 --- a/strongback/src/org/strongback/ExecutorDriver.java +++ b/strongback/src/org/strongback/ExecutorDriver.java @@ -64,6 +64,8 @@ public void start() { if (thread == null) { thread = new Thread(this::run); thread.setName(name); + // run with a bit higher priority to reduce thread context switches + thread.setPriority(8); stopped = new CountDownLatch(1); running = true; thread.start(); diff --git a/strongback/src/org/strongback/Strongback.java b/strongback/src/org/strongback/Strongback.java index e2fbfd8..fe5174a 100644 --- a/strongback/src/org/strongback/Strongback.java +++ b/strongback/src/org/strongback/Strongback.java @@ -102,7 +102,7 @@ public static enum TimerMode { private Supplier> loggersSupplier = () -> str -> new SystemLogger().enable(Level.INFO); private Supplier timeSystemSupplier = Clock::fpgaOrSystem; private TimerMode executionWaitMode = TimerMode.BUSY; - private long executionPeriodInNanos = TimeUnit.MILLISECONDS.toNanos(5); + private long executionPeriodInNanos = TimeUnit.MILLISECONDS.toNanos(20); private volatile boolean initialized = false; private String dataRecorderFilenameRoot = "strongback"; private String eventRecorderFilenameRoot = "strongback"; @@ -433,6 +433,7 @@ public static Executor executor() { * * @return Strongback's logger instance; never null * @see Configurator#useSystemLogger(org.strongback.Logger.Level) + * @see Configurator#useCustomLogger(Function) */ public static Logger logger() { return logger(""); @@ -444,11 +445,24 @@ public static Logger logger() { * @param context the context of the logger * @return Strongback's logger instance; never null * @see Configurator#useSystemLogger(org.strongback.Logger.Level) + * @see Configurator#useCustomLogger(Function) */ public static Logger logger(String context) { return INSTANCE.loggers.apply(context); } + /** + * Get Strongback's global {@link Logger} implementation. + * + * @param context the context of the logger + * @return Strongback's logger instance; never null + * @see Configurator#useSystemLogger(org.strongback.Logger.Level) + * @see Configurator#useCustomLogger(Function) + */ + public static Logger logger(Class context) { + return INSTANCE.loggers.apply(context.getName()); + } + /** * Get Strongback's {@link Clock time system} implementation. * diff --git a/strongback/src/org/strongback/SwitchReactor.java b/strongback/src/org/strongback/SwitchReactor.java index 451471f..8bbcc89 100644 --- a/strongback/src/org/strongback/SwitchReactor.java +++ b/strongback/src/org/strongback/SwitchReactor.java @@ -16,7 +16,10 @@ package org.strongback; +import java.util.function.Supplier; + import org.strongback.annotation.ThreadSafe; +import org.strongback.command.Command; import org.strongback.components.Switch; /** @@ -37,6 +40,26 @@ @ThreadSafe public interface SwitchReactor { + /** + * Submit a {@link Command} the moment when the specified {@link Switch} is triggered. + * + * @param swtch the {@link Switch} + * @param commandSupplier the supplier of the command to submit; may not be null but may return a null command + */ + default public void onTriggeredSubmit(Switch swtch, Supplier commandSupplier) { + onTriggered(swtch,()->Strongback.submit(commandSupplier.get())); + } + + /** + * Submit a {@link Command} the moment when the specified {@link Switch} is untriggered. + * + * @param swtch the {@link Switch} + * @param commandSupplier the supplier of the command to submit; may not be null but may return a null command + */ + default public void onUntriggeredSubmit(Switch swtch, Supplier commandSupplier) { + onTriggered(swtch,()->Strongback.submit(commandSupplier.get())); + } + /** * Register a {@link Runnable} function that is to be called the moment when the specified {@link Switch} is triggered. * diff --git a/strongback/src/org/strongback/components/Solenoid.java b/strongback/src/org/strongback/components/Solenoid.java index c649021..5092259 100644 --- a/strongback/src/org/strongback/components/Solenoid.java +++ b/strongback/src/org/strongback/components/Solenoid.java @@ -79,10 +79,9 @@ default boolean isRetracting() { } /** - * Determine if this solenoid is or was retracting. + * Determine if this solenoid is stopped. * - * @return {@code true} if this solenoid is in the process of retracting but not yet fully retracted, or {@code false} - * otherwise + * @return {@code true} if this solenoid is not retracting or extending, or false otherwise */ default boolean isStopped() { return getDirection() == Direction.STOPPED; diff --git a/strongback/src/org/strongback/hardware/Hardware.java b/strongback/src/org/strongback/hardware/Hardware.java index 6451722..7f671fd 100644 --- a/strongback/src/org/strongback/hardware/Hardware.java +++ b/strongback/src/org/strongback/hardware/Hardware.java @@ -253,16 +253,6 @@ public static TwoAxisAccelerometer analogAccelerometer(int xAxisChannel, int yAx */ public static final class Switches { - /** - * Create a relay on the specified channel. - * - * @param channel the channel the relay is connected to - * @return a relay on the specified channel - */ - public static Relay relay(int channel) { - return new HardwareRelay(channel); - } - /** * Create a generic normally closed digital switch sensor on the specified digital channel. * @@ -553,6 +543,17 @@ public static Solenoid doubleSolenoid(int module, int extendChannel, int retract DoubleSolenoid solenoid = new DoubleSolenoid(module, extendChannel, retractChannel); return new HardwareDoubleSolenoid(solenoid, initialDirection); } + + /** + * Create a relay on the specified channel. + * + * @param channel the channel the relay is connected to + * @return a relay on the specified channel + */ + public static Relay relay(int channel) { + return new HardwareRelay(channel); + } + } public static final class HumanInterfaceDevices {